系统 : Windows xp

程序 : Keygenme # 2

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

要求 : 注册机编写 

使用工具 : OD

可在“PEDIY CrackMe 2007”中查找关于此程序的讨论,标题为“一个据说是新手级Crackme的分析”。

 

运行程序,查找字符串定位关键算法位置。大致的看一下程序主体:

004014AF  |.  C74424 04 CE0>mov     dword ptr [esp+4], 004400CE      ;  enter user-name: enter user-id: enter password: access granted !
004014B7  |.  C70424 C03344>mov     dword ptr [esp], 004433C0
004014BE  |.  E8 95AE0300   call    0043C358
004014C3  |.  C74424 04 28B>mov     dword ptr [esp+4], 0043B128
004014CB  |.  890424        mov     dword ptr [esp], eax
004014CE  |.  E8 DD8D0200   call    0042A2B0
004014D3  |.  C74424 04 CF0>mov     dword ptr [esp+4], 004400CF      ;  enter user-name: enter user-id: enter password: access granted !
004014DB  |.  C70424 C03344>mov     dword ptr [esp], 004433C0
004014E2  |.  E8 71AE0300   call    0043C358
004014E7  |.  8D85 F8FEFFFF lea     eax, dword ptr [ebp-108]         ; |
004014ED  |.  890424        mov     dword ptr [esp], eax             ; |
004014F0  |.  E8 8BF40000   call    <jmp.&msvcrt.gets>               ; \gets
004014F5  |.  80BD F8FEFFFF>cmp     byte ptr [ebp-108], 0            ;  是否为空?
004014FC  |.  0F84 A8010000 je      004016AA                         ;  是则失败
00401502  |.  C74424 04 E10>mov     dword ptr [esp+4], 004400E1      ;  enter user-id: enter password: access granted !
0040150A  |.  C70424 C03344>mov     dword ptr [esp], 004433C0
00401511  |.  E8 42AE0300   call    0043C358
00401516  |.  8D85 DCFEFFFF lea     eax, dword ptr [ebp-124]
0040151C  |.  894424 04     mov     dword ptr [esp+4], eax
00401520  |.  C70424 603444>mov     dword ptr [esp], 00443460
00401527  |.  E8 C4720200   call    004287F0                         ;  读入id的子程序
0040152C  |.  C785 D8FEFFFF>mov     dword ptr [ebp-128], 0           ;  循环变量初始化
00401536  |>  8D85 F8FEFFFF /lea     eax, dword ptr [ebp-108]        ; |
0040153C  |.  890424        |mov     dword ptr [esp], eax            ; |
0040153F  |.  E8 2CF40000   |call    <jmp.&msvcrt.strlen>            ; \strlen
00401544  |.  3B85 D8FEFFFF |cmp     eax, dword ptr [ebp-128]        ;  长度低于等于 循环变量
0040154A  |.  76 5B         |jbe     short 004015A7                  ;  则跳出循环
0040154C  |.  8D45 F8       |lea     eax, dword ptr [ebp-8]
0040154F  |.  0385 D8FEFFFF |add     eax, dword ptr [ebp-128]        ;  地址 加上 循环变量
00401555  |.  2D 00010000   |sub     eax, 100                        ;  还原成User-Name
0040155A  |.  0FBE00        |movsx   eax, byte ptr [eax]             ;  扩展载入到eax
0040155D  |.  8985 F4FEFFFF |mov     dword ptr [ebp-10C], eax
00401563  |.  8D85 F4FEFFFF |lea     eax, dword ptr [ebp-10C]
00401569  |.  8100 656C2A03 |add     dword ptr [eax], 32A6C65        ;  保存的值加上一个 固定数值
0040156F  |.  8B85 DCFEFFFF |mov     eax, dword ptr [ebp-124]        ;  读入的id
00401575  |.  0FAF85 DCFEFF>|imul    eax, dword ptr [ebp-124]
0040157C  |.  01C0          |add     eax, eax
0040157E  |.  0385 F4FEFFFF |add     eax, dword ptr [ebp-10C]        ;  加上之前保存的值
00401584  |.  05 237AD602   |add     eax, 2D67A23                    ;  再加
00401589  |.  8985 F4FEFFFF |mov     dword ptr [ebp-10C], eax
0040158F  |.  8B95 F4FEFFFF |mov     edx, dword ptr [ebp-10C]        ;  存入edx
00401595  |.  8D85 F0FEFFFF |lea     eax, dword ptr [ebp-110]
0040159B  |.  0110          |add     dword ptr [eax], edx
0040159D  |.  8D85 D8FEFFFF |lea     eax, dword ptr [ebp-128]
004015A3  |.  FF00          |inc     dword ptr [eax]                 ;  循环变量自增
004015A5  |.^ EB 8F         \jmp     short 00401536
004015A7  |>  C74424 04 F10>mov     dword ptr [esp+4], 004400F1      ;  enter password: access granted !
004015AF  |.  C70424 C03344>mov     dword ptr [esp], 004433C0
004015B6  |.  E8 9DAD0300   call    0043C358
004015BB  |.  8D85 E8FEFFFF lea     eax, dword ptr [ebp-118]
004015C1  |.  894424 04     mov     dword ptr [esp+4], eax
004015C5  |.  C70424 603444>mov     dword ptr [esp], 00443460
004015CC  |.  E8 1F720200   call    004287F0
004015D1  |.  C74424 04 CE0>mov     dword ptr [esp+4], 004400CE      ;  enter user-name: enter user-id: enter password: access granted !
004015D9  |.  C70424 C03344>mov     dword ptr [esp], 004433C0
004015E0  |.  E8 73AD0300   call    0043C358
004015E5  |.  C74424 04 28B>mov     dword ptr [esp+4], 0043B128
004015ED  |.  890424        mov     dword ptr [esp], eax
004015F0  |.  E8 BB8C0200   call    0042A2B0
004015F5  |.  8B85 F0FEFFFF mov     eax, dword ptr [ebp-110]
004015FB  |.  3B85 E8FEFFFF cmp     eax, dword ptr [ebp-118]
00401601      75 3A         jnz     short 0040163D
00401603  |.  C74424 04 020>mov     dword ptr [esp+4], 00440102      ;  access granted !
0040160B  |.  C70424 C03344>mov     dword ptr [esp], 004433C0
00401612  |.  E8 41AD0300   call    0043C358
00401617  |.  C74424 04 28B>mov     dword ptr [esp+4], 0043B128
0040161F  |.  890424        mov     dword ptr [esp], eax
00401622  |.  E8 898C0200   call    0042A2B0
00401627  |.  C74424 04 140>mov     dword ptr [esp+4], 00440114      ;  you did it cracker...now make a keygen !access denied !press any key to continue...access violation !
0040162F  |.  C70424 C03344>mov     dword ptr [esp], 004433C0
00401636  |.  E8 1DAD0300   call    0043C358
0040163B  |.  EB 5C         jmp     short 00401699
0040163D  |>  C74424 04 3D0>mov     dword ptr [esp+4], 0044013D      ;  access denied !press any key to continue...access violation !

一个比较典型的二元函数加密的例子,算法也很简单。唯一的难点是不能对存放id的地址下内存断点,一旦这样操作就会导致读取失败,不过用硬件断点可以很方便地解决问题。

打开http://www.cnblogs.com/ZRBYYXDM/p/5115596.html中搭建的框架,加入新的ID文本编辑框控件,并在消息响应函数中加上解密代码:

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

    if ( str.GetLength() && ID.GetLength() ){               //格式控制。
        int IDnum = atoi( ID );
        DWORD Res = 0,Sum = 0;
        for ( int i = 0 ; i != str.GetLength() ; i++ ){
            Sum = IDnum * IDnum;
            Sum += Sum;
            Sum += ( str.GetAt(i) + 0x32A6C65 );
            Sum += 0x2D67A23;
            Res += Sum;
        }

        CString PassWord;
        PassWord.Format( "%d",Res );
        SetDlgItemText( IDC_EDIT_PASSWORD,PassWord );
    }
    else
        MessageBox( "用户名格式错误!" );
}

继续完善一下拷贝按钮:

void CKengen_TemplateDlg::OnBtnCopy() 
{
    // TODO: Add your control notification handler code here
    CString cmd;
    GetDlgItemText( IDC_BTN_COPY,cmd );

    if ( OpenClipboard() ){                                        //打开剪贴板
        CString str;
        HANDLE hClip;
        char *pBuf;

        EmptyClipboard();
        
        if ( cmd == "拷贝用户名" )                                //如果命令是拷贝用户名
            GetDlgItemText( IDC_EDIT_NAME,str );
        else{
            if ( cmd == "拷贝ID" )
                GetDlgItemText( IDC_EDIT_ID,str );
            else
                GetDlgItemText( IDC_EDIT_PASSWORD,str );
        }

        hClip = GlobalAlloc( GMEM_MOVEABLE,str.GetLength() + 1 );
        pBuf = (char*)GlobalLock( hClip );
        strcpy( pBuf,str );
        GlobalUnlock( hClip );
        SetClipboardData( CF_TEXT,hClip );
        CloseClipboard();

        if ( cmd == "拷贝用户名" ){                                //变换命令
            SetDlgItemText( IDC_BTN_COPY,"拷贝ID" );
            SetDlgItemText( IDC_STC_MSG,"拷贝用户名成功!" );    //提示成功
        }
        else{
            if ( cmd == "拷贝ID" ){
                SetDlgItemText( IDC_BTN_COPY,"拷贝序列号" );
                SetDlgItemText( IDC_STC_MSG,"拷贝ID成功!" );
            }
            else{
                SetDlgItemText( IDC_BTN_COPY,"拷贝用户名" );
                SetDlgItemText( IDC_STC_MSG,"拷贝序列号成功!" );
            }
        }
    }
    else
        SetDlgItemText( IDC_STC_MSG,"拷贝失败!" );
}

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

运行效果: