summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Potchik <brian@vector35.com>2025-07-08 12:13:19 -0400
committerBrian Potchik <brian@vector35.com>2025-07-08 12:13:19 -0400
commit5b575ff6a87061221e1c17824b2b42af839ccc74 (patch)
tree5f37836f732f1af49a048c9a957250e2bc57984b
parent33e9108b92a73782e271852c6b438c2937706fbe (diff)
Various improvements for guided disassembly mode.
-rw-r--r--binaryninjaapi.h4
-rw-r--r--binaryninjacore.h8
-rw-r--r--defaultabb.cpp7
-rw-r--r--function.cpp6
-rw-r--r--python/architecture.py18
-rw-r--r--python/function.py16
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]]: