diff options
| author | Mason Reed <mason@vector35.com> | 2025-05-30 16:39:32 -0400 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2025-05-30 19:17:10 -0400 |
| commit | 68b00cdf45551ba64c4f7217963055fc5a1a0cc4 (patch) | |
| tree | f6bdef06bc02d16596bdf62870c8a1cfafe49859 /rust/src/high_level_il | |
| parent | 77ab5e812af200b8e3bca0aac31d5fe0f638fba3 (diff) | |
[Rust] Express expression vs instruction index for MLIL and HLIL APIs
This was done to fix unintended behavior using an instruction or expression index in place of the other.
Fixes https://github.com/Vector35/binaryninja-api/issues/6897
Diffstat (limited to 'rust/src/high_level_il')
| -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 |
4 files changed, 298 insertions, 248 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 { |
