首页
社区
课程
招聘
7
[原创]VMP入门: VMP1.81 Demo分析
发表于: 2025-3-31 20:31 5887

[原创]VMP入门: VMP1.81 Demo分析

2025-3-31 20:31
5887

本文主要是通过分析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]

[注意]看雪招聘,专注安全领域的专业人才平台!

收藏
免费 7
支持
分享
赞赏记录
参与人
雪币
留言
时间
jmpcall
谢谢你的细致分析,受益匪浅!
2025-4-8 10:47
0x指纹
+1
感谢你分享这么好的资源!
2025-4-7 09:46
东方玻璃
+1
感谢你的贡献,论坛因你而更加精彩!
2025-4-5 10:44
咖啡_741298
期待更多优质内容的分享,论坛有你更精彩!
2025-4-4 17:35
Abelly
你的分享对大家帮助很大,非常感谢!
2025-4-2 09:04
TubituX
+1
感谢你的贡献,论坛因你而更加精彩!
2025-4-1 09:42
马来
你的帖子非常有用,感谢分享!
2025-3-31 21:51
最新回复 (7)
雪    币: 36
活跃值: (561)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
2
VMP 都3.94了 
2025-4-2 00:38
0
雪    币: 4
活跃值: (4095)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习了
2025-4-4 17:35
0
雪    币: 173
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
学习了,分析的很好
2025-4-4 18:02
0
雪    币: 20
活跃值: (1209)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
老公,能不能把例子发上来
2025-4-6 06:42
0
雪    币: 6205
活跃值: (19785)
能力值: ( LV13,RANK:357 )
在线值:
发帖
回帖
粉丝
6
感谢分享
2025-4-7 09:46
0
雪    币: 1396
活跃值: (1046)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
在第三部分案例分析开头给了链接,这是吾爱破解的Cr4ckm3大佬,也是看雪中的穆恩大佬给例子。链接我在这里再贴一下:
https://www.52pojie.cn/thread-713219-1-1.html
https://bbs.kanxue.com/thread-225262.htm
2025-4-8 14:16
0
雪    币: 201
活跃值: (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
3.0没有dispatcher了,采用的是winlicense一样的handler尾部跳转的方式
2025-4-15 20:02
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

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