也沒人說句話,再寫一篇 SantMat's ReverseME #2 數字遊戲 (12千字)
SantMat's ReverseME #2 數字遊戲
下載地址: http://www.reversemes.de/reversemes/reme2.zip
這個又是讓我們到程式裡去看任務,主要有三條:一是去掉開始時的視窗,二是把兩個按鈕的程式碼填上,每按一次隨機出現0-100的數,兩個按鈕分別對應兩個玩家,誰的數大就得到1分,先得50分者為勝,三是用鍵盤上的“M”和“Z”控制兩個按鈕。
先反彙編,從開頭看:
//********************** Start of Code in Object .text **************
Program Entry Point = 00401000 (SantMat-ReverseMe2.exe File Offset:00001600)
//******************** Program Entry Point ********
:00401000 6A00 push 00000000
* Reference To: KERNEL32.GetModuleHandleA, Ord:0111h
|
:00401002 E859010000 Call 00401160
:00401007 A39C304000 mov dword ptr [0040309C], eax
:0040100C 6A00 push 00000000
* Possible StringData Ref from Code Obj ->"U} "
|
:0040100E 6842104000 push 00401042 <-對話方塊的訊息處理
:00401013 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"MEMO"
|
:00401015 6800304000 push 00403000 <-看看,應該是開始時出現的對話方塊
:0040101A FF359C304000 push dword ptr [0040309C]
* Reference To: USER32.DialogBoxParamA, Ord:0092h
|
:00401020 E81D010000 Call 00401142 <-這叫"基於對話方塊的程式"吧,我不太懂
:00401025 6A00 push 00000000
* Reference To: KERNEL32.LoadLibraryA, Ord:01A9h
|
:00401027 E840010000 Call 0040116C
:0040102C 6A00 push 00000000
* Reference To: KERNEL32.FreeLibrary, Ord:00A2h
|
:0040102E E827010000 Call 0040115A
:00401033 6A00 push 00000000
:00401035 6A00 push 00000000
* Reference To: KERNEL32.GetProcAddress, Ord:0129h
|
:00401037 E82A010000 Call 00401166
:0040103C 50 push eax
* Reference To: KERNEL32.ExitProcess, Ord:0075h
|
:0040103D E812010000 Call 00401154
:00401042 55 push ebp
:00401043 8BEC mov ebp, esp
:00401045 817D0C10010000 cmp dword ptr [ebp+0C], 00000110
:0040104C 7502 jne 00401050
:0040104E EB66 jmp 004010B6
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040104C(C)
|
:00401050 837D0C10 cmp dword ptr [ebp+0C], 00000010
:00401054 750C jne 00401062
:00401056 6A00 push 00000000
:00401058 FF7508 push [ebp+08]
* Reference To: USER32.EndDialog, Ord:00B8h
|
:0040105B E8E8000000 Call 00401148
:00401060 EB54 jmp 004010B6
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401054(C)
|
:00401062 817D0C11010000 cmp dword ptr [ebp+0C], 00000111
:00401069 7542 jne 004010AD
:0040106B 8B4510 mov eax, dword ptr [ebp+10]
:0040106E 663DEC03 cmp ax, 03EC
:00401072 7542 jne 004010B6
:00401074 C1E810 shr eax, 10
:00401077 660BC0 or ax, ax
:0040107A 752F jne 004010AB
:0040107C 6A00 push 00000000
:0040107E FF7508 push [ebp+08]
* Reference To: USER32.EndDialog, Ord:00B8h
|
:00401081 E8C2000000 Call 00401148 <-至此是第一個對話方塊
:00401086 6A00 push 00000000
* Reference To: KERNEL32.GetModuleHandleA, Ord:0111h
|
:00401088 E8D3000000 Call 00401160 <-又出現一次,第二個對話方塊開始了
:0040108D A3A0304000 mov dword ptr [004030A0], eax
:00401092 6A00 push 00000000
* Possible StringData Ref from Code Obj ->"U} "
|
:00401094 68BF104000 push 004010BF
:00401099 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"GAME"
|
:0040109B 6805304000 push 00403005
:004010A0 FF35A0304000 push dword ptr [004030A0]
* Reference To: USER32.DialogBoxParamA, Ord:0092h
|
:004010A6 E897000000 Call 00401142
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040107A(C)
|
:004010AB EB09 jmp 004010B6
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401069(C)
|
:004010AD B800000000 mov eax, 00000000
:004010B2 C9 leave
:004010B3 C21000 ret 0010
可見這兩個對話方塊是“獨立”的,只要把關於第一個對話方塊的程式碼去掉就可以了,怎麼去掉?全NOP?當然可以,不過是不是累點?我乾脆把程式的入口點改在了401086,前面全沒用了,HEHE~~~~
接下來看第二個對話方塊的訊息處理:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004010D1(C)
|
:004010DF 817D0C11010000 cmp dword ptr [ebp+0C], 00000111
:004010E6 7547 jne 0040112F
:004010E8 8B4510 mov eax, dword ptr [ebp+10]
:004010EB 663DED03 cmp ax, 03ED
:004010EF 751B jne 0040110C
:004010F1 C1E810 shr eax, 10
:004010F4 660BC0 or ax, ax
:004010F7 7513 jne 0040110C
:004010F9 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Number Game"
|
:004010FB 680A304000 push 0040300A
* Possible StringData Ref from Data Obj ->"This is the part you need to change "
->"into a number generator! :)"
|
:00401100 6816304000 push 00403016
:00401105 6A00 push 00000000
* Reference To: USER32.MessageBoxA, Ord:01BBh
|
:00401107 E842000000 Call 0040114E <-按第一個按鈕後出現的對話方塊
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:004010EF(C), :004010F7(C)
|
:0040110C 663DEE03 cmp ax, 03EE
:00401110 7526 jne 00401138
:00401112 C1E810 shr eax, 10
:00401115 660BC0 or ax, ax
:00401118 7513 jne 0040112D
:0040111A 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Number Game"
|
:0040111C 680A304000 push 0040300A
* Possible StringData Ref from Data Obj ->"This is the other part you need "
->"to change into a number generator! "
->":)"
|
:00401121 6856304000 push 00403056
:00401126 6A00 push 00000000
* Reference To: USER32.MessageBoxA, Ord:01BBh
|
:00401128 E821000000 Call 0040114E <-按第二個按鈕後出現的對話方塊
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401118(C)
|
:0040112D EB09 jmp 00401138
很顯然只要在顯示對話方塊的地方加上我們的程式碼就行了,還是老方法,跳到後面去.
改動的地方: :004010F9 E974000000 jmp 00401172
:0040111A A138214000 mov eax, dword ptr [00402138] <-這是我寫在.data塊裡的程式碼裡的第一句,那裡看起來是空地,結果一執行就會把這一句吃掉,所以只好寫在這裡(建議寫在自己新建的塊裡安全一些)
:0040111F E9811F0000 jmp 004030A5 <-跨塊跳轉(沒有地方了:))
下面是我自己寫的程式碼,很長,但實現了一個相當複雜的過程,自豪中....
先說說思路,因為遊戲是兩個按鈕各按一次後再比較大小,如果不停的重複按一個按鈕,應該沒有作用.所以我把按下按鈕後得到的隨機數分別存在[402130]和[402138]兩個地方,當按其中一個按鈕時,如果相應的記憶體裡沒有值,就得到一個隨機數並放在相應的記憶體裡,如果記憶體裡已經有數就不處理.只有兩個地方都有數時才進行比較,比較以後顯示結果,把兩個地方清零,以進行下次比較.(要是用高階語言寫多好!)
下面是按鈕1的處理:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004010F9(U) <-從上面跳過來的
|
:00401172 90 nop <-跳的位置有點錯位:)
:00401173 A130214000 mov eax, dword ptr [00402130] <-把相應記憶體中的值取出來
:00401178 85C0 test eax, eax <-看是否為0
:0040117A 7590 jne 0040110C <-如果已經有值就返回
:0040117C FF153F604000 call dword ptr [0040603F] <-這是函式GetTickCount,隨機數種子
:00401182 B923000000 mov ecx, 00000023 <-隨機數的計算公式:
:00401187 F7E1 mul ecx Ran_Num=[(Ran_Seed*X)+Y] mod Z
:00401189 83C007 add eax, 00000007 其中X,Y為素數,Z為範圍
:0040118C B964000000 mov ecx, 00000064
:00401191 F7F1 div ecx
:00401193 42 inc edx <-上面是計算1-100的隨機數的過程
:00401194 891530214000 mov dword ptr [00402130], edx <-把結果放好
:0040119A 6A00 push 00000000
:0040119C 52 push edx <-要顯示的結果
* Possible Reference to Dialog: GAME, CONTROL_ID:03F0, ""
|
:0040119D 68F0030000 push 000003F0 <-按鈕對應的文字框的ID,用資源工具可查
:004011A2 FF7508 push [ebp+08] <-對話方塊的控制程式碼
:004011A5 FF151B604000 call dword ptr [0040601B] <-函式SetDlgItemInt
:004011AB A138214000 mov eax, dword ptr [00402138] <-取另一個地方的記憶體
:004011B0 85C0 test eax, eax
:004011B2 0F8454FFFFFF je 0040110C <-如果為空說明對方還沒有按,返回
:004011B8 8B1530214000 mov edx, dword ptr [00402130] <-取出己方得到的數
:004011BE 3BC2 cmp eax, edx <-比較
:004011C0 7C18 jl 004011DA
:004011C2 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Number Game"
|
:004011C4 680A304000 push 0040300A
* Possible StringData Ref from Data Obj ->"Player 2 win !"
|
:004011C9 6856304000 push 00403056 <-這裡我把原來的字串改了
:004011CE 6A00 push 00000000
:004011D0 E879FFFFFF call 0040114E <-函式MessageBox,顯示"Player 2 win !"
:004011D5 E913000000 jmp 004011ED
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011C0(C)
|
:004011DA 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"Number Game"
|
:004011DC 680A304000 push 0040300A
* Possible StringData Ref from Data Obj ->"Player 1 win !"
|
:004011E1 6816304000 push 00403016
:004011E6 6A00 push 00000000
:004011E8 E861FFFFFF call 0040114E <-顯示"Player 1 win !"
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004011D5(U)
|
:004011ED 33C0 xor eax, eax <-善後工作,EAX=0
:004011EF A330214000 mov dword ptr [00402130], eax
:004011F4 A338214000 mov dword ptr [00402138], eax <-把兩處記憶體都清零,以便下次比較
:004011F9 E90EFFFFFF jmp 0040110C <-走嘍
:004011FE 0000 add byte ptr [eax], al <-好險,只剩兩個位元組的空餘了
按鈕2的處理十分類似,只是因為地方不夠了,在後面403XXX處找了一塊空地(本來是.data塊,比較危險,不推薦使用,最好新建一個塊)在HIEW裡這種跨塊的長跳轉好像有點問題,總是搞不對地址,(不知是HIEW的問題還是我的腦袋的問題,請高手講解)後來只好用專門的虛擬碼工具得到機器碼再輸進去.(痛苦啊!)
改成以後試試,很像樣子了。任務只完成了一半,那個得50分勝利和按“M”AND“Z”還沒寫,不過我實在想歇歇了,而且寒假作業還沒寫呢。BYE!
相關文章
- 一個ReverseME破解 SynApsus's ReverseME #1 (13千字)2015-11-15
- 再貼一篇譯文 (1千字)2000-09-10
- 照片也能說話了?嘴型表情全同步,AI數字人時代要來了2024-03-09AI
- 光碟版遊戲變硬碟版遊戲2===>>月影傳說 (4千字)2001-08-23遊戲硬碟
- 一句話解釋數字簽名。一句話解釋數字證書2017-06-06
- 我是非常喜歡國產軟體的,再貼一篇給大家壯壯膽。反正沒人知道我是誰,大不了再換個ID罷了。^-^ (2千字)2001-05-19
- 再貼一篇cd-chcek破解譯文 (4千字)2000-08-27
- 談到軟體狗,我說幾句 (1千字)2000-05-08
- S-DEMO2 註冊分析 (14千字)2002-06-25
- 最近很忙,剛寫了一篇Uedit32 8.0破解過程(高手莫入)! (12千字)2001-05-07
- 分析破解數字五筆3.0 (2千字)2002-04-17
- 為Java說句公道話2016-01-20Java
- 初學者請進(一篇破解javagirl的心得) (2千字)2000-05-09Java
- 如果沒有Java 人類就像不會說話的嬰兒2013-10-09Java
- PolyView再破解---請指教 (5千字)2001-01-02View
- 再貼一篇,進階篇,比上面那個難一些!! (6千字)2001-07-19
- 再來一篇演算法分析,eryl兄弟你要的東西!! (15千字)2015-11-15演算法
- ThumbNailer (2千字)2001-02-02AI
- 如何進入遊戲行業?給想做遊戲的朋友說幾句心裡話2020-07-07遊戲行業
- 一篇破解入門 (7千字)2000-09-04
- Modify the CoDe_InSiDe's 1st ReverseMe2015-11-15IDE
- 25 屆秋招真的回暖了?說這句話的都是哪些人2024-08-28
- 細數iOS最良心的幾款APP,好用到沒話說!2017-09-26iOSAPP
- estiprojm 註冊 (12千字)2001-11-08
- 初學者(12) (1千字)2000-06-09
- 先分析,再脫殼(二) (13千字)2003-09-04
- 轉一篇比較簡單的installshiled的破解 (2千字)2001-05-14
- 我可是遊戲主角,為啥連說話的權利都沒有?!2019-10-12遊戲
- 分享給職場人的幾句話2019-06-03
- 印度撤銷奇葩的PUBG遊戲禁令,總理莫迪說了句公道話2019-04-15遊戲
- 再見數字化轉型:對數字化轉型的再思考2023-09-22
- 不錯的軟體,我來寫過程。:) (2千字)2001-05-13
- 申請加入BCG之第一篇!------LC3破解! (2千字)2001-10-06
- 再貼一篇稍微複雜點的:對於DLL通過增加重定位項直接呼叫引入表函式
(2千字)2015-11-15函式
- 一句話+兩張圖搞定JDK1.7HashMap,剩下湊字數2020-05-16JDKHashMap
- 一句話設定UITextField、UITextview的字數限制和placeholder2017-09-27UITextView
- 拼圖遊戲 (32千字)2015-11-15遊戲
- Restools系列完全破解~~~~~~~~~~~~~~~~~~~~~~~ (12千字)2002-03-03REST