〖软件名称〗极品私人密盘Build 050915
〖运行平台〗XP
〖下载地址〗http://www.sharebank.com.cn/soft/soft_view.php?id=12934
〖软件功能〗在硬盘上建立一个密盘,大小可以调整,将私人需要保密的文件存入密盘。当密盘关闭时,程序会自动将密盘中的文件加密,无密码者无法对密盘进行访问,杀毒程序也无法访问,方便又安全。有了密盘你的HGame和武藤兰就不会给你带来麻烦咯!呵呵。
〖破解目标〗该软件此前已被暴破过但不彻底,双击密盘时仍然有注册界面跳出。目标找出算法,写注册机。
〖破解声明〗业余爱好,无商业企图。
破解过程:
一、第一次亲密接触:
软件无壳,编程语言Borland Delphi 6.0 - 7.0
软件主界面上方Title显示“极品私人密盘Build 050915(未注册)”字样。
如果不注册,可以试用30次,试用次数达到25次开始提示剩余的次数,达到30次就不给用了,卸载重安装也不能继续试用。
注册与硬盘序列号有关,一机一码。
注册码错误不报错,重启校验。
二、关于试用次数:
用注册表工具比对运行前后发现――HKEY_LOCAL_MACHINE\software\class\.panz这个键值里放的是试用次数。
试用次数满了之后,我改过这个键值,又可以继续试用了,至于有无其他影响就不知道了,反正破解的目标不是“继续试用”。
三、填写注册码后的部分:
工具:OD
1、OD载入,运行程序。
2、打开注册界面,有两个编辑框“机器码”和“注册码”,两个按钮“确定”“返回”。
3、填入87878787,回OD,暂停,显示窗口(W图标),找到输入注册码对话框的控件“确定”,设置WM_LBUTTONUP消息断点。
注:刚开始学习还不知道更好的断点方法,因为该软件不for 98,所以TRW搞不了,hmemcpy也就用不上;曾看过一篇文章,是说明Delphi写的程序,对GetDlgItemTextA之类的断点都免疫的原因,这次也不例外,断不下来。最后决定用WM_LBUTTONUP。
4、继续,设置好断点,运行,回到输入注册码对话框点确定,程序断下,跟踪一段回到程序领空(过程冗长省略)。
5、分析代码(摘录)
004AA79D . E8 2ABCFAFF call 004563CC------------------取机器码"WD-WMAJ71258689"
004AA7A2 . 837D F4 00 cmp dword ptr [ebp-C], 0------比较是否为空
004AA7A6 . 74 17 je short 004AA7BF------------是就跳死
004AA7A8 . 8D55 F0 lea edx, [ebp-10]
004AA7AB . 8B45 FC mov eax, [ebp-4]
004AA7AE . 8B80 FC020000 mov eax, [eax+2FC]
004AA7B4 . E8 13BCFAFF call 004563CC------------------取试码"87878787"
004AA7B9 . 837D F0 00 cmp dword ptr [ebp-10], 0-----是否为空
004AA7BD . 75 14 jnz short 004AA7D3------------不跳就死
004AA7BF > B8 78A94A00 mov eax, 004AA978
004AA7C4 . E8 2770F8FF call 004317F0
004AA7C9 . E8 5E98F5FF call 0040402C
004AA7CE . E9 56010000 jmp 004AA929
004AA7D3 > 8D45 F8 lea eax, [ebp-8]--------------跳转到这里
004AA7D6 . 50 push eax
004AA7D7 . 8D55 EC lea edx, [ebp-14]
004AA7DA . 8B45 FC mov eax, [ebp-4]
004AA7DD . 8B80 FC020000 mov eax, [eax+2FC]
004AA7E3 . E8 E4BBFAFF call 004563CC
004AA7E8 . 8B45 EC mov eax, [ebp-14]-------------试码放入EAX
004AA7EB . B9 06000000 mov ecx, 6
004AA7F0 . BA 01000000 mov edx, 1
004AA7F5 . E8 6AA2F5FF call 00404A64------------------取试码前6位
004AA7FA . 33C0 xor eax, eax
004AA7FC . 55 push ebp
004AA7FD . 68 BAA84A00 push 004AA8BA
004AA802 . 64:FF30 push dword ptr fs:[eax]
004AA805 . 64:8920 mov fs:[eax], esp
004AA808 . 8B45 F8 mov eax, [ebp-8]---------------前6位放入EAX
004AA80B . E8 B8E3F5FF call 00408BC8-------------------前6位通过算法一得出一个临时数放入EAX
004AA810 . B9 03000000 mov ecx, 3
004AA815 . 99 cdq
004AA816 . F7F9 idiv ecx------------------------EAX中的数除3取商
004AA818 . 8D55 E8 lea edx, [ebp-18]
004AA81B . E8 6CE2F5FF call 00408A8C-------------------EAX中的数通过算法二换算成一个“变形码”
004AA820 . 8B45 E8 mov eax, [ebp-18]
004AA823 . E8 74FCFFFF call 004AA49C-------------------将变形码通过算法三转换成一个12位字串与"66FFMJRXJELR"比较
004AA828 . 84C0 test al, al
004AA82A 74 62 je short 004AA88E
看到这里,有必要把算法一和算法二做一下交代:
算法一:
基数 乘数 对应位数 得数
0 * A + 8 = 8 --------将得数作为下一次的基数
8 * A + 7 = 57
57 * A + 8 = 36E
36E * A + 7 = 2253
2253 * A + 8 = 15746
15746 * A + 7 = D68C3------这个临时数在4AA816时被除以3,EAX的值成为47841
算法一在004AA80B行 call 00408BC8----代码冗长,不贴出来了。
算法二:
基数 被除数 商 余数
47841 / A = 726C 9------------将商作为下一次的基数
726C / A = B71 2
B71 / A = 124 9
124 / A = 1D 2
1D / A = 2 9
2 / A = 0 2------------"292929"就是我的试码前6位转换成的变形码
算法二在004AA81B行 call 00408A8C----代码冗长,不贴了。
至于算法三就是把变形码的每一位取出来通过两次运算,得出两个字符,然后连在一起就成了12位的字符串。
"292929"得出的字符串是"77JJFCTZGBRX",显然和"66FFMJRXJELR"不同,接下来就是al=0,判断之后跳走,程序弹出MessageBox"感谢您的注册,请重启本软件"。
由4AA823处的call跟进,至4AA4E0处,该处的call 404804里就是算法三,有兴趣的朋友可以跟进去看一下。
当然重启后依然是未注册版本,但是既然看懂了代码,那么就逆推出正确的前6位吧。
算法三逆推:
"66FFMJRXJELR"逆推出的变形码是"159753"
算法二逆推:
基数 乘数 变形码 得数
0 * A + 1 = 1
1 * A + 5 = F
F * A + 9 = 9F
9F * A + 7 = 63D
63D * A + 5 = 3E67
3E67 * A + 3 = 27009---------27009*3=7501B这个就是正确的临时数
算法一逆推:
基数 被除数 商 余数
7501B / A = BB35 9
BB35 / A = 12B8 5
12B8 / A = 1DF 2
1DF / A = 2F 9
2F / A = 4 7
4 / A = 0 4------------"479259"就是注册码正确的前6位
用"47925987878787"这个假码试一次。
当004AA823处的 call 004AA49C比较过两个12位字符串之后,如果相同,程序在system32下的driveset.dll写入如下内容:
[edia]
t=25
zcm=47925987878787
jqm=WD-WMAJ71258689
呵呵 假码和机器码都写在这里备用了。
接下来,程序弹出MessageBox“感谢您的注册,请重启本软件”。
既然前6位是固定的,而且机器码也没有用到,那就不可能这么简单啦,果然重启后依然是未注册版本。还好我有预见性,一点都没有失望,欲将剩勇追穷寇!
四、重启校验部分
OD加载后程序停在4B56B4
这次我用的断点是bpx GetSystemDirectoryA,改断点有两处4B2294和4B25F9
F9运行,OD断下,一路F8步过,可以看到程序取得了路径"d:\windows\system32"和文件"driveset.dll"
接下来的代码摘录如下:
004B2331 . B9 442A4B00 mov ecx, 004B2A44 ; ASCII "zcm"
004B2336 . BA 502A4B00 mov edx, 004B2A50 ; ASCII "edia"
004B233B . 8B30 mov esi, [eax]
004B233D . FF16 call [esi] ;取得机器码"WD-WMAJ71258689"
004B233F . 6A 00 push 0
004B2341 . 8D45 A4 lea eax, [ebp-5C]
004B2344 . 50 push eax
004B2345 . 8B45 FC mov eax, [ebp-4]
004B2348 . 8B80 AC040000 mov eax, [eax+4AC]
004B234E . B9 602A4B00 mov ecx, 004B2A60 ; ASCII "jqm"
004B2353 . BA 502A4B00 mov edx, 004B2A50 ; ASCII "edia"
004B2358 . 8B30 mov esi, [eax]
004B235A . FF16 call [esi] ;取得试验码"47925987878787"
......
004B23B3 . 8BC8 mov ecx, eax ;ECX=实验码长度
004B23B5 . 83E9 0A sub ecx, 0A
004B23B8 . BA 0B000000 mov edx, 0B
......
004B2402 . 8B80 A4040000 mov eax, [eax+4A4] ;实验码7-10位"8787"
004B2408 . E8 BB67F5FF call 00408BC8 ;和前面的算法一一样,计算出一个临时数
004B240D . B9 03000000 mov ecx, 3
004B2412 . 99 cdq
004B2413 . F7F9 idiv ecx ;临时数字除3
004B2415 . 8D55 9C lea edx, [ebp-64]
004B2418 . E8 6F66F5FF call 00408A8C ;转换出一个变形码
004B241D . 8B45 9C mov eax, [ebp-64]
004B2420 . E8 E7EAFFFF call 004B0F0C ;不同的是这里,只验证中间四位是否为整型数字
004B2425 . 84C0 test al, al
004B2427 > 837D D4 1D cmp dword ptr [ebp-2C], 1D
004B242B . 0F8E 9D000000 jle 004B24CE ;跳死
004B2431 . 8B45 FC mov eax, [ebp-4]
004B2434 . 8B80 A0040000 mov eax, [eax+4A0] ;再一次取前6位
004B243A . E8 8967F5FF call 00408BC8 ;算法一,计算临时数字
004B243F . B9 03000000 mov ecx, 3
004B2444 . 99 cdq
004B2445 . F7F9 idiv ecx ;临时数除3
004B2447 . 8D55 98 lea edx, [ebp-68]
004B244A . E8 3D66F5FF call 00408A8C ;计算变形码
004B244F . 8B45 98 mov eax, [ebp-68]
004B2452 . E8 DDE7FFFF call 004B0C34 ;比较字串"66FFMJRXJELR"
004B2457 . 84C0 test al, al
004B2459 . 74 73 je short 004B24CE
004B245B . 8D55 94 lea edx, [ebp-6C]
004B245E . 8B45 FC mov eax, [ebp-4]
004B2461 . 8B80 60040000 mov eax, [eax+460] ;EAX=机器码"WD-WMAJ71258689"终于用到了
004B2467 . E8 78E6FFFF call 004B0AE4 ;机器码变形
004B246C . 8B45 94 mov eax, [ebp-6C]
004B246F . 8B55 FC mov edx, [ebp-4]
004B2472 . 8B92 A8040000 mov edx, [edx+4A8]
004B2478 . E8 D324F5FF call 00404950 ;实验码第11位开始到最后与机器变形码比较
004B247D . 74 36 je short 004B24B5
关于7-10位的计算方法完全和前6位一样,但是却没有用到计算出来的值,我很迷惑,4B2420处的处理是检验这四位是否为数字,如果是字母、符号或者其他什么就报错,并且判定注册失败。有兴趣的朋友请跟进去看一看,如果不是这样请一定跟贴告诉我,谢谢。
4B2467处的CALL是对机器码进行了变形处理,由于代码冗长而且算法平淡,就不详述了。
方法是将机器码每一位的ASCII加1:例如我的机器吗"WD-WMAJ71258689"会成为这样――"XE.XNBK8236979:",然后把这个变形码中的1、3、5、7这四数字替代掉:
1------I
3------M
5------Q
7------N
我机器码的最后形态为"XE.XNBK82M69N9:"
五、最后总结:
注册码的组成分三个部分:
前6位(固定) 中4位(数字) 后N位
479259 0000 XE.XNBK82M69N9:
1、填写注册码后,程序对前六位进行验算,如果正确,就把这个注册码和机器码一起写入文件driveset.dll
2、验算中间四位是否为数字
3、后N位与变形机器码进行比较,相同就注册成功。
另:由于注册码分段校验,爆破的难度自然也就大了,这个软件已经出新版本了,注册码的计算方法也进行了改进,不过有趣的是如果注册了build 050915版后再安装新版本,新版本也承认我是注册用户。
这是第二篇破文,谢谢关注。
[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!