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    CmpE(LiftedBinaryOp),
75    CmpNe(LiftedBinaryOp),
76    CmpSlt(LiftedBinaryOp),
77    CmpUlt(LiftedBinaryOp),
78    CmpSle(LiftedBinaryOp),
79    CmpUle(LiftedBinaryOp),
80    CmpSge(LiftedBinaryOp),
81    CmpUge(LiftedBinaryOp),
82    CmpSgt(LiftedBinaryOp),
83    CmpUgt(LiftedBinaryOp),
84    TestBit(LiftedBinaryOp),
85    AddOverflow(LiftedBinaryOp),
86    Fadd(LiftedBinaryOp),
87    Fsub(LiftedBinaryOp),
88    Fmul(LiftedBinaryOp),
89    Fdiv(LiftedBinaryOp),
90    FcmpE(LiftedBinaryOp),
91    FcmpNe(LiftedBinaryOp),
92    FcmpLt(LiftedBinaryOp),
93    FcmpLe(LiftedBinaryOp),
94    FcmpGe(LiftedBinaryOp),
95    FcmpGt(LiftedBinaryOp),
96    FcmpO(LiftedBinaryOp),
97    FcmpUo(LiftedBinaryOp),
98    ArrayIndex(LiftedArrayIndex),
99    ArrayIndexSsa(LiftedArrayIndexSsa),
100    Assign(LiftedAssign),
101    AssignMemSsa(LiftedAssignMemSsa),
102    AssignUnpack(LiftedAssignUnpack),
103    AssignUnpackMemSsa(LiftedAssignUnpackMemSsa),
104    Block(LiftedBlock),
105    Call(LiftedCall),
106    Tailcall(LiftedCall),
107    CallSsa(LiftedCallSsa),
108    Case(LiftedCase),
109    Const(Const),
110    ConstPtr(Const),
111    Import(Const),
112    ConstData(LiftedConstData),
113    Deref(LiftedUnaryOp),
114    AddressOf(LiftedUnaryOp),
115    Neg(LiftedUnaryOp),
116    Not(LiftedUnaryOp),
117    Sx(LiftedUnaryOp),
118    Zx(LiftedUnaryOp),
119    LowPart(LiftedUnaryOp),
120    BoolToInt(LiftedUnaryOp),
121    UnimplMem(LiftedUnaryOp),
122    Fsqrt(LiftedUnaryOp),
123    Fneg(LiftedUnaryOp),
124    Fabs(LiftedUnaryOp),
125    FloatToInt(LiftedUnaryOp),
126    IntToFloat(LiftedUnaryOp),
127    FloatConv(LiftedUnaryOp),
128    RoundToInt(LiftedUnaryOp),
129    Floor(LiftedUnaryOp),
130    Ceil(LiftedUnaryOp),
131    Ftrunc(LiftedUnaryOp),
132    DerefFieldSsa(LiftedDerefFieldSsa),
133    DerefSsa(LiftedDerefSsa),
134    ExternPtr(ExternPtr),
135    FloatConst(FloatConst),
136    For(LiftedForLoop),
137    ForSsa(LiftedForLoopSsa),
138    Goto(LiftedLabel),
139    Label(LiftedLabel),
140    If(LiftedIf),
141    Intrinsic(LiftedIntrinsic),
142    IntrinsicSsa(LiftedIntrinsicSsa),
143    Jump(LiftedJump),
144    MemPhi(LiftedMemPhi),
145    Ret(LiftedRet),
146    Split(LiftedSplit),
147    StructField(LiftedStructField),
148    DerefField(LiftedStructField),
149    Switch(LiftedSwitch),
150    Syscall(LiftedSyscall),
151    SyscallSsa(LiftedSyscallSsa),
152    Trap(Trap),
153    VarDeclare(Var),
154    Var(Var),
155    VarInit(LiftedVarInit),
156    VarInitSsa(LiftedVarInitSsa),
157    VarPhi(LiftedVarPhi),
158    VarSsa(VarSsa),
159    While(LiftedWhile),
160    DoWhile(LiftedWhile),
161    WhileSsa(LiftedWhileSsa),
162    DoWhileSsa(LiftedWhileSsa),
163}
164
165impl HighLevelILLiftedInstruction {
166    pub fn name(&self) -> &'static str {
167        use HighLevelILLiftedInstructionKind::*;
168        match self.kind {
169            Nop => "Nop",
170            Break => "Break",
171            Continue => "Continue",
172            Noret => "Noret",
173            Unreachable => "Unreachable",
174            Bp => "Bp",
175            Undef => "Undef",
176            Unimpl => "Unimpl",
177            Adc(_) => "Adc",
178            Sbb(_) => "Sbb",
179            Rlc(_) => "Rlc",
180            Rrc(_) => "Rrc",
181            Add(_) => "Add",
182            Sub(_) => "Sub",
183            And(_) => "And",
184            Or(_) => "Or",
185            Xor(_) => "Xor",
186            Lsl(_) => "Lsl",
187            Lsr(_) => "Lsr",
188            Asr(_) => "Asr",
189            Rol(_) => "Rol",
190            Ror(_) => "Ror",
191            Mul(_) => "Mul",
192            MuluDp(_) => "MuluDp",
193            MulsDp(_) => "MulsDp",
194            Divu(_) => "Divu",
195            DivuDp(_) => "DivuDp",
196            Divs(_) => "Divs",
197            DivsDp(_) => "DivsDp",
198            Modu(_) => "Modu",
199            ModuDp(_) => "ModuDp",
200            Mods(_) => "Mods",
201            ModsDp(_) => "ModsDp",
202            CmpE(_) => "CmpE",
203            CmpNe(_) => "CmpNe",
204            CmpSlt(_) => "CmpSlt",
205            CmpUlt(_) => "CmpUlt",
206            CmpSle(_) => "CmpSle",
207            CmpUle(_) => "CmpUle",
208            CmpSge(_) => "CmpSge",
209            CmpUge(_) => "CmpUge",
210            CmpSgt(_) => "CmpSgt",
211            CmpUgt(_) => "CmpUgt",
212            TestBit(_) => "TestBit",
213            AddOverflow(_) => "AddOverflow",
214            Fadd(_) => "Fadd",
215            Fsub(_) => "Fsub",
216            Fmul(_) => "Fmul",
217            Fdiv(_) => "Fdiv",
218            FcmpE(_) => "FcmpE",
219            FcmpNe(_) => "FcmpNe",
220            FcmpLt(_) => "FcmpLt",
221            FcmpLe(_) => "FcmpLe",
222            FcmpGe(_) => "FcmpGe",
223            FcmpGt(_) => "FcmpGt",
224            FcmpO(_) => "FcmpO",
225            FcmpUo(_) => "FcmpUo",
226            ArrayIndex(_) => "ArrayIndex",
227            ArrayIndexSsa(_) => "ArrayIndexSsa",
228            Assign(_) => "Assign",
229            AssignMemSsa(_) => "AssignMemSsa",
230            AssignUnpack(_) => "AssignUnpack",
231            AssignUnpackMemSsa(_) => "AssignUnpackMemSsa",
232            Block(_) => "Block",
233            Call(_) => "Call",
234            Tailcall(_) => "Tailcall",
235            CallSsa(_) => "CallSsa",
236            Case(_) => "Case",
237            Const(_) => "Const",
238            ConstPtr(_) => "ConstPtr",
239            Import(_) => "Import",
240            ConstData(_) => "ConstData",
241            Deref(_) => "Deref",
242            AddressOf(_) => "AddressOf",
243            Neg(_) => "Neg",
244            Not(_) => "Not",
245            Sx(_) => "Sx",
246            Zx(_) => "Zx",
247            LowPart(_) => "LowPart",
248            BoolToInt(_) => "BoolToInt",
249            UnimplMem(_) => "UnimplMem",
250            Fsqrt(_) => "Fsqrt",
251            Fneg(_) => "Fneg",
252            Fabs(_) => "Fabs",
253            FloatToInt(_) => "FloatToInt",
254            IntToFloat(_) => "IntToFloat",
255            FloatConv(_) => "FloatConv",
256            RoundToInt(_) => "RoundToInt",
257            Floor(_) => "Floor",
258            Ceil(_) => "Ceil",
259            Ftrunc(_) => "Ftrunc",
260            DerefFieldSsa(_) => "DerefFieldSsa",
261            DerefSsa(_) => "DerefSsa",
262            ExternPtr(_) => "ExternPtr",
263            FloatConst(_) => "FloatConst",
264            For(_) => "For",
265            ForSsa(_) => "ForSsa",
266            Goto(_) => "Goto",
267            Label(_) => "Label",
268            If(_) => "If",
269            Intrinsic(_) => "Intrinsic",
270            IntrinsicSsa(_) => "IntrinsicSsa",
271            Jump(_) => "Jump",
272            MemPhi(_) => "MemPhi",
273            Ret(_) => "Ret",
274            Split(_) => "Split",
275            StructField(_) => "StructField",
276            DerefField(_) => "DerefField",
277            Switch(_) => "Switch",
278            Syscall(_) => "Syscall",
279            SyscallSsa(_) => "SyscallSsa",
280            Trap(_) => "Trap",
281            VarDeclare(_) => "VarDeclare",
282            Var(_) => "Var",
283            VarInit(_) => "VarInit",
284            VarInitSsa(_) => "VarInitSsa",
285            VarPhi(_) => "VarPhi",
286            VarSsa(_) => "VarSsa",
287            While(_) => "While",
288            DoWhile(_) => "DoWhile",
289            WhileSsa(_) => "WhileSsa",
290            DoWhileSsa(_) => "DoWhileSsa",
291        }
292    }
293
294    pub fn operands(&self) -> Vec<(&'static str, HighLevelILLiftedOperand)> {
295        use HighLevelILLiftedInstructionKind::*;
296        use HighLevelILLiftedOperand as Operand;
297        match &self.kind {
298            Nop | Break | Continue | Noret | Unreachable | Bp | Undef | Unimpl => vec![],
299            Adc(op) | Sbb(op) | Rlc(op) | Rrc(op) => vec![
300                ("left", Operand::Expr(*op.left.clone())),
301                ("right", Operand::Expr(*op.right.clone())),
302                ("carry", Operand::Expr(*op.carry.clone())),
303            ],
304            Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op)
305            | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op)
306            | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op) | CmpE(op)
307            | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op)
308            | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | Fadd(op)
309            | Fsub(op) | Fmul(op) | Fdiv(op) | FcmpE(op) | FcmpNe(op) | FcmpLt(op) | FcmpLe(op)
310            | FcmpGe(op) | FcmpGt(op) | FcmpO(op) | FcmpUo(op) => vec![
311                ("left", Operand::Expr(*op.left.clone())),
312                ("right", Operand::Expr(*op.right.clone())),
313            ],
314            ArrayIndex(op) => vec![
315                ("src", Operand::Expr(*op.src.clone())),
316                ("index", Operand::Expr(*op.index.clone())),
317            ],
318            ArrayIndexSsa(op) => vec![
319                ("src", Operand::Expr(*op.src.clone())),
320                ("src_memory", Operand::Int(op.src_memory)),
321                ("index", Operand::Expr(*op.index.clone())),
322            ],
323            Assign(op) => vec![
324                ("dest", Operand::Expr(*op.dest.clone())),
325                ("src", Operand::Expr(*op.src.clone())),
326            ],
327            AssignMemSsa(op) => vec![
328                ("dest", Operand::Expr(*op.dest.clone())),
329                ("dest_memory", Operand::Int(op.dest_memory)),
330                ("src", Operand::Expr(*op.src.clone())),
331                ("src_memory", Operand::Int(op.src_memory)),
332            ],
333            AssignUnpack(op) => vec![
334                ("dest", Operand::ExprList(op.dest.clone())),
335                ("src", Operand::Expr(*op.src.clone())),
336            ],
337            AssignUnpackMemSsa(op) => vec![
338                ("dest", Operand::ExprList(op.dest.clone())),
339                ("dest_memory", Operand::Int(op.dest_memory)),
340                ("src", Operand::Expr(*op.src.clone())),
341                ("src_memory", Operand::Int(op.src_memory)),
342            ],
343            Block(op) => vec![("body", Operand::ExprList(op.body.clone()))],
344            Call(op) | Tailcall(op) => vec![
345                ("dest", Operand::Expr(*op.dest.clone())),
346                ("params", Operand::ExprList(op.params.clone())),
347            ],
348            CallSsa(op) => vec![
349                ("dest", Operand::Expr(*op.dest.clone())),
350                ("params", Operand::ExprList(op.params.clone())),
351                ("dest_memory", Operand::Int(op.dest_memory)),
352                ("src_memory", Operand::Int(op.src_memory)),
353            ],
354            Case(op) => vec![
355                ("values", Operand::ExprList(op.values.clone())),
356                ("body", Operand::Expr(*op.body.clone())),
357            ],
358            Const(op) | ConstPtr(op) | Import(op) => vec![("constant", Operand::Int(op.constant))],
359            ConstData(op) => vec![(
360                "constant_data",
361                Operand::ConstantData(op.constant_data.clone()),
362            )],
363            Deref(op) | AddressOf(op) | Neg(op) | Not(op) | Sx(op) | Zx(op) | LowPart(op)
364            | BoolToInt(op) | UnimplMem(op) | Fsqrt(op) | Fneg(op) | Fabs(op) | FloatToInt(op)
365            | IntToFloat(op) | FloatConv(op) | RoundToInt(op) | Floor(op) | Ceil(op)
366            | Ftrunc(op) => vec![("src", Operand::Expr(*op.src.clone()))],
367            DerefFieldSsa(op) => vec![
368                ("src", Operand::Expr(*op.src.clone())),
369                ("src_memory", Operand::Int(op.src_memory)),
370                ("offset", Operand::Int(op.offset)),
371                ("member_index", Operand::MemberIndex(op.member_index)),
372            ],
373            DerefSsa(op) => vec![
374                ("src", Operand::Expr(*op.src.clone())),
375                ("src_memory", Operand::Int(op.src_memory)),
376            ],
377            ExternPtr(op) => vec![
378                ("constant", Operand::Int(op.constant)),
379                ("offset", Operand::Int(op.offset)),
380            ],
381            FloatConst(op) => vec![("constant", Operand::Float(op.constant))],
382            For(op) => vec![
383                ("init", Operand::Expr(*op.init.clone())),
384                ("condition", Operand::Expr(*op.condition.clone())),
385                ("update", Operand::Expr(*op.update.clone())),
386                ("body", Operand::Expr(*op.body.clone())),
387            ],
388            ForSsa(op) => vec![
389                ("init", Operand::Expr(*op.init.clone())),
390                ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
391                ("condition", Operand::Expr(*op.condition.clone())),
392                ("update", Operand::Expr(*op.update.clone())),
393                ("body", Operand::Expr(*op.body.clone())),
394            ],
395            Goto(op) | Label(op) => vec![("target", Operand::Label(op.target.clone()))],
396            If(op) => vec![
397                ("condition", Operand::Expr(*op.condition.clone())),
398                ("cond_true", Operand::Expr(*op.cond_true.clone())),
399                ("cond_false", Operand::Expr(*op.cond_false.clone())),
400            ],
401            Intrinsic(op) => vec![
402                ("intrinsic", Operand::Intrinsic(op.intrinsic)),
403                ("params", Operand::ExprList(op.params.clone())),
404            ],
405            IntrinsicSsa(op) => vec![
406                ("intrinsic", Operand::Intrinsic(op.intrinsic)),
407                ("params", Operand::ExprList(op.params.clone())),
408                ("dest_memory", Operand::Int(op.dest_memory)),
409                ("src_memory", Operand::Int(op.src_memory)),
410            ],
411            Jump(op) => vec![("dest", Operand::Expr(*op.dest.clone()))],
412            MemPhi(op) => vec![
413                ("dest", Operand::Int(op.dest)),
414                ("src", Operand::IntList(op.src.clone())),
415            ],
416            Ret(op) => vec![("src", Operand::ExprList(op.src.clone()))],
417            Split(op) => vec![
418                ("high", Operand::Expr(*op.high.clone())),
419                ("low", Operand::Expr(*op.low.clone())),
420            ],
421            StructField(op) | DerefField(op) => vec![
422                ("src", Operand::Expr(*op.src.clone())),
423                ("offset", Operand::Int(op.offset)),
424                ("member_index", Operand::MemberIndex(op.member_index)),
425            ],
426            Switch(op) => vec![
427                ("condition", Operand::Expr(*op.condition.clone())),
428                ("default", Operand::Expr(*op.default.clone())),
429                ("cases", Operand::ExprList(op.cases.clone())),
430            ],
431            Syscall(op) => vec![("params", Operand::ExprList(op.params.clone()))],
432            SyscallSsa(op) => vec![
433                ("params", Operand::ExprList(op.params.clone())),
434                ("dest_memory", Operand::Int(op.dest_memory)),
435                ("src_memory", Operand::Int(op.src_memory)),
436            ],
437            Trap(op) => vec![("vector", Operand::Int(op.vector))],
438            VarDeclare(op) | Var(op) => vec![("var", Operand::Var(op.var))],
439            VarInit(op) => vec![
440                ("dest", Operand::Var(op.dest)),
441                ("src", Operand::Expr(*op.src.clone())),
442            ],
443            VarInitSsa(op) => vec![
444                ("dest", Operand::VarSsa(op.dest)),
445                ("src", Operand::Expr(*op.src.clone())),
446            ],
447            VarPhi(op) => vec![
448                ("dest", Operand::VarSsa(op.dest)),
449                ("src", Operand::VarSsaList(op.src.clone())),
450            ],
451            VarSsa(op) => vec![("var", Operand::VarSsa(op.var))],
452            While(op) | DoWhile(op) => vec![
453                ("condition", Operand::Expr(*op.condition.clone())),
454                ("body", Operand::Expr(*op.body.clone())),
455            ],
456            WhileSsa(op) | DoWhileSsa(op) => vec![
457                ("condition_phi", Operand::Expr(*op.condition_phi.clone())),
458                ("condition", Operand::Expr(*op.condition.clone())),
459                ("body", Operand::Expr(*op.body.clone())),
460            ],
461        }
462    }
463}
464
465impl Debug for HighLevelILLiftedInstruction {
466    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
467        f.debug_struct("HighLevelILLiftedInstruction")
468            .field("address", &self.address)
469            .field("expr_index", &self.expr_index)
470            .field("size", &self.size)
471            .field("kind", &self.kind)
472            .finish()
473    }
474}