awesome-vmp
关于软件虚拟化保护(如VMProtect)的资料。
工具篇介绍了VM保护的现有分析工具,并进行了简单的试用分析。
文章篇介绍了VM保护相关的分析文章,包括对虚拟机的分析,及一些反混淆方法。
本项目发在了github上, https://github.com/lmy375/awesome-vmp
如果有其他好用的工具或者优秀的文章可以留言链接或者直接在github上提交 pull request,优秀的资源需要分享才能最大发挥其价值。
工具篇
FKVMP
- 针对目标:VMProtect 1.x 2.x (大概到 VMProtect 2.09)
- 类型:Ollydbg 插件
- 开发者:Nooby
- 功能:Handler 识别、还原 PCODE 等
FKVMP 是比较古老的一款 Ollydbg 插件,但在当时非常有名。
使用方法简单,在虚拟机入口处(push/call 或 jmp)右键 FKVMP -> start 即可。
下图是对如下代码
mov ebx, 0deadbeefhmov eax, 0beefdeadh
使用 VMProtect 1.60 保护后, 使用 FKVMP 分析的结果(结果打印在 OD 的日志窗口中)。
可以所有Handler已经为指令都已经识别出来,初始化压栈的寄存器顺序也会打印出来。
本工具(可能是第1次完成)字节码的还原的实现(其实可以认为是虚拟机指令的反汇编)使对 VMProtect 的人工分析成为可能。
缺点是只支持单一的基本块,每次分析到 SetEIP 指令(实际就是跳转指令)就会停止,需要人工操作,去分析下一基本块。
VMP分析插件
- 针对目标:VMProtect 1.x 2.x (大概到 VMProtect 2.09)
- 类型:Ollydbg / Immunity Debugger 插件
- 开发者:zdhysd
- 功能:Handler 识别、虚拟字节码调试、表达式化简
- 链接:https://bbs.pediy.com/thread-154621.htm
- 最后更新时间:v1.4 2013/01/30
可以认为是 FKVMP 的超级加强版,在同类工具之中功能最为强大的工具。
首先该工具支持了跨基本块的分析,可以一次性将全部虚拟机字节码提取出来。除此外,还有许多亮点功能:
- 虚拟指令级别的调试。可以像调试汇编一样调试虚拟机指令,可以单步运行一条虚拟指令,并查看虚拟寄存器、虚拟栈的信息。
- 表达式转化及化简。本功能会在虚拟指令级别进行数据流和控制流的分析,进行字节码的收缩。 VMProtect 是栈机结构,同时有 NOR 逻辑的混淆膨胀,字节码的收缩还原一直是研究的重点,本工具可以完成字节码收缩过程,输出收缩后的表达式。唯一不同是没有转化成原始的 x86 代码。但在分析上,已经可以提供极为有力的参考。
- 支持字节码的 Patch。由于加密的存在,字节码 Patch 一直是十分痛苦的过程,本工具可以像 Patch 普通指令一样 Patch 虚拟指令。
- 支持自定义模板。模板包括 Handler 识别模板和表达式化简模板。该工具提供了模板文件及模板修改工具。理论上,可以通过对模板文件的修改使及兼容所有版本的 VMProtect 1.x 2.x。( 3.x 因为虚拟机结构变化不能支持)。
下图是工具使用截图。该工具以插件的形式,实现了一个与原生OD非常相似的VMP调试界面,寄存器、栈的内容可以实时查看。
使用方法简单,在虚拟机入口处(push/call 或 jmp)右键 VMP分析插件 -> 分析虚拟程序 完成分析。然后可以打开插件的虚拟指令窗口、调试窗口查看字节码并进行调试分析。
VMSweeper
- 针对目标:VMProtect 2.x 、Code Virtualizer
- 类型:Ollydbg 插件
- 开发者:Vamit
- 功能:VMProtect 保护下的 x86 代码还原
- 最后更新时间:v1.5 2014
可以完成 VMP 保护代码还原的工具。 完全的代码还原是十分困难的,因此该工具稳定性不高,经常出现异常。但是某些简单样本的测试,确实有不错的还原效果。
使用方法:
- 使用纯净版 OD 加载插件,避免插件间冲突。
- Plugins -> VMPSweeper -> Analyze all VM reference
- 弹出窗口选要分析的 VM, 右键 Decode VM。
- 此时会自动在虚拟机入口点断下,F1 快捷键,VMSweeper会开始进行分析。
- 分析完成后,会弹出提示框重新运行进程。重新运行后, Plugins -> VMPSweeper -> Continue decode VM。继续分析。
- 如果分析没有产生任何异常,VMPSweeper 会把还原后的代码 Patch 到原本的虚拟机入口处。
- 但上述过程经常出错,可以在 OD 根目录下查找 VMS_xxx 文件夹,查看日志文件,*.log 文件中保存着还原的过程输出。
如下是log文件截取。
...++++++++++++++++++++++++++++++++++++ Section a12 final++++++++++++++++++++++++++++++++++++004100BC: push ebp004100C2: rvm_38 = esp004100C9: push esi004100D5: push edi004100F6: [rvm_38 + 0xFFFFFFFC] = 000410111: eax = [rvm_38 + 0xFFFFFFFC]00410131: rvm_34 = [rvm_38 + 8]00410167: eax = [eax * 4 + rvm_34]00410186: rvm_10 = [rvm_38 + 0xFFFFFFFC]004101A6: edi = [rvm_38 + 8]004101EC: rvm_08 = [rvm_10 * 4 + edi + 4 + eax]0041021C: eax = [rvm_38 + 0xFFFFFFFC]0041023C: rvm_10 = [rvm_38 + 0x0000000C]00410278: [eax * 4 + rvm_10] = rvm_0800410292: rvm_34 = [rvm_38 + 0xFFFFFFFC]0041029C: eax = rvm_34 + 1004102D4: [rvm_38 + 0xFFFFFFFC] = eax004102EF: edx = [rvm_38 + 0xFFFFFFFC]0041030F: eax = [rvm_38 + 8]0041032F: rvm_18 = [rvm_38 + 0xFFFFFFFC]0041034F: eax = [rvm_38 + 8]00410385: rvm_3C = [edx * 4 + eax]00410466: edi = and ~and ~rvm_3C, [rvm_18 * 4 + rvm_24 + ~4], ~and rvm_3C, [rvm_18 * 4 + rvm_24 + 4]...