花差花差

像写情书一样写代码

费照东ID:fzd999
164672次访问,排名449好友3人,关注者32
物格而后知致,知致而后身修~
fzd999的文章
原创 46 篇
翻译 0 篇
转载 0 篇
评论 769 篇
花差花差的公告

这里全部是我的原创,一点一滴积累下来的文字。
闲时,总喜欢把玩自己写的小玩艺,细细读网友的评论,然后再看一遍。
如果你是我的朋友,很开心你能来这里做客,如果你是匆匆过客,也希望小坐一会儿,留下几字评论。

最近评论
zhaowanru19:你来上海了。。。
我都不知道。。。
呵呵。。。
最近工作怎样?
忙不。。。

lyai007:要跟你做個朋友不知道可不可以
gongmingwind:思考中!
carren1218:很伤感。。。
fzd999:楼上是???
文章分类
收藏
    相册
    值得纪念的一切
    我的朋友们
    ee——左边风景
    团团的饭团
    大东——东大传说
    大雨仔
    我们的婉如同学
    我心如水
    流风轩主——颜鹏
    默默——心绪缥缈
    友情链接
    Dicky'Blog
    sugi的暗黑木屋
    南京程序员之家
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 使用SoftICE破解Winzip8.0全攻略收藏

    新一篇: 關於進程殺死問題的研究報告 | 旧一篇: 在VC++中使用斷言

    使用SoftICE破解Winzip8.0全攻略

    摘要

    Winzip是大家都很熟悉的压缩解压工具,装机必备工具。Winzip是个免费的共享软件,不注册也一样使用,只是会出现一个未注册的画面而已。它对注册码的保护并不复杂,破解这个软件也是相对简单的。

    程序名 :Winzip

    版本   V8.03105

    大小   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函数来获取用户输入文本,它们是GetWindowTextGetWindowTextAGetDlgItemTextGetDlgItemTextA

    (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一步步走下去,同时监控ESIECXEAX指向的内容,务必找到最后一次更改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