diff options
| -rw-r--r-- | arch/msp430/src/architecture.rs | 8 | ||||
| -rw-r--r-- | arch/msp430/src/lift.rs | 8 | ||||
| -rw-r--r-- | arch/riscv/src/lib.rs | 39 | ||||
| -rw-r--r-- | plugins/warp/src/cache.rs | 14 | ||||
| -rw-r--r-- | plugins/warp/src/lib.rs | 16 | ||||
| -rw-r--r-- | plugins/warp/src/plugin/workflow.rs | 3 | ||||
| -rw-r--r-- | rust/examples/workflow.rs | 2 | ||||
| -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 |
19 files changed, 202 insertions, 293 deletions
diff --git a/arch/msp430/src/architecture.rs b/arch/msp430/src/architecture.rs index 0ef6e449..91826193 100644 --- a/arch/msp430/src/architecture.rs +++ b/arch/msp430/src/architecture.rs @@ -20,7 +20,7 @@ use binaryninja::architecture::{ BranchKind, FlagClassId, FlagGroupId, FlagId, FlagWriteId, RegisterId, }; use binaryninja::low_level_il::expression::ValueExpr; -use binaryninja::low_level_il::{MutableLiftedILExpr, MutableLiftedILFunction}; +use binaryninja::low_level_il::{LowLevelILMutableExpression, LowLevelILMutableFunction}; use log::error; const MIN_MNEMONIC: usize = 9; @@ -194,7 +194,7 @@ impl Architecture for Msp430 { &self, data: &[u8], addr: u64, - il: &MutableLiftedILFunction, + il: &LowLevelILMutableFunction, ) -> Option<(usize, bool)> { match msp430_asm::decode(data) { Ok(inst) => { @@ -226,8 +226,8 @@ impl Architecture for Msp430 { fn flag_group_llil<'a>( &self, _group: Self::FlagGroup, - _il: &'a MutableLiftedILFunction, - ) -> Option<MutableLiftedILExpr<'a, ValueExpr>> { + _il: &'a LowLevelILMutableFunction, + ) -> Option<LowLevelILMutableExpression<'a, ValueExpr>> { None } diff --git a/arch/msp430/src/lift.rs b/arch/msp430/src/lift.rs index 124911f0..3e69b5a4 100644 --- a/arch/msp430/src/lift.rs +++ b/arch/msp430/src/lift.rs @@ -12,7 +12,7 @@ use msp430_asm::single_operand::SingleOperand; use msp430_asm::two_operand::TwoOperand; use binaryninja::low_level_il::expression::ValueExpr; -use binaryninja::low_level_il::{MutableLiftedILExpr, MutableLiftedILFunction}; +use binaryninja::low_level_il::{LowLevelILMutableExpression, LowLevelILMutableFunction}; use log::info; macro_rules! auto_increment { @@ -163,7 +163,7 @@ macro_rules! conditional_jump { }; } -pub(crate) fn lift_instruction(inst: &Instruction, addr: u64, il: &MutableLiftedILFunction) { +pub(crate) fn lift_instruction(inst: &Instruction, addr: u64, il: &LowLevelILMutableFunction) { match inst { Instruction::Rrc(inst) => { let size = match inst.operand_width() { @@ -623,8 +623,8 @@ pub(crate) fn lift_instruction(inst: &Instruction, addr: u64, il: &MutableLifted fn lift_source_operand<'a>( operand: &Operand, size: usize, - il: &'a MutableLiftedILFunction, -) -> MutableLiftedILExpr<'a, ValueExpr> { + il: &'a LowLevelILMutableFunction, +) -> LowLevelILMutableExpression<'a, ValueExpr> { match operand { Operand::RegisterDirect(r) => il.reg(size, Register::try_from(*r as u32).unwrap()), Operand::Indexed((r, offset)) => il diff --git a/arch/riscv/src/lib.rs b/arch/riscv/src/lib.rs index 4e9e4783..f59e1ebb 100644 --- a/arch/riscv/src/lib.rs +++ b/arch/riscv/src/lib.rs @@ -43,8 +43,8 @@ use binaryninja::low_level_il::lifting::{ LiftableLowLevelIL, LiftableLowLevelILWithSize, LowLevelILLabel, }; use binaryninja::low_level_il::{ - expression::ExpressionHandler, instruction::InstructionHandler, LowLevelILRegisterKind, - MutableLiftedILExpr, MutableLiftedILFunction, RegularLowLevelILFunction, + expression::ExpressionHandler, instruction::InstructionHandler, LowLevelILMutableExpression, + LowLevelILMutableFunction, LowLevelILRegisterKind, LowLevelILRegularFunction, }; use riscv_dis::{ FloatReg, FloatRegType, Instr, IntRegType, Op, RegFile, Register as RiscVRegister, @@ -207,7 +207,10 @@ impl<D: RiscVDisassembler> architecture::Register for Register<D> { impl<'a, D: RiscVDisassembler> LiftableLowLevelIL<'a> for Register<D> { 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.reg_type() { RegType::Integer(0) => il.const_int(reg.size(), 0), RegType::Integer(_) => il.reg(reg.size(), reg), @@ -218,10 +221,10 @@ impl<'a, D: RiscVDisassembler> LiftableLowLevelIL<'a> for Register<D> { impl<'a, D: RiscVDisassembler> LiftableLowLevelILWithSize<'a> for Register<D> { fn lift_with_size( - il: &'a MutableLiftedILFunction, + il: &'a LowLevelILMutableFunction, reg: Self, size: usize, - ) -> MutableLiftedILExpr<'a, ValueExpr> { + ) -> LowLevelILMutableExpression<'a, ValueExpr> { #[cfg(debug_assertions)] { if reg.size() < size { @@ -1062,7 +1065,7 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> { &self, data: &[u8], addr: u64, - il: &MutableLiftedILFunction, + il: &LowLevelILMutableFunction, ) -> Option<(usize, bool)> { let max_width = self.default_integer_size(); @@ -1306,41 +1309,41 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> { Op::Ebreak => il.bp().append(), Op::Uret => { il.intrinsic( - MutableLiftedILFunction::NO_OUTPUTS, + LowLevelILMutableFunction::NO_OUTPUTS, RiscVIntrinsic::<D>::from(Intrinsic::Uret), - MutableLiftedILFunction::NO_INPUTS, + LowLevelILMutableFunction::NO_INPUTS, ) .append(); il.no_ret().append(); } Op::Sret => { il.intrinsic( - MutableLiftedILFunction::NO_OUTPUTS, + LowLevelILMutableFunction::NO_OUTPUTS, RiscVIntrinsic::<D>::from(Intrinsic::Sret), - MutableLiftedILFunction::NO_INPUTS, + LowLevelILMutableFunction::NO_INPUTS, ) .append(); il.no_ret().append(); } Op::Mret => { il.intrinsic( - MutableLiftedILFunction::NO_OUTPUTS, + LowLevelILMutableFunction::NO_OUTPUTS, RiscVIntrinsic::<D>::from(Intrinsic::Mret), - MutableLiftedILFunction::NO_INPUTS, + LowLevelILMutableFunction::NO_INPUTS, ) .append(); il.no_ret().append(); } Op::Wfi => il .intrinsic( - MutableLiftedILFunction::NO_OUTPUTS, + LowLevelILMutableFunction::NO_OUTPUTS, RiscVIntrinsic::<D>::from(Intrinsic::Wfi), - MutableLiftedILFunction::NO_INPUTS, + LowLevelILMutableFunction::NO_INPUTS, ) .append(), Op::Fence(i) => il .intrinsic( - MutableLiftedILFunction::NO_OUTPUTS, + LowLevelILMutableFunction::NO_OUTPUTS, RiscVIntrinsic::<D>::from(Intrinsic::Fence), [il.const_int(4, i.imm() as u32 as u64)], ) @@ -1353,7 +1356,7 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> { if i.rd().id() == 0 { il.intrinsic( - MutableLiftedILFunction::NO_OUTPUTS, + LowLevelILMutableFunction::NO_OUTPUTS, RiscVIntrinsic::<D>::from(Intrinsic::Csrwr), [csr, rs1], ) @@ -1404,7 +1407,7 @@ impl<D: RiscVDisassembler> Architecture for RiscVArch<D> { if i.rd().id() == 0 { il.intrinsic( - MutableLiftedILFunction::NO_OUTPUTS, + LowLevelILMutableFunction::NO_OUTPUTS, RiscVIntrinsic::<D>::from(Intrinsic::Csrwr), [csr, imm], ) @@ -2848,7 +2851,7 @@ impl FunctionRecognizer for RiscVELFPLTRecognizer { &self, bv: &BinaryView, func: &Function, - llil: &RegularLowLevelILFunction, + llil: &LowLevelILRegularFunction, ) -> bool { // Look for the following code pattern: // t3 = plt diff --git a/plugins/warp/src/cache.rs b/plugins/warp/src/cache.rs index 7219b547..cc8dfded 100644 --- a/plugins/warp/src/cache.rs +++ b/plugins/warp/src/cache.rs @@ -3,10 +3,8 @@ use crate::{build_function, function_guid}; use binaryninja::binary_view::{BinaryView, BinaryViewExt}; use binaryninja::confidence::MAX_CONFIDENCE; use binaryninja::function::Function as BNFunction; -use binaryninja::low_level_il::function::{ - FunctionMutability, LowLevelILFunction, NonSSA, RegularNonSSA, -}; -use binaryninja::low_level_il::RegularLowLevelILFunction; +use binaryninja::low_level_il::function::{FunctionMutability, LowLevelILFunction, NonSSA}; +use binaryninja::low_level_il::LowLevelILRegularFunction; use binaryninja::rc::Guard; use binaryninja::rc::Ref as BNRef; use binaryninja::symbol::Symbol as BNSymbol; @@ -67,7 +65,7 @@ pub fn try_cached_function_match(function: &BNFunction) -> Option<Function> { .to_owned() } -pub fn cached_function(function: &BNFunction, llil: &RegularLowLevelILFunction) -> Function { +pub fn cached_function(function: &BNFunction, llil: &LowLevelILRegularFunction) -> Function { let view = function.view(); let view_id = ViewID::from(view.as_ref()); let function_cache = FUNCTION_CACHE.get_or_init(Default::default); @@ -120,7 +118,7 @@ where pub fn cached_function_guid<M: FunctionMutability>( function: &BNFunction, - llil: &LowLevelILFunction<M, NonSSA<RegularNonSSA>>, + llil: &LowLevelILFunction<M, NonSSA>, ) -> FunctionGUID { let view = function.view(); let view_id = ViewID::from(view); @@ -198,7 +196,7 @@ pub struct FunctionCache { } impl FunctionCache { - pub fn function(&self, function: &BNFunction, llil: &RegularLowLevelILFunction) -> Function { + pub fn function(&self, function: &BNFunction, llil: &LowLevelILRegularFunction) -> Function { let function_id = FunctionID::from(function); match self.cache.get(&function_id) { Some(function) => function.value().to_owned(), @@ -325,7 +323,7 @@ impl GUIDCache { pub fn function_guid<M: FunctionMutability>( &self, function: &BNFunction, - llil: &LowLevelILFunction<M, NonSSA<RegularNonSSA>>, + llil: &LowLevelILFunction<M, NonSSA>, ) -> FunctionGUID { let function_id = FunctionID::from(function); match self.cache.get(&function_id) { diff --git a/plugins/warp/src/lib.rs b/plugins/warp/src/lib.rs index 3d68b402..62af0102 100644 --- a/plugins/warp/src/lib.rs +++ b/plugins/warp/src/lib.rs @@ -10,9 +10,7 @@ use binaryninja::binary_view::BinaryViewExt; use binaryninja::confidence::MAX_CONFIDENCE; use binaryninja::function::{Function as BNFunction, NativeBlock}; use binaryninja::low_level_il::expression::{ExpressionHandler, LowLevelILExpressionKind}; -use binaryninja::low_level_il::function::{ - FunctionMutability, LowLevelILFunction, NonSSA, RegularNonSSA, -}; +use binaryninja::low_level_il::function::{FunctionMutability, LowLevelILFunction, NonSSA}; use binaryninja::low_level_il::instruction::{ InstructionHandler, LowLevelILInstruction, LowLevelILInstructionKind, }; @@ -46,7 +44,7 @@ pub fn user_signature_dir() -> PathBuf { pub fn build_function<M: FunctionMutability>( func: &BNFunction, - llil: &LowLevelILFunction<M, NonSSA<RegularNonSSA>>, + llil: &LowLevelILFunction<M, NonSSA>, ) -> Function { let bn_fn_ty = func.function_type(); Function { @@ -78,7 +76,7 @@ pub fn sorted_basic_blocks(func: &BNFunction) -> Vec<BNRef<BNBasicBlock<NativeBl pub fn function_guid<M: FunctionMutability>( func: &BNFunction, - llil: &LowLevelILFunction<M, NonSSA<RegularNonSSA>>, + llil: &LowLevelILFunction<M, NonSSA>, ) -> FunctionGUID { let basic_blocks = sorted_basic_blocks(func); let basic_block_guids = basic_blocks @@ -90,7 +88,7 @@ pub fn function_guid<M: FunctionMutability>( pub fn basic_block_guid<M: FunctionMutability>( basic_block: &BNBasicBlock<NativeBlock>, - llil: &LowLevelILFunction<M, NonSSA<RegularNonSSA>>, + llil: &LowLevelILFunction<M, NonSSA>, ) -> BasicBlockGUID { let func = basic_block.function(); let view = func.view(); @@ -98,7 +96,7 @@ pub fn basic_block_guid<M: FunctionMutability>( let max_instr_len = arch.max_instr_len(); // NOPs and useless moves are blacklisted to allow for hot-patchable functions. - let is_blacklisted_instr = |instr: &LowLevelILInstruction<M, NonSSA<RegularNonSSA>>| { + let is_blacklisted_instr = |instr: &LowLevelILInstruction<M, NonSSA>| { match instr.kind() { LowLevelILInstructionKind::Nop(_) => true, LowLevelILInstructionKind::SetReg(op) => { @@ -126,8 +124,8 @@ pub fn basic_block_guid<M: FunctionMutability>( } }; - let is_variant_instr = |instr: &LowLevelILInstruction<M, NonSSA<RegularNonSSA>>| { - let is_variant_expr = |expr: &LowLevelILExpressionKind<M, NonSSA<RegularNonSSA>>| { + let is_variant_instr = |instr: &LowLevelILInstruction<M, NonSSA>| { + let is_variant_expr = |expr: &LowLevelILExpressionKind<M, NonSSA>| { // TODO: Checking the section here is slow, we should gather all section ranges outside of this. match expr { LowLevelILExpressionKind::ConstPtr(op) diff --git a/plugins/warp/src/plugin/workflow.rs b/plugins/warp/src/plugin/workflow.rs index 9f7c4d0d..f5763116 100644 --- a/plugins/warp/src/plugin/workflow.rs +++ b/plugins/warp/src/plugin/workflow.rs @@ -3,7 +3,6 @@ use crate::matcher::cached_function_matcher; use binaryninja::background_task::BackgroundTask; use binaryninja::binary_view::{BinaryView, BinaryViewExt}; use binaryninja::command::Command; -use binaryninja::low_level_il::function::RegularNonSSA; use binaryninja::workflow::{Activity, AnalysisContext, Workflow}; use std::time::Instant; @@ -74,7 +73,7 @@ pub fn insert_workflow() { let guid_activity = |ctx: &AnalysisContext| { let function = ctx.function(); // TODO: Returning RegularNonSSA means we cant modify the il (the lifting code was written just for lifted il, that needs to be fixed) - if let Some(llil) = unsafe { ctx.llil_function::<RegularNonSSA>() } { + if let Some(llil) = unsafe { ctx.llil_function() } { cached_function_guid(&function, &llil); } }; diff --git a/rust/examples/workflow.rs b/rust/examples/workflow.rs index 2d8f0054..49560579 100644 --- a/rust/examples/workflow.rs +++ b/rust/examples/workflow.rs @@ -41,7 +41,7 @@ fn example_activity(analysis_context: &AnalysisContext) { } } } - analysis_context.set_lifted_il_function(&llil); + analysis_context.set_llil_function(&llil.finalized()); } } 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) } } |
