Skip to main content

binaryninja/high_level_il/
operation.rs

1use binaryninjacore_sys::*;
2use core::ffi;
3use std::fmt::{Debug, Formatter};
4
5use super::{HighLevelExpressionIndex, HighLevelILLiftedInstruction};
6use crate::architecture::CoreIntrinsic;
7use crate::function::Function;
8use crate::rc::Ref;
9use crate::string::{BnString, IntoCStr};
10use crate::variable::{ConstantData, PossibleValueSet, SSAVariable, Variable};
11
12#[derive(Clone, PartialEq, Eq)]
13pub struct GotoLabel {
14    pub(crate) function: Ref<Function>,
15    pub target: u64,
16}
17
18impl GotoLabel {
19    pub fn name(&self) -> String {
20        unsafe { BnString::into_string(BNGetGotoLabelName(self.function.handle, self.target)) }
21    }
22
23    fn set_name(&self, name: &str) {
24        let raw = name.to_cstr();
25        unsafe {
26            BNSetUserGotoLabelName(
27                self.function.handle,
28                self.target,
29                raw.as_ref().as_ptr() as *const ffi::c_char,
30            )
31        }
32    }
33}
34
35impl Debug for GotoLabel {
36    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
37        f.debug_struct("GotoLabel")
38            .field("name", &self.name())
39            .field("target", &self.target)
40            .finish()
41    }
42}
43
44// ADC, SBB, RLC, RRC
45#[derive(Debug, Copy, Clone)]
46pub struct BinaryOpCarry {
47    pub left: HighLevelExpressionIndex,
48    pub right: HighLevelExpressionIndex,
49    pub carry: HighLevelExpressionIndex,
50}
51#[derive(Clone, Debug, PartialEq)]
52pub struct LiftedBinaryOpCarry {
53    pub left: Box<HighLevelILLiftedInstruction>,
54    pub right: Box<HighLevelILLiftedInstruction>,
55    pub carry: Box<HighLevelILLiftedInstruction>,
56}
57
58// 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
59#[derive(Debug, Copy, Clone)]
60pub struct BinaryOp {
61    pub left: HighLevelExpressionIndex,
62    pub right: HighLevelExpressionIndex,
63}
64#[derive(Clone, Debug, PartialEq)]
65pub struct LiftedBinaryOp {
66    pub left: Box<HighLevelILLiftedInstruction>,
67    pub right: Box<HighLevelILLiftedInstruction>,
68}
69
70// ARRAY_INDEX
71#[derive(Debug, Copy, Clone)]
72pub struct ArrayIndex {
73    pub src: HighLevelExpressionIndex,
74    pub index: HighLevelExpressionIndex,
75}
76#[derive(Clone, Debug, PartialEq)]
77pub struct LiftedArrayIndex {
78    pub src: Box<HighLevelILLiftedInstruction>,
79    pub index: Box<HighLevelILLiftedInstruction>,
80}
81
82// ARRAY_INDEX_SSA
83#[derive(Debug, Copy, Clone)]
84pub struct ArrayIndexSsa {
85    pub src: HighLevelExpressionIndex,
86    pub src_memory: u64,
87    pub index: HighLevelExpressionIndex,
88}
89#[derive(Clone, Debug, PartialEq)]
90pub struct LiftedArrayIndexSsa {
91    pub src: Box<HighLevelILLiftedInstruction>,
92    pub src_memory: u64,
93    pub index: Box<HighLevelILLiftedInstruction>,
94}
95
96// ASSERT
97#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
98pub struct Assert {
99    pub src: Variable,
100    pub constraint_index: usize,
101}
102#[derive(Clone, Debug, PartialEq, Eq)]
103pub struct LiftedAssert {
104    pub src: Variable,
105    pub constraint: PossibleValueSet,
106}
107
108// ASSERT_SSA
109#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
110pub struct AssertSsa {
111    pub src: SSAVariable,
112    pub constraint_index: usize,
113}
114#[derive(Clone, Debug, PartialEq, Eq)]
115pub struct LiftedAssertSsa {
116    pub src: SSAVariable,
117    pub constraint: PossibleValueSet,
118}
119
120// ASSIGN
121#[derive(Debug, Copy, Clone)]
122pub struct Assign {
123    pub dest: HighLevelExpressionIndex,
124    pub src: HighLevelExpressionIndex,
125}
126#[derive(Clone, Debug, PartialEq)]
127pub struct LiftedAssign {
128    pub dest: Box<HighLevelILLiftedInstruction>,
129    pub src: Box<HighLevelILLiftedInstruction>,
130}
131
132// ASSIGN_MEM_SSA
133#[derive(Debug, Copy, Clone)]
134pub struct AssignMemSsa {
135    pub dest: HighLevelExpressionIndex,
136    pub dest_memory: u64,
137    pub src: HighLevelExpressionIndex,
138    pub src_memory: u64,
139}
140#[derive(Clone, Debug, PartialEq)]
141pub struct LiftedAssignMemSsa {
142    pub dest: Box<HighLevelILLiftedInstruction>,
143    pub dest_memory: u64,
144    pub src: Box<HighLevelILLiftedInstruction>,
145    pub src_memory: u64,
146}
147
148// ASSIGN_UNPACK
149#[derive(Debug, Copy, Clone)]
150pub struct AssignUnpack {
151    pub first_dest: usize,
152    pub num_dests: usize,
153    pub src: HighLevelExpressionIndex,
154}
155#[derive(Clone, Debug, PartialEq)]
156pub struct LiftedAssignUnpack {
157    pub dest: Vec<HighLevelILLiftedInstruction>,
158    pub src: Box<HighLevelILLiftedInstruction>,
159}
160
161// ASSIGN_UNPACK_MEM_SSA
162#[derive(Debug, Copy, Clone)]
163pub struct AssignUnpackMemSsa {
164    pub first_dest: usize,
165    pub num_dests: usize,
166    pub dest_memory: u64,
167    pub src: HighLevelExpressionIndex,
168    pub src_memory: u64,
169}
170#[derive(Clone, Debug, PartialEq)]
171pub struct LiftedAssignUnpackMemSsa {
172    pub dest: Vec<HighLevelILLiftedInstruction>,
173    pub dest_memory: u64,
174    pub src: Box<HighLevelILLiftedInstruction>,
175    pub src_memory: u64,
176}
177
178// BLOCK
179#[derive(Debug, Copy, Clone)]
180pub struct Block {
181    pub first_param: usize,
182    pub num_params: usize,
183}
184#[derive(Clone, Debug, PartialEq)]
185pub struct LiftedBlock {
186    pub body: Vec<HighLevelILLiftedInstruction>,
187}
188
189// CALL, TAILCALL
190#[derive(Debug, Copy, Clone)]
191pub struct Call {
192    pub dest: HighLevelExpressionIndex,
193    pub first_param: usize,
194    pub num_params: usize,
195}
196#[derive(Clone, Debug, PartialEq)]
197pub struct LiftedCall {
198    pub dest: Box<HighLevelILLiftedInstruction>,
199    pub params: Vec<HighLevelILLiftedInstruction>,
200}
201
202// CALL_SSA
203#[derive(Debug, Copy, Clone)]
204pub struct CallSsa {
205    pub dest: HighLevelExpressionIndex,
206    pub first_param: usize,
207    pub num_params: usize,
208    pub dest_memory: u64,
209    pub src_memory: u64,
210}
211#[derive(Clone, Debug, PartialEq)]
212pub struct LiftedCallSsa {
213    pub dest: Box<HighLevelILLiftedInstruction>,
214    pub params: Vec<HighLevelILLiftedInstruction>,
215    pub dest_memory: u64,
216    pub src_memory: u64,
217}
218
219// CASE
220#[derive(Debug, Copy, Clone)]
221pub struct Case {
222    pub first_value: usize,
223    pub num_values: usize,
224    pub body: HighLevelExpressionIndex,
225}
226#[derive(Clone, Debug, PartialEq)]
227pub struct LiftedCase {
228    pub values: Vec<HighLevelILLiftedInstruction>,
229    pub body: Box<HighLevelILLiftedInstruction>,
230}
231
232// CONST, CONST_PTR, IMPORT
233#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
234pub struct Const {
235    pub constant: u64,
236}
237
238// CONST_DATA
239#[derive(Debug, Copy, Clone)]
240pub struct ConstData {
241    pub constant_data_kind: u32,
242    pub constant_data_value: i64,
243    pub size: usize,
244}
245
246#[derive(Clone, Debug, PartialEq)]
247pub struct LiftedConstData {
248    pub constant_data: ConstantData,
249}
250
251// 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
252#[derive(Debug, Copy, Clone)]
253pub struct UnaryOp {
254    pub src: HighLevelExpressionIndex,
255}
256#[derive(Clone, Debug, PartialEq)]
257pub struct LiftedUnaryOp {
258    pub src: Box<HighLevelILLiftedInstruction>,
259}
260
261// DEREF_FIELD_SSA
262#[derive(Debug, Copy, Clone)]
263pub struct DerefFieldSsa {
264    pub src: HighLevelExpressionIndex,
265    pub src_memory: u64,
266    pub offset: u64,
267    pub member_index: Option<usize>,
268}
269
270#[derive(Clone, Debug, PartialEq)]
271pub struct LiftedDerefFieldSsa {
272    pub src: Box<HighLevelILLiftedInstruction>,
273    pub src_memory: u64,
274    pub offset: u64,
275    pub member_index: Option<usize>,
276}
277
278// DEREF_SSA
279#[derive(Debug, Copy, Clone)]
280pub struct DerefSsa {
281    pub src: HighLevelExpressionIndex,
282    pub src_memory: u64,
283}
284
285#[derive(Clone, Debug, PartialEq)]
286pub struct LiftedDerefSsa {
287    pub src: Box<HighLevelILLiftedInstruction>,
288    pub src_memory: u64,
289}
290
291// EXTERN_PTR
292#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
293pub struct ExternPtr {
294    pub constant: u64,
295    pub offset: u64,
296}
297
298// FLOAT_CONST
299#[derive(Copy, Clone, Debug, PartialEq)]
300pub struct FloatConst {
301    pub constant: f64,
302}
303
304// FOR
305#[derive(Debug, Copy, Clone)]
306pub struct ForLoop {
307    pub init: HighLevelExpressionIndex,
308    pub condition: HighLevelExpressionIndex,
309    pub update: HighLevelExpressionIndex,
310    pub body: HighLevelExpressionIndex,
311}
312
313#[derive(Clone, Debug, PartialEq)]
314pub struct LiftedForLoop {
315    pub init: Box<HighLevelILLiftedInstruction>,
316    pub condition: Box<HighLevelILLiftedInstruction>,
317    pub update: Box<HighLevelILLiftedInstruction>,
318    pub body: Box<HighLevelILLiftedInstruction>,
319}
320
321// FOR_SSA
322#[derive(Debug, Copy, Clone)]
323pub struct ForLoopSsa {
324    pub init: HighLevelExpressionIndex,
325    pub condition_phi: HighLevelExpressionIndex,
326    pub condition: HighLevelExpressionIndex,
327    pub update: HighLevelExpressionIndex,
328    pub body: HighLevelExpressionIndex,
329}
330#[derive(Clone, Debug, PartialEq)]
331pub struct LiftedForLoopSsa {
332    pub init: Box<HighLevelILLiftedInstruction>,
333    pub condition_phi: Box<HighLevelILLiftedInstruction>,
334    pub condition: Box<HighLevelILLiftedInstruction>,
335    pub update: Box<HighLevelILLiftedInstruction>,
336    pub body: Box<HighLevelILLiftedInstruction>,
337}
338
339// FORCE_VER
340#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
341pub struct ForceVer {
342    pub dest: Variable,
343    pub src: Variable,
344}
345
346// FORCE_VER_SSA
347#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
348pub struct ForceVerSsa {
349    pub dest: SSAVariable,
350    pub src: SSAVariable,
351}
352
353// GOTO, LABEL
354#[derive(Debug, Copy, Clone)]
355pub struct Label {
356    pub target: u64,
357}
358#[derive(Clone, Debug, PartialEq)]
359pub struct LiftedLabel {
360    pub target: GotoLabel,
361}
362
363impl LiftedLabel {
364    pub fn name(&self) -> String {
365        self.target.name()
366    }
367
368    pub fn set_name(&self, name: &str) {
369        self.target.set_name(name)
370    }
371}
372
373// IF
374#[derive(Debug, Copy, Clone)]
375pub struct If {
376    pub condition: HighLevelExpressionIndex,
377    pub cond_true: HighLevelExpressionIndex,
378    pub cond_false: HighLevelExpressionIndex,
379}
380#[derive(Clone, Debug, PartialEq)]
381pub struct LiftedIf {
382    pub condition: Box<HighLevelILLiftedInstruction>,
383    pub cond_true: Box<HighLevelILLiftedInstruction>,
384    pub cond_false: Box<HighLevelILLiftedInstruction>,
385}
386
387// INTRINSIC
388#[derive(Debug, Copy, Clone)]
389pub struct Intrinsic {
390    pub intrinsic: u32,
391    pub first_param: usize,
392    pub num_params: usize,
393}
394#[derive(Clone, Debug, PartialEq)]
395pub struct LiftedIntrinsic {
396    pub intrinsic: CoreIntrinsic,
397    pub params: Vec<HighLevelILLiftedInstruction>,
398}
399
400// INTRINSIC_SSA
401#[derive(Debug, Copy, Clone)]
402pub struct IntrinsicSsa {
403    pub intrinsic: u32,
404    pub first_param: usize,
405    pub num_params: usize,
406    pub dest_memory: u64,
407    pub src_memory: u64,
408}
409#[derive(Clone, Debug, PartialEq)]
410pub struct LiftedIntrinsicSsa {
411    pub intrinsic: CoreIntrinsic,
412    pub params: Vec<HighLevelILLiftedInstruction>,
413    pub dest_memory: u64,
414    pub src_memory: u64,
415}
416
417// JUMP
418#[derive(Debug, Copy, Clone)]
419pub struct Jump {
420    pub dest: HighLevelExpressionIndex,
421}
422#[derive(Clone, Debug, PartialEq)]
423pub struct LiftedJump {
424    pub dest: Box<HighLevelILLiftedInstruction>,
425}
426
427// MEM_PHI
428#[derive(Debug, Copy, Clone)]
429pub struct MemPhi {
430    pub dest: u64,
431    pub first_src: usize,
432    pub num_srcs: usize,
433}
434#[derive(Clone, Debug, PartialEq)]
435pub struct LiftedMemPhi {
436    pub dest: u64,
437    pub src: Vec<u64>,
438}
439
440// RET
441#[derive(Debug, Copy, Clone)]
442pub struct Ret {
443    pub first_src: usize,
444    pub num_srcs: usize,
445}
446#[derive(Clone, Debug, PartialEq)]
447pub struct LiftedRet {
448    pub src: Vec<HighLevelILLiftedInstruction>,
449}
450
451// SPLIT
452#[derive(Debug, Copy, Clone)]
453pub struct Split {
454    pub high: HighLevelExpressionIndex,
455    pub low: HighLevelExpressionIndex,
456}
457#[derive(Clone, Debug, PartialEq)]
458pub struct LiftedSplit {
459    pub high: Box<HighLevelILLiftedInstruction>,
460    pub low: Box<HighLevelILLiftedInstruction>,
461}
462
463// STRUCT_FIELD, DEREF_FIELD, STRUCT_INIT_FIELD
464#[derive(Debug, Copy, Clone)]
465pub struct StructField {
466    pub src: HighLevelExpressionIndex,
467    pub offset: u64,
468    pub member_index: Option<usize>,
469}
470#[derive(Clone, Debug, PartialEq)]
471pub struct LiftedStructField {
472    pub src: Box<HighLevelILLiftedInstruction>,
473    pub offset: u64,
474    pub member_index: Option<usize>,
475}
476
477// STRUCT_INIT
478#[derive(Debug, Copy, Clone)]
479pub struct StructInit {
480    pub first_field: usize,
481    pub num_fields: usize,
482}
483#[derive(Clone, Debug, PartialEq)]
484pub struct LiftedStructInit {
485    pub fields: Vec<HighLevelILLiftedInstruction>,
486}
487
488// SWITCH
489#[derive(Debug, Copy, Clone)]
490pub struct Switch {
491    pub condition: HighLevelExpressionIndex,
492    pub default: HighLevelExpressionIndex,
493    pub first_case: usize,
494    pub num_cases: usize,
495}
496#[derive(Clone, Debug, PartialEq)]
497pub struct LiftedSwitch {
498    pub condition: Box<HighLevelILLiftedInstruction>,
499    pub default: Box<HighLevelILLiftedInstruction>,
500    pub cases: Vec<HighLevelILLiftedInstruction>,
501}
502
503// SYSCALL
504#[derive(Debug, Copy, Clone)]
505pub struct Syscall {
506    pub first_param: usize,
507    pub num_params: usize,
508}
509#[derive(Clone, Debug, PartialEq)]
510pub struct LiftedSyscall {
511    pub params: Vec<HighLevelILLiftedInstruction>,
512}
513
514// SYSCALL_SSA
515#[derive(Debug, Copy, Clone)]
516pub struct SyscallSsa {
517    pub first_param: usize,
518    pub num_params: usize,
519    pub dest_memory: u64,
520    pub src_memory: u64,
521}
522#[derive(Clone, Debug, PartialEq)]
523pub struct LiftedSyscallSsa {
524    pub params: Vec<HighLevelILLiftedInstruction>,
525    pub dest_memory: u64,
526    pub src_memory: u64,
527}
528
529// TRAP
530#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
531pub struct Trap {
532    pub vector: u64,
533}
534
535// VAR_DECLARE, VAR
536#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
537pub struct Var {
538    pub var: Variable,
539}
540
541// VAR_INIT
542#[derive(Debug, Copy, Clone)]
543pub struct VarInit {
544    pub dest: Variable,
545    pub src: HighLevelExpressionIndex,
546}
547#[derive(Clone, Debug, PartialEq)]
548pub struct LiftedVarInit {
549    pub dest: Variable,
550    pub src: Box<HighLevelILLiftedInstruction>,
551}
552
553// VAR_INIT_SSA
554#[derive(Debug, Copy, Clone)]
555pub struct VarInitSsa {
556    pub dest: SSAVariable,
557    pub src: HighLevelExpressionIndex,
558}
559#[derive(Clone, Debug, PartialEq)]
560pub struct LiftedVarInitSsa {
561    pub dest: SSAVariable,
562    pub src: Box<HighLevelILLiftedInstruction>,
563}
564
565// VAR_PHI
566#[derive(Debug, Copy, Clone)]
567pub struct VarPhi {
568    pub dest: SSAVariable,
569    pub first_src: usize,
570    pub num_srcs: usize,
571}
572#[derive(Clone, Debug, PartialEq)]
573pub struct LiftedVarPhi {
574    pub dest: SSAVariable,
575    pub src: Vec<SSAVariable>,
576}
577
578// VAR_SSA
579#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
580pub struct VarSsa {
581    pub var: SSAVariable,
582}
583
584// VAR_SSA_PARTIAL
585#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
586pub struct VarSsaPartial {
587    pub dest: SSAVariable,
588    pub prev: SSAVariable,
589}
590
591// WHILE, DO_WHILE
592#[derive(Debug, Copy, Clone)]
593pub struct While {
594    pub condition: HighLevelExpressionIndex,
595    pub body: HighLevelExpressionIndex,
596}
597#[derive(Clone, Debug, PartialEq)]
598pub struct LiftedWhile {
599    pub condition: Box<HighLevelILLiftedInstruction>,
600    pub body: Box<HighLevelILLiftedInstruction>,
601}
602
603// WHILE_SSA, DO_WHILE_SSA
604#[derive(Debug, Copy, Clone)]
605pub struct WhileSsa {
606    pub condition_phi: HighLevelExpressionIndex,
607    pub condition: HighLevelExpressionIndex,
608    pub body: HighLevelExpressionIndex,
609}
610#[derive(Clone, Debug, PartialEq)]
611pub struct LiftedWhileSsa {
612    pub condition_phi: Box<HighLevelILLiftedInstruction>,
613    pub condition: Box<HighLevelILLiftedInstruction>,
614    pub body: Box<HighLevelILLiftedInstruction>,
615}