• 破解 “PEDIY CrackMe 2007” 之 k4n2


    系统 : Windows xp

    程序 : k4n2

    程序下载地址 :http://pan.baidu.com/s/1sklslvJ

    要求 : 注册机编写

    使用工具 : IDA Pro & OD

    “PEDIY CrackMe 2007”中关于此程序的破文标题为“Borland C++写的Crackme的算法分析(适合新手)”,可在“搜索”标签下查找。

     

    使用IDA载入程序,根据成功/失败的字符串提示找到关键代码,本程序中关键代码在401052处:

    00401052  |.  B9 19000000   mov     ecx, 19
    00401057  |.  F3:A5         rep     movs dword ptr es:[edi], dword ptr [esi]    ;  edi的值在这里确定下来,0012F538
    00401059  |.  33C0          xor     eax, eax
    0040105B  |.  8945 C4       mov     dword ptr [ebp-3C], eax
    0040105E  |.  33D2          xor     edx, edx
    00401060  |.  8955 C0       mov     dword ptr [ebp-40], edx
    00401063  |.  33C9          xor     ecx, ecx
    00401065  |.  894D BC       mov     dword ptr [ebp-44], ecx
    00401068  |.  33C0          xor     eax, eax
    0040106A  |.  8945 B8       mov     dword ptr [ebp-48], eax
    0040106D  |.  33D2          xor     edx, edx
    0040106F  |.  8955 B4       mov     dword ptr [ebp-4C], edx
    00401072  |.  33C9          xor     ecx, ecx
    00401074  |.  894D B0       mov     dword ptr [ebp-50], ecx
    00401077  |.  33C0          xor     eax, eax
    00401079  |.  8945 AC       mov     dword ptr [ebp-54], eax
    0040107C  |.  33D2          xor     edx, edx
    0040107E  |.  8955 A8       mov     dword ptr [ebp-58], edx
    00401081  |.  6A 66         push    66                                          ; /ControlID = 66 (102.)
    00401083  |.  53            push    ebx                                         ; |hWnd
    00401084  |.  E8 D99C0000   call    <jmp.&USER32.GetDlgItem>                    ; GetDlgItem
    00401089  |.  6A 64         push    64                                          ; /Count = 64 (100.)
    0040108B  |.  8D8D 44FFFFFF lea     ecx, dword ptr [ebp-BC]                     ; |
    00401091  |.  51            push    ecx                                         ; |Buffer
    00401092  |.  50            push    eax                                         ; |hWnd
    00401093  |.  E8 D69C0000   call    <jmp.&USER32.GetWindowTextA>                ; GetWindowTextA
    00401098  |.  6A 68         push    68                                          ; /ControlID = 68 (104.)
    0040109A  |.  53            push    ebx                                         ; |hWnd
    0040109B  |.  E8 C29C0000   call    <jmp.&USER32.GetDlgItem>                    ; GetDlgItem
    004010A0  |.  6A 64         push    64                                          ; /Count = 64 (100.)
    004010A2  |.  8D95 E0FEFFFF lea     edx, dword ptr [ebp-120]                    ; |
    004010A8  |.  52            push    edx                                         ; |Buffer
    004010A9  |.  50            push    eax                                         ; |hWnd
    004010AA  |.  E8 BF9C0000   call    <jmp.&USER32.GetWindowTextA>                ; GetWindowTextA
    004010AF  |.  6A 67         push    67                                          ; /ControlID = 67 (103.)
    004010B1  |.  53            push    ebx                                         ; |hWnd
    004010B2  |.  E8 AB9C0000   call    <jmp.&USER32.GetDlgItem>                    ; GetDlgItem
    004010B7  |.  8945 FC       mov     dword ptr [ebp-4], eax
    004010BA  |.  8D85 44FFFFFF lea     eax, dword ptr [ebp-BC]
    004010C0  |.  50            push    eax
    004010C1  |.  E8 2A060000   call    004016F0
    004010C6  |.  59            pop     ecx
    004010C7  |.  8945 D4       mov     dword ptr [ebp-2C], eax
    004010CA  |.  8D8D E0FEFFFF lea     ecx, dword ptr [ebp-120]
    004010D0  |.  51            push    ecx
    004010D1  |.  E8 1A060000   call    004016F0
    004010D6  |.  59            pop     ecx
    004010D7  |.  68 EAB04000   push    0040B0EA
    004010DC  |.  E8 0F060000   call    004016F0
    004010E1  |.  59            pop     ecx
    004010E2  |.  68 0EB14000   push    0040B10E
    004010E7  |.  E8 04060000   call    004016F0
    004010EC  |.  59            pop     ecx
    004010ED  |.  837D D4 03    cmp     dword ptr [ebp-2C], 3                       ;  用户名字串长度<=3 ,则跳转
    004010F1  |.  0F8E 38010000 jle     0040122F                                    ;  是则跳转到出错函数
    004010F7  |.  33D2          xor     edx, edx
    004010F9  |.  33DB          xor     ebx, ebx
    004010FB  |.  8B55 D4       mov     edx, dword ptr [ebp-2C]                     ;  edx = 长度
    004010FE  |.  0155 C4       add     dword ptr [ebp-3C], edx                     ;  长度赋给变量3C(假设有这么个变量)
    00401101  |.  0155 C4       add     dword ptr [ebp-3C], edx                     ;  变量 = 长度 * 2
    00401104  |.  8BC2          mov     eax, edx
    00401106  |.  83C0 05       add     eax, 5                                      ;  eax = 长度+5
    00401109  |.  8945 B8       mov     dword ptr [ebp-48], eax                     ;  结果保存至变量48(假设)
    0040110C  |.  33C0          xor     eax, eax
    0040110E  |.  8BCF          mov     ecx, edi
    00401110  |.  83C1 04       add     ecx, 4
    00401113  |.  894D B4       mov     dword ptr [ebp-4C], ecx                     ;  变量4C(假设)的值=0012F538+4
    00401116  |.  33C9          xor     ecx, ecx
    00401118  |.  0155 BC       add     dword ptr [ebp-44], edx
    0040111B  |.  017D BC       add     dword ptr [ebp-44], edi                     ;  变量44(假设)=用户名字串长度+edi(0012F538)
    0040111E  |.  6BFF 03       imul    edi, edi, 3
    00401121  |.  897D C0       mov     dword ptr [ebp-40], edi                     ;  变量40(假设)=0012F538*3
    00401124  |.  33FF          xor     edi, edi
    00401126  |.  0FBE8C05 44FF>movsx   ecx, byte ptr [ebp+eax-BC]                  ;  取字符串首个字符
    0040112E  |.  83F9 61       cmp     ecx, 61                                     ;  如果该字符不是小写字母或是‘{}|~’
    00401131  |.  7C 07         jl      short 0040113A                              ;  则跳转进入子程序进行一些操作
    00401133  |.  90            nop
    00401134  |.  90            nop
    00401135  |.  90            nop
    00401136  |.  90            nop
    00401137  |.  83E9 20       sub     ecx, 20                                     ;  是小写字母则转换为大写
    0040113A  |>  8BF1          mov     esi, ecx
    0040113C  |.  03DE          add     ebx, esi
    0040113E  |.  0FAFD9        imul    ebx, ecx
    00401141  |.  4A            dec     edx
    00401142  |>  0FBE8C2F 44FF>/movsx   ecx, byte ptr [edi+ebp-BC]                 ;  遍历用户名字符串,该指令取前一个字符
    0040114A  |.  0FBEB42F 45FF>|movsx   esi, byte ptr [edi+ebp-BB]                 ;  该指令取出后一个字符
    00401152  |.  83F9 61       |cmp     ecx, 61                                    ;  如果前一个字符是小写字母,则跳转
    00401155  |.  7D 12         |jge     short 00401169                             ;  将字符转换为大写
    00401157  |.  90            |nop
    00401158  |.  90            |nop
    00401159  |.  90            |nop
    0040115A  |.  90            |nop
    0040115B  |>  83FE 61       |cmp     esi, 61                                    ;  如果后一个字符是小写字母,则跳转
    0040115E  |.  7D 0E         |jge     short 0040116E
    00401160  |.  90            |nop
    00401161  |.  90            |nop
    00401162  |.  90            |nop
    00401163  |.  90            |nop
    00401164  |.  EB 0B         |jmp     short 00401171
    00401166  |   90            |nop
    00401167  |   90            |nop
    00401168  |   90            |nop
    00401169  |>  83E9 20       |sub     ecx, 20
    0040116C  |.^ EB ED         |jmp     short 0040115B
    0040116E  |>  83EE 20       |sub     esi, 20                                    ;  将字符转换为大写
    00401171  |>  47            |inc     edi                                        ;  索引变量自增
    00401172  |.  03DE          |add     ebx, esi                                   ;  对ebx进行一些操作。。
    00401174  |.  0FAFD9        |imul    ebx, ecx
    00401177  |.  4A            |dec     edx                                        ;  循环变量自减
    00401178  |.^ 75 C8         jnz     short 00401142
    0040117A  |.  895D C8       mov     dword ptr [ebp-38], ebx                     ;  循环的目的看似是转换大小写,其实是对ebx的值做调整,最后保存至变量38(假设)
    0040117D  |.  33C9          xor     ecx, ecx
    0040117F  |.  33D2          xor     edx, edx
    00401181  |.  33DB          xor     ebx, ebx
    00401183  |.  33C0          xor     eax, eax
    00401185  |.  837D D4 32    cmp     dword ptr [ebp-2C], 32                      ;  如果用户名字串长度大于等于32h,则跳转
    00401189  |.  0F8D A0000000 jge     0040122F                                    ;  是则跳转到出错函数
    0040118F  |>  0FBE840D 44FF>/movsx   eax, byte ptr [ebp+ecx-BC]                 ;  遍历用户名字符串
    00401197  |.  03C1          |add     eax, ecx                                   ;  加上循环变量
    00401199  |.  03D8          |add     ebx, eax                                   ;  累加的值存入ebx
    0040119B  |.  41            |inc     ecx
    0040119C  |.  3B4D D4       |cmp     ecx, dword ptr [ebp-2C]
    0040119F  |.^ 75 EE         jnz     short 0040118F
    004011A1  |.  D1C0          rol     eax, 1                                      ;  把eax循环左移1次,每次从最高位(最左)移出的数据位都补充到最低位
    004011A3  |.  35 40E20100   xor     eax, 1E240                                  ;  将eax与1E240h异或
    004011A8  |.  8945 B0       mov     dword ptr [ebp-50], eax                     ;  保存至变量50(假设)
    004011AB  |.  33C9          xor     ecx, ecx
    004011AD  |.  33D2          xor     edx, edx
    004011AF  |.  33DB          xor     ebx, ebx
    004011B1  |.  33C0          xor     eax, eax
    004011B3  |>  0FBE840D 44FF>/movsx   eax, byte ptr [ebp+ecx-BC]                 ;  遍历用户名字符串
    004011BB  |.  6BD0 06       |imul    edx, eax, 6                                ;  edx = eax * 6
    004011BE  |.  33C2          |xor     eax, edx
    004011C0  |.  03D8          |add     ebx, eax
    004011C2  |.  41            |inc     ecx
    004011C3  |.  3B4D D4       |cmp     ecx, dword ptr [ebp-2C]
    004011C6  |.^ 75 EB         jnz     short 004011B3
    004011C8  |.  035D B0       add     ebx, dword ptr [ebp-50]                     ;  结果加上变量50(假设)
    004011CB  |.  895D AC       mov     dword ptr [ebp-54], ebx                     ;  保存至变量54(假设)
    004011CE  |.  FF75 C0       push    dword ptr [ebp-40]
    004011D1  |.  FF75 C4       push    dword ptr [ebp-3C]
    004011D4  |.  FF75 BC       push    dword ptr [ebp-44]
    004011D7  |.  FF75 C8       push    dword ptr [ebp-38]
    004011DA  |.  FF75 B4       push    dword ptr [ebp-4C]
    004011DD  |.  FF75 B8       push    dword ptr [ebp-48]
    004011E0  |.  FF75 AC       push    dword ptr [ebp-54]
    004011E3  |.  FF75 B0       push    dword ptr [ebp-50]
    004011E6  |.  68 38B44000   push    0040B438                                    ;  ASCII "%lX%lu-%lu%lX-%lu%lu-%lX%lX"
    004011EB  |.  8D85 7CFEFFFF lea     eax, dword ptr [ebp-184]
    004011F1  |.  50            push    eax
    004011F2  |.  E8 8D3D0000   call    00404F84                                    ;  将数据按照格式保存至ebp-184
    004011F7  |.  83C4 28       add     esp, 28                                     ;  平衡堆栈
    004011FA  |.  8D95 7CFEFFFF lea     edx, dword ptr [ebp-184]
    00401200  |.  52            push    edx                                         ; /String2
    00401201  |.  8D8D E0FEFFFF lea     ecx, dword ptr [ebp-120]                    ; |
    00401207  |.  51            push    ecx                                         ; |String1
    00401208  |.  E8 399C0000   call    <jmp.&KERNEL32.lstrcmpA>                    ; lstrcmpA
    0040120D  |.  85C0          test    eax, eax
    0040120F  |.  75 0F         jnz     short 00401220
    00401211  |.  68 54B44000   push    0040B454                                    ; /Text = "Congratulations! IF this number comes *FROM YOUR* keygen, Write a tutorial dude ;)."
    00401216  |.  FF75 FC       push    dword ptr [ebp-4]                           ; |hWnd
    00401219  |.  E8 2C9B0000   call    <jmp.&USER32.SetWindowTextA>                ; SetWindowTextA
    0040121E  |.  EB 1C         jmp     short 0040123C
    00401220  |>  68 A8B44000   push    0040B4A8                                    ; /Text = "This serial is *NOT* Valid!! Try again... : UNREGISTERED"
    00401225  |.  FF75 FC       push    dword ptr [ebp-4]                           ; |hWnd
    00401228  |.  E8 1D9B0000   call    <jmp.&USER32.SetWindowTextA>                ; SetWindowTextA
    0040122D  |.  EB 0D         jmp     short 0040123C
    0040122F  |>  68 E1B44000   push    0040B4E1                                    ; /Text = "Name must contain more than 3 chars!"
    00401234  |.  FF75 FC       push    dword ptr [ebp-4]                           ; |hWnd
    00401237  |.  E8 0E9B0000   call    <jmp.&USER32.SetWindowTextA>                ; SetWindowTextA

    好了,算法到这里分析完毕,我们根据加密算法开始编写注册机吧!

    复制一份http://www.cnblogs.com/ZRBYYXDM/p/5002789.html中搭建的MFC窗口程序,打开并修改OnOk函数如下:

    void CSerialNumber_KeygenDlg::OnOK() 
    {
        // TODO: Add extra validation here
        CString str;
        GetDlgItem( IDC_EDIT_NAME )->GetWindowText( str );        //获取用户名
    
        int len = str.GetLength();                                //获取长度
    
        if ( len <= 3 || len >= 50 )    
            MessageBox( "用户名必须长度大于3、小于50!" );
        else
        {
            unsigned int Serial[8] = { 0,0,0,0,0,0,0,0 };            //存放组成密钥的字串。
    
            Serial[0] += (str[len - 1] + len - 1);    //变量50
    
            __asm {
                push eax
                mov eax,Serial[0]
                rol eax,1
                mov Serial[0],eax
                pop eax
            }
            Serial[0] ^= 0x1E240;            
    
            int i = 0;
            for ( i = 0 ; i != len ; i++ )        //变量54
                Serial[1] += (str[i] * 6) ^ str[i];
            Serial[1] += Serial[0];            
    
            Serial[2] = len + 5;                    //变量48
            Serial[3] = 0x12F538+4;                    //变量4C
            
                                                    //变量38
            if ( str[0] >= 0x61 )                    //如果第一个字符是小写字符
                Serial[4] = str[0] - 0x20;
            else
                Serial[4] = str[0];
    
            Serial[4] *= Serial[4];
            str.MakeUpper();                        //将小写转换为大写。
            for ( i = 0 ; i != (len - 1) ; i++ ){
                Serial[4] += str[i + 1];
                Serial[4] *= str[i];
            }
    
            Serial[5] = len + 0x12F538;                //变量44
            Serial[6] = len * 2;                    //变量3C
            Serial[7] = 0x12F538 * 3;                //变量40
    
    
            CString res;
            res.Format( _T("%lX%lu-%lu%lX-%lu%lu-%lX%lX"),Serial[0],Serial[1],
                        Serial[2],Serial[3],Serial[4],Serial[5],Serial[6],Serial[7] );
    
            GetDlgItem( IDC_EDIT_Number )->SetWindowText( res );
        }
    
        //CDialog::OnOK();                    //屏蔽基类OnOk函数
    }

    再在OnInitDialog中添加此代码修改标题:SetWindowText(_T("k4n2_Keygen"));

    运行程序,并将解密得到的序列号黏贴至k4n2程序中,单击check。。。

    效果拔群:

    我们一路奋战,不是为了改变世界,而是不让世界改变我们 ——《熔炉》
  • 相关阅读:
    redhat 7.6 常用命令
    redhat 7.6 VI编辑操作
    redhat 7.6 网络配置
    华为学习配置笔记-01 配置con密码
    redhat 7.6 ssh 服务配置
    web前端面试第一次[addEventListenr();绑定事件]
    redis集群搭建
    linux服务器重启后redis数据丢失问题
    redis日志文件路径的设置
    linux下redis安装使用
  • 原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5063100.html
Copyright © 2020-2023  润新知