yangjiajiang 转的那个crackME算法分析+注册机
本帖最后由 missviola 于 2009-10-20 16:00 编辑【破文标题】yangjiajiang 转的那个crackME算法分析+注册机
【破文作者】missviola
【破解工具】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 , 14
004019E7|.33D2 xor edx, edx
004019E9|.8955 FC mov dword ptr , edx
004019EC|.8D55 FC lea edx, dword ptr
004019EF|.FF45 F0 inc dword ptr
004019F2 >|.8B83 F8020000 mov eax, dword ptr ;*edtName:TEdit
004019F8|.E8 A39F0400 call 0044B9A0 ;获取注册名长度
004019FD|.66:C745 E4 08>mov word ptr , 8
00401A03|.66:C745 E4 20>mov word ptr , 20
00401A09|.33C9 xor ecx, ecx
00401A0B|.894D F8 mov dword ptr , ecx
00401A0E|.8D55 F8 lea edx, dword ptr
00401A11|.FF45 F0 inc dword ptr
00401A14 >|.8B83 FC020000 mov eax, dword ptr ;*edtCode:TEdit
00401A1A|.E8 819F0400 call 0044B9A0 ;取注册码长度
00401A1F|.66:C745 E4 08>mov word ptr , 8
00401A25|.BE B0214600 mov esi, 004621B0 ;0
00401A2A|.8D7D A8 lea edi, dword ptr
00401A2D|.B9 07000000 mov ecx, 7
00401A32|.F3:A5 rep movs dword ptr es:, dword p>
00401A34|.66:A5 movs word ptr es:, word ptr [esi>
00401A36|.BE CE214600 mov esi, 004621CE ;0
00401A3B|.8D7D 88 lea edi, dword ptr
00401A3E|.B9 07000000 mov ecx, 7
00401A43|.F3:A5 rep movs dword ptr es:, dword p>
00401A45|.66:A5 movs word ptr es:, word ptr [esi>
00401A47|.837D FC 00 cmp dword ptr , 0 ;检查是否输入了注册名
00401A4B|.74 05 je short 00401A52
00401A4D|.8B45 FC mov eax, dword ptr
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
00401A61|.F2:AE repne scas byte ptr es:
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:, dword p>
00401A72|.8BCA mov ecx, edx
00401A74|.83E1 03 and ecx, 3
00401A77|.F3:A4 rep movs byte ptr es:, byte ptr>
00401A79|.837D F8 00 cmp dword ptr , 0 ;检查是否输入了注册码
00401A7D|.74 05 je short 00401A84
00401A7F|.8B45 F8 mov eax, dword ptr
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
00401A93|.F2:AE repne scas byte ptr es:
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:, dword p>
00401AA4|.8BCA mov ecx, edx
00401AA6|.8D45 A8 lea eax, dword ptr
00401AA9|.83E1 03 and ecx, 3
00401AAC|.F3:A4 rep movs byte ptr es:, 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
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
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
004018CF|.33DB xor ebx, ebx
004018D1|.8B45 08 mov eax, dword ptr
004018D4|.8BC8 mov ecx, eax
004018D6|.3BFB cmp edi, ebx
004018D8|.7E 15 jle short 004018EF
004018DA|>0FBE01 /movsx eax, byte ptr ;取注册名各位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 , eax
00401AD5|.33D2 xor edx, edx
00401AD7|.8D45 88 lea eax, dword ptr
00401ADA|.3BFA cmp edi, edx
00401ADC|.7E 14 jle short 00401AF2
00401ADE|>0FBE08 /movsx ecx, byte ptr ;依次取注册码各位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 , 1
00401AF9|.66:C745 E4 08>mov word ptr , 8
00401AFF|.C745 C8 01000>mov dword ptr , 1
00401B06|.3BFE cmp edi, esi
00401B08|.74 07 je short 00401B11
00401B0A|.33D2 xor edx, edx
00401B0C|.8955 CC mov dword ptr , edx
00401B0F|.EB 46 jmp short 00401B57
00401B11|>8B45 F8 mov eax, dword ptr
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
00401B24|.83C4 F8 add esp, -8
00401B27|.DD1C24 fstp qword ptr
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 ;S2同固定数相加,=19860109,结果记为
S3
00401B3F|.895D 84 mov dword ptr , ebx
00401B42|.DB45 84 fild dword ptr
00401B45|.DEE9 fsubp st(1), st ;S3-S1
00401B47|.D81D E01B4000 fcomp dword ptr ;同0相比较,也就是说S3=S1 =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技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
missviold是文章作者把?怎么用的名字不一样?最近的算法分析很不错,继续加精鼓励~:)eee 我是新手~~~~~ 学习啦。。。 学习学习啦,再学习哈
页:
[1]