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, 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// ASSIGN
97#[derive(Debug, Copy, Clone)]
98pub struct Assign {
99    pub dest: HighLevelExpressionIndex,
100    pub src: HighLevelExpressionIndex,
101}
102#[derive(Clone, Debug, PartialEq)]
103pub struct LiftedAssign {
104    pub dest: Box<HighLevelILLiftedInstruction>,
105    pub src: Box<HighLevelILLiftedInstruction>,
106}
107
108// ASSIGN_MEM_SSA
109#[derive(Debug, Copy, Clone)]
110pub struct AssignMemSsa {
111    pub dest: HighLevelExpressionIndex,
112    pub dest_memory: u64,
113    pub src: HighLevelExpressionIndex,
114    pub src_memory: u64,
115}
116#[derive(Clone, Debug, PartialEq)]
117pub struct LiftedAssignMemSsa {
118    pub dest: Box<HighLevelILLiftedInstruction>,
119    pub dest_memory: u64,
120    pub src: Box<HighLevelILLiftedInstruction>,
121    pub src_memory: u64,
122}
123
124// ASSIGN_UNPACK
125#[derive(Debug, Copy, Clone)]
126pub struct AssignUnpack {
127    pub first_dest: usize,
128    pub num_dests: usize,
129    pub src: HighLevelExpressionIndex,
130}
131#[derive(Clone, Debug, PartialEq)]
132pub struct LiftedAssignUnpack {
133    pub dest: Vec<HighLevelILLiftedInstruction>,
134    pub src: Box<HighLevelILLiftedInstruction>,
135}
136
137// ASSIGN_UNPACK_MEM_SSA
138#[derive(Debug, Copy, Clone)]
139pub struct AssignUnpackMemSsa {
140    pub first_dest: usize,
141    pub num_dests: usize,
142    pub dest_memory: u64,
143    pub src: HighLevelExpressionIndex,
144    pub src_memory: u64,
145}
146#[derive(Clone, Debug, PartialEq)]
147pub struct LiftedAssignUnpackMemSsa {
148    pub dest: Vec<HighLevelILLiftedInstruction>,
149    pub dest_memory: u64,
150    pub src: Box<HighLevelILLiftedInstruction>,
151    pub src_memory: u64,
152}
153
154// BLOCK
155#[derive(Debug, Copy, Clone)]
156pub struct Block {
157    pub first_param: usize,
158    pub num_params: usize,
159}
160#[derive(Clone, Debug, PartialEq)]
161pub struct LiftedBlock {
162    pub body: Vec<HighLevelILLiftedInstruction>,
163}
164
165// CALL, TAILCALL
166#[derive(Debug, Copy, Clone)]
167pub struct Call {
168    pub dest: HighLevelExpressionIndex,
169    pub first_param: usize,
170    pub num_params: usize,
171}
172#[derive(Clone, Debug, PartialEq)]
173pub struct LiftedCall {
174    pub dest: Box<HighLevelILLiftedInstruction>,
175    pub params: Vec<HighLevelILLiftedInstruction>,
176}
177
178// CALL_SSA
179#[derive(Debug, Copy, Clone)]
180pub struct CallSsa {
181    pub dest: HighLevelExpressionIndex,
182    pub first_param: usize,
183    pub num_params: usize,
184    pub dest_memory: u64,
185    pub src_memory: u64,
186}
187#[derive(Clone, Debug, PartialEq)]
188pub struct LiftedCallSsa {
189    pub dest: Box<HighLevelILLiftedInstruction>,
190    pub params: Vec<HighLevelILLiftedInstruction>,
191    pub dest_memory: u64,
192    pub src_memory: u64,
193}
194
195// CASE
196#[derive(Debug, Copy, Clone)]
197pub struct Case {
198    pub first_value: usize,
199    pub num_values: usize,
200    pub body: HighLevelExpressionIndex,
201}
202#[derive(Clone, Debug, PartialEq)]
203pub struct LiftedCase {
204    pub values: Vec<HighLevelILLiftedInstruction>,
205    pub body: Box<HighLevelILLiftedInstruction>,
206}
207
208// CONST, CONST_PTR, IMPORT
209#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
210pub struct Const {
211    pub constant: u64,
212}
213
214// CONST_DATA
215#[derive(Debug, Copy, Clone)]
216pub struct ConstData {
217    pub constant_data_kind: u32,
218    pub constant_data_value: i64,
219    pub size: usize,
220}
221
222#[derive(Clone, Debug, PartialEq)]
223pub struct LiftedConstData {
224    pub constant_data: ConstantData,
225}
226
227// 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
228#[derive(Debug, Copy, Clone)]
229pub struct UnaryOp {
230    pub src: HighLevelExpressionIndex,
231}
232#[derive(Clone, Debug, PartialEq)]
233pub struct LiftedUnaryOp {
234    pub src: Box<HighLevelILLiftedInstruction>,
235}
236
237// DEREF_FIELD_SSA
238#[derive(Debug, Copy, Clone)]
239pub struct DerefFieldSsa {
240    pub src: HighLevelExpressionIndex,
241    pub src_memory: u64,
242    pub offset: u64,
243    pub member_index: Option<usize>,
244}
245
246#[derive(Clone, Debug, PartialEq)]
247pub struct LiftedDerefFieldSsa {
248    pub src: Box<HighLevelILLiftedInstruction>,
249    pub src_memory: u64,
250    pub offset: u64,
251    pub member_index: Option<usize>,
252}
253
254// DEREF_SSA
255#[derive(Debug, Copy, Clone)]
256pub struct DerefSsa {
257    pub src: HighLevelExpressionIndex,
258    pub src_memory: u64,
259}
260
261#[derive(Clone, Debug, PartialEq)]
262pub struct LiftedDerefSsa {
263    pub src: Box<HighLevelILLiftedInstruction>,
264    pub src_memory: u64,
265}
266
267// EXTERN_PTR
268#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
269pub struct ExternPtr {
270    pub constant: u64,
271    pub offset: u64,
272}
273
274// FLOAT_CONST
275#[derive(Copy, Clone, Debug, PartialEq)]
276pub struct FloatConst {
277    pub constant: f64,
278}
279
280// FOR
281#[derive(Debug, Copy, Clone)]
282pub struct ForLoop {
283    pub init: HighLevelExpressionIndex,
284    pub condition: HighLevelExpressionIndex,
285    pub update: HighLevelExpressionIndex,
286    pub body: HighLevelExpressionIndex,
287}
288
289#[derive(Clone, Debug, PartialEq)]
290pub struct LiftedForLoop {
291    pub init: Box<HighLevelILLiftedInstruction>,
292    pub condition: Box<HighLevelILLiftedInstruction>,
293    pub update: Box<HighLevelILLiftedInstruction>,
294    pub body: Box<HighLevelILLiftedInstruction>,
295}
296
297// FOR_SSA
298#[derive(Debug, Copy, Clone)]
299pub struct ForLoopSsa {
300    pub init: HighLevelExpressionIndex,
301    pub condition_phi: HighLevelExpressionIndex,
302    pub condition: HighLevelExpressionIndex,
303    pub update: HighLevelExpressionIndex,
304    pub body: HighLevelExpressionIndex,
305}
306#[derive(Clone, Debug, PartialEq)]
307pub struct LiftedForLoopSsa {
308    pub init: Box<HighLevelILLiftedInstruction>,
309    pub condition_phi: Box<HighLevelILLiftedInstruction>,
310    pub condition: Box<HighLevelILLiftedInstruction>,
311    pub update: Box<HighLevelILLiftedInstruction>,
312    pub body: Box<HighLevelILLiftedInstruction>,
313}
314
315// GOTO, LABEL
316#[derive(Debug, Copy, Clone)]
317pub struct Label {
318    pub target: u64,
319}
320#[derive(Clone, Debug, PartialEq)]
321pub struct LiftedLabel {
322    pub target: GotoLabel,
323}
324
325impl LiftedLabel {
326    pub fn name(&self) -> String {
327        self.target.name()
328    }
329
330    pub fn set_name(&self, name: &str) {
331        self.target.set_name(name)
332    }
333}
334
335// IF
336#[derive(Debug, Copy, Clone)]
337pub struct If {
338    pub condition: HighLevelExpressionIndex,
339    pub cond_true: HighLevelExpressionIndex,
340    pub cond_false: HighLevelExpressionIndex,
341}
342#[derive(Clone, Debug, PartialEq)]
343pub struct LiftedIf {
344    pub condition: Box<HighLevelILLiftedInstruction>,
345    pub cond_true: Box<HighLevelILLiftedInstruction>,
346    pub cond_false: Box<HighLevelILLiftedInstruction>,
347}
348
349// INTRINSIC
350#[derive(Debug, Copy, Clone)]
351pub struct Intrinsic {
352    pub intrinsic: u32,
353    pub first_param: usize,
354    pub num_params: usize,
355}
356#[derive(Clone, Debug, PartialEq)]
357pub struct LiftedIntrinsic {
358    pub intrinsic: CoreIntrinsic,
359    pub params: Vec<HighLevelILLiftedInstruction>,
360}
361
362// INTRINSIC_SSA
363#[derive(Debug, Copy, Clone)]
364pub struct IntrinsicSsa {
365    pub intrinsic: u32,
366    pub first_param: usize,
367    pub num_params: usize,
368    pub dest_memory: u64,
369    pub src_memory: u64,
370}
371#[derive(Clone, Debug, PartialEq)]
372pub struct LiftedIntrinsicSsa {
373    pub intrinsic: CoreIntrinsic,
374    pub params: Vec<HighLevelILLiftedInstruction>,
375    pub dest_memory: u64,
376    pub src_memory: u64,
377}
378
379// JUMP
380#[derive(Debug, Copy, Clone)]
381pub struct Jump {
382    pub dest: HighLevelExpressionIndex,
383}
384#[derive(Clone, Debug, PartialEq)]
385pub struct LiftedJump {
386    pub dest: Box<HighLevelILLiftedInstruction>,
387}
388
389// MEM_PHI
390#[derive(Debug, Copy, Clone)]
391pub struct MemPhi {
392    pub dest: u64,
393    pub first_src: usize,
394    pub num_srcs: usize,
395}
396#[derive(Clone, Debug, PartialEq)]
397pub struct LiftedMemPhi {
398    pub dest: u64,
399    pub src: Vec<u64>,
400}
401
402// RET
403#[derive(Debug, Copy, Clone)]
404pub struct Ret {
405    pub first_src: usize,
406    pub num_srcs: usize,
407}
408#[derive(Clone, Debug, PartialEq)]
409pub struct LiftedRet {
410    pub src: Vec<HighLevelILLiftedInstruction>,
411}
412
413// SPLIT
414#[derive(Debug, Copy, Clone)]
415pub struct Split {
416    pub high: HighLevelExpressionIndex,
417    pub low: HighLevelExpressionIndex,
418}
419#[derive(Clone, Debug, PartialEq)]
420pub struct LiftedSplit {
421    pub high: Box<HighLevelILLiftedInstruction>,
422    pub low: Box<HighLevelILLiftedInstruction>,
423}
424
425// STRUCT_FIELD, DEREF_FIELD
426#[derive(Debug, Copy, Clone)]
427pub struct StructField {
428    pub src: HighLevelExpressionIndex,
429    pub offset: u64,
430    pub member_index: Option<usize>,
431}
432#[derive(Clone, Debug, PartialEq)]
433pub struct LiftedStructField {
434    pub src: Box<HighLevelILLiftedInstruction>,
435    pub offset: u64,
436    pub member_index: Option<usize>,
437}
438
439// SWITCH
440#[derive(Debug, Copy, Clone)]
441pub struct Switch {
442    pub condition: HighLevelExpressionIndex,
443    pub default: HighLevelExpressionIndex,
444    pub first_case: usize,
445    pub num_cases: usize,
446}
447#[derive(Clone, Debug, PartialEq)]
448pub struct LiftedSwitch {
449    pub condition: Box<HighLevelILLiftedInstruction>,
450    pub default: Box<HighLevelILLiftedInstruction>,
451    pub cases: Vec<HighLevelILLiftedInstruction>,
452}
453
454// SYSCALL
455#[derive(Debug, Copy, Clone)]
456pub struct Syscall {
457    pub first_param: usize,
458    pub num_params: usize,
459}
460#[derive(Clone, Debug, PartialEq)]
461pub struct LiftedSyscall {
462    pub params: Vec<HighLevelILLiftedInstruction>,
463}
464
465// SYSCALL_SSA
466#[derive(Debug, Copy, Clone)]
467pub struct SyscallSsa {
468    pub first_param: usize,
469    pub num_params: usize,
470    pub dest_memory: u64,
471    pub src_memory: u64,
472}
473#[derive(Clone, Debug, PartialEq)]
474pub struct LiftedSyscallSsa {
475    pub params: Vec<HighLevelILLiftedInstruction>,
476    pub dest_memory: u64,
477    pub src_memory: u64,
478}
479
480// TRAP
481#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
482pub struct Trap {
483    pub vector: u64,
484}
485
486// VAR_DECLARE, VAR
487#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
488pub struct Var {
489    pub var: Variable,
490}
491
492// VAR_INIT
493#[derive(Debug, Copy, Clone)]
494pub struct VarInit {
495    pub dest: Variable,
496    pub src: HighLevelExpressionIndex,
497}
498#[derive(Clone, Debug, PartialEq)]
499pub struct LiftedVarInit {
500    pub dest: Variable,
501    pub src: Box<HighLevelILLiftedInstruction>,
502}
503
504// VAR_INIT_SSA
505#[derive(Debug, Copy, Clone)]
506pub struct VarInitSsa {
507    pub dest: SSAVariable,
508    pub src: HighLevelExpressionIndex,
509}
510#[derive(Clone, Debug, PartialEq)]
511pub struct LiftedVarInitSsa {
512    pub dest: SSAVariable,
513    pub src: Box<HighLevelILLiftedInstruction>,
514}
515
516// VAR_PHI
517#[derive(Debug, Copy, Clone)]
518pub struct VarPhi {
519    pub dest: SSAVariable,
520    pub first_src: usize,
521    pub num_srcs: usize,
522}
523#[derive(Clone, Debug, PartialEq)]
524pub struct LiftedVarPhi {
525    pub dest: SSAVariable,
526    pub src: Vec<SSAVariable>,
527}
528
529// VAR_SSA
530#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
531pub struct VarSsa {
532    pub var: SSAVariable,
533}
534
535// WHILE, DO_WHILE
536#[derive(Debug, Copy, Clone)]
537pub struct While {
538    pub condition: HighLevelExpressionIndex,
539    pub body: HighLevelExpressionIndex,
540}
541#[derive(Clone, Debug, PartialEq)]
542pub struct LiftedWhile {
543    pub condition: Box<HighLevelILLiftedInstruction>,
544    pub body: Box<HighLevelILLiftedInstruction>,
545}
546
547// WHILE_SSA, DO_WHILE_SSA
548#[derive(Debug, Copy, Clone)]
549pub struct WhileSsa {
550    pub condition_phi: HighLevelExpressionIndex,
551    pub condition: HighLevelExpressionIndex,
552    pub body: HighLevelExpressionIndex,
553}
554#[derive(Clone, Debug, PartialEq)]
555pub struct LiftedWhileSsa {
556    pub condition_phi: Box<HighLevelILLiftedInstruction>,
557    pub condition: Box<HighLevelILLiftedInstruction>,
558    pub body: Box<HighLevelILLiftedInstruction>,
559}