lingyin 发表于 2018-12-30 16:10

一个简单的CrackMe破解

加密与解密买了有半个多月了,一直在学习。昨天把书的第五章看完了,理论知道后,技术只能通过大量的练习来提高。以我现在的水平,难度大的也不会,所以就挑些简单的来练习。

这个例子是《加密与解密 第四版》第五章中附带的2007年的CrackMe中给的。逆向的作者是 爱在天涯 大佬,不过看到最后,大佬可能是困了,不分析了。这个例子对我来说,不算简单,但稍微思考一下,应该可以做出来。

新手逆向,会存在很多纰漏,望大佬们加以指正,感谢。



根据错误提示,来到关键代码处:


00401139   $6A 32         push    32                               ; /Count = 32 (50.)
0040113B   .68 F3204000   push    004020F3                         ; |Buffer = Crackme1.004020F3
00401140   .68 C8000000   push    0C8                              ; |ControlID = C8 (200.)
00401145   .FF75 08       push    dword ptr                 ; |hWnd
00401148   .E8 DE000000   call    <jmp.&USER32.GetDlgItemTextA>    ; \GetDlgItemTextA
0040114D   .83F8 00       cmp   eax, 0                           ;空字符串
00401150   .0F84 99000000 je      004011EF                         ;失败
00401156   .83F8 04       cmp   eax, 4
00401159   .0F82 90000000 jb      004011EF                         ;长度<4,失败
0040115F   .33C9          xor   ecx, ecx                         ;i = 0
00401161   .33DB          xor   ebx, ebx
00401163   .33F6          xor   esi, esi                         ;sum = 0
00401165   .8945 FC       mov   dword ptr , eax         ;len = strlen(name)
00401168   >0FBE81 F32040>movsx   eax, byte ptr
0040116F   .83F8 20       cmp   eax, 20
00401172   .74 07         je      short 0040117B                   ;如果是空格,忽略,进行下一个循环
00401174   .6BC0 04       imul    eax, eax, 4                      ;用户名的单个字符的16进制*4
00401177   .03D8          add   ebx, eax
00401179   .8BF3          mov   esi, ebx                         ;sum = sum+eax*4
0040117B   >41            inc   ecx
0040117C   .3B4D FC       cmp   ecx, dword ptr
0040117F   .^ 75 E7         jnz   short 00401168                   ;未处理完毕,继续循环
00401181   .83FE 00       cmp   esi, 0
00401184   .74 69         je      short 004011EF
00401186   .BB 89476500   mov   ebx, 654789                      ;tmp = 0x654789
0040118B   >0FBE81 F22040>movsx   eax, byte ptr        ;注册码的倒序
00401192   .4B            dec   ebx                              ;tmp--
00401193   .6BC3 02       imul    eax, ebx, 2
00401196   .03D8          add   ebx, eax                         ;tmp = tmp * 0x2
00401198   .4B            dec   ebx                              ;tmp--
00401199   .49            dec   ecx                              ;len - 1
0040119A   .^ 75 EF         jnz   short 0040118B
0040119C   .56            push    esi                              ; /<%lu>
0040119D   .53            push    ebx                              ; |<%lX>
0040119E   .68 C7204000   push    004020C7                         ; |Format = "BS-%lX-%lu"
004011A3   .68 BB214000   push    004021BB                         ; |s = Crackme1.004021BB
004011A8   .E8 6C000000   call    <jmp.&USER32.wsprintfA>          ; \wsprintfA
004011AD   .58            pop   eax
004011AE   .58            pop   eax
004011AF   .58            pop   eax
004011B0   .58            pop   eax
004011B1   .E8 01000000   call    004011B7
004011B6   .C3            retn
004011B7   $33C9          xor   ecx, ecx
004011B9   .6A 32         push    32                               ; /Count = 32 (50.)
004011BB   .68 57214000   push    00402157                         ; |Buffer = Crackme1.00402157
004011C0   .68 C9000000   push    0C9                              ; |ControlID = C9 (201.)
004011C5   .FF75 08       push    dword ptr                 ; |hWnd
004011C8   .E8 5E000000   call    <jmp.&USER32.GetDlgItemTextA>    ; \GetDlgItemTextA
004011CD   .83F8 00       cmp   eax, 0
004011D0   .74 1D         je      short 004011EF                   ;注册码为0,失败
004011D2   .33C9          xor   ecx, ecx                         ;j = 0
004011D4   >0FBE81 572140>movsx   eax, byte ptr        ;获取注册码首位
004011DB   .0FBE99 BB2140>movsx   ebx, byte ptr        ;取正确的注册码首位
004011E2   .3BC3          cmp   eax, ebx
004011E4   .75 09         jnz   short 004011EF                   ;不相等,失败
004011E6   .83F8 00       cmp   eax, 0
004011E9   .74 19         je      short 00401204                   ;输入的注册码为NULL,失败
004011EB   .41            inc   ecx                              ;j++
004011EC   .^ EB E6         jmp   short 004011D4                   ;继续比较下一位
004011EE   .C3            retn
004011EF   >6A 10         push    10                               ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
004011F1   .68 E4204000   push    004020E4                         ; |Title = "Nope"
004011F6   .68 E9204000   push    004020E9                         ; |Text = "Try again"
004011FB   .FF75 08       push    dword ptr                 ; |hOwner
004011FE   .E8 34000000   call    <jmp.&USER32.MessageBoxA>      ; \MessageBoxA
00401203   .C3            retn
00401204   >6A 40         push    40                               ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401206   .68 D2204000   push    004020D2                         ; |Title = "Solved"
0040120B   .68 D9204000   push    004020D9                         ; |Text = "Well done."
00401210   .FF75 08       push    dword ptr                 ; |hOwner
00401213   .E8 1F000000   call    <jmp.&USER32.MessageBoxA>      ; \MessageBoxA
00401218   .C3            retn




可以看到,程序调用了两次GetDlgItemTextA(),不出意外,分别是获取用户名和注册码。
具体的分析可以看注释。

贴一个简单的注册机:



/*

reference:http://bbs.pediy.com/showthread.php?threadid=10533
author:lingyin
date:2018-12-30

*/

#include<string.h>
#include<stdio.h>

int main()
{
    char name;
    int i,sum = 0;
    int len = 0;
    char ch;
    int tmp = 0x654789;

    printf("请输入要逆向的账号:\n");
    scanf("%s",name);
    len = strlen(name);

    if(len < 4)
    {
      printf("请至少输入4个字符!!!!");
      return;
    }

    //printf("%d",strlen(name));
    //printf("%s\n",name);

    for(i = 0;i < len;i++)
    {
      ch = name;

      if(ch < 0x20)
            return;

      sum += ch * 0x4;


    }

    for(i = len-1;i >= 0;i--)
    {
      ch = name;
      tmp--;
      tmp += tmp*0x2;
      tmp--;

    }


    //输出最后的正确的注册码
    printf("BS-%lX-%lu\n",tmp,sum);
   
    getch();
    return 0;

}



输入xuepojie,会输出注册码:BS-23AE2AE9-3492.



逆向成功

这个注册机,我测试了几个账号,没问题,如果哪位朋友,发现存在BUG,麻烦告诉我,万分感谢.


Shark恒 发表于 2018-12-30 16:18

真不错,赞!

lingyin 发表于 2018-12-30 16:40

Shark恒 发表于 2018-12-30 16:18
真不错,赞!

多谢鼓励,

lyxc 发表于 2019-1-7 17:25

谢谢分享,学习中

2022688010 发表于 2019-2-27 13:08

多谢分享,共同进步

别管我了行 发表于 2022-5-6 03:28

三月十六 发表于 2022-5-6 11:29


[快捷回复]-软件反汇编逆向分析,软件安全必不可少!

三月十六 发表于 2022-5-6 11:34

[快捷回复]-学破解防逆向,知进攻懂防守!

玖霊後 发表于 2022-5-6 13:53

[快捷回复]-学破解防逆向,知进攻懂防守!

别来无恙 发表于 2022-5-27 15:28

感谢分享逆向思路,努力学习
页: [1] 2
查看完整版本: 一个简单的CrackMe逆向