1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
use super::{operation::*, HighLevelILFunction};

#[derive(Clone, Debug, PartialEq)]
pub enum HighLevelILLiftedInstruction {
    Adc(LiftedBinaryOpCarry),
    Sbb(LiftedBinaryOpCarry),
    Rlc(LiftedBinaryOpCarry),
    Rrc(LiftedBinaryOpCarry),
    Add(LiftedBinaryOp),
    Sub(LiftedBinaryOp),
    And(LiftedBinaryOp),
    Or(LiftedBinaryOp),
    Xor(LiftedBinaryOp),
    Lsl(LiftedBinaryOp),
    Lsr(LiftedBinaryOp),
    Asr(LiftedBinaryOp),
    Rol(LiftedBinaryOp),
    Ror(LiftedBinaryOp),
    Mul(LiftedBinaryOp),
    MuluDp(LiftedBinaryOp),
    MulsDp(LiftedBinaryOp),
    Divu(LiftedBinaryOp),
    DivuDp(LiftedBinaryOp),
    Divs(LiftedBinaryOp),
    DivsDp(LiftedBinaryOp),
    Modu(LiftedBinaryOp),
    ModuDp(LiftedBinaryOp),
    Mods(LiftedBinaryOp),
    ModsDp(LiftedBinaryOp),
    CmpE(LiftedBinaryOp),
    CmpNe(LiftedBinaryOp),
    CmpSlt(LiftedBinaryOp),
    CmpUlt(LiftedBinaryOp),
    CmpSle(LiftedBinaryOp),
    CmpUle(LiftedBinaryOp),
    CmpSge(LiftedBinaryOp),
    CmpUge(LiftedBinaryOp),
    CmpSgt(LiftedBinaryOp),
    CmpUgt(LiftedBinaryOp),
    TestBit(LiftedBinaryOp),
    AddOverflow(LiftedBinaryOp),
    Fadd(LiftedBinaryOp),
    Fsub(LiftedBinaryOp),
    Fmul(LiftedBinaryOp),
    Fdiv(LiftedBinaryOp),
    FcmpE(LiftedBinaryOp),
    FcmpNe(LiftedBinaryOp),
    FcmpLt(LiftedBinaryOp),
    FcmpLe(LiftedBinaryOp),
    FcmpGe(LiftedBinaryOp),
    FcmpGt(LiftedBinaryOp),
    FcmpO(LiftedBinaryOp),
    FcmpUo(LiftedBinaryOp),
    ArrayIndex(LiftedArrayIndex),
    ArrayIndexSsa(LiftedArrayIndexSsa),
    Assign(LiftedAssign),
    AssignMemSsa(LiftedAssignMemSsa),
    AssignUnpack(LiftedAssignUnpack),
    AssignUnpackMemSsa(LiftedAssignUnpackMemSsa),
    Block(LiftedBlock),
    Call(LiftedCall),
    Tailcall(LiftedCall),
    CallSsa(LiftedCallSsa),
    Case(LiftedCase),
    Const(Const),
    ConstPtr(Const),
    Import(Const),
    ConstData(LiftedConstantData),
    Deref(LiftedUnaryOp),
    AddressOf(LiftedUnaryOp),
    Neg(LiftedUnaryOp),
    Not(LiftedUnaryOp),
    Sx(LiftedUnaryOp),
    Zx(LiftedUnaryOp),
    LowPart(LiftedUnaryOp),
    BoolToInt(LiftedUnaryOp),
    UnimplMem(LiftedUnaryOp),
    Fsqrt(LiftedUnaryOp),
    Fneg(LiftedUnaryOp),
    Fabs(LiftedUnaryOp),
    FloatToInt(LiftedUnaryOp),
    IntToFloat(LiftedUnaryOp),
    FloatConv(LiftedUnaryOp),
    RoundToInt(LiftedUnaryOp),
    Floor(LiftedUnaryOp),
    Ceil(LiftedUnaryOp),
    Ftrunc(LiftedUnaryOp),
    DerefFieldSsa(LiftedDerefFieldSsa),
    DerefSsa(LiftedDerefSsa),
    ExternPtr(ExternPtr),
    FloatConst(FloatConst),
    For(LiftedForLoop),
    ForSsa(LiftedForLoopSsa),
    Goto(Label),
    Label(Label),
    If(LiftedIf),
    Intrinsic(LiftedIntrinsic),
    IntrinsicSsa(LiftedIntrinsicSsa),
    Jump(Jump),
    MemPhi(LiftedMemPhi),
    Nop(NoArgs),
    Break(NoArgs),
    Continue(NoArgs),
    Noret(NoArgs),
    Unreachable(NoArgs),
    Bp(NoArgs),
    Undef(NoArgs),
    Unimpl(NoArgs),
    Ret(LiftedRet),
    Split(LiftedSplit),
    StructField(LiftedStructField),
    DerefField(LiftedStructField),
    Switch(LiftedSwitch),
    Syscall(LiftedSyscall),
    SyscallSsa(LiftedSyscallSsa),
    Trap(Trap),
    VarDeclare(Var),
    Var(Var),
    VarInit(LiftedVarInit),
    VarInitSsa(LiftedVarInitSsa),
    VarPhi(LiftedVarPhi),
    VarSsa(VarSsa),
    While(LiftedWhile),
    DoWhile(LiftedWhile),
    WhileSsa(LiftedWhileSsa),
    DoWhileSsa(LiftedWhileSsa),
}

impl HighLevelILLiftedInstruction {
    pub fn address(&self) -> u64 {
        use HighLevelILLiftedInstruction::*;
        match self {
            Adc(op) => op.address,
            Sbb(op) => op.address,
            Rlc(op) => op.address,
            Rrc(op) => op.address,
            Add(op) => op.address,
            Sub(op) => op.address,
            And(op) => op.address,
            Or(op) => op.address,
            Xor(op) => op.address,
            Lsl(op) => op.address,
            Lsr(op) => op.address,
            Asr(op) => op.address,
            Rol(op) => op.address,
            Ror(op) => op.address,
            Mul(op) => op.address,
            MuluDp(op) => op.address,
            MulsDp(op) => op.address,
            Divu(op) => op.address,
            DivuDp(op) => op.address,
            Divs(op) => op.address,
            DivsDp(op) => op.address,
            Modu(op) => op.address,
            ModuDp(op) => op.address,
            Mods(op) => op.address,
            ModsDp(op) => op.address,
            CmpE(op) => op.address,
            CmpNe(op) => op.address,
            CmpSlt(op) => op.address,
            CmpUlt(op) => op.address,
            CmpSle(op) => op.address,
            CmpUle(op) => op.address,
            CmpSge(op) => op.address,
            CmpUge(op) => op.address,
            CmpSgt(op) => op.address,
            CmpUgt(op) => op.address,
            TestBit(op) => op.address,
            AddOverflow(op) => op.address,
            Fadd(op) => op.address,
            Fsub(op) => op.address,
            Fmul(op) => op.address,
            Fdiv(op) => op.address,
            FcmpE(op) => op.address,
            FcmpNe(op) => op.address,
            FcmpLt(op) => op.address,
            FcmpLe(op) => op.address,
            FcmpGe(op) => op.address,
            FcmpGt(op) => op.address,
            FcmpO(op) => op.address,
            FcmpUo(op) => op.address,
            ArrayIndex(op) => op.address,
            ArrayIndexSsa(op) => op.address,
            Assign(op) => op.address,
            AssignMemSsa(op) => op.address,
            AssignUnpack(op) => op.address,
            AssignUnpackMemSsa(op) => op.address,
            Block(op) => op.address,
            Call(op) => op.address,
            Tailcall(op) => op.address,
            CallSsa(op) => op.address,
            Case(op) => op.address,
            Const(op) => op.address,
            ConstPtr(op) => op.address,
            Import(op) => op.address,
            ConstData(op) => op.address,
            Deref(op) => op.address,
            AddressOf(op) => op.address,
            Neg(op) => op.address,
            Not(op) => op.address,
            Sx(op) => op.address,
            Zx(op) => op.address,
            LowPart(op) => op.address,
            BoolToInt(op) => op.address,
            UnimplMem(op) => op.address,
            Fsqrt(op) => op.address,
            Fneg(op) => op.address,
            Fabs(op) => op.address,
            FloatToInt(op) => op.address,
            IntToFloat(op) => op.address,
            FloatConv(op) => op.address,
            RoundToInt(op) => op.address,
            Floor(op) => op.address,
            Ceil(op) => op.address,
            Ftrunc(op) => op.address,
            DerefFieldSsa(op) => op.address,
            DerefSsa(op) => op.address,
            ExternPtr(op) => op.address,
            FloatConst(op) => op.address,
            For(op) => op.address,
            ForSsa(op) => op.address,
            Goto(op) => op.address,
            Label(op) => op.address,
            If(op) => op.address,
            Intrinsic(op) => op.address,
            IntrinsicSsa(op) => op.address,
            Jump(op) => op.address,
            MemPhi(op) => op.address,
            Nop(op) => op.address,
            Break(op) => op.address,
            Continue(op) => op.address,
            Noret(op) => op.address,
            Unreachable(op) => op.address,
            Bp(op) => op.address,
            Undef(op) => op.address,
            Unimpl(op) => op.address,
            Ret(op) => op.address,
            Split(op) => op.address,
            StructField(op) => op.address,
            DerefField(op) => op.address,
            Switch(op) => op.address,
            Syscall(op) => op.address,
            SyscallSsa(op) => op.address,
            Trap(op) => op.address,
            VarDeclare(op) => op.address,
            Var(op) => op.address,
            VarInit(op) => op.address,
            VarInitSsa(op) => op.address,
            VarPhi(op) => op.address,
            VarSsa(op) => op.address,
            While(op) => op.address,
            DoWhile(op) => op.address,
            WhileSsa(op) => op.address,
            DoWhileSsa(op) => op.address,
        }
    }

    pub fn function(&self) -> &HighLevelILFunction {
        use HighLevelILLiftedInstruction::*;
        match self {
            Adc(op) => &op.function,
            Sbb(op) => &op.function,
            Rlc(op) => &op.function,
            Rrc(op) => &op.function,
            Add(op) => &op.function,
            Sub(op) => &op.function,
            And(op) => &op.function,
            Or(op) => &op.function,
            Xor(op) => &op.function,
            Lsl(op) => &op.function,
            Lsr(op) => &op.function,
            Asr(op) => &op.function,
            Rol(op) => &op.function,
            Ror(op) => &op.function,
            Mul(op) => &op.function,
            MuluDp(op) => &op.function,
            MulsDp(op) => &op.function,
            Divu(op) => &op.function,
            DivuDp(op) => &op.function,
            Divs(op) => &op.function,
            DivsDp(op) => &op.function,
            Modu(op) => &op.function,
            ModuDp(op) => &op.function,
            Mods(op) => &op.function,
            ModsDp(op) => &op.function,
            CmpE(op) => &op.function,
            CmpNe(op) => &op.function,
            CmpSlt(op) => &op.function,
            CmpUlt(op) => &op.function,
            CmpSle(op) => &op.function,
            CmpUle(op) => &op.function,
            CmpSge(op) => &op.function,
            CmpUge(op) => &op.function,
            CmpSgt(op) => &op.function,
            CmpUgt(op) => &op.function,
            TestBit(op) => &op.function,
            AddOverflow(op) => &op.function,
            Fadd(op) => &op.function,
            Fsub(op) => &op.function,
            Fmul(op) => &op.function,
            Fdiv(op) => &op.function,
            FcmpE(op) => &op.function,
            FcmpNe(op) => &op.function,
            FcmpLt(op) => &op.function,
            FcmpLe(op) => &op.function,
            FcmpGe(op) => &op.function,
            FcmpGt(op) => &op.function,
            FcmpO(op) => &op.function,
            FcmpUo(op) => &op.function,
            ArrayIndex(op) => &op.function,
            ArrayIndexSsa(op) => &op.function,
            Assign(op) => &op.function,
            AssignMemSsa(op) => &op.function,
            AssignUnpack(op) => &op.function,
            AssignUnpackMemSsa(op) => &op.function,
            Block(op) => &op.function,
            Call(op) => &op.function,
            Tailcall(op) => &op.function,
            CallSsa(op) => &op.function,
            Case(op) => &op.function,
            Const(op) => &op.function,
            ConstPtr(op) => &op.function,
            Import(op) => &op.function,
            ConstData(op) => &op.function,
            Deref(op) => &op.function,
            AddressOf(op) => &op.function,
            Neg(op) => &op.function,
            Not(op) => &op.function,
            Sx(op) => &op.function,
            Zx(op) => &op.function,
            LowPart(op) => &op.function,
            BoolToInt(op) => &op.function,
            UnimplMem(op) => &op.function,
            Fsqrt(op) => &op.function,
            Fneg(op) => &op.function,
            Fabs(op) => &op.function,
            FloatToInt(op) => &op.function,
            IntToFloat(op) => &op.function,
            FloatConv(op) => &op.function,
            RoundToInt(op) => &op.function,
            Floor(op) => &op.function,
            Ceil(op) => &op.function,
            Ftrunc(op) => &op.function,
            DerefFieldSsa(op) => &op.function,
            DerefSsa(op) => &op.function,
            ExternPtr(op) => &op.function,
            FloatConst(op) => &op.function,
            For(op) => &op.function,
            ForSsa(op) => &op.function,
            Goto(op) => &op.function,
            Label(op) => &op.function,
            If(op) => &op.function,
            Intrinsic(op) => &op.function,
            IntrinsicSsa(op) => &op.function,
            Jump(op) => &op.function,
            MemPhi(op) => &op.function,
            Nop(op) => &op.function,
            Break(op) => &op.function,
            Continue(op) => &op.function,
            Noret(op) => &op.function,
            Unreachable(op) => &op.function,
            Bp(op) => &op.function,
            Undef(op) => &op.function,
            Unimpl(op) => &op.function,
            Ret(op) => &op.function,
            Split(op) => &op.function,
            StructField(op) => &op.function,
            DerefField(op) => &op.function,
            Switch(op) => &op.function,
            Syscall(op) => &op.function,
            SyscallSsa(op) => &op.function,
            Trap(op) => &op.function,
            VarDeclare(op) => &op.function,
            Var(op) => &op.function,
            VarInit(op) => &op.function,
            VarInitSsa(op) => &op.function,
            VarPhi(op) => &op.function,
            VarSsa(op) => &op.function,
            While(op) => &op.function,
            DoWhile(op) => &op.function,
            WhileSsa(op) => &op.function,
            DoWhileSsa(op) => &op.function,
        }
    }
}