summaryrefslogtreecommitdiff
path: root/rust/src/high_level_il
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2025-05-30 16:39:32 -0400
committerMason Reed <mason@vector35.com>2025-05-30 19:17:10 -0400
commit68b00cdf45551ba64c4f7217963055fc5a1a0cc4 (patch)
treef6bdef06bc02d16596bdf62870c8a1cfafe49859 /rust/src/high_level_il
parent77ab5e812af200b8e3bca0aac31d5fe0f638fba3 (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.rs21
-rw-r--r--rust/src/high_level_il/instruction.rs425
-rw-r--r--rust/src/high_level_il/lift.rs6
-rw-r--r--rust/src/high_level_il/operation.rs94
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 {