• 2011年成都信息工程学院第二季极客大挑战逆向第二题Crackwho破文


    【文章标题】: 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

  • 相关阅读:
    Maven入门教程
    认识Java Core和Heap Dump
    [Java IO]03_字符流
    Eclipse 实用技巧
    可变和不可变的区分
    什么猴子补丁待补充
    当退出python时,是否释放全部内存
    解释python中的help()和dir()函数
    在python中是如何管理内存的
    解释一下python中的继承
  • 原文地址:https://www.cnblogs.com/Joy7/p/2546429.html
Copyright © 2020-2023  润新知