/** * Remap a section which type is SHT_SYMTAB or SHT_DYNSYM * @param s * @param diff * @return */ int elfsh_reloc_symtab(elfshsect_t *s, eresi_Addr diff) { elfsh_Sym *symtab; u_int i; eresi_Addr vaddr; u_int count; eresi_Addr base; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); if (s == NULL || s->shdr == NULL) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid NULL parameter", -1); else if (s->shdr->sh_type != SHT_SYMTAB && s->shdr->sh_type != SHT_DYNSYM) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Section is not a symbol table", -1); symtab = elfsh_readmem(s); base = elfsh_get_object_baseaddr(s->parent); for (count = i = 0; i < s->shdr->sh_size / sizeof(elfsh_Sym); i++) { vaddr = elfsh_get_symbol_value(symtab + i); if (vaddr > base) { elfsh_set_symbol_value(symtab + i, vaddr + diff); count++; } } /* Synchronize the symtab hash table */ elfsh_sync_sorted_symtab(s); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (count)); }
/** * Called from elfsh_fixup_symtab * When trying to inject part of the libc, some bss symbols have a wrong sctndx * @param symtab * @return */ elfshsect_t *elfsh_fixup_sctndx(elfshsect_t *symtab) { int index; elfsh_Sym *sym; elfsh_SAddr offset; elfsh_Shdr *shdr; elfshsect_t *sct; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); //return (symtab); // XXX sym = symtab->data; shdr = symtab->parent->sht + symtab->index; for (index = 0; index < shdr->sh_size / sizeof(elfsh_Sym); index++) { if (elfsh_get_symbol_link(sym + index) != SHN_COMMON) { if (elfsh_get_symbol_type(sym + index) == STT_SECTION) continue; sct = elfsh_get_parent_section(symtab->parent, elfsh_get_symbol_value(sym + index), &offset); if (sct == NULL) { sct = elfsh_get_section_by_index(symtab->parent, elfsh_get_symbol_link(sym + index), NULL, NULL); if (sct && elfsh_get_section_type(sct->shdr) == SHT_NOBITS) { #if __DEBUG_MAP__ printf(" [*] Symbol [%s] sctndx changed from %u to SHN_COMMON\n", elfsh_get_symbol_name(symtab->parent, sym + index), elfsh_get_symbol_link(sym + index)); #endif elfsh_set_symbol_link(sym + index, SHN_COMMON); continue; } } if (sct && elfsh_get_section_type(sct->shdr) == SHT_NOBITS) { elfsh_set_symbol_link(sym + index, SHN_COMMON); #if __DEBUG_MAP__ printf(" [*] Symbol [%s] sctndx changed to SHN_COMMON\n", elfsh_get_symbol_name(symtab->parent, sym + index)); #endif } } } PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, symtab); }
/** * Print the chosen symbol table * @param file * @param sect * @param tab * @param num * @param regx * @param get_symname * @return */ int ds(elfshobj_t *file, elfshsect_t *sect, u_int num, regex_t *regx, char *(*get_symname)(elfshobj_t *f, elfsh_Sym *s)) { elfsh_Sym *table; char *name; char *type; char *bind; u_int typenum; u_int bindnum; u_int foff; u_int index; char *sect_name; char buff[512]; char off[50]; char type_unk[ERESI_MEANING + 1]; char bind_unk[ERESI_MEANING + 1]; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); /* Sort the table if necessary */ if (world.state.sort != NULL) switch (*world.state.sort) { case ELFSH_SORT_BY_ADDR: table = sect->altdata; break; case ELFSH_SORT_BY_SIZE: table = sect->terdata; break; default: PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unknown sort mode", -1); } /* Avoid reading inexistant memory in the process for .symtab */ else table = (elfsh_Sym *) (sect->shdr->sh_addr ? elfsh_readmem(sect) : sect->data); /* Browse symtab */ for (index = 0; index < num; index++) { /* Retreive names */ typenum = elfsh_get_symbol_type(table + index); bindnum = elfsh_get_symbol_bind(table + index); type = (char *) (typenum > ELFSH_SYMTYPE_MAX ? revm_build_unknown(type_unk, "type", typenum) : elfsh_sym_type[typenum].desc); bind = (char *) (bindnum >= ELFSH_SYMBIND_MAX ? revm_build_unknown(bind_unk, "type", bindnum) : elfsh_sym_bind[bindnum].desc); name = get_symname(world.curjob->curfile, table + index); sect_name = NULL; sect = elfsh_get_parent_section(world.curjob->curfile, table[index].st_value, NULL); if (sect == NULL && table[index].st_shndx) sect = elfsh_get_section_by_index(world.curjob->curfile, table[index].st_shndx, NULL, NULL); if (sect != NULL) sect_name = elfsh_get_section_name(world.curjob->curfile, sect); /* Fixup names */ if (name == NULL || *name == 0) name = ELFSH_NULL_STRING; if (type == NULL || *type == 0) type = ELFSH_NULL_STRING; if (bind == NULL || *bind == 0) bind = ELFSH_NULL_STRING; if (sect_name == NULL) sect_name = ELFSH_NULL_STRING; foff = (!table[index].st_value ? 0 : elfsh_get_foffset_from_vaddr(world.curjob->curfile, table[index].st_value)); if (sect && sect->shdr->sh_addr != table[index].st_value) snprintf(off, sizeof(off), " + %s", revm_colornumber("%u", (u_int) (table[index].st_value - sect->shdr->sh_addr))); else *off = '\0'; /* Different output depending on the quiet flag */ if (!world.state.revm_quiet) { snprintf(buff, sizeof(buff), " %s %s %s %s %s%s " "%s%s %s%s %s%s => %s%s\n", revm_colornumber("[%03u]", index), revm_coloraddress(XFMT, (eresi_Addr) elfsh_get_symbol_value(table + index) + file->rhdr.base), revm_colortypestr_fmt("%-8s", type), revm_colorstr_fmt("%-40s", name), revm_colorfieldstr("size:"), revm_colornumber("%010u", elfsh_get_symbol_size(table + index)), revm_colorfieldstr("foffset:"), revm_colornumber("%06u", foff), revm_colorfieldstr("scope:"), revm_colortypestr_fmt("%-6s", bind), revm_colorfieldstr("sctndx:"), revm_colornumber("%02u", elfsh_get_symbol_link(table + index)), revm_colorstr(sect_name), off); } else { snprintf(buff, sizeof(buff), " %s %s %s %s %s%s %s%s %s%-6s\n", revm_colornumber("[%03u]", index), revm_coloraddress(XFMT, (eresi_Addr) elfsh_get_symbol_value(table + index) + file->rhdr.base), revm_colortypestr_fmt("%-8s", type), revm_colorstr_fmt("%-15s", name), revm_colorfieldstr("sz:"), revm_colornumber("%06u", elfsh_get_symbol_size(table + index)), revm_colorfieldstr("foff:"), revm_colornumber("%06u", foff), revm_colorfieldstr("scop:"), revm_colortypestr_fmt("%-6s", bind)); } if (regx == NULL || (regx != NULL && regexec(regx, buff, 0, 0, 0) == 0)) { /* If the user ask quit, we just break */ if (revm_output(buff) == -1) break; } revm_endline(); } revm_endline(); revm_output("\n"); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }