[系統安全] 五.OllyDbg和Cheat Engine工具逆向分析植物大戰殭屍遊戲

您可能之前看到過我寫的類似文章,爲什麼還要重複撰寫呢?只是想更好地幫助初學者瞭解病毒逆向分析和系統安全,更加成體系且不破壞之前的系列。因此,我重新開設了這個專欄,準備系統整理和深入學習系統安全、逆向分析和惡意代碼檢測,“系統安全”系列文章會更加聚焦,更加系統,更加深入,也是作者的慢慢成長史。換專業確實挺難的,逆向分析也是塊硬骨頭,但我也試試,看看自己未來四年究竟能將它學到什麼程度,漫漫長征路,偏向虎山行。享受過程,一起加油~

系統安全系列作者將深入研究惡意樣本分析、逆向分析、攻防實戰和Windows漏洞利用等,通過在線筆記和實踐操作的形式分享與博友們學習,希望能與您一起進步。前文普及了OllyDbg的基礎用法和CrakeMe案例;這篇文章將詳細講解OllyDbg和Cheat Engine工具逆向分析用法,完成植物大戰殭屍的遊戲輔助器,包括修改陽光值和自動拾取陽光兩個功能,希望對入門的同學有幫助。

在這裏插入圖片描述

話不多說,讓我們開始新的征程吧!您的點贊、評論、收藏將是對我最大的支持,感恩安全路上一路前行,如果有寫得不好的地方,可以聯繫我修改。基礎性文章,希望對您有所幫助,作者的目的是與安全人共同進步,加油~

作者的github資源:

前文分析:


聲明:本人堅決反對利用教學方法進行犯罪的行爲,一切犯罪行爲必將受到嚴懲,綠色網絡需要我們共同維護,更推薦大家瞭解它們背後的原理,更好地進行防護。


一.VS內存地址查看

在講解OllyDbg和Cheat Engine工具逆向分析遊戲之前,我想先給大家普及下內存地址的基礎概念,以及通過創建項目來講解下內存、地址、值它們的關係。

在這裏插入圖片描述

第一步,打開VS2019創建空項目“RE_ZWDZJS01”,然後添加main.cpp源文件。

在這裏插入圖片描述

如下圖所示,選中項目右鍵“添加”->“新建項”,然後創建main.cpp文件。

在這裏插入圖片描述


第二步,添加代碼如下所示,我們嘗試在內存中查看變量的位置。
其中%#表示輸出提示方式,如果是8進制在前面加0,如果是十進制不加任何字符,如果是十六進制會加上0x。

#include "stdio.h"

int main()
{
   
      
	int x = 1000;

	//內存中查看值得位置
	printf("%#X\n", &x);

	//暫停
	getchar();
	return 0;
}

我們嘗試添加個斷點,然後運行程序。

在這裏插入圖片描述


第三步,按下F5調試,輸出結果爲0x12FFCDC。

  • 0x12FFCDC

在這裏插入圖片描述


第四步,接着我們需要在內存中查看這個值,選擇“調試”->“窗口”->“內存”,然後隨便選擇一個“內存”。

在這裏插入圖片描述

輸入地址“0x12FFCDC”即可。

在這裏插入圖片描述

接着我們打開程序員型計算機,可以看到1000對應的十六進制就是3E8,剛好和上面的 E8 03 00 00 一致。

  • E8 03 00 00

在這裏插入圖片描述

注意這裏僅顯示了一個字節,我們如果右鍵選中轉換爲4字節,則可以顯示完整的數值,如下圖所示。

  • 0x000003e8

在這裏插入圖片描述


寫到這裏,VS簡單查看內存的方法就介紹完畢了,其原理類比爲:

  • 內存 --> 旅館
  • 地址 --> 門牌號
  • 值 --> 旅客A

那麼,我們怎麼將“旅客A”換成“旅客B”呢?這就需要通過門牌號在旅館中找到“旅客A”再替換,但之前需要進行權限提升,才能進行後續的操作。同樣,在遊戲中,如果我們想在內存中修改值,也是通過地址訪問這個值再進行修改,修改前也需要提升權限。具體操作主要包括四個步驟:

  • 第一步,找到遊戲窗口
  • 第二步,通過窗口找到進程ID
  • 第三步,通過進程ID打開進程
  • 第四步,通過打開的進程完成內容修改

講解完這個基礎知識,接着我們開始植物大戰殭屍的逆向吧!



二.Cheat Engine逆向修改陽光值

修改陽光值其實就是修改遊戲的分數、能量、血量、攻擊力之類的,其原理是通過地址修改內存中的值,這裏主要使用的是Cheat Engine工具。

在這裏插入圖片描述


第一步,通過Cheat Engine工具打開運行着的植物大戰殭屍遊戲。

在這裏插入圖片描述


第二步,輸入數字“100”,點擊“首次掃描”。

在這裏插入圖片描述

返回結果爲762個。

在這裏插入圖片描述


第三步,接着反覆玩遊戲,並輸入對應的數字進行“再次掃描”,比如輸入數字“150”,點擊“再次掃描”。

在這裏插入圖片描述

最終我們得到了一個結果,其地址爲:

  • 0x207FB5A0

在這裏插入圖片描述


第四步,打開任務管理器,然後選中植物大戰殭屍遊戲,右鍵選擇“轉到詳細信息”按鈕。

在這裏插入圖片描述

顯示結果如下圖所示,這裏獲取了植物大戰殭屍的進程ID。

  • PID:3256

在這裏插入圖片描述

原理搞懂之後,接下來就需要編寫代碼完成陽光值的修改。


第五步,在編寫C語言代碼修改陽關的參數前,先講解Spy++的查找窗口功能和FindWindow函數。
我們在VS中可以看到查找窗口函數FindWindow包括兩個參數,即窗口的類型和窗口的標題。

FindWindow(
  lpClassName,        {
   
                窗口的類名}
  lpWindowName: PChar {
   
                窗口的標題}
);

在這裏插入圖片描述

這裏我們可以通過Spy++來進行輔助講解。

在這裏插入圖片描述

在彈出的界面中選擇這個查找窗口(從左數第五個)按鈕。

在這裏插入圖片描述

然後移動選擇遊戲窗口,查看對應的信息,它包括窗口句柄,如下圖所示。所以接下來我們可以通過標題和類進行查找。

  • 標題:植物大戰殭屍中文版
  • 類:MainWindow

在這裏插入圖片描述


第六步,編寫核心C語言代碼,實現相關遊戲修改功能。

通過GetWindowThreadProcessld函數找到進程ID。

DWORD GetWindowThreadProcessld(
	HWND hwnd,                   //窗口句柄
	LPDWORD lpdwProcessld        //接收進程標識的32位值的地址
);

通過OpenProcess函數打開一個已存在的進程對象,並返回進程的句柄。

HANDLE OpenProcess(
	DWORD dwDesiredAccess,   //渴望得到的訪問權限(標誌)
	BOOL bInheritHandle,     //是否繼承句柄
	DWORD dwProcessId        //進程標示符
);

通過WriteProcessMemory函數寫入某一進程的內存區域。注意,直接寫入會出Access Violation錯誤,故需此函數入口區必須可以訪問,否則操作將失敗。

BOOL WriteProcessMemory(
	HANDLE hProcess,                 //由OpenProcess返回的進程句柄
	LPVOID lpBaseAddress,            //要寫的內存首地址
	LPVOID lpBuffer,                 //指向要寫的數據的指針
	DWORD nSize,                     //要寫入的字節數
	LPDWORD lpNumberOfBytesWritten
);

完整代碼如下:

#include "stdio.h"
#include "windows.h"

int main()
{
   
                 
	//輸入值作爲修改陽光參數
	int x;
	scanf("%d", &x);

	//進程ID
	DWORD pid;

	//1.找到遊戲窗口 窗口類型、窗口標題
	HWND hwnd = FindWindow(NULL,L"植物大戰殭屍中文版");

	//2.通過窗口找到進程ID
	GetWindowThreadProcessId(hwnd,&pid);

	//3.通過進程ip打開進程
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);

	//4.通過打開進程修改遊戲內容
	WriteProcessMemory(hProcess, (LPVOID)0x207FB5A0, 
		               (LPVOID)&x,sizeof(x),&pid);

	return 0;
}

第七步,當我們進行數值修改時,我們的植物大戰殭屍陽光也就行對應的修改。
先設置爲“0”,如下圖所示修改成功,哈哈!是不是完成了一個簡單的遊戲輔助器呢?

在這裏插入圖片描述

接着我們修改成10086,如果360提示警告(識別遠程線程注入),我們點擊“允許本次修改”即可,最終成功將陽光值修改爲“10086”。我們終於可以愉快的玩耍了,媽媽再也不用擔心我的陽光!

在這裏插入圖片描述

在這裏插入圖片描述

同樣第二關我們也可以進行修改,但此時的窗口地址會有變化,它變爲了0x2099AE60,修改核心函數:

  • WriteProcessMemory(hProcess, (LPVOID)0x2099AE60, (LPVOID)&x,sizeof(x),&pid);

在這裏插入圖片描述

注意,如果遊戲存在地址保護的情況,我們可以嘗試注入進行修改。本系列文章僅分析經典的本地遊戲,至於網絡遊戲一律禁止大家去修改或破壞,原理普及安全防護爲主。


第八步,編程中遇到的錯誤一定要學會獨立百度、谷歌解決,這是至關重要的一種能力提升。
注意,如果提示錯誤“error C4996: ‘scanf’: This function or variable may be unsafe. ”,則因爲VS認爲scanf函數是不安全的,進行安全開發生命週期SDL檢查設置即可。

在這裏插入圖片描述

在這裏插入圖片描述



三.OllyDbg逆向自動拾取陽光

自動撿取的關鍵是點擊鼠標,如果你點擊到了陽光上它纔會增加。所以我們希望在陽光下落的時候觸發點擊陽光事件,然後陽光地址會增加,初步預測涉及兩個CALL函數。

  • 陽光出現call
  • 判斷是否點擊到陽光然後增加陽光的call

第一步,當我們使用Cheat Engine定位到陽光的地址後,可以選中該地址右鍵設置“找出是什麼修改了這個地址”。

在這裏插入圖片描述

首先,植物大戰殭屍此時定位的地址爲:0x2099AE60;然後選中改地址右鍵,設置“找出是什麼修改了這個地址”。

  • 0x2099AE60

在這裏插入圖片描述


第二步,等待下一個陽光撿起後,可以在下圖所示窗口中獲取新產生的值,即0x00430A11。接着點擊0x00430A11地址,將擴展信息記錄下來,方便接下來的自動拾取功能。

  • 0x00430A11

在這裏插入圖片描述

同時,點擊“顯示反彙編程序”會形成下圖所示的效果圖。

在這裏插入圖片描述


第三步,利用OllyDbg軟件打開“PlantsVsZombies.exe”遊戲。

在這裏插入圖片描述


第四步,前面我們已經定位到了陽光的窗口地址0x00430A11,接着按下Ctrl+G或者右鍵“轉到”->“表達式”,然後跳轉到指定位置。

在這裏插入圖片描述

跳轉0x00430A11如下圖所示:

在這裏插入圖片描述


第五步,按下F2給它增加個斷點以及註釋,遊戲運行到點擊陽光增加數值時就會斷到這裏。
我們可以查看ECX數值,它應該是19,對應十進制的25,所以猜測這裏是增加陽關值。

在這裏插入圖片描述

運行程序直到撿起陽光,它會自動停到斷點位置,並且ECX修改爲0x19,對應的陽光值增加25分。觀察彙編代碼,發現它是一個增加語句,即驗證了它是陽光的增加語句。

  • 0x00430A11 ADD DWORD PTR DS:[EAX+5560],ECX

在這裏插入圖片描述


第六步,點擊“調試”->“執行到返回”按鈕(快捷鍵Ctrl+F9)。

在這裏插入圖片描述

接着跳轉到0x00430AB4位置,如下圖所示,注意返回到0x004314FD位置。

  • 返回地址:0x004314FD

在這裏插入圖片描述


第七步,在RETN返回處按下F7,執行單步步入,會看到CALL函數執行完畢。我們不難推測這個函數就是增加陽光的函數。

  • 0x004313F8 CALL PlantsVs.004309D0

接着我們給它增加一個斷點,然後再次運行程序,點擊拾取陽光後會自動定位到該位置。

在這裏插入圖片描述


第八步,選中該條語句進行nop操作。
NOP指令相當於空指令,不執行任何動作,對應16進制字節碼爲90。當我們的軟件有廣告彈窗時,我們可以通過nop設置過濾掉彈窗。

在這裏插入圖片描述

接着選中0x004313F8該行,右鍵“彙編”,然後在彈出的窗口中設置爲nop即可。

在這裏插入圖片描述

如下圖所示,設置之後0x004313F8位置變成了NOP空指令。我們可以把這個語句NOP設置後,發現點擊陽光數值是不增加的,從而確定了增加函數。

在這裏插入圖片描述


第九步,然後右鍵撤銷修改,接着分析彙編代碼JNZ操作。

在這裏插入圖片描述

這時可以看到,在CALL函數之前有一個JNZ操作,也就是說它可能需要判斷值纔會進入增加陽光的函數,我們在這個JNZ下斷點,再進入遊戲點擊陽光。

  • JNZ:jump if not zero,結果不爲零(或不相等)則轉移。

在這裏插入圖片描述

多次運行程序放行之後會發現,當我們點擊陽光之後,陽光會往上走,只有當陽光完全到達指定位置(左上角)之後,纔會執行call增加陽光值,由此得知這個JNZ主要是判斷陽關是否到位。

在這裏插入圖片描述

注意,這裏需要多次在0x004313F4處下斷點再取消運行遊戲,反覆操作之後會發現實現JNZ操作後陽光會向左上角移動,否則會停止狀態。作者也是一點點摸着過河,加油!

在這裏插入圖片描述


第十步,繼續執行程序定位點擊函數。
在增加陽光的CALL函數(0x0043159B)前有個跳轉,當JNZ執行成功之後纔會增加這個CALL。我們在JNZ處下斷點調試它的執行流程。

在這裏插入圖片描述

當我們在JNZ處下斷點後,運行遊戲會突然跳轉到斷點處停止,如下圖所示,並且遊戲屏幕沒有任何操作,接着按下F7運行發現陽光即將出現。

在這裏插入圖片描述

陽光出現如下圖所示。

在這裏插入圖片描述

由於JNZ斷點會讓遊戲很卡,接着我們將該處斷點取消,而在0x0043159B位置CALL增加斷點,執行程序後會發現當我們點擊陽光的時候會被斷下,所以判斷它是陽光采集函數。這是個很典型的if-else語句, 如果沒有被點擊就會一直執行動畫CALL,如果被點擊那麼就會執行增加陽光的CALL。

在這裏插入圖片描述


第十一步,最重要的步驟出現,我們將jnz修改爲jmp,從而實現自動撿取陽光。

在這裏插入圖片描述

當我們修改完成之後,會發現陽光一出現就自動增加,根本不需要手動去點擊,最終完成了該輔助功能。同樣,我們可以嘗試編寫C語言實現相關自動化修改,這裏不再進行講解。

  • JNZ:jump if not zero,結果不爲零(或不相等)則轉移。
  • JMP:彙編無條件跳轉指令。

注意,CMP BYTE PTR DS:[EBX+50],0 是判斷是否收集陽光的標誌,然後才執行JNZ或JMP操作。當我們點擊一個植物時,程序斷了下來,可以看到賦值0,JNZ是不會跳轉的;當我們點擊陽光的時候纔會賦值1,調用函數採集陽光。

在這裏插入圖片描述

在這裏插入圖片描述



四.總結及學習推薦

寫到這裏,這篇文章就介紹完畢,希望對您有所幫助,最後進行簡單的總結下。

  • VS內存地址查看
  • Cheat Engine逆向修改陽光值
  • OllyDbg逆向自動拾取陽光

學安全一年,認識了很多安全大佬和朋友,希望大家一起進步。這篇文章中如果存在一些不足,還請海涵。作者作爲網絡安全初學者的慢慢成長路吧!希望未來能更透徹撰寫相關文章。同時非常感謝參考文獻中的安全大佬們的文章分享,深知自己很菜,得努力前行。

很多朋友問我如何學逆向分析?
下面給出推薦的學習路線和安全書籍。軟件逆行其實就是搬磚活,你需要的是任性和基本功。可能大佬們會有很多技巧,但我希望你能紮紮實實去躺過那些坑,會看懂代碼,會寫代碼,然後IDA和OD工具(倚天屠龍)用好,每天泡在代碼中,肯定能行的。你應該這樣學習:

  • 多敲代碼,重視實戰;
  • 程序不是寫出來的,是調出來的;
  • 根據自己興趣和市場需求做一定規模的項目。

下圖開發和逆向項目非常推薦你去完成,開發遠控軟件有助於你分析木馬,CAD軟件能提升你C++分析能力,做一個調製器或許反調試就不再那麼難,自制一個小操作系統、小編譯器、任務管理器,或許逆向原理就懂了。

在這裏插入圖片描述


編程沒有捷徑,逆向也沒有捷徑,它們都是搬磚活,少琢磨技巧,幹就對了。什麼時候你把攻擊對手按在地上摩擦,你就贏了,也會慢慢形成了自己的安全經驗和技巧。加油吧,少年希望這個路線對你有所幫助,共勉。

2020年8月18新開的“娜璋AI安全之家”,主要圍繞Python大數據分析、網絡空間安全、人工智能、Web滲透及攻防技術進行講解,同時分享論文的算法實現。娜璋之家會更加系統,並重構作者的所有文章,從零講解Python和安全,寫了近十年文章,真心想把自己所學所感所做分享出來,還請各位多多指教,真誠邀請您的關注!謝謝。

在這裏插入圖片描述

(By:Eastmount 2020-12-23 週三夜於武漢 https://blog.csdn.net/Eastmount)


參考資料:
[1] C語言逆向工程之遊戲輔助開發 - C語言Plus
[2] 遊戲輔助製作核心–植物大戰殭屍逆向之召喚殭屍call(九)
[3] 遊戲輔助製作核心–植物大戰殭屍逆向之植物攻擊加速(六)
[4] 植物大戰殭屍自動拾取陽光 - TD.Jia
[5] 遊戲逆向篇 - 星星向蓉
[6] [CE遊戲逆向] Plants vs. zombies - Simpler_若離

































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章