From 3cc4a962cda0cbaad5e881f1466f9f8028be957f Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Mon, 9 Mar 2026 11:38:56 -0400 Subject: [PATCH] Avoid creating functions at jump table entries in shared cache function tables Add a heuristic to skip creating functions at addresses that appear to be jump table entries rather than actual function starts. On aarch64, any entry that disassembles as a `udf` instruction is skipped, since `udf` is used as padding/data in jump tables and is not a valid function prologue. Fix https://github.com/Vector35/binaryninja-api/issues/7992 --- view/sharedcache/core/MachOProcessor.cpp | 29 +++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/view/sharedcache/core/MachOProcessor.cpp b/view/sharedcache/core/MachOProcessor.cpp index 8895a6f05..7a1c74f0e 100644 --- a/view/sharedcache/core/MachOProcessor.cpp +++ b/view/sharedcache/core/MachOProcessor.cpp @@ -17,6 +17,30 @@ SharedCacheMachOProcessor::SharedCacheMachOProcessor(Ref view, std:: } } +static bool HeuristicIsAFunction(Platform* targetPlatform, std::shared_ptr vm, uint64_t func) +{ + // Very dumb heuristic which prevents us from creating function at jump tables + if (targetPlatform->GetArchitecture()->GetName() == "aarch64") + { + // disassemble then and ensure it's not a UDF instruction + uint32_t instruction = 0; + size_t instructionLength = 4; + vm->Read(&instruction, func, sizeof(instruction)); + std::vector result; + targetPlatform->GetArchitecture()->GetInstructionText((uint8_t*)&instruction, func, instructionLength, result); + bool isUDF = false; + for (const auto& instructionText : result) + { + if (instructionText.type == BNInstructionTextTokenType::InstructionToken && instructionText.text == "udf") + { + // This is likely a jump table entry, skip creating a function here. + return false; + } + } + } + return true; +} + void SharedCacheMachOProcessor::ApplyHeader(const SharedCache& cache, SharedCacheMachOHeader& header) { auto typeLibraryFromName = [&](const std::string& name) -> Ref { @@ -52,7 +76,10 @@ void SharedCacheMachOProcessor::ApplyHeader(const SharedCache& cache, SharedCach auto targetPlatform = m_view->GetDefaultPlatform(); auto functions = header.ReadFunctionTable(*m_vm); for (const auto& func : functions) - m_view->AddFunctionForAnalysis(targetPlatform, func, false); + { + if (HeuristicIsAFunction(targetPlatform, m_vm, func)) + m_view->AddFunctionForAnalysis(targetPlatform, func, false); + } } BulkSymbolModification bulkSymbolModification(m_view);