爆破 Hide Window Hotkey 2.5
–脱壳,去自校验,破解
在游荡了一年之如果不出意外可能下个周一就去上班了,这一年经历了太多太多,不知道该怎么说,到了现在内心充满了痛苦和无奈。现实 一次次的把我逼到了绝境,面对的是一次次的失败。我说不出内心的那种感觉。开始说了这些废话只是想发泄下,内心很痛苦。如果文章发表了,编辑感觉这段文字太多余那就删除吧。
下面开始我们的正题吧,目标程序:Hide Window Hotkey 2.5。
一:脱壳
用Peid查壳:ASPack 2.12 -> Alexey Solodovnikov如图01。
这是一个压缩壳,用ESP定律脱掉就可以了。直接用OD载入。OD会提示是否继续分析代码,选择否,如图02所示。
OD会中断在程序入口点。单步F8一次,在寄存器窗口中选中ESP,右键数据窗口中跟随。选中数据窗口的前四个字节,下硬件访问断点(Word),具体操作见图03。
F9运行程序,OD会中断在下面的代码处:
005A03B0 /75 08 jnz short HideWind.005A03BA
005A03B2 |B8 01000000 mov eax,1
005A03B7 |C2 0C00 retn 0C
005A03BA \68 88B04C00 push HideWind.004CB088
此时删除所有硬件断点,图04,F8单步往下走,走过Retn后就到了程序入口点了,如图05。此时就可以用LordPe脱壳了,运行LordPe选中要脱壳的进程,右键Dump Full,将内存镜像保存到磁盘,如图06。下面来修复IAT,运行Import REC,在OEP处填入程序的入口点偏移,此处为CB088,关于程序的OEP可以用OD的脱壳插件得到,运行插件中的Olly Dump就可以得到程序的OEP了,此处为用EIP修正OEP,也就是CB088,如图07所示。将得到的值填入Import Rec的OEP中,点击IAT Auto Search(自动搜索IAT),然后点获取输入表。得到输入表后删除无效的指针,这里的数据都是有效的就不操作了,最后来修复脱壳的文件。点修复抓取的文件,选择刚才抓取的Dump.exe进行修复,如图08所示。这样脱壳修复就完成了。下面进行第二步去自校验。
图04
图05
图06
图07
图08
二:去自校验
脱壳后的程序双击运行鼠标一闪就消失了,这个不是脱壳的问题。由于程序的自校验,在程序在检测到被修改之后运行就自动退出了。
用OD载入脱壳修复后的程序dumped_.exe,程序退出会调用ExitProcess这个系统API函数,那么就对这个函数下断。在od的反汇编窗口中,右键搜索->所有模块间的调用,如图09,就可以打开系统API的调用列表了。找到ExitProcess函数,对函数下F2断点,F9运行程序。程序会中断在如下行:
图09
004C4B8B |. 3D 20A10700 cmp eax,7A120
004C4B90 |. 7E 15 jle short dumped_.004C4BA7
004C4B92 |. 8D85 ACFEFFFF lea eax,dword ptr ss:[ebp-154]
004C4B98 |. E8 3FE3F3FF call dumped_.00402EDC
004C4B9D |. E8 62DDF3FF call dumped_.00402904
004C4BA2 |. E8 49F9F3FF call dumped_.004044F0
由上面的jle跳转可以知道,要想不让程序退出只需要让004C4B90行的跳转实现就可以了,通过对上面的代码跟踪分析可以得知这个是对文件大小的校验,对比一下脱壳后的文件与原文件的大小就可以知道了,如图10,我们脱壳后程序大小已经超过了1M,而没有脱壳的程序只有不到500K。当文件大小超过7A120(十六进制)时程序会自动退出。这个地方的修改可以将jle修改为jmp,也可以将7A120修改成一个大得多的数值,只要比脱壳后的文件大小值大就可以了。这里修改成0FFFFFFF,修改004C4B8B行为 cmp eax,0FFFFFFF (这里需要注意下,不能修改为FFFFFFFF。因为十六进制数据如果是字母开头的,前面第一个字符必须为零,否则在OD中会报错),保存修改后的文件为“去掉自校验.exe”。现在程序可以正常运行了。下面开始最后一步–对程序的爆破。
图10
图11
三:程序破解
用OD载入去掉自校验的程序,直接F9运行。在出现要求注册窗口之后点OD的暂停暂停按钮,也就是键盘上的F12。然后打开堆栈调用窗口,快捷键Ctrl+k,如图12。双击第二行跟入到汇编窗口,找到程序段头,在代码头下F2断点,如图13。
图12
图13
重新载入程序,F9直接运行。注意观察堆栈窗口,OD中断后在堆栈窗口的第一行,右键->在反汇编窗口中跟随,来到调用这段子程序的代码处,找到这一段的程序段头,下F2断点,这时删除上次设置的断点。设置好断点后重新载入程序,如此重复进行。直到在反汇编窗口中跟随出现如下的代码:
004C51AA |. E8 5DF8F3FF call 去除自校.00404A0C ;程序关键Call
004C51AF |. 75 1C jnz short 去除自校.004C51CD ;关键跳
004C51B1 |. 33D2 xor edx,edx
004C51B3 |. 8B83 A8030000 mov eax,dword ptr ds:[ebx+3A8]
004C51B9 |. E8 BA40FAFF call 去除自校.00469278
004C51BE |. 33D2 xor edx,edx
004C51C0 |. 8B83 A4030000 mov eax,dword ptr ds:[ebx+3A4]
这里简单的说下这么操作的原理:程序都是一层层调用的,要想知道到底是如何调用这个子程序的必须要返回到主程序的领空。OD在每次中断后堆栈窗口都会记录程序的调用来源,在子程序执行完毕后会返回到主程序,这也就是堆栈窗口的第一行是放回到某一个地址的原理了。另外主程序在调用子程序的时候必然会经过一次判断,可能是用户的操作,也可能是其他的一些操作比如注册验证等,主程序会对用户或者其他的操作做出不同的反应。这个实例就是根据注册码的正确错误进行调用子程序,如果注册码错误则调用注册对话框,如果注册码正确则调用主程序的主窗体。这就是我们一层一层循环往回找的原因了。在明白这个原理之后程序的修改也就简单了,只需要跳过注册窗口就行了,直接调用程序的主窗口。这就是下面进行的修改的原理。
在程序段开始处下F2断点,重新载入程序。对这段程序进行反复跟踪可以发现程序的关键跳在004C51AF这一行,如果这行跳转了就会出现程序注册窗口。程序的关键Call也就是上面的004C51AA 行的这个Call了。如果想爆破程序,不出现注册窗口只需要让这个跳转失效就可以了。最简单的修改方法也就是把004C51AF这一行直接Nop掉。把这行Nop掉后保存修改的程序,重新运行下看看。
运行修改后的“Crack.exe”可以发现要求注册的窗口消失了,并且程序菜单中的注册也没有了,对比如下图15为爆破后的程序界面,图16为没有注册的程序界面。
图14
图15
后记:对这个程序的爆破费了很多周折,从网上也没找到相关的资料。网上只有这个东西的序列号,没有破解版的。程序的相关注册信息是保存在注册表中的,如图17所示。对于软件的爆破也想了很多不同的办法。程序读取注册表用的API函数是RegQueryValueExA,而软件对于这个函数的调用是很多的,下断之后不容易分析,跟踪多次没有发现关键的地方。可能是自己水平不够吧,在注册的时候虽然有错误提示但是却没有跟踪到注册码。另外需要说明下,就算吧Message对话框爆破了使程序注册成功,程序在重新启动的时候还是会进行验证。也就是说通过对注册对话框的爆破是无效的。虽然这么一个小程序安全性却做的相当不错,虽然壳的强度不大,但是程序的自校验破除需要一定的基础。另外程序的注册爆破由于内存中没有明文比较,在爆破上也增加了一定的难度。程序的重启验证则是爆破程序的最大障碍,整体而言软件的安全做的还是不错的。另外如果有人追到了注册码欢迎和我交流,好了文章就到这里,有什么问题欢迎到论坛和我交流。
声明:本文已经发表于《黑客手册》2009第十期,未经本人允许严禁任何性质的转载!