diff options
| author | kat <kat@vector35.com> | 2024-06-04 10:59:44 -0400 |
|---|---|---|
| committer | kat <kat@vector35.com> | 2024-06-11 14:28:26 -0400 |
| commit | c5df1bf9d788344192b1a63690d8d5845b713f29 (patch) | |
| tree | a1fb7aafa9f3e93671fe3b35528b59cc4bb29827 | |
| parent | 1707989955983663933377329952944577678076 (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.cpp | 62 | ||||
| -rw-r--r-- | view/macho/machoview.h | 4 |
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; |
