diff options
| author | clubby789 <jamie@hill-daniel.co.uk> | 2024-06-06 15:46:11 +0100 |
|---|---|---|
| committer | Josh F <negasora@users.noreply.github.com> | 2024-06-24 15:32:06 -0400 |
| commit | 1ffd063fc7e0bad3ee60f257d0df2324fbe09a36 (patch) | |
| tree | c6f8001e6a14d48b495e2d14cb1f65fecc1f8abc /view/elf | |
| parent | 750c2ffd35c202fb4a16af1f5714fe61fc62153c (diff) | |
Add `Elf{32,64}_{Rel,Rela}` table to ELF view
Diffstat (limited to 'view/elf')
| -rw-r--r-- | view/elf/elfview.cpp | 88 | ||||
| -rw-r--r-- | view/elf/elfview.h | 2 |
2 files changed, 73 insertions, 17 deletions
diff --git a/view/elf/elfview.cpp b/view/elf/elfview.cpp index d94498f1..f054094b 100644 --- a/view/elf/elfview.cpp +++ b/view/elf/elfview.cpp @@ -64,6 +64,8 @@ ElfView::ElfView(BinaryView* data, bool parseOnly): BinaryView("ELF", data->GetF memset(&m_dynamicSymbolTableSection, 0, sizeof(m_dynamicSymbolTableSection)); memset(&m_dynamicStringTable, 0, sizeof(m_dynamicStringTable)); memset(&m_dynamicTable, 0, sizeof(m_dynamicTable)); + memset(&m_relocSection, 0, sizeof(m_relocSection)); + memset(&m_relocaSection, 0, sizeof(m_relocaSection)); memset(&m_tlsSegment, 0, sizeof(m_tlsSegment)); memset(&m_auxSymbolTable, 0, sizeof(m_auxSymbolTable)); memset(&m_sectionStringTable, 0, sizeof(m_sectionStringTable)); @@ -784,10 +786,8 @@ bool ElfView::Init() uint64_t adjustedVirtualAddr = m_dynamicTable.virtualAddress + imageBaseAdjustment; reader.Seek(adjustedVirtualAddr - dynSeg->GetStart() + dynSeg->GetDataOffset()); - Elf64SectionHeader reloca, plt, rel; - memset(&reloca, 0, sizeof(reloca)); + Elf64SectionHeader plt; memset(&plt, 0, sizeof(plt)); - memset(&rel, 0, sizeof(rel)); uint64_t pltType = ELF_DT_RELA; bool end = false; uint64_t entrySize = m_elf32 ? 8 : 16; @@ -852,25 +852,25 @@ bool ElfView::Init() m_gnuHashHeader = value + imageBaseAdjustment; break; case ELF_DT_RELA: - reloca.offset = value + imageBaseAdjustment; + m_relocaSection.offset = value + imageBaseAdjustment; break; case ELF_DT_RELASZ: - reloca.size = value; + m_relocaSection.size = value; break; case ELF_DT_RELAENT: - reloca.entrySize = value; + m_relocaSection.entrySize = value; break; case ELF_DT_STRSZ: m_dynamicStringTable.size = value; break; case ELF_DT_REL: - rel.offset = value + imageBaseAdjustment; + m_relocSection.offset = value + imageBaseAdjustment; break; case ELF_DT_RELSZ: - rel.size = value; + m_relocSection.size = value; break; case ELF_DT_RELENT: - rel.entrySize = value; + m_relocSection.entrySize = value; break; case ELF_DT_PLTGOT: gotStart = value + imageBaseAdjustment; @@ -925,16 +925,17 @@ bool ElfView::Init() StoreMetadata("Libraries", new Metadata(libraries), true); StoreMetadata("LibraryFound", new Metadata(libraryFound), true); - if (reloca.size > 0) + if (m_relocaSection.size > 0) { bool alreadyExists = false; for (auto& relSec : relocASections) - if (relSec.offset == reloca.offset) + if (relSec.offset == m_relocaSection.offset) alreadyExists = true; if (!alreadyExists) { - dynRelocASections.push_back(reloca); - AddAutoSection(".dynamic_rela", reloca.offset, reloca.size, ReadOnlyDataSectionSemantics); + dynRelocASections.push_back(m_relocaSection); + AddAutoSection( + ".dynamic_rela", m_relocaSection.offset, m_relocaSection.size, ReadOnlyDataSectionSemantics); } } if (plt.size > 0) @@ -964,16 +965,17 @@ bool ElfView::Init() } } } - if (rel.size > 0) + if (m_relocSection.size > 0) { bool alreadyExists = false; for (auto& relSec : relocSections) - if ((relSec.address + imageBaseAdjustment) == rel.offset) + if ((relSec.address + imageBaseAdjustment) == m_relocSection.offset) alreadyExists = true; if (!alreadyExists) { - dynRelocSections.push_back(rel); - AddAutoSection(".dynamic_rel", rel.offset, rel.size, ReadOnlyDataSectionSemantics); + dynRelocSections.push_back(m_relocSection); + AddAutoSection( + ".dynamic_rel", m_relocSection.offset, m_relocSection.size, ReadOnlyDataSectionSemantics); } } } @@ -2237,6 +2239,58 @@ bool ElfView::Init() } } + if (m_relocSection.size) + { + StructureBuilder relocationTableBuilder; + if (m_elf32) + { + relocationTableBuilder.AddMember(Type::IntegerType(4, false), "r_offset"); + relocationTableBuilder.AddMember(Type::IntegerType(4, false), "r_info"); + } + else + { + relocationTableBuilder.AddMember(Type::IntegerType(8, false), "r_offset"); + relocationTableBuilder.AddMember(Type::IntegerType(8, false), "r_info"); + }; + Ref<Structure> relocationTableStruct = relocationTableBuilder.Finalize(); + Ref<Type> relocationTableType = Type::StructureType(relocationTableStruct); + QualifiedName relocationTableName = m_elf32 ? string("Elf32_Rel") : string("Elf64_Rel"); + const string relocationTableTypeId = Type::GenerateAutoTypeId("elf", relocationTableName); + + QualifiedName relocTableTypeName = DefineType(relocationTableTypeId, relocationTableName, relocationTableType); + DefineDataVariable(m_relocSection.offset, + Type::ArrayType(Type::NamedType(this, relocTableTypeName), m_relocSection.size / m_relocSection.entrySize)); + DefineAutoSymbol(new Symbol(DataSymbol, "__elf_rel_table", m_relocSection.offset, NoBinding)); + } + + if (m_relocaSection.size) + { + StructureBuilder relocationATableBuilder; + if (m_elf32) + { + relocationATableBuilder.AddMember(Type::IntegerType(4, false), "r_offset"); + relocationATableBuilder.AddMember(Type::IntegerType(4, false), "r_info"); + relocationATableBuilder.AddMember(Type::IntegerType(4, true), "r_addend"); + } + else + { + relocationATableBuilder.AddMember(Type::IntegerType(8, false), "r_offset"); + relocationATableBuilder.AddMember(Type::IntegerType(8, false), "r_info"); + relocationATableBuilder.AddMember(Type::IntegerType(8, true), "r_addend"); + }; + Ref<Structure> relocationATableStruct = relocationATableBuilder.Finalize(); + Ref<Type> relocationATableType = Type::StructureType(relocationATableStruct); + QualifiedName relocationATableName = m_elf32 ? string("Elf32_Rela") : string("Elf64_Rela"); + const string relocationATableTypeId = Type::GenerateAutoTypeId("elf", relocationATableName); + + QualifiedName relocaTableTypeName = + DefineType(relocationATableTypeId, relocationATableName, relocationATableType); + DefineDataVariable(m_relocaSection.offset, + Type::ArrayType( + Type::NamedType(this, relocaTableTypeName), m_relocaSection.size / m_relocaSection.entrySize)); + DefineAutoSymbol(new Symbol(DataSymbol, "__elf_rela_table", m_relocaSection.offset, NoBinding)); + } + // In 32-bit mips with .got, add .extern symbol "RTL_Resolve" if (gotStart && In(m_arch->GetName(), {"mips32", "mipsel32", "mips64", "nanomips"})) { diff --git a/view/elf/elfview.h b/view/elf/elfview.h index db60fdb7..438dee4f 100644 --- a/view/elf/elfview.h +++ b/view/elf/elfview.h @@ -501,6 +501,8 @@ namespace BinaryNinja std::vector<Elf64ProgramHeader> m_programHeaders; Elf64SectionHeader m_symbolTableSection, m_dynamicSymbolTableSection; Elf64SectionHeader m_auxSymbolTable, m_dynamicStringTable, m_sectionStringTable, m_sectionOpd; + Elf64SectionHeader m_relocSection; + Elf64SectionHeader m_relocaSection; Elf64ProgramHeader m_dynamicTable; Elf64ProgramHeader m_tlsSegment; std::map<uint64_t, uint64_t> m_localGotEntries; |
