【C++】從零開始的CS:GO逆向分析1——尋找偏移與基址的方法
尋找地址前的準備
進入遊戲,選擇人機練習賽,進入遊戲,在遊戲內使用`鍵打開控制台,在遊戲控制台內輸入如下指令
sv_cheats 1
mp_roundtime_defuse 60
bot_stop 1
mp_restartgame 1
指令完成後休閑模式變成60分鐘一局,機器人暫停,以方便基址的查找,不然找一會兒遊戲重新開始了,又要重找
使用CheatEngine附加到CS:GO進程
1.找自己的角度
找角度的方法:用(角度是單浮點類型,頭抬到最上方時,上下角度=-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],得到:
得到人物角度的基址
2.找自己的坐標
坐標:遊戲中人物的坐標是三維的,其數據類型為浮點型,其中Z軸的值是最好確認增加和減少的,所以採取的方法是先尋找Z軸的值,在Z軸旁邊的就是X,Y軸的值
找坐標的方法:幾次搜索後可以得到Z軸的值,得到Z軸的地址後,X,Y軸的地址就在Z軸地址旁邊
在遊戲中找一個箱子,CE先搜索未知的初始值(單浮點)
跳到箱子上後CE再次搜索增加的數值
從箱子上跳下來後CE搜索減少的數值
不移動人物,進行開槍,開鏡,換彈,丟槍操作後CE搜索未變動的數值,在平地上左右移動後搜索未變動的數值
來回反覆幾次,最後過濾到四百多條,基本過濾不動了,將所有的結果添加到下面,再次篩選
篩選方法:
對半修改,選擇一半,改為一個隨便的值,看人物的是否上下移動
如果上下移動,則說明其中有正確的值,將另外一半的地址刪除
重複,直到出現一個或多個值
註:遊戲改崩了很正常,不要在意,重新來過
選擇瀏覽相關記憶體區域,可以看到Z軸的數據前有兩個數據,通過修改,人物前後左右移動,確定是X軸的值和Y軸的值
得到:
z坐標 = 7808B764
y坐標 = z坐標的地址 – 4
進入下一步,通過偏移值尋找基址(至於為什麼沒有圖,原因是忘記截了,又懶得再搞一遍了)
先下訪問斷點,得到 Z軸的坐標 = [EDI + 000001E4] EDI = 7808B580
在ce里四位元組,十六進位 搜索7808B580(EDI),得到兩個基址,裡面儲存了7808B580,隨便拿一個用,可以得到 EDI=
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坐標,這個是通過視角矩陣和人物坐標實現的
矩陣的特徵:
視角轉變會變化,開鏡會變化
抬頭(最上面)看的時候,array[3][3]和array[3][4]都是1.00
低頭(最下面)看的時候,array[3][3]和array[3][4]都是-1.00
方法:
先搜未知的初始值,轉個頭、開個鏡、轉個身 都搜變動的數值,不動視角切槍,換彈,搜未變動的數值,幾次下來就剩下幾個數值了
挨個點擊瀏覽相關記憶體,動視角,看哪一塊記憶體是4*4的動,再不動,單獨看開鏡,是否變動,結合上面的1.00和-1.00直到找到覺得正確的值
可以在記憶體里看到矩陣
至此,找偏移的部分就結束了。
後記:
寫這篇文章的原因:當時感興趣想學一下的時候網上沒有能參考的文章,現在我把方法和思路分享出來,未來如果有想學習的人,可以多一篇參考文章
後面的程式碼部分會用到這篇文章找到一些基址
大佬的github://github.com/frk1/hazedumper