diff --git a/view/macho/machoview.cpp b/view/macho/machoview.cpp index d4ccf5636..0240f4f5d 100644 --- a/view/macho/machoview.cpp +++ b/view/macho/machoview.cpp @@ -1103,22 +1103,7 @@ bool MachoView::IsValidFunctionStart(uint64_t addr) { uint8_t opcode[BN_MAX_INSTRUCTION_LENGTH]; size_t opLen = Read(opcode, addr, m_arch->GetMaxInstructionLength()); - if (!opLen) - return false; - - Ref ilFunc = new LowLevelILFunction(m_arch, nullptr); - ilFunc->SetCurrentAddress(m_arch, addr); - m_arch->GetInstructionLowLevelIL(opcode, addr, opLen, *ilFunc); - for (size_t i = 0; i < ilFunc->GetInstructionCount(); i++) - { - const auto& instr = ilFunc->GetInstruction(i); - if (instr.operation == LLIL_UNDEF) - return false; - if (i == 0 && instr.operation == LLIL_TRAP) - return false; - } - - return true; + return ::IsValidFunctionStart(m_arch, addr, opcode, opLen); } diff --git a/view/macho/machoview.h b/view/macho/machoview.h index f41cd8bdf..55426bfd9 100644 --- a/view/macho/machoview.h +++ b/view/macho/machoview.h @@ -5,6 +5,7 @@ #include #include "binaryninjaapi.h" +#include "lowlevelilinstruction.h" #include "objc.h" //These are laready defined in one of the osx headers we want to override @@ -1546,3 +1547,26 @@ namespace BinaryNinja void InitMachoViewType(); } + +// Check whether the instruction at `addr` looks like a valid function entry point. +// Returns false for undefined or trap instructions that typically indicate jump table entries. +// `opcode` must contain at least `opLen` bytes read from `addr`. +inline bool IsValidFunctionStart(BinaryNinja::Architecture* arch, uint64_t addr, const uint8_t* opcode, size_t opLen) +{ + if (!opLen) + return false; + + BinaryNinja::Ref ilFunc = new BinaryNinja::LowLevelILFunction(arch, nullptr); + ilFunc->SetCurrentAddress(arch, addr); + arch->GetInstructionLowLevelIL(opcode, addr, opLen, *ilFunc); + for (size_t i = 0; i < ilFunc->GetInstructionCount(); i++) + { + const auto& instr = ilFunc->GetInstruction(i); + if (instr.operation == LLIL_UNDEF) + return false; + if (i == 0 && instr.operation == LLIL_TRAP) + return false; + } + + return true; +} diff --git a/view/sharedcache/core/MachOProcessor.cpp b/view/sharedcache/core/MachOProcessor.cpp index 8895a6f05..d6f335f96 100644 --- a/view/sharedcache/core/MachOProcessor.cpp +++ b/view/sharedcache/core/MachOProcessor.cpp @@ -50,9 +50,16 @@ void SharedCacheMachOProcessor::ApplyHeader(const SharedCache& cache, SharedCach if (m_applyFunctions && header.functionStartsPresent) { auto targetPlatform = m_view->GetDefaultPlatform(); + auto arch = targetPlatform->GetArchitecture(); auto functions = header.ReadFunctionTable(*m_vm); for (const auto& func : functions) - m_view->AddFunctionForAnalysis(targetPlatform, func, false); + { + uint8_t opcode[BN_MAX_INSTRUCTION_LENGTH]; + size_t opLen = arch->GetMaxInstructionLength(); + m_vm->Read(opcode, func, opLen); + if (IsValidFunctionStart(arch, func, opcode, opLen)) + m_view->AddFunctionForAnalysis(targetPlatform, func, false); + } } BulkSymbolModification bulkSymbolModification(m_view);