Skip to content

Commit 2b3ce70

Browse files
committed
[Mach-O] Handling for special library ordinals used in binding information
1 parent 99ed22f commit 2b3ce70

File tree

2 files changed

+96
-20
lines changed

2 files changed

+96
-20
lines changed

view/macho/machoview.cpp

Lines changed: 81 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2093,10 +2093,74 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_
20932093
if (objcProcessor)
20942094
objcProcessor->AddRelocatedPointer(relocationLocation, slidTarget);
20952095
}
2096-
for (auto& [relocation, name] : header.externalRelocations)
2096+
for (auto& [relocation, name, ordinal] : header.bindingRelocations)
20972097
{
2098-
if (auto symbol = GetSymbolByRawName(name, GetExternalNameSpace()); symbol)
2099-
DefineRelocation(m_arch, relocation, symbol, relocation.address);
2098+
bool handled = false;
2099+
2100+
switch (ordinal)
2101+
{
2102+
case BindSpecialDylibSelf:
2103+
if (auto symbol = GetSymbolByRawName(name, GetInternalNameSpace()); symbol)
2104+
{
2105+
DefineRelocation(m_arch, relocation, symbol, relocation.address);
2106+
if (objcProcessor)
2107+
objcProcessor->AddRelocatedPointer(relocation.address, symbol->GetAddress());
2108+
handled = true;
2109+
}
2110+
break;
2111+
2112+
case BindSpecialDylibMainExecutable:
2113+
case BindSpecialDylibFlatLookup:
2114+
case BindSpecialDylibWeakLookup:
2115+
// In cases where we are the primary executable, flat lookup should find us first,
2116+
// it seems like our best course of action is to try and find internally first on
2117+
// executables, and externally on libraries.
2118+
if (header.ident.filetype == MH_EXECUTE)
2119+
{
2120+
if (auto symbol = GetSymbolByRawName(name, GetInternalNameSpace()); symbol)
2121+
{
2122+
DefineRelocation(m_arch, relocation, symbol, relocation.address);
2123+
if (objcProcessor)
2124+
objcProcessor->AddRelocatedPointer(relocation.address, symbol->GetAddress());
2125+
handled = true;
2126+
}
2127+
else if (auto symbol = GetSymbolByRawName(name, GetExternalNameSpace()); symbol)
2128+
{
2129+
DefineRelocation(m_arch, relocation, symbol, relocation.address);
2130+
handled = true;
2131+
}
2132+
}
2133+
else
2134+
{
2135+
if (auto symbol = GetSymbolByRawName(name, GetExternalNameSpace()); symbol)
2136+
{
2137+
DefineRelocation(m_arch, relocation, symbol, relocation.address);
2138+
handled = true;
2139+
}
2140+
else if (auto symbol = GetSymbolByRawName(name, GetInternalNameSpace()); symbol)
2141+
{
2142+
DefineRelocation(m_arch, relocation, symbol, relocation.address);
2143+
if (objcProcessor)
2144+
objcProcessor->AddRelocatedPointer(relocation.address, symbol->GetAddress());
2145+
handled = true;
2146+
}
2147+
}
2148+
break;
2149+
2150+
default:
2151+
if (ordinal > 0)
2152+
{
2153+
if (auto symbol = GetSymbolByRawName(name, GetExternalNameSpace()); symbol)
2154+
{
2155+
DefineRelocation(m_arch, relocation, symbol, relocation.address);
2156+
handled = true;
2157+
}
2158+
}
2159+
break;
2160+
}
2161+
2162+
if (!handled)
2163+
m_logger->LogError("Failed to find external symbol '%s', couldn't bind symbol at 0x%llx", name.c_str(), relocation.address);
21002164
}
21012165

21022166
auto relocationHandler = m_arch->GetRelocationHandler("Mach-O");
@@ -2848,7 +2912,7 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
28482912
BNRelocationInfo externReloc;
28492913

28502914
BNSymbolType symtype = incomingType;
2851-
// uint64_t ordinal = 0;
2915+
uint64_t ordinal = 0;
28522916
// int64_t addend = 0;
28532917
uint64_t segmentIndex = 0;
28542918
uint64_t address = 0;
@@ -2866,7 +2930,7 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
28662930
switch (opcode)
28672931
{
28682932
case BindOpcodeDone:
2869-
// ordinal = 0;
2933+
ordinal = 0;
28702934
// addend = 0;
28712935
segmentIndex = 0;
28722936
address = 0;
@@ -2876,9 +2940,9 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
28762940
type = 0;
28772941
symtype = incomingType;
28782942
break;
2879-
case BindOpcodeSetDylibOrdinalImmediate: /* ordinal = imm; */ break;
2880-
case BindOpcodeSetDylibOrdinalULEB: /* ordinal = */ readLEB128(table, tableSize, i); break;
2881-
case BindOpcodeSetDylibSpecialImmediate: /* ordinal = -imm; */ break;
2943+
case BindOpcodeSetDylibOrdinalImmediate: ordinal = imm;break;
2944+
case BindOpcodeSetDylibOrdinalULEB: ordinal = readLEB128(table, tableSize, i); break;
2945+
case BindOpcodeSetDylibSpecialImmediate: ordinal = -imm; break;
28822946
case BindOpcodeSetSymbolTrailingFlagsImmediate:
28832947
/* flags = imm; */
28842948
name = (char*)&table[i];
@@ -2911,8 +2975,7 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
29112975
externReloc.size = m_addressSize;
29122976
externReloc.pcRelative = false;
29132977
externReloc.external = true;
2914-
header.externalRelocations.emplace_back(externReloc, string(name));
2915-
2978+
header.bindingRelocations.emplace_back(externReloc, string(name), ordinal);
29162979
address += m_addressSize;
29172980
break;
29182981
case BindOpcodeDoBindAddAddressULEB:
@@ -2925,7 +2988,7 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
29252988
externReloc.size = m_addressSize;
29262989
externReloc.pcRelative = false;
29272990
externReloc.external = true;
2928-
header.externalRelocations.emplace_back(externReloc, string(name));
2991+
header.bindingRelocations.emplace_back(externReloc, string(name), ordinal);
29292992

29302993
address += m_addressSize;
29312994
address += readLEB128(table, tableSize, i);
@@ -2940,7 +3003,7 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
29403003
externReloc.size = m_addressSize;
29413004
externReloc.pcRelative = false;
29423005
externReloc.external = true;
2943-
header.externalRelocations.emplace_back(externReloc, string(name));
3006+
header.bindingRelocations.emplace_back(externReloc, string(name), ordinal);
29443007
address += m_addressSize;
29453008
address += (imm * m_addressSize);
29463009
break;
@@ -2959,7 +3022,7 @@ void MachoView::ParseDynamicTable(BinaryReader& reader, MachOHeader& header, BNS
29593022
externReloc.size = m_addressSize;
29603023
externReloc.pcRelative = false;
29613024
externReloc.external = true;
2962-
header.externalRelocations.emplace_back(externReloc, string(name));
3025+
header.bindingRelocations.emplace_back(externReloc, string(name), ordinal);
29633026

29643027
address += skip + m_addressSize;
29653028
}
@@ -3288,7 +3351,7 @@ void MachoView::ParseChainedFixups(
32883351
{
32893352
uint32_t importEntry = parentReader.Read32();
32903353
dyld_chained_import import = *(reinterpret_cast<dyld_chained_import*>(&importEntry));
3291-
processChainedImport(import.lib_ordinal, 0, import.name_offset, import.weak_import, parentReader);
3354+
processChainedImport(static_cast<int8_t>(import.lib_ordinal), 0, import.name_offset, import.weak_import, parentReader);
32923355
}
32933356
break;
32943357
}
@@ -3298,7 +3361,7 @@ void MachoView::ParseChainedFixups(
32983361
{
32993362
dyld_chained_import_addend import;
33003363
parentReader.Read(&import, sizeof(import));
3301-
processChainedImport(import.lib_ordinal, import.addend, import.name_offset, import.weak_import, parentReader);
3364+
processChainedImport(static_cast<int8_t>(import.lib_ordinal), import.addend, import.name_offset, import.weak_import, parentReader);
33023365
}
33033366
break;
33043367
}
@@ -3308,7 +3371,7 @@ void MachoView::ParseChainedFixups(
33083371
{
33093372
dyld_chained_import_addend64 import;
33103373
parentReader.Read(&import, sizeof(import));
3311-
processChainedImport(import.lib_ordinal, import.addend, import.name_offset, import.weak_import, parentReader);
3374+
processChainedImport(static_cast<int16_t>(import.lib_ordinal), import.addend, import.name_offset, import.weak_import, parentReader);
33123375
}
33133376
break;
33143377
}
@@ -3521,7 +3584,7 @@ void MachoView::ParseChainedFixups(
35213584
chainEntryAddress += (nextEntryStrideCount * strideSize);
35223585
if (chainEntryAddress > pageAddress + starts.page_size)
35233586
{
3524-
m_logger->LogDebug("Chained Fixups: Pointer at %llx left page",
3587+
m_logger->LogError("Chained Fixups: Pointer at %llx left page",
35253588
GetStart() + ((chainEntryAddress - (nextEntryStrideCount * strideSize))) - m_universalImageOffset);
35263589
fixupsDone = true;
35273590
}
@@ -3546,9 +3609,8 @@ void MachoView::ParseChainedFixups(
35463609
externReloc.address = targetAddress;
35473610
externReloc.size = m_addressSize;
35483611
externReloc.pcRelative = false;
3549-
externReloc.external = true;
35503612
externReloc.addend = entry.addend;
3551-
header.externalRelocations.emplace_back(externReloc, entry.name);
3613+
header.bindingRelocations.emplace_back(externReloc, entry.name, entry.lib_ordinal);
35523614
}
35533615
else
35543616
{

view/macho/machoview.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,13 @@ namespace BinaryNinja
818818
RebaseOpcodeDoRebaseUlebTimesSkippingUleb = 0x80u, // REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB
819819
};
820820

821+
enum BindSpecial {
822+
BindSpecialDylibSelf = 0, // BIND_SPECIAL_DYLIB_SELF
823+
BindSpecialDylibMainExecutable = -1, // BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
824+
BindSpecialDylibFlatLookup = -2, // BIND_SPECIAL_DYLIB_FLAT_LOOKUP
825+
BindSpecialDylibWeakLookup = -3 // BIND_SPECIAL_DYLIB_WEAK_LOOKUP
826+
};
827+
821828
enum BindOpcode {
822829
BindOpcodeMask = 0xF0u, // BIND_OPCODE_MASK
823830
BindImmediateMask = 0x0Fu, // BIND_IMMEDIATE_MASK
@@ -1375,6 +1382,13 @@ namespace BinaryNinja
13751382
uint32_t reserved;
13761383
};
13771384

1385+
struct BoundRelocation
1386+
{
1387+
BNRelocationInfo info;
1388+
std::string name;
1389+
int64_t ordinal;
1390+
};
1391+
13781392
struct MachOHeader {
13791393
bool isMainHeader = false;
13801394

@@ -1386,7 +1400,7 @@ namespace BinaryNinja
13861400
std::vector<std::pair<uint64_t, bool>> entryPoints;
13871401
std::vector<uint64_t> m_entryPoints; //list of entrypoints
13881402

1389-
std::vector<std::pair<BNRelocationInfo, std::string>> externalRelocations;
1403+
std::vector<BoundRelocation> bindingRelocations;
13901404
std::vector<BNRelocationInfo> rebaseRelocations;
13911405

13921406
symtab_command symtab;

0 commit comments

Comments
 (0)