Elf32_Shdr *elf_section_by_name(Elf32_Ehdr *hdr, char *name) { int i; for(i=0; i < hdr->e_shnum; i++) { if(!strcmp(elf_lookup_sh_string(hdr, elf_section(hdr, i)->sh_name), name)) return elf_section(hdr, i); } return NULL; }
int kmodule_bind_got_reldyn(Elf32_Ehdr *h, t_elfparse *ep, t_elfparse_symb *ksym) { int sz; t_elfparse_sections *secs; secs = &ep->sections; sz = secs->reldyn->sh_size / secs->reldyn->sh_entsize - 1; for ( ; sz >= 0 ; --sz) { Elf32_Rel *rel = (Elf32_Rel *)((int)h + secs->reldyn->sh_offset) + sz; Elf32_Shdr *tab = elf_section(h, secs->reldyn->sh_link); Elf32_Sym *newsymbol = ((Elf32_Sym *)((int)h + tab->sh_offset)) + ELF32_R_SYM(rel->r_info); /* printf("%x %x %x\n", rel, tab, newsymbol); */ if (ELF32_R_TYPE(rel->r_info) != R_386_GLOB_DAT) continue; if (newsymbol->st_shndx == SHN_UNDEF) { Elf32_Sym *newrealsymbol = ((Elf32_Sym *)((int)h + secs->dynsym->sh_offset)) + ELF32_R_SYM(rel->r_info); char *name = (char *)h + secs->dynstr->sh_addr + newrealsymbol->st_name; *(unsigned*)((int)h + rel->r_offset) = kresolve_symb(name, ksym); } else *(unsigned*)((int)h + rel->r_offset) = newsymbol->st_value + (int)h; } return (0); }
int kmodule_bind_got_relplt(Elf32_Ehdr *h, t_elfparse *ep, t_elfparse_symb *ksym) { int sz; t_elfparse_sections *secs; secs = &ep->sections; sz = secs->relplt->sh_size / secs->relplt->sh_entsize - 1; for ( ; sz >= 0 ; --sz) { Elf32_Rel *rel = (Elf32_Rel *)((int)h + secs->relplt->sh_offset) + sz; if (ELF32_R_SYM(rel->r_info) == SHN_UNDEF) { printf("Skipping undef symb\n"); continue; } Elf32_Shdr *tab = elf_section(h, secs->relplt->sh_link); Elf32_Sym *newsymbol = ((Elf32_Sym *)((int)h + tab->sh_offset)) + ELF32_R_SYM(rel->r_info); if (newsymbol->st_shndx == SHN_UNDEF) { Elf32_Sym *newrealsymbol = ((Elf32_Sym *)((int)h + secs->dynsym->sh_offset)) + ELF32_R_SYM(rel->r_info); char *name = (char *)h + secs->dynstr->sh_addr + newrealsymbol->st_name; *(unsigned*)((int)h + rel->r_offset) = kresolve_symb(name, ksym); } else *(unsigned*)((int)h + rel->r_offset) = newsymbol->st_value + (int)h; } return (0); }
int lua_elf_t_section_exists (lua_State * L) { struct _elf * elf; struct _elf_section section; int section_i; int found; char * name; elf = lua_check_elf(L, 1); name = (char *) luaL_checkstring(L, 2); lua_pop(L, 2); found = 0; for (section_i = 0; section_i < int_t_get(elf_shnum(elf)); section_i++) { elf_section(elf, §ion, section_i); if (strcmp(elf_section_name(§ion), name) == 0) { found = 1; break; } } if (found) lua_pushboolean(L, 1); else lua_pushboolean(L, 0); return 1; }
int lua_elf_t_symbols (lua_State * L) { struct lua_elf_t * elf_t; struct lua_elf_section_t * section_t; struct _elf_section section; struct _elf * elf; int section_i; int sym_i; int symbols_i = 1; struct lua_elf_symbol_t * symbol_t; elf_t = lua_check_elf_t(L, 1); lua_pop(L, 1); elf = elf_t->elf; lua_newtable(L); for (section_i = 0; section_i < int_t_get(elf_shnum(elf)); section_i++) { elf_section(elf, §ion, section_i); if ( (int_t_get(elf_section_type(§ion)) == SHT_SYMTAB) || (int_t_get(elf_section_type(§ion)) == SHT_DYNSYM)) { lua_push_elf_section_t(L); section_t = lua_check_elf_section_t(L, -1); lua_pop(L, 1); elf_section(elf, &(section_t->section), section_i); section_t->elf_t = elf_t; elf_t->ref_count++; for (sym_i = 0; sym_i < elf_section_num(§ion); sym_i++) { lua_pushinteger(L, (lua_Integer) symbols_i++); lua_push_elf_symbol_t(L); symbol_t = lua_check_elf_symbol_t(L, -1); elf_section_symbol(§ion, &(symbol_t->symbol), sym_i); symbol_t->section_t = section_t; section_t->ref_count++; elf_t->ref_count++; lua_settable(L, -3); } } } return 1; }
int lua_elf_t_section (lua_State * L) { struct lua_elf_t * elf; struct _elf_section section; int section_i = -1; int found; struct lua_elf_section_t * section_t; elf = lua_check_elf_t(L, 1); if (lua_isnumber(L, 2)) section_i = luaL_checkinteger(L, 2); else if (lua_isstring(L, 2)) { found = 0; for (section_i = 0; section_i < int_t_get(elf_shnum(elf->elf)); section_i++) { elf_section(elf->elf, §ion, section_i); if (strcmp(elf_section_name(§ion), lua_tostring(L, 2)) == 0) { found = 1; break; } } if (! found) luaL_error(L, "no section found by name %s", lua_tostring(L, 2)); } else luaL_error(L, "expected a string or number"); lua_pop(L, 2); if (section_i >= int_t_get(elf_shnum(elf->elf))) luaL_error(L, "elf does not have %d sections", section_i); lua_push_elf_section_t(L); section_t = lua_check_elf_section_t(L, 1); elf_section(elf->elf, &(section_t->section), section_i); section_t->elf_t = elf; elf->ref_count++; return 1; }
int lua_elf_symbol_t_disassemble (lua_State * L) { struct lua_elf_symbol_t * symbol_t; struct _elf * elf; struct _elf_symbol symbol; struct _elf_section section; unsigned char * data; int section_i; int symbol_i; uint_t offset; int end_address_set = 0; uint_t end_address; uint_t_8_set(&end_address, 0); symbol_t = lua_check_elf_symbol_t(L, 1); lua_pop(L, 1); elf = symbol_t->section_t->elf_t->elf; // find function sym at next highest address, save it's start address in // end_address for (section_i = 0; section_i < int_t_get(elf_shnum(elf)); section_i++) { elf_section(elf, §ion, section_i); if (int_t_get(elf_section_type(§ion)) == SHT_SYMTAB) { for (symbol_i = 0; symbol_i < elf_section_num(§ion); symbol_i++) { elf_section_symbol(§ion, &symbol, symbol_i); if ( (elf_symbol_type(&symbol) == STT_FUNC) && (uint_t_cmp(elf_symbol_value(&(symbol_t->symbol)), elf_symbol_value(&symbol)) < 0) && (uint_t_cmp(elf_symbol_shndx(&symbol), elf_symbol_shndx(&(symbol_t->symbol))) == 0) && ( (uint_t_cmp(elf_symbol_value(&symbol), &end_address) < 0) || (end_address_set == 0) ) ) { uint_t_set(&end_address, elf_symbol_value(&symbol)); end_address_set = 1; } } } } // end address not set? set it to the end of the linked section if (end_address_set == 0) { elf_section(elf, §ion, uint_t_get(elf_symbol_shndx(&(symbol_t->symbol)))); uint_t_int_t(&end_address, elf_section_size(§ion)); uint_t_add(&end_address, elf_section_addr(§ion)); } // load the linked section elf_section(elf, §ion, uint_t_get(elf_symbol_shndx(&(symbol_t->symbol)))); data = elf_section_data(§ion); uint_t_set(&offset, elf_symbol_value(&(symbol_t->symbol))); uint_t_sub(&offset, elf_section_addr(§ion)); // disassemble that function like it was 1980 lua_dis_table(L, elf_symbol_value(&(symbol_t->symbol)), &(data[uint_t_get(&offset)]), uint_t_get(&end_address) - uint_t_get(elf_symbol_value(&(symbol_t->symbol))), ELF_CLASS(elf)); return 1; }
static inline char *elf_str_table(Elf32_Ehdr *hdr) { if(hdr->e_shstrndx == SHN_UNDEF) return NULL; return (char *)hdr + elf_section(hdr, hdr->e_shstrndx)->sh_offset; }