红色警戒2修改器原理百科(六)
??? 先說一件事情,昨天我在繼續OD調試游戲的時候,運行錯了版本,然后OD的備注、標簽和斷點通通沒有了。喜大普奔上天關上了一扇門,然后我開了一扇窗戶——拋棄之前的枷鎖,重新出發,目前來看可能是找到了判斷地圖觸發器的整個過程,待進一步測試;還找到了立即勝利的源頭。
??? 讓我們書接上回。
(十三)枚舉地圖玩家——隱藏在背后的黑暗勢力
??? 如果細心的你在進行上一步的瘋狂的掠奪的時候,發現了沒人占有的建筑物的pOwner不是NULL,你就可能發現一片新大陸。是誰擁有了這個建筑物,卻還能顯示沒有歸屬。
??? 前一篇最后一個圖,轉移所屬函數(call [ebx+378])前面有這么備注的一個CALL:玩家ID獲取數據基址(其實這個描述不準確),不知是否注意到了?當時調試時,傳入ECX=0,EAX返回玩家數據地址,然后粗略的看了看里面的循環,就做了個這樣的標簽。畢竟能返回玩家數據地址的函數,需要一個參數,那八成就是玩家ID,因為咱就是本地第一個玩家,就是0號位置咯。聯網對戰時,才會變成其他位置,單機只能在0號。。。
??? 既然有這么一個ID,就來找找ID在哪個偏移處。用CE的分析數據/結構功能,對比分析地圖上所有玩家數據(通過電腦建筑的pOwner獲得電腦玩家數據地址,我測試時就兩個玩家,我用美國,對手是簡單的蘇聯),同時嘗試發現一些其他顯而易見的數據,只發現偏移+30處比較明顯,我是0,電腦是1。基本就確定(玩家數據地址——[game.exe+635DB4])+30偏移就是玩家ID。然后就是一堆不明顯的數據,一大片0。
??? 然而,當我因某些原因又去看了下那個所謂的CALL<玩家ID獲取數據基址>,卻發現沒有一條指令讀取了+30偏移,Amazing!然后仔細跟蹤發現一個莫名其妙的循環次數,地圖上有2個玩家,卻循環了4次。嘗試3個玩家,結果循環5次。而且和參數ECX比較的是玩家數據+34偏移處的一個地址的+B8偏移處的數據,文字表述比較復雜。C語言描述就是:if (CurrentPlayer.onePointer->oneValue == ECX)。
??? 這個oneValue,它永遠和玩家ID相同的嗎?冥思苦想一番,這個指針指向的是什么結構?最終從地圖編輯器獲得靈感,地圖上的單位歸屬可以設置給不同國家,還有平(即無歸屬)和治安(一個神秘的組織),這就解釋了為什么循環次數永遠多兩次:平和治安在你看不到的地方,作為特殊玩家一直存在。也解釋了單位看起來沒有歸屬,實際上還是有個歸屬者。玩家數據+34偏移是所屬勢力對象指針,所屬勢力對象結構的+B8偏移是勢力編號。那么這個CALL的準確備注應該是:勢力編號獲取數據基址。
??? 現在才算進入正題了,來分析下這個函數(004ED760),就能找到枚舉全圖玩家的必要條件了:地圖玩家數(包括平和治安)(game.exe+6322A8),地圖玩家數組(game.exe+63229C)。然后你就能知道他們有多少錢,有幾個步兵,有幾個建筑等等等等,這些偏移比較好找。
??? 號外,好像是在一個蘇軍任務上發現,玩家ID終于不是0了,因為劇情是強行登陸建立基地,我是侵略者還有最后一關,俘獲總統任務地圖上有13個玩家(還有兩個隱藏的更深的勢力叫GDI和Nod)——我眼瞎,玩得時候沒看到。。
(十四)立即勝利——來打我啊~
??? 如果對游戲編程有些許了解的話,一個簡單的小游戲的大概框架簡單描述如下:
int main() {init(); //程序初始化,防止重復啟動等setGameOption();startGame();cleanup();return 0; }void startGame() {initGame(); //初始化數據,加載資源while(true){doSomething();draw();if (gameIsOver())break;} }??? 由此,只要找到游戲的主循環就很容易找到游戲判斷結束的地方。游戲的所有操作都在doSomething()里,對于具體游戲而言,當然會有好多層調用,在游戲的一個操作斷下后,一直返回上層,就可以來到主循環了。
??? 就以建造單位時金錢減少為例,應該是這個地方:
然后查看調用堆棧:
game.<ModuleEntryPoint>+0DB就是調用程序main()函數的地方,前面都是編譯器附加的初始化代碼;
繼續往上看,game.00690883:
看到字符串“Main_Game”,估計00690883就對應上面所說的startGame()函數。
繼續往上, game.00481DBA:
??? 這段比較長,因為實際情況不可能像上面那么一個簡化的模型那么簡單。圖中“game loop finished”是OD自己分析出來的程序內部字符串,另外我添加的“//”開頭的注釋也讓這段程序的流程變得很清晰。注意紅警和上述游戲模型的異同!
進入0053F840:
??? 通常游戲中會設置一個邏輯變量來標識是否結束,當結束條件滿足時,被設置成TRUE,所以可以注意mov [xxxxxxxx],1;
??? 從上圖看出,al=1游戲就結束了,可以從函數尾向上分析al如何變成1的;
??? 也可以把類似“[A35DB1]”這樣的固定的內存地址都添加到CT表中,觀察游戲結束時是怎樣的狀態,然后依次修改;
??? ……等等其他方法。
最后給出,其實就是上面的提到的,立即勝利=1(字節,game.exe+635DB1)。
To be continued…
轉載請注明來源,http://www.cnblogs.com/viewll/p/4773802.html
轉載于:https://www.cnblogs.com/viewll/p/4773802.html
總結
以上是生活随笔為你收集整理的红色警戒2修改器原理百科(六)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SAP 财务月结之 外币评估(TCODE
- 下一篇: 快捷方式图标变成白色