// With help from: // http://pramode.net/articles/lfy/ptrace/pramode.html // http://www.psc.ru/sergey/bgtraq/PODVAL/LDPRoblem.htm // And code from: John Daniele jdaniele@kpmg.ca // Currently notices ioctl() calls to lookup HWADDR (but doesn't alter) // Change def of WRAPPED to change code executed. #include #include #include #include #include #include #include #include // For EBX define (which is just 0) #include // For number/define of syscall to capture #include #define WRAPPED "/sbin/ifconfig" int main(void) { int status = 0, pid, r; struct user_regs_struct uregs; if ((pid=fork())==0) { ptrace(PTRACE_TRACEME, 0, 0, 0); kill(getpid(), SIGINT); execl(WRAPPED, WRAPPED,NULL,(char *)0); exit(0); } while (1) { int x, y; ptrace(PTRACE_SYSCALL, pid, 0, 0); wait(&status); if (WIFEXITED(status)) exit(0); // We have a syscall, or an exit x = ptrace(PTRACE_PEEKUSER, pid, 44, 0); if (x==-1 && errno==ESRCH) exit(0); // ioctl() if (x == SYS_ioctl) { // // Example - this changes the return value? // y = ptrace(PTRACE_PEEKUSER, pid, EBX, 0); // ptrace(PTRACE_POKEDATA, pid, y, 2175984000); ptrace(PTRACE_GETREGS, pid, 0, &uregs); if (uregs.ecx==SIOCGIFHWADDR) { char *argp; // Go to return of syscall ptrace(PTRACE_SYSCALL, pid, 0, 0); ptrace(PTRACE_GETREGS, pid, 0, &uregs); printf("ioctl(%x,SIOCGIFHWADDR,0x%x..)\n",uregs.ebx,uregs.edx); // Not sure how to change result of ioctl HWADDR. // The LD_PRELOAD code implies that we should store it at argp+18 // but that didn't seem to work when I tried it. //argp = (char*)uregs.edx; //printf("ARGP: %x\n",argp); //ptrace(PTRACE_SETREGS, pid, 0, &uregs); } } } }