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