實現電子遊戲ACE(Arbitrary Code Execution)的具體原理是什麼?

《MATRIX攻略法,8分25秒通關惡魔城月下》

MATRIX法通關惡魔城月下,8分25秒

只知道大致的過程,利用正常的遊戲操作(比如更改排列道具順序)往內存中輸入特定數據,形成cpu指令,用指令操縱遊戲程序,直接跳到結局畫面。MARIO穿牆也是同樣的原理。


正好昨天看了《超級馬里奧世界》(SMW)的一個任意代碼執行 TAS 直接通關甚至玩小遊戲,獻上原理。下面是 AGDQ2014 上的演示視頻,現場演示是用 Raspberry Pi 輸入 SFC 真機完成的

視頻封面【TAS-2513】SFC《超級馬里奧世界》任意執行代碼 2分25秒19視頻

首先 SMW 可以利用 bug(似乎是吃到寄存的物品的同時耀西吐舌頭?)去刷任意 id 的物體(Sprite),在某些情況下可以刷編號為 0xFA 的物體。SMW 刷物體的時候會根據物體的 ID 執行一段代碼,而 0xFA 的代碼位於……顯存……(地址是 $0322)

於是就可以利用操作給顯存中填入特定的數值(當然為了填充這個數值做了很多操作)。接著刷一個 0xFA,CPU 開始嘗試執行顯存中的數據,而之前操縱的結果是把它填上了 4C 18 42,即 JMP $4218,這個跳轉會跳轉到……手柄對應的內存。(超任使用 MMIO,讀手柄狀態就是讀取內存。)

於是緊接下來你就可以用手柄來直接輸入代碼了。


惡魔城月下這款遊戲我沒玩過,看了一下視頻感覺原理很相似(如果不對請指出)

應該是:物品欄緩衝區溢出

然後物品欄的內存數據附近又正好有函數指針或者一些關鍵數據指針(比如下個地圖數據指針)

簡單來說,例如:

物品欄有20個位置佔用內存0-19位置,一共20 byte,開始地址為0x10,然後接下來1 byte是玩家受到攻擊的傷害計算的函數指針,位於0x24,跟著4 byte當前地圖的4個方向門通往的下一個地圖的指針.

如果能找到一些bug讓物品放到物品欄外,比如卡bug把物品卡到第21個空位,那麼實際上物品欄接下來的1 byte位置上的函數指針的地址被溢出改寫為了該物品的數據.或者是任意其他bug或方法能改寫位於0x24的數據(但這個過程中間可能會很複雜).

如果你有意找一個物品它的數據正好是0x10(比如正好是生命回復水什麼的)卡進去,這時候的你事先已經往物品欄里塞了一些精心構造的物品序列,其對應的數據是可執行的代碼,比如正好是直接改寫遊戲狀態到通關.這一個物品序列的數據位於0x10.最後你去挨一下打,遊戲調用位於0x24的函數指針,然而它已經被溢出的物品改寫為了0x10,好~直接跳轉到0x10執行特意構造通關函數,遊戲通關了.

這裡有Pokemon Yellow物品欄溢出Arbitrary code execution的POC(proof of concept)可以參考一下:

TASVideos submissions: #2913: p4wn3r"s GBC Pok??mon Yellow in 01:36.95

http://aurellem.org/vba-clojure/html/total-control.html


說個PC上的吧,感覺關係不大。

背景:大約是星際1 1.12f(含)之前。SC1常見的有8個玩家P1~P8,有個P12代表中立,這是個1位元組值所以最大可以到255。單位ID記得上限是0xFFFF。

以前版本Set Deaths指令(其他的記得也不檢查,聽說過通過擊殺指定Player建築來達到修改效果的)沒有檢驗玩家ID和單位ID的最大值,於是可以利用這個地圖指令訪問/修改一大片內存(255個玩家×65535個單位ID×一個數據4位元組)。這個Bug最早在國外(Staredit Network)被發現,大名是EUD(Extend Unit Death),主要在1.12f上玩。

那時候浩方還在1.08b,中國星際RPG聯盟(CSGA)那邊重新抓過1.08b的內存表以後也能用了,碰巧那時候有個大神發現這片內存里有個函數指針,於是做了個框架配合Comment指令寫了個框架(A.L.I.C.E系統或者AEUD)直接導入指令。有了這個框架以後就可以隨意訪問內存了(不能寫時間太長的指令,否則掉線),我見到的成果包括但不限於:不用插件中文化,各種特效(修改單位貼圖,動畫,技能效果,技能,科技樹etc)。在SC1 RPG區混過的大概聽說過Entrance Through系列地圖。

當然這個技術是地圖開發者的專用福利,而且1.13以後就沒了。

現在想玩這些地圖估計還得關掉數據執行保護DEP(要不然就用XP)。


我聽說過一些有關的方法,但是道聽途說,我也不知道對不對。

遊戲操作指令,從物理設備,到驅動,到底層API,到遊戲程序,每一步都可以hack,把實時輸入替換成預編製的輸入程序。

模擬器一般都是替換「物理設備」,因為模擬器其實都是虛擬機,物理設備都是虛擬的,驅動就是簡單地接收調用,很容易用程序代替。

原平台程序一般是注入底層API,比如DirectX的Dinput就有hook可以寫程序來注入。

不改驅動是因為驅動一般複雜封閉很難改;不改遊戲程序是因為編程操作是要和作弊嚴格劃分界限的,改了遊戲程序就很難和作弊劃界限了。

至於為什麼能發生正常遊戲無法發生的事情呢,這是因為這些遊戲其實是有bug的。在機能受限的平台上,很多校驗都不能做,所以很多在極端條件下才會發生的bug就不修復了。這種bug類似緩衝區溢出攻擊,用非常規的輸入改寫原來不能訪問的內存位置。


接著上面天象的回答,說白了就是利用遊戲本身校驗少或者編程有bug,比如內存溢出之類的強行修改內存實現的。


推薦閱讀:

如何發展成一名黑客?
如何看待盤古推出的 iOS 8.1 越獄?
黑客大牛會不會比常人更擔心自己被入侵?
如何確定自己的電腦有沒有被黑客入侵?
被別的網站攻擊,首頁強制跳轉到另外網站去了,怎麼解決,求詳情?

TAG:遊戲開發 | 單機遊戲 | 遊戲機 | 黑客Hacker | 遊戲破解 |