/** * XXX .::. TODO for ET_EXEC to ET_DYN : * - Insertion a new .rel section * - Change objtype and entryp in ELF header * - Relocate PHT and SHT * - Change reloc section size in .dynamic * * * @param file * @param new_addr * @return */ int elfsh_remap(elfshobj_t *file, eresi_Addr new_addr) { elfshsect_t *sect; eresi_Addr diff; u_int count; int ret; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); count = 0; if (file == NULL) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid NULL parameter", -1); else if (elfsh_read_obj(file) < 0) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unable to read object", -1); diff = elfsh_get_object_baseaddr(file); if (diff == (eresi_Addr) -1); PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Object base address is NULL", -1); for (sect = file->sectlist; sect != NULL; sect = sect->next) { ret = elfsh_relocate_section(sect, -diff); printf("Relocation number found for %-20s : %d \n", sect->name, ret); if (ret < 0) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unable to relocate section", -1); count += ret; } PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (count)); }
/** * 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)); }
/** * Remap the Program Header Table * @param file * @param diff * @return */ int elfsh_reloc_pht(elfshobj_t *file, eresi_Addr diff) { u_int i; u_int count; eresi_Addr base; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); base = elfsh_get_object_baseaddr(file); if (file == NULL || file->pht == NULL || file->hdr->e_phnum == 0) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid NULL parameter", 0); for (count = i = 0; i < file->hdr->e_phnum; i++) { if (file->pht[i].p_vaddr >= base) { file->pht[i].p_vaddr += diff; count++; } if (file->pht[i].p_paddr >= base) { file->pht[i].p_paddr += diff; count++; } } PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, (count)); }
int remap_cmd() { elfshobj_t *file; elfshsect_t *cur; u_int new_base; u_int real_base = 0xffffffff; int diff; int i; int cnt; u_int count_raw = 0; u_int count_pht = 0; u_int count_sht = 0; u_int count_ent = 0; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); /* Sanity checks */ i = sscanf(world.curjob->curcmd->param[0], "0x%X", &new_base); if (new_base == 0 || i != 1) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid new base address", -1); file = world.curjob->curfile; if (elfsh_read_obj(file) < 0) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unable to read object file", -1); if (elfsh_get_symtab(file, NULL) < 0) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unable to read symbol table", -1); /* Calculate delta */ real_base = elfsh_get_object_baseaddr(file); if (real_base == 0xffffffff) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Base address not found", -1); if (new_base & 0xfff) { revm_output(" [*] Base address adapted to be congruent pagesize \n"); new_base &= 0xfffff000; } diff = new_base - real_base; printf(" [*] Delta is %08X \n", diff); /* Update entry point */ if (file->hdr->e_entry > real_base) { file->hdr->e_entry += diff; count_ent++; } /* For all sections of the current object */ for (cur = file->sectlist; cur != NULL; cur = cur->next) { cnt = elfsh_relocate_section(cur, diff); if (cnt < 0) { printf(" [*] MODREMAP : Section %s wont be relocated\n", cur->name); continue; } count_raw += cnt; } /* Fixup SHT */ count_sht += elfsh_reloc_sht(file, diff); /* Fixup PHT */ count_pht += elfsh_reloc_pht(file, diff); /* Print msg */ printf(" [*] Total number of modified references : %u \n" "\t PHT relocation : %u \n" "\t SHT relocation : %u \n" "\t ENT relocation : %u \n" "\t RAW relocation : %u \n", count_pht + count_sht + count_ent + count_raw, count_pht , count_sht , count_ent , count_raw); printf(" [*] Remapping at base %08X -OK-\n\n", new_base); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }