【文章标题】: CUIT极客大挑战Crackwho破文
【软件名称】: Crackwho
【软件大小】: 36.5KB
【下载地址】: http://www.kuaipan.cn/file/id_32222188979355669.html
【加壳方式】: yoda's Protector 1.03.2 -> Ashkbiz Danehkar
【保护方式】: 序列号保护
【编写语言】: Microsoft Visual C++ 8.0 *
【使用工具】: PEiD,OD
【操作平台】: Windows Xp sp3
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
首先PEID查壳,一看yoda's Protector 1.03.2,貌似没见过,因为用得比较少。
我们还是先脱壳吧。
首先,调试设置除了内存访问异常,其他都忽略掉。
1 0040E549 > E8 03000000 call Crackwho.0040E551//OD加载程序 2 0040E54E EB 01 jmp short Crackwho.0040E551//F9运行 3 0040E550 E8 BB550000 call Crackwho.00413B10//此时注意堆栈 4 0040E555 00E8 add al,ch 5 0040E557 0300 add eax,dword ptr ds:[eax] 6 0040E559 0000 add byte ptr ds:[eax],al 7 0040E55B EB 01 jmp short Crackwho.0040E55E 8 //堆栈显示 9 0012EAF0 0012EC70 指针到下一个 SEH 记录 10 0012EAF4 00410F50 SE 句柄 11 12 CTRL+G,来到00410F50 13 14 00410F50 55 push ebp//F2下断,F9运行,单步走 15 00410F51 8BEC mov ebp,esp 16 00410F53 57 push edi 17 00410F54 36:8B45 10 mov eax,dword ptr ss:[ebp+10] 18 00410F58 3E:8BB8 C400000>mov edi,dword ptr ds:[eax+C4] 19 00410F5F 3E:FF37 push dword ptr ds:[edi] 20 00410F62 33FF xor edi,edi 21 00410F64 64:8F07 pop dword ptr fs:[edi] 22 00410F67 3E:8380 C400000>add dword ptr ds:[eax+C4],8 23 00410F6F 3E:8BB8 A400000>mov edi,dword ptr ds:[eax+A4] 24 00410F76 C1C7 07 rol edi,7 25 00410F79 3E:89B8 B800000>mov dword ptr ds:[eax+B8],edi//运行到此,edi的值就是OEP的地址0040157C 26 00410F80 B8 00000000 mov eax,0//然后ctrl+G来到这个地址0040157C,然后下断点运行到此,然后dump,fix 27 00410F85 5F pop edi 28 00410F86 C9 leave 29 00410F87 C3 retn
脱完后,运行,程序主界面变了,发现程序有自校验。我们再将脱壳后的程序用OD载入
用插件查找ascii,未找到任何字符串。
我们接着右键,查找,所有参考文本串,就可以看到相应的字符串,双击来到代码处,ctrl+A,分析下代码,
就可以看到Sorry,You are wrong,和自校验的字符串
1 0040128B /73 1B jnb short 1.004012A8 2 0040128D |. |8B4424 04 mov eax,dword ptr ss:[esp+4] 3 00401291 |. |6A 00 push 0 ; /lParam = NULL 4 00401293 |. |68 10114000 push 1.00401110 ; |DlgProc = 1.00401110 5 00401298 |. |6A 00 push 0 ; |hOwner = NULL 6 0040129A |. |6A 65 push 65 ; |pTemplate = 65 7 0040129C |. |50 push eax ; |hInst 8 0040129D |. |FF15 04814000 call dword ptr ds:[<&User32.DialogBoxPara>; \DialogBoxParamW 9 004012A3 |. |33C0 xor eax,eax 10 004012A5 |. |C2 1000 retn 10 11 004012A8 |> \6A 01 push 1 ; /Style = MB_OKCANCEL|MB_APPLMODAL 12 004012AA |. 68 909A4000 push 1.00409A90 ; |Title = "哎呀" 13 004012AF |. 68 989A4000 push 1.00409A98 ; |Text = "雅蠛蝶!不要脱我~~~~~~" 14 004012B4 |. 6A 00 push 0 ; |hOwner = NULL 15 004012B6 |. FF15 FC804000 call dword ptr ds:[<&User32.MessageBoxW>] ; \MessageBoxW
16 发现0040128B这个跳是跳到自校验这来,所以我们将jnb改为jb,保存运行就可以了。
脱壳完毕。接下来就是破解找码了。
用OD加载脱壳完全的程序,还是右键查找,所有参考字符串,来到关键代码。
1 004011AC . FFD6 call esi ; \获取用户名,长度返回给eax 2 004011AE . 6A 09 push 9 ; /Count = 9 3 004011B0 . 8D4424 0C lea eax,dword ptr ss:[esp+C] ; | 4 004011B4 . 50 push eax ; |Buffer 5 004011B5 . 68 EB030000 push 3EB ; |ControlID = 3EB (1003.) 6 004011BA . 57 push edi ; |hWnd 7 004011BB . FFD6 call esi ; \获取假码,长度依然给eax 8 004011BD . 8D7424 08 lea esi,dword ptr ss:[esp+8] ; 假码 9 004011C1 . 8D4C24 1C lea ecx,dword ptr ss:[esp+1C] ; 用户名 10 004011C5 . E8 36FEFFFF call Crackwho.00401000 //这里就是算法,进去看就知道了,算法了,很简单的,还是比较适合新手,这里我就把注册机贴出来吧。 11 004011CA . 5E pop esi 12 004011CB . 6A 00 push 0 13 004011CD . 68 3C9A4000 push Crackwho.00409A3C 14 004011D2 . 85C0 test eax,eax 15 004011D4 . 74 20 je short Crackwho.004011F6 16 004011D6 . 68 449A4000 push Crackwho.00409A44 ; UNICODE "Congratulation" 17 004011DB . 57 push edi 18 004011DC . FF15 FC804000 call dword ptr ds:[4080FC] 19 004011E2 . 33C0 xor eax,eax 20 004011E4 . 5F pop edi 21 004011E5 . 8B4C24 28 mov ecx,dword ptr ss:[esp+28] 22 004011E9 . 33CC xor ecx,esp 23 004011EB . E8 D1000000 call Crackwho.004012C1 24 004011F0 . 83C4 2C add esp,2C 25 004011F3 . C2 1000 retn 10 26 004011F6 > 68 649A4000 push Crackwho.00409A64 ; UNICODE "Sorry,You are wrong" 27 004011FB . 57 push edi 28 004011FC . FF15 FC804000 call dword ptr ds:[4080FC] 29 30 进入call到这发现算法,这只是第一重循环,我想下面的7次循环应该也没问题了 31 0040103E |. 0FB701 movzx eax,word ptr ds:[ecx] ; eax指向用户名 32 00401041 |. 0FB71424 movzx edx,word ptr ss:[esp] ; edx指向syclover 33 00401045 |. 33C2 xor eax,edx ; 第一位用户名和‘s’异或 34 00401047 |. 99 cdq 35 00401048 |. 57 push edi 36 00401049 |. BF 1A000000 mov edi,1A 37 0040104E |. F7FF idiv edi ; 异或的结果与1A的余数给edx 38 00401050 |. 0FB741 02 movzx eax,word ptr ds:[ecx+2] ; 此时将假码第二位给eax,准备进行下一次循环 39 00401054 |. 6A 09 push 9 ; /Arg3 = 00000009 40 00401056 |. 56 push esi ; |Arg2 41 00401057 |. 51 push ecx ; |Arg1 42 00401058 |. 83C2 41 add edx,41 ; |余数加41 43 0040105B |. 66:8911 mov word ptr ds:[ecx],dx ; |结果放回ecx
用户名:JoyChou
注册码:FWAVHZQK
PS:当看到出现一个字符串:syclover就可以猜测注册码是8位的。此题是明码比较的,菜鸟就装B的吧算法写了出来,忘老鸟勿喷。
算法:
用户名每一位和syclover十六进制异或,结果%1A,再+0x41,结果转字符
换成十进制就是,结果%26,再加上65
由于菜鸟只会C语言,所以只能写个苦逼的C程序,忘大牛见怪
1 #include <stdio.h> 2 3 int main(void) 4 { 5 char name[10]; 6 int i, c; 7 char temp[10] = "syclover"; 8 char key[10]; 9 10 printf("input your name:"); 11 gets(name); 12 13 14 15 for (i = 0; i < 8; i++) 16 { 17 key = ( (name ^ temp)%26 ) + 65; 18 } 19 key= '\0'; 20 21 printf("the key is: "); 22 puts(key); 23 24 printf("\n"); 25 26 c=getchar(); 27 28 return 0; 29 }
--------------------------------------------------------------------------------
【经验总结】
比较简单,适合新手!
--------------------------------------------------------------------------------
【版权声明】: 本文原创于JoyChou, 转载请注明作者并保持文章的完整, 谢谢!
2012年06月12日 15:35:45