奇門遁甲演義V6.3破解手記--註冊碼演算法分析
奇門遁甲演義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檔案中。以明檔案形式保留。
相關文章
- 快捷反垃圾郵件破解手記--找出註冊碼2015-11-15
- i-view32註冊碼的破解手記 (778字)2001-02-03View
- SMailserver2.5註冊碼的破解手記 (1千字)2001-03-01AIServer
- 32bit Convert
It 9.52.01破解手記--找到註冊碼2015-11-15
- Instant Source 註冊演算法分析+註冊器原始碼2015-11-15演算法原始碼
- HTMLock 1.9.3破解手記---演算法分析2003-06-27HTML演算法
- IEPopupKiller 1.2破解手記--演算法分析2015-11-15演算法
- 註冊碼演算法入門!----菜鳥篇2015-11-15演算法
- supercleaner註冊演算法分析2015-11-15演算法
- QuickCD 1.0.320破解手記--演算法分析2015-11-15UI演算法
- SpeedFlash註冊演算法分析(VB)2015-11-15演算法
- 財智老闆通3.04註冊版---註冊演算法分析2003-03-16演算法
- GreenBrowser 1.0.312破解手記--演算法分析2015-11-15演算法
- Golden 5.7 Build 391破解手記--演算法分析2015-11-15GoUI演算法
- 拱豬大戰 1.8破解手記--演算法分析2015-11-15演算法
- Setup2Go 1.97破解手記--演算法分析2015-11-15Go演算法
- Theme Builder註冊碼分析2015-11-15UI
- ShadowDefender 註冊碼 分析2024-08-17
- Green Tea 2.60註冊碼演算法分析 (3千字)2000-07-17演算法
- Screen Demo Maker 3.0 註冊演算法分析2003-07-15演算法
- <<Anti-Hack>> 2.0註冊演算法分析2003-06-06演算法
- Personal Antispy 1.14 註冊演算法分析2015-11-15演算法
- 冰盾濾鏡註冊演算法分析2015-11-15演算法
- nacos註冊中心原始碼流程分析2020-12-23原始碼
- SuperCleaner 2.31註冊碼演算法分析 - OCG (13千字)2002-04-02演算法
- Registry Crawler 4.0註冊碼演算法分析 - OCG
(20千字)2002-04-07演算法
- UltraEdit-32
10註冊碼演算法分析 (19千字)2003-05-17演算法
- **********.exe註冊碼演算法分析--高手莫笑 (31千字)2015-11-15演算法
- DLL Show V4.4 註冊演算法分析2015-11-15演算法
- Disk
Chief 1.2 簡單註冊演算法分析2015-11-15演算法
- Konvertor 3.03的註冊碼演算法模組的分析
(7千字)2015-11-15演算法
- Magic convertor 2.8註冊碼演算法分析
- OCG (9千字)2015-11-15演算法
- 註冊碼演算法 (2千字)2001-01-14演算法
- @angular/router 原始碼分析之註冊路由2018-07-10Angular原始碼路由
- pcmedik V5.4.8.2003破解手記--演算法分析2003-05-10演算法
- 極速傳真[SpeedFax] 2.4 破解手記--程式逆向分析演算法2015-11-15演算法
- E族百變桌面6.0註冊演算法分析2015-11-15演算法
- FolderView 1.7
註冊演算法分析 (14千字)2015-11-15View演算法