從游戲安全的角度我們來看看FPS游戲,這種型別的游戲變態外掛總是層出不窮,如飛天、蹲地、無后座力、加速等等,
那么為什么總是“無法杜絕”這一類變態功能呢?FPS游戲注重游戲體驗,游戲公司為了保證玩家的流暢性和打擊感,將許多重要資料放在本地客戶端進行處理,這就給了外掛開發者有機可乘,
但是隨著5G時代的到來,會得到很大的緩解,不過也要考慮到服務器壓力,
另外自瞄等演算法類功能是永遠無法完全避免的,因為他可以單純的是把人類的演算法自動化,精準化而已,雖然看上去功能很BT,但實際上他并不是串改游戲代碼或則利用什么BUG,
如果在關鍵處修改一些邏輯代碼,即可實作多樣性的變態功能,夸張的說,只有你想不到,沒有做不到,如下圖變態功能:
全屏爆頭:

一個完整的變態功能,往往是由多個功能組合而成,如果想要檢測它,不妨分析一下實作原理:
- 子彈加速,先前有文章詳細講解,有興趣的朋友可以翻看之前筆者的發文,
- 無需換彈,先前有文章詳細講解,有興趣的朋友可以翻看之前筆者的發文,
- 不難看出,該玩家明明打在空處,卻有怪物不斷死亡被爆頭,應該修改了怪物受傷點相關的代碼,或者通過明文發包發送了“打中怪物頭部”的封包,
說到槍槍爆頭,很多人第一反應想到的是自動瞄準,確實,自動瞄準已經司空見慣,幾乎所有的fps型別游戲都不可避免受其毒害,也是我們最熟悉的一種惡性外掛,
然而觀上面動態圖的效果,并非自動瞄準,可以看出明明打在了空處,卻有怪物不斷死亡,明顯修改了客戶端邏輯代碼,那么今天就跟隨筆者一起深入分析“爆頭”實作的可能性,
正文:
熟悉fps游戲的朋友,應該都知道“擊中部位”,比如擊中腿部傷害略低,擊中胸部傷害略高,而擊中頭部幾乎就是滿血秒殺,從逆向的角度出發,不難想象,游戲人物/怪物模型 在記憶體中存在著這樣一些地址,
例:
- 頭部受傷點地址
- 胸部受傷點地址
- 手部受傷點地址
- 腿部受傷點地址
- 等等,
而這些屬性很大的可能是人物/怪物的某個下標,不妨在遍歷出物件以后,在物件下進行仔細的觀察,說不定有意外的驚喜,
可能有的朋友會問,知道這些有什么用? fps特性在此不再重復,不明原理的童鞋可以簡單粗暴的把fps想象成一個“單機游戲”,既然是“單機游戲”,是不是資料都在玩家電腦上? 假如將胸部受傷點,強制鎖定為頭部,是不是擊中玩家胸部以后,實際打中的是頭部呢?如果將所有的受傷點都遍歷出來,全部鎖定為頭部,是不是可以實作“槍槍爆頭”?
明白了槍槍爆頭原理,那么這個全屏打怪又是什么原理?真的是所謂的“子彈追蹤”這么厲害嗎?其實原理非常簡單,人物/怪物模型每個受傷點都有一個“區域”,而這個“區域”有著“大小”屬性,而擊中模型這塊“區域”決定著你打中的是哪里,
例:
頭部受傷點地址
下標之一 范圍:20
胸部受傷點地址
下標之一 范圍:50
手部受傷點地址
下標之一 范圍:10
腿部受傷點地址
下標之一 范圍:30
知道了“區域大小”這個屬性的存在以后,是不是很容易就明白了?將“頭部區域”改為特別大的數值,列入原先20,將其改為200,2000甚至更高,是不是不管指哪里,都可打中目標,配合前邊分析的槍槍爆頭原理,即使修改的是其他“區域大小”,也可實作所謂的“全屏追蹤爆頭”,
那么應該尋找這個受傷點和“區域大小”呢?在cf中,打中人物模型之后,無論是何部位,準星都會變成紅色,以此為突破口,
分析作業完畢,接下來就是實踐,筆者一項信奉實踐是唯一的真理,fps記憶體資料變化較快,還是老套路,先保存記憶體,看過先前文章的童鞋此處自動忽略:
OpenProcess () //取得游戲句柄
ZwSuspendProcess() //通過句柄將其掛起,保存記憶體狀態,
ZwResumeProcess() //通過句柄恢復掛起,還原記憶體狀態,
CloseHandle () //釋放句柄
首先,擊中人物/怪物的一瞬間,也就是準星變成紅色的時候,將游戲掛起,保存記憶體狀態,搜索未知的初始值,如下兩圖:

在此狀態下將其掛起,

搜索未知的初始值

恢復記憶體狀態,再次擊中(別和上次同一個部位,如上次擊中胸部,此時可以選擇擊中腿部)將其掛起,保存記憶體狀態,搜索變動的數值,由于需要搜索多次,建議拿手槍或者威力較小的槍,或者直接在血量較多的模式下搜索,否則容易將物件打死,

再次掛起,保存記憶體狀態,

來回重復搜索后,發現某個地址,在擊中不同的部位下,數值都不同,且平時為0(空),
直接改這個地址是否可行?其實仔細想想,以這種方式搜索出來的地址,只是擊中瞬間讀到的“受傷點”而已,修改他并沒有什么效果,真正的受傷點地址,是不會因為被打中而發生變化(猜測:可能會因為人物移動 跳躍下蹲等發生變化),那我們這么幸苦的搜索,有何意義?
得到了這個“受傷點相關”的值以后,是不是給他進行范圍搜索?先遍歷出當前人物/怪物的物件,在物件地址一定范圍內進行搜索,結果一幕了然,搜索出的地址就一個,不妨大膽猜測,是不是就是上面分析的“區域大小”呢?
如實驗的怪物物件名稱是“古代老鼠”,地址處于物件下標(值得注意,怪物和人物不處于同一遍歷下) 0x354 處,原有值為 15(float),將其修改為200(float),發現在游戲中并沒有實際效果,說明該地址也不是真正的“受傷點”,而用CE查看訪問代碼的時候,卻發現在不停的訪問,證明與其他地方有關聯,
那么嘗試去去OD中下硬體寫入斷點,來到了一個類似于“陣列”的地方,如下圖,eax來源于[esp+0x3954],esp來源于一個基地址(防止他人惡意用途,基址不進行截圖),

且在該地址+4,+8等處,都是相似的(float)值,如下圖:

那么再次嘗試將其修改鎖定為200(float),這次終于了有實際效果,
(注意:截圖中是以人物模型為例,怪物模型方法同上)

只要準星在該型別怪物附近(不用瞄準),都可打中怪物,且槍槍爆頭,說明該處為怪物的“頭部受傷區域”,而在+4的位置修改為200,也可打中怪物,不過失去了原有的爆頭效果,猜測可能為胸部或腿部“受傷區域”,
而一個圖內,不可能只有一種怪物,也會有BOSS和其他一些小怪,想要實作槍槍爆頭,必須每種怪物都修改“受傷區域大小”,仔細觀察該地址附近,尋找是否有(float)值(從正向角度出發,一般坐標型別的,以浮點可以表達的更加精準),都進行一個嘗試性的修改,如地址附近 [基址]+0x35690 的位置,發現的類似的浮點,修改后發現為“滾球”的怪物頭部受傷點區域,而要將每一種怪物都找出來,就需要一定的時間和耐心了,
多觀察附近地址,說不定有意外驚喜,單浮點十六進制多以0x4開頭,

小結:該游戲將模型“受傷點區域大小”這一屬性,存放到了相同的遍歷下,通過ID在某處進行了一個關聯,而不是在物件之下,
游戲安全防護和反外掛建議:
- 對容易被串改的代碼進行CRC驗證以及CRC的CRC,
- 除了本地加一定的檢測(CRC之類的)之外,服務器可以判斷爆頭率和子彈射速,雖說fps實時檢測會影響玩家體驗,但卻可以進行資料回掃,如玩家打完一局之后,進行該對局資料回掃,判斷其戰績(檢測爆頭),以及流量監控(加速類功能會大量給服務器發包),
- 檢測滑鼠軌跡和滑鼠速度,沒有哪個變態家伙是可以每次都瞬間直線滑動滑鼠進行精準爆頭的,
- 通過玩家的舉報進行精準確認,
深入學習游戲逆向分析,CSDN學院任鳥飛逆向
課程的內容、價格、售前、售后服務在線客服咨詢
免費0基礎逆向入門課
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/202144.html
標籤:其他
