【C++】從零開始的CS:GO逆向分析1——尋找偏移與基址的方法

2022-09-25 21:00:21
【C++】從零開始的CS:GO逆向分析1——尋找偏移與基址的方法
 
前言:此文章主要用於提供方法與思路,fps遊戲基本都能如此找偏移,文章裡找的偏移比較少,主要用來演示尋找思路,文章的後記中會附一個大佬的github專案,專案會定期更新CS:GO遊戲中常用的偏移值,寫程式的時候使用大佬專案裡的內容即可。本章需要CE基礎,達到會改植物大戰殭屍的陽光就可以了,全稱採用CE搜基址,沒有使用組合分析。
 
環境:Steam裡的CS:GO 和 Cheat Engine7.4,設定好這兩個我們就正式開始了
 

尋找地址前的準備

進入遊戲,選擇人機練習賽,進入遊戲,在遊戲內使用`開啟控制檯,在遊戲控制檯內輸入如下指令

sv_cheats 1
mp_roundtime_defuse 60
bot_stop 1
mp_restartgame 1

 

指令完成後休閒模式變成60分鐘一局,機器人暫停,以方便基址的查詢,不然找一會兒遊戲重新開始了,又要重找

使用CheatEngine附加到CS:GO程序

1.找自己的角度

角度:是人物面朝的方向,有上下角度和左右角度(搖頭,點頭),在遊戲開始時,上下角度和左右角度都為0,角度是單浮點型別,頭擡到最上方時,上下角度=-89,低到最低的時候上下角度=89,左右角度和上下角度的數值是連在一起的

 

找角度的方法:用(角度是單浮點型別,頭擡到最上方時,上下角度=-89,低到最低的時候上下角度=89)這個特徵尋找:

頭擡到最高處,CE搜尋單浮點精確數值-89

頭擡到最低處,CE搜尋單浮點精確數值89

頭往上擡一點,則搜尋減少的數值,往下低一點,則搜尋增加的數值

 

幾次過濾後得到七百多條資料,將這些資料都拖到下面,進行篩選

篩選方法:

一次選中一半的數值,按Enter鍵批次修改數值,隨便修改一個 -89~89的數值

如果人物的視角發生了改變,則說明其中有正確的數值

將沒選中的另一半刪除掉

再對剩下的數值進行上述操作,幾次後能找到一個正確的數值(或者幾個),修改數值,視角變化,則確定是上下角度

選擇瀏覽相關記憶體區域,尋找左右角度,一般上下角度和左右角度是連在一起的

 

將資料顯示模式改為浮點型

 

可以在上下座標(29.40)右側,發現資料(-130.82),修改右側資料,人物畫面左右移動,則確認是左右角度

 

由此得到:上下角度的偏移值=FBF64DA0 、 左右角度偏移值= 上下角度偏移值+4

進入下一步,通過偏移值尋找基址

尋找基址一般有兩種方法,一種是通過CE掃地址,來追基址,一種是讀組合,不斷找上層call,這邊就採用第一種來舉例:

下一個存取斷點

 

可以看到視角來源於ESI+4D90

上下角度 = [ESI+4D90]   ESI=FC690010

 

CE中搜尋 FC690010(ESI) ,看哪塊記憶體儲存了ESI的值,直接搜出來一個基址,直接拿來用就行了

得到 ESI=[engine.dll+58CFDC],結合上下角度 = [ESI+4D90],得到:

上下角度 = [[engine.dll+58CFDC]+00004D90]

左右角度 = [[engine.dll+58CFDC]+00004D90]+4

得到人物角度的基址

 

2.找自己的座標

座標:遊戲中人物的座標是三維的,其資料型別為浮點型,其中Z軸的值是最好確認增加和減少的,所以採取的方法是先尋找Z軸的值,在Z軸旁邊的就是X,Y軸的值

找座標的方法:幾次搜尋後可以得到Z軸的值,得到Z軸的地址後,X,Y軸的地址就在Z軸地址旁邊

在遊戲中找一個箱子,CE先搜尋未知的初始值(單浮點)

 

跳到箱子上後CE再次搜尋增加的數值

 

從箱子上跳下來後CE搜尋減少的數值

 

不移動人物,進行開槍,開鏡,換彈,丟槍操作後CE搜尋未變動的數值,在平地上左右移動後搜尋未變動的數值

 

來回反覆幾次,最後過濾到四百多條,基本過濾不動了,將所有的結果新增到下面,再次篩選

 

篩選方法:

對半修改,選擇一半,改為一個隨便的值,看人物的是否上下移動

如果上下移動,則說明其中有正確的值,將另外一半的地址刪除

重複,直到出現一個或多個值

注:遊戲改崩了很正常,不要在意,重新來過

 

選擇瀏覽相關記憶體區域,可以看到Z軸的資料前有兩個資料,通過修改,人物前後左右移動,確定是X軸的值和Y軸的值

得到:

z座標 = 7808B764

x座標 = z座標的地址 - 8

y座標 = z座標的地址 - 4

進入下一步,通過偏移值尋找基址(至於為什麼沒有圖,原因是忘記截了,又懶得再搞一遍了)

先下存取斷點,得到 Z軸的座標 = [EDI + 000001E4]   EDI = 7808B580

在ce裡四位元組,十六進位制 搜尋7808B580(EDI),得到兩個基址,裡面儲存了7808B580,隨便拿一個用,可以得到 EDI=[server.dll+AC6258]

綜上所述:

Z軸 = [[server.dll+AC6258]+1E4]

x軸 = [[server.dll+AC6258]+1E4-8]

y軸 = [[server.dll+AC6258]+1E4-4]

得到人物座標的基址

 

3.找敵人的的座標

座標:敵人的座標也是三維的,前文已經找到自己的座標,可以通過自己與敵人的相對位置來找,即,自己站的比敵人低則搜尋值大於***(自己的座標)

找座標的方法:

先在遊戲控制檯輸入

mp_limitteams 0
bot_kick
bot_add_ct

 把其他機器人都踢掉,只留一個ct,方便查詢

先搜尋單浮點,未知的初始值

 

自己站的比敵人高則搜尋值小於***(自己座標),此時站得比CT高,自己的z軸是56,搜尋值小於56

 

 自己站的比敵人高則搜尋值小於***(自己座標),此時站得比CT低,自己的z軸是-102,搜尋值大於-102

 

 此時和CT同一高度,則搜尋值等於0.27

 

期間可以通過bot_stop 1 指令使機器人停止活動,以方便查詢

經過幾次重複可以找到幾百個值,選取修改,如果修改後人物浮空,則說明正確的值在其中,則刪除另外一半的值,反覆幾次,得到一個正確的偏移值

 

選擇瀏覽相關記憶體區域,顯示型別改成單浮點,可以看到敵人的X軸和Y軸

 

通過偏移值尋找基址

選擇敵人x,y,z軸中的一個,使用上面使用的方法(下存取斷點,搜上一層偏移)可以得到

人物的座標 = [[client.dll+0x4DDD91C]+138]

此時需要補充一個知識點,在遊戲開發的過程中,同樣型別的事物會被寫成類,而在遊戲中範例化物件,像CS:GO此類fps遊戲中,人物物件一般都包括人物的血量,人物的護甲,人物開鏡狀態,人物蹲起狀態,人物的位置,人物的骨骼矩陣,人物視角矩陣,而此偏移138,則有可能是人物的位置,通過CE,可以分析這個結構,判斷其他偏移

 

選擇檢視記憶體,分析資料結構

 

在框中輸入client.dll+0x4DDD91C,選擇 結構->定義新結構,得到如下檢視,可以發現,每個指向C_CSPlayer物件的指標之間都差0x10

 

點開一個結構,可以在A8處看見人物的Z軸座標

 

 在100處看見人物的血量

 

則可以得到

人物的血量 = [[client.dll+0x4DDD91C]+100

人物的Z軸座標 = [[client.dll+0x4DDD91C]+A8

其他的資料也都可以通過這個指標來分析,故總結一些就是通過人物的座標( [[client.dll+0x4DDD91C]+0x138]) 找到 人物物件([client.dll+0x4DDD91C]) ,通過人物物件找到血量([client.dll+0x4DDD91C]+0x100)

 

4.找自己的視角矩陣

注:只寫方法,沒有截圖

視角矩陣:這是個3D遊戲,但螢幕是二維的,所以需要一種方法把3D的座標轉換為螢幕上的2D座標,這個是通過視角矩陣和人物座標實現的

矩陣的特徵:

4x4

array[0][0]不開鏡的時候小於1

自己的矩陣下面一行會跟著一行幾乎一樣的資料

視角轉變會變化,開鏡會變化

擡頭(最上面)看的時候,array[3][3]和array[3][4]都是1.00

低頭(最下面)看的時候,array[3][3]和array[3][4]都是-1.00

方法:

先搜未知的初始值,轉個頭、開個鏡、轉個身 都搜變動的數值,不動視角切槍,換彈,搜未變動的數值,幾次下來就剩下幾個數值了

挨個點選瀏覽相關記憶體,動視角,看哪一塊記憶體是4*4的動,再不動,單獨看開鏡,是否變動,結合上面的1.00和-1.00直到找到覺得正確的值

可以在記憶體裡看到矩陣

至此,找偏移的部分就結束了。

後記:

  寫這篇文章的原因:當時感興趣想學一下的時候網上沒有能參考的文章,現在我把方法和思路分享出來,未來如果有想學習的人,可以多一篇參考文章

  後面的程式碼部分會用到這篇文章找到一些基址

  大佬的github:https://github.com/frk1/hazedumper