奇门遁甲演义V6.3破解手记--注册码算法分析
作者:newlaos[DFCG]
软件名称:奇门遁甲演义V6.3(周易)
文件大小:2360KB(软件做好后,没有做任何处理,建议作者有类似UPX将软件压缩一下)
软件授权:共享软件
使用平台:Win9x/Me/NT/2000/XP
发布公司:"http://www.380000.com/
软件简介:自动排出从1900年到2050年内的任意时间的时家、日家、月家、年家奇门遁甲局况;附有相应的古注语和现注解,用彩色标出其中常见的凶格和吉格;方便的时间查找功能,自动查找满足输入条件的时间;可以导出局图的纯文字版本,方便复制和传播;时间调整功能;更详细的帮助文档。
加密方式:注册码
功能限制:频繁弹出注册对话框
PJ工具:TRW20001.23注册版、W32Dasm8.93黄金版,FI2.5
PJ日期:2003-03-23
作者newlaos申明:只是学习,请不用于商业用途或是将本文方法制作的注册机任意传播,造成后果,本人一概不负。
1、先用FI2.5看一下主程序“奇门遁甲演义VI.exe”,没有加壳。是用VB编写的。
2、用W32Dasm8.93黄金版对主文件进行静态反汇编,再用串式数据参考,找到"注册成功!"(很经典的句子),双击来到下面代码段。这样就找到注册码的计算部分。
3、再用TRW20001.23注册版进行动态跟踪,下断BPX 0040B73E(通常在注册成功与否的前面一些下断,这样,才能找到关键部分),先输入假码78787878
.......
.......
:0040B73E
FF15C4D14100 Call dword ptr [0041D1C4]
:0040B744
A1D0D64100 mov eax, dword ptr
[0041D6D0]
:0040B749 8D4C2448
lea ecx, dword ptr [esp+48]
:0040B74D 50
push eax
*
Possible Reference to String Resource ID=00002: "212112121222#8"
|
:0040B74E 6A02
push 00000002
*
Possible StringData Ref from Data Obj ->"register.ini"
|
:0040B750 68782D4200
push 00422D78 <===文件里放了只有我们输入的假码(78787878)
:0040B755
E816830000 call 00413A70
:0040B75A 8D7C2408
lea edi, dword ptr [esp+08]
:0040B75E 83C9FF
or ecx, FFFFFFFF
:0040B761 33C0
xor eax, eax
:0040B763
F2 repnz
:0040B764
AE scasb
:0040B765
F7D1 not
ecx
:0040B767 49
dec ecx
:0040B768 51
push ecx
:0040B769 8D4C240C
lea ecx, dword ptr [esp+0C]
:0040B76D
51 push
ecx
:0040B76E 8D4C2450 lea
ecx, dword ptr [esp+50]
:0040B772 E835830000
call 00413AAC
:0040B777 8D4C2448
lea ecx, dword ptr [esp+48]
:0040B77B E8827E0000
call 00413602
:0040B780 8B0D643F4200
mov ecx, dword ptr [00423F64]
:0040B786
E8F5020000 call 0040BA80 <===这个CALL会改变88FCA4处的值(这是一个标志位),所以F8跟进
:0040B78B
8B15643F4200 mov edx, dword ptr [00423F64]
:0040B791
5F pop
edi
:0040B792 8A8228A40000 mov al,
byte ptr [edx+0000A428]
<===EDX=88587C(在88FCA4处的值很关键, 不能为0)
:0040B798
84C0 test
al, al <===要不为0,才能正确跳转
:0040B79A 7515
jne 0040B7B1
<===关键跳转,跳才正确
*
Possible Reference to String Resource ID=00016: "221212212121#3"
|
:0040B79C 6A10
push 00000010
*
Possible StringData Ref from Data Obj ->"错误"
|
:0040B79E 6874004200 push
00420074
* Possible
StringData Ref from Data Obj ->"注册失败!"
|
:0040B7A3 686C2D4200 push
00422D6C
:0040B7A8 56
push esi
*
Reference To: USER32.MessageBoxA, Ord:01BEh
|
:0040B7A9
FF1580D14100 Call dword ptr [0041D180]
:0040B7AF
EB78 jmp
0040B829
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:0040B79A(C)
|
*
Possible Reference to String Resource ID=00064: "212112121222#13"
|
:0040B7B1 6A40
push 00000040
*
Possible StringData Ref from Data Obj ->"提示"
|
:0040B7B3 68FC2C4200 push
00422CFC
* Possible
StringData Ref from Data Obj ->"注册成功!"
|
:0040B7B8 68602D4200 push
00422D60
:0040B7BD 56
push esi
*
Reference To: USER32.MessageBoxA, Ord:01BEh
|
:0040B7BE
FF1580D14100 Call dword ptr [0041D180]
:0040B7C4
A1643F4200 mov eax, dword ptr
[00423F64]
:0040B7C9 6A00
push 00000000
:0040B7CB 56
push esi
:0040B7CC C78004A40000FA000000
mov dword ptr [ebx+0000A404], 000000FA
*
Reference To: USER32.EndDialog, Ord:00B9h
|
:0040B7D6
FF15DCD14100 Call dword ptr [0041D1DC]
:0040B7DC
EB4B jmp
0040B829
.......
.......
-----0040B786
call 0040BA80 我们按F8跟进来到下面代码段-------
这一段的功能:是把我的注册码以“-”为标志分成5串,而后与机器生成的5串依次比较,只一次错就跳出
:0040BA80
6AFF push
FFFFFFFF
:0040BA82 6858BB4100 push
0041BB58
:0040BA87 64A100000000 mov
eax, dword ptr fs:[00000000]
:0040BA8D 50
push eax
:0040BA8E 64892500000000
mov dword ptr fs:[00000000], esp
:0040BA95
81EC80000000 sub esp, 00000080
:0040BA9B
55 push
ebp
:0040BA9C 8BE9
mov ebp, ecx
:0040BA9E 57
push edi
*
Possible Reference to String Resource ID=00001: "121121212221#19"
|
:0040BA9F 6A01
push 00000001
:0040BAA1 8D4C244C
lea ecx, dword ptr [esp+4C]
:0040BAA5
E8587A0000 call 00413502
*
Possible Reference to String Resource ID=00007: "121212212121#13"
|
:0040BAAA B907000000
mov ecx, 00000007
:0040BAAF 33C0
xor eax, eax
:0040BAB1 8D7C2428
lea edi, dword ptr [esp+28]
:0040BAB5
6A00 push
00000000
:0040BAB7 F3
repz
:0040BAB8 AB
stosd
*
Possible StringData Ref from Data Obj ->"register.ini"
|
:0040BAB9 68782D4200
push 00422D78
:0040BABE C784249800000000000000 mov dword
ptr [esp+00000098], 00000000
:0040BAC9 66AB
stosw
:0040BACB E879FC0000
call 0041B749
:0040BAD0 83C408
add esp, 00000008
:0040BAD3
83F8FF cmp eax,
FFFFFFFF
:0040BAD6 0F84CC000000
je 0040BBA8 <===这是不能跳,跳过去就OVER了。
:0040BADC
A1D0D64100 mov eax, dword ptr
[0041D6D0]
:0040BAE1 8D4C2448
lea ecx, dword ptr [esp+48]
:0040BAE5 50
push eax
*
Possible Reference to String Resource ID=00001: "121121212221#19"
|
:0040BAE6 6A01
push 00000001
*
Possible StringData Ref from Data Obj ->"register.ini"
|
:0040BAE8 68782D4200
push 00422D78
:0040BAED E8D47A0000
call 004135C6
:0040BAF2 8B54244C
mov edx, dword ptr [esp+4C]
*
Possible Reference to String Resource ID=00010: "121121212221#10"
|
:0040BAF6 6A0A
push 0000000A
:0040BAF8 8D4C242C
lea ecx, dword ptr [esp+2C]
*
Possible Reference to String Resource ID=00030: "1221123121221#30"
|
:0040BAFC 6A1E
push 0000001E
:0040BAFE 42
inc edx
:0040BAFF
51 push
ecx
:0040BB00 8D4C2454 lea
ecx, dword ptr [esp+54]
:0040BB04 89542458
mov dword ptr [esp+58], edx
:0040BB08 E8E27F0000
call 00413AEF
:0040BB0D 8D4C2448
lea ecx, dword ptr [esp+48]
:0040BB11
E8EC7A0000 call 00413602
:0040BB16
8BCD mov
ecx, ebp
:0040BB18 E8A3FDFFFF call
0040B8C0
:0040BB1D 8D542414
lea edx, dword ptr [esp+14]
:0040BB21 89442408
mov dword ptr [esp+08], eax
:0040BB25 52
push edx
:0040BB26
8D44242C lea eax, dword
ptr [esp+2C]
* Possible
Reference to String Resource ID=00045: "112112122212#13"
|
:0040BB2A 6A2D
push 0000002D
:0040BB2C 50
push eax
:0040BB2D 8BCD
mov ecx,
ebp
:0040BB2F E8FC4F0000 call
00410B30 <===这个CALL主要功能是看输入的注册码里有没有五个“-”字符,到这里我们将假码改为78-78-78-78-78-78,重新来(为了说明方便,我们定义为注册码的1、2、3、4、5串)
:0040BB34
83F805 cmp eax,
00000005 <===EAX必须等于5,否则就跳走出错了。
:0040BB37 756F
jne 0040BBA8
<===因为跳到错的地方有两个,上面那不会跳,所以这里是一个很关键的跳转
:0040BB39 53
push ebx
:0040BB3A 56
push
esi
:0040BB3B 33FF
xor edi, edi <===EDI是个计数器,共5次,对应注册码有5串
:0040BB3D
8D5C241C lea ebx, dword
ptr [esp+1C]
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:0040BB8D(C)
|
:0040BB41
8B542410 mov edx, dword
ptr [esp+10]
:0040BB45 8D4C2414
lea ecx, dword ptr [esp+14]
:0040BB49 51
push ecx
:0040BB4A 57
push edi
:0040BB4B
52 push
edx
:0040BB4C 8BCD
mov ecx, ebp
:0040BB4E E89DFDFFFF
call 0040B8F0 <===呵呵,这个就是算出正确的串值的CALL了。F8跟进
:0040BB53
8B33 mov
esi, dword ptr [ebx]
:0040BB55 8D442414
lea eax, dword ptr [esp+14]
<===我的机器出现EAX=为正确的串值(这里用于比较的),共5次,在这里设断,得到一个值就将它改为注册码的对应的串,再点注册,又失败,但得到下一串的值,如此循环,注册失败5次后,你就得到全部的注册码了,我的是PLT6D-1DNLD-1KFDD-0XXXX-PLSCG
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BB77(C)
|
:0040BB59
8A10 mov
dl, byte ptr [eax]
:0040BB5B 8ACA
mov cl, dl
:0040BB5D 3A16
cmp dl, byte ptr [esi]
:0040BB5F
751C jne
0040BB7D
:0040BB61 84C9
test cl, cl
:0040BB63
7414 je 0040BB79
:0040BB65
8A5001 mov dl, byte
ptr [eax+01]
:0040BB68 8ACA
mov cl, dl
:0040BB6A 3A5601
cmp dl, byte ptr [esi+01]
:0040BB6D 750E
jne 0040BB7D
:0040BB6F
83C002 add eax,
00000002
:0040BB72 83C602
add esi, 00000002
:0040BB75 84C9
test cl, cl
:0040BB77 75E0
jne 0040BB59
<===这里构成一个小循环功能是把我们输入的假码以“-”字符分开的字符与在0040BB55给出的EAX值作比较,只要一处错就跳到40BB7D,就OVER了。
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BB63(C)
|
:0040BB79
33C0 xor
eax, eax
:0040BB7B EB05
jmp 0040BB82
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040BB5F(C),
:0040BB6D(C)
|
:0040BB7D 1BC0
sbb eax, eax <===(带位减法)EAX清0
:0040BB7F
83D8FF sbb eax,
FFFFFFFF <===EAX=1
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BB7B(U)
|
:0040BB82
85C0 test
eax, eax
<===EAX=1说明上面循环比较出错了,EAX=0就说明比较对了。
:0040BB84
750B jne
0040BB91 <===如果EAX=1,这里再跳走,EAX=0不跳
:0040BB86 47
inc edi
:0040BB87 83C304
add ebx, 00000004
:0040BB8A 83FF05
cmp edi, 00000005
:0040BB8D 7CB2
jl 0040BB41
<===这里是个大循环,共5次,分别比较机器算出的5个串和我们输入的5个串做比较。
:0040BB8F
EB07 jmp
0040BB98 <===5次循环都正确,就到这里再跳向胜利。
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040BB84(C)
|
:0040BB91
C68528A4000000 mov byte ptr [ebp+0000A428],
00
* Referenced by a
(U)nconditional or (C)onditional Jump at Address:
|:0040BB8F(U)
|
:0040BB98
5E pop
esi
:0040BB99 83FF05
cmp edi, 00000005
<===这里也是一个很关键的对比,上面0040BB91已经把标志位清0
:0040BB9C
5B pop
ebx
:0040BB9D 7510
jne 0040BBAF <===如果这里跳走,就OVER
:0040BB9F C68528A4000001
mov byte ptr [ebp+0000A428], 01
<===[ebp+0000A428]是个标志位,能到这里,说明成功
:0040BBA6 EB07
jmp 0040BBAF
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040BAD6(C),
:0040BB37(C)
|
:0040BBA8 C68528A4000000 mov
byte ptr [ebp+0000A428], 00
<===[ebp+0000A428]是个标志位,要是到这里,说明失败
* Referenced by a (U)nconditional or (C)onditional Jump
at Addresses:
|:0040BB9D(C), :0040BBA6(U)
|
:0040BBAF 8D4C2454
lea ecx, dword ptr [esp+54]
:0040BBB3
C7842490000000FFFFFFFF mov dword ptr [esp+00000090], FFFFFFFF
:0040BBBE
E8F0790000 call 004135B3
:0040BBC3
8D4C2454 lea ecx, dword
ptr [esp+54]
:0040BBC7 E8DE780000
call 004134AA
:0040BBCC 8B8C2488000000 mov
ecx, dword ptr [esp+00000088]
:0040BBD3 5F
pop edi
:0040BBD4 5D
pop ebp
:0040BBD5
64890D00000000 mov dword ptr fs:[00000000],
ecx
:0040BBDC 81C48C000000 add esp,
0000008C
:0040BBE2 C3
ret
-----0040BB4E
call 0040B8F0 这个就是算出正确的串值的CALL了---------------
我的注册码机器454376902,注册码就是PLT6D-1DNLD-1KFDD-0XXXX-PLSCG
*
Referenced by a CALL at Address:
|:0040BB4E
|
:0040B8F0 83EC18
sub esp, 00000018
:0040B8F3
33C0 xor
eax, eax <===每次进来EAX都要清0
:0040B8F5 53
push ebx
:0040B8F6 8B5C2428
mov ebx, dword ptr [esp+28]
:0040B8FA
8BCB mov
ecx, ebx
:0040B8FC 56
push esi
:0040B8FD 57
push edi
:0040B8FE 8901
mov dword ptr [ecx], eax
:0040B900
66894104 mov word ptr [ecx+04],
ax
:0040B904 E8B68F0000 call
004148BF
:0040B909 99
cdq
*
Possible Reference to String Resource ID=00100: "221121121221#5"
|
:0040B90A B964000000
mov ecx, 00000064
:0040B90F F7F9
idiv ecx <===整数除法(EAX/ECX),商回EAX,余数回ECX
:0040B911
33C0 xor
eax, eax
:0040B913 85D2
test edx, edx
:0040B915 7E14
jle 0040B92B
:0040B917 8B4C2428
mov ecx, dword ptr [esp+28]
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B929(C)
|
:0040B91B
85C0 test
eax, eax
:0040B91D 7405
je 0040B924
:0040B91F 0FAFC8
imul ecx, eax
:0040B922 EB02
jmp 0040B926
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B91D(C)
|
:0040B924
8BCA mov
ecx, edx
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:0040B922(U)
|
:0040B926
40 inc
eax
:0040B927 3BC2
cmp eax, edx
:0040B929 7CF0
jl 0040B91B <===这里是一个循环结构
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B915(C)
|
:0040B92B
8B44242C mov eax, dword
ptr [esp+2C] <===从EAX=0开始,每次循环到里,就加1,最后
:0040B92F 83F804
cmp eax, 00000004
<===最后EAX=4,退出,共循环5次,正好是注册码的5个串值
:0040B932 7761
ja 0040B995
:0040B934 FF248560BA4000
jmp dword ptr [4*eax+0040BA60]
<===注意由于每次EAX都加1,所以导致这个无条件跳转到的位置不同,每次不同跳转产生不同的值共同构成这个注册码。
:0040B93B 8B442428
mov eax, dword ptr [esp+28]
<===第一次跳到这里,EAX=1B153DC6
,它的十进制是454376732,正好是我的机器码!
:0040B93F 3503008519
xor eax, 19850003 <===1B153DC6与19850003做异或运算
:0040B944
0D34120000 or eax, 00001234 <===EAX再与1234做或运算,值放入EAX(为说明问题,我们定义为EAX1)
:0040B949
EB4E jmp
0040B999 <===跳走
:0040B94B 8B442428
mov eax, dword ptr [esp+28]
<===第二次跳到这里,EAX=1B153DC6,它的十进制是454376732,正好是我的机器码!
*
Possible Reference to String Resource ID=00001: "121121212221#19"
|
:0040B94F B901000000
mov ecx, 00000001 <===ECX初始化为1,计数器
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B95D(C)
|
:0040B954
8BD1 mov
edx, ecx
:0040B956 0FAFC2
imul eax, edx <===但实际动态跟踪时发现是EAX=EAX*1*2*3*4*5*6*7*8*9*A*B*C*D*E*F*10*11*12*13
:0040B959
41 inc
ecx <===ECX=ECX+1
:0040B95A
83F913 cmp ecx,
00000013
:0040B95D 7EF5
jle 0040B954 <===共循环16(注13是十六进制)次。
:0040B95F
0D34120000 or eax, 00001234
<===EAX再与1234做或运算,值放入EAX(为说明问题,我们定义为EAX2)
:0040B964 EB33
jmp 0040B999
<===跳走
:0040B966 8B442428
mov eax, dword ptr [esp+28]
<===第三次跳到这里,EAX=1B153DC6,它的十进制是454376732,正好是我的机器码!
:0040B96A
69C03C642B01 imul eax, 012B643C
<===EAX=EAX*12B643C
:0040B970 0D34120000
or eax, 00001234 <===EAX再与1234做或运算,值放入EAX(为说明问题,我们定义为EAX3)
:0040B975
EB22 jmp
0040B999 <===跳走
:0040B977 8B442428
mov eax, dword ptr [esp+28]
<===第四次跳到这里,EAX=1B153DC6,它的十进制是454376732,正好是我的机器码!
* Possible Reference
to String Resource ID=00010: "121121212221#10"
|
:0040B97B B90A000000 mov
ecx, 0000000A <===将ECX初始化为10,
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B986(C)
|
:0040B980
8BD0 mov
edx, eax
:0040B982 0FAFC2
imul eax, edx
<===最后(EAX的值用C语言表示)
eax=1B153DC6;
for(i=0;i<>10;i++)
{eax=eax^2;
}
:0040B985 49
dec ecx
<===ECX=ECX-1
:0040B986 75F8
jne 0040B980
<===共一个小的循环结构,共循环10次,后退出!
:0040B988 EB0F
jmp 0040B999
<===跳走,这里的EAX(为说明问题,我们定义为EAX4)
:0040B98A 8B442428
mov eax, dword ptr [esp+28]
:0040B98E
3506068519 xor eax, 19850606
:0040B993
EB04 jmp
0040B999
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:0040B932(C)
|
:0040B995
8B442428 mov eax, dword
ptr [esp+28]
<===第五次跳到这里,EAX=1B153DC6,它的十进制是454376732,正好是我的机器码!。这里EAX不再做任何处理,直接拿来用了。(为说明问题,我们定义为EAX5)
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040B949(U),
:0040B964(U), :0040B975(U), :0040B988(U), :0040B993(U)
|
:0040B999 8D4C240C
lea ecx, dword ptr [esp+0C]
*
Possible Reference to String Resource ID=00036: "2114112212221#24"
|
:0040B99D 6A24
push 00000024
:0040B99F 51
push ecx
<====ECX=8850D8
:0040B9A0
50 push
eax
<====这里的EAX1,EAX2,EAX3,EAX4,EAX5分别为2903FF5,B2F61234,CB5DD27,0000000,2903BC0
:0040B9A1
E879FD0000 call 0041B71F
<===这里面,EAX1,EAX2,EAX3,EAX4,EAX5再进行处理,就生成最终对应的串值,并放在出来的EAX中,F8跟进
:0040B9A6
8D7C2418 lea edi, dword
ptr [esp+18]
:0040B9AA 83C9FF
or ecx, FFFFFFFF
:0040B9AD 33C0
xor eax, eax
:0040B9AF 83C40C
add esp, 0000000C
:0040B9B2
F2 repnz
:0040B9B3
AE scasb
:0040B9B4
F7D1 not
ecx
:0040B9B6 49
dec ecx
:0040B9B7 8BF1
mov esi, ecx
:0040B9B9 33C9
xor ecx, ecx
:0040B9BB 85F6
test esi,
esi
:0040B9BD 7E17
jle 0040B9D6
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B9D4(C)
|
:0040B9BF
8A440C0C mov al, byte ptr
[esp+ecx+0C]
:0040B9C3 3C61
cmp al, 61
:0040B9C5 7C0A
jl 0040B9D1
:0040B9C7 3C7A
cmp al, 7A
:0040B9C9
7F06 jg 0040B9D1
:0040B9CB
2C20 sub
al, 20
:0040B9CD 88440C0C
mov byte ptr [esp+ecx+0C], al
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0040B9C5(C),
:0040B9C9(C)
|
:0040B9D1 41
inc ecx
:0040B9D2 3BCE
cmp ecx, esi
:0040B9D4 7CE9
jl 0040B9BF
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040B9BD(C)
|
:0040B9D6
83FE05 cmp esi,
00000005
:0040B9D9 7C1C
jl 0040B9F7
:0040B9DB 8D54240C
lea edx, dword ptr [esp+0C]
:0040B9DF 52
push edx
*
Possible StringData Ref from Data Obj ->"%.5s"
|
:0040B9E0 68F82D4200
push 00422DF8
:0040B9E5 53
push ebx
:0040B9E6 E8EE890000
call 004143D9
:0040B9EB 83C40C
add esp, 0000000C
:0040B9EE
5F pop
edi
:0040B9EF 5E
pop esi
:0040B9F0 5B
pop ebx
:0040B9F1 83C418
add esp, 00000018
:0040B9F4 C20C00
ret 000C
---------:0040B9A1
call 0041B71F 按F8跟进来到下面代码段--------------------
这段代码的作用:将EAX1,EAX2,EAX3,EAX4,EAX5再进行处理,就生成最终对应的串值,并放在出来的EAX中
*
Referenced by a CALL at Addresses:
|:0040B80D , :0040B9A1
|
:0041B71F
55 push
ebp
:0041B720 8BEC
mov ebp, esp
:0041B722 33C0
xor eax, eax
:0041B724 837D100A
cmp dword ptr [ebp+10], 0000000A <===[EBP+10]每次都是24
:0041B728
7508 jne
0041B732
<===所以这里每次跳走
:0041B72A 394508
cmp dword ptr [ebp+08], eax
:0041B72D 7D03
jge 0041B732
*
Possible Reference to String Resource ID=00001: "121121212221#19"
|
:0041B72F 6A01
push 00000001
:0041B731 58
pop eax
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0041B728(C),
:0041B72D(C)
|
:0041B732 50
push eax
:0041B733 FF7510
push [ebp+10] <===跳到这里,将24(十六进制)压入栈
:0041B736
FF750C push [ebp+0C]
<===将8850D8压入栈,这个是最终串值返回时的地址
:0041B739
FF7508 push [ebp+08]
<===依次将EAX1,EAX2,EAX3,EAX4,EAX5压入栈
:0041B73C
E882FFFFFF call 0041B6C3
<===这个CALL出来,EAX里就是正确的串值了,F8再跟进
:0041B741
8B450C mov eax,
dword ptr [ebp+0C] <===最终将正确的串值放入EAX中
:0041B744 83C410
add esp, 00000010
:0041B747
5D pop
ebp
:0041B748 C3
ret
---------:0041B73C
call 0041B6C3 按F8跟进来到下面代码段--------------------
这段代码的作用:将EAX1,EAX2,EAX3,EAX4,EAX5再进行处理,就生成最终对应的串值,并放在出来的EAX中
*
Referenced by a CALL at Addresses:
|:0041B6B6 , :0041B73C
|
:0041B6C3
55 push
ebp
:0041B6C4 8BEC
mov ebp, esp
:0041B6C6 837D1400
cmp dword ptr [ebp+14], 00000000 <===这里5次都相等
:0041B6CA
8B4D0C mov ecx,
dword ptr [ebp+0C]
:0041B6CD 53
push ebx
:0041B6CE 56
push esi
:0041B6CF 57
push edi
:0041B6D0
740B je 0041B6DD
<===这里5次都跳走
:0041B6D2
8B7508 mov esi,
dword ptr [ebp+08]
:0041B6D5 C6012D
mov byte ptr [ecx], 2D
:0041B6D8 41
inc ecx
:0041B6D9 F7DE
neg esi
:0041B6DB
EB03 jmp
0041B6E0
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:0041B6D0(C)
|
:0041B6DD
8B7508 mov esi,
dword ptr [ebp+08] <===跳到这里,ESI=EAX(1,2,3,4,5)
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B6DB(U)
|
:0041B6E0
8BF9 mov
edi, ecx
<===EDI=8850D8
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B706(C)
|
:0041B6E2
8BC6 mov
eax, esi
<===EAX=EAX(1,2,3,4,5)
:0041B6E4 33D2
xor edx, edx
<===将EDX清0
:0041B6E6 F77510
div [ebp+10] <===将EAX(1,2,3,4,5)除以24,商回EAX,余数回EDX
:0041B6E9
8BC6 mov
eax, esi <===EAX=EAX(1,2,3,4,5)
:0041B6EB 8BDA
mov ebx, edx <===EBX=余数
:0041B6ED
33D2 xor
edx, edx <===将EDX清0
:0041B6EF F77510
div [ebp+10] <===将EAX(1,2,3,4,5)除以24(十六进制),商回EAX,余数回EDX(不明白为什么又除一遍)
:0041B6F2
83FB09 cmp ebx,
00000009 <===这个判断很重要!
:0041B6F5 8BF0
mov esi, eax
:0041B6F7 7605
jbe 0041B6FE
<===如果余数是数字,就跳转。如果余数是字符,就不跳转
:0041B6F9 80C357
add bl, 57
:0041B6FC EB03
jmp 0041B701
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B6F7(C)
|
:0041B6FE
80C330 add bl, 30
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B6FC(U)
|
:0041B701
8819 mov
byte ptr [ecx], bl <===其实这个判断的处理作用就是将余数处理为其对应的ASCII值(字符是小写)
:0041B703 41
inc
ecx
:0041B704 85F6
test esi, esi
:0041B706 77DA
ja 0041B6E2 <===从这里向上,构成一个循环结构,共循环5次,第n次在bl处得到余数转为字符后,就构成串值的第n位
*****
这一小段的循环作用(以EAX1为例):
公式
商 余数 对应的字符
2903FF5/24
123AAA D d
123AAA/24 81A1 6
6
81A1/24 339
1D t (d字符后面的16位的字符)以ASC码表为顺序
339/24 19
15 l (数字5后面的16位的字符)
19/24 0 19
p (数字9后面的16位的字符)
***** 最后在内存的8850D8位置上得到串值d6tlp
:0041B708
802100 and byte
ptr [ecx], 00
:0041B70B 49
dec ecx
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041B718(C)
|
:0041B70C
8A17 mov
dl, byte ptr [edi]
:0041B70E 8A01
mov al, byte ptr [ecx]
:0041B710 8811
mov byte ptr [ecx], dl
:0041B712
8807 mov
byte ptr [edi], al
:0041B714 49
dec ecx
:0041B715 47
inc edi
:0041B716 3BF9
cmp edi, ecx
:0041B718
72F2 jb 0041B70C
<===从这里向上,构成一个循环结构,作用是将上面得到串值反向再取值,所以最后8850D8位置上得到串值plt6d(其它程序段会把它转为大写)
:0041B71A
5F pop
edi
:0041B71B 5E
pop esi
:0041B71C 5B
pop ebx
:0041B71D 5D
pop ebp
:0041B71E C3
ret
此段总结:依照上面的步骤将EAX1,EAX2,EAX3,EAX4,EAX5最后处理为plt6d,1dnld,1kfdd,0xxxx,plscg
----注册码浮出水面
-------------------------------------------------------------------------------------------------
4、算法总结:-----类型:f(机器码)=注册码------
a、将机器码454376732(每台机器码都不一样),转换为十六进制1B153DC6
b、将1B153DC6分别做5种的处理,得到相应串值的第一次变形
第一种处理:1B153DC6与19850003做异或运算,再与1234做或运算,得到2903FF5
第二种处理:1B153DC6EAX=EAX*1*2*3*4*5*6*7*8*9*A*B*C*D*E*F*10*11*12*13,再与1234做或运算,得到B2F61234
第三种处理:1B153DC6*12B643C,再与1234做或运算,得到CB5DD27C
第四种处理:eax=1B153DC6; for(i=0;i<>10;i++) {eax=eax^2;}一般情况EAX都会因为值太大,而爆为00000000
第五种处理:1B153DC6不做处理
c、分别将上一步得到的5串数字,做同样的处理,也就是(以EAX1为例):
公式 商
余数 对应的字符
2903FF5/24
123AAA D d
123AAA/24 81A1 6
6
81A1/24 339
1D t (d字符后面的16位的字符)以ASC码表为顺序
339/24 19 15
l (数字5后面的16位的字符)
19/24
0 19 p (数字9后面的16位的字符)
最后改为字符串d6tlp,其它的四个串也依次类推。
d、将上一步得到的5个字符分别反向取值,分别得到plt6d,1dnld,1kfdd,0xxxx,plscg,最后的注册码就是将它转为大写后,中间分别加上“-”,PLT6D-1DNLD-1KFDD-0XXXX-PLSCG
5、注册信息存放在奇门遁甲演义V6.3所在目录的register.ini文件中。以明文件形式保留。