Skip to content

Commit 7ad9550

Browse files
committed
Shared Cache: use IsValidFunctionStart to filter jump table entries
Extract MachoView::IsValidFunctionStart logic into a shared inline function and reuse it in the shared cache MachOProcessor to skip creating functions at jump table entries (udf/trap instructions).
1 parent f860e52 commit 7ad9550

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

view/macho/machoview.cpp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,22 +1103,7 @@ bool MachoView::IsValidFunctionStart(uint64_t addr)
11031103
{
11041104
uint8_t opcode[BN_MAX_INSTRUCTION_LENGTH];
11051105
size_t opLen = Read(opcode, addr, m_arch->GetMaxInstructionLength());
1106-
if (!opLen)
1107-
return false;
1108-
1109-
Ref<LowLevelILFunction> ilFunc = new LowLevelILFunction(m_arch, nullptr);
1110-
ilFunc->SetCurrentAddress(m_arch, addr);
1111-
m_arch->GetInstructionLowLevelIL(opcode, addr, opLen, *ilFunc);
1112-
for (size_t i = 0; i < ilFunc->GetInstructionCount(); i++)
1113-
{
1114-
const auto& instr = ilFunc->GetInstruction(i);
1115-
if (instr.operation == LLIL_UNDEF)
1116-
return false;
1117-
if (i == 0 && instr.operation == LLIL_TRAP)
1118-
return false;
1119-
}
1120-
1121-
return true;
1106+
return ::IsValidFunctionStart(m_arch, addr, opcode, opLen);
11221107
}
11231108

11241109

view/macho/machoview.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <string.h>
66

77
#include "binaryninjaapi.h"
8+
#include "lowlevelilinstruction.h"
89
#include "objc.h"
910

1011
//These are laready defined in one of the osx headers we want to override
@@ -1546,3 +1547,26 @@ namespace BinaryNinja
15461547

15471548
void InitMachoViewType();
15481549
}
1550+
1551+
// Check whether the instruction at `addr` looks like a valid function entry point.
1552+
// Returns false for undefined or trap instructions that typically indicate jump table entries.
1553+
// `opcode` must contain at least `opLen` bytes read from `addr`.
1554+
inline bool IsValidFunctionStart(BinaryNinja::Architecture* arch, uint64_t addr, const uint8_t* opcode, size_t opLen)
1555+
{
1556+
if (!opLen)
1557+
return false;
1558+
1559+
BinaryNinja::Ref<BinaryNinja::LowLevelILFunction> ilFunc = new BinaryNinja::LowLevelILFunction(arch, nullptr);
1560+
ilFunc->SetCurrentAddress(arch, addr);
1561+
arch->GetInstructionLowLevelIL(opcode, addr, opLen, *ilFunc);
1562+
for (size_t i = 0; i < ilFunc->GetInstructionCount(); i++)
1563+
{
1564+
const auto& instr = ilFunc->GetInstruction(i);
1565+
if (instr.operation == LLIL_UNDEF)
1566+
return false;
1567+
if (i == 0 && instr.operation == LLIL_TRAP)
1568+
return false;
1569+
}
1570+
1571+
return true;
1572+
}

view/sharedcache/core/MachOProcessor.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,16 @@ void SharedCacheMachOProcessor::ApplyHeader(const SharedCache& cache, SharedCach
5050
if (m_applyFunctions && header.functionStartsPresent)
5151
{
5252
auto targetPlatform = m_view->GetDefaultPlatform();
53+
auto arch = targetPlatform->GetArchitecture();
5354
auto functions = header.ReadFunctionTable(*m_vm);
5455
for (const auto& func : functions)
55-
m_view->AddFunctionForAnalysis(targetPlatform, func, false);
56+
{
57+
uint8_t opcode[BN_MAX_INSTRUCTION_LENGTH];
58+
size_t opLen = arch->GetMaxInstructionLength();
59+
m_vm->Read(opcode, func, opLen);
60+
if (IsValidFunctionStart(arch, func, opcode, opLen))
61+
m_view->AddFunctionForAnalysis(targetPlatform, func, false);
62+
}
5663
}
5764

5865
BulkSymbolModification bulkSymbolModification(m_view);

0 commit comments

Comments
 (0)