diff options
| author | Brian Potchik <brian@vector35.com> | 2025-07-08 12:13:19 -0400 |
|---|---|---|
| committer | Brian Potchik <brian@vector35.com> | 2025-07-08 12:13:19 -0400 |
| commit | 5b575ff6a87061221e1c17824b2b42af839ccc74 (patch) | |
| tree | 5f37836f732f1af49a048c9a957250e2bc57984b | |
| parent | 33e9108b92a73782e271852c6b438c2937706fbe (diff) | |
Various improvements for guided disassembly mode.
| -rw-r--r-- | binaryninjaapi.h | 4 | ||||
| -rw-r--r-- | binaryninjacore.h | 8 | ||||
| -rw-r--r-- | defaultabb.cpp | 7 | ||||
| -rw-r--r-- | function.cpp | 6 | ||||
| -rw-r--r-- | python/architecture.py | 18 | ||||
| -rw-r--r-- | python/function.py | 16 |
6 files changed, 50 insertions, 9 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 2d21ef6d..252b4659 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -8178,9 +8178,10 @@ namespace BinaryNinja { BasicBlockAnalysisContext(BNBasicBlockAnalysisContext* context); BNFunctionAnalysisSkipOverride GetAnalysisSkipOverride() const { return m_context->analysisSkipOverride; } + bool GetGuidedAnalysisMode() const { return m_context->guidedAnalysisMode; } + bool GetTriggerGuidedOnInvalidInstruction() const { return m_context->triggerGuidedOnInvalidInstruction; } bool GetTranslateTailCalls() const { return m_context->translateTailCalls; } bool GetDisallowBranchToString() const { return m_context->disallowBranchToString; } - bool GetHaltOnInvalidInstructions() const { return m_context->haltOnInvalidInstructions; } uint64_t GetMaxFunctionSize() const { return m_context->maxFunctionSize; } bool GetMaxSizeReached() const { return m_context->maxSizeReached; } @@ -11523,6 +11524,7 @@ namespace BinaryNinja { void SetGuidedSourceBlocks(const std::vector<ArchAndAddr>& addresses); void AddGuidedSourceBlocks(const std::vector<ArchAndAddr>& addresses); void RemoveGuidedSourceBlocks(const std::vector<ArchAndAddr>& addresses); + bool IsGuidedSourceBlock(Architecture* arch, uint64_t addr) const; std::vector<ArchAndAddr> GetGuidedSourceBlocks(); std::vector<IndirectBranchInfo> GetIndirectBranches(); diff --git a/binaryninjacore.h b/binaryninjacore.h index b9237c0d..a073006b 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -37,14 +37,14 @@ // Current ABI version for linking to the core. This is incremented any time // there are changes to the API that affect linking, including new functions, // new types, or modifications to existing functions or types. -#define BN_CURRENT_CORE_ABI_VERSION 120 +#define BN_CURRENT_CORE_ABI_VERSION 121 // Minimum ABI version that is supported for loading of plugins. Plugins that // are linked to an ABI version less than this will not be able to load and // will require rebuilding. The minimum version is increased when there are // incompatible changes that break binary compatibility, such as changes to // existing types or functions. -#define BN_MINIMUM_CORE_ABI_VERSION 117 +#define BN_MINIMUM_CORE_ABI_VERSION 121 #ifdef __GNUC__ #ifdef BINARYNINJACORE_LIBRARY @@ -1872,9 +1872,10 @@ extern "C" // IN BNFunctionAnalysisSkipOverride analysisSkipOverride; + bool guidedAnalysisMode; + bool triggerGuidedOnInvalidInstruction; bool translateTailCalls; bool disallowBranchToString; - bool haltOnInvalidInstructions; uint64_t maxFunctionSize; size_t indirectBranchesCount; @@ -5154,6 +5155,7 @@ extern "C" BINARYNINJACOREAPI void BNSetGuidedSourceBlocks(BNFunction* func, BNArchitectureAndAddress* addresses, size_t count); BINARYNINJACOREAPI void BNAddGuidedSourceBlocks(BNFunction* func, BNArchitectureAndAddress* addresses, size_t count); BINARYNINJACOREAPI void BNRemoveGuidedSourceBlocks(BNFunction* func, BNArchitectureAndAddress* addresses, size_t count); + BINARYNINJACOREAPI bool BNIsGuidedSourceBlock(BNFunction* func, BNArchitecture* arch, uint64_t addr); BINARYNINJACOREAPI BNArchitectureAndAddress* BNGetGuidedSourceBlocks(BNFunction* func, size_t* count); BINARYNINJACOREAPI void BNFreeArchitectureAndAddressList(BNArchitectureAndAddress* addresses); diff --git a/defaultabb.cpp b/defaultabb.cpp index 1c4c38bb..647bbfb6 100644 --- a/defaultabb.cpp +++ b/defaultabb.cpp @@ -63,9 +63,10 @@ void Architecture::DefaultAnalyzeBasicBlocks(Function* function, BasicBlockAnaly map<ArchAndAddr, Ref<BasicBlock>> instrBlocks; set<ArchAndAddr> seenBlocks; + bool guidedAnalysisMode = context.GetGuidedAnalysisMode(); + bool triggerGuidedOnInvalidInstruction = context.GetTriggerGuidedOnInvalidInstruction(); bool translateTailCalls = context.GetTranslateTailCalls(); bool disallowBranchToString = context.GetDisallowBranchToString(); - bool haltOnInvalidInstructions = context.GetHaltOnInvalidInstructions(); auto& indirectBranches = context.GetIndirectBranches(); auto& indirectNoReturnCalls = context.GetIndirectNoReturnCalls(); @@ -674,10 +675,10 @@ void Architecture::DefaultAnalyzeBasicBlocks(Function* function, BasicBlockAnaly if (maxSizeReached) break; - if (haltOnInvalidInstructions && block->HasInvalidInstructions()) + if (triggerGuidedOnInvalidInstruction && block->HasInvalidInstructions()) hasInvalidInstructions = true; - if (hasInvalidInstructions) + if (guidedAnalysisMode || hasInvalidInstructions || guidedSourceBlocksSet.size()) { queue<ArchAndAddr> guidedBlocksToProcess; while (!blocksToProcess.empty()) diff --git a/function.cpp b/function.cpp index 19d3fbc7..c2e52e55 100644 --- a/function.cpp +++ b/function.cpp @@ -1780,6 +1780,12 @@ void Function::RemoveGuidedSourceBlocks(const std::vector<ArchAndAddr>& addresse } +bool Function::IsGuidedSourceBlock(Architecture* arch, uint64_t addr) const +{ + return BNIsGuidedSourceBlock(m_object, arch->GetObject(), addr); +} + + std::vector<ArchAndAddr> Function::GetGuidedSourceBlocks() { size_t count; diff --git a/python/architecture.py b/python/architecture.py index 099b56f1..a3307146 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -81,10 +81,11 @@ class BasicBlockAnalysisContext: _indirect_branches: List["variable.IndirectBranchInfo"] _indirect_no_return_calls: Set["function.ArchAndAddr"] _analysis_skip_override: core.FunctionAnalysisSkipOverride + _guided_analysis_mode: bool + _trigger_guided_on_invalid_instruction: bool _translate_tail_calls: bool _disallow_branch_to_string: bool _max_function_size: int - _halt_on_invalid_instruction: bool _max_size_reached: bool # In/Out @@ -157,10 +158,11 @@ class BasicBlockAnalysisContext: _indirect_branches=indirect_branches, _indirect_no_return_calls=indirect_no_return_calls, _analysis_skip_override=bn_bb_context.analysisSkipOverride, + _guided_analysis_mode=bn_bb_context.guidedAnalysisMode, + _trigger_guided_on_invalid_instruction=bn_bb_context.triggerGuidedOnInvalidInstruction, _translate_tail_calls=bn_bb_context.translateTailCalls, _disallow_branch_to_string=bn_bb_context.disallowBranchToString, _max_function_size=bn_bb_context.maxFunctionSize, - _halt_on_invalid_instruction=bn_bb_context.haltOnInvalidInstructions, _max_size_reached=bn_bb_context.maxSizeReached, _contextual_returns=contextual_returns, _contextual_returns_dirty=False, @@ -188,6 +190,18 @@ class BasicBlockAnalysisContext: return self._analysis_skip_override @property + def guided_analysis_mode(self) -> bool: + """Get the setting that determines if functions start in guided analysis mode.""" + + return self._guided_analysis_mode + + @property + def trigger_guided_on_invalid_instruction(self) -> bool: + """Get the setting that determines if guided mode should be triggered on invalid instructions.""" + + return self._trigger_guided_on_invalid_instruction + + @property def translate_tail_calls(self) -> bool: """Get setting from context that determines if tail calls should be translated.""" diff --git a/python/function.py b/python/function.py index 37bd3396..9ea8093b 100644 --- a/python/function.py +++ b/python/function.py @@ -2326,6 +2326,22 @@ class Function: address_list[i].address = addresses[i][1] core.BNRemoveGuidedSourceBlocks(self.handle, address_list, len(addresses)) + def is_guided_source_block( + self, arch: 'architecture.Architecture', addr: int + ) -> bool: + """ + ``is_guided_source_block`` checks if the given address is a guided source block. + + :param architecture.Architecture arch: Architecture of the address to check + :param int addr: Address to check + :rtype: bool + :Example: + + >>> current_function.is_guided_source_block(arch, 0x400000) + True + """ + return core.BNIsGuidedSourceBlock(self.handle, arch.handle, addr) + def get_guided_source_blocks( self ) -> List[Tuple['architecture.Architecture', int]]: |
