CE 修改器者,本地內存修改之工具也。其核心邏輯至爲純粹,乃掃描並定位程序運行於計算機本地物理內存中之數據,而後強制修改之。雖其素以遊戲逆向與遊戲漏洞挖掘(即俗稱“開掛”或“修改內存”)而聲名鵲起,然其應用場景遠不止於此。吾輩完全可藉此工具,嘗試挖掘各類 APP,乃至 Web 端業務邏輯之漏洞。

關於軟件之獲取,諸君可直赴 Cheat Engine 官方網站下載最新版本並行無腦安裝,安裝過程甚爲簡易,本文不再贅述。爲令諸君更直觀理解其強大功能,本教程將隨意開啓一款遊戲作爲測試載體,藉此遊戲,手把手帶汝拆解 CE 之各項核心功能,以及如何利用其搜索、修改內存數據,並最終轉化爲漏洞挖掘之實戰思路。


一、環境準備與進程附加機制

於使用 CE 修改器進行任何操作之前,最核心之前置條件爲“附加進程”。因內存數據乃依附於正在運行之程序進程而存在。

1.1 尋覓目標進程

開啓 CE 修改器後,於界面左上角,可見一帶有放大鏡圖標之小電腦按鈕。點擊此圖標,會彈出“進程列表(Process List)”窗口。此列表展示當前計算機上正在運行之所有活躍進程。

1.2 模擬器進程之特殊性

若吾輩欲測試者爲手機遊戲或移動端 APP,通常會於電腦上使用安卓模擬器。例如可使用雷電模擬器。於進程列表中,需仔細尋覓一名爲 headless 之進程(完整進程名通常帶有特定前綴,如雷電模擬器可能爲 leidianLdBox 等前綴加上 headless)。

不同之模擬器,其進程前綴可能千差萬別,然若深入觀察,其後端渲染或核心運行進程之後,大概率皆帶有 headless 此標識。尋得此目標進程後,直接選中,然後點擊右下角之 Open(打開)按鈕,即可成功將 CE 注入並附加至該模擬器之內存空間中。


二、數據類型與搜索模式

附加進程後,CE 主界面雖看似參數衆多,然入門遊戲漏洞挖掘(即修改內存)之邏輯實則甚爲簡單:於搜索框中輸入吾輩欲修改之數據,然後將其尋出。

2.1 深入理解數據類型

於 CE 搜索界面右側,有一下拉菜單用於選擇數據類型。內存世界之數據並非單一,彼等根據存儲需求被劃分爲不同類型:

  • 四字節 (4 Bytes):此乃 CE 之默認選項。於絕大多數遊戲及常規應用中,代表數量、狀態、金幣等常見數值之變量,一般皆使用四字節之整型(Integer)存儲。大概率吾輩測試遊戲時,默認之四字節便足以應對九成場景,幾用不到其他類型。
  • 其他類型科普:當然,爲應對複雜之業務邏輯,CE 亦支持其他類型。譬如八字節 (8 Bytes) 用於存儲極其龐大之數值;單浮點 (Float)雙浮點 (Double) 常用於存儲帶有小數點之精確數據(例如遊戲人物之坐標 X/Y/Z 軸、複雜之屬性加成比例);此外尚有專門用於搜索文本之字符串 (String) 類型以及各種各樣之數組類型。彼等可能皆存於內存中,然初學者請牢牢鎖定“四字節”。

2.2 精確搜索與範圍搜索策略

於確認數據類型後,吾輩需決定採用何種掃描類型。CE 提供了極其豐富之條件過濾手段:

  1. 精確數值:首個選項,亦爲最常用之選項。當吾輩於遊戲中明確知曉某個數值具體爲多少時(例如吾現有十個金幣),便精確搜索此具體數字。
  2. 比...大:當數值被遮擋或模糊化,然汝知其定然大于某個臨界值時使用。例如,汝知當前數值比十大。
  3. 比...小:同理,用於篩選比某個值(如比十小)之內存地址。結合上面兩項,汝可手動逼近一個範圍。
  4. 介於兩者之間:此可讓汝直接圈定一個範圍區間。例如,汝推測某個隱藏屬性之數值介於十至一百之間,即可用此選項進行初步海選。

三、已知數值之精確搜索與“一不等於一”

當吾輩知曉目標數值時,搜索看似簡單,然實操中會遇大量干擾。吾輩將用下面此例演示此過程。

3.1 首次掃描之“信息大爆炸”

假設吾輩現欲搜索一個數值 10。於輸入框輸入十後,點擊首次掃描 (First Scan)

此時,左側地址列表會瞬間爆滿,或會掃出數十萬個對應之數值來。

  • 何爲內存地址? 內存地址即計算機本地內存條上,用來專門儲存此等數據之一個個“房間號”或“坐標”。左邊顯示者爲十六進制之內存地址,右邊顯示者爲該地址當前對應之數值。

    此數十萬個地址中,僅有一個或幾個乃吾輩真正所需,其餘全爲模擬器系統中其他應用或系統底層之無關緩存。

3.2 遊戲內存中之“一不一定等於一”

假設吾輩於遊戲中見某個道具或狀態顯示爲 1。若其數據類型爲四字節,且程序底層邏輯中確實讓“顯示之一等於內存之一”,則吾輩便直接在輸入框輸入 1,點擊首次掃描。

結果甚爲驚人:左側或會出現 五百多萬個 值全爲一之內存地址!

  • 此第一次搜索之意爲,CE 在整個雷電模擬器(包括其中運行之其他所有後台應用、安卓系統本身以及當前測試之此款遊戲)之廣袤內存海中,把所有值爲一之內存地址全部揪出。更重要者,於遊戲開發中,1 被極其頻繁地用來代表“狀態”。比如 1 代表“開啓/激活”,0 代表“關閉/取消”。此亦爲何單獨搜個一能搜出數百萬條記錄之原因。

3.3 大浪淘沙

面對五百萬個地址,吾輩不知所措。解決之法爲:回到遊戲,設法令此數值產生變化。

  1. 數值變成二:於遊戲中操作,讓原本之一往上增加,變成了 2
  2. 再次掃描:切回 CE,於輸入框輸入 2,點擊再次掃描。注意!此非重新搜索,而是二次過濾。 其邏輯爲:“請幫我把剛才那五百多萬個舊值爲一之地址中,現在值剛好變成二之那些地址篩選出來”。
  3. 瞬間,地址數量或會銳減至 兩千多個
  4. 繼續循環:吾輩將數值繼續改成 3(此於測試遊戲道具數量、屬性加點方面經常用到)。於 CE 中輸入三繼續“再次掃描”,意爲把剛才變成二之那兩千個地址裏,現在變成三之篩選出來。此時,地址可能只剩下 十七個
  5. 殘酷之現實(紅字警示):當吾輩嘗試把數值改成 6,並於 CE 中搜索六時,左側列表突然全空了!之前遺留之地址變成了紅色(紅色代表該內存地址之值在此刻發生了自動改變),然無任何一個值是六。
  • “於遊戲中,一不一定等於一。它有可能等於其他任何奇葩之數值。”

四、未知初始值與動態過濾

當“一不等於一”之情況出現,或吾輩面對者爲血條、藍條、模型大小此種根本無數字顯示之屬性時,吾輩便不知要搜之值究竟爲何。此時,必須啓用未知的初始值掃描模式。

4.1 九億地址之汪洋大海

於掃描類型中選擇“未知的初始值”,此意味著吾輩要求 CE 把模擬器裏所有的內存地址全部找出來。點擊首次掃描後,因無數值過濾,CE 會抓取海量數據。彼等可能是:“個、十、百、千、萬、十萬、百萬、千萬、億……足足 九億個 內存地址!”

面對此九億個地址,吾輩如何定位那個控制特定屬性之唯一內存?答案爲:尋找變化規律

4.2 追蹤增減規律

假設吾輩測試者爲一個模型大小滑塊。

  1. 吾輩將滑塊從零之位置往右拉大(比如拉到了刻度一之位置)。雖不知底層數字變成了幾,然吾輩確信其數值變大了
  2. 於 CE 中,將掃描類型切換爲 “數值增加了”。此亦是區別於精確搜索、大於/小於區間之另一種動態邏輯過濾。
  3. 點擊再次掃描,其邏輯爲:“把此九億個內存地址中,當前值比上一次記錄之值變大了之地址全部找到”。
  4. 瞬間,九億個地址銳減至 一千萬個(個十百千萬十萬百萬千萬)。
  5. 繼續於遊戲中把模型變大,再次使用“數值增加了”進行掃描,不斷縮小範圍。

4.3 無變化之值之妙用

於不斷放大之過程中,假設吾輩將滑塊拉到了最大值 10,無法再超過了。

爲繼續篩選,吾輩或會將其改回 0,然後再重新拉回 10

此時,一個致命之邏輯陷阱出現了:

上一次吾輩掃描之終點狀態,滑塊是十。現在吾輩折騰一圈又拉回了十。若此時吾輩再去搜索“數值變大了”,汝會發現找不到目標了!因當前狀態之 10,對比上一次 CE 記錄之狀態 10它既沒有變大,也沒有變小,它是沒有改變的!

此時,就必須祭出 CE 過濾中最核心之一招:無變化的值

爲何會有此選項?因當吾輩無法確定數值到底變大還是變小時(或如上述情況兜轉回原點時),只要吾輩知其相對於上一次掃描沒有變化,便可用其來大清洗。

  • 清洗底層噪音:計算機系統中,有無數之內存地址在每一毫秒都在瘋狂跳動(系統時間、渲染幀率、網絡心跳包等)。比如,吾輩可隨便搜索一下無變化之值,原本 三萬九千個地址瞬間就變成了 三千九百個!因那些始終在後台跳動之垃圾數據,直接被“無變化”此嚴苛之條件給踢出局了。
  • 重複過濾:吾輩可不改變遊戲內之狀態,連續多次點擊“再次掃描(無變化的值)”。汝會看到它一直在持續剔除那些偷偷發生改變之無關內存地址,直到地址數量徹底穩定下來。

經過反覆之“變大(尋找 Increased value)”、“變小(de 開頭,尋找 Decreased value)”以及“靜止不動(尋找 Unchanged value)”之交叉過濾,最終地址減少之速度會越來越慢,可能卡在 兩千多個地址,再也不像之前那般大幅縮減了。


五、二分法與內存鎖定機制

爲何經過如此嚴密之過濾,還會剩下兩千多個地址同時在變動呢?

因某些功能點牽扯到了無數個底層程序。 汝拉動一個滑塊,不僅改變了模型參數,可能同時觸發了 UI 渲染、陰影重算、物理碰撞體積更新等一系列連帶反應。此兩千個地址都在忠實地根據汝之拖動而變化。

然控制核心邏輯之源頭地址只有一個!吾輩怎從此兩千個長得一模一樣之同步變化地址中將其揪出?

下面將介紹一種被稱爲“最笨但也最無解”之法——二分法內存鎖定

5.1 待修改區域與鎖定功能

首先,於左側地址欄按下 Ctrl + A 全選此兩千多個內存地址。然後點擊列表右下方之一個紅色對角線小箭頭,將此等地址全部轉移到底部之**“待修改區域”**。

於此區域裏:

  1. 雙擊某個地址後面之數值,可將其強行改爲任意值。
  2. 更關鍵者爲最前方之方塊(鎖定框)。一旦勾選鎖定,意味著 CE 會以極高之頻率凍結此內存地址。無論汝於遊戲中如何拖動、如何改變狀態,此被鎖定之內存地址之數據都將被死死釘住,絕對不會被改變!

5.2 鎖定排查實戰演練

吾輩就要利用此鎖定特性來做排除法:

  1. 最大化狀態:首先於遊戲中把滑塊拉到最大,觀察模型大和小之明顯視覺變化。
  2. 鎖定一半:於底部之待修改區域,選中最上面之一批內存地址(大概一半),按住 Shift 鍵往下拉選中一段,然後輕輕敲擊鍵盤上之 空格鍵。瞬間,此批被選中之地址前面都打上了鎖定勾。
  3. 遊戲內驗證:回到遊戲,嘗試把滑塊往小拉。
    • 理論邏輯:若真正之控制內存被吾輩鎖定了,那麼無論滑塊怎麼動,遊戲裏之模型應始終保持“最大”之狀態(因前端數據被凍結了)。
    • 實際表現:拉小滑塊後,發現模型居然跟著變小了!並未被影響。此說明什麼?說明剛才鎖定之那一半地址裏,全都是廢物,沒有吾輩要找之源頭值
  4. 無情剔除:既然不是,右鍵點擊此批地址,選擇 Delete(或者直接按鍵盤快捷鍵 Del),將其直接刪除掉。
  5. 循環逼近:再選中剩下地址中之一半,按空格鎖定,回遊戲觀察。沒影響?繼續右鍵 Delete。就這樣劈一半、刪一半,再劈一半、刪一半。
  6. 曙光乍現:當刪到某一批時,再回遊戲拖動滑塊,發現**“不太對勁了,模型越來越小了,甚至都凹進去了!”** 此說明什麼?說明這一次鎖定之地址堆裏,終於包含了那個真正之核心控制地址。
  7. 逆向反推:先把凹進去之模型恢復原狀取消鎖定。既然目標在上面此一批裏,那下面剩下之那些地址就全都不用了,直接刪掉。
  8. 終極鎖定:於包含目標之此一小堆地址裏,繼續切分。鎖定一半,沒反應?刪掉。鎖定另一半,有反應了!範圍縮小到只剩兩個地址。兩個兩個來試,排除掉不是之那倆,刪掉。
  9. 真相大白:最後審視剩下之最後兩個內存地址。修改第一個地址,發現遊戲畫面立刻出現不規則之劇變(“越來越那啥了”)。至此,吾輩成功揪出了唯一之控制內存!

六、從內存修改到後端業務邏輯漏洞

前面花費了大量篇幅講解內存搜索與修改,很多人(尤其是純做 Web 滲透之人)會產生一個巨大之疑惑:“吾於本地把內存改了,只有吾自己電腦之屏幕上能看到變化(俗稱自娛自樂),此到底有何用呢?”

6.1 案例一:道具購買時之負數繞過漏洞

假設遊戲中有一道具商城,道具有其對應之屬性和數量。

正常情況下,吾輩於商城界面點擊購買“一個”道具時,客戶端(前端)會在底層組裝一個請求,給服務器(後端)傳送兩個關鍵數據:

  1. 道具 ID(比如 1001
  2. 購買數量(比如 1

此兩個參數,在發送給服務器之前,是實實在在地躺在吾輩本地內存裏的!

若此時,吾輩利用上述學過之 CE 搜索技巧,精確找到了儲存“購買數量”之那個內存地址,並在其發送請求前,強制把原本之 3 改成了 -3(負三)

核心爆破點來了:

吾輩於本地改掉後,再次點擊購買按鈕。客戶端此時抓取之內存數據已經是 -3,它會將此被篡改之負數原封不動地傳給服務器。

若後端之開發人員在編寫業務邏輯時,只校驗了“金幣是否足夠”,卻忘記對購買數量進行負數校驗,那麼服務器就會處理此 -3。結果往往是:玩家非但沒有扣錢,反而因“扣除負三個道具之造價”,導致自己之金幣餘額瞬間暴漲!此即利用本地內存修改直接影響前後端數據交互,從而引發之嚴重業務邏輯漏洞。同理,前面提到之修改人物建模參數,若後端接收並保存,汝便能在全服玩家面前展示出一個突破常規建模之畸形/與衆不同之角色。

6.2 案例二:利用隱藏職業 ID 實現越權創建

除外部數據篡改外,內存修改還能窺探和提前利用未開放之功能。

職業切換乃一個極其典型之重災區。假設遊戲後端已經實裝了下一款大版本更新之職業——“槍炮手”。後端之代碼邏輯、數據表都寫好了,僅僅是當前之客戶端(前端)尚未放出,UI 界面看不到此按鈕。

此時客戶端看不到怎麼辦?吾輩依然可掏出 CE!

  1. 模糊搜索定位 ID:吾輩於創建角色界面,反覆切換現有之職業。比如先選中弓箭手,使用模糊搜索(未知初始值);然後切換爲戰士,搜索“變化的值”。通過不斷之反覆切換、有變化、無變化之篩選,最終於內存中揪出代表“職業 ID”之那個內存地址。
  2. 尋找工整之規律:此類核心 ID 於遊戲中通常設計得非常工整。無論是技能 ID、人物 ID 還是副本 ID,彼等絕非雜亂無章。比如:戰士之職業 ID 是 10101,法師是 20101,道士是 30101。此乃一種高度規範之格式。
  3. 盲猜與越權發送:掌握了規律後,吾輩不難推測出那個被隱藏之槍炮手 ID 可能是 40101 或某個極其相近之值。吾輩於找到之內存地址中,將原本戰士之 ID 強制篡改爲此隱藏 ID。
  4. 絕殺:點擊“創建角色”按鈕!若後端僅僅依靠前端 UI 來限制玩家,而忘記在接口處做二次校驗(鑑權),那麼吾輩向服務器發起之“創建槍炮師”請求就會被綠燈放行。作爲一個普通玩家,吾輩就這樣硬生生地越權創建了一個隱藏職業!此於遊戲安全測試中,乃一個極其經典之漏洞點。

6.3 爲何不用抓包?

講到此處,很多懂得安全測試之讀者一定會拋出一個靈魂拷問:“既然是爲了篡改發給服務端之數據,吾輩用 Burp Suite 或者 Fiddler 直接抓包改包,不是更直接、更簡單一些嗎?沒毛病吧?”

抓包確實更簡單,然問題出在網絡協議與加密機制上!

  1. 非 HTTP 協議之阻礙:現在之網遊、手遊,基本上爲保證通信之低延遲和實時性,極少會走傳統之 HTTP/HTTPS 協議,絕大多數都是直接走 TCP 或 UDP 底層協議。傳統之 Web 抓包工具對此往往束手無策。
  2. 加密數據之亂碼困境:不僅如此,遊戲數據在發送前幾乎全被高強度加密了。吾輩就算用 Wireshark 抓到了包,抓到之也全是一堆毫無規律之亂碼。
  3. 解密門檻過高:若要行走抓包路線,遇到加密,吾輩要麼得自己具備極強之逆向分析能力去寫一套解密工具,要麼得花錢買解密腳本。大多數人都不會寫解密工具,硬著頭皮解密極爲繁瑣和困難。

爲何 CE 能無視此等難點?

因無論數據在網絡傳輸中被加密成了什麼鬼樣子,在其剛剛產生於客戶端內部、尚未被加密函數處理、還躺在本地物理內存裏之那一刻,它一定是明文的! 吾輩於內存中修改它,相當於在數據加密打包“上車”之前,就把貨物給調包了。隨後,客戶端自己之加密代碼會自動幫吾輩把此份“假數據”完美加密,並走 TCP/UDP 穩穩當當地發給服務器。此乃極其優雅之降維打擊!

6.4 案例三:突破 APP 加密之直播間越權開播漏洞

此種降維打擊不僅適用於遊戲,於 APP 和 Web 業務線同樣大放異彩。

於測試某些直播平台時,汝可能會發現直播間之許多核心功能點沒走 HTTP 協議,而是走了 TCP/UDP,並且傳輸數據全被加密,抓出來之包全是亂碼,根本解密不了。沒法抓包改包,測試陷入死胡同。

此時內存測試法就成了破局之唯一希望:越權開播漏洞

  1. 吾輩打開 CE,附加到直播 APP 之進程中。
  2. 通過數值變化規律,於本地內存裏找到了儲存“吾之直播間房間號”之地址。
  3. 於點擊開播之前,吾輩將此內存地址裏之數值,強行改成了他主播之直播間 ID
  4. 點擊「開播」按鈕。APP 前端攜此遭篡改之他人 ID 進行本地加密,順利經由網絡傳至後端伺服器。
  5. 因彼時後端開發者過度信任前端傳來(且經嚴密加密)之數據流,忘卻於後端執行至關重要之鑒權操作(校驗發請求之用戶 UID 是否具備該直播間 ID 之開播權限),終致漏洞觸發——吾等今竟於他人直播間內強行開播矣!

此亦完美印證,於遭遇加密、非標準協議之死胡同時,內存修改於特定業務場景下,實為極好用之神兵利器。


七,無他,唯手熟爾

何謂內存修改器?如何使用之?歸根結柢,核心僅兩步:

  1. 搜索吾欲尋之值
  2. 修改吾欲尋之值

Cheat Engine 僅為汝手中之劍。招式看似簡單,無非「搜索」與「修改」;然此劍能刺多深、斬多準,終究取決於持劍人之功力。

此路無捷徑。汝須親自動手,拆解數十款遊戲,啃透上百 App 之本地內存交互,於海量數據中反覆篩查、不斷試錯,直至從混沌中逼近那唯一正確之答案。過程往往枯燥,亦正因如此,當真相浮現時,方更令人著迷。