【文章标题】: CRACKME破解分析
【文章作者】: 逍遥风
【下载地址】: 本地下载
【使用工具】: OD,计算器
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
菜鸟偶得一点心得,与大家分享
----------------------------------------------------------------------
【详细过程】
这个CRACKME用到了SHA加密算法。
注意用字符串查找功能找不到关键的提示信息,所以在命令行下断点
BP GetWindowTextLengthA
或者
BP GetWindowTextA
都可以中断在关键处
0040555B |. E8 94EAFFFF call <jmp.&user32.GetWindowTextA> ; \GetWindowTextA
00405560 |. 8D45 F8 lea eax, [ebp-8] ; 取注册名的位数
00405563 |. E8 A0D8FFFF call 00402E08
00405568 |. A1 34754000 mov eax, [407534]
0040556D |. 50 push eax ; /hWnd => 000E04C6 (class='Edit',parent=000D0518)
0040556E |. E8 89EAFFFF call <jmp.&user32.GetWindowTextLength>; \GetWindowTextLengthA
00405573 |. 99 cdq ; 取输入的注册码的位数
00405574 |. 8945 E8 mov [ebp-18], eax
00405577 |. 8955 EC mov [ebp-14], edx
0040557A |. 8B5D E8 mov ebx, [ebp-18]
0040557D |. 85DB test ebx, ebx
0040557F |. 7E 10 jle short 00405591
00405581 |> 8D45 F8 /lea eax, [ebp-8]
00405584 |. BA 8C564000 |mov edx, 0040568C
00405589 |. E8 9AD9FFFF |call 00402F28
0040558E |. 4B |dec ebx
0040558F |.^ 75 F0 \jnz short 00405581
00405591 |> 6A 20 push 20
00405593 |. 8B45 F8 mov eax, [ebp-8]
00405596 |. E8 55DAFFFF call 00402FF0
0040559B |. 50 push eax ; |Buffer
0040559C |. A1 34754000 mov eax, [407534] ; |
004055A1 |. 50 push eax ; |hWnd => 000E04C6 (class='Edit',parent=000D0518)
004055A2 |. E8 4DEAFFFF call <jmp.&user32.GetWindowTextA> ; \GetWindowTextA
004055A7 |. 8D45 F8 lea eax, [ebp-8] ; 取输入的注册码
004055AA |. 8B4D F8 mov ecx, [ebp-8] ; 使ECX等于输入的注册码
004055AD |. BA 98564000 mov edx, 00405698 ; 0
004055B2 |. E8 B5D9FFFF call 00402F6C
004055B7 |. 83C9 FF or ecx, FFFFFFFF
004055BA |. 837D F4 00 cmp dword ptr [ebp-C], 0
004055BE |. 75 08 jnz short 004055C8
004055C0 |. 837D F0 1E cmp dword ptr [ebp-10], 1E
004055C4 |. 77 53 ja short 00405619
004055C6 |. EB 02 jmp short 004055CA
004055C8 |> 7F 4F jg short 00405619
以上分别是对注册名/码的位数,进行一些检验。
检验完毕后运行到下面代码处。
004055CA |> 8D45 FC lea eax, [ebp-4] ; 取输入的注册名
004055CD |. 8B4D FC mov ecx, [ebp-4] ; 使ECX等于输入的注册名
004055D0 |. BA A4564000 mov edx, 004056A4 ; diken
004055D5 |. E8 92D9FFFF call 00402F6C ; 取固定字符串"DiKeN"
004055DA |. 8B45 FC mov eax, [ebp-4] ; 固定字符串DiKeN与注册名合并,组成字符串A
将固定字符串DiKeN与注册名合并组成字符串A
以注册名lovetc为例:
组成的字符串A就是 DiKeNlovetc
004055DD |. E8 3ED9FFFF call 00402F20 ; 取字符串A的位数
004055E2 |. 99 cdq
004055E3 |. 8945 F0 mov [ebp-10], eax ; 保存字符串A的位数
004055E6 |. 8955 F4 mov [ebp-C], edx
004055E9 |. 8D45 D4 lea eax, [ebp-2C]
004055EC |. 8B4D FC mov ecx, [ebp-4] ; 使ECX等于字符串A
004055EF |. BA 04000000 mov edx, 4 ; 使EDX等于4
004055F4 |. E8 0FFDFFFF call 00405308 ; 对字符串A进行SHA计算
关键部分,对字符串A进行SHA计算。如何得知是SHA计算呢?
跟进上面那个CALL看看
----------------------------------------
来到004055F4 处的CALL
55 push ebp ; 来到这里
00405309 |. 8BEC mov ebp, esp
0040530B |. 83C4 A4 add esp, -5C
省略一些代码。。。
00405333 |. 64:8920 mov fs:[eax], esp
00405336 |. C703 01234567 mov dword ptr [ebx], 67452301
0040533C |. C743 04 89ABC>mov dword ptr [ebx+4], EFCDAB89
00405343 |. C743 08 FEDCB>mov dword ptr [ebx+8], 98BADCFE
0040534A |. C743 0C 76543>mov dword ptr [ebx+C], 10325476
00405351 |. C743 10 F0E1D>mov dword ptr [ebx+10], C3D2E1F0
上面5组数字就是SHA常数,根据这些常数就可以判断出所用到的算法是SHA。
与根据常数判断MD5一个道理。
------------------------------------------
计算完毕以后来到这里:
004055F9 |. B8 04000000 mov eax, 4 ; 使EAX等于4
004055FE |. 8D55 D8 lea edx, [ebp-28] ; 分别对5组结果进行X0R运算
00405601 |> 8B0A /mov ecx, [edx] ; 依次取第2,3,4,5组结果
00405603 |. 314D D4 |xor [ebp-2C], ecx ; 与第1组结果进行XOR运算
00405606 |. 83C2 04 |add edx, 4
00405609 |. 48 |dec eax ; 每计算一次EAX加1
0040560A |.^ 75 F5 \jnz short 00405601 ; 循环计算
这是如何计算的呢。
先归纳一下计算过程再举例说明。
1)将SHA计算的结果分组
2)用第2,3,4,5 组结果,依次与第1组结果进行循环XOR运算
以注册名lovetc为例。
字符串A为DiKeNlovetc
将DiKeNlovetc进行砂SHA计算,得到的结果是“9BD089B5FE1A80197C4A6285ABDCFFD20EC2E5F6”
将这个结果8位一组分成5组:
第1组 > 9BD089B5
第2组 > FE1A8019
第3组 > 7C4A6285
第4组 > ABDCFFD2
第5组 > 0EC2E5F6
现在开始,先将第2组与第1组进行XOR运算。
XOR(9BD089B5,FE1A8019) = 65CA09AC ---------- 结果A
然后用第3组与结果A进行XOR运算。
XOR(65CA09AC,7C4A6285) = 19806B29 ---------- 结果B
再用第4组与结果B进行XOR运算。
XOR(19806B29,ABDCFFD2) = B25C94FB ---------- 结果C
最后用第5组与结果C进行XOR运算。
XOR(B25C94FB,0EC2E5F6) = BC9E710D ---------- 结果D
最后得出的结果D就是最后用来比较的结果。后面要用到
0040560C |. 8B45 F8 mov eax, [ebp-8] ; 使EAX等于输入的注册码
0040560F |. E8 88EBFFFF call 0040419C ; 将输入的注册码转换成对应的16进制数
00405614 |. 8BC8 mov ecx, eax ; 使ECX等于输入注册码的16进制数
00405616 |. 334D D4 xor ecx, [ebp-2C] ; 将结果D与注册码16进制比较
00405619 |> 85C9 test ecx, ecx ; 两者相等吗?
0040561B |. 75 29 jnz short 00405646 ; 不相等就跳向失败
所以可以很容易的得到
将结果D转换成对应的10进制数,就是注册码了。
所以注册名:lovetc
对应的注册码就是:3164500237
----------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2006年08月27日 17:42:03
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)