binaryninja/high_level_il/
lift.rs

1use super::operation::*;
2use super::{HighLevelExpressionIndex, HighLevelILFunction, HighLevelInstructionIndex};
3use std::fmt::{Debug, Formatter};
4
5use crate::architecture::CoreIntrinsic;
6use crate::rc::Ref;
7use crate::variable::{ConstantData, SSAVariable, Variable};
8
9#[derive(Clone, Debug)]
10pub enum HighLevelILLiftedOperand {
11    ConstantData(ConstantData),
12    Expr(HighLevelILLiftedInstruction),
13    ExprList(Vec<HighLevelILLiftedInstruction>),
14    Float(f64),
15    Int(u64),
16    IntList(Vec<u64>),
17    Intrinsic(CoreIntrinsic),
18    Label(GotoLabel),
19    MemberIndex(Option<usize>),
20    Var(Variable),
21    VarSsa(SSAVariable),
22    VarSsaList(Vec<SSAVariable>),
23}
24
25// TODO: UGH, if your gonna call it expr_idx, call the instruction and expression!!!!!
26// TODO: We dont even need to say instruction in the type!
27// TODO: IF you want to have an instruction type, there needs to be a separate expression type
28// TODO: See the lowlevelil module.
29#[derive(Clone, PartialEq)]
30pub struct HighLevelILLiftedInstruction {
31    pub function: Ref<HighLevelILFunction>,
32    pub address: u64,
33    pub instr_index: HighLevelInstructionIndex,
34    pub expr_index: HighLevelExpressionIndex,
35    pub size: usize,
36    pub kind: HighLevelILLiftedInstructionKind,
37}
38
39#[derive(Clone, Debug, PartialEq)]
40pub enum HighLevelILLiftedInstructionKind {
41    Nop,
42    Break,
43    Continue,
44    Noret,
45    Unreachable,
46    Bp,
47    Undef,
48    Unimpl,
49    Adc(LiftedBinaryOpCarry),
50    Sbb(LiftedBinaryOpCarry),
51    Rlc(LiftedBinaryOpCarry),
52    Rrc(LiftedBinaryOpCarry),
53    Add(LiftedBinaryOp),
54    Sub(LiftedBinaryOp),
55    And(LiftedBinaryOp),
56    Or(LiftedBinaryOp),
57    Xor(LiftedBinaryOp),
58    Lsl(LiftedBinaryOp),
59    Lsr(LiftedBinaryOp),
60    Asr(LiftedBinaryOp),
61    Rol(LiftedBinaryOp),
62    Ror(LiftedBinaryOp),
63    Mul(LiftedBinaryOp),
64    MuluDp(LiftedBinaryOp),
65    MulsDp(LiftedBinaryOp),
66    Divu(LiftedBinaryOp),
67    DivuDp(LiftedBinaryOp),
68    Divs(LiftedBinaryOp),
69    DivsDp(LiftedBinaryOp),
70    Modu(LiftedBinaryOp),
71    ModuDp(LiftedBinaryOp),
72    Mods(LiftedBinaryOp),
73    ModsDp(LiftedBinaryOp),
74    MinSigned(LiftedBinaryOp),
75    MaxSigned(LiftedBinaryOp),
76    MinUnsigned(LiftedBinaryOp),
77    MaxUnsigned(LiftedBinaryOp),
78    CmpE(LiftedBinaryOp),
79    CmpNe(LiftedBinaryOp),
80    CmpSlt(LiftedBinaryOp),
81    CmpUlt(LiftedBinaryOp),
82    CmpSle(LiftedBinaryOp),
83    CmpUle(LiftedBinaryOp),
84    CmpSge(LiftedBinaryOp),
85    CmpUge(LiftedBinaryOp),
86    CmpSgt(LiftedBinaryOp),
87    CmpUgt(LiftedBinaryOp),
88    TestBit(LiftedBinaryOp),
89    AddOverflow(LiftedBinaryOp),
90    Fadd(LiftedBinaryOp),
91    Fsub(LiftedBinaryOp),
92    Fmul(LiftedBinaryOp),
93    Fdiv(LiftedBinaryOp),
94    FcmpE(LiftedBinaryOp),
95    FcmpNe(LiftedBinaryOp),
96    FcmpLt(LiftedBinaryOp),
97    FcmpLe(LiftedBinaryOp),
98    FcmpGe(LiftedBinaryOp),
99    FcmpGt(LiftedBinaryOp),
100    FcmpO(LiftedBinaryOp),
101    FcmpUo(LiftedBinaryOp),
102    ArrayIndex(LiftedArrayIndex),
103    ArrayIndexSsa(LiftedArrayIndexSsa),
104    Assign(LiftedAssign),
105    AssignMemSsa(LiftedAssignMemSsa),
106    AssignUnpack(LiftedAssignUnpack),
107    AssignUnpackMemSsa(LiftedAssignUnpackMemSsa),
108    Block(LiftedBlock),
109    Call(LiftedCall),
110    Tailcall(LiftedCall),
111    CallSsa(LiftedCallSsa),
112    Case(LiftedCase),
113    Const(Const),
114    ConstPtr(Const),
115    Import(Const),
116    ConstData(LiftedConstData),
117    Deref(LiftedUnaryOp),
118    AddressOf(LiftedUnaryOp),
119    PassByRef(LiftedUnaryOp),
120    ReturnByRef(LiftedUnaryOp),
121    Neg(LiftedUnaryOp),
122    Not(LiftedUnaryOp),
123    Bswap(LiftedUnaryOp),
124    Popcnt(LiftedUnaryOp),
125    Clz(LiftedUnaryOp),
126    Ctz(LiftedUnaryOp),
127    Rbit(LiftedUnaryOp),
128    Cls(LiftedUnaryOp),
129    Abs(LiftedUnaryOp),
130    Sx(LiftedUnaryOp),
131    Zx(LiftedUnaryOp),
132    LowPart(LiftedUnaryOp),
133    BoolToInt(LiftedUnaryOp),
134    UnimplMem(LiftedUnaryOp),
135    Fsqrt(LiftedUnaryOp),
136    Fneg(LiftedUnaryOp),
137    Fabs(LiftedUnaryOp),
138    FloatToInt(LiftedUnaryOp),
139    IntToFloat(LiftedUnaryOp),
140    FloatConv(LiftedUnaryOp),
141    RoundToInt(LiftedUnaryOp),
142    Floor(LiftedUnaryOp),
143    Ceil(LiftedUnaryOp),
144    Ftrunc(LiftedUnaryOp),
145    DerefFieldSsa(LiftedDerefFieldSsa),
146    DerefSsa(LiftedDerefSsa),
147    ExternPtr(ExternPtr),
148    FloatConst(FloatConst),
149    For(LiftedForLoop),
150    ForSsa(LiftedForLoopSsa),
151    Goto(LiftedLabel),
152    Label(LiftedLabel),
153    If(LiftedIf),
154    Intrinsic(LiftedIntrinsic),
155    IntrinsicSsa(LiftedIntrinsicSsa),
156    Jump(LiftedJump),
157    MemPhi(LiftedMemPhi),
158    Ret(LiftedRet),
159    Split(LiftedSplit),
160    StructField(LiftedStructField),
161    DerefField(LiftedStructField),
162    StructInit(LiftedStructInit),
163    StructInitField(LiftedStructField),
164    Switch(LiftedSwitch),
165    Syscall(LiftedSyscall),
166    SyscallSsa(LiftedSyscallSsa),
167    Trap(Trap),
168    VarDeclare(Var),
169    Var(Var),
170    VarInit(LiftedVarInit),
171    VarInitSsa(LiftedVarInitSsa),
172    VarPhi(LiftedVarPhi),
173    VarSsa(VarSsa),
174    VarSsaPartial(VarSsaPartial),
175    While(LiftedWhile),
176    DoWhile(LiftedWhile),
177    WhileSsa(LiftedWhileSsa),
178    DoWhileSsa(LiftedWhileSsa),
179}
180
181impl HighLevelILLiftedInstruction {
182    pub fn name(&self) -> &'static str {
183        use HighLevelILLiftedInstructionKind::*;
184        match self.kind {
185            Nop => "Nop",
186            Break => "Break",
187            Continue => "Continue",
188            Noret => "Noret",
189            Unreachable => "Unreachable",
190            Bp => "Bp",
191            Undef => "Undef",
192            Unimpl => "Unimpl",
193            Adc(_) => "Adc",
194            Sbb(_) => "Sbb",
195            Rlc(_) => "Rlc",
196            Rrc(_) => "Rrc",
197            Add(_) => "Add",
198            Sub(_) => "Sub",
199            And(_) => "And",
200            Or(_) => "Or",
201            Xor(_) => "Xor",
202            Lsl(_) => "Lsl",
203            Lsr(_) => "Lsr",
204            Asr(_) => "Asr",
205            Rol(_) => "Rol",
206            Ror(_) => "Ror",
207            Mul(_) => "Mul",
208            MuluDp(_) => "MuluDp",
209            MulsDp(_) => "MulsDp",
210            Divu(_) => "Divu",
211            DivuDp(_) => "DivuDp",
212            Divs(_) => "Divs",
213            DivsDp(_) => "DivsDp",
214            Modu(_) => "Modu",
215            ModuDp(_) => "ModuDp",
216            Mods(_) => "Mods",
217            ModsDp(_) => "ModsDp",
218            MinSigned(_) => "MinSigned",
219            MaxSigned(_) => "MaxSigned",
220            MinUnsigned(_) => "MinUnsigned",
221            MaxUnsigned(_) => "MaxUnsigned",
222            CmpE(_) => "CmpE",
223            CmpNe(_) => "CmpNe",
224            CmpSlt(_) => "CmpSlt",
225            CmpUlt(_) => "CmpUlt",
226            CmpSle(_) => "CmpSle",
227            CmpUle(_) => "CmpUle",
228            CmpSge(_) => "CmpSge",
229            CmpUge(_) => "CmpUge",
230            CmpSgt(_) => "CmpSgt",
231            CmpUgt(_) => "CmpUgt",
232            TestBit(_) => "TestBit",
233            AddOverflow(_) => "AddOverflow",
234            Fadd(_) => "Fadd",
235            Fsub(_) => "Fsub",
236            Fmul(_) => "Fmul",
237            Fdiv(_) => "Fdiv",
238            FcmpE(_) => "FcmpE",
239            FcmpNe(_) => "FcmpNe",
240            FcmpLt(_) => "FcmpLt",
241            FcmpLe(_) => "FcmpLe",
242            FcmpGe(_) => "FcmpGe",
243            FcmpGt(_) => "FcmpGt",
244            FcmpO(_) => "FcmpO",
245            FcmpUo(_) => "FcmpUo",
246            ArrayIndex(_) => "ArrayIndex",
247            ArrayIndexSsa(_) => "ArrayIndexSsa",
248            Assign(_) => "Assign",
249            AssignMemSsa(_) => "AssignMemSsa",
250            AssignUnpack(_) => "AssignUnpack",
251            AssignUnpackMemSsa(_) => "AssignUnpackMemSsa",
252            Block(_) => "Block",
253            Call(_) => "Call",
254            Tailcall(_) => "Tailcall",
255            CallSsa(_) => "CallSsa",
256            Case(_) => "Case",
257            Const(_) => "Const",
258            ConstPtr(_) => "ConstPtr",
259            Import(_) => "Import",
260            ConstData(_) => "ConstData",
261            Deref(_) => "Deref",
262            AddressOf(_) => "AddressOf",
263            PassByRef(_) => "PassByRef",
264            ReturnByRef(_) => "ReturnByRef",
265            Neg(_) => "Neg",
266            Not(_) => "Not",
267            Bswap(_) => "Bswap",
268            Popcnt(_) => "Popcnt",
269            Clz(_) => "Clz",
270            Ctz(_) => "Ctz",
271            Rbit(_) => "Rbit",
272            Cls(_) => "Cls",
273            Abs(_) => "Abs",
274            Sx(_) => "Sx",
275            Zx(_) => "Zx",
276            LowPart(_) => "LowPart",
277            BoolToInt(_) => "BoolToInt",
278            UnimplMem(_) => "UnimplMem",
279            Fsqrt(_) => "Fsqrt",
280            Fneg(_) => "Fneg",
281            Fabs(_) => "Fabs",
282            FloatToInt(_) => "FloatToInt",
283            IntToFloat(_) => "IntToFloat",
284            FloatConv(_) => "FloatConv",
285            RoundToInt(_) => "RoundToInt",
286            Floor(_) => "Floor",
287            Ceil(_) => "Ceil",
288            Ftrunc(_) => "Ftrunc",
289            DerefFieldSsa(_) => "DerefFieldSsa",
290            DerefSsa(_) => "DerefSsa",
291            ExternPtr(_) => "ExternPtr",
292            FloatConst(_) => "FloatConst",
293            For(_) => "For",
294            ForSsa(_) => "ForSsa",
295            Goto(_) => "Goto",
296            Label(_) => "Label",
297            If(_) => "If",
298            Intrinsic(_) => "Intrinsic",
299            IntrinsicSsa(_) => "IntrinsicSsa",
300            Jump(_) => "Jump",
301            MemPhi(_) => "MemPhi",
302            Ret(_) => "Ret",
303            Split(_) => "Split",
304            StructField(_) => "StructField",
305            DerefField(_) => "DerefField",
306            StructInit(_) => "StructInit",
307            StructInitField(_) => "StructInitField",
308            Switch(_) => "Switch",
309            Syscall(_) => "Syscall",
310            SyscallSsa(_) => "SyscallSsa",
311            Trap(_) => "Trap",
312            VarDeclare(_) => "VarDeclare",
313            Var(_) => "Var",
314            VarInit(_) => "VarInit",
315            VarInitSsa(_) => "VarInitSsa",
316            VarPhi(_) => "VarPhi",
317            VarSsa(_) => "VarSsa",
318            VarSsaPartial(_) => "VarSsaPartial",
319            While(_) => "While",
320            DoWhile(_) => "DoWhile",
321            WhileSsa(_) => "WhileSsa",
322            DoWhileSsa(_) => "DoWhileSsa",
323        }
324    }
325
326    pub fn operands(&self) -> Vec<(&'static str, HighLevelILLiftedOperand)> {
327        use HighLevelILLiftedInstructionKind::*;
328        use HighLevelILLiftedOperand as Operand;
329        match &self.kind {
330            Nop | Break | Continue | Noret | Unreachable | Bp | Undef | Unimpl => vec![],
331            Adc(op) | Sbb(op) | Rlc(op) | Rrc(op) => vec![
332                ("left", Operand::Expr(*op.left.clone())),
333                ("right", Operand::Expr(*op.right.clone())),
334                ("carry", Operand::Expr(*op.carry.clone())),
335            ],
336            Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op)
337            | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op)
338            | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op)
339            | MinSigned(op) | MaxSigned(op) | MinUnsigned(op) | MaxUnsigned(op) | CmpE(op)
340            | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op)
341            | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | Fadd(op)
342            | Fsub(op) | Fmul(op) | Fdiv(op) | FcmpE(op) | FcmpNe(op) | FcmpLt(op) | FcmpLe(op)
343            | FcmpGe(op) | FcmpGt(op) | FcmpO(op) | FcmpUo(op) => vec![
344                ("left", Operand::Expr(*op.left.clone())),
345                ("right", Operand::Expr(*op.right.clone())),
346            ],
347            ArrayIndex(op) => vec![
348                ("src", Operand::Expr(*op.src.clone())),
349                ("index", Operand::Expr(*op.index.clone())),
350            ],
351            ArrayIndexSsa(op) => vec![
352                ("src", Operand::Expr(*op.src.clone())),
353                ("src_memory", Operand::Int(op.src_memory)),
354                ("index", Operand::Expr(*op.index.clone())),
355            ],
356            Assign(op) => vec![
357                ("dest", Operand::Expr(*op.dest.clone())),
358                ("src", Operand::Expr(*op.src.clone())),
359            ],
360            AssignMemSsa(op) => vec![
361                ("dest", Operand::Expr(*op.dest.clone())),
362                ("dest_memory", Operand::Int(op.dest_memory)),
363                ("src", Operand::Expr(*op.src.clone())),
364                ("src_memory", Operand::Int(op.src_memory)),
365            ],
366            AssignUnpack(op) => vec![
367                ("dest", Operand::ExprList(op.dest.clone())),
368                ("src", Operand::Expr(*op.src.clone())),
369            ],
370            AssignUnpackMemSsa(op) => vec![
371                ("dest", Operand::ExprList(op.dest.clone())),
372                ("dest_memory", Operand::Int(op.dest_memory)),
373                ("src", Operand::Expr(*op.src.clone())),
374                ("src_memory", Operand::Int(op.src_memory)),
375            ],
376            Block(op) => vec![("body", Operand::ExprList(op.body.clone()))],
377            Call(op) | Tailcall(op) => vec![
378                ("dest", Operand::Expr(*op.dest.clone())),
379                ("params", Operand::ExprList(op.params.clone())),
380            ],
381            CallSsa(op) => vec![
382                ("dest", Operand::Expr(*op.dest.clone())),
383                ("params", Operand::ExprList(op.params.clone())),
384                ("dest_memory", Operand::Int(op.dest_memory)),
385                ("src_memory", Operand::Int(op.src_memory)),
386            ],
387            Case(op) => vec![
388                ("values", Operand::ExprList(op.values.clone())),
389                ("body", Operand::Expr(*op.body.clone())),
390            ],
391            Const(op) | ConstPtr(op) | Import(op) => vec![("constant", Operand::Int(op.constant))],
392            ConstData(op) => vec![(
393                "constant_data",
394                Operand::ConstantData(op.constant_data.clone()),
395            )],
396            Deref(op) | AddressOf(op) | PassByRef(op) | ReturnByRef(op) | Neg(op) | Not(op)
397            | Bswap(op) | Popcnt(op) | Clz(op) | Ctz(op) | Rbit(op) | Cls(op) | Abs(op)
398            | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op) | Fsqrt(op)
399            | Fneg(op) | Fabs(op) | FloatToInt(op) | IntToFloat(op) | FloatConv(op)
400            | RoundToInt(op) | Floor(op) | Ceil(op) | Ftrunc(op) => {
401                vec![("src", Operand::Expr(*op.src.clone()))]
402            }
403            DerefFieldSsa(op) => vec![
404                ("src", Operand::Expr(*op.src.clone())),
405                ("src_memory", Operand::Int(op.src_memory)),
406                ("offset", Operand::Int(op.offset)),
407                ("member_index", Operand::MemberIndex(op.member_index)),
408            ],
409            DerefSsa(op) => vec![
410                ("src", Operand::Expr(*op.src.clone())),
411                ("src_memory", Operand::Int(op.src_memory)),
412            ],
413            ExternPtr(op) => vec![
414                ("constant", Operand::Int(op.constant)),
415                ("offset", Operand::Int(op.offset)),
416            ],
417            FloatConst(op) => vec![("constant", Operand::Float(op.constant))],
418            For(op) => vec![
419                ("init", Operand::Expr(*op.init.clone())),
420                ("condition", Operand::Expr(*op.condition.clone())),
421                ("update", Operand::Expr(*op.update.clone())),
422                ("body", Operand::Expr(*op.body.clone())),
423            ],
424            ForSsa(op) => vec![
425                ("init", Operand::Expr(*op.init.clone())),
426                ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
427                ("condition", Operand::Expr(*op.condition.clone())),
428                ("update", Operand::Expr(*op.update.clone())),
429                ("body", Operand::Expr(*op.body.clone())),
430            ],
431            Goto(op) | Label(op) => vec![("target", Operand::Label(op.target.clone()))],
432            If(op) => vec![
433                ("condition", Operand::Expr(*op.condition.clone())),
434                ("cond_true", Operand::Expr(*op.cond_true.clone())),
435                ("cond_false", Operand::Expr(*op.cond_false.clone())),
436            ],
437            Intrinsic(op) => vec![
438                ("intrinsic", Operand::Intrinsic(op.intrinsic)),
439                ("params", Operand::ExprList(op.params.clone())),
440            ],
441            IntrinsicSsa(op) => vec![
442                ("intrinsic", Operand::Intrinsic(op.intrinsic)),
443                ("params", Operand::ExprList(op.params.clone())),
444                ("dest_memory", Operand::Int(op.dest_memory)),
445                ("src_memory", Operand::Int(op.src_memory)),
446            ],
447            Jump(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
448            MemPhi(op) => vec![
449                ("dest", Operand::Int(op.dest)),
450                ("src", Operand::IntList(op.src.clone())),
451            ],
452            Ret(op) => vec![("src", Operand::ExprList(op.src.clone()))],
453            Split(op) => vec![
454                ("high", Operand::Expr(*op.high.clone())),
455                ("low", Operand::Expr(*op.low.clone())),
456            ],
457            StructField(op) | DerefField(op) => vec![
458                ("src", Operand::Expr(*op.src.clone())),
459                ("offset", Operand::Int(op.offset)),
460                ("member_index", Operand::MemberIndex(op.member_index)),
461            ],
462            StructInit(op) => vec![("fields", Operand::ExprList(op.fields.clone()))],
463            StructInitField(op) => vec![
464                ("offset", Operand::Int(op.offset)),
465                ("member_index", Operand::MemberIndex(op.member_index)),
466                ("src", Operand::Expr(*op.src.clone())),
467            ],
468            Switch(op) => vec![
469                ("condition", Operand::Expr(*op.condition.clone())),
470                ("default", Operand::Expr(*op.default.clone())),
471                ("cases", Operand::ExprList(op.cases.clone())),
472            ],
473            Syscall(op) => vec![("params", Operand::ExprList(op.params.clone()))],
474            SyscallSsa(op) => vec![
475                ("params", Operand::ExprList(op.params.clone())),
476                ("dest_memory", Operand::Int(op.dest_memory)),
477                ("src_memory", Operand::Int(op.src_memory)),
478            ],
479            Trap(op) => vec![("vector", Operand::Int(op.vector))],
480            VarDeclare(op) | Var(op) => vec![("var", Operand::Var(op.var))],
481            VarInit(op) => vec![
482                ("dest", Operand::Var(op.dest)),
483                ("src", Operand::Expr(*op.src.clone())),
484            ],
485            VarInitSsa(op) => vec![
486                ("dest", Operand::VarSsa(op.dest)),
487                ("src", Operand::Expr(*op.src.clone())),
488            ],
489            VarPhi(op) => vec![
490                ("dest", Operand::VarSsa(op.dest)),
491                ("src", Operand::VarSsaList(op.src.clone())),
492            ],
493            VarSsa(op) => vec![("var", Operand::VarSsa(op.var))],
494            VarSsaPartial(op) => vec![
495                ("dest", Operand::VarSsa(op.dest)),
496                ("prev", Operand::VarSsa(op.prev)),
497            ],
498            While(op) | DoWhile(op) => vec![
499                ("condition", Operand::Expr(*op.condition.clone())),
500                ("body", Operand::Expr(*op.body.clone())),
501            ],
502            WhileSsa(op) | DoWhileSsa(op) => vec![
503                ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
504                ("condition", Operand::Expr(*op.condition.clone())),
505                ("body", Operand::Expr(*op.body.clone())),
506            ],
507        }
508    }
509}
510
511impl Debug for HighLevelILLiftedInstruction {
512    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
513        f.debug_struct("HighLevelILLiftedInstruction")
514            .field("address", &self.address)
515            .field("expr_index", &self.expr_index)
516            .field("size", &self.size)
517            .field("kind", &self.kind)
518            .finish()
519    }
520}