前言
首先十分感谢整理这些CrackMe的吾爱大佬,真是方便了我这样的小白。希望最后这160个CrackMe都可以做出,我会认真做好分析过程的。
准备
- 系统:Windows 7 SP1 x64 ultimate
- 工具:PEiD、OD
分析
运行程序,看下需要做些什么。
程序先弹出了一个对话框,就是一个简单的欢迎框,确定后即可看到主界面。
从主界面可以看到该程序有两个需要破解的地方,一个是左边的按钮,点开是序列号与用户名破解,另一个是右边的按钮,点开是序列号的破解。
那么,一个一个来吧。
Serial
先从单独一个序列号的开始吧。
先查下壳。
无壳,Delphi写的。
在序列号输入框中,随便输入,看看得到什么提示。
得到一个Try Again!
的提示。
将程序载入OD,搜索下字符串,可以看到三个Try Again!
字符串。其中有一个挨着Failed
,所以猜测可能是这个。
双击定位,然后在调用函数的地方下断。
运行程序,输入错误的序列号,成功断下。
0042F4CA |. 8B45 F0 mov eax,[local.4]
0042F4CD |. 8B55 F4 mov edx,[local.3]
0042F4D0 |. E8 2745FDFF call Acid_bur.004039FC //检测输入的序列号
0042F4D5 |. 75 1A jnz short Acid_bur.0042F4F1
0042F4D7 |. 6A 00 push 0x0
0042F4D9 |. B9 64F54200 mov ecx,Acid_bur.0042F564 ; Congratz!
0042F4DE |. BA 70F54200 mov edx,Acid_bur.0042F570 ; God Job dude !! =)
0042F4E3 |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042F4E8 |. 8B00 mov eax,dword ptr ds:[eax]
0042F4EA |. E8 81ACFFFF call Acid_bur.0042A170
0042F4EF |. EB 18 jmp short Acid_bur.0042F509
0042F4F1 |> 6A 00 push 0x0
0042F4F3 |. B9 84F54200 mov ecx,Acid_bur.0042F584 ; Failed!
0042F4F8 |. BA 8CF54200 mov edx,Acid_bur.0042F58C ; Try Again!!
0042F4FD |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042F502 |. 8B00 mov eax,dword ptr ds:[eax]
0042F504 |. E8 67ACFFFF call Acid_bur.0042A170
0042F509 |> 33C0 xor eax,eax
可以看到成功提示和失败提示紧挨着,说明0x0042F4D0处调用的Acid_bur.00039FC
函数,可能就是检测函数。
在0x0042F4D0处下断,运行到此处,可以看到该函数有两个参数,分别保存在eax和edx中,观察两个寄存器的值,可以看到我们输入的错误序列号和另一个序列号。
EAX 004F636C ASCII "123456"
ECX 75F66D51 user32.75F66D51
EDX 004F9834 ASCII "Hello Dude!"
EBX 004FA788
ESP 0018F8E0
EBP 0018F900
ESI 004F2480
EDI 004F2480
EIP 0042F4D0 Acid_bur.0042F4D0
那么Hello Dude!
应该就是正确的序列号,输入测试,提示成功。
Serial/Name
接下来破解序列号+用户名。
随便输入,获取提示。
查看OD搜索的字符串,看到两组挨着的Try Again!
和Sorry , The serial is incorect !
。
点开第一组失败提示。
0042FA3B |. 8B45 EC mov eax,[local.5]
0042FA3E |. 0FB640 02 movzx eax,byte ptr ds:[eax+0x2]
0042FA42 |. 6BC0 0E imul eax,eax,0xE
0042FA45 |. 03F0 add esi,eax
0042FA47 |. 8935 58174300 mov dword ptr ds:[0x431758],esi
0042FA4D |. A1 6C174300 mov eax,dword ptr ds:[0x43176C]
0042FA52 |. E8 D96EFDFF call Acid_bur.00406930 //计算用户名长度
0042FA57 |. 83F8 04 cmp eax,0x4 //用户名长度需要大于等于4
0042FA5A |. 7D 1D jge short Acid_bur.0042FA79
0042FA5C |. 6A 00 push 0x0
0042FA5E |. B9 74FB4200 mov ecx,Acid_bur.0042FB74 ; Try Again!
0042FA63 |. BA 80FB4200 mov edx,Acid_bur.0042FB80 ; Sorry , The serial is incorect !
0042FA68 |. A1 480A4300 mov eax,dword ptr ds:[0x430A48] ; x_O
0042FA6D |. 8B00 mov eax,dword ptr ds:[eax]
0042FA6F |. E8 FCA6FFFF call Acid_bur.0042A170
0042FA74 |. E9 BE000000 jmp Acid_bur.0042FB37
0x0042FA57处的比较指令可能是在比较用户名的长度。在此处下断,运行到此处,发现正好是用户名的长度,确定0x0042FA52处计算用户名长度,然后是否大于等于4,如果小于4的话,就弹出失败提示。
再定位到第二组失败提示。
0042FAE5 |. E8 C23EFDFF call Acid_bur.004039AC
0042FAEA |. 8D55 F0 lea edx,[local.4]
0042FAED |. 8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042FAF3 |. E8 60AFFEFF call Acid_bur.0041AA58
0042FAF8 |. 8B55 F0 mov edx,[local.4]
0042FAFB |. 8B45 F4 mov eax,[local.3]
0042FAFE |. E8 F93EFDFF call Acid_bur.004039FC
0042FB03 |. 75 1A jnz short Acid_bur.0042FB1F
0042FB05 |. 6A 00 push 0x0
0042FB07 |. B9 CCFB4200 mov ecx,Acid_bur.0042FBCC ; Congratz !!
0042FB0C |. BA D8FB4200 mov edx,Acid_bur.0042FBD8 ; Good job dude =)
0042FB11 |. A1 480A4300 mov eax,dword ptr ds:[0x430A48] ; x_O
0042FB16 |. 8B00 mov eax,dword ptr ds:[eax]
0042FB18 |. E8 53A6FFFF call Acid_bur.0042A170
0042FB1D |. EB 18 jmp short Acid_bur.0042FB37
0042FB1F |> 6A 00 push 0x0
0042FB21 |. B9 74FB4200 mov ecx,Acid_bur.0042FB74 ; Try Again!
0042FB26 |. BA 80FB4200 mov edx,Acid_bur.0042FB80 ; Sorry , The serial is incorect !
0042FB2B |. A1 480A4300 mov eax,dword ptr ds:[0x430A48] ; x_O
0042FB30 |. 8B00 mov eax,dword ptr ds:[eax]
0042FB32 |. E8 39A6FFFF call Acid_bur.0042A170
0042FB37 |> 33C0 xor eax,eax
与成功提示紧挨着,那么0x0042FAFE处调用的Acid_bur.0042FB1F
函数可能就是检测函数。有趣的是,函数与跳转指令之间没有比较指令,那么很有可能比较指令放在了函数里进行。
在0x0042FAFE处下断,运行到此处,可以看到该函数的两个参数的值。
EAX 004FA030 ASCII "CW-9512-CRACKED"
ECX 75F66D51 user32.75F66D51
EDX 004F90B0 ASCII "123456"
EBX 004F67B0 ASCII "x鸟"
ESP 0018F8D4
EBP 0018F900
ESI 00000B46
EDI 004F9B3C
EIP 0042FAFE Acid_bur.0042FAFE
edx中是输入的序列号,那么eax中的CW-9512-CRACKED
应该就是正确的序列号了。
输入测试。弹出成功提示。
值得注意的是,序列号中的CW和CRACKED是固定的,9512是根据用户名计算的,
反向追踪9512出现的位置,可以发现算法的核心位置。
首先取用户名的第一个字母,与0x29相乘得到注册码初始值,然后计算出注册码,与CW、CRACKED连接起来与输入的注册码比较。
0042FA79 |> \8D55 F0 lea edx,[local.4]
0042FA7C |. 8B83 DC010000 mov eax,dword ptr ds:[ebx+0x1DC]
0042FA82 |. E8 D1AFFEFF call Acid_bur.0041AA58
0042FA87 |. 8B45 F0 mov eax,[local.4]
0042FA8A |. 0FB600 movzx eax,byte ptr ds:[eax] ; 取用户名首字母
0042FA8D |. F72D 50174300 imul dword ptr ds:[0x431750] ; 与0x29相乘
0042FA93 |. A3 50174300 mov dword ptr ds:[0x431750],eax
0042FA98 |. A1 50174300 mov eax,dword ptr ds:[0x431750]
0042FA9D |. 0105 50174300 add dword ptr ds:[0x431750],eax
0042FAA3 |. 8D45 FC lea eax,[local.1]
0042FAA6 |. BA ACFB4200 mov edx,Acid_bur.0042FBAC ; CW
0042FAAB |. E8 583CFDFF call Acid_bur.00403708
0042FAB0 |. 8D45 F8 lea eax,[local.2]
0042FAB3 |. BA B8FB4200 mov edx,Acid_bur.0042FBB8 ; CRACKED
0042FAB8 |. E8 4B3CFDFF call Acid_bur.00403708
0042FABD |. FF75 FC push [local.1]
0042FAC0 |. 68 C8FB4200 push Acid_bur.0042FBC8 ; -
0042FAC5 |. 8D55 E8 lea edx,[local.6]
0042FAC8 |. A1 50174300 mov eax,dword ptr ds:[0x431750]
0042FACD |. E8 466CFDFF call Acid_bur.00406718 ; 计算函数
进一步分析,注册码初始值通过不断与0xA相除,余数+0x30,直到除法的结果为0,最后将每次结果的顺序逆序存放。
00406DC7 |> 8D75 C4 lea esi,[local.15]
00406DCA |> |31D2 /xor edx,edx
00406DCC |. |F7F1 |div ecx
00406DCE |. |80C2 30 |add dl,0x30
00406DD1 |. |80FA 3A |cmp dl,0x3A
00406DD4 |. |72 03 |jb short Acid_bur.00406DD9
00406DD6 |. |80C2 07 |add dl,0x7
00406DD9 |> |4E |dec esi
00406DDA |. |8816 |mov byte ptr ds:[esi],dl
00406DDC |. |09C0 |or eax,eax
00406DDE |.^|75 EA \jnz short Acid_bur.00406DCA
00406DE0 |. |8D4D C4 lea ecx,[local.15]
00406DE3 |. |29F1 sub ecx,esi ; 计算注册码长度
00406DE5 |. |8B55 E0 mov edx,[local.8]
00406DE8 |. |83FA 10 cmp edx,0x10
00406DEB |. |72 01 jb short Acid_bur.00406DEE
比如用户名为"test",取首字母‘t‘,即0x74。0x74 * 0x29 = 0x2528。
然后不断执行除法:
0x2528 / 0xA = 0x3B7...0x2,0x2 + 0x30 = 0x32
0x3B7 / 0xA = 0x5F...0x1,0x1 + 0x30 = 0x31
0x5F / 0xA = 0x9...0x5,0x5 + 0x30 = 0x35
0x9 / 0xA = 0...0x9,0x9 + 0x30 = 0x39
所以注册码应为9512。
参考
原文地址:https://www.cnblogs.com/Roachs/p/9365254.html