diff options
| author | Glenn Smith <glenn@vector35.com> | 2025-06-10 18:38:47 -0400 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2025-06-11 17:37:30 -0400 |
| commit | 7714756208488751236371949777023618888407 (patch) | |
| tree | 3e8dcfcabb9736cc03ad7ad2d521e71b7b5fe25b | |
| parent | 4559573522332364873709280012593875935285 (diff) | |
API to create immediate function graphs
| -rw-r--r-- | binaryninjaapi.h | 4 | ||||
| -rw-r--r-- | binaryninjacore.h | 8 | ||||
| -rw-r--r-- | function.cpp | 7 | ||||
| -rw-r--r-- | highlevelil.cpp | 7 | ||||
| -rw-r--r-- | lowlevelil.cpp | 7 | ||||
| -rw-r--r-- | mediumlevelil.cpp | 7 | ||||
| -rw-r--r-- | python/function.py | 30 | ||||
| -rw-r--r-- | python/highlevelil.py | 7 | ||||
| -rw-r--r-- | python/lowlevelil.py | 7 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 7 | ||||
| -rw-r--r-- | rust/src/function.rs | 12 |
11 files changed, 103 insertions, 0 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index ad16ca84..650fa8a2 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -11217,6 +11217,7 @@ namespace BinaryNinja { void ApplyAutoDiscoveredType(Type* type); Ref<FlowGraph> CreateFunctionGraph(const FunctionViewType& type, DisassemblySettings* settings = nullptr); + Ref<FlowGraph> CreateFunctionGraphImmediate(const FunctionViewType& type, DisassemblySettings* settings = nullptr); std::map<int64_t, std::vector<VariableNameAndType>> GetStackLayout(); void CreateAutoStackVariable(int64_t offset, const Confidence<Ref<Type>>& type, const std::string& name); @@ -13394,6 +13395,7 @@ namespace BinaryNinja { } Ref<FlowGraph> CreateFunctionGraph(DisassemblySettings* settings = nullptr); + Ref<FlowGraph> CreateFunctionGraphImmediate(DisassemblySettings* settings = nullptr); }; /*! @@ -13786,6 +13788,7 @@ namespace BinaryNinja { } Ref<FlowGraph> CreateFunctionGraph(DisassemblySettings* settings = nullptr); + Ref<FlowGraph> CreateFunctionGraphImmediate(DisassemblySettings* settings = nullptr); std::set<size_t> GetLiveInstructionsForVariable(const Variable& var, bool includeLastUse = true); @@ -14081,6 +14084,7 @@ namespace BinaryNinja { void VisitAllExprs(const std::function<bool(const HighLevelILInstruction& expr)>& func); Ref<FlowGraph> CreateFunctionGraph(DisassemblySettings* settings = nullptr); + Ref<FlowGraph> CreateFunctionGraphImmediate(DisassemblySettings* settings = nullptr); size_t GetExprIndexForLabel(uint64_t label); std::set<size_t> GetUsesForLabel(uint64_t label); diff --git a/binaryninjacore.h b/binaryninjacore.h index 99e10969..ae906bb9 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -5654,6 +5654,14 @@ extern "C" BNMediumLevelILFunction* func, BNDisassemblySettings* settings); BINARYNINJACOREAPI BNFlowGraph* BNCreateHighLevelILFunctionGraph( BNHighLevelILFunction* func, BNDisassemblySettings* settings); + BINARYNINJACOREAPI BNFlowGraph* BNCreateImmediateFunctionGraph( + BNFunction* func, BNFunctionViewType type, BNDisassemblySettings* settings); + BINARYNINJACOREAPI BNFlowGraph* BNCreateLowLevelILImmediateFunctionGraph( + BNLowLevelILFunction* func, BNDisassemblySettings* settings); + BINARYNINJACOREAPI BNFlowGraph* BNCreateMediumLevelILImmediateFunctionGraph( + BNMediumLevelILFunction* func, BNDisassemblySettings* settings); + BINARYNINJACOREAPI BNFlowGraph* BNCreateHighLevelILImmediateFunctionGraph( + BNHighLevelILFunction* func, BNDisassemblySettings* settings); BINARYNINJACOREAPI BNFlowGraph* BNCreateCustomFlowGraph(BNCustomFlowGraph* callbacks); BINARYNINJACOREAPI BNFlowGraph* BNNewFlowGraphReference(BNFlowGraph* graph); BINARYNINJACOREAPI void BNFreeFlowGraph(BNFlowGraph* graph); diff --git a/function.cpp b/function.cpp index 593085d2..2e6b702e 100644 --- a/function.cpp +++ b/function.cpp @@ -1292,6 +1292,13 @@ Ref<FlowGraph> Function::CreateFunctionGraph(const FunctionViewType& type, Disas } +Ref<FlowGraph> Function::CreateFunctionGraphImmediate(const FunctionViewType& type, DisassemblySettings* settings) +{ + BNFlowGraph* graph = BNCreateImmediateFunctionGraph(m_object, type.ToAPIObject(), settings ? settings->GetObject() : nullptr); + return new CoreFlowGraph(graph); +} + + map<int64_t, vector<VariableNameAndType>> Function::GetStackLayout() { size_t count; diff --git a/highlevelil.cpp b/highlevelil.cpp index 91ce5cfc..7e65e1e6 100644 --- a/highlevelil.cpp +++ b/highlevelil.cpp @@ -564,6 +564,13 @@ Ref<FlowGraph> HighLevelILFunction::CreateFunctionGraph(DisassemblySettings* set } +Ref<FlowGraph> HighLevelILFunction::CreateFunctionGraphImmediate(DisassemblySettings* settings) +{ + BNFlowGraph* graph = BNCreateHighLevelILImmediateFunctionGraph(m_object, settings ? settings->GetObject() : nullptr); + return new CoreFlowGraph(graph); +} + + size_t HighLevelILFunction::GetExprIndexForLabel(uint64_t label) { return BNGetHighLevelILExprIndexForLabel(m_object, label); diff --git a/lowlevelil.cpp b/lowlevelil.cpp index 239abed0..33dea219 100644 --- a/lowlevelil.cpp +++ b/lowlevelil.cpp @@ -1038,3 +1038,10 @@ Ref<FlowGraph> LowLevelILFunction::CreateFunctionGraph(DisassemblySettings* sett BNFlowGraph* graph = BNCreateLowLevelILFunctionGraph(m_object, settings ? settings->GetObject() : nullptr); return new CoreFlowGraph(graph); } + + +Ref<FlowGraph> LowLevelILFunction::CreateFunctionGraphImmediate(DisassemblySettings* settings) +{ + BNFlowGraph* graph = BNCreateLowLevelILImmediateFunctionGraph(m_object, settings ? settings->GetObject() : nullptr); + return new CoreFlowGraph(graph); +} diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index 52679a12..0a285628 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -941,6 +941,13 @@ Ref<FlowGraph> MediumLevelILFunction::CreateFunctionGraph(DisassemblySettings* s } +Ref<FlowGraph> MediumLevelILFunction::CreateFunctionGraphImmediate(DisassemblySettings* settings) +{ + BNFlowGraph* graph = BNCreateMediumLevelILImmediateFunctionGraph(m_object, settings ? settings->GetObject() : nullptr); + return new CoreFlowGraph(graph); +} + + set<size_t> MediumLevelILFunction::GetLiveInstructionsForVariable(const Variable& var, bool includeLastUse) { size_t count; diff --git a/python/function.py b/python/function.py index d571bc55..cf8bafdd 100644 --- a/python/function.py +++ b/python/function.py @@ -2213,6 +2213,16 @@ class Function: self, graph_type: FunctionViewTypeOrName = FunctionGraphType.NormalFunctionGraph, settings: Optional['DisassemblySettings'] = None ) -> flowgraph.CoreFlowGraph: + """ + Create a flow graph with the disassembly of this function. + + .. note:: This graph waits for function analysis, so Workflow Activities should instead use + :py:func:`create_graph_immediate` to create graphs with the function contents as-is. + + :param graph_type: IL form of the disassembly in the graph + :param settings: Optional settings for the disassembly text renderer + :return: Flow graph object + """ if settings is not None: settings_obj = settings.handle else: @@ -2220,6 +2230,26 @@ class Function: graph_type = FunctionViewType(graph_type)._to_core_struct() return flowgraph.CoreFlowGraph(core.BNCreateFunctionGraph(self.handle, graph_type, settings_obj)) + def create_graph_immediate( + self, graph_type: FunctionViewTypeOrName = FunctionGraphType.NormalFunctionGraph, + settings: Optional['DisassemblySettings'] = None + ) -> flowgraph.CoreFlowGraph: + """ + Create a flow graph with the disassembly of this function, specifically using the + instructions as they are in the function when this is called. You probably want to use + this if you are creating a Debug Report in a Workflow Activity. + + :param graph_type: IL form of the disassembly in the graph + :param settings: Optional settings for the disassembly text renderer + :return: Flow graph object + """ + if settings is not None: + settings_obj = settings.handle + else: + settings_obj = None + graph_type = FunctionViewType(graph_type)._to_core_struct() + return flowgraph.CoreFlowGraph(core.BNCreateImmediateFunctionGraph(self.handle, graph_type, settings_obj)) + def apply_imported_types(self, sym: 'types.CoreSymbol', type: Optional[StringOrType] = None) -> None: if isinstance(type, str): (type, _) = self.view.parse_type_string(type) diff --git a/python/highlevelil.py b/python/highlevelil.py index 101b2e9f..1ac81617 100644 --- a/python/highlevelil.py +++ b/python/highlevelil.py @@ -4608,6 +4608,13 @@ class HighLevelILFunction: settings_obj = None return flowgraph.CoreFlowGraph(core.BNCreateHighLevelILFunctionGraph(self.handle, settings_obj)) + def create_graph_immediate(self, settings: Optional['function.DisassemblySettings'] = None) -> 'flowgraph.CoreFlowGraph': + if settings is not None: + settings_obj = settings.handle + else: + settings_obj = None + return flowgraph.CoreFlowGraph(core.BNCreateHighLevelILImmediateFunctionGraph(self.handle, settings_obj)) + @property def il_form(self) -> FunctionGraphType: if len(list(self.basic_blocks)) < 1: diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 09786cd9..6cd87227 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -6128,6 +6128,13 @@ class LowLevelILFunction: settings_obj = None return flowgraph.CoreFlowGraph(core.BNCreateLowLevelILFunctionGraph(self.handle, settings_obj)) + def create_graph_immediate(self, settings: Optional['function.DisassemblySettings'] = None) -> flowgraph.CoreFlowGraph: + if settings is not None: + settings_obj = settings.handle + else: + settings_obj = None + return flowgraph.CoreFlowGraph(core.BNCreateLowLevelILImmediateFunctionGraph(self.handle, settings_obj)) + class LowLevelILBasicBlock(basicblock.BasicBlock): """ diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 7d60abd1..1026df7d 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -5518,6 +5518,13 @@ class MediumLevelILFunction: settings_obj = None return flowgraph.CoreFlowGraph(core.BNCreateMediumLevelILFunctionGraph(self.handle, settings_obj)) + def create_graph_immediate(self, settings: Optional['function.DisassemblySettings'] = None) -> flowgraph.CoreFlowGraph: + if settings is not None: + settings_obj = settings.handle + else: + settings_obj = None + return flowgraph.CoreFlowGraph(core.BNCreateMediumLevelILImmediateFunctionGraph(self.handle, settings_obj)) + @property def arch(self) -> 'architecture.Architecture': return self._arch diff --git a/rust/src/function.rs b/rust/src/function.rs index e7e269dc..33b22d19 100644 --- a/rust/src/function.rs +++ b/rust/src/function.rs @@ -2435,6 +2435,18 @@ impl Function { unsafe { FlowGraph::ref_from_raw(result) } } + pub fn create_graph_immediate( + &self, + view_type: FunctionViewType, + settings: Option<&DisassemblySettings>, + ) -> Ref<FlowGraph> { + let settings_raw = settings.map(|s| s.handle).unwrap_or(std::ptr::null_mut()); + let raw_view_type = FunctionViewType::into_raw(view_type); + let result = unsafe { BNCreateImmediateFunctionGraph(self.handle, raw_view_type, settings_raw) }; + FunctionViewType::free_raw(raw_view_type); + unsafe { FlowGraph::ref_from_raw(result) } + } + pub fn parent_components(&self) -> Array<Component> { let mut count = 0; let result = |
