新手求助,被人防守的时候总是害怕结界突破防守阵容

正在加载验证码......
请先拖动验证码到相应位置等级:新手入门
 骷髅: 0 个 soj: ; 信用: 1  宝石: 0 颗 注册: 
【求助】各位战网达人,请问是不是有了无限的法师就能秒杀一切怪物,电免也不怕吗?
【求助】各位战网达人,请问是不是有了无限的法师就能秒杀一切怪物,电免的怪物也不怕吗?
那为什么拿无限的法师都练电系,而不练:冰系呢,冰系掌握是减冰抗的啊,配合无限减抗,那不是更加厉害吗,无敌了?
您目前仅能浏览部分内容,查看全部内容及附件,请先
等级:巴尔
头衔: 没头衔的小兵
昵称: 聪明的笨蛋
帖子: 2363
 骷髅: 0 个 soj: ; 信用: 13  宝石: 0 颗 注册: 
不能,无限破不了电免,只能靠pet打,如果是电免加物免那你就得跑了
上传图片提示“无效的图片文件”打开IE,选择 工具>>internet选项>>安全>>自定义级别 >>
进入安全自定义设置后,找到【 将文件上载到服务器时包含本地目录路径 】,改成“启用”,点确定保存
UID35564&帖子2363&精华&积分5813&soj8890 &阅读权限90&在线时间6873 小时&注册时间&最后登录&
等级:巴尔
头衔: 没头衔的小兵
昵称: 聪明的笨蛋
帖子: 2363
 骷髅: 0 个 soj: ; 信用: 13  宝石: 0 颗 注册: 
地狱里小怪电抗低所以选电法,而冰免和高冰抗怪多,
上传图片提示“无效的图片文件”打开IE,选择 工具>>internet选项>>安全>>自定义级别 >>
进入安全自定义设置后,找到【 将文件上载到服务器时包含本地目录路径 】,改成“启用”,点确定保存
UID35564&帖子2363&精华&积分5813&soj8890 &阅读权限90&在线时间6873 小时&注册时间&最后登录&
等级:都瑞尔
 骷髅: 0 个 soj: ; 信用: 8  宝石: 0 颗 注册: 
无限电法一般用来干嘛?
UID252037&帖子256&精华&积分1033&soj8288 &阅读权限50&性别男&在线时间1538 小时&注册时间&最后登录&
等级:巴尔(物理,魔法,元素攻击全免疫)
头衔: 蛋炒饭
昵称: 老李
帖子: 51081
 骷髅: 0 个 soj: ; 信用: 126  宝石: 0 颗 注册: 
里面有介绍。。
UID186601&帖子51081&精华&积分51884&soj7936 &阅读权限90&性别男&来自河北辛集市&在线时间1354 小时&注册时间&最后登录&
队长兼版主
昵称: 专业捡尸体
帖子: 6382
 骷髅: 5 个 soj: ; 信用: 235  宝石: 0 颗 注册: 
做沙发的不太懂,不要乱说误人子弟!无线能破一定程度的电免!碰到117电抗以上的电免同时又物免的怪,电法才打不动,但是这样的怪物很少很少,碰到的机会很少很少。
无线是12级信念,能破117以下的电免,而一般超过117以上的电免怪物比较少,碰到的概率自然低,所以一般带了小弟无线的电法可以通杀DY了!所以大家都在练电法,除了MF的!
同样无线能破117以下的冰免和火免,但是117以上的冰免和火免的怪物很多,这样的怪物无线破不了,所以冰免和火免的法师一般带无线没用,一般带丧钟来打,打出衰老自身还安全些,扯远了!另外法师的冰系掌握减去冰抗对于冰免是无效的,只有当冰抗低于100以下才起作用!
[ 本帖最后由 ace1228 于
09:07 编辑 ]
等级:巴尔
头衔: 学者
昵称: 维加
帖子: 3473
 骷髅: 0 个 soj: 567  信用: 177  宝石: 0 颗 注册: 
LS说得很正确:anhei3.net-85
无限电法是实用的PVC角色之一,拥有最快的TP速度,强大的清场能力以及良好的操作手感,无论是带PASS,KD,KB,KC都是一把好手,除了安全性略差几乎是最完美的PVC职业
收未辩识黄项链黄戒指黄头环蓝头环
467防御,无ED和耐久的灰幕寿衣
无形5孔,88LV,无ED和耐久的巨战斧
17灵气6双倍260ED的巨长眼光
2NEC技能30高跑20FCR2洞头环
10LL30力量无形安头,IAS火抗猪
UID74867&帖子3473&精华&积分5553&soj567 &阅读权限90&性别男&在线时间3806 小时&注册时间&最后登录&
等级:暗黑破坏神
帖子: 3269
 骷髅: 0 个 soj: 719  信用: 160  宝石: 0 颗 注册: 
对于电法来说,无限只是基本了,要想爽还需要的东西多着呢。-抗起码要凑个50以上,才能对破除电免的怪有力杀伤(ERROR:15) & 访客不能直接访问后使用快捷导航没有帐号?
抱歉,指定的主题不存在或已被删除或正在被审核【转】适合的新手破解教程+练手的各种基础软件(本教程的亮点是练手的软件实战破解) - 『脱壳破解区』
- 吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn
后使用快捷导航没有帐号?
只需一步,快速开始
请完成以下验证码
请完成以下验证码
查看: 51217|回复: 213
【转】适合的新手破解教程+练手的各种基础软件(本教程的亮点是练手的软件实战破解)
阅读权限25
本帖最后由 Jorge 于
14:31 编辑
入门-第一章-前言 好多哥们儿说看教程跟老大的书都看不太明白,所以,我尽量把话说到最容易理解的份上,本文写给那些刚入门和尚未入门的朋友们...
no.1------------------前言(说明一下)
no.2------------------汇编语言
no.3------------------Windows程序
no.4------------------调试器及相关工具入门
no.5------------------破解原理
no.6------------------初级破解实践,强暴一个软件
no.7------------------中级破解实践,找到及写内存
no.8------------------高级破解实践,分析软件算法,编写注册机
常见的修改方法有两种,我给你举例说明:
在某软件中,这样来进行注册:
CALL 00405E02&&(关键CALL,用来判断用户输入的注册码是否正确)
0045123D JZ & &(!!!&--此为关键跳转,如果用户输入的注册码正确,就跳向成功处,即处)
0045XXXX YYYYYYYYYY
XXXXXXXX YYYYYYYYYY
XXXXXXXX YYYYYYYYYY
XXXXXXXX 执行到此处,就提示用户注册失败
...提示用户注册码不正确等相关信息
...&&&--(注册成功处!!!)
...提示用户注册成功等相关信息
呵呵,看明白了吗?没有的话,我来给你讲一下。在软件执行到处的时候,CALL置0045E02处来进行注册码判断。接着回来后就来一个跳转语句,即如果用户输入的注册码正确就跳到处,跳到此处,就算是注册成功了。如果用户输入的注册码不正确的话,那么就不会在 0045123D处进行跳转,而一直执行下去。在下面等它的,是注册失败部分。
想明白了吗?嘿嘿...没错,我们只要把那个关键跳转JZ给改为JNZ(如果用户输入的注册码错误,就注册成功,输入正确则注册失败)。当然你也可以将JNZ修改为Jmp,这样的话,你输入的注册码无论正确与否。都可以注册成功。
我们再来讲一下另外的一种情况:
CALL 00405E02&&(关键CALL,用来判断用户输入的注册码是否正确)
0045123D JNZ & &(!!!&--此为关键跳转,如果用户输入的注册码不正确,就跳向失败处,即处)
0045XXXX YYYYYYYYYY
XXXXXXXX YYYYYYYYYY
XXXXXXXX YYYYYYYYYY
XXXXXXXX 执行到此处,就提示用户注册成功
...提示用户注册成功等相关信息
...&&&--(注册失败处!!!)
...提示用户注册码不正确等相关信息
这次我相信,并且深信不疑。你一定明白了。我还是不明白...倒...
你一定看出跟第一种情况不同的地方了吧。没错!它与第一种不同的,就是第一种情况是如果注册码正确,就跳到注册成功处,如果没有跳走,就会执行到失败处。而这一种情况则是如果注册码不正确,就跳到注册失败处,否则将执行到注册成功处。
这种情况的修改,除了把JNZ改为JZ外,还可以将其改为Nop,Nop这个指令没有任何意义,将该条指令修改为Nop后,便可随意输入注册码来进行注册了。
原理以经给你讲了,下面我们再来讲一下具体的修改办法吧。(我假设你以经明白了我所说的工具的使用方法)
先说一下虚拟地址和偏移量转换的问题,在SoftICE和W32Dasm下显示的地址值是所谓的内存地址(memory offset),或称之为虚拟地址(Virual Address,VA)。而十六进制工具里,如:Hiew、Hex Workshop等显示的地址就是文件地址,称之为偏移量(File offset) 或物理地址(RAWoffset)。
所以当我们要通过那些十六进制工具来对可执行文件中的相应指令进行修改的话,先要找到它的Fileoffset。我们没有必要去使用那些专门的转换工具,在W32Dasm中就有这个功能,比如说你W32Dasm中来到0045123D处,在 W32Dasm界面下方的状态栏中就会出现该条指令的虚拟地址和偏移地址,即@:0045123D@offset 0005063Dh 后面的这个0005063Dh就是相应的偏移地址。我们得到该地址后,便可用UltraEdit等十六进制工具来对可执行文件进行修改了。比如使用UltraEdit,你先用UltraEdit打开该可执行文件,然后按Ctrl+G,接着输入你得到的偏移地址,就可以来到其相应的机器码处。
再给你讲一下机器码,所谓的机器码。就是你看到的那些个十六进制数据了。还记的它们与汇编指令是一一对应的吗?
以下这几个是爆破时要用到的,其它的如果感兴趣,可自行查看相关资料:
JZ=74;JNZ=75;JMP=EB;Nop=90
爆破的时候,只要对以上机器码进行相应的修改就行了,比如第一种情况的时候,可以将74修改为EB,即将JZ修改为JMP。而第二种情况,责需将75修改为90,即将JNZ修改为Nop。
由于本章只讲原理,具体一点的。如怎样找到关键跳转等,我们在下一章中再讲。(一个砖头飞了上来!嘿嘿,这次被俺接到了)
上边讲了爆破的原理,你需要明白的是。爆破只是你学习Crack的开始,是很简单的手段。刚入门的时候可以玩玩儿,但希望你不要就此不前!
(嘿嘿,再说了。人家的软件中不是都说了嘛,不准对其进行逆向修改。你动了人家的身子,怎么能不买帐呢? )
偶就不喜欢爆破,做不出注册机也要找出注册码。否则我就不会去注册这个软件,既然想不掏钱,就要靠你自己的本事。(等以后我有钱了,会考虑去注册那些优秀的共享软件的 )。所以,从某种意义上来说,我是一个正人君子
其实要找到注册码并不是一件多么难的事,我是指你所针对的软件不太那个的时候 不过你无需惧怕。
刚才我们说爆破的时候不提到过关键CALL吗?一般情况下,这个关键CALL就是对两个注册码(一个是软件自身通过你的注册名或机器什么的计算出来的正确的注册码,令一个就是你输入的错误的注册码)进行比较。我前边提到过,CALL之前一般会把所用到的数据先放到一个地方,CALL过去的时候再从这些地方把先前放入的数据取出来,进行相应的处理。这个关键CALL也是这样,在CALL之前,一般会把那两个注册码放到堆栈或某个寄存器中。嘿嘿,我们只要在调试器中,单步执行到该CALL,在未进去之前通过CALL之前的指令判断其将正确的和不正确的注册码放到哪里了。然后再用相应指令进行查看就成了,我说过不难的。
下面列出两个最常见的情况(可参考相关教程):
mov&&eax [& && &]&&这里可以是地址,也可以是其它寄存器
mov&&edx [& && &]&&同上,该条指令也可以是pop edx
call 00??????& &关键call
test eax eax& &&&
jz(jnz)或jne(je)&&关键跳转
看明白了吧,在关键CALL之前,软件会把两个注册码分别放入eax和edx中,你只要在CALL处下d eax或d edx就能看到正确的注册码了。
mov&&eax [& && &]&&这里可以是地址,也可以是其它寄存器
mov&&edx [& && &]&&同上,该条指令也可以是pop edx
call 00??????& &关键call
jne(je)& && && &关键跳转
以上两种情况最为常见,而那些个不太常见的情况,我们这里就不再提了。到下下一章的时候,我会给你讲相关方法的...
关于查找软件注册码的部分,就到这里。具体内容,下下一章咱们再说。(不是说了吗?我以经可以接到你的砖头了,干嘛还要丢呢? )
最后,再来说最后的所谓的高级阶段,如果你相信自己。并且热爱Crack,那么你一定会熬到这个阶段的,只是时间因人而异。
其实分析软件的算法,是有好多技巧在里面的。呵呵,最起码我刚开始的时候就摸不着头脑,那么多CALL,每个看起来,都很重要,都追一遍?结果连好多API 都被追了进去。等你自己真正用心分析了一个软件的算法,并写出了注册机后。你就会明白其中的道理了,我们下下下一章再说。(大哥,你不是吧,连你家太阳能都丢过来了&&)
第六章--爆破软件
爆破其实很简单,最起码比你能一下把你家的牙膏给全挤出来要容易多了。你只要先到大街上买几根雷管,然后放到你的显示器上再点着就OK了(不难吧,记的点着后跑远点儿)
爆破的原理我也说过了,相信你很容易就能理解了。我们今天就具体讲一下如何找到那个关键跳转以及如何才能买到即便宜又好用的雷管...
爆破一个软件一般只需要很少的几个步骤,首先先看一下其有无加壳,有的话是用何工具加的壳,知道了以后用相应的工具将其脱掉或进行手工,参考以有教程。接着我们就可以对脱过壳之后的软件来开刀了。你有两种选择,用W32Dasm或调试器,一般如果你遇上的是那种很菜的软件的话,用W32Dasm就可以搞定了。如果遇上的不是那种比较菜的,就买股票吧,因为股票是你如胶似漆的妻子!当!快醒醒啊...哦,一般如果你遇上的不是那种很菜的软件的话,就用调试器吧。先来说W32Dasm:我们首先用W32Dasm来进行反汇编(废话!)之后在串式参考中找到错误提示信息或可能是正确的提示信息双击鼠标左键来到相应的地址处。在W32Dasm的主窗口中分析相应汇编代码,找出关键跳转和关键call。绿色光条停在关键跳转,在W32Dasm主窗口底部找到关键跳转的偏移地址(实际修改地址)。用ultraedit找到偏移地址(实际修改地址)修改机器码(或放上一根雷管),保存(点火)!而用调试器也同样简单,等会儿会详细说明。
道理废话了那么多,来实例动手说明吧:
首先讲解用W32Dasm来进行爆破:
【软件名称】中华压缩(ChinaZip)
【软件版本】7.0
【文件大小】1041KB
【适用平台】Win9x/Me/NT/2000
【软件简介】ChinaZip(中华压缩)是一款压缩、解压各种压缩文档的工具软件,它支持包括ZIP格式文件在内的各种常见压缩格式如:ARJ、CAB、GZIP、JAR、LHA、TAR、ZOO、ARC、LZH、Pak等等。
软件的出处是电脑报2001年的合订本配套光盘,7.0时的保护做的很那个,目前最新版应该好多了...
好的,我们开始吧,首先第一步是你得把它装上(引来野狼N头),之后先随便找个字符串填上去注册一下,会看到一个错误对话框,提示&注册码不正确,无法注册 &。接着我们用FI来看一下它用的是什么壳。ASPack 2.001,caspr出场。脱过壳后我们用W32Dasm花上半分钟或半小时的时间来对它进行反汇编。我们以经反汇编完毕。之后在串式参考中(字符串数据参考)中找刚才你看到的那个错误提示,找到之后双击几次,发现其只有一处调用。我们会来到004F0E64处,我把具体代码给贴上(请你从代码的最下边开始看):
:004F4DD1E84EE1F3FF& && && && & call 00432F24
:004F4DD68B55F0& && && && && &&&mov edx, dword ptr [ebp-10]
:004F4DD98D4DF4& && && && && &&&lea ecx, dword ptr [ebp-0C]
:004F4DDC8BC3& && && && && && & mov eax, ebx
:004F4DDEE8C9010000& && && && & call 004F4FAC
:004F4DE3 8B55F4& && && && && &&&mov edx, dword ptr [ebp-0C]
:004F4DE658& && && && && && && &pop eax
:004F4DE7E830F3F0FF& && && && & call 0040411C
:004F4DEC7576& && && && && && & jne004F4E64& && && && && && & &--这个就是传说中的男人,Stop!这个就是传说中的关键跳转
:004F4DEEB201& && && && && && & mov dl, 01
:004F4DF0A& && && && & mov eax, dword ptr []* Referenced by a(U)nconditional or (C)onditional Jump at Address:
|:004F4D86(C)
:004F4DF5E85ED8F5FF& && && && & call
:004F4DFA8945FC& && && && && &&&mov dword ptr [ebp-04], eax
:004F4DFD33C0& && && && && && & xor eax, eax
:004F4DFF55& && && && && && && &push ebp
:004F4EF00& && && && & push 004F4E5D
:004F4E0564FF30& && && && && &&&push dword ptr fs:[eax]
:004F4E& && && && && &&&mov dword ptr fs:[eax], esp
:004F4E0BB101& && && && && && & mov cl, 01* Possible StringData Reffrom Code Obj -&&Software\XDZHAN\ChinaZip&
& && && && && && && && && && &&&|
:004F4E0DBAA84E4F00& && && && & mov edx, 004F4EA8
:004F4E128B45FC& && && && && &&&mov eax, dword ptr [ebp-04]
:004F4E15E822DAF5FF& && && && & call 0045283C* Possible StringData Reffrom Code Obj -&&Real Programmers Use Pascal!&
& && && && && && && && && && &&&|
:004F4E1AB9CC4E4F00& && && && & mov ecx, 004F4ECC* Possible StringData Reffrom Code Obj -&&Key&
& && && && && && && && && && &&&|
:004F4E1FBAF44E4F00& && && && & mov edx, 004F4EF4
:004F4E248B45FC& && && && && &&&mov eax, dword ptr [ebp-04]
:004F4E27E854DEF5FF& && && && & call 00452C80* Possible StringData Reffrom Code Obj -&&软件注册成功,谢谢您的支持!&& &&&&--我们向上看会在这里发现注册成功后的正确信息。正确信息处向上找第一个跳转就是我们要找的关键跳转。
& && && && && && && && && && &&&|
:004F4E2CB& && && && & mov eax, 004F4F00
:004F4E31E8563DF6FF& && && && & call 00458B8C
:004F4E36A16C305000& && && && & mov eax, dword ptr [0050306C]
:004F4E3B8B00& && && && && && & mov eax, dword ptr [eax]* Possible StringData Reffrom Code Obj -&&中华压缩(ChinaZip)-注册版&
& && && && && && && && && && &&&|
:004F4E3DBA244F4F00& && && && & mov edx, 004F4F24
:004F4E42 E80DE1F3FF& && && && & call 00432F54
:004F4E4733C0& && && && && && & xor eax, eax
:004F4E495A& && && && && && && &pop edx
:004F4E4A59& && && && && && && &pop ecx
:004F4E4B59& && && && && && && &pop ecx
:004F4E4C648910& && && && && &&&mov dword ptr fs:[eax], edx
:004F4E4F686E4E4F00& && && && & push 004F4E6E* Referenced by a(U)nconditional or (C)onditional Jump at Address:
|:004F4E62(U)
:004F4E548B45FC& && && && && &&&mov eax, dword ptr [ebp-04]
:004F4E57E868E2F0FF& && && && & call
:004F4E5C C3& && && && && && && &ret
:004F4E5DE9C2E9F0FF& && && && & jmp
:004F4E62EBF0& && && && && && & jmp 004F4E54* Referenced by a(U)nconditional or (C)onditional Jump at Address:
|:004F4DEC(C)
|* Possible StringData Ref from Code Obj -&&注册码不正确,无法注册!&&&&--这个就是出错的信息了,那正确信息也就在附近,上下看看。& &
& && && && && && && && && && &&&|
:004F4E64B& && && && & mov eax,004F4F48& && && && && && && && &&--双击来到这里
:004F4E69E81E3DF6FF& && && && & call 00458B8C
:004F4E6E33C0& && && && && && & xor eax, eax
:004F4E705A& && && && && && && &pop edx
:004F4E7159& && && && && && && &pop ecx
:004F4E7259& && && && && && && &pop ecx
:004F4E& && && && && &&&mov dword ptr fs:[eax], edx
:004F4EF00& && && && & push 004F4E9B
你可能有点不明白,为什么我说它就是关键跳转呢?还记的在破解原理中我举的例子吗?
我再给你讲一遍好了,通常我们会遇到两种关键跳转,我分别举例说明:
je (jne,jz,jnz)
........&&XXXXXXXXXX
........&&XXXXXXXXXX
........&&软件注册正确的相关信息
软件的出错信息
也就是说这第一种情况是先判断注册码是否正确,如果不正确就跳到处,正确的话就不跳转,一直执行下去,直至注册正确处。
对于这种情况,我们要找的关键跳转,就是正确信息上面的第一个跳转。我们可能对其作相应修改或将其给nop掉就万事OK了。
je (jne,jz,jnz)
........&&XXXXXXXXXX
........&&XXXXXXXXXX
........&&软件的出错信息
软件注册正确的相关信息
而这第二种情况就是先判断注册码正确与否,如果正确就跳到处,不正确的话就不跳转,一直执行下去,直至出错处。
对于这种情况,我们要找的关键跳转就是出错信息上面的第一个跳转。将其做相应修改或改为jmp后我们就可以为所欲为了
呵呵,道理也都给你讲明白了,我们来改一下试试吧。我们在W32Dasm中选中关键跳转,在右下角的状态栏中看到相应的偏移地址为000F41EC。好的,我们用UltraEdit来打开它。Ctrl+G,接着输入0xF41EC,回车后便会跳到相应的位置。相应的机器码是75(jne),我们将其改为74 (jz)后存盘退出。
好了,运行一下看看,我们来随便输入一个注册码注册一下试试。呵呵,注册成功!
用W32Dasm我们就讲到这里,呵呵,很简单的,你下去之后自己找些保护简单的软件上上手吧。
我们接着来讲用调试器来进行爆破。
如果你真的试图用W32Dasm去爆破几个软件的话,用不了多少时间你就会发现一些问题。比如说有的软件你用W32Dasm反汇编后串式参考根本就不能用。或者串式参考中没有出错或正确的信息。还有就是有的软件就算你通过串式参考来到了相应的地方,刚想去找关键跳转你就会发现眼前的东西比你想像中的要乱的多...虽然你有可能通过认真仔细地找,仍会找到,但我不认为那是一件聪明的事情。毕竟,有一些动静是只有在程序执行期间才能看出来的。好的,如果你用 W32Dasm遇到了找不到关键跳转的软件,就去用调试器吧!(你用调试器前可先用W32Dasm打开一遍看个先,如果很容易就让你找到了。那就没必要了)
在开始之前我们有必要讲一下用调试器来爆破的步骤(我知道你一定会用调试器的 ):首先,我们当然还是要把你要Crack的软件给装上(我挡我挡我挡,不要乱丢东西嘛!)然后来到输入注册码的地方,仍旧随便输入一个,接着不要按确定,待我们把调试器叫出来先。还记的我前面跟你讲的API的事情吗?软件要得到你输入的注册码,就一定会调用某个API函数来达到目的。我们就在调试器中用相应的API来做断点,这样的话,只要一有程序调用这个API,就会被调试器给拦截下来。
GetDlgItemInt、 GetDlgItemText、GetDlgItemTextA这三个函数可能会有用。但是如果你用的是98,那为什么不用hmemcpy呢?那真的是一个不错的主意。当我们下完断点后就返回到你要注册的那个软件中,点确定这类的按钮。如果被调试器给断了下来,就说明你刚才下的断点有用,如果没有被断下来,就换个断点试试。接下来我们在调试器中来取消刚才你下的那个断点,我们以TRW2000为例(SoftICE与其操作大体相同)取消断点用bc *指令。然后我们就输入pmodule指令来返回到程序的领空(而在SoftICE中由于没有相应指令,呵呵,狂按F12吧)。现在我们把话题岔开一下,什么是领空呢?举个例子吧,你的程序要得到你输入的那个注册码,就会去调用相应的函数。比如调用GetDlgItemTextA,而GetDlgItemTextA本身又会去调用Hmemcpy这个函数,而这些函数都是存在于系统中的某个DLL 文件中的。那么当这个程序调用相应的API函数的话,程序的领空就会转到这个相应的DLL文件中去执行这个API函数。(你就这样理解就行了)我前边也说过了,Hmemcpy这个函数应用程序本身并不直接调用,而是由其它的API函数来调用。那么,你就可以理解为你的程序调用了一个API函数,调用的同时程序的领空会转到这个API所在的DLL文件里,而这个API又调用了Hmemcpy函数,那么此时领空就会又转到了Hmemcpy所在的DLL文件中,之后当Hmemcpy执行完毕,就会返回到调用它的API的领空中去,而当这个API执行完毕的后就会返回到调用它的应用程序的领空中去。比如说我们用 Hmemcpy这个函数来当断点,当我们输入完注册码按确定后,程序就会去调用某个API来得到你输入的那些数据,而这“某个API”又会去调用 Hmemcpy,所以程序就被断到了。当然此时程序的领空也就不会在应用程序中了,但是当我们输入过pmodule指令之后我们就可以反回到应用程序本身的领空中去了。这样的话你看到的就是应用程序自身的代码了,而不是API的!好了,我接着刚才的说(到哪儿了来着?)当我们返回到程序自身的领空中去后就一直狂按F12吧,F12的作用是一直执行程序,直到遇上ret等指令。也就是一大坨一大坨地来执行程序^_^你一直按F12,直到程序出现注册错误对话框。然后记下刚才你按的次数,接着从头做起,这一次按F12的次数是你刚才按的次数-1,也就是说比上一次要少按一次。而后按键由F12换至F10(怎么没有F4?),还是一路狂按,直到软件提示出错,这次记下你按F10的次数。好的,再从头来一遍,我们再次按F10的时候,要一步一步慢慢来,一般你按 F10的次数离你上次按的次数相差五六步的时候,一般就会看见一个CALL,接着是一个跳转指令。你一步一步地来,看过了这个跳转指令之后会不会跳走,如果跳走了,那一般你不会再过两三步就应该出错了。当然也有可能是你没有跳走,而过了两三步就出错了。这个应该不难理解,因为基本上它和我前边跟你介绍过的是一个道理。然而另外一种情况是你一路按F10下来,到了最后会发现根本没什么跳转指令,呵呵,别害怕,这个很常见的。遇上这种情况,我们只要把F10的次数变换为上次按F10的次数-1,这样的话你一般就会停在一个CALL处,而这个CALL,就是程序中的关键CALL,我们之后要吃点儿苦,要按F8追进去分析它,程序注册的成功与失败,就在这个CALL中,也就是说我们要修改的关键跳转,也在这个CALL中。呵呵,其实也很好理解的,就是把我上边说的那些个判断什么地放到了一个CALL里面。我们按F8追进去之后便仍旧按F10来一步一步执行,过不了多长时间你就会发现关键跳转了,找关键跳转的方法跟我前边说的一样,即按F10的次数跟上一次差五六步的时候慢下来,就会看到了。
你应该明白,程序是很灵活的东西,并没有那么多公式化的东西在里边,大概的分析方法就是这个样子,一切都要靠你自己去掌握,别人跟你讲,也只是讲一个分析的方法而以,我相信随着你以后经验的提高,你慢慢地就能应付各种情况了。
现在,我们再用调试器来对CHINAZIP这个软件进行分析,希望你能够掌握这个并不难的方法。
首先,你要把刚才爆破过了的再改回来,或直接重装一遍。之后我们打开它,任意输入注册码,接着按Ctrl+N呼出TRW,下断点hmemcpy。下过后按F5退出(它就是不用F4,我也没办法^_^)然后我们点击确定。好的,程序被断了下来:
KERNEL?HMEMCPY
&&push& &&&bp
&&mov& && &bp,sp
&&push& &&&ds
&&push& &&&edi
&&push& &&&esi
b&&mov& && &ecx,[bp+06]
f&&jcxz& &&&9ee9
……以下N多代码省略……
我们输入bc *来取消断点,然后用pmodule来返回到程序的领空:
d13&&mov& && &[ebx+0c],eax
d16&&mov& && &eax,[ebx]
d18&&cmp& && &eax,byte +0c
d1b&&jnz& && &00436d38
d1d&&mov& && &edx,[ebx+08]
d20&&push& &&&edx
d21&&mov& && &ecx,[ebx+04]
d24&&mov& && &edx,eax
d26&&mov& && &eax,esi
d28&&call& &&&00432b24
……N多代码仍旧省略……
按7 下F12另加1下F10来到dc4处,我们接着一下一下来按F10,大概按了10多下,就可以看到004f4dec处有一个跳转,我们执行到004f4dec处后果然跳走了。会跳到004f4e64处,我们跳过去之后按不了三下,程序就提示出错了。呵呵,明白过来了吧, 004f4dec处的那个跳转jnz 004f4e64就是关键跳转,嘿嘿,找到了之后不用我说了吧
dc4&&mov& &&&eax,[ebp-08]& &&&
dc7&&push& & eax& && && && &
dc8&&lea& && &edx,[ebp-10]
dcb&&mov& && &eax,[ebx+02e0]
dd1&&call& & 00432f24& && && &
dd6&&mov& &&&edx,[ebp-10]& &&&
dd9&&lea& && &ecx,[ebp-0c]
ddc&&mov& && &eax,ebx
dde&&call& &&&004f4fac& && &
de3&&mov& &&&edx,[ebp-0c]& &
de6&&pop& &&&eax& && && && &
de7&&call& & 0040411c& && && &
dec&&jnz& &&&004f4e64& && && && && && & &--关键跳转!!& && && &
dee&&mov& && &dl,01
df0&&mov& && &eax,[]
df5&&call& &&&
dfa&&mov& && &[ebp-04],eax
dfd&&xor& && &eax,eax
dff&&push& &&&ebp
e00&&push& &&&dword 004f4e5d
e05&&push& &&&dword [fs:eax]
e08&&mov& && &[fs:eax],esp
e0b&&mov& && &cl,01
e0d&&mov& && &edx,004f4ea8
e12&&mov& && &eax,[ebp-04]
e15&&call& &&&0045283c
e1a&&mov& && &ecx,004f4ecc
e1f&&mov& && &edx,004f4ef4
e24&&mov& && &eax,[ebp-04]
e27&&call& &&&00452c80
e2c&&mov& && &eax,004f4f00
e31&&call& &&&00458b8c
e36&&mov& && &eax,[0050306c]
e3b&&mov& && &eax,[eax]
e3d&&mov& && &edx,004f4f24
e42&&call& &&&00432f54
e47&&xor& && &eax,eax
e49&&pop& && &edx
e4a&&pop& && &ecx
e4b&&pop& && &ecx
e4c&&mov& && &[fs:eax],edx
e4f&&push& &&&dword 004f4e6e
e54&&mov& && &eax,[ebp-04]
e57&&call& &&&
e5c&&ret& &
e5d&&jmp& && &
e62&&jmp& && &short 004f4e54
e64&&mov& &&&eax,004f4f48& && &&---由上面的dec处跳来,出错!;
e69&&call& &&&00458b8c
e6e&&xor& && &eax,eax
再来给你举另一个例子:
【软件名称】天网防火墙
【软件版本】2.46 Beta
【文件大小】1289KB
【适用平台】Win9x/Me/NT/2000
【软件简介】天网防火墙个人版是一套给个人电脑使用的网络安全程序,它可以帮你抵挡网络入侵和攻击,防止信息泄露,并可与我们的网站相配合,根据可疑的攻击信息,来找到攻击者。同时天网防火墙个人版把网络分为本地网和互联网,可以针对来自不同网络的信息,来设置不同的安全方案,它适合于在拨号上网的用户,也适合通过网络共享软件上网的用户。
该软件仍旧是我从电脑报2001年合订本的配套光盘中找的,软件的注册码可以到其网站免费获得...
我们还是要先把它装上(某民工:你小子敢再说一句废话试试!^_^)之后我们用FI看一下它有没有加壳,呵呵,BC++编译,没有加壳,爽!运行它,在注册对话框中随便输入点什么,比如说这星期又出了几部新电影,都叫什么名字等等...
好的,我们接下来请TRW2000出场。先胡乱输入两个字符串,比如第一个输入“英雄的导演是?”第二个输入“可能是赵本山”:)
接下来就按Ctrl+N把TRW2K叫出来,下bpx hmemcpy,之后按F5退出。
接着可以按确定就成了,程序会被TRW2K断掉,我们紧接着输入bc *以及pmodule。
下面可以开始按F12了,一共按8下程序就会报错,我们第二次就按7下然后开始按F10,按70下F10程序就又报错了(呵呵,一定要有耐心哦)。
好的,我把反汇编后的代码给你贴出来:
7&&lea& &&&edx,[ebp-04]& && && && && && && && && &&&&--7下F12后按一下F10来到这里
a&&mov& && &ecx,[0052ae7c]
0&&mov& && &eax,[ecx]
2&&mov& && &eax,[eax+0318]
8&&add& && &eax,byte +2c
b&&call& &&&
0&&dec& && &dword [ebp-20]
3&&lea& && &eax,[ebp-04]
6&&mov& && &edx,02
b&&call& &&&
0&&mov& && &word [ebp-2c],14
6&&lea& && &eax,[ebp-08]
9&&call& &&&00401d60
e&&mov& && &edx,eax
0&&inc& && &dword [ebp-20]
3&&mov& && &ecx,[ebp-40]
6&&mov& && &eax,[ecx+02e0]
c&&call& &&&004b9f14
1&&lea& && &edx,[ebp-08]
4&&mov& && &ecx,[0052ae7c]
a&&mov& && &eax,[ecx]
c&&mov& && &eax,[eax+0318]
2&&add& && &eax,byte +30
5&&call& &&&
a&&dec& && &dword [ebp-20]
d&&lea& && &eax,[ebp-08]
0&&mov& && &edx,02
5&&call& &&&
a&&lea& && &eax,[ebp-10]
d&&call& &&&00401d60
2&&mov& && &edx,eax
4&&inc& && &dword [ebp-20]
7&&mov& && &ecx,[ebp-40]
a&&mov& && &eax,[ecx+02e0]
a0&&call& &&&004b9f14
a5&&lea& && &edx,[ebp-10]
a8&&push& &&&dword [edx]
aa&&mov& && &word [ebp-2c],20
b0&&lea& && &eax,[ebp-0c]
b3&&call& &&&00401d60
b8&&mov& && &edx,eax
ba&&inc& && &dword [ebp-20]
bd&&mov& && &ecx,[ebp-40]
c0&&mov& && &eax,[ecx+02d4]
c6&&call& &&&004b9f14
cb&&lea& && &edx,[ebp-0c]
ce&&mov& && &edx,[edx]
d0&&mov& && &eax,[0052ae7c]
d5&&mov& && &eax,[eax]
d7&&pop& && &ecx
d8&&call& &&&0040525c
dd&&mov& && &[ebp-45],al
e0&&dec& && &dword [ebp-20]
e3&&lea& && &eax,[ebp-10]
e6&&mov& && &edx,02
eb&&call& &&&
f0&&dec& && &dword [ebp-20]
f3&&lea& && &eax,[ebp-0c]
f6&&mov& && &edx,02
fb&&call& &&&
0&&cmp& && &byte [ebp-45],00
4&&jz& && && && && && && && && & &--按了60多下F10后会在这里发现一个跳转,嘿嘿,就是它了!!!
6&&mov& && &ecx,[0052ae7c]
c&&mov& && &eax,[ecx]
e&&mov& && &eax,[eax+0318]
4&&call& &&&00411fd0
9&&mov& && &word [ebp-2c],2c
f&&mov& && &edx,00521b50
4&&lea& && &eax,[ebp-14]
7&&call& &&&
c&&inc& && &dword [ebp-20]
f&&mov& && &eax,[eax]
1&&call& &&&004b41b0
6&&dec& && &dword [ebp-20]
9&&lea& && &eax,[ebp-14]
c&&mov& && &edx,02
1&&call& &&&
6&&mov& && &eax,[ebp-40]
9&&call& &&&004a81d0
e&&jmp& && &short 0041c77d
0&&mov& && &word [ebp-2c],38
6&&mov& && &edx,00521b6b
b&&lea& && &eax,[ebp-18]
e&&call& &&&
3&&inc& && &dword [ebp-20]
找到了关键跳转之后就别闲着了,呵呵,放雷管吧!(你可以用W32Dasm打开这个文件,然后按Shift+F12,之后输入,这样就可以在右下角看到相应的偏移地址了)
小技巧:在TRW中,如果你觉的某处可能是关键跳转的话,可以用r fl z这个指令来进行测试,该指令可使以成立的条件取反,比如说本来JZXXXXXXXX成立,可以跳走了,用r fl z指令后该条指令就不成立了,即就不会跳走了。以上也是,你可以在处输入r fl z,呵呵,再执行几步看看,是不是成功了?还有就是如果你只是想达到注册软件的目的,且该软件只在注册的时候验证一次的话,用这个方法就可以代替雷管了!
呵呵,最后还是要说一句,爆破只是一些雕虫小技。刚入门时玩几次就够了,切莫就此不前...
后话:你可能慢慢就会发现,有一些软件其实并没有你想象中那么简单,你甚至连找到它的关键跳转都找不到。这很正常,你要做的便是多动手多练习,慢慢你就会明白过来的。我今天之所以给你举这两个例子,就是因为它们两个都比较简单,且能说明重点,给你讲那些比较那个的软件的爆破,反而会让你看的一头雾水...第七章-寻找软件的注册码
我们来寻找软件真正的注册码!
寻找软件的注册码就像你小时玩的躲猫猫一样,简单又有趣,虽然后来你会不这样觉的
好的,我们开始。
我不知道你有没有明白我前面在原理中讲的那些东西,如果没明白,我就再说一遍
软件通过你输入的用户名或者机器码什么的生成一个正确的注册码来与你输入的注册码进行比较,如果两个相同,也就是说你输入的注册码是正确的话,那软件就会完成注册。如果你输入的不正确,嘿嘿,当然就不会注册成功。
好的,现在你已经知道软件会有一个比较两个注册码的过程,这就是关键所在。一般如果你遇到的是那种明码比较的软件,这会是一件非常另人愉快的事情的
软件会先计算出正确的注册码然后再与你输入的那个进行比较,也就是说正确的注册码会被软件自己算出来!嘿嘿,搜身你会吗?虽然法律以及道德不允许我们去搜身,但…
我接着说,虽然现在的软件已经比以前要厉害上许多,但,那种用明码比较的,还是大有人在的。所谓明码比较,就是说软件先算出正确的注册码,然后放到内存或你家的沙发下面,之后再得到你输入的那个注册码,接着就比较了。呵呵,好理解吧,我们只要找到那个比较的地方,看一下软件把注册码放到内存的哪里了,再到相应的内存处瞧一瞧,就万事OK了!
还记的对你说过的那些常见的(也是最菜的)比较吗?我捡其中最简单的一个来给你再解释一下:
mov&&eax [& && &]& &这里可以是地址,也可以是其它寄存器 该条指令也可以是mov&&eax [& && & ]
mov&&edx [& && &]& &同上& &通常这两个地址就储存着重要信息 该指令也可以是 pop edx
call 00??????& &关键call
jz(jnz)或&&jne(je)&&关键跳转
第一条mov eax [& &]指令是将一个内存地址或另外一个寄存器(该寄存器中装的是内存地址)装入eax中。第二条指令与其相同,是将一个内存地址或另外一个寄存器中的内存地址装入edx中。而这两条指令是干什么的呢?嘿嘿嘿嘿…
这两条指令就是用来存放真假两个注册码的地址的,也就是说eax和edx这两个寄存器中此时一个装的是正确的注册码的内存地址,一个是你输入的那个错误的注册码的内存地址。软件在比较注册码前将两个注册码的内存地址分别装入到两个寄存器中,然后就是关键Call出场。在这个关键Call中对注册码进行比较时,软件会从相应的寄存器中取出两个注册码来比较,接着出来就是一个关键跳转,通过上面Call中的比较结果来做相应的跳转…
你应该已经想到什么了吧!没错,我们只要找到软件的关键Call,然后在关键Call处来查看相应的内存地址就可以找到正确的注册码了 而这一切,都可以通过调试器来完成。从某种意义上来说,如果你能自己一个人把你家的微波炉修好,那你就绝对会用调试器&&我们在调试器中,只要一步一步执行到关键Call处,然后用d eax和d edx就可以查看两个地址中放的两个注册码,如果你发现其中的一个是你自己刚才输入的,那么另一条就是正确的
而所谓的内存注册机呢?我这里就不再多说了,它的原理就是自动在软件注册的时候中断到相应的地方,并显示相应内存处的值,当然它是需要配置的... 此类软件有CRACKCODE2000和注册机编写器keymake,具体用法你可以参考软件的联机帮助^_^
我们剩下的问题就是如何来找个这关键Call了,基本上来说你就用前边给你讲爆破时的那种方法就可以了,很简单的
但是就像你家后门的玻璃可能永远擦不干净一样,我们家后门的玻璃也从来没擦干净过 导演:NG!重说,就像所有事情都有例外一样,有些软件的关键Call会比较难找一点,但如果你掌握了适当的方法,同样也会很好找的...
我们就来玩玩吧:
首先,我们还来用CHINAZIP这个软件上上手^_^
它已经是我们的老朋友了,所以就不用再介绍它了吧
好的,我们先装上它(嘿嘿,偶就是喜欢说废话,你打偶偶也要说^_^)接着我们点帮助-注册,输入Name:Suunb[CCG],Code:
然后请出我们的老伙计TRW2000,下bpx hmemcpy 按F5点确定被拦:& &
KERNEL?HMEMCPY
&&push& &&&bp
&&mov& && &bp,sp
&&push& &&&ds
&&push& &&&edi
&&push& &&&esi
b&&mov& && &ecx,[bp+06]
f&&jcxz& &&&9ee9
& & ...省略N多代码...
输入bc *,删除断点。pmodule ,直接跳到程序领空:
d13&&mov& && &[ebx+0c],eax
d16&&mov& && &eax,[ebx]
d18&&cmp& && &eax,byte +0c
d1b&&jnz& && &00436d38
d1d&&mov& && &edx,[ebx+08]
d20&&push& &&&edx
d21&&mov& && &ecx,[ebx+04]
d24&&mov& && &edx,eax
d26&&mov& && &eax,esi
d28&&call& &&&00432b24
...省略N多代码...
按8 下F12就会提示出错,我们第二次就按7次&&接着我们再来按F10,按16下就会报错,好的,我们再来:这一次我们按F10的时候,就按我前边说过的方法,到与上次按的次数相差五六次的时候就慢下来。好的,我们按十来下的时候就慢下来仔细瞅瞅,呵呵,一下子就看到004f4dec处的那个跳转以及它上面的关键CALL了&&我们按F10单步执行到004f4de7处(即关键CALL处)后下指令d edx就可看到真正的注册码,而d eax则可以看到我刚才输入的&&代码给你:
dc4&&mov& &&&eax,[ebp-08]& && &&---7下F12,1下F10就来到这里(此时ebp-08处放的是刚才输入的注册码)
dc7&&push& & eax& && && && &&&&---将EAX压栈;
dc8&&lea& && &edx,[ebp-10]
dcb&&mov& && &eax,[ebx+02e0]
dd1&&call& & 00432f24& && && & &---该CALL用来得到用户输入的用户名,其实就是某个API函数,嘿嘿,好奇的话可以追进去看看
dd6&&mov& &&&edx,[ebp-10]& && &&---将得到的用户名放入EDX;
dd9&&lea& && &ecx,[ebp-0c]
ddc&&mov& && &eax,ebx
dde&&call& & 004f4fac& && && & &---该CALL用来计算出真正的注册码;
de3&&mov& &&&edx,[ebp-0c]& && &&---将计算出的真.注册码放入EDX,在下条指令时可用D EDX查看;
de6&&pop& &&&eax& && && && &&&&---先前压入的注册码出栈;
de7&&call& & 0040411c& && && & &---该CALL用来比较两个注册码,罪魁祸首啊!;
dec&&jnz& &&&004f4e64& && && & &---不相等则跳,跳必死,暴破将75改为74或EB,当然90也行;& && &
dee&&mov& && &dl,01
df0&&mov& && &eax,[]
df5&&call& &&&
dfa&&mov& && &[ebp-04],eax
dfd&&xor& && &eax,eax
dff&&push& &&&ebp
e00&&push& &&&dword 004f4e5d
e05&&push& &&&dword [fs:eax]
e08&&mov& && &[fs:eax],esp
e0b&&mov& && &cl,01
e0d&&mov& && &edx,004f4ea8
e12&&mov& && &eax,[ebp-04]
e15&&call& &&&0045283c
e1a&&mov& && &ecx,004f4ecc
e1f&&mov& && &edx,004f4ef4
e24&&mov& && &eax,[ebp-04]
e27&&call& &&&00452c80
e2c&&mov& && &eax,004f4f00
e31&&call& &&&00458b8c
e36&&mov& && &eax,[0050306c]
e3b&&mov& && &eax,[eax]
e3d&&mov& && &edx,004f4f24
e42&&call& &&&00432f54
e47&&xor& && &eax,eax
e49&&pop& && &edx
e4a&&pop& && &ecx
e4b&&pop& && &ecx
e4c&&mov& && &[fs:eax],edx
e4f&&push& &&&dword 004f4e6e
e54&&mov& && &eax,[ebp-04]
e57&&call& &&&
e5c&&ret& &
e5d&&jmp& && &
e62&&jmp& && &short 004f4e54
e64&&mov& &&&eax,004f4f48& && &&---由上面的dec处跳来,挂!;
e69&&call& &&&00458b8c
e6e&&xor& && &eax,eax
Name:Suunb[CCG]
Code:SCCG5296
可以真接在TRW2000中下断点bpx 004f4de6,中断后用D EDX来查看真.注册码。
另附:CRACKCODE2000的CRACKCODE.INI
CommandLine=CHINAZIP.exe
Mode=2& && && && && && && && && &
First_Break_Address=4f4de7& && &
First_Break_Address_Code=E8& &&&
First_Break_Address_Code_Lenth=5
Second_Break_Address=404123& &&&
Second_Break_Address_Code_Lenth=2
Save_Code_Address=EDX
呵呵,是不是很简单?我说过了嘛,其实并不难的
我不知道你有没有发现,其实上面的软件的关键CALL还是很好找的,相信你用W32Dasm就中以找出来,那为什么不用呢?对于那些比较简单的软件,何必非请出调试器呢?
给你贴个用W32Dasm找关键CALL的:
【软件名称】e族百变桌面
【软件版本】4.0
【文件大小】1316KB
【适用平台】Win9x/Me/NT/2000
【软件简介】提供25种变换桌面的方式,让你的桌面焕然一新。操作简单,无需费力[url=]学习[/url]。支持多种Internet流行图片格式。将壁纸文件打包,方便存储、转发。将壁纸包展开,还原图片文件。
嘿嘿,我也懒的去折腾我的小猫了,咱们就还用电脑报2001年合订本配套光盘上的软件吧&&(2002年的偶没有买)
首先装上它(嘿嘿,你习惯了?为什么不丢东西了? ^_^)运行一下该软件先,该软件自动生成了相应的机器码,并停留在注册项上,输入注册码,点确定,挂!
用fi检查,该软件为Delphi编译,没加壳。
用W32DASM打开该执行文件,参考-串式参考,在最下边,见到了刚才弹出的&注册码不正确,请联系作者&。
用鼠标双击,发现只有一处调用,在00488E97处,接着在串式参考对话框中在&注册码不正确,请联系作者&处向上找,找到&感谢您支持国产软件,祝您好运&(说的我都不好意思了)&&
用鼠标双击,仍旧只有一处调用,在00488DF7处:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00488DCD(U)
:0FC& && && && && &&&mov eax, dword ptr [ebp-04]
:00488DDC8B& && && &&&mov eax, dword ptr [eax+]
:0BB61E& && && && & xor eax, 1EB60B28
:0B45F8& && && && && &&&cmp eax, dword ptr [ebp-08]&&&---关键比较,? EAX来查看软件正确的注册码;
:00488DEA0F85A0000000& && && &&&jne00488E90& && && && && & &---关键跳转,不相等就跳,跳必挂!
:0& && && && && && & push * Possible StringData Reffrom Code Obj -&&注册成功&
& && && && && && && && &|
:0E4800& && && && & push 00488ED4* Possible StringData Reffrom Code Obj -&&感谢您支持国产软件,祝您好运!&
& && && && && && && && &|
:0E4800& && && && & push00488EE0& && && && && &&---双击串式参考便跳到此行,我们向上找第一个跳转处就是关键跳转,关键跳转上面就是关键比较;
:00488DFC8B45FC& && && && && &&&mov eax, dword ptr [ebp-04]
:00488DFFE81CD2FBFF& && && && & call
:& && && && && && && &push eax
...省略代码若干...
向上看,00488DEA处有一跳转,不相等便跳到00488E90处,跳必挂!还记的00488E97处的出错对话框吧! 罪魁祸首啊!
在向上一行,看00488DE7处:cmp eax, dword ptr [ebp-08],此为关键比较。可用? EAX查看软件正确的注册码。
打开该软件,在注册码处输入,打开TRW2000,下断点bpx 00488DE7,点注册被拦。输入? EAX得到软件正确的注册码。
用注册机编写器keymake编写该软件的注册机:
点其它-另类注册机(F8),软件名称输入ePaper.exe,注册码选寄存器方式 EAX 十进制。
添加断点,中断地址:00488DE7,中断次数:1,第一字节:3B,指令长度:3。
生成注册机后完工,万事OK!
嘿嘿,现在是不是觉的找软件的注册码越来越像小时候玩的躲猫猫了?&&可惜偶小时候没有青梅竹马那种类型的伙伴...
好的,我们这次讲个有点儿名气的软件,WinZIP8.1,这个软件相信大家都用过吧,反正偶是喜欢用RAR,不过也多少用过几天这玩意儿...
如果你没听说过,那看介绍好了
【软件名称】WinZIP
【软件版本】8.1 Beta 2
【文件大小】1757KB
【适用平台】Win9x/Me/NT/2000
【软件简介】一个强大并且易用的压缩实用程序,支持ZIP、CAB、TAR、GZIP、MIME,以及更多格式的压缩文件。其特点是紧密地与Windows资源管理器拖放集成,不用离开资源管理器而进行压缩、解压缩。
不用我说了吧,出处仍旧是电脑报2001年合订本的配套光盘
我之所以先择它,是因为觉得它的关键CALL没有前边那两个那样好找(其实也就那样了^_^)极具代表性,而且通过它可以让你感受一下这个魅力比你家的荼几还大的调试器
这里之所以提到Ollydbg,是觉的它真是一个非常非常棒的调试器...强烈建议你多玩几次...(MP3好听吗? ^_^)
我们来吧,首先当然还是要装上它(左闪术,右闪术),然后用Ollydbg来载入,此时界面会被分成四个部分,左上方是软件反汇编后的代码,右上方是寄存器开会的地方,左下方是内存区,右下方显示的则是堆栈的信息。
我们来下断点,按Alt+F4,之后选USER32,然后再鼠标右键--&搜索--&当前模块中的名称,然后在那一大堆函数中找到GetDlgItemTextA,按F2来下断点,它会提示你错误,并说无法设置中断点,是不是很过瘾?(呜呜呜...大哥,我错了,再也不敢了...)
呵呵,这个我也不知道什么原因,明明是用了这个函数嘛,就是不让断,其实我对Ollydbg也不是太那个(关键是讨厌它的下断方式)看来还是用我们的万能断点吧,输入注册名Suunb[CCG],输入注册码 ,然后用TRW2000下断bpx hmemcpy,断到之后,pmodule返回领空后一次F12就会出错,看来所有的东东就在这里了...
我们用TRW2000再断一下,返回领空之后记着第一条指令的地址0040bd5f,呜呜呜...上条指令明明是调用GetDlgItemTextA,为什么在Ollydbg中不让下呢?
没关系,我们记下这个地址后仍旧用Ollydbg来加载程序,之后在反汇编窗口中找到0040bd5f处,然后按下F2来下断(会变为红色),下断之后便按 F9来运行程序,接着输入注册名Suunb[CCG],注册码后按确定,程序会被Ollydbg给断到:
0040BD5F&&|.57& && && && & PUSHEDI
0040BD60&&|. E8 F34A0500& & CALL WINZIP32.
0040BD65&&|.57& && && && & PUSHEDI& && && && && && && && && && &&&; /Arg1
0040BD66&&|. E8 164B0500& & CALLWINZIP32.& && && && && && &; \WINZIP32.
0040BD6B&&|.59& && && && & POPECX
0040BD6C&&|. BE 1CCA4C00& & MOV ESI,WINZIP32.004CCA1C
0040BD71&&|.59& && && && & POPECX
0040BD72&&|. 6A 0B& && && &PUSH0B& && && && && && && && && && && &; /Count = B (11.)
0040BD74&&|.56& && && && & PUSHESI& && && && && && && && && && &&&; |Buffer =& WINZIP32.004CCA1C
0040BD75&&|. 68 810C0000& & PUSH0C81& && && && && && && && && && & ; |ControlID = C81 (3201.)
0040BD7A&&|.53& && && && & PUSHEBX& && && && && && && && && && &&&; |hWnd
0040BD7B&&|. FF15 F4C54A00&&CALL DWORD PTRDS:[&&USER32.GetDlgItemTe&; \GetDlgItemTextA
0040BD81&&|.56& && && && & PUSHESI
0040BD82&&|. E8 D14A0500& & CALL WINZIP32.
0040BD87&&|.56& && && && & PUSHESI
0040BD88&&|. E8 F44A0500& & CALL WINZIP32.
0040BD8D&&|. 803D F0C94C00 &CMP BYTE PTR DS:[4CC9F0],0
0040BD94&&|.59& && && && & POPECX
0040BD95&&|.59& && && && & POPECX
0040BD96&&|. 74 5F& && && &JE SHORT WINZIP32.0040BDF7
0040BD98&&|. 803D 1CCA4C00 &CMP BYTE PTR DS:[4CCA1C],0
0040BD9F&&|. 74 56& && && &JE SHORT WINZIP32.0040BDF7
0040BDA1&&|. E8 31F9FFFF& & CALLWINZIP32.& && && && && && &&--关键CALL,等会儿进去玩玩
0040BDA6&&|. 84C0& && && & TESTAL,AL& && && && && && && && && && &&--根据关键CALL中比较的结果来做相应的测试
0040BDA8&&|. 74 4D& && && &JE SHORTWINZIP32.0040BDF7& && && && &&&&--跳走就没戏!
0040BDAA&&|.57& && && && & PUSHEDI
0040BDAB&&|. 68 08DE4B00& & PUSHWINZIP32.004BDE08& && && && && && &;&&ASCII &Name&
0040BDB0&&|. FF35 1CC74A00&&PUSH DWORD PTRDS:[4AC71C]& && && && &&&;&&WINZIP32.004BDDEC
0040BDB6&&|. E8 8AFA0400& & CALL WINZIP32.
0040BDBB&&|.56& && && && & PUSHESI
0040BDBC&&|. 68 C8EB4B00& & PUSHWINZIP32.004BEBC8& && && && && && &;&&ASCII &SN&
0040BDC1&&|. FF35 1CC74A00&&PUSH DWORD PTRDS:[4AC71C]& && && && &&&;&&WINZIP32.004BDDEC
0040BDC7&&|. E8 79FA0400& & CALL WINZIP32.
0040BDCC&&|. FF35 18C74A00&&PUSH DWORD PTRDS:[4AC718]& && && && &&&; |Arg4 = 004BDDF4 ASCII &winzip32.ini&
0040BDD2&&|. 6A 00& && && &PUSH0& && && && && && && && && && && & ; |Arg3 =
0040BDD4&&|. 6A 00& && && &PUSH0& && && && && && && && && && && & ; |Arg2 =
0040BDD6&&|. 68 14DE4B00& & PUSHWINZIP32.004BDE14& && && && && && &; |Arg1 = 004BDE14 ASCII &rrs&
0040BDDB&&|. E8 4CFA0400& & CALLWINZIP32.0045B82C& && && && && && &; \WINZIP32.0045B82C
0040BDE0&&|. A1 A8914C00& & MOV EAX,DWORD PTR DS:[4C91A8]
0040BDE5&&|. 83C4 28& && &&&ADD ESP,28
0040BDE8&&|.85C0& && && &&&TEST EAX,EAX
0040BDEA&&|. 74 07& && && &JE SHORT WINZIP32.0040BDF3
0040BDEC&&|.50& && && && & PUSHEAX& && && && && && && && && && &&&; /hObject =&
0040BDED&&|. FF15 80C04A00&&CALL DWORD PTRDS:[&&GDI32.DeleteObject&&; \DeleteObject
0040BDF3&&|& 6A01& && && & PUSH 1
0040BDF5&&|. EB 30& && && &JMP SHORT WINZIP32.0040BE27
0040BDF7&&|& E8 C3020000& & CALL WINZIP32.0040C0BF
0040BDFC&&|. 68 8E020000& & PUSH 28E
0040BE01&&|. E8 & & CALL WINZIP32.
0040BE06&&|.50& && && && & PUSHEAX& && && && && && && && && && &&&; |Arg3
0040BE07&&|.53& && && && & PUSHEBX& && && && && && && && && && &&&; |Arg2
0040BE08&&|. 6A 3D& && && &PUSH3D& && && && && && && && && && && &; |Arg1 = 0000003D
0040BE0A&&|. E8 C8050400& & CALL WINZIP32.& && && && && && &; \WINZIP32.我们用Ollydbg断到之后,可以像在TRW2000中一样通过F8(这个调试器跟我一样,也不喜欢F4^_^)来单步执行程序,我们按32下F8后程序就会出错,那我们在第二遍载入时按F8按到20多下时就仔细看看有没有可疑的地方,你一眼就可以看到0040BDA1处的这个关键CALL,我们只要追到这里时追进去就有可能看到软件正确的注册码
那还等什么呢?我们就进去吧...
按F7 跟进后你会看的眼花眼花缭乱,到处都是PUSH跟POP,到底哪个才是呢?现在知道我为什么让你用Ollydbg了吧(偶起初也是要用TRW2000的,但临时改变主意 ^_^)用Ollydbg的一个最大好处就是可以真接看到寄存器中的值,特别是你通过F8来单步执行的时候,在反汇编代码的下边,会有一个小窗体,在那里可以显示相关指令中所使用的寄存器的值,爽吧!
我们按76下F8之后,在处就可以第一次看到正确的注册码了,呵呵,我这边儿是71C20EDC,然后你还会再陆续看到几次,爽?
另外我还发现一个有趣的事情,在WinZIP8.1中,一个注册名可以有两个注册码,呵呵,不知道是不是还有为特别用户准备的特别注册码以用来和普通的做区别&&当程序通过比较,发现你输入的注册码不正确后竟然会再次算出另一个注册码来再比较一次,嘿嘿,我的第二个注册码是
追入关键CALL里的代码:
&&/$55& && && && & PUSHEBP
&&|.8BEC& && && &&&MOV EBP,ESP
0040B6DA&&|. 81EC 0C020000&&SUB ESP,20C
&&|. 8065 FF 00& &&&AND BYTE PTR SS:[EBP-1],0
&&|. 803D F0C94C00 &CMP BYTE PTR DS:[4CC9F0],0
0040B6EB&&|.53& && && && & PUSHEBX
0040B6EC&&|.56& && && && & PUSHESI
0040B6ED&&|.57& && && && & PUSHEDI
0040B6EE&&|. 0F84 FB000000&&JE WINZIP32.0040B7EF
&&|. 8D45 E8& && &&&LEAEAX,DWORD PTR SS:[EBP-18]
&&|.50& && && && & PUSHEAX
&&|. 68 C0E84B00& & PUSH WINZIP32.004BE8C0
0040B6FD&&|. E8 DE61FFFF& & CALL WINZIP32.
&&|. 8D45 E8& && &&&LEAEAX,DWORD PTR SS:[EBP-18]
&&|.50& && && && & PUSHEAX
&&|. E8 F57C0800& & CALL WINZIP32.
0040B70B&&|. 83C4 0C& && &&&ADD ESP,0C
0040B70E&&|. 83F8 14& && &&&CMP EAX,14
&&|. 72 11& && && &JB SHORT WINZIP32.
&&|. BF 20C74A00& & MOVEDI,WINZIP32.004AC720& && && && && &;&&ASCII &auth.c&
&&|. 6A 21& && && &PUSH 21
0040B71A&&|.57& && && && & PUSHEDI
0040B71B&&|. E8 86F60000& & CALL WINZIP32.0041ADA6
&&|.59& && && && & POPECX
&&|.59& && && && & POPECX
&&|. EB 05& && && &JMP SHORT WINZIP32.
&&|& BF 20C74A00& & MOVEDI,WINZIP32.004AC720& && && && && &;&&ASCII &auth.c&
&&|& 8D85 F4FDFFFF&&LEA EAX,DWORD PTR SS:[EBP-20C]
0040B72F&&|. BB F0C94C00& & MOVEBX,WINZIP32.004CC9F0& && && && && &;&&ASCII &Suunb[CCG]&
&&|.50& && && && & PUSHEAX
&&|.53& && && && & PUSHEBX
&&|. E8 & & CALL WINZIP32.0040BA8B
0040B73B&&|. 8D85 F4FDFFFF&&LEA EAX,DWORD PTR SS:[EBP-20C]
&&|.50& && && && & PUSHEAX
&&|. E8 B97C0800& & CALL WINZIP32.
&&|. BE C8000000& & MOV ESI,0C8
0040B74C&&|. 83C4 0C& && &&&ADD ESP,0C
0040B74F&&|.3BC6& && && &&&CMP EAX,ESI
&&|. 72 0A& && && &JB SHORT WINZIP32.0040B75D
&&|. 6A 23& && && &PUSH 23
&&|.57& && && && & PUSHEDI
&&|. E8 4BF60000& & CALL WINZIP32.0041ADA6
0040B75B&&|.59& && && && & POPECX
0040B75C&&|.59& && && && & POPECX
0040B75D&&|& 8D85 F4FDFFFF&&LEA EAX,DWORD PTR SS:[EBP-20C]
&&|.50& && && && & PUSHEAX
&&|. 8D45 E8& && &&&LEAEAX,DWORD PTR SS:[EBP-18]
&&|.50& && && && & PUSHEAX
&&|. E8 & & CALL WINZIP32.
0040B76D&&|.59& && && && & POPECX
0040B76E&&|.85C0& && && &&&TEST EAX,EAX
&&|.59& && && && & POPECX
&&|. 75 04& && && &JNZ SHORT WINZIP32.
&&|. C645 FF 01& &&&MOV BYTE PTR SS:[EBP-1],1
&&|& 8D45 E8& && &&&LEAEAX,DWORD PTR SS:[EBP-18]
0040B77A&&|.50& && && && & PUSHEAX
0040B77B&&|. 68 D0E84B00& & PUSH WINZIP32.004BE8D0
&&|. E8 5B61FFFF& & CALL WINZIP32.
&&|. 8D45 E8& && &&&LEAEAX,DWORD PTR SS:[EBP-18]
&&|.50& && && && & PUSHEAX
&&|. E8 727C0800& & CALL WINZIP32.
0040B78E&&|. 83C4 0C& && &&&ADD ESP,0C
&&|. 83F8 14& && &&&CMP EAX,14
&&|. 72 0A& && && &JB SHORT WINZIP32.
&&|. 6A 27& && && &PUSH 27
&&|.57& && && && & PUSHEDI
&&|. E8 08F60000& & CALL WINZIP32.0041ADA6
0040B79E&&|.59& && && && & POPECX
0040B79F&&|.59& && && && & POPECX
&&|& 8D45 E8& && &&&LEAEAX,DWORD PTR SS:[EBP-18]
&&|.50& && && && & PUSHEAX
&&|.53& && && && & PUSHEBX
&&|. E8 C62F0900& & CALL WINZIP32.
0040B7AA&&|.59& && && && & POPECX
0040B7AB&&|.85C0& && && &&&TEST EAX,EAX
0040B7AD&&|.59& && && && & POPECX
0040B7AE&&|. 75 0E& && && &JNZ SHORT WINZIP32.0040B7BE
&&|. FF15 F0C14A00&&CALL DWORD PTRDS:[&&KERNEL32.GetTickCou&; [GetTickCount
&&|. A8 01& && && &TEST AL,1
&&|. 74 04& && && &JE SHORT WINZIP32.0040B7BE
0040B7BA&&|. C645 FF 01& &&&MOV BYTE PTR SS:[EBP-1],1
0040B7BE&&|& 6A14& && && & PUSH 14
&&|. 8D45 E8& && &&&LEAEAX,DWORD PTR SS:[EBP-18]
&&|. 6A 00& && && &PUSH 0
&&|.50& && && && & PUSHEAX
&&|. E8 & & CALL WINZIP32.00493A40
0040B7CB&&|.56& && && && & PUSHESI
0040B7CC&&|. 8D85 F4FDFFFF&&LEA EAX,DWORD PTR SS:[EBP-20C]
&&|. 6A 00& && && &PUSH 0
&&|.50& && && && & PUSHEAX
&&|. E8 & & CALL WINZIP32.00493A40
0040B7DA&&|. 83C4 18& && &&&ADD ESP,18
0040B7DD&&|. 807D FF 00& &&&CMP BYTE PTR SS:[EBP-1],0
&&|. 74 13& && && &JE SHORT WINZIP32.
&&|. E8 D7080000& & CALL WINZIP32.0040C0BF
&&|. 8025 EDBF4C00 &AND BYTE PTR DS:[4CBFED],0
0040B7EF&&|&32C0& && && &&&XOR AL,AL
&&|. E9 F5000000& & JMP WINZIP32.0040B8EB
&&|& 8D85 BCFEFFFF&&LEA EAX,DWORD PTR SS:[EBP-144]
0040B7FC&&|.50& && && && & PUSHEAX
0040B7FD&&|.53& && && && & PUSHEBX
0040B7FE&&|. E8 ED000000& & CALLWINZIP32.& && && && && && & &--参与计算软正确的注册码
&&|. 8D85 BCFEFFFF&&LEA EAX,DWORD PTRSS:[EBP-144]& && && &&&&--在这里第一次发现软件正确的注册码
&&|.50& && && && & PUSHEAX& && && && && && && && && && &
0040B80A&&|. E8 F17B0800& & CALL WINZIP32.
0040B80F&&|. BE 2C010000& & MOV ESI,12C
&&|. 83C4 0C& && &&&ADD ESP,0C
&&|.3BC6& && && &&&CMP EAX,ESI
&&|. 72 0A& && && &JB SHORT WINZIP32.
0040B81B&&|. 6A 39& && && &PUSH 39
0040B81D&&|.57& && && && & PUSHEDI
0040B81E&&|. E8 83F50000& & CALL WINZIP32.0041ADA6
&&|.59& && && && & POPECX
&&|.59& && && && & POPECX
&&|& BF 1CCA4C00& & MOVEDI,WINZIP32.004CCA1C& && && && && &;&&ASCII&&& && && && &&--将刚才输入的错误的注册码放入EDI
0040B82A&&|. 8D85 BCFEFFFF&&LEA EAX,DWORD PTRSS:[EBP-144]& && && & &--EAX中装入正确的注册码所在的地址
&&|.57& && && && & PUSHEDI& && && && && && && && && && &&&&--用户输入的注册码入栈
&&|.50& && && && & PUSHEAX& && && && && && && && && && &&&&--软件计算出的正确的注册码入栈
&&|. E8 392F0900& & CALLWINZIP32.& && && && && && &&--关键CALL,用于比较用户输入的注册码
&&|.F7D8& && && &&&NEG EAX
&&|.1AC0& && && &&&SBB AL,AL
0040B83B&&|.59& && && && & POPECX
0040B83C&&|.FEC0& && && &&&INC AL
0040B83E&&|.59& && && && & POPECX
0040B83F&&|. A2 EDBF4C00& & MOV BYTE PTR DS:[4CBFED],AL
&&|. 0F85 8A000000&&JNZ WINZIP32.
0040B84A&&|. 8D85 BCFEFFFF&&LEA EAX,DWORD PTR SS:[EBP-144]
&&|.50& && && && & PUSHEAX
&&|.53& && && && & PUSHEBX
&&|. E8 & & CALLWINZIP32.0040B98A& && && && && && &&--参与计算软件的第二个注册码
&&|. 8D85 BCFEFFFF&&LEA EAX,DWORD PTRSS:[EBP-144]& && && &&&&--此时软件会再算出另
外一个注册码
0040B85D&&|.50& && && && & PUSHEAX& && && && && && && && && && &
0040B85E&&|. E8 9D7B0800& & CALL WINZIP32.
&&|. 83C4 0C& && &&&ADD ESP,0C
&&|.3BC6& && && &&&CMP EAX,ESI
&&|. 72 0E& && && &JB SHORT WINZIP32.
0040B86A&&|. 6A 3E& && && &PUSH 3E
0040B86C&&|. 68 20C74A00& & PUSHWINZIP32.004AC720& && && && && && &;&&ASCII &auth.c&
&&|. E8 30F50000& & CALL WINZIP32.0041ADA6
&&|.59& && && && & POPECX
&&|.59& && && && & POPECX
&&|& 8D85 BCFEFFFF&&LEA EAX,DWORD PTRSS:[EBP-144]& && && &&&&--软件计算出的第二个注册码装入EAX中
0040B87E&&|.57& && && && & PUSHEDI& && && && && && && && && && &&&&--用户输入的注册码入栈
0040B87F&&|.50& && && && & PUSHEAX& && && && && && && && && && &&&&--软件计算出的第二个注册码入栈
&&|. E8 EB2E0900& & CALLWINZIP32.& && && && && && &&--另一个关键CALL,用于比较第二次生成的注册码
&&|.F7D8& && && &&&NEG EAX
&&|. 1AC0& && && & SBB AL,AL
&&|.59& && && && & POPECX
0040B88A&&|.FEC0& && && &&&INC AL
0040B88C&&|.59& && && && & POPECX
0040B88D&&|. A2 EDBF4C00& & MOV BYTE PTR DS:[4CBFED],AL
&&|. 75 40& && && &JNZ SHORT WINZIP32.
&&|. 8D85 C0FEFFFF&&LEA EAX,DWORD PTR SS:[EBP-140]
0040B89A&&|. 6A 04& && && &PUSH 4
0040B89C&&|.50& && && && & PUSHEAX
0040B89D&&|.57& && && && & PUSHEDI
0040B89E&&|. E8 DD690900& & CALL WINZIP32.004A2280
&&|. 83C4 0C& && &&&ADD ESP,0C
&&|. 85C0& && && & TEST EAX,EAX
&&|. 75 23& && && &JNZ SHORT WINZIP32.0040B8CD
0040B8AA&&|. 8D85 BCFEFFFF&&LEA EAX,DWORD PTR SS:[EBP-144]
&&|. 6A 04& && && &PUSH 4
&&|.50& && && && & PUSHEAX
&&|. 68 20CA4C00& & PUSH WINZIP32.004CCA20& && && && && && &;&&ASCII &0219&
&&|. E8 C3690900& & CALL WINZIP32.004A2280
0040B8BD&&|. 83C4 0C& && &&&ADD ESP,0C
&&|.85C0& && && &&&TEST EAX,EAX
&&|. 75 09& && && &JNZ SHORT WINZIP32.0040B8CD
&&|. C605 EDBF4C00 &MOV BYTE PTR DS:[4CBFED],1
0040B8CB&&|. EB 07& && && &JMP SHORT WINZIP32.
0040B8CD&&|& 8025 EDBF4C00 &AND BYTE PTR DS:[4CBFED],0
&&|&56& && && && & PUSHESI
&&|. 8D85 BCFEFFFF&&LEA EAX,DWORD PTR SS:[EBP-144]
0040B8DB&&|. 6A 00& && && &PUSH 0
0040B8DD&&|.50& && && && & PUSHEAX
0040B8DE&&|. E8 5D810800& & CALL WINZIP32.00493A40
&&|. A0 EDBF4C00& & MOV AL,BYTE PTR DS:[4CBFED]
&&|. 83C4 0C& && &&&ADD ESP,0C
0040B8EB&&|&5F& && && && & POPEDI
0040B8EC&&|. 5E& && && && &POP ESI
0040B8ED&&|.5B& && && && & POPEBX
0040B8EE&&|.C9& && && && &LEAVE
0040B8EF&&\.C3& && && && & RETN整理一下:
注册名:Suunb[CCG]
注册码:71C20EDC or
其实如果你坐在那里肯花上一杯茶的功夫来仔细想一下,就会知道,其实一点儿也不难,只是有一点点麻烦而以
这一章也就到这里吧,我现在巨困无比...
最后说一下的是,现在有仍有N多的软件用的是明码的比较方法,所以,要想找一两个软件练练手还是挺容易的
这一章本来还打算讲一下那些非明码比较的软件的,但忽然发现,如果通过非明码比较的软件能找到注册码的话,那应该也就把它的算法给搞的差不多了,所以,到下一章,分析软件的注册算法时再讲吧...第八章--注册码是怎样炼成的
你应该明白的是,并不是所有的软件作者都像你想象并希望的那笨 没有人愿意自己的软件被别人在调试器中用一条d指令就能找到正确的注册码...要是那样的话还出来搞什么?
前边儿我们讲的查找软件注册码的方法是有针对性的,必须保证的是该软件使用的是明码比较,这样的话,我们只需找对地方,一个d指令就成了。那既然有明码比较这个词,就不难猜出还有相应的非明码比较...非明码比较也比较容易理解,就是软件比较两个注册码的方法不同而以,并不是计算出正确的注册码后就与用户输入的进行比较,它可能会采用每计算出一位就与注码中的相应位比较一次,一但发现与用户输入的不同,就提示出错等等等等...
遇到这样的软件,我们其实也可以找到其相应的注册码,但有点儿惨,要一位一位的计下来...但是如果人家不给你面子,一但计算出某位不正确就跳走的话,那你怎么办?所以,国民想致富,种树是根本...NG!所以遇到这种软件,我们就只有对其算法进行分析,并做出注册机才是唯一的方法(如果你想写注册机的话)...
你要明白,就算我们能找到那些采用明码比较的软件的注册码,原因也仅仅是因为其采用的是明码比较,所以我们没有什么值的高兴的地方,我们真正要做的,并不是找到一个注册码而以...当然如果你刚入门,那对你的提高还是很有帮助的。我们Crack一个软件的最终目的,是对其进行相应的分析,搞懂它的注册算法并写出注册机,这样才算是成功的Crack了一个软件,成功后的[url=]心情[/url]是难以表达的!就像你便秘了多天后一下子排了出来一样 ^_^,呵呵这个比喻虽然粗俗,但是你可以想象一下,对一个软件进行仔细的分析,最后一下把它的算法给搞明白了,那种感觉...我深信不疑的认为有一天你也能体会的到,偶等你
相信你以前看过那些高人大虾的关于软件注册算法分析的文章,同时也相信你有过试图跟踪分析某软件的举动,虽然后来的结果另人不太满意
其实分析一个软件的注册算法,这其中包括了一些技巧性方面的东西以及必要的经验,很难想象一个连调试器的使用都还没掌握的人试图去分析一个软件会是怎样一个场面...嘿嘿,偶是见过的 使用调试器并不难,但那并不意味着你就能去分析一个软件了,见CALL就追这样的举动可不是偶一个人有过的经历,本章我尽量给你说明适当的分析方法。
相信大家都有不在父母陪同下独自使用调试器的能力以及看懂大部分汇编指令的能力了吧,那就够了!我们开始...
正式开始今天的正题,我来举两个例子,相信这两个例子都有足够的表达能力,最起码比我们家楼下那个卖油条的表达能力要强多了...
好的,首先,我们还是请出我们的那位老朋友吧 嘿嘿,在此,偶向CHINAZIP(中华压缩)v7.0的作者表示我内心最真诚的歉意!相信我用这个老版本的中华压缩不会给您带来经济上的麻烦...
通过前边儿两章的讲解,我们已经把这个软件大体上给搞明白了,并且也追出了其相应的注册码。而我们今天的目的是对其注册算法进行分析,并写出注册机!这个软件的注册算法其实也比较简(并且存在Bug)用它来当例子,很能说明情况...
好的,我们开始,前边儿追注册码的时候我们就已经知道了其用于计算正确注册码的关键CALL的所在位置为004f4dde,我们用TRW2000来对其进行分析!(鉴于目前大部分教程中仍以TRW2000为主,而且这个是大多数菜鸟都会用的调试器,偶就用这个调试器来做具体讲解)
先启动CHINAZIP,帮助--注册(所以我才说这个软件非常适合写教程用嘛,注册后仍然中以再次注册)输入注册名Suunb[CCG],注册码。之看按Ctrl+N呼出TRW2000,下断点bpx 004f4dde,F5返回。
接着就按确定吧,呵呵,被TRW2000拦到了。通过前边两章的分析,我们以经知道了004f4dde处的这个CALL用于计算正确的注册码,所以我们直接按F8跟进吧!注册码的算法,就包涵在这个CALL中,把它给分析透了,我们也就能弄明白软件的注册码是怎样生成的了。但是要怎么分析呢?这是一个比较严肃的问题,面对那一堆堆的指令,我不知道你是怎么想的,反正我第一次时是觉的找不着北,我怎么哪些重要哪些不重要呢?再说了,里面又包涵了那么多CALL,我还要一个一个地追进去看看?
呵呵,这就是我说的技巧所在了。其实也没什么可怕的,只要你汇编不是问题,就行了。我们首先可以先把这个计算注册码的CALL从头到尾执行一遍,搞明白其中大概的跳转以及其中某些CALL的作用,hehe~~你可以执行过一个CALL后就看一下各个寄存器的变化情况(如果寄存器中的值改变了,颜色就会变)如果某寄存器的值在CALL过之后改变了,我们就可以看一下其包含的值是何类型,如是内存地址就用d指令看一下,如是数值就看一下是不是得到你输入注册名或注册码的位数等等,这样的话就可以淘汰下来一大部分的CALL,因为有许多CALL的作用只是把注册名或注册码装入到内存中的某个地址或者得到注册名(注册码)的位数或注册码某一位的ASCII码,对与这些,我们不必深究。还是推荐你用Ollydbg,执行过一条指令后很多信息都可以看到 好的,我接着说,按F8追入CALL之后先大概走一遍...我给出追入后的反汇编代码,并给出注释,相应的分析看后面...
fac push ebp &--F8跟入后的第一条指令
fad mov ebp,esp
faf push byte +00
fb1 push byte +00
fb3 push byte +00
fb5 push byte +00
fb7 push byte +00
fb9 push byte +00
fbb push byte +00
fbd push ebx
fbe push esi
fbf push edi
fc0 mov [ebp-08],ecx
fc3 mov [ebp-04],edx
fc6 mov eax,[ebp-04]
fce xor eax,eax
fd0 push ebp
fd1 push dword 004f5097
fd6 push dword [fs:eax]
fd9 mov [fs:eax],esp
fdc xor esi,esi
fde lea eax,[ebp-0c]
fe1 mov edx,[ebp-04]
fe4 call 00403e24 &--此CALL过后用于得到用户输入的注册名
fe9 mov eax,[ebp-0c] &--将得到的注册名的地址装用eax寄存器
fec call 0040400c &--此CALL用于得到用户输入的注册名的位数,并将其放入eax中
ff1 mov edi,eax &--将注册名的位数装入edi中
ff3 test edi,edi &--对edi进行测试
ff5 jng 004f5051 &--如果edi中的值为0就会跳走
ff7 mov ebx,01 &--ebx置1,用于后面的运算
ffc mov eax,[ebp-0c] &--ebp-0c中装的是注册名的内存地址,此时将其付于eax
fff mov al,[eax+ebx-01] &--eax中此时装的是注册名的内存地址,加上ebx中的值再减去01,用于得到注册码中的相应位的字符,比如说我们第一次执行到这里的时候ebx中装入的是01,再减去01后得到的值其实还是eax本身,这样就能得到注册名中的第一个字符了,而执行到后边再跳回来时ebx会加上1,所以就能得到下一个字符了...
3 call 004f4f60 &--这个CALL很重要,后面会说明我们是怎样知道它很重要的
8 test al,al &--在这里我们会发现一个测试运算,对象是al,而al在前边CALL之前刚装入了注册名中的某一个字符,所以我们可以断定上面的那个CALL会对得到的字符做上一些手脚,待会儿我们再跟入...
a jz 004f5031 &--如果al中装的是0就跳到004f5031处,而al中的值会被004f5003处的那个CALL所改变
c lea eax,[ebp-18]
f mov edx,[ebp-0c] &--ebp-0c中装的是注册名的内存地址,此时装入edx中
2 mov dl,[edx+ebx-01] &--跟前边儿004f4fff处的指令道理相同,得到注册码中的当前参加运算的字符
6 call 00403f34 &--不重要!!
b mov eax,[ebp-18]
e lea edx,[ebp-14]
1 call 004088ac &--不重要!!
6 mov edx,[ebp-14]
9 lea eax,[ebp-10]
&--该CALL同样比较重要,其作用是这样的,如果当前参加运算的字符在前边004f5003的CALL里进行运算之后符合了要求(符合要求后al会被置非0值)那么在004f500a处的跳转将会失去作用,而执行到这里后该CALL会将当前的这个符合要求的字符保存到00D3B3C4处(内存)!!后边儿会再详细说明
1 cmp ebx,byte +01 &--用此时ebx中装的值减去1
4 jz 004f5040 &--如果为零,也就是说此时计算的是注册名中的第一个字符的话就跳到004f5040处
6 mov eax,[ebp-0c] &--ebp-0c中装的是注册名的内存地址,该指令将注册名的内存地址装入eax中
9 movzx eax,byte [eax+ebx-02] &--用于得到上一个参加运算的字符
e jmp short 004f5046 &--无条件跳转到004f5046处
0 mov eax,[ebp-0c] &--ebp-0c中装的是注册名的内存地址
3 movzx eax,byte [eax] &--得到注册名的第一个字符
6 lea esi,[esi+eax*4+a8] &--!!!这一条指令就是关键所在,后面会说明的!!!此指令先得到本轮参加运算的字符的ASCII码,然后乘以6,之后再加上a8(即十进制数168,呵呵,可以理解)同时再将这个字符计算得到的值与前面已经运算过的字符的值的和相加!
d inc ebx &--ebx加1,用于得到注册码的下一个字符
e dec edi &--edi减1,edi中装的是注册码的位数
f jnz 004f4ffc &--不为零就跳到004f4ffc处开始对下一个字符进行运算...也就是说每计算完一个字符就将edi减去1,直到其为0也就是所有的字符全参加过运算为止。
1 lea edx,[ebp-1c] &--把装注册码后半部分的地址装入edx,传给下面的CALL
4 mov eax,esi &--将前面计算的注册码的后半部分的值装入eax中
6 call 00408c70 &--将前面计算得到的注册码后半部分的值转换为十进制,并装入ebp-1c中
b mov ecx,[ebp-1c] &--epb-1c中装的是注册码的后半部分
e lea eax,[ebp-0c]
1 mov edx,[ebp-10] &--ebp-10中装的是注册码的前半部分
&--该CALL用于将前后两部分注册码合并置一起,合并后的注册码会存放置ebp-0c处
9 mov eax,[ebp-08]
c mov edx,[ebp-0c]
f call 00403de0
4 xor eax,eax
9 mov [fs:eax],edx
c push dword 004f509e
1 lea eax,[ebp-1c]
4 mov edx,05
9 call 00403db0
e lea eax,[ebp-04]
1 call 00403d8c
呵呵,看了我加了注释后的代码是不是好理解多了?你也许会问,你怎么知道那些CALL是做什么的?我前边儿不是说过方法了吗?我们先大概地过上一遍,看一下各个跳转,然后再大大概的看一下各个CALL的作用...你以为上面这些注释是我过一遍之后就能写出来的?你多过几遍,心中就会有了个大概...
你现在在想些什么?众人:站着说话不腰痛...我晕~~
呵呵,我尽量说的仔细一些:
其实很好理解的,我们追了进来,之后大概的看一下那些个CALL,其中一些稍有经验的一看就知道是用来得到注册名或长度什么的...之后我们再从头跟一遍...跟到004f4ff3处,会发现其会对注册名的位数进行一个比较,看用户是否输入了注册名...(也就是说如果edi中装的注册名的位数不大于0,即没输入就跳走,一会儿我会在后面说一下关于这点儿的Bug)而后在004f4ffc处我们会发现软件会得到注册名的内存地址,接下来的一条指令一看就知道是用来得到注册名中的各个字符的,嘿嘿,见到这类指令,马上就向下看吧,找一下下边儿哪条指令会再跳回到004f4ffc处...呵呵,我们会在004f504f处发现目标,好了,现在我们就知道了从004f4ffc到004f504f之间的那些个指令会对注册名中的每一个字符进行计算...
呵呵,也就是说软件从004f4ffc处开始先是得到注册名中的第N位字符,然后进行一系列的运算,之后执行到了004f504e处时把先前先到的注册名的位数减去1然后看其是否为0,不为0就再跳到004f4ffc处,然后得以注册名的N+1位再来进行计算。此举的目的就是为了看注册名的各位是否都被计算过了,如果不为0就说明还没有计算完,呵呵,很简单的道理嘛,edi中装的是注册名的位数,第计算过一位后就将其减1,减完了,注册名的各位也就都参加了运算...
好的,我们再来看具体的算法部分:
在004f4ff5的跳转,如果你输入了注册名,其就不会跳走...偶输入的是Suunb[CCG],好的,此时会继续执行到004f4ff7处,该指令对ebx进行初始化...给它付1,然后在004f4ffc处时会将ebp-0c中装的注册名的内存地址装入eax中,接着的004f4fff处用于得到注册名的第一个字符,并将其装入al。想象一下,eax中装的是注册名的内存地址,从该地址开始连续10个内存单元是我们输入的注册名S u u n b [ C C G ] 呵呵,明白了吗?eax中装的内存地址就是注册名在内存中的首地址,第一次执行到这里时ebx中装的是1,eax+ebx-01后得到的还是注册名的首地址,也就是S。而等到后面004f504f处的跳转指令跳转回来之前,会在004f504d处有一条inc指令会给ebx加1,这样的话再执行到这里时就会得到注册名中的第2个字符u了,嘿嘿,第三次来之前会再给ebx加上1,明白了吗?总知你可以把ebx中的值理解为当前参加运算的字符在注册名中的位数,即ebx是1就是得到注册名的第一位(S),如果ebx是2就是得到注册名的第2位(u).
而后紧接着在004f5003处会有一个CALL等着我们,呵呵,这个CALL比较关键,注册码的一部份由它来决定,要发现它的重要性并不难,因为在004f5003处下面会有一个跳转,跳转之前会对al进行测试,嘿嘿,而al在CALL之前装入的是当前参与运算的字符...并且你用调试器过一下这个CALL就会发现其对al进行了修改,呵呵,这个CALL会对al做一些处理,而处理的结果直接影响了后面部分的流程,所以,对于它,我们一定要跟进...最好能派出两个人在边路对其进行防守,并找专门的后位对其盯梢...
我们待会儿再跟进它,现在还是要先搞明白软件大体上的算法。好的,我接着说,在004f5008处对al进行了测试之后会有一个跳转,即如果al中此时装的值为0就跳到004f5031处去...你可以理解为这个CALL会对字符进行一些运算,如果符合了要求,al就会被置0或1什么的,出来后的测试用来判断当前字符是否符合要求,如果符合就跳或不符合就跳...
继续,由于我输入的注册名的第一个字符是S,而S刚好能通过004f5003处的那个CALL的计算 所以就没有跳走,我继续按F10进行单步执行...接下来的004f500c、004f500f、004f5012这三条指令跟前边儿的得到注册码第N位字符的指令道理是一样的,你看注释好了...而后面从004f29处的这几条指令也没什么好讲的,对中间的两个CALL好奇的话可以进去大概看一下。得不到什么实质性的东西...而004f502c处的这个CALL嘛,就很重要了,呵呵,它的作用是什么呢?还记的我刚才说过的004f5003处的那个CALL吧,它执行过后会使al发生变化,它下面的跳转指令会根据al的值做相应跳转,即如果al为0,就跳到004f5031处,刚好就跳过了004f502c处的这个CALL...而我输入的第一个字符是S,刚好符合了004f5003处那个CALL的要求,所以没有跳走,于是就执行到了这里,你可以追进去看一下,里面并不复杂,只是将当前参加运算的字符装入内存的00D3B3C4处(如果当前参加运算的字符在004f5003处没有通过,就不会执行到这里,呵呵,明白过来了吧,这个CALL用于收集注册名中所有符合004f5003处那个CALL要求的字符)
HOHOHO~~(请模仿周星星式的笑声...)现在我们已经明白了一半了...好的,我们继续...
不管你是从004f500a处跳到004f5031处的,还是一步步执行到这里的,总知,不管你输入的注册名中参加当前运算的那一个字符符不符合004f5003处的那个CALL的要求,总知都会执行到这里...这条指令用来干什么呢?还记的ebx中装的是参加运算的字符在注册名中的相应的位数吗?cmp ebx,byte +01 就是用ebx减去1,该条指令的用途也就是看一下当前参加运算的字符是不是注册名中的第一个字符,如果是就跳到 004f5040处,否则继续... 我们先看004f5040处,当执行到此处时,ebp-0c中装的其实是注册名的内存地址(前边就已经说过了)在这里将其装入eax中,而后面004f5043处的指令的用途就是得到注册名的第一个字符...好了,我们再拐回来看004f5036处,如果当前参加运算的字符不是注册名中的第一个字符,就不会跳走,而执行到这里时同样将ebp-0c中装的注册名的内存地址放入eax中,而004f5039处的eax,byte [eax+ebx-02]嘛,呵呵,很好理解,eax+ebx-01得到的是当前参加运算的字符的内存地址,而这里的eax+ebx-02得到的就是当前参加运算的字符的前面的那个字符,了解?
我们接着看004f5046处的那条指令吧,这个同样非常重要,它的作用是计算注册码的后半部分!
我相信你很容易就能理解它的意思了,当执行到这里时,eax中装的或者是注册码中的第一个字符,或者是当前参加运算的字符的前一个字符(注:字符在内存或寄存器中是以ASCII码来表示的,如S在eax中会显示为,而S的ASCII码便是53,十进制为83)...我们第一次执行到这里时,esi中的值为0(即)eax*4+a8的意思就是用当前参加运算的字符的ASCII码乘以4,再用积加上a8(也就是十进制数168,一路发?)再用这个和与esi相加,我已经说过了,第一次执行到这里时esi中的值为0...而当第二次执行到这里时,esi中装的便是注册名的第一个字符的ASCII码乘以4再加一路发的和...
你会问你为什么知道它是计算注册码的后半部分的?猜的!!呵呵,当然不是,我们可以看到,在004f5054处,程序会将前面计算的结果装用eax中,后边儿紧接着就是一个CALL,嘿嘿,光天化日之下,这也太明显了吧,我们追进去大概看一下就知道它的作用是将十六进制的数转换为十进制的...并将转换后的结果装入edx中装的内存地址处,在CALL之前我们会看到edx中的值以由004f5051处装入,即ebp-1c,呵呵,CALL过之后你用d ebp-1c看一下,就会看到你注册码的后半部分了...
而后程序会在004f505b将注册码后半部分装入ecx中,在004f505e处时会将一个内存地址ebp-0c装入eax处(它的作用就是起一个传递参数的作用,在待会儿的CALL中会用eax中装入的值来存放结果)之后的004f5061处会将ebp-10装入edx中,ebp-10处装的是什么呢?我们用d ebp-10指令看一下就会知道它的地址为00D3B3C4,嘿嘿,你的嗅觉敏感吗?不敏感的话我就再说一遍,还记的004f502c处的那个CALL吗?它的作用就是收集符合004f5003处的那个CALL的要求的字符...
嘿嘿,你明白过来了吗?
这个软件的注册算法是这样的:首先得到注册码的位数,看其是否大于0,不大于0就跳到004f5051处...好的,我们输入了Suunb[CCG]这个注册名,此时的注册码位数就是10,所以不会跳走,之后我们会来到004f4fff处,第一次执行到这里时会将注册名的第一个字符S装入al中,第二次来时会将注册名中的第二个字符(即u)装入al中,它的作用就是将当前参加运算的字符装入al中,之后紧接着就是一个CALL,这个CALL会对当前参加运算的字符进行计算...接着出来会有一个跳转,看al中装的是不是0,如果是就跳到004f5031处,如果不是非0值就说明当前这个字符符合了要求,那么就会执行到004f502c处,这里的CALL会将其存放置内存的00D3B3C4处...而后到了004f5031处会有一个比较,作用是看当前参加运算的字符是不是注册名中的第一个字符,是的话就跳到004f5040处,在此将注册名的第一个字符装入eax,用来参加004f5046处的计算。如果当前参加运算的不是注册名的第一个字符,那么就会在执行到004f5039处时得到当前参加运算的字符前面的那个字符,将其装入eax后就无条件跳到004f5046处来参加运算。了解?也就是说你输入的注册名的第一个字符会参加两次计算,而最后一个字符不会参加计算(想想看,如果当前参加运算的字符是注册名中的第一个字符,它会参加计算,如果是第二个,就取前边的一个,即第一个又会参加一次计算,到了第三个的时候取第二个,到了第四个的时候取第三个...而当最后一个字符来到这里时会取前边的那个

我要回帖

更多关于 结界突破最强防守阵容 的文章

 

随机推荐