美文网首页
crackme破解

crackme破解

作者: dmzlingyin | 来源:发表于2018-12-30 18:55 被阅读0次

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

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

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

    image

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

    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 [ebp+8]                ; |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 [ebp-4], eax           ;  len = strlen(name)
    00401168   >  0FBE81 F32040>movsx   eax, byte ptr [ecx+4020F3]
    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 [ebp-4]
    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 [ecx+4020F2]       ;  注册码的倒序
    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 [ebp+8]                ; |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 [ecx+402157]       ;  获取注册码首位
    004011DB   .  0FBE99 BB2140>movsx   ebx, byte ptr [ecx+4021BB]       ;  取正确的注册码首位
    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 [ebp+8]                ; |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 [ebp+8]                ; |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[20];
        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[i];
    
            if(ch < 0x20)
                return;
    
            sum += ch * 0x4;
    
    
        }
    
        for(i = len-1;i >= 0;i--)
        {
            ch = name[i];
            tmp--;
            tmp += tmp*0x2;
            tmp--;
    
        }
    
    
        //输出最后的正确的注册码
        printf("BS-%lX-%lu\n",tmp,sum);
        
        getch();
        return 0;
    
    }
    
    image

    输入pediy,会输出注册码:BS-6022E527-2156.
    这个注册机,我测试了几个账号,没问题,如果哪位朋友,发现存在BUG,麻烦告诉我,万分感谢.

    相关文章

      网友评论

          本文标题:crackme破解

          本文链接:https://www.haomeiwen.com/subject/bdzvlqtx.html