系统 : Windows xp

程序 : Splish

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

要求 : 注册机编写 & 找出硬编码

使用工具 : OD & IDA

可在“PEDIY CrackMe 2007”中查找关于此程序的破文,标题为“一个简单crackme的详细算法分析(高手莫入)”

 

 

首先我们来查查看硬编码,IDA载入程序,查看字串表找到“Congratulations, you got the hard coded serial”。定位字串调用位置并向上翻找到硬编码:

.text:0040135D loc_40135D:                             ; CODE XREF: sub_401178+1D9j
.text:0040135D                 push    20h             ; nMaxCount
.text:0040135F                 push    offset String   ; lpString
.text:00401364                 push    hWnd            ; hWnd
.text:0040136A                 call    GetWindowTextA
.text:0040136F                 lea     eax, aHardcoded ; "HardCoded"
.text:00401375                 lea     ebx, String
.text:0040137B
.text:0040137B loc_40137B:                             ; CODE XREF: sub_401178+212j
.text:0040137B                 cmp     byte ptr [eax], 0
.text:0040137E                 jz      short loc_40138C

很简单的一个硬编码就被我们找到了。

 

继续查看字串表,看到提示成功的字串“Good job, now keygen it.”,定位调用位置并翻找到关键算法:

004015E4  /$  55            push    ebp
004015E5  |.  8BEC          mov     ebp, esp
004015E7  |.  6A 20         push    20                               ; /Count = 20 (32.)
004015E9  |.  68 42324000   push    00403242                         ; |Buffer = Splish.00403242
004015EE  |.  FF75 0C       push    dword ptr [ebp+C]                ; |hWnd
004015F1  |.  E8 34010000   call    <jmp.&USER32.GetWindowTextA>     ; \GetWindowTextA
004015F6  |.  85C0          test    eax, eax                         ;  序列号长度为0?
004015F8  |.  0F84 95000000 je      00401693                         ;  是则提示出错
004015FE  |.  A3 67344000   mov     dword ptr [403467], eax
00401603  |.  6A 0B         push    0B                               ; /Count = B (11.)
00401605  |.  68 36324000   push    00403236                         ; |Buffer = Splish.00403236
0040160A  |.  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
0040160D  |.  E8 18010000   call    <jmp.&USER32.GetWindowTextA>     ; \GetWindowTextA
00401612  |.  85C0          test    eax, eax                         ;  用户名长度为0?
00401614  |.  74 68         je      short 0040167E                   ;  是则提示出错
00401616  |.  A3 63344000   mov     dword ptr [403463], eax
0040161B  |.  33C9          xor     ecx, ecx
0040161D  |.  33DB          xor     ebx, ebx
0040161F  |.  33D2          xor     edx, edx
00401621  |.  8D35 36324000 lea     esi, dword ptr [403236]          ;  取用户名
00401627  |.  8D3D 58324000 lea     edi, dword ptr [403258]          ;  取一段内存
0040162D  |.  B9 0A000000   mov     ecx, 0A
00401632  |>  0FBE041E      /movsx   eax, byte ptr [esi+ebx]         ;  迭代字串
00401636  |.  99            |cdq
00401637  |.  F7F9          |idiv    ecx                             ;  除以0A
00401639  |.  33D3          |xor     edx, ebx                        ;  余数 与 循环变量异或
0040163B  |.  83C2 02       |add     edx, 2                          ;  +2
0040163E  |.  80FA 0A       |cmp     dl, 0A                          ;  小于0A则跳转
00401641  |.  7C 03         |jl      short 00401646
00401643  |.  80EA 0A       |sub     dl, 0A
00401646  |>  88141F        |mov     byte ptr [edi+ebx], dl          ;  保存
00401649  |.  43            |inc     ebx                             ;  循环变量自增
0040164A  |.  3B1D 63344000 |cmp     ebx, dword ptr [403463]         ;  迭代完毕?
00401650  |.^ 75 E0         \jnz     short 00401632
00401652  |.  33C9          xor     ecx, ecx
00401654  |.  33DB          xor     ebx, ebx
00401656  |.  33D2          xor     edx, edx
00401658  |.  8D35 42324000 lea     esi, dword ptr [403242]          ;  取序列号
0040165E  |.  8D3D 4D324000 lea     edi, dword ptr [40324D]          ;  取一段内存
00401664  |.  B9 0A000000   mov     ecx, 0A
00401669  |>  0FBE041E      /movsx   eax, byte ptr [esi+ebx]         ;  迭代字串
0040166D  |.  99            |cdq
0040166E  |.  F7F9          |idiv    ecx                             ;  除以0A
00401670  |.  88141F        |mov     byte ptr [edi+ebx], dl          ;  保存余数
00401673  |.  43            |inc     ebx                             ;  循环变量自增
00401674  |.  3B1D 67344000 |cmp     ebx, dword ptr [403467]         ;  迭代完毕?
0040167A  |.^ 75 ED         \jnz     short 00401669
0040167C  |.  EB 2A         jmp     short 004016A8
0040167E  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
00401680  |.  68 0A304000   push    0040300A                         ; |Title = "Splish, Splash"
00401685  |.  68 A0304000   push    004030A0                         ; |Text = "Please enter your name."
0040168A  |.  6A 00         push    0                                ; |hOwner = NULL
0040168C  |.  E8 B7000000   call    <jmp.&USER32.MessageBoxA>        ; \MessageBoxA
00401691  |.  EB 62         jmp     short 004016F5
00401693  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
00401695  |.  68 0A304000   push    0040300A                         ; |Title = "Splish, Splash"
0040169A  |.  68 B8304000   push    004030B8                         ; |Text = "Please enter your serial number."
0040169F  |.  6A 00         push    0                                ; |hOwner = NULL
004016A1  |.  E8 A2000000   call    <jmp.&USER32.MessageBoxA>        ; \MessageBoxA
004016A6  |.  EB 4D         jmp     short 004016F5
004016A8  |>  8D35 4D324000 lea     esi, dword ptr [40324D]          ;  取F(序列号)
004016AE  |.  8D3D 58324000 lea     edi, dword ptr [403258]          ;  取F(用户名)
004016B4  |.  33DB          xor     ebx, ebx
004016B6  |>  3B1D 63344000 /cmp     ebx, dword ptr [403463]         ;  比较字串
004016BC  |.  74 0F         |je      short 004016CD
004016BE  |.  0FBE041F      |movsx   eax, byte ptr [edi+ebx]
004016C2  |.  0FBE0C1E      |movsx   ecx, byte ptr [esi+ebx]
004016C6  |.  3BC1          |cmp     eax, ecx
004016C8  |.  75 18         |jnz     short 004016E2
004016CA  |.  43            |inc     ebx
004016CB  |.^ EB E9         \jmp     short 004016B6
004016CD  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
004016CF  |.  68 0A304000   push    0040300A                         ; |Title = "Splish, Splash"
004016D4  |.  68 42304000   push    00403042                         ; |Text = "Good job, now keygen it."
004016D9  |.  6A 00         push    0                                ; |hOwner = NULL
004016DB  |.  E8 68000000   call    <jmp.&USER32.MessageBoxA>        ; \MessageBoxA
004016E0  |.  EB 13         jmp     short 004016F5
004016E2  |>  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
004016E4  |.  68 0A304000   push    0040300A                         ; |Title = "Splish, Splash"
004016E9  |.  68 67304000   push    00403067                         ; |Text = "Sorry, please try again."
004016EE  |.  6A 00         push    0                                ; |hOwner = NULL
004016F0  |.  E8 53000000   call    <jmp.&USER32.MessageBoxA>        ; \MessageBoxA
004016F5  |>  C9            leave
004016F6  \.  C2 0800       retn    8

以上,算法分析完毕,我们发现它实现的F(序列号)很有意思,根据它我们可以推导出多个序列号。这里,我们将F(用户名)的结果加上50作为算出的序列号。

直接打开http://www.cnblogs.com/ZRBYYXDM/p/5115596.html中搭建的框架,并修改OnBtnDecrypt函数如下:

void CKengen_TemplateDlg::OnBtnDecrypt() 
{
    // TODO: Add your control notification handler code here
    CString str;
    GetDlgItemText( IDC_EDIT_NAME,str );                    //获取用户名字串基本信息。
    int len = str.GetLength();

    if ( len != 0 ){                                        //格式控制。
        int i;
        int FNameRes[100];

        for ( i = 0 ; i != len ; i++ ){
            FNameRes[i] = ( ( (str[i]%0xA) ^ i ) + 2 );        //注意运算符的优先级与结合性
            if ( FNameRes[i] >= 0xA )
                FNameRes[i] -= 0xA;
        }

        //模拟F(序列号)
        /*
            CString Serial = "123";
            int FSerialRes[100];
            for ( i = 0 ; i != Serial.GetLength() ; i++ )
                FSerialRes[i] = Serial[i] % 0xA;
        */

        CString PassWord = "";
        for ( i = 0 ; i != len ; i++ ){
            PassWord += ( FNameRes[i] + 50 );
        }

        SetDlgItemText( IDC_EDIT_PASSWORD,PassWord );
    }
    else
        MessageBox( "用户名格式错误!" );
}

再在OnInitDialog中添加此代码修改标题:

运行效果: