摘要
Winzip是大家都很熟悉的压缩解压工具,装机必备工具。Winzip是个免费的共享软件,不注册也一样使用,只是会出现一个未注册的画面而已。它对注册码的保护并不复杂,破解这个软件也是相对简单的。
程序名 :Winzip
版本 :V8.0(3105)
大小 :1,230KB
运行平台:Windows 95/98/NT/2000
保护方式:注册码
破解方式:制作注册补丁?
1??????? 破解的准备工作
(1)??? 安装好SoftICE,并进入Windows。通过CTRL+D来检查SoftICE是否可用。
(2)??? 加载符号表,可以采用两种方式:一是在当前情况下,使用Symbol Loader动态加载,另一种是修改Windows目录下的Winice.dat文件,删除usr32.dll前面的“exp=”。
2??????? 监测软件的代码
2.1????? 设置断点
(1)?? Windows通过user32.dll库的四个API函数来获取用户输入文本,它们是GetWindowText,GetWindowTextA,GetDlgItemText,GetDlgItemTextA。
(2)?? 前面已经加载了user32.dll,可以使用exp getwindowtext来查看GetWindowText这个符号是否已经加载,其余仿此。如果没有加载,请参考1.(2)加载。
(3)?? 为(1)所列的四个函数设置断点,方法是bpx GetWindowText……
(4)?? 设置完四个断点以后用bl命令确认一下。
(5)?? 使用bd *命令暂时禁用所有的断点
2.2????? 中断注册过程
(1)??? 安装运行Winzip,在主接口中选择”Help”下面的” Enter Registration Code…”,输入用户名”FeiZhaoDong”,注册码”Bingo”。
(2)??? 按CTRL+D呼出SoftICE,使用be *命令启用所有的断点。
(3)??? 按F5回到WinZip注册接口,按下”OK”按钮,程序很快被中断在”GetDlgItemTextA”的位置。按F11继续,可以看到又中断在”GetDlgItemTextA”一次。这样我们可以猜测,Winzip是使用了GetDlgItemTextA这个函数来获取用户名和注册码。
(4)??? 使用bc命令清除掉GetDlgItemTextA以外的三个断点。
(5)??? 重新输入用户名和注册码(同上),准备进行正式的拆解过程。
2.3????? 分析注册码的验证过程
(1)??? 按下”OK”按钮,程序停留在GetDlgItemTextA的入口,按F11跳出这个函数,这样可以看到以下的汇编代码:
?
0167:00407F6D CALL [USER32!GetDlgItemTextA]
0167:00407F73 PUSH EDI ;程序停留在这里,EDI指向”FeiZhaoDoing”
0167:00407F74 CALL 0043F89A
0167:00407F79 PUSH EDI
0167:00407F7A CALL 0043F8C3
0167:00407F7F POP ECX
0167:00407F80 MOV ESI, 0048CDA4
0167:00407F85 POP ECX
0167:00407F86 PUSH 0B
0167:00407F88 PUSH ESI
0167:00407F89 PUSH 00000C81
0167:00407F8E PUSH EBX
0167:00407F8F CALL [USER32!GetDlgItemTextA]
0167:00407F95 PUSH ESI ;ESI指向”Bingo”
?
按下F11之后程序停留在上面标志的语句,用d EDI命令可以看待,EDI中地址的内容是用户名。按F10一步步走下来,不远处是另一个GetDlgItemTextA,按F10跟进去, 然后按F11跳出来,可以用b ESI看到ESI指向注册码。
这样我们已经证明了前面的判断是正确的,Winzip是使用了GetDlgItemTextA这个函数来获取用户名和注册码。
?
(2)??? Winzip已经得到了它想要的用户名和注册码,接下来应该是验证过程了。按F10接着走,我们看到以下一段代码:
?
0167:00407F96 CALL 0043F89A
0167:00407F9B PUSH ESI
0167:00407F9C CALL 0043F8C3
0167:00407FA1 CMP BYTE PTR [0048CD78],00 ;[0048CD78]指向“FeiZhaoDong”
0167:00407FA8 POP ECX
0167:00407FA9 POP ECX
0167:00407FAA JZ 00408005
0167:00407FAC CMP BYTE PTR [0048CDA4],00 ;[0048CDA4]指向“Bingo”
0167:00407FB3 JZ 00408005
0167:00407FB5 CALL 00407905
0167:00407FBA TEST EAX,EAX
0167:00407FC3 JZ 00408005
?
注意样的两部分代码
0167:00407FA1 CMP BYTE PTR [0048CD78],00 ;[0048CD78]指向“FeiZhaoDong”
……
0167:00407FAA JZ 00408005
0167:00407FAC CMP BYTE PTR [0048CDA4],00 ;[0048CDA4]指向“Bingo”
……
0167:00407FB3 JZ 00408005
熟悉汇编语言的人都能很容易的看出这是在判断字符串是否为空。Winzip在判断出字符串为空以后跳转到[00408005],那个地方估计就是弹出注册失败对话框的地方。再走下去,可以看到:
0167:00407FB5 CALL 00407905
0167:00407FBA TEST EAX,EAX
0167:00407FC3 JZ 00408005 ;注意这里的跳转
Winzip在调用了[00407905]以后,判断EAX是否为0,如果是则跳转到[00408005]。
多幺熟悉的[00408005]!
跟着走下去到了[00408005],按着F10很快注册失败的消息框就弹出来了。这样证明了前面的判断,[00408005]就是弹出注册失败对话框的地方。
?
(3)??? 程序看到这里已经没有悬念了,[00407905]的调用就是判断注册码是否正确的过程,如果正确,那幺返回EAX为非0值,否则返回0,注册也就失败了。
2.4????? 深入注册码计算过程
(1)??? 我们的目的是让这个验证注册码的过程永远返回1这个代表正确的值,因此有必要进入到[00407905]里面去看看,按F10一步步走下去,同时监控ESI、ECX和EAX指向的内容,务必找到最后一次更改EAX值的地方!
(2)??? 看着看着有了意外的收获:
0167:00407AA9 PUSH ESI ? ;ESI指向输入的注册码“Bingo”
0167:00407AAA PUSH EAX ?? ;EAX指向正确的注册码“3E41159C”
……
0167:00407AD2 PUSH ESI ;ESI指向输入的注册码“Bingo”
0167:00407AD3 PUSH EAX ;EAX指向正确的注册码“65293585”
?
其实到这里我们已经可以利用给出的正确注册码注册成功了,不过目标还是没有达到。
?
(3) 按F10走了好久好久(有多久?你试试好了^_^),终于看到了下面的代码:
0167:00407B3A? MOV EAX ,[0048FDC] ;最后一次更改EAX的值,这里是0
……
0167:00407B46? RET
接着走下去,验证过程就结束了,返回以后很快就弹出注册失败的消息框了。我们已经找到了最后一次更改EAX值的地方,接下去就是修改汇编代码了。
?
2.5????? 小结
通过上面的跟踪过程,我们可以看出:
(1)??????? Winzip对验证过程的保护的确是很弱的,我们很容易就能找到验证是否成功的标志;
(2)??????? 要注意调用API之后的第一个PUSH指令,这往往是重要的数据和标志;
(3)??????? 要注意判空代码,其后面的跳转往往是很重要的标志。
好了,下面让我们去直接修改程序的二进制代码吧。
3??????? 制作注册补丁
3.1????? 修改内存中的代码
(1)??? 先修改内存中的代码试试,目的是让验证过程永远返回1值。
(2)??? 0167:00407B3A? MOV EAX ,[0048FDC]这个代码是关键,考虑到MOV这个指令有立即数赋值的功能,试着这样改:
0167:00407B3A? MOV EAX ,1
(3)??? 让程序停在[00407B3A],使用a命令,按上述方法修改代码,然后按Esc退出修改模式。
(4)??? 用bd *禁用所有断点。
(5)??? 按F5接着执行程序,哈哈,注册成功的消息框弹出来了。选择Retry再试一次,仍然可以注册成功。
3.2????? 制作注册补丁
(1)??? 最后,直接修改exe文件来制作注册补丁。重复3.1的过程,当走到[00407B3A]的时候,不要直接修改,先看看这个指令的二进制代码,使用d 407B3A命令,可以看到以下内容:
00407B3A: A1 DC 9F 48 00 83……
(2)??? 如3.1所述修改汇编代码以后,再使用d 407B3A命令,可以看到以下内容:
00407B3A: B8 01 00 00 00 83……
(3)??? 关闭Winzip,使用WinHEX打开Winzip32.exe文件,直接寻找十六进制串A1 DC 9F 48 00 83,找到以后修改为B8 01 00 00 00 83,关闭文件,OK!大功告成。储存修改过的Winzip32.exe文件,这就是我们要的补丁。
4??????? 补丁效果
重新安装Winzip,然后用补丁文件替换原来的Winzip32.exe文件,打开注册接口,输入用户名”FeiZhaoDong”,注册码”Bingo”,然后按”OK”,注册成功。重启Winzip以后可以在”help”里面看到注册信息。如附图。
5??????? 结论
通过这次破解的过程,我熟悉了SoftICE的使用方法,作为一种优秀的调试工具,SoftICE必然在将来的工作中有广泛的应用。另外,还了解了软件注册码保护和破解补丁制作的基本原理。
中国好的的加密解秘网站是看雪学院,里有很多加密解秘的相关资料,部分不是免费的,可以参阅。直接在浏览器中输入”看雪学苑”即可。
参考资料:
(1)??? 拆解教程,看雪学院
(2)??? SoftICE使用手册?
?
(图略)
?
费照东