-
-
屏幕监视专家算法分析
-
发表于: 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中存储正确的注册码
注册机就不在这里发了
版本: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中存储正确的注册码
注册机就不在这里发了
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: