/** * @brief Shift relocation tables at some point for allowing non-present symbol resolving * mostly applied on section injection for ET_DYN objects. * @param file The host file where shift must happens. * @param diff Absolute difference to shift to. * @param relplt Section descriptor for the .relplt section. * @param limit Upper limit address beyond which shifting must not be performed (or ELFSH_NOLIMIT) * @return Always 0. */ int elfsh_shift_ia32_relocs(elfshobj_t *file, eresi_Addr diff, elfshsect_t *relplt, eresi_Addr limit) { elfsh_Rel *l; int index; eresi_Addr reloff; elfshsect_t *parent; elfsh_SAddr off; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); for (index = 0; index < relplt->shdr->sh_size / sizeof(elfsh_Rel); index++) { l = (elfsh_Rel *) relplt->data + index; if (ELFSH_NOLIMIT == limit || elfsh_get_reloffset((elfsh_Rel *) l) >= limit) { reloff = elfsh_get_reloffset((elfsh_Rel *) l); reloff += diff; elfsh_set_reloffset((elfsh_Rel *) l, reloff); /* Shifting memory -pointed- by the relative relocation */ if (elfsh_get_reltype(l) != R_386_RELATIVE) continue; parent = elfsh_get_parent_section(file, reloff, &off); if (strstr(parent->name, "got") || strstr(parent->name, "bss") || strstr(parent->name, "elfsh")) continue; *(eresi_Addr *) ((char *) parent->data + off) += diff; } } PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }
/** * @brief Shift the SPARC relocation to make points the entries inside .alt.plt instead of .plt * @param file The host file where shift must happens. * @param diff Absolute difference to shift to. * @param relplt Section descriptor for the .relplt section. * @return Always 0. */ int elfsh_shift_generic_relocs(elfshobj_t *file, eresi_Addr diff, elfshsect_t *relplt) { elfsh_Rela *l; int index; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); for (index = 0; index < relplt->shdr->sh_size / sizeof(elfsh_Rela); index++) { l = (elfsh_Rela *) relplt->data + index; elfsh_set_reloffset((elfsh_Rel *) l, elfsh_get_reloffset((elfsh_Rel *) l) + diff); } PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }
/** * @brief Shift the ALPHA relocation table. * @param file The file where to relocate the table. * @param name Name of symbol for which to relocate entry. * @param altgot Descriptor for the ALTGOT section. * @param off * @return Success (0) or Error (-1). */ int elfsh_shift_alpha_relocs(elfshobj_t *file, char *name, elfshsect_t *altgot, u_int off) { u_int entsz; elfsh_Rela *rel; eresi_Addr addr; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); /* Find the relocation entry */ entsz = elfsh_get_pltentsz(file); rel = (elfsh_Rela *) elfsh_get_relent_by_name(file, name); if (rel == NULL) { #if __DEBUG_COPYPLT__ printf("[DEBUG_COPYPLT] Did not find relocation entry from symbol %s \n", name); #endif PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,"Unable to get relocation entry", -1); } #if __DEBUG_COPYPLT__ else printf("[DEBUG_COPYPLT] Found relocation entry (" AFMT ") from symbol %s \n", elfsh_get_reloffset((elfsh_Rel *) rel), name); #endif /* Compute the new value */ addr = altgot->shdr->sh_addr + (((off - 8) / entsz) * sizeof(eresi_Addr)); #if __DEBUG_COPYPLT__ printf("[DEBUG_COPYPLT] Setting relocation entry to " AFMT " \n", addr); #endif /* Write it */ elfsh_set_reloffset((elfsh_Rel *) rel, addr); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }
void reloc_set_relaoffset(elf_bf_Rela *r, Elf64_Addr off) { if (r->rel) { elfsh_set_reloffset((elfsh_Rel *) r->rel, off); } }