大致过程。 (8千字)
本人用的windows优化大师是2.5版,其它版本注册算法应该基本相同。接下来我们大致了解一下,注册涉及三个数:申请码、注册码第一部分和注册码第二部分,但参与计算的申请码并非它本身,而是在显示的申请码后插入“1234567”,然后取前8个数进行计算,我机器上的申请码是162445,故参与计算的是“16244512”,注册码分别用12345678和34567890,计算使用的注册码也非它本身,它会把你输入是注册码"12345678"认为十六进制数"12345678",十进制就是305419896,在内存中存为“78563412”第二部分也同样,当然注册码中可以有A~F的字母,但必须是大写。还有就是不要忘了“You are big pig”这句话。
先看大致流程:
0167:00544272 MOV EAX,[EDI+ESI*4]
0167:00544275 MOV [EBP-1C],EAX
0167:00544278 MOV EAX,[EDI+ESI*4+04]
0167:0054427C MOV [EBP-18],EAX
0167:0054427F MOV EDX,EBX
0167:00544281 LEA EAX,[EBP-1C]
0167:00544284 CALL 00544170 <--根据申请码计算得数1
0167:00544289 MOV EAX,[EBX]
0167:0054428B MOV [EBX+08],EAX
0167:0054428E MOV EAX,[EBX+04]
0167:00544291 MOV [EBX+0C],EAX
0167:00544294 MOV EAX,[EBP-1C]
0167:00544297 MOV [EBX],EAX
0167:00544299 MOV EAX,[EBP-18]
0167:0054429C MOV [EBX+04],EAX
0167:0054429F ADD ESI,BYTE +02
0167:005442A2 MOV EAX,[EBP-04]
0167:005442A5 CALL 00542F74
0167:005442AA TEST EAX,EAX
0167:005442AC JNS 005442B1
0167:005442AE ADD EAX,BYTE +03
0167:005442B1 SAR EAX,02
0167:005442B4 CMP ESI,EAX
0167:005442B6 JC 00544272
0167:005442B8 MOV EAX,[EBP-10]
0167:005442BB XOR EDX,EDX
0167:005442BD PUSH EDX
0167:005442BE PUSH EAX
0167:005442BF PUSH DWORD [005450D0]
0167:005442C5 PUSH DWORD [005450CC]
0167:005442CB PUSH DWORD [005450D8]
0167:005442D1 PUSH DWORD [005450D4] 根据注册码第一部分计算,
0167:005442D7 CALL 005440B8 〈--结果放入EAX,设为数2
0167:005442DC SUB EAX,BYTE +02 〈--数2减2
0167:005442DF MOV [EBP-24],EAX 〈--放入内存
0167:005442E2 MOV EAX,[EBP-0C]
0167:005442E5 XOR EDX,EDX
0167:005442E7 PUSH EDX
0167:005442E8 PUSH EAX
0167:005442E9 PUSH DWORD [005450D0]
0167:005442EF PUSH DWORD [005450CC]
0167:005442F5 PUSH DWORD [005450D8]
0167:005442FB PUSH DWORD [005450D4] 根据注册码第二部分计算,
0167:00544301 CALL 005440B8 〈--结果放入EAX,设为数3
0167:00544306 SUB EAX,BYTE +02 〈--数3减2
0167:00544309 MOV [EBP-20],EAX 〈--放入内存
0167:0054430C SHL DWORD [EBP-24],02 〈--数2左移2位
0167:00544310 LEA ECX,[EBP-24]
0167:00544313 MOV EAX,[ECX] 〈--取出数2
0167:00544315 MOV EDX,[ECX+04] 〈--取出数3
0167:00544318 SHRD EAX,EDX,02 〈--数2、数3联合移位,数2改变,数3不变
0167:0054431C SHR EDX,02 〈--数3右移2位
0167:0054431F MOV [ECX],EAX 〈--数2放入内存
0167:00544321 MOV [ECX+04],EDX 〈--数3放入内存
0167:00544324 MOV EAX,[EBP-24]
0167:00544327 CMP EAX,[EBP-1C] <--数2与数1如相同则跳转
0167:0054432A JZ 00544330 正确应跳
0167:0054432C XOR EBX,EBX
0167:0054432E JMP SHORT 00544341 〈--如到这句,注册失败
0167:00544330 MOV AX,[EBP-20] 〈--取数3的低16位放入AX,
0167:00544334 AND AX,FFFF 以后验证,正确应为0014
0167:00544338 MOV EDX,[EBP-08]
0167:0054433B MOV [EDX],AX
0167:0054433E OR EBX,BYTE -01
0167:00544341 XOR EAX,EAX
0167:00544343 POP EDX
0167:00544344 POP ECX
0167:00544345 POP ECX
0167:00544346 MOV [FS:EAX],EDX
0167:00544349 PUSH DWORD 00544366
0167:0054434E LEA EAX,[EBP-14]
0167:00544351 CALL 00542E5C
0167:00544356 LEA EAX,[EBP-04]
0167:00544359 CALL 00542E5C
0167:0054435E RET
具体看申请码的计算:
0167:00544170 PUSH EBX
0167:00544171 PUSH ESI
0167:00544172 PUSH EDI
0167:00544173 PUSH ECX
0167:00544174 MOV [ESP],EAX
0167:00544177 MOV EAX,20 <--设定循环次数
0167:0054417C MOV ECX,[ESP]
0167:0054417F MOV ECX,[ECX] <--申请码前4位放入ecx
0167:00544181 MOV EBX,[ESP]
0167:00544184 MOV EBX,[EBX+04] <--申请码后4位放入ebx
0167:00544187 XOR ESI,ESI
0167:00544189 DEC EAX
0167:0054418A ADD ESI,[005450C8]<--esi加常数9e3779b9
0167:00544190 MOV EDI,EBX
0167:00544192 SHL EDI,04
0167:00544195 ADD ECX,EDI
0167:00544197 MOV EDI,[EDX] <--将"You "的ASC码放入edi,
0167:00544199 XOR EDI,EBX 注意高低位及空格
0167:0054419B ADD ECX,EDI
0167:0054419D MOV EDI,EBX
0167:0054419F SHR EDI,05
0167:005441A2 XOR EDI,ESI
0167:005441A4 ADD ECX,EDI
0167:005441A6 ADD ECX,[EDX+04] <--将"are "的ASC码放入ecx,
0167:005441A9 MOV EDI,ECX
0167:005441AB SHL EDI,04
0167:005441AE ADD EBX,EDI
0167:005441B0 MOV EDI,[EDX+08] <--将"big "的ASC码放入edi,
0167:005441B3 XOR EDI,ECX
0167:005441B5 ADD EBX,EDI
0167:005441B7 MOV EDI,ECX
0167:005441B9 SHR EDI,05
0167:005441BC XOR EDI,ESI
0167:005441BE ADD EBX,EDI
0167:005441C0 ADD EBX,[EDX+0C]<--将ebx加上"pig "的ASC码,
0167:005441C3 TEST EAX,EAX
0167:005441C5 JA 00544189 <--回到上面循环
0167:005441C7 MOV EAX,[ESP]
0167:005441CA MOV [EAX],ECX <--ecx的值即为算得的数1
0167:005441CC MOV EAX,[ESP]
0167:005441CF MOV [EAX+04],EBX
0167:005441D2 POP EDX
0167:005441D3 POP EDI
0167:005441D4 POP ESI
0167:005441D5 POP EBX
0167:005441D6 RET
上面这些移来移去实在不明白什么意思,但用C语言或VC来写,还是很容易的,
注册码的计算过程就复杂多了
两个注册码的计算完全一样,看第一个:
计算中涉及到内存中的几个数如下
在内存地址 77f600处有
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx<--数4,初始为01000000,即十进制数1
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx<--数5,初始为E3A0AA69,即十进制数1772789987
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx<--注册码第一部分,初始为78563412,设为数6
计算过程:
0167:005440CE PUSH BYTE +00
0167:005440D0 PUSH BYTE +02
0167:005440D2 MOV EAX,[EBP+10]
0167:005440D5 MOV EDX,[EBP+14]
0167:005440D8 CALL 00543B6D <--判断内存中一数7为奇为偶,
0167:005440DD CMP EDX,BYTE +00 为奇则跳转至0054411B,
0167:005440E0 JNZ 0054411B 数7初始值为994323192
0167:005440E2 CMP EAX,BYTE +00
0167:005440E5 JNZ 0054411B
0167:005440E7 PUSH BYTE +00
0167:005440E9 PUSH BYTE +02
0167:005440EB MOV EAX,[EBP+10]
0167:005440EE MOV EDX,[EBP+14]
0167:005440F1 CALL 00543A7A <--如数7为偶则除2,结果放回原处
0167:005440F6 MOV [EBP+10],EAX
0167:005440F9 MOV [EBP+14],EDX
0167:005440FC PUSH DWORD [EBP+1C]
0167:005440FF PUSH DWORD [EBP+18]
0167:00544102 PUSH DWORD [EBP+1C]
0167:00544105 PUSH DWORD [EBP+18]
0167:00544108 PUSH DWORD [EBP+0C]
0167:0054410B PUSH DWORD [EBP+08]
0167:0054410E CALL 00544060 \
0167:00544113 MOV [EBP+18],EAX <--数6先平方,再除数5,余数放回数6处
0167:00544116 MOV [EBP+1C],EDX /
0167:00544119 JMP SHORT 0054414A
0167:0054411B MOV EAX,[EBP+10] \
0167:0054411E MOV EDX,[EBP+14] \
0167:00544121 SUB EAX,BYTE +01 \
0167:00544124 SBB EDX,BYTE +00 /<--数7减1,变为偶数
0167:00544127 MOV [EBP+10],EAX /
0167:0054412A MOV [EBP+14],EDX /
0167:0054412D PUSH DWORD [EBP+1C]
0167:00544130 PUSH DWORD [EBP+18]
0167:00544133 PUSH DWORD [EBP-04]
0167:00544136 PUSH DWORD [EBP-08]
0167:00544139 PUSH DWORD [EBP+0C]
0167:0054413C PUSH DWORD [EBP+08]
0167:0054413F CALL 00544060 \
0167:00544144 MOV [EBP-08],EAX <--数6乘数4除数5,余数放回数4
0167:00544147 MOV [EBP-04],EDX /
0167:0054414A CMP DWORD [EBP+14],BYTE +00
0167:0054414E JNZ 0054415C
0167:00544150 CMP DWORD [EBP+10],BYTE +00
0167:00544154 JA NEAR 005440CE
0167:0054415A JMP SHORT 00544162 <--当数7减小为0时到此处跳出返回,
0167:0054415C JG NEAR 005440CE 并将数4的最后值作为返回值数2
0167:00544162 MOV EAX,[EBP-08]
0167:00544165 MOV EDX,[EBP-04]
0167:00544168 POP ECX
0167:00544169 POP ECX
0167:0054416A POP EBP
0167:0054416B RET
注册码第二部分地运算过程完全相同,不再赘述。
问题:由于数4,数6都为32位数,数6平方的结果及数4、数6相乘的结果都将为64位数,然后将这64位数除32位数求余。所以运算过程比较复杂,而且一般的高级语言所涉及的长整数只有32位,如C语言和VC,即使想把它的运算过程模拟下来也比较困难。再者,对于这样复杂的迭代运算,申请码与注册码是否一一对应还是一个问题,小弟的水平不够,有没有高手可以求出逆运算并写出注册机!(不修改程序!)
小弟的水平不够,写得不好之处请各位海涵。
