/* * from spoty@r00tworld.com * * plt resolving, with some help from #social/pulltheplug (dmk ) * * 10:43 quick msg the plt-resolve-netbsd.c has to be compiled w/ -DELFSIZE=32 to actually compile.. forgot to tell you * */ #include #include #include #include #include #include #include #define RTLD_MAGIC 0xd550b87a /* found in /usr/src/libexec/ld.elf_so/rtld.h , thx dmk :)*/ typedef struct Stub_Obj_Entry { Elf32_Word magic; /* Magic number (sanity check) */ Elf32_Word version; /* Version number of struct format */ struct Stub_Obj_Entry *next; char *path; /* Pathname of underlying file (%) */ int refcount; int dl_refcount; /* Number of times loaded by dlopen */ /* These items are computed by map_object() or by digest_phdr(). */ caddr_t mapbase; /* Base address of mapped region */ size_t mapsize; /* Size of mapped region in bytes */ size_t textsize; /* Size of text segment in bytes */ Elf_Addr vaddrbase; /* Base address in shared object file */ caddr_t relocbase; /* Reloc const = mapbase - *vaddrbase */ Elf_Dyn *dynamic; /* Dynamic section */ caddr_t entry; /* Entry point */ const Elf_Phdr *__junk001; size_t pathlen; /* Pathname length */ /* Items from the dynamic section. */ Elf_Addr *pltgot; /* PLTGOT table */ const Elf_Rel *rel; /* Relocation entries */ const Elf_Rel *rellim; /* Limit of Relocation entries */ const Elf_Rela *rela; /* Relocation entries */ const Elf_Rela *relalim; /* Limit of Relocation entries */ const Elf_Rel *pltrel; /* PLT relocation entries */ const Elf_Rel *pltrellim; /* Limit of PLT relocation entries */ const Elf_Rela *pltrela; /* PLT relocation entries */ const Elf_Rela *pltrelalim; /* Limit of PLT relocation entries */ const Elf_Sym *symtab; /* Symbol table */ const char *strtab; /* String table */ unsigned long strsize; /* Size in bytes of string table */ /* there is more.... */ /* ... */ } stuboe_t; /* * this code resolves external library references etc. */ void resolve(void *l, char *what) { struct link_map *lm = (struct link_map *)(l); Elf32_Dyn *dyn; Elf32_Sym *sym; char *strtab; for(;lm != NULL; lm = lm->l_next) { printf("load_addr: 0x%08x\n", lm->l_addr); printf("name: %p\n", lm->l_name); printf("dyn sect: 0x%08x\n", lm->l_ld); printf("lm->next: 0x%08x\n", lm->l_next); printf("--\n"); dyn = (Elf32_Dyn *)(unsigned int)(lm->l_ld); sym = NULL; strtab = NULL; printf("dyn is @ 0x%08x\n", dyn); fflush(stdout); for(; dyn->d_tag != DT_NULL; dyn++) { if(dyn->d_tag == DT_STRTAB) strtab = (char *)(dyn->d_un.d_ptr); if(dyn->d_tag == DT_SYMTAB) sym = (Elf32_Sym *)(dyn->d_un.d_ptr); } while(sym) { if(sym->st_name > 0x10000) { printf("breaking cause sym->st_name is too large\n"); break; } printf("%s\n", strtab + sym->st_name); printf("%d\n", sym->st_value); printf("%d\n", sym->st_info); printf("%d\n", sym->st_size); if(strcmp(strtab + sym->st_name, what) == 0) { printf("--> we have found %s @ 0x%08x\n", strtab + sym->st_name, sym->st_value); } sym++; } } } /* here is the netbsd version of the symbol resolver */ void netbsd_resolve(void * l, char * what) { stuboe_t * p = (stuboe_t *)l; Elf32_Dyn *dyn; Elf32_Sym *sym; char *strtab; p = p->next; for (; p != NULL ; p = p->next) { fprintf(stderr, "I M IN %s\n", p->path); fprintf(stderr, "DYNAMIC @ %p\n", p->dynamic); dyn = (Elf32_Dyn *) (unsigned int)(p->dynamic); sym = NULL; strtab = NULL; fprintf(stderr,"BASE: %p\n", p->mapbase); for (; dyn->d_tag != DT_NULL; dyn++) { fprintf(stderr,"DYN @ %p\n", dyn); fprintf(stderr,"TAG: 0x%08x\n", dyn->d_tag); if (dyn->d_tag == DT_STRTAB) { strtab = (char *)(dyn->d_un.d_ptr); errno = 0; if ((access(strtab,0) < 0) && (errno == EFAULT)) strtab = (char *)(p->mapbase+(int)dyn->d_un.d_ptr); fprintf(stderr,"STRTAB: %p\n", strtab); } if (dyn->d_tag == DT_SYMTAB) sym = (Elf32_Sym *)(dyn->d_un.d_ptr); errno = 0; if ((access((char *)sym,0) < 0) && (errno == EFAULT)) sym = (Elf32_Sym *)(p->mapbase+(int)dyn->d_un.d_ptr); fprintf(stderr,"SYMTAB: %p\n", sym); } fprintf(stderr," JE SORSS!!!!!\n"); while (sym) { fprintf(stderr," JE SUIS DEDANS sym: %p strtab: %p!!!\n", sym, strtab); if (sym->st_name > 0x10000) break; fprintf(stderr," SUIVANT!!!\n"); fprintf(stderr,"symbol: %s\n", strtab+sym->st_name); fprintf(stderr," SUIVANT 2!!!\n"); fprintf(stderr,"value: 0x%08x\n", sym->st_value); fprintf(stderr," SUIVANT 3!!!\n"); fprintf(stderr,"info: 0x%08x\n", sym->st_info); fprintf(stderr," SUIVANT 4!!!\n"); fprintf(stderr,"size: 0x%08x\n", sym->st_size); if (strcmp(strtab+sym->st_name, what) == 0) fprintf(stderr, ">>>> found %s @ 0x%08x\n", strtab+sym->st_name, sym->st_value); sym++; } } } int main(int argc, char **argv) { Elf32_Ehdr *elf; Elf32_Phdr *phdr; Elf32_Dyn *dyn; int i, cnt; unsigned long *got; struct link_map *lm; stuboe_t * so, * ptr; elf = (Elf32_Ehdr *)((unsigned int)(main) & 0xfffff000); phdr = (Elf32_Phdr *)((unsigned char *)(elf) + elf->e_phoff); fprintf(stderr, "MAG1: %c MAG2: %c MAG3: %c\n", elf->e_ident[EI_MAG1], elf->e_ident[EI_MAG2], elf->e_ident[EI_MAG3]); if (!( ( elf->e_ident[EI_MAG1] == 'E' ) && ( elf->e_ident[EI_MAG2] == 'L') )) return -1; for(i = 0; i < elf->e_phnum; i++) { if(phdr[i].p_type == PT_DYNAMIC) break; } if(i == elf->e_phnum) { printf("Not a dynamic elf file?\n"); exit(EXIT_FAILURE); } fprintf(stderr, "I: %d\n", i); phdr += i; fprintf(stderr, "phdr: %p type: %d\n", phdr, phdr->p_type); dyn = (Elf32_Dyn *)(phdr->p_vaddr); cnt = phdr->p_filesz / sizeof(Elf32_Dyn); fprintf(stderr,"number of dyn elements : %d\n", cnt); got = NULL; for(i = 0; i < cnt; i++) { if(dyn[i].d_tag == DT_PLTGOT) { fprintf(stderr,"FOUND GOT!!\n"); fprintf(stderr,"val: %p\n", (void *) dyn[i].d_un.d_val); fprintf(stderr,"ptr: %p\n", (void *) dyn[i].d_un.d_ptr); got = (unsigned long *)(dyn[i].d_un.d_ptr); } } if(got == NULL) { printf("Unable to find GOT\n"); exit(EXIT_FAILURE); } fprintf(stderr, "got[1]: %p\n", got[1]); /* this is not link map */ /* lm = (struct link_map *)(got[1]); fprintf(stderr,"lm at %p\n", lm); fprintf(stderr,"lm->l_addr: %p\n", lm->l_addr); fprintf(stderr,"lm->l_ld: %p\n", lm->l_ld); fprintf(stderr,"lm->l_next: %p\n", lm->l_next); */ so = (stuboe_t *) (got[1]); fprintf(stderr,"soe at %p\n", so); fprintf(stderr,"soe->magic: 0x%08x\n", so->magic); fprintf(stderr,"soe->version: 0x%08x\n", so->version); fprintf(stderr,"soe->next: %p\n", so->next); fprintf(stderr,"soe->path: %s\n", so->path); fprintf(stderr,"soe->pltgot: %p\n", so->pltgot); fprintf(stderr,"soe->symtab: %p\n", so->symtab); ptr = so; while ( ptr ) { fprintf(stderr,"---- ELEMENT ----\n"); fprintf(stderr,"soe->magic: 0x%08x\n", ptr->magic); fprintf(stderr,"soe->version: 0x%08x\n", ptr->version); fprintf(stderr,"soe->next: %p\n", ptr->next); fprintf(stderr,"soe->path: %s\n", ptr->path); fprintf(stderr,"soe->dynamic: %p\n", ptr->dynamic); fprintf(stderr,"soe->symtab: %p\n", ptr->symtab); ptr = ptr->next; } netbsd_resolve(so, "connect"); /* printf("link_map @ 0x%08x\n", lm); resolve(lm, "connect"); resolve(lm, "read"); */ }