系统 : Windows xp

程序 : CrackMe#1

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

要求 : 编写注册机

使用工具 :IDA & OD 

可在看雪论坛中查找关于此程序的破文:http://bbs.pediy.com/showthread.php?t=29063

 

IDA载入程序,找出提示破解成功的字串“You cracked the UBC CrackMe#1 ! Please send your solution to ubcrackers@hotmail.com !”并定位关键代码:

00458800  /.  55            push    ebp
00458801  |.  8BEC          mov     ebp, esp
00458803  |.  6A 00         push    0
00458805  |.  53            push    ebx
00458806  |.  8BD8          mov     ebx, eax
00458808  |.  33C0          xor     eax, eax
0045880A  |.  55            push    ebp
0045880B  |.  68 74884500   push    00458874
00458810  |.  64:FF30       push    dword ptr fs:[eax]
00458813  |.  64:8920       mov     dword ptr fs:[eax], esp
00458816  |.  E8 45FFFFFF   call    00458760                         ;  获取用户名
0045881B  |.  8D55 FC       lea     edx, dword ptr [ebp-4]           ;  取一段内存
0045881E  |.  8B83 D0020000 mov     eax, dword ptr [ebx+2D0]
00458824  |.  E8 97CDFCFF   call    004255C0                         ;  获取序列号
00458829  |.  8B45 FC       mov     eax, dword ptr [ebp-4]           ;  取序列号
0045882C  |.  E8 43EFFAFF   call    00407774                         ;  F(序列号)
00458831  |.  3B05 44B84500 cmp     eax, dword ptr [45B844]
00458837  |.  75 1B         jnz     short 00458854
00458839  |.  B8 88884500   mov     eax, 00458888                    ;  ASCII "You cracked the UBC CrackMe#1 ! Please send your solution to ubcrackers@hotmail.com !"
0045883E  |.  E8 29C1FEFF   call    0044496C
00458843  |.  BA E8884500   mov     edx, 004588E8                    ;  ASCII "CRACKED"
00458848  |.  A1 3CB84500   mov     eax, dword ptr [45B83C]
0045884D  |.  E8 9ECDFCFF   call    004255F0
00458852  |.  EB 0A         jmp     short 0045885E
00458854  |>  B8 F8884500   mov     eax, 004588F8                    ;  ASCII "Try Again !"
00458859  |.  E8 0EC1FEFF   call    0044496C

进入F(序列号):

00407774  /$  55            push    ebp
00407775  |.  8BEC          mov     ebp, esp
00407777  |.  83C4 F0       add     esp, -10
0040777A  |.  53            push    ebx
0040777B  |.  56            push    esi
0040777C  |.  33D2          xor     edx, edx
0040777E  |.  8955 F8       mov     dword ptr [ebp-8], edx
00407781  |.  8BD8          mov     ebx, eax
00407783  |.  33C0          xor     eax, eax
00407785  |.  55            push    ebp
00407786  |.  68 DC774000   push    004077DC
0040778B  |.  64:FF30       push    dword ptr fs:[eax]
0040778E  |.  64:8920       mov     dword ptr fs:[eax], esp
00407791  |.  8D55 FC       lea     edx, dword ptr [ebp-4]
00407794  |.  8BC3          mov     eax, ebx
00407796  |.  E8 D9B1FFFF   call    00402974                         ;  关键call
0040779B  |.  8BF0          mov     esi, eax
0040779D  |.  837D FC 00    cmp     dword ptr [ebp-4], 0
004077A1  |.  74 23         je      short 004077C6
004077A3  |.  8D55 F8       lea     edx, dword ptr [ebp-8]
004077A6  |.  A1 90A44500   mov     eax, dword ptr [45A490]
004077AB  |.  E8 A4D6FFFF   call    00404E54
004077B0  |.  8B45 F8       mov     eax, dword ptr [ebp-8]
004077B3  |.  50            push    eax
004077B4  |.  895D F0       mov     dword ptr [ebp-10], ebx
004077B7  |.  C645 F4 0B    mov     byte ptr [ebp-C], 0B
004077BB  |.  8D55 F0       lea     edx, dword ptr [ebp-10]
004077BE  |.  33C9          xor     ecx, ecx
004077C0  |.  58            pop     eax
004077C1  |.  E8 A6FCFFFF   call    0040746C
004077C6  |>  33C0          xor     eax, eax
004077C8  |.  5A            pop     edx
004077C9  |.  59            pop     ecx
004077CA  |.  59            pop     ecx
004077CB  |.  64:8910       mov     dword ptr fs:[eax], edx
004077CE  |.  68 E3774000   push    004077E3
004077D3  |>  8D45 F8       lea     eax, dword ptr [ebp-8]
004077D6  |.  E8 0DC0FFFF   call    004037E8
004077DB  \.  C3            retn

关键call:

00402974  /$  53            push    ebx
00402975  |.  56            push    esi
00402976  |.  57            push    edi
00402977  |.  89C6          mov     esi, eax
00402979  |.  50            push    eax
0040297A  |.  85C0          test    eax, eax                         ;  序列号为空?
0040297C  |.  74 73         je      short 004029F1
0040297E  |.  31C0          xor     eax, eax
00402980  |.  31DB          xor     ebx, ebx
00402982  |.  BF CCCCCC0C   mov     edi, 0CCCCCCC
00402987  |>  8A1E          /mov     bl, byte ptr [esi]              ;  迭代序列号
00402989  |.  46            |inc     esi
0040298A  |.  80FB 20       |cmp     bl, 20                          ;  字符 = 0x20?
0040298D  |.^ 74 F8         \je      short 00402987                  ;  不是则退出循环
0040298F  |.  B5 00         mov     ch, 0
00402991  |.  80FB 2D       cmp     bl, 2D                           ;  Switch (cases 24..78)
00402994  |.  74 69         je      short 004029FF
00402996  |.  80FB 2B       cmp     bl, 2B                           ;  ‘+’
00402999  |.  74 66         je      short 00402A01
0040299B  |.  80FB 24       cmp     bl, 24
0040299E  |.  74 66         je      short 00402A06
004029A0  |.  80FB 78       cmp     bl, 78
004029A3  |.  74 61         je      short 00402A06
004029A5  |.  80FB 58       cmp     bl, 58
004029A8  |.  74 5C         je      short 00402A06
004029AA  |.  80FB 30       cmp     bl, 30
004029AD  |.  75 13         jnz     short 004029C2
004029AF  |.  8A1E          mov     bl, byte ptr [esi]               ;  Case 30 ('0') of switch 00402991
004029B1  |.  46            inc     esi
004029B2  |.  80FB 78       cmp     bl, 78
004029B5  |.  74 4F         je      short 00402A06
004029B7  |.  80FB 58       cmp     bl, 58
004029BA  |.  74 4A         je      short 00402A06
004029BC  |.  84DB          test    bl, bl
004029BE  |.  74 20         je      short 004029E0
004029C0  |.  EB 04         jmp     short 004029C6
004029C2  |>  84DB          test    bl, bl                           ;  Default case of switch 00402991
004029C4  |.  74 34         je      short 004029FA                   ;  为空则跳转
004029C6  |>  80EB 30       /sub     bl, 30
004029C9  |.  80FB 09       |cmp     bl, 9                           ;  高于9?
004029CC  |.  77 2C         |ja      short 004029FA
004029CE  |.  39F8          |cmp     eax, edi                        ;  高于0CCCCCCC?
004029D0  |.  77 28         |ja      short 004029FA
004029D2  |.  8D0480        |lea     eax, dword ptr [eax+eax*4]      ;  eax = eax + eax*4
004029D5  |.  01C0          |add     eax, eax                        ;  eax += eax
004029D7  |.  01D8          |add     eax, ebx                        ;  累加
004029D9  |.  8A1E          |mov     bl, byte ptr [esi]              ;  取下一个字符
004029DB  |.  46            |inc     esi
004029DC  |.  84DB          |test    bl, bl                          ;  不为空?
004029DE  |.^ 75 E6         \jnz     short 004029C6
004029E0  |>  FECD          dec     ch
004029E2  |.  74 10         je      short 004029F4
004029E4  |.  85C0          test    eax, eax
004029E6  |.  7C 12         jl      short 004029FA
004029E8  |>  59            pop     ecx
004029E9  |.  31F6          xor     esi, esi
004029EB  |>  8932          mov     dword ptr [edx], esi
004029ED  |.  5F            pop     edi
004029EE  |.  5E            pop     esi
004029EF  |.  5B            pop     ebx
004029F0  |.  C3            retn

再回去看看程序流程中的关键比对,将eax与45B844处的数据进行对比。这里,对45B844下写入断点,重新运行程序发现关键算法:

004587A2  |.  33C0          xor     eax, eax                         ;  清空eax
004587A4  |.  8903          mov     dword ptr [ebx], eax             ;  对内存置零
004587A6  |.  8B07          mov     eax, dword ptr [edi]             ;  取用户名
004587A8  |.  E8 B7B2FAFF   call    00403A64                         ;  计算长度
004587AD  |.  85C0          test    eax, eax                         ;  为空?
004587AF  |.  7E 19         jle     short 004587CA
004587B1  |.  C706 01000000 mov     dword ptr [esi], 1
004587B7  |>  8B17          /mov     edx, dword ptr [edi]            ;  取用户名
004587B9  |.  8B0E          |mov     ecx, dword ptr [esi]
004587BB  |.  0FB6540A FF   |movzx   edx, byte ptr [edx+ecx-1]       ;  迭代字串
004587C0  |.  C1E2 03       |shl     edx, 3                          ;  逻辑左移3位
004587C3  |.  0113          |add     dword ptr [ebx], edx            ;  与内存值累加
004587C5  |.  FF06          |inc     dword ptr [esi]                 ;  循环变量自增
004587C7  |.  48            |dec     eax                             ;  长度-1
004587C8  |.^ 75 ED         \jnz     short 004587B7
004587CA  |>  8B07          mov     eax, dword ptr [edi]
004587CC  |.  E8 93B2FAFF   call    00403A64                         ;  计算长度
004587D1  |.  C1E0 03       shl     eax, 3                           ;  长度逻辑左移3位
004587D4  |.  0103          add     dword ptr [ebx], eax             ;  与内存值累加
004587D6  |.  8B03          mov     eax, dword ptr [ebx]
004587D8  |.  C1E0 02       shl     eax, 2                           ;  长度逻辑左移2位
004587DB  |.  8903          mov     dword ptr [ebx], eax             ;  存入内存
004587DD  |.  33C0          xor     eax, eax
004587DF  |.  5A            pop     edx
004587E0  |.  59            pop     ecx
004587E1  |.  59            pop     ecx
004587E2  |.  64:8910       mov     dword ptr fs:[eax], edx
004587E5  |.  68 FA874500   push    004587FA
004587EA  |>  8D45 FC       lea     eax, dword ptr [ebp-4]
004587ED  |.  E8 F6AFFAFF   call    004037E8
004587F2  \.  C3            retn

至此,程序算法流程已经分析得差不多了。马上动手编写注册机。

我们直接打开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();

    int FNameres = 0;
    if ( len != 0 ){                                        //格式控制。
        for ( int i = 0 ; i != len ; i++ )
            FNameres += str[i] << 3;

        FNameres += len << 3;
        FNameres = FNameres << 2;

        //模拟F(序列号):十进制转化十六进制
        /*
            CString serial = "1234";
            
            int FSelres = 0;
            for ( int j = 0 ; j != serial.GetLength() ; j++ ){
                FSelres *= 10;
                FSelres += ( serial[j] - 0x30 );
            }
        */

        if ( FNameres > 0x0CCCCCCC )
            return ;

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

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

运行效果: