首页
社区
课程
招聘
屏幕监视专家算法分析
发表于: 2005-3-23 14:00 3066

屏幕监视专家算法分析

2005-3-23 14:00
3066
主页http://www.tlxsoft.com/pmjszj/index.htm
版本:V2.1 Build20050322

验证注册的代码如下
......
.text:00423058                 mov     ecx, off_4A93D0
.text:0042305E                 push    dword ptr [ecx]
.text:00423060                 call    sub_4099E4   ;这里是验证的第一步
.text:00423065                 pop     ecx
.text:00423066                 cmp     al, 1
.text:00423068                 jnz     loc_4230F2   ;验证不成功就跳到失败,成功继续第二步
.text:0042306E                 mov     eax, off_4A93D0
.text:00423073                 push    dword ptr [eax]
.text:00423075                 call    sub_409A38   ;这里是验证的第二步
.text:0042307A                 pop     ecx
.text:0042307B                 cmp     al, 1
.text:0042307D                 jnz     short loc_4230F2  ;成功,继续
.text:0042307F                 mov     [ebp+var_24], 14h
.text:00423085                 mov     edx, offset aVSJ ; "注册成功"
......

下面来看第一步验证的算法

.text:004099E4 sub_4099E4      proc near               ; CODE XREF: sub_408378+C0p
.text:004099E4                                         ; sub_408378+2DFp ...
.text:004099E4
.text:004099E4 var_8           = dword ptr -8
.text:004099E4 var_4           = dword ptr -4
.text:004099E4 arg_0           = dword ptr  8
.text:004099E4
.text:004099E4                 push    ebp
.text:004099E5                 mov     ebp, esp
.text:004099E7                 add     esp, 0FFFFFFF8h
.text:004099EA                 xor     eax, eax
.text:004099EC                 mov     [ebp+var_8], eax
.text:004099EF                 xor     edx, edx
.text:004099F1                 mov     [ebp+var_4], edx
.text:004099F4
.text:004099F4 loc_4099F4:                             ; CODE XREF: sub_4099E4+28j
.text:004099F4                 mov     ecx, [ebp+arg_0]
.text:004099F7                 mov     eax, [ebp+var_4]
.text:004099FA                 movsx   edx, byte ptr [ecx+eax+445h] ; 指向注册码
.text:00409A02                 add     [ebp+var_8], edx
.text:00409A05                 inc     [ebp+var_4]
.text:00409A08                 cmp     [ebp+var_4], 13h ; 前19位注册码累加
.text:00409A0C                 jl      short loc_4099F4
.text:00409A0E                 mov     ecx, [ebp+arg_0]
.text:00409A11                 movsx   eax, byte ptr [ecx+458h] ;eax为第20位注册码
.text:00409A18                 add     eax, 0FFFFFFBFh       ;减去0x41
.text:00409A1B                 mov     [ebp+var_4], eax
.text:00409A1E                 mov     eax, [ebp+var_8]
.text:00409A21                 mov     ecx, 14h
.text:00409A26                 cdq
.text:00409A27                 idiv    ecx                ;除以0x14
.text:00409A29                 cmp     edx, [ebp+var_4] ;取余数进行对比
.text:00409A2C                 jnz     short loc_409A32
.text:00409A2E                 mov     al, 1
.text:00409A30                 jmp     short loc_409A34
.text:00409A32 loc_409A32:                             ; CODE XREF: sub_4099E4+48j
.text:00409A32                 xor     eax, eax
.text:00409A34
.text:00409A34 loc_409A34:                             ; CODE XREF: sub_4099E4+4Cj
.text:00409A34                 pop     ecx
.text:00409A35                 pop     ecx
.text:00409A36                 pop     ebp
.text:00409A37                 retn
.text:00409A37 sub_4099E4      endp
.text:00409A37
.text:00409A38

第一步验证仅对注册码进行,成功后进入第二步,加入机器码与用户名,如下

.text:00409A4D loc_409A4D:                             ; CODE XREF: sub_409A38+3Dj
.text:00409A4D                 mov     ecx, [ebp+var_30]
.text:00409A50                 mov     eax, [ebp+arg_0]
.text:00409A53                 mov     dl, [eax+ecx+430h] ; 取出用户名的一位
.text:00409A5A                 mov     ecx, [ebp+var_30]
.text:00409A5D                 mov     eax, [ebp+arg_0]
.text:00409A60                 xor     dl, [eax+ecx+46Fh] ; 与机器码的相应位进行异或
.text:00409A67                 mov     ecx, [ebp+var_30]
.text:00409A6A                 mov     [ebp+ecx+var_54], dl ; 异或后的值存在var_54中
.text:00409A6E                 inc     [ebp+var_30]
.text:00409A71                 cmp     [ebp+var_30], 14h   ; 进行20次
.text:00409A75                 jl      short loc_409A4D
.text:00409A77                 xor     edx, edx
.text:00409A79                 mov     [ebp+var_34], edx
.text:00409A7C                 xor     eax, eax
.text:00409A7E                 mov     [ebp+var_30], eax

.text:00409A81 loc_409A81:                             ; CODE XREF: sub_409A38+7Ej
.text:00409A81                 mov     edx, [ebp+var_30]
.text:00409A84                 movsx   ecx, [ebp+edx+var_54] ; 从var_54中取出异或后的值的一位
.text:00409A89                 mov     [ebp+var_58], ecx
.text:00409A8C                 fild    [ebp+var_58]
.text:00409A8F                 add     esp, 0FFFFFFF8h ; x
.text:00409A92                 fstp    [esp+60h+var_60]
.text:00409A95                 call    _fabs
.text:00409A9A                 add     esp, 8
.text:00409A9D                 fild    [ebp+var_30]  ;var30是当前循环次数
.text:00409AA0                 fmulp   st(1), st     ;取出的值与当前的循环数相乘
.text:00409AA2                 fild    [ebp+var_34]
.text:00409AA5                 faddp   st(1), st
.text:00409AA7                 call    @_ftol$qv       ; _ftol(void)
.text:00409AAC                 mov     [ebp+var_34], eax ;var34是累加和
.text:00409AAF                 inc     [ebp+var_30]    ;
.text:00409AB2                 cmp     [ebp+var_30], 14h
.text:00409AB6                 jl      short loc_409A81
.text:00409AB8                 add     [ebp+var_34], 0D431h ; 累加和+0xd431
.text:00409ABF                 xor     edx, edx
.text:00409AC1                 mov     [ebp+var_30], edx

.text:00409AC4 loc_409AC4:                             ; CODE XREF: sub_409A38+AAj
.text:00409AC4                 mov     ecx, [ebp+var_30]
.text:00409AC7                 mov     eax, [ebp+arg_0]
.text:00409ACA                 mov     dl, [eax+ecx+445h] ; 取出注册码的一位
.text:00409AD1                 add     dl, 0E7h           ; +0xe7
.text:00409AD4                 mov     ecx, [ebp+var_30]
.text:00409AD7                 mov     byte ptr [ebp+ecx+var_3C], dl
.text:00409ADB                 inc     [ebp+var_30]
.text:00409ADE                 cmp     [ebp+var_30], 5
.text:00409AE2                 jl      short loc_409AC4   ; 共取出前5位
.text:00409AE4                 mov     [ebp+var_37], 0
.text:00409AE8                 mov     eax, [ebp+var_34] ; var_34中为累加和
.text:00409AEB                 mov     edx, [ebp+arg_0]
.text:00409AEE                 mov     [edx+418h], eax
.text:00409AF4                 lea     eax, [ebp+var_8]
.text:00409AF7                 mov     edx, [ebp+var_34]
.text:00409AFA                 call    @System@WideString@$bctr$qqrul ; System::WideString::WideString(ulong)
.text:00409AFF                 push    eax
.text:00409B00                 inc     [ebp+var_10]
.text:00409B03                 mov     [ebp+var_1C], 8
.text:00409B09                 lea     edx, [ebp+var_3C]
.text:00409B0C                 lea     eax, [ebp+var_4]
.text:00409B0F                 call    sub_498F70
.text:00409B14                 inc     [ebp+var_10]
.text:00409B17                 pop     edx
.text:00409B18                 call    @System@AnsiString@$beql$xqqrrx17System@AnsiString ; System::AnsiString::operator==

(System::AnsiString &)
;这里可以看作,前5位注册码分别加0xe7,然后将累加和转化为5位十进制数的字符串,并比较两个字符串是否相同
.text:00409B1D                 push    eax            
.text:00409B1E                 dec     [ebp+var_10]
.text:00409B21                 lea     eax, [ebp+var_8]
.text:00409B24                 mov     edx, 2
.text:00409B29                 call    @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
.text:00409B2E                 dec     [ebp+var_10]
.text:00409B31                 lea     eax, [ebp+var_4]
.text:00409B34                 mov     edx, 2
.text:00409B39                 call    @System@AnsiString@$bdtr$qqrv ; System::AnsiString::~AnsiString(void)
.text:00409B3E                 pop     eax
.text:00409B3F                 test    al, al
.text:00409B41                 jz      short loc_409B51
.text:00409B43                 mov     al, 1
.text:00409B45                 mov     edx, [ebp+var_2C]
.text:00409B48                 mov     large fs:0, edx
.text:00409B4F                 jmp     short loc_409B5D

两步验证均通过,注册成功。
注册机算法如下,先根据机器码和用户名确定注册码的前5位,随后中间14位随机取,再根据这19位算出最后一位注册码:
        int        tmp1=0;
        int        tmp2=0;
        char sztmp[254]={0};//其实没必要这么大

        for(int i=0;i<20;i++)
        {
                sztmp[i]=name[i]^machine[i];
        }

        for(int i=0;i<20;i++)
        {
                tmp1+=sztmp[i]*i;
        }

        tmp1+=0xd431;
       
        wsprintf(sztmp,"%d",tmp1);

        for(int i=0;i<5;i++)
        {
                szCode[i]=sztmp[i]-0xe7;
                tmp2+=szCode[i];
        }

        for(int i=5;i<19;i++)
        {
                szCode[i]=(rand()%26+'A');
                tmp2+=szCode[i];
        }
        szCode[19]=(tmp2%0x14+0x41);//最后,szCode中存储正确的注册码

注册机就不在这里发了

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//