系统 : Windows xp

程序 : KeyGenMe-iNF1

程序下载地址 :https://pan.baidu.com/s/1nvfLBIh

要求 : 编写Keygen

使用工具 : OD

可在看雪论坛中查找关于此程序的破文:传送门

 

打开od,根据字符串“Serial is Correct!!!\nNow make a keygen”找到关键算法:

00401530  /$  8B4C24 04     mov ecx,dword ptr ss:[esp+0x4]
00401534  |.  8D4424 04     lea eax,dword ptr ss:[esp+0x4]
00401538  |.  50            push eax
00401539  |.  68 20304000   push KeyGenMe.00403020                   ; |%x
0040153E  |.  51            push ecx                                 ; |s
0040153F  |.  FF15 A4214000 call dword ptr ds:[<&MSVCRT.sscanf>]     ; \sscanf
00401545  |.  8B4424 10     mov eax,dword ptr ss:[esp+0x10]          ;  将密码从字符串形式转换成十六进制
00401549  |.  83C4 0C       add esp,0xC                              ;  平衡堆栈
0040154C  \.  C3            retn
0040154D      90            nop
0040154E      90            nop
0040154F      90            nop
00401550   .  83EC 2C       sub esp,0x2C
00401553   .  8D4424 0C     lea eax,dword ptr ss:[esp+0xC]
00401557   .  53            push ebx
00401558   .  56            push esi
00401559   .  57            push edi
0040155A   .  6A 1F         push 0x1F
0040155C   .  50            push eax
0040155D   .  8BF9          mov edi,ecx
0040155F   .  68 E8030000   push 0x3E8
00401564   .  E8 29030000   call <jmp.&MFC42.#3098>                  ;  获取字符串
00401569   .  8D4C24 0C     lea ecx,dword ptr ss:[esp+0xC]
0040156D   .  6A 0A         push 0xA
0040156F   .  51            push ecx
00401570   .  68 E9030000   push 0x3E9
00401575   .  8BCF          mov ecx,edi
00401577   .  E8 16030000   call <jmp.&MFC42.#3098>                  ;  获取字符串
0040157C   .  BE 3C314000   mov esi,KeyGenMe.0040313C
00401581   .  8D4424 18     lea eax,dword ptr ss:[esp+0x18]
00401585   >  8A10          mov dl,byte ptr ds:[eax]                 ;  存储用户名字符串首字符
00401587   .  8A1E          mov bl,byte ptr ds:[esi]
00401589   .  8ACA          mov cl,dl
0040158B   .  3AD3          cmp dl,bl
0040158D   .  75 1E         jnz XKeyGenMe.004015AD                   ;  首字符不等于00则进行跳转
0040158F   .  84C9          test cl,cl
00401591   .  74 16         je XKeyGenMe.004015A9
00401593   .  8A50 01       mov dl,byte ptr ds:[eax+0x1]
00401596   .  8A5E 01       mov bl,byte ptr ds:[esi+0x1]
00401599   .  8ACA          mov cl,dl
0040159B   .  3AD3          cmp dl,bl
0040159D   .  75 0E         jnz XKeyGenMe.004015AD
0040159F   .  83C0 02       add eax,0x2
004015A2   .  83C6 02       add esi,0x2
004015A5   .  84C9          test cl,cl
004015A7   .^ 75 DC         jnz XKeyGenMe.00401585
004015A9   >  33C0          xor eax,eax
004015AB   .  EB 05         jmp XKeyGenMe.004015B2
004015AD   >  1BC0          sbb eax,eax
004015AF   .  83D8 FF       sbb eax,-0x1
004015B2   >  85C0          test eax,eax                             ;  如果eax等于 0,则跳转
004015B4   .  0F84 A1000000 je KeyGenMe.0040165B
004015BA   .  BE 3C314000   mov esi,KeyGenMe.0040313C
004015BF   .  8D4424 0C     lea eax,dword ptr ss:[esp+0xC]           ;  取密码
004015C3   >  8A10          mov dl,byte ptr ds:[eax]                 ;  取密码首字符
004015C5   .  8A1E          mov bl,byte ptr ds:[esi]
004015C7   .  8ACA          mov cl,dl
004015C9   .  3AD3          cmp dl,bl
004015CB   .  75 1E         jnz XKeyGenMe.004015EB
004015CD   .  84C9          test cl,cl
004015CF   .  74 16         je XKeyGenMe.004015E7
004015D1   .  8A50 01       mov dl,byte ptr ds:[eax+0x1]
004015D4   .  8A5E 01       mov bl,byte ptr ds:[esi+0x1]
004015D7   .  8ACA          mov cl,dl
004015D9   .  3AD3          cmp dl,bl
004015DB   .  75 0E         jnz XKeyGenMe.004015EB
004015DD   .  83C0 02       add eax,0x2
004015E0   .  83C6 02       add esi,0x2
004015E3   .  84C9          test cl,cl
004015E5   .^ 75 DC         jnz XKeyGenMe.004015C3
004015E7   >  33C0          xor eax,eax
004015E9   .  EB 05         jmp XKeyGenMe.004015F0
004015EB   >  1BC0          sbb eax,eax
004015ED   .  83D8 FF       sbb eax,-0x1
004015F0   >  85C0          test eax,eax                             ;  如果eax等于 0,则跳转
004015F2   .  74 67         je XKeyGenMe.0040165B
004015F4   .  8D4424 0C     lea eax,dword ptr ss:[esp+0xC]
004015F8   .  50            push eax                                 ;  取密码
004015F9   .  E8 B2FEFFFF   call KeyGenMe.004014B0
004015FE   .  83C4 04       add esp,0x4
00401601   .  85C0          test eax,eax
00401603   .  74 66         je XKeyGenMe.0040166B                    ;  call结果为0则为不正确
00401605   .  8D4C24 0C     lea ecx,dword ptr ss:[esp+0xC]
00401609   .  51            push ecx
0040160A   .  E8 21FFFFFF   call KeyGenMe.00401530
0040160F   .  8D5424 1C     lea edx,dword ptr ss:[esp+0x1C]          ;  取用户名
00401613   .  8BF0          mov esi,eax
00401615   .  52            push edx                                 ;  传入 密码、用户名
00401616   .  E8 55FEFFFF   call KeyGenMe.00401470                   ;  F(用户名)
0040161B   .  05 8F020000   add eax,0x28F
00401620   .  B9 34120000   mov ecx,0x1234
00401625   .  99            cdq
00401626   .  F7F9          idiv ecx
00401628   .  B9 01000100   mov ecx,0x10001
0040162D   .  83C4 08       add esp,0x8
00401630   .  8BC2          mov eax,edx
00401632   .  0FAFC6        imul eax,esi                             ;  eax * 密码 = 10002
00401635   .  99            cdq
00401636   .  F7F9          idiv ecx
00401638   .  B8 01000000   mov eax,0x1
0040163D   .  2BC2          sub eax,edx                              ;  结果算出来edx等于1
0040163F   .  75 2A         jnz XKeyGenMe.0040166B
00401641   .  6A 00         push 0x0
00401643   .  68 60304000   push KeyGenMe.00403060                   ;  Good Work
00401648   .  68 38304000   push KeyGenMe.00403038                   ;  Serial is Correct!!!\nNow make a keygen
0040164D   .  8BCF          mov ecx,edi
0040164F   .  E8 38020000   call <jmp.&MFC42.#4224>
00401654   .  5F            pop edi
00401655   .  5E            pop esi
00401656   .  5B            pop ebx
00401657   .  83C4 2C       add esp,0x2C
0040165A   .  C3            retn
0040165B   >  6A 00         push 0x0
0040165D   .  6A 00         push 0x0
0040165F   .  68 24304000   push KeyGenMe.00403024                   ;  Insufficient Info
00401664   .  8BCF          mov ecx,edi
00401666   .  E8 21020000   call <jmp.&MFC42.#4224>
0040166B   >  5F            pop edi
0040166C   .  5E            pop esi
0040166D   .  5B            pop ebx
0040166E   .  83C4 2C       add esp,0x2C
00401671   .  C3            retn

跟入f(用户名):

00401470  /$  8B5424 04     mov edx,dword ptr ss:[esp+0x4]
00401474  |.  B8 9A020000   mov eax,0x29A
00401479  |.  8A0A          mov cl,byte ptr ds:[edx]                 ;  取首字符
0040147B  |.  84C9          test cl,cl
0040147D  |.  74 2E         je XKeyGenMe.004014AD                    ;  为空则直接退出call
0040147F  |.  56            push esi
00401480  |>  0FBEC9        /movsx ecx,cl
00401483  |.  8BF1          |mov esi,ecx
00401485  |.  81F6 DADA0000 |xor esi,0xDADA                          ;  字符与固定值异或
0040148B  |.  03F0          |add esi,eax                             ;  再加上固定值
0040148D  |.  8BC1          |mov eax,ecx                             ;  再取用户名的字符
0040148F  |.  35 BEBA0000   |xor eax,0xBABE
00401494  |.  81F1 01F00000 |xor ecx,0xF001
0040149A  |.  F7D0          |not eax
0040149C  |.  8D04B0        |lea eax,dword ptr ds:[eax+esi*4]
0040149F  |.  C1F8 03       |sar eax,0x3                             ;  算数右移
004014A2  |.  03C1          |add eax,ecx
004014A4  |.  8A4A 01       |mov cl,byte ptr ds:[edx+0x1]            ;  取下一个
004014A7  |.  42            |inc edx
004014A8  |.  84C9          |test cl,cl                              ;  是否已经迭代完毕
004014AA  |.^ 75 D4         \jnz XKeyGenMe.00401480
004014AC  |.  5E            pop esi
004014AD  \>  C3            retn

根据以上汇编代码,可以很容易地写出注册机。

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

void CKeygenDlg::OnBtnDecrypt() 
{
    // TODO: Add your control notification handler code here
    CString Name = "";
    GetDlgItemText( IDC_EDIT_NAME,Name );

    if ( Name.GetLength() == 0 ){
        MessageBox( "用户名不能为空!" );
        return ;
    }

    unsigned int ESI = 0;
    unsigned int a = 0x29A;
    unsigned int ECX = 0;
    for ( int i = 0 ; i != Name.GetLength() ; i++ ){
        ESI = (Name[i] ^ 0xDADA) + a;
        a = (Name[i] ^ 0xBABE);
        ECX = Name[i] ^ 0xF001;

        __asm{
            push eax

            mov eax,a
            not eax
            mov a,eax

            pop eax
        }
        
        a = a + ESI * 4;
        a = a>>3;
        a += ECX;
    }

    a = ( a + 0x28F ) % 0x1234;

    for ( int j = 1 ; j != 1000000 ; j++ )
        if ( (j*a) % 0x10001 == 1 )
            break;
         
    CString PassWord;
    PassWord.Format( "%x",j );
    SetDlgItemText( IDC_EDIT_SERIAL,PassWord );
}

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

运行效果: