在以前,遊戲外掛其實是因為遊戲(MMORPG)的伺服器(Server)並沒有嚴謹的檢測客戶端(Client)的封包,導致血量、攻擊、金幣、裝備、技能等等的資訊被篡改,這樣就能實現大部分的作弊功能,像是無限血量、技能無冷卻時間、裝備複製、攻擊和移動加速等等,不過後來因為遊戲公司有了安全意識,為了不讓外掛破壞遊戲的平衡,因此將封包加密,也在伺服端加強檢測封包,杜絕遊戲外掛,那麼之後也衍生了自動打怪(Bot)的外掛,它是透過程式去模擬人物去打怪升級,這樣就能節省自己打怪的時間,同時可以操作許多人物去賺取遊戲金幣,因此目前大部分的遊戲外掛都比較傾向於自動打怪(僅包含練等相關的遊戲)。
那麼自動打怪的外掛是要怎樣製作的呢 ? 實現的方法有二種,第一種是模擬鍵盤和滑鼠以及判斷遊戲裡面的RGB色彩,這樣就能知道現在血量是否要補血、怪物在哪、當前是否有障礙物等等,這也是最簡單快速的方法;第二種是透過逆向工程的技術,分析Client端的程式是如何運作的,我們也模仿它的運作以及蒐集相關記憶體資訊,就能有效的實現Bot功能,不過遊戲公司也知道會發生這種事情,因此會有反編譯的防護機制,對於初學者,根本很難繞過這些防護機制(Packer),所以如果要使用逆向工程的技術,我會建議先用沒有Packer的遊戲來練習。
逆向的目的在於分析遊戲的運作以及搜尋相關記憶體的資訊,不過遊戲的主程式那麼龐大,總不能從頭分析到結束,可能會分析到猴年馬月都分析不完,那麼有那些技巧可以讓我們有效的分析這些功能,常見的技巧如下列所示:
記憶體分析能從已知或未知的數值,分析數值的變化,從而得知是哪行程式碼在處理它,並且找出血量在結構的位移,例如分析人物的血量,可以讓怪物攻擊,因此血量就會降低,我們可以搜尋當前的血量值,就能推敲出相關的程式碼,那麼有哪些工具能幫助我們分析能 ? 就我所知目前比較好用的記憶體分析工具是Cheat Engine (https://www.cheatengine.org/),它的過濾數值的功能還蠻強的。
主要是將遊戲的傳送和接收封包的數值拿來分析,把每個數值的來源都精確的了解,例如人物在購買物品時,會發送相關的封包,我們可以藉由這些封包推敲出相關的程式碼,這樣就能利用這些程式碼來實現這些功能(也能自己建構這些封包數值)。由於現在的遊戲都會加密封包,那麼是否封包分析就沒有用了 ? 其實不然,我們可以透過封包的長度(通常前1 Byte或2 Byte是封包長度,之後才是加密訊息),去識別各種封包的型態,然後再從遊戲裡找到解密後的明文封包,也是能提高我們分析效率。封包分析的工具可以使用Wireshark和WPE (Winsock Packet Editor) Pro,這二種工具的功能不太一樣,說明如下所示:
a. Wireshark
Wireshark (https://www.wireshark.org/)是透過網路卡介面來分析網路流量,因此會有除了遊戲的封包,也會摻雜其他的網路流量,不過Wireshark的過濾功能很強,這部分的問題,也可輕易解決。
b. WPE (Winsock Packet Editor) Pro
WPE (Winsock Packet Editor) Pro (https://winsock-packet-editor-wpe-pro.apponic.com/)是透過Hook send、sendto、WSASend、WSASendto和recv、recvfrom、WSARecv、WSARecvFrom,因此只會錄到此遊戲的封包,這樣封包數量就會少很多,也比較好分析。
那麼有人會有疑問 ? 我就是想要分析明文的封包,那要使用什麼工具 ? 由於每款遊戲的加解密方法都不一樣,因此需要找到加解密封包的相關函式,然後再去Hook它,就能獲得所有的明文封包,不過程式都必須自己撰寫,也因此想要更完善的分析包封,該寫的程式還是逃不掉。
當前MMORPG較多使用的DirectX 3D函式庫(有些是用OpenGL),因此我們可以Hook它的API,也許能找到記憶體分析也找不到的資訊,由於DirectX 3D在繪製時圖形時,不能讓使用者有明顯閃爍的情形,因此會有Front Buffer和Back Buffer,Front Buffer是顯示圖形在螢幕上的Buffer,Back Buffer是預先繪製的圖形,因此只要將2個Buffer置換就能改變螢幕顯示的圖形,這樣就能減少閃爍的問題,所以只要Back Buffer越多性能就越好,那麼我們可以利用它會預先繪製的特性,Hook相關繪製圖形的API,就能知道螢幕外的物件的位址,不過要怎麼知道哪些物件是建築物;哪些物件是怪物等等,我們可以在Hook繪製3D圖的前(Present)或後(EndScene),然後再獲取圖形的頂點(Vertex)數量,因為每種3D圖形的頂點(Vertex)數量都不盡相同,所以可以識別這個物件是屬於建築物或是怪物了。
由於遊戲外掛的氾濫,因此遊戲公司會透過一些防護機制,加強Client端的程式碼,常見的就是在程式碼裡面加殼(Packer),這樣在反編譯時就很難找到主程式,甚至直接閃退遊戲,除非將遊戲解殼(UnPacker)。那麼常見的加殼(Packer)手法分為壓縮殼、加密殼、VMP (Virtual Machine Protection)和驅動層的防護殼等,往往這些殼很容易就秒殺初學者,因此非常受遊戲公司的歡迎。
將部分程式碼壓縮(EntryPoint和IAT[Import Address Table]等等)起來,並且修改EntryPoint到要解壓縮的程式區塊。
在主要的關鍵程式碼加密,執行時才會解密,執行完再加密,往往加密殼還會伴隨者程式碼混淆,將call改成push和jmp組合,增加分析的困難。
將關鍵程式碼,利用自製的程式指令,將它替換,在執行時,會透過查表的方式,找出指令所代表的組合語言。
由於在驅動層能任意修改核心的記憶體,因此能Hook SSDT (System Service Descriptor Table)和相關Debug的API,然後就可以有效的偵測,到底有誰在反編譯它,也可直接拒絕被反編譯,另一方面,在核心層運作,一般人也很難去繞過它,不過僅限於32位元的系統,因為在Windows 64位元會有PatchGuard保護核心層的記憶體不被修改,所以在64位元的防護,頂多透過PEB (Process Environment Block)來檢測Process (BeingDebugged Flag)是否有被反編譯。
CRC (Cyclic Redundancy Check)檢測是基於反編譯軟體會在程式區塊下軟中斷點(Soft Breakpoint會在程式碼標記為0xCC),因此會透過CRC計算程式碼區塊,判斷結果是否跟之前的不一樣,如果不一樣就會結束程式,因此需要在CRC啟動前繞過它。
探討了這些技術,和防護技術,唯一不變的是,逆向工程技術要非常的熟練,必須駕輕就熟,這樣一來不管是什麼防護,都可以輕易地繞過,不過初學者也別灰心,可以透過舊版較沒有防護的遊戲來練習分析遊戲的架構,因為遊戲的架構,在不同的遊戲依然有類似的情形,所以就慢慢的累積逆向經驗,終究能成為逆向高手。
那麼自動打怪的外掛是要怎樣製作的呢 ? 實現的方法有二種,第一種是模擬鍵盤和滑鼠以及判斷遊戲裡面的RGB色彩,這樣就能知道現在血量是否要補血、怪物在哪、當前是否有障礙物等等,這也是最簡單快速的方法;第二種是透過逆向工程的技術,分析Client端的程式是如何運作的,我們也模仿它的運作以及蒐集相關記憶體資訊,就能有效的實現Bot功能,不過遊戲公司也知道會發生這種事情,因此會有反編譯的防護機制,對於初學者,根本很難繞過這些防護機制(Packer),所以如果要使用逆向工程的技術,我會建議先用沒有Packer的遊戲來練習。
一、探討逆向工程的技術
1. 記憶體分析
2. 封包分析
a. Wireshark
Wireshark (https://www.wireshark.org/)是透過網路卡介面來分析網路流量,因此會有除了遊戲的封包,也會摻雜其他的網路流量,不過Wireshark的過濾功能很強,這部分的問題,也可輕易解決。
b. WPE (Winsock Packet Editor) Pro
WPE (Winsock Packet Editor) Pro (https://winsock-packet-editor-wpe-pro.apponic.com/)是透過Hook send、sendto、WSASend、WSASendto和recv、recvfrom、WSARecv、WSARecvFrom,因此只會錄到此遊戲的封包,這樣封包數量就會少很多,也比較好分析。
那麼有人會有疑問 ? 我就是想要分析明文的封包,那要使用什麼工具 ? 由於每款遊戲的加解密方法都不一樣,因此需要找到加解密封包的相關函式,然後再去Hook它,就能獲得所有的明文封包,不過程式都必須自己撰寫,也因此想要更完善的分析包封,該寫的程式還是逃不掉。
二、DirectX 3D探討
當前MMORPG較多使用的DirectX 3D函式庫(有些是用OpenGL),因此我們可以Hook它的API,也許能找到記憶體分析也找不到的資訊,由於DirectX 3D在繪製時圖形時,不能讓使用者有明顯閃爍的情形,因此會有Front Buffer和Back Buffer,Front Buffer是顯示圖形在螢幕上的Buffer,Back Buffer是預先繪製的圖形,因此只要將2個Buffer置換就能改變螢幕顯示的圖形,這樣就能減少閃爍的問題,所以只要Back Buffer越多性能就越好,那麼我們可以利用它會預先繪製的特性,Hook相關繪製圖形的API,就能知道螢幕外的物件的位址,不過要怎麼知道哪些物件是建築物;哪些物件是怪物等等,我們可以在Hook繪製3D圖的前(Present)或後(EndScene),然後再獲取圖形的頂點(Vertex)數量,因為每種3D圖形的頂點(Vertex)數量都不盡相同,所以可以識別這個物件是屬於建築物或是怪物了。
三、遊戲的防護機制
由於遊戲外掛的氾濫,因此遊戲公司會透過一些防護機制,加強Client端的程式碼,常見的就是在程式碼裡面加殼(Packer),這樣在反編譯時就很難找到主程式,甚至直接閃退遊戲,除非將遊戲解殼(UnPacker)。那麼常見的加殼(Packer)手法分為壓縮殼、加密殼、VMP (Virtual Machine Protection)和驅動層的防護殼等,往往這些殼很容易就秒殺初學者,因此非常受遊戲公司的歡迎。
a. 壓縮殼
將部分程式碼壓縮(EntryPoint和IAT[Import Address Table]等等)起來,並且修改EntryPoint到要解壓縮的程式區塊。
b. 加密殼
在主要的關鍵程式碼加密,執行時才會解密,執行完再加密,往往加密殼還會伴隨者程式碼混淆,將call改成push和jmp組合,增加分析的困難。
c. VMP (Virtual Machine Protection)
將關鍵程式碼,利用自製的程式指令,將它替換,在執行時,會透過查表的方式,找出指令所代表的組合語言。
d. 驅動層的防護殼
由於在驅動層能任意修改核心的記憶體,因此能Hook SSDT (System Service Descriptor Table)和相關Debug的API,然後就可以有效的偵測,到底有誰在反編譯它,也可直接拒絕被反編譯,另一方面,在核心層運作,一般人也很難去繞過它,不過僅限於32位元的系統,因為在Windows 64位元會有PatchGuard保護核心層的記憶體不被修改,所以在64位元的防護,頂多透過PEB (Process Environment Block)來檢測Process (BeingDebugged Flag)是否有被反編譯。
e. CRC檢測
CRC (Cyclic Redundancy Check)檢測是基於反編譯軟體會在程式區塊下軟中斷點(Soft Breakpoint會在程式碼標記為0xCC),因此會透過CRC計算程式碼區塊,判斷結果是否跟之前的不一樣,如果不一樣就會結束程式,因此需要在CRC啟動前繞過它。
探討了這些技術,和防護技術,唯一不變的是,逆向工程技術要非常的熟練,必須駕輕就熟,這樣一來不管是什麼防護,都可以輕易地繞過,不過初學者也別灰心,可以透過舊版較沒有防護的遊戲來練習分析遊戲的架構,因為遊戲的架構,在不同的遊戲依然有類似的情形,所以就慢慢的累積逆向經驗,終究能成為逆向高手。