Skip to content

Commit 910fb8f

Browse files
committed
Simplify operand list retrieval for MLIL and HLIL Rust API
1 parent 3592d34 commit 910fb8f

File tree

5 files changed

+276
-362
lines changed

5 files changed

+276
-362
lines changed

rust/src/high_level_il/instruction.rs

Lines changed: 95 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use super::{HighLevelILFunction, HighLevelILLiftedInstruction, HighLevelILLifted
77
use crate::architecture::{CoreIntrinsic, IntrinsicId};
88
use crate::confidence::Conf;
99
use crate::disassembly::DisassemblyTextLine;
10-
use crate::operand_iter::OperandIter;
1110
use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Ref};
1211
use crate::types::Type;
1312
use crate::variable::{ConstantData, RegisterValue, SSAVariable, Variable};
@@ -552,6 +551,38 @@ impl HighLevelILInstruction {
552551
}
553552
}
554553

554+
fn get_operand_list(&self, operand_idx: usize) -> Vec<u64> {
555+
let mut count = 0;
556+
let raw_list_ptr = unsafe {
557+
BNHighLevelILGetOperandList(
558+
self.function.handle,
559+
self.expr_index.0,
560+
operand_idx,
561+
&mut count,
562+
)
563+
};
564+
assert!(!raw_list_ptr.is_null());
565+
let list = unsafe { std::slice::from_raw_parts(raw_list_ptr, count).to_vec() };
566+
unsafe { BNHighLevelILFreeOperandList(raw_list_ptr) };
567+
list
568+
}
569+
570+
fn get_ssa_var_list(&self, operand_idx: usize) -> Vec<SSAVariable> {
571+
self.get_operand_list(operand_idx)
572+
.chunks(2)
573+
.map(|chunk| (Variable::from_identifier(chunk[0]), chunk[1] as usize))
574+
.map(|(var, version)| SSAVariable::new(var, version))
575+
.collect()
576+
}
577+
578+
fn get_expr_list(&self, operand_idx: usize) -> Vec<HighLevelILInstruction> {
579+
self.get_operand_list(operand_idx)
580+
.into_iter()
581+
.map(|val| HighLevelInstructionIndex(val as usize))
582+
.filter_map(|idx| self.function.instruction_from_expr_index(idx))
583+
.collect()
584+
}
585+
555586
pub fn lift(&self) -> HighLevelILLiftedInstruction {
556587
use HighLevelILInstructionKind::*;
557588
use HighLevelILLiftedInstructionKind as Lifted;
@@ -630,7 +661,11 @@ impl HighLevelILInstruction {
630661
src: self.lift_operand(op.src),
631662
}),
632663
AssignUnpack(op) => Lifted::AssignUnpack(LiftedAssignUnpack {
633-
dest: self.lift_instruction_list(op.first_dest, op.num_dests),
664+
dest: self
665+
.get_expr_list(0)
666+
.iter()
667+
.map(|expr| expr.lift())
668+
.collect(),
634669
src: self.lift_operand(op.src),
635670
}),
636671
AssignMemSsa(op) => Lifted::AssignMemSsa(LiftedAssignMemSsa {
@@ -640,26 +675,42 @@ impl HighLevelILInstruction {
640675
src_memory: op.src_memory,
641676
}),
642677
AssignUnpackMemSsa(op) => Lifted::AssignUnpackMemSsa(LiftedAssignUnpackMemSsa {
643-
dest: self.lift_instruction_list(op.first_dest, op.num_dests),
678+
dest: self
679+
.get_expr_list(0)
680+
.iter()
681+
.map(|expr| expr.lift())
682+
.collect(),
644683
dest_memory: op.dest_memory,
645684
src: self.lift_operand(op.src),
646685
src_memory: op.src_memory,
647686
}),
648-
Block(op) => Lifted::Block(LiftedBlock {
649-
body: self.lift_instruction_list(op.first_param, op.num_params),
687+
Block(_op) => Lifted::Block(LiftedBlock {
688+
body: self
689+
.get_expr_list(0)
690+
.iter()
691+
.map(|expr| expr.lift())
692+
.collect(),
650693
}),
651694

652695
Call(op) => Lifted::Call(self.lift_call(op)),
653696
Tailcall(op) => Lifted::Tailcall(self.lift_call(op)),
654697
CallSsa(op) => Lifted::CallSsa(LiftedCallSsa {
655698
dest: self.lift_operand(op.dest),
656-
params: self.lift_instruction_list(op.first_param, op.num_params),
699+
params: self
700+
.get_expr_list(1)
701+
.iter()
702+
.map(|expr| expr.lift())
703+
.collect(),
657704
dest_memory: op.dest_memory,
658705
src_memory: op.src_memory,
659706
}),
660707

661708
Case(op) => Lifted::Case(LiftedCase {
662-
values: self.lift_instruction_list(op.first_value, op.num_values),
709+
values: self
710+
.get_expr_list(0)
711+
.iter()
712+
.map(|expr| expr.lift())
713+
.collect(),
663714
body: self.lift_operand(op.body),
664715
}),
665716
Const(op) => Lifted::Const(op),
@@ -740,15 +791,23 @@ impl HighLevelILInstruction {
740791
IntrinsicId(op.intrinsic),
741792
)
742793
.expect("Invalid intrinsic"),
743-
params: self.lift_instruction_list(op.first_param, op.num_params),
794+
params: self
795+
.get_expr_list(1)
796+
.iter()
797+
.map(|expr| expr.lift())
798+
.collect(),
744799
}),
745800
IntrinsicSsa(op) => Lifted::IntrinsicSsa(LiftedIntrinsicSsa {
746801
intrinsic: CoreIntrinsic::new(
747802
self.function.function().arch(),
748803
IntrinsicId(op.intrinsic),
749804
)
750805
.expect("Invalid intrinsic"),
751-
params: self.lift_instruction_list(op.first_param, op.num_params),
806+
params: self
807+
.get_expr_list(1)
808+
.iter()
809+
.map(|expr| expr.lift())
810+
.collect(),
752811
dest_memory: op.dest_memory,
753812
src_memory: op.src_memory,
754813
}),
@@ -757,10 +816,14 @@ impl HighLevelILInstruction {
757816
}),
758817
MemPhi(op) => Lifted::MemPhi(LiftedMemPhi {
759818
dest: op.dest,
760-
src: OperandIter::new(&*self.function, op.first_src, op.num_srcs).collect(),
819+
src: self.get_operand_list(1),
761820
}),
762-
Ret(op) => Lifted::Ret(LiftedRet {
763-
src: self.lift_instruction_list(op.first_src, op.num_srcs),
821+
Ret(_op) => Lifted::Ret(LiftedRet {
822+
src: self
823+
.get_expr_list(0)
824+
.iter()
825+
.map(|expr| expr.lift())
826+
.collect(),
764827
}),
765828
Split(op) => Lifted::Split(LiftedSplit {
766829
high: self.lift_operand(op.high),
@@ -771,13 +834,25 @@ impl HighLevelILInstruction {
771834
Switch(op) => Lifted::Switch(LiftedSwitch {
772835
condition: self.lift_operand(op.condition),
773836
default: self.lift_operand(op.default),
774-
cases: self.lift_instruction_list(op.first_case, op.num_cases),
837+
cases: self
838+
.get_expr_list(2)
839+
.iter()
840+
.map(|expr| expr.lift())
841+
.collect(),
775842
}),
776-
Syscall(op) => Lifted::Syscall(LiftedSyscall {
777-
params: self.lift_instruction_list(op.first_param, op.num_params),
843+
Syscall(_op) => Lifted::Syscall(LiftedSyscall {
844+
params: self
845+
.get_expr_list(0)
846+
.iter()
847+
.map(|expr| expr.lift())
848+
.collect(),
778849
}),
779850
SyscallSsa(op) => Lifted::SyscallSsa(LiftedSyscallSsa {
780-
params: self.lift_instruction_list(op.first_param, op.num_params),
851+
params: self
852+
.get_expr_list(0)
853+
.iter()
854+
.map(|expr| expr.lift())
855+
.collect(),
781856
dest_memory: op.dest_memory,
782857
src_memory: op.src_memory,
783858
}),
@@ -794,9 +869,7 @@ impl HighLevelILInstruction {
794869
}),
795870
VarPhi(op) => Lifted::VarPhi(LiftedVarPhi {
796871
dest: op.dest,
797-
src: OperandIter::new(&*self.function, op.first_src, op.num_srcs)
798-
.ssa_vars()
799-
.collect(),
872+
src: self.get_ssa_var_list(2),
800873
}),
801874
VarSsa(op) => Lifted::VarSsa(op),
802875

@@ -907,8 +980,9 @@ impl HighLevelILInstruction {
907980
fn lift_call(&self, op: Call) -> LiftedCall {
908981
LiftedCall {
909982
dest: self.lift_operand(op.dest),
910-
params: OperandIter::new(&*self.function, op.first_param, op.num_params)
911-
.exprs()
983+
params: self
984+
.get_expr_list(1)
985+
.iter()
912986
.map(|expr| expr.lift())
913987
.collect(),
914988
}
@@ -936,17 +1010,6 @@ impl HighLevelILInstruction {
9361010
member_index: op.member_index,
9371011
}
9381012
}
939-
940-
fn lift_instruction_list(
941-
&self,
942-
first_instruction: usize,
943-
num_instructions: usize,
944-
) -> Vec<HighLevelILLiftedInstruction> {
945-
OperandIter::new(&*self.function, first_instruction, num_instructions)
946-
.exprs()
947-
.map(|expr| expr.lift())
948-
.collect()
949-
}
9501013
}
9511014

9521015
impl CoreArrayProvider for HighLevelILInstruction {

rust/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
#[macro_use]
2828
mod ffi;
29-
mod operand_iter;
3029

3130
pub mod architecture;
3231
pub mod background_task;

0 commit comments

Comments
 (0)