?? htelf.cc
字號:
ELF_SECTION_HEADER32 *s = elf_shared->sheaders.sheaders32; s[elf_shared->fake_undefined_shidx].sh_name = 0; s[elf_shared->fake_undefined_shidx].sh_type = ELF_SHT_NOBITS; s[elf_shared->fake_undefined_shidx].sh_flags = ELF_SHF_WRITE | ELF_SHF_ALLOC; s[elf_shared->fake_undefined_shidx].sh_addr = 0; s[elf_shared->fake_undefined_shidx].sh_offset = 0; s[elf_shared->fake_undefined_shidx].sh_size = 0; // filled in below s[elf_shared->fake_undefined_shidx].sh_link = 0; s[elf_shared->fake_undefined_shidx].sh_info = 0; s[elf_shared->fake_undefined_shidx].sh_addralign = 0; s[elf_shared->fake_undefined_shidx].sh_entsize = 0; elf32_addr a = elf32_invent_address(elf_shared->fake_undefined_shidx, s, elf_shared->sheaders.count, FAKE_SECTION_BASEADDR); s[elf_shared->fake_undefined_shidx].sh_addr = a; LOG("fake section %d", elf_shared->fake_undefined_shidx); // allocate fake addresses elf_shared->undefined2fakeaddr = new AVLTree(true); uint32 nextFakeAddr = FAKE_SECTION_BASEADDR; for (uint secidx = 0; secidx < elf_shared->sheaders.count; secidx++) { if (elf_shared->sheaders.sheaders32[secidx].sh_type == ELF_SHT_SYMTAB) { FileOfs symh = elf_shared->sheaders.sheaders32[secidx].sh_offset; uint symnum = elf_shared->sheaders.sheaders32[secidx].sh_size / sizeof (ELF_SYMBOL32); for (uint symidx = 1; symidx < symnum; symidx++) { ELF_SYMBOL32 sym; file->seek(symh+symidx*sizeof (ELF_SYMBOL32)); file->read(&sym, sizeof sym); createHostStruct(&sym, ELF_SYMBOL32_struct, elf_shared->byte_order); if (sym.st_shndx == ELF_SHN_UNDEF) { elf_shared->undefined2fakeaddr->insert( new FakeAddr(secidx, symidx, nextFakeAddr) ); nextFakeAddr += 4; } } } } elf_shared->fake_undefined_size = nextFakeAddr-FAKE_SECTION_BASEADDR; s[elf_shared->fake_undefined_shidx].sh_size = elf_shared->fake_undefined_size;}void ht_elf::auto_relocate32(){ ht_elf32_reloc_file *rf = new ht_elf32_reloc_file(file, false, (ht_elf_shared_data*)shared_data); bool reloc_needed = false; ht_elf_shared_data *elf_shared=(ht_elf_shared_data *)shared_data; ELF_SECTION_HEADER32 *s=elf_shared->sheaders.sheaders32; if (!elf_shared->sheaders.count) { String fn; LOG("%y: ELF: segment header count is zero", &file->getFilename(fn)); } else { elf_shared->shrelocs = ht_malloc(elf_shared->sheaders.count * sizeof (ht_elf_reloc_section32)); } /* relocate sections */ for (uint i=0; i<elf_shared->sheaders.count; i++) { elf_shared->shrelocs[i].relocAddr = 0; if ((s[i].sh_type == ELF_SHT_PROGBITS) && (s[i].sh_addr == 0)) { uint j = find_reloc_section_for(i); if (j) { elf32_addr a = elf32_invent_address(i, s, elf_shared->sheaders.count); if (a) { reloc_needed = true; // update section header entry s[i].sh_addr = a; elf_shared->shrelocs[i].relocAddr = a; elf_shared->shrelocs[i].relocShIdx = j; } } } } /* apply relocations to section descriptors */ for (uint i=0; i < elf_shared->sheaders.count; i++) { if (elf_shared->shrelocs[i].relocAddr) { //LOG("section %d to %08x", i, elf_shared->shrelocs[i].relocAddr); try { relocate_section(rf, i, elf_shared->shrelocs[i].relocShIdx, elf_shared->shrelocs[i].relocAddr); } catch (const Exception &x) { LOG("error while relocating section %d: %s", i, &x); } } } if (reloc_needed) { rf->finalize(); own_file = true; file = rf; String fn; LOG("%y: ELF: relocation layer enabled (invented relocation addresses)", &file->getFilename(fn)); } else { free(elf_shared->shrelocs); elf_shared->shrelocs = NULL; delete rf; }}bool ht_elf::loc_enum_next(ht_format_loc *loc){ ht_elf_shared_data *sh = (ht_elf_shared_data*)shared_data; if (loc_enum) { loc->name = "elf"; loc->start = sh->header_ofs; loc->length = file->getSize() - loc->start; /* FIXME: ENOTOK */ loc_enum = false; return true; } return false;}void ht_elf::loc_enum_start(){ loc_enum = true;}/* * address conversion routines */bool elf_phys_and_mem_section(elf_section_header *sh, uint elfclass){ switch (elfclass) { case ELFCLASS32: { ELF_SECTION_HEADER32 *s = &sh->sheaders32; return s->sh_type == ELF_SHT_PROGBITS && s->sh_addr; } case ELFCLASS64: { ELF_SECTION_HEADER64 *s = &sh->sheaders64; return s->sh_type==ELF_SHT_PROGBITS && s->sh_addr; } } return false;}bool elf_valid_section(elf_section_header *sh, uint elfclass){ switch (elfclass) { case ELFCLASS32: { ELF_SECTION_HEADER32 *s = &sh->sheaders32; return (s->sh_type==ELF_SHT_PROGBITS || s->sh_type==ELF_SHT_NOBITS) && s->sh_addr; } case ELFCLASS64: { ELF_SECTION_HEADER64 *s = &sh->sheaders64; return (s->sh_type==ELF_SHT_PROGBITS || s->sh_type==ELF_SHT_NOBITS) && s->sh_addr; } } return false;}bool elf_addr_to_ofs(elf_section_headers *section_headers, uint elfclass, ELFAddress addr, FileOfs *ofs){ switch (elfclass) { case ELFCLASS32: { ELF_SECTION_HEADER32 *s = section_headers->sheaders32; for (uint i=0; i < section_headers->count; i++) { if ((elf_phys_and_mem_section((elf_section_header*)s, elfclass)) && (addr.a32 >= s->sh_addr) && (addr.a32 < s->sh_addr+s->sh_size)) { *ofs = addr.a32 - s->sh_addr + s->sh_offset; return true; } s++; } break; } case ELFCLASS64: { ELF_SECTION_HEADER64 *s = section_headers->sheaders64; for (uint i=0; i < section_headers->count; i++) { if ((elf_phys_and_mem_section((elf_section_header*)s, elfclass)) && addr.a64 >= s->sh_addr && (addr.a64 < s->sh_addr + s->sh_size)) { *ofs = addr.a64 - s->sh_addr + s->sh_offset; return true; } s++; } break; } } return false;}bool elf_addr_to_section(elf_section_headers *section_headers, uint elfclass, ELFAddress addr, int *section){ switch (elfclass) { case ELFCLASS32: { ELF_SECTION_HEADER32 *s = section_headers->sheaders32; for (uint i = 0; i < section_headers->count; i++) { if ((elf_valid_section((elf_section_header*)s, elfclass)) && (addr.a32 >= s->sh_addr) && (addr.a32 < s->sh_addr + s->sh_size)) { *section = i; return true; } s++; } break; } case ELFCLASS64: { ELF_SECTION_HEADER64 *s = section_headers->sheaders64; for (uint i = 0; i < section_headers->count; i++) { if ((elf_valid_section((elf_section_header*)s, elfclass)) && addr.a64 >= s->sh_addr && (addr.a64 < s->sh_addr + s->sh_size)) { *section = i; return true; } s++; } break; } } return false;}bool elf_addr_is_valid(elf_section_headers *section_headers, uint elfclass, ELFAddress addr){ switch (elfclass) { case ELFCLASS32: { ELF_SECTION_HEADER32 *s = section_headers->sheaders32; for (uint i=0; i<section_headers->count; i++) { if ((elf_valid_section((elf_section_header*)s, elfclass)) && (addr.a32 >= s->sh_addr) && (addr.a32 < s->sh_addr + s->sh_size)) { return true; } s++; } break; } case ELFCLASS64: { ELF_SECTION_HEADER64 *s = section_headers->sheaders64; for (uint i=0; i<section_headers->count; i++) { if ((elf_valid_section((elf_section_header*)s, elfclass)) && addr.a64 >= s->sh_addr && (addr.a64 < s->sh_addr + s->sh_size)) { return true; } s++; } break; } } return false;}bool elf_addr_is_physical(elf_section_headers *section_headers, uint elfclass, ELFAddress addr){ return false;}/* * offset conversion routines */bool elf_ofs_to_addr(elf_section_headers *section_headers, uint elfclass, FileOfs ofs, ELFAddress *addr){ switch (elfclass) { case ELFCLASS32: { ELF_SECTION_HEADER32 *s = section_headers->sheaders32; for (uint i = 0; i < section_headers->count; i++) { if ((elf_phys_and_mem_section((elf_section_header*)s, elfclass)) && (ofs >= s->sh_offset) && (ofs<s->sh_offset+s->sh_size)) { addr->a32 = ofs - s->sh_offset + s->sh_addr; return true; } s++; } break; } case ELFCLASS64: { ELF_SECTION_HEADER64 *s = section_headers->sheaders64; uint64 qofs = ofs; for (uint i = 0; i < section_headers->count; i++) { if ((elf_phys_and_mem_section((elf_section_header*)s, elfclass)) && qofs >= s->sh_offset && (qofs < s->sh_offset + s->sh_size)) { addr->a64 = qofs - s->sh_offset + s->sh_addr; return true; } s++; } break; } } return false;}bool elf_ofs_to_section(elf_section_headers *section_headers, uint elfclass, uint32 ofs, int *section){ switch (elfclass) { case ELFCLASS32: { ELF_SECTION_HEADER32 *s=section_headers->sheaders32; for (uint i=0; i<section_headers->count; i++) { if ((elf_valid_section((elf_section_header*)s, elfclass)) && (ofs >= s->sh_offset) && (ofs<s->sh_offset+s->sh_size)) { *section = i; return true; } s++; } break; } case ELFCLASS64: { ELF_SECTION_HEADER64 *s = section_headers->sheaders64; uint64 qofs = ofs; for (uint i=0; i < section_headers->count; i++) { if ((elf_valid_section((elf_section_header*)s, elfclass)) && qofs >= s->sh_offset && (qofs < s->sh_offset + s->sh_size)) { *section = i; return true; } s++; } break; } } return false;}bool elf_ofs_to_addr_and_section(elf_section_headers *section_headers, uint elfclass, uint32 ofs, ELFAddress *addr, int *section){ return false;}/* * ht_elf32_reloc_entry *///ht_elf32_reloc_entry::ht_elf32_reloc_entry(uint symtabidx, elf32_addr addr, uint t, uint symbolidx, elf32_addr addend, ht_elf_shared_data *data, File *file)ht_elf32_reloc_entry::ht_elf32_reloc_entry(uint t, uint32 A, uint32 P, uint32 S){ type = t; switch (type) { case ELF_R_386_32: relocs.r_32 = S+A; break; case ELF_R_386_PC32: relocs.r_pc32 = S+A-P; break; }}/* * ht_elf32_reloc_file */ht_elf32_reloc_file::ht_elf32_reloc_file(File *s, bool os, ht_elf_shared_data *d) : ht_reloc_file(s, os), data(d){}void ht_elf32_reloc_file::reloc_apply(Object *reloc, byte *buf){ ht_elf32_reloc_entry *e=(ht_elf32_reloc_entry*)reloc; switch (e->type) { case ELF_R_386_32: { uint32 v = createHostInt(buf, 4, data->byte_order); v += e->relocs.r_32; createForeignInt(buf, v, 4, data->byte_order); break; } case ELF_R_386_PC32: { uint32 v = createHostInt(buf, 4, data->byte_order); v += e->relocs.r_pc32; createForeignInt(buf, v, 4, data->byte_order); break; } }}bool ht_elf32_reloc_file::reloc_unapply(Object *reloc, byte *data){ return false;// ht_elf32_reloc_entry *e=(ht_elf32_reloc_entry*)reloc;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -