【作者主页】: www.iawen.com
【作者QQ号】: =======**======
【软件名称】: Crackme.exe
【下载地址】: 见附件
【使用工具】: OD,PETool,ImportREC
【操作平台】: XP SP3
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
——————————————————————————–
【详细过程】
一个简单的压缩壳,用PEID查看显示为:Morphine 1.4 – 2.7 -> Holy_Father & Ratter/29A
我没见过,直接用OD载入得啦:
00511654 Cr> 67:97 xchg eax,edi ; ntdll.7C930208
00511656 67:97 xchg eax,edi
00511658 F5 cmc
00511659 90 nop
0051165A 84ED test ch,ch
先F8单步一下吧:
0051165F 51 push ecx //单步到这里时,ESP显示红色
00511660 52 push edx
00511661 53 push ebx
呵呵,就先用ESP试试吧,下断点:hr 0013FFC0
F9运行时,出现一个错误提示窗口,不管它了,确定后继续运行,就到了这里:
00401941 6A 00 push 0
00401943 E8 60060000 call Crackm_1.00401FA8 ; jmp 到,停在了这里,呵呵
00401948 A3 30364000 mov dword ptr ds:[403630],eax
0040194D 6A 00 push 0
0040194F 68 69194000 push Crackm_1.00401969
00401954 6A 00 push 0
00401956 6A 65 push 65
00401958 FF35 30364000 push dword ptr ds:[403630]
0040195E E8 09060000 call Crackm_1.00401F6C ; jmp 到
00401963 50 push eax
00401964 E8 33060000 call Crackm_1.00401F9C ; jmp 到
嗯,一看,不是MASM的入口了么??难道就到了?
先DUMP一下试试吧!
在00401941上新建EIP,然后DUMP,再修复!
我用LoadPE来Dump时,修正大小之后就无法Dump了,只好用PETool了,呵呵,修复一路顺风,运行OK!
到些壳也就脱了,我也不来什么优化了,(我不会,^#^),再试试破解吧,哈
用OD载入脱壳后的程序,直接运行起来!用户名,程序直接取了电脑名了,呵呵!
我们也就不用输入了,随便输入一个假码吧,按确定,有出错提示!这样,我们就直接用堆栈调用来返回吧!
00401B3E /$ 55 push ebp
00401B3F |. 8BEC mov ebp,esp
00401B41 |. 68 75304000 push Dumped_.00403075 ; ASCII "Error !"
00401B46 |. E8 D4FFFFFF call Dumped_.00401B1F
00401B4B |. 68 C3304000 push Dumped_.004030C3 ; ASCII "The Serial You Entered Is Not Valid !"
00401B50 |. E8 CAFFFFFF call Dumped_.00401B1F
00401B55 |. 6A 30 push 30 ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401B57 |. 68 75304000 push Dumped_.00403075 ; |Title = "Error !"
00401B5C |. 68 C3304000 push Dumped_.004030C3 ; |Text = "The Serial You Entered Is Not Valid !"
00401B61 |. FF75 08 push dword ptr ss:[ebp+8] ; |hOwner
00401B64 |. E8 21040000 call <jmp.&user32.MessageBoxA> ; \MessageBoxA
00401B69 |. 68 75304000 push Dumped_.00403075 ; ASCII "Error !"
00401B6E |. E8 ACFFFFFF call Dumped_.00401B1F
00401B73 |. 68 C3304000 push Dumped_.004030C3 ; ASCII "The Serial You Entered Is Not Valid !"
00401B78 |. E8 A2FFFFFF call Dumped_.00401B1F
00401B7D |. C9 leave
00401B7E \. C2 0400 retn 4
返回到上面的代码,在段首位置00401B3E上点击一下,留意提示窗口:
Local Calls from 00401B06, 00401CD8
先来到00401B06处,跑到段首下好断点:
00401AD6 /$ 55 push ebp //F2下断
00401AD7 |. 8BEC mov ebp,esp
00401AD9 |. 33DB xor ebx,ebx
00401ADB |. 8A1D 34384000 mov bl,byte ptr ds:[403834]
00401AE1 |. 53 push ebx
00401AE2 |. C605 34384000>mov byte ptr ds:[403834],0
00401AE9 |. 6A 00 push 0
00401AEB |. 6A 04 push 4
00401AED |. 68 30384000 push Dumped_.00403830 ; ASCII "1111"
00401AF2 |. E8 19FEFFFF call Dumped_.00401910
00401AF7 |. 8B1D 11324000 mov ebx,dword ptr ds:[403211]
00401AFD |. 0FCB bswap ebx
00401AFF |. 3BC3 cmp eax,ebx
00401B01 |. 74 0C je short Dumped_.00401B0F
00401B03 |. FF75 08 push dword ptr ss:[ebp+8]
00401B06 |. E8 33000000 call Dumped_.00401B3E
00401B0B |. 33C0 xor eax,eax
00401B0D |. EB 05 jmp short Dumped_.00401B14
00401B0F |> B8 01000000 mov eax,1
00401B14 |> 5B pop ebx
00401B15 |. 881D 34384000 mov byte ptr ds:[403834],bl
00401B1B |. C9 leave
00401B1C \. C2 0400 retn 4
再到00401CD8处,同样到段首下断:
00401C8D /$ 55 push ebp //F2下断
00401C8E |. 8BEC mov ebp,esp
00401C90 |. 68 8E394000 push Dumped_.0040398E
00401C95 |. 6A 20 push 20
00401C97 |. 68 6C374000 push Dumped_.0040376C
00401C9C |. E8 F3FDFFFF call Dumped_.00401A94
00401CA1 |. 68 C0394000 push Dumped_.004039C0
00401CA6 |. 6A 20 push 20
00401CA8 |. 68 34384000 push Dumped_.00403834
00401CAD |. E8 E2FDFFFF call Dumped_.00401A94
00401CB2 |. BF 8E394000 mov edi,Dumped_.0040398E
00401CB7 |. BE C0394000 mov esi,Dumped_.004039C0
00401CBC |. B9 20000000 mov ecx,20
00401CC1 |. FC cld
00401CC2 |. F3:A6 repe cmps byte ptr es:[edi],byte ptr ds:[e>
00401CC4 |. 75 0F jnz short Dumped_.00401CD5
00401CC6 |. FF75 08 push dword ptr ss:[ebp+8]
00401CC9 |. E8 39FFFFFF call Dumped_.00401C07
00401CCE |. B8 01000000 mov eax,1
00401CD3 |. EB 0A jmp short Dumped_.00401CDF
00401CD5 |> FF75 08 push dword ptr ss:[ebp+8]
00401CD8 |. E8 61FEFFFF call Dumped_.00401B3E
00401CDD |. 33C0 xor eax,eax
00401CDF |> C9 leave
00401CE0 \. C2 0400 retn 4
下好这两个断点后,我们就可以继续了,确定错误窗口后,重新输入一个假码,然后确定,中断在了:
00401AD6 /$ 55 push ebp //F2下断
我们F8单步:
00401AE9 |. 6A 00 push 0
00401AEB |. 6A 04 push 4
00401AED |. 68 30384000 push Dumped_.00403830 ; ASCII "1234"
00401AF2 |. E8 19FEFFFF call Dumped_.00401910 ; 这里开始取假码的前4位
跟进去一看,一个循环,通过查表取值,然后进行XOR运算,得到的值保存到EAX
00401910 /$ 55 push ebp
00401911 |. 8BEC mov ebp,esp
00401913 |. 56 push esi
00401914 |. 8B45 10 mov eax,dword ptr ss:[ebp+10]
00401917 |. 8B4D 0C mov ecx,dword ptr ss:[ebp+C]
0040191A |. 83F0 FF xor eax,FFFFFFFF
0040191D |. 85C9 test ecx,ecx
0040191F |. 8B75 08 mov esi,dword ptr ss:[ebp+8]
00401922 |. 74 15 je short Dumped_.00401939
00401924 |> 3206 /xor al,byte ptr ds:[esi]
00401926 |. 0FB6D0 |movzx edx,al
00401929 |. C1E8 08 |shr eax,8
0040192C |. 8B1495 283240>|mov edx,dword ptr ds:[edx*4+403228] ; 查表取值
00401933 |. 46 |inc esi
00401934 |. 33C2 |xor eax,edx
00401936 |. 49 |dec ecx
00401937 |.^ 75 EB \jnz short Dumped_.00401924
00401939 |> 83F0 FF xor eax,FFFFFFFF
0040193C |. 5E pop esi
0040193D |. C9 leave
0040193E \. C2 0C00 retn 0C
计算返回后,就来到了一个关键的比较处了:
00401AF7 |. 8B1D 11324000 mov ebx,dword ptr ds:[403211] ; 取一个固定的值
ds:[00403211]=89EB6EA5
00401AFD |. 0FCB bswap ebx ; 逆转一下
//逆转后得到:A56EEB89
00401AFF |. 3BC3 cmp eax,ebx ; 然后开始与上面取得的值比较
00401B01 |. 74 0C je short Dumped_.00401B0F ; 不相等再出错
爆破的话,就只需要把 je short Dumped_.00401B0F 改成 jmp short Dumped_.00401B0F 了,呵呵!
我这里先爆了,修改之后,F9运行,又来到了第2个断点处:
00401C8D /$ 55 push ebp //F2下断
继续F8单步吧,没几下,出现一个字符串:
ASCII “017341B-1D1E518-9DDE3AB-EADCC91C”
00401C97 |. 68 6C374000 push Dumped_.0040376C ; ASCII "017341B-1D1E518-9DDE3AB-EADCC91C"
00401C9C |. E8 F3FDFFFF call Dumped_.00401A94
00401CA1 |. 68 C0394000 push Dumped_.004039C0 ; ASCII "50B594E2B5C0234FD98240F2F2F9ABCD"
这里的call Dumped_.00401A94
其实就是一个简单的MD5加密了,所以注册码的后32位就是对应的ASCII “017341B-1D1E518-9DDE3AB-EADCC91C”
就OK了,至于这个这个字符串如何得来,我没有继续分析了!
然后取假码的后32位(我这里明显不够,呵呵):
00401CA1 |. 68 C0394000 push Dumped_.004039C0
00401CA6 |. 6A 20 push 20
00401CA8 |. 68 34384000 push Dumped_.00403834 ; ASCII "5678901234afdsf"
00401CAD |. E8 E2FDFFFF call Dumped_.00401A94
运算得出上个字符串,然后与上面运算得出的字符串,进行比较,
00401CB2 |. BF 8E394000 mov edi,Dumped_.0040398E ; ASCII "50B594E2B5C0234FD98240F2F2F9ABCD"
00401CB7 |. BE C0394000 mov esi,Dumped_.004039C0 ; ASCII "5E8C523F88968DA0BAE6EBF3073315F9"
00401CBC |. B9 20000000 mov ecx,20
00401CC1 |. FC cld
00401CC2 |. F3:A6 repe cmps byte ptr es:[edi],byte ptr ds:[e> //这里按位比较
00401CC4 |. 75 0F jnz short Dumped_.00401CD5 //不等就OVER了
我这里爆破,直接将jnz short Dumped_.00401CD5给NOP掉,呵呵
F9运行,就出现正确的对话框了!
——————————————————————————–
【经验总结】
这个CM的关键之处在于:
1、前4位的获取算法,如何逆向运算?
2、那个字符串是如何得来??其实这个字符串,也是通过一个MD5运算得来的,呵呵
——————————————————————————–
【版权声明】: 转载请注明作者并保持文章的完整, 谢谢!
2009年01月28日 21:04:00