VMP3.X脱壳技巧

样本分析中,偶尔会见到一些加了VMP的样本。

众所周知VMP是软件保护中的硬骨头,但得益于很多前辈们的研究,现在有很多可以辅助我们对VMP进行分析的好用的工具。

本文以加了VMP3.5的程序为例,讲解一下只加了壳,没有加虚拟的VMP样本如何进行脱壳,方便我们在IDA中分析。

使用的样例程序为SysinternalsSuite套件中的WinObj.exe 32位。本文主要是工具流,32位下趁手的工具有很多,方便我们进行分析处理。当然,如果遇到64位的程序,也是可以自己写程序去处理的。

加壳使用默认配置

这也是很多样本或者不了解VMP的人使用时候的常见设置。但实际上VMP强大之处在于它的虚拟功能。保护类型默认是无。

生成的程序,入口是VMP壳的代码,我们首先要找到程序原入口点。对于MSVC2008以上版本编译出来的程序,有一个非常好使的API可以帮助我们快速找到入口点。

这个API就是GetSystemTimeAsFileTime,原理如下:

MSVC高版本编译的程序,入口的特征通常是一个call,一个jmp,我们找入口点,即是找该特征

___security_init_cookie中有一个___get_entropy函数调用,该调用结束后,call返回后就是上面的jmp位置

而GetSystemTimeAsFileTime是在___get_entropy中调用的,我通常还会在QueryPerformanceCounter上下一个断点,这样走完流程后单步几下就到jmp了

我们选择在函数尾部下断点,这是因为VMP有头部断点检测,防止各种幺蛾子妨碍我们分析。

对于反调试我使用的是xjun的插件,如下配置即可

我们执行起来,断点命中

命中后可以看到,返回地址是0xDF9FF9,从内存区域看发现该地址位于.vmp0段,说明还在VMP的壳代码中,并不是我们想要的位于原程序代码中,我们继续执行

第二次命中后,返回地址是0xD880E0,位于.text段,正是我们想要的,因为还断了QueryPerformanceCounter,使用同样的方法,等到返回地址位于.text段时我们再单步跟踪

经过几次单步,来到一个jmp,上方是一个call,此处即是程序原入口点了,我们将入口点设置到call上面

下一步进行IAT修复,使用github开源工具vmp3-import-fix,使用方法很简单,到达入口点后,命令行参数是进程ID即可完成IAT获取

该工具的日志输出中可以看到结果

我们跳到这些地址也可以看到API被标注了

第一步修复完成,我们使用x64dbg自带的scylla进行dump,imports窗口中的无效项可以删除掉

然后使用UIF工具进行IAT重建

查看之前dump的文件,是否有重定位项,有的话去除掉

然后使用IF对dump文件进行修复,选择.text段,入口点是7AFC

获取Imports后,记得勾选新增区段,选择fix dump对上面的dump进行修复

修复后的程序名为Winobj.vmp_dump_IF.exe,我们用IDA打开,就可以愉快的进行分析了。