diff options
| author | Mason Reed <mason@vector35.com> | 2025-12-09 20:03:22 -0500 |
|---|---|---|
| committer | Mason Reed <35282038+emesare@users.noreply.github.com> | 2025-12-10 16:37:14 -0500 |
| commit | 0ec8e7d31dcd5c38498ac473db46e3b55883edd2 (patch) | |
| tree | 21ff1ee1f27abf830139e4f3f5c388ce412943aa | |
| parent | 570a01aa6c9a3299ce30f04af89b3f01e96aebe4 (diff) | |
[Rust] Fix crash when calling `LowLevelILFunction::generate_ssa_form` without an owner
You cannot generate SSA form of an LLIL function without a backing function unfortunately.
| -rw-r--r-- | rust/src/low_level_il/function.rs | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/rust/src/low_level_il/function.rs b/rust/src/low_level_il/function.rs index 15a83c19..837b45ef 100644 --- a/rust/src/low_level_il/function.rs +++ b/rust/src/low_level_il/function.rs @@ -213,6 +213,8 @@ where impl<M: FunctionMutability> LowLevelILFunction<M, NonSSA> { /// Retrieve the SSA form of the function. + /// + /// If the function has not had the SSA form generated you may call `generate_ssa_form`. pub fn ssa_form(&self) -> Option<Ref<LowLevelILFunction<M, SSA>>> { let handle = unsafe { BNGetLowLevelILSSAForm(self.handle) }; if handle.is_null() { @@ -220,6 +222,29 @@ impl<M: FunctionMutability> LowLevelILFunction<M, NonSSA> { } Some(unsafe { LowLevelILFunction::ref_from_raw(handle) }) } + + /// Generates the SSA form of the function. Typically called **after** `finalize`. + /// + /// If you created a freestanding [`LowLevelILFunction`] with no [`LowLevelILFunction::function`] + /// than this function will **not** generate the SSA form, as it is currently impossible. + /// + /// # Example + /// + /// ```no_run + /// use binaryninja::low_level_il::LowLevelILMutableFunction; + /// use binaryninja::rc::Ref; + /// # let mutable_llil: Ref<LowLevelILMutableFunction> = unimplemented!(); + /// // ... modify the IL + /// let finalized_llil = mutable_llil.finalized(); + /// finalized_llil.generate_ssa_form(); + /// ``` + pub fn generate_ssa_form(&self) { + use binaryninjacore_sys::BNGenerateLowLevelILSSAForm; + // SSA form may only be generated if there is an owning function, otherwise it will crash. + if self.function().is_some() { + unsafe { BNGenerateLowLevelILSSAForm(self.handle) }; + } + } } // Allow instantiating Lifted IL functions for querying Lifted IL from Architectures @@ -242,14 +267,24 @@ impl LowLevelILFunction<Mutable, NonSSA> { unsafe { Self::ref_from_raw_with_arch(handle, Some(arch)) } } - - pub fn generate_ssa_form(&self) { - use binaryninjacore_sys::BNGenerateLowLevelILSSAForm; - unsafe { BNGenerateLowLevelILSSAForm(self.handle) }; - } } impl Ref<LowLevelILFunction<Mutable, NonSSA>> { + /// Finalize the mutated [`LowLevelILFunction`], returning a [`LowLevelILRegularFunction`]. + /// + /// This function **will not** correct the SSA related dataflow, to do that you must call + /// the function [`LowLevelILMutableFunction::generate_ssa_form`]. + /// + /// # Example + /// + /// ```no_run + /// use binaryninja::low_level_il::LowLevelILMutableFunction; + /// use binaryninja::rc::Ref; + /// # let mutable_llil: Ref<LowLevelILMutableFunction> = unimplemented!(); + /// // ... modify the IL + /// let finalized_llil = mutable_llil.finalized(); + /// finalized_llil.generate_ssa_form(); + /// ``` pub fn finalized(self) -> Ref<LowLevelILFunction<Finalized, NonSSA>> { unsafe { BNFinalizeLowLevelILFunction(self.handle); |
