社区应用 最新帖子 精华区 社区服务 会员列表 统计排行
  • 2918阅读
  • 3回复

破解之算法教学系列课程

楼层直达
级别: 光盘中级
发帖
237
飞翔币
335
威望
363
飞扬币
708
信誉值
0
最近学破解,找到一个资料,大家分享!大家不要跟帖,因为要随时添加课程!

算法教学第一课

掌握算法最基本的是用户名取abcde,其相应ascii码是61,62,63,64,65 (16进制),这些一定要牢记于心。你在各个调试软件中所看到的寄存器值都是16进制的。切记不要见到 call就进入。若经过某个call,发现用户名变成ABCDE,其ascii码是41,42,43,44,45 (16进制),那么此call的作用就是小写转大写,再追入此call就显得多此一举了。
找到算法关键的一段循环或进入关键call,这时开始警觉,慢慢跟踪,单步追踪时时刻留意和观察各个寄存器的变化,主要是eax,ebx,ecx,edx。下面一段是典型的计算注册码的循环。
由于OllyDbg的布局设计,使用它观察注册算法比TRW更为清晰、流畅。
在某个寄存器中已存放着用户名字符的个数
111111 movsx XXXX,XXXXX 依次取用户名
.................
inc ecx ecx是计数器
...............
cmp xxxx,xxxx 比较用户名是否取完
jl或jg 111111 没有取完就跳回去取完就向下走
当你看到某个寄存器中61,62,63,64,65周期性出现时,就会发现循环开始了,
算法就在这一块了,分析和检查出它的算法流程吧,其实一切并不难,祝:早日成功!

[ 本帖最后由 一帆风 于 2006-6-4 00:05 编辑 ]
 
级别: 光盘中级
发帖
237
飞翔币
335
威望
363
飞扬币
708
信誉值
0
只看该作者 3 发表于: 2006-06-04
算法教学第四课

例一xx软件(这里不提供)
用户名输入abcd

注册码计算的关键部分见下:

==============▲=计算开始=▲===============


:004011E0 33DB xor ebx, ebx    ---------->EBX清0。
:004011E2 8A5C05E4mov bl, byte ptr [ebp+eax-1C]--->依次取注册名字符的16进制值送入EBX的低位。
:004011E6 03D3 add edx, ebx  ---------->EDX=EBX+EDX
              其中,EDX的初始值为0。EDX用来保存每次循环后的结果。
:004011E8 40 inc eax --------->EAX加1,作为计数器
:004011E9 3BC8 cmp ecx, eax   --------->取完了吗?? Ecx装姓名的长度

由于我们输入的abcd有4个字符,因此这里ecx=4
:004011EB 7FF3 jg 004011E0   --------->没取完就跳回循环。

=================计算结束=================

若用ollydbg,在这段儿时刻留心右上角各个寄存器的数值。

若用trw,在这段儿时刻留心顶部各个寄存器的数值。

追踪过程中各寄存器值的列表清单:



说明:C3=61+62; 126=C3+63; 18A=126+64

18A=61+62+63+64 十进制394

总结:用户名abcd 注册码394

它的注册算法就是将姓名的所有字母ascii码之和相加,就是注册码。

例二(也就是前一课的软件)

破解极酷桌面工具栏

[ 目 的 ] 找出注册码,去除次数限制,同时练习Ollydbg破解软件。
[破解工具] W32Dasm9.0汉化版 ollydbg1.07汉化增强版。
[破 解 人] 小白菜[OCN]
[破解过程]
1:用W32Dasm反汇编,点击参考--字符串数据参考;往下查到“注册失败”,
双击来到下面(我们将进行断点分析)

00406EBA|. 8B45 B8MOV EAX,DWORD PTR SS:[EBP-48]
00406EBD|. 8B80 00020000 MOV EAX,DWORD PTR DS:[EAX+200]
00406EC3|. E8 64170200 CALL Tbfof.0042862C
00406EC8|. 8D45 F4LEA EAX,DWORD PTR SS:[EBP-C]
00406ECB|. 5A POP EDX
00406ECC|. E8 F73F0500 CALL Tbfof.0045AEC8

;在上面這個CALL下斷點。EDX中就是真註冊碼的"地址"。EAX就是假註冊碼的"地址"。

如果你用TR2000的話。你可以下指令" d *edx "(注意:在EDX前要加"*"號,不然你
看到的只是註冊碼的地址)如果你用的是ollydbg的話,你可以在內存窗口點右鍵,
在彈出的窗口上選擇"Go to --->>expression",然後在跳出的窗口中輸入"EDX"指向
的內存地址的值(注意:不是EDX的值哦!如:在我的機子上edx的值是0012f850它指向
的內存中的值是00a3f000,那麽你就要輸入00a3f00,而不是0012f850 ).輸入地址後,
按OK,你就可以在內存窗口看到你的真註冊碼了。


00406ED1|. 50 PUSH EAX ;存註冊成功與否的標志。
00406ED2|. FF4D D8DEC DWORD PTR SS:[EBP-28]
00406ED5|. 8D45 F4LEA EAX,DWORD PTR SS:[EBP-C]
00406ED8|. BA 02000000 MOV EDX,2
00406EDD|. E8 163F0500 CALL Tbfof.0045ADF8
00406EE2|. FF4D D8DEC DWORD PTR SS:[EBP-28] ; |
00406EE5|. 8D45 F0LEA EAX,DWORD PTR SS:[EBP-10] ; |
00406EE8|. BA 02000000 MOV EDX,2 ; |
00406EED|. E8 063F0500 CALL Tbfof.0045ADF8 ; \Tbfof.0045ADF8
00406EF2|. 59 POP ECX ;取出註冊成功與否的標志。
00406EF3|. 84C9 TEST CL,CL
00406EF5|. 0F84 E0000000 JE Tbfof.00406FDB ;如果爲0就跳到出錯窗口了。
00406EFB|. 33C0 XOR EAX,EAX
00406EFD|. 8945 E8MOV DWORD PTR SS:[EBP-18],EAX
00406F00|. 8D55 E8LEA EDX,DWORD PTR SS:[EBP-18]
00406F03|. FF45 D8INC DWORD PTR SS:[EBP-28]
00406F06|. 8B4D B8MOV ECX,DWORD PTR SS:[EBP-48]
00406F09|. 8B81 F4010000 MOV EAX,DWORD PTR DS:[ECX+1F4]
00406F0F|. E8 18170200 CALL Tbfof.0042862C
00406F14|. 8D55 E8LEA EDX,DWORD PTR SS:[EBP-18]
00406F17|. 8D45 ECLEA EAX,DWORD PTR SS:[EBP-14]
00406F1A|. 8B0A MOV ECX,DWORD PTR DS:[EDX]
00406F1C|. BA 20E54500 MOV EDX,Tbfof.0045E520 ; ASCII "User"
00406F21|. 51 PUSH ECX
00406F22|. 66:C745 CC 2C0>MOV WORD PTR SS:[EBP-34],2C
00406F28|. E8 9B3D0500 CALL Tbfof.0045ACC8
00406F2D|. FF45 D8INC DWORD PTR SS:[EBP-28]
00406F30|. 8B10 MOV EDX,DWORD PTR DS:[EAX]
00406F32|. 8B45 B8MOV EAX,DWORD PTR SS:[EBP-48]
00406F35|. 59 POP ECX
00406F36|. E8 ADF5FFFF CALL Tbfof.004064E8
00406F3B|. FF4D D8DEC DWORD PTR SS:[EBP-28]
00406F3E|. 8D45 E8LEA EAX,DWORD PTR SS:[EBP-18]
00406F41|. BA 02000000 MOV EDX,2
00406F46|. E8 AD3E0500 CALL Tbfof.0045ADF8
00406F4B|. FF4D D8DEC DWORD PTR SS:[EBP-28]
00406F4E|. 8D45 ECLEA EAX,DWORD PTR SS:[EBP-14]
00406F51|. BA 02000000 MOV EDX,2
00406F56|. E8 9D3E0500 CALL Tbfof.0045ADF8
00406F5B|. 33C9 XOR ECX,ECX
00406F5D|. 894D E0MOV DWORD PTR SS:[EBP-20],ECX
00406F60|. 8D55 E0LEA EDX,DWORD PTR SS:[EBP-20]
00406F63|. FF45 D8INC DWORD PTR SS:[EBP-28]
00406F66|. 8B45 B8MOV EAX,DWORD PTR SS:[EBP-48]
00406F69|. 8B80 00020000 MOV EAX,DWORD PTR DS:[EAX+200]
00406F6F|. E8 B8160200 CALL Tbfof.0042862C
00406F74|. 8D55 E0LEA EDX,DWORD PTR SS:[EBP-20]
00406F77|. 8D45 E4LEA EAX,DWORD PTR SS:[EBP-1C]
00406F7A|. 8B0A MOV ECX,DWORD PTR DS:[EDX]
00406F7C|. BA 25E54500 MOV EDX,Tbfof.0045E525 ; ASCII "Reg"
00406F81|. 51 PUSH ECX
00406F82|. 66:C745 CC 380>MOV WORD PTR SS:[EBP-34],38
00406F88|. E8 3B3D0500 CALL Tbfof.0045ACC8
00406F8D|. FF45 D8INC DWORD PTR SS:[EBP-28]
00406F90|. 8B10 MOV EDX,DWORD PTR DS:[EAX]
00406F92|. 8B45 B8MOV EAX,DWORD PTR SS:[EBP-48]
00406F95|. 59 POP ECX
00406F96|. E8 4DF5FFFF CALL Tbfof.004064E8
00406F9B|. FF4D D8DEC DWORD PTR SS:[EBP-28]
00406F9E|. 8D45 E0LEA EAX,DWORD PTR SS:[EBP-20]
00406FA1|. BA 02000000 MOV EDX,2
00406FA6|. E8 4D3E0500 CALL Tbfof.0045ADF8
00406FAB|. FF4D D8DEC DWORD PTR SS:[EBP-28]
00406FAE|. 8D45 E4LEA EAX,DWORD PTR SS:[EBP-1C]
00406FB1|. BA 02000000 MOV EDX,2
00406FB6|. E8 3D3E0500 CALL Tbfof.0045ADF8
00406FBB|. A1 EC344600 MOV EAX,DWORD PTR DS:[4634EC]
00406FC0|. 6A 00 PUSH 0
00406FC2|. B9 34E54500 MOV ECX,Tbfof.0045E534
00406FC7|. BA 29E54500 MOV EDX,Tbfof.0045E529
00406FCC|. 8B00 MOV EAX,DWORD PTR DS:[EAX]
00406FCE|. E8 DD3C0500 CALL Tbfof.0045ACB0 ;註冊成功的提示。
00406FD3|. 66:C745 CC 200>MOV WORD PTR SS:[EBP-34],20
00406FD9|. EB 32 JMP SHORT Tbfof.0040700D
00406FDB|> A1 EC344600 MOV EAX,DWORD PTR DS:[4634EC]
00406FE0|. 6A 00 PUSH 0
00406FE2|. B9 4AE54500 MOV ECX,Tbfof.0045E54A
00406FE7|. BA 3FE54500 MOV EDX,Tbfof.0045E53F
00406FEC|. 8B00 MOV EAX,DWORD PTR DS:[EAX]
00406FEE|. E8 BD3C0500 CALL Tbfof.0045ACB0 ;註冊不成功的提示。
我們向上看有沒有跳轉
跳過這個出錯窗口。
00406FF3|. 8B55 B8MOV EDX,DWORD PTR SS:[EBP-48]
00406FF6|. 8B82 F4010000 MOV EAX,DWORD PTR DS:[EDX+1F4]
00406FFC|. 8B10 MOV EDX,DWORD PTR DS:[EAX]
00406FFE|. FF52 7CCALL DWORD PTR DS:[EDX+7C]
00407001|. 8B4D BCMOV ECX,DWORD PTR SS:[EBP-44]
00407004|. 64:890D 000000>MOV DWORD PTR FS:[0],ECX

2:好了,断点分析完毕,就是0045AEC8。运行Ollydbg装入软件,在右上角0045AEC8按F2
下断点,按F9运行软件,注意右下角是否出现Running字样,点击软件进行注册,我的是
用户名:xbc
注册号:98989898
然后按确定,被拦!返回ollydbg界面,在右下角往下找一下,呵呵!
在98989898上面是什么?哈~破解成功!
3:小白菜的注册码:
==================
用户名:xbc
注册号:34012224
==================
例三 FoldView 1.51算法分析 破解人:pzhccy

破解对象:FoldView 1.51
目标:了解算法并写出注册机
难度:简单,适合我这等初学者
各位初学的朋友们,想学注册算法的,一定要试下这个软件
1、检查是否加壳,无壳;
2、输入那些注册码,注册名;
3、打开TRW, bpx hmemcpy 万能中断 g
4、点注册,中断了
5、pmoude 来到领空下( 我用的是最新版的TRW,旧的会弹出错误的对话框)
如下:按几下F10到下面
* Possible Reference to Dialog: DialogID_0067, CONTROL_ID:03ED, ""
|
:00405934 68ED030000 push 000003ED
:00405939 56 push esi
:0040593A FFD7 call edi<<-----------此为取出注册码,当然是假的
:0040593C 8D442408 lea eax, dword ptr [esp+08]<<----------你输入的假的注册码
:00405940 8D8C2408010000 lea ecx, dword ptr [esp+00000108]<<--------你的注册名
:00405947 50 push eax
:00405948 51 push ecx
:00405949 E842030000 call 00405C90<<-----------过此,见真码,追入
:0040594E 83C408 add esp, 00000008
:00405951 85C0 test eax, eax
:00405953 5F pop edi
:00405954 7443 je 00405999<<---------- 一跳就死了
:00405956 8D542404 lea edx, dword ptr [esp+04]
:0040595A 8D842404010000 lea eax, dword ptr [esp+00000104]
:00405961 52 push edx
:00405962 50 push eax

* Possible StringData Ref from Data Obj ->"Software\FolderView\Registration"
| <<---不跳就幸福了,把注册名等放入注册表
:00405963 6824254100 push 00412524
:00405968 6801000080 push 80000001
:0040596D E85E030000 call 00405CD0

* Possible StringData Ref from Data Obj ->"Software\FolderView\Registration"
|
:00405972 6824254100 push 00412524
:00405977 6801000080 push 80000001
:0040597C E8BF010000 call 00405B40
:00405981 83C418 add esp, 00000018

* Possible Reference to String Resource ID=00001: "Registered to: %s"<<-----注册给谁了?
|
:00405984 6A01 push 00000001
:00405986 56 push esi

* Reference To: USER32.EndDialog, Ord:00C6h
|
:00405987 FF15CC014100 Call dword ptr [004101CC]
:0040598D 33C0 xor eax, eax
:0040598F 5E pop esi
:00405990 81C400020000 add esp, 00000200
:00405996 C21000 ret 0010



* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405954(C)
|
:00405999 6A00 push 00000000<<-----------跳到这里,死硬了吧!55555

* Possible StringData Ref from Data Obj ->"FolderView"
|
:0040599B 6880254100 push 00412580

* Possible StringData Ref from Data Obj ->"Sorry, you have entered an incorrect "<<----可恶的字
->"registration code."
|
:004059A0 68CC284100 push 004128CC
:004059A5 56 push esi
追入:


* Referenced by a CALL at Addresses:
|:00405949 , :00405C0D
|
:00405C90 8B4C2404 mov ecx, dword ptr [esp+04]
:00405C94 81EC00010000 sub esp, 00000100
:00405C9A 8D442400 lea eax, dword ptr [esp]
:00405C9E 50 push eax
:00405C9F 51 push ecx
:00405CA0 E8AB000000 call 00405D50<<-----------------过此,见真码,追入
:00405CA5 8B842410010000 mov eax, dword ptr [esp+00000110]
:00405CAC 8D542408 lea edx, dword ptr [esp+08]
:00405CB0 52 push edx<<--------d edx
:00405CB1 50 push eax<<-----d eax 你看到什么了
:00405CB2 E889FFFFFF call 00405C40
:00405CB7 F7D8 neg eax
:00405CB9 1BC0 sbb eax, eax
:00405CBB F7D8 neg eax
:00405CBD 81C410010000 add esp, 00000110
:00405CC3 C3 ret
追入后如下:



|:00405CA0
|
:00405D50 81EC00010000 sub esp, 00000100
:00405D56 A02C574100 mov al, byte ptr [0041572C]
:00405D5B 53 push ebx
:00405D5C 55 push ebp
:00405D5D 56 push esi
:00405D5E 57 push edi
:00405D5F 88442410 mov byte ptr [esp+10], al
:00405D63 B93F000000 mov ecx, 0000003F
:00405D68 33C0 xor eax, eax
:00405D6A 8D7C2411 lea edi, dword ptr [esp+11]
:00405D6E F3 repz
:00405D6F AB stosd
:00405D70 66AB stosw
:00405D72 AA stosb
:00405D73 8BBC2414010000 mov edi, dword ptr [esp+00000114]
:00405D7A 57 push edi

* Reference To: KERNEL32.lstrlenA, Ord:03AEh
|
:00405D7B FF1550014100 Call dword ptr [00410150]
:00405D81 8BF0 mov esi, eax
:00405D83 33C9 xor ecx, ecx
:00405D85 33C0 xor eax, eax
:00405D87 85F6 test esi, esi<<-----------用户为空吗?
:00405D89 7613 jbe 00405D9E<<----------为空则跳走了
:00405D8B 8B15BC284100 mov edx, dword ptr [004128BC]<<---------edx=32H

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405D9C(C)
|
:00405D91 0FBE1C38 movsx ebx, byte ptr [eax+edi]<<-----逐个取出用户名对应的ASCII码
:00405D95 03DA add ebx, edx<<-----逐个+32
:00405D97 03CB add ecx, ebx<<------求和
:00405D99 40 inc eax<<------计数器加1
:00405D9A 3BC6 cmp eax, esi<<---比较是否取完
:00405D9C 72F3 jb 00405D91<<---------循环结束则继续

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405D89(C)
|
:00405D9E 8B9C2418010000 mov ebx, dword ptr [esp+00000118]
:00405DA5 51 push ecx

* Possible StringData Ref from Data Obj ->"%u-"<<--------这里转为十进制并加上-,记为M1
|
:00405DA6 6814294100 push 00412914
:00405DAB 53 push ebx

* Reference To: USER32.wsprintfA, Ord:02D6h
|
:00405DAC FF15C4014100 Call dword ptr [004101C4]
:00405DB2 83C40C add esp, 0000000C
:00405DB5 33C9 xor ecx, ecx
:00405DB7 33C0 xor eax, eax
:00405DB9 85F6 test esi, esi
:00405DBB 7614 jbe 00405DD1
:00405DBD 8B15C0284100 mov edx, dword ptr [004128C0]<<-------edx=28H

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405DCF(C)
|
:00405DC3 0FBE2C38 movsx ebp, byte ptr [eax+edi]
:00405DC7 0FAFEA imul ebp, edx<<----------------相乘
:00405DCA 03CD add ecx, ebp<<--------求和
:00405DCC 40 inc eax
:00405DCD 3BC6 cmp eax, esi
:00405DCF 72F2 jb 00405DC3

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405DBB(C)
|
:00405DD1 51 push ecx
:00405DD2 8D4C2414 lea ecx, dword ptr [esp+14]

* Possible StringData Ref from Data Obj ->"%u-"<<--------这里转为十进制并加上-,记为M2
|
:00405DD6 6814294100 push 00412914
:00405DDB 51 push ecx

* Reference To: USER32.wsprintfA, Ord:02D6h
|
:00405DDC FF15C4014100 Call dword ptr [004101C4]<<--------这里是把M1+M2
:00405DE2 83C40C add esp, 0000000C
:00405DE5 8D542410 lea edx, dword ptr [esp+10]
:00405DE9 52 push edx
:00405DEA 53 push ebx

* Reference To: KERNEL32.lstrcatA, Ord:039Fh
|
:00405DEB FF1588014100 Call dword ptr [00410188]
:00405DF1 33C9 xor ecx, ecx
:00405DF3 33C0 xor eax, eax
:00405DF5 85F6 test esi, esi
:00405DF7 7613 jbe 00405E0C
:00405DF9 8B15C4284100 mov edx, dword ptr [004128C4]<<-------edx=1eH

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405E0A(C)
|
:00405DFF 0FBE2C38 movsx ebp, byte ptr [eax+edi]
:00405E03 03EA add ebp, edx<<--------------相加
:00405E05 03CD add ecx, ebp<<--------求和
:00405E07 40 inc eax
:00405E08 3BC6 cmp eax, esi
:00405E0A 72F3 jb 00405DFF

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405DF7(C)
|
:00405E0C 51 push ecx
:00405E0D 8D442414 lea eax, dword ptr [esp+14]

* Possible StringData Ref from Data Obj ->"%u-"
|
:00405E11 6814294100 push 00412914
:00405E16 50 push eax

* Reference To: USER32.wsprintfA, Ord:02D6h
|
:00405E17 FF15C4014100 Call dword ptr [004101C4]
:00405E1D 83C40C add esp, 0000000C
:00405E20 8D4C2410 lea ecx, dword ptr [esp+10]
:00405E24 51 push ecx
:00405E25 53 push ebx

* Reference To: KERNEL32.lstrcatA, Ord:039Fh
|
:00405E26 FF1588014100 Call dword ptr [00410188]
:00405E2C 33C9 xor ecx, ecx
:00405E2E 33C0 xor eax, eax
:00405E30 85F6 test esi, esi
:00405E32 7614 jbe 00405E48
:00405E34 8B15C8284100 mov edx, dword ptr [004128C8]<<------edx=0bH

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405E46(C)
|
:00405E3A 0FBE2C38 movsx ebp, byte ptr [eax+edi]
:00405E3E 0FAFEA imul ebp, edx<<-------------相乘
:00405E41 03CD add ecx, ebp<<------求和
:00405E43 40 inc eax
:00405E44 3BC6 cmp eax, esi
:00405E46 72F2 jb 00405E3A

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405E32(C)
|
:00405E48 51 push ecx
:00405E49 8D542414 lea edx, dword ptr [esp+14]

* Possible StringData Ref from Data Obj ->"%u"
|
:00405E4D 6898274100 push 00412798
:00405E52 52 push edx

* Reference To: USER32.wsprintfA, Ord:02D6h
|
:00405E53 FF15C4014100 Call dword ptr [004101C4]<<--------全部连起来
:00405E59 83C40C add esp, 0000000C
:00405E5C 8D442410 lea eax, dword ptr [esp+10]
:00405E60 50 push eax
:00405E61 53 push ebx

* Reference To: KERNEL32.lstrcatA, Ord:039Fh
|
:00405E62 FF1588014100 Call dword ptr [00410188]
:00405E68 5F pop edi
:00405E69 5E pop esi
:00405E6A 5D pop ebp
:00405E6B 5B pop ebx
:00405E6C 81C400010000 add esp, 00000100
:00405E72 C3 ret
举例:注册名:pzhccy[bcg]
M1= p z h c c y [ b c g ]
70+32+ 7A+32+ 68+32+ 63+32+ 63+32+ 79+32+ 5B+32+ 62+32+ 63+32+ 67+32+ 5D+32=69B=1691 再在后面加-

以下就如此类推,就可以得出真码。
注册机应该很容易写吧! 反正我已经写好了。
整理:注册名:pzhccy[bcg] 注册码:1691-45640-1471-12551

例四 极速火龙CD压缩器 1.28 算法分析 破解人:pzhccy
破解目标:极速火龙CD压缩器 1.28
下载地址:www.softreg.com
1、检查是否加壳,unpetite脱壳
2、打开TRW,下命令 bpx hmemcpy
g 被拦
大约按F10 N下,来到下面(已经记不清了,但很容易,因为它按几下一个ret)
注册算法如下:

|:0047694A(U)
|
:00476958 0FBE45FC movsx eax, byte ptr [ebp-04]<<------ 取用户名的第一个字符的ASCII码
:0047695C 0FBE55FD movsx edx, byte ptr [ebp-03] <<------- 取出第二个
:00476960 03C2 add eax, edx<<---------------------第一、二ASCII码相加
:00476962 0FBE55FE movsx edx, byte ptr [ebp-02]<<-------取出第三个
:00476966 03C2 add eax, edx<<-----------------第一、二、三相加,值在eax中
:00476968 0FBE55FF movsx edx, byte ptr [ebp-01]<<----------取出第四个
:0047696C 03C2 add eax, edx<<-----------------第一、二、三、四全部加起来到eax中
:0047696E 69C04E61BC00 imul eax, 00BC614E<<----------和乘以BC614E(十进制为12345678,哈哈…)
:00476974 B9BB000000 mov ecx, 000000BB<<---------ecx等于BB
:00476979 99 cdq<<--------------------双字扩展,edx清零
:0047697A F7F9 idiv ecx<<-------------eax除以ecx,商在eax,余数在edx中
:0047697C 3BD8 cmp ebx, eax<<-------比较来了,?ebx ,? eax 看到什么了
:0047697E 0F85DB000000 jne 00476A5F<<---------- 一跳就死
:00476984 3DE8030000 cmp eax, 000003E8<<------这里实在不敢恭惟,可能作者故意加上去的,但一点用处

都没有,比较你的注册码是否少于3E8,十进制为1000,你试一下就知道,随便输,算出来的结果都不会被它小。


:00476989 0F8ED0000000 jle 00476A5F<<--------------少于等于都要死
:0047698F 6A00 push 00000000
:00476991 8D55F0 lea edx, dword ptr [ebp-10]
:00476994 A1DC474800 mov eax, dword ptr [004847DC]
:00476999 E8BEEFF8FF call 0040595C
:0047699E 8B45F0 mov eax, dword ptr [ebp-10]
:004769A1 E8EED5F8FF call 00403F94
:004769A6 50 push eax
:004769A7 8D55EC lea edx, dword ptr [ebp-14]
:004769AA A14C4B4800 mov eax, dword ptr [00484B4C]
:004769AF E8A8EFF8FF call 0040595C
:004769B4 8B45EC mov eax, dword ptr [ebp-14]
:004769B7 E8D8D5F8FF call 00403F94
:004769BC 8BD0 mov edx, eax
:004769BE A18C4A4800 mov eax, dword ptr [00484A8C]
:004769C3 8B00 mov eax, dword ptr [eax]
:004769C5 59 pop ecx
:004769C6 E8B549FDFF call 0044B380
:004769CB B201 mov dl, 01

* Possible StringData Ref from Data Obj ->"
"
|
:004769CD A1C05D4700 mov eax, dword ptr [00475DC0]
:004769D2 E8E9F4FFFF call 00475EC0
:004769D7 8BD8 mov ebx, eax
:004769D9 BA01000080 mov edx, 80000001
:004769DE 8BC3 mov eax, ebx
:004769E0 E87BF5FFFF call 00475F60
:004769E5 B101 mov cl, 01

* Possible StringData Ref from Data Obj ->"\Software\Microsoft\Windows\CurrentVersion\Exp"
->"lorer\tips"<<----------注册后,把信息放在这里
|
:004769E7 BADC6A4700 mov edx, 00476ADC
:004769EC 8BC3 mov eax, ebx
:004769EE E8D1F5FFFF call 00475FC4
:004769F3 B901000000 mov ecx, 00000001

* Possible StringData Ref from Data Obj ->"TipsForAllSkip"
|
:004769F8 BA206B4700 mov edx, 00476B20
:004769FD 8BC3 mov eax, ebx
:004769FF E800F8FFFF call 00476204
:00476A04 8BC3 mov eax, ebx
:00476A06 E825F5FFFF call 00475F30
:00476A0B 8BC3 mov eax, ebx
:00476A0D E8F2C3F8FF call 00402E04
:00476A12 6A30 push 00000030
:00476A14 8D55E8 lea edx, dword ptr [ebp-18]
:00476A17 A1DC484800 mov eax, dword ptr [004848DC]
:00476A1C E83BEFF8FF call 0040595C
:00476A21 8B45E8 mov eax, dword ptr [ebp-18]
:00476A24 E86BD5F8FF call 00403F94
:00476A29 50 push eax
:00476A2A 8D55E4 lea edx, dword ptr [ebp-1C]
:00476A2D A10C484800 mov eax, dword ptr [0048480C]
:00476A32 E825EFF8FF call 0040595C
:00476A37 8B45E4 mov eax, dword ptr [ebp-1C]
:00476A3A E855D5F8FF call 00403F94
:00476A3F 8BD0 mov edx, eax
:00476A41 A18C4A4800 mov eax, dword ptr [00484A8C]
:00476A46 8B00 mov eax, dword ptr [eax]
:00476A48 59 pop ecx
:00476A49 E83249FDFF call 0044B380
:00476A4E A18C4A4800 mov eax, dword ptr [00484A8C]
:00476A53 8B00 mov eax, dword ptr [eax]
:00476A55 8B4038 mov eax, dword ptr [eax+38]
:00476A58 E83F15FDFF call 00447F9C
:00476A5D EB3C jmp 00476A9B<<-----------------跳向成功处

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0047697E(C), :00476989(C)
|
:00476A5F 6A00 push 00000000<<---------------下到这里就硬又冰了
:00476A61 8D55E0 lea edx, dword ptr [ebp-20]
:00476A64 A1DC474800 mov eax, dword ptr [004847DC]
:00476A69 E8EEEEF8FF call 0040595C
:00476A6E 8B45E0 mov eax, dword ptr [ebp-20]
:00476A71 E81ED5F8FF call 00403F94
:00476A76 50 push eax
:00476A77 8D55DC lea edx, dword ptr [ebp-24]
:00476A7A A1AC484800 mov eax, dword ptr [004848AC]
:00476A7F E8D8EEF8FF call 0040595C
:00476A84 8B45DC mov eax, dword ptr [ebp-24]
:00476A87 E808D5F8FF call 00403F94
:00476A8C 8BD0 mov edx, eax
:00476A8E A18C4A4800 mov eax, dword ptr [00484A8C]
:00476A93 8B00 mov eax, dword ptr [eax]
:00476A95 59 pop ecx
:00476A96 E8E548FDFF call 0044B380
举例:pzhccy
只取前四个去算,如不够四位,则其它位数为0,
p z h c
70 +7a +68 +63=1b5
1b5 * bc614e / bb = 59c3e7H = 5882855
整理:注册名:pzhccy 注册码: 5882855
例4五folderview1.46 破解人:pzhccy

破解对象:folderview 1.46 和 supercleaner 2.41 的算法一模一样
难度:一般
1、查壳,无壳
2、有出错信息,反汇编,找不到出错信息,无办法,唯有用动态跟踪了,
3、打开tr,
bpx getdlgitemtexta
g 确定,被拦
按F10单步跟踪到下面,大约按10多下。
016F:00405018 CALL EDI
016F:0040501A LEA EDX,[ESP+08]
016F:0040501E PUSH DWORD 0100
016F:00405023 PUSH EDX
016F:00405024 PUSH DWORD 03FC
016F:00405029 PUSH ESI
016F:0040502A CALL EDI 取出注册名、码的CALL
016F:0040502C LEA EAX,[ESP+08]
016F:00405030 LEA ECX,[ESP+0108]
016F:00405037 PUSH EAX d eax,d ecx 可见注册名、码
016F:00405038 PUSH ECX
016F:00405039 CALL 004053B0 这里为重要CALL,因为下面不跳就死,所以,这个是关键的CALL
016F:0040503E ADD ESP,BYTE +08
016F:00405041 TEST EAX,EAX
016F:00405043 POP EDI
016F:00405044 JZ 00405089 不跳就死


我们进入405039这个CALL,如下:算法分析:注册码由四部分组成,a1-b1-c1-d1
016F:004053B0 MOV ECX,[ESP+04]
016F:004053B4 SUB ESP,0100
016F:004053BA LEA EAX,[ESP+00]
016F:004053BE PUSH EAX
016F:004053BF PUSH ECX 你的注册名
016F:004053C0 CALL 00405470 重要CALL,因为过此CALL后,你已见到真码
016F:004053C5 MOV EAX,[ESP+0110]
016F:004053CC LEA EDX,[ESP+08]
016F:004053D0 PUSH EDX d eax,d edx 一真一假码
016F:004053D1 PUSH EAX
016F:004053D2 CALL 00405360 此为比较真假的CALL
016F:004053D7 NEG EAX
016F:004053D9 SBB EAX,EAX
016F:004053DB NEG EAX
016F:004053DD ADD ESP,0110
ret
我们进入4053C0这个CALL

016F:00405470 SUB ESP,0100
016F:00405476 MOV AL,[004145AC]
016F:0040547B PUSH EBX
016F:0040547C PUSH EBP
016F:0040547D PUSH ESI
016F:0040547E PUSH EDI
016F:0040547F MOV [ESP+10],AL
016F:00405483 MOV ECX,3F
016F:00405488 XOR EAX,EAX
016F:0040548A LEA EDI,[ESP+11]
016F:0040548E REP STOSD
016F:00405490 STOSW
016F:00405492 STOSB
016F:00405493 MOV EDI,[ESP+0114]
016F:0040549A PUSH EDI
016F:0040549B CALL `KERNEL32!lstrlenA`
016F:004054A1 MOV ESI,EAX
016F:004054A3 XOR ECX,ECX
016F:004054A5 XOR EAX,EAX
016F:004054A7 TEST ESI,ESI esi为名字的长度,看名字是否为空
016F:004054A9 JNA 004054BE 为空即跳走
016F:004054AB MOV EDX,[00411744] ? edx ,edx=32H 这是16进制
016F:004054B1 MOVSX EBX,BYTE [EAX+EDI] 提取姓名的一个字符 (计算a1部分)
016F:004054B5 ADD EBX,EDX ebx+edx=ebx 即每一个字符的16进制+32H
016F:004054B7 ADD ECX,EBX 结果送入ecx,即为储数器
016F:004054B9 INC EAX 寄存器每次加一,即第一位,再第二位数,直到结束
016F:004054BA CMP EAX,ESI 这时就是比较是否完结
016F:004054BC JC 004054B1 循环结束即继续
016F:004054BE MOV EBX,[ESP+0118]
016F:004054C5 PUSH ECX
016F:004054C6 PUSH DWORD 0041179C
016F:004054CB PUSH EBX
016F:004054CC CALL `USER32!wsprintfA`
016F:004054D2 ADD ESP,BYTE +0C
016F:004054D5 XOR ECX,ECX
016F:004054D7 XOR EAX,EAX
016F:004054D9 TEST ESI,ESI 同上
016F:004054DB JNA 004054F1
016F:004054DD MOV EDX,[00411748] 计算b1部分 edx=28
016F:004054E3 MOVSX EBP,BYTE [EAX+EDI] 同上
016F:004054E7 IMUL EBP,EDX 即每一个字符的16进制*28H
016F:004054EA ADD ECX,EBP
016F:004054EC INC EAX
016F:004054ED CMP EAX,ESI 同上
016F:004054EF JC 004054E3
016F:004054F1 PUSH ECX
016F:004054F2 LEA ECX,[ESP+14]
016F:004054F6 PUSH DWORD 0041179C
016F:004054FB PUSH ECX
016F:004054FC CALL `USER32!wsprintfA`
016F:00405502 ADD ESP,BYTE +0C
016F:00405505 LEA EDX,[ESP+10]
016F:00405509 PUSH EDX
016F:0040550A PUSH EBX
016F:0040550B CALL `KERNEL32!lstrcatA`
016F:00405511 XOR ECX,ECX
016F:00405513 XOR EAX,EAX
016F:00405515 TEST ESI,ESI 同上
016F:00405517 JNA 0040552C
016F:00405519 MOV EDX,[0041174C] edx=1e
016F:0040551F MOVSX EBP,BYTE [EAX+EDI] 提取姓名的一个字符 (计算c1部分)
016F:00405523 ADD EBP,EDX
016F:00405525 ADD ECX,EBP
016F:00405527 INC EAX
016F:00405528 CMP EAX,ESI
016F:0040552A JC 0040551F
016F:0040552C PUSH ECX
016F:0040552D LEA EAX,[ESP+14]
016F:00405531 PUSH DWORD 0041179C
016F:00405536 PUSH EAX
016F:00405537 CALL `USER32!wsprintfA`
016F:0040553D ADD ESP,BYTE +0C
016F:00405540 LEA ECX,[ESP+10]
016F:00405544 PUSH ECX
016F:00405545 PUSH EBX
016F:00405546 CALL `KERNEL32!lstrcatA`
016F:0040554C XOR ECX,ECX
016F:0040554E XOR EAX,EAX
016F:00405550 TEST ESI,ESI 同上
016F:00405552 JNA 00405568
016F:00405554 MOV EDX,[00411750] edx=0b
016F:0040555A MOVSX EBP,BYTE [EAX+EDI] 计算d1部分
016F:0040555E IMUL EBP,EDX
016F:00405561 ADD ECX,EBP
016F:00405563 INC EAX 同上
016F:00405564 CMP EAX,ESI
016F:00405566 JC 0040555A
016F:00405568 PUSH ECX
016F:00405569 LEA EDX,[ESP+14]
016F:0040556D PUSH DWORD 00411620
016F:00405572 PUSH EDX
016F:00405573 CALL `USER32!wsprintfA`
016F:00405579 ADD ESP,BYTE +0C
016F:0040557C LEA EAX,[ESP+10]
016F:00405580 PUSH EAX
016F:00405581 PUSH EBX
016F:00405582 CALL `KERNEL32!lstrcatA`
016F:00405588 POP EDI
016F:00405589 POP ESI
016F:0040558A POP EBP
016F:0040558B POP EBX
016F:0040558C ADD ESP,0100

整理:注册名:pzhccy 注册码:957-26280-837-7227
例6破解社区游戏伴侣
[下载地址]
http://www.softreg.com.cn/download.asp?id={6A697B98-6D96-4CF1-A14C-A060A31D299C}
[破解工具]PEiD0.8英文版,AspackDie 1.4 汉化版、W32Dasm9.00汉化版,Ollydbg1.07汉化增强版
[破解人] 小白菜
[破解目的]找出注册码
[破解时间]2002年8月25日
[破解过程]
1 探测:用PEiD装入软件,发现软件有壳,为ASPack 2.12 -> Alexey Solodovnikov。
2 脱壳:用AspackDie 1.4 汉化版脱壳,生成脱壳文件unpacked.ExE。
3 用W32Dasm9.00汉化版反汇编,点击参考-字符串数据参考,发现我们比较感兴趣的字样:
"感谢您注册使用本软件,您注册码已保存在本机,以后",以及"注册码错误!!如您没有注册,
不必输入也可以直接进?”正常应该是双击"注册码错误!!如您没有注册,不必输入也可以直接进?”
字样,可是我双击以后提示“数据没发现”!晕倒~不知道是不是版本太低的原因;没办法,只好
双击"感谢您注册使用本软件,您注册码已保存在本机,以后"字样并来到下面,分析断点

联众断点分析:

00469DA0 /. 55 PUSH EBP;仅仅是判断函数入口
。。。。。。
00469DC8 |. 8B80 08030000 MOV EAX,DWORD PTR DS:[EAX+308]
00469DCE |. E8 FDE9FCFF CALL unpacked.004387D0 ;读入注册码
00469DD3 |. 8B45 C8MOV EAX,DWORD PTR SS:[EBP-38]
00469DD6 |. 33D2 XOR EDX,EDX
00469DD8 |. E8 33EDF9FF CALL unpacked.00408B10 ;转化成数值
00469DDD |. 8BC8 MOV ECX,EAX
00469DDF |. 81F9 80969800 CMP ECX,989680 ;十进制10000000
00469DE5 |. 7D 0F JGE SHORT unpacked.00469DF6 ;小于就不是8位数,失败
。。。。。。
00469E00 |. 8B80 08030000 MOV EAX,DWORD PTR DS:[EAX+308]
00469E06 |. E8 C5E9FCFF CALL unpacked.004387D0 ;注册码
00469E0B |. 8B45 C0MOV EAX,DWORD PTR SS:[EBP-40]
00469E0E |. B9 04000000 MOV ECX,4
00469E13 |. 33D2 XOR EDX,EDX
00469E15 |. E8 7EABF9FF CALL unpacked.00404998 ;注册码的前4位
00469E1A |. 8B45 C4MOV EAX,DWORD PTR SS:[EBP-3C]
00469E1D |. E8 B2ECF9FF CALL unpacked.00408AD4 ;转化成数值
00469E22 |. 8945 F0MOV DWORD PTR SS:[EBP-10],EAX ;存放起来,后面有用哟!
00469E25 |. 8D55 B8LEA EDX,DWORD PTR SS:[EBP-48]
00469E28 |. 8B45 FCMOV EAX,DWORD PTR SS:[EBP-4]
00469E2B |. 8B80 04030000 MOV EAX,DWORD PTR DS:[EAX+304]
00469E31 |. E8 9AE9FCFF CALL unpacked.004387D0 ;读入注册名
00469E36 |. 8B45 B8MOV EAX,DWORD PTR SS:[EBP-48]
00469E39 |. 8D55 BCLEA EDX,DWORD PTR SS:[EBP-44]
00469E3C |. E8 37E9F9FF CALL unpacked.00408778 ;转换成小写
00469E41 |. 8B45 BCMOV EAX,DWORD PTR SS:[EBP-44]
00469E44 |. 8D55 F4LEA EDX,DWORD PTR SS:[EBP-C]
00469E47 |. E8 08EAF9FF CALL unpacked.00408854
00469E4C |. 8D45 B4LEA EAX,DWORD PTR SS:[EBP-4C]
00469E4F |. 50 PUSH EAX
00469E50 |. 8D55 B0LEA EDX,DWORD PTR SS:[EBP-50]
00469E53 |. 8B45 FCMOV EAX,DWORD PTR SS:[EBP-4]
00469E56 |. 8B80 08030000 MOV EAX,DWORD PTR DS:[EAX+308]
00469E5C |. E8 6FE9FCFF CALL unpacked.004387D0 ;还是注册码
00469E61 |. 8B45 B0MOV EAX,DWORD PTR SS:[EBP-50]
00469E64 |. B9 04000000 MOV ECX,4
00469E69 |. BA 05000000 MOV EDX,5
00469E6E |. E8 25ABF9FF CALL unpacked.00404998 ;取出后面的4位
00469E73 |. 8B55 B4MOV EDX,DWORD PTR SS:[EBP-4C]
00469E76 |. 8D45 F4LEA EAX,DWORD PTR SS:[EBP-C]
00469E79 |. E8 CAA8F9FF CALL unpacked.00404748 ;放在注册名后面(例如upfeed0000)
00469E7E |. 8B45 F4MOV EAX,DWORD PTR SS:[EBP-C]
00469E81 |. E8 BAA8F9FF CALL unpacked.00404740 ;上面串的长度
00469E86 |. 8945 F8MOV DWORD PTR SS:[EBP-8],EAX
00469E89 |. 8D45 CDLEA EAX,DWORD PTR SS:[EBP-33]
00469E8C |. 8B55 F4MOV EDX,DWORD PTR SS:[EBP-C]
00469E8F |. E8 1CF0F9FF CALL unpacked.00408EB0

00469E94 |. BB DE040000 MOV EBX,4DE
。。。。。。这里略去的就是一段对上面那个串的计算


00469EE9 |> 8BC3 MOV EAX,EBX ;验证的最后了,ebx出来的是计算的结果
00469EEB |. B9 10270000 MOV ECX,2710
00469EF0 |. 99 CDQ
00469EF1 |. F7F9 IDIV ECX;ebx模10000
00469EF3 |. 8BDA MOV EBX,EDX
00469EF5 |. 81FB E8030000 CMP EBX,3E8
00469EFB |. 7D 06 JGE SHORT unpacked.00469F03
00469EFD |. 81C3 70170000 ADD EBX,1770
00469F03 |> 3B5D F0CMP EBX,DWORD PTR SS:[EBP-10] ;注意到这里就是前面存放的注册码的前四位;好了关键的比较,至于注册码很明显了把!
00469F06 |. 74 0C JE SHORT unpacked.00469F14
---------------
好了,断点就下在00469F03

边锋断点分析:

由于以上分析比较详细,这里忽略,只指出关键call了!
继续往下面寻找可以发现:

:0046A228 3B5DF0 cmp ebx, dword ptr [ebp-10] ;关键比较,在这里下断点
:0046A22B 740Cje 0046A239 ;相等或为零则跳转

* Possible StringData Ref from Code Obj ->"注册码错误!!如您没有注册,不必输入也可以直接进?
->"胗蜗?但功能受限.."
|
:0046A22D B838A34600 mov eax, 0046A338
:0046A232 E8897DFCFF call 00431FC0
:0046A237 EB74jmp 0046A2AD

---------------
好了断点就下在0046A228

4 用Ollydbg装入脱壳以后的软件,按Ctrl+G,并填入00469F03,按F2下断点!
5 按F9运行软件,分别填入
联众
用户ID:xbc
注册码:98989898

6 按确定以后,右下角在98989898出现9898,这时我们注意左上角处的字样:
Stack SS:[0012EAA0]=000026aa
EBX=000019C5
用右键点击修改寄存器内容你会发现[0012EAA0]=000026aa的值为9898而EBX=000019C5的值为6597。
开始我也不明白,原来是拦截后。EBX值转为十进制就可以了,并将转换后的数填入前四位;破解成功!
7 换断点:0046A228
边锋
用户ID:xbc
注册码:989898989
重复4~6,破解成功!
8 整理一下
联众
用户ID:xbc
注册码:65979898
边锋
用户ID:xbc
注册码:884728989
级别: 光盘中级
发帖
237
飞翔币
335
威望
363
飞扬币
708
信誉值
0
只看该作者 2 发表于: 2006-06-04
算法教学第三课

通过前两课的学习,大家肯定掌握了不少知识,初学算法千万要记住:掌握算法最基本的是用户名取abcde,其相应ascii码是61,62,63,64,65 (16进制),这些一定要牢记于心。下面简单复习一下算法的一些基本知识(也可以作为今后查阅之用)

一、数据传输指令
───────────────────────────────────────
它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.
1. 通用数据传送指令.
MOV 传送字或字节.
MOVSX 先符号扩展,再传送.
MOVZX 先零扩展,再传送.
PUSH 把字压入堆栈.
POP 把字弹出堆栈.
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.
POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.
POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.
BSWAP 交换32位寄存器里字节的顺序
XCHG 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数)
CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX )
XADD 先交换再累加.( 结果在第一个操作数里 )
XLAT 字节查表转换.
── BX 指向一张 256 字节的表的起点, AL 为表的索引值 (0-255,即
0-FFH); 返回 AL 为查表结果. ( [BX+AL]->AL )
2. 输入输出端口传送指令.
IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} )
OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 )
输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时,
其范围是 0-65535.
3. 目的地址传送指令.
LEA 装入有效地址.
例: LEA DX,string ;把偏移地址存到DX.
LDS 传送目标指针,把指针内容装入DS.
例: LDS SI,string ;把段地址:偏移地址存到DS:SI.
LES 传送目标指针,把指针内容装入ES.
例: LES DI,string ;把段地址:偏移地址存到ES:DI.
LFS 传送目标指针,把指针内容装入FS.
例: LFS DI,string ;把段地址:偏移地址存到FS:DI.
LGS 传送目标指针,把指针内容装入GS.
例: LGS DI,string ;把段地址:偏移地址存到GS:DI.
LSS 传送目标指针,把指针内容装入SS.
例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
4. 标志传送指令.
LAHF 标志寄存器传送,把标志装入AH.
SAHF 标志寄存器传送,把AH内容装入标志寄存器.
PUSHF 标志入栈.
POPF 标志出栈.
PUSHD 32位标志入栈.
POPD 32位标志出栈.

二、算术运算指令
───────────────────────────────────────
  ADD 加法.
ADC 带进位加法.
INC 加 1.
AAA 加法的ASCII码调整.
DAA 加法的十进制调整.
SUB 减法.
SBB 带借位减法.
DEC 减 1.
NEC 求反(以 0 减之).
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).
AAS 减法的ASCII码调整.
DAS 减法的十进制调整.
MUL 无符号乘法.
IMUL 整数乘法.
以上两条,结果回送AH和AL(字节运算),或DX和AX(字运算),
AAM 乘法的ASCII码调整.
DIV 无符号除法.
IDIV 整数除法.
以上两条,结果回送:
商回送AL,余数回送AH, (字节运算);
或 商回送AX,余数回送DX, (字运算).
AAD 除法的ASCII码调整.
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)

三、逻辑运算指令
───────────────────────────────────────
  AND 与运算.
OR 或运算.
XOR 异或运算.
NOT 取反.
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
SHL 逻辑左移.
SAL 算术左移.(=SHL)
SHR 逻辑右移.
SAR 算术右移.(=SHR)
ROL 循环左移.
ROR 循环右移.
RCL 通过进位的循环左移.
RCR 通过进位的循环右移.
以上八种移位指令,其移位次数可达255次.
移位一次时, 可直接用操作码. 如 SHL AX,1.
移位>1次时, 则由寄存器CL给出移位次数.
如 MOV CL,04
SHL AX,CL

四、串指令
───────────────────────────────────────
 DS:SI 源串段寄存器 :源串变址.
ES:DI 目标串段寄存器:目标串变址.
CX 重复次数计数器.
AL/AX 扫描值.
D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.
Z标志 用来控制扫描或比较操作的结束.
MOVS 串传送.
( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )
CMPS 串比较.
( CMPSB 比较字符. CMPSW 比较字. )
SCAS 串扫描.
把AL或AX的内容与目标串作比较,比较结果反映在标志位.
LODS 装入串.
把源串中的元素(字或字节)逐一装入AL或AX中.
( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )
STOS 保存串.
是LODS的逆过程.
REP 当CX/ECX<>0时重复.
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复.
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复.
REPC 当CF=1且CX/ECX<>0时重复.
REPNC 当CF=0且CX/ECX<>0时重复.

五、程序转移指令
───────────────────────────────────────
 1>无条件转移指令 (长转移)
JMP 无条件转移指令
CALL 过程调用
RET/RETF过程返回.
2>条件转移指令 (短转移,-128到+127的距离内)
( 当且仅当(SF XOR OF)=1时,OP1JA/JNBE 不小于或不等于时转移.
JAE/JNB 大于或等于转移.
JB/JNAE 小于转移.
JBE/JNA 小于或等于转移.
以上四条,测试无符号整数运算的结果(标志C和Z).
JG/JNLE 大于转移.
JGE/JNL 大于或等于转移.
JL/JNGE 小于转移.
JLE/JNG 小于或等于转移.
以上四条,测试带符号整数运算的结果(标志S,O和Z).
JE/JZ 等于转移.
JNE/JNZ 不等于时转移.
JC 有进位时转移.
JNC 无进位时转移.
JNO 不溢出时转移.
JNP/JPO 奇偶性为奇数时转移.
JNS 符号位为 "0" 时转移.
JO 溢出转移.
JP/JPE 奇偶性为偶数时转移.
JS 符号位为 "1" 时转移.
3>循环控制指令(短转移)
LOOP CX不为零时循环.
LOOPE/LOOPZ CX不为零且标志Z=1时循环.
LOOPNE/LOOPNZ CX不为零且标志Z=0时循环.
JCXZ CX为零时转移.
JECXZ ECX为零时转移.
4>中断指令
INT 中断指令
INTO 溢出中断
IRET 中断返回
5>处理器控制指令
HLT 处理器暂停, 直到出现中断或复位信号才继续.
WAIT 当芯片引线TEST为高电平时使CPU进入等待状态.
ESC 转换到外处理器.
LOCK 封锁总线.
NOP 空操作.
STC 置进位标志位.
CLC 清进位标志位.
CMC 进位标志取反.
STD 置方向标志位.
CLD 清方向标志位.
STI 置中断允许位.
CLI 清中断允许位.

六、伪指令
───────────────────────────────────────
  DW 定义字(2字节).
PROC 定义过程.
ENDP 过程结束.
SEGMENT 定义段.
ASSUME 建立段寄存器寻址.
ENDS 段结束.
END 程序结束.
例一
飞狐为初学者提供的又一篇教程

电子书制作软件介绍:我想熟悉电子书制作的人,应该知道这个软件。我喜欢它,是我常用的
一个工具。此软件是用aspack加的壳,很容易去的。未注册版本不能编辑和编译大于15个节点的项目。此次pj只是为了学习它的算法。为了作者的权益,我想各位如果喜欢这个软件
的话,请购买正版软件,以支持作者继续开发下去。同时也请作者海涵。
使用工具:trw2000。win32dasm(我用它只是为了取它的代码)
你可以设中断BPX HMEMCPY 剩下怎么追法就不用我说了吧。
:004F2440 8BD8 mov ebx, eax
:004F2442 8B55FC mov edx, dword ptr [ebp-04]
:004F2445 8BC3 mov eax, ebx
:004F2447 E89464FFFF call 004E88E0
:004F244C C6434400mov [ebx+44], 00
* Possible StringData Ref from Code Obj ->"F0E1"此字符串的作用是与你的用户名所计算
的数值相异或。
|
:004F2450 BA70254F00 mov edx, 004F2570此处地址存的就是F0E1
:004F2455 8BC3 mov eax, ebx
:004F2457 E82864FFFF call 004E8884
:004F245C 8BC3 mov eax, ebx
:004F245E E81967FFFF call 004E8B7C按F8进入吧。
:004F2463 837B3400cmp dword ptr [ebx+34], 00000000
:004F2467 0F84CB000000 je 004F2538
:004F246D 8B4334 mov eax, dword ptr [ebx+34]真码

:004F2470 8B55F8 mov edx, dword ptr [ebp-08]假码
:004F2473 E83429F1FF call 00404DAC比较二者是否相等。
如果你单纯想找到注册码,那么至此就可以了,如果你想学习它的算法,就请继续
往下看。
*******************************************************************
注册算法:
首先是计算注册码的前两位。
:004E89AA BF64000000 mov edi, 00000064它实际就是注册码的前两位
:004E89AF 8D45F0 lea eax, dword ptr [ebp-10]
:004E89B2 50 push eax
:004E89B3 897DDC mov dword ptr [ebp-24], edi
:004E89B6 C645E000mov [ebp-20], 00
:004E89BA 8D55DC lea edx, dword ptr [ebp-24]
:004E89BD 33C9 xor ecx, ecx

* Possible StringData Ref from Code Obj ->"%1.2x"
|
:004E89BF B8688B4E00 mov eax, 004E8B68
:004E89C4 E8CB17F2FF call 0040A194按F8进入吧。
欲知它的作用请看下文
:00409F52 80F944 cmp cl, 44
:00409F55 7415 je 00409F6C
:00409F57 80F955 cmp cl, 55
:00409F5A 7422 je 00409F7E
:00409F5C 80F958 cmp cl, 58
:00409F5F 0F8530FFFFFF jne 00409E95
:00409F65 B910000000 mov ecx, 00000010除数
:00409F6A EB17 jmp 00409F83

:00409F86 31D2 xor edx, edx为零
:00409F88 F7F1 div ecx EAX为64
:00409F8A 80C230 add dl, 30余数DL与30相加
:00409F8D 80FA3A cmp dl, 3A
:00409F90 7203 jb 00409F95
:00409F92 80C207 add dl, 07

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409F90(C)
|
:00409F95 4E dec esi串首地址减1
:00409F96 8816 mov byte ptr [esi], dl把结果存入ESI中
:00409F98 09C0 or eax, eax为刚才计算时的商。
:00409F9A 75EA jne 00409F86不相等就继续计算,
总结:此部分代码首先是计算注册码的第二位,然后再计算第一位,结果是64
:00409F9C 8D4D9F lea ecx, dword ptr [ebp-61]
:00409F9F 29F1 sub ecx, esi
:00409FA1 8B55DC mov edx, dword ptr [ebp-24]
:00409FA4 83FA10 cmp edx, 00000010
:00409FA7 7601 jbe 00409FAA
:00409FA9 C3 ret


***************************
第二步是根据你的用户名以及字符串F0E1计算剩下的几位注册码。注意所计算的ASCII值就是注册码,
用户名的位数乘以2就是注册码的位数。
0167:004E89DC MOV DWORD [EBP-14],01
0167:004E89E3 MOV EAX,[EBP-04]你所输入的用户名
0167:004E89E6 MOV EDX,[EBP-14]用户名的序号。
0167:004E89E9 MOVZX EAX,BYTE [EAX+EDX-01]取用户名中的一个字节
0167:004E89EE ADD EAX,EDI EDI是上一次计算出的密码。
0167:004E89F0 MOV ECX,FF除数
0167:004E89F5 CDQ
0167:004E89F6 IDIV ECX
0167:004E89F8 MOV EBX,EDX余数存入EBX中
0167:004E89FA CMP ESI,[EBP-0C] ESI是字符串F0E1的序号,
[EBP-0C]是F0E1这个字符串的个数(也就是4)

0167:004E89FD JNL 004E8A02大于就跳
0167:004E89FF INC ESI序号加1
0167:004E8A00 JMP SHORT 004E8A07
0167:004E8A02 MOV ESI,01重新赋值为1
0167:004E8A07 MOV EAX,[EBP-08]<==为字符串F0E1
0167:004E8A0A MOVZX EAX,BYTE [EAX+ESI-01]从字符串F0E1中取一个字符。
0167:004E8A0F XOR EBX,EAX二者相互异或。运行后EBX的值就是注册码。
0167:004E8A11 LEA EAX,[EBP-28]
0167:004E8A14 PUSH EAX
0167:004E8A15 MOV [EBP-24],EBX把注册码存入[EBP-24]中。
0167:004E8A18 MOV BYTE [EBP-20],00
0167:004E8A1C LEA EDX,[EBP-24]
0167:004E8A1F XOR ECX,ECX
0167:004E8A21 MOV EAX,004E8B68
0167:004E8A26 CALL 0040A194
0167:004E8A2B MOV EDX,[EBP-28]
0167:004E8A2E LEA EAX,[EBP-10]
0167:004E8A31 CALL 00404C70
0167:004E8A36 MOV EDI,EBX
0167:004E8A38 INC DWORD [EBP-14]
0167:004E8A3B DEC DWORD [EBP-1C]
0167:004E8A3E JNZ 004E89E3
举例说明:用户名:abcde(它们的ASCII值分别是61、62、63、64、65)
一、首先按照第一步的方法计算它的前两位注册码即64。
二、根据你的用户名以及字符串F0E1计算后几位注册码。
有几位用户名就得计算几次。
1、计算3、4位的密码。
取用户名的首字a(61),与前一步的注册码(64)相加,结果为c5;然后c5除以FF,
余数为c5,最后取F0E1中的F(ASCII值为46)相异或,结果为83,这就是第三、四
位的注册码。
2、计算5、6位的密码。
取用户名的第二个字符b(62),与前一步的注册码(83)相加,结果为e5;然后e5除以FF,
余数为e5,最后取F0E1中的0(ASCII值为30)相异或,结果为D5,这就是第五、六
位的注册码。
3、计算7、8位的密码。
取用户名的第三个字符c(63),与前一步的注册码(D5)相加,结果为138;然后138除以FF,
余数为39,最后取F0E1中的E(ASCII值为45)相异或,结果为7C,这就是第七、八
位的注册码。
4、计算9、10位的密码。
取用户名的第四个字符d(64),与前一步的注册码(7C)相加,结果为E0;然后E0除以FF,
余数为E0,最后取F0E1中的1(ASCII值为31)相异或,结果为D1,这就是第九、十
位的注册码。
5、计算11、12位的密码。
取用户名的第五个字符e(65),与前一步的注册码(D1)相加,结果为136;然后136除以FF,
余数为37,因为字符串F0E1已经循环完毕,所以重新设指针,取F0E1中的F(ASCII值为46)相异或,结果为71,这就是第11、12
位的注册码。
也就是:用户名:abcde 注册码:6483D57CD171
当用户名为汉字时与此同。

例二
算法分析:胜天财务进销存 XP 2003

破解作者:RUIWIN[OCN]

//////////////////////////////////////////////
///// 如何到达这里也不用多说了,文章主要是/////
///// 分析一下算法。 /////
//////////////////////////////////////////////


007C0CE6 |. 8B55 E8MOV EDX, DWORD PTR SS:[EBP-18]
007C0CE9 |. 58 POP EAX
007C0CEA |. E8 0544C4FF CALL 004050F4; 这个CALL是将机器码与注册名连接.
007C0CEF |. 8B45 ECMOV EAX, DWORD PTR SS:[EBP-14]; 把连后的地址传到EAX,后面称为MM
007C0CF2 |. 8D4D F4LEA ECX, DWORD PTR SS:[EBP-C]
007C0CF5 |. BA EC0D7C00 MOV EDX, 7C0DEC /////////////////// ******* 注意:这里是取地址7C0DEC 设为BB
007C0CFA |. E8 99FBFFFF CALL 007C0898================>算法就在里面。进去瞧瞧吧。



007C0DE7 FF DB FF
007C0DE8 04 DB 04
007C0DE9 00 DB 00
007C0DEA 00 DB 00
007C0DEB 00 DB 00
007C0DEC 01 DB 01 ***************BB
007C0DED 07 DB 07****************BB+1
007C0DEE 00 DB 00****************BB+2
007C0DEF 05 DB 05****************BB+3
007C0DF0 00 DB 00
007C0DF1 00 DB 00
007C0DF2 00 DB 00
007C0DF3 00 DB 00

////////////////////////////////////////////////////////
///////007C0CFA E899FBFFFF CALL 007C0898////////////
////////////////////////////////////////////////////////
007C0898 /$ 55 PUSH EBP
007C0899 |. 8BEC MOV EBP, ESP
007C089B |. 83C4 ECADD ESP, -14
007C089E |. 53 PUSH EBX
007C089F |. 56 PUSH ESI
007C08A0 |. 57 PUSH EDI
007C08A1 |. 33DB XOR EBX, EBX
007C08A3 |. 895D ECMOV DWORD PTR SS:[EBP-14], EBX
007C08A6 |. 895D F0MOV DWORD PTR SS:[EBP-10], EBX
007C08A9 |. 8BF1 MOV ESI, ECX
007C08AB |. 8955 F8MOV DWORD PTR SS:[EBP-8], EDX; [ebp-8]=BB
007C08AE |. 8945 FCMOV DWORD PTR SS:[EBP-4], EAX; [ebp-4]=MM
007C08B1 |. 8B45 FCMOV EAX, DWORD PTR SS:[EBP-4]; eax=MM 注意:BB和MM是地址值
007C08B4 |. E8 1B4AC4FF CALL 004052D4;
007C08B9 |. 8B45 F8MOV EAX, DWORD PTR SS:[EBP-8]; EAX=BB
007C08BC |. E8 134AC4FF CALL 004052D4;
007C08C1 |. 33C0 XOR EAX, EAX
007C08C3 |. 55 PUSH EBP
007C08C4 |. 68 6E097C00 PUSH 7C096E
007C08C9 |. 64:FF30PUSH DWORD PTR FS:[EAX]
007C08CC |. 64:8920MOV DWORD PTR FS:[EAX], ESP
007C08CF |. BB 01000000 MOV EBX, 1 ; ebx+1;初始为1
007C08D4 |. 8BC6 MOV EAX, ESI
007C08D6 |. E8 4945C4FF CALL 00404E24;
007C08DB |. 8B45 FCMOV EAX, DWORD PTR SS:[EBP-4]; eax=mm
007C08DE |. E8 0948C4FF CALL 004050EC; 取MM长度值放到EAXC
007C08E3 |. 8BF8 MOV EDI, EAX ; edi=eax=长度值
007C08E5 |. 85FF TEST EDI, EDI
007C08E7 |. 7E 49 JLE SHORT 007C0932 ;
007C08E9 |. C745 F4 01000>MOV DWORD PTR SS:[EBP-C], 1 ; [EBP-C]初始1TR
007C08F0 |> 8D45 F0/LEA EAX, DWORD PTR SS:[EBP-10]
007C08F3 |. 8B55 FC|MOV EDX, DWORD PTR SS:[EBP-4]; MM的地址传到EDXWORD
007C08F6 |. 8B4D F4|MOV ECX, DWORD PTR SS:[EBP-C]; ECX=1 ;[EBP-C]=1是来从上面)BP-C]
007C08F9 |. 8A540A FF |MOV DL, BYTE PTR DS:[EDX+ECX-1] ; 依次取MM一个字母放到DLPTR DS:[E
007C08FD |. 8B4D F8|MOV ECX, DWORD PTR SS:[EBP-8]; BB地址移到ECXDWOR
007C0900 |. 8A4C19 FF |MOV CL, BYTE PTR DS:[ECX+EBX-1] ; BB地址中的值放到CL,第一轮BB=01,第二轮BB=07,第三轮BB=00,第四轮BB=05,以MM四位为一个循环.
007C0904 |. 32D1 |XOR DL, CL ; MM第一位 XOR BB ,XOR后得到第一位注册码
007C0906 |. E8 F946C4FF |CALL 00405004;
007C090B |. 8B55 F0|MOV EDX, DWORD PTR SS:[EBP-10]
007C090E |. 8BC6 |MOV EAX, ESI
007C0910 |. E8 DF47C4FF |CALL 004050F4;
007C0915 |. 8B45 F8|MOV EAX, DWORD PTR SS:[EBP-8]
007C0918 |. E8 CF47C4FF |CALL 004050EC;
007C091D |. 8D53 01|LEA EDX, DWORD PTR DS:[EBX+1]; EDX=EBX+1 作用是为BB作循环读数器.BX+1]
007C0920 |. 3BC2 |CMP EAX, EDX ; EDX是否大于4 EDX
007C0922 |. 7C 03 |JL SHORT 007C0927 ; 如果EDX大于4的话EBX就重新赋值
007C0924 |. 43 |INC EBX ; ebx+1
007C0925 |. EB 05 |JMP SHORT 007C092C ;
007C0927 |> BB 01000000 |MOV EBX, 1 ; EBX大于的话就重新初始为1
007C092C |> FF45 F4|INC DWORD PTR SS:[EBP-C] ; [ebp-c]自加1 ;我的理解是MM的读数器.
007C092F |. 4F |DEC EDI ; 长度-1ED
007C0930 |.^ 75 BE \JNZ SHORT 007C08F0 ; 未取完继续向上取T 007C08
007C0932 |> 8D55 ECLEA EDX, DWORD PTR SS:[EBP-14]
007C0935 |. 8B06 MOV EAX, DWORD PTR DS:[ESI] ; 到这里已经得到所有异或后的注册码了,但还不是真正的注册码.还要处理一下.我的注册码是:XME\K6G11273876<125=36rphpikā?




007C096D \. C3 RETN

//////////////////////////////////////////////////////////////////////
///////// 从CALL出来//////////////
///////// 接007C0CFA E899FBFFFF CALL 007C0898 之后//////////////
//////////////////////////////////////////////////////////////////////

007C0CFA |. E8 99FBFFFF CALL 007C0898 ;这个CALL是我们刚才进去看算法的CALL,已经看过了,我们接着往下看吧。
007C0CFF |. 8D55 E4LEA EDX, DWORD PTR SS:[EBP-1C]; MM
007C0D02 |. 8B45 F4MOV EAX, DWORD PTR SS:[EBP-C] ; 未处理过的注册码,设为MM2PTR SS:[EB
007C0D05 |. E8 F6000000 CALL 007C0E00 ; WINSALE.007C0E00
007C0D0A |. 8B55 E4MOV EDX, DWORD PTR SS:[EBP-1C]
007C0D0D |. 8D45 F4LEA EAX, DWORD PTR SS:[EBP-C]
007C0D10 |. E8 A741C4FF CALL 00404EBC ; 这个CALL就是把MM2过滤.也就是注册码只要"A-Z" "a-z" "0-9"其余的滤除不要
007C0D15 |. 8B45 F4MOV EAX, DWORD PTR SS:[EBP-C] ; EAX=[EBP-C]=XMEK6G1127387612536rphpik
007C0D18 |. E8 CF43C4FF CALL 004050EC ; WINSALE.004050EC
007C0D1D |. 8BF0 MOV ESI, EAX
007C0D1F |. 85F6 TEST ESI, ESI
007C0D21 |. 7E 46 JLE SHORT 007C0D69 ;
007C0D23 |. BB 01000000 MOV EBX, 1
007C0D28 |> 8D45 E0/LEA EAX, DWORD PTR SS:[EBP-20];/////////////////
007C0D2B |. 50 |PUSH EAX ;//这一段懒得/////
007C0D2C |. B9 01000000 |MOV ECX, 1 ;//去分析它了。///
007C0D31 |. 8BD3 |MOV EDX, EBX ;//它的主要作用///
007C0D33 |. 8B45 F4|MOV EAX, DWORD PTR SS:[EBP-C];//就是每四位注///
007C0D36 |. E8 0946C4FF |CALL 00405344;//册码之间插入///
007C0D3B |. 8B55 E0|MOV EDX, DWORD PTR SS:[EBP-20];//一个“-”。////
007C0D3E |. 8D45 F0|LEA EAX, DWORD PTR SS:[EBP-10];/////////////////
007C0D41 |. E8 AE43C4FF |CALL 004050F4;/////////////////
007C0D46 |. 8BC3 |MOV EAX, EBX ;/////////////////
007C0D48 |. 25 03000080 |AND EAX, 80000003 ;/////////////////
007C0D4D |. 79 05 |JNS SHORT 007C0D54 ;/////////////////
007C0D4F |. 48 |DEC EAX ;/////////////////
007C0D50 |. 83C8 FC|OR EAX, FFFFFFFC ;/////////////////
007C0D53 |. 40 |INC EAX ;/////////////////
007C0D54 |> 85C0 |TEST EAX, EAX;/////////////////
007C0D56 |. 75 0D |JNZ SHORT 007C0D65 ;/////////////////
007C0D58 |. 8D45 F0|LEA EAX, DWORD PTR SS:[EBP-10];/////////////////
007C0D5B |. BA FC0D7C00 |MOV EDX, 7C0DFC ;/////////////////
007C0D60 |. E8 8F43C4FF |CALL 004050F4;/////////////////
007C0D65 |> 43 |INC EBX ;/////////////////
007C0D66 |. 4E |DEC ESI ;/////////////////
007C0D67 |.^ 75 BF \JNZ SHORT 007C0D28 ;/////////////////
007C0D69 |> 8D45 DCLEA EAX, DWORD PTR SS:[EBP-24]
007C0D6C |. 50 PUSH EAX
007C0D6D |. 8B45 F0MOV EAX, DWORD PTR SS:[EBP-10];得到我的注册码:XMEK-6G11-2738-7612-536r-phpi-k
007C0D70 |. E8 7743C4FF CALL 004050EC ;





////////////////////////////////////////////////////
//////////////// 算法小结: ////
////////////////////////////////////////////////////
它先定义四个常数,分别是1、7、0、5 [注意:是按顺序的,因为它要循环嘛]上面设为BB
然后取机器码和注册名连接。
如:
机器码:YJEYJ1G405769069055821
注册名:ruiwin
两者连接得:YJEYJ1G405769069055821ruiwin 上面设为MM

Y J E Y J 1 G 4 0 5 7 6 9 0 6 9 0 5 5 8 2 1 r u i w i n
XOR
1 7 0 5 1 7 0 5 1 7 0 5 1 7 0 5 1 7 0 5 1 7 0 5 1 7 0 5
=
X M E \ K 6 G 1 1 2 7 3 8 7 6 < 1 2 5 = 3 6 r p h p i k
只取A-Z a-z 0-9 其余的滤除得:
XMEK6G1127387612536rphpik
然后每间隔四位加一个“-”得到真正注册码:
XMEK-6G11-2738-7612-536r-phpi-k

例三
破解软件:Easun Studio Windows系统切换工具
破解人:powerboy[ocn]
NAME:powerboy
SN:2123771504
下载地址:http://easun.yeah.net(路杨工作室)www.softreg.com

破解:该软件是用aspack v2.11加的壳,轻松脱壳反汇编后:

:00407032 68A4924100 push 004192A4
:00407037 51 push ecx

* Reference To: MFC42.Ordinal:0B02, Ord:0B02h
|
:00407038 E8B78D0000 Call 0040FDF4----------------->获取用户名长度
:0040703D 8B54241Cmov edx, dword ptr [esp+1C]
:00407041 83C40C add esp, 0000000C
:00407044 8B42F8 mov eax, dword ptr [edx-08]
:00407047 83F803 cmp eax, 00000003------------->比较用户名长度和3
:0040704A 7D0E jge 0040705A------------------>大于则跳
:0040704C 6AFF push FFFFFFFF
:0040704E 6A00 push 00000000

* Possible Reference to String Resource ID=61491: "You name should at lest be 3 characters."
|
:00407050 6833F00000 push 0000F033
:00407055 E9B5010000 jmp 0040720F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040704A(C)
|
:0040705A 53 push ebx
:0040705B 6A00 push 00000000
:0040705D 6874040000 push 00000474
:00407062 8BCF mov ecx, edi

* Reference To: MFC42.Ordinal:0C17, Ord:0C17h
|
:00407064 E8978D0000 Call 0040FE00------------------>将输入的注册码变成十六进制设为SN16
:00407069 8BF0 mov esi, eax------------------->ESI=EAX
:0040706B 8D442410lea eax, dword ptr [esp+10]
:0040706F 56 push esi
:00407070 51 push ecx
:00407071 8BCC mov ecx, esp
:00407073 8964241Cmov dword ptr [esp+1C], esp
:00407077 50 push eax


* Reference To: MFC42.Ordinal:0217, Ord:0217h
|
:00407078 E8CD8E0000 Call 0040FF4A
:0040707D 8BCF mov ecx, edi
:0040707F E83C020000 call 004072C0 ------------------>关键CALL1->F8
:00407084 85C0 test eax, eax ---->测试eax=0吗?注册标记!
:00407086 0F847A010000 je 00407206 ---->等于0则跳,跳就死
:0040708C 56 push esi
:0040708D 8D4C241Clea ecx, dword ptr [esp+1C]

* Possible Reference to Dialog:
|
:00407091 68AC904100 push 004190AC
:00407096 51 push ecx

* Reference To: MFC42.Ordinal:0B02, Ord:0B02h
|
:00407097 E8588D0000 Call 0040FDF4
:0040709C 8B542424mov edx, dword ptr [esp+24]
:004070A0 8D442424lea eax, dword ptr [esp+24]
:004070A4 52 push edx

* Possible StringData Ref from Data Obj ->"%s"
|
:004070A5 68A4924100 push 004192A4
:004070AA 50 push eax

* Reference To: MFC42.Ordinal:0B02, Ord:0B02h
|
:004070AB E8448D0000 Call 0040FDF4
:004070B0 8B4764 mov eax, dword ptr [edi+64]
:004070B3 8B4C2428mov ecx, dword ptr [esp+28]

* Reference To: KERNEL32.WritePrivateProfileStringA, Ord:02E5h
|
:004070B7 8B2DB0304100 mov ebp, dword ptr [004130B0]
:004070BD 83C418 add esp, 00000018
:004070C0 50 push eax
:004070C1 51 push ecx

* Possible StringData Ref from Data Obj ->"User"
|
:004070C2 683C964100 push 0041963C

* Possible StringData Ref from Data Obj ->"Easun"
|
:004070C7 6834964100 push 00419634
:004070CC FFD5 call ebp
:004070CE 8D7760 lea esi, dword ptr [edi+60]

* Possible StringData Ref from Data Obj ->"key.dll" -->注册后,生成此文件->删除又是未注册版
|
:004070D1 682C964100 push 0041962C
:004070D6 8D542418lea edx, dword ptr [esp+18]
:004070DA 56 push esi
:004070DB 52 push edx
============================================================================================
追入关键call1到这里............
* Referenced by a CALL at Address:
|:0040707F
|
:004072C0 6AFF push FFFFFFFF
:004072C2 68B8114100 push 004111B8
:004072C7 64A100000000 mov eax, dword ptr fs:[00000000]
:004072CD 50 push eax
:004072CE 64892500000000 mov dword ptr fs:[00000000], esp
:004072D5 83EC10 sub esp, 00000010
:004072D8 53 push ebx
:004072D9 55 push ebp
:004072DA 56 push esi
:004072DB 57 push edi
:004072DC 8BF9 mov edi, ecx
:004072DE 51 push ecx
:004072DF 8D442434lea eax, dword ptr [esp+34]
:004072E3 8BCC mov ecx, esp
:004072E5 8964241Cmov dword ptr [esp+1C], esp
:004072E9 50 push eax
:004072EA C744243000000000mov [esp+30], 00000000

* Reference To: MFC42.Ordinal:0217, Ord:0217h
|
:004072F2 E8538C0000 Call 0040FF4A
:004072F7 8BCF mov ecx, edi
:004072F9 E822010000 call 00407420 -->根据NAME计算-->call(2)
:004072FE 8BF0 mov esi, eax -->把计算后的数值传给esi
:00407300 85F6 test esi, esi
:00407302 0F84F0000000 je 004073F8
:00407308 51 push ecx
:00407309 8BCC mov ecx, esp
:0040730B 8964241Cmov dword ptr [esp+1C], esp

* Possible Reference to Dialog:
|
:0040730F 6894964100 push 00419694

* Reference To: MFC42.Ordinal:0219, Ord:0219h
|
:00407314 E8178B0000 Call 0040FE30
:00407319 8BCF mov ecx, edi
:0040731B E800010000 call 00407420--------->根据"EasunLee"进行计算
:00407320 51 push ecx ------------->EBP=0x629B
:00407321 8BD8 mov ebx, eax
:00407323 8BCC mov ecx, esp
:00407325 8964241Cmov dword ptr [esp+1C], esp

* Possible Reference to Dialog:
|
:00407329 6894964100 push 00419694

* Reference To: MFC42.Ordinal:0219, Ord:0219h
|
:0040732E E8FD8A0000 Call 0040FE30
:00407333 8BCF mov ecx, edi
:00407335 E8E6000000 call 00407420
:0040733A 51 push ecx
:0040733B 8BE8 mov ebp, eax
:0040733D 8BCC mov ecx, esp
:0040733F 8964241Cmov dword ptr [esp+1C], esp

* Possible Reference to Dialog:
|
:00407343 6880964100 push 00419680

* Reference To: MFC42.Ordinal:0219, Ord:0219h
|
:00407348 E8E38A0000 Call 0040FE30
:0040734D 8BCF mov ecx, edi
:0040734F E8CC000000 call 00407420--------->根据"easunlee98meiosys"进行计算
:00407354 51 push ecx-------------->[ESP+14]=0xE69BB
:00407355 89442418mov dword ptr [esp+18], eax
:00407359 8BCC mov ecx, esp
:0040735B 8964241Cmov dword ptr [esp+1C], esp

* Possible Reference to Dialog:
|
:0040735F 6864964100 push 00419664

* Reference To: MFC42.Ordinal:0219, Ord:0219h
|
:00407364 E8C78A0000 Call 0040FE30
:00407369 8BCF mov ecx, edi
:0040736B E8B0000000 call 00407420---------->根据"Luyanghs&&Tsai&&bluebird"进行计算
:00407370 51 push ecx--------------->[ESP+10]=0x682B7762
:00407371 89442414mov dword ptr [esp+14], eax
:00407375 8BCC mov ecx, esp
:00407377 8964241Cmov dword ptr [esp+1C], esp

* Possible Reference to Dialog:
|
:0040737B 685C964100 push 0041965C

* Reference To: MFC42.Ordinal:0219, Ord:0219h
|
:00407380 E8AB8A0000 Call 0040FE30
:00407385 8BCF mov ecx, edi
:00407387 E894000000 call 00407420---------->根据"hesheng"进行计算
:0040738C 51 push ecx--------------->EDX=0x340E
:0040738D 8944241Cmov dword ptr [esp+1C], eax
:00407391 8BCC mov ecx, esp
:00407393 89642420mov dword ptr [esp+20], esp

* Possible Reference to Dialog:
|
:00407397 6850964100 push 00419650

* Reference To: MFC42.Ordinal:0219, Ord:0219h
|
:0040739C E88F8A0000 Call 0040FE30
:004073A1 8BCF mov ecx, edi
:004073A3 E878000000 call 00407420---------->根据"200970878"进行计算得EAX=0x6E0A

EAX=0x6E0A ; EDX=0x340E ; EBP=0x629B ; [ESP+14]=0xE69BBB ; [ESP+18]=0x340E ; [ESP+10]=0x682B7762;
ESI=NAME16=0x71F2 "powerboy"经过计算所得 //// [ESP+34]=SN十六进制

:004073A8 81F678EE0220 xor esi, 2002EE78------------->ESI=ESI XOR 0x2002EE78
:004073AE 8B7C2414mov edi, dword ptr [esp+14]--->EDI=[ESP+14]=0xE69BB
:004073B2 81EE21050E20 sub esi, 200E0521------------->ESI=ESI-0x200E0521
:004073B8 8B542418mov edx, dword ptr [esp+18]--->EDX=[ESP+18]=0x340E
:004073BC 81F678563472 xor esi, 72345678------------->ESI=ESI XOR 0x72345678
:004073C2 81EE88F76877 sub esi, 7768F788------------->ESI=ESI-0x7768F788
:004073C8 33F3 xor esi, ebx------------------>ESI=ESI XOR EBX =ESI XOR 0x629B
:004073CA 8B5C2410mov ebx, dword ptr [esp+10]--->EBX=[ESP+10]=0x682B7762
:004073CE 03F5 add esi, ebp------------------>ESI=ESI+EBP=ESI+0x629B
:004073D0 33F3 xor esi, ebx------------------>ESI=ESI XOR EBX=ESI XOR 0x682B7762
:004073D2 33F7 xor esi, edi------------------>ESI=ESI XOR EDI=ESI XOR 0xE69BBB
:004073D4 2BF2 sub esi, edx------------------>ESI=ESI-EBX=ESI-0x340E
:004073D6 03F0 add esi, eax------------------>ESI=ESI+EAX=ESI+0x6E0A
:004073D8 8B442434mov eax, dword ptr [esp+34]--->EAX=SN16
:004073DC 3BF0 cmp esi, eax------------------>比较EAX和ESI
:004073DE 7518 jne 004073F8------------------>不相等则跳
:004073E0 8D4C2430lea ecx, dword ptr [esp+30]
:004073E4 C7442428FFFFFFFFmov [esp+28], FFFFFFFF

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:004073EC E8F1890000 Call 0040FDE2
:004073F1 B801000000 mov eax, 00000001 -->如果esi与eax相等就把注册标记传给eax
:004073F6 EB13 jmp 0040740B

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00407302(C), :004073DE(C)
|
:004073F8 8D4C2430lea ecx, dword ptr [esp+30]
:004073FC C7442428FFFFFFFFmov [esp+28], FFFFFFFF

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:00407404 E8D9890000 Call 0040FDE2
:00407409 33C0 xor eax, eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004073F6(U)
|
:0040740B 8B4C2420mov ecx, dword ptr [esp+20]
:0040740F 5F pop edi
:00407410 5E pop esi
:00407411 5D pop ebp
:00407412 64890D00000000 mov dword ptr fs:[00000000], ecx
:00407419 5B pop ebx
:0040741A 83C41C add esp, 0000001C
:0040741D C20800 ret 0008
================================================================================
跟进call2来到这里 ...............

* Referenced by a CALL at Addresses:
|:004072F9 , :0040731B , :00407335 , :0040734F , :0040736B
|:00407387 , :004073A3
|
:00407420 64A100000000 mov eax, dword ptr fs:[00000000]
:00407426 6AFF push FFFFFFFF
:00407428 68D8114100 push 004111D8
:0040742D 50 push eax
:0040742E 64892500000000 mov dword ptr fs:[00000000], esp
:00407435 56 push esi
:00407436 57 push edi
:00407437 8B7C2418mov edi, dword ptr [esp+18]
:0040743B 8B57F8 mov edx, dword ptr [edi-08]
:0040743E 83FA03 cmp edx, 00000003
:00407441 7D26 jge 00407469
:00407443 8D4C2418lea ecx, dword ptr [esp+18]
:00407447 C7442410FFFFFFFFmov [esp+10], FFFFFFFF

* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:0040744F E88E890000 Call 0040FDE2
:00407454 33C0 xor eax, eax
:00407456 8B4C2408mov ecx, dword ptr [esp+08]
:0040745A 64890D00000000 mov dword ptr fs:[00000000], ecx
:00407461 5F pop edi
:00407462 5E pop esi
:00407463 83C40C add esp, 0000000C
:00407466 C20400 ret 0004

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00407441(C)
|
:00407469 33F6 xor esi, esi
:0040746B 33C9 xor ecx, ecx
:0040746D 85D2 test edx, edx
:0040746F 7E0D jle 0040747E

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040747C(C)
|
:00407471 0FBE0439movsx eax, byte ptr [ecx+edi]----->依次取注册名
:00407475 D3E0 shl eax, cl ---------------------->EAX=EAX << ECX 逻辑左移ECX
:00407477 03F0 add esi, eax---------------------->ESI=ESI+EAX 把左移后的结果累加
:00407479 41 inc ecx -------------------------->ECX=ECX+1
:0040747A 3BCA cmp ecx, edx---------------------->比较注册名是否取完
:0040747C 7CF3 jl 00407471----------------------->没取完,继续
================================================================================

算法整理:
1.首先把:“NAME”、“EasunLee”、"200970878"、"hesheng"、"Luyanghs&&Tsai&&bluebird"、"easunlee98meiosys"
这6个字符串按照关键CALL2进行计算,所得的值分别存入一下寄存器中:
1.NAME("powerboy")======================ESI=0x71F2;
2."200970878"进行计算得=================EAX=0x6E0A;
3."EasunLee"计算所得====================EBP=0x629B;
4."hesheng"进行计算=====================EDX=[ESP+18]=0x340E;
5."easunlee98meiosys"进行计算所得=======[ESP+14]=0xE69BBB ;
6."Luyanghs&&Tsai&&bluebird"============[ESP+10]=0x682B7762;
7. SN变成十六进制=======================[ESP+34]=SN十六进制;
2.然后进行计算
ESI=ESI XOR 0x2002EE78
EDI=[ESP+14]=0xE69BB
ESI=ESI-0x200E0521
EDX=[ESP+18]=0x340E
>ESI=ESI XOR 0x72345678
>ESI=ESI-0x7768F788
>ESI=ESI XOR EBX =ESI XOR 0x629B
>EBX=[ESP+10]=0x682B7762
>ESI=ESI+EBP=ESI+0x629B
>ESI=ESI XOR EBX=ESI XOR 0x682B7762
>ESI=ESI XOR EDI=ESI XOR 0xE69BBB
>ESI=ESI-EBX=ESI-0x340E
>ESI=ESI+EAX=ESI+0x6E0A
将ESI变成十六进制就是正确的注册码了
以我的用户名为例:
"powerboy"------ESI=0x71F2

>ESI=ESI XOR 0x2002EE78=0x71F2 XOR 0x2002EE78=0x20029F8A
>EDI=[ESP+14]=0xE69BB
>ESI=ESI-0x200E0521=0x20029F8A-0x200E0521=0xFFF49A69
>EDX=[ESP+18]=0x340E
>ESI=ESI XOR 0x72345678=0xFFF49A69 XOR 0x72345678=0x8DC0CC11
>ESI=ESI-0x7768F788=0x8DC0CC11-0x7768F788=0x1657D489
>ESI=ESI XOR EBX =0x1657D489 XOR 0x629B=0x1657B612
>EBX=[ESP+10]=0x682B7762
>ESI=ESI+EBP=0x1657B612+0x629B=0x165818AD
>ESI=ESI XOR EBX=0x165818AD XOR 0x682B7762=0x7E736FCF
>ESI=ESI XOR EDI=0x7E736FCF XOR 0xE69BBB=0x7E95F474
>ESI=ESI-EBX=0x7E95F474-0x340E=0x7E962E70
>ESI=ESI+EAX=0x7E962E70+0x6E0A=0x7E962E70

0x7E962E70=2123771504
级别: 光盘中级
发帖
237
飞翔币
335
威望
363
飞扬币
708
信誉值
0
只看该作者 1 发表于: 2006-06-04
算法教学第二课

如何快速找到 关键call关键jn,大家知道这是算法开始的关键,找到了等于成功了一半。
我的经验是这样的:首先看程序的代码的位置,比如0047A012,然后看CALL子程序的指向,假如指向的也是0047XXXX,那这个子程序应该是作者自己写的,应该特别注意。但是假如指向的是0040XXXX,一般来说是系统级的子程序调用,比如取字符串长度,字符串比较。这样的CALL就不用跟踪进去了,只需要知道入口参数、出口参数基本就知道这个子程序的功能了。
不过,猜也不是办法,最好能有这方面的资料。比如WINDOWS下的汇编手册之类的。

Talisman 2.3 注册算法分析(算法入门)
目的:给已经破解入门的朋友一些启示,使其更快的学会算法!
输入用户名:powerboy(要记住啊!下面你就知道作用了啊!)
注册码任意:1234567890(我喜欢这样因为这样就能知道程序到底是取哪位注册码进行比较的啊!)

程序地址: http://www.skycn.com/download.php?id=3877&url=http://js.skycn.net/down/talisman.zip
破解之前先介绍一些汇编指令:
jle----的意思是说小于或等于0则跳;
inc----每次加1,类似i++或i=i+1;
dec----每次减1,类似i--或i=i-1;
jnz----不为0则跳;

下断点:BPX HMEMCPY
点击注册按钮被拦到.....
按F12共N次来到下面........

0047B5E8 E82787F8FF call 00403D14
0047B5ED 85C0 test eax, eax
0047B5EF 7E13 jle 0047B604
0047B5F1 BA01000000 mov edx, $00000001
0047B5F6 8B4DF8 mov ecx, [ebp-$08]
0047B5F9 0FB64C11FF movzx ecx, byte ptr [ecx+edx-$01]
0047B5FE 03F1 add esi, ecx
0047B600 42 inc edx
0047B601 48 dec eax
0047B602 75F2 jnz 0047B5F6
0047B604 8975EC mov [ebp-$14], esi
0047B607 DB45EC fild dword ptr [ebp-$14]
0047B60A E8B173F8FF call 004029C0
0047B60F 69C009030000 imul eax, eax, $00000309
0047B615 8BF0 mov esi, eax
0047B617 3B75FC cmp esi, [ebp-$04]
0047B61A 0F85BF000000 jnz 0047B6DF
0047B620 B201 mov dl, $01

****下面我们来仔细解释一下程序********************************************

0047B5E8 E82787F8FF call 00403D14******************//这个CALL的作用是获取用户名长度,作为循环标志;
-----------------------------------------------------------------------------------------------------------------------
为什么是这样哪!听我来解释:
当你走过call 00403D14的时候你就会发现EAX变颜色了,其值变了,如果你记住了你输入的用户名就会想出来了。EAX的值等于你输入用户名的长度,这就证明call 00403D14的作用是获取用户名的长度(这就是动态调试的好处了,不用分析就可以知道CALL的作用),这样我们就可以不用分析这个CALL就可以知道这个CALL的作用了,是不是很方便啊!!!!!!!!
-----------------------------------------------------------------------------------------------------------------------
0047B5ED 85C0 test eax, eax******************//这句是比较EAX是不是为0
0047B5EF 7E13 jle 0047B604******************//jle的意思是说小于或等于0则跳
-----------------------------------------------------------------------------------------------------------------------
这就证明这三句程序是获取用户名长度并比较用户名长度是否为0,为0则跳.(如果跳了,就证明你没输入用户名啊!对吗?)
-----------------------------------------------------------------------------------------------------------------------

0047B5F1 BA01000000 mov edx, $00000001************//EDX=1;这里是给EDX复初值为1
0047B5F6 8B4DF8 mov ecx, [ebp-$08]************//(ECX为用户名)怎么知道的呢!用D ECX 啊!
0047B5F9 0FB64C11FF movzx ecx, byte ptr [ecx+edx-$01]
0047B5FE 03F1 add esi, ecx
0047B600 42 inc edx***********************//EDX=EDX+1
0047B601 48 dec eax***********************//EAX=EAX-1
0047B602 75F2 jnz 0047B5F6(此处是一个用户名ASC值累加过程)
-----------------------------------------------------------------------------------------------------------------------
有破解基础的人也许会问,这里只是一个不等则跳的跳转怎么是说明将用户名ASCII码值累积相加的过程哪?

其实是这样的,EAX=EAX-1 然后比较EAX不为0则跳,也就是说EAX每次都减1只道减到0为止,那么就证明是一个循环并以EAX的值作为循环结束与否的标志,用动态调试使用F10键就可以看出是个循环。
那么我们来分析一下EAX是干什么用的呢!对了上面解释了啊!EAX中保存着用户名的长度啊!
-----------------------------------------------------------------------------------------------------------------------
然后向跳转的上面看啊!
movzx ecx, byte ptr [ecx+edx-$01]//这句程序代码说明ECX按位取用户名的ASCII码值
(顺便说一下程序中用户名参与计算都是将用户名变成ASCII码值在参与计算的)动态调试就知道了啊!不信你注意看每次循环到这里的时候ECX的值都会改变,是按怎么样的规律改变的呢!就是每进行一次循环都取一位用户名字母的ASCII码值;
下面,假设你的用户名为 ABC
当你的光标第一次停在这里时,你会发现ECX=00,再按一个F10,看 ECX 寄存器的值,以蓝色高亮显示,ECX 发生变化,变为0,结合movzx指令的解释,可以理解为,从[eax+edx-01]取 0 送 ecx 。大家要学会观察,高亮显示表示上一步执行后的结果,结合上一行的汇编指令,就很容易理解。这是关键中的关键!!!!!
当你第2次来到这里时,XXX 变成什么?是41,41是16进制值,你在 SoftICE 中下 ? 41 (注意,TRW 2000 是没有这项功能的!),看到 41 转换成为字符"A",所以第二次循环在这里是取字符"A"。同理,第3、4次分别取的是"B","C",当取完所有字符后,循环也准备结束了。既然它取你的用户名各个字符进行了计算,所以,这段肯定是算法无疑了!!!!!!!
(建议你破解软件用sice因为用sice 的 ? eax 命令就可以将ASCII码变回原形式,例如:eax=41;? eax;那么就显示eax="A"怎么样懂了吗?)
------------------------------------------------------------------------------------------------------------------------
最后,看0047B5FE 03F1add esi, ecx************//这句是说ESI=ESI+ECX(如果这句都不懂我劝你该补习一下汇编的知识了)
在每次循环到这句的时候都用ESI+ECX并把值都保存到ESI中,你说是什么作用啊!
------------------------------------------------------------------------------------------------------------------------
0047B604 8975EC mov [ebp-$14], esi*****************//这句是将ESI送入[EBP-14]我们设为A以后要用的,记住啊!
0047B607 DB45EC fild dword ptr [ebp-$14] 也就是说[EBP-14]中保存着,我们用用户名计算的值

* Reference to: system.@ROUND;
|
0047B60A E8B173F8FF call 004029C0***********************//通过这句之后EAX=[EBP-14]等于我们之前计算所得的值
------------------------------------------------------------------------------------------------------------------------
这里提醒大家对于能通过查看寄存器的数值变化就可以知道该CALL作用的时候,就不用在F8跟进CALL中了,以减少破解的时间和工作量。并且有时候还看不太懂的。
------------------------------------------------------------------------------------------------------------------------
0047B60F 69C009030000 imul eax, eax, $00000309 ***********//EAX=EAX*0x309 这时EAX中就是我们上面计算所得的A
(注意!这里是十六进计算!)
------------------------------------------------------------------------------------------------------------------------
这句程序的意思是,将上面计算所得的将用户名累加的值,与常数Ox309相乘.
------------------------------------------------------------------------------------------------------------------------
0047B615 8BF0 mov esi, eax***********************//ESI=EAX等于通过我们输入的用户名计算所得的数值
0047B617 3B75FC cmp esi, [ebp-$04]*****************//比较ESI和[EBP-04]中的值
------------------------------------------------------------------------------------------------------------------------
既然ESI保存着用用户名计算所得的数值,[EBP-04]就应该相应保存着要与其比较的值会是什么呢!用? *(EBP-04)看一下;果然保存着我们输入的注册码哈哈!!!那么用用户名计算所得的数值就是正确的注册码了啊!!(算法就是这么简单怎么样学会了吗?)
------------------------------------------------------------------------------------------------------------------------
0047B61A 0F85BF000000 jnz 0047B6DF **********************//不跳就成功,跳就失败(爆破该这里)
0047B620 B201 mov dl, $01 **********//这里就是成功的标志位,可能会和重启效验有关这里就不介绍了!
**************************************************************************************************************************

既然已经分析完了算法,我们来进行一下手算测试:

我们以大写的ABC为用户名进行一下计算来验证一下我们分析的算法是否正确!
首先,先查出A、B、C的ASCII码值;
"A"=41;"B"=42;"C"=43;
然后,根据算法将用户名的ASCII码值累加;
0x41+0x42+0x43=0xC6(用WINDOWS自带的计算器就可以。但是,注意为十六进制计算啊!)
最后,根据算法将累加后的值与常数0x309相乘;
0xC6*0x309=0x258F6
看看258F6是不是正确的注册码啊!
嗯!!!!!!!!!
居然不是为什么呢?在分析一下程序,原来比较的时候是用0x258F6和0x4996022D2(1234567890的十六进制数)进行比较的!那么我们输入的注册码就应该是0x258F6的十进制形式啊。
好了原因已经清楚了,计算吧!将0x258F6变一下形为153846(别告诉我你不会变,我倒!用windows自带的计算器啊!)
在次输入哈!^_^正确了吧!
--------------------------------------------------------------
keymake 编写注册机源码
.data
szHomePage db "http://www.1699.net/bbs/list.asp?boardid=72",0
szEmail db "mailto:powerboy_bcg@163.com",0
szErrMess db "输入的序列号不正确!",0
szdec db "%1u",0
hShow db 30 dup(0)
.code
MOV ESI,EAX
invoke lstrlen,esi
XOR EBX,EBX
XOR ECX,ECX
XOR EDX,EDX
XOR EDI,EDI
MOV EDX,1
begin:
MOVZX EBX, byte ptr [ESI+EDX-1]
ADD EDI,EBX
INC EDX
CMP EDX,EAX
JLE begin
MOV EAX,EDI
IMUL EAX,EAX,309h
PUSH EAX
PUSH OFFSET szdec
PUSH OFFSET hShow
CALL wsprintf
LEA EAX,hShow

谢谢大家能看到这里,不知道大家看懂没有,这只是本人一些经验之谈希望能令大家少走一些弯路!