本文主要是通过分析VMProtect 1.81 Demo版加密后的程序,讲述VMP的基本结构,并尝试分析虚拟代码的功能以及虚拟代码还原。
虚拟机保护技术是将程序的可执行代码转化为自定义的中间操作码(一字节或多字节),用以保护源程序不被逆向和篡改,这些中间操作码通过虚拟机解释执行,实现程序原来的功能。在这种情况下,如果要逆向程序,就需要对整个虚拟机结构进行逆向,理解程序功能,还需要结合操作码进行分析,整个程序逆向工程将会十分繁琐。以下是一个一般虚拟机结构:

虚拟机解释执行流程如下:
与虚拟机相关的数据结构如下:
本案例的样本来自于如何分析虚拟机系列(1):新手篇VMProtect 1.81 Demo - 吾爱破解 - 52pojie.cn。样本的汇编代码如下,就是一个简单的加减同一个常量。
经过VMP保护后,变成如下所示
这里有个典型的VMP入口特征:push call。push压入栈的数据是虚拟指令操作码表(VM Opcode Table)所在地址,然后通过call sub_40472C进入VM Entry。byte_404781 如下
首先一个很典型的特征就是VMP在创建虚拟机环境时,会将真实环境中寄存器的值入栈保存。
以上两条指令把要被操作的数据压入栈,这是基于栈的虚拟机的一个特点:数据的操作需要在栈上进行。那么可以确定这里应该是虚拟栈了。
初始化esi,通过画堆栈图分析,可知 esi 的值为 byte_404781,也就是虚拟指令操作码表(VM Opcode Table)的基址。
初始化 ebp 的值为 esp,指向虚拟栈的栈顶,然后创建一个新的栈帧,用于当作虚拟寄存器使用,edi指向虚拟寄存器的基址。
之后是获取虚拟栈栈顶数据,即虚拟指令操作码的偏移地址,然后加上虚拟操作码表的基址,此时 esi 指向第一个将要被执行的虚拟指令操作码。
根据虚拟指令操作码跳转到对应的VM Handler来执行相应功能。jpt_404757 是一个函数地址表,存放的是VM Handlers的偏移。

虚拟栈栈顶的两个单字节数相加,结果存入后者所在位置,标志寄存器入真实栈,然后将真实栈顶元素(标志寄存器的值)存入到虚拟栈顶处。
参与加法运算的是[源ebp+2] 、[源ebp]的两个字节相加,而不是[源ebp+1] 、[源ebp]的两个字节相加,可能的原因是虚拟栈按两字节对齐。
虚拟栈栈顶两个双字节数相加。此时虚拟栈提升两字节。虚拟栈顶的前四字节为运算产生的标志位,后两字节为运算产生的值。
虚拟栈栈顶两个四字节数相加。此时虚拟栈顶的位置不变。
从虚拟栈栈顶取出两个单字节数据,进行逻辑右移运算。将结果零扩展至双字节(右移结果存储在al中,但入栈的却是ax)。此时虚拟栈提升两字节。
从虚拟栈中依次取出双字节数据、单字节数据(作为位移值),进行逻辑右移运算。此时虚拟栈提升两字节。
从虚拟栈栈顶依次取四字节数据、一字节数据(作为位移值),进行逻辑右移运算。此时虚拟栈提升两字节。
从虚拟栈栈顶依次取两个四字节数据、一个一字节数据,进行双精度右移,这里仅将高位eax放入栈中。此时虚拟栈缩小两字节。
从虚拟栈中依次取出两个单字节数据,进行逻辑左移运算。将结果零扩展为双字节(结果存储在al,但入栈的却是ax)。此时虚拟栈提升两字节。
从虚拟栈的栈顶中依次取出双字节数据、单字节数据(位移值),进行逻辑左移。此时虚拟栈提升两字节。
从虚拟栈的栈顶中依次取出四字节数据、单字节数据(位移值),进行逻辑左移。此时虚拟栈提升两字节。
从虚拟栈栈顶依次取两个四字节数据、一个一字节数据,进行双精度左移。此时虚拟栈缩小两字节。
从虚拟栈中依次取出两个双字节数据,实际上是低位一字节先进行非运算,然后再进行与运算。此时虚拟栈提升两字节。
对虚拟栈栈顶的四字节取反,然后分成两个双字节数进行与运算。此时虚拟栈提升两字节。
从虚拟栈栈顶依次取两个四字节数据,先进行非运算,然后与运算。此时虚拟栈顶位置不变。
取虚拟指令中的操作数(单字节),零扩展至单字,然后入栈。此时虚拟栈提升两字节。
取虚拟指令中操作数(两字节),将其入栈。此时虚拟栈提升两字节。
取虚拟指令中操作数(四字节),将其入栈。此时虚拟栈提升四字节。
取虚拟指令中操作数(单字节),符号扩展成双字,然后入栈。此时虚拟栈提升四字节。
取虚拟指令中的操作数(两字节),符号扩展至双字,然后入栈。此时虚拟栈提升四字节。
从虚拟指令中取出操作数(单字节),作为虚拟寄存器的索引值,然后取出对应的虚拟寄存器中的值(单字节),将其入栈。此时虚拟栈提升两字节。
sub esi, 0FFFFFFFFh等价于 add esi, 1
从虚拟指令中取出操作数(单字节),作为虚拟寄存器的索引值,取出对应虚拟寄存器的数据(双字节),将其入栈。此时虚拟栈提升两字节。
虚拟指令的操作码(单字节)与常量0x3C进行与运算,作为虚拟寄存器的索引值,取出对应虚拟寄存器中的值(四字节),将其入栈。此时虚拟栈提升四字节。
从虚拟指令中取出一字节操作数作为虚拟寄存器索引,取虚拟栈栈顶的两字节数据,将其存储到对应虚拟寄存器中,实际存储低位(一字节)。此时虚拟栈缩小两字节。
从虚拟指令中取出一字节操作数作为虚拟寄存器索引,然后取虚拟栈栈顶的两字节数据,将其存入对应虚拟寄存器中。此时虚拟栈缩小两字节。
虚拟指令的操作码(一字节)与0x3C进行与运算,取出虚拟栈栈顶的四字节数据,将其存放到指定的虚拟寄存器中。此时虚拟栈缩小四字节。
虚拟栈的栈顶指针入栈(低位两字节)。此时虚拟栈提升两字节。
虚拟栈的栈顶指针入栈(四字节)。此时虚拟栈提升四字节。
虚拟栈栈顶的两字节数据加载到虚拟栈指针寄存器中。此时虚拟栈顶变化未知。
虚拟栈栈顶的四字节数据加载到虚拟栈指针寄存器中。此时虚拟栈顶变化未知。
从虚拟栈中依次取四字节数据(内存地址)、一字节数据(待存储的值),将一字节数据存储到四字节数据所指向的内存中。此时虚拟栈缩小六字节。
另一种使用堆栈段寄存器 ss 的情况:
从虚拟栈中依次取四字节数据(内存地址)、两字节数据(待存储的值),将两字节数据存储到四字节数据所指向的内存中。此时虚拟栈缩小六字节。
另一种使用堆栈段寄存器 ss 的情况:
从虚拟栈栈顶依次取两个四字节数据,前者作为内存地址,后者作为待存储的值,然后将值存储到对应内存中。此时虚拟栈缩小八字节。
另一种使用堆栈段寄存器 ss 的情况:
从虚拟栈顶中取出四字节数据作为内存地址,从对应地址中取出单字节数据,零扩展至单字后将其入栈。此时虚拟栈缩小两字节。
另一种使用堆栈段寄存器 ss 的情况:
从虚拟栈中依次取四字节数据作为内存地址,取出对应内存的两字节数据,将其压入栈。此时虚拟栈缩小两字节。
另一种使用堆栈段寄存器 ss 的情况:
取虚拟栈栈顶的四字节数据作为内存地址,然后取对应内存地址的四字节数据,将其压入栈。此时虚拟栈顶位置不变。
另一种使用堆栈段寄存器 ss 的情况:
按照vm_entry入栈顺序进行逆序出栈,还原本机环境。
先检查栈空间是否充足,如果充足的话,跳转到vm_dispatcher,否则进行栈空间调整然后再跳转到vm_dispatcher。
这里借助OllyDBG的Trace功能,跟踪程序执行的代码流,使用方法如下:
通过VM Handler的分析,已经知晓了这些指令类型,通过地址与一级虚拟指令的映射关系,可以初步根据代码流将虚拟代码还原成一级虚拟指令代码流,但是这些一级虚拟指令在不同环境下,操作数是不同的,因此还需要根据OD Trace到的寄存器和内存再做进一步优化。我这里偷点懒,使用的方法仅针对该样本,并不是一个通用的方法:找到一级虚拟指令地址后,选取该Handler中合适的指令,从记录到的上下文环境中提取操作数,手动执行运算得到结果。
具体代码如下:
最终得到一级虚拟指令如下:
一级虚拟指令还原成二级虚拟指令的方法是利用虚拟堆栈平衡,即二级虚拟指令执行后,虚拟栈保持平衡。具体步骤如下:
需注意:
对于刚才还原出的一级虚拟指令样本,先从最后面分析,往上连续的PushReg指令一般都是虚拟寄存器入栈,用于后续恢复真实环境。那么,切割出一级虚拟指令片段如下:
那么根据这个,就需要往前寻找相同数量且连续的PopReg指令,对应一级虚拟指令片段如下:
这里根据VM Entry处的代码进行了虚拟寄存器与真实寄存器之间的映射。
找到了虚拟栈到虚拟寄存器的映射后,就可以从这里开始往下利用虚拟栈平衡划分一级虚拟指令片段了,这里挑出几个片段进行分析。
以上片段可还原成二级虚拟指令
以上片段可还原成二级虚拟指令
以上片段可还原成二级虚拟指令
对于有符号整数x
,根据补码规则可得−x=∼x+1
,进一步有∼x=−(x+1)
,通过这个化简上述二级虚拟指令,可得
这部分代码进行了复杂的标志位计算,然而其产生的结果在后续代码中并没有用到,因此是一段混淆代码。对于标志位的计算,一般与条件跳转指令有关,即先通过逻辑运算提取某一标志位是否为1(例如ZF),然后根据这个结果计算目标跳转指令,接着就是执行条件跳转指令。
至于最上面那个一级虚拟指令片段,通过分析发现其虚拟栈并没有平衡,原因在于,VM Entry处在保存真实环境时,额外入栈了两个数据,加上这两个push指令就平衡了。
不过后续并没有用到该ADDDW虚拟指令产生的结果和标志位,因此认定为这个片段为混淆指令片段。
最终去除混淆代码以及虚拟寄存器与真实寄存器映射(Pop和Push指令,这个主要是在多个虚拟机中跟踪真实寄存器),还原出的二级虚拟指令如下:
此时的二级虚拟指令可以说是与源指令一模一样了,所实现的功能并无差异。
对于虚拟代码还原,首要是识别处虚拟机的相关数据结构,例如虚拟栈指针、虚拟字节码指针、虚拟字节码表等等,然后人工分析处VM Handler的功能,当然,对于VM Handler的分析,可以借助AI来完成,需要告知虚拟机的相关数据结构,使AI的回答能够更精确。分析完虚拟机的结构以及相关数据结构后,可以尝试提取虚拟机结构的特征,比如VM Dispatcher存在VM Handler Table的使用,然后可以尝试编写代码自动化虚拟机结构的识别。之后借助模拟执行来获取整个代码流的执行情况,根据这个还原出虚拟代码流的一级虚拟指令。
对于一级虚拟指令还原成二级虚拟指令,需要利用到虚拟栈平衡这一特征来划分一级虚拟指令片段,这些片段对应一条或多条二级虚拟指令(复杂的逻辑运算可以尝试简化)。这里我总结了一点规律,如有不对的地方,恳请斧正:
因为基于栈的虚拟机,对于一个完整的二级虚拟指令,首先是将操作数据入栈,然后在栈中进行运算,然后将运算产生的标志位或运算结果出栈,因此对于push操作,可以认定是二级虚拟指令开始的标志,对于pop操作,可以认定是二级虚拟指令结束标志。但仍需要注意的是,运算指令后跟随的第一个出栈指令,是将运算产生的标志位出栈,如果后续没有第二个出栈指令,即运算结果仍然保留在虚拟栈中,则有可能该运算结果仍参与后续的指令的执行,因此还需往后进行虚拟栈平衡分析(test、cmp除外,它们只在意运算产生的标志位)
对于模拟执行得到的本机指令以及还原出的一级虚拟指令中,可能存在无用代码,可以借助**变量存活分析(Live-variable analysis)**识别出无用代码并删除,达到简化代码目的。
参考:
如何分析虚拟机系列(1):新手篇VMProtect 1.81 Demo - 吾爱破解 - 52pojie.cn
https://blog.back.engineering/17/05/2021
.text:
00401000
sub_401000 proc near ; CODE XREF: start↓p
.text:
00401000
mov eax, dword_403000; 值为
0deadbeefh
.text:
00401005
add eax,
12345678h
.text:
0040100A
sub eax,
12345678h
.text:
0040100F
mov dword_403000, eax
.text:
00401014
retn
.text:
00401014
sub_401000 endp
.text:
00401000
sub_401000 proc near ; CODE XREF: start↓p
.text:
00401000
mov eax, dword_403000; 值为
0deadbeefh
.text:
00401005
add eax,
12345678h
.text:
0040100A
sub eax,
12345678h
.text:
0040100F
mov dword_403000, eax
.text:
00401014
retn
.text:
00401014
sub_401000 endp
.text:
00401000
; void sub_401000()
.text:
00401000
sub_401000 proc near ; CODE XREF: start↓p
.text:
00401000
push offset byte_404781
.text:
00401005
call sub_40472C
.text:
0040100A
.text:
0040100A
loc_40100A: ; CODE XREF: sub_40472C
+
2B
↓j
.text:
0040100A
; DATA XREF: .vmp0:jpt_404757↓o
.text:
0040100A
mov esi, [ebp
+
0
] ; jumptable
00404757
cases
126
,
128
,
146
,
149
,
246
,
255
.text:
0040100D
add ebp,
4
.text:
00401010
jmp loc_40474E
.text:
00401010
sub_401000 end
.text:
00401000
; void sub_401000()
.text:
00401000
sub_401000 proc near ; CODE XREF: start↓p
.text:
00401000
push offset byte_404781
.text:
00401005
call sub_40472C
.text:
0040100A
.text:
0040100A
loc_40100A: ; CODE XREF: sub_40472C
+
2B
↓j
.text:
0040100A
; DATA XREF: .vmp0:jpt_404757↓o
.text:
0040100A
mov esi, [ebp
+
0
] ; jumptable
00404757
cases
126
,
128
,
146
,
149
,
246
,
255
.text:
0040100D
add ebp,
4
.text:
00401010
jmp loc_40474E
.text:
00401010
sub_401000 end
.vmp0:
00404781
byte_404781 db
0Eh
,
0E8h
,
81h
; DATA XREF: sub_401000↑o
.vmp0:
00404784
dd
5C765DA9h
,
3E0A1A1Eh
,
3A36262Eh
,
602122Ah
,
3000E822h
.vmp0:
00404798
dd
16790040h
,
34567869h
,
1E7A1412h
,
5678E836h
,
97341234h
.vmp0:
004047AC
dd
5C066B4Dh
,
1121973Eh
,
4C3C0622h
,
0EB161121h
,
1E11F7EAh
.vmp0:
004047C0
dd
326B2020h
,
78081577h
,
36325C32h
,
30006904h
,
0ED0040h
.vmp0:
004047D4
dd
4382010h
,
8342C24h
,
0E1001Ch
,
8
dup(
0
)
.vmp0:
00404800
dd
200h
dup(?)
.vmp0:
00404781
byte_404781 db
0Eh
,
0E8h
,
81h
; DATA XREF: sub_401000↑o
.vmp0:
00404784
dd
5C765DA9h
,
3E0A1A1Eh
,
3A36262Eh
,
602122Ah
,
3000E822h
.vmp0:
00404798
dd
16790040h
,
34567869h
,
1E7A1412h
,
5678E836h
,
97341234h
.vmp0:
004047AC
dd
5C066B4Dh
,
1121973Eh
,
4C3C0622h
,
0EB161121h
,
1E11F7EAh
.vmp0:
004047C0
dd
326B2020h
,
78081577h
,
36325C32h
,
30006904h
,
0ED0040h
.vmp0:
004047D4
dd
4382010h
,
8342C24h
,
0E1001Ch
,
8
dup(
0
)
.vmp0:
00404800
dd
200h
dup(?)
.vmp0:
0040472C
push esi
.vmp0:
0040472D
push edi
.vmp0:
0040472E
push esp
.vmp0:
0040472F
push ebx
.vmp0:
00404730
push eax
.vmp0:
00404731
push edx
.vmp0:
00404732
push ebp
.vmp0:
00404733
pushf
.vmp0:
00404734
push ecx
.vmp0:
0040472C
push esi
.vmp0:
0040472D
push edi
.vmp0:
0040472E
push esp
.vmp0:
0040472F
push ebx
.vmp0:
00404730
push eax
.vmp0:
00404731
push edx
.vmp0:
00404732
push ebp
.vmp0:
00404733
pushf
.vmp0:
00404734
push ecx
.vmp0:
00404735
push ds:dword_404649
.vmp0:
0040473B
push
0
.vmp0:
00404735
push ds:dword_404649
.vmp0:
0040473B
push
0
.vmp0:
00404740
mov esi, [esp
+
2Ch
+
arg_0] ;arg_0
=
dword ptr
4
.vmp0:
00404740
mov esi, [esp
+
2Ch
+
arg_0] ;arg_0
=
dword ptr
4
.vmp0:
00404744
mov ebp, esp
.vmp0:
00404746
sub esp,
0C0h
.vmp0:
0040474C
mov edi, esp
.vmp0:
00404744
mov ebp, esp
.vmp0:
00404746
sub esp,
0C0h
.vmp0:
0040474C
mov edi, esp
.vmp0:
0040474E
loc_40474E:
.vmp0:
0040474E
add esi, [ebp
+
0
] ;index of vm opcode
.vmp0:
0040474E
loc_40474E:
.vmp0:
0040474E
add esi, [ebp
+
0
] ;index of vm opcode
mov al, [esi] ;get vm opcode
movzx eax, al
inc esi ;index
+
1
jmp ds:jpt_404757[eax
*
4
] ; jmp to vm handler
mov al, [esi] ;get vm opcode
movzx eax, al
inc esi ;index
+
1
jmp ds:jpt_404757[eax
*
4
] ; jmp to vm handler
loc_40476F:
mov al, [ebp
+
0
]
sub ebp,
2
add [ebp
+
4
], al
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_40476F:
mov al, [ebp
+
0
]
sub ebp,
2
add [ebp
+
4
], al
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_4045FC:
mov ax, [ebp
+
0
]
sub ebp,
2
add [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_4045FC:
mov ax, [ebp
+
0
]
sub ebp,
2
add [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_404000:
mov eax, [ebp
+
0
]
add [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_404751
loc_404000:
mov eax, [ebp
+
0
]
add [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_404751
loc_404680:
mov al, [ebp
+
0
]
mov cl, [ebp
+
2
]
sub ebp,
2
shr al, cl
mov [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_404680:
mov al, [ebp
+
0
]
mov cl, [ebp
+
2
]
sub ebp,
2
shr al, cl
mov [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_40454E:
mov ax, [ebp
+
0
]
mov cl, [ebp
+
2
]
sub ebp,
2
shr ax, cl
mov [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_40454E:
mov ax, [ebp
+
0
]
mov cl, [ebp
+
2
]
sub ebp,
2
shr ax, cl
mov [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_404077:
mov eax, [ebp
+
0
]
mov cl, [ebp
+
4
]
sub ebp,
2
shr eax, cl
mov [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_404077:
mov eax, [ebp
+
0
]
mov cl, [ebp
+
4
]
sub ebp,
2
shr eax, cl
mov [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_404610:
mov eax, [ebp
+
0
]
mov edx, [ebp
+
4
]
mov cl, [ebp
+
8
]
add ebp,
2
shrd eax, edx, cl
mov [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_404751
loc_404610:
mov eax, [ebp
+
0
]
mov edx, [ebp
+
4
]
mov cl, [ebp
+
8
]
add ebp,
2
shrd eax, edx, cl
mov [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_404751
loc_4045C0:
mov al, [ebp
+
0
]
mov cl, [ebp
+
2
]
sub ebp,
2
shl al, cl
mov [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_4045C0:
mov al, [ebp
+
0
]
mov cl, [ebp
+
2
]
sub ebp,
2
shl al, cl
mov [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_404698:
mov ax, [ebp
+
0
]
mov cl, [ebp
+
2
]
sub ebp,
2
shl ax, cl
mov [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_404698:
mov ax, [ebp
+
0
]
mov cl, [ebp
+
2
]
sub ebp,
2
shl ax, cl
mov [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_4046EF:
mov eax, [ebp
+
0
]
mov cl, [ebp
+
4
]
sub ebp,
2
shl eax, cl
mov [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_4046EF:
mov eax, [ebp
+
0
]
mov cl, [ebp
+
4
]
sub ebp,
2
shl eax, cl
mov [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_4046BF:
mov eax, [ebp
+
0
]
mov edx, [ebp
+
4
]
mov cl, [ebp
+
8
]
add ebp,
2
shld eax, edx, cl
mov [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_404751
loc_4046BF:
mov eax, [ebp
+
0
]
mov edx, [ebp
+
4
]
mov cl, [ebp
+
8
]
add ebp,
2
shld eax, edx, cl
mov [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_404751
loc_404591:
mov ax, [ebp
+
0
]
mov dx, [ebp
+
2
]
not
al
not
dl
sub ebp,
2
and
al, dl
mov [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_404591:
mov ax, [ebp
+
0
]
mov dx, [ebp
+
2
]
not
al
not
dl
sub ebp,
2
and
al, dl
mov [ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_404041:
not
dword ptr [ebp
+
0
]
mov ax, [ebp
+
0
]
sub ebp,
2
and
[ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_404041:
not
dword ptr [ebp
+
0
]
mov ax, [ebp
+
0
]
sub ebp,
2
and
[ebp
+
4
], ax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_40400F
loc_40451A:
mov eax, [ebp
+
0
]
mov edx, [ebp
+
4
]
not
eax
not
edx
and
eax, edx
mov [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_404751
loc_40451A:
mov eax, [ebp
+
0
]
mov edx, [ebp
+
4
]
not
eax
not
edx
and
eax, edx
mov [ebp
+
4
], eax
pushf
pop dword ptr [ebp
+
0
]
jmp loc_404751
loc_4044E4:
movzx eax, byte ptr [esi]
sub ebp,
2
mov [ebp
+
0
], ax
add esi,
1
jmp loc_40400F
loc_4044E4:
movzx eax, byte ptr [esi]
sub ebp,
2
mov [ebp
+
0
], ax
add esi,
1
jmp loc_40400F
loc_40464D:
mov ax, [esi]
lea esi, [esi
+
2
]
sub ebp,
2
mov [ebp
+
0
], ax
jmp loc_40400F
loc_40464D:
mov ax, [esi]
lea esi, [esi
+
2
]
sub ebp,
2
mov [ebp
+
0
], ax
jmp loc_40400F
loc_40462B:
mov eax, [esi]
sub ebp,
4
lea esi, [esi
+
4
]
mov [ebp
+
0
], eax
jmp loc_40400F
loc_40462B:
mov eax, [esi]
sub ebp,
4
lea esi, [esi
+
4
]
mov [ebp
+
0
], eax
jmp loc_40400F
loc_40453B:
mov al, [esi]
cbw
cwde
sub ebp,
4
lea esi, [esi
+
1
]
mov [ebp
+
0
], eax
jmp loc_40400F
loc_40453B:
mov al, [esi]
cbw
cwde
sub ebp,
4
lea esi, [esi
+
1
]
mov [ebp
+
0
], eax
jmp loc_40400F
loc_4044BE:
mov ax, [esi]
cwde
add esi,
2
sub ebp,
4
mov [ebp
+
0
], eax
jmp loc_40400F
loc_4044BE:
mov ax, [esi]
cwde
add esi,
2
sub ebp,
4
mov [ebp
+
0
], eax
jmp loc_40400F
loc_4044D0:
mov al, [esi]
mov al, [edi
+
eax]
sub ebp,
2
sub esi,
0FFFFFFFFh
mov [ebp
+
0
], ax
jmp loc_40400F
loc_4044D0:
mov al, [esi]
mov al, [edi
+
eax]
sub ebp,
2
sub esi,
0FFFFFFFFh
mov [ebp
+
0
], ax
jmp loc_40400F
loc_4045E9:
mov al, [esi]
inc esi
mov ax, [edi
+
eax]
sub ebp,
2
mov [ebp
+
0
], ax
jmp loc_40400F
loc_4045E9:
mov al, [esi]
inc esi
mov ax, [edi
+
eax]
sub ebp,
2
mov [ebp
+
0
], ax
jmp loc_40400F
loc_4045AF:
and
al,
3Ch
mov edx, [edi
+
eax]
sub ebp,
4
mov [ebp
+
0
], edx
jmp loc_40400F
loc_4045AF:
and
al,
3Ch
mov edx, [edi
+
eax]
sub ebp,
4
mov [ebp
+
0
], edx
jmp loc_40400F
loc_404568:
mov al, [esi]
mov dx, [ebp
+
0
]
sub esi,
0FFFFFFFFh
add ebp,
2
mov [edi
+
eax], dl
jmp loc_404751
loc_404568:
mov al, [esi]
mov dx, [ebp
+
0
]
sub esi,
0FFFFFFFFh
add ebp,
2
mov [edi
+
eax], dl
jmp loc_404751
loc_4046DA:
mov al, [esi]
add esi,
1
mov dx, [ebp
+
0
]
add ebp,
2
mov [edi
+
eax], dx
jmp loc_404751
loc_4046DA:
mov al, [esi]
add esi,
1
mov dx, [ebp
+
0
]
add ebp,
2
mov [edi
+
eax], dx
jmp loc_404751
loc_404058:
and
al,
3Ch
mov edx, [ebp
+
0
]
add ebp,
4
mov [edi
+
eax], edx
jmp loc_404751
loc_404058:
and
al,
3Ch
mov edx, [ebp
+
0
]
add ebp,
4
mov [edi
+
eax], edx
jmp loc_404751
loc_40463B:
mov eax, ebp
sub ebp,
2
mov [ebp
+
0
], ax
jmp loc_40400F
loc_40463B:
mov eax, ebp
sub ebp,
2
mov [ebp
+
0
], ax
jmp loc_40400F
loc_4046B2:
mov eax, ebp
sub ebp,
4
mov [ebp
+
0
], eax
jmp loc_40400F
loc_4046B2:
mov eax, ebp
sub ebp,
4
mov [ebp
+
0
], eax
jmp loc_40400F
loc_404532:
mov bp, [ebp
+
0
]
jmp loc_40400F
loc_404532:
mov bp, [ebp
+
0
]
jmp loc_40400F
loc_40457C:
mov ebp, [ebp
+
0
]
jmp loc_40400F
loc_40457C:
mov ebp, [ebp
+
0
]
jmp loc_40400F
loc_4044AE:
mov eax, [ebp
+
0
]
mov dl, [ebp
+
4
]
add ebp,
6
mov [eax], dl
jmp loc_404751
loc_4044AE:
mov eax, [ebp
+
0
]
mov dl, [ebp
+
4
]
add ebp,
6
mov [eax], dl
jmp loc_404751
loc_40475E:
mov eax, [ebp
+
0
]
mov dl, [ebp
+
4
]
add ebp,
6
mov ss:[eax], dl
jmp loc_404751
loc_40475E:
mov eax, [ebp
+
0
]
mov dl, [ebp
+
4
]
add ebp,
6
mov ss:[eax], dl
jmp loc_404751
loc_4044F6:
mov eax, [ebp
+
0
]
mov dx, [ebp
+
4
]
add ebp,
6
mov [eax], dx
jmp loc_404751
loc_4044F6:
mov eax, [ebp
+
0
]
mov dx, [ebp
+
4
]
add ebp,
6
mov [eax], dx
jmp loc_404751
loc_404706:
mov eax, [ebp
+
0
]
mov dx, [ebp
+
4
]
add ebp,
6
mov ss:[eax], dx
jmp loc_404751
loc_404706:
mov eax, [ebp
+
0
]
mov dx, [ebp
+
4
]
add ebp,
6
mov ss:[eax], dx
jmp loc_404751
loc_404670:
mov eax, [ebp
+
0
]
mov edx, [ebp
+
4
]
add ebp,
8
mov [eax], edx
jmp loc_404751
loc_404670:
mov eax, [ebp
+
0
]
mov edx, [ebp
+
4
]
add ebp,
8
mov [eax], edx
jmp loc_404751
loc_4045D8:
mov eax, [ebp
+
0
]
mov edx, [ebp
+
4
]
add ebp,
8
mov ss:[eax], edx
jmp loc_404751
loc_4045D8:
mov eax, [ebp
+
0
]
mov edx, [ebp
+
4
]
add ebp,
8
mov ss:[eax], edx
jmp loc_404751
loc_40465F:
mov edx, [ebp
+
0
]
add ebp,
2
mov al, [edx]
mov [ebp
+
0
], ax
jmp loc_404751
loc_40465F:
mov edx, [ebp
+
0
]
add ebp,
2
mov al, [edx]
mov [ebp
+
0
], ax
jmp loc_404751
loc_40449C:
mov edx, [ebp
+
0
]
add ebp,
2
mov al, ss:[edx]
mov [ebp
+
0
], ax
jmp loc_404751
loc_40449C:
mov edx, [ebp
+
0
]
add ebp,
2
mov al, ss:[edx]
mov [ebp
+
0
], ax
jmp loc_404751
loc_404508:
mov eax, [ebp
+
0
]
add ebp,
2
mov ax, [eax]
mov [ebp
+
0
], ax
jmp loc_404751
loc_404508:
mov eax, [ebp
+
0
]
add ebp,
2
mov ax, [eax]
mov [ebp
+
0
], ax
jmp loc_404751
loc_404719:
mov eax, [ebp
+
0
]
add ebp,
2
mov ax, ss:[eax]
mov [ebp
+
0
], ax
jmp loc_404751
loc_404719:
mov eax, [ebp
+
0
]
add ebp,
2
mov ax, ss:[eax]
mov [ebp
+
0
], ax
jmp loc_404751
loc_404584:
mov eax, [ebp
+
0
]
mov eax, [eax]
mov [ebp
+
0
], eax
jmp loc_404751
loc_404584:
mov eax, [ebp
+
0
]
mov eax, [eax]
mov [ebp
+
0
], eax
jmp loc_404751
loc_404069:
mov eax, [ebp
+
0
]
mov eax, ss:[eax]
mov [ebp
+
0
], eax
jmp loc_404751
loc_404069:
mov eax, [ebp
+
0
]
[注意]看雪招聘,专注安全领域的专业人才平台!