#include #include #include #include #include #include /* * 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: %s\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++; } } } 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; elf = (Elf32_Ehdr *)((unsigned int)(main) & 0xfffff000); phdr = (Elf32_Phdr *)((unsigned char *)(elf) + elf->e_phoff); 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); } phdr += i; dyn = (Elf32_Dyn *)(phdr->p_vaddr); cnt = phdr->p_filesz / sizeof(Elf32_Dyn); got = NULL; for(i = 0; i < cnt; i++) { if(dyn[i].d_tag == DT_PLTGOT) got = (unsigned long *)(dyn[i].d_un.d_ptr); } if(got == NULL) { printf("Unable to find GOT\n"); exit(EXIT_FAILURE); } lm = (struct link_map *)(got[1]); printf("link_map @ 0x%08x\n", lm); resolve(lm, "connect"); resolve(lm, "read"); }