http://www.52pojie.cn/thread-56725-1-1.html 发表于 2010-8-9 22:10:49
ximo兄在《庆祝A-new苏醒系列之一--简单的VM保护程序的爆破分析》一文中介绍了如何Patch e_flag来对vmp进行爆破,文章写得通俗易懂,适合入门。相信有不少同学都跟我一样好奇,ximo是如何调试到那个地方的。通过一晚上的调试,我想和各位分享一下我的心得,如有错漏,忘不吝赐教。
另外,建议大家参考一下aa1ss2大牛所著的《VMProtect 逆向分析》。认真读一遍,收获会不小的。1、记录Handlers
既然要分析VM,应该记录一下有哪些操作,所以记录Handler是十分必要的。vmp有个Dispatch,通过 解密EIP(esi)来确定应该执行啥指令,然后根据DispatchTable跳转过去执行。通常,Dispatch的最后是一个push [esp + xxx]接上一个retn 0xXX,而ecx或者edx中保存的是handler的地址。所以,我们可以在这里将程序断下来,记录handler,以便于分析VM。
之前我试过用脚本记录,但会严重影响程序的效率,所以这次我写了一个dll,在Dispatch结束的时候,跳转到dll的代码中,将handler记录下来。dll的代码很简单,就是写文件而已,大家都会写。
在ximo的那个程序中,Dispatch是这样的:
- 0040C47E FF7424 2C push dword ptr [esp+0x2C]
- 0040C482 C2 3000 retn 0x30
通过观察,当执行到0040C47E的时候,ecx中的值即是Handler,所以Patch 0040C47E处的代码,让其跳转到一块空间,然在那里把ecx的值传递给dll,dll负责记录。这样跑一遍,Handler基本就可以记录完了。
2,分析Handlers
知道了有哪些操作,下一步就是要知道他们是干嘛的。其实这个和反汇编是一个道理,通常是调试器帮你把代码反汇编好,然后等着你去理解。现在也差不多,是该理解一下了。
分析Handlers是体力活。看了一下记录,有4519行,也就是说这个过程执行了4519条Handlers。接下来就是人肉了,在OD中转到对应的Handler的地址,观察其功能,然后利用记事本的替换功能,把Handler对应的指令注释上去。
注释完大概会得到这样的结果:
- 0040CCF8 GetI32
- 0040D672 GetR32
- 0040CCF8 GetI32
- 0040DA5A GetESP
- 0040CE9C GetI8
- 0040D74B Add32
- 0040C1EE SetR32
- 0040D271 WmSs32
- 0040C1EE SetR32
- 0040D74B Add32
- 0040C1EE SetR32
- 0040D125 nor32
- 0040C1EE SetR32
- 0040D672 GetR32
- 0040DA5A GetESP
- 0040D37F RmSs32
- 0040D125 nor32
- 0040C1EE SetR32
- 0040CCF8 GetI32
当然,这里只是一小部分而已。还有很多,等下一起上传了,欢迎批评指正。
这里说一点废话,识别Handler,我目前还是使用肉眼,之前调试过很多次,对VMP有了一定的了解,还算比较容易。如果大家想偷懒,建议大家去Upk找Nooby在某个回复里面发的一个记事本,里面有一个记事本和完整的VM记录,看样子是OD插件生成的。大家可以使用那个记录来看看Handler是啥样的。具体哪个帖子我忘记了……大牛们都有自动化插件了,我等菜鸟还在人肉,差距啊。
3,分析程序
从Handlers到程序的差距还是挺大的。由于之前调试过vmp,知道vmp在进行比较的时候会使用NOR32指令,所以需要在NOR32下段并进行观察。
当前的NOR32是这样的:
- 0040D125 10CC adc ah, cl
- 0040D127 66:0D DC76 or ax, 0x76DC
- 0040D12B 8B45 00 mov eax, dword ptr [ebp]
- 0040D12E 66:0FABF2 bts dx, si
- 0040D132 8B55 04 mov edx, dword ptr [ebp+0x4]
- 0040D135 66:0FBAE4 08 bt sp, 0x8
可以看到分别把两个操作数从vm堆栈装入eax和edx,所以我选择在0040D135下断点,方便观察eax和edx的值。
接下来在控制台中输入43690,选择输入这个的原因是,43690的十六进制形式是AAAA,比较容易观察,以免错过。
在scanf返回后,NOR32中断了17次后,eax的值为AAAA,此时转到Handler记录,F3搜索0040D125,第十七次附近的代码是这样的:
- 0040D672 GetR32
- 0040D125 nor32
- 0040C1EE SetR32
- 0040D74B Add32
- 0040C1EE SetR32
- 0040DA5A GetESP
- 0040D37F RmSs32
F7两条指令,来到0040D74B,也就是Add32指令,指令的核心部分是这样的:
- 0040C592 0145 04 add dword ptr [ebp+0x4], eax
我们此时执行到0040C592的时候,esi等于00410611,[ebp+0x4]会出现明文,也就是2010,经过了Add32的运算,[ebp+0x4]的值如果是-1,即输入的值为2010,不是-1,输入错误。
接下来如何Patch,我就不用说了。
4,结尾
我只分析了一部分,有兴趣的同学可以继续搞,或者提供一种更好的解决方案。
好吧,回头看了一下,觉得我写得好烂。各位拍砖轻一点,谢谢。
exe见ximo的帖子,我上传Handlers的记录好了,记录是从scanf返回开始的。