老文章档案 · 2003 年

豪杰超级解霸3000[英雄版] (15千字) 算法分析

赢政天下 [WINZHENG.COM] · 网络学院 · 2003-08-05 · 作者:hoto 人气: · 出处:赢政天下整理收藏)

看见有朋友分析了一下XXXXX3000英雄版的注册码的比较过程的分析,就想也分析一下,写出它的注册码的生成的算法过程,也写了一个注册机。

所用工具:TRW2000,W32DASM

Referenced by a CALL at Addresses:

|:00401C93 , :00401EF9

|

:00402840 83EC20 sub esp, 00000020

:00402843 56 push esi

:00402844 57 push edi

:00402845 B908000000 mov ecx, 00000008

:0040284A 33C0 xor eax, eax

:0040284C 8D7C2408 lea edi, dword ptr [esp+08]<----存入第一组注册码的局部变量,以下记为reg1,是一个DWORD类型,也可以看成4个字符形式。

:00402850 F3 repz

:00402851 AB stosd

:00402852 8B44242C mov eax, dword ptr [esp+2C] <----得到用户名的地址

:00402856 50 push eax <----将用户名作为参数传入

:00402857 E8B4010000 call 00402A10 <----此CALL(记为CALL 1)内将用户名进行变化后在EAX以长整数返回,按F8进入.

:0040285C 83C404 add esp, 00000004

:0040285F 89442408 mov dword ptr [esp+08], eax <----将返回的值放入reg1中

:00402863 33F6 xor esi, esi

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402888(C)

|

:00402865 0FBE443408 movsx eax, byte ptr [esp+esi+08]

:0040286A 83F841 cmp eax, 00000041

:0040286D 7C08 jl 00402877

:0040286F 83F85A cmp eax, 0000005A

:00402872 7F03 jg 00402877

:00402874 83C020 add eax, 00000020 <---- 如果是大写的,则变为小写。

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:0040286D(C), :00402872(C)

|

:00402877 50 push eax

:00402878 E863020000 call 00402AE0 <---- 将EAX 转化为一个字符。(记为CALL 3)

:0040287D 83C404 add esp, 00000004

:00402880 88443408 mov byte ptr [esp+esi+08], <----保存这个字符到reg1中。

:00402884 46 inc esi

:00402885 83FE04 cmp esi, 00000004

:00402888 7CDB jl 00402865 <----是否完成第一组

:0040288A 8B7C2430 mov edi, dword ptr [esp+30]

:0040288E 8D4C2408 lea ecx, dword ptr [esp+08]

:00402892 8BF7 mov esi, edi

:00402894 33D2 xor edx, edx

:00402896 2BF1 sub esi, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004028BC(C)

|

:00402898 8D4C1408 lea ecx, dword ptr [esp+edx+08]

:0040289C 0FBE040E movsx eax, byte ptr [esi+ecx]

:004028A0 83F841 cmp eax, 00000041

:004028A3 7C08 jl 004028AD

:004028A5 83F85A cmp eax, 0000005A

:004028A8 7F03 jg 004028AD

:004028AA 83C020 add eax, 00000020

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:004028A3(C), :004028A8(C)

|

:004028AD 0FBE09 movsx ecx, byte ptr [ecx]

:004028B0 3BC1 cmp eax, ecx <----比较第一组注册码

:004028B2 0F8520010000 jne 004029D8

:004028B8 42 inc edx

:004028B9 83FA04 cmp edx, 00000004

:004028BC 7CDA jl 00402898

:004028BE 8B442408 mov eax, dword ptr [esp+08]

:004028C2 8D1480 lea edx, dword ptr [eax+4*eax]

:004028C5 8D0450 lea eax, dword ptr [eax+2*edx]

:004028C8 03C0 add eax, eax

:004028CA 33F6 xor esi, esi

:004028CC 8944240C mov dword ptr [esp+0C], eax <----将reg1的值进行第二次变化.放入第二个地址中,以下记为reg2, reg2 = reg1 *22;

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004028F1(C)

|

:004028D0 8A4C340C mov cl, byte ptr [esp+esi+0C]

:004028D4 51 push ecx

:004028D5 56 push esi

:004028D6 E815010000 call 004029F0

:004028DB 25FF000000 and eax, 000000FF

:004028E0 50 push eax

:004028E1 E8FA010000 call 00402AE0 <----转化成第二组注册码

:004028E6 83C40C add esp, 0000000C

:004028E9 8844340C mov byte ptr [esp+esi+0C], al

:004028ED 46 inc esi

:004028EE 83FE04 cmp esi, 00000004

:004028F1 7CDD jl 004028D0

:004028F3 33C9 xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402918(C)

|

:004028F5 0FBE440F05 movsx eax, byte ptr [edi+ecx+05]

:004028FA 83F841 cmp eax, 00000041

:004028FD 7C08 jl 00402907

:004028FF 83F85A cmp eax, 0000005A

:00402902 7F03 jg 00402907

:00402904 83C020 add eax, 00000020

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:004028FD(C), :00402902(C)

|

:00402907 0FBE540C0C movsx edx, byte ptr [esp+ecx+0C]

:0040290C 3BC2 cmp eax, edx <----比较第二组注册码

:0040290E 0F85C4000000 jne 004029D8

:00402914 41 inc ecx

:00402915 83F904 cmp ecx, 00000004

:00402918 7CDB jl 004028F5

:0040291A 8B44240C mov eax, dword ptr [esp+0C]

:0040291E 8B4C2408 mov ecx, dword ptr [esp+08]

:00402922 8BD0 mov edx, eax

:00402924 33D1 xor edx, ecx

:00402926 8D0440 lea eax, dword ptr [eax+2*eax]

:00402929 83C208 add edx, 00000008

:0040292C 0FAFD1 imul edx, ecx

:0040292F 03D0 add edx, eax

:00402931 33F6 xor esi, esi

:00402933 89542410 mov dword ptr [esp+10], edx <----将用户名转化的值进行第三次变化记为 reg3 = reg2*3 + ((reg2 ^ reg1)+8)*reg1;

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:0040294D(C)

|

:00402937 0FBE4C3410 movsx ecx, byte ptr [esp+esi+10]

:0040293C 51 push ecx

:0040293D E89E010000 call 00402AE0 <----转化成第三组注册码

:00402942 83C404 add esp, 00000004

:00402945 88443410 mov byte ptr [esp+esi+10], al

:00402949 46 inc esi

:0040294A 83FE04 cmp esi, 00000004

:0040294D 7CE8 jl 00402937

:0040294F 33C9 xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402970(C)

|

:00402951 0FBE440F0A movsx eax, byte ptr [edi+ecx+0A]

:00402956 83F841 cmp eax, 00000041

:00402959 7C08 jl 00402963

:0040295B 83F85A cmp eax, 0000005A

:0040295E 7F03 jg 00402963

:00402960 83C020 add eax, 00000020

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:00402959(C), :0040295E(C)

|

:00402963 0FBE540C10 movsx edx, byte ptr [esp+ecx+10]

:00402968 3BC2 cmp eax, edx <----比较第三组注册码

:0040296A 756C jne 004029D8

:0040296C 41 inc ecx

:0040296D 83F904 cmp ecx, 00000004

:00402970 7CDF jl 00402951

:00402972 8B4C240C mov ecx, dword ptr [esp+0C]

:00402976 8B442408 mov eax, dword ptr [esp+08]

:0040297A 0FAFC8 imul ecx, eax

:0040297D 83C106 add ecx, 00000006

:00402980 8D1480 lea edx, dword ptr [eax+4*eax]

:00402983 0FAF4C2410 imul ecx, dword ptr [esp+10]

:00402988 03CA add ecx, edx

:0040298A 33F6 xor esi, esi

:0040298C 894C2414 mov dword ptr [esp+14], ecx <----将用户名转化的值进行第四次变化.记为 reg4 = reg1*5 + ((reg2 * reg1)+6)*reg3;

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004029A6(C)

|

:00402990 0FBE443414 movsx eax, byte ptr [esp+esi+14]

:00402995 50 push eax

:00402996 E845010000 call 00402AE0 <----转化出第4组注册码

:0040299B 83C404 add esp, 00000004

:0040299E 88443414 mov byte ptr [esp+esi+14], al

:004029A2 46 inc esi

:004029A3 83FE04 cmp esi, 00000004

:004029A6 7CE8 jl 00402990

:004029A8 33C9 xor ecx, ecx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004029C9(C)

|

:004029AA 0FBE440F0F movsx eax, byte ptr [edi+ecx+0F]

:004029AF 83F841 cmp eax, 00000041

:004029B2 7C08 jl 004029BC

:004029B4 83F85A cmp eax, 0000005A

:004029B7 7F03 jg 004029BC

:004029B9 83C020 add eax, 00000020

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:004029B2(C), :004029B7(C)

|

:004029BC 0FBE540C14 movsx edx, byte ptr [esp+ecx+14]

:004029C1 3BC2 cmp eax, edx <----比较第四组注册码

:004029C3 7513 jne 004029D8

:004029C5 41 inc ecx

:004029C6 83F904 cmp ecx, 00000004

:004029C9 7CDF jl 004029AA

:004029CB 5F pop edi

* Possible Reference to String Resource ID=00001: "Register Success"

|

:004029CC B801000000 mov eax, 00000001

:004029D1 5E pop esi

:004029D2 83C420 add esp, 00000020

:004029D5 C20800 ret 0008

-----------------以下是进入CALL 1后的内容--------------------------------------------------

00402A10 81EC00020000 sub esp, 00000200

:00402A16 B980000000 mov ecx, 00000080

:00402A1B 33C0 xor eax, eax

:00402A1D 53 push ebx

:00402A1E 55 push ebp

:00402A1F 56 push esi

:00402A20 8BB42410020000 mov esi, dword ptr [esp+00000210]

:00402A27 57 push edi

:00402A28 8D7C2410 lea edi, dword ptr [esp+10]

:00402A2C F3 repz

:00402A2D AB stosd

:00402A2E 56 push esi

:00402A2F 33ED xor ebp, ebp

* Reference To: KERNEL32.lstrlenA, Ord:0308h

|

:00402A31 FF1590704000 Call dword ptr [00407090] <----取用户名长度

:00402A37 8BD8 mov ebx, eax

:00402A39 81FB00020000 cmp ebx, 00000200 <----比较用户名是否超过512字符

:00402A3F 7612 jbe 00402A53

:00402A41 B980000000 mov ecx, 00000080

:00402A46 8D7C2410 lea edi, dword ptr [esp+10]

:00402A4A BB00020000 mov ebx, 00000200

:00402A4F F3 repz

:00402A50 A5 movsd

:00402A51 EB0C jmp 00402A5F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402A3F(C)

|

:00402A53 8D442410 lea eax, dword ptr [esp+10]

:00402A57 56 push esi

:00402A58 50 push eax

* Reference To: KERNEL32.lstrcpyA, Ord:0302h

|

:00402A59 FF1528704000 Call dword ptr [00407028] <----将用户名复制到另一地址(以下记作地址1).

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402A51(U)

|

:00402A5F 8BC3 mov eax, ebx

:00402A61 99 cdq

:00402A62 83E203 and edx, 00000003

:00402A65 03C2 add eax, edx

:00402A67 8BF8 mov edi, eax

:00402A69 C1FF02 sar edi, 02 <----EDI为用户名长度除4后取整

:00402A6C F6C303 test bl, 03

:00402A6F 7401 je 00402A72

:00402A71 47 inc edi <----如果有余数,再加1,该值用于第二次变化的循环变量.

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402A6F(C)

|

:00402A72 33C9 xor ecx, ecx

:00402A74 85DB test ebx, ebx

:00402A76 7E17 jle 00402A8F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402A8D(C)

|

:00402A78 8A540C10 mov dl, byte ptr [esp+ecx+10] <----取出地址1中用户名的一位.

:00402A7C 52 push edx

:00402A7D 51 push ecx <----压入两个参数,ECX为循环变量,第一次时是0;

:00402A7E E86DFFFFFF call 004029F0 <----此CALL(记为CALL 2)将取出的字符进行变化,按F8可进入分析;

:00402A83 83C408 add esp, 00000008

:00402A86 88440C10 mov byte ptr [esp+ecx+10], al <----将处理后的字符再次写入

:00402A8A 41 inc ecx

:00402A8B 3BCB cmp ecx, ebx <----是否将用户名的第一位都处理了.

:00402A8D 7CE9 jl 00402A78 <----没有处理完就继续.

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402A76(C)

|

:00402A8F 33F6 xor esi, esi

:00402A91 85FF test edi, edi

:00402A93 7E1C jle 00402AB1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402AAF(C)

|

:00402A95 8B5CB410 mov ebx, dword ptr [esp+4*esi+10] <----取出第一次处理后用户名的4位。

:00402A99 8BC6 mov eax, esi

:00402A9B 83E01F and eax, 0000001F

:00402A9E 03EB add ebp, ebx <----将处理的结果进行累加。

:00402AA0 50 push eax

:00402AA1 55 push ebp

:00402AA2 E819000000 call 00402AC0 <----此CALL内比较简单,是将EBP的值通过CF进行循环移位EAX次。

:00402AA7 83C408 add esp, 00000008

:00402AAA 46 inc esi

:00402AAB 3BF7 cmp esi, edi

:00402AAD 8BE8 mov ebp, eax <----是否处理完

:00402AAF 7CE4 jl 00402A95

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402A93(C)

|

:00402AB1 5F pop edi

:00402AB2 8BC5 mov eax, ebp <----将最后累加的值放入EAX后返回。

:00402AB4 5E pop esi

:00402AB5 5D pop ebp

:00402AB6 5B pop ebx

:00402AB7 81C400020000 add esp, 00000200

:00402ABD C3 ret

-----------------------------------------------------------------------------

-----------------CALL 2 分析--------------------------------------

-----------------------------------------------------------------

:004029F0 55 push ebp

:004029F1 8BEC mov ebp, esp

:004029F3 53 push ebx

:004029F4 8A4508 mov al, byte ptr [ebp+08] <----取第一个参数,即上面ECX的值

:004029F7 8A5D0C mov bl, byte ptr [ebp+0C] <----取第二个参数,即上面DL的值

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402A04(C)

|

:004029FA F6C3C3 test bl, C3 <----将BL与C3进行逻辑与后看结果是否为偶数

:004029FD 7A01 jpe 00402A00 <----是偶数就不跳.

:004029FF F9 stc <----将CF置1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:004029FD(C)

|

:00402A00 D0DB rcr bl, 1 <----通过CF进行向右位移

:00402A02 FEC8 dec al

:00402A04 75F4 jne 004029FA <----循环,直到AL为0

:00402A06 885D0C mov byte ptr [ebp+0C], bl

:00402A09 8A450C mov al, byte ptr [ebp+0C] <----将结果放入AL中返回

:00402A0C 5B pop ebx

:00402A0D 5D pop ebp

:00402A0E C3 ret

-------------------------------------------------------------------

----------------此CALL结束-----------------------------------------

标 题:XXXX3000英雄版注册算法分析二(附 VC 6.0 注册机代码) (5千字)

发信人:hoto

时 间:2003-1-17 9:37:38

详细信息:

----------------------------进入CALL 3--------------------------------

----------------------------------------------------------------------

----------------------------------------------------------------------

:00402AE0 8B442404 mov eax, dword ptr [esp+04] <----取出参数到EAX

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:00402B02(U), :00402B13(U), :00402B2E(U)

|

:00402AE4 83E07F and eax, 0000007F

:00402AE7 83F841 cmp eax, 00000041

:00402AEA 7C07 jl 00402AF3

:00402AEC 83F85A cmp eax, 0000005A

:00402AEF 7F02 jg 00402AF3

:00402AF1 0C20 or al, 20 <----如果是大写,则转为小写

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:00402AEA(C), :00402AEF(C)

|

:00402AF3 83F86F cmp eax, 0000006F <----如果是o,再继续

:00402AF6 750C jne 00402B04

:00402AF8 B890000000 mov eax, 00000090

:00402AFD 83F00E xor eax, 0000000E

:00402B00 0C31 or al, 31

:00402B02 EBE0 jmp 00402AE4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402AF6(C)

|

:00402B04 83F830 cmp eax, 00000030 <----如果是0,再继续

:00402B07 750C jne 00402B15

:00402B09 B8CF000000 mov eax, 000000CF

:00402B0E 83F00E xor eax, 0000000E

:00402B11 0C31 or al, 31

:00402B13 EBCF jmp 00402AE4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402B07(C)

|

:00402B15 83F861 cmp eax, 00000061

:00402B18 7C05 jl 00402B1F

:00402B1A 83F87A cmp eax, 0000007A

:00402B1D 7E11 jle 00402B30 <----如果是小写字母,则返回

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402B18(C)

|

:00402B1F 83F831 cmp eax, 00000031

:00402B22 7C05 jl 00402B29

:00402B24 83F839 cmp eax, 00000039

:00402B27 7E07 jle 00402B30 <----如果是数学,则返回

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00402B22(C)

|

:00402B29 83F00E xor eax, 0000000E

:00402B2C 0C31 or al, 31

:00402B2E EBB4 jmp 00402AE4 <----再继续处理.

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:00402B1D(C), :00402B27(C)

|

:00402B30 C3 ret

---------------------------------------------------------------

---------------------------------------------------------------

---------------------------------------------------------------

注册算法

1.将用户名转化为DWORD值;

2.将DWORD值的4个字节依次转化为字符形式,得到第一组注册码

3.再进行3次变化,依次得到后面3组注册码.

-----------------VC++ 6.0 通过------------------

void CHero3000Dlg::OnOK()

{

char name[512];

unsigned char code1[5];

unsigned char code2[5];

unsigned char code3[5];

unsigned char code4[5];

int namelen;

long reg1,reg2,reg3,reg4,temp;

int i,n;

this->UpdateData();

memset(name,0,512);

namelen = this->m_name.GetLength();

strcpy(name,this->m_name);

for(i=0;i<namelen;i++)

{

name[i] = change(i,name[i]);

}

i = (namelen / 4);

if((namelen % 4)>0) i++;

reg1 = 0;

for(n=0;n<i;n++)

{

memcpy(&temp,&name[n*4],4);

reg1 += temp;

_asm mov eax,reg1;

_asm mov ecx,n;

_asm ror eax,cl;

_asm mov reg1,eax;

}

memcpy(code1,&reg1,4);

for(i=0;i<4;i++)

{

code1[i] = this->regtoa(code1[i]);

}

code1[4]=0; //处理完第一组注册码

memcpy(&reg1,code1,4);

reg2 = reg1 * 22;

memcpy(code2,&reg2,4);

for(i=0;i<4;i++)

{

code2[i] = this->change(i,code2[i]);

code2[i] = this->regtoa(code2[i]);

}

code2[4] =0; //处理完第二组注册码

memcpy(&reg2,code2,4);

reg3 = reg2*3 + ((reg2 ^ reg1)+8)*reg1;

memcpy(code3,&reg3,4);

for(i=0;i<4;i++)

{

code3[i] = this->regtoa(code3[i]);

}

code3[4] =0; //处理完第三组注册码

memcpy(&reg3,code3,4);

reg4 = reg1*5 + ((reg2 * reg1)+6)*reg3;

memcpy(code4,&reg4,4);

for(i=0;i<4;i++)

{

code4[i] = this->regtoa(code4[i]);

}

code4[4] =0; //处理完第四组注册码

this->m_regcode = code1;

this->m_regcode += "-";

this->m_regcode += code2;

this->m_regcode += "-";

this->m_regcode += code3;

this->m_regcode += "-";

this->m_regcode += code4;

this->UpdateData(false);

// CDialog::OnOK();

}

char CHero3000Dlg::change(unsigned char a, char b)

{

do

{

_asm mov bl,b;

_asm test bl,0xC3;

_asm jpe st0;

_asm stc;

st0:

_asm rcr bl,1;

_asm mov b,bl;

if(a==0)

a=0xff;

else

a--;

}

while(a>0);

return b;

}

unsigned char CHero3000Dlg::regtoa(unsigned char a)

{

for(;1;)

{

a = a & 0x7f;

if(a>='A' && a<='Z' )

{

a = a | 0x20; //转为小写

}

if(a == 0x6f) //如果是字符'o'则不要它。可能是'o'与'0'比较相似,在注册码中会去除。

{

a = 0x90;

a = a ^ 0x0e;

a = a | 0x31;

continue ;

}

if(a == 0x30) //如果是字符'0',就不要它

{

a = 0xcf;

a = a ^ 0x0e;

a = a | 0x31;

continue;

}

if(a>='a' && a<='z')

{

return a;

}

if(a>='1' && a<='9')

{

return a;

}

a = a ^ 0x0e;

a = a | 0x31;

}

}

---------------------------------------------------------

(出处:赢政天下整理收藏)

相关文章:

·语音界面2.0算法分析及注册机源码!

·侠客系统修改器1.21破解手记--算法分析

·中文拨号上网计时计费器 V4.12注册算法分析

·ClockWise 3.22e注册码算法分析

·CoolClock V1.02注册算法分析

·Directory Scanner v1.5 注册算法分析

·Disk Chief 1.2 简单注册算法分析

·EffeTech HTTP Sniffer 3.2注册算法分析

·eLib2.01算法分析

·EZ MP3 Recorder 1.15 注册算法分析

相关软件:

→ 特别推荐

→ 热点TOP10

关于我们 |

帮助(?)

| 广告服务 |

版权声明 |

商业合作 |

发展历程 |

加盟我们 |

联系我们

Copyright © 1999-2003

winzheng.com All Rights Reserved.

繁体版:由华琦数码技术提供

Powered

by:MeSky.Net

2003-2004 年,宽带刚刚普及,下载站的文章区是许多人学电脑的第一课堂。
🕰 → 🤖 从那时到现在

当年一篇教程能让一台电脑焕然一新;今天的效率工具换成了 AI。 想知道当下最可靠的 AI 模型怎么选?看 赢政指数——我们用了 28 年的选软件严谨,现在用来评测大模型。

档案性质声明:本页为赢政天下(1998-2011)老文章的历史档案复原, 内容反映当年发表时的原貌——包括当年的技术表述、软件版本与观点,部分方法在今天已不适用或不合规,仅作互联网历史记录与研究用途, 不提供任何形式的下载。原始数据经由公共网络存档(Internet Archive)复原。发现问题请联系我们
← 返回老文章档案 · 软件史档案馆 · 赢政天下站史