void fix_dynamic_table(elf_bf_exec_t *env) { elfsh_Dyn *dyn; elfshobj_t *f = env->ee_lm.lm_f; dyn = elfsh_get_dynamic_entry_by_type(f, DT_RELA); env->ee_rela_orig = elfsh_get_dynentry_val(dyn); elfsh_set_dynentry_val(dyn, elfsh_get_section_addr(env->ee_lm.lm_reloc->shdr)); dyn = elfsh_get_dynamic_entry_by_type(f, DT_RELASZ); env->ee_relasz_orig = elfsh_get_dynentry_val(dyn); elfsh_set_dynentry_val(dyn, elfsh_get_section_size(env->ee_lm.lm_reloc->shdr)); env->ee_dt_relasz_value = elfsh_get_section_size(env->ee_lm.lm_reloc->shdr); env->ee_reloc_end_value = elfsh_get_section_addr(env->ee_lm.lm_reloc->shdr) + env->ee_dt_relasz_value; dyn = elfsh_get_dynamic_entry_by_type(f, DT_GNU_HASH); env->ee_dt_gnu_hash = elfsh_get_dynentry_val(dyn); dyn = elfsh_get_dynamic_entry_by_type(f, DT_SYMTAB); env->ee_sym_orig = elfsh_get_dynentry_val(dyn); elfsh_set_dynentry_val(dyn, elfsh_get_section_addr(env->ee_lm.lm_sym->shdr)); dyn = elfsh_get_dynamic_entry_by_type(f, DT_JMPREL); env->ee_dt_jmprel_value = elfsh_get_dynentry_val(dyn); elfsh_set_dynentry_val(dyn, 0); dyn = elfsh_get_dynamic_entry_by_type(f, DT_PLTRELSZ); env->ee_dt_pltrelsz_value = elfsh_get_dynentry_val(dyn); elfsh_set_dynentry_val(dyn, 0); //dyn = elfsh_get_dynamic_entry_by_type(f, DT_SYMENT); //env->ee_sym_orig = elfsh_get_dynentry_val(dyn); }
void fixup_dynamic_rela(elfshobj_t *f, eresi_Addr rel, eresi_Addr sz) { elfsh_Dyn *dyn; dyn = elfsh_get_dynamic_entry_by_type(f, DT_RELA); elfsh_set_dynentry_val(dyn, rel); dyn = elfsh_get_dynamic_entry_by_type(f, DT_RELASZ); elfsh_set_dynentry_val(dyn, sz); }
/** * @brief Change the DT_PLTGOT entry in the .dynamic section to change * the relocation base address. * @param file The host file. * @param altgot Section descriptor for the .elfsh.altgot section. * @param got Section descriptor for the .got section. * @param plt Section descriptor for the .plt section. * @param altplt Section descriptor for the .elfsh.altplt section. * @return Success (0) or Error (-1). */ int elfsh_redirect_pltgot(elfshobj_t *file, elfshsect_t *altgot, elfshsect_t *got, elfshsect_t *plt, elfshsect_t *altplt) { elfsh_Sym *sym; elfsh_Dyn *dyn; elfshsect_t *relplt; char *name; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); /* Get the DT_PLTGOT entry in .dynamic */ dyn = elfsh_get_dynamic_entry_by_type(file, DT_PLTGOT); if (!dyn) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Cannot find DT_PLTGOT", -1); /* Get the PLT related relocation table */ name = IS_REL(plt) ? ELFSH_SECTION_NAME_RELPLT : ELFSH_SECTION_NAME_RELAPLT; relplt = elfsh_get_section_by_name(plt->parent, name, 0, 0, 0); if (!relplt) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Cannot find RELPLT section by name", -1); /* On MIPS we change it from .got to .alt.got : ALTGOT technique */ if (FILE_IS_MIPS(file) || FILE_IS_IA32(file)) { elfsh_set_dynentry_val(dyn, altgot->shdr->sh_addr); if (FILE_IS_MIPS(file)) { elfsh_set_gpvalue(file, altgot->shdr->sh_addr + 0x8000 - 0x10); sym = elfsh_get_dynsymbol_by_name(file, "_gp_disp"); if (sym == NULL) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Could not find _gp_disp ", -1); sym->st_value = altgot->shdr->sh_addr + 0x8000 - 0x10; elfsh_shift_mips_relocs(file, altgot->shdr->sh_addr - got->shdr->sh_addr); } else elfsh_shift_ia32_relocs(file, altgot->shdr->sh_addr - got->shdr->sh_addr, relplt, ELFSH_NOLIMIT); } /* On SPARC we change it from .plt to .alt.plt : ALTPLT technique */ else if (FILE_IS_SPARC(file)) { elfsh_set_dynentry_val(dyn, altplt->shdr->sh_addr); elfsh_shift_sparc_relocs(file, altplt->shdr->sh_addr - plt->shdr->sh_addr, relplt); } PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }
/** * Remap the .dynamic section * @param sect * @param diff * @return */ int elfsh_reloc_dynamic(elfshsect_t *sect, eresi_Addr diff) { elfshsect_t *parent; elfsh_Dyn *dyn; u_int index; u_int count; eresi_Addr val; u_int nbr; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); if (sect == NULL || sect->shdr == NULL) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid NULL parameter", -1); else if (sect->shdr->sh_type != SHT_DYNAMIC) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unexpected section type", -1); nbr = sect->shdr->sh_size / sizeof(elfsh_Dyn); for (dyn = elfsh_readmem(sect), count = index = 0; index < nbr; index++) { val = elfsh_get_dynentry_val(dyn + index); parent = elfsh_get_parent_section(sect->parent, val, NULL); if (val && parent != NULL && parent->shdr->sh_addr != NULL) { elfsh_set_dynentry_val(dyn + index, val + diff); count++; } } PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (count)); }
void fixup_dynamic_sym(elfshobj_t *f, eresi_Addr sym, eresi_Addr sz) { elfsh_Dyn *dyn; dyn = elfsh_get_dynamic_entry_by_type(f, DT_SYMTAB); elfsh_set_dynentry_val(dyn, sym); //dyn = elfsh_get_dynamic_entry_by_type(f, DT_RELASZ); //elfsh_set_dynentry_val(dyn, sz); }
/** * Shift the .dynamic section in ET_DYN files * * @param file * @param size * @return */ int elfsh_shift_dynamic(elfshobj_t *file, u_int size) { elfsh_Dyn *dyn; u_int nbr; u_int idx; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); dyn = elfsh_get_dynamic(file, &nbr); if (dyn == NULL) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Cannot find .dynamic in ET_DYN", -1); for (idx = 0; idx < nbr; idx++) if (elfsh_shiftable_dynent(dyn + idx)) elfsh_set_dynentry_val(dyn + idx, elfsh_get_dynentry_val(dyn + idx) + size); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (0)); }