拱豬大戰 1.8破解手記--演算法分析
拱豬大戰
1.8破解手記--演算法分析
作者:newlaos[DFCG]
軟體名稱:拱豬大戰
1.8(棋牌遊戲)
整理日期:2003.3.14
檔案大小:1107KB
軟體授權:共享軟體
使用平臺:Win9x/Me/NT/2000/XP
釋出公司:"http://www.joygames.com/
軟體簡介:支援對家結盟模式,支援現在流行的拱雙豬,允許亮牌,支援"除羊全亮",支援幾乎所有的拱豬規則;可以隨時察看亮牌和已經得到的分數;具有積分榜和英雄榜,更加你的成就感;自由的設計軟體皮膚;軟體介面友好,易用性強.
加密方式:註冊碼
功能限制:次數限制
PJ工具:TRW20001.23註冊版、PE-SCAN3.31、W32Dasm8.93黃金版,FI2.5
PJ日期:2003-03-22
作者newlaos申明:只是學習,請不用於商業用途或是將本文方法制作的序號產生器任意傳播,造成後果,本人一概不負。
1、先用FI2.5看一下主程式“拱豬大戰.exe”,加了個ASPACK2.12的殼,先脫了它。這種殼很容易脫,用PE-scan3.31很快搞定。脫殼生成檔案UNPACK.EXE
2、用W32Dasm8.93黃金版對UNPACK.EXE進行靜態反彙編,再用串式資料參考,找到"註冊碼輸入錯誤,請重新檢查後輸入!"(很經典的句子),雙擊來到下面程式碼段。這樣就找到註冊碼的計算部分。
3、再用TRW20001.23註冊版進行動態跟蹤,下斷BPX 00425ACE(通常在註冊成功與否的前面一些下斷,這樣,才能找到關鍵部分),先輸入假碼78787878
......
......
:00425ACE
66C747101400 mov [edi+10], 0014
:00425AD4
33C9 xor
ecx, ecx
:00425AD6 894DF4
mov dword ptr [ebp-0C], ecx
:00425AD9 8D55F4
lea edx, dword ptr [ebp-0C]
:00425ADC
FF471C inc [edi+1C]
:00425ADF
8B830C030000 mov eax, dword ptr [ebx+0000030C]
:00425AE5
E8D6EB0300 call 004646C0
:00425AEA
8D4DF4 lea ecx,
dword ptr [ebp-0C]
:00425AED 33D2
xor edx, edx
:00425AEF 8B01
mov eax, dword ptr [ecx]
:00425AF1
50 push
eax
:00425AF2 8955F0
mov dword ptr [ebp-10], edx
:00425AF5 FF471C
inc [edi+1C]
:00425AF8 8D55F0
lea edx, dword ptr [ebp-10]
:00425AFB
8B8310030000 mov eax, dword ptr [ebx+00000310]
:00425B01
E8BAEB0300 call 004646C0
:00425B06
8D4DF0 lea ecx,
dword ptr [ebp-10]
:00425B09 8B01
mov eax, dword ptr [ecx] <===EAX=78787878
:00425B0B
50 push
eax <===這裡壓進去的還是78787878
:00425B0C
E81F39FFFF call 00419430
<===最後推斷,這裡就是演算法CALL了,F8跟進
:00425B11 83C408
add esp, 00000008
:00425B14
BA02000000 mov edx, 00000002
:00425B19
50 push
eax <===這裡EAX的值就決定了,不能為0
:00425B1A
8D45F0 lea eax,
dword ptr [ebp-10]
:00425B1D FF4F1C
dec [edi+1C]
:00425B20 E88B6B0900
call 004BC6B0
:00425B25 FF4F1C
dec [edi+1C]
:00425B28 8D45F4
lea eax, dword ptr [ebp-0C]
:00425B2B
BA02000000 mov edx, 00000002
:00425B30
E87B6B0900 call 004BC6B0
:00425B35
59 pop
ecx <===說明,最終判斷是由堆疊最上面的值決定!向上看
:00425B36
84C9 test
cl, cl <===如果,ECX的低位是0,則下面就跳轉了,也就OVER了
:00425B38
0F84EF010000 je 00425D2D
<===關鍵跳轉
:00425B3E B201
mov dl, 01
:00425B40 A1808F4900
mov eax, dword ptr [00498F80]
:00425B45
E836350700 call 00499080
:00425B4A
8BF0 mov
esi, eax
:00425B4C BA02000080 mov
edx, 80000002
:00425B51 8BC6
mov eax, esi
:00425B53 E8CC690900
call 004BC524
:00425B58 66C747102000
mov [edi+10], 0020
.......
.......
中間這段程式碼的主要功能,就是在驗證註冊碼正確後,把註冊資訊寫入登錄檔,與關鍵演算法無關,所以省略
.......
.......
*
Possible StringData Ref from Data Obj ->"資訊"
|
:00425CCC 6800E24F00
push 004FE200
*
Possible StringData Ref from Data Obj ->"註冊成功!註冊版本在重新啟動程式後生效!"
|
:00425CD1 68D9E14F00
push 004FE1D9
:00425CD6 8BC3
mov eax, ebx
:00425CD8 E873500400
call 0046AD50
:00425CDD 50
push
eax
:00425CDE E8FD1B0D00 call
004F78E0
:00425CE3 BAEBFFFFFF mov
edx, FFFFFFEB
:00425CE8 8B83F8020000 mov
eax, dword ptr [ebx+000002F8]
:00425CEE E8F16C0900
call 004BC9E4
:00425CF3 8BD0
mov edx, eax
:00425CF5 8B83F8020000
mov eax, dword ptr [ebx+000002F8]
:00425CFB
FFD2 call
edx
* Referenced by
a (U)nconditional or (C)onditional Jump at Address:
|:00425BBC(C)
|
:00425CFD
8BC6 mov
eax, esi
:00425CFF E8EC330700 call
004990F0
:00425D04 8BDE
mov ebx, esi
:00425D06 895DCC
mov dword ptr [ebp-34], ebx
:00425D09 85DB
test ebx, ebx
:00425D0B
7439 je 00425D46
:00425D0D
8B03 mov
eax, dword ptr [ebx]
:00425D0F 8945D0
mov dword ptr [ebp-30], eax
:00425D12 66C747106800
mov [edi+10], 0068
:00425D18 BA03000000
mov edx, 00000003
:00425D1D 8B45CC
mov eax, dword ptr
[ebp-34]
:00425D20 8B08
mov ecx, dword ptr [eax]
:00425D22 FF51FC
call [ecx-04]
:00425D25 66C747105C00
mov [edi+10], 005C
:00425D2B EB19
jmp 00425D46
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00425B38(C)
<===由於上一行是無條件跳轉,所以,關鍵跳轉在00425B38
|
:00425D2D
6A40 push
00000040
* Possible
StringData Ref from Data Obj ->"資訊"
|
:00425D2F 6826E24F00 push
004FE226
* Possible
StringData Ref from Data Obj ->"註冊碼輸入錯誤,請重新檢查後輸入!"
|
:00425D34 6805E24F00
push 004FE205
:00425D39 8BC3
mov eax, ebx
:00425D3B E810500400
call 0046AD50
:00425D40 50
push eax
:00425D41
E89A1B0D00 call 004F78E0
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00425D0B(C),
:00425D2B(U)
|
:00425D46 8B17
mov edx, dword ptr [edi]
:00425D48 64891500000000
mov dword ptr fs:[00000000], edx
*
Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00425AC9(U),
:00425C0D(U)
|
:00425D4F 5F
pop edi
:00425D50 5E
pop esi
:00425D51 5B
pop ebx
:00425D52
8BE5 mov
esp, ebp
:00425D54 5D
pop ebp
:00425D55 C3
ret
......
......
------00425B0C
call 00419430 演算法CALL,F8跟進到下列程式碼段-----------------------
:00419430
55 push
ebp
:00419431 8BEC
mov ebp, esp
:00419433 81C4BCFEFFFF
add esp, FFFFFEBC
:00419439 53
push ebx
:0041943A 56
push esi
:0041943B
57 push
edi
:0041943C 8D7DCC
lea edi, dword ptr [ebp-34]
:0041943F B830AC4F00
mov eax, 004FAC30
:00419444 E88B750900
call 004B09D4
:00419449 C7471C02000000
mov [edi+1C], 00000002
:00419450 8D550C
lea edx, dword ptr [ebp+0C]
:00419453
8D450C lea eax,
dword ptr [ebp+0C]
:00419456 E835310A00
call 004BC590
:0041945B FF471C
inc [edi+1C]
:0041945E 8D5508
lea edx, dword ptr [ebp+08]
:00419461
66C747100800 mov [edi+10], 0008
:00419467
8D4508 lea eax,
dword ptr [ebp+08]
:0041946A E821310A00
call 004BC590
:0041946F FF471C
inc [edi+1C]
:00419472 57
push edi
:00419473 8DBDBCFEFFFF
lea edi, dword ptr [ebp+FFFFFEBC]
*
Possible StringData Ref from Data Obj ->""
|
:00419479 BEF4814F00
mov esi, 004F81F4
:0041947E B90C000000
mov ecx, 0000000C
:00419483 F3
repz
:00419484 A5
movsd
:00419485 837D0800
cmp dword ptr [ebp+08],
00000000
:00419489 5F
pop edi
:0041948A 7408
je 00419494
:0041948C 8B4508
mov eax, dword ptr [ebp+08] <===EAX=78787878
:0041948F
8B50FC mov edx,
dword ptr [eax-04] <===EDX=8(為輸入的註冊碼長度)
:00419492 EB02
jmp 00419496
<===從這裡跳走
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041948A(C)
|
:00419494
33D2 xor
edx, edx
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:00419492(U)
|
:00419496
83FA0B cmp edx,
0000000B
<===跳到這裡,可以看出,規定註冊註冊碼必須等於0xB(也就是11位),將輸入的假碼改為78787878787,重新來
:00419499
7432 je 004194CD
<===當註冊碼長度為11位時,這裡要跳走
:0041949B 33C0
xor eax, eax
:0041949D
BA02000000 mov edx, 00000002
:004194A2
50 push
eax
:004194A3 8D4508
lea eax, dword ptr [ebp+08]
:004194A6 FF4F1C
dec [edi+1C]
:004194A9 E802320A00
call 004BC6B0
:004194AE FF4F1C
dec [edi+1C]
:004194B1
8D450C lea eax,
dword ptr [ebp+0C]
:004194B4 BA02000000
mov edx, 00000002
:004194B9 E8F2310A00
call 004BC6B0
:004194BE 58
pop eax
:004194BF 8B17
mov edx, dword ptr
[edi]
:004194C1 64891500000000 mov dword
ptr fs:[00000000], edx
:004194C8 E9B0020000
jmp 0041977D <===如果,輸入的假碼長度不為11,則從這裡跳到OVER
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419499(C)
|
:004194CD
BE01000000 mov esi, 00000001
<===從上面跳到這裡
:004194D2 8D8548FFFFFF
lea eax, dword ptr [ebp+FFFFFF48]
:004194D8 8945C8
mov dword ptr [ebp-38], eax
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004195A3(C)
|
<===從這一行開始到004195A3是一個迴圈結構,主要的功能是檢測輸入的11位註冊碼,是不是數字
:004194DB
66C747101400 mov [edi+10], 0014
:004194E1 33D2
xor edx, edx
:004194E3 8D4DFC
lea ecx, dword ptr [ebp-04]
:004194E6 8955FC
mov dword ptr [ebp-04],
edx
:004194E9 51
push ecx
:004194EA FF471C
inc [edi+1C]
:004194ED B901000000
mov ecx, 00000001
:004194F2 8BD6
mov edx, esi
:004194F4 8D4508
lea eax, dword ptr
[ebp+08]
:004194F7 E82C330A00 call
004BC828
:004194FC 837DFC00
cmp dword ptr [ebp-04], 00000000
:00419500 7405
je 00419507
:00419502 8B45FC
mov eax, dword ptr
[ebp-04]
:00419505 EB05
jmp 0041950C
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419500(C)
|
:00419507
B888874F00 mov eax, 004F8788
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419505(U)
|
:0041950C
8A18 mov
bl, byte ptr [eax]
:0041950E FF4F1C
dec [edi+1C]
:00419511 8D45FC
lea eax, dword ptr [ebp-04]
:00419514 BA02000000
mov edx, 00000002
:00419519
E892310A00 call 004BC6B0
:0041951E
0FBEC3 movsx eax,
bl <===這裡就是將依次取出的註冊碼的ASC碼值的(16進製表示形式),放入EAX
:00419521 83F830
cmp eax, 00000030
--
:00419524 7C05
jl 0041952B |
:00419526 83F839
cmp eax, 00000039
|===>很典型的一段程式碼,功能是看輸入的註冊碼每位是不是數字
:00419529 7E32
jle 0041955D
-- ===>如果是數字,這裡小跳
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419524(C)
|
:0041952B
33C0 xor
eax, eax
<===一但有一位是註冊碼不是數字,就來到這裡,隨著00419558的無條件跳轉,也就是要OVER了
:0041952D
BA02000000 mov edx, 00000002
:00419532
50 push
eax
:00419533 8D4508
lea eax, dword ptr [ebp+08]
:00419536 FF4F1C
dec [edi+1C]
:00419539 E872310A00
call 004BC6B0
:0041953E FF4F1C
dec [edi+1C]
:00419541
8D450C lea eax,
dword ptr [ebp+0C]
:00419544 BA02000000
mov edx, 00000002
:00419549 E862310A00
call 004BC6B0
:0041954E 58
pop eax
:0041954F 8B17
mov edx, dword ptr
[edi]
:00419551 64891500000000 mov dword
ptr fs:[00000000], edx
:00419558 E920020000
jmp 0041977D
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419529(C)
|
:0041955D
66C747102000 mov [edi+10], 0020 <===每次迴圈(共11次了),只要註冊都是數字,就會從上面小跳到這裡
:00419563
33C9 xor
ecx, ecx
:00419565 8D45F8
lea eax, dword ptr [ebp-08]
:00419568 894DF8
mov dword ptr [ebp-08], ecx
:0041956B
50 push
eax
:0041956C FF471C
inc [edi+1C]
:0041956F 8D4508
lea eax, dword ptr [ebp+08]
:00419572 B901000000
mov ecx, 00000001
:00419577 8BD6
mov edx, esi
:00419579
E8AA320A00 call 004BC828
:0041957E
8D45F8 lea eax,
dword ptr [ebp-08]
:00419581 E886330A00
call 004BC90C
:00419586 8B55C8
mov edx, dword ptr [ebp-38]
:00419589 8902
mov dword ptr [edx],
eax
:0041958B FF4F1C
dec [edi+1C]
:0041958E 8D45F8
lea eax, dword ptr [ebp-08]
:00419591 BA02000000
mov edx, 00000002
:00419596 E815310A00
call 004BC6B0
:0041959B 46
inc
esi
:0041959C 8345C804 add
dword ptr [ebp-38], 00000004
:004195A0 83FE0B
cmp esi, 0000000B <===ESI實際上是個計數器
:004195A3
0F8E32FFFFFF jle 004194DB
<===迴圈11次後,這裡就不再跳轉了!
:004195A9 BE01000000
mov esi, 00000001
<===呵呵,這個計數器又被初始化了。也就是又要迴圈了,幾次呢看下面0041967C行,原來是9次。
:004195AE
8D85F0FEFFFF lea eax, dword ptr [ebp+FFFFFEF0]
:004195B4
8945C4 mov dword
ptr [ebp-3C], eax
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041967F(C)
|
<===從這一行開始到0041967F是一個迴圈結構,迴圈9次,正好是取機器碼的9次了。我的機器碼是642652146
:004195B7
66C747102C00 mov [edi+10], 002C
:004195BD
33D2 xor
edx, edx
:004195BF 8D4DF4
lea ecx, dword ptr [ebp-0C]
:004195C2 8955F4
mov dword ptr [ebp-0C], edx
:004195C5
51 push
ecx
:004195C6 FF471C
inc [edi+1C]
:004195C9 B901000000
mov ecx, 00000001
:004195CE 8BD6
mov edx, esi
:004195D0 8D450C
lea eax, dword ptr [ebp+0C] <===EAX裡放的是一個地址指標,指向機器碼
:004195D3
E850320A00 call 004BC828
<===這裡當然是將機器碼處理一下了。
:004195D8
837DF400 cmp dword ptr
[ebp-0C], 00000000
:004195DC 7405
je 004195E3
:004195DE 8B45F4
mov eax, dword ptr [ebp-0C]
:004195E1
EB05 jmp
004195E8
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:004195DC(C)
|
:004195E3
B889874F00 mov eax, 004F8789
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004195E1(U)
|
:004195E8
8A18 mov
bl, byte ptr [eax]
:004195EA FF4F1C
dec [edi+1C]
:004195ED 8D45F4
lea eax, dword ptr [ebp-0C]
:004195F0 BA02000000
mov edx, 00000002
:004195F5
E8B6300A00 call 004BC6B0
:004195FA
0FBEC3 movsx eax,
bl
:004195FD 83F830
cmp eax, 00000030
----很典型的一小段程式碼(功能同上)
:00419600 7C05
jl 00419607
----
:00419602 83F839
cmp eax, 00000039 ----
:00419605
7E32 jle
00419639 ----這裡小跳
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419600(C)
|
:00419607
33C0 xor
eax, eax
:00419609 BA02000000 mov
edx, 00000002
:0041960E 50
push eax
:0041960F 8D4508
lea eax, dword ptr [ebp+08]
:00419612 FF4F1C
dec [edi+1C]
:00419615
E896300A00 call 004BC6B0
:0041961A
FF4F1C dec [edi+1C]
:0041961D
8D450C lea eax,
dword ptr [ebp+0C]
:00419620 BA02000000
mov edx, 00000002
:00419625 E886300A00
call 004BC6B0
:0041962A 58
pop eax
:0041962B 8B17
mov edx, dword ptr
[edi]
:0041962D 64891500000000 mov dword
ptr fs:[00000000], edx
:00419634 E944010000
jmp 0041977D
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419605(C)
|
:00419639
66C747103800 mov [edi+10], 0038
<===小跳來到這裡
:0041963F 33C9
xor ecx, ecx
:00419641 8D45F0
lea eax, dword ptr
[ebp-10]
:00419644 894DF0
mov dword ptr [ebp-10], ecx
:00419647 50
push eax
:00419648 FF471C
inc [edi+1C]
:0041964B
8D450C lea eax,
dword ptr [ebp+0C]
:0041964E B901000000
mov ecx, 00000001
:00419653 8BD6
mov edx, esi
:00419655 E8CE310A00
call 004BC828
:0041965A 8D45F0
lea eax, dword ptr [ebp-10]
:0041965D
E8AA320A00 call 004BC90C
:00419662
8B55C4 mov edx,
dword ptr [ebp-3C]
:00419665 8902
mov dword ptr [edx], eax
:00419667 FF4F1C
dec [edi+1C]
:0041966A
8D45F0 lea eax,
dword ptr [ebp-10]
:0041966D BA02000000
mov edx, 00000002
:00419672 E839300A00
call 004BC6B0
:00419677 46
inc esi
:00419678 8345C404
add dword ptr [ebp-3C],
00000004
:0041967C 83FE09
cmp esi, 00000009
:0041967F 0F8E32FFFFFF
jle 004195B7 <===迴圈9次後,這裡就不再跳轉了!
:00419685
33F6 xor
esi, esi <===ESI被清0了。又要迴圈了。
:00419687
8D95BCFEFFFF lea edx, dword ptr [ebp+FFFFFEBC]
:0041968D 8D8548FFFFFF lea
eax, dword ptr [ebp+FFFFFF48]
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004196A8(C)
|
<===這一行到004196A5,又構成一個小迴圈
:00419693
8B1A mov
ebx, dword ptr [edx]
<===這裡出現11次的數字是固定的(4,A,6,8,9,2,1,3,5,7,B
),估計是機器碼的變形(後來發現沒有用)
:00419695 8B08
mov ecx, dword ptr [eax]
<===這裡依次就是我們輸入的註冊碼的了(7,8,7,8,7,8,7,8,7,8,7)
:00419697
83C004 add eax,
00000004
:0041969A 83C204
add edx, 00000004
:0041969D 46
inc esi
:0041969E 898C9D14FFFFFF
mov dword ptr [ebp+4*ebx-000000EC], ecx
:004196A5
83FE0A cmp esi,
0000000A <===由於初始值是0,所以這裡也要迴圈11次,
:004196A8 7EE9
jle 00419693
<===迴圈11次後,不再跳轉了。
:004196AA BE01000000
mov esi, 00000001 <===又初始化了,呵呵,又要迴圈了
:004196AF
8D55A0 lea edx,
dword ptr [ebp-60]
:004196B2 8D8518FFFFFF
lea eax, dword ptr [ebp+FFFFFF18]
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004196C6(C)
<===這一行到004196C6,又構成一個小迴圈
|
:004196B8 8B08
mov ecx, dword ptr [eax]
****注:這裡的ECX的取值如下1、取輸入的註冊碼第7位(7)
2、取輸入的註冊碼第6位(8)
3、取輸入的註冊碼第8位(8)
4、取輸入的註冊碼第1位(7)
5、取輸入的註冊碼第9位(7)
6、取輸入的註冊碼第3位(7)
7、取輸入的註冊碼第10位(8)
8、取輸入的註冊碼第4位(8)
9、取輸入的註冊碼第5位(7)
****注:這裡可以推斷出輸入的註冊碼第2位和第11位,可以為任意數字!
由於是定位取值,所在用假碼78787878787將很定位,所以將假碼改為12345678901,重新來。
對應的取值變碼是768193045,記住這個對應關係後面用得到!
:004196BA
890A mov
dword ptr [edx], ecx
<===取得這些值依次放在EDX步進為4的位置上,ECX的初始地址8AF250正好與最後比較的地址相同,故要仔細觀察其變化
:004196BC
46 inc
esi
:004196BD 83C204
add edx, 00000004
:004196C0 83C004
add eax, 00000004
:004196C3 83FE09
cmp esi, 00000009
<===初始值是1,所以要迴圈9次。
:004196C6 7EF0
jle 004196B8 <===迴圈9次後,不再跳轉了。
:004196C8
BB04000000 mov ebx, 00000004
:004196CD
BE01000000 mov esi, 00000001 <===又初始化了,呵呵,又要迴圈了
:004196D2
3BDE cmp
ebx, esi <===不相等
:004196D4 7C2B
jl 00419701
<===不會跳
* Referenced
by a (U)nconditional or (C)onditional Jump at Address:
|:004196FF(C)
<===這一行到004196FF,又構成一個小迴圈,
:004196D6 8D8574FFFFFF
lea eax, dword ptr [ebp+FFFFFF74]
:004196DC 50
push eax
:004196DD
8D559C lea edx,
dword ptr [ebp-64]
:004196E0 52
push edx
:004196E1 E8FAFCFFFF
call 004193E0
<===第一個CALL會使我們所關心的值(以8AF250為起始地址的步進為4的位置)有變化,F8進去看得究竟吧
:004196E6
83C408 add esp,
00000008
:004196E9 8D4D9C
lea ecx, dword ptr [ebp-64]
:004196EC 51
push ecx
:004196ED 8D8574FFFFFF
lea eax, dword ptr [ebp+FFFFFF74]
:004196F3
50 push
eax
:004196F4 E8E7FCFFFF call
004193E0
<===第二個同樣的CALL使我們所關心的值有變化
:004196F9
83C408 add esp,
00000008
:004196FC 46
inc esi <===esi為計數器,每次加1
:004196FD
3BDE cmp
ebx, esi <===EBX=4
:004196FF 7DD5
jge 004196D6
<===這裡迴圈4次,但由於有了兩個同樣的CALL,所以實際上768193045(假碼的變形)已經被處理了8次,如何處理的呢?我們再研究一下call
004193E0(功能在下面有說),
**** 將768193045處理後為:524472195
將524472195處理後為:502225745
將502225745處理後為:055757895
將055757895處理後為:550523445
將550523445處理後為:969148595
將969148595處理後為:815477145
將815477145處理後為:083225295
將083225295處理後為:826757845
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004196D4(C)
|
:00419701
BE01000000 mov esi, 00000001 <===又初始化了,呵呵,又要迴圈了
:00419706
8D95F0FEFFFF lea edx, dword ptr [ebp+FFFFFEF0]
:0041970C
8D45A0 lea eax,
dword ptr [ebp-60]
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041974E(C)
|
<===這一行到0041974E,又構成一個小迴圈,將註冊碼處理成826757845後,與機器碼依次比較,只要一次錯了,就OVER
:0041970F
8B08 mov
ecx, dword ptr [eax] <===EAX的初始地址8AF250
:00419711 3B0A
cmp ecx, dword ptr [edx]
<===ECX的初始地址8AF1A0
:00419713 742F
je 00419744 <===這裡必須跳走,不然到00419742一行無條件跳轉,就OVER了
:00419715
33C0 xor
eax, eax
:00419717 BA02000000 mov
edx, 00000002
:0041971C 50
push eax
:0041971D 8D4508
lea eax, dword ptr [ebp+08]
:00419720 FF4F1C
dec [edi+1C]
:00419723
E8882F0A00 call 004BC6B0
:00419728
FF4F1C dec [edi+1C]
:0041972B
8D450C lea eax,
dword ptr [ebp+0C]
:0041972E BA02000000
mov edx, 00000002
:00419733 E8782F0A00
call 004BC6B0
:00419738 58
pop eax
:00419739 8B17
mov edx, dword ptr
[edi]
:0041973B 64891500000000 mov dword
ptr fs:[00000000], edx
:00419742 EB39
jmp 0041977D
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419713(C)
|
:00419744
46 inc
esi
:00419745 83C204
add edx, 00000004
:00419748 83C004
add eax, 00000004
:0041974B 83FE09
cmp esi, 00000009
:0041974E
7EBF jle
0041970F <===迴圈9次後,不再跳轉了
:00419750
B001 mov
al, 01
:00419752 BA02000000 mov
edx, 00000002
:00419757 50
push eax
:00419758 8D4508
lea eax, dword ptr [ebp+08]
:0041975B FF4F1C
dec [edi+1C]
:0041975E
E84D2F0A00 call 004BC6B0
:00419763
FF4F1C dec [edi+1C]
:00419766
8D450C lea eax,
dword ptr [ebp+0C]
:00419769 BA02000000
mov edx, 00000002
:0041976E E83D2F0A00
call 004BC6B0
:00419773 58
pop eax
<===這裡要求是EAX出來的不能為0
:00419774 8B17
mov edx, dword ptr [edi]
:00419776
64891500000000 mov dword ptr fs:[00000000],
edx
* Referenced by
a (U)nconditional or (C)onditional Jump at Addresses:
|:004194C8(U), :00419558(U),
:00419634(U), :00419742(U)
|
:0041977D 5F
pop edi
:0041977E 5E
pop esi
:0041977F
5B pop
ebx
:00419780 8BE5
mov esp, ebp
:00419782 5D
pop ebp
:00419783 C3
ret
.......
.......
--------------F8進入的數字變形call
004193E0-------------------------------------------------
* Referenced by a
CALL at Addresses:
|:004196E1 , :004196F4
|
:004193E0 55
push ebp
:004193E1 8BEC
mov ebp, esp
:004193E3 53
push ebx
:004193E4
8B450C mov eax,
dword ptr [ebp+0C]
:004193E7 8B5508
mov edx, dword ptr [ebp+08]
:004193EA 8B4A24
mov ecx, dword ptr [edx+24]
:004193ED
894824 mov dword
ptr [eax+24], ecx
:004193F0 8B4A20
mov ecx, dword ptr [edx+20]
:004193F3 3B4A24
cmp ecx, dword ptr [edx+24]
<===第8位與第9位相比
:004193F6 7D04
jge 004193FC
<===相等就跳走
:004193F8 8342200A
add dword ptr [edx+20], 0000000A <===如果不相等,這裡第8位就加上A(防止第8位比第9小)
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004193F6(C)
|
:004193FC
8B4A20 mov ecx,
dword ptr [edx+20]
:004193FF 2B4A24
sub ecx, dword ptr [edx+24]
<===如果第8位與第9位相等,則ECX=0;如果不等,則ECX=第8位+第9位
:00419402
894820 mov dword
ptr [eax+20], ecx <===將ECX的值
:00419405 B907000000
mov ecx, 00000007 <===ECX為計數器,初始值為7
:0041940A
83C020 add eax,
00000020
:0041940D 83C21C
add edx, 0000001C
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041942A(C)
|
<===這一行到0041942A,又構成一個小迴圈
:00419410 8B1A
mov ebx, dword ptr [edx]
:00419412
3B18 cmp
ebx, dword ptr [eax]
:00419414 7D03
jge 00419419
:00419416 83020A
add dword ptr [edx], 0000000A
*
Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00419414(C)
|
:00419419
8B1A mov
ebx, dword ptr [edx]
:0041941B 2B18
sub ebx, dword ptr [eax]
:0041941D 8958FC
mov dword ptr [eax-04],
ebx
:00419420 49
dec ecx <===計數器減去1
:00419421
83C0FC add eax,
FFFFFFFC
:00419424 83C2FC
add edx, FFFFFFFC
:00419427 83F901
cmp ecx, 00000001
:0041942A 7DE4
jge 00419410
<===共迴圈7次
:0041942C 5B
pop ebx
:0041942D 5D
pop ebp
:0041942E C3
ret
*** 此小段功能是(為了說明問題,這裡假設在新值尾部加個0,這個0在得出新值後去掉):將得到的9位數字,從尾部開始依次取值,例如取到第N位值,減去新值的第N+1的值(如果不夠減,則第N位值就加上10),得到的數就是新值的第N位值!
*** 768193045經過這段處理後,就應該是524472195 (詳細數字處理變化情況,在上面有列表)
-----------------------------------------------------------------------------------
4、演算法總結:
a、將註冊碼12345678901,按特定取位得到768193045
b、將768193045經過8次的處理
768193045
524472195
502225745
055757895
550523445
969148595
815477145
083225295
826757845 <===將最後這個值與機器碼比較
c、反推的話就是:假設在舊值尾部加個0,新值第N位=舊第N位值+舊第N+1位值(如果有進位,就只取個位數),
機器碼做如此處理8次,再按當初取碼位置反歸位,就得到了註冊碼。
d、我的機器碼是:64265214 註冊碼就是:4?82648431?(?為任意數字)
5、序號產生器的製作:(我的C語言沒學完,就不在這現醜了),哪位C高手請幫忙寫一段程式碼給我,謝謝!(TC就可以了,其它的看不懂:)
6、註冊資訊存放在登錄檔:(刪除整個鍵值就成未註冊版本)
[HKEY_LOCAL_MACHINE\Software\Hearts\Register]
"user"="newlaos"
"pass"="48826484318"
相關文章
- 拱豬大戰 V2.3XP 演算法破解手記2015-11-15演算法
- HTMLock 1.9.3破解手記---演算法分析2003-06-27HTML演算法
- IEPopupKiller 1.2破解手記--演算法分析2015-11-15演算法
- QuickCD 1.0.320破解手記--演算法分析2015-11-15UI演算法
- GreenBrowser 1.0.312破解手記--演算法分析2015-11-15演算法
- Golden 5.7 Build 391破解手記--演算法分析2015-11-15GoUI演算法
- Setup2Go 1.97破解手記--演算法分析2015-11-15Go演算法
- 《豬弟拱Java》連載番外篇:Java代理(中)2018-01-16Java
- 《豬弟拱Java》連載番外篇:Java代理(上)2018-01-15Java
- pcmedik V5.4.8.2003破解手記--演算法分析2003-05-10演算法
- 極速傳真[SpeedFax] 2.4 破解手記--程式逆向分析演算法2015-11-15演算法
- Advanced MP3WMA Recorder 3.7.3破解手記--完美演算法分析2015-11-15演算法
- 法律文書、合同樣本庫
5.10破解手記--演算法分析2015-11-15演算法
- Iparmor 木馬克星 V5.40 Build 0414破解手記-演算法分析2015-11-15UI演算法
- MySQL Manager 2.8.0.1脫殼破解手記破解分析2004-11-03MySql
- 奇門遁甲演義V6.3破解手記--註冊碼演算法分析2015-11-15演算法
- JDK1.8原始碼分析筆記-HashMap2019-03-03JDK原始碼筆記HashMap
- Bannershop 4.5破解手記2015-11-15
- Irfanview破解手記 (668字)2001-02-02View
- Download Boost 2002 Go 2.0漢化版演算法破解手記2015-11-15Go演算法
- 《只狼》小 Boss 戰分析:戰鬥記憶-武士大將 河原田直盛2019-04-25
- 《鐵甲風暴之黑色戰線》免CD破解手記 (5千字)2002-02-14
- HashMap原始碼分析(JDK 1.8)2018-02-04HashMap原始碼JDK
- 破大防2024-09-22
- hanami1005破解手記2003-08-19
- 《Erlang
4.08》另類破解手記2002-06-24
- 大豬網網頁遊戲平臺2019-05-11網頁遊戲
- JDK1.8 hashMap原始碼分析2020-04-07JDKHashMap原始碼
- HashMap原始碼分析 JDK1.82019-03-25HashMap原始碼JDK
- ArrayList原始碼分析(JDK1.8)2021-02-03原始碼JDK
- 原始碼分析–HashSet(JDK1.8)2019-01-21原始碼JDK
- 原始碼分析–ArrayList(JDK1.8)2019-01-17原始碼JDK
- java SE 1.8中Collection介面分析2016-11-08Java
- ArrayList原始碼分析 jdk1.82018-04-08原始碼JDK
- 【 標題:SmartWhoIs 3.0 (build 21) 破解手記
】2000-11-30UI
- GetSmart破解手記 (1011字)2001-02-02
- 分析家資料批量轉換器暴力破解手記 (3千字)2001-09-07
- 【筆記】《Python大戰機器學習》2018-03-12筆記Python機器學習