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    Switch(LiftedSwitch),
163    Syscall(LiftedSyscall),
164    SyscallSsa(LiftedSyscallSsa),
165    Trap(Trap),
166    VarDeclare(Var),
167    Var(Var),
168    VarInit(LiftedVarInit),
169    VarInitSsa(LiftedVarInitSsa),
170    VarPhi(LiftedVarPhi),
171    VarSsa(VarSsa),
172    VarSsaPartial(VarSsaPartial),
173    While(LiftedWhile),
174    DoWhile(LiftedWhile),
175    WhileSsa(LiftedWhileSsa),
176    DoWhileSsa(LiftedWhileSsa),
177}
178
179impl HighLevelILLiftedInstruction {
180    pub fn name(&self) -> &'static str {
181        use HighLevelILLiftedInstructionKind::*;
182        match self.kind {
183            Nop => "Nop",
184            Break => "Break",
185            Continue => "Continue",
186            Noret => "Noret",
187            Unreachable => "Unreachable",
188            Bp => "Bp",
189            Undef => "Undef",
190            Unimpl => "Unimpl",
191            Adc(_) => "Adc",
192            Sbb(_) => "Sbb",
193            Rlc(_) => "Rlc",
194            Rrc(_) => "Rrc",
195            Add(_) => "Add",
196            Sub(_) => "Sub",
197            And(_) => "And",
198            Or(_) => "Or",
199            Xor(_) => "Xor",
200            Lsl(_) => "Lsl",
201            Lsr(_) => "Lsr",
202            Asr(_) => "Asr",
203            Rol(_) => "Rol",
204            Ror(_) => "Ror",
205            Mul(_) => "Mul",
206            MuluDp(_) => "MuluDp",
207            MulsDp(_) => "MulsDp",
208            Divu(_) => "Divu",
209            DivuDp(_) => "DivuDp",
210            Divs(_) => "Divs",
211            DivsDp(_) => "DivsDp",
212            Modu(_) => "Modu",
213            ModuDp(_) => "ModuDp",
214            Mods(_) => "Mods",
215            ModsDp(_) => "ModsDp",
216            MinSigned(_) => "MinSigned",
217            MaxSigned(_) => "MaxSigned",
218            MinUnsigned(_) => "MinUnsigned",
219            MaxUnsigned(_) => "MaxUnsigned",
220            CmpE(_) => "CmpE",
221            CmpNe(_) => "CmpNe",
222            CmpSlt(_) => "CmpSlt",
223            CmpUlt(_) => "CmpUlt",
224            CmpSle(_) => "CmpSle",
225            CmpUle(_) => "CmpUle",
226            CmpSge(_) => "CmpSge",
227            CmpUge(_) => "CmpUge",
228            CmpSgt(_) => "CmpSgt",
229            CmpUgt(_) => "CmpUgt",
230            TestBit(_) => "TestBit",
231            AddOverflow(_) => "AddOverflow",
232            Fadd(_) => "Fadd",
233            Fsub(_) => "Fsub",
234            Fmul(_) => "Fmul",
235            Fdiv(_) => "Fdiv",
236            FcmpE(_) => "FcmpE",
237            FcmpNe(_) => "FcmpNe",
238            FcmpLt(_) => "FcmpLt",
239            FcmpLe(_) => "FcmpLe",
240            FcmpGe(_) => "FcmpGe",
241            FcmpGt(_) => "FcmpGt",
242            FcmpO(_) => "FcmpO",
243            FcmpUo(_) => "FcmpUo",
244            ArrayIndex(_) => "ArrayIndex",
245            ArrayIndexSsa(_) => "ArrayIndexSsa",
246            Assign(_) => "Assign",
247            AssignMemSsa(_) => "AssignMemSsa",
248            AssignUnpack(_) => "AssignUnpack",
249            AssignUnpackMemSsa(_) => "AssignUnpackMemSsa",
250            Block(_) => "Block",
251            Call(_) => "Call",
252            Tailcall(_) => "Tailcall",
253            CallSsa(_) => "CallSsa",
254            Case(_) => "Case",
255            Const(_) => "Const",
256            ConstPtr(_) => "ConstPtr",
257            Import(_) => "Import",
258            ConstData(_) => "ConstData",
259            Deref(_) => "Deref",
260            AddressOf(_) => "AddressOf",
261            PassByRef(_) => "PassByRef",
262            ReturnByRef(_) => "ReturnByRef",
263            Neg(_) => "Neg",
264            Not(_) => "Not",
265            Bswap(_) => "Bswap",
266            Popcnt(_) => "Popcnt",
267            Clz(_) => "Clz",
268            Ctz(_) => "Ctz",
269            Rbit(_) => "Rbit",
270            Cls(_) => "Cls",
271            Abs(_) => "Abs",
272            Sx(_) => "Sx",
273            Zx(_) => "Zx",
274            LowPart(_) => "LowPart",
275            BoolToInt(_) => "BoolToInt",
276            UnimplMem(_) => "UnimplMem",
277            Fsqrt(_) => "Fsqrt",
278            Fneg(_) => "Fneg",
279            Fabs(_) => "Fabs",
280            FloatToInt(_) => "FloatToInt",
281            IntToFloat(_) => "IntToFloat",
282            FloatConv(_) => "FloatConv",
283            RoundToInt(_) => "RoundToInt",
284            Floor(_) => "Floor",
285            Ceil(_) => "Ceil",
286            Ftrunc(_) => "Ftrunc",
287            DerefFieldSsa(_) => "DerefFieldSsa",
288            DerefSsa(_) => "DerefSsa",
289            ExternPtr(_) => "ExternPtr",
290            FloatConst(_) => "FloatConst",
291            For(_) => "For",
292            ForSsa(_) => "ForSsa",
293            Goto(_) => "Goto",
294            Label(_) => "Label",
295            If(_) => "If",
296            Intrinsic(_) => "Intrinsic",
297            IntrinsicSsa(_) => "IntrinsicSsa",
298            Jump(_) => "Jump",
299            MemPhi(_) => "MemPhi",
300            Ret(_) => "Ret",
301            Split(_) => "Split",
302            StructField(_) => "StructField",
303            DerefField(_) => "DerefField",
304            Switch(_) => "Switch",
305            Syscall(_) => "Syscall",
306            SyscallSsa(_) => "SyscallSsa",
307            Trap(_) => "Trap",
308            VarDeclare(_) => "VarDeclare",
309            Var(_) => "Var",
310            VarInit(_) => "VarInit",
311            VarInitSsa(_) => "VarInitSsa",
312            VarPhi(_) => "VarPhi",
313            VarSsa(_) => "VarSsa",
314            VarSsaPartial(_) => "VarSsaPartial",
315            While(_) => "While",
316            DoWhile(_) => "DoWhile",
317            WhileSsa(_) => "WhileSsa",
318            DoWhileSsa(_) => "DoWhileSsa",
319        }
320    }
321
322    pub fn operands(&self) -> Vec<(&'static str, HighLevelILLiftedOperand)> {
323        use HighLevelILLiftedInstructionKind::*;
324        use HighLevelILLiftedOperand as Operand;
325        match &self.kind {
326            Nop | Break | Continue | Noret | Unreachable | Bp | Undef | Unimpl => vec![],
327            Adc(op) | Sbb(op) | Rlc(op) | Rrc(op) => vec![
328                ("left", Operand::Expr(*op.left.clone())),
329                ("right", Operand::Expr(*op.right.clone())),
330                ("carry", Operand::Expr(*op.carry.clone())),
331            ],
332            Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op)
333            | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op)
334            | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op)
335            | MinSigned(op) | MaxSigned(op) | MinUnsigned(op) | MaxUnsigned(op) | CmpE(op)
336            | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op)
337            | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | Fadd(op)
338            | Fsub(op) | Fmul(op) | Fdiv(op) | FcmpE(op) | FcmpNe(op) | FcmpLt(op) | FcmpLe(op)
339            | FcmpGe(op) | FcmpGt(op) | FcmpO(op) | FcmpUo(op) => vec![
340                ("left", Operand::Expr(*op.left.clone())),
341                ("right", Operand::Expr(*op.right.clone())),
342            ],
343            ArrayIndex(op) => vec![
344                ("src", Operand::Expr(*op.src.clone())),
345                ("index", Operand::Expr(*op.index.clone())),
346            ],
347            ArrayIndexSsa(op) => vec![
348                ("src", Operand::Expr(*op.src.clone())),
349                ("src_memory", Operand::Int(op.src_memory)),
350                ("index", Operand::Expr(*op.index.clone())),
351            ],
352            Assign(op) => vec![
353                ("dest", Operand::Expr(*op.dest.clone())),
354                ("src", Operand::Expr(*op.src.clone())),
355            ],
356            AssignMemSsa(op) => vec![
357                ("dest", Operand::Expr(*op.dest.clone())),
358                ("dest_memory", Operand::Int(op.dest_memory)),
359                ("src", Operand::Expr(*op.src.clone())),
360                ("src_memory", Operand::Int(op.src_memory)),
361            ],
362            AssignUnpack(op) => vec![
363                ("dest", Operand::ExprList(op.dest.clone())),
364                ("src", Operand::Expr(*op.src.clone())),
365            ],
366            AssignUnpackMemSsa(op) => vec![
367                ("dest", Operand::ExprList(op.dest.clone())),
368                ("dest_memory", Operand::Int(op.dest_memory)),
369                ("src", Operand::Expr(*op.src.clone())),
370                ("src_memory", Operand::Int(op.src_memory)),
371            ],
372            Block(op) => vec![("body", Operand::ExprList(op.body.clone()))],
373            Call(op) | Tailcall(op) => vec![
374                ("dest", Operand::Expr(*op.dest.clone())),
375                ("params", Operand::ExprList(op.params.clone())),
376            ],
377            CallSsa(op) => vec![
378                ("dest", Operand::Expr(*op.dest.clone())),
379                ("params", Operand::ExprList(op.params.clone())),
380                ("dest_memory", Operand::Int(op.dest_memory)),
381                ("src_memory", Operand::Int(op.src_memory)),
382            ],
383            Case(op) => vec![
384                ("values", Operand::ExprList(op.values.clone())),
385                ("body", Operand::Expr(*op.body.clone())),
386            ],
387            Const(op) | ConstPtr(op) | Import(op) => vec![("constant", Operand::Int(op.constant))],
388            ConstData(op) => vec![(
389                "constant_data",
390                Operand::ConstantData(op.constant_data.clone()),
391            )],
392            Deref(op) | AddressOf(op) | PassByRef(op) | ReturnByRef(op) | Neg(op) | Not(op)
393            | Bswap(op) | Popcnt(op) | Clz(op) | Ctz(op) | Rbit(op) | Cls(op) | Abs(op)
394            | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op) | Fsqrt(op)
395            | Fneg(op) | Fabs(op) | FloatToInt(op) | IntToFloat(op) | FloatConv(op)
396            | RoundToInt(op) | Floor(op) | Ceil(op) | Ftrunc(op) => {
397                vec![("src", Operand::Expr(*op.src.clone()))]
398            }
399            DerefFieldSsa(op) => vec![
400                ("src", Operand::Expr(*op.src.clone())),
401                ("src_memory", Operand::Int(op.src_memory)),
402                ("offset", Operand::Int(op.offset)),
403                ("member_index", Operand::MemberIndex(op.member_index)),
404            ],
405            DerefSsa(op) => vec![
406                ("src", Operand::Expr(*op.src.clone())),
407                ("src_memory", Operand::Int(op.src_memory)),
408            ],
409            ExternPtr(op) => vec![
410                ("constant", Operand::Int(op.constant)),
411                ("offset", Operand::Int(op.offset)),
412            ],
413            FloatConst(op) => vec![("constant", Operand::Float(op.constant))],
414            For(op) => vec![
415                ("init", Operand::Expr(*op.init.clone())),
416                ("condition", Operand::Expr(*op.condition.clone())),
417                ("update", Operand::Expr(*op.update.clone())),
418                ("body", Operand::Expr(*op.body.clone())),
419            ],
420            ForSsa(op) => vec![
421                ("init", Operand::Expr(*op.init.clone())),
422                ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
423                ("condition", Operand::Expr(*op.condition.clone())),
424                ("update", Operand::Expr(*op.update.clone())),
425                ("body", Operand::Expr(*op.body.clone())),
426            ],
427            Goto(op) | Label(op) => vec![("target", Operand::Label(op.target.clone()))],
428            If(op) => vec![
429                ("condition", Operand::Expr(*op.condition.clone())),
430                ("cond_true", Operand::Expr(*op.cond_true.clone())),
431                ("cond_false", Operand::Expr(*op.cond_false.clone())),
432            ],
433            Intrinsic(op) => vec![
434                ("intrinsic", Operand::Intrinsic(op.intrinsic)),
435                ("params", Operand::ExprList(op.params.clone())),
436            ],
437            IntrinsicSsa(op) => vec![
438                ("intrinsic", Operand::Intrinsic(op.intrinsic)),
439                ("params", Operand::ExprList(op.params.clone())),
440                ("dest_memory", Operand::Int(op.dest_memory)),
441                ("src_memory", Operand::Int(op.src_memory)),
442            ],
443            Jump(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
444            MemPhi(op) => vec![
445                ("dest", Operand::Int(op.dest)),
446                ("src", Operand::IntList(op.src.clone())),
447            ],
448            Ret(op) => vec![("src", Operand::ExprList(op.src.clone()))],
449            Split(op) => vec![
450                ("high", Operand::Expr(*op.high.clone())),
451                ("low", Operand::Expr(*op.low.clone())),
452            ],
453            StructField(op) | DerefField(op) => vec![
454                ("src", Operand::Expr(*op.src.clone())),
455                ("offset", Operand::Int(op.offset)),
456                ("member_index", Operand::MemberIndex(op.member_index)),
457            ],
458            Switch(op) => vec![
459                ("condition", Operand::Expr(*op.condition.clone())),
460                ("default", Operand::Expr(*op.default.clone())),
461                ("cases", Operand::ExprList(op.cases.clone())),
462            ],
463            Syscall(op) => vec![("params", Operand::ExprList(op.params.clone()))],
464            SyscallSsa(op) => vec![
465                ("params", Operand::ExprList(op.params.clone())),
466                ("dest_memory", Operand::Int(op.dest_memory)),
467                ("src_memory", Operand::Int(op.src_memory)),
468            ],
469            Trap(op) => vec![("vector", Operand::Int(op.vector))],
470            VarDeclare(op) | Var(op) => vec![("var", Operand::Var(op.var))],
471            VarInit(op) => vec![
472                ("dest", Operand::Var(op.dest)),
473                ("src", Operand::Expr(*op.src.clone())),
474            ],
475            VarInitSsa(op) => vec![
476                ("dest", Operand::VarSsa(op.dest)),
477                ("src", Operand::Expr(*op.src.clone())),
478            ],
479            VarPhi(op) => vec![
480                ("dest", Operand::VarSsa(op.dest)),
481                ("src", Operand::VarSsaList(op.src.clone())),
482            ],
483            VarSsa(op) => vec![("var", Operand::VarSsa(op.var))],
484            VarSsaPartial(op) => vec![
485                ("dest", Operand::VarSsa(op.dest)),
486                ("prev", Operand::VarSsa(op.prev)),
487            ],
488            While(op) | DoWhile(op) => vec![
489                ("condition", Operand::Expr(*op.condition.clone())),
490                ("body", Operand::Expr(*op.body.clone())),
491            ],
492            WhileSsa(op) | DoWhileSsa(op) => vec![
493                ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
494                ("condition", Operand::Expr(*op.condition.clone())),
495                ("body", Operand::Expr(*op.body.clone())),
496            ],
497        }
498    }
499}
500
501impl Debug for HighLevelILLiftedInstruction {
502    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
503        f.debug_struct("HighLevelILLiftedInstruction")
504            .field("address", &self.address)
505            .field("expr_index", &self.expr_index)
506            .field("size", &self.size)
507            .field("kind", &self.kind)
508            .finish()
509    }
510}