首页
社区
课程
招聘
5
一次使用Ghidra反编译vmp的尝试
发表于: 2023-9-27 12:22 9388

一次使用Ghidra反编译vmp的尝试

2023-9-27 12:22
9388

想尝试使用Ghidra直接对vmp handler进行反编译,由于工作量比较大,因此需要快速验证一下可行性怎么样。


C++代码编写

编写一段简单的算法代码

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
//禁止优化
#pragma optimize("", off) 
unsigned int VmpCipher(unsigned int a,unsigned int b)
{
    unsigned int result = 0xFF;
    __asm {
        _emit 0xEB;
        _emit 0x10;
        _emit 0x56;
        _emit 0x4D;
        _emit 0x50;
        _emit 0x72;
        _emit 0x6F;
        _emit 0x74;
        _emit 0x65;
        _emit 0x63;
        _emit 0x74;
        _emit 0x20;
        _emit 0x62;
        _emit 0x65;
        _emit 0x67;
        _emit 0x69;
        _emit 0x6E;
        _emit 0x00;
    }
    result += a;
    result += b;
    result -= a;
    result -= b;
    result *= a;
    result *= b;
    result = result / b;
    result = result & b;
    result = result % a;
    result = result ^ a;
    result = result ^ b;
    __asm {
        _emit 0xEB;
        _emit 0xE;
        _emit 0x56;
        _emit 0x4D;
        _emit 0x50;
        _emit 0x72;
        _emit 0x6F;
        _emit 0x74;
        _emit 0x65;
        _emit 0x63;
        _emit 0x74;
        _emit 0x20;
        _emit 0x65;
        _emit 0x6E;
        _emit 0x64;
        _emit 0x00;
    }
    return result;
}
#pragma optimize("", on) // 禁止优化
 
int main() { 
    unsigned int a = 0x12345678;
    unsigned int b = 0xDEADC0DE;
    unsigned int result = VmpCipher(a, b);
    std::cout << result << std::endl;
    return 0;
}

使用vmp3.5加一下简单的壳,打印一下执行的所有handler,大概是下面这样的

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
0x0048C184  vStoreContext ->
[0x0019FECC] = 0x00000000
[0x0019FED0] = ECX = 0x00000000
[0x0019FED4] = EDX = 0x0028E000
[0x0019FED8] = ESI = 0x0071DA20
[0x0019FEDC] = EBP = 0x0019FF08
[0x0019FEE0] = EAX = 0x00432878
[0x0019FEE4] = EBX = 0x0028B000
[0x0019FEE8] = EDI = 0x00721D90
[0x0019FEEC] = eflags = 0x00000202
[0x0019FEF0] = 0x0048C18E
[0x0019FEF4] = 0x0FBC1001
0x004AE6D7  vPopReg4 -> [0x0019FE34] = 0x00000000
0x00456C38  vPopReg4 -> [0x0019FE3C] = 0x00000000
0x00462CC6  vPopReg4 -> [0x0019FE38] = 0x0028E000
0x00464F1F  vPopReg4 -> [0x0019FE28] = 0x0071DA20
0x0043CAE2  vPopReg4 -> [0x0019FE14] = 0x0019FF08
0x00482926  vPopReg4 -> [0x0019FE44] = 0x00432878
0x0045798B  vPopReg4 -> [0x0019FE20] = 0x0028B000
0x004A9E05  vPopReg4 -> [0x0019FE10] = 0x00721D90
0x00462733  vPopReg4 -> [0x0019FE2C] = 0x00000202
0x004505CC  vPopReg4 -> [0x0019FE30] = 0x0048C18E
0x00468302  vPopReg4 -> [0x0019FE18] = 0x0FBC1001
0x0047A836  vPushImm4 -> [0x0019FEF4] = 0x0048DA57
0x004AE6D7  vPopReg4 -> [0x0019FE40] = 0x0048DA57
0x004AF244  vPushReg4 -> [0x0019FE18] -> push 0x0FBC1001
0x0044ACCE  vPushReg4 -> [0x0019FE10] -> push 0x00721D90
0x004B1210  vPushReg4 -> [0x0019FE20] -> push 0x0028B000
0x00442173  vPushReg4 -> [0x0019FE38] -> push 0x0028E000
0x0049B0A0  vPushReg4 -> [0x0019FE10] -> push 0x00721D90
0x0044D4A0  vPushReg4 -> [0x0019FE14] -> push 0x0019FF08
0x0048A8EE  vPushReg4 -> [0x0019FE28] -> push 0x0071DA20
0x00485351  vPushReg4 -> [0x0019FE2C] -> push 0x00000202
0x004B9752  vPushReg4 -> [0x0019FE3C] -> push 0x00000000
0x00433ADC  vPushReg4 -> [0x0019FE44] -> push 0x00432878
0x0043EB27  vPushReg4 -> [0x0019FE34] -> push 0x00000000
0x004AF244  vPushReg4 -> [0x0019FE40] -> push 0x0048DA57
0x00440BFB  vJmp 0x0048DA57
0x00453411  vPopReg4 -> [0x0019FE10] = 0x00000000
0x00478C66  vPopReg4 -> [0x0019FE28] = 0x00432878
0x004AFAC9  vPopReg4 -> [0x0019FE24] = 0x00000000
0x004B3AAC  vPopReg4 -> [0x0019FE2C] = 0x00000202
0x004BB8C6  vPopReg4 -> [0x0019FE3C] = 0x0071DA20
0x004675A0  vPopReg4 -> [0x0019FE48] = 0x0019FF08
0x00496DEB  vPopReg4 -> [0x0019FE44] = 0x00721D90
0x0045DB45  vPopReg4 -> [0x0019FE18] = 0x0028E000
0x0046E259  vPopReg4 -> [0x0019FE30] = 0x0028B000
0x00434A2D  vPopReg4 -> [0x0019FE34] = 0x00721D90
0x00493DA8  vPopReg4 -> [0x0019FE0C] = 0x0FBC1001
0x00447DE0  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x00454004  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0047862F  vPushImm4 -> [0x0019FEEC] = 0xFFFFFFFC
0x004A11FB  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x00453411  vPopReg4 -> [0x0019FE1C] = 0x00000213
0x004B3312  0x000000FF = vReadMem4(0x0019FF04)
0x00478C66  vPopReg4 -> [0x0019FE38] = 0x000000FF
0x0044C27C  vPushImm4 -> [0x0019FEF0] = 0x00000008
0x00455D02  (0x00000212,0x0019FF10) = vAdd4(0x00000008,0x0019FF08)
0x004AFAC9  vPopReg4 -> [0x0019FE0C] = 0x00000212
0x004AEFE3  0x12345678 = vReadMem4(0x0019FF10)
0x00474718  vPushReg4 -> [0x0019FE38] -> push 0x000000FF
0x00434485  (0x00000216,0x12345777) = vAdd4(0x000000FF,0x12345678)
0x004B3AAC  vPopReg4 -> [0x0019FE28] = 0x00000216
0x004BB8C6  vPopReg4 -> [0x0019FE20] = 0x12345777
0x00433334  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x00450289  vPushImm4 -> [0x0019FEF0] = 0xFFFFFFFC
0x0047B276  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x0043A13C  vPushReg4 -> [0x0019FE20] -> push 0x12345777
0x00494385  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0043B6EE  vPushImm4 -> [0x0019FEE4] = 0xFFFFFFFC
0x00448025  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x004675A0  vPopReg4 -> [0x0019FE0C] = 0x00000213
0x0045BDCD  vWriteMem4 -> [0x0019FF04] = 0x12345777
0x00496DEB  vPopReg4 -> [0x0019FE28] = 0x00000213
0x0044D78D  0x12345777 = vReadMem4(0x0019FF04)
0x0045DB45  vPopReg4 -> [0x0019FE38] = 0x12345777
0x004B3AE2  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x004C0C92  vPushImm4 -> [0x0019FEF0] = 0x0000000C
0x004ACF24  (0x00000216,0x0019FF14) = vAdd4(0x0000000C,0x0019FF08)
0x0046E259  vPopReg4 -> [0x0019FE34] = 0x00000216
0x004ACD2E  0xDEADC0DE = vReadMem4(0x0019FF14)
0x004ADC6E  vPushReg4 -> [0x0019FE38] -> push 0x12345777
0x0045E73A  (0x00000296,0xF0E21855) = vAdd4(0x12345777,0xDEADC0DE)
0x00434A2D  vPopReg4 -> [0x0019FE34] = 0x00000296
0x00493DA8  vPopReg4 -> [0x0019FE14] = 0xF0E21855
0x004BD01A  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x004412F4  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x004553C3  vPushImm4 -> [0x0019FEEC] = 0xFFFFFFFC
0x0043BC53  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x0049C796  vPushReg4 -> [0x0019FE14] -> push 0xF0E21855
0x00447DE0  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0047A771  vPushImm4 -> [0x0019FEE0] = 0xFFFFFFFC
0x004B72B0  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x00453411  vPopReg4 -> [0x0019FE0C] = 0x00000213
0x0043F7C2  vWriteMem4 -> [0x0019FF04] = 0xF0E21855
0x00478C66  vPopReg4 -> [0x0019FE0C] = 0x00000213
0x0049DF0A  0xF0E21855 = vReadMem4(0x0019FF04)
0x004AFAC9  vPopReg4 -> [0x0019FE38] = 0xF0E21855
0x00486D1C  vPushImm4 -> [0x0019FEF0] = 0x00000008
0x004B6320  (0x00000212,0x0019FF10) = vAdd4(0x00000008,0x0019FF08)
0x004B3AAC  vPopReg4 -> [0x0019FE18] = 0x00000212
0x0049693C  0x12345678 = vReadMem4(0x0019FF10)
0x00454004  vPushReg4 -> [0x0019FE38] -> push 0xF0E21855
0x00474718  vPushReg4 -> [0x0019FE38] -> push 0xF0E21855
0x004601A6  (0x00000206,0x0F1DE7AA) = vNor4(0xF0E21855,0xF0E21855)
0x004BB8C6  vPopReg4 -> [0x0019FE24] = 0x00000206
0x00440C16  (0x00000216,0x21523E22) = vAdd4(0x0F1DE7AA,0x12345678)
0x004675A0  vPopReg4 -> [0x0019FE28] = 0x00000216
0x0045E5CD  vPushVEsp 0x0019FEF4
0x0048EA3E  0x21523E22 = vReadMem4(0x0019FEF4)
0x0044F0A7  (0x00000286,0xDEADC1DD) = vNand4(0x21523E22,0x21523E22)
0x00496DEB  vPopReg4 -> [0x0019FE18] = 0x00000286
0x0045DB45  vPopReg4 -> [0x0019FE40] = 0xDEADC1DD
0x00433334  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x00443E96  vPushImm4 -> [0x0019FEF0] = 0x0000000C
0x0043A13C  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x004611E7  vPushImm4 -> [0x0019FEE8] = 0xFFFFFFFC
0x004A11FB  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x00494385  vPushReg4 -> [0x0019FE40] -> push 0xDEADC1DD
0x004B3AE2  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0048F933  vPushImm4 -> [0x0019FEDC] = 0xFFFFFFFC
0x00455D02  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x0046E259  vPopReg4 -> [0x0019FE1C] = 0x00000213
0x00499ED8  vWriteMem4 -> [0x0019FF04] = 0xDEADC1DD
0x00434A2D  vPopReg4 -> [0x0019FE38] = 0x00000213
0x0049605F  0xDEADC1DD = vReadMem4(0x0019FF04)
0x00493DA8  vPopReg4 -> [0x0019FE24] = 0xDEADC1DD
0x00434485  (0x00000216,0x0019FF14) = vAdd4(0x0000000C,0x0019FF08)
0x00453411  vPopReg4 -> [0x0019FE20] = 0x00000216
0x00493716  0xDEADC0DE = vReadMem4(0x0019FF14)
0x004ADC6E  vPushReg4 -> [0x0019FE24] -> push 0xDEADC1DD
0x004BD01A  vPushReg4 -> [0x0019FE24] -> push 0xDEADC1DD
0x004BE66F  (0x00000206,0x21523E22) = vNor4(0xDEADC1DD,0xDEADC1DD)
0x00478C66  vPopReg4 -> [0x0019FE38] = 0x00000206
0x0047B276  (0x00000296,0xFFFFFF00) = vAdd4(0x21523E22,0xDEADC0DE)
0x004AFAC9  vPopReg4 -> [0x0019FE34] = 0x00000296
0x0047016F  vPushVEsp 0x0019FEF4
0x00495B56  0xFFFFFF00 = vReadMem4(0x0019FEF4)
0x00440238  (0x00000206,0x000000FF) = vNor4(0xFFFFFF00,0xFFFFFF00)
0x004B3AAC  vPopReg4 -> [0x0019FE20] = 0x00000206
0x004BB8C6  vPopReg4 -> [0x0019FE1C] = 0x000000FF
0x004412F4  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0047862F  vPushImm4 -> [0x0019FEF0] = 0x00000008
0x00448025  (0x00000212,0x0019FF10) = vAdd4(0x00000008,0x0019FF08)
0x0049C796  vPushReg4 -> [0x0019FE1C] -> push 0x000000FF
0x00447DE0  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0044C27C  vPushImm4 -> [0x0019FEE4] = 0xFFFFFFFC
0x004ACF24  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x004675A0  vPopReg4 -> [0x0019FE28] = 0x00000213
0x004ACF50  vWriteMem4 -> [0x0019FF04] = 0x000000FF
0x00454004  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x00450289  vPushImm4 -> [0x0019FEE8] = 0xFFFFFFFC
0x0045E73A  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x00496DEB  vPopReg4 -> [0x0019FE34] = 0x00000213
0x0047C032  0x000000FF = vReadMem4(0x0019FF04)
0x0045DB45  vPopReg4 -> [0x0019FE18] = 0x000000FF
0x0046E259  vPopReg4 -> [0x0019FE0C] = 0x00000212
0x004B3312  0x12345678 = vReadMem4(0x0019FF10)
0x00474718  vPushReg4 -> [0x0019FE18] -> push 0x000000FF
0x0046E6B1  (0x00000A07,0x0000001222222188) = vImul(0x12345678,0x000000FF)
0x00434A2D  vPopReg4 -> [0x0019FE14] = 0x00000A07
0x00493DA8  vPopReg4 -> [0x0019FE0C] = 0x00000012
0x00453411  vPopReg4 -> [0x0019FE34] = 0x22222188
0x00433334  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0043B6EE  vPushImm4 -> [0x0019FEF0] = 0x0000000C
0x0043BC53  (0x00000216,0x0019FF14) = vAdd4(0x0000000C,0x0019FF08)
0x0043A13C  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x00494385  vPushReg4 -> [0x0019FE34] -> push 0x22222188
0x004B3AE2  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x004C0C92  vPushImm4 -> [0x0019FEE0] = 0xFFFFFFFC
0x004B72B0  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x00478C66  vPopReg4 -> [0x0019FE14] = 0x00000213
0x004B6FB9  vWriteMem4 -> [0x0019FF04] = 0x22222188
0x004553C3  vPushImm4 -> [0x0019FEE8] = 0xFFFFFFFC
0x004B6320  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x004AFAC9  vPopReg4 -> [0x0019FE38] = 0x00000213
0x004AEFE3  0x22222188 = vReadMem4(0x0019FF04)
0x004B3AAC  vPopReg4 -> [0x0019FE14] = 0x22222188
0x004BB8C6  vPopReg4 -> [0x0019FE0C] = 0x00000216
0x0044D78D  0xDEADC0DE = vReadMem4(0x0019FF14)
0x004ADC6E  vPushReg4 -> [0x0019FE14] -> push 0x22222188
0x00478A95  (0x00000A87,0xFB8EA253CBA713F0) = vImul(0xDEADC0DE,0x22222188)
0x004675A0  vPopReg4 -> [0x0019FE28] = 0x00000A87
0x00496DEB  vPopReg4 -> [0x0019FE40] = 0xFB8EA253
0x0045DB45  vPopReg4 -> [0x0019FE18] = 0xCBA713F0
0x004BD01A  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x004412F4  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0047A771  vPushImm4 -> [0x0019FEEC] = 0xFFFFFFFC
0x00440C16  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x0049C796  vPushReg4 -> [0x0019FE18] -> push 0xCBA713F0
0x00447DE0  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x00486D1C  vPushImm4 -> [0x0019FEE0] = 0xFFFFFFFC
0x004A11FB  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x0046E259  vPopReg4 -> [0x0019FE38] = 0x00000213
0x004ADEC1  vWriteMem4 -> [0x0019FF04] = 0xCBA713F0
0x00434A2D  vPopReg4 -> [0x0019FE20] = 0x00000213
0x00454004  vPushReg4 -> [0x0019FE18] -> push 0xCBA713F0
0x00474718  vPushReg4 -> [0x0019FE18] -> push 0xCBA713F0
0x00492CE8  (0x00000206,0x3458EC0F) = vNor4(0xCBA713F0,0xCBA713F0)
0x00493DA8  vPopReg4 -> [0x0019FE14] = 0x00000206
0x00433334  vPushReg4 -> [0x0019FE18] -> push 0xCBA713F0
0x004B6966  (0x00000286,0xFFFFFFFF) = vNand4(0xCBA713F0,0x3458EC0F)
0x00453411  vPopReg4 -> [0x0019FE40] = 0x00000286
0x0043A13C  vPushReg4 -> [0x0019FE18] -> push 0xCBA713F0
0x00494385  vPushReg4 -> [0x0019FE18] -> push 0xCBA713F0
0x004B3AE2  vPushReg4 -> [0x0019FE18] -> push 0xCBA713F0
0x0046423B  (0x00000206,0x3458EC0F) = vNand4(0xCBA713F0,0xCBA713F0)
0x00478C66  vPopReg4 -> [0x0019FE40] = 0x00000206
0x0047417D  (0x00000286,0xFFFFFFFF) = vNand4(0x3458EC0F,0xCBA713F0)
0x004AFAC9  vPopReg4 -> [0x0019FE38] = 0x00000286
0x00459E51  (0x00000246,0x00000000) = vNand4(0xFFFFFFFF,0xFFFFFFFF)
0x004B3AAC  vPopReg4 -> [0x0019FE24] = 0x00000246
0x004BB8C6  vPopReg4 -> [0x0019FE40] = 0x00000000
0x004ACD2E  0xCBA713F0 = vReadMem4(0x0019FF04)
0x004675A0  vPopReg4 -> [0x0019FE14] = 0xCBA713F0
0x00443E96  vPushImm4 -> [0x0019FEF0] = 0x0000000C
0x00455D02  (0x00000216,0x0019FF14) = vAdd4(0x0000000C,0x0019FF08)
0x00496DEB  vPopReg4 -> [0x0019FE0C] = 0x00000216
0x0049DF0A  0xDEADC0DE = vReadMem4(0x0019FF14)
0x004ADC6E  vPushReg4 -> [0x0019FE14] -> push 0xCBA713F0
0x004BD01A  vPushReg4 -> [0x0019FE40] -> push 0x00000000
0x00483128  (0x00000202,0xCBA713F0,0x00000000) = vDiv(0x00000000CBA713F0,0xDEADC0DE)
0x0045DB45  vPopReg4 -> [0x0019FE20] = 0x00000202
0x0046E259  vPopReg4 -> [0x0019FE0C] = 0xCBA713F0
0x00434A2D  vPopReg4 -> [0x0019FE24] = 0x00000000
0x004412F4  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x004611E7  vPushImm4 -> [0x0019FEF0] = 0x0000000C
0x00434485  (0x00000216,0x0019FF14) = vAdd4(0x0000000C,0x0019FF08)
0x0049C796  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0048F933  vPushImm4 -> [0x0019FEE8] = 0xFFFFFFFC
0x00447DE0  vPushReg4 -> [0x0019FE24] -> push 0x00000000
0x00454004  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0047862F  vPushImm4 -> [0x0019FEDC] = 0xFFFFFFFC
0x0047B276  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x00493DA8  vPopReg4 -> [0x0019FE28] = 0x00000213
0x004387DB  vWriteMem4 -> [0x0019FF04] = 0x00000000
0x00448025  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x00453411  vPopReg4 -> [0x0019FE28] = 0x00000213
0x0049693C  0x00000000 = vReadMem4(0x0019FF04)
0x00478C66  vPopReg4 -> [0x0019FE20] = 0x00000000
0x004AFAC9  vPopReg4 -> [0x0019FE18] = 0x00000216
0x0048EA3E  0xDEADC0DE = vReadMem4(0x0019FF14)
0x0047249F  vPushVEsp 0x0019FEF4
0x0049605F  0xDEADC0DE = vReadMem4(0x0019FEF4)
0x004718A9  (0x00000206,0x21523F21) = vNor4(0xDEADC0DE,0xDEADC0DE)
0x004B3AAC  vPopReg4 -> [0x0019FE40] = 0x00000206
0x00474718  vPushReg4 -> [0x0019FE20] -> push 0x00000000
0x00433334  vPushReg4 -> [0x0019FE20] -> push 0x00000000
0x004BC537  (0x00000286,0xFFFFFFFF) = vNor4(0x00000000,0x00000000)
0x004BB8C6  vPopReg4 -> [0x0019FE28] = 0x00000286
0x004B8D8D  (0x00000246,0x00000000) = vNor4(0xFFFFFFFF,0x21523F21)
0x004675A0  vPopReg4 -> [0x0019FE40] = 0x00000246
0x00496DEB  vPopReg4 -> [0x0019FE18] = 0x00000000
0x0044C27C  vPushImm4 -> [0x0019FEF4] = 0x00401E09
0x0043A13C  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x00450289  vPushImm4 -> [0x0019FEEC] = 0x00000008
0x004ACF24  (0x00000212,0x0019FF10) = vAdd4(0x00000008,0x0019FF08)
0x00494385  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0043B6EE  vPushImm4 -> [0x0019FEE4] = 0xFFFFFFFC
0x004B3AE2  vPushReg4 -> [0x0019FE18] -> push 0x00000000
0x004ADC6E  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x004C0C92  vPushImm4 -> [0x0019FED8] = 0xFFFFFFFC
0x0045E73A  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x0045DB45  vPopReg4 -> [0x0019FE1C] = 0x00000213
0x00473B3E  vWriteMem4 -> [0x0019FF04] = 0x00000000
0x0043BC53  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x0046E259  vPopReg4 -> [0x0019FE20] = 0x00000213
0x004BD01A  vPushReg4 -> [0x0019FE0C] -> push 0xCBA713F0
0x004412F4  vPushReg4 -> [0x0019FE0C] -> push 0xCBA713F0
0x004A4319  (0x00000206,0x3458EC0F) = vNand4(0xCBA713F0,0xCBA713F0)
0x00434A2D  vPopReg4 -> [0x0019FE40] = 0x00000206
0x0049C796  vPushReg4 -> [0x0019FE0C] -> push 0xCBA713F0
0x00447DE0  vPushReg4 -> [0x0019FE0C] -> push 0xCBA713F0
0x0047149E  (0x00000206,0x3458EC0F) = vNand4(0xCBA713F0,0xCBA713F0)
0x00493DA8  vPopReg4 -> [0x0019FE40] = 0x00000206
0x004400E1  (0x00000286,0xCBA713F0) = vNor4(0x3458EC0F,0x3458EC0F)
0x00453411  vPopReg4 -> [0x0019FE40] = 0x00000286
0x00454004  vPushReg4 -> [0x0019FE0C] -> push 0xCBA713F0
0x00474718  vPushReg4 -> [0x0019FE0C] -> push 0xCBA713F0
0x00472872  (0x00000206,0x3458EC0F) = vNor4(0xCBA713F0,0xCBA713F0)
0x00478C66  vPopReg4 -> [0x0019FE1C] = 0x00000206
0x004596E6  (0x00000246,0x00000000) = vNor4(0x3458EC0F,0xCBA713F0)
0x004AFAC9  vPopReg4 -> [0x0019FE40] = 0x00000246
0x004B3AAC  vPopReg4 -> [0x0019FE24] = 0x00000000
0x00493716  0x00000000 = vReadMem4(0x0019FF04)
0x004BB8C6  vPopReg4 -> [0x0019FE38] = 0x00000000
0x004675A0  vPopReg4 -> [0x0019FE18] = 0x00000212
0x00495B56  0x12345678 = vReadMem4(0x0019FF10)
0x00433334  vPushReg4 -> [0x0019FE38] -> push 0x00000000
0x0043A13C  vPushReg4 -> [0x0019FE24] -> push 0x00000000
0x004742E4  (0x00000206,0x00000000,0x00000000) = vDiv(0x0000000000000000,0x12345678)
0x00496DEB  vPopReg4 -> [0x0019FE20] = 0x00000206
0x0045DB45  vPopReg4 -> [0x0019FE28] = 0x00000000
0x00494385  vPushReg4 -> [0x0019FE28] -> push 0x00000000
0x004B3AE2  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x004553C3  vPushImm4 -> [0x0019FEE4] = 0xFFFFFFFC
0x004B72B0  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x0046E259  vPopReg4 -> [0x0019FE24] = 0x00000213
0x004B8006  vWriteMem4 -> [0x0019FF04] = 0x00000000
0x004ADC6E  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0047A771  vPushImm4 -> [0x0019FEE8] = 0xFFFFFFFC
0x004B6320  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x00434A2D  vPopReg4 -> [0x0019FE20] = 0x00000213
0x0047C032  0x00000000 = vReadMem4(0x0019FF04)
0x00493DA8  vPopReg4 -> [0x0019FE14] = 0x00000000
0x004BD01A  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x00486D1C  vPushImm4 -> [0x0019FEE8] = 0x00000008
0x00440C16  (0x00000212,0x0019FF10) = vAdd4(0x00000008,0x0019FF08)
0x00453411  vPopReg4 -> [0x0019FE0C] = 0x00000212
0x004B3312  0x12345678 = vReadMem4(0x0019FF10)
0x00438A2C  vPushVEsp 0x0019FEEC
0x004AEFE3  0x12345678 = vReadMem4(0x0019FEEC)
0x00466B07  (0x00000286,0xEDCBA987) = vNand4(0x12345678,0x12345678)
0x00478C66  vPopReg4 -> [0x0019FE24] = 0x00000286
0x004412F4  vPushReg4 -> [0x0019FE14] -> push 0x00000000
0x0049C796  vPushReg4 -> [0x0019FE14] -> push 0x00000000
0x0045FF32  (0x00000286,0xFFFFFFFF) = vNor4(0x00000000,0x00000000)
0x004AFAC9  vPopReg4 -> [0x0019FE0C] = 0x00000286
0x004601A6  (0x00000246,0x00000000) = vNor4(0xFFFFFFFF,0xEDCBA987)
0x004B3AAC  vPopReg4 -> [0x0019FE24] = 0x00000246
0x00447DE0  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x00443E96  vPushImm4 -> [0x0019FEE4] = 0x00000008
0x004A11FB  (0x00000212,0x0019FF10) = vAdd4(0x00000008,0x0019FF08)
0x004BB8C6  vPopReg4 -> [0x0019FE24] = 0x00000212
0x0044D78D  0x12345678 = vReadMem4(0x0019FF10)
0x00454004  vPushReg4 -> [0x0019FE14] -> push 0x00000000
0x004BE66F  (0x00000286,0xEDCBA987) = vNor4(0x00000000,0x12345678)
0x004675A0  vPopReg4 -> [0x0019FE40] = 0x00000286
0x00440238  (0x00000206,0x12345678) = vNor4(0xEDCBA987,0x00000000)
0x00496DEB  vPopReg4 -> [0x0019FE24] = 0x00000206
0x0045DB45  vPopReg4 -> [0x0019FE0C] = 0x12345678
0x00474718  vPushReg4 -> [0x0019FE0C] -> push 0x12345678
0x00433334  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x004611E7  vPushImm4 -> [0x0019FEE4] = 0xFFFFFFFC
0x00455D02  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x0046E259  vPopReg4 -> [0x0019FE1C] = 0x00000213
0x00450FDF  vWriteMem4 -> [0x0019FF04] = 0x12345678
0x0043A13C  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0048F933  vPushImm4 -> [0x0019FEE8] = 0xFFFFFFFC
0x00434485  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x00434A2D  vPopReg4 -> [0x0019FE24] = 0x00000213
0x004ACD2E  0x12345678 = vReadMem4(0x0019FF04)
0x00493DA8  vPopReg4 -> [0x0019FE40] = 0x12345678
0x00494385  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0047862F  vPushImm4 -> [0x0019FEE8] = 0x0000000C
0x0047B276  (0x00000216,0x0019FF14) = vAdd4(0x0000000C,0x0019FF08)
0x00453411  vPopReg4 -> [0x0019FE14] = 0x00000216
0x0049DF0A  0xDEADC0DE = vReadMem4(0x0019FF14)
0x004B8432  vPushVEsp 0x0019FEEC
0x0049693C  0xDEADC0DE = vReadMem4(0x0019FEEC)
0x00492CE8  (0x00000206,0x21523F21) = vNor4(0xDEADC0DE,0xDEADC0DE)
0x00478C66  vPopReg4 -> [0x0019FE1C] = 0x00000206
0x004B3AE2  vPushReg4 -> [0x0019FE40] -> push 0x12345678
0x004ADC6E  vPushReg4 -> [0x0019FE40] -> push 0x12345678
0x0048273D  (0x00000286,0xEDCBA987) = vNand4(0x12345678,0x12345678)
0x004AFAC9  vPopReg4 -> [0x0019FE24] = 0x00000286
0x004718A9  (0x00000202,0x12244058) = vNor4(0xEDCBA987,0x21523F21)
0x004B3AAC  vPopReg4 -> [0x0019FE34] = 0x00000202
0x004BD01A  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x0044C27C  vPushImm4 -> [0x0019FEE4] = 0x0000000C
0x00448025  (0x00000216,0x0019FF14) = vAdd4(0x0000000C,0x0019FF08)
0x004BB8C6  vPopReg4 -> [0x0019FE14] = 0x00000216
0x0048EA3E  0xDEADC0DE = vReadMem4(0x0019FF14)
0x004412F4  vPushReg4 -> [0x0019FE40] -> push 0x12345678
0x004BC537  (0x00000202,0x21422901) = vNor4(0x12345678,0xDEADC0DE)
0x004675A0  vPopReg4 -> [0x0019FE34] = 0x00000202
0x004B8D8D  (0x00000286,0xCC9996A6) = vNor4(0x21422901,0x12244058)
0x00496DEB  vPopReg4 -> [0x0019FE24] = 0x00000286
0x0045DB45  vPopReg4 -> [0x0019FE14] = 0xCC9996A6
0x0049C796  vPushReg4 -> [0x0019FE14] -> push 0xCC9996A6
0x00447DE0  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x00450289  vPushImm4 -> [0x0019FEE4] = 0xFFFFFFFC
0x004ACF24  (0x00000213,0x0019FF04) = vAdd4(0xFFFFFFFC,0x0019FF08)
0x0046E259  vPopReg4 -> [0x0019FE20] = 0x00000213
0x004BA046  vWriteMem4 -> [0x0019FF04] = 0xCC9996A6
0x00434A2D  vPopReg4 -> [0x0019FE28] = 0x00000000
0x00454004  vPushReg4 -> [0x0019FE48] -> push 0x0019FF08
0x00474718  vPushReg4 -> [0x0019FE14] -> push 0xCC9996A6
0x00433334  vPushReg4 -> [0x0019FE0C] -> push 0x12345678
0x0043A13C  vPushReg4 -> [0x0019FE44] -> push 0x00721D90
0x00494385  vPushReg4 -> [0x0019FE24] -> push 0x00000286
0x004B3AE2  vPushReg4 -> [0x0019FE30] -> push 0x0028B000
0x004ADC6E  vPushReg4 -> [0x0019FE3C] -> push 0x0071DA20
0x004BD01A  vPushReg4 -> [0x0019FE28] -> push 0x00000000
0x0046A912  vExit

GhidraIR生成

很明显,这么一大堆handler阅读起来非常困难,我要这打印有何用......


那么转变分析思路,我们知道vm代码是拿ebp这类寄存器当作实际程序的堆栈寄存器,而esp则沦为了vmContext,指向vm自定义寄存器,我们既然已经拿到了handler,不如将其转换为基于堆栈的操作。

例如vStoreContext这个handler,我们将其翻译为等价于以下汇编的GhidraIR

1
2
3
4
5
6
7
8
9
10
11
push 0x0FBC1001
push 0x0048C18E
push eflags
push EDI
push EBX
push EAX
push EBP
push ESI
push EDX
push ECX
push 0x0

再比如vPushReg4这个handler,在vmp中汇编是这样的

1
2
3
mov ecx,dword ptr ss:[esp+edx]
sub esi,0x4
mov dword ptr ds:[esi],ecx

我们将其翻译成等价于以下汇编的GhidraIR,这里ecx的来源esp偏移要提前计算好

1
2
mov ecx,[esp+xxx]
push ecx

最后一个例子vDiv,在汇编中的表现形式是

1
2
3
4
5
6
7
8
mov eax,dword ptr ds:[esi+0x4]
mov edx,dword ptr ds:[esi]
mov ecx,dword ptr ds:[esi+0x8]
div ecx
mov dword ptr ds:[esi+0x4],edx
mov dword ptr ds:[esi+0x8],eax
pushfd
pop dword ptr ds:[esi]

我们将其翻译成等价于以下汇编的GhidraIR

1
2
3
4
5
6
7
mov eax,dword ptr ds:[esp+0x4]
mov edx,dword ptr ds:[esp]
mov ecx,dword ptr ds:[esp+0x8]
div ecx
mov dword ptr ds:[esp],eflags
mov dword ptr ds:[esp+0x4],edx
mov dword ptr ds:[esp+0x8],eax

反编译

不得不说,给每个handler编写IR生成代码还挺累的,写完了以后进行反编译,得到的化简IR如下:

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
0
Basic Block 0 0x0048c184-0x004c0c92
0x004a11fb:9c:  u0x10002f95(0x004a11fb:9c) = EBP(i) + #0xfffffffc
0x004a11fb:139b:    u0x100000d4(0x004a11fb:139b) = (cast) u0x10002f95(0x004a11fb:9c)
0x004b3312:cd:  u0x1000015a(0x004b3312:cd) = *(ram,u0x100000d4(0x004a11fb:139b))
0x00455d02:da:  u0x10002f99(0x00455d02:da) = EBP(i) + #0x8
0x00455d02:139c:    u0x10000172(0x00455d02:139c) = (cast) u0x10002f99(0x00455d02:da)
0x004aefe3:10b: u0x100001f8(0x004aefe3:10b) = *(ram,u0x10000172(0x00455d02:139c))
0x00434485:115: u0x1000020c(0x00434485:115) = u0x1000015a(0x004b3312:cd) + u0x100001f8(0x004aefe3:10b)
0x0047b276:153: u0x10002f9d(0x0047b276:153) = EBP(i) + #0xfffffffc
0x0047b276:139d:    u0x100002a6(0x0047b276:139d) = (cast) u0x10002f9d(0x0047b276:153)
0x00448025:18e: u0x10002fa1(0x00448025:18e) = EBP(i) + #0xfffffffc
0x00448025:139e:    u0x1000033c(0x00448025:139e) = (cast) u0x10002fa1(0x00448025:18e)
0x0045bdcd:1c1: *(ram,u0x1000033c(0x00448025:139e)) = u0x1000020c(0x00434485:115)
0x0044d78d:1c7: u0x100003ce(0x0044d78d:1c7) = *(ram,u0x100002a6(0x0047b276:139d))
0x004acf24:1d7: u0x10002fa5(0x004acf24:1d7) = EBP(i) + #0xc
0x004acf24:139f:    u0x100003ea(0x004acf24:139f) = (cast) u0x10002fa5(0x004acf24:1d7)
0x004acd2e:208: u0x10000470(0x004acd2e:208) = *(ram,u0x100003ea(0x004acf24:139f))
0x0045e73a:212: u0x10000484(0x0045e73a:212) = u0x100003ce(0x0044d78d:1c7) + u0x10000470(0x004acd2e:208)
0x0043bc53:253: u0x10002fa9(0x0043bc53:253) = EBP(i) + #0xfffffffc
0x0043bc53:13a0:    u0x10000522(0x0043bc53:13a0) = (cast) u0x10002fa9(0x0043bc53:253)
0x004b72b0:28e: u0x10002fad(0x004b72b0:28e) = EBP(i) + #0xfffffffc
0x004b72b0:13a1:    u0x100005b8(0x004b72b0:13a1) = (cast) u0x10002fad(0x004b72b0:28e)
0x0043f7c2:2c1: *(ram,u0x100005b8(0x004b72b0:13a1)) = u0x10000484(0x0045e73a:212)
0x0049df0a:2c7: u0x1000064a(0x0049df0a:2c7) = *(ram,u0x10000522(0x0043bc53:13a0))
0x004b6320:2d4: u0x10002fb1(0x004b6320:2d4) = EBP(i) + #0x8
0x004b6320:13a2:    u0x10000662(0x004b6320:13a2) = (cast) u0x10002fb1(0x004b6320:2d4)
0x0049693c:305: u0x100006e8(0x0049693c:305) = *(ram,u0x10000662(0x004b6320:13a2))
0x004601a6:310: u0x10000700(0x004601a6:310) = ~ u0x1000064a(0x0049df0a:2c7)
0x00440c16:349: u0x10000799(0x00440c16:349) = u0x10000700(0x004601a6:310) + u0x100006e8(0x0049693c:305)
0x0044f0a7:382: u0x10000833(0x0044f0a7:382) = ~ u0x10000799(0x00440c16:349)
0x004a11fb:3ca: u0x10002fb5(0x004a11fb:3ca) = EBP(i) + #0xfffffffc
0x004a11fb:13a3:    u0x100008e0(0x004a11fb:13a3) = (cast) u0x10002fb5(0x004a11fb:3ca)
0x00455d02:405: u0x10002fb9(0x00455d02:405) = EBP(i) + #0xfffffffc
0x00455d02:13a4:    u0x10000976(0x00455d02:13a4) = (cast) u0x10002fb9(0x00455d02:405)
0x00499ed8:438: *(ram,u0x10000976(0x00455d02:13a4)) = u0x10000833(0x0044f0a7:382)
0x0049605f:43e: u0x10000a08(0x0049605f:43e) = *(ram,u0x100008e0(0x004a11fb:13a3))
0x00434485:448: u0x10002fbd(0x00434485:448) = EBP(i) + #0xc
0x00434485:13a5:    u0x10000a1c(0x00434485:13a5) = (cast) u0x10002fbd(0x00434485:448)
0x00493716:479: u0x10000aa2(0x00493716:479) = *(ram,u0x10000a1c(0x00434485:13a5))
0x004be66f:484: u0x10000aba(0x004be66f:484) = ~ u0x10000a08(0x0049605f:43e)
0x0047b276:4bd: u0x10000b53(0x0047b276:4bd) = u0x10000aba(0x004be66f:484) + u0x10000aa2(0x00493716:479)
0x00440238:4f6: u0x10000bed(0x00440238:4f6) = ~ u0x10000b53(0x0047b276:4bd)
0x00448025:538: u0x10002fc1(0x00448025:538) = EBP(i) + #0x8
0x00448025:13a6:    u0x10000c92(0x00448025:13a6) = (cast) u0x10002fc1(0x00448025:538)
0x004acf24:573: u0x10002fc5(0x004acf24:573) = EBP(i) + #0xfffffffc
0x004acf24:13a7:    u0x10000d28(0x004acf24:13a7) = (cast) u0x10002fc5(0x004acf24:573)
0x004acf50:5a6: *(ram,u0x10000d28(0x004acf24:13a7)) = u0x10000bed(0x00440238:4f6)
0x0045e73a:5b3: u0x10002fc9(0x0045e73a:5b3) = EBP(i) + #0xfffffffc
0x0045e73a:13a8:    u0x10000dc6(0x0045e73a:13a8) = (cast) u0x10002fc9(0x0045e73a:5b3)
0x0047c032:5e4: u0x10000e4c(0x0047c032:5e4) = *(ram,u0x10000dc6(0x0045e73a:13a8))
0x004b3312:5ed: u0x10000e5c(0x004b3312:5ed) = *(ram,u0x10000c92(0x00448025:13a6))
0x0046e6b1:1395:    u0x10000e80(0x0046e6b1:1395) = u0x10000e5c(0x004b3312:5ed) * u0x10000e4c(0x0047c032:5e4)
0x0043bc53:639: u0x10002fcd(0x0043bc53:639) = EBP(i) + #0xc
0x0043bc53:13a9:    u0x10000f29(0x0043bc53:13a9) = (cast) u0x10002fcd(0x0043bc53:639)
0x004b72b0:677: u0x10002fd1(0x004b72b0:677) = EBP(i) + #0xfffffffc
0x004b72b0:13aa:    u0x10000fc3(0x004b72b0:13aa) = (cast) u0x10002fd1(0x004b72b0:677)
0x004b6fb9:6aa: *(ram,u0x10000fc3(0x004b72b0:13aa)) = u0x10000e80(0x0046e6b1:1395)
0x004b6320:6b4: u0x10002fd5(0x004b6320:6b4) = EBP(i) + #0xfffffffc
0x004b6320:13ab:    u0x1000105d(0x004b6320:13ab) = (cast) u0x10002fd5(0x004b6320:6b4)
0x004aefe3:6e5: u0x100010e3(0x004aefe3:6e5) = *(ram,u0x1000105d(0x004b6320:13ab))
0x0044d78d:6ee: u0x100010f3(0x0044d78d:6ee) = *(ram,u0x10000f29(0x0043bc53:13a9))
0x00478a95:1398:    u0x10001117(0x00478a95:1398) = u0x100010f3(0x0044d78d:6ee) * u0x100010e3(0x004aefe3:6e5)
0x00440c16:73d: u0x10002fd9(0x00440c16:73d) = EBP(i) + #0xfffffffc
0x00440c16:13ac:    u0x100011c4(0x00440c16:13ac) = (cast) u0x10002fd9(0x00440c16:73d)
0x004a11fb:778: u0x10002fdd(0x004a11fb:778) = EBP(i) + #0xfffffffc
0x004a11fb:13ad:    u0x1000125a(0x004a11fb:13ad) = (cast) u0x10002fdd(0x004a11fb:778)
0x004adec1:7ab: *(ram,u0x1000125a(0x004a11fb:13ad)) = u0x10001117(0x00478a95:1398)
0x004acd2e:8d9: u0x10001605(0x004acd2e:8d9) = *(ram,u0x100011c4(0x00440c16:13ac))
0x00455d02:8e6: u0x10002fe1(0x00455d02:8e6) = EBP(i) + #0xc
0x00455d02:13ae:    u0x1000161d(0x00455d02:13ae) = (cast) u0x10002fe1(0x00455d02:8e6)
0x0049df0a:917: u0x100016a3(0x0049df0a:917) = *(ram,u0x1000161d(0x00455d02:13ae))
0x00483128:929: u0x100016f3(0x00483128:929) = u0x10001605(0x004acd2e:8d9) / u0x100016a3(0x0049df0a:917)
0x00434485:968: u0x10002fe5(0x00434485:968) = EBP(i) + #0xc
0x00434485:13af:    u0x10001794(0x00434485:13af) = (cast) u0x10002fe5(0x00434485:968)
0x0047b276:9a9: u0x10002fe9(0x0047b276:9a9) = EBP(i) + #0xfffffffc
0x0047b276:13b0:    u0x10001832(0x0047b276:13b0) = (cast) u0x10002fe9(0x0047b276:9a9)
0x004387db:9dc: *(ram,u0x10001832(0x0047b276:13b0)) = u0x100016f3(0x00483128:929)
0x00448025:9e3: u0x10002fed(0x00448025:9e3) = EBP(i) + #0xfffffffc
0x00448025:13b1:    u0x100018c8(0x00448025:13b1) = (cast) u0x10002fed(0x00448025:9e3)
0x0049693c:a14: u0x1000194e(0x0049693c:a14) = *(ram,u0x100018c8(0x00448025:13b1))
0x0048ea3e:a1d: u0x1000195e(0x0048ea3e:a1d) = *(ram,u0x10001794(0x00434485:13af))
0x004b8d8d:aa0: u0x10001abc(0x004b8d8d:aa0) = u0x1000194e(0x0049693c:a14) & u0x1000195e(0x0048ea3e:a1d)
0x004acf24:ae1: u0x10002ff1(0x004acf24:ae1) = EBP(i) + #0x8
0x004acf24:13b2:    u0x10001b5d(0x004acf24:13b2) = (cast) u0x10002ff1(0x004acf24:ae1)
0x0045e73a:b22: u0x10002ff5(0x0045e73a:b22) = EBP(i) + #0xfffffffc
0x0045e73a:13b3:    u0x10001bfb(0x0045e73a:13b3) = (cast) u0x10002ff5(0x0045e73a:b22)
0x00473b3e:b55: *(ram,u0x10001bfb(0x0045e73a:13b3)) = u0x10001abc(0x004b8d8d:aa0)
0x0043bc53:b5c: u0x10002ff9(0x0043bc53:b5c) = EBP(i) + #0xfffffffc
0x0043bc53:13b4:    u0x10001c91(0x0043bc53:13b4) = (cast) u0x10002ff9(0x0043bc53:b5c)
0x00493716:cb5: u0x10002030(0x00493716:cb5) = *(ram,u0x10001c91(0x0043bc53:13b4))
0x00495b56:cbe: u0x10002040(0x00495b56:cbe) = *(ram,u0x10001b5d(0x004acf24:13b2))
0x004742e4:cd0: u0x10002090(0x004742e4:cd0) = u0x10002030(0x00493716:cb5) / u0x10002040(0x00495b56:cbe)
0x004742e4:cd2: u0x1000209c(0x004742e4:cd2) = u0x10002030(0x00493716:cb5) % u0x10002040(0x00495b56:cbe)
0x004b72b0:d0f: u0x10002ffd(0x004b72b0:d0f) = EBP(i) + #0xfffffffc
0x004b72b0:13b5:    u0x10002131(0x004b72b0:13b5) = (cast) u0x10002ffd(0x004b72b0:d0f)
0x004b8006:d42: *(ram,u0x10002131(0x004b72b0:13b5)) = u0x1000209c(0x004742e4:cd2)
0x004b6320:d4f: u0x10003001(0x004b6320:d4f) = EBP(i) + #0xfffffffc
0x004b6320:13b6:    u0x100021cf(0x004b6320:13b6) = (cast) u0x10003001(0x004b6320:d4f)
0x0047c032:d80: u0x10002255(0x0047c032:d80) = *(ram,u0x100021cf(0x004b6320:13b6))
0x00440c16:d90: u0x10003005(0x00440c16:d90) = EBP(i) + #0x8
0x00440c16:13b7:    u0x10002271(0x00440c16:13b7) = (cast) u0x10003005(0x00440c16:d90)
0x004b3312:dc1: u0x100022f7(0x004b3312:dc1) = *(ram,u0x10002271(0x00440c16:13b7))
0x004601a6:e44: u0x10002455(0x004601a6:e44) = u0x10002255(0x0047c032:d80) & u0x100022f7(0x004b3312:dc1)
0x004a11fb:e7f: u0x10003009(0x004a11fb:e7f) = EBP(i) + #0x8
0x004a11fb:13b8:    u0x100024ee(0x004a11fb:13b8) = (cast) u0x10003009(0x004a11fb:e7f)
0x0044d78d:eb0: u0x10002574(0x0044d78d:eb0) = *(ram,u0x100024ee(0x004a11fb:13b8))
0x004be66f:eb8: u0x10002588(0x004be66f:eb8) = ~ u0x10002255(0x0047c032:d80)
0x004be66f:eb9: u0x1000258c(0x004be66f:eb9) = ~ u0x10002574(0x0044d78d:eb0)
0x004be66f:ebc: u0x10002590(0x004be66f:ebc) = u0x10002588(0x004be66f:eb8) & u0x1000258c(0x004be66f:eb9)
0x00440238:eef: u0x10002621(0x00440238:eef) = ~ u0x10002590(0x004be66f:ebc)
0x00440238:ef0: u0x10002625(0x00440238:ef0) = ~ u0x10002455(0x004601a6:e44)
0x00440238:ef3: u0x10002629(0x00440238:ef3) = u0x10002621(0x00440238:eef) & u0x10002625(0x00440238:ef0)
0x00455d02:f34: u0x1000300d(0x00455d02:f34) = EBP(i) + #0xfffffffc
0x00455d02:13b9:    u0x100026ca(0x00455d02:13b9) = (cast) u0x1000300d(0x00455d02:f34)
0x00450fdf:f67: *(ram,u0x100026ca(0x00455d02:13b9)) = u0x10002629(0x00440238:ef3)
0x00434485:f74: u0x10003011(0x00434485:f74) = EBP(i) + #0xfffffffc
0x00434485:13ba:    u0x10002768(0x00434485:13ba) = (cast) u0x10003011(0x00434485:f74)
0x004acd2e:fa5: u0x100027ee(0x004acd2e:fa5) = *(ram,u0x10002768(0x00434485:13ba))
0x0047b276:fb5: u0x10003015(0x0047b276:fb5) = EBP(i) + #0xc
0x0047b276:13bb:    u0x1000280a(0x0047b276:13bb) = (cast) u0x10003015(0x0047b276:fb5)
0x0049df0a:fe6: u0x10002890(0x0049df0a:fe6) = *(ram,u0x1000280a(0x0047b276:13bb))
0x004718a9:1069:    u0x100029ee(0x004718a9:1069) = u0x100027ee(0x004acd2e:fa5) & u0x10002890(0x0049df0a:fe6)
0x00448025:10a4:    u0x10003019(0x00448025:10a4) = EBP(i) + #0xc
0x00448025:13bc:    u0x10002a87(0x00448025:13bc) = (cast) u0x10003019(0x00448025:10a4)
0x0048ea3e:10d5:    u0x10002b0d(0x0048ea3e:10d5) = *(ram,u0x10002a87(0x00448025:13bc))
0x004bc537:10dd:    u0x10002b21(0x004bc537:10dd) = ~ u0x100027ee(0x004acd2e:fa5)
0x004bc537:10de:    u0x10002b25(0x004bc537:10de) = ~ u0x10002b0d(0x0048ea3e:10d5)
0x004bc537:10e1:    u0x10002b29(0x004bc537:10e1) = u0x10002b21(0x004bc537:10dd) & u0x10002b25(0x004bc537:10de)
0x004b8d8d:1114:    u0x10002bba(0x004b8d8d:1114) = ~ u0x10002b29(0x004bc537:10e1)
0x004b8d8d:1115:    u0x10002bbe(0x004b8d8d:1115) = ~ u0x100029ee(0x004718a9:1069)
0x004b8d8d:1118:    u0x10002bc2(0x004b8d8d:1118) = u0x10002bba(0x004b8d8d:1114) & u0x10002bbe(0x004b8d8d:1115)
0x004acf24:1159:    u0x1000301d(0x004acf24:1159) = EBP(i) + #0xfffffffc
0x004acf24:13bd:    u0x10002c63(0x004acf24:13bd) = (cast) u0x1000301d(0x004acf24:1159)
0x004ba046:118c:    *(ram,u0x10002c63(0x004acf24:13bd)) = u0x10002bc2(0x004b8d8d:1118)
0x0046a912:11a9:    EAX(0x0046a912:11a9) = u0x10002090(0x004742e4:cd0)
0x0046a912:11ab:    ESI(0x0046a912:11ab) = ESI(i)
0x0046a912:11ad:    EBX(0x0046a912:11ad) = EBX(i)
0x0046a912:11b1:    EDI(0x0046a912:11b1) = EDI(i)
0x0046a912:11b3:    ECX(0x0046a912:11b3) = u0x10002629(0x00440238:ef3)
0x0046a912:11b5:    EDX(0x0046a912:11b5) = u0x10002bc2(0x004b8d8d:1118)
0x0046a912:11b7:    EBP(0x0046a912:11b7) = EBP(i)
0x0046a912:11bb:    return(EAX(0x0046a912:11a9)) ECX(0x0046a912:11b3),EDX(0x0046a912:11b5),EBX(0x0046a912:11ad),EBP(0x0046a912:11b7),ESI(0x0046a912:11ab),EDI(0x0046a912:11b1),EAX(0x0046a912:11a9),EDX(0x0046a912:11b5)

这样其实已经能够进行一些阅读分析了,再调用Ghidra的IR转C,得到以下C代码:

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
void sub_0(void)
{
  uint4 uVar1;
  uint4 uVar2;
  uint4 uVar3;
  xunknown4 unaff_EBX;
  int4 unaff_EBP;
  xunknown4 unaff_ESI;
  xunknown4 unaff_EDI;
   
  *(int4 *)(unaff_EBP + -4) = *(int4 *)(unaff_EBP + -4) + *(int4 *)(unaff_EBP + 8);
  *(int4 *)(unaff_EBP + -4) = *(int4 *)(unaff_EBP + -4) + *(int4 *)(unaff_EBP + 0xc);
  *(uint4 *)(unaff_EBP + -4) = ~(~*(uint4 *)(unaff_EBP + -4) + *(int4 *)(unaff_EBP + 8));
  *(uint4 *)(unaff_EBP + -4) = ~(~*(uint4 *)(unaff_EBP + -4) + *(int4 *)(unaff_EBP + 0xc));
  *(int4 *)(unaff_EBP + -4) = *(int4 *)(unaff_EBP + 8) * *(int4 *)(unaff_EBP + -4);
  *(int4 *)(unaff_EBP + -4) = *(int4 *)(unaff_EBP + 0xc) * *(int4 *)(unaff_EBP + -4);
  *(uint4 *)(unaff_EBP + -4) = *(uint4 *)(unaff_EBP + -4) / *(uint4 *)(unaff_EBP + 0xc);
  *(uint4 *)(unaff_EBP + -4) = *(uint4 *)(unaff_EBP + -4) & *(uint4 *)(unaff_EBP + 0xc);
  uVar2 = *(uint4 *)(unaff_EBP + -4);
  *(uint4 *)(unaff_EBP + -4) = uVar2 % *(uint4 *)(unaff_EBP + 8);
  uVar1 = ~(~*(uint4 *)(unaff_EBP + -4) & ~*(uint4 *)(unaff_EBP + 8)) &
          ~(*(uint4 *)(unaff_EBP + -4) & *(uint4 *)(unaff_EBP + 8));
  *(uint4 *)(unaff_EBP + -4) = uVar1;
  uVar3 = ~(~*(uint4 *)(unaff_EBP + -4) & ~*(uint4 *)(unaff_EBP + 0xc)) &
          ~(*(uint4 *)(unaff_EBP + -4) & *(uint4 *)(unaff_EBP + 0xc));
  *(uint4 *)(unaff_EBP + -4) = uVar3;
  uVar2 = uVar2 / *(uint4 *)(unaff_EBP + 8);
  return uVar1;
}

整理一下

1
2
3
4
5
6
7
8
9
10
11
[ebp-4] = [ebp-4] + [ebp+8]
[ebp-4] = [ebp-4] + [ebp+C]
[ebp-4] = ~(~[ebp-4] + [ebp+8])
[ebp-4] = ~(~[ebp-4] + [ebp+C])
[ebp-4] = [ebp+8] * [ebp-4]
[ebp-4] = [ebp+C] * [ebp-4]
[ebp-4] = [ebp-4] / [ebp+C];
[ebp-4] = [ebp-4] & [ebp+C];
[ebp-4] = [ebp-4] % [ebp+8]
[ebp-4] = ~(~[ebp-4] & ~[ebp+8]) & ~([ebp-4] & [ebp+8]);
[ebp-4] = ~(~[ebp-4] & ~[ebp+C]) & ~([ebp-4] & [ebp+C]);

好像还可以接受。


总结

1、目前只是做了一次基础的还原尝试,像vmp中重要的分支跳转、call很多问题都还没有处理,像这一次vJmp handler我都是把它当成add esp,0x4来忽略掉的

2、我个人认为vmp将一套指令集转换为另一套指令集,中间信息可能会发生损失,因此没必要再还原回汇编了,就直接对vmp的opcode进行反编译分析,其实还挺不错。

3、vmp将一些基础运算进行了变异,像上面的减法和异或运算,这些后续理论上也可以继续编写Ghidra规则来进行优化。



[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!

最后于 2023-9-27 16:52 被fjqisba编辑 ,原因:
收藏
免费 5
支持
分享
赞赏记录
参与人
雪币
留言
时间
g0mx
为你点赞~
2024-1-2 16:18
wInFoG_2017
为你点赞~
2023-9-28 14:20
R0g
为你点赞~
2023-9-28 03:29
hkdong
为你点赞~
2023-9-27 15:56
fjqisba
为你点赞~
2023-9-27 13:57
最新回复 (7)
雪    币: 228
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
大佬移动端加壳的VMP研究过没
2023-9-27 13:33
0
雪    币: 6
活跃值: (1242)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
非常好,大佬给了一个还原方向
2023-9-27 13:56
0
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
6666
2023-9-27 16:35
0
雪    币: 452
活跃值: (1709)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
我不太熟悉VMP,看着文章感觉它好像是个基于栈的虚拟机?这里面的“给每个handler编写IR生成代码”这个是怎么做的?(难道是手写的吗)虽然Ghidra里面也有对JVM字节码的反编译描述实现,但是那一套描述十分的。。。丑
2023-9-28 09:51
0
雪    币: 2656
活跃值: (7188)
能力值: ( LV7,RANK:102 )
在线值:
发帖
回帖
粉丝
6
wInFoG_2017 我不太熟悉VMP,看着文章感觉它好像是个基于栈的虚拟机?这里面的“给每个handler编写IR生成代码”这个是怎么做的?(难道是手写的吗)虽然Ghidra里面也有对JVM字节码的反编译描述实现,但是那 ...

对,我估计vmp相当于是把X86指令集转成类似于C#、JAVA那种基于堆栈的指令集了,当然C#和JAVA我也不太懂。

给每个handler编写IR生成代码,这个由于Ghidra是开源的做起来并不难,Ghidra将汇编转成IR的逻辑都在Sleigh::oneInstruction函数里面,分析清楚IR的结构,就能主动给Funcdata添加IR,比如下面是构造一个push const的IR代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void FuncBuildHelper::BuildPushConst(ghidra::Funcdata& data, size_t addr, size_t val)
{
    auto regESP = data.getArch()->translate->getRegister("ESP");
 
    ghidra::Address pc = ghidra::Address(data.getArch()->getDefaultCodeSpace(), addr);
    ghidra::PcodeOp* opCopy = data.newOp(1, pc);
    data.opSetOpcode(opCopy, ghidra::CPUI_COPY);
    ghidra::Varnode* uniqReg = data.newUniqueOut(4, opCopy);
    data.opSetInput(opCopy, data.newConstant(0x4, val), 0);
 
    ghidra::PcodeOp* opSub = data.newOp(2, pc);
    data.opSetOpcode(opSub, ghidra::CPUI_INT_SUB);
    data.newVarnodeOut(regESP.size, regESP.getAddr(), opSub);
    data.opSetInput(opSub, data.newVarnode(regESP.size, regESP.space, regESP.offset), 0);
    data.opSetInput(opSub, data.newConstant(4, 0x4), 1);
 
    ghidra::PcodeOp* opStore = data.newOp(3, pc);
    data.opSetOpcode(opStore, ghidra::CPUI_STORE);
    data.opSetInput(opStore, data.newVarnodeSpace(data.getArch()->getSpaceByName("ram")), 0);
    data.opSetInput(opStore, data.newVarnode(regESP.size, regESP.space, regESP.offset), 1);
    data.opSetInput(opStore, uniqReg, 2);
}


2023-9-28 10:37
1
雪    币: 4233
活跃值: (31506)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感谢分享
2023-11-7 18:28
1
雪    币: 0
活跃值: (658)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
大佬,你那个打印handler是自己编译的VMP打印的吗
2024-6-27 22:03
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册