聯眾鬥地主計牌器V2.2註冊演算法分析
【破解作者】 mejy【BCG】【DFCG】【FCG】【NUKE】
【作者郵箱】 yjychao@sohu.com
【作者主頁】 mejy.126.com
【使用工具】 OD1.09d,W32ASM
【破解平臺】 Win2000
【軟體名稱】 聯眾鬥地主計牌器
【下載地址】 http://www3.skycn.com/soft/1436.html
【軟體簡介】 軟體介紹:可用於聯眾一副牌和兩副牌的鬥地主遊戲,具有自動記錄已出牌、剩餘牌和剩餘張數的功能,使用者註冊後不是地主也能看底牌(二副牌時),軟體介面美觀,使用方便
更新日期:2004-02-16 14:50:20
保護方式:反除錯,採用Aspack加殼,手動脫去,檢測DELPHI編寫
【軟體大小】 641K
【加殼方式】 Aspack
【破解宣告】 我是一隻小菜鳥,偶得一點心得,願與大家分享:)哎,都沒人追演算法了,都脫殼去了。呵呵!!!
--------------------------------------------------------------------------------
【破解內容】
我們脫殼後利用W32ASM反彙編查詢"軟體已註冊",可以找到下面的地方
0045A6D0 /. 55 PUSH EBP可在此設斷,在社斷之前建議你試著註冊一次,因為不論註冊是否成功,程式會將你輸入的註冊碼儲存在登錄檔當中。並且如果註冊失敗程式不會提示,我們猜想程式每次啟動時,必然會檢測程式是否已經註冊。我們除錯也可從這裡入手。好了下一步,你用OD載入程式,並在上面的地址社斷,F9呵呵,OD被無聲無息的關閉了。^_^不要著急,看來程式用了ANTI,我們重新來過F8單步執行,一步步抽絲撥繭,具體的單步執行後,看看在那個CALL會退出程式,然後重新來過,進入上面退出程式的CALL。來到下面的地方:
0045ABC0 /$ 55 PUSH EBP
0045ABC1 |. 8BEC MOV EBP,ESP
。。。。。。。。。。。。。
0045AC01 |. E8 9AD7FAFF CALL un_.004083A0
0045AC06 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
0045AC09 BA 64AC4500 MOV EDX,un_.0045AC64 ; ASCII "EXPLORER.EXE"
這裡幹什麼,哈哈如果呼叫該程式的主程式不是"EXPLORER.EXE"就強行退出
0045AC0E |. E8 FD9BFAFF CALL un_.00404810
0045AC13 |. 75 1D JE SHORT un_.0045AC32 改這裡就行了
0045AC15 |. 56 PUSH ESI ; /ProcessId
。。。。。。。。
0045AC4C . C3 RETN
0045A6D0 /. 55 PUSH EBP
0045A6D1 |. 8BEC MOV EBP,ESP
。。。。。。省略
0045A703 B8 94A74500 MOV EAX,un_.0045A794 ; ASCII "RegCode"
。。。。。。。。
0045A729 |. 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C]
0045A72C |. E8 BBB6FFFF CALL un_.00455DEC很明顯這裡很關鍵我們跟蹤
0045A731 |. 84C0 TEST AL,AL 條件
0045A733 |. 74 26 JE SHORT un_.0045A75B
0045A735 |. 33D2 XOR EDX,EDX
略。。。。。
0045A77D . C3 RETN
局級分析後來到這裡
00455568 /$ 55 PUSH EBP
00455569 |. 8BEC MOV EBP,ESP
。。。。。略
004555C2 |> 8D45 FC /LEA EAX,DWORD PTR SS:[EBP-4]
004555C5 |. 33C9 |XOR ECX,ECX
004555C7 |. BA 04000000 |MOV EDX,4
004555CC |. E8 EBD9FAFF |CALL un_.00402FBC
004555D1 |. 8D45 F8 |LEA EAX,DWORD PTR SS:[EBP-8]
004555D4 |. 50 |PUSH EAX
004555D5 |. B9 03000000 |MOV ECX,3
004555DA |. 8BD6 |MOV EDX,ESI
004555DC |. 8B43 30 |MOV EAX,DWORD PTR DS:[EBX+30]機器碼入棧
004555DF |. E8 40F3FAFF |CALL un_.00404924依次取機器碼的3位進行計算
004555E4 |. 8B45 F8 |MOV EAX,DWORD PTR SS:[EBP-8]
略
00455603 |. 50 |PUSH EAX ; /Arg1
00455604 |. 8D55 FC |LEA EDX,DWORD PTR SS:[EBP-4] ; |
00455607 |. 8BCF |MOV ECX,EDI 這裡是所取字串的長度,可能是3,當取道最後幾個字元時可能是1,2 計為"值1 " ; |
00455609 |. 8BC3 |MOV EAX,EBX ; |
0045560B |. E8 A8FBFFFF |CALL un_.004551B8 ; un_.004551B8
關鍵CALL一定要跟進 ,對上面取得的機器碼進行變形,見下面得分析
00455610 |. 8B55 F4 |MOV EDX,DWORD PTR SS:[EBP-C]轉移變形後的字串
00455613 |. 8D43 34 |LEA EAX,DWORD PTR DS:[EBX+34]
00455616 |. E8 B9F0FAFF |CALL un_.004046D4
0045561B |. 66:83BB 820000>|CMP WORD PTR DS:[EBX+82],0
00455623 |. 74 31 |JE SHORT un_.00455656
跳走下面一段程式碼在我分析中沒用到不知幹嗎的
00455625 |. 8B43 30 |MOV EAX,DWORD PTR DS:[EBX+30]
00455628 |. E8 9FF0FAFF |CALL un_.004046CC
0045562D |. 8945 F0 |MOV DWORD PTR SS:[EBP-10],EAX
00455630 |. DB45 F0 |FILD DWORD PTR SS:[EBP-10]
00455633 |. 8BC6 |MOV EAX,ESI
00455635 |. 48 |DEC EAX
00455636 |. 03F8 |ADD EDI,EAX
00455638 |. 897D EC |MOV DWORD PTR SS:[EBP-14],EDI
0045563B |. DB45 EC |FILD DWORD PTR SS:[EBP-14]
0045563E |. DEF1 |FDIVRP ST(1),ST
00455640 |. E8 3FD4FAFF |CALL un_.00402A84
00455645 |. 6BC8 64 |IMUL ECX,EAX,64
00455648 |. 8BD3 |MOV EDX,EBX
0045564A |. 8B83 84000000 |MOV EAX,DWORD PTR DS:[EBX+84]
00455650 |. FF93 80000000 |CALL DWORD PTR DS:[EBX+80]
00455656 |> 83C6 03 |ADD ESI,3
00455659 |. 8B43 30 |MOV EAX,DWORD PTR DS:[EBX+30]
0045565C |. E8 6BF0FAFF |CALL un_.004046CC
00455661 |. 3BF0 |CMP ESI,EAX
00455663 |.^0F8E 59FFFFFF JLE un_.004555C2一個迴圈處理的過程,跳回去
上面的CALL
004551B8 /$ 55 PUSH EBP
略
004551CC |. BA 05000000 MOV EDX,5
004551D1 |. E8 E6DDFAFF CALL un_.00402FBC
004551D6 |. 8A03 MOV AL,BYTE PTR DS:[EBX] 以下這幾句作用是逆序
004551D8 |. 8A53 02 MOV DL,BYTE PTR DS:[EBX+2]
004551DB |. 8813 MOV BYTE PTR DS:[EBX],DL
004551DD |. 8843 02 MOV BYTE PTR DS:[EBX+2],AL
004551E0 |. 8B13 MOV EDX,DWORD PTR DS:[EBX]
這裡我感覺很奇怪,我在這裡寫序號產生器時,想了好久,如何實現
例如"BFE"經上面的處理變為"EFB"
004551E2 |. 8BC2 MOV EAX,EDX 將逆序所得的ASCII碼付給EAX
004551E4 |. 25 0000FC00 AND EAX,0FC0000 進行與運算
004551E9 |. C1E8 12 SHR EAX,12 右移0x12位
004551EC |. 8A4406 3C MOV AL,BYTE PTR DS:[ESI+EAX+3C]
根據上面的結果查表,找到相應位置的字元付給AL,這就是對機器碼進行變形
在記憶體1177F14+3C的地方有一張字元表"ABCDEFGHIJKLMNOPQRST。。。"
第一個字元結果查的的字元為"Q";
004551F0 |. 8845 F7 MOV BYTE PTR SS:[EBP-9],AL
004551F3 |. 8BC2 MOV EAX,EDX
004551F5 |. 25 00F00300 AND EAX,3F000 計算第二個字元
004551FA |. C1E8 0C SHR EAX,0C
004551FD |. 8A4406 3C MOV AL,BYTE PTR DS:[ESI+EAX+3C]查表
00455201 |. 8845 F8 MOV BYTE PTR SS:[EBP-8],AL
00455204 |. 837D FC 01 CMP DWORD PTR SS:[EBP-4],1
這裡處理當經過幾次迴圈後,當上面"值1"等於1,跳到後面在轉化後的字串上加上"="
例如我得"BFEB0C28"經兩次迴圈後剩下"28"沒處理,這時在下面一個地方跳。
00455208 |. 7E 13 JLE SHORT un_.0045521D
0045520A |. 8BC2 MOV EAX,EDX
0045520C |. 25 C00F0000 AND EAX,0FC0 計算得到第三個字元
00455211 |. C1E8 06 SHR EAX,6
00455214 |. 8A4406 3C MOV AL,BYTE PTR DS:[ESI+EAX+3C]查表
00455218 |. 8845 F9 MOV BYTE PTR SS:[EBP-7],AL
0045521B |. EB 04 JMP SHORT un_.00455221
0045521D |> C645 F9 3D MOV BYTE PTR SS:[EBP-7],3D
比較字串轉換是否結束如果結束就在轉換後的字串後面加上"="所以轉換後的結果肯定為"********="的形式
00455221 |> 837D FC 02 CMP DWORD PTR SS:[EBP-4],2
00455225 |. 7E 0E JLE SHORT un_.00455235
00455227 |. 8BC2 MOV EAX,EDX
00455229 |. 83E0 3F AND EAX,3F
0045522C |. 8A4406 3C MOV AL,BYTE PTR DS:[ESI+EAX+3C]
00455230 |. 8845 FA MOV BYTE PTR SS:[EBP-6],AL
00455233 |. EB 04 JMP SHORT un_.00455239
00455235 |> C645 FA 3D MOV BYTE PTR SS:[EBP-6],3D加上"="
00455239 |> 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
0045523C |. 8D55 F7 LEA EDX,DWORD PTR SS:[EBP-9]
0045523F |. B9 05000000 MOV ECX,5
00455244 |. E8 33F4FAFF CALL un_.0040467C
00455249 |. 5E POP ESI
0045524A |. 5B POP EBX
0045524B |. 8BE5 MOV ESP,EBP
0045524D |. 5D POP EBP
0045524E . C2 0400 RETN 4 返回後來到下面
004559CC $ 55 PUSH EBP
略
00455A5D . 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]
00455A60 . E8 67ECFAFF CALL un_.004046CC這兒取得轉化後字串的長度
00455A65 . 8BF0 MOV ESI,EAX
00455A67 . 85F6 TEST ESI,ESI
00455A69 . 7E 3E JLE SHORT un_.00455AA9
00455A6B . BB 01000000 MOV EBX,1
00455A70 > 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]
下面是一個計算註冊碼的迴圈
00455A73 . 807C18 FF 3D CMP BYTE PTR DS:[EAX+EBX-1],3D
比較字串中所取的的字元是否是"="如果是則跳走。不對這裡進行處理
00455A78 . 74 2B JE SHORT un_.00455AA5
00455A7A . 8D45 E8 LEA EAX,DWORD PTR SS:[EBP-18]
00455A7D . 50 PUSH EAX
00455A7E . 8D45 E4 LEA EAX,DWORD PTR SS:[EBP-1C]
00455A81 . 8B55 EC MOV EDX,DWORD PTR SS:[EBP-14]
00455A84 . 8A541A FF MOV DL,BYTE PTR DS:[EDX+EBX-1]
依次取字串的每一位
00455A88 . E8 67EBFAFF CALL un_.004045F4
00455A8D . 8B55 E4 MOV EDX,DWORD PTR SS:[EBP-1C]
00455A90 . 8A4D F7 MOV CL,BYTE PTR SS:[EBP-9]
00455A93 . 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
00455A96 . E8 61000000 CALL un_.00455AFC 這裡又是關鍵我們跟進見下面
00455A9B . 8B55 E8 MOV EDX,DWORD PTR SS:[EBP-18]
00455A9E . 8BC7 MOV EAX,EDI
00455AA0 . E8 2FECFAFF CALL un_.004046D4這裡是對上面返回的字串進行連線
00455AA5 > 43 INC EBX
00455AA6 . 4E DEC ESI
00455AA7 .^75 C7 JNZ SHORT un_.00455A70
略
00455ABE . C3 RETN
上面的將變形後的機器碼經過計算求出註冊碼
00455AFC /$ 55 PUSH EBP
00455AFD |. 8BEC MOV EBP,ESP
00455AFF |. 83C4 F4 ADD ESP,-0C
00455B02 |. 53 PUSH EBX
00455B03 |. 8BD9 MOV EBX,ECX
00455B05 |. 8955 FC MOV DWORD PTR SS:[EBP-4],EDX這裡是上面取得字元
00455B08 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
00455B0B |. E8 A4EDFAFF CALL un_.004048B4
00455B10 |. 33C0 XOR EAX,EAX
00455B12 |. 55 PUSH EBP
00455B13 |. 68 615B4500 PUSH un_.00455B61
00455B18 |. 64:FF30 PUSH DWORD PTR FS:[EAX]
00455B1B |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
00455B1E |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
00455B21 |. 50 PUSH EAX
00455B22 |. 33C0 XOR EAX,EAX
00455B24 |. 8AC3 MOV AL,BL
00455B26 |. 8B1485 28CC450>MOV EDX,DWORD PTR DS:[EAX*4+45CC28]
這裡又有一張固定的表
"AL9=HtGzUJ4mvIJY3D7ykQgAYf+TjWCd1RhZl5oEOeBF8bF0ubKrVSaM6qp2n/xcN"
下面將知道他是幹嗎的!
00455B2D |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
00455B30 |. E8 D3EEFAFF CALL un_.00404A08關鍵CALL我們可以看看跟進
主要思想是在上面的字串中查詢取得上面位置字元的下標
00455B35 |. 8945 F4 MOV DWORD PTR SS:[EBP-C],EAX ; |
這裡EAX中儲存的就是那個下標
00455B38 |. C645 F8 00 MOV BYTE PTR SS:[EBP-8],0 ; |
00455B3C |. 8D55 F4 LEA EDX,DWORD PTR SS:[EBP-C] ; |
00455B3F |. 33C9 XOR ECX,ECX ; |
00455B41 |. B8 785B4500 MOV EAX,un_.00455B78 ; |ASCII "%0.2d"
00455B46 |. E8 E136FBFF CALL un_.0040922C ; un_.0040922C
這裡對下標進行轉化,將他轉化成十進位制的字串
例如字元"H"的位置是1,那麼轉化後形成的字串為"01";
00455B4B |. 33C0 XOR EAX,EAX
00455B4D |. 5A POP EDX
00455B4E |. 59 POP ECX
00455B4F |. 59 POP ECX
00455B50 |. 64:8910 MOV DWORD PTR FS:[EAX],EDX
00455B53 |. 68 685B4500 PUSH un_.00455B68
00455B58 |> 8D45 FC LEA EAX,DWORD PTR SS:[EBP-4]
00455B5B |. E8 B4E8FAFF CALL un_.00404414
00455B60 . C3 RETN
--------------------------------------------------------------------------------
【破解總結】
總結一下注冊演算法思想:大體是先根據取得的機器號(如何取得機器號,我跟了半天沒找到誰找到了,TELL ME)然後對他進行變形,每次取機器碼的3位,進行轉化演算法較煩見0045560B處的CALL,然後對變形後的字串的每一位一次查表,如果遇到"=",拋棄掉,否則取該字串在固定串2,的位置。然後將位置下標轉化成字串。逐位連線就形成了註冊碼!這個軟體演算法的CALL比較多,很容易糊塗。很感謝你能看到這裡!希望您看懂了!
我用VC寫了一個序號產生器,誰有興趣改變一下程式,使註冊碼出現在EDIT筐中,當然高手就免了!很簡單的,就一個地方。
--------------------------------------------------------------------------------
【版權宣告】 本文純屬技術交流, 轉載請註明作者並保持文章的完整, 謝謝!
相關文章
- JAVA集合練習:鬥地主發牌2017-04-17Java
- 鬥地主4.0註冊演算法,序號產生器在OCG論壇
(22千字)2015-11-15演算法
- Map實現鬥地主發牌有序版二2020-11-04
- 集合框架-模擬鬥地主洗牌和發牌案例2017-05-02框架
- 開心鬥地主1.7S4非法註冊破解 (512字)2001-06-16
- Instant Source 註冊演算法分析+註冊器原始碼2015-11-15演算法原始碼
- 開心鬥地主1.6標準版 註冊碼破解 (4千字)2001-04-25
- 集合框架-模擬鬥地主洗牌和發牌並對牌進行排序案例2017-05-02框架排序
- 1.cocos2d-x鬥地主實現-發牌2014-02-17
- Python鬥地主2024-10-15Python
- 模擬鬥地主2024-03-18
- supercleaner註冊演算法分析2015-11-15演算法
- 鬥地主AI演算法——第五章の總值計算2021-09-09AI演算法
- 珠聯跳棋2.27之註冊分析2003-06-09
- SpeedFlash註冊演算法分析(VB)2015-11-15演算法
- 財智老闆通3.04註冊版---註冊演算法分析2003-03-16演算法
- 自己實現鬥地主引擎2018-06-05
- Java鬥地主專案碎片2024-11-05Java
- 鬥地主 V3.0 Build 215 註冊碼破解(VB6-Pcode 形式) (4千字)2001-10-20UI
- 練習4. 鬥地主遊戲2016-11-14遊戲
- Android鬥地主遊戲原始碼2014-06-26Android遊戲原始碼
- 破解鬥地主1。0 (932字)2000-09-05
- 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演算法
- 蒼鷹象棋1.0
註冊演算法分析和序號產生器2004-05-16演算法
- Java寫的鬥地主遊戲原始碼2018-08-10Java遊戲原始碼
- 用Python破解鬥地主殘局2018-09-10Python
- DLL Show V4.4 註冊演算法分析2015-11-15演算法
- Disk
Chief 1.2 簡單註冊演算法分析2015-11-15演算法
- Python 三人鬥地主程式碼2018-12-05Python
- Golang多執行緒簡單鬥地主2020-09-12Golang執行緒
- 請教如何破解鬥地主 (269字)2000-07-29
- E族百變桌面6.0註冊演算法分析2015-11-15演算法
- FolderView 1.7
註冊演算法分析 (14千字)2015-11-15View演算法
- ffmpeg分析系列之一(註冊該註冊的)2010-11-04
- LanSee 註冊演算法2015-11-15演算法