summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkat <kat@vector35.com>2024-06-04 10:59:44 -0400
committerkat <kat@vector35.com>2024-06-11 14:28:26 -0400
commitc5df1bf9d788344192b1a63690d8d5845b713f29 (patch)
treea1fb7aafa9f3e93671fe3b35528b59cc4bb29827
parent1707989955983663933377329952944577678076 (diff)
[Mach-O] Fix issue where imported symbols did not have relocations applied, Fix an issue with binding opcode 0xC0
-rw-r--r--view/macho/machoview.cpp62
-rw-r--r--view/macho/machoview.h4
2 files changed, 58 insertions, 8 deletions
diff --git a/view/macho/machoview.cpp b/view/macho/machoview.cpp
index c01acadd..69b81df6 100644
--- a/view/macho/machoview.cpp
+++ b/view/macho/machoview.cpp
@@ -1992,6 +1992,12 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_
EndBulkModifySymbols();
+ for (auto& [relocation, name] : header.externalRelocations)
+ {
+ if (auto symbol = GetSymbolByRawName(name, GetExternalNameSpace()); symbol)
+ DefineRelocation(m_arch, relocation, symbol, relocation.address);
+ }
+
auto relocationHandler = m_arch->GetRelocationHandler("Mach-O");
if (relocationHandler)
{
@@ -2465,6 +2471,7 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
try {
reader.Seek(tableOffset);
auto table = reader.Read(tableSize);
+ BNRelocationInfo externReloc;
BNSymbolType symtype = incomingType;
// uint64_t ordinal = 0;
@@ -2525,6 +2532,15 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
throw MachoFormatException();
DefineMachoSymbol(symtype, string(name), address, binding, true);
+
+ memset(&externReloc, 0, sizeof(externReloc));
+ externReloc.nativeType = BINARYNINJA_MANUAL_RELOCATION;
+ externReloc.address = address;
+ externReloc.size = m_addressSize;
+ externReloc.pcRelative = false;
+ externReloc.external = true;
+ header.externalRelocations.emplace_back(externReloc, string(name));
+
address += m_addressSize;
break;
case BindOpcodeDoBindAddAddressULEB:
@@ -2532,6 +2548,15 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
throw MachoFormatException();
DefineMachoSymbol(symtype, string(name), address, binding, true);
+
+ memset(&externReloc, 0, sizeof(externReloc));
+ externReloc.nativeType = BINARYNINJA_MANUAL_RELOCATION;
+ externReloc.address = address;
+ externReloc.size = m_addressSize;
+ externReloc.pcRelative = false;
+ externReloc.external = true;
+ header.externalRelocations.emplace_back(externReloc, string(name));
+
address += m_addressSize;
address += readLEB128(table, tableSize, i);
break;
@@ -2540,6 +2565,14 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
throw MachoFormatException();
DefineMachoSymbol(symtype, string(name), address, binding, true);
+
+ memset(&externReloc, 0, sizeof(externReloc));
+ externReloc.nativeType = BINARYNINJA_MANUAL_RELOCATION;
+ externReloc.address = address;
+ externReloc.size = m_addressSize;
+ externReloc.pcRelative = false;
+ externReloc.external = true;
+ header.externalRelocations.emplace_back(externReloc, string(name));
address += m_addressSize;
address += (imm * m_addressSize);
break;
@@ -2552,8 +2585,17 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
uint64_t skip = readLEB128(table, tableSize, i);
for (; count > 0; count--)
{
- address += skip + m_addressSize;
DefineMachoSymbol(symtype, string(name), address, binding, true);
+
+ memset(&externReloc, 0, sizeof(externReloc));
+ externReloc.nativeType = BINARYNINJA_MANUAL_RELOCATION;
+ externReloc.address = address;
+ externReloc.size = m_addressSize;
+ externReloc.pcRelative = false;
+ externReloc.external = true;
+ header.externalRelocations.emplace_back(externReloc, string(name));
+
+ address += skip + m_addressSize;
}
break;
}
@@ -2595,7 +2637,7 @@ void MachoView::ParseSymbolTable(BinaryReader& reader, MachOHeader& header, cons
if (header.chainedFixupsPresent)
{
m_logger->LogDebug("Chained Fixups");
- ParseChainedFixups(header.chainedFixups);
+ ParseChainedFixups(header, header.chainedFixups);
}
if (header.exportTriePresent && header.isMainHeader)
ParseExportTrie(reader, header.exportTrie);
@@ -2793,9 +2835,7 @@ void MachoView::ParseSymbolTable(BinaryReader& reader, MachOHeader& header, cons
}
-
-
-void MachoView::ParseChainedFixups(linkedit_data_command chainedFixups)
+void MachoView::ParseChainedFixups(MachOHeader& header, linkedit_data_command chainedFixups)
{
if (!chainedFixups.dataoff)
return;
@@ -3103,10 +3143,18 @@ void MachoView::ParseChainedFixups(linkedit_data_command chainedFixups)
if (!entry.name.empty())
{
reloc.address = targetAddress;
- DefineRelocation(m_arch, reloc, 0, reloc.address);
- DefineMachoSymbol(ImportedDataSymbol, entry.name,
+ DefineMachoSymbol(ImportAddressSymbol, entry.name,
targetAddress,
entry.weak ? WeakBinding : GlobalBinding, true);
+
+ BNRelocationInfo externReloc;
+ memset(&externReloc, 0, sizeof(externReloc));
+ externReloc.nativeType = BINARYNINJA_MANUAL_RELOCATION;
+ externReloc.address = targetAddress;
+ externReloc.size = m_addressSize;
+ externReloc.pcRelative = false;
+ externReloc.external = true;
+ header.externalRelocations.emplace_back(externReloc, entry.name);
}
else
{
diff --git a/view/macho/machoview.h b/view/macho/machoview.h
index 8dd5328d..240dcc54 100644
--- a/view/macho/machoview.h
+++ b/view/macho/machoview.h
@@ -1238,6 +1238,8 @@ namespace BinaryNinja
std::vector<std::pair<uint64_t, bool>> entryPoints;
std::vector<uint64_t> m_entryPoints; //list of entrypoints
+ std::vector<std::pair<BNRelocationInfo, std::string>> externalRelocations;
+
symtab_command symtab;
dysymtab_command dysymtab;
dyld_info_command dyldInfo;
@@ -1345,7 +1347,7 @@ namespace BinaryNinja
BNSymbolBinding binding);
bool GetSectionPermissions(MachOHeader& header, uint64_t address, uint32_t &flags);
bool GetSegmentPermissions(MachOHeader& header, uint64_t address, uint32_t &flags);
- void ParseChainedFixups(linkedit_data_command chainedFixups);
+ void ParseChainedFixups(MachOHeader& header, linkedit_data_command chainedFixups);
virtual uint64_t PerformGetEntryPoint() const override;