学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

2万

积分

41

好友

1171

主题

[转载图文] 谈谈vmp的还原(2)

发表于 2020-9-18 14:08:03 | 查看: 2234| 回复: 0
0x00 前言
写之前就在想该以一个怎样的方式阐述这些东西,最终还是决定以逆推的方式来描述
另外 先回答下问题 分析的是vmp的主程序,很早的版本


0x01 虚拟化后
测试的指令


1
2
3
4
5
68 34504200      PUSH OFFSET zf.??_C@_02MECO@?$CFd?$AA@   ; /format = "%d"
E8 13010000      CALL zf.scanf                            ; \scanf
83C4 08          ADD ESP,0x8
817D FC 33020000 CMP DWORD PTR SS:[EBP-0x4],0x233
75 09            JNZ SHORT zf.00401062


被用来vm的两条指令:

1
2
817DFC33020000          cmp dword ptr [ebp-04],00000233
7509                    jnz 00401062


先看看是cmp被vm之后的情况,因为既然大S提到了这个,看了他的帖子,所以叫他大S
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
1.lodsd -0x233
  push -0x233
   
stack_top   fffffdcd
   
2.lodsb [index]
  push _context[index] <===> push ebp
   
stack_top   ebp
        fffffdcd

3.lodsb [disp]
  push disp
   
stack_top   disp
        ebp
        fffffdcd

4.pop disp
  add ebp,dis <===> get addr input

stack_top   ebp+disp
        fffffdcd
     
5.pop addr (input)
  push input

stack_top   input
        fffffdcd

6.pop input
  add [-0x233],input ... get a
     
stack_top   fffffe48
   
  pushfw
     
stack_top   fe480296

7.push eflags
stack_top    02960216
             00fffffe48

8.push stack
stack_top   ebp
        02960216
        fffffe48

9.pop stack
  push [stack]
   
stack_top   02160216
        fe480296

10.and(not(eflags),not(eflags))
stack_top   fde9fde9

stack_top   0296fde9
        fffffe48

11.lodsw ~0x400
    push ~0x400
     
stack_top   FDE9FBFF
        FE480296
     
11.and(not(eflags),not(~0x400)) = and(eflags,0x400)
stack_top   02160400

stack_top   02960000
        fffffe48

12.pop result
   add [pushfw],result
     
stack_top   fe480296 <==> 0296+result
     
13.lodsb [index]
   pop _context[index]

_context[index] == 0296
stack_top   fffffe48

14.pop a

eax == a <==> fffffe48
stack_top ebp

15.push lodsw[esi]
   push 0x11
     
stack_top   FF48FFEE
            0018

16.push [pushfw]
stack_top   FFEE0296
            0018FF48
17.push [pushfw]
stack_top   02960296
        FF48FFEE
        00000018

18.and(not(pushfw),not(pushfw))
stack_top   FD69FD69
        FF48FFEE
        00000018
            
stack_top   FFEEFD69
        0018FF48

19.and(0x11,pushfw)
stack_top   FF480010 <==> and(0x11,0x269)
                0018


20.push pushfw
stack_top   00100296
        0018FF48

21.lodb push 0x11
stack_top    02960011
             FF480010
                 0018


22.and(not(pushfw),not(0x11))
stack_top       0010FD68
        0018FF48

23.and(not(result),not(0x11))
stack_top       FF480287
            0018

24.lodb [index]
   push _context[index] <===> push [pushfw]
     
stack_top       02870296
        0018FF48
            
24.lodb [index]
   push _context[index] <===> push [pushfw]
     
stack_top       02960296
        FF480287
            0018

25.and(296,296)

stack_top       0287FD69
        0018FF48

26.lodw ~0x400
    push ~0x400
     
stack_top       FD69FBFF
                FF480287
        0018
                 
27.and(0x400,0x296)

stack_top   02870000
        0018FF48

28.pop result
   add [esp],result
   
stack_top   FF480287
        00000018
              
29.lodsb [index]
     pop _context[index] <==> result save to context
     
stack_top   0018FF48

28.lodsb [index]
     push _context[index]
   
stack_top   00000000
                0018FF48

以上就是cmp的vm流程

hex如下
0042FB21  6C CD FD CF 05 38 FC 69  l妄?8黫
0042FB29  C4 C1 B6 08 0C 8E 99 57  牧?.帣W
0042FB31  FF FB 99 3B 5D 08 08 57  麢;]W
0042FB39  EE FF B6 08 FA 08 99 99  ???櫃
0042FB41  E9 08 A0 11 99 99 B6 08  ??櫃?
0042FB49  B6 08 99 57 FF FB 99 3B  ?橶麢;
0042FB51  5D 08 18 0C              ].



0x10 原由
那么我们先来看看是如何得到这些hex

谈谈vmp的还原(2)

谈谈vmp的还原(2)

代码很简单
匹配就行了,那么我们来看看匹配表,注意到上一篇的handle_size == 1488 / 8

谈谈vmp的还原(2)

谈谈vmp的还原(2)

恩,vmp实现虚拟引擎的核心可以说就是这些虚拟规则。注意到我是用的这些,而不是186个,因为在写之前,我担心版本太老,所以又去逆了逆v2.12.3,发现框架太体差不多,不过代码量优化了很多。还有昨天看了看大Z哥的帖子,对里面有句话感触很深(它们的价值来自于本身的神秘面纱)。但毕竟吧,vmp也3.x,代码重构了,我想也可以谈一谈了。扯远了。
查看引用表的地方

谈谈vmp的还原(2)

谈谈vmp的还原(2)

在看看RandIndexArray的引用,来到这个地方

谈谈vmp的还原(2)

谈谈vmp的还原(2)



注意到这里可能是乱序之后的,那么如果说不乱序的话,这个表和vm_opcode的应该是一一对应的关系
举例:

谈谈vmp的还原(2)

谈谈vmp的还原(2)

定位到handler_table,
则有
Handle_471094:
LODS BYTE PTR DS:[ESI]
PUSH DWORD PTR DS:[EDI+EAX*4]
对应
01 02 02 00 00 00 00 00
如下:

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
struct _vmp_esi_table _esi_table[] = {
    {0x1,0x2,0x2,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]" }
    ,{0x1,0x1,0x2,0x0,0x0,0x0,0x0,0x0,"LODS DWORD PTR DS:[ESI] PUSH EAX" }
    ,{0x1,0x2,0x2,0x0,0x1,0x0,0x0,0x0,"PUSH ESP" }
    ,{0x1,0x3,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR ES:[EAX]" }
    ,{0x1,0x3,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR CS:[EAX]" }
    ,{0x1,0x3,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR SS:[EAX]" }
    ,{0x1,0x3,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR DS:[EAX]" }
    ,{0x1,0x3,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR FS:[EAX]" }
    ,{0x1,0x3,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX PUSH DWORD PTR GS:[EAX]" }
    ,{0x1,0x2,0x1,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] PUSH WORD PTR DS:[EDI+EAX*4]" }
    ,{0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,"LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX PUSH AX"}
    ,{0x1,0x1,0x1,0x0,0x1,0x0,0x0,0x0,"LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX CWDE PUSH EAX"}
    ,{0x1,0x3,0x1,0x0,0x0,0x0,0x0,0x0,"POP EDX PUSH WORD PTR ES:[EDX]" }
    ,{0x1,0x3,0x1,0x0,0x1,0x0,0x0,0x0,"POP EDX PUSH WORD PTR CS:[EDX]" }
    ,{0x1,0x3,0x1,0x0,0x2,0x0,0x0,0x0,"POP EDX PUSH WORD PTR SS:[EDX]" }
    ,{0x1,0x3,0x1,0x0,0x3,0x0,0x0,0x0,"POP EDX PUSH WORD PTR DS:[EDX]" }
    ,{0x1,0x3,0x1,0x0,0x4,0x0,0x0,0x0,"POP EDX PUSH WORD PTR FS:[EDX]" }
    ,{0x1,0x3,0x1,0x0,0x5,0x0,0x0,0x0,"POP EDX PUSH WORD PTR GS:[EDX]" }
    ,{0x1,0x2,0x0,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL MOV AL,BYTE PTR DS:[EDI+EAX*4] PUSH AX"}
    ,{0x1,0x2,0x0,0x0,0x1,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL MOV AL,BYTE PTR DS:[EDI+EAX*4+0x1] PUSH AX"}
    ,{0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL PUSH AX"}
    ,{0x1,0x1,0x0,0x0,0x1,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL CBW CWDE PUSH EAX"}
    ,{0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR ES:[EDX] PUSH AX"}
    ,{0x1,0x3,0x0,0x0,0x1,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR CS:[EDX] PUSH AX"}
    ,{0x1,0x3,0x0,0x0,0x2,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR SS:[EDX] PUSH AX"}
    ,{0x1,0x3,0x0,0x0,0x3,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR DS:[EDX] PUSH AX"}
    ,{0x1,0x3,0x0,0x0,0x4,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR FS:[EDX] PUSH AX"}
    ,{0x1,0x3,0x0,0x0,0x5,0x0,0x0,0x0,"POP EAX MOV AL,BYTE PTR GS:[EDX] PUSH AX"}
    ,{0x1,0x5,0x1,0x0,0x0,0x0,0x0,0x0,"PUSH ES" }
    ,{0x1,0x5,0x1,0x0,0x1,0x0,0x0,0x0,"PUSH CS" }
    ,{0x1,0x5,0x1,0x0,0x2,0x0,0x0,0x0,"PUSH SS" }
    ,{0x1,0x5,0x1,0x0,0x3,0x0,0x0,0x0,"PUSH DS" }
    ,{0x1,0x5,0x1,0x0,0x4,0x0,0x0,0x0,"PUSH FS" }
    ,{0x1,0x5,0x1,0x0,0x5,0x0,0x0,0x0,"PUSH GS" }
    ,{0x1,0x2,0x1,0x0,0x1,0x0,0x0,0x0,"PUSH SP" }
    ,{0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL POP DWORD PTR DS:[EDI+EAX*4]"}
    ,{0x2,0x1,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX"}
    ,{0x2,0x2,0x2,0x0,0x1,0x0,0x0,0x0,"POP ESP"}
    ,{0x2,0x3,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POP DWORD PTR ES:[EAX]"}
    ,{0x2,0x3,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POP DWORD PTR CS:[EAX]"}
    ,{0x2,0x3,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX POP DWORD PTR SS:[EAX]" }
    ,{0x2,0x3,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX POP DWORD PTR DS:[EAX]" }
    ,{0x2,0x3,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX POP DWORD PTR FS:[EAX]" }
    ,{0x2,0x3,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX POP DWORD PTR GS:[EAX]" }
    ,{0x2,0x2,0x1,0x0,0x0,0x0,0x0,0x0,"LODS BYTE PTR DS:[ESI] POP WORD PTR DS:[EDI+EAX*4]" }
    ,{0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX" }
    ,{0x2,0x3,0x1,0x0,0x0,0x0,0x0,0x0,"POP EAX POP WORD PTR ES:[EAX]" }
    ,{0x2,0x3,0x1,0x0,0x1,0x0,0x0,0x0,"POP EAX POP WORD PTR CS:[EAX]" }
    ,{0x2,0x3,0x1,0x0,0x2,0x0,0x0,0x0,"POP EAX POP WORD PTR SS:[EAX]" }
    ,{0x2,0x3,0x1,0x0,0x3,0x0,0x0,0x0,"POP EAX POP WORD PTR DS:[EAX]" }
    ,{0x2,0x3,0x1,0x0,0x4,0x0,0x0,0x0,"POP EAX POP WORD PTR FS:[EAX]" }
    ,{0x2,0x3,0x1,0x0,0x5,0x0,0x0,0x0,"POP EAX POP WORD PTR GS:[EAX]" }
    ,{0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,"POP DX LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL MOV BYTE PTR DS:[EDI+EAX*4],DL"}
    ,{0x2,0x2,0x0,0x0,0x1,0x0,0x0,0x0,"POP DX LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL MOV BYTE PTR DS:[EDI+EAX*4+1],DL"}
    ,{0x1,0x6,0x2,0x0,0x0,0x0,0x0,0x0,"MOV EAX,CR0 PUSH EAX"}
    ,{0x1,0x6,0x2,0x0,0x1,0x0,0x0,0x0,"MOV EAX,CR1 PUSH EAX"}
    ,{0x1,0x6,0x2,0x0,0x2,0x0,0x0,0x0,"MOV EAX,CR2 PUSH EAX"}
    ,{0x1,0x6,0x2,0x0,0x3,0x0,0x0,0x0,"MOV EAX,CR3 PUSH EAX"}
    ,{0x1,0x6,0x2,0x0,0x4,0x0,0x0,0x0,"MOV EAX,CR4 PUSH EAX"}
    ,{0x1,0x6,0x2,0x0,0x5,0x0,0x0,0x0,"MOV EAX,CR5 PUSH EAX"}
    ,{0x1,0x6,0x2,0x0,0x6,0x0,0x0,0x0,"MOV EAX,CR6 PUSH EAX"}
    ,{0x1,0x6,0x2,0x0,0x7,0x0,0x0,0x0,"MOV EAX,CR7 PUSH EAX"}
    ,{0x2,0x6,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX MOV CR0,EAX"}
    ,{0x2,0x6,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX MOV CR1,EAX"}
    ,{0x2,0x6,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX MOV CR2,EAX"}
    ,{0x2,0x6,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX MOV CR3,EAX"}
    ,{0x2,0x6,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX MOV CR4,EAX"}
    ,{0x2,0x6,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX MOV CR5,EAX"}
    ,{0x2,0x6,0x2,0x0,0x6,0x0,0x0,0x0,"POP EAX MOV CR6,EAX"}
    ,{0x2,0x6,0x2,0x0,0x7,0x0,0x0,0x0,"POP EAX MOV CR7,EAX"}
    ,{0x1,0x7,0x2,0x0,0x0,0x0,0x0,0x0,"MOV EAX,DR0 PUSH EAX"}
    ,{0x1,0x7,0x2,0x0,0x1,0x0,0x0,0x0,"MOV EAX,DR1 PUSH EAX"}
    ,{0x1,0x7,0x2,0x0,0x2,0x0,0x0,0x0,"MOV EAX,DR2 PUSH EAX"}
    ,{0x1,0x7,0x2,0x0,0x3,0x0,0x0,0x0,"MOV EAX,DR3 PUSH EAX"}
    ,{0x1,0x7,0x2,0x0,0x4,0x0,0x0,0x0,"MOV EAX,DR4 PUSH EAX"}
    ,{0x1,0x7,0x2,0x0,0x5,0x0,0x0,0x0,"MOV EAX,DR5 PUSH EAX"}
    ,{0x1,0x7,0x2,0x0,0x6,0x0,0x0,0x0,"MOV EAX,DR6 PUSH EAX"}
    ,{0x1,0x7,0x2,0x0,0x7,0x0,0x0,0x0,"MOV EAX,DR7 PUSH EAX"}
    ,{0x2,0x7,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX MOV DR0,EAX"}
    ,{0x2,0x7,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX MOV DR1,EAX"}
    ,{0x2,0x7,0x2,0x0,0x2,0x0,0x0,0x0,"POP EAX MOV DR2,EAX"}
    ,{0x2,0x7,0x2,0x0,0x3,0x0,0x0,0x0,"POP EAX MOV DR3,EAX"}
    ,{0x2,0x7,0x2,0x0,0x4,0x0,0x0,0x0,"POP EAX MOV DR4,EAX"}
    ,{0x2,0x7,0x2,0x0,0x5,0x0,0x0,0x0,"POP EAX MOV DR5,EAX"}
    ,{0x2,0x7,0x2,0x0,0x6,0x0,0x0,0x0,"POP EAX MOV DR6,EAX"}
    ,{0x2,0x7,0x2,0x0,0x7,0x0,0x0,0x0,"POP EAX MOV DR7,EAX"}
    ,{0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX" }
    ,{0x2,0x3,0x0,0x0,0x0,0x0,0x0,0x0,"POP EAX POP AX MOV BYTE PTR ES:[EDX],AL"}
    ,{0x2,0x3,0x0,0x0,0x1,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR CS:[EDX],AL"}
    ,{0x2,0x3,0x0,0x0,0x2,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR SS:[EDX],AL"}
    ,{0x2,0x3,0x0,0x0,0x3,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR DS:[EDX],AL"}
    ,{0x2,0x3,0x0,0x0,0x4,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR FS:[EDX],AL"}
    ,{0x2,0x3,0x0,0x0,0x5,0x0,0x0,0x0,"POP EDX POP AX MOV BYTE PTR GS:[EDX],AL"}
    ,{0x2,0x5,0x1,0x0,0x0,0x0,0x0,0x0,"POP ES" }
    ,{0x2,0x5,0x1,0x0,0x2,0x0,0x0,0x0,"POP SS" }
    ,{0x2,0x5,0x1,0x0,0x3,0x0,0x0,0x0,"POP DS" }
    ,{0x2,0x5,0x1,0x0,0x4,0x0,0x0,0x0,"POP FS" }
    ,{0x2,0x5,0x1,0x0,0x5,0x0,0x0,0x0,"POP GS" }
    ,{0x2,0x2,0x1,0x0,0x1,0x0,0x0,0x0,"POP SP" }
    ,{0x4,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX ADD DWORD PTR SS:[ESP],EAX"}
    ,{0x4,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX ADD DWORD PTR SS:[ESP],EAX PUSHFW"}
    ,{0x4,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX ADD DWORD PTR SS:[ESP],AX" }
    ,{0x4,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP AX ADD DWORD PTR SS:[ESP],AX PUSHFW" }
    ,{0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX ADD BYTE PTR SS:[ESP],AL" }
    ,{0x4,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX ADD BYTE PTR SS:[ESP],AL PUSHFW" }
    ,{0xF6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX NOT EAX NOT DWORD PTR SS:[ESP] AND DWORD PTR SS:[ESP],EAX"}
    ,{0xF6,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX NOT EAX NOT DWORD PTR SS:[ESP] AND DWORD PTR SS:[ESP],EAX PUSHFW"}
    ,{0xF6,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"NOT DWORD PTR SS:[ESP] POP AX AND WORD PTR SS:[ESP],AX" }
    ,{0xF6,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"NOT DWORD PTR SS:[ESP] POP AX AND WORD PTR SS:[ESP],AX PUSHFW" }
    ,{0xF6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX NOT AL NOT CL AND AL,CL PUSH AX"}
    ,{0xF6,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX NOT AL NOT CL AND AL,CL PUSH AX PUSHFW"}
    ,{0x1C,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POP CX SHL EAX,CL PUSH EAX"}
    ,{0x1C,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POP CX SHL EAX,CL PUSH EAX PUSHFW"}
    ,{0x1C,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHL AX,CL PUSH AX"}
    ,{0x1C,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHL AX,CL PUSH AX PUSHFW"}
    ,{0x1C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHL AL,CL PUSH AX"}
    ,{0x1C,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHL AL,CL PUSH AX PUSHFW"}
    ,{0x1D,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POP CX SHR EAX,CL PUSH EAX"}
    ,{0x1D,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POP CX SHR EAX,CL PUSH EAX PUSHFW"}
    ,{0x1D,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHR AX,CL PUSH AX"}
    ,{0x1D,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHR AX,CL PUSH AX PUSHFW"}
    ,{0x1D,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX SHR AL,CL PUSH AX"}
    ,{0x1D,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP AX POP CX SHR AL,CL PUSH AX PUSHFW"}
    ,{0xF8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX POPAD POPFD RETN"}
    ,{0x3D,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EDX POP EAX POP ECX DIV ECX PUSH EAX PUSH EDX"}
    ,{0x3D,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP DX POP AX POP CX DIV CX PUSH AX PUSH DX" }
    ,{0x3D,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX DIV CL PUSH AX" }
    ,{0x3F,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EDX POP EAX POP ECX IDIV ECX PUSH EAX"}
    ,{0x3F,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"POP DX POP AX POP CX IDIV CX PUSH AX PUSH DX" }
    ,{0x3F,0x0,0x0,0x0,0x0,0x0,0x0,0x0,"POP AX POP CX IDIV CL PUSH AX" }
    ,{0x40,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EDX POP EAX MUL EDX PUSH EAX PUSH EDX PUSHFW" }
    ,{0x40,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX MUL EX PUSH AX PUSH DX PUSHFW" }
    ,{0x40,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX MUL DL PUSH AX PUSHFW" }
    ,{0x3E,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EDX POP EAX IMUL EDX PUSH EAX PUSH EDX PUSHFW" }
    ,{0x3E,0x0,0x1,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX IMUL DX PUSH AX PUSH DX PUSHFW" }
    ,{0x3E,0x0,0x0,0x0,0x1,0x0,0x0,0x0,"POP DX POP AX IMUL DL PUSH AX PUSHFW"}
    ,{0x1C,0x0,0x3,0x0,0x1,0x0,0x0,0x0,"POP EAX POP EDX POP CX SHLD EAX,EDX,CL PUSH EAX PUSHFW"}
    ,{0x1D,0x0,0x3,0x0,0x1,0x0,0x0,0x0,"POP EAX POP EDX POP CX SHRD EAX,EDX,CL POUSH EAX PUSHFW"}
    ,{0xF7,0x0,0x2,0x0,0x1,0x0,0x0,0x0,"POP EAX POPAD POPFD RETF" }
    ,{0x2E,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"WAIT" }
    ,{0xB6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FILD DWORD PTR SS:[ESP]" }
    ,{0xB6,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FILD QWORD PTR SS:[ESP]" }
    ,{0xBB,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLD DWORD PTR SS:[ESP]" }
    ,{0xBB,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FLD QWORD PTR SS:[ESP]" }
    ,{0xBB,0x0,0x4,0x0,0x0,0x0,0x0,0x0,"FLD TBYTE PTR SS:[ESP]" }
    ,{0xA0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FADD DWORD PTR SS:[ESP]" }
    ,{0xA0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FADD QWORD PTR SS:[ESP]" }
    ,{0xA4,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSUB DWORD PTR SS:[ESP]" }
    ,{0xA4,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FSUB QWORD PTR SS:[ESP]" }
    ,{0xA5,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSUBR DWORD PTR SS:[ESP]" }
    ,{0xA5,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FSUBR QWORD PTR SS:[ESP]" }
    ,{0xBC,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSTP DWORD PTR SS:[ESP]" }
    ,{0xBC,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FSTP QWORD PTR SS:[ESP]" }
    ,{0xBC,0x0,0x4,0x0,0x0,0x0,0x0,0x0,"FSTP TBYTE PTR SS:[ESP]" }
    ,{0xA6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FDIV DWORD PTR SS:[ESP]" }
    ,{0xA6,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FDIV QWORD PTR SS:[ESP]" }
    ,{0xA1,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FMUL DWORD PTR SS:[ESP]" }
    ,{0xA1,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FMUL QWORD PTR SS:[ESP]" }
    ,{0xA3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCOMP DWORD PTR SS:[ESP]" }
    ,{0xA3,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FCOMP QWORD PTR SS:[ESP]" }
    ,{0xC8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCHS" }
    ,{0xDB,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSQRT" }
    ,{0xEE,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FSTSW AX PUSH AX" }
    ,{0xC6,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FSTCW WORD PTR SS:[ESP]" }
    ,{0xC4,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FLDCW WORD PTR SS:[ESP]" }
    ,{0xE3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"F2XM1" }
    ,{0xC9,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FABS" }
    ,{0xE6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCLEX" }
    ,{0xE0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FCOS" }
    ,{0xD7,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FDECSTP" }
    ,{0xD8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FINCSTP" }
    ,{0xE5,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FINIT" }
    ,{0xD0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLDLN2" }
    ,{0xCF,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLDLG2" }
    ,{0xD9,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPREM" }
    ,{0xD6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPREM1" }
    ,{0xD3,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPTAN" }
    ,{0xDD,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FRNDINT" }
    ,{0xDF,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FSIN" }
    ,{0xE1,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FTST" }
    ,{0xD2,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FYL2X" }
    ,{0xD4,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FPATAN" }
    ,{0xD1,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FLDZ" }
    ,{0xB8,0x0,0x1,0x0,0x0,0x0,0x0,0x0,"FISTP WORD PTR SS:[ESP]" }
    ,{0xB8,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"FISTP DWORD PTR SS:[ESP]" }
    ,{0xB8,0x0,0x3,0x0,0x0,0x0,0x0,0x0,"FISTP QWORD PTR SS:[ESP]" }
};




Btw:不保证全对哈,最好看看,哈哈
接着我们看一看Vmp_GetVmHandleIndex的调用

谈谈vmp的还原(2)

谈谈vmp的还原(2)

ida的有点乱,把这个函数整理之后

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
void _func_101()
{
    _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( esi->_var1_vm_mnemonic, 0, esi->_var3_lval, (esi->ispushfw) != 0);
}

void _func_104()
{
    _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( esi->_var1_vm_mnemonic, 0, esi->_var3_lval, 0));
}

void _func_3(}
{
    _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( esi->_var1_vm_mnemonic, 0, esi->_var3_lval, 1));
}

int _getindex( int _n)
{
    switch(_n)
    {
    case 1:
        return 0;
    case 2:
        return 1;
    case 3:
        return 2;
    case 5:
        return 4;
    case 6:
        return 5;
    default:
        return 3;
    }
}

_DWORD *__usercall Vmp_FindAndSetTOStruct@<eax>(struct_esi *a1@<eax>, int _size@<ebx>, int _i@<esi>)
{
    esi->_esi_size = 0;
    if( esi->_var1_vm_mnemonic > 0xc4)
    {
        switch(esi->_var1_vm_mnemonic)
        {
        case 0xC6:
        case 0xC8:
        case 0xC9:
        case 0xCF:
        case 0xD0:
        case 0xD1:
        case 0xD2:
        case 0xD3:
        case 0xD4:
        case 0xD6:
        case 0xD7:
        case 0xD8:
        case 0xD9:
        case 0xDB:
        case 0xDD:
        case 0xDF:
        case 0xE0:
        case 0xE1:
        case 0xE3:
        case 0xE5:
        case 0xE6:
        case 0xEE:
        case 0xF8:
            {
                _func_104();
                return;
            }
        case 0xF6:
            {
                _func_101();
                return;
            }
        case 0xF7:
            {
                _func_3();
                break;
            }
        default:
            return;
        }
    }

    if( esi->_var1_vm_mnemonic == 0xC4)
    {
        _func_104();
        return;
    }
    if( esi->_var1_vm_mnemonic > 0x40)
    {
        if( esi->_var1_vm_mnemonic > 0xb6)
        {
            if( esi->_var1_vm_mnemonic != 0xb8 && esi->_var1_vm_mnemonic - 0xbb >= 2)
            {
                return;
            }
        }
        else if( esi->_var1_vm_mnemonic != 0xb6)
        {
            if( esi->_var1_vm_mnemonic == 0x8b)
            {
                esi->_hex = esi->_displacement_immediate;
                esi->size += 4;
                return;
            }
            if( esi->_var1_vm_mnemonic - 0xA0 >= 2 && esi->_var1_vm_mnemonic - 0xA3 >= 4)
            {
                return ;
            }
        }
        _func_104();
        return;
    }
    if ( esi->_var1_vm_mnemonic == 0x40 )          // mul
        _func_104();
    return;
    if ( esi->_var1_vm_mnemonic > 0x2E )
    {
        if ( esi->_var1_vm_mnemonic != 0x3D )
        {
            if ( esi->_var1_vm_mnemonic == 0x3E )      // pop dx
                _func_101();
            return;
            if ( esi->_var1_vm_mnemonic != 0x3F )
                return;
        }
        _func_104();
        return;
    }
    if ( esi->_var1_vm_mnemonic == 0x2E )          // wait
        _func_104();
    return;
    if ( esi->_var1_vm_mnemonic - 1 >= 2 )
    {
        if ( esi->_var1_vm_mnemonic != 4 && esi->_var1_vm_mnemonic - 28 >= 2 )// !=4 || >= 0x1E
            return;
        _func_101();
        return;
    }
    if ( esi->_var1_vm_mnemonic - 1 != 0 )
    {
        if ( esi->_var1_vm_mnemonic == 2 )                              // pop
        {
            switch ( _esi->_var2_addressing_mode )
            {
            case 1:
                {
                    _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 2, 1, esi->_var3_lval, 0));// pop eax|ax
                    break;
                }
            case 2:   
                {
                    if ( _esi->_var3_lval >= 3 || _esi->_REG_Index != 4 )
                    {
                        int flag = !_esi->_var3_lval && (_esi->_REG_Index & 4) == 4;
                        _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 2, _esi->_var3_lval, flag);
                        _hex2 = Vmp_GetEmptyVMContext(_esi->Struct_vtable_477C54,_esi->_var3_lval,_esi->_REG_Index,1);
                        saveToStruct(_esi, _hex2);
                    }
                    else
                    {
                        _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 2, _esi->_var3_lval, 1));// pop sp|esp
                    }
                    break;
                }
            case 3:
                {
                    _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 3, _esi->_var3_lval, _getindex(esi->var5));
                    break;
                }
            case 5:
                {
                    _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 5, 1, _esi->_REG_Index));// pop prefiexreg_index
                    break;
                }
            case 6:
                {
                    _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 6, 2, _esi->_REG_Index));
                    break;
                }
            case 7:
                {
                    _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(2, 7, 2, _esi->_REG_Index));
                    break;
                }
            default:
                break;
            }
        }
    }
    else if ( _esi->_var2_addressing_mode == 1 )
    {
        switch ( _esi->_rand_switch )
        {
        case 1:
            {
                do
                v5 = rand()%(-1);
                while ( !v5 && 0 == *_esi->_Displacement_Immediate );
                _lval_disp_imm = *_esi->_Displacement_Immediate - v5;
                v6 = sub_47817C(_esi);
                v7 = getStruct_1(_esi->Struct_vtable_477C54, v6 + 1);
                *v7->_Displacement_Immediate = v5;
                Vmp_FindAndSetTOStruct(v7, v5, _lval_disp_imm);
            }
            break;
        case 2:
            {
                do
                v8 = ~*_esi->_Displacement_Immediate & rand()%(-1);
                while ( !v8 && 0 == ~*_esi->_Displacement_Immediate );
                _lval_disp_imm = v8 | ~*_esi->_Displacement_Immediate & ~v8;
                v9 = sub_47817C(_esi);
                v10 = getStruct_1(_esi->Struct_vtable_477C54, v9 + 1);
                *v10->_Displacement_Immediate = v8;
                Vmp_FindAndSetTOStruct(v10, v8, _lval_disp_imm);
            }
            break;
        case 3:
            {
                v11 = 0;
                v12 = *_esi->_Displacement_Immediate;
                while ( !(v12 & 1) ) //偶数
                {
                    v12 >>= 1;
                    ++v11;
                }
                v13 = System::__linkproc__ RandInt(v11);
                _lval_disp_imm = v13 + 1;
                v14 = *_esi->_Displacement_Immediate >> (v13 + 1);
                v15 = sub_47817C(_esi);
                v16 = getStruct_1(_esi->Struct_vtable_477C54, v15 + 1);
                *v16->_Displacement_Immediate = v14;
                Vmp_FindAndSetTOStruct(v16, v14, _lval_disp_imm);
                break;
            }
        case 4:
            {
                v17 = 0;
                while ( _esi->__var4 == 2 && *_esi->_Displacement_Immediate >= 0 || _esi->__var4 == 1 && (*_esi->_Displacement_Immediate & 0x8000) == 0 )
                {
                    *_esi->_Displacement_Immediate *= 2;
                    ++v17;
                }
                v19 = System::__linkproc__ RandInt(v17);
                _lval_disp_imm = v19 + 1;
                v20 = *_esi->_Displacement_Immediate << (v19 + 1);
                v21 = sub_47817C(_esi);
                v22 = getStruct_1(_esi->Struct_vtable_477C54, v21 + 1);
                *v22->_Displacement_Immediate = v20;
                Vmp_FindAndSetTOStruct(v22, v20, _lval_disp_imm);
                break;
            }
        default:
            {
                _lval_disp_imm = *_esi->_Displacement_Immediate;
                break;
            }
        }
        if ( _esi->_rand_switch )
        {
            setAddress(&_esi->_esi_hex[8], *(&off_4CE17C + _esi->_var1_vm_interpreter_mnemonic));
            if ( _esi->_var3_lval == 1 )
            {
                a2a = _lval_disp_imm;
                LOBYTE(v66) = 0;
                sub_409984(&str____4x[1], &a2a, 0, v64);
                System::__linkproc__ LStrCat(&_esi->_esi_hex[8], *v64);
            }
            else if ( _esi->_var3_lval == 2 )
            {
                a2a = _lval_disp_imm;
                LOBYTE(v66) = 0;
                sub_409984(&str____8x[1], &a2a, 0, v67);
                System::__linkproc__ LStrCat(&_esi->_esi_hex[8], *v67);
            }
            if ( _esi->__var4 == 1 )
            {
                a2a = *_esi->_Displacement_Immediate;
                LOBYTE(v66) = 0;
                sub_409984(&str___4x[1], &a2a, 0, v62);
                setAddress(&_esi->_esi_hex[12], *v62);
            }
            else if ( _esi->__var4 == 2 )
            {
                a2a = *_esi->_Displacement_Immediate;
                LOBYTE(v66) = 0;
                sub_409984(&str___8x[1], &a2a, 0, v63);
                setAddress(&_esi->_esi_hex[12], *v63);
            }
        }
        else
        {
            Free_Mem(&_esi->_esi_hex[12]);
        }
        if ( _esi->_var3_lval == 1 )
        {
            if ( _lval_disp_imm & 0xFF00 )
            {
                _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 1, 0);// LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX PUSH AX
                Move_Word(_esi, _lval_disp_imm);
            }
            else
            {
                _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 0, 0);// LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL PUSH AX
                saveToStruct(_esi, _lval_disp_imm);
            }
        }
        else if ( _esi->_var3_lval == 2 )
        {
            if ( _esi->_ispushfw & 2 || _lval_disp_imm != Byte_Extension(_lval_disp_imm) )
            {
                if ( _esi->_ispushfw & 2 || _lval_disp_imm != Word_Extension(_lval_disp_imm) )
                {
                    _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 2, 0);// LODS DWORD PTR DS:[ESI] ADD EAX,EBX ADD EBX,EAX PUSH EAX
                    Move_Dword(_esi, _lval_disp_imm);
                }
                else
                {
                    _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 1, 1);// LODS WORD PTR DS:[ESI] ADD AX,BX ADD BX,AX CWDE PUSH EAX
                    Move_Word(_esi, _lval_disp_imm);
                }
            }
            else
            {
                _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 0, 1);// LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL CBW CWDE PUSH EAX
                saveToStruct(_esi, _lval_disp_imm);
            }
        }
        else
        {
            _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 1, 0, 0);// LODS BYTE PTR DS:[ESI] ADD AL,BL ADD BL,AL PUSH AX
            saveToStruct(_esi, _lval_disp_imm);
        }
    }
    else
    {
        switch ( _esi->_var2_addressing_mode )
        {
        case 2:
            {
                if ( _esi->_var3_lval >= 3 || _esi->_REG_Index != 4 )
                {
                    _vmp_setIndexToStruct( esi,_vmp_getVmHandlerIndex(1, 2, _esi->_var3_lval, _esi->_var3_lval == 0 && (_esi->_REG_Index & 4) == 4);//利用空间  push _context[]
                    v34 = Vmp_GetEmptyVMContext(_esi->Struct_vtable_477C54,_esi->_var3_lval,_esi->_REG_Index,0);//选择index
                    saveToStruct(_esi, v34);
                }
                else
                {
                    _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 2, _esi->_var3_lval, 1);//// push sp|esp
                }
                break;
            }
        case 3:
            {
                _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex(1,3,_esi->_var3_lval,_getindex(_esi->_var5));// pop e?x push ? ptr ?
                break;
            }
        case 5:
            {
                _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 5, 1, _esi->_REG_Index));//push prefix_reg
                break;
            }
        case 6:
            {
                _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 6, 2, _esi->_REG_Index));//mov eax,cr_index push eax
                break;
            }
        case 7:
            {
                _vmp_setIndexToStruct( esi, _vmp_getVmHandlerIndex( 1, 7, 2, _esi->_REG_Index));// mov eax,dr_index push eax
                break;
            }
        default:
            {
                break;
            }
        }
    }
}




1.       判断vm_mnemonic
2.       再判断寻址方式以及类型
继续,我们看看vm_mnemonic怎么得到的

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
char __fastcall Vmp_SetEsiStruct(struct_vtable_477C54 *var1, char _var1_interpreter_mnemonic, char _var2_addressing_mode, unsigned __int8 _3_lval_type, int _var5_index, int var6, int var7)
{
    v8 = (var1->Vtable_477C54->SetCapacity)();
    if ( var6 & 8 )
        Classes::TList::Add(_var1->Ptr_Struct_Vtable_40F3B8, v8);
    v8->_var1_vm_interpreter_mnemonic = _var1_vm_mnemonic;
    v8->_var2_addressing_mode = _var2_addressing_mode;
    v8->_var3_lval_type_byte_word_dword_or_vm_displacement = _3_lval_type;
    if ( var6 & 0x20 )
        v8->_ispushfw |= 0x20u;
    switch ( _var2_addressing_mode )                 // 第3个参数进行switch
    {
    case 0:
        if ( _var5_index == 1 )
            v8->_ispushfw |= 1u;
        else
            v8->_ispushfw &= 0xFEu;
        break;
    case 1:                                     // 先判断类型 第4个参数进行判断
        if ( _3_lval_type < 1u )                  // [base]
        {
            *v8->_Displacement_Immediate = (char)_var5_index;
        }
        else if ( _3_lval_type == 1 )             // [base + disp8]
        {
            *v8->_Displacement_Immediate = (short)_var5_index;
        }
        else                                      // [base + disp32]
        {
            *v8->_Displacement_Immediate = _var5_index;
        }
        if ( var6 & 0x10 )
        {
            v8->_ispushfw |= 8u;
            v9 = var7;
            v8->_init0xffff_oppositecondition = var7;
        }
        if ( var6 & 2 )
            v8->_ispushfw |= 2u;
        if ( var6 & 1 )
        {
            LOBYTE(v9) = 1;
            v31 = 1;
        }
        else
        {
            LOBYTE(v9) = 0;
            v31 = 0;
        }
        if ( var6 & 0x40 )
            v31 |= 0x40u;
        if ( var6 & 4 )
        {
            if ( _3_lval_type >= 3 )                              // qword的拆分吗
            {
                if ( _var1->Struct_Vtable_477E80->Struct_Vtable_477F00->_vm_type & 4 )
                {
                    v8->__var4 = _3_lval_type;
                    _rand_type[0] = 1;
                    _rand_type[2] = 1;
                    if ( statisticsbinaryis1count(~*v8->_Displacement_Immediate, _3_lval_type) >= 3u )// 统计奇数为 大于3
                    {
                        _rand_type[1] = 2;
                        _rand_type[3] = 2;
                    }
                    else
                    {
                        _rand_type[1] = 1;
                        _rand_type[3] = 1;
                    }
                    if ( !(v8->_ispushfw & 2) && *v8->_Displacement_Immediate )
                    {
                        if ( !(v8->_Displacement_Immediate[0] & 1) )
                            _rand_type[2] = 3;
                        if ( _3_lval_type == 2 && v8->_Displacement_Immediate[3] >= 0
                            || _3_lval_type == 1 && v8->_Displacement_Immediate[1] >= 0 )
                        {
                            _rand_type[3] = 4;
                        }
                    }
                    v8->_rand_switch = _rand_type[rand()%4];
                    switch ( v8->_rand_switch )
                    {
                    case 1:
                        {
                            Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31 | 2, -1);// LODS DWORD PTR DS:[ESI] PUSH EAX
                            Vmp_SetEsiStruct(_var1, 4, 0, _3_lval_type, 0, v31, -1);// POP EAX ADD DWORD PTR SS:[ESP],EAX
                            break;
                        }
                    case 2:
                        {
                            Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31 | 2, -1);
                            Vmp_SetEsiStruct(_var1, 0xF6, 0, _3_lval_type, 0, v31, -1);// POP EAX NOT EAX NOT DWORD PTR SS:[ESP] AND DWORD PTR SS:[ESP],EAX
                            break;
                        }
                    case 3:
                        {
                            v8->_var3_lval_type_byte_word_dword_or_vm_displacement = 1;
                            Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31 | 2, -1);
                            LOBYTE(v9) = Vmp_SetEsiStruct(_var1, 0x1C, 0, _3_lval_type, 0, v31, -1);// POP EAX POP CX SHL EAX,CL PUSH EAX
                            break;
                            default:
                            if ( v8->_rand_switch == 4 )
                            {
                                v8->_var3_lval_type_byte_word_dword_or_vm_displacement = 1;
                                Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, 0, v31|2, -1);//LODS DWORD PTR DS:[ESI] PUSH EAX
                                Vmp_SetEsiStruct(_var1, 0x1D, 0, _3_lval_type, 0, v31, -1);// POP EAX POP CX SHR EAX,CL PUSH EAX
                            }
                            break;
                        }
                    }
                }
            }
        }
    }
    if ( _3_lval_type == 2 && var6 & 0x10 && _1_interpreter_mnemonic != 0x8Bu )// [base + disp32]
    {
        if ( var7 == -1 )
        {
            v9 = 3;
        }
        else
        {
            v9 = sub_479128(*&_var1->Struct_Vtable_477E80->Struct_Vtable_477F00->Struct_table_477E80->field_60, var7)->field_C;
        }
        switch(v9)
        {
        case 3:
            {
                Vmp_SetEsiStruct(_var1, 1, 2, 2, 10, v31, -1);//LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]
                Vmp_SetEsiStruct(_var1, 4, 0, 2, 0, v31, -1);//POP EAX ADD DWORD PTR SS:[ESP],EAX
                break;
            }
        case 2:
            {
                Vmp_SetEsiStruct(_var1, 1, 1, 1, 0, v31, -1);//LODS WORD PTR DS:[ESI] PUSH AX
                Vmp_SetEsiStruct(_var1, 1, 2, 1, 10, v31, -1);//LODS BYTE PTR DS:[ESI] PUSH WORD PTR DS:[EDI+EAX*4]
                Vmp_SetEsiStruct(_var1, 4, 0, 2, 0, v31, -1);//POP EAX ADD DWORD PTR SS:[ESP],EAX
                break;
            }
        case 1:
            {
                Vmp_SetEsiStruct(_var1, 1, 2, 2, 10, v31, -1);// LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]
                Vmp_SetEsiStruct(_var1, 2, 1, 1, 0, v31, -1);// LODS BYTE PTR DS:[ESI] POP WORD PTR DS:[EDI+EAX*4]
                Vmp_SetEsiStruct(_var1, 1, 1, 1, 0, v31, -1);// LODS WORD PTR DS:[ESI] PUSH AX
                Vmp_SetEsiStruct(_var1, 4, 0, 2, 0, v31, -1);// POP EAX ADD DWORD PTR SS:[ESP],EAX
                break;
            }
        }
        if ( !(var6 & 0x40) && !(var6 & 8) && _1_interpreter_mnemonic == 1 )
        {
            if ( _var1->Struct_Vtable_477E80->Struct_Vtable_477F00->_vm_type & 0x20 )
            {
                v9 = rand()%2 - 1;
                if ( !v9 )//(int)[esp] += [[esi]]
                {
                    v31 |= 0x40u;
                    v23 = sub_48BC1C(_var1->Struct_Vtable_477E80->Struct_Vtable_477F00, &v30);
                    Vmp_SetEsiStruct(_var1, 1, 1, 2, v30, v31 | 0x14, -1);// LODS DWORD PTR DS:[ESI] PUSH EAX
                    Vmp_SetEsiStruct(_var1, 1, 3, _3_lval_type, 0, v31, -1);// POP EAX PUSH DWORD PTR SS:[EAX]
                    Vmp_SetEsiStruct(_var1, 1, 1, _3_lval_type, -v23, v31 | 4, -1);// LODS DWORD PTR DS:[ESI] PUSH EAX
                    Vmp_SetEsiStruct(_var1, 4, 0, _3_lval_type, 0, v31, -1);// POP EAX
                    Vmp_SetEsiStruct(_var1, 4, 0, _3_lval_type, 0, v31, -1);// POP EAX ADD DWORD PTR SS:[ESP],EAX
                }
            }
        }
        break;
        case 2:
        case 5:
        case 6:
        case 7:
            v8->_REG_Index = _var5_index;
            break;
        case 3:
            v8->field_F = _var5_index;
            break;
        default:
            break;
    }
    if ( var6 & 1 )                               // 奇数成立
        Vmp_FindAndSetTOStruct(v8, var6, v8);// Make
    return v9;
}




可以发现由传参决定并对于某些方式递归调用
继续寻找怎么来的

谈谈vmp的还原(2)

谈谈vmp的还原(2)

谈谈vmp的还原(2)

谈谈vmp的还原(2)

定位到cmp。看看vmp是如何实现对cmp,jcc的膨胀的

谈谈vmp的还原(2)

谈谈vmp的还原(2)

首先可以很直观的看到,在早期版本中
把sub cmp sbb放在一起来处理
那么看看是如何usedisasmstruct的

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
char __usercall _get_prefix@<al>(int index@<eax>, int a2)
{
    _operand = ( _disasm + 21 * _operand_index + 24)
    if ( _disasm.About_Prefixes == 4 )
        return 0;
    if ( _disasm.About_Prefixes == 0
        && (v2->FirstVar_Trans_ModRM_mod & 0x10
        && (v2->ThirdVar_SIB__Base_Index - 4) < 2
        || v2->FirstVar_Trans_ModRM_mod & 4
        && (v2->SecondVar_Trans_ModRM_rm_Index - 4) < 2) )
    {
        return 3;
    }
    return _disasm.About_Prefixes;
}



int __usercall Vmp_UseDisasmStruct@<eax>(int _operand_index@<eax>, char a2@<dl>, int a3@<ecx>, int a4@<ebx>, int a5)
{
    _operand = ( _disasm + 21 * _operand_index + 24);
    if ( _operand.FirstVar_Trans_ModRM.mod == 0 )               // FirstVar_Trans_ModRM.mod == 0  return
        return 0;
    int ret = 1;
    if ( a2 & 4 )
    {
        _Type = 1;
    }
    else if ( a2 & 8 )
    {
        _Type = 2;
    }
    else
    {
        _Type = _operand->About_Lval_Byte_Word_Dword;
    }
    BYTE1(__n) = 0;
    if ( _operand->FirstVar_Trans_ModRM_mod == 0x24 )// prefix
    {
        if ( a2 & 1 && (__n = *(a5 - 4), *(__n + 22) != 1) )// != push
        {
            _vmp_SetEsiStruct(*(a5 - 4), 2, 5, 1, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// POP PREFIX
            if ( _Type == 2 )
            {
                _vmp_SetEsiStruct(*(a5 - 4), 2, 1, 1, 0, 0, -1);// POP AX
            }
        }
        else                                        // pop
        {
            if ( _Type == 2 )
            {
                _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1, 0, 0, -1);// LODS WORD PTR DS:[ESI] PUSH AX
            }
            _vmp_SetEsiStruct(*(a5 - 4), 1, 5, 1, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// PUSH PREFIX
        }
    }
    else if ( _operand->FirstVar_Trans_ModRM_mod == 0x84 )// DR?
    {
        if ( a2 & 1 && _disasm->Mnemonic_Counter_4CE17C != 1 )     // Mnemonic_Counter_4CE17C != 1 push
        {
            _vmp_SetEsiStruct(*(a5 - 4), 2, 7, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// POP EAX MOV DR?,EAX
        }
        else
        {
            _vmp_SetEsiStruct(*(a5 - 4), 1, 7, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// MOV EAX,DR? PUSH EAX
        }
    }
    else
    {
        if ( _operand->FirstVar_Trans_ModRM_mod == 0x44 )// CR?
        {
            if ( a2 & 1 && _disasm->Mnemonic_Counter_4CE17C != 1 )   // push
            {
                _vmp_SetEsiStruct(*(a5 - 4), 2, 6, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// POP EAX MOV CR?,EAX
            }
            else
            {
                _vmp_SetEsiStruct(*(a5 - 4), 1, 6, 2, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// MOV CR?,EAX PUSH EAX
            }
        }
        else
        {
            if ( _operand->FirstVar_Trans_ModRM_mod & 2 )
            {
                if ( _operand->FirstVar_Trans_ModRM_mod & 8 )
                    _Size = 2;                            // 0xC 0xE
                else
                    _Size = _Type;
                v15 = _operand->RestHex_Lval_Displacement_Immediate;
                RestHex_Displacement_Immediate = _operand->RestHex_Lval_Displacement_Immediate;
                if ( _operand->Lavl_Btye_Word_Dword )                              // if(v8->Lavl_Btye_Word_Dword != 0)
                {
                    if ( _operand->Lavl_Btye_Word_Dword == 1 && _Size == 2 )         // word
                    {
                        RestHex_Displacement_Immediate = Word_Extension(_operand->RestHex_Lval_Displacement_Immediate);
                    }
                }
                else if ( _Size == 2 )                  // dword
                {
                    RestHex_Displacement_Immediate = Byte_Extension(_operand->RestHex_Lval_Displacement_Immediate);
                }
                else if ( _Size == 1 )                  // word
                {
                    RestHex_Displacement_Immediate = Byte_Extension_Word(_operand->RestHex_Lval_Displacement_Immediate);
                }
                if ( !(_operand->FirstVar_Trans_ModRM_mod & 8) && _a2 & 2 )
                {
                    if ( _disasm->Mnemonic_Counter_4CE17C != 0x13 && _disasm->Mnemonic_Counter_4CE17C != 0x43 )// sbb 0x44不算
                        // Opcode_counter_4CE17C != 19 || != 67
                        //                    _str_sub || _str_cmp
                        RestHex_Displacement_Immediate = ~RestHex_Displacement_Immediate;// 反码
                    else
                        RestHex_Displacement_Immediate = -RestHex_Displacement_Immediate;//
                    // sub || cmp
                    // 补码
                }
                if ( _operand->Lavl_Btye_Word_Dword == 2 )
                {
                    __Type1 = 4;
                    v16 = *(*(a5 - 4) + 0x80);
                    if ( v16 && *(v16 + 8) )
                        __Type1 = 0xE;
                }
                else
                {
                    __Type1 = 0;
                }
                if ( _operand->Fix > 0xFFFFFFFF || (_disasm->Mnemonic_Counter_4CE17C + 0xC) < 2u && !_operand_index && _operand->FirstVar_Trans_ModRM_mod == 2 )// _disasm->Mnemonic_Counter_4CE17C <===> mnemonic
                {
                    __Type1 |= 0x10u;
                }                                       // 到时候好从[esi]读出补码或反码
                // 在push
                // 那么下面就是与输入的数进行and
                _vmp_SetEsiStruct(*(a5 - 4), 1, 1, _Size, RestHex_Displacement_Immediate, __Type1, _operand->Fix);
            }                                         // lods immediate push eax
            if ( _operand->FirstVar_Trans_ModRM_mod & 4 )
            {
                if ( _operand->FirstVar_Trans_ModRM_mod & 8 )
                {
                    if ( _operand->SibFirstVar_SIB_Scable_Index )
                    {
                        _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1, _operand->SibFirstVar_SIB_Scable_Index, 0, -1);// LODS WORD PTR DS:[ESI] PUSH EAX
                    }
                    if ( _operand->About_RegType_8_16_32 == 1 )
                    {
                        _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1, 0, 0, -1);// LODS WORD PTR DS:[ESI] PUSH AX
                    }
                    _vmp_SetEsiStruct( *(a5 - 4), 1, 2, _operand->About_RegType_8_16_32, _operand->SecondVar_Trans_ModRM_rm_Index,0,-1);
                    if ( _operand->SecondVar_Trans_ModRM_rm_Index == 4 )// sp
                        sub_486A30(2u, a5);
                }
                else
                {
                    if ( _a2 & 1 && _disasm->Mnemonic_Counter_4CE17C != 1 )
                    {
                        _vmp_SetEsiStruct(*(a5 - 4), 2, 2, _Type, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// LODS BYTE PTR DS:[ESI] POP DWORD PTR DS:[EDI+EAX*4]
                    }
                    else
                    {
                        _vmp_SetEsiStruct(*(a5 - 4), 1, 2, _Type, _operand->SecondVar_Trans_ModRM_rm_Index, 0, -1);// LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]
                    }
                    if ( _Type < 3 && _operand->SecondVar_Trans_ModRM_rm_Index == 4 && !(_a2 & 1) )
                        sub_486A30(_Type, a5);//ADD DWORD PTR SS:[ESP],LODSD DS:[ESI]
                }
            }
            if ( _operand->FirstVar_Trans_ModRM_mod & 8 )
            {
                if ( _operand->FirstVar_Trans_ModRM_mod & 4 && _operand->SibFirstVar_SIB_Scable_Index )
                {
                    _vmp_SetEsiStruct(*(a5 - 4), 28, 0, 2u, 0, 0, -1);
                }
                if ( _operand->FirstVar_Trans_ModRM_mod & 0x10 )
                {
                    if ( _operand->About_RegType_8_16_32 == 1 )
                    {
                        _vmp_SetEsiStruct(*(a5 - 4), 1, 1, 1u, 0, 0, -1);
                    }
                    _vmp_SetEsiStruct(*(a5 - 4), 1, 2, _operand->About_RegType_8_16_32, _operand->ThirdVar_SIB__Base_Index, 0, -1);
                    if ( _operand->ThirdVar_SIB__Base_Index == 4 )
                        sub_486A30(2, a5);//ADD DWORD PTR SS:[ESP],LODSD DS:[ESI]
                    if ( _operand->FirstVar_Trans_ModRM_mod & 4 )
                    {
                        _vmp_SetEsiStruct(*(a5 - 4), 4, 0, 2u, 0, 0, -1);
                    }
                }
                if ( _operand->FirstVar_Trans_ModRM_mod & 2 && (_operand->FirstVar_Trans_ModRM_mod & 4 || _operand->FirstVar_Trans_ModRM_mod & 0x10) )
                {
                    _vmp_SetEsiStruct(*(a5 - 4), 4, 0, 2u, 0, 0, -1);
                }
                if ( !(_a2 & 0x10) )//addressing prefix:[eax]
                {
                    if ( _a2 & 1 )
                    {
                        v25 = _get_prefix(__operand_index, a5) & 0x7F;
                        _vmp_SetEsiStruct(*(a5 - 4), 2, 3, _Type, v25, 0, -1);//POP EAX POP DWORD PTR prefix:[EAX]
                    }
                    else
                    {
                        v27 = _get_prefix(__operand_index, a5) & 0x7F;
                        _vmp_SetEsiStruct(*(a5 - 4), 1, 3, _Type, v27, 0, -1);//POP EAX PUSH DWORD PTR prefix:[EAX]
                    }
                }
            }
        }
    }
    return ret;
}




结合刚开始给的,则有先读operand[1]
注意到:

1
2
3
4
5
if ( _disasm->Mnemonic_Counter_4CE17C != 0x13 && _disasm->Mnemonic_Counter_4CE17C != 0x43 )
// sbb 0x44不算 Opcode_counter_4CE17C != 19 || != 67  _str_sub || _str_cmp
    RestHex_Displacement_Immediate = ~RestHex_Displacement_Immediate;// 反码
else
    RestHex_Displacement_Immediate = -RestHex_Displacement_Immediate;// sub || cmp 补码



然后其他的对应膨胀规则看看就明白了

谈谈vmp的还原(2)

谈谈vmp的还原(2)
分析sub_485884

谈谈vmp的还原(2)

谈谈vmp的还原(2)

分析sub_4857DC

谈谈vmp的还原(2)

谈谈vmp的还原(2)

可以看到这整套就是一个计算好初始eflags,然后压入_context的过程
分析sub_4858E0
这里就没注释了,可以对照规则

谈谈vmp的还原(2)

谈谈vmp的还原(2)
至此,早期版本中的cmp就这样vm了
一个细节的地方
注意到Vmp_SetEsiStruct函数

1
2
3
v8 = (var1->Vtable_477C54->SetCapacity)();
if ( var6 & 8 )
Classes::TList::Add(_var1->Ptr_Struct_Vtable_40F3B8, v8);



那么我们可以这样理解,在早期版本
vm的基本单位是指令,而指令通过反编译得到 ----> _struct_disasm
加上一个list,抽象出来

1
2
3
4
5
6
_struct_disasm
{
    ……
    …..
    list<?> ls;
};




注意到esi是怎样生成的,通过那些规则,故

1
2
3
4
5
6
_struct_disasm
{
    ……
     …..
    list<_struct_esi> ls;
};




同时我们可以猜一猜vmp设计的思路
一开始应该是vm的各种运算(add sub mul xor)
这个不难,如果叫我们来实现,直接将代码替换就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
稍微面向一点
switch(mnemonic)
{
case _sub:
case _cmp
}
再面向一些,查表
int _table[] = {1,2,3,4……}
switch(mnemonic)
{
case _sub:
index = 1;
case _cmp:
index = 2;
}




最后在进行匹配
我不知道其他的vm引擎是怎么设计的,如果是我写的话应该也会这样。
第一步可以看成写编译器的语法分析

1
2
3
另外
{0xF6,0x0,0x2,0x0,0x0,0x0,0x0,0x0,"POP EAX NOT EAX NOT DWORD PTR SS:[ESP] AND DWORD PTR SS:[ESP],EAX"}
这个0xf6取得蛮有意思的




在说说jcc


谈谈vmp的还原(2)

谈谈vmp的还原(2)



注意到

谈谈vmp的还原(2)

谈谈vmp的还原(2)

这几个参数,已上个帖子提到

谈谈vmp的还原(2)

谈谈vmp的还原(2)

谈谈vmp的还原(2)

谈谈vmp的还原(2)

谈谈vmp的还原(2)

谈谈vmp的还原(2)

恩,很多人爆破提到的shr。这个我想动态跟一跟,因为我觉得设计得很好

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
push add1

push 0
add [add1],0  
stack_top   0042fbcd

push addr2
push 0
add [addr2],0 //这两个地址很有意思
stack_top   0042fb9b
            0042fbcd

lodw [not(0x40)]
push not(0x40
lodb [index]
push _context[index] ----> push eflags
stack_top ffbf0287


not [esp]  ---> 0040fd78
pop ax
and [esp],ax
stack_top   fb9b0040
            fbcd0042
                0042

losb [index]
pop _context[index] ---> 0x40
stack_top   42fb9b
            42fbcb
            001848

losb [4]
push 4
stack_top   fb9b0004
            fbcd0042
                0042

Lodb [index]
Push _context[_index]
Stack_top   00040040
            0042fb9b
            0042fbcd

Pop ax
Pop cx
Shr ax,cl  ---> result == 0x4
Push ax
Stack_top   fb9b0004
            Fbcd0042
                0042

//这个4很有意思
Lodb [index]
Pop _context[index] ---> 4
stack_top   0042fb9b
            0042fbcd


Push esp //注意到这里
stack_top   0018FE98(addr_42fb9b)
            0042FB9B
            0042FBCD


Lodsb [index]
Push ax  --> 0
Stack_top   fe98000
            Fb9b0018
            Fbcd0042
            Ff480042


Lodsb [index]
Push _context[index] ---> 0x4
Stack_top   00000004
            0018fe98
Pop eax   --->       eax == 0x4
add [esp],eax
stack_top   0018FE98(addr_42fb9b)
            0042FB9B
            0042FBCD


注意到这里,很重要
vmp先压了两个地址然后取eflags运算进行shr,通常会得到4
那么这个4是用来干什么的
我们看看这两个地址的内容

谈谈vmp的还原(2)

谈谈vmp的还原(2)

谈谈vmp的还原(2)

谈谈vmp的还原(2)
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
恩,没错。实现了分支
在注意到这里的地址

Stack_top   0018fe9c(addr_0042fbcd)
            0042fb9b
            0042fbcd

Pop eax
Push [eax]
Stack_top   0042fbcd
            0042fb9b
            0042fbcd

但是有个问题,vmp怎么修改esi
Lodsd [vmp_entry]
Push vmp_entry
Stack_top   0042F000(vmp_entry)
            00000000(_addressing)
            0042fbcd

Pop eax
Add [esp],eax
Stack_top   0042f000
            0042fbcd

保存环境

Stack_top   00000000
            0018FEF4
            00000000
            0018FEF4
            0018FE84
            7EFDE000
            00000000
            00425036
            00000001
            00000287
            0042F000
            0042FBCD


谈谈vmp的还原(2)

谈谈vmp的还原(2)




谈谈vmp的还原(2)

谈谈vmp的还原(2)



这样就返回vm_entry,改变esi了
看到这,相信大家应该有很多爆破的思路了吧

0x11 结束语
就这样,先写到这里





温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
论坛交流群:672619046

小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

GMT+8, 2024-12-27 23:49 , Processed in 0.177491 second(s), 38 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表