首页 > 代码库 > 第七章-寻找软件的注册码

第七章-寻找软件的注册码

我们来寻找软件真正的注册码!
寻找软件的注册码就像你小时玩的躲猫猫一样,简单又有趣,虽然后来你会不这样觉的
好的,我们开始。
我不知道你有没有明白我前面在原理中讲的那些东西,如果没明白,我就再说一遍
软件通过你输入的用户名或者机器码什么的生成一个正确的注册码来与你输入的注册码进行比较,如果两个相同,也就是说你输入的注册码是正确的话,那软件就会完成注册。如果你输入的不正确,嘿嘿,当然就不会注册成功。
好的,现在你已经知道软件会有一个比较两个注册码的过程,这就是关键所在。一般如果你遇到的是那种明码比较的软件,这会是一件非常另人愉快的事情的
软件会先计算出正确的注册码然后再与你输入的那个进行比较,也就是说正确的注册码会被软件自己算出来!嘿嘿,搜身你会吗?虽然法律以及道德不允许我们去搜身,但…
我接着说,虽然现在的软件已经比以前要厉害上许多,但,那种用明码比较的,还是大有人在的。所谓明码比较,就是说软件先算出正确的注册码,然后放到内存或你家的沙发下面,之后再得到你输入的那个注册码,接着就比较了。呵呵,好理解吧,我们只要找到那个比较的地方,看一下软件把注册码放到内存的哪里了,再到相应的内存处瞧一瞧,就万事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:19870219
然后请出我们的老伙计TRW2000,下bpx hmemcpy 按F5点确定被拦:
KERNEL?HMEMCPY
0147:9e62 push bp
0147:9e63 mov bp,sp
0147:9e65 push ds
0147:9e66 push edi
0147:9e68 push esi
0147:9e6a cld
0147:9e6b mov ecx,[bp+06]
0147:9e6f jcxz 9ee9
...省略N多代码...
输入bc *,删除断点。pmodule ,直接跳到程序领空:
0167:00436d13 mov [ebx+0c],eax
0167:00436d16 mov eax,[ebx]
0167:00436d18 cmp eax,byte +0c
0167:00436d1b jnz 00436d38
0167:00436d1d mov edx,[ebx+08]
0167:00436d20 push edx
0167:00436d21 mov ecx,[ebx+04]
0167:00436d24 mov edx,eax
0167:00436d26 mov eax,esi
0167:00436d28 call 00432b24
...省略N多代码...
按8下F12就会提示出错,我们第二次就按7次 接着我们再来按F10,按16下就会报错,好的,我们再来:这一次我们按F10的时候,就按我前边说过的方法,到与上次按的次数相差五六次的时候就慢下来。好的,我们按十来下的时候就慢下来仔细瞅瞅,呵呵,一下子就看到004f4dec处的那个跳转以及它上面的关键CALL了 我们按F10单步执行到004f4de7处(即关键CALL处)后下指令d edx就可看到真正的注册码,而d eax则可以看到我刚才输入的19870219 代码给你:
0167:004f4dc4 mov eax,[ebp-08] <---7下F12,1下F10就来到这里(此时ebp-08处放的是刚才输入的注册码19870219)
0167:004f4dc7 push eax <---将EAX压栈;
0167:004f4dc8 lea edx,[ebp-10]
0167:004f4dcb mov eax,[ebx+02e0]
0167:004f4dd1 call 00432f24 <---该CALL用来得到用户输入的用户名,其实就是某个API函数,嘿嘿,好奇的话可以追进去看看
0167:004f4dd6 mov edx,[ebp-10] <---将得到的用户名放入EDX;
0167:004f4dd9 lea ecx,[ebp-0c]
0167:004f4ddc mov eax,ebx
0167:004f4dde call 004f4fac <---该CALL用来计算出真正的注册码;
0167:004f4de3 mov edx,[ebp-0c] <---将计算出的真.注册码放入EDX,在下条指令时可用D EDX查看;
0167:004f4de6 pop eax <---先前压入的注册码出栈;
0167:004f4de7 call 0040411c <---该CALL用来比较两个注册码,罪魁祸首啊!;
0167:004f4dec jnz 004f4e64 <---不相等则跳,跳必死,暴破将75改为74或EB,当然90也行;
0167:004f4dee mov dl,01
0167:004f4df0 mov eax,[00452558]
0167:004f4df5 call 00452658
0167:004f4dfa mov [ebp-04],eax
0167:004f4dfd xor eax,eax
0167:004f4dff push ebp
0167:004f4e00 push dword 004f4e5d
0167:004f4e05 push dword [fs:eax]
0167:004f4e08 mov [fs:eax],esp
0167:004f4e0b mov cl,01
0167:004f4e0d mov edx,004f4ea8
0167:004f4e12 mov eax,[ebp-04]
0167:004f4e15 call 0045283c
0167:004f4e1a mov ecx,004f4ecc
0167:004f4e1f mov edx,004f4ef4
0167:004f4e24 mov eax,[ebp-04]
0167:004f4e27 call 00452c80
0167:004f4e2c mov eax,004f4f00
0167:004f4e31 call 00458b8c
0167:004f4e36 mov eax,[0050306c]
0167:004f4e3b mov eax,[eax]
0167:004f4e3d mov edx,004f4f24
0167:004f4e42 call 00432f54
0167:004f4e47 xor eax,eax
0167:004f4e49 pop edx
0167:004f4e4a pop ecx
0167:004f4e4b pop ecx
0167:004f4e4c mov [fs:eax],edx
0167:004f4e4f push dword 004f4e6e
0167:004f4e54 mov eax,[ebp-04]
0167:004f4e57 call 004030c4
0167:004f4e5c ret
0167:004f4e5d jmp 00403824
0167:004f4e62 jmp short 004f4e54
0167:004f4e64 mov eax,004f4f48 <---由上面的0167:004f4dec处跳来,挂!;
0167:004f4e69 call 00458b8c
0167:004f4e6e xor eax,eax
整理:
Name:Suunb[CCG]
Code:SCCG5296
可以真接在TRW2000中下断点bpx 004f4de6,中断后用D EDX来查看真.注册码。
另附:CRACKCODE2000的CRACKCODE.INI
[Options]
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种变换桌面的方式,让你的桌面焕然一新。操作简单,无需费力学习。支持多种Internet流行图片格式。将壁纸文件打包,方便存储、转发。将壁纸包展开,还原图片文件。
嘿嘿,我也懒的去折腾我的小猫了,咱们就还用电脑报2001年合订本配套光盘上的软件吧 (2002年的偶没有买)
首先装上它(嘿嘿,你习惯了?为什么不丢东西了? ^_^)运行一下该软件先,该软件自动生成了相应的机器码,并停留在注册项上,输入注册码19870219,点确定,挂!
用fi检查,该软件为Delphi编译,没加壳。
用W32DASM打开该执行文件,参考-串式参考,在最下边,见到了刚才弹出的"注册码不正确,请联系作者"。
用鼠标双击,发现只有一处调用,在00488E97处,接着在串式参考对话框中在"注册码不正确,请联系作者"处向上找,找到"感谢您支持国产软件,祝您好运"(说的我都不好意思了)
用鼠标双击,仍旧只有一处调用,在00488DF7处:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00488DCD(U)
|
:00488DD9 8B45FC mov eax, dword ptr [ebp-04]
:00488DDC 8B8020040000 mov eax, dword ptr [eax+00000420]
:00488DE2 35280BB61E xor eax, 1EB60B28
:00488DE7 3B45F8 cmp eax, dword ptr [ebp-08] <---关键比较,? EAX来查看软件正确的注册码;
:00488DEA 0F85A0000000 jne 00488E90 <---关键跳转,不相等就跳,跳必挂!
:00488DF0 6A40 push 00000040

* Possible StringData Ref from Code Obj ->"注册成功"
|
:00488DF2 68D48E4800 push 00488ED4

* Possible StringData Ref from Code Obj ->"感谢您支持国产软件,祝您好运!"
|
:00488DF7 68E08E4800 push 00488EE0 <---双击串式参考便跳到此行,我们向上找第一个跳转处就是关键跳转,关键跳转上面就是关键比较;
:00488DFC 8B45FC mov eax, dword ptr [ebp-04]
:00488DFF E81CD2FBFF call 00446020
:00488E04 50 push eax
...省略代码若干...
向上看,00488DEA处有一跳转,不相等便跳到00488E90处,跳必挂!还记的00488E97处的出错对话框吧! 罪魁祸首啊!
在向上一行,看00488DE7处:cmp eax, dword ptr [ebp-08],此为关键比较。可用? EAX查看软件正确的注册码。
整理:
打开该软件,在注册码处输入19870219,打开TRW2000,下断点bpx 00488DE7,点注册被拦。输入? EAX得到软件正确的注册码。
机器码:533226313
注册码:25061473
用注册机编写器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这个魅力比你家的荼几还大的调试器
这里之所以提到Ollydbg,是觉的它真是一个非常非常棒的调试器...强烈建议你多玩几次...(MP3好听吗? ^_^)
我们来吧,首先当然还是要装上它(左闪术,右闪术),然后用Ollydbg来载入,此时界面会被分成四个部分,左上方是软件反汇编后的代码,右上方是寄存器开会的地方,左下方是内存区,右下方显示的则是堆栈的信息。
我们来下断点,按Alt+F4,之后选USER32,然后再鼠标右键-->搜索-->当前模块中的名称,然后在那一大堆函数中找到GetDlgItemTextA,按F2来下断点,它会提示你错误,并说无法设置中断点,是不是很过瘾?(呜呜呜...大哥,我错了,再也不敢了...)
呵呵,这个我也不知道什么原因,明明是用了这个函数嘛,就是不让断,其实我对Ollydbg也不是太那个(关键是讨厌它的下断方式)看来还是用我们的万能断点吧,输入注册名Suunb[CCG],输入注册码19870219,然后用TRW2000下断bpx hmemcpy,断到之后,pmodule返回领空后一次F12就会出错,看来所有的东东就在这里了...
我们用TRW2000再断一下,返回领空之后记着第一条指令的地址0040bd5f,呜呜呜...上条指令明明是调用GetDlgItemTextA,为什么在Ollydbg中不让下呢?
没关系,我们记下这个地址后仍旧用Ollydbg来加载程序,之后在反汇编窗口中找到0040bd5f处,然后按下F2来下断(会变为红色),下断之后便按F9来运行程序,接着输入注册名Suunb[CCG],注册码19870219后按确定,程序会被Ollydbg给断到:
0040BD5F |. 57 PUSH EDI
0040BD60 |. E8 F34A0500 CALL WINZIP32.00460858
0040BD65 |. 57 PUSH EDI ; /Arg1
0040BD66 |. E8 164B0500 CALL WINZIP32.00460881 ; \WINZIP32.00460881
0040BD6B |. 59 POP ECX
0040BD6C |. BE 1CCA4C00 MOV ESI,WINZIP32.004CCA1C
0040BD71 |. 59 POP ECX
0040BD72 |. 6A 0B PUSH 0B ; /Count = B (11.)
0040BD74 |. 56 PUSH ESI ; |Buffer => WINZIP32.004CCA1C
0040BD75 |. 68 810C0000 PUSH 0C81 ; |ControlID = C81 (3201.)
0040BD7A |. 53 PUSH EBX ; |hWnd
0040BD7B |. FF15 F4C54A00 CALL DWORD PTR DS:[<&USER32.GetDlgItemTe>; \GetDlgItemTextA
0040BD81 |. 56 PUSH ESI
0040BD82 |. E8 D14A0500 CALL WINZIP32.00460858
0040BD87 |. 56 PUSH ESI
0040BD88 |. E8 F44A0500 CALL WINZIP32.00460881
0040BD8D |. 803D F0C94C00 >CMP BYTE PTR DS:[4CC9F0],0
0040BD94 |. 59 POP ECX
0040BD95 |. 59 POP ECX
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 CALL WINZIP32.0040B6D7 <--关键CALL,等会儿进去玩玩
0040BDA6 |. 84C0 TEST AL,AL <--根据关键CALL中比较的结果来做相应的测试
0040BDA8 |. 74 4D JE SHORT WINZIP32.0040BDF7 <--跳走就没戏!
0040BDAA |. 57 PUSH EDI
0040BDAB |. 68 08DE4B00 PUSH WINZIP32.004BDE08 ; ASCII "Name"
0040BDB0 |. FF35 1CC74A00 PUSH DWORD PTR DS:[4AC71C] ; WINZIP32.004BDDEC
0040BDB6 |. E8 8AFA0400 CALL WINZIP32.0045B845
0040BDBB |. 56 PUSH ESI
0040BDBC |. 68 C8EB4B00 PUSH WINZIP32.004BEBC8 ; ASCII "SN"
0040BDC1 |. FF35 1CC74A00 PUSH DWORD PTR DS:[4AC71C] ; WINZIP32.004BDDEC
0040BDC7 |. E8 79FA0400 CALL WINZIP32.0045B845
0040BDCC |. FF35 18C74A00 PUSH DWORD PTR DS:[4AC718] ; |Arg4 = 004BDDF4 ASCII "winzip32.ini"
0040BDD2 |. 6A 00 PUSH 0 ; |Arg3 = 00000000
0040BDD4 |. 6A 00 PUSH 0 ; |Arg2 = 00000000
0040BDD6 |. 68 14DE4B00 PUSH WINZIP32.004BDE14 ; |Arg1 = 004BDE14 ASCII "rrs"
0040BDDB |. E8 4CFA0400 CALL WINZIP32.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 PUSH EAX ; /hObject => 000013F4 (font)
0040BDED |. FF15 80C04A00 CALL DWORD PTR DS:[<&GDI32.DeleteObject>>; \DeleteObject
0040BDF3 |> 6A 01 PUSH 1
0040BDF5 |. EB 30 JMP SHORT WINZIP32.0040BE27
0040BDF7 |> E8 C3020000 CALL WINZIP32.0040C0BF
0040BDFC |. 68 8E020000 PUSH 28E
0040BE01 |. E8 61470500 CALL WINZIP32.00460567
0040BE06 |. 50 PUSH EAX ; |Arg3
0040BE07 |. 53 PUSH EBX ; |Arg2
0040BE08 |. 6A 3D PUSH 3D ; |Arg1 = 0000003D
0040BE0A |. E8 C8050400 CALL WINZIP32.0044C3D7 ; \WINZIP32.0044C3D7

我们用Ollydbg断到之后,可以像在TRW2000中一样通过F8(这个调试器跟我一样,也不喜欢F4^_^)来单步执行程序,我们按32下F8后程序就会出错,那我们在第二遍载入时按F8按到20多下时就仔细看看有没有可疑的地方,你一眼就可以看到0040BDA1处的这个关键CALL,我们只要追到这里时追进去就有可能看到软件正确的注册码
那还等什么呢?我们就进去吧...
按F7跟进后你会看的眼花眼花缭乱,到处都是PUSH跟POP,到底哪个才是呢?现在知道我为什么让你用Ollydbg了吧(偶起初也是要用TRW2000的,但临时改变主意 ^_^)用Ollydbg的一个最大好处就是可以真接看到寄存器中的值,特别是你通过F8来单步执行的时候,在反汇编代码的下边,会有一个小窗体,在那里可以显示相关指令中所使用的寄存器的值,爽吧!
我们按76下F8之后,在0040B803处就可以第一次看到正确的注册码了,呵呵,我这边儿是71C20EDC,然后你还会再陆续看到几次,爽?
另外我还发现一个有趣的事情,在WinZIP8.1中,一个注册名可以有两个注册码,呵呵,不知道是不是还有为特别用户准备的特别注册码以用来和普通的做区别 当程序通过比较,发现你输入的注册码不正确后竟然会再次算出另一个注册码来再比较一次,嘿嘿,我的第二个注册码是25170288
追入关键CALL里的代码:
0040B6D7 /$ 55 PUSH EBP
0040B6D8 |. 8BEC MOV EBP,ESP
0040B6DA |. 81EC 0C020000 SUB ESP,20C
0040B6E0 |. 8065 FF 00 AND BYTE PTR SS:[EBP-1],0
0040B6E4 |. 803D F0C94C00 >CMP BYTE PTR DS:[4CC9F0],0
0040B6EB |. 53 PUSH EBX
0040B6EC |. 56 PUSH ESI
0040B6ED |. 57 PUSH EDI
0040B6EE |. 0F84 FB000000 JE WINZIP32.0040B7EF
0040B6F4 |. 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18]
0040B6F7 |. 50 PUSH EAX
0040B6F8 |. 68 C0E84B00 PUSH WINZIP32.004BE8C0
0040B6FD |. E8 DE61FFFF CALL WINZIP32.004018E0
0040B702 |. 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18]
0040B705 |. 50 PUSH EAX
0040B706 |. E8 F57C0800 CALL WINZIP32.00493400
0040B70B |. 83C4 0C ADD ESP,0C
0040B70E |. 83F8 14 CMP EAX,14
0040B711 |. 72 11 JB SHORT WINZIP32.0040B724
0040B713 |. BF 20C74A00 MOV EDI,WINZIP32.004AC720 ; ASCII "auth.c"
0040B718 |. 6A 21 PUSH 21
0040B71A |. 57 PUSH EDI
0040B71B |. E8 86F60000 CALL WINZIP32.0041ADA6
0040B720 |. 59 POP ECX
0040B721 |. 59 POP ECX
0040B722 |. EB 05 JMP SHORT WINZIP32.0040B729
0040B724 |> BF 20C74A00 MOV EDI,WINZIP32.004AC720 ; ASCII "auth.c"
0040B729 |> 8D85 F4FDFFFF LEA EAX,DWORD PTR SS:[EBP-20C]
0040B72F |. BB F0C94C00 MOV EBX,WINZIP32.004CC9F0 ; ASCII "Suunb[CCG]"
0040B734 |. 50 PUSH EAX
0040B735 |. 53 PUSH EBX
0040B736 |. E8 50030000 CALL WINZIP32.0040BA8B
0040B73B |. 8D85 F4FDFFFF LEA EAX,DWORD PTR SS:[EBP-20C]
0040B741 |. 50 PUSH EAX
0040B742 |. E8 B97C0800 CALL WINZIP32.00493400
0040B747 |. BE C8000000 MOV ESI,0C8
0040B74C |. 83C4 0C ADD ESP,0C
0040B74F |. 3BC6 CMP EAX,ESI
0040B751 |. 72 0A JB SHORT WINZIP32.0040B75D
0040B753 |. 6A 23 PUSH 23
0040B755 |. 57 PUSH EDI
0040B756 |. E8 4BF60000 CALL WINZIP32.0041ADA6
0040B75B |. 59 POP ECX
0040B75C |. 59 POP ECX
0040B75D |> 8D85 F4FDFFFF LEA EAX,DWORD PTR SS:[EBP-20C]
0040B763 |. 50 PUSH EAX
0040B764 |. 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18]
0040B767 |. 50 PUSH EAX
0040B768 |. E8 03300900 CALL WINZIP32.0049E770
0040B76D |. 59 POP ECX
0040B76E |. 85C0 TEST EAX,EAX
0040B770 |. 59 POP ECX
0040B771 |. 75 04 JNZ SHORT WINZIP32.0040B777
0040B773 |. C645 FF 01 MOV BYTE PTR SS:[EBP-1],1
0040B777 |> 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18]
0040B77A |. 50 PUSH EAX
0040B77B |. 68 D0E84B00 PUSH WINZIP32.004BE8D0
0040B780 |. E8 5B61FFFF CALL WINZIP32.004018E0
0040B785 |. 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18]
0040B788 |. 50 PUSH EAX
0040B789 |. E8 727C0800 CALL WINZIP32.00493400
0040B78E |. 83C4 0C ADD ESP,0C
0040B791 |. 83F8 14 CMP EAX,14
0040B794 |. 72 0A JB SHORT WINZIP32.0040B7A0
0040B796 |. 6A 27 PUSH 27
0040B798 |. 57 PUSH EDI
0040B799 |. E8 08F60000 CALL WINZIP32.0041ADA6
0040B79E |. 59 POP ECX
0040B79F |. 59 POP ECX
0040B7A0 |> 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18]
0040B7A3 |. 50 PUSH EAX
0040B7A4 |. 53 PUSH EBX
0040B7A5 |. E8 C62F0900 CALL WINZIP32.0049E770
0040B7AA |. 59 POP ECX
0040B7AB |. 85C0 TEST EAX,EAX
0040B7AD |. 59 POP ECX
0040B7AE |. 75 0E JNZ SHORT WINZIP32.0040B7BE
0040B7B0 |. FF15 F0C14A00 CALL DWORD PTR DS:[<&KERNEL32.GetTickCou>; [GetTickCount
0040B7B6 |. A8 01 TEST AL,1
0040B7B8 |. 74 04 JE SHORT WINZIP32.0040B7BE
0040B7BA |. C645 FF 01 MOV BYTE PTR SS:[EBP-1],1
0040B7BE |> 6A 14 PUSH 14
0040B7C0 |. 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18]
0040B7C3 |. 6A 00 PUSH 0
0040B7C5 |. 50 PUSH EAX
0040B7C6 |. E8 75820800 CALL WINZIP32.00493A40
0040B7CB |. 56 PUSH ESI
0040B7CC |. 8D85 F4FDFFFF LEA EAX,DWORD PTR SS:[EBP-20C]
0040B7D2 |. 6A 00 PUSH 0
0040B7D4 |. 50 PUSH EAX
0040B7D5 |. E8 66820800 CALL WINZIP32.00493A40
0040B7DA |. 83C4 18 ADD ESP,18
0040B7DD |. 807D FF 00 CMP BYTE PTR SS:[EBP-1],0
0040B7E1 |. 74 13 JE SHORT WINZIP32.0040B7F6
0040B7E3 |. E8 D7080000 CALL WINZIP32.0040C0BF
0040B7E8 |. 8025 EDBF4C00 >AND BYTE PTR DS:[4CBFED],0
0040B7EF |> 32C0 XOR AL,AL
0040B7F1 |. E9 F5000000 JMP WINZIP32.0040B8EB
0040B7F6 |> 8D85 BCFEFFFF LEA EAX,DWORD PTR SS:[EBP-144]
0040B7FC |. 50 PUSH EAX
0040B7FD |. 53 PUSH EBX
0040B7FE |. E8 ED000000 CALL WINZIP32.0040B8F0 <--参与计算软正确的注册码
0040B803 |. 8D85 BCFEFFFF LEA EAX,DWORD PTR SS:[EBP-144] <--在这里第一次发现软件正确的注册码
0040B809 |. 50 PUSH EAX
0040B80A |. E8 F17B0800 CALL WINZIP32.00493400
0040B80F |. BE 2C010000 MOV ESI,12C
0040B814 |. 83C4 0C ADD ESP,0C
0040B817 |. 3BC6 CMP EAX,ESI
0040B819 |. 72 0A JB SHORT WINZIP32.0040B825
0040B81B |. 6A 39 PUSH 39
0040B81D |. 57 PUSH EDI
0040B81E |. E8 83F50000 CALL WINZIP32.0041ADA6
0040B823 |. 59 POP ECX
0040B824 |. 59 POP ECX
0040B825 |> BF 1CCA4C00 MOV EDI,WINZIP32.004CCA1C ; ASCII "19870219" <--将刚才输入的错误的注册码放入EDI
0040B82A |. 8D85 BCFEFFFF LEA EAX,DWORD PTR SS:[EBP-144] <--EAX中装入正确的注册码所在的地址
0040B830 |. 57 PUSH EDI <--用户输入的注册码入栈
0040B831 |. 50 PUSH EAX <--软件计算出的正确的注册码入栈
0040B832 |. E8 392F0900 CALL WINZIP32.0049E770 <--关键CALL,用于比较用户输入的注册码
0040B837 |. F7D8 NEG EAX
0040B839 |. 1AC0 SBB AL,AL
0040B83B |. 59 POP ECX
0040B83C |. FEC0 INC AL
0040B83E |. 59 POP ECX
0040B83F |. A2 EDBF4C00 MOV BYTE PTR DS:[4CBFED],AL
0040B844 |. 0F85 8A000000 JNZ WINZIP32.0040B8D4
0040B84A |. 8D85 BCFEFFFF LEA EAX,DWORD PTR SS:[EBP-144]
0040B850 |. 50 PUSH EAX
0040B851 |. 53 PUSH EBX
0040B852 |. E8 33010000 CALL WINZIP32.0040B98A <--参与计算软件的第二个注册码
0040B857 |. 8D85 BCFEFFFF LEA EAX,DWORD PTR SS:[EBP-144] <--此时软件会再算出另外一个注册码
0040B85D |. 50 PUSH EAX
0040B85E |. E8 9D7B0800 CALL WINZIP32.00493400
0040B863 |. 83C4 0C ADD ESP,0C
0040B866 |. 3BC6 CMP EAX,ESI
0040B868 |. 72 0E JB SHORT WINZIP32.0040B878
0040B86A |. 6A 3E PUSH 3E
0040B86C |. 68 20C74A00 PUSH WINZIP32.004AC720 ; ASCII "auth.c"
0040B871 |. E8 30F50000 CALL WINZIP32.0041ADA6
0040B876 |. 59 POP ECX
0040B877 |. 59 POP ECX
0040B878 |> 8D85 BCFEFFFF LEA EAX,DWORD PTR SS:[EBP-144] <--软件计算出的第二个注册码装入EAX中
0040B87E |. 57 PUSH EDI <--用户输入的注册码入栈
0040B87F |. 50 PUSH EAX <--软件计算出的第二个注册码入栈
0040B880 |. E8 EB2E0900 CALL WINZIP32.0049E770 <--另一个关键CALL,用于比较第二次生成的注册码
0040B885 |. F7D8 NEG EAX
0040B887 |. 1AC0 SBB AL,AL
0040B889 |. 59 POP ECX
0040B88A |. FEC0 INC AL
0040B88C |. 59 POP ECX
0040B88D |. A2 EDBF4C00 MOV BYTE PTR DS:[4CBFED],AL
0040B892 |. 75 40 JNZ SHORT WINZIP32.0040B8D4
0040B894 |. 8D85 C0FEFFFF LEA EAX,DWORD PTR SS:[EBP-140]
0040B89A |. 6A 04 PUSH 4
0040B89C |. 50 PUSH EAX
0040B89D |. 57 PUSH EDI
0040B89E |. E8 DD690900 CALL WINZIP32.004A2280
0040B8A3 |. 83C4 0C ADD ESP,0C
0040B8A6 |. 85C0 TEST EAX,EAX
0040B8A8 |. 75 23 JNZ SHORT WINZIP32.0040B8CD
0040B8AA |. 8D85 BCFEFFFF LEA EAX,DWORD PTR SS:[EBP-144]
0040B8B0 |. 6A 04 PUSH 4
0040B8B2 |. 50 PUSH EAX
0040B8B3 |. 68 20CA4C00 PUSH WINZIP32.004CCA20 ; ASCII "0219"
0040B8B8 |. E8 C3690900 CALL WINZIP32.004A2280
0040B8BD |. 83C4 0C ADD ESP,0C
0040B8C0 |. 85C0 TEST EAX,EAX
0040B8C2 |. 75 09 JNZ SHORT WINZIP32.0040B8CD
0040B8C4 |. C605 EDBF4C00 >MOV BYTE PTR DS:[4CBFED],1
0040B8CB |. EB 07 JMP SHORT WINZIP32.0040B8D4
0040B8CD |> 8025 EDBF4C00 >AND BYTE PTR DS:[4CBFED],0
0040B8D4 |> 56 PUSH ESI
0040B8D5 |. 8D85 BCFEFFFF LEA EAX,DWORD PTR SS:[EBP-144]
0040B8DB |. 6A 00 PUSH 0
0040B8DD |. 50 PUSH EAX
0040B8DE |. E8 5D810800 CALL WINZIP32.00493A40
0040B8E3 |. A0 EDBF4C00 MOV AL,BYTE PTR DS:[4CBFED]
0040B8E8 |. 83C4 0C ADD ESP,0C
0040B8EB |> 5F POP EDI
0040B8EC |. 5E POP ESI
0040B8ED |. 5B POP EBX
0040B8EE |. C9 LEAVE
0040B8EF \. C3 RETN

整理一下:
注册名:Suunb[CCG]
注册码:71C20EDC or 25170288
其实如果你坐在那里肯花上一杯茶的功夫来仔细想一下,就会知道,其实一点儿也不难,只是有一点点麻烦而以
这一章也就到这里吧,我现在巨困无比...
最后说一下的是,现在有仍有N多的软件用的是明码的比较方法,所以,要想找一两个软件练练手还是挺容易的
这一章本来还打算讲一下那些非明码比较的软件的,但忽然发现,如果通过非明码比较的软件能找到注册码的话,那应该也就把它的算法给搞的差不多了,所以,到下一章,分析软件的注册算法时再讲吧...
<本章完>