VMProtect是一种很可靠的工具,可以保护应用程序代码免受分析和破解,但只有在应用程序内保护机制正确构建且没有可能破坏整个保护的严重错误的情况下,才能实现最好的效果。

VMProtect通过在具有非标准体系结构的虚拟机上执行代码来保护代码,这将使分析和破解软件变得十分困难。除此之外,VMProtect还可以生成和验证序列号,限制免费升级等等。

下载VMProtect最新试用版

VMProtect正版授权在线订购享受最低价,仅售801元起!还不赶紧加入你的订购清单?>>更多详情可点击咨询购买

相关链接:

代码保护软件VMP逆向分析虚拟机指令:初步认识与环境搭建(一)

代码保护软件VMP逆向分析虚拟机指令:VMP代码的提取(二)

代码保护软件VMP逆向分析虚拟机指令详细分析(三)

代码保护软件VMP逆向分析虚拟机指令:分析那4条汇编被VM的VM指令

五、分析VM的一些细节

我们差不多讲完基础分析是吧,基本上可以说是可以动手分析了,但是在那之前我们有些东西好像还没讲清楚,一些细节。

1、VM的栈问题

有个地方我们还没讲 ,就是如果压栈时 , 如果超出了栈大小 (就目前我们看到的还没有超栈的情况),占用到了vm_context怎么办下面是我截取的汇编, 所以你看到地址有时候很奇怪 。我们来分析一下如果压栈超出了栈空间怎么办
00433391 8D4424 60 lea eax,dword ptr ss:[esp+0x60]
00433395 F6C5 65 test ch,0x65
00433398 3BC9 cmp ecx,ecx
0043339A 66:81FD EA79 cmp bp,0x79EA
0043339F 3BE8 cmp ebp,eax
004333A1 E9 0F3A0000 jmp vmptest_.00436DB5
00436DB5 /0F87 F2C80200 ja vmptest_.004636AD ;看到这里我们之前都是跳了 我们追踪代码
00436DBB |8BC4 mov eax,esp ;的时候下面的代码就被跳过了,直接到了
00436DBD |8ACB mov cl,bl ;vmtest_.004636AD 接下来我们重点讲没跳
00436DBF |B9 40000000 mov ecx,0x40 ;过的这部分代码
00436DC4 |0FC0F6 xadd dh,dh
00436DC7 |8D5425 80 lea edx,dword ptr ss:[ebp-0x80]
00436DCB |3BFF cmp edi,edi
00436DCD ^|E9 101CFEFF jmp vmptest_.004189E2
004189E2 81E2 FCFFFFFF and edx,0xFFFFFFFC
004189E8 F9 stc
004189E9 66:F7C7 8465 test di,0x6584
004189EE 2BD1 sub edx,ecx
004189F0 ^ E9 38D1FFFF jmp vmptest_.00415B2D
00415B2D 8BE2 mov esp,edx
00415B2F 57 push edi
00415B30 66:BF CD59 mov di,0x59CD
00415B34 0FBFF8 movsx edi,ax
00415B37 E9 FA590400 jmp vmptest_.0045B536
0045B536 56 push esi
0045B537 ^ E9 058AFEFF jmp vmptest_.00443F41
00443F41 9C pushfd
00443F42 66:0FCE bswap si
00443F45 8BF0 mov esi,eax
00443F47 66:0F46FB cmovbe di,bx
00443F4B 8BFA mov edi,edx
00443F4D E9 490E0400 jmp vmptest_.00484D9B
00484D9B FC cld
00484D9C ^ E9 9513F9FF jmp vmptest_.00416136
00416136 F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
00416138 C1E6 B0 shl esi,0xB0
0041613B C1C7 FA rol edi,0xFA
0041613E 66:0FBAFF 16 btc di,0x16
00416143 9D popfd
00416144 5E pop esi
00416145 66:0FCF bswap di
00416148 8BFB mov edi,ebx
0041614A 5F pop edi
0041614B E9 5DD50400 jmp vmptest_.004636AD
004636AD FFE7 jmp edi
我们先去混淆一下看看,按之前的方法
00433391 8D4424 60 lea eax,dword ptr ss:[esp+0x60]
0043339F 3BE8 cmp ebp,eax ;比较栈顶 与vm_context末尾位置
00436DB5 /0F87 F2C80200 ja vmptest_.004636AD ;如果栈顶 大于 vm_context最末尾位置 证明栈还没有顶到vm_context
00436DBB |8BC4 mov eax,esp ;eax记录一下vm_context位置
00436DBF |B9 40000000 mov ecx,0x40
00436DC7 |8D5425 80 lea edx,dword ptr ss:[ebp-0x80]
004189E2 81E2 FCFFFFFF and edx,0xFFFFFFFC ;让后2位为0 地址对齐
004189EE 2BD1 sub edx,ecx ;其实就是栈顶 -0xC0
00415B2D 8BE2 mov esp,edx ;把vm_context 与栈底 拉高0xC0个字节 主要是栈底不动 vm_context动
00415B2F 57 push edi ;这一方面也是看出来为什么每次都要和esp+0x60比较
0045B536 56 push esi -------------------------------------
00443F41 9C pushfd ;备份 edi 、esi、和eflags值
00443F45 8BF0 mov esi,eax
00443F4B 8BFA mov edi,edx
00416136 F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi] ;然后把旧vm_context线上值 拷贝到新vm_context上
00416143 9D popfd ---------------------------------------
00416144 5E pop esi ;还原 edi、esi、和eflags值
0041614A 5F pop edi
004636AD FFE7 jmp edi
然后你发现了什么问题, 在最后的rep movs中, 我们是拷贝byte为单位, 拷贝的长度是由ecx决定的,但是ecx=0x40, 而我们之前很早之前说 esp+0x60我们推出寄存器有 0x60/4=0x18 个, 芜湖!!!!!!!那么我们现在怎么解释呢? 这里我们应该可以看出来 vm_context应该只有16个寄存器。 即0x10个寄存器而多出来的 0x20个byte(8 int32) 应该是给压栈时缓冲用的, 比如像这里他是先压栈, 在判断栈是否报栈了 ,那么如果爆栈了, 假如vm_context是0x18个寄存器, 他就会覆盖到第0x17编号寄存器,那么他就没办法回缩 还原vm_context上被感染的寄存器值(如果要能还原 带价太大) 所以这里多出的8 int32 应该是缓冲用的。
所以说分析问题 往往都是 ,从假设开始 ,你之前看到的可能 会被后面的又重新定义 ,然后你会发现
你之前的好像不太严谨 ,往后看这个就严谨了 ,好像一切 就 豁然开朗了。

2、寄存器轮转机制

VM_PushImm32 0x00002222 ;执行下面的VM_Add后 | dwResult 0x00005555
VM_PushReg32 vm_context->0x00 ;0x00003333 | eflags 0x00000206
VM_Add
VM_PopReg32 vm_context->0x1C ;0x00000206 EFLAGS
VM_PopReg32 vm_context->0x1C ;0x00005555
VM_PushImm32 0x00001010
VM_PushReg32 vm_context->0x1C ;0x00005555 dwResult 上一次Add的结果
VM_PushReg32 vm_context->0x1C ;0x00005555
VM_Nand ;执行后 [ESP] = EFLAGS = 0x286 [ESP+4]=0xFFFFAAAA
VM_PopReg32 vm_context->0x00 ;0x286 弹出这个后 现在栈上应该是[ESP]=0xFFFFAAAA [ESP+4]=0x0x00001010
VM_Add ;执行这个这里后 [ESP] = EFLAGS = 0x282 [ESP+4]=0xFFFFBABA
VM_PopReg32 vm_context->0x0C ;0x282 eflags
VM_PushReg32 vm_esp ;现在[ESP] = ESP+4 即保存这个地址 这个地址对应的值是 0xFFFFBABA 没问题吧
VM_SSReadMemSS ;把栈顶的值当mem读 值返回到自身 [ESP]=[[ESP]] = [ESP + 4] = 0xFFFFBABA
VM_Nand ;还没运行这个指令时[ESP]=0xFFFFBABA [ESP+4]=0xFFFFBABA
VM_PopReg32 vm_context->0x20 ;0x202 eflags
VM_PopReg32 vm_context->0x10 ;0x00004545 到这里 可以说这4句汇编已经运行完毕了
我们可以看到 0x2222 + 0x3333 = 0x5555 如果按我们的那4句汇编来的话, 这个0x5555应该是在eax寄存器上,如果说vm_context 的某个偏移值与我们物理机的寄存器是绝对对应关系的话, 那么往下走得到的最终结果应该也是在 0x5555所在的这个寄存器上即 vm_context->0x1C, 但是我们发现不是了, 而是vm_context + 0x10上。这就是VMP所谓的寄存器轮转机制, 这个轮转是在程序编译期间有一张表, 所以现在你是无法看到这个对应关系的转变。
3、同一条指令的不同比较

VM_PushReg32 vm_context->0x1C VM_PushReg32 vm_context->0x1C
/------------------------------------------------------------------------------------------
0042E1A7 LEA ESI,DWORD PTR DS:[ESI-1] 0043B877 SUB ESI,1
0042E1AD MOVZX EAX,BYTE PTR DS:[ESI] 0043B87D ROL EAX,CL
0042E1B0 SHR DX,CL 0043B87F MOVSX ECX,DX
0042E1B3 MOVZX EDX,BX 0043B882 MOVZX EAX,BYTE PTR DS:[ESI]
0042E1B6 CDQ 0043B885 BTC CX,BX
0042E1B7 XOR AL,BL 0043B889 BTS ECX,EBX
0042E1B9 ADD ECX,605116AB 0043B88C OR DH,64
0042E1BF CMP DH,87 0043B88F XOR AL,BL
0042E1C2 ADD AL,19 0043B891 ADD AL,19
0042E1C4 ROR AL,1 0043B893 MOVZX CX,DH
0042E1C6 CMOVNB EDX,ESI 0043B897 ROR AL,1
0042E1C9 XCHG CX,DX 0043B899 JMP vmptest_.0045256F
0042E1CC MOV EDX,EBP 0045256F INC AL
0042E1CE INC AL 00452571 XOR AL,49
0042E1D0 AND DX,53E2 00452573 ROR DH,CL
0042E1D5 XOR AL,49 00452575 XOR BL,AL
0042E1D7 BSF CX,BX 00452577 MOVSX EDX,SP
0042E1DB SBB ECX,EBP 0045257A BTR ECX,ESP
0042E1DD XOR BL,AL 0045257D SUB EDX,1D2A7287
0042E1DF SAR DX,CL 00452583 MOV EDX,DWORD PTR SS:[ESP+EAX]
0042E1E2 MOV EDX,DWORD PTR SS:[ESP+EA 00452586 NOT ECX
0042E1E5 MOV CL,1A 00452588 LEA EDI,DWORD PTR DS:[EDI-4]
0042E1E7 RCR CH,CL 0045258E MOV DWORD PTR DS:[EDI],EDX
0042E1E9 MOVSX ECX,CX 00452590 SUB ESI,4
0042E1EC LEA EDI,DWORD PTR DS:[EDI-4] 00452596 DEC CX
0042E1F2 MOV DWORD PTR DS:[EDI],EDX 00452599 JMP vmptest_.00410D3E
0042E1F4 XOR CH,0A4 00410D3E MOV ECX,DWORD PTR DS:[ESI]
0042E1F7 BTS ECX,EBX 00410D40 CMC
0042E1FA SUB ESI,4 00410D41 STC
0042E200 MOV ECX,DWORD PTR DS:[ESI] 00410D42 CLC
0042E202 STC 00410D43 XOR ECX,EBX
0042E203 TEST DH,DH 00410D45 CMP EDI,ESP
0042E205 XOR ECX,EBX 00410D47 NOT ECX
0042E207 CLC 00410D49 CMP DL,0F7
0042E208 CMC 00410D4C STC
0042E209 NOT ECX 00410D4D ADD ECX,1B2352AE
0042E20B CLC 00410D53 BSWAP ECX
0042E20C ADD ECX,1B2352AE 00410D55 TEST ESP,4D941F4C
0042E212 CMC 00410D5B XOR ECX,26A7DD4
0042E213 CLC 00410D61 STC
0042E214 BSWAP ECX 00410D62 XOR EBX,ECX
0042E216 TEST EDI,EDI 00410D64 CLC
0042E218 STC 00410D65 CMP BP,11E1
0042E219 XOR ECX,26A7DD4 00410D6A CMC
0042E21F CMP CX,BX 00410D6B ADD EBP,ECX
0042E222 XOR EBX,ECX 00410D6D JMP vmptest_.0047F0F3
0042E224 STC 0047F0F3 JMP vmptest_.00472E41
0042E225 TEST ECX,ESI 00472E41 LEA EDX,DWORD PTR SS:[ESP+60]
0042E227 ADD EBP,ECX 00472E45 TEST DH,AL
0042E229 JMP vmptest_.00409E73 00472E47 CLC
00409E73 JMP vmptest_.00472E41 00472E48 CMP EDI,EDX
00472E41 LEA EDX,DWORD PTR SS:[ESP+60] 00472E4A JMP vmptest_.0046EE86
00472E45 TEST DH,AL 0046EE86 JA vmptest_.00480A05
00472E47 CLC 00480A05 JMP EBP
00472E48 CMP EDI,EDX
00472E4A JMP vmptest_.0046EE86
0046EE86 JA vmptest_.00480A05
00480A05 JMP EBP
---------------------------------------------------------------------------------
指令与压哪个寄存器无关,我这里只是恰巧找了两个压了相同VM寄存器的。 你看他们的主要代码是不是一样的, 去混淆一下, 就发现是一模一样的, 解密都一样,不过可能存在乱序(在不影响经结果的情况下), 而每次vmp加壳同一个程序这些同vm指令解密都不一样。去混淆我就不去了, 很简单 1-2min的事情 从vm的环境去提取关键汇编就可以了。不过我相信现在你用肉眼就已经看出来了。那么我们上面分析的东西材料我都放在demo文件夹下了。
六、简单总结一下过程
总结就是 :
1.VM_Entry 进入虚拟机
2.VM_Init 物理环境映射虚拟机
3.VM_Init_bytescode vm的代码解析环境初始化
4.执行VM的代码
5.VM_Destroy 虚拟机环境压栈
6.VM_Exit 物理环境从栈上弹出

在整个过程中我们并没有看到有一个大循环, 心脏去驱动 去取指令, 然后解析指令是吧。 这个就是vmp3与vmp1和vmp2的最大区别,解析bytescode不在由VMDispatcher 分发下一个指令执行什么了(每个指令记为一个handle) 而是有vm_bytescode掌管,执行上一个指令才能得到下一个指令地址 这样一来代码的膨胀可想而知。在VM_Instruct内部应该是没有CALL指令的。

如果您对该加密/解密软件感兴趣,欢迎加入vmpQQ交流群:740060302

代码保护软件VMP逆向分析虚拟机指令相关推荐

  1. 代码保护软件VMP逆向分析虚拟机指令:VMP代码的提取

    VMProtect是一种很可靠的工具,可以保护应用程序代码免受分析和破解,但只有在应用程序内保护机制正确构建且没有可能破坏整个保护的严重错误的情况下,才能实现最好的效果. VMProtect通过在具有 ...

  2. 代码保护软件VMP指令中包含了函数调用

    VMProtect是一种很可靠的工具,可以保护应用程序代码免受分析和破解,但只有在应用程序内保护机制正确构建且没有可能破坏整个保护的严重错误的情况下,才能实现最好的效果. VMProtect通过在具有 ...

  3. 代码保护软件 VMProtect 用户手册:分析,破解和保护软件

    是一款虚拟机保护软件,是目前最为流行的保护壳之一.VMProtect将保护后的代码放到虚拟机中运行, 这将使分析反编译后的代码和破解变得极为困难.除了代码保护,VMProtect 还可以生成和验证序列 ...

  4. X64驱动开发和保护+X86X64游戏逆向分析课程

    老师教学范围和方式:木塔负责PC电脑端C语言基础和端游逆向分析部分内容,采用录制+部分直播课程教学,晚上还有专业老师讲解和指导.我要的是质量不是数量.老师备课,设计课件需要时间的. 学习周期:PC端3 ...

  5. 代码保护软件 VMProtect 3.3已将Taggant System移除

    VMProtect通过在具有非标准体系结构的虚拟机上执行代码来保护代码,这将使分析和破解软件变得十分困难.除此之外,VMProtect还可以生成和验证序列号,限制免费升级等等. 本篇文章主要是想告知大 ...

  6. 代码保护软件 VMProtect 用户手册之使用VMProtect: 准备项目

    VMProtect 是一种很可靠的工具,可以保护应用程序代码免受分析和破解,但只有在应用程序内保护机制正确构建且没有可能破坏整个保护的严重错误的情况下,才能实现最好的效果. VMProtect最新试用 ...

  7. 代码保护软件VMProtect用户手册主窗口之控制面板“项目”部分(4)

    VMProtect是一种很可靠的工具,可以保护应用程序代码免受分析和破解,但只有在应用程序内保护机制正确构建且没有可能破坏整个保护的严重错误的情况下,才能实现最好的效果. 下载VMProtect最新试 ...

  8. 代码保护软件VMProtect用户手册主窗口之主菜单

    VMProtect是一种很可靠的工具,可以保护应用程序代码免受分析和破解,但只有在应用程序内保护机制正确构建且没有可能破坏整个保护的严重错误的情况下,才能实现最好的效果. 下载VMProtect最新试 ...

  9. 代码保护软件VMProtect用户手册之内置功能(1)——字符串功能作用

    VMProtect是一种很可靠的工具,可以保护应用程序代码免受分析和破解,但只有在应用程序内保护机制正确构建且没有可能破坏整个保护的严重错误的情况下,才能实现最好的效果. 本文继续对VMProtect ...

最新文章

  1. Android实现炫酷的星空变幻效果
  2. python人脸识别毕业设计-Python 40行代码实现人脸识别功能
  3. JavaScript label语句
  4. 计算机指令取决,不同的计算机,其指令不同,这主要取决于什么?
  5. java searchterm_elasticsearch – 弹性搜索:“Term”,“Match Phrase”和“Query String”之间的差异...
  6. 荣耀正式加入GSMA 成为其企业成员单位
  7. 20190804:有效的括号(误删补发)
  8. BZOJ3828 : [Poi2014]Criminals
  9. 微信扫码支付模式二【无法回调】解决方案(转)
  10. PUBG - 罗技鼠标宏 | 兴趣使然的项目,完虐收费宏!点个Star支持一下作者!
  11. 3.1.4_cardView原理解析
  12. java用dockerfile生成镜像_【HAVENT原创】创建 Dockerfile 生成新的镜像,并发布到 DockerHub...
  13. NOIP2017翻车记
  14. 实验二 SQL Server数据查询
  15. 系统分区减小_每日一练,防排烟系统,6.1
  16. VTK/OpenGL中球坐标转直角坐标
  17. ubuntu18.04 使用scp命令
  18. 【题解】天梯赛练习集 L1-059 敲笨钟
  19. 阿里云云计算专业认证考试(Alibaba Cloud Certified Professional,ACP)
  20. SpringBoot设置网站页面小图标——Favicon

热门文章

  1. 点亮stm32开发板的led灯
  2. CS大类专硕都有哪些?前景如何?
  3. dnsmasq选项介绍
  4. 深圳python培训脱产
  5. What's wrong baby?
  6. vld for memory leak detector (release version)
  7. 设计电脑必备软件合集,实用工具推荐
  8. 基于单片机的ILI2132驱动调试
  9. 软件定义网络、网络虚拟化和网络功能虚拟化的区别
  10. Android sdk 21~23 WebView加载报错