diff options
| -rw-r--r-- | rust/src/high_level_il/function.rs | 21 | ||||
| -rw-r--r-- | rust/src/high_level_il/instruction.rs | 425 | ||||
| -rw-r--r-- | rust/src/high_level_il/lift.rs | 6 | ||||
| -rw-r--r-- | rust/src/high_level_il/operation.rs | 94 | ||||
| -rw-r--r-- | rust/src/language_representation.rs | 12 | ||||
| -rw-r--r-- | rust/src/low_level_il/operation.rs | 2 | ||||
| -rw-r--r-- | rust/src/medium_level_il/block.rs | 2 | ||||
| -rw-r--r-- | rust/src/medium_level_il/function.rs | 18 | ||||
| -rw-r--r-- | rust/src/medium_level_il/instruction.rs | 592 | ||||
| -rw-r--r-- | rust/src/medium_level_il/lift.rs | 8 | ||||
| -rw-r--r-- | rust/src/medium_level_il/operation.rs | 97 | ||||
| -rw-r--r-- | rust/tests/high_level_il.rs | 7 | ||||
| -rw-r--r-- | rust/tests/language_representation.rs | 10 | ||||
| -rw-r--r-- | rust/tests/medium_level_il.rs | 48 |
14 files changed, 744 insertions, 598 deletions
diff --git a/rust/src/high_level_il/function.rs b/rust/src/high_level_il/function.rs index a65a244c..0a55470e 100644 --- a/rust/src/high_level_il/function.rs +++ b/rust/src/high_level_il/function.rs @@ -3,7 +3,9 @@ use std::hash::{Hash, Hasher}; use binaryninjacore_sys::*; -use super::{HighLevelILBlock, HighLevelILInstruction, HighLevelInstructionIndex}; +use super::{ + HighLevelExpressionIndex, HighLevelILBlock, HighLevelILInstruction, HighLevelInstructionIndex, +}; use crate::basic_block::BasicBlock; use crate::function::{Function, Location}; use crate::rc::{Array, Ref, RefCountable}; @@ -35,31 +37,34 @@ impl HighLevelILFunction { if index.0 >= self.instruction_count() { None } else { - Some(HighLevelILInstruction::new(self.to_owned(), index)) + Some(HighLevelILInstruction::from_instr_index( + self.to_owned(), + index, + )) } } pub fn instruction_from_expr_index( &self, - expr_index: HighLevelInstructionIndex, + expr_index: HighLevelExpressionIndex, ) -> Option<HighLevelILInstruction> { if expr_index.0 >= self.expression_count() { None } else { - Some(HighLevelILInstruction::new_expr( + Some(HighLevelILInstruction::from_expr_index( self.to_owned(), expr_index, )) } } - // TODO: This returns an expression index! - pub fn root_instruction_index(&self) -> HighLevelInstructionIndex { - HighLevelInstructionIndex(unsafe { BNGetHighLevelILRootExpr(self.handle) }) + pub fn root_expression_index(&self) -> HighLevelExpressionIndex { + HighLevelExpressionIndex(unsafe { BNGetHighLevelILRootExpr(self.handle) }) } pub fn root(&self) -> HighLevelILInstruction { - HighLevelILInstruction::new_expr(self.as_ast(), self.root_instruction_index()) + self.instruction_from_expr_index(self.root_expression_index()) + .expect("Invalid root expression index") } pub fn set_root(&self, new_root: &HighLevelILInstruction) { diff --git a/rust/src/high_level_il/instruction.rs b/rust/src/high_level_il/instruction.rs index 67225eea..e571354c 100644 --- a/rust/src/high_level_il/instruction.rs +++ b/rust/src/high_level_il/instruction.rs @@ -38,28 +38,76 @@ impl Display for HighLevelInstructionIndex { } } +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct HighLevelExpressionIndex(pub usize); + +impl HighLevelExpressionIndex { + pub fn next(&self) -> Self { + Self(self.0 + 1) + } +} + +impl From<usize> for HighLevelExpressionIndex { + fn from(index: usize) -> Self { + Self(index) + } +} + +impl From<u64> for HighLevelExpressionIndex { + fn from(index: u64) -> Self { + Self(index as usize) + } +} + +impl Display for HighLevelExpressionIndex { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_fmt(format_args!("{}", self.0)) + } +} + #[derive(Clone)] pub struct HighLevelILInstruction { pub function: Ref<HighLevelILFunction>, pub address: u64, - pub expr_index: HighLevelInstructionIndex, + pub instr_index: HighLevelInstructionIndex, + pub expr_index: HighLevelExpressionIndex, pub size: usize, pub kind: HighLevelILInstructionKind, } impl HighLevelILInstruction { - pub(crate) fn new( + pub(crate) fn from_instr_index( + function: Ref<HighLevelILFunction>, + instr_index: HighLevelInstructionIndex, + ) -> Self { + // Get the associated expression index for the top-level instruction. + let expr_index_raw = + unsafe { BNGetHighLevelILIndexForInstruction(function.handle, instr_index.0) }; + Self::new( + function, + instr_index, + HighLevelExpressionIndex(expr_index_raw), + ) + } + + pub(crate) fn from_expr_index( function: Ref<HighLevelILFunction>, - index: HighLevelInstructionIndex, + expr_index: HighLevelExpressionIndex, ) -> Self { - let expr_index = unsafe { BNGetHighLevelILIndexForInstruction(function.handle, index.0) }; - Self::new_expr(function, HighLevelInstructionIndex(expr_index)) + // Get the associated top-level instruction index for the expression. + let instr_index_raw = + unsafe { BNGetHighLevelILInstructionForExpr(function.handle, expr_index.0) }; + Self::new( + function, + HighLevelInstructionIndex(instr_index_raw), + expr_index, + ) } - // TODO: I need HighLevelILExpression YESTERDAY!!!! - pub(crate) fn new_expr( + pub(crate) fn new( function: Ref<HighLevelILFunction>, - expr_index: HighLevelInstructionIndex, + instr_index: HighLevelInstructionIndex, + expr_index: HighLevelExpressionIndex, ) -> Self { let op = unsafe { BNGetHighLevelILByIndex(function.handle, expr_index.0, function.full_ast) }; @@ -76,234 +124,234 @@ impl HighLevelILInstruction { HLIL_FORCE_VER | HLIL_FORCE_VER_SSA | HLIL_ASSERT | HLIL_ASSERT_SSA => Op::Undef, HLIL_UNIMPL => Op::Unimpl, HLIL_ADC => Op::Adc(BinaryOpCarry { - left: op.operands[0] as usize, - right: op.operands[1] as usize, - carry: op.operands[2] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), + carry: HighLevelExpressionIndex::from(op.operands[2]), }), HLIL_SBB => Op::Sbb(BinaryOpCarry { - left: op.operands[0] as usize, - right: op.operands[1] as usize, - carry: op.operands[2] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), + carry: HighLevelExpressionIndex::from(op.operands[2]), }), HLIL_RLC => Op::Rlc(BinaryOpCarry { - left: op.operands[0] as usize, - right: op.operands[1] as usize, - carry: op.operands[2] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), + carry: HighLevelExpressionIndex::from(op.operands[2]), }), HLIL_RRC => Op::Rrc(BinaryOpCarry { - left: op.operands[0] as usize, - right: op.operands[1] as usize, - carry: op.operands[2] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), + carry: HighLevelExpressionIndex::from(op.operands[2]), }), HLIL_ADD => Op::Add(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_SUB => Op::Sub(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_AND => Op::And(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_OR => Op::Or(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_XOR => Op::Xor(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_LSL => Op::Lsl(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_LSR => Op::Lsr(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_ASR => Op::Asr(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_ROL => Op::Rol(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_ROR => Op::Ror(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_MUL => Op::Mul(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_MULU_DP => Op::MuluDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_MULS_DP => Op::MulsDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_DIVU => Op::Divu(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_DIVU_DP => Op::DivuDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_DIVS => Op::Divs(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_DIVS_DP => Op::DivsDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_MODU => Op::Modu(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_MODU_DP => Op::ModuDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_MODS => Op::Mods(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_MODS_DP => Op::ModsDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_CMP_E => Op::CmpE(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_CMP_NE => Op::CmpNe(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_CMP_SLT => Op::CmpSlt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_CMP_ULT => Op::CmpUlt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_CMP_SLE => Op::CmpSle(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_CMP_ULE => Op::CmpUle(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_CMP_SGE => Op::CmpSge(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_CMP_UGE => Op::CmpUge(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_CMP_SGT => Op::CmpSgt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_CMP_UGT => Op::CmpUgt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_TEST_BIT => Op::TestBit(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_ADD_OVERFLOW => Op::AddOverflow(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FADD => Op::Fadd(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FSUB => Op::Fsub(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FMUL => Op::Fmul(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FDIV => Op::Fdiv(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FCMP_E => Op::FcmpE(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FCMP_NE => Op::FcmpNe(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FCMP_LT => Op::FcmpLt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FCMP_LE => Op::FcmpLe(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FCMP_GE => Op::FcmpGe(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FCMP_GT => Op::FcmpGt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FCMP_O => Op::FcmpO(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_FCMP_UO => Op::FcmpUo(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_ARRAY_INDEX => Op::ArrayIndex(ArrayIndex { - src: op.operands[0] as usize, - index: op.operands[1] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), + index: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_ARRAY_INDEX_SSA => Op::ArrayIndexSsa(ArrayIndexSsa { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), src_memory: op.operands[1], - index: op.operands[2] as usize, + index: HighLevelExpressionIndex::from(op.operands[2]), }), HLIL_ASSIGN => Op::Assign(Assign { - dest: op.operands[0] as usize, - src: op.operands[1] as usize, + dest: HighLevelExpressionIndex::from(op.operands[0]), + src: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_ASSIGN_MEM_SSA => Op::AssignMemSsa(AssignMemSsa { - dest: op.operands[0] as usize, + dest: HighLevelExpressionIndex::from(op.operands[0]), dest_memory: op.operands[1], - src: op.operands[2] as usize, + src: HighLevelExpressionIndex::from(op.operands[2]), src_memory: op.operands[3], }), HLIL_ASSIGN_UNPACK => Op::AssignUnpack(AssignUnpack { num_dests: op.operands[0] as usize, first_dest: op.operands[1] as usize, - src: op.operands[2] as usize, + src: HighLevelExpressionIndex::from(op.operands[2]), }), HLIL_ASSIGN_UNPACK_MEM_SSA => Op::AssignUnpackMemSsa(AssignUnpackMemSsa { num_dests: op.operands[0] as usize, first_dest: op.operands[1] as usize, dest_memory: op.operands[2], - src: op.operands[3] as usize, + src: HighLevelExpressionIndex::from(op.operands[3]), src_memory: op.operands[4], }), HLIL_BLOCK => Op::Block(Block { @@ -311,17 +359,17 @@ impl HighLevelILInstruction { first_param: op.operands[1] as usize, }), HLIL_CALL => Op::Call(Call { - dest: op.operands[0] as usize, + dest: HighLevelExpressionIndex::from(op.operands[0]), num_params: op.operands[1] as usize, first_param: op.operands[2] as usize, }), HLIL_TAILCALL => Op::Tailcall(Call { - dest: op.operands[0] as usize, + dest: HighLevelExpressionIndex::from(op.operands[0]), num_params: op.operands[1] as usize, first_param: op.operands[2] as usize, }), HLIL_CALL_SSA => Op::CallSsa(CallSsa { - dest: op.operands[0] as usize, + dest: HighLevelExpressionIndex::from(op.operands[0]), num_params: op.operands[1] as usize, first_param: op.operands[2] as usize, dest_memory: op.operands[3], @@ -330,7 +378,7 @@ impl HighLevelILInstruction { HLIL_CASE => Op::Case(Case { num_values: op.operands[0] as usize, first_value: op.operands[1] as usize, - body: op.operands[2] as usize, + body: HighLevelExpressionIndex::from(op.operands[2]), }), HLIL_CONST => Op::Const(Const { constant: op.operands[0], @@ -347,70 +395,70 @@ impl HighLevelILInstruction { size: op.size, }), HLIL_DEREF => Op::Deref(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_ADDRESS_OF => Op::AddressOf(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_NEG => Op::Neg(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_NOT => Op::Not(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_SX => Op::Sx(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_ZX => Op::Zx(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_LOW_PART => Op::LowPart(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_BOOL_TO_INT => Op::BoolToInt(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_UNIMPL_MEM => Op::UnimplMem(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_FSQRT => Op::Fsqrt(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_FNEG => Op::Fneg(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_FABS => Op::Fabs(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_FLOAT_TO_INT => Op::FloatToInt(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_INT_TO_FLOAT => Op::IntToFloat(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_FLOAT_CONV => Op::FloatConv(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_ROUND_TO_INT => Op::RoundToInt(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_FLOOR => Op::Floor(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_CEIL => Op::Ceil(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_FTRUNC => Op::Ftrunc(UnaryOp { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_DEREF_FIELD_SSA => Op::DerefFieldSsa(DerefFieldSsa { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), src_memory: op.operands[1], offset: op.operands[2], member_index: get_member_index(op.operands[3]), }), HLIL_DEREF_SSA => Op::DerefSsa(DerefSsa { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), src_memory: op.operands[1], }), HLIL_EXTERN_PTR => Op::ExternPtr(ExternPtr { @@ -421,17 +469,17 @@ impl HighLevelILInstruction { constant: get_float(op.operands[0], op.size), }), HLIL_FOR => Op::For(ForLoop { - init: op.operands[0] as usize, - condition: op.operands[1] as usize, - update: op.operands[2] as usize, - body: op.operands[3] as usize, + init: HighLevelExpressionIndex::from(op.operands[0]), + condition: HighLevelExpressionIndex::from(op.operands[1]), + update: HighLevelExpressionIndex::from(op.operands[2]), + body: HighLevelExpressionIndex::from(op.operands[3]), }), HLIL_FOR_SSA => Op::ForSsa(ForLoopSsa { - init: op.operands[0] as usize, - condition_phi: op.operands[1] as usize, - condition: op.operands[2] as usize, - update: op.operands[3] as usize, - body: op.operands[4] as usize, + init: HighLevelExpressionIndex::from(op.operands[0]), + condition_phi: HighLevelExpressionIndex::from(op.operands[1]), + condition: HighLevelExpressionIndex::from(op.operands[2]), + update: HighLevelExpressionIndex::from(op.operands[3]), + body: HighLevelExpressionIndex::from(op.operands[4]), }), HLIL_GOTO => Op::Goto(Label { target: op.operands[0], @@ -440,9 +488,9 @@ impl HighLevelILInstruction { target: op.operands[0], }), HLIL_IF => Op::If(If { - condition: op.operands[0] as usize, - cond_true: op.operands[1] as usize, - cond_false: op.operands[2] as usize, + condition: HighLevelExpressionIndex::from(op.operands[0]), + cond_true: HighLevelExpressionIndex::from(op.operands[1]), + cond_false: HighLevelExpressionIndex::from(op.operands[2]), }), HLIL_INTRINSIC => Op::Intrinsic(Intrinsic { intrinsic: op.operands[0] as u32, @@ -457,7 +505,7 @@ impl HighLevelILInstruction { src_memory: op.operands[4], }), HLIL_JUMP => Op::Jump(Jump { - dest: op.operands[0] as usize, + dest: HighLevelExpressionIndex::from(op.operands[0]), }), HLIL_MEM_PHI => Op::MemPhi(MemPhi { dest: op.operands[0], @@ -469,22 +517,22 @@ impl HighLevelILInstruction { first_src: op.operands[1] as usize, }), HLIL_SPLIT => Op::Split(Split { - high: op.operands[0] as usize, - low: op.operands[1] as usize, + high: HighLevelExpressionIndex::from(op.operands[0]), + low: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_STRUCT_FIELD => Op::StructField(StructField { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), offset: op.operands[1], member_index: get_member_index(op.operands[2]), }), HLIL_DEREF_FIELD => Op::DerefField(StructField { - src: op.operands[0] as usize, + src: HighLevelExpressionIndex::from(op.operands[0]), offset: op.operands[1], member_index: get_member_index(op.operands[2]), }), HLIL_SWITCH => Op::Switch(Switch { - condition: op.operands[0] as usize, - default: op.operands[1] as usize, + condition: HighLevelExpressionIndex::from(op.operands[0]), + default: HighLevelExpressionIndex::from(op.operands[1]), num_cases: op.operands[2] as usize, first_case: op.operands[3] as usize, }), @@ -509,11 +557,11 @@ impl HighLevelILInstruction { }), HLIL_VAR_INIT => Op::VarInit(VarInit { dest: get_var(op.operands[0]), - src: op.operands[1] as usize, + src: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_VAR_INIT_SSA => Op::VarInitSsa(VarInitSsa { dest: get_var_ssa((op.operands[0], op.operands[1] as usize)), - src: op.operands[2] as usize, + src: HighLevelExpressionIndex::from(op.operands[2]), }), HLIL_VAR_PHI => Op::VarPhi(VarPhi { dest: get_var_ssa((op.operands[0], op.operands[1] as usize)), @@ -524,27 +572,28 @@ impl HighLevelILInstruction { var: get_var_ssa((op.operands[0], op.operands[1] as usize)), }), HLIL_WHILE => Op::While(While { - condition: op.operands[0] as usize, - body: op.operands[1] as usize, + condition: HighLevelExpressionIndex::from(op.operands[0]), + body: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_DO_WHILE => Op::DoWhile(While { - body: op.operands[0] as usize, - condition: op.operands[1] as usize, + body: HighLevelExpressionIndex::from(op.operands[0]), + condition: HighLevelExpressionIndex::from(op.operands[1]), }), HLIL_WHILE_SSA => Op::WhileSsa(WhileSsa { - condition_phi: op.operands[0] as usize, - condition: op.operands[1] as usize, - body: op.operands[2] as usize, + condition_phi: HighLevelExpressionIndex::from(op.operands[0]), + condition: HighLevelExpressionIndex::from(op.operands[1]), + body: HighLevelExpressionIndex::from(op.operands[2]), }), HLIL_DO_WHILE_SSA => Op::DoWhileSsa(WhileSsa { - condition_phi: op.operands[0] as usize, - condition: op.operands[1] as usize, - body: op.operands[2] as usize, + condition_phi: HighLevelExpressionIndex::from(op.operands[0]), + condition: HighLevelExpressionIndex::from(op.operands[1]), + body: HighLevelExpressionIndex::from(op.operands[2]), }), }; Self { function, address: op.address, + instr_index, expr_index, size: op.size, kind, @@ -578,7 +627,7 @@ impl HighLevelILInstruction { fn get_expr_list(&self, operand_idx: usize) -> Vec<HighLevelILInstruction> { self.get_operand_list(operand_idx) .into_iter() - .map(|val| HighLevelInstructionIndex(val as usize)) + .map(|val| HighLevelExpressionIndex(val as usize)) .filter_map(|idx| self.function.instruction_from_expr_index(idx)) .collect() } @@ -882,6 +931,7 @@ impl HighLevelILInstruction { HighLevelILLiftedInstruction { function: self.function.clone(), address: self.address, + instr_index: self.instr_index, expr_index: self.expr_index, size: self.size, kind, @@ -932,18 +982,11 @@ impl HighLevelILInstruction { SSAVariable::new(variable, version) } - fn lift_operand(&self, expr_idx: usize) -> Box<HighLevelILLiftedInstruction> { - // TODO: UGH, if your gonna call it expr_idx, call the instruction and expression!!!!! - // TODO: We dont even need to say instruction in the type! - // TODO: IF you want to have an instruction type, there needs to be a separate expression type - // TODO: See the lowlevelil module. - let expr_idx_is_really_instr_idx = HighLevelInstructionIndex(expr_idx); - // TODO: Ugh, this is so dumb..... i want HighLevelILLiftedExpression yesterday!!! - let operand_instr = self - .function - .instruction_from_expr_index(expr_idx_is_really_instr_idx) - .unwrap(); - // TODO: Why box it here??!?!?! insane. + fn lift_operand( + &self, + expr_idx: HighLevelExpressionIndex, + ) -> Box<HighLevelILLiftedInstruction> { + let operand_instr = self.function.instruction_from_expr_index(expr_idx).unwrap(); Box::new(operand_instr.lift()) } @@ -1024,7 +1067,9 @@ unsafe impl CoreArrayProviderInner for HighLevelILInstruction { } unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> { - Self::new(context.clone(), HighLevelInstructionIndex(*raw)) + context + .instruction_from_index(HighLevelInstructionIndex(*raw)) + .unwrap() } } diff --git a/rust/src/high_level_il/lift.rs b/rust/src/high_level_il/lift.rs index fd0b9398..ab04f44b 100644 --- a/rust/src/high_level_il/lift.rs +++ b/rust/src/high_level_il/lift.rs @@ -1,5 +1,5 @@ use super::operation::*; -use super::{HighLevelILFunction, HighLevelInstructionIndex}; +use super::{HighLevelExpressionIndex, HighLevelILFunction, HighLevelInstructionIndex}; use std::fmt::{Debug, Formatter}; use crate::architecture::CoreIntrinsic; @@ -30,8 +30,8 @@ pub enum HighLevelILLiftedOperand { pub struct HighLevelILLiftedInstruction { pub function: Ref<HighLevelILFunction>, pub address: u64, - // TODO: Please i need expression - pub expr_index: HighLevelInstructionIndex, + pub instr_index: HighLevelInstructionIndex, + pub expr_index: HighLevelExpressionIndex, pub size: usize, pub kind: HighLevelILLiftedInstructionKind, } diff --git a/rust/src/high_level_il/operation.rs b/rust/src/high_level_il/operation.rs index 9c218227..702ec38a 100644 --- a/rust/src/high_level_il/operation.rs +++ b/rust/src/high_level_il/operation.rs @@ -2,7 +2,7 @@ use binaryninjacore_sys::*; use core::ffi; use std::fmt::{Debug, Formatter}; -use super::HighLevelILLiftedInstruction; +use super::{HighLevelExpressionIndex, HighLevelILLiftedInstruction}; use crate::architecture::CoreIntrinsic; use crate::function::Function; use crate::rc::Ref; @@ -44,9 +44,9 @@ impl Debug for GotoLabel { // ADC, SBB, RLC, RRC #[derive(Debug, Copy, Clone)] pub struct BinaryOpCarry { - pub left: usize, - pub right: usize, - pub carry: usize, + pub left: HighLevelExpressionIndex, + pub right: HighLevelExpressionIndex, + pub carry: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedBinaryOpCarry { @@ -58,8 +58,8 @@ pub struct LiftedBinaryOpCarry { // ADD, SUB, AND, OR, XOR, LSL, LSR, ASR, ROL, ROR, MUL, MULU_DP, MULS_DP, DIVU, DIVU_DP, DIVS, DIVS_DP, MODU, MODU_DP, MODS, MODS_DP, CMP_E, CMP_NE, CMP_SLT, CMP_ULT, CMP_SLE, CMP_ULE, CMP_SGE, CMP_UGE, CMP_SGT, CMP_UGT, TEST_BIT, ADD_OVERFLOW, FADD, FSUB, FMUL, FDIV, FCMP_E, FCMP_NE, FCMP_LT, FCMP_LE, FCMP_GE, FCMP_GT, FCMP_O, FCMP_UO #[derive(Debug, Copy, Clone)] pub struct BinaryOp { - pub left: usize, - pub right: usize, + pub left: HighLevelExpressionIndex, + pub right: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedBinaryOp { @@ -70,8 +70,8 @@ pub struct LiftedBinaryOp { // ARRAY_INDEX #[derive(Debug, Copy, Clone)] pub struct ArrayIndex { - pub src: usize, - pub index: usize, + pub src: HighLevelExpressionIndex, + pub index: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedArrayIndex { @@ -82,9 +82,9 @@ pub struct LiftedArrayIndex { // ARRAY_INDEX_SSA #[derive(Debug, Copy, Clone)] pub struct ArrayIndexSsa { - pub src: usize, + pub src: HighLevelExpressionIndex, pub src_memory: u64, - pub index: usize, + pub index: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedArrayIndexSsa { @@ -96,8 +96,8 @@ pub struct LiftedArrayIndexSsa { // ASSIGN #[derive(Debug, Copy, Clone)] pub struct Assign { - pub dest: usize, - pub src: usize, + pub dest: HighLevelExpressionIndex, + pub src: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedAssign { @@ -108,9 +108,9 @@ pub struct LiftedAssign { // ASSIGN_MEM_SSA #[derive(Debug, Copy, Clone)] pub struct AssignMemSsa { - pub dest: usize, + pub dest: HighLevelExpressionIndex, pub dest_memory: u64, - pub src: usize, + pub src: HighLevelExpressionIndex, pub src_memory: u64, } #[derive(Clone, Debug, PartialEq)] @@ -126,7 +126,7 @@ pub struct LiftedAssignMemSsa { pub struct AssignUnpack { pub first_dest: usize, pub num_dests: usize, - pub src: usize, + pub src: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedAssignUnpack { @@ -140,7 +140,7 @@ pub struct AssignUnpackMemSsa { pub first_dest: usize, pub num_dests: usize, pub dest_memory: u64, - pub src: usize, + pub src: HighLevelExpressionIndex, pub src_memory: u64, } #[derive(Clone, Debug, PartialEq)] @@ -165,7 +165,7 @@ pub struct LiftedBlock { // CALL, TAILCALL #[derive(Debug, Copy, Clone)] pub struct Call { - pub dest: usize, + pub dest: HighLevelExpressionIndex, pub first_param: usize, pub num_params: usize, } @@ -178,7 +178,7 @@ pub struct LiftedCall { // CALL_SSA #[derive(Debug, Copy, Clone)] pub struct CallSsa { - pub dest: usize, + pub dest: HighLevelExpressionIndex, pub first_param: usize, pub num_params: usize, pub dest_memory: u64, @@ -197,7 +197,7 @@ pub struct LiftedCallSsa { pub struct Case { pub first_value: usize, pub num_values: usize, - pub body: usize, + pub body: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedCase { @@ -227,7 +227,7 @@ pub struct LiftedConstData { // DEREF, ADDRESS_OF, NEG, NOT, SX, ZX, LOW_PART, BOOL_TO_INT, UNIMPL_MEM, FSQRT, FNEG, FABS, FLOAT_TO_INT, INT_TO_FLOAT, FLOAT_CONV, ROUND_TO_INT, FLOOR, CEIL, FTRUNC #[derive(Debug, Copy, Clone)] pub struct UnaryOp { - pub src: usize, + pub src: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedUnaryOp { @@ -237,7 +237,7 @@ pub struct LiftedUnaryOp { // DEREF_FIELD_SSA #[derive(Debug, Copy, Clone)] pub struct DerefFieldSsa { - pub src: usize, + pub src: HighLevelExpressionIndex, pub src_memory: u64, pub offset: u64, pub member_index: Option<usize>, @@ -254,7 +254,7 @@ pub struct LiftedDerefFieldSsa { // DEREF_SSA #[derive(Debug, Copy, Clone)] pub struct DerefSsa { - pub src: usize, + pub src: HighLevelExpressionIndex, pub src_memory: u64, } @@ -280,10 +280,10 @@ pub struct FloatConst { // FOR #[derive(Debug, Copy, Clone)] pub struct ForLoop { - pub init: usize, - pub condition: usize, - pub update: usize, - pub body: usize, + pub init: HighLevelExpressionIndex, + pub condition: HighLevelExpressionIndex, + pub update: HighLevelExpressionIndex, + pub body: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] @@ -297,11 +297,11 @@ pub struct LiftedForLoop { // FOR_SSA #[derive(Debug, Copy, Clone)] pub struct ForLoopSsa { - pub init: usize, - pub condition_phi: usize, - pub condition: usize, - pub update: usize, - pub body: usize, + pub init: HighLevelExpressionIndex, + pub condition_phi: HighLevelExpressionIndex, + pub condition: HighLevelExpressionIndex, + pub update: HighLevelExpressionIndex, + pub body: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedForLoopSsa { @@ -335,9 +335,9 @@ impl LiftedLabel { // IF #[derive(Debug, Copy, Clone)] pub struct If { - pub condition: usize, - pub cond_true: usize, - pub cond_false: usize, + pub condition: HighLevelExpressionIndex, + pub cond_true: HighLevelExpressionIndex, + pub cond_false: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedIf { @@ -379,7 +379,7 @@ pub struct LiftedIntrinsicSsa { // JUMP #[derive(Debug, Copy, Clone)] pub struct Jump { - pub dest: usize, + pub dest: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedJump { @@ -413,8 +413,8 @@ pub struct LiftedRet { // SPLIT #[derive(Debug, Copy, Clone)] pub struct Split { - pub high: usize, - pub low: usize, + pub high: HighLevelExpressionIndex, + pub low: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSplit { @@ -425,7 +425,7 @@ pub struct LiftedSplit { // STRUCT_FIELD, DEREF_FIELD #[derive(Debug, Copy, Clone)] pub struct StructField { - pub src: usize, + pub src: HighLevelExpressionIndex, pub offset: u64, pub member_index: Option<usize>, } @@ -439,8 +439,8 @@ pub struct LiftedStructField { // SWITCH #[derive(Debug, Copy, Clone)] pub struct Switch { - pub condition: usize, - pub default: usize, + pub condition: HighLevelExpressionIndex, + pub default: HighLevelExpressionIndex, pub first_case: usize, pub num_cases: usize, } @@ -493,7 +493,7 @@ pub struct Var { #[derive(Debug, Copy, Clone)] pub struct VarInit { pub dest: Variable, - pub src: usize, + pub src: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedVarInit { @@ -505,7 +505,7 @@ pub struct LiftedVarInit { #[derive(Debug, Copy, Clone)] pub struct VarInitSsa { pub dest: SSAVariable, - pub src: usize, + pub src: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedVarInitSsa { @@ -535,8 +535,8 @@ pub struct VarSsa { // WHILE, DO_WHILE #[derive(Debug, Copy, Clone)] pub struct While { - pub condition: usize, - pub body: usize, + pub condition: HighLevelExpressionIndex, + pub body: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedWhile { @@ -547,9 +547,9 @@ pub struct LiftedWhile { // WHILE_SSA, DO_WHILE_SSA #[derive(Debug, Copy, Clone)] pub struct WhileSsa { - pub condition_phi: usize, - pub condition: usize, - pub body: usize, + pub condition_phi: HighLevelExpressionIndex, + pub condition: HighLevelExpressionIndex, + pub body: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedWhileSsa { diff --git a/rust/src/language_representation.rs b/rust/src/language_representation.rs index 536203fe..6008ec0c 100644 --- a/rust/src/language_representation.rs +++ b/rust/src/language_representation.rs @@ -10,7 +10,7 @@ use crate::binary_view::BinaryView; use crate::disassembly::{DisassemblySettings, DisassemblyTextLine}; use crate::function::{Function, HighlightColor}; use crate::high_level_il::token_emitter::HighLevelILTokenEmitter; -use crate::high_level_il::{HighLevelILFunction, HighLevelInstructionIndex}; +use crate::high_level_il::{HighLevelExpressionIndex, HighLevelILFunction}; use crate::line_formatter::CoreLineFormatter; use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref, RefCountable}; use crate::string::{BnString, IntoCStr}; @@ -57,7 +57,7 @@ pub trait LanguageRepresentationFunction: Send + Sync { fn expr_text( &self, il: &HighLevelILFunction, - expr_index: HighLevelInstructionIndex, + expr_index: HighLevelExpressionIndex, tokens: &HighLevelILTokenEmitter, settings: &DisassemblySettings, as_full_ast: bool, @@ -68,14 +68,14 @@ pub trait LanguageRepresentationFunction: Send + Sync { fn begin_lines( &self, il: &HighLevelILFunction, - expr_index: HighLevelInstructionIndex, + expr_index: HighLevelExpressionIndex, tokens: &HighLevelILTokenEmitter, ); fn end_lines( &self, il: &HighLevelILFunction, - expr_index: HighLevelInstructionIndex, + expr_index: HighLevelExpressionIndex, tokens: &HighLevelILTokenEmitter, ); @@ -281,7 +281,7 @@ impl CoreLanguageRepresentationFunction { pub fn expr_text( &self, il: &HighLevelILFunction, - expr_index: HighLevelInstructionIndex, + expr_index: HighLevelExpressionIndex, settings: &DisassemblySettings, as_full_ast: bool, precedence: OperatorPrecedence, @@ -306,7 +306,7 @@ impl CoreLanguageRepresentationFunction { pub fn linear_lines( &self, il: &HighLevelILFunction, - expr_index: HighLevelInstructionIndex, + expr_index: HighLevelExpressionIndex, settings: &DisassemblySettings, as_full_ast: bool, ) -> Array<DisassemblyTextLine> { diff --git a/rust/src/low_level_il/operation.rs b/rust/src/low_level_il/operation.rs index bc8e579e..0db23c82 100644 --- a/rust/src/low_level_il/operation.rs +++ b/rust/src/low_level_il/operation.rs @@ -86,7 +86,7 @@ where self.op.operands[operand_idx] as usize, ) }; - PossibleValueSet::from_owned_raw(raw_pvs) + PossibleValueSet::from_owned_core_raw(raw_pvs) } } diff --git a/rust/src/medium_level_il/block.rs b/rust/src/medium_level_il/block.rs index 1fcd51ca..162b19b0 100644 --- a/rust/src/medium_level_il/block.rs +++ b/rust/src/medium_level_il/block.rs @@ -14,8 +14,6 @@ impl BlockContext for MediumLevelILBlock { type Iter = MediumLevelILBlockIter; fn start(&self, block: &BasicBlock<Self>) -> MediumLevelILInstruction { - // TODO: instruction_from_index says that it is not mapped and will do the call - // TODO: What if this IS already MAPPED!?!?!? self.function .instruction_from_index(block.start_index()) .unwrap() diff --git a/rust/src/medium_level_il/function.rs b/rust/src/medium_level_il/function.rs index bdbe3159..8751111b 100644 --- a/rust/src/medium_level_il/function.rs +++ b/rust/src/medium_level_il/function.rs @@ -2,7 +2,10 @@ use binaryninjacore_sys::*; use std::fmt::{Debug, Formatter}; use std::hash::{Hash, Hasher}; -use super::{MediumLevelILBlock, MediumLevelILInstruction, MediumLevelInstructionIndex}; +use super::{ + MediumLevelExpressionIndex, MediumLevelILBlock, MediumLevelILInstruction, + MediumLevelInstructionIndex, +}; use crate::architecture::CoreArchitecture; use crate::basic_block::BasicBlock; use crate::confidence::Conf; @@ -33,7 +36,7 @@ impl MediumLevelILFunction { } pub fn instruction_at<L: Into<Location>>(&self, loc: L) -> Option<MediumLevelILInstruction> { - Some(MediumLevelILInstruction::new( + Some(MediumLevelILInstruction::from_instr_index( self.to_owned(), self.instruction_index_at(loc)?, )) @@ -64,18 +67,21 @@ impl MediumLevelILFunction { if index.0 >= self.instruction_count() { None } else { - Some(MediumLevelILInstruction::new(self.to_owned(), index)) + Some(MediumLevelILInstruction::from_instr_index( + self.to_owned(), + index, + )) } } pub fn instruction_from_expr_index( &self, - expr_index: MediumLevelInstructionIndex, + expr_index: MediumLevelExpressionIndex, ) -> Option<MediumLevelILInstruction> { if expr_index.0 >= self.expression_count() { None } else { - Some(MediumLevelILInstruction::new_expr( + Some(MediumLevelILInstruction::from_expr_index( self.to_owned(), expr_index, )) @@ -402,7 +408,7 @@ impl MediumLevelILFunction { unsafe { BNMediumLevelILSetCurrentAddress(self.handle, arch, location.addr) } } - /// Returns the [`BasicBlock`] at the given instruction `index`. + /// Returns the [`BasicBlock`] at the given instruction `index`. Function must be finalized. /// /// You can also retrieve this using [`MediumLevelILInstruction::basic_block`]. pub fn basic_block_containing_index( diff --git a/rust/src/medium_level_il/instruction.rs b/rust/src/medium_level_il/instruction.rs index 70d69b7f..3af9e424 100644 --- a/rust/src/medium_level_il/instruction.rs +++ b/rust/src/medium_level_il/instruction.rs @@ -41,30 +41,76 @@ impl Display for MediumLevelInstructionIndex { } } +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct MediumLevelExpressionIndex(pub usize); + +impl MediumLevelExpressionIndex { + pub fn next(&self) -> Self { + Self(self.0 + 1) + } +} + +impl From<usize> for MediumLevelExpressionIndex { + fn from(index: usize) -> Self { + Self(index) + } +} + +impl From<u64> for MediumLevelExpressionIndex { + fn from(index: u64) -> Self { + Self(index as usize) + } +} + +impl Display for MediumLevelExpressionIndex { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_fmt(format_args!("{}", self.0)) + } +} + #[derive(Clone)] pub struct MediumLevelILInstruction { pub function: Ref<MediumLevelILFunction>, pub address: u64, - // TODO; Because this structure is incorrectly named instruction, we want to make it clear that we actually have the expression index. - pub expr_index: MediumLevelInstructionIndex, + pub instr_index: MediumLevelInstructionIndex, + pub expr_index: MediumLevelExpressionIndex, pub size: usize, pub kind: MediumLevelILInstructionKind, } impl MediumLevelILInstruction { - pub(crate) fn new( + pub(crate) fn from_instr_index( function: Ref<MediumLevelILFunction>, - index: MediumLevelInstructionIndex, + instr_index: MediumLevelInstructionIndex, ) -> Self { - // TODO: If op.sourceOperation == BN_INVALID_OPERAND && op.operation == MLIL_NOP return None - let expr_index = unsafe { BNGetMediumLevelILIndexForInstruction(function.handle, index.0) }; - Self::new_expr(function, MediumLevelInstructionIndex(expr_index)) + // Get the associated expression index for the top-level instruction. + let expr_index_raw = + unsafe { BNGetMediumLevelILIndexForInstruction(function.handle, instr_index.0) }; + Self::new( + function, + instr_index, + MediumLevelExpressionIndex(expr_index_raw), + ) + } + + pub(crate) fn from_expr_index( + function: Ref<MediumLevelILFunction>, + expr_index: MediumLevelExpressionIndex, + ) -> Self { + // Get the associated top-level instruction index for the expression. + let instr_index_raw = + unsafe { BNGetMediumLevelILInstructionForExpr(function.handle, expr_index.0) }; + Self::new( + function, + MediumLevelInstructionIndex(instr_index_raw), + expr_index, + ) } - // TODO: I need MediumLevelILExpression YESTERDAY!!!! - pub(crate) fn new_expr( + pub(crate) fn new( function: Ref<MediumLevelILFunction>, - expr_index: MediumLevelInstructionIndex, + instr_index: MediumLevelInstructionIndex, + expr_index: MediumLevelExpressionIndex, ) -> Self { // TODO: If op.sourceOperation == BN_INVALID_OPERAND && op.operation == MLIL_NOP return None let op = unsafe { BNGetMediumLevelILByIndex(function.handle, expr_index.0) }; @@ -78,7 +124,7 @@ impl MediumLevelILInstruction { MLIL_ASSERT | MLIL_ASSERT_SSA | MLIL_FORCE_VER | MLIL_FORCE_VER_SSA => Op::Undef, MLIL_UNIMPL => Op::Unimpl, MLIL_IF => Op::If(MediumLevelILOperationIf { - condition: op.operands[0] as usize, + condition: MediumLevelExpressionIndex::from(op.operands[0]), dest_true: MediumLevelInstructionIndex(op.operands[1] as usize), dest_false: MediumLevelInstructionIndex(op.operands[2] as usize), }), @@ -104,35 +150,35 @@ impl MediumLevelILInstruction { size: op.size, }), MLIL_JUMP => Op::Jump(Jump { - dest: op.operands[0] as usize, + dest: MediumLevelExpressionIndex::from(op.operands[0]), }), MLIL_RET_HINT => Op::RetHint(Jump { - dest: op.operands[0] as usize, + dest: MediumLevelExpressionIndex::from(op.operands[0]), }), MLIL_STORE_SSA => Op::StoreSsa(StoreSsa { - dest: op.operands[0] as usize, + dest: MediumLevelExpressionIndex::from(op.operands[0]), dest_memory: op.operands[1], src_memory: op.operands[2], - src: op.operands[3] as usize, + src: MediumLevelExpressionIndex::from(op.operands[3]), }), MLIL_STORE_STRUCT_SSA => Op::StoreStructSsa(StoreStructSsa { - dest: op.operands[0] as usize, + dest: MediumLevelExpressionIndex::from(op.operands[0]), offset: op.operands[1], dest_memory: op.operands[2], src_memory: op.operands[3], - src: op.operands[4] as usize, + src: MediumLevelExpressionIndex::from(op.operands[4]), }), MLIL_STORE_STRUCT => Op::StoreStruct(StoreStruct { - dest: op.operands[0] as usize, + dest: MediumLevelExpressionIndex::from(op.operands[0]), offset: op.operands[1], - src: op.operands[2] as usize, + src: MediumLevelExpressionIndex::from(op.operands[2]), }), MLIL_STORE => Op::Store(Store { - dest: op.operands[0] as usize, - src: op.operands[1] as usize, + dest: MediumLevelExpressionIndex::from(op.operands[0]), + src: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_JUMP_TO => Op::JumpTo(JumpTo { - dest: op.operands[0] as usize, + dest: MediumLevelExpressionIndex::from(op.operands[0]), num_operands: op.operands[1] as usize, first_operand: op.operands[2] as usize, }), @@ -145,11 +191,11 @@ impl MediumLevelILInstruction { MLIL_SET_VAR_FIELD => Op::SetVarField(SetVarField { dest: get_var(op.operands[0]), offset: op.operands[1], - src: op.operands[2] as usize, + src: MediumLevelExpressionIndex::from(op.operands[2]), }), MLIL_SET_VAR => Op::SetVar(SetVar { dest: get_var(op.operands[0]), - src: op.operands[1] as usize, + src: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FREE_VAR_SLOT_SSA => Op::FreeVarSlotSsa(FreeVarSlotSsa { dest: get_var_ssa(op.operands[0], op.operands[1] as usize), @@ -159,22 +205,22 @@ impl MediumLevelILInstruction { dest: get_var_ssa(op.operands[0], op.operands[1] as usize), prev: get_var_ssa(op.operands[0], op.operands[2] as usize), offset: op.operands[3], - src: op.operands[4] as usize, + src: MediumLevelExpressionIndex::from(op.operands[4]), }), MLIL_SET_VAR_ALIASED_FIELD => Op::SetVarAliasedField(SetVarSsaField { dest: get_var_ssa(op.operands[0], op.operands[1] as usize), prev: get_var_ssa(op.operands[0], op.operands[2] as usize), offset: op.operands[3], - src: op.operands[4] as usize, + src: MediumLevelExpressionIndex::from(op.operands[4]), }), MLIL_SET_VAR_ALIASED => Op::SetVarAliased(SetVarAliased { dest: get_var_ssa(op.operands[0], op.operands[1] as usize), prev: get_var_ssa(op.operands[0], op.operands[2] as usize), - src: op.operands[3] as usize, + src: MediumLevelExpressionIndex::from(op.operands[3]), }), MLIL_SET_VAR_SSA => Op::SetVarSsa(SetVarSsa { dest: get_var_ssa(op.operands[0], op.operands[1] as usize), - src: op.operands[2] as usize, + src: MediumLevelExpressionIndex::from(op.operands[2]), }), MLIL_VAR_PHI => Op::VarPhi(VarPhi { dest: get_var_ssa(op.operands[0], op.operands[1] as usize), @@ -193,7 +239,7 @@ impl MediumLevelILInstruction { MLIL_SET_VAR_SPLIT => Op::SetVarSplit(SetVarSplit { high: get_var(op.operands[0]), low: get_var(op.operands[1]), - src: op.operands[2] as usize, + src: MediumLevelExpressionIndex::from(op.operands[2]), }), MLIL_VAR_SPLIT_SSA => Op::VarSplitSsa(VarSplitSsa { high: get_var_ssa(op.operands[0], op.operands[1] as usize), @@ -202,212 +248,212 @@ impl MediumLevelILInstruction { MLIL_SET_VAR_SPLIT_SSA => Op::SetVarSplitSsa(SetVarSplitSsa { high: get_var_ssa(op.operands[0], op.operands[1] as usize), low: get_var_ssa(op.operands[2], op.operands[3] as usize), - src: op.operands[4] as usize, + src: MediumLevelExpressionIndex::from(op.operands[4]), }), MLIL_ADD => Op::Add(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_SUB => Op::Sub(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_AND => Op::And(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_OR => Op::Or(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_XOR => Op::Xor(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_LSL => Op::Lsl(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_LSR => Op::Lsr(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_ASR => Op::Asr(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_ROL => Op::Rol(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_ROR => Op::Ror(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_MUL => Op::Mul(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_MULU_DP => Op::MuluDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_MULS_DP => Op::MulsDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_DIVU => Op::Divu(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_DIVU_DP => Op::DivuDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_DIVS => Op::Divs(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_DIVS_DP => Op::DivsDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_MODU => Op::Modu(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_MODU_DP => Op::ModuDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_MODS => Op::Mods(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_MODS_DP => Op::ModsDp(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_CMP_E => Op::CmpE(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_CMP_NE => Op::CmpNe(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_CMP_SLT => Op::CmpSlt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_CMP_ULT => Op::CmpUlt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_CMP_SLE => Op::CmpSle(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_CMP_ULE => Op::CmpUle(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_CMP_SGE => Op::CmpSge(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_CMP_UGE => Op::CmpUge(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_CMP_SGT => Op::CmpSgt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_CMP_UGT => Op::CmpUgt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_TEST_BIT => Op::TestBit(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_ADD_OVERFLOW => Op::AddOverflow(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FCMP_E => Op::FcmpE(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FCMP_NE => Op::FcmpNe(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FCMP_LT => Op::FcmpLt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FCMP_LE => Op::FcmpLe(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FCMP_GE => Op::FcmpGe(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FCMP_GT => Op::FcmpGt(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FCMP_O => Op::FcmpO(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FCMP_UO => Op::FcmpUo(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FADD => Op::Fadd(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FSUB => Op::Fsub(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FMUL => Op::Fmul(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_FDIV => Op::Fdiv(BinaryOp { - left: op.operands[0] as usize, - right: op.operands[1] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), }), MLIL_ADC => Op::Adc(BinaryOpCarry { - left: op.operands[0] as usize, - right: op.operands[1] as usize, - carry: op.operands[2] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), + carry: MediumLevelExpressionIndex::from(op.operands[2]), }), MLIL_SBB => Op::Sbb(BinaryOpCarry { - left: op.operands[0] as usize, - right: op.operands[1] as usize, - carry: op.operands[2] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), + carry: MediumLevelExpressionIndex::from(op.operands[2]), }), MLIL_RLC => Op::Rlc(BinaryOpCarry { - left: op.operands[0] as usize, - right: op.operands[1] as usize, - carry: op.operands[2] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), + carry: MediumLevelExpressionIndex::from(op.operands[2]), }), MLIL_RRC => Op::Rrc(BinaryOpCarry { - left: op.operands[0] as usize, - right: op.operands[1] as usize, - carry: op.operands[2] as usize, + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), + carry: MediumLevelExpressionIndex::from(op.operands[2]), }), MLIL_CALL => Op::Call(Call { num_outputs: op.operands[0] as usize, first_output: op.operands[1] as usize, - dest: op.operands[2] as usize, + dest: MediumLevelExpressionIndex::from(op.operands[2]), num_params: op.operands[3] as usize, first_param: op.operands[4] as usize, }), @@ -432,7 +478,7 @@ impl MediumLevelILInstruction { MLIL_TAILCALL => Op::Tailcall(Call { num_outputs: op.operands[0] as usize, first_output: op.operands[1] as usize, - dest: op.operands[2] as usize, + dest: MediumLevelExpressionIndex::from(op.operands[2]), num_params: op.operands[3] as usize, first_param: op.operands[4] as usize, }), @@ -457,7 +503,7 @@ impl MediumLevelILInstruction { first_param: op.operands[4] as usize, }), MLIL_MEMORY_INTRINSIC_SSA => Op::MemoryIntrinsicSsa(MemoryIntrinsicSsa { - output: op.operands[0] as usize, + output: MediumLevelExpressionIndex::from(op.operands[0]), intrinsic: op.operands[1] as u32, num_params: op.operands[2] as usize, first_param: op.operands[3] as usize, @@ -471,124 +517,124 @@ impl MediumLevelILInstruction { }) } MLIL_CALL_SSA => Op::CallSsa(CallSsa { - output: op.operands[0] as usize, - dest: op.operands[1] as usize, + output: MediumLevelExpressionIndex::from(op.operands[0]), + dest: MediumLevelExpressionIndex::from(op.operands[1]), num_params: op.operands[2] as usize, first_param: op.operands[3] as usize, src_memory: op.operands[4], }), MLIL_TAILCALL_SSA => Op::TailcallSsa(CallSsa { - output: op.operands[0] as usize, - dest: op.operands[1] as usize, + output: MediumLevelExpressionIndex::from(op.operands[0]), + dest: MediumLevelExpressionIndex::from(op.operands[1]), num_params: op.operands[2] as usize, first_param: op.operands[3] as usize, src_memory: op.operands[4], }), MLIL_CALL_UNTYPED_SSA => Op::CallUntypedSsa(CallUntypedSsa { - output: op.operands[0] as usize, - dest: op.operands[1] as usize, - params: op.operands[2] as usize, - stack: op.operands[3] as usize, + output: MediumLevelExpressionIndex::from(op.operands[0]), + dest: MediumLevelExpressionIndex::from(op.operands[1]), + params: MediumLevelExpressionIndex::from(op.operands[2]), + stack: MediumLevelExpressionIndex::from(op.operands[3]), }), MLIL_TAILCALL_UNTYPED_SSA => Op::TailcallUntypedSsa(CallUntypedSsa { - output: op.operands[0] as usize, - dest: op.operands[1] as usize, - params: op.operands[2] as usize, - stack: op.operands[3] as usize, + output: MediumLevelExpressionIndex::from(op.operands[0]), + dest: MediumLevelExpressionIndex::from(op.operands[1]), + params: MediumLevelExpressionIndex::from(op.operands[2]), + stack: MediumLevelExpressionIndex::from(op.operands[3]), }), MLIL_SYSCALL_SSA => Op::SyscallSsa(SyscallSsa { - output: op.operands[0] as usize, + output: MediumLevelExpressionIndex::from(op.operands[0]), num_params: op.operands[1] as usize, first_param: op.operands[2] as usize, src_memory: op.operands[3], }), MLIL_SYSCALL_UNTYPED_SSA => Op::SyscallUntypedSsa(SyscallUntypedSsa { - output: op.operands[0] as usize, - params: op.operands[1] as usize, - stack: op.operands[2] as usize, + output: MediumLevelExpressionIndex::from(op.operands[0]), + params: MediumLevelExpressionIndex::from(op.operands[1]), + stack: MediumLevelExpressionIndex::from(op.operands[2]), }), MLIL_CALL_UNTYPED => Op::CallUntyped(CallUntyped { - output: op.operands[0] as usize, - dest: op.operands[1] as usize, - params: op.operands[2] as usize, - stack: op.operands[3] as usize, + output: MediumLevelExpressionIndex::from(op.operands[0]), + dest: MediumLevelExpressionIndex::from(op.operands[1]), + params: MediumLevelExpressionIndex::from(op.operands[2]), + stack: MediumLevelExpressionIndex::from(op.operands[3]), }), MLIL_TAILCALL_UNTYPED => Op::TailcallUntyped(CallUntyped { - output: op.operands[0] as usize, - dest: op.operands[1] as usize, - params: op.operands[2] as usize, - stack: op.operands[3] as usize, + output: MediumLevelExpressionIndex::from(op.operands[0]), + dest: MediumLevelExpressionIndex::from(op.operands[1]), + params: MediumLevelExpressionIndex::from(op.operands[2]), + stack: MediumLevelExpressionIndex::from(op.operands[3]), }), MLIL_SYSCALL_UNTYPED => Op::SyscallUntyped(SyscallUntyped { - output: op.operands[0] as usize, - params: op.operands[1] as usize, - stack: op.operands[2] as usize, + output: MediumLevelExpressionIndex::from(op.operands[0]), + params: MediumLevelExpressionIndex::from(op.operands[1]), + stack: MediumLevelExpressionIndex::from(op.operands[2]), }), MLIL_NEG => Op::Neg(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_NOT => Op::Not(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_SX => Op::Sx(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_ZX => Op::Zx(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_LOW_PART => Op::LowPart(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_BOOL_TO_INT => Op::BoolToInt(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_UNIMPL_MEM => Op::UnimplMem(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_FSQRT => Op::Fsqrt(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_FNEG => Op::Fneg(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_FABS => Op::Fabs(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_FLOAT_TO_INT => Op::FloatToInt(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_INT_TO_FLOAT => Op::IntToFloat(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_FLOAT_CONV => Op::FloatConv(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_ROUND_TO_INT => Op::RoundToInt(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_FLOOR => Op::Floor(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_CEIL => Op::Ceil(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_FTRUNC => Op::Ftrunc(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_LOAD => Op::Load(UnaryOp { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), MLIL_LOAD_STRUCT => Op::LoadStruct(LoadStruct { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), offset: op.operands[1], }), MLIL_LOAD_STRUCT_SSA => Op::LoadStructSsa(LoadStructSsa { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), offset: op.operands[1], src_memory: op.operands[2], }), MLIL_LOAD_SSA => Op::LoadSsa(LoadSsa { - src: op.operands[0] as usize, + src: MediumLevelExpressionIndex::from(op.operands[0]), src_memory: op.operands[1], }), MLIL_RET => Op::Ret(Ret { @@ -639,6 +685,7 @@ impl MediumLevelILInstruction { Self { function, address: op.address, + instr_index, expr_index, size: op.size, kind, @@ -679,7 +726,7 @@ impl MediumLevelILInstruction { fn get_expr_list(&self, operand_idx: usize) -> Vec<MediumLevelILInstruction> { self.get_operand_list(operand_idx) .into_iter() - .map(|val| MediumLevelInstructionIndex(val as usize)) + .map(|val| MediumLevelExpressionIndex(val as usize)) .filter_map(|idx| self.function.instruction_from_expr_index(idx)) .collect() } @@ -949,49 +996,60 @@ impl MediumLevelILInstruction { CallUntypedSsa(op) => Lifted::CallUntypedSsa(self.lift_call_untyped_ssa(op)), TailcallUntypedSsa(op) => Lifted::TailcallUntypedSsa(self.lift_call_untyped_ssa(op)), - SyscallSsa(op) => Lifted::SyscallSsa(LiftedSyscallSsa { - output: get_call_output_ssa(&MediumLevelILInstruction::new( - self.function.clone(), - MediumLevelInstructionIndex(op.output), - )), - params: self - .get_expr_list(1) - .iter() - .map(|expr| expr.lift()) - .collect(), - src_memory: op.src_memory, - }), - SyscallUntypedSsa(op) => Lifted::SyscallUntypedSsa(LiftedSyscallUntypedSsa { - output: get_call_output_ssa(&MediumLevelILInstruction::new( - self.function.clone(), - MediumLevelInstructionIndex(op.output), - )), - params: get_call_params_ssa(&MediumLevelILInstruction::new( - self.function.clone(), - MediumLevelInstructionIndex(op.params), - )) - .iter() - .map(|param| param.lift()) - .collect(), - stack: self.lift_operand(op.stack), - }), + SyscallSsa(op) => { + let output_instr = self + .function + .instruction_from_expr_index(op.output) + .expect("Valid output expression index"); + Lifted::SyscallSsa(LiftedSyscallSsa { + output: get_call_output_ssa(&output_instr), + params: self + .get_expr_list(1) + .iter() + .map(|expr| expr.lift()) + .collect(), + src_memory: op.src_memory, + }) + } + SyscallUntypedSsa(op) => { + let output_instr = self + .function + .instruction_from_expr_index(op.output) + .expect("Valid output expression index"); + let params_instr = self + .function + .instruction_from_expr_index(op.params) + .expect("Valid params expression index"); + Lifted::SyscallUntypedSsa(LiftedSyscallUntypedSsa { + output: get_call_output_ssa(&output_instr), + params: get_call_params_ssa(¶ms_instr) + .iter() + .map(|param| param.lift()) + .collect(), + stack: self.lift_operand(op.stack), + }) + } CallUntyped(op) => Lifted::CallUntyped(self.lift_call_untyped(op)), TailcallUntyped(op) => Lifted::TailcallUntyped(self.lift_call_untyped(op)), - SyscallUntyped(op) => Lifted::SyscallUntyped(LiftedSyscallUntyped { - output: get_call_output(&MediumLevelILInstruction::new( - self.function.clone(), - MediumLevelInstructionIndex(op.output), - )), - params: get_call_params(&MediumLevelILInstruction::new( - self.function.clone(), - MediumLevelInstructionIndex(op.params), - )) - .iter() - .map(|param| param.lift()) - .collect(), - stack: self.lift_operand(op.stack), - }), + SyscallUntyped(op) => { + let output_instr = self + .function + .instruction_from_expr_index(op.output) + .expect("Valid output expression index"); + let params_instr = self + .function + .instruction_from_expr_index(op.params) + .expect("Valid params expression index"); + Lifted::SyscallUntyped(LiftedSyscallUntyped { + output: get_call_output(&output_instr), + params: get_call_params(¶ms_instr) + .iter() + .map(|param| param.lift()) + .collect(), + stack: self.lift_operand(op.stack), + }) + } Neg(op) => Lifted::Neg(self.lift_unary_op(op)), Not(op) => Lifted::Not(self.lift_unary_op(op)), @@ -1060,7 +1118,8 @@ impl MediumLevelILInstruction { MediumLevelILLiftedInstruction { function: self.function.clone(), address: self.address, - index: self.expr_index, + instr_index: self.instr_index, + expr_index: self.expr_index, size: self.size, kind, } @@ -1090,7 +1149,7 @@ impl MediumLevelILInstruction { /// Returns the [`BasicBlock`] containing the given [`MediumLevelILInstruction`]. pub fn basic_block(&self) -> Option<Ref<BasicBlock<MediumLevelILBlock>>> { // TODO: We might be able to .expect this if we guarantee that self.index is valid. - self.function.basic_block_containing_index(self.expr_index) + self.function.basic_block_containing_index(self.instr_index) } /// Possible values of expression using path-sensitive static data flow analysis @@ -1494,17 +1553,14 @@ impl MediumLevelILInstruction { Variable::new(var.ty, index, var.storage) } - fn lift_operand(&self, expr_idx: usize) -> Box<MediumLevelILLiftedInstruction> { - // TODO: UGH, if your gonna call it expr_idx, call the instruction and expression!!!!! - // TODO: We dont even need to say instruction in the type! - // TODO: IF you want to have an instruction type, there needs to be a separate expression type - // TODO: See the lowlevelil module. - let expr_idx_is_really_instr_idx = MediumLevelInstructionIndex(expr_idx); - // TODO: See the comment in the unchecked function, ugh, i hate this.. + fn lift_operand( + &self, + expr_idx: MediumLevelExpressionIndex, + ) -> Box<MediumLevelILLiftedInstruction> { let operand_instr = self .function - .instruction_from_expr_index(expr_idx_is_really_instr_idx) - .unwrap(); + .instruction_from_expr_index(expr_idx) + .expect("Invalid operand expression index"); Box::new(operand_instr.lift()) } @@ -1542,29 +1598,32 @@ impl MediumLevelILInstruction { } fn lift_call_untyped(&self, op: CallUntyped) -> LiftedCallUntyped { + let output_instr = self + .function + .instruction_from_expr_index(op.output) + .expect("Valid output expression index"); + let params_instr = self + .function + .instruction_from_expr_index(op.params) + .expect("Valid params expression index"); LiftedCallUntyped { - output: get_call_output(&MediumLevelILInstruction::new( - self.function.clone(), - MediumLevelInstructionIndex(op.output), - )), + output: get_call_output(&output_instr), dest: self.lift_operand(op.dest), - params: get_call_params(&MediumLevelILInstruction::new( - self.function.clone(), - MediumLevelInstructionIndex(op.params), - )) - .iter() - .map(|expr| expr.lift()) - .collect(), + params: get_call_params(¶ms_instr) + .iter() + .map(|expr| expr.lift()) + .collect(), stack: self.lift_operand(op.stack), } } fn lift_call_ssa(&self, op: CallSsa) -> LiftedCallSsa { + let output_instr = self + .function + .instruction_from_expr_index(op.output) + .expect("Valid output expression index"); LiftedCallSsa { - output: get_call_output_ssa(&MediumLevelILInstruction::new( - self.function.clone(), - MediumLevelInstructionIndex(op.output), - )), + output: get_call_output_ssa(&output_instr), dest: self.lift_operand(op.dest), params: self .get_expr_list(2) @@ -1576,19 +1635,21 @@ impl MediumLevelILInstruction { } fn lift_call_untyped_ssa(&self, op: CallUntypedSsa) -> LiftedCallUntypedSsa { + let output_instr = self + .function + .instruction_from_expr_index(op.output) + .expect("Valid output expression index"); + let params_instr = self + .function + .instruction_from_expr_index(op.params) + .expect("Valid params expression index"); LiftedCallUntypedSsa { - output: get_call_output_ssa(&MediumLevelILInstruction::new( - self.function.clone(), - MediumLevelInstructionIndex(op.output), - )), + output: get_call_output_ssa(&output_instr), dest: self.lift_operand(op.dest), - params: get_call_params_ssa(&MediumLevelILInstruction::new( - self.function.clone(), - MediumLevelInstructionIndex(op.params), - )) - .iter() - .map(|param| param.lift()) - .collect(), + params: get_call_params_ssa(¶ms_instr) + .iter() + .map(|param| param.lift()) + .collect(), stack: self.lift_operand(op.stack), } } @@ -1598,7 +1659,8 @@ impl Debug for MediumLevelILInstruction { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("MediumLevelILInstruction") .field("address", &self.address) - .field("index", &self.expr_index) + .field("instr_index", &self.instr_index) + .field("expr_index", &self.expr_index) .field("size", &self.size) .field("kind", &self.kind) .finish() @@ -1617,8 +1679,6 @@ unsafe impl CoreArrayProviderInner for MediumLevelILInstruction { } unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> { - // TODO: This needs to be tested!!!! - // TODO: What if this does not need to be mapped!!!! context .instruction_from_index(MediumLevelInstructionIndex(*raw)) .unwrap() @@ -1832,9 +1892,9 @@ unsafe impl CoreArrayProviderInner for BranchDependence { unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> { Self { - instruction: MediumLevelILInstruction::new( + instruction: MediumLevelILInstruction::from_expr_index( context.clone(), - MediumLevelInstructionIndex(raw.branch), + MediumLevelExpressionIndex(raw.branch), ), dependence: raw.dependence, } diff --git a/rust/src/medium_level_il/lift.rs b/rust/src/medium_level_il/lift.rs index 399bda78..e563f26d 100644 --- a/rust/src/medium_level_il/lift.rs +++ b/rust/src/medium_level_il/lift.rs @@ -1,5 +1,5 @@ use super::operation::*; -use super::{MediumLevelILFunction, MediumLevelInstructionIndex}; +use super::{MediumLevelExpressionIndex, MediumLevelILFunction, MediumLevelInstructionIndex}; use crate::architecture::CoreIntrinsic; use crate::rc::Ref; use crate::variable::{ConstantData, SSAVariable, Variable}; @@ -27,7 +27,8 @@ pub enum MediumLevelILLiftedOperand { pub struct MediumLevelILLiftedInstruction { pub function: Ref<MediumLevelILFunction>, pub address: u64, - pub index: MediumLevelInstructionIndex, + pub instr_index: MediumLevelInstructionIndex, + pub expr_index: MediumLevelExpressionIndex, pub size: usize, pub kind: MediumLevelILLiftedInstructionKind, } @@ -36,7 +37,8 @@ impl Debug for MediumLevelILLiftedInstruction { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("MediumLevelILLiftedInstruction") .field("address", &self.address) - .field("index", &self.index) + .field("instr_index", &self.instr_index) + .field("expr_index", &self.expr_index) .field("size", &self.size) .field("kind", &self.kind) .finish() diff --git a/rust/src/medium_level_il/operation.rs b/rust/src/medium_level_il/operation.rs index e8b70cc6..578087d0 100644 --- a/rust/src/medium_level_il/operation.rs +++ b/rust/src/medium_level_il/operation.rs @@ -1,4 +1,6 @@ -use super::{MediumLevelILLiftedInstruction, MediumLevelInstructionIndex}; +use super::{ + MediumLevelExpressionIndex, MediumLevelILLiftedInstruction, MediumLevelInstructionIndex, +}; use crate::architecture::CoreIntrinsic; use crate::variable::{ConstantData, SSAVariable, Variable}; use std::collections::BTreeMap; @@ -6,7 +8,7 @@ use std::collections::BTreeMap; // IF #[derive(Debug, Copy, Clone)] pub struct MediumLevelILOperationIf { - pub condition: usize, + pub condition: MediumLevelExpressionIndex, pub dest_true: MediumLevelInstructionIndex, pub dest_false: MediumLevelInstructionIndex, } @@ -51,7 +53,7 @@ pub struct LiftedConstData { // JUMP, RET_HINT #[derive(Debug, Copy, Clone)] pub struct Jump { - pub dest: usize, + pub dest: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedJump { @@ -61,10 +63,10 @@ pub struct LiftedJump { // STORE_SSA #[derive(Debug, Copy, Clone)] pub struct StoreSsa { - pub dest: usize, + pub dest: MediumLevelExpressionIndex, pub dest_memory: u64, pub src_memory: u64, - pub src: usize, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedStoreSsa { @@ -77,11 +79,11 @@ pub struct LiftedStoreSsa { // STORE_STRUCT_SSA #[derive(Debug, Copy, Clone)] pub struct StoreStructSsa { - pub dest: usize, + pub dest: MediumLevelExpressionIndex, pub offset: u64, pub dest_memory: u64, pub src_memory: u64, - pub src: usize, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedStoreStructSsa { @@ -95,9 +97,9 @@ pub struct LiftedStoreStructSsa { // STORE_STRUCT #[derive(Debug, Copy, Clone)] pub struct StoreStruct { - pub dest: usize, + pub dest: MediumLevelExpressionIndex, pub offset: u64, - pub src: usize, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedStoreStruct { @@ -109,8 +111,8 @@ pub struct LiftedStoreStruct { // STORE #[derive(Debug, Copy, Clone)] pub struct Store { - pub dest: usize, - pub src: usize, + pub dest: MediumLevelExpressionIndex, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedStore { @@ -121,7 +123,7 @@ pub struct LiftedStore { // JUMP_TO #[derive(Debug, Copy, Clone)] pub struct JumpTo { - pub dest: usize, + pub dest: MediumLevelExpressionIndex, pub first_operand: usize, pub num_operands: usize, } @@ -148,7 +150,7 @@ pub struct FreeVarSlot { pub struct SetVarField { pub dest: Variable, pub offset: u64, - pub src: usize, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSetVarField { @@ -161,8 +163,7 @@ pub struct LiftedSetVarField { #[derive(Debug, Copy, Clone)] pub struct SetVar { pub dest: Variable, - // TODO: Expression? - pub src: usize, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSetVar { @@ -183,7 +184,7 @@ pub struct SetVarSsaField { pub dest: SSAVariable, pub prev: SSAVariable, pub offset: u64, - pub src: usize, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSetVarSsaField { @@ -198,7 +199,7 @@ pub struct LiftedSetVarSsaField { pub struct SetVarAliased { pub dest: SSAVariable, pub prev: SSAVariable, - pub src: usize, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSetVarAliased { @@ -211,7 +212,7 @@ pub struct LiftedSetVarAliased { #[derive(Debug, Copy, Clone)] pub struct SetVarSsa { pub dest: SSAVariable, - pub src: usize, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSetVarSsa { @@ -257,7 +258,7 @@ pub struct VarSplit { pub struct SetVarSplit { pub high: Variable, pub low: Variable, - pub src: usize, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSetVarSplit { @@ -278,7 +279,7 @@ pub struct VarSplitSsa { pub struct SetVarSplitSsa { pub high: SSAVariable, pub low: SSAVariable, - pub src: usize, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSetVarSplitSsa { @@ -290,8 +291,8 @@ pub struct LiftedSetVarSplitSsa { // ADD, SUB, AND, OR, XOR, LSL, LSR, ASR, ROL, ROR, MUL, MULU_DP, MULS_DP, DIVU, DIVU_DP, DIVS, DIVS_DP, MODU, MODU_DP, MODS, MODS_DP, CMP_E, CMP_NE, CMP_SLT, CMP_ULT, CMP_SLE, CMP_ULE, CMP_SGE, CMP_UGE, CMP_SGT, CMP_UGT, TEST_BIT, ADD_OVERFLOW, FCMP_E, FCMP_NE, FCMP_LT, FCMP_LE, FCMP_GE, FCMP_GT, FCMP_O, FCMP_UO, FADD, FSUB, FMUL, FDIV #[derive(Debug, Copy, Clone)] pub struct BinaryOp { - pub left: usize, - pub right: usize, + pub left: MediumLevelExpressionIndex, + pub right: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedBinaryOp { @@ -302,9 +303,9 @@ pub struct LiftedBinaryOp { // ADC, SBB, RLC, RRC #[derive(Debug, Copy, Clone)] pub struct BinaryOpCarry { - pub left: usize, - pub right: usize, - pub carry: usize, + pub left: MediumLevelExpressionIndex, + pub right: MediumLevelExpressionIndex, + pub carry: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedBinaryOpCarry { @@ -318,7 +319,7 @@ pub struct LiftedBinaryOpCarry { pub struct Call { pub first_output: usize, pub num_outputs: usize, - pub dest: usize, + pub dest: MediumLevelExpressionIndex, pub first_param: usize, pub num_params: usize, } @@ -426,7 +427,7 @@ pub struct LiftedIntrinsicSsa { // MEMORY_INTRINSIC_SSA #[derive(Debug, Copy, Clone)] pub struct MemoryIntrinsicSsa { - pub output: usize, + pub output: MediumLevelExpressionIndex, pub intrinsic: u32, pub first_param: usize, pub num_params: usize, @@ -456,8 +457,8 @@ pub struct LiftedMemoryIntrinsicOutputSsa { // CALL_SSA, TAILCALL_SSA #[derive(Debug, Copy, Clone)] pub struct CallSsa { - pub output: usize, - pub dest: usize, + pub output: MediumLevelExpressionIndex, + pub dest: MediumLevelExpressionIndex, pub first_param: usize, pub num_params: usize, pub src_memory: u64, @@ -473,10 +474,10 @@ pub struct LiftedCallSsa { // CALL_UNTYPED_SSA, TAILCALL_UNTYPED_SSA #[derive(Debug, Copy, Clone)] pub struct CallUntypedSsa { - pub output: usize, - pub dest: usize, - pub params: usize, - pub stack: usize, + pub output: MediumLevelExpressionIndex, + pub dest: MediumLevelExpressionIndex, + pub params: MediumLevelExpressionIndex, + pub stack: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedCallUntypedSsa { @@ -489,7 +490,7 @@ pub struct LiftedCallUntypedSsa { // SYSCALL_SSA #[derive(Debug, Copy, Clone)] pub struct SyscallSsa { - pub output: usize, + pub output: MediumLevelExpressionIndex, pub first_param: usize, pub num_params: usize, pub src_memory: u64, @@ -504,9 +505,9 @@ pub struct LiftedSyscallSsa { // SYSCALL_UNTYPED_SSA #[derive(Debug, Copy, Clone)] pub struct SyscallUntypedSsa { - pub output: usize, - pub params: usize, - pub stack: usize, + pub output: MediumLevelExpressionIndex, + pub params: MediumLevelExpressionIndex, + pub stack: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSyscallUntypedSsa { @@ -518,10 +519,10 @@ pub struct LiftedSyscallUntypedSsa { // CALL_UNTYPED, TAILCALL_UNTYPED #[derive(Debug, Copy, Clone)] pub struct CallUntyped { - pub output: usize, - pub dest: usize, - pub params: usize, - pub stack: usize, + pub output: MediumLevelExpressionIndex, + pub dest: MediumLevelExpressionIndex, + pub params: MediumLevelExpressionIndex, + pub stack: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedCallUntyped { @@ -534,9 +535,9 @@ pub struct LiftedCallUntyped { // SYSCALL_UNTYPED #[derive(Debug, Copy, Clone)] pub struct SyscallUntyped { - pub output: usize, - pub params: usize, - pub stack: usize, + pub output: MediumLevelExpressionIndex, + pub params: MediumLevelExpressionIndex, + pub stack: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSyscallUntyped { @@ -548,7 +549,7 @@ pub struct LiftedSyscallUntyped { // NEG, NOT, SX, ZX, LOW_PART, BOOL_TO_INT, UNIMPL_MEM, FSQRT, FNEG, FABS, FLOAT_TO_INT, INT_TO_FLOAT, FLOAT_CONV, ROUND_TO_INT, FLOOR, CEIL, FTRUNC, LOAD #[derive(Debug, Copy, Clone)] pub struct UnaryOp { - pub src: usize, + pub src: MediumLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedUnaryOp { @@ -558,7 +559,7 @@ pub struct LiftedUnaryOp { // LOAD_STRUCT #[derive(Debug, Copy, Clone)] pub struct LoadStruct { - pub src: usize, + pub src: MediumLevelExpressionIndex, pub offset: u64, } #[derive(Clone, Debug, PartialEq)] @@ -570,7 +571,7 @@ pub struct LiftedLoadStruct { // LOAD_STRUCT_SSA #[derive(Debug, Copy, Clone)] pub struct LoadStructSsa { - pub src: usize, + pub src: MediumLevelExpressionIndex, pub offset: u64, pub src_memory: u64, } @@ -584,7 +585,7 @@ pub struct LiftedLoadStructSsa { // LOAD_SSA #[derive(Debug, Copy, Clone)] pub struct LoadSsa { - pub src: usize, + pub src: MediumLevelExpressionIndex, pub src_memory: u64, } #[derive(Clone, Debug, PartialEq)] diff --git a/rust/tests/high_level_il.rs b/rust/tests/high_level_il.rs index 4466678c..e757301e 100644 --- a/rust/tests/high_level_il.rs +++ b/rust/tests/high_level_il.rs @@ -1,6 +1,8 @@ use binaryninja::binary_view::BinaryViewExt; use binaryninja::headless::Session; -use binaryninja::high_level_il::{HighLevelILInstructionKind, HighLevelInstructionIndex}; +use binaryninja::high_level_il::{ + HighLevelExpressionIndex, HighLevelILInstructionKind, HighLevelInstructionIndex, +}; use std::path::PathBuf; #[test] @@ -23,7 +25,8 @@ fn test_hlil_info() { // 00025f22 HLIL_CALL (HLIL_CONST_PTR.d __crt_interlocked_read_32)((HLIL_VAR.d arg1)))) // 00025f10 ) let instr_0 = hlil_instr_iter.next().unwrap(); - assert_eq!(instr_0.expr_index, HighLevelInstructionIndex(5)); + assert_eq!(instr_0.instr_index, HighLevelInstructionIndex(0)); + assert_eq!(instr_0.expr_index, HighLevelExpressionIndex(5)); assert_eq!(instr_0.address, image_base + 0x00025f22); println!("{:?}", instr_0.kind); match instr_0.kind { diff --git a/rust/tests/language_representation.rs b/rust/tests/language_representation.rs index c3d60966..f4aeb7bd 100644 --- a/rust/tests/language_representation.rs +++ b/rust/tests/language_representation.rs @@ -8,7 +8,7 @@ use binaryninja::disassembly::{ use binaryninja::function::Function; use binaryninja::headless::Session; use binaryninja::high_level_il::token_emitter::HighLevelILTokenEmitter; -use binaryninja::high_level_il::{HighLevelILFunction, HighLevelInstructionIndex}; +use binaryninja::high_level_il::{HighLevelExpressionIndex, HighLevelILFunction}; use binaryninja::language_representation::{ register_language_representation_function_type, CoreLanguageRepresentationFunction, CoreLanguageRepresentationFunctionType, LanguageRepresentationFunction, @@ -60,7 +60,7 @@ impl LanguageRepresentationFunction for MyLangRepr { fn expr_text( &self, il: &HighLevelILFunction, - expr_index: HighLevelInstructionIndex, + expr_index: HighLevelExpressionIndex, tokens: &HighLevelILTokenEmitter, _settings: &DisassemblySettings, _as_full_ast: bool, @@ -101,7 +101,7 @@ impl LanguageRepresentationFunction for MyLangRepr { fn begin_lines( &self, _il: &HighLevelILFunction, - _expr_index: HighLevelInstructionIndex, + _expr_index: HighLevelExpressionIndex, _tokens: &HighLevelILTokenEmitter, ) { } @@ -109,7 +109,7 @@ impl LanguageRepresentationFunction for MyLangRepr { fn end_lines( &self, _il: &HighLevelILFunction, - _expr_index: HighLevelInstructionIndex, + _expr_index: HighLevelExpressionIndex, _tokens: &HighLevelILTokenEmitter, ) { } @@ -149,7 +149,7 @@ fn test_custom_language_representation() { let il = func.high_level_il(false).unwrap(); let settings = DisassemblySettings::new(); - let root_idx = il.root_instruction_index(); + let root_idx = il.root_expression_index(); let result = _repr.linear_lines(&il, root_idx, &settings, false); let output: String = result.iter().map(|dis| dis.to_string()).collect(); assert_eq!( diff --git a/rust/tests/medium_level_il.rs b/rust/tests/medium_level_il.rs index b8c1c108..7d4d8af1 100644 --- a/rust/tests/medium_level_il.rs +++ b/rust/tests/medium_level_il.rs @@ -1,7 +1,8 @@ use binaryninja::binary_view::BinaryViewExt; use binaryninja::headless::Session; use binaryninja::medium_level_il::{ - MediumLevelILInstructionKind, MediumLevelILLiftedInstructionKind, MediumLevelInstructionIndex, + MediumLevelExpressionIndex, MediumLevelILInstructionKind, MediumLevelILLiftedInstructionKind, + MediumLevelInstructionIndex, }; use std::path::PathBuf; @@ -21,50 +22,54 @@ fn test_mlil_info() { // 0 @ 00025f10 (MLIL_SET_VAR.d edi_1 = (MLIL_VAR.d edi)) let instr_0 = mlil_instr_iter.next().unwrap(); - assert_eq!(instr_0.expr_index, MediumLevelInstructionIndex(1)); + assert_eq!(instr_0.instr_index, MediumLevelInstructionIndex(0)); + assert_eq!(instr_0.expr_index, MediumLevelExpressionIndex(1)); assert_eq!(instr_0.address, image_base + 0x00025f10); println!("{:?}", instr_0.kind); match instr_0.kind { MediumLevelILInstructionKind::SetVar(op) => { assert_eq!(op.dest.index, 524288); - assert_eq!(op.src, 0); + assert_eq!(op.src, MediumLevelExpressionIndex(0)); } _ => panic!("Expected SetVar"), } // 1 @ 00025f15 (MLIL_SET_VAR.d eax = (MLIL_VAR.d arg1)) let instr_1 = mlil_instr_iter.next().unwrap(); - assert_eq!(instr_1.expr_index, MediumLevelInstructionIndex(3)); + assert_eq!(instr_1.instr_index, MediumLevelInstructionIndex(1)); + assert_eq!(instr_1.expr_index, MediumLevelExpressionIndex(3)); assert_eq!(instr_1.address, image_base + 0x00025f15); println!("{:?}", instr_1.kind); match instr_1.kind { MediumLevelILInstructionKind::SetVar(op) => { assert_eq!(op.dest.index, 5); - assert_eq!(op.src, 2); + assert_eq!(op.src, MediumLevelExpressionIndex(2)); } _ => panic!("Expected SetVar"), } // 2 @ 00025f18 (MLIL_SET_VAR.d var_8 = (MLIL_VAR.d eax)) let instr_2 = mlil_instr_iter.next().unwrap(); - assert_eq!(instr_2.expr_index, MediumLevelInstructionIndex(5)); + assert_eq!(instr_2.instr_index, MediumLevelInstructionIndex(2)); + assert_eq!(instr_2.expr_index, MediumLevelExpressionIndex(5)); assert_eq!(instr_2.address, image_base + 0x00025f18); println!("{:?}", instr_2.kind); match instr_2.kind { MediumLevelILInstructionKind::SetVar(op) => { assert_eq!(op.dest.index, 8); - assert_eq!(op.src, 4); + assert_eq!(op.src, MediumLevelExpressionIndex(4)); } _ => panic!("Expected SetVar"), } // 3 @ 00025f19 (MLIL_CALL eax_1 = (MLIL_CONST_PTR.d __crt_interlocked_read_32)((MLIL_VAR.d var_8))) let instr_3 = mlil_instr_iter.next().unwrap(); - assert_eq!(instr_3.expr_index, MediumLevelInstructionIndex(10)); + assert_eq!(instr_3.instr_index, MediumLevelInstructionIndex(3)); + assert_eq!(instr_3.expr_index, MediumLevelExpressionIndex(10)); assert_eq!(instr_3.address, image_base + 0x00025f19); println!("{:?}", instr_3.kind); match instr_3.kind { MediumLevelILInstructionKind::Call(op) => { assert_eq!(op.first_output, 8); assert_eq!(op.num_outputs, 1); - assert_eq!(op.dest, 7); + assert_eq!(op.dest, MediumLevelExpressionIndex(7)); assert_eq!(op.first_param, 9); assert_eq!(op.num_params, 1); } @@ -72,7 +77,7 @@ fn test_mlil_info() { } match instr_3.lift().kind { MediumLevelILLiftedInstructionKind::Call(lifted_call) => { - assert_eq!(lifted_call.dest.index, MediumLevelInstructionIndex(7)); + assert_eq!(lifted_call.dest.expr_index, MediumLevelExpressionIndex(7)); assert_eq!(lifted_call.output.len(), 1); assert_eq!(lifted_call.params.len(), 1); } @@ -80,7 +85,8 @@ fn test_mlil_info() { } // 4 @ 00025f22 (MLIL_RET return (MLIL_VAR.d eax_1)) let instr_4 = mlil_instr_iter.next().unwrap(); - assert_eq!(instr_4.expr_index, MediumLevelInstructionIndex(13)); + assert_eq!(instr_4.instr_index, MediumLevelInstructionIndex(4)); + assert_eq!(instr_4.expr_index, MediumLevelExpressionIndex(13)); assert_eq!(instr_4.address, image_base + 0x00025f22); println!("{:?}", instr_4.kind); match instr_4.kind { @@ -91,3 +97,23 @@ fn test_mlil_info() { _ => panic!("Expected Ret"), } } + +#[test] +fn test_mlil_basic_blocks() { + let _session = Session::new().expect("Failed to initialize session"); + let out_dir = env!("OUT_DIR").parse::<PathBuf>().unwrap(); + let view = binaryninja::load(out_dir.join("atox.obj")).expect("Failed to create view"); + + // Make sure that all basic blocks are correctly associated with the instruction. + for func in &view.functions() { + let mlil_function = func.medium_level_il().expect("Failed to get MLIL"); + for mlil_basic_block in &mlil_function.basic_blocks() { + for instr in mlil_basic_block.iter() { + let instr_basic_block = instr + .basic_block() + .expect("Instruction without basic block"); + assert_eq!(instr_basic_block, mlil_basic_block.to_owned()); + } + } + } +} |
