Skip to content

Commit 080495b

Browse files
bdash0cyn
authored andcommitted
[MachO] Handle chained imports with addends
They show up in some macOS system executables.
1 parent e216329 commit 080495b

File tree

1 file changed

+47
-24
lines changed

1 file changed

+47
-24
lines changed

view/macho/machoview.cpp

+47-24
Original file line numberDiff line numberDiff line change
@@ -3118,45 +3118,67 @@ void MachoView::ParseChainedFixups(MachOHeader& header, linkedit_data_command ch
31183118
std::vector<import_entry> importTable;
31193119
parentReader.Seek(importsAddress);
31203120

3121+
auto processChainedImport =
3122+
[symbolsAddress, &importTable](
3123+
uint64_t ordinal, uint64_t addend, uint32_t nameOffset, bool weak, auto& reader) {
3124+
import_entry entry;
3125+
entry.lib_ordinal = ordinal;
3126+
entry.addend = addend;
3127+
entry.weak = weak;
3128+
3129+
auto nextEntryAddress = reader.GetOffset();
3130+
size_t symNameAddr = symbolsAddress + nameOffset;
3131+
3132+
reader.Seek(symNameAddr);
3133+
try
3134+
{
3135+
string symbolName = reader.ReadCString();
3136+
entry.name = symbolName;
3137+
}
3138+
catch (ReadException& ex)
3139+
{
3140+
entry.name = "";
3141+
}
3142+
3143+
importTable.push_back(entry);
3144+
reader.Seek(nextEntryAddress);
3145+
};
3146+
31213147
switch (fixupsHeader.imports_format)
31223148
{
31233149
case DYLD_CHAINED_IMPORT:
31243150
{
31253151
for (size_t i = 0; i < fixupsHeader.imports_count; i++)
31263152
{
31273153
uint32_t importEntry = parentReader.Read32();
3128-
uint64_t nextEntryAddress = parentReader.GetOffset();
3129-
31303154
dyld_chained_import import = *(reinterpret_cast<dyld_chained_import*>(&importEntry));
3131-
3132-
import_entry entry;
3133-
3134-
entry.lib_ordinal = (uint64_t)import.lib_ordinal;
3135-
entry.addend = 0;
3136-
entry.weak = (import.weak_import == 1);
3137-
3138-
size_t symNameAddr = symbolsAddress + import.name_offset;
3139-
3140-
parentReader.Seek(symNameAddr);
3141-
try {
3142-
string symbolName = parentReader.ReadCString();
3143-
entry.name = symbolName;
3144-
}
3145-
catch (ReadException& ex)
3146-
{
3147-
entry.name = "";
3148-
}
3149-
3150-
importTable.push_back(entry);
3151-
parentReader.Seek(nextEntryAddress);
3155+
processChainedImport(import.lib_ordinal, 0, import.name_offset, import.weak_import, parentReader);
31523156
}
31533157
break;
31543158
}
31553159
case DYLD_CHAINED_IMPORT_ADDEND:
3160+
{
3161+
for (size_t i = 0; i < fixupsHeader.imports_count; i++)
3162+
{
3163+
dyld_chained_import_addend import;
3164+
parentReader.Read(&import, sizeof(import));
3165+
processChainedImport(import.lib_ordinal, import.addend, import.name_offset, import.weak_import, parentReader);
3166+
}
3167+
break;
3168+
}
31563169
case DYLD_CHAINED_IMPORT_ADDEND64:
3170+
{
3171+
for (size_t i = 0; i < fixupsHeader.imports_count; i++)
3172+
{
3173+
dyld_chained_import_addend64 import;
3174+
parentReader.Read(&import, sizeof(import));
3175+
processChainedImport(import.lib_ordinal, import.addend, import.name_offset, import.weak_import, parentReader);
3176+
}
3177+
break;
3178+
}
31573179
default:
31583180
{
3159-
m_logger->LogWarn("Chained Fixups: Unknown import binding format");
3181+
m_logger->LogWarn("Chained Fixups: Unknown import binding format %d", fixupsHeader.imports_format);
31603182
processBinds = false; // We can still handle rebases.
31613183
break;
31623184
}
@@ -3392,6 +3414,7 @@ void MachoView::ParseChainedFixups(MachOHeader& header, linkedit_data_command ch
33923414
externReloc.size = m_addressSize;
33933415
externReloc.pcRelative = false;
33943416
externReloc.external = true;
3417+
externReloc.addend = entry.addend;
33953418
header.externalRelocations.emplace_back(externReloc, entry.name);
33963419
}
33973420
else

0 commit comments

Comments
 (0)