diff options
| author | Mason Reed <mason@vector35.com> | 2025-05-10 19:24:35 -0400 |
|---|---|---|
| committer | Mason Reed <35282038+emesare@users.noreply.github.com> | 2025-05-12 17:45:24 -0400 |
| commit | 7e32ee8b629e3e4f8d061cbe0729ff961b3502d7 (patch) | |
| tree | b33eedcd9afb5422aefd1a42e95f4a9ab2e7cca0 /rust/src | |
| parent | 4180c31fda63b6ccb9ce4ee543031fe4a5060d5f (diff) | |
[Rust] Remove `NonSSAVariant` bound from `LowLevelILFunction`
We don't do enough with the lifted il != non lifted il to justify the bound.
This makes modifying IL much less work as the historical lifted il bound is gone.
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/architecture.rs | 50 | ||||
| -rw-r--r-- | rust/src/flowgraph.rs | 6 | ||||
| -rw-r--r-- | rust/src/function.rs | 18 | ||||
| -rw-r--r-- | rust/src/function_recognizer.rs | 4 | ||||
| -rw-r--r-- | rust/src/low_level_il.rs | 27 | ||||
| -rw-r--r-- | rust/src/low_level_il/expression.rs | 48 | ||||
| -rw-r--r-- | rust/src/low_level_il/function.rs | 27 | ||||
| -rw-r--r-- | rust/src/low_level_il/instruction.rs | 37 | ||||
| -rw-r--r-- | rust/src/low_level_il/lifting.rs | 132 | ||||
| -rw-r--r-- | rust/src/low_level_il/operation.rs | 20 | ||||
| -rw-r--r-- | rust/src/relocation.rs | 8 | ||||
| -rw-r--r-- | rust/src/workflow.rs | 28 |
12 files changed, 158 insertions, 247 deletions
diff --git a/rust/src/architecture.rs b/rust/src/architecture.rs index 211446d1..41150840 100644 --- a/rust/src/architecture.rs +++ b/rust/src/architecture.rs @@ -23,7 +23,6 @@ use crate::{ calling_convention::CoreCallingConvention, data_buffer::DataBuffer, disassembly::InstructionTextToken, - low_level_il::{MutableLiftedILExpr, MutableLiftedILFunction}, platform::Platform, rc::*, relocation::CoreRelocationHandler, @@ -50,6 +49,7 @@ use crate::low_level_il::expression::ValueExpr; use crate::low_level_il::lifting::{ get_default_flag_cond_llil, get_default_flag_write_llil, LowLevelILFlagWriteOp, }; +use crate::low_level_il::{LowLevelILMutableExpression, LowLevelILMutableFunction}; pub use binaryninjacore_sys::BNFlagRole as FlagRole; pub use binaryninjacore_sys::BNImplicitRegisterExtend as ImplicitRegisterExtend; pub use binaryninjacore_sys::BNLowLevelILFlagCondition as FlagCondition; @@ -467,7 +467,7 @@ pub trait Architecture: 'static + Sized + AsRef<CoreArchitecture> { &self, data: &[u8], addr: u64, - il: &MutableLiftedILFunction, + il: &LowLevelILMutableFunction, ) -> Option<(usize, bool)>; /// Fallback flag value calculation path. This method is invoked when the core is unable to @@ -484,8 +484,8 @@ pub trait Architecture: 'static + Sized + AsRef<CoreArchitecture> { flag: Self::Flag, flag_write_type: Self::FlagWrite, op: LowLevelILFlagWriteOp<Self::Register>, - il: &'a MutableLiftedILFunction, - ) -> Option<MutableLiftedILExpr<'a, ValueExpr>> { + il: &'a LowLevelILMutableFunction, + ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>> { let role = flag.role(flag_write_type.class()); Some(get_default_flag_write_llil(self, role, op, il)) } @@ -513,8 +513,8 @@ pub trait Architecture: 'static + Sized + AsRef<CoreArchitecture> { &self, cond: FlagCondition, class: Option<Self::FlagClass>, - il: &'a MutableLiftedILFunction, - ) -> Option<MutableLiftedILExpr<'a, ValueExpr>> { + il: &'a LowLevelILMutableFunction, + ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>> { Some(get_default_flag_cond_llil(self, cond, class, il)) } @@ -535,8 +535,8 @@ pub trait Architecture: 'static + Sized + AsRef<CoreArchitecture> { fn flag_group_llil<'a>( &self, _group: Self::FlagGroup, - _il: &'a MutableLiftedILFunction, - ) -> Option<MutableLiftedILExpr<'a, ValueExpr>> { + _il: &'a LowLevelILMutableFunction, + ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>> { None } @@ -1513,7 +1513,7 @@ impl Architecture for CoreArchitecture { &self, data: &[u8], addr: u64, - il: &MutableLiftedILFunction, + il: &LowLevelILMutableFunction, ) -> Option<(usize, bool)> { let mut size = data.len(); let success = unsafe { @@ -1538,8 +1538,8 @@ impl Architecture for CoreArchitecture { _flag: Self::Flag, _flag_write: Self::FlagWrite, _op: LowLevelILFlagWriteOp<Self::Register>, - _il: &'a MutableLiftedILFunction, - ) -> Option<MutableLiftedILExpr<'a, ValueExpr>> { + _il: &'a LowLevelILMutableFunction, + ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>> { None } @@ -1575,16 +1575,16 @@ impl Architecture for CoreArchitecture { &self, _cond: FlagCondition, _class: Option<Self::FlagClass>, - _il: &'a MutableLiftedILFunction, - ) -> Option<MutableLiftedILExpr<'a, ValueExpr>> { + _il: &'a LowLevelILMutableFunction, + ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>> { None } fn flag_group_llil<'a>( &self, _group: Self::FlagGroup, - _il: &'a MutableLiftedILFunction, - ) -> Option<MutableLiftedILExpr<'a, ValueExpr>> { + _il: &'a LowLevelILMutableFunction, + ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>> { None } @@ -2224,8 +2224,9 @@ where { let custom_arch = unsafe { &*(ctxt as *mut A) }; let data = unsafe { std::slice::from_raw_parts(data, *len) }; - let lifter = - unsafe { MutableLiftedILFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) }; + let lifter = unsafe { + LowLevelILMutableFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) + }; match custom_arch.instruction_llil(data, addr, &lifter) { Some((res_len, res_value)) => { @@ -2611,8 +2612,9 @@ where let flag_write = custom_arch.flag_write_from_id(FlagWriteId(flag_write)); let flag = custom_arch.flag_from_id(FlagId(flag)); let operands = unsafe { std::slice::from_raw_parts(operands_raw, operand_count) }; - let lifter = - unsafe { MutableLiftedILFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) }; + let lifter = unsafe { + LowLevelILMutableFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) + }; if let (Some(flag_write), Some(flag)) = (flag_write, flag) { if let Some(op) = LowLevelILFlagWriteOp::from_op(custom_arch, size, op, operands) { @@ -2660,8 +2662,9 @@ where let custom_arch = unsafe { &*(ctxt as *mut A) }; let class = custom_arch.flag_class_from_id(FlagClassId(class)); - let lifter = - unsafe { MutableLiftedILFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) }; + let lifter = unsafe { + LowLevelILMutableFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) + }; if let Some(expr) = custom_arch.flag_cond_llil(cond, class, &lifter) { // TODO verify that returned expr is a bool value return expr.index.0; @@ -2679,8 +2682,9 @@ where A: 'static + Architecture<Handle = CustomArchitectureHandle<A>> + Send + Sync, { let custom_arch = unsafe { &*(ctxt as *mut A) }; - let lifter = - unsafe { MutableLiftedILFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) }; + let lifter = unsafe { + LowLevelILMutableFunction::from_raw_with_arch(il, Some(*custom_arch.as_ref())) + }; if let Some(group) = custom_arch.flag_group_from_id(FlagGroupId(group)) { if let Some(expr) = custom_arch.flag_group_llil(group, &lifter) { diff --git a/rust/src/flowgraph.rs b/rust/src/flowgraph.rs index 0faab0e4..f0b34853 100644 --- a/rust/src/flowgraph.rs +++ b/rust/src/flowgraph.rs @@ -17,7 +17,7 @@ use binaryninjacore_sys::*; use crate::high_level_il::HighLevelILFunction; -use crate::low_level_il::RegularLowLevelILFunction; +use crate::low_level_il::LowLevelILRegularFunction; use crate::medium_level_il::MediumLevelILFunction; use crate::rc::*; use crate::render_layer::CoreRenderLayer; @@ -58,11 +58,11 @@ impl FlowGraph { unsafe { Array::new(nodes_ptr, count, ()) } } - pub fn low_level_il(&self) -> Result<Ref<RegularLowLevelILFunction>, ()> { + pub fn low_level_il(&self) -> Result<Ref<LowLevelILRegularFunction>, ()> { unsafe { let llil_ptr = BNGetFlowGraphLowLevelILFunction(self.handle); match llil_ptr.is_null() { - false => Ok(RegularLowLevelILFunction::ref_from_raw(llil_ptr)), + false => Ok(LowLevelILRegularFunction::ref_from_raw(llil_ptr)), true => Err(()), } } diff --git a/rust/src/function.rs b/rust/src/function.rs index 92538384..ec859f7e 100644 --- a/rust/src/function.rs +++ b/rust/src/function.rs @@ -41,7 +41,7 @@ use crate::architecture::RegisterId; use crate::confidence::Conf; use crate::high_level_il::HighLevelILFunction; use crate::language_representation::CoreLanguageRepresentationFunction; -use crate::low_level_il::{LiftedILFunction, RegularLowLevelILFunction}; +use crate::low_level_il::LowLevelILRegularFunction; use crate::medium_level_il::MediumLevelILFunction; use crate::variable::{ IndirectBranchInfo, MergedVariable, NamedVariableWithType, RegisterValue, RegisterValueType, @@ -558,38 +558,38 @@ impl Function { } } - pub fn low_level_il(&self) -> Result<Ref<RegularLowLevelILFunction>, ()> { + pub fn low_level_il(&self) -> Result<Ref<LowLevelILRegularFunction>, ()> { unsafe { let llil_ptr = BNGetFunctionLowLevelIL(self.handle); match llil_ptr.is_null() { - false => Ok(RegularLowLevelILFunction::ref_from_raw(llil_ptr)), + false => Ok(LowLevelILRegularFunction::ref_from_raw(llil_ptr)), true => Err(()), } } } - pub fn low_level_il_if_available(&self) -> Option<Ref<RegularLowLevelILFunction>> { + pub fn low_level_il_if_available(&self) -> Option<Ref<LowLevelILRegularFunction>> { let llil_ptr = unsafe { BNGetFunctionLowLevelILIfAvailable(self.handle) }; match llil_ptr.is_null() { - false => Some(unsafe { RegularLowLevelILFunction::ref_from_raw(llil_ptr) }), + false => Some(unsafe { LowLevelILRegularFunction::ref_from_raw(llil_ptr) }), true => None, } } - pub fn lifted_il(&self) -> Result<Ref<LiftedILFunction>, ()> { + pub fn lifted_il(&self) -> Result<Ref<LowLevelILRegularFunction>, ()> { unsafe { let llil_ptr = BNGetFunctionLiftedIL(self.handle); match llil_ptr.is_null() { - false => Ok(LiftedILFunction::ref_from_raw(llil_ptr)), + false => Ok(LowLevelILRegularFunction::ref_from_raw(llil_ptr)), true => Err(()), } } } - pub fn lifted_il_if_available(&self) -> Option<Ref<LiftedILFunction>> { + pub fn lifted_il_if_available(&self) -> Option<Ref<LowLevelILRegularFunction>> { let llil_ptr = unsafe { BNGetFunctionLiftedILIfAvailable(self.handle) }; match llil_ptr.is_null() { - false => Some(unsafe { LiftedILFunction::ref_from_raw(llil_ptr) }), + false => Some(unsafe { LowLevelILRegularFunction::ref_from_raw(llil_ptr) }), true => None, } } diff --git a/rust/src/function_recognizer.rs b/rust/src/function_recognizer.rs index cd5592ee..0d85d827 100644 --- a/rust/src/function_recognizer.rs +++ b/rust/src/function_recognizer.rs @@ -1,5 +1,5 @@ use crate::low_level_il::function::LowLevelILFunction; -use crate::low_level_il::RegularLowLevelILFunction; +use crate::low_level_il::LowLevelILRegularFunction; use crate::medium_level_il::MediumLevelILFunction; use crate::{architecture::CoreArchitecture, binary_view::BinaryView, function::Function}; use binaryninjacore_sys::*; @@ -10,7 +10,7 @@ pub trait FunctionRecognizer { &self, _bv: &BinaryView, _func: &Function, - _llil: &RegularLowLevelILFunction, + _llil: &LowLevelILRegularFunction, ) -> bool { false } diff --git a/rust/src/low_level_il.rs b/rust/src/low_level_il.rs index 4c52e313..010fa0bc 100644 --- a/rust/src/low_level_il.rs +++ b/rust/src/low_level_il.rs @@ -36,19 +36,20 @@ use self::expression::*; use self::function::*; use self::instruction::*; -pub type MutableLiftedILFunction = LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>>; -pub type LiftedILFunction = LowLevelILFunction<Finalized, NonSSA<LiftedNonSSA>>; -pub type MutableLiftedILExpr<'a, ReturnType> = - LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, ReturnType>; -pub type RegularLowLevelILFunction = LowLevelILFunction<Finalized, NonSSA<RegularNonSSA>>; -pub type RegularLowLevelILInstruction<'a> = - LowLevelILInstruction<'a, Finalized, NonSSA<RegularNonSSA>>; -pub type RegularLowLevelILInstructionKind<'a> = - LowLevelILInstructionKind<'a, Finalized, NonSSA<RegularNonSSA>>; -pub type RegularLowLevelILExpression<'a, ReturnType> = - LowLevelILExpression<'a, Finalized, NonSSA<RegularNonSSA>, ReturnType>; -pub type RegularLowLevelILExpressionKind<'a> = - LowLevelILExpressionKind<'a, Finalized, NonSSA<RegularNonSSA>>; +/// Regular low-level IL, if you are not modifying the functions IL or needing SSA, use this. +pub type LowLevelILRegularFunction = LowLevelILFunction<Finalized, NonSSA>; +pub type LowLevelILRegularInstruction<'a> = LowLevelILInstruction<'a, Finalized, NonSSA>; +pub type LowLevelILRegularInstructionKind<'a> = LowLevelILInstructionKind<'a, Finalized, NonSSA>; +pub type LowLevelILRegularExpression<'a, ReturnType> = + LowLevelILExpression<'a, Finalized, NonSSA, ReturnType>; +pub type LowLevelILRegularExpressionKind<'a> = LowLevelILExpressionKind<'a, Finalized, NonSSA>; + +/// Mutable low-level IL, used when lifting in architectures and modifying IL in workflow activities. +pub type LowLevelILMutableFunction = LowLevelILFunction<Mutable, NonSSA>; +pub type LowLevelILMutableExpression<'a, ReturnType> = + LowLevelILExpression<'a, Mutable, NonSSA, ReturnType>; + +/// SSA Variant of low-level IL, this can never be mutated directly. pub type LowLevelILSSAFunction = LowLevelILFunction<Finalized, SSA>; #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] diff --git a/rust/src/low_level_il/expression.rs b/rust/src/low_level_il/expression.rs index 73bec38d..8df8dfe0 100644 --- a/rust/src/low_level_il/expression.rs +++ b/rust/src/low_level_il/expression.rs @@ -135,12 +135,12 @@ where } } -impl<'func, M> ExpressionHandler<'func, M, NonSSA<LiftedNonSSA>> - for LowLevelILExpression<'func, M, NonSSA<LiftedNonSSA>, ValueExpr> +impl<'func, M> ExpressionHandler<'func, M, NonSSA> + for LowLevelILExpression<'func, M, NonSSA, ValueExpr> where M: FunctionMutability, { - fn kind(&self) -> LowLevelILExpressionKind<'func, M, NonSSA<LiftedNonSSA>> { + fn kind(&self) -> LowLevelILExpressionKind<'func, M, NonSSA> { #[allow(unused_imports)] use binaryninjacore_sys::BNLowLevelILOperation::*; let op = unsafe { BNGetLowLevelILByIndex(self.function.handle, self.index.0) }; @@ -154,41 +154,7 @@ where fn visit_tree<T>(&self, f: &mut T) -> VisitorAction where - T: FnMut(&LowLevelILExpression<'func, M, NonSSA<LiftedNonSSA>, ValueExpr>) -> VisitorAction, - { - // Visit the current expression. - match f(self) { - VisitorAction::Descend => { - // Recursively visit sub expressions. - self.kind().visit_sub_expressions(|e| e.visit_tree(f)) - } - action => action, - } - } -} - -impl<'func, M> ExpressionHandler<'func, M, NonSSA<RegularNonSSA>> - for LowLevelILExpression<'func, M, NonSSA<RegularNonSSA>, ValueExpr> -where - M: FunctionMutability, -{ - fn kind(&self) -> LowLevelILExpressionKind<'func, M, NonSSA<RegularNonSSA>> { - use binaryninjacore_sys::BNLowLevelILOperation::*; - let op = unsafe { BNGetLowLevelILByIndex(self.function.handle, self.index.0) }; - match op.operation { - // Any invalid ops for Non-Lifted IL will be checked here. - LLIL_FLAG_COND => unreachable!("LLIL_FLAG_COND is only valid in Lifted IL"), - LLIL_FLAG_GROUP => unreachable!("LLIL_FLAG_GROUP is only valid in Lifted IL"), - // SAFETY: We have checked for illegal operations. - _ => LowLevelILExpressionKind::from_raw(self.function, op, self.index), - } - } - - fn visit_tree<T>(&self, f: &mut T) -> VisitorAction - where - T: FnMut( - &LowLevelILExpression<'func, M, NonSSA<RegularNonSSA>, ValueExpr>, - ) -> VisitorAction, + T: FnMut(&LowLevelILExpression<'func, M, NonSSA, ValueExpr>) -> VisitorAction, { // Visit the current expression. match f(self) { @@ -272,9 +238,9 @@ where LowPart(Operation<'func, M, F, operation::UnaryOp>), // Valid only in Lifted IL - FlagCond(Operation<'func, M, NonSSA<LiftedNonSSA>, operation::FlagCond>), + FlagCond(Operation<'func, M, F, operation::FlagCond>), // Valid only in Lifted IL - FlagGroup(Operation<'func, M, NonSSA<LiftedNonSSA>, operation::FlagGroup>), + FlagGroup(Operation<'func, M, F, operation::FlagGroup>), CmpE(Operation<'func, M, F, operation::Condition>), CmpNe(Operation<'func, M, F, operation::Condition>), @@ -708,7 +674,7 @@ where } } -impl LowLevelILExpressionKind<'_, Mutable, NonSSA<LiftedNonSSA>> { +impl LowLevelILExpressionKind<'_, Mutable, NonSSA> { pub fn flag_write(&self) -> Option<CoreFlagWrite> { use self::LowLevelILExpressionKind::*; diff --git a/rust/src/low_level_il/function.rs b/rust/src/low_level_il/function.rs index 62811b1d..495aae79 100644 --- a/rust/src/low_level_il/function.rs +++ b/rust/src/low_level_il/function.rs @@ -36,22 +36,13 @@ impl FunctionMutability for Mutable {} impl FunctionMutability for Finalized {} #[derive(Copy, Clone, Debug)] -pub struct LiftedNonSSA; -#[derive(Copy, Clone, Debug)] -pub struct RegularNonSSA; - -pub trait NonSSAVariant: 'static + Debug {} -impl NonSSAVariant for LiftedNonSSA {} -impl NonSSAVariant for RegularNonSSA {} - -#[derive(Copy, Clone, Debug)] pub struct SSA; #[derive(Copy, Clone, Debug)] -pub struct NonSSA<V: NonSSAVariant>(V); +pub struct NonSSA; pub trait FunctionForm: 'static + Debug {} impl FunctionForm for SSA {} -impl<V: NonSSAVariant> FunctionForm for NonSSA<V> {} +impl FunctionForm for NonSSA {} pub struct LowLevelILFunction<M: FunctionMutability, F: FunctionForm> { pub(crate) handle: *mut BNLowLevelILFunction, @@ -170,7 +161,7 @@ where } } -impl<M: FunctionMutability, V: NonSSAVariant> LowLevelILFunction<M, NonSSA<V>> { +impl<M: FunctionMutability> LowLevelILFunction<M, NonSSA> { /// Retrieve the SSA form of the function. pub fn ssa_form(&self) -> Option<Ref<LowLevelILFunction<M, SSA>>> { let handle = unsafe { BNGetLowLevelILSSAForm(self.handle) }; @@ -182,7 +173,7 @@ impl<M: FunctionMutability, V: NonSSAVariant> LowLevelILFunction<M, NonSSA<V>> { } // Allow instantiating Lifted IL functions for querying Lifted IL from Architectures -impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { +impl LowLevelILFunction<Mutable, NonSSA> { // TODO: Document what happens when you pass None for `source_func`. // TODO: Doing so would construct a LowLevelILFunction with no basic blocks // TODO: Document why you would want to do that. @@ -208,6 +199,16 @@ impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { } } +impl Ref<LowLevelILFunction<Mutable, NonSSA>> { + pub fn finalized(self) -> Ref<LowLevelILFunction<Finalized, NonSSA>> { + unsafe { + BNFinalizeLowLevelILFunction(self.handle); + // Now that we have finalized return the function as is so the caller can reference the "finalized function". + LowLevelILFunction::from_raw(self.handle).to_owned() + } + } +} + impl<M, F> ToOwned for LowLevelILFunction<M, F> where M: FunctionMutability, diff --git a/rust/src/low_level_il/instruction.rs b/rust/src/low_level_il/instruction.rs index 19b721af..ef546412 100644 --- a/rust/src/low_level_il/instruction.rs +++ b/rust/src/low_level_il/instruction.rs @@ -141,12 +141,11 @@ where } } -impl<'func, M> InstructionHandler<'func, M, NonSSA<LiftedNonSSA>> - for LowLevelILInstruction<'func, M, NonSSA<LiftedNonSSA>> +impl<'func, M> InstructionHandler<'func, M, NonSSA> for LowLevelILInstruction<'func, M, NonSSA> where M: FunctionMutability, { - fn kind(&self) -> LowLevelILInstructionKind<'func, M, NonSSA<LiftedNonSSA>> { + fn kind(&self) -> LowLevelILInstructionKind<'func, M, NonSSA> { #[allow(unused_imports)] use binaryninjacore_sys::BNLowLevelILOperation::*; let raw_op = self.into_raw(); @@ -162,37 +161,7 @@ where fn visit_tree<T>(&self, f: &mut T) -> VisitorAction where - T: FnMut(&LowLevelILExpression<'func, M, NonSSA<LiftedNonSSA>, ValueExpr>) -> VisitorAction, - { - // Recursively visit sub expressions. - self.kind().visit_sub_expressions(|e| e.visit_tree(f)) - } -} - -impl<'func, M> InstructionHandler<'func, M, NonSSA<RegularNonSSA>> - for LowLevelILInstruction<'func, M, NonSSA<RegularNonSSA>> -where - M: FunctionMutability, -{ - fn kind(&self) -> LowLevelILInstructionKind<'func, M, NonSSA<RegularNonSSA>> { - #[allow(unused_imports)] - use binaryninjacore_sys::BNLowLevelILOperation::*; - let raw_op = self.into_raw(); - #[allow(clippy::match_single_binding)] - match raw_op.operation { - // Any invalid ops for Non-Lifted IL will be checked here. - // SAFETY: We have checked for illegal operations. - _ => unsafe { - LowLevelILInstructionKind::from_raw(self.function, self.expr_idx(), raw_op) - }, - } - } - - fn visit_tree<T>(&self, f: &mut T) -> VisitorAction - where - T: FnMut( - &LowLevelILExpression<'func, M, NonSSA<RegularNonSSA>, ValueExpr>, - ) -> VisitorAction, + T: FnMut(&LowLevelILExpression<'func, M, NonSSA, ValueExpr>) -> VisitorAction, { // Recursively visit sub expressions. self.kind().visit_sub_expressions(|e| e.visit_tree(f)) diff --git a/rust/src/low_level_il/lifting.rs b/rust/src/low_level_il/lifting.rs index b0f85f11..f2850776 100644 --- a/rust/src/low_level_il/lifting.rs +++ b/rust/src/low_level_il/lifting.rs @@ -29,17 +29,17 @@ pub trait LiftableLowLevelIL<'func> { type Result: ExpressionResultType; fn lift( - il: &'func MutableLiftedILFunction, + il: &'func LowLevelILMutableFunction, expr: Self, - ) -> MutableLiftedILExpr<'func, Self::Result>; + ) -> LowLevelILMutableExpression<'func, Self::Result>; } pub trait LiftableLowLevelILWithSize<'func>: LiftableLowLevelIL<'func, Result = ValueExpr> { fn lift_with_size( - il: &'func MutableLiftedILFunction, + il: &'func LowLevelILMutableFunction, expr: Self, size: usize, - ) -> MutableLiftedILExpr<'func, ValueExpr>; + ) -> LowLevelILMutableExpression<'func, ValueExpr>; } #[derive(Copy, Clone)] @@ -459,8 +459,8 @@ pub fn get_default_flag_write_llil<'func, A>( arch: &A, role: FlagRole, op: LowLevelILFlagWriteOp<A::Register>, - il: &'func MutableLiftedILFunction, -) -> MutableLiftedILExpr<'func, ValueExpr> + il: &'func LowLevelILMutableFunction, +) -> LowLevelILMutableExpression<'func, ValueExpr> where A: 'func + Architecture, { @@ -487,8 +487,8 @@ pub fn get_default_flag_cond_llil<'func, A>( arch: &A, cond: FlagCondition, class: Option<A::FlagClass>, - il: &'func MutableLiftedILFunction, -) -> MutableLiftedILExpr<'func, ValueExpr> + il: &'func LowLevelILMutableFunction, +) -> LowLevelILMutableExpression<'func, ValueExpr> where A: 'func + Architecture, { @@ -512,16 +512,16 @@ macro_rules! prim_int_lifter { impl<'a> LiftableLowLevelIL<'a> for $x { type Result = ValueExpr; - fn lift(il: &'a MutableLiftedILFunction, val: Self) - -> MutableLiftedILExpr<'a, Self::Result> + fn lift(il: &'a LowLevelILMutableFunction, val: Self) + -> LowLevelILMutableExpression<'a, Self::Result> { il.const_int(std::mem::size_of::<Self>(), val as i64 as u64) } } impl<'a> LiftableLowLevelILWithSize<'a> for $x { - fn lift_with_size(il: &'a MutableLiftedILFunction, val: Self, size: usize) - -> MutableLiftedILExpr<'a, ValueExpr> + fn lift_with_size(il: &'a LowLevelILMutableFunction, val: Self, size: usize) + -> LowLevelILMutableExpression<'a, ValueExpr> { let raw = val as i64; @@ -560,7 +560,10 @@ where { type Result = ValueExpr; - fn lift(il: &'a MutableLiftedILFunction, reg: Self) -> MutableLiftedILExpr<'a, Self::Result> { + fn lift( + il: &'a LowLevelILMutableFunction, + reg: Self, + ) -> LowLevelILMutableExpression<'a, Self::Result> { match reg { LowLevelILRegisterKind::Arch(r) => R::lift(il, r), LowLevelILRegisterKind::Temp(t) => il.reg( @@ -576,10 +579,10 @@ where R: LiftableLowLevelILWithSize<'a> + Into<LowLevelILRegisterKind<R>> + ArchReg, { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a LowLevelILMutableFunction, reg: Self, size: usize, - ) -> MutableLiftedILExpr<'a, ValueExpr> { + ) -> LowLevelILMutableExpression<'a, ValueExpr> { match reg { LowLevelILRegisterKind::Arch(r) => R::lift_with_size(il, r, size), LowLevelILRegisterKind::Temp(t) => il.reg(size, LowLevelILRegisterKind::<R>::Temp(t)), @@ -595,7 +598,10 @@ where { type Result = ValueExpr; - fn lift(il: &'a MutableLiftedILFunction, reg: Self) -> MutableLiftedILExpr<'a, Self::Result> { + fn lift( + il: &'a LowLevelILMutableFunction, + reg: Self, + ) -> LowLevelILMutableExpression<'a, Self::Result> { match reg { LowLevelILRegisterOrConstant::Register(size, r) => { LowLevelILRegisterKind::<R>::lift_with_size(il, r, size) @@ -612,10 +618,10 @@ where R: LiftableLowLevelILWithSize<'a> + Into<LowLevelILRegisterKind<R>> + ArchReg, { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a LowLevelILMutableFunction, reg: Self, size: usize, - ) -> MutableLiftedILExpr<'a, ValueExpr> { + ) -> LowLevelILMutableExpression<'a, ValueExpr> { // TODO ensure requested size is compatible with size of this constant match reg { LowLevelILRegisterOrConstant::Register(_, r) => { @@ -628,26 +634,27 @@ where } } -impl<'a, R> LiftableLowLevelIL<'a> for LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, R> +impl<'a, R> LiftableLowLevelIL<'a> for LowLevelILExpression<'a, Mutable, NonSSA, R> where R: ExpressionResultType, { type Result = R; - fn lift(il: &'a MutableLiftedILFunction, expr: Self) -> MutableLiftedILExpr<'a, Self::Result> { + fn lift( + il: &'a LowLevelILMutableFunction, + expr: Self, + ) -> LowLevelILMutableExpression<'a, Self::Result> { debug_assert!(expr.function.handle == il.handle); expr } } -impl<'a> LiftableLowLevelILWithSize<'a> - for LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, ValueExpr> -{ +impl<'a> LiftableLowLevelILWithSize<'a> for LowLevelILExpression<'a, Mutable, NonSSA, ValueExpr> { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a LowLevelILMutableFunction, expr: Self, _size: usize, - ) -> MutableLiftedILExpr<'a, Self::Result> { + ) -> LowLevelILMutableExpression<'a, Self::Result> { #[cfg(debug_assertions)] { use crate::low_level_il::ExpressionHandler; @@ -667,7 +674,7 @@ impl<'a> LiftableLowLevelILWithSize<'a> } } -impl<R> LowLevelILExpression<'_, Mutable, NonSSA<LiftedNonSSA>, R> +impl<R> LowLevelILExpression<'_, Mutable, NonSSA, R> where R: ExpressionResultType, { @@ -686,7 +693,7 @@ pub struct ExpressionBuilder<'func, R> where R: ExpressionResultType, { - function: &'func LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>>, + function: &'func LowLevelILFunction<Mutable, NonSSA>, op: BNLowLevelILOperation, size: usize, flag_write: FlagWriteId, @@ -701,7 +708,7 @@ impl<'a, R> ExpressionBuilder<'a, R> where R: ExpressionResultType, { - pub fn from_expr(expr: LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, R>) -> Self { + pub fn from_expr(expr: LowLevelILExpression<'a, Mutable, NonSSA, R>) -> Self { use binaryninjacore_sys::BNGetLowLevelILByIndex; let instr = unsafe { BNGetLowLevelILByIndex(expr.function.handle, expr.index.0) }; @@ -725,7 +732,7 @@ where self } - pub fn build(self) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, R> { + pub fn build(self) -> LowLevelILExpression<'a, Mutable, NonSSA, R> { use binaryninjacore_sys::BNLowLevelILAddExpr; let expr_idx = unsafe { @@ -744,10 +751,7 @@ where LowLevelILExpression::new(self.function, LowLevelExpressionIndex(expr_idx)) } - pub fn with_source_operand( - self, - op: u32, - ) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, R> { + pub fn with_source_operand(self, op: u32) -> LowLevelILExpression<'a, Mutable, NonSSA, R> { self.build().with_source_operand(op) } @@ -763,7 +767,10 @@ where { type Result = R; - fn lift(il: &'a MutableLiftedILFunction, expr: Self) -> MutableLiftedILExpr<'a, Self::Result> { + fn lift( + il: &'a LowLevelILMutableFunction, + expr: Self, + ) -> LowLevelILMutableExpression<'a, Self::Result> { debug_assert!(expr.function.handle == il.handle); expr.build() @@ -772,10 +779,10 @@ where impl<'a> LiftableLowLevelILWithSize<'a> for ExpressionBuilder<'a, ValueExpr> { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a LowLevelILMutableFunction, expr: Self, _size: usize, - ) -> MutableLiftedILExpr<'a, ValueExpr> { + ) -> LowLevelILMutableExpression<'a, ValueExpr> { #[cfg(debug_assertions)] { use binaryninjacore_sys::BNLowLevelILOperation::{LLIL_UNIMPL, LLIL_UNIMPL_MEM}; @@ -796,7 +803,7 @@ impl<'a> LiftableLowLevelILWithSize<'a> for ExpressionBuilder<'a, ValueExpr> { macro_rules! no_arg_lifter { ($name:ident, $op:ident, $result:ty) => { - pub fn $name(&self) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, $result> { + pub fn $name(&self) -> LowLevelILExpression<Mutable, NonSSA, $result> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::$op; @@ -829,10 +836,7 @@ macro_rules! sized_no_arg_lifter { macro_rules! unsized_unary_op_lifter { ($name:ident, $op:ident, $result:ty) => { - pub fn $name<'a, E>( - &'a self, - expr: E, - ) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, $result> + pub fn $name<'a, E>(&'a self, expr: E) -> LowLevelILExpression<'a, Mutable, NonSSA, $result> where E: LiftableLowLevelIL<'a, Result = ValueExpr>, { @@ -967,14 +971,14 @@ macro_rules! binary_op_carry_lifter { }; } -impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { +impl LowLevelILMutableFunction { pub const NO_INPUTS: [ExpressionBuilder<'static, ValueExpr>; 0] = []; pub const NO_OUTPUTS: [LowLevelILRegisterKind<CoreRegister>; 0] = []; pub fn expression<'a, E: LiftableLowLevelIL<'a>>( &'a self, expr: E, - ) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, E::Result> { + ) -> LowLevelILExpression<'a, Mutable, NonSSA, E::Result> { E::lift(self, expr) } @@ -1002,11 +1006,7 @@ impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { true } - pub fn const_int( - &self, - size: usize, - val: u64, - ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + pub fn const_int(&self, size: usize, val: u64) -> LowLevelILMutableExpression<ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_CONST; @@ -1016,11 +1016,7 @@ impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { LowLevelILExpression::new(self, LowLevelExpressionIndex(expr_idx)) } - pub fn const_ptr_sized( - &self, - size: usize, - val: u64, - ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + pub fn const_ptr_sized(&self, size: usize, val: u64) -> LowLevelILMutableExpression<ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_CONST_PTR; @@ -1030,14 +1026,11 @@ impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { LowLevelILExpression::new(self, LowLevelExpressionIndex(expr_idx)) } - pub fn const_ptr( - &self, - val: u64, - ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + pub fn const_ptr(&self, val: u64) -> LowLevelILMutableExpression<ValueExpr> { self.const_ptr_sized(self.arch().address_size(), val) } - pub fn trap(&self, val: u64) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, VoidExpr> { + pub fn trap(&self, val: u64) -> LowLevelILExpression<Mutable, NonSSA, VoidExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_TRAP; @@ -1064,7 +1057,7 @@ impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { cond: C, true_label: &'b mut LowLevelILLabel, false_label: &'b mut LowLevelILLabel, - ) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, VoidExpr> + ) -> LowLevelILExpression<'a, Mutable, NonSSA, VoidExpr> where C: LiftableLowLevelIL<'b, Result = ValueExpr>, { @@ -1104,7 +1097,7 @@ impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { pub fn goto<'a: 'b, 'b>( &'a self, label: &'b mut LowLevelILLabel, - ) -> LowLevelILExpression<'a, Mutable, NonSSA<LiftedNonSSA>, VoidExpr> { + ) -> LowLevelILExpression<'a, Mutable, NonSSA, VoidExpr> { use binaryninjacore_sys::BNLowLevelILGoto; let mut raw_label = BNLowLevelILLabel::from(*label); @@ -1125,7 +1118,7 @@ impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { &self, size: usize, reg: LR, - ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + ) -> LowLevelILMutableExpression<ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_REG; @@ -1143,7 +1136,7 @@ impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { size: usize, hi_reg: LR, lo_reg: LR, - ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + ) -> LowLevelILMutableExpression<ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_REG_SPLIT; @@ -1232,10 +1225,7 @@ impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { } } - pub fn flag( - &self, - flag: impl Flag, - ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + pub fn flag(&self, flag: impl Flag) -> LowLevelILMutableExpression<ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG; @@ -1247,10 +1237,7 @@ impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { LowLevelILExpression::new(self, LowLevelExpressionIndex(expr_idx)) } - pub fn flag_cond( - &self, - cond: FlagCondition, - ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + pub fn flag_cond(&self, cond: FlagCondition) -> LowLevelILMutableExpression<ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG_COND; @@ -1261,10 +1248,7 @@ impl LowLevelILFunction<Mutable, NonSSA<LiftedNonSSA>> { LowLevelILExpression::new(self, LowLevelExpressionIndex(expr_idx)) } - pub fn flag_group( - &self, - group: impl FlagGroup, - ) -> LowLevelILExpression<Mutable, NonSSA<LiftedNonSSA>, ValueExpr> { + pub fn flag_group(&self, group: impl FlagGroup) -> LowLevelILMutableExpression<ValueExpr> { use binaryninjacore_sys::BNLowLevelILAddExpr; use binaryninjacore_sys::BNLowLevelILOperation::LLIL_FLAG_GROUP; diff --git a/rust/src/low_level_il/operation.rs b/rust/src/low_level_il/operation.rs index f2ce9d1a..6e0dda91 100644 --- a/rust/src/low_level_il/operation.rs +++ b/rust/src/low_level_il/operation.rs @@ -90,11 +90,14 @@ where } } -impl<M, O> Operation<'_, M, NonSSA<LiftedNonSSA>, O> +impl<M, O> Operation<'_, M, NonSSA, O> where M: FunctionMutability, O: OperationArguments, { + /// Get the [`CoreFlagWrite`] for the operation. + /// + /// NOTE: This is only expected to be present for lifted IL. pub fn flag_write(&self) -> Option<CoreFlagWrite> { match self.op.flags { 0 => None, @@ -1419,9 +1422,10 @@ where // Valid only in Lifted IL pub struct FlagGroup; -impl<M> Operation<'_, M, NonSSA<LiftedNonSSA>, FlagGroup> +impl<M, F> Operation<'_, M, F, FlagGroup> where M: FunctionMutability, + F: FunctionForm, { pub fn flag_group(&self) -> CoreFlagGroup { let id = self.op.operands[0] as u32; @@ -1432,9 +1436,10 @@ where } } -impl<M> Debug for Operation<'_, M, NonSSA<LiftedNonSSA>, FlagGroup> +impl<M, F> Debug for Operation<'_, M, F, FlagGroup> where M: FunctionMutability, + F: FunctionForm, { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("FlagGroup") @@ -1443,15 +1448,6 @@ where } } -impl<M> Debug for Operation<'_, M, SSA, FlagGroup> -where - M: FunctionMutability, -{ - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_struct("FlagGroup").finish() - } -} - // LLIL_TRAP pub struct Trap; diff --git a/rust/src/relocation.rs b/rust/src/relocation.rs index 2b24279b..a4f9667e 100644 --- a/rust/src/relocation.rs +++ b/rust/src/relocation.rs @@ -1,4 +1,4 @@ -use crate::low_level_il::RegularLowLevelILFunction; +use crate::low_level_il::LowLevelILRegularFunction; use crate::rc::Guard; use crate::string::IntoCStr; use crate::{ @@ -265,7 +265,7 @@ pub trait RelocationHandler: 'static + Sized + AsRef<CoreRelocationHandler> { _data: &[u8], _addr: u64, // TODO: Are we sure this is not a liftedilfunction? - _il: &RegularLowLevelILFunction, + _il: &LowLevelILRegularFunction, _reloc: &Relocation, ) -> RelocationOperand { RelocationOperand::AutocoerceExternPtr @@ -363,7 +363,7 @@ impl RelocationHandler for CoreRelocationHandler { &self, data: &[u8], addr: u64, - il: &RegularLowLevelILFunction, + il: &LowLevelILRegularFunction, reloc: &Relocation, ) -> RelocationOperand { unsafe { @@ -495,7 +495,7 @@ where return RelocationOperand::Invalid.into(); } let arch = unsafe { CoreArchitecture::from_raw(arch) }; - let il = unsafe { RegularLowLevelILFunction::from_raw_with_arch(il, Some(arch)) }; + let il = unsafe { LowLevelILRegularFunction::from_raw_with_arch(il, Some(arch)) }; custom_handler .get_operand_for_external_relocation(data, addr, &il, &reloc) diff --git a/rust/src/workflow.rs b/rust/src/workflow.rs index 0b1925a9..3dcb1042 100644 --- a/rust/src/workflow.rs +++ b/rust/src/workflow.rs @@ -5,8 +5,7 @@ use crate::binary_view::BinaryView; use crate::flowgraph::FlowGraph; use crate::function::{Function, NativeBlock}; use crate::high_level_il::HighLevelILFunction; -use crate::low_level_il::function::{LowLevelILFunction, Mutable, NonSSA, NonSSAVariant}; -use crate::low_level_il::MutableLiftedILFunction; +use crate::low_level_il::{LowLevelILMutableFunction, LowLevelILRegularFunction}; use crate::medium_level_il::MediumLevelILFunction; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable}; use crate::string::{BnString, IntoCStr}; @@ -45,41 +44,32 @@ impl AnalysisContext { unsafe { Function::ref_from_raw(result) } } - /// [`LowLevelILFunction`] used to represent Low Level IL - pub unsafe fn lifted_il_function(&self) -> Option<Ref<MutableLiftedILFunction>> { + /// [`LowLevelILMutableFunction`] used to represent Lifted Level IL + pub unsafe fn lifted_il_function(&self) -> Option<Ref<LowLevelILMutableFunction>> { let func = self.function(); let result = unsafe { BNGetFunctionLiftedIL(func.handle) }; unsafe { - Some(LowLevelILFunction::ref_from_raw( + Some(LowLevelILMutableFunction::ref_from_raw( NonNull::new(result)?.as_ptr(), )) } } - pub fn set_lifted_il_function(&self, value: &MutableLiftedILFunction) { + pub fn set_lifted_il_function(&self, value: &LowLevelILRegularFunction) { unsafe { BNSetLiftedILFunction(self.handle.as_ptr(), value.handle) } } - // TODO: This returns LiftedNonSSA because the lifting code was written before we could patch the IL - // TODO: At some point we need to take the lifting code and make it available to regular IL. - /// [`LowLevelILFunction`] used to represent Low Level IL - pub unsafe fn llil_function<V: NonSSAVariant>( - &self, - ) -> Option<Ref<LowLevelILFunction<Mutable, NonSSA<V>>>> { + /// [`LowLevelILMutableFunction`] used to represent Low Level IL + pub unsafe fn llil_function(&self) -> Option<Ref<LowLevelILMutableFunction>> { let result = unsafe { BNAnalysisContextGetLowLevelILFunction(self.handle.as_ptr()) }; unsafe { - Some(LowLevelILFunction::ref_from_raw( + Some(LowLevelILMutableFunction::ref_from_raw( NonNull::new(result)?.as_ptr(), )) } } - // TODO: This returns LiftedNonSSA because the lifting code was written before we could patch the IL - // TODO: At some point we need to take the lifting code and make it available to regular IL. - pub fn set_llil_function<V: NonSSAVariant>( - &self, - value: &LowLevelILFunction<Mutable, NonSSA<V>>, - ) { + pub fn set_llil_function(&self, value: &LowLevelILRegularFunction) { unsafe { BNSetLowLevelILFunction(self.handle.as_ptr(), value.handle) } } |
