好友
阅读权限 40
听众
最后登录 1970-1-1
本帖最后由 missviola 于 2009-10-20 16:00 编辑
【破文标题】yangjiajiang 转的那个crackME算法分析+注册机
【破文作者】missviola[LCG]
【破解 工具】PEID OD
【破解平台】Windows XP
【原版下载】http://www.52pojie.cn/thread-26116-1-1.html
【破解声明】只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
------------------------------------------------------------------------
【破解过程】首先PEID查壳,发现为Borland C++ 1999,用DEDE打开,查看btnclick对应的地址为4019CC。OD载入,在4019CC处下断
点,F9运行,输入用户名viola,注册码123456。点击注册,crackme断下,F8单步往下分析。
004019CC >/. 55 push ebp ; <-TForm1@btnRegClick
004019CD |. 8BEC mov ebp, esp
004019CF |. 83C4 84 add esp, -7C
004019D2 |. 53 push ebx
004019D3 |. 56 push esi
004019D4 |. 57 push edi
004019D5 |. 8BD8 mov ebx, eax
004019D7 |. B8 54224600 mov eax, 00462254
004019DC |. E8 5B660500 call 0045803C
004019E1 |. 66:C745 E4 14>mov word ptr [ebp-1C], 14
004019E7 |. 33D2 xor edx, edx
004019E9 |. 8955 FC mov dword ptr [ebp-4], edx
004019EC |. 8D55 FC lea edx, dword ptr [ebp-4]
004019EF |. FF45 F0 inc dword ptr [ebp-10]
004019F2 >|. 8B83 F8020000 mov eax, dword ptr [ebx+2F8] ; *edtName:TEdit
004019F8 |. E8 A39F0400 call 0044B9A0 ; 获取注册名长度
004019FD |. 66:C745 E4 08>mov word ptr [ebp-1C], 8
00401A03 |. 66:C745 E4 20>mov word ptr [ebp-1C], 20
00401A09 |. 33C9 xor ecx, ecx
00401A0B |. 894D F8 mov dword ptr [ebp-8], ecx
00401A0E |. 8D55 F8 lea edx, dword ptr [ebp-8]
00401A11 |. FF45 F0 inc dword ptr [ebp-10]
00401A14 >|. 8B83 FC020000 mov eax, dword ptr [ebx+2FC] ; *edtCode:TEdit
00401A1A |. E8 819F0400 call 0044B9A0 ; 取注册码长度
00401A1F |. 66:C745 E4 08>mov word ptr [ebp-1C], 8
00401A25 |. BE B0214600 mov esi, 004621B0 ; 0
00401A2A |. 8D7D A8 lea edi, dword ptr [ebp-58]
00401A2D |. B9 07000000 mov ecx, 7
00401A32 |. F3:A5 rep movs dword ptr es:[edi], dword p>
00401A34 |. 66:A5 movs word ptr es:[edi], word ptr [esi>
00401A36 |. BE CE214600 mov esi, 004621CE ; 0
00401A3B |. 8D7D 88 lea edi, dword ptr [ebp-78]
00401A3E |. B9 07000000 mov ecx, 7
00401A43 |. F3:A5 rep movs dword ptr es:[edi], dword p>
00401A45 |. 66:A5 movs word ptr es:[edi], word ptr [esi>
00401A47 |. 837D FC 00 cmp dword ptr [ebp-4], 0 ; 检查是否输入了注册名
00401A4B |. 74 05 je short 00401A52
00401A4D |. 8B45 FC mov eax, dword ptr [ebp-4]
00401A50 |. EB 05 jmp short 00401A57
00401A52 |> B8 F0214600 mov eax, 004621F0
00401A57 |> 8BF8 mov edi, eax
00401A59 |. 33C0 xor eax, eax
00401A5B |. 83C9 FF or ecx, FFFFFFFF
00401A5E |. 8D75 A8 lea esi, dword ptr [ebp-58]
00401A61 |. F2:AE repne scas byte ptr es:[edi]
00401A63 |. F7D1 not ecx
00401A65 |. 2BF9 sub edi, ecx
00401A67 |. 8BD1 mov edx, ecx
00401A69 |. 87F7 xchg edi, esi
00401A6B |. C1E9 02 shr ecx, 2
00401A6E |. 8BC7 mov eax, edi
00401A70 |. F3:A5 rep movs dword ptr es:[edi], dword p>
00401A72 |. 8BCA mov ecx, edx
00401A74 |. 83E1 03 and ecx, 3
00401A77 |. F3:A4 rep movs byte ptr es:[edi], byte ptr>
00401A79 |. 837D F8 00 cmp dword ptr [ebp-8], 0 ; 检查是否输入了注册码
00401A7D |. 74 05 je short 00401A84
00401A7F |. 8B45 F8 mov eax, dword ptr [ebp-8]
00401A82 |. EB 05 jmp short 00401A89
00401A84 |> B8 F1214600 mov eax, 004621F1
00401A89 |> 8BF8 mov edi, eax
00401A8B |. 33C0 xor eax, eax
00401A8D |. 83C9 FF or ecx, FFFFFFFF
00401A90 |. 8D75 88 lea esi, dword ptr [ebp-78]
00401A93 |. F2:AE repne scas byte ptr es:[edi]
00401A95 |. F7D1 not ecx
00401A97 |. 2BF9 sub edi, ecx
00401A99 |. 8BD1 mov edx, ecx
00401A9B |. 87F7 xchg edi, esi
00401A9D |. C1E9 02 shr ecx, 2
00401AA0 |. 8BC7 mov eax, edi
00401AA2 |. F3:A5 rep movs dword ptr es:[edi], dword p>
00401AA4 |. 8BCA mov ecx, edx
00401AA6 |. 8D45 A8 lea eax, dword ptr [ebp-58]
00401AA9 |. 83E1 03 and ecx, 3
00401AAC |. F3:A4 rep movs byte ptr es:[edi], byte ptr>
00401AAE |. 50 push eax
00401AAF |. E8 4C630500 call 00457E00
00401AB4 |. 59 pop ecx
00401AB5 |. 8BD8 mov ebx, eax
00401AB7 |. 8D45 88 lea eax, dword ptr [ebp-78]
00401ABA |. 50 push eax
00401ABB |. E8 40630500 call 00457E00
00401AC0 |. 59 pop ecx
00401AC1 |. 8BF8 mov edi, eax
00401AC3 |. 33F6 xor esi, esi
00401AC5 |. 53 push ebx
00401AC6 |. 8D45 A8 lea eax, dword ptr [ebp-58]
00401AC9 |. 50 push eax
00401ACA |. E8 F5FDFFFF call 004018C4 ; 算法call1 跟进
401ACA处为第一处算法call,我们跟进去看看。
004018C4 /$ 55 push ebp
004018C5 |. 8BEC mov ebp, esp
004018C7 |. 53 push ebx
004018C8 |. 56 push esi
004018C9 |. 57 push edi
004018CA |. 33F6 xor esi, esi
004018CC |. 8B7D 0C mov edi, dword ptr [ebp+C]
004018CF |. 33DB xor ebx, ebx
004018D1 |. 8B45 08 mov eax, dword ptr [ebp+8]
004018D4 |. 8BC8 mov ecx, eax
004018D6 |. 3BFB cmp edi, ebx
004018D8 |. 7E 15 jle short 004018EF
004018DA |> 0FBE01 /movsx eax, byte ptr [ecx] ; 取注册名各位ASCII码值
004018DD |. 51 |push ecx
004018DE |. B9 0A000000 |mov ecx, 0A ; 0x0A送ecx
004018E3 |. 99 |cdq ; 清零
004018E4 |. F7F9 |idiv ecx ; ASCII码值 idiv 0x0A
004018E6 |. 59 |pop ecx
004018E7 |. 03F2 |add esi, edx ; 各位的余数相加,esi初始值为零
004018E9 |. 43 |inc ebx ; 循环次数加1
004018EA |. 41 |inc ecx
004018EB |. 3BFB |cmp edi, ebx ; 同注册名长度比较
004018ED |.^ 7F EB \jg short 004018DA
004018EF |> 8BC6 mov eax, esi
004018F1 |. B9 14000000 mov ecx, 14 ; 0x14送ecx
004018F6 |. 99 cdq
004018F7 |. F7F9 idiv ecx ; 之前那个循环累加的结果 idiv 0x14,结果记为A1
004018F9 |. 8BF2 mov esi, edx
004018FB |. 8BC6 mov eax, esi
004018FD |. 5F pop edi
004018FE |. 5E pop esi
004018FF |. 5B pop ebx
00401900 |. 5D pop ebp
00401901 \. C3 retn
通过上面的分析,我们可以总结出第一处算法call的流程。依次取用户名各位的ASCII码值,除以0xA以后的余数相加,然后将余数累
加的和再除以0x14取它的余数,这里我们把这个call的最终结果记为A1,接着往下看。
00401ACF |. 83C4 08 add esp, 8
00401AD2 |. 8945 D0 mov dword ptr [ebp-30], eax
00401AD5 |. 33D2 xor edx, edx
00401AD7 |. 8D45 88 lea eax, dword ptr [ebp-78]
00401ADA |. 3BFA cmp edi, edx
00401ADC |. 7E 14 jle short 00401AF2
00401ADE |> 0FBE08 /movsx ecx, byte ptr [eax] ; 依次取注册码各位ASCII码值
00401AE1 |. 83F9 39 |cmp ecx, 39 ; 同0x39(9)比较
00401AE4 |. 7F 06 |jg short 00401AEC ; 大于就跳走
00401AE6 |. 83F9 30 |cmp ecx, 30 ; 同0x30(0)比较
00401AE9 |. 7C 01 |jl short 00401AEC ; 小于就跳走
00401AEB |. 46 |inc esi
00401AEC |> 42 |inc edx ; 循环次数加1
00401AED |. 40 |inc eax
00401AEE |. 3BFA |cmp edi, edx
00401AF0 |.^ 7F EC \jg short 00401ADE
上面的这个循环检查注册码各位是否为数字。
00401AF2 |> C745 CC 01000>mov dword ptr [ebp-34], 1
00401AF9 |. 66:C745 E4 08>mov word ptr [ebp-1C], 8
00401AFF |. C745 C8 01000>mov dword ptr [ebp-38], 1
00401B06 |. 3BFE cmp edi, esi
00401B08 |. 74 07 je short 00401B11
00401B0A |. 33D2 xor edx, edx
00401B0C |. 8955 CC mov dword ptr [ebp-34], edx
00401B0F |. EB 46 jmp short 00401B57
00401B11 |> 8B45 F8 mov eax, dword ptr [ebp-8]
00401B14 |. E8 BF090100 call 004124D8 ; 这个call将注册码转换为16进制
00401B19 |. 8BD8 mov ebx, eax
00401B1B |. 81F3 A25D4F00 xor ebx, 4F5DA2 ; 注册码 xor 0x4F5DA2(5201314,我爱你一生一世
? -_-|||| ),结果记为S1
00401B21 |. DB45 D0 fild dword ptr [ebp-30]
00401B24 |. 83C4 F8 add esp, -8
00401B27 |. DD1C24 fstp qword ptr [esp]
00401B2A |. 68 00000040 push 40000000
00401B2F |. 6A 00 push 0
00401B31 |. E8 D6880500 call 0045A40C ; 这个call进行乘方运算,计算方法为2的A1次方,
运算的结果可以在寄存器窗口的st0中看到,这里的结果记为S2
00401B36 |. 83C4 10 add esp, 10
00401B39 |. DC05 D81B4000 fadd qword ptr [401BD8] ; S2同固定数相加,[401BD8]=19860109,结果记为
S3
00401B3F |. 895D 84 mov dword ptr [ebp-7C], ebx
00401B42 |. DB45 84 fild dword ptr [ebp-7C]
00401B45 |. DEE9 fsubp st(1), st ; S3-S1
00401B47 |. D81D E01B4000 fcomp dword ptr [401BE0] ; 同0相比较,也就是说S3=S1 [401BE0]=0.0
00401B4D |. DFE0 fstsw ax
00401B4F |. 9E sahf
00401B50 74 05 je short 00401B57 ; 关键跳
这里我们总结一下第二部分的算法。首先检查注册码各位是否为数字。随后将注册码异或0x4F5DA2,结果记为S1。通过第一个算法的
结果A1计算出2的A1次方为多少,加上固定值19860109,结果记为S3,S1要等于S3,就算是注册成功了。
------------------------------------------------------------------------
【破解总结】
这个crackme分析到这里我们最后来总结一下它的算法吧:
1.依次取用户名各位的ASCII码值,除以0A,将它们的余数相加。随后再将余数相加的和除以0x14,取其余数,这里记为A1。
2.注册码各位必须为数字。将注册码异或5201314,结果记为S1。
3.计算2的A1次方为多少,加上固定值19860109,结果记为S3。
4.如果S1=S3则注册成功。
由于异或运算是可逆的,所以我们可以知道注册码应该为S3 xor 5201314。虽然creantan大侠已经在原来的帖子里面贴上了他写的注册机
了。不过这里我还是送上我用python写的注册机源代码(在windows xp+python 2.5下编译通过):
regname = raw_input("Please input your regname:")
A1 = 0
for i in range(0, len(regname)):
A1 = A1 + (ord(regname) % 10)
A1 = A1 % 20
sn = (19860109 + 2**A1) ^ 5201314
print "Your regname is:", sn
raw_input('Press any key to exit!')
------------------------------------------------------------------------
【版权声明】本文原创于52pojie技术论坛, 转载请注明作者并保持文章的完整, 谢谢!