• 标 题:斗地主4.0注册算法,注册机在OCG论坛 (22千字)
  • 作 者:heXer
  • 时 间:2002-4-18 21:02:35
  • 链 接:http://bbs.pediy.com

斗地主4.0注册算法分析

====================================================================================
004991B1                call    rtcRandomNext
004991B7                fmul    dbl_403920
004991BD                call    __vbaFpI4
004991C3                mov    dword_4D1030, eax            ;随机数R1
004991C8                lea    ecx, [ebp-98h]
004991CE                call    __vbaFreeVar
004991D4                mov    dword ptr [ebp-4], 0Eh
004991DB                mov    dword ptr [ebp-90h], 80020004h
004991E5                mov    dword ptr [ebp-98h], 0Ah
004991EF                lea    ecx, [ebp-98h]
004991F5                push    ecx
004991F6                call    rtcRandomize
004991FC                lea    ecx, [ebp-98h]
00499202                call    __vbaFreeVar
00499208                mov    dword ptr [ebp-4], 0Fh
0049920F                mov    dword ptr [ebp-90h], 3
00499219                mov    dword ptr [ebp-98h], 2
00499223                lea    edx, [ebp-98h]
00499229                push    edx
0049922A                call    rtcRandomNext
00499230                fmul    dbl_403920
00499236                call    __vbaFpI4
0049923C                mov    dword_4D1044, eax            ;随机数R2
00499241                lea    ecx, [ebp-98h]
00499247                call    __vbaFreeVar
0049924D                mov    dword ptr [ebp-4], 10h
00499254                mov    eax, dword_4D1030
00499259                xor    eax, 9DB7h
0049925E                mov    dword_4D11EC, eax            ;R3=R1 xor 9DB7h
00499263                mov    dword ptr [ebp-4], 11h
0049926A                mov    ecx, dword_4D1044
00499270                xor    ecx, 10A7Bh
00499276                mov    dword_4D10D8, ecx            ;R4=R2 xor 10A7Bh

====================================================================================
004BD57B                lea    ecx, [ebp-54h]
004BD57E                push    ecx
004BD57F                push    4
004BD581                lea    edx, [ebp-74h]
004BD584                push    edx
004BD585                lea    eax, [ebp-64h]
004BD588                push    eax
004BD589                mov    dword ptr [ebp-4Ch], 5
004BD590                mov    dword ptr [ebp-54h], 2
004BD597                mov    [ebp-6Ch], edi
004BD59A                mov    dword ptr [ebp-74h], 4008h
004BD5A1                call    rtcMidCharVar
004BD5A7                lea    ecx, [ebp-64h]                ;str1=机器码第4到8组成的5位字符串
004BD5AA                push    ecx
004BD5AB                lea    edx, [ebp-18h]
004BD5AE                push    edx
004BD5AF                call    __vbaStrVarVal
004BD5B5                push    eax                    ;str1
004BD5B6                call    sub_4A8290                ;H1 = invoke sub_4A8290 ,str1
004BD5BB                mov    ecx, dword_4D1030            ;R1
004BD5C1                xor    ecx, dword_4D11EC            ;ecx=R1 xor R3 = 9DB7h
004BD5C7                push    ecx                    ;9DB7h
004BD5C8                push    eax                    ;H1
004BD5C9                call    sub_4A83F0                ;X1 = invoke sub_4A83F0 ,H1,9DB7h
004BD5CE                mov    edx, [esi+48h]
004BD5D1                push    edx
004BD5D2                push    eax                    ;X1
004BD5D3                call    sub_4A83F0                ;
004BD5D8                lea    ecx, [ebp-18h]
004BD5DB                mov    [esi+34h], eax                ;A1 = invoke sub_4A83F0 ,X1,[esi+48h]

====================================================================================
004BDE78                lea    eax, [ebp-2Ch]
004BDE7B                push    eax
004BDE7C                lea    ecx, [ebp-3Ch]
004BDE7F                push    ecx
004BDE80                mov    dword ptr [ebp-2Ch], 9
004BDE87                call    edi ; rtcTrimVar
004BDE89                mov    edx, [esi+44h]
004BDE8C                push    5
004BDE8E                lea    eax, [ebp-0BCh]
004BDE94                push    eax
004BDE95                lea    ecx, [ebp-3Ch]                ;注册名
004BDE98                mov    [ebp-0B4h], edx
004BDE9E                push    ecx
004BDE9F                lea    edx, [ebp-4Ch]                ;机器码的右3位
004BDEA2                push    edx
004BDEA3                mov    dword ptr [ebp-0BCh], 8
004BDEAD                call    __vbaVarCat                ;str0=机器码的右3位 + 注册名
004BDEB3                push    eax
004BDEB4                lea    eax, [ebp-5Ch]
004BDEB7                push    eax
004BDEB8                call    rtcRightCharVar
004BDEBE                lea    ecx, [ebp-5Ch]                ;str2=str0的右5位
004BDEC1                push    ecx
004BDEC2                lea    edx, [ebp-18h]
004BDEC5                push    edx
004BDEC6                call    __vbaStrVarVal
004BDECC                push    eax                    ;str2
004BDECD                call    sub_4A8290                ;H2 = invoke sub_4A8290 ,str2
004BDED2                mov    ecx, dword_4D1044            ;R2
004BDED8                xor    ecx, dword_4D10D8            ;ecx=R2 xor R4 = 10A7Bh
004BDEDE                push    ecx                    ;10A7Bh
004BDEDF                push    eax                    ;H2
004BDEE0                call    sub_4A83F0                ;X2 = invoke sub_4A83F0 ,H2,10A7Bh
004BDEE5                mov    edx, [esi+4Ch]
004BDEE8                push    edx
004BDEE9                push    eax                    ;X2
004BDEEA                call    sub_4A83F0                ;
004BDEEF                lea    ecx, [ebp-18h]
004BDEF2                mov    [esi+38h], eax                ;A2 = invoke sub_4A83F0 ,X2,[esi+4Ch]

====================================================================================
004BD9B2                lea    edx, [ebp-28h]
004BD9B5                mov    [ebp-20h], eax
004BD9B8                push    edx
004BD9B9                lea    eax, [ebp-38h]
004BD9BC                push    eax
004BD9BD                mov    dword ptr [ebp-28h], 9
004BD9C4                call    edi ; rtcTrimVar
004BD9C6                push    5
004BD9C8                lea    ecx, [ebp-38h]                ;SN = 输入的注册码
004BD9CB                push    ecx
004BD9CC                lea    edx, [ebp-48h]
004BD9CF                push    edx
004BD9D0                call    rtcLeftCharVar
004BD9D6                mov    eax, [esi+48h]
004BD9D9                push    eax
004BD9DA                lea    ecx, [ebp-48h]                ;snl5 = SN 的前5位
004BD9DD                push    ecx
004BD9DE                call    __vbaI4ErrVar
004BD9E4                push    eax                    ;Y1 = hex(snl5)
004BD9E5                call    sub_4A83F0                ;
004BD9EA                lea    edx, [ebp-48h]
004BD9ED                push    edx
004BD9EE                mov    [esi+3Ch], eax                ;B1 = invoke sub_4A83F0 ,Y1,[esi+48h]

====================================================================================
004BDAE5                lea    ecx, [ebp-28h]
004BDAE8                push    ecx
004BDAE9                lea    edx, [ebp-38h]
004BDAEC                push    edx
004BDAED                mov    [ebp-20h], eax
004BDAF0                mov    dword ptr [ebp-28h], 9
004BDAF7                call    edi ; rtcTrimVar
004BDAF9                push    5
004BDAFB                lea    eax, [ebp-38h]                ;SN = 输入的注册码
004BDAFE                push    eax
004BDAFF                lea    ecx, [ebp-48h]
004BDB02                push    ecx
004BDB03                call    rtcRightCharVar
004BDB09                mov    edx, [esi+4Ch]
004BDB0C                push    edx
004BDB0D                lea    eax, [ebp-48h]                ;snr5 = SN 的后5位
004BDB10                push    eax
004BDB11                call    __vbaI4ErrVar
004BDB17                push    eax                    ;Y2 = hex(snr5)
004BDB18                call    sub_4A83F0                ;
004BDB1D                lea    ecx, [ebp-48h]
004BDB20                push    ecx
004BDB21                lea    edx, [ebp-48h]
004BDB24                push    edx
004BDB25                mov    [esi+40h], eax                ;B2 = invoke sub_4A83F0 ,Y2,[esi+4Ch]

====================================================================================
004BCAAC                mov    eax, [esi+3Ch]
004BCAAF                mov    ecx, [esi+40h]
004BCAB2                mov    edx, dword_4D1030
004BCAB8                add    esp, 1Ch
004BCABB                mov    [ebp-0C4h], eax
004BCAC1                mov    [ebp-0C8h], ecx
004BCAC7                push    edx                    ;R1
004BCAC8                push    eax                    ;B1
004BCAC9                call    sub_4A83F0                ;
004BCACE                mov    ecx, [ebp-0C8h]
004BCAD4                mov    [esi+3Ch], eax                ;N1 = invoke sub_4A83F0 ,B1,R1
004BCAD7                mov    eax, dword_4D1044
004BCADC                push    eax                    ;R2
004BCADD                push    ecx                    ;B2
004BCADE                call    sub_4A83F0                ;
004BCAE3                mov    [esi+40h], eax                ;N2 = invoke sub_4A83F0 ,B2,R2
004BCAE6                call    rtcGetTimer
004BCAEC                fsub    dword ptr [esi+50h]
004BCAEF                fcomp  flt_403914
004BCAF5                fnstsw  ax
004BCAF7                test    ah, 41h
004BCAFA                jnz    short loc_4BCB52
004BCAFC                cmp    dword_4D1F98, edi
004BCB02                jnz    short loc_4BCB14
004BCB04                push    offset dword_4D1F98
004BCB09                push    offset dword_416764
004BCB0E                call    __vbaNew2
004BCB14
004BCB14 loc_4BCB14:
004BCB14                mov    edi, dword_4D1F98
004BCB1A                mov    ebx, [edi]
004BCB1C                push    esi
004BCB1D                lea    edx, [ebp-34h]
004BCB20                push    edx
004BCB21                call    __vbaObjSetAddref
004BCB27                push    eax
004BCB28                push    edi
004BCB29                call    dword ptr [ebx+10h]
004BCB2C                fnclex
004BCB2E                test    eax, eax
004BCB30                jge    short loc_4BCB41
004BCB32                push    10h
004BCB34                push    offset dword_416754
004BCB39                push    edi
004BCB3A                push    eax
004BCB3B                call    __vbaHresultCheckObj
004BCB41
004BCB41 loc_4BCB41:
004BCB41                lea    ecx, [ebp-34h]
004BCB44                call    __vbaFreeObj
004BCB4A                mov    ebx, __vbaStrMove
004BCB50                xor    edi, edi
004BCB52
004BCB52 loc_4BCB52:
004BCB52                mov    eax, [esi+40h]
004BCB55                mov    ecx, [esi+3Ch]
004BCB58                mov    edx, [esi+38h]
004BCB5B                push    eax                    ;arg_C = N2
004BCB5C                mov    eax, [esi+34h]
004BCB5F                push    ecx                    ;arg_8 = N1
004BCB60                push    edx                    ;arg_4 = A2
004BCB61                push    eax                    ;arg_0 = A1
004BCB62                call    sub_4A8060                ;这个call是比较的核心
004BCB67                test    ax, ax                    ;返回ax=0则注册失败
004BCB6A                jz      loc_4BCDC4


====================================================================================
004A8060                push    ebp
004A8061                mov    ebp, esp
004A8063                sub    esp, 8
004A8066                push    offset loc_404806
004A806B                mov    eax, large fs0
004A8071                push    eax
004A8072                mov    large fs0, esp
004A8079                sub    esp, 34h
004A807C                push    ebx
004A807D                push    esi
004A807E                push    edi
004A807F                mov    [ebp+var_8], esp
004A8082                mov    [ebp+var_4], offset dword_403928
004A8089                mov    ecx, [ebp+arg_0]            ;A1
004A808C                xor    eax, eax
004A808E                mov    [ebp+var_2C], eax
004A8091                mov    [ebp+var_40], eax
004A8094                mov    [ebp+var_1C], eax
004A8097                mov    eax, dword_4D1030            ;R1
004A809C                push    eax                    ;R1
004A809D                push    ecx                    ;A1
004A809E                call    sub_4A83F0                ;
004A80A3                mov    edx, dword_4D1044            ;R2
004A80A9                mov    [ebp+arg_0], eax            ;M1 = invoke sub_4A83F0 ,A1,R1
004A80AC                mov    eax, [ebp+arg_4]            ;A2
004A80AF                push    edx                    ;R2
004A80B0                push    eax                    ;A2
004A80B1                call    sub_4A83F0                ;
004A80B6                mov    ecx, [ebp+arg_0]            ;M1
004A80B9                mov    edx, [ebp+arg_8]            ;N1
004A80BC                add    edx, ecx                ;M1+N1
004A80BE                add    ecx, ecx                ;M1+M1
004A80C0                cmp    ecx, edx                ;M1+N1 =? M1+M1 等效为N1 =? M1
004A80C2                mov    [ebp+arg_4], eax            ;M2 = invoke sub_4A83F0 ,A2,R2
004A80C5                jnz    short loc_4A80E6
004A80C7                mov    edx, [ebp+arg_C]            ;N2
004A80CA                lea    ecx, [eax+edx]                ;M2+N2
004A80CD                lea    edx, [eax+eax]                ;M2+M2
004A80D0                cmp    ecx, edx                ;M2+N2 =? M2+M2 等效为N2 =? M2
004A80D2                jnz    short loc_4A80E6
004A80D4                mov    [ebp+var_1C], 0FFFFFFFFh        ;到这里置注册成功标志

=========================sub_4A8290======================================
004A8290                push    ebp
004A8291                mov    ebp, esp
004A8293                sub    esp, 8
004A8296                push    offset loc_404806
004A829B                mov    eax, large fs0
004A82A1                push    eax
004A82A2                mov    large fs0, esp
004A82A9                sub    esp, 70h
004A82AC                push    ebx
004A82AD                push    esi
004A82AE                push    edi
004A82AF                mov    [ebp+var_8], esp
004A82B2                mov    [ebp+var_4], offset dword_403938
004A82B9                mov    edx, [ebp+arg_0]            ;5位的str,(都是WideChar)
004A82BC                xor    esi, esi
004A82BE                lea    ecx, [ebp+var_18]
004A82C1                mov    [ebp+var_18], esi
004A82C4                mov    [ebp+var_28], esi
004A82C7                mov    [ebp+var_38], esi
004A82CA                mov    [ebp+var_48], esi
004A82CD                mov    [ebp+var_58], esi
004A82D0                call    __vbaStrCopy
004A82D6                mov    edi, 1
004A82DB                mov    [ebp+var_24], esi
004A82DE                mov    ebx, edi
004A82E0                mov    esi, edi                ;第n位WideChar
004A82E2 loc_4A82E2:
004A82E2                mov    eax, 5                    ;循环5次
004A82E7                cmp    esi, eax
004A82E9                jg      loc_4A839D
004A82EF                lea    ecx, [ebp+var_38]
004A82F2                push    ecx
004A82F3                lea    eax, [ebp+var_18]
004A82F6                push    edi
004A82F7                lea    edx, [ebp+var_58]
004A82FA                mov    [ebp+var_50], eax
004A82FD                push    edx
004A82FE                lea    eax, [ebp+var_48]
004A8301                push    eax
004A8302                mov    [ebp+var_30], 1
004A8309                mov    [ebp+var_38], 2            
004A8310                mov    [ebp+var_58], 4008h
004A8317                call    rtcMidCharVar
004A831D                lea    ecx, [ebp+var_48]            ;取出一位WideChar
004A8320                push    ecx
004A8321                lea    edx, [ebp+var_28]
004A8324                push    edx
004A8325                call    __vbaStrVarVal
004A832B                push    eax
004A832C                call    rtcByteValueBstr            ;
004A8332                mov    byte ptr [ebp+var_6C], al        ;只保留WideChar的低字节
004A8335                mov    eax, 5
004A833A                sub    eax, esi
004A833C                mov    [ebp+var_7C], eax            ;5-n
004A833F                fild    [ebp+var_7C]
004A8342                sub    esp, 8
004A8345                fstp    [esp]
004A8348                push    40240000h                ;浮点数10
004A834D                push    0
004A834F                call    __vbaPowerR8                ;10^(5-n)
004A8355                mov    eax, [ebp+var_6C]            ;每位WideChar的低字节
004A8358                and    eax, 0FFh
004A835D                cdq
004A835E                mov    ecx, 0Ah
004A8363                idiv    ecx
004A8365                mov    [ebp+var_80], edx            ;r = 每位WideChar的低字节mod 10
004A8368                fild    [ebp+var_80]
004A836B                fmulp  st(1), st                ;r*10^(5-n)
004A836D                fiadd  [ebp+var_24]                ;循环相加
004A8370                call    __vbaFpI4
004A8376                lea    ecx, [ebp+var_28]
004A8379                mov    [ebp+var_24], eax            ;经5次循环后,H = r1*10^4+r2*10^3+r3*10^2+r4*10+r5
004A837C                call    __vbaFreeStr
004A8382                lea    edx, [ebp+var_48]
004A8385                push    edx
004A8386                lea    eax, [ebp+var_38]
004A8389                push    eax
004A838A                push    2
004A838C                call    __vbaFreeVarList
004A8392                add    esp, 0Ch
004A8395                inc    edi
004A8396                add    esi, ebx
004A8398                jmp    loc_4A82E2
004A839D loc_4A839D:
004A839D                wait
004A839E                push    offset loc_4A83CC
004A83A3                jmp    short loc_4A83C2
004A83A5                lea    ecx, [ebp-28h]
004A83A8                call    __vbaFreeStr
004A83AE                lea    ecx, [ebp-48h]
004A83B1                push    ecx
004A83B2                lea    edx, [ebp-38h]
004A83B5                push    edx
004A83B6                push    2
004A83B8                call    __vbaFreeVarList
004A83BE                add    esp, 0Ch
004A83C1                retn
004A83C2 loc_4A83C2:
004A83C2                lea    ecx, [ebp+var_18]
004A83C5                call    __vbaFreeStr
004A83CB                retn
004A83CC loc_4A83CC:
004A83CC                mov    ecx, [ebp-10h]
004A83CF                mov    eax, [ebp-24h]                ;返回值H
004A83D2                pop    edi
004A83D3                pop    esi
004A83D4                mov    large fs0, ecx
004A83DB                pop    ebx
004A83DC                mov    esp, ebp
004A83DE                pop    ebp
004A83DF sub_4A8290      endp

=========================sub_4A83F0======================================
004A83F0 sub_4A83F0      proc near
004A83F0 arg_0          = dword ptr  4
004A83F0 arg_4          = dword ptr  8
004A83F0                mov    ecx, [esp+arg_0]
004A83F4                xor    ecx, [esp+arg_4]
004A83F8                cmp    ecx, 1869Fh            ;99999
004A83FE                jle    short loc_4A8413
004A8400                mov    eax, 66666667h
004A8405                imul    ecx
004A8407                mov    ecx, edx
004A8409                sar    ecx, 2
004A840C                mov    eax, ecx
004A840E                shr    eax, 1Fh
004A8411                add    ecx, eax
004A8413 loc_4A8413:
004A8413                cmp    ecx, 2710h
004A8419                jge    short loc_4A8421
004A841B                add    ecx, 2710h            ;10000
004A8421 loc_4A8421:
004A8421                mov    eax, ecx            ;返回一个10000到99999之间的10进制5位数
004A8423                retn    8
004A8423 sub_4A83F0      endp
======================================================================================================


把上面过程可以整理成如下四个步骤:

====步骤1:==========================================================================================
                                                                        H1 = invoke sub_4A8290 ,str1
                                                X1 = invoke sub_4A83F0 ,H1,9DB7h
                        A1 = invoke sub_4A83F0 ,X1,[esi+48h]
M1 = invoke sub_4A83F0 ,A1,R1
====================================================================================================

====步骤2:==========================================================================================
                        B1 = invoke sub_4A83F0 ,Y1,[esi+48h]
N1 = invoke sub_4A83F0 ,B1,R1
====================================================================================================

====步骤3:==========================================================================================
                                                                        H2 = invoke sub_4A8290 ,str2
                                                X2 = invoke sub_4A83F0 ,H2,10A7Bh
                        A2 = invoke sub_4A83F0 ,X2,[esi+4Ch]
M2 = invoke sub_4A83F0 ,A2,R2
====================================================================================================

====步骤4:==========================================================================================
                        B2 = invoke sub_4A83F0 ,Y2,[esi+4Ch]
N2 = invoke sub_4A83F0 ,B2,R2
====================================================================================================
注册成功的条件是: M1=N1,M2=N2
从而只要满足充分条件:
    (1) Y1=X1=invoke sub_4A83F0 ,H1,9DB7h
                            其中H1=invoke sub_4A8290 ,str1
                                                      str1=机器码第4到8位

    (2) Y2=X2=invoke sub_4A83F0 ,H2,10A7Bh
                            其中H2=invoke sub_4A8290 ,str2
                                                      str2=(机器码的右3位+注册名)的右5位
===================================================================================================
将Y1转换成10进制得到注册码的前5位
将Y2转换成10进制得到注册码的后5位
===================================================================================================

总结:本注册算法并不复杂,只是VB的程序有些烦人,尤其是unicode字符看起来很不习惯
    注册机比较容易做,由于我未曾编过WideChar的程序,开始时在WideChar的处理上遇到一点障碍,
    无法注册中文用户名,经反复调试修改现已克服。

===============================heXer/OCG==========2002.04.18=======================================