好友
阅读权限 40
听众
最后登录 1970-1-1
软件作者采用假注册的方式来保护软件,注册过程的算法是假算法,能注册成功,但有水印。重启验证过程算法为真算法。
下面直接到算法段。
【详细过程】
下面是重启后的验证段。比较标志位,
004CDCED8BDAmov ebx, edx
004CDCEF8945 FC mov dword ptr [ebp-4], eax
004CDCF28B45 FC mov eax, dword ptr [ebp-4]
004CDCF5E8 A276F3FF call0040539C
004CDCFA33C0xor eax, eax
004CDCFC55pushebp
004CDCFD68 7EDD4C00 push004CDD7E
004CDD0264:FF30 pushdword ptr fs:[eax]
004CDD0564:8920 mov dword ptr fs:[eax], esp
004CDD088B45 FC mov eax, dword ptr [ebp-4]
004CDD0BBA 94DD4C00 mov edx, 004CDD94;
004CDD10E8 E375F3FF call004052F8
004CDD1575 24 jnz short 004CDD3B
004CDD178B0D D0905700 mov ecx, dword ptr [5790D0]
004CDD1D8B15 CC905700 mov edx, dword ptr [5790CC]
004CDD23B8 CCDD4C00 mov eax, 004CDDCC; picalbum
004CDD28E8 93FBFFFF call004CD8C0 // 验证算法,F7进入。
===============================================================================================
004CD8C055pushebp
004CD8C18BECmov ebp, esp
004CD8C351pushecx
004CD8C4B9 12000000 mov ecx, 12
004CD8C96A 00 push0
004CD8CB6A 00 push0
004CD8CD49dec ecx
004CD8CE^ 75 F9 jnz short 004CD8C9
004CD8D0874D FC xchgdword ptr [ebp-4], ecx
004CD8D353pushebx
004CD8D456pushesi
004CD8D557pushedi
004CD8D6894D F4 mov dword ptr [ebp-C], ecx
004CD8D98955 F8 mov dword ptr [ebp-8], edx
004CD8DC8945 FC mov dword ptr [ebp-4], eax
004CD8DF8B45 FC mov eax, dword ptr [ebp-4]
004CD8E2E8 B57AF3FF call0040539C
004CD8E78B45 F8 mov eax, dword ptr [ebp-8]
004CD8EAE8 AD7AF3FF call0040539C
004CD8EF8B45 F4 mov eax, dword ptr [ebp-C]
004CD8F2E8 A57AF3FF call0040539C
004CD8F733C0xor eax, eax
004CD8F955pushebp
004CD8FA68 CADC4C00 push004CDCCA
004CD8FF64:FF30 pushdword ptr fs:[eax]
004CD90264:8920 mov dword ptr fs:[eax], esp
004CD9058D55 90 lea edx, dword ptr [ebp-70]
004CD9088B45 F4 mov eax, dword ptr [ebp-C]
004CD90BE8 9CBCF3FF call004095AC
004CD9108B55 90 mov edx, dword ptr [ebp-70]
004CD9138D45 F4 lea eax, dword ptr [ebp-C]
004CD916E8 7976F3FF call00404F94
004CD91B8B45 F4 mov eax, dword ptr [ebp-C]
004CD91EE8 9178F3FF call004051B4
004CD92383F8 17 cmp eax, 17 //看是不是23位的注册码。不是就over。
004CD92674 07 jeshort 004CD92F
004CD92833DBxor ebx, ebx
004CD92AE9 70030000 jmp 004CDC9F
004CD92FC645 97 50mov byte ptr [ebp-69], 50
004CD933C645 98 39mov byte ptr [ebp-68], 39
004CD937C645 99 43mov byte ptr [ebp-67], 43
004CD93BC645 9A 38mov byte ptr [ebp-66], 38
004CD93FC645 9B 55mov byte ptr [ebp-65], 55
004CD943C645 9C 37mov byte ptr [ebp-64], 37
004CD947C645 9D 45mov byte ptr [ebp-63], 45
004CD94BC645 9E 36mov byte ptr [ebp-62], 36
004CD94FC645 9F 48mov byte ptr [ebp-61], 48
004CD953C645 A0 35mov byte ptr [ebp-60], 35
004CD957C645 A1 55mov byte ptr [ebp-5F], 55
004CD95BC645 A2 34mov byte ptr [ebp-5E], 34
004CD95FC645 A3 49mov byte ptr [ebp-5D], 49
004CD963C645 A4 33mov byte ptr [ebp-5C], 33
004CD967C645 A5 47mov byte ptr [ebp-5B], 47
004CD96BC645 A6 32mov byte ptr [ebp-5A], 32//固定串“P9C8U7E6H5U4I3G2”
004CD96F33DBxor ebx, ebx
004CD9718D45 AC lea eax, dword ptr [ebp-54]
004CD97469D3 89000000 imuledx, ebx, 89 //89*(0...16)
004CD97A8910mov dword ptr [eax], edx//乘积分别放置,好与下面的相加。
004CD97C43inc ebx//计数器加一
004CD97D83C0 04 add eax, 4
004CD98083FB 10 cmp ebx, 10 //看到没到16
004CD983^ 75 EF jnz short 004CD974
004CD9858D55 F0 lea edx, dword ptr [ebp-10]
004CD9888B45 F8 mov eax, dword ptr [ebp-8]
004CD98BE8 1CBCF3FF call004095AC
004CD9908B45 F0 mov eax, dword ptr [ebp-10]
004CD993E8 1C78F3FF call004051B4
004CD9988BF8mov edi, eax
004CD99A83FF 01 cmp edi, 1 //注册名位数与1比较
004CD99D7D 07 jge short 004CD9A6
004CD99F33DBxor ebx, ebx
004CD9A1E9 F9020000 jmp 004CDC9F
004CD9A683FF 10 cmp edi, 10 // 位数大不大于16,
004CD9A97D 25 jge short 004CD9D0
004CD9AB8D55 8C lea edx, dword ptr [ebp-74]
004CD9AE8B45 F8 mov eax, dword ptr [ebp-8]
004CD9B1E8 F6BBF3FF call004095AC
004CD9B68B55 8C mov edx, dword ptr [ebp-74]
004CD9B98D45 F0 lea eax, dword ptr [ebp-10]
004CD9BCE8 FB77F3FF call004051BC //重复追加注册名
004CD9C18B45 F0 mov eax, dword ptr [ebp-10]
004CD9C4E8 EB77F3FF call004051B4
004CD9C98BF8mov edi, eax
004CD9CB83FF 10 cmp edi, 10
004CD9CE^ 7C DB jlshort 004CD9AB//位数小于16就循环追加
004CD9D033F6xor esi, esi
004CD9D28B45 FC mov eax, dword ptr [ebp-4]
004CD9D5E8 DA77F3FF call004051B4
004CD9DA85C0testeax, eax
004CD9DC7E 13 jle short 004CD9F1
004CD9DEBB 01000000 mov ebx, 1
004CD9E38B55 FC mov edx, dword ptr [ebp-4]
004CD9E60FB6541A FF movzx edx, byte ptr [edx+ebx-1]
004CD9EB03F2add esi, edx
004CD9ED43inc ebx
004CD9EE48dec eax
004CD9EF^ 75 F2 jnz short 004CD9E3//求 “PicAlbum ”字符的十六进制数加和
004CD9F18BC7mov eax, edi
004CD9F385C0testeax, eax
004CD9F57E 13 jle short 004CDA0A
004CD9F7BB 01000000 mov ebx, 1
004CD9FC8B55 F0 mov edx, dword ptr [ebp-10]
004CD9FF0FB6541A FF movzx edx, byte ptr [edx+ebx-1]
004CDA0403F2add esi, edx
004CDA0643inc ebx
004CDA0748dec eax
004CDA08^ 75 F2 jnz short 004CD9FC//求 注册名 字符的十六进制数加和
004CDA0A8BC7mov eax, edi
004CDA0C48dec eax
004CDA0D85C0testeax, eax
004CDA0F7C 40 jlshort 004CDA51
004CDA1140inc eax
004CDA1233DBxor ebx, ebx
004CDA148B55 F0 mov edx, dword ptr [ebp-10]
004CDA178A141Amov dl, byte ptr [edx+ebx]
004CDA1A81E2 FF000000 and edx, 0FF
004CDA208BCBmov ecx, ebx
004CDA2281E1 0F000080 and ecx, 8000000F
004CDA2879 05 jns short 004CDA2F
004CDA2A49dec ecx
004CDA2B83C9 F0 orecx, FFFFFFF0
004CDA2E41inc ecx
004CDA2F0FB64C0D 97 movzx ecx, byte ptr [ebp+ecx-69]
004CDA340FAFD1imuledx, ecx
004CDA370FAFD6imuledx, esi
004CDA3A8BCBmov ecx, ebx
004CDA3C81E1 0F000080 and ecx, 8000000F
004CDA4279 05 jns short 004CDA49
004CDA4449dec ecx
004CDA4583C9 F0 orecx, FFFFFFF0
004CDA4841inc ecx
004CDA4901548D AC add dword ptr [ebp+ecx*4-54], edx
004CDA4D43inc ebx
004CDA4E48dec eax
004CDA4F^ 75 C3 jnz short 004CDA14
004CDA51BB 10000000 mov ebx, 10
004CDA568D4D AC lea ecx, dword ptr [ebp-54]
004CDA598D75 97 lea esi, dword ptr [ebp-69]
004CDA5C8B01mov eax, dword ptr [ecx]
004CDA5EBF FF010000 mov edi, 1FF//edi赋值1FF
004CDA6399cdq
004CDA64F7FFidivedi //eax除edi
004CDA666BC2 35 imuleax, edx, 35 // eax=余数*35
004CDA696BC0 59 imuleax, eax, 59 //eax=上面的结果再*59
004CDA6CBF 25000000 mov edi, 25 //edi赋值1FF
004CDA7199cdq //将EAX值带符号扩展到EDX
004CDA72F7FFidivedi // 除
004CDA748BFAmov edi, edx //余数给edi
004CDA768939mov dword ptr [ecx], edi// 余数给指定地址
004CDA7883FF 24 cmp edi, 24 //与24比较
004CDA7B75 06 jnz short 004CDA83//不等则跳
004CDA7DC701 12000000 mov dword ptr [ecx], 12//等于就赋值12
004CDA838B01mov eax, dword ptr [ecx]//不等到这里 指定地址的结果给eax
004CDA8583F8 0A cmp eax, 0A //与A比较
004CDA887D 07 jge short 004CDA91 //大于等于就跳
004CDA8A83C0 30 add eax, 30 //小于到这里,eax+30
004CDA8D8806mov byte ptr [esi], al//结果保存
004CDA8FEB 08 jmp short 004CDA99
004CDA9183C0 41 add eax, 41 //大于等于到这里,eax+41
004CDA9483E8 0A sub eax, 0A //上面的结果再 eax -A
004CDA978806mov byte ptr [esi], al //结果保存
004CDA9946inc esi
004CDA9A83C1 04 add ecx, 4
004CDA9D4Bdec ebx
004CDA9E^ 75 BC jnz short 004CDA5C
004CDAA08D45 F0 lea eax, dword ptr [ebp-10]
004CDAA3E8 5474F3FF call00404EFC
004CDAA833F6xor esi, esi
004CDAAABB 04000000 mov ebx, 4
004CDAAF8D7D 97 lea edi, dword ptr [ebp-69] //获取刚才计算结果的地址
004CDAB233C0xor eax, eax
004CDAB48A07mov al, byte ptr [edi] //字符逐个给al
004CDAB6B9 0A000000 mov ecx, 0A //ecx赋值A
004CDABB33D2xor edx, edx
004CDABDF7F1div ecx//eax/ecx余数放在edx
004CDABF83C2 30 add edx, 30//余数+30这里得到分段注册码前四位数的十六进制数。
004CDAC28D45 88 lea eax, dword ptr [ebp-78]
004CDAC5E8 1276F3FF call004050DC
004CDACA8B55 88 mov edx, dword ptr [ebp-78]
004CDACD8D45 F0 lea eax, dword ptr [ebp-10]
004CDAD0E8 E776F3FF call004051BC
004CDAD533C0xor eax, eax
004CDAD78A07mov al, byte ptr [edi]//重新将刚才的字符给al 计算第5、10、15、20位
004CDAD98D0440lea eax, dword ptr [eax+eax*2]//eax=eax+eax*2
004CDADC03F0add esi, eax//将加和结果给esi
004CDADE47inc edi
004CDADF4Bdec ebx
004CDAE0^ 75 D0 jnz short 004CDAB2 //循环处理
004CDAE28BC6mov eax, esi //加和结果给eax,进行求余计算
004CDAE4B9 0A000000 mov ecx, 0A// ecx赋值A
004CDAE999cdq
004CDAEAF7F9idivecx//除
004CDAEC8BF2mov esi, edx//余数给esi
004CDAEE8D46 05 lea eax, dword ptr [esi+5]//eax=余数esi+5(这里与注册不同)
004CDAF1B9 0A000000 mov ecx, 0A// ecx赋值A
004CDAF699cdq
004CDAF7F7F9idivecx
004CDAF98BF2mov esi, edx //余数给esi
004CDAFBFF75 F0 pushdword ptr [ebp-10]
004CDAFE8D45 84 lea eax, dword ptr [ebp-7C]
004CDB018D56 30 lea edx, dword ptr [esi+30] //edx=esi+30 这里得到的是5、10、15、20位注册码的十六进制数。
004CDB04E8 D375F3FF call004050DC保存处理
004CDB09FF75 84 pushdword ptr [ebp-7C]
004CDB0C68 E4DC4C00 push004CDCE4 ; -
004CDB118D45 F0 lea eax, dword ptr [ebp-10]
004CDB14BA 03000000 mov edx, 3
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
中间省略
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
004CDC7B8D56 30 lea edx, dword ptr [esi+30]
004CDC7EE8 5974F3FF call004050DC
004CDC838B95 6CFFFFFF mov edx, dword ptr [ebp-94]
004CDC898D45 F0 lea eax, dword ptr [ebp-10]
004CDC8CE8 2B75F3FF call004051BC
004CDC918B45 F0 mov eax, dword ptr [ebp-10]
004CDC948B55 F4 mov edx, dword ptr [ebp-C]
004CDC97E8 5C76F3FF call004052F8
004CDC9C0F94C3setebl
004CDC9F33C0xor eax, eax
004CDCA15Apop edx
004CDCA259pop ecx
004CDCA359pop ecx
004CDCA464:8910 mov dword ptr fs:[eax], edx
004CDCA768 D1DC4C00 push004CDCD1
004CDCAC8D85 6CFFFFFF lea eax, dword ptr [ebp-94]
004CDCB2BA 0A000000 mov edx, 0A
004CDCB7E8 6472F3FF call00404F20
004CDCBC8D45 F0 lea eax, dword ptr [ebp-10]
004CDCBFBA 04000000 mov edx, 4
004CDCC4E8 5772F3FF call00404F20
004CDCC9C3retn
004CDCCA^ E9 D16BF3FF jmp 004048A0
004CDCCF^ EB DB jmp short 004CDCAC
004CDCD18BC3mov eax, ebx
004CDCD35Fpop edi
004CDCD45Epop esi
004CDCD55Bpop ebx
004CDCD68BE5mov esp, ebp
004CDCD85Dpop ebp
004CDCD9C3retn
--------------------------------------------------------------------------------
【经验总结】
算法为:注册名:lqiulu
if 注册名位数 <16
注册名+注册名 重复加 直到大于16位即:lqiululqiululqiulu
X=大于十六位的注册名 “lqiululqiululqiulu”
Y= (逐位取 X 字符的十六进制数) * (逐位 字值串“P9C8U7E6H5U4I3G2”十六进制数(不足位重复)) *(X+
“PicAlbum”十六进制字符)+(89H*(0..16))
Z=(((Y 求余 1FF)*35*59)求余25)
等于24赋值12
不等于24:
≥A(H):Z=Z+41-A(H)
<A(H): Z=Z+30
得到算出的数值。共16位。
即:用l的十六进制 6C*固定字串的第一个字符“P”50,*“PicAlbumlqiululqiululqiulu”字符十六进制数加和(30D+7D4
)=AE1,+89*0。即 :
Z=[((6C*50*AE1+0*89)MOD 1FF)*35*59]MOD 25
Z是否为24
是,赋值12
不是:看是否大于A
大于A:+41-A
小于A:+30
( Z MOD A )+30 得到第一位注册码的十六进制数,转换为字符就是注册码:2。这样只能得到注册码的 1、2、3、4
6、7、8、9、11、12、13、1416、17、18、19位 。少四位。就要用到新字串了。
得到16位新字串:ROA6 B1FY XS0N 29XD
四位一组十六进制加和[((X1+X1*2+X2+X2*2+X3+X3*2+X4+X4*2)MOD A )+5] MOD A +30 得到第5、10、15、20位的十
六进制数,转为字符就是注册码。
将以上连接为12345-12345-12345-12345的形式就OK了。
【delphi原码】
procedure TfmmakerKey.sbtCalcClick(Sender: TObject);
var
name,word,str1:string;
w,x,y,z,i,j,k,l,len,code:integer;
S0,s1,s2:array[1..32] of integer;
n,m:array[1..16] of longword;
begin
name:= edName.Text;
str1:='P9C8U7E6H5U4I3G2';
J:=0;
if edName.Text='' then
begin
ShowMessage('请输入注册名!!!');
exit;
end;
word:=name;
while length(word)< 16 do
begin
word:=word+ name;
end;
len:=length(word) ;
//对注册码进行处理
for i:=1 to len do
begin
j:=J+ORD(WORD[I]);
s0:=ord(WORD);
end;
J:=J+781;
//得到中间值
for i:=1 to len do
begin
if i<=16 then
begin
s1:=ORD(str1);
s2:=137*(i-1);
m:=s0*s1*J+s2;
end
else
begin
s1[i-16]:=ORD(str1[i-16]);
m[i-16]:=s0*s1[i-16]*J+ m[i-16];
end;
end;
//求注册码
for l:=1 to 16 do
n[l]:=((m[l] MOD 511)*53*89) MOD 37;
for l:=1 to 16 do
if n[l]>=10 then
n[l]:=n[l]+65-10
else
n[l]:=n[l] + 48;
//求注册码的其余几位
w:=0;
y:=0;
x:=0;
z:=0;
for i:=1 to 4 do
w:=w+ (n+ n *2);
for i:=5 to 8 do
x:=x+ (n+ n *2);
for i:=9 to 12 do
y:=y+ (n+ n *2);
for i:=13 to 16 do
z:=z+ (n+ n *2);
w:=(w mod 10 + 5 )mod 10 +48;
x:=(x mod 10 + 5 )mod 10 +48;
y:=(y mod 10 + 5 )mod 10 +48;
z:=(z mod 10 + 5 )mod 10 +48;
for k:=1 to 16 do
n[k]:= n[k] mod 10 +48;
//输出注册码
edCode.Text:=chr(n[1]) + chr(n[2]) + chr(n[3])+ chr(n[4]) +chr(w)+'-'+chr(n[5]) + chr(n[6]) + chr(n[7])+ chr(n[8]) +chr(x) + '-'+chr(n[9]) + chr(n[10]) + chr(n[11])+ chr(n[12]) +chr(y)+'-'+chr(n[13]) + chr(n[14]) + chr(n[15])+ chr(n[16]) +chr(z);
end;