/* * Copyright (C) 2009 nex * * Reepointer is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 or (at your option) any later * version. * * Reepointer is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with Reepointer; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include typedef struct stat stat_t; typedef struct user_regs_struct reg_t; void die(int code,char *fmt,...); /* Die function...I love it...:) */ void perr_die(char * string,int code); /* Stupid function -.-' */ int is_elf(Elf32_Ehdr *elf); /* Useful function... */ int main(int argc,char *argv[]) { char * path; int fd; unsigned int size,entry; unsigned char * buf; stat_t stats; pid_t pid; reg_t regs; int status = 0; /* Elf32 Structure */ Elf32_Ehdr *elf_header; if (!argv[1]) die(-1,"Usage: %s \n",argv[0]); if(getuid()) /* Root privilege */ die(-1,"You MUST be root to run this program.\n"); pid = atoi(argv[1]); /* Take pid */ path = (char*)malloc(sizeof(char)*10+strlen(argv[1])*sizeof(char)); sprintf(path,"/proc/%d/exe",pid); /* Take the executable path */ printf( "@ File name \t: %s .\n", path ); if ((fd = open(path,0x0)) < 0 ) /* Open the file in read only mode O_RDONLY (fcntl.h) */ perr_die("open",-1); printf( "@ File descriptor \t: %d .\n", fd ); if( stat( path, &stats ) < 0 ) /* Find file's lenght with stat */ perr_die("stats",-1); size = stats.st_size; printf( "@ File size \t: %d bytes .\n", size ); buf = (unsigned char*)malloc(sizeof(char)*size+1); /* Alloc memory for reading*/ if ( read(fd,buf,size) != size) /* Read all bytes in the file */ perr_die("read",-1); close(fd); /* Close file descriptor */ elf_header = (Elf32_Ehdr *)buf; /* Copy the buffer in Elf32_Ehdr structure */ if (is_elf(elf_header) == -1) /* Not valid elf */ die(-1,"This is not valid elf file.\n"); entry = elf_header->e_entry; printf("@ Entry point \t: 0x%X .\n", entry ); /* Ed ecco l'entry point del nostro file */ if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) /* Attach to process */ perr_die("attach",-1); wait(&status); /* Wait the process */ if (ptrace(PTRACE_GETREGS, pid, ®s, ®s) < 0) /* Get attual registry */ perr_die("getregs",-1); printf("@ Old EIP \t: 0x%lX .\n", regs.eip ); printf("@ Injecting to EIP the entry point address...\n"); regs.eip = entry; /* Setting EIP(Istruction Pointer) to Entry Point */ if (ptrace(PTRACE_SETREGS, pid, ®s, ®s) < 0) /* Set the modified registry */ perr_die("setregs",-1); ptrace(PTRACE_DETACH, pid, NULL, NULL); /* Detach process */ free(buf); /* Free buffer memory */ return 0; } void die(int code,char *fmt,...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); exit(code); } void perr_die(char * string,int code) { perror(string); exit(code); } int is_elf(Elf32_Ehdr *elf) { if ((elf->e_ident[0] != 0x7f) || (elf->e_ident[1] != 'E' ) || (elf->e_ident[2] != 'L' ) || (elf->e_ident[3] != 'F' ) || (elf->e_ident[4] != 1 ) || (elf->e_ident[5] != 1 )) return -1; return 0; }