外掛的前世今生
一、引入主題
-
提出兩個問題(不需要ppt):玩個遊戲?沒開過外掛?
-
韓國開掛違法
https://techcrunch.com/2018/06/25/overwatch-hacker-seoul-jail-time/
-
因此不考慮反外掛機制
-
因此很多韓國遊戲:DNF、冒險島、CF外掛橫飛
-
CF底層設計爛,當時韓國遊戲公司Neowiz出售戰地之王給騰訊,為了更大的利益,將CF作為繫結贈品,要求騰訊出低價買入。由於戰地之王對電腦的高配置要求攔截了大量玩家,CF熱度逐漸上升,騰訊壓根沒有想到,一款贈品遊戲竟能成功。
二、什麼是外掛?外掛的功能?外掛的相關概念?
-
外掛——非法竄改遊戲資料流
-
功能——在遊戲程式執行時執行,能訪問遊戲程式記憶體,從而對資料進行增刪查改
[]: https://blog.csdn.net/weixin_30755393/article/details/96607741?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160830999416780276319996%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fblog.%252522%25257D&request_id=160830999416780276319996&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_v1~rank_blog_v1-12-96607741.pc_v1_rank_blog_v1&utm_term=cf%20自瞄%20原理
三、如何實現一個簡單外掛?
https://www.bilibili.com/video/BV1ys411e711
//main.c
void change(){
MessageBoxA(0,"ABCD","EFGH",0);
}
int add(int a,int b){
return a+b;
}
void main(){
int num=0;
printf("%x,%x,%x",change,add,&num);//三個關鍵的地址
while(1){
printf("%d",num++);
sleep(5000);
}
}
執行該程式,列印函式change、add和num的地址,每5秒num+1,這就類比一個遊戲程式,num為其中實時改變的資料。
假設change地址為0xde1064,我們可以定義一個函式指標來呼叫它。
_declspec(dllexport) void mainA(){
void(*p1)()=(void(*)())0xde1064;
p1();
//通過函式指標呼叫函式
}
由於一個程式不能訪問另一個程式的記憶體空間,我們將該程式設定為動態連結庫dll檔案,從而使mainA可以從外部呼叫。
我們知道,Windows自身就是大量使用dll的系統,許多dll檔案在啟動時便被相關的應用程式載入進記憶體裡執行了,可是有誰在程式裡直接看到過某個dll在執行的?因為系統是把dll視為一種模組性質的執行體來呼叫的,它內部只包含了一堆以函式形式輸出的模組,也就是說每個dll都需要由一個用到它的某個函式的exe來載入,當dll裡的函式執行完畢後就會返回一個執行結果給呼叫它的exe,然後dll程式退出記憶體結束這次執行過程,這就是標準的dll執行週期
這也叫dll注入或鉤子注入。
如此,我們便可以從外部呼叫內部的函式,從而實現外掛的功能,
比如:有一個撿金幣的函式getCoin()只有在人物觸碰金幣時觸發。但通過這種dll注入,我們便可以不斷地在dll檔案中呼叫getCoin()從而實現無限金幣。其他同理。
修改遊戲資料也是一樣
_declspec(dllexport) void mainA(){
int*p1=(int*)0x24fcb0;
*p1=99999;
//通過指標改變資料
}
四、外掛的分類(按照資料鏈路來分)
- 內掛(修改客戶端資料)
- 離線掛(修改網路資料)
- 私服(修改服務端資料)
五、CF外掛史
https://www.bilibili.com/video/BV157411u7VV?t=481
https://www.bilibili.com/video/BV1WE411E7mQ?t=690
5.1 2008 幽靈顯刀、火線指南針
-
新地圖狼穴→rf017.rez bug→玩家發現bug→舊檔案覆蓋新檔案→顯刀
-
非外掛,而是檔案錯誤
-
為後續外掛提供思路
-
80%透視顯鬼都基於此
5.2 2009-2011 外掛爆發:大為、小刀
5.2.1 起因
- 頁游出現,缺乏引流
- 2010年起出現捆綁外掛
- 以免費為噱頭,鑽法律空子
- 廣告聯盟+1刀999,1刀999賺到錢反哺外掛作者
- 網咖全員紅框框綠框框,一局遊戲16個人15個是掛
5.2.2 外掛作者過掉反外掛檢測的手段
-
如今國際外掛界仍在使用
-
寄生獸法:輸入法注入(利用Windows特性)
- 利用Windows系統中在切換輸入法需要輸入字元時,系統就會把這個輸入法需要的ime(即dll)檔案裝載到當前程式中,因此我們可以利用這個特性,在ime檔案中使用LoadLibrary()函式待注入的DLL檔案
-
不斷改名法
- 比較暴力
- 在作業系統看來,上一秒你是迅雷,下一秒就成了QQ,再下一秒成了快播
-
如何過掉CF的CRC檢測?(可能不會講)
-
CRC(迴圈冗餘校驗碼)
-
記憶體程式碼段:
jnz=非0則跳轉
mov eax,xxx CMP eax,1 jnz xxxxxxxx
-
假設,jnz 這句程式碼是執行換彈完畢的動作,那麼我們們想要零秒換彈的功能,在伺服器不做驗證的情況下,我們們可以修改cmp 或者 jnz為 JMP,在換子彈的時候,強制執行換彈完畢的動作,那麼如果改了這個地方,CRC會如何查呢?
-
CRC檢測原理:
- 機器碼
- JNZ xxx=0F85 xxx
- JMP xxx=E9 xxx
- CALL xxx=E8 xxx
- 因此只要修改了JNZ,機器碼必定會發生改變,CRC則是檢驗此處。
- 機器碼
-
一段CRC檢驗程式碼例子
mov eax,剛剛JNZ程式碼段的值 cmp eax,0f85 jnz 是否上報異常
-
5.2.3 自瞄透視的幾何原理
-
三個核心資料
- 1、視角FOV
- 2、準星資料地址
- 3、敵我XZY座標
-
四個技術問題
-
工具:CE(Cheat Engine)
-
1、如何找FOV?
- 視場角又稱FOV,視場角的大小決定了攝像機的視野範圍,簡單來說FOV就是螢幕與攝像機之間的夾角,我們可以通過狙擊槍的狙擊鏡來找到遊戲的視場角度,當未開鏡狀態時搜尋未知初始化資料(浮點數),開鏡後搜尋改變的數值(浮點數),依次遍歷即可找到該遊戲的視場角度,一般的FPS遊戲視場角為90度的居多。
-
2、如何找準星資料?
- 通常FPS遊戲滑鼠的準心Y座標向上抬會減少,滑鼠準心向下會增加,不斷的遍歷(浮點數)就可以搜尋到滑鼠的準心Y座標,得到了滑鼠的Y座標之後然後+4就能得到滑鼠的X的座標引數。
-
3、如何找玩家XZY座標?
- 通常情況下(X,Y)座標的浮動較大不好定位,我們可以找Z座標因為Z座標控制人物的高低引數比較好找,首先搜尋未知初始值(浮點數)然後跳到箱子上或走向更高的位置搜尋增加的數值,回到地面上搜尋減少的數值,重複這個過程最後就能找到Z軸的座標,在遊戲中(X,Y,Z)座標是緊挨著的結構(+0,+4,+8) 找到了Z座標相應的就可以計算出(X,Y)座標。
-
4、如何找敵人XZY座標?
- 首先在開始遊戲之前通過控制檯暫停對方陣營機器人的走動,使用
bot_stop 1
命令暫停,暫停後搜尋未知初始值,然後使用bot_stop 0
命令讓機器人走兩步後馬上暫停,搜尋變化的數值,開啟機器人走動馬上暫停,再次搜尋變化的數值,不斷嘗試直到找到正確的資料,只要找到X軸的座標,可以通過+4,+8的方式得到(Y,Z)的相對偏移。
- 首先在開始遊戲之前通過控制檯暫停對方陣營機器人的走動,使用
-
5、如何根據以上資料繪製方框透視?
-
假設遊戲分別率為1024*768
假設X視角為 π/2,那麼視角和2D螢幕的比例即為——1024/(π/2),那麼如何知道Y視角?768*(1024/(π/2))這個比例就可以輕鬆得到,反之知道Y視角,也可算出X視角。
那麼接下來就可以直接在2D視窗上繪製方框了,假設敵人在x視角內座標 0.56 的位置,那麼0.56*(1024/(π/2)),即敵人坐在螢幕X座標,Y座標同理。最終實現透視效果如下:
-
-
-
三個安全問題(時間不夠不講)
- 1、如何反找FOV?
- 在不影響遊戲流暢性的前提下,將視角地址存放在堆疊或臨時申請的記憶體地址中,即用即銷,增大逆向難度。
- 2、如何反找準星資料?
- 該遊戲雖然對準星進行了加密,但卻過於簡單。在不影響遊戲流暢性的前提下,建議將X座標進行動態加密,達到”肉眼無法分析“的效果,以增大逆向難度。
- 3、反外掛的建議?
- Hook所有讀記憶體函式,跨程式實現透視功能,必須要讀取遊戲記憶體,讀取資料時多多少少會留下痕跡,可用作判斷是否有第三方程式越權。
- 1、如何反找FOV?
5.2.4 騰訊安全團隊的對策
-
CRC(迴圈冗餘校驗碼)
- 記憶體程式碼段:
jnz=非0則跳轉
mov eax,xxx CMP eax,1 jnz xxxxxxxx
- 假設,jnz 這句程式碼是執行換彈完畢的動作,那麼我們們想要零秒換彈的功能,在伺服器不做驗證的情況下,我們們可以修改cmp 或者 jnz為 JMP,在換子彈的時候,強制執行換彈完畢的動作,那麼如果改了這個地方,CRC會如何查呢?
- CRC檢測原理:
- 機器碼
- JNZ xxx=0F85 xxx
- JMP xxx=E9 xxx
- CALL xxx=E8 xxx
- 因此只要修改了JNZ,機器碼必定會發生改變,CRC則是檢驗此處。
- 一段CRC檢驗程式碼例子
mov eax,剛剛JNZ程式碼段的值 cmp eax,0f85 jnz 是否上報異常
-
錯誤程式碼230
- 遊戲資料發生修改就報錯
-
TP反外掛系統
- 一天25小時高強度監測後臺
- 防止遊戲被注入
-
與警方合作
- 2011年大批元老外掛作者被捕,平均刑期在兩年左右
-
推出挑戰模式,拉回大量被外掛勸退的元老玩家。
5.3 2010-2011 封包時代:WPE地圖修改、VE刷槍
- WPE(Winsock Packet Editor)網路封包編輯器
- 使用原因:資訊在伺服器上,修改的可能性微乎其微
- C/S互動過程:玩遊戲時發出的指令→向伺服器傳送封包→伺服器分析封包→返回結果封包
- 例子:wpe所要改的,不是[遊戲裡面的數值],而是[修改資訊封包]。 什麼意思咧??就是我們用wpe所要改的,並不是"生命力由100變成10000"之類的東西, 這種東西無法用wpe改, 我們要改的可能是把"我賣了一個500元的東西" 改成"我賣了一個50000元的東西"或把"我得了10的金錢"改成"我得了10000的金錢"之類 的,或者是明明身上沒東西還一直賣"500元的東西"或沒怪物還"一直打10的exp"。
- 原理:WPE可以擷取網路上的資訊封包,然後分析和修改裡面的值.
- VE(Vzla Engine)遊戲記憶體修改器
- 搜尋變數基址達到修改目的
- 卡槍、刷槍騙局的工具
5.4 2011-2014 yy公會時代
- 漩渦老七公佈CF rez檔案解包方法
- 裝死外掛——改倒地為站立
- 飛天遁地——改走路為爬梯子
5.5 2015-?滑鼠巨集、驅動外掛肆意妄為
-
滑鼠巨集
https://www.bilibili.com/read/cv1223810
- 速點壓槍
- 遊戲中每種槍械是有屬性設定的,後坐力不同,那麼要比別人打得準,就要更好的控制好後坐力
- 壓槍巨集就是根據不同槍械的彈道,做一定幅度(可調)的游標下壓控制,你自己連發時不需要費勁的下往下拖拽滑鼠
- 一鍵上箱
- 一般的箱子按space空格鍵是跳不上去的
- 上箱子的跳法:W+S+蹲+跳
- 巨集設定了某個鍵一鍵觸發WS蹲跳四個鍵實現一鍵上箱
- 速點壓槍
-
驅動外掛(BadUSB)
https://www.bilibili.com/read/cv8046387/
- 附加一個硬體元件在使用者的CPU上,CPU直接從CF提取資料,這樣一來便無法檢測到
- 有一些外部硬體連線到使用者系統上,幫助他作弊時不被發現,因為一切都是在使用者系統之外執行的,所以作弊系統根本不可能被檢測出來
- 如加密狗
- [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-7SujBABU-1608453436840)(/Users/waterking/Downloads/EPOAim.jpg)]
六、外掛與前沿技術的結合
-
AI+Hack(Overwatch Aimbot)
https://ghostwarecheats.com
- 守望先鋒自瞄掛
-
openCV based Overwatch Aimbot
-
基於影像處理
https://github.com/HarrisonKeeling/overwatch-aimbot
-
動態找色
https://tieba.baidu.com/p/6447280329?pn=1
-
七、私服
- 服務端原始碼完全暴露
- CS1.6
- 找到人物生存的邏輯修改可實現無敵
- 冒險島
- 在Navicat 8.0資料庫中找到註冊的使用者
- 修改gm=0為gm=6實現設定管理員
- 直接使用各種內部邏輯
八、總結
抵制不良遊戲,拒絕盜版遊戲。注意自我保護,謹防受騙上當。適度遊戲益腦,沉迷遊戲傷身。合理安排時間,享受健康生活。抵制外掛,從我做起,謝謝大家!
相關文章
- MySQL 的前世今生MySql
- 遊戲的前世今生遊戲
- Mybatis的前世今生MyBatis
- IPD的前世今生
- RabbitMQ的前世今生MQ
- Serverless 的前世今生Server
- JavaScript的前世今生JavaScript
- WebP 的前世今生Web
- RunLoop的前世今生OOP
- Webpack前世今生Web
- Unicode的前世今生Unicode
- HTTP/2.0的前世今生HTTP
- 元件化的前世今生元件化
- React ref 的前世今生React
- Https的前世今生HTTP
- React Portal的前世今生React
- Android的前世今生Android
- React Mixin 的前世今生React
- Serverless For Frontend 前世今生Server
- 一、MySQL前世今生MySql
- 資料庫的前世今生資料庫
- iOS Device ID 的前世今生iOSdev
- 前端模組化的前世今生前端
- Redux的前世-今生-來世Redux
- HTTP 協議的前世今生HTTP協議
- JavaScript – 非同步的前世今生JavaScript非同步
- JavaScript 包管理的前世今生JavaScript
- 物聯網的前世今生
- ORACLE ERP 的前世今生Oracle
- LangChain和Hub的前世今生LangChain
- JavaScript 模組化前世今生JavaScript
- SQLMap的前世今生(Part1)SQL
- 對話系統的前世今生
- Apache Hudi和Presto的前世今生ApacheREST
- SAP UI5 的前世今生UI
- PYTHON編碼的前世今生Python
- 新零售的前世今生
- Jupyter專案的前世今生