use binaryninjacore_sys::*; use core::ffi; use std::fmt::{Debug, Formatter}; use super::{HighLevelExpressionIndex, HighLevelILLiftedInstruction}; use crate::architecture::CoreIntrinsic; use crate::function::Function; use crate::rc::Ref; use crate::string::{BnString, IntoCStr}; use crate::variable::{ConstantData, SSAVariable, Variable}; #[derive(Clone, PartialEq, Eq)] pub struct GotoLabel { pub(crate) function: Ref, pub target: u64, } impl GotoLabel { pub fn name(&self) -> String { unsafe { BnString::into_string(BNGetGotoLabelName(self.function.handle, self.target)) } } fn set_name(&self, name: &str) { let raw = name.to_cstr(); unsafe { BNSetUserGotoLabelName( self.function.handle, self.target, raw.as_ref().as_ptr() as *const ffi::c_char, ) } } } impl Debug for GotoLabel { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("GotoLabel") .field("name", &self.name()) .field("target", &self.target) .finish() } } // ADC, SBB, RLC, RRC #[derive(Debug, Copy, Clone)] pub struct BinaryOpCarry { pub left: HighLevelExpressionIndex, pub right: HighLevelExpressionIndex, pub carry: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedBinaryOpCarry { pub left: Box, pub right: Box, pub carry: Box, } // 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: HighLevelExpressionIndex, pub right: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedBinaryOp { pub left: Box, pub right: Box, } // ARRAY_INDEX #[derive(Debug, Copy, Clone)] pub struct ArrayIndex { pub src: HighLevelExpressionIndex, pub index: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedArrayIndex { pub src: Box, pub index: Box, } // ARRAY_INDEX_SSA #[derive(Debug, Copy, Clone)] pub struct ArrayIndexSsa { pub src: HighLevelExpressionIndex, pub src_memory: u64, pub index: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedArrayIndexSsa { pub src: Box, pub src_memory: u64, pub index: Box, } // ASSIGN #[derive(Debug, Copy, Clone)] pub struct Assign { pub dest: HighLevelExpressionIndex, pub src: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedAssign { pub dest: Box, pub src: Box, } // ASSIGN_MEM_SSA #[derive(Debug, Copy, Clone)] pub struct AssignMemSsa { pub dest: HighLevelExpressionIndex, pub dest_memory: u64, pub src: HighLevelExpressionIndex, pub src_memory: u64, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedAssignMemSsa { pub dest: Box, pub dest_memory: u64, pub src: Box, pub src_memory: u64, } // ASSIGN_UNPACK #[derive(Debug, Copy, Clone)] pub struct AssignUnpack { pub first_dest: usize, pub num_dests: usize, pub src: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedAssignUnpack { pub dest: Vec, pub src: Box, } // ASSIGN_UNPACK_MEM_SSA #[derive(Debug, Copy, Clone)] pub struct AssignUnpackMemSsa { pub first_dest: usize, pub num_dests: usize, pub dest_memory: u64, pub src: HighLevelExpressionIndex, pub src_memory: u64, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedAssignUnpackMemSsa { pub dest: Vec, pub dest_memory: u64, pub src: Box, pub src_memory: u64, } // BLOCK #[derive(Debug, Copy, Clone)] pub struct Block { pub first_param: usize, pub num_params: usize, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedBlock { pub body: Vec, } // CALL, TAILCALL #[derive(Debug, Copy, Clone)] pub struct Call { pub dest: HighLevelExpressionIndex, pub first_param: usize, pub num_params: usize, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedCall { pub dest: Box, pub params: Vec, } // CALL_SSA #[derive(Debug, Copy, Clone)] pub struct CallSsa { pub dest: HighLevelExpressionIndex, pub first_param: usize, pub num_params: usize, pub dest_memory: u64, pub src_memory: u64, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedCallSsa { pub dest: Box, pub params: Vec, pub dest_memory: u64, pub src_memory: u64, } // CASE #[derive(Debug, Copy, Clone)] pub struct Case { pub first_value: usize, pub num_values: usize, pub body: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedCase { pub values: Vec, pub body: Box, } // CONST, CONST_PTR, IMPORT #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Const { pub constant: u64, } // CONST_DATA #[derive(Debug, Copy, Clone)] pub struct ConstData { pub constant_data_kind: u32, pub constant_data_value: i64, pub size: usize, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedConstData { pub constant_data: ConstantData, } // 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: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedUnaryOp { pub src: Box, } // DEREF_FIELD_SSA #[derive(Debug, Copy, Clone)] pub struct DerefFieldSsa { pub src: HighLevelExpressionIndex, pub src_memory: u64, pub offset: u64, pub member_index: Option, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedDerefFieldSsa { pub src: Box, pub src_memory: u64, pub offset: u64, pub member_index: Option, } // DEREF_SSA #[derive(Debug, Copy, Clone)] pub struct DerefSsa { pub src: HighLevelExpressionIndex, pub src_memory: u64, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedDerefSsa { pub src: Box, pub src_memory: u64, } // EXTERN_PTR #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct ExternPtr { pub constant: u64, pub offset: u64, } // FLOAT_CONST #[derive(Copy, Clone, Debug, PartialEq)] pub struct FloatConst { pub constant: f64, } // FOR #[derive(Debug, Copy, Clone)] pub struct ForLoop { pub init: HighLevelExpressionIndex, pub condition: HighLevelExpressionIndex, pub update: HighLevelExpressionIndex, pub body: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedForLoop { pub init: Box, pub condition: Box, pub update: Box, pub body: Box, } // FOR_SSA #[derive(Debug, Copy, Clone)] pub struct ForLoopSsa { pub init: HighLevelExpressionIndex, pub condition_phi: HighLevelExpressionIndex, pub condition: HighLevelExpressionIndex, pub update: HighLevelExpressionIndex, pub body: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedForLoopSsa { pub init: Box, pub condition_phi: Box, pub condition: Box, pub update: Box, pub body: Box, } // GOTO, LABEL #[derive(Debug, Copy, Clone)] pub struct Label { pub target: u64, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedLabel { pub target: GotoLabel, } impl LiftedLabel { pub fn name(&self) -> String { self.target.name() } pub fn set_name(&self, name: &str) { self.target.set_name(name) } } // IF #[derive(Debug, Copy, Clone)] pub struct If { pub condition: HighLevelExpressionIndex, pub cond_true: HighLevelExpressionIndex, pub cond_false: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedIf { pub condition: Box, pub cond_true: Box, pub cond_false: Box, } // INTRINSIC #[derive(Debug, Copy, Clone)] pub struct Intrinsic { pub intrinsic: u32, pub first_param: usize, pub num_params: usize, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedIntrinsic { pub intrinsic: CoreIntrinsic, pub params: Vec, } // INTRINSIC_SSA #[derive(Debug, Copy, Clone)] pub struct IntrinsicSsa { pub intrinsic: u32, pub first_param: usize, pub num_params: usize, pub dest_memory: u64, pub src_memory: u64, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedIntrinsicSsa { pub intrinsic: CoreIntrinsic, pub params: Vec, pub dest_memory: u64, pub src_memory: u64, } // JUMP #[derive(Debug, Copy, Clone)] pub struct Jump { pub dest: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedJump { pub dest: Box, } // MEM_PHI #[derive(Debug, Copy, Clone)] pub struct MemPhi { pub dest: u64, pub first_src: usize, pub num_srcs: usize, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedMemPhi { pub dest: u64, pub src: Vec, } // RET #[derive(Debug, Copy, Clone)] pub struct Ret { pub first_src: usize, pub num_srcs: usize, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedRet { pub src: Vec, } // SPLIT #[derive(Debug, Copy, Clone)] pub struct Split { pub high: HighLevelExpressionIndex, pub low: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSplit { pub high: Box, pub low: Box, } // STRUCT_FIELD, DEREF_FIELD #[derive(Debug, Copy, Clone)] pub struct StructField { pub src: HighLevelExpressionIndex, pub offset: u64, pub member_index: Option, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedStructField { pub src: Box, pub offset: u64, pub member_index: Option, } // SWITCH #[derive(Debug, Copy, Clone)] pub struct Switch { pub condition: HighLevelExpressionIndex, pub default: HighLevelExpressionIndex, pub first_case: usize, pub num_cases: usize, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSwitch { pub condition: Box, pub default: Box, pub cases: Vec, } // SYSCALL #[derive(Debug, Copy, Clone)] pub struct Syscall { pub first_param: usize, pub num_params: usize, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSyscall { pub params: Vec, } // SYSCALL_SSA #[derive(Debug, Copy, Clone)] pub struct SyscallSsa { pub first_param: usize, pub num_params: usize, pub dest_memory: u64, pub src_memory: u64, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedSyscallSsa { pub params: Vec, pub dest_memory: u64, pub src_memory: u64, } // TRAP #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Trap { pub vector: u64, } // VAR_DECLARE, VAR #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct Var { pub var: Variable, } // VAR_INIT #[derive(Debug, Copy, Clone)] pub struct VarInit { pub dest: Variable, pub src: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedVarInit { pub dest: Variable, pub src: Box, } // VAR_INIT_SSA #[derive(Debug, Copy, Clone)] pub struct VarInitSsa { pub dest: SSAVariable, pub src: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedVarInitSsa { pub dest: SSAVariable, pub src: Box, } // VAR_PHI #[derive(Debug, Copy, Clone)] pub struct VarPhi { pub dest: SSAVariable, pub first_src: usize, pub num_srcs: usize, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedVarPhi { pub dest: SSAVariable, pub src: Vec, } // VAR_SSA #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct VarSsa { pub var: SSAVariable, } // WHILE, DO_WHILE #[derive(Debug, Copy, Clone)] pub struct While { pub condition: HighLevelExpressionIndex, pub body: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedWhile { pub condition: Box, pub body: Box, } // WHILE_SSA, DO_WHILE_SSA #[derive(Debug, Copy, Clone)] pub struct WhileSsa { pub condition_phi: HighLevelExpressionIndex, pub condition: HighLevelExpressionIndex, pub body: HighLevelExpressionIndex, } #[derive(Clone, Debug, PartialEq)] pub struct LiftedWhileSsa { pub condition_phi: Box, pub condition: Box, pub body: Box, }