目标程序:休闲麻将3.4版本
时间:2009.8.18
工具:OLLydbg,peid0.94,lordpe,ImportREC_fix
面向对象:爱好破解的菜鸟朋友们
写在前面的话:
目标程序是妈妈在家无聊时玩的一个麻将游戏,由P-CODE编写,即VB中的伪代码。
用Ollydbg破解这种语言的程序非常的痛苦,有一定破解基础的朋友可以先行用
Ollydbg破解下程序(其他工具破解,参考看雪论坛精华9:休闲麻将P-CODE浅析)。
而我由于刚开始并不知道P-CODE,硬是用Ollydbg花了3天时间来研究它,此中苦乐
非爱好破解的菜鸟朋友无法理解。。。。
第一步:
用peid0.94查壳。ASPack 2.12 用ESP定律手动脱壳。
介于是个简单壳,我就说下自己所理解的ESP定律,手动脱壳过程不再详细描述。
问题:ESP定律下硬件访问断点的原因以及为什么可以到程序的入口?
首先大家应该明白程序要运行必须要在特定的环境下,一些压缩壳为了不破坏环境,
让程序能够正常运行,将这些环境经行了保护,故当程序运行并访问环境时,Ollydbg
帮我们断下来,然后单步走即可到达OEP(程序入口)。。
第二步:
脱壳之后发现程序是Microsoft Visual Basic 5.0 / 6.0编写的。
试运行程序知道为重启验证,然后搜索注册表,发现了之前用户信息。。。
于是下注册表的断点(至于为什么下这个断点是测试出来的!)
bp RegCloseKey
F9运行(不过在这之前请确定用户名跟假码存在于注册表)
同时注意寄存器窗口跟堆栈窗口,然后F9一路狂飙下去,
直到寄存器窗口出现你的假码:
EAX 77DA6BF0 ADVAPI32.RegCloseKey;
ECX 00000035
EDX 0040247C unpack.0040247C
EBX 00165244 UNICODE "1234567890" ;你之前输入的假码
ESP 0012F6E8
EBP 0012F7EC
ESI 0044CC61 unpack.0044CC61
EDI 0012F6F0
EIP 77DA6BF0 ADVAPI32.RegCloseKey
此时F8单步走,到达msvbvm60的领空,哎,也怪我孤陋寡闻竟不知道P-CODE。
害我花了半天时间研究为什么不回到程序的领空。。。。
单步走,因为感觉一直在循环,于是我在刚进入的位置下了断点F2,然后又在
其他两处下了F2断点(又一个偷懒的办法,没办法F8手都按疼了)
733B5434 msvbvm60 始终 CALL DWORD PTR DS:[734A0E7C]
7348F7F3 msvbvm60 始终 CALL EAX
7348F996 msvbvm60 始终 CALL msvbvm60.__vbaStrCat
这些断点我是取“寄存器窗口或堆栈窗口出现重要数据时候”时的位置,大家可以在
第一次单步走的时候注意下然后自己下断点,因为本人接触破解才两个多月,黑鹰
算法分析的教程我还没来得及学,所以没想过搞什么算法,也就不必单步跑下去了。
下好断点后,直接按F9,注意寄存器窗口与堆栈窗口,当堆栈出现停止按F9
0012F718 001501BC UNICODE "2808222223138415"
0012F71C 0000000A
……
0012F748 00000010
0012F74C 001501BC UNICODE "2808222223138415"
0012F750 0000000B
0012F754 00000073
0012F758 001503A4 UNICODE "zjm8888889search"
0012F75C 00000011
为什么这个什么时候停,你一直按着F9,又如何知道这个时候停?
呵呵,大家注意到字符的长度没有,两串字符串长度一样。
在有机器码出现算注册码的程序中,一般注册码跟机器码相同位数,
当然肯定还有另外了,这里说的是一般情况,也就是当字符串相同长度
停下来观看一下比较好,当然这些是因为我们偷懒下好断点按F9的缘故。
F8单步走几步,发现寄存器窗口出现了10位字符串:
EAX 001506F4 UNICODE "2223138415"
我们试运行程序的时候,可以发现注册码为10位,所以这10位字符串应该
引起大家的足够重视。继续F8单步走,在堆栈窗口中发现
0012F7FC 00167454 UNICODE "2223138415"
0012F800 001669C4 UNICODE "0987654321"
我们输入的假码反置于之前得到的10位字符串出现在一起
在下方不远处又发现了
0012F828 00167454 UNICODE "2223138415"
0012F82C 80000002
0012F830 00000000
0012F834 00165244 UNICODE "zjm8888889"
0012F838 001669C4 UNICODE "0987654321"
0012F83C 00165DF4 UNICODE "search"
于是推断注册码为2223138415的反置 5148313222
至于如何推断出来的,大家可以试着去尝试,同时注意我们输入的假码
已经被反置了。哎,当时输入10个1的时候根本没发现被倒置,害我把几个
出现的10位字符串试了又试,而且,继续单步走,后面又会出现几个10位
字符串。因为已经得到注册码了,所以后面也就不继续了。
第三步:
爆破或者做内存注册机尝试了很多次,结果:失败!!!。
最后在仔细研究看雪论坛精华上相关的文章后,摸清楚了这个程序的算法。
但因为编程水平,没能写出算法注册机。下面将领悟到的算法简单阐述下:
休闲麻将3.4版本算法分析:(用户名不小于2位,注册码为10位)
首先输入用户名得到注册字符串
zjm+机器码后7位+用户名(大于7位的取后七位)
第一步:取第一个字符串z的ASCII值/10得到商与余数
第二步:将上一步得到的商加上第二个字符串j的ASCII值除10得到商与余数。
第三步:将上一步得到的商加上第三个字符串m的ASCII值除10得到商与余数。
第四步:将上一步得到的商加上第四个字符串(机器码)的ASCII值除10得到商与余数。
……
第十步:将上一步得到的商加上第十个字符串(机器码)的ASCII值除10得到商与余数。
第十一步:将上一步得到的商加上第十一个字符串(用户名)的ASCII值除10得到商与余数。
……
最后一步:将上一步得到的商加上最后一个个字符串(用户名)的ASCII值除10得到商与余数。
然后将每一步得到余数合在一起,组成一串12位到17位的数据(根据用户名的长短而定)
取后面的10位数字,反置即可得到注册码。实例计算我就不写了,留着给读者自己去实践,这
样也可以让读者对算法多一些理解,能够做到触类旁通,举一反三。
总结:
首先要感谢黑鹰基地的三人行或者称之为天草,感谢你让我进入破解的大门。其次还要感谢看雪
论坛,在我屡次碰壁不得结果差不多想要放弃时,看雪论坛精华9里这篇类似的破解文章出现在我
面前,这个发现使疲惫不堪的我又充满了破解的斗志。因为学习破解的时间不长,根本不知道何
为P-CODE,也不会使用WKTVBDebugger,更别说看懂此文章中出现的那些诡异的代码。并且
由于在追踪注册码的过程中出现过很多类似注册码的假码,使我屡次以为成功却遭失败,我都差点
以为程序是不是出错了,还好通过论坛此文章让我了解到注册码长啥样,为后来寻找真正的注册码提
供了方向。在查找相关资料了解了P-CODE编译的软件后,我明白了为什么每次返回到用户代码都会
落到msvbvm60领空。总的来说,这次破解让我收获颇多,从遇到问题分析问题到解决问题的过程
中,我进一步提升了处理问题的能力,更重要的是激起了学习的兴趣。因此我希望加入看雪论坛这个
大家庭,与更多的破解爱好者交流技术。
[课程]FART 脱壳王!加量不加价!FART作者讲授!