summaryrefslogtreecommitdiff
path: root/view/elf
diff options
context:
space:
mode:
authorclubby789 <jamie@hill-daniel.co.uk>2024-06-06 15:46:11 +0100
committerJosh F <negasora@users.noreply.github.com>2024-06-24 15:32:06 -0400
commit1ffd063fc7e0bad3ee60f257d0df2324fbe09a36 (patch)
treec6f8001e6a14d48b495e2d14cb1f65fecc1f8abc /view/elf
parent750c2ffd35c202fb4a16af1f5714fe61fc62153c (diff)
Add `Elf{32,64}_{Rel,Rela}` table to ELF view
Diffstat (limited to 'view/elf')
-rw-r--r--view/elf/elfview.cpp88
-rw-r--r--view/elf/elfview.h2
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;