来叩网
请输入搜索词:
  

[原创]FPS网络游戏自动瞄准自瞄外挂漏洞分析以及实现_killcoco的小窝-CSDN博客

以下是大数据处理后,找到符合游戏外挂漏洞 [原创]FPS网络游戏自动瞄准自瞄外挂漏洞分析以及实现_killcoco的小窝-CSDN博客的所有相关结果,可以点击标题打开查看!

0x0. 前言

来到论坛已经有一段时间了,目前大三学生,乐于分享知识,看到论坛招聘讲师的帖子,于是想发点文字,分享知识,不知道能不能申请精华。

新年刚刚过去,不知道大家亲戚走没走完,新的一年里,祝大家财源广进,身体健康,万事如意,一切都会好起来的!

 

0x1. 了解FPS游戏自瞄漏洞

经常玩游戏的朋友,应该知道FPS游戏,例如:穿越火线,逆战等等,他们的特点就是以第一人称视角进行操作人物,屏幕中间会有一个准星,通过准星瞄准敌人进行攻击以达到击杀效果和游戏体验。

 

由于FPS游戏的特殊游戏体验,所以使得很多不法分子利用逆向知识开发了很多自动瞄准的工具,破坏了游戏平衡。具体的原理如下:

1.找到存放鼠标准星的坐标基地址

2.找到人物数组基地址

3.找到人物数组下人物的相关属性偏移:血量,名字,坐标,阵营等

4.通过阵营判断是否为敌人,通过血量判断是否死亡,利用算法将自己的准星坐标修改为敌人所处的位置,实现自动瞄准

 

0x2. 利用某FPS网络游戏进行分析

 

用到工具:CE,OllyDbg

 

首先,我们分析了解一下FPS鼠标准星的知识,并且找出他的内存地址:

 

搜索前,我们要理清思路,那就是如何去定位鼠标的坐标,怎么定位比较方便。因为游戏分为鼠标X和鼠标Y两种坐标,鼠标X即左右的坐标,鼠标Y为上下坐标,由于左右坐标在游戏中转一圈无法确定坐标数据是否增大还是减小,所以我们通常分析鼠标的Y,即上下坐标。

 

针对鼠标Y坐标变动的情况分析:

 

无鼠标准星特殊加密:

1.向上移动准星坐标增大,向下移动准星坐标减小

2. 向上移动准星坐标减小,向下移动准星坐标增大

 

鼠标准星特殊加密: 

鼠标准星上下无规律变动

 

对于没有鼠标准星特殊加密的游戏,我们通常在CE工具中搜索增加或者减少

对于存在 鼠标准星特殊加密的游戏,我们通常在CE工具中搜索变动或者未变动

 

另外,由于坐标等数据精度都是比较高的,所以我们通常搜索浮点数或者双浮点数

 

-----------------------------------------------------------------------------------------------------------------------------------------------------

                                                                                               ①开始分析鼠标坐标内存地址

 

我分析的游戏是创世战车,这是一款FPS射击网游,由于我已经提前逆向过,所以我们的CE操作顺序依次是:

 

附加进程->切换为搜索浮点数->搜索未知的初始值 ->鼠标向上搜索增加 ->鼠标向下搜索减少

 

然后 鼠标向上搜索增加 ->鼠标向下搜索减少重复循环过滤,最后我们剩下9个内存地址,通过修改得知:0x23E3588  是我们的鼠标Y内存地址

 

 

 

此时,我们已经得到了鼠标Y的内存地址,这个时候,我们不必去搜索鼠标X的内存地址,只需观察该地址相邻或者附近的地址值的变化即可得知鼠标X

因为鼠标XY坐标在游戏中存放是连续的,类似我们在上课写C语言结构体里面变量数据内存地址是连续的一样的道理

 

那么如何查看相邻地址内存呢?CE有个自带的功能:

 

 

按照图示的标注的顺序,在下面的窗口编辑框内填入相关地址:

 

 

 

在这里解释一下为什么我们需要填入23E3500,因为鼠标Y地址是: 23E3588,鼠标X在附近的位置,所以我们存在一个取值范围,这个范围不是很大,所以我们填入了一个估值,填入后定义结构体,一切回车默认即可。

 

通过观察和修改,我们发现当修改23E3584这个地址时,鼠标的X准星会变动,由此我们得知了该游戏的鼠标坐标内存地址,即:

 

鼠标X:Crossout.exe+1963584

鼠标Y:Crossout.exe+1963588(该游戏基地址存放是以模块名+模块偏移存放的)

 

 

 

至此,我们的鼠标坐标内存地址分析完毕,当然了,分析这个还不够,下面我们来分析一下人物数组及其结构:

 

-----------------------------------------------------------------------------------------------------------------------------------------------------

                                                                                               ②开始分析人物数组

 

说到人物数组,我们必须要了解一下游戏中人物对象的存放形式,一般均为数组, 优点:

1、按照索引查询元素速度快 2、能存储大量数据 3、按照索引遍历数组方便

 

而且这也是我们C/C++语言中常用的写法

 

那么我们来分析一下该游戏,由于该游戏没有子弹数量,所以我们可以通过血量来分析该游戏的数据:

 

由于血量精度也比较高,所以存放形式也多为浮点数或者双浮点数,由于精度过高,所以我们不能够搜索精确数值,改为搜索两者之间的数值:

 

 

通过撞击建筑物或者其他车辆,使自身血量变动,然后过滤到血量地址:

 

 

这个时候,我们需要用到另外一款调试器:OllyDbg

 

我们附加进程,使用dd指令,查看血量地址,然后下硬件断点,寻找数组和基地址

 

 

程序断在了0x011299D9位置处,观察寄存器,我们得知eax为人物的临时对象地址,0x0C0为我们的血量地址偏移:0x39EE8FF0 + 0x0c0 = 0x39EE90B0 (eax)

 

 

所以我们继续去追eax,通过单步call,我们发现eax实际上来源于上方的Call的返回值:

 

 

 

我们进入Call去追踪Eax来源,通过追踪我们发现了数组:

 

 

并且我们发现了数组的基地址:

 

 

关于最终数组的地址的寻址过程,在这里不再赘述,我只放出大概的OD逆向的注释,大家对照一下就可以了:

 

 

 

 

最终通过我们的分析得到数组的表达式:

 

dd   [[1C6E1F0]+(([[23E20D4]*7c0+2BE8+23CFD80]&0FFF)+2aad)*c]+0c0

 

其中,通过我们的分析,得知:0x23E20D4这个地址存放的使我们自身的数组的下标,所以,表达式可转换为

 

dd   [[1C6E1F0]+(( n*7c0 + 2BE8 + 23CFD80 ]&0FFF)+2aad)*c]+0c0   n为下标

 

分析完数组之后,我们接下来就来分析人物的结构了!

 

-----------------------------------------------------------------------------------------------------------------------------------------------------

                                                                                               ③开始分析人物结构

 

由于人物结构是一个结构体,该结构体的起始地址为人物对象地址,所以,我们继续用CE的结构体分析工具去分析人物对象地址,也就是刚才的eax地址:

 

通过观察,我们立刻就得到了人物名称的偏移量:0x68

 

 

通过观察和修改浮点数,我们观察到了人物坐标的偏移量:

 

人物左右X:0x2B0

人物前后Y:0x2B8

人物高度Z:0x2B4(个人习惯这个为Z)

 

 

由此,我们可以总结几个表达式了!!!

 

 

dd [[1C6E1F0]+(([n*7c0+2BE8+23CFD80]&0FFF)+2aad)*c]+0c0  人物血量

 

dd [[1C6E1F0]+(([n*7c0+2BE8+23CFD80]&0FFF)+2aad)*c]+068  人物名称

dd [[1C6E1F0]+(([n*7c0+2BE8+23CFD80]&0FFF)+2aad)*c]+02B0  人物X坐标

 

dd [[1C6E1F0]+(([n*7c0+2BE8+23CFD80]&0FFF)+2aad)*c]+02B8  人物Y坐标

 

dd [[1C6E1F0]+(([n*7c0+2BE8+23CFD80]&0FFF)+2aad)*c]+02B4  人物Z坐标

 

然后,我们就可以去游戏写个遍历器看一下了!走!去写遍历器!

 

-----------------------------------------------------------------------------------------------------------------------------------------------------

                                                                                              ④写遍历器查看游戏数据

 

 

大致逻辑如下,可能我的代码功底不是很好,让大家见笑啦~

 

因为该游戏房间人数最多为32人,所以我们for循环的次数为i自身X  敌人Y>自身Y   敌人位于第一象限

2. 当敌人X自身Y   敌人位于第二象限

3. 当敌人X0  游戏中为: -π->π/2,所以依然需要在原公式的基础上-π/2

 

那么最终的第一象限的算法也就是:- atan2((敌人Y-我们Y),(敌人X-我们X)) - π/2

 

以此类推,全部象限的鼠标X算法大致如下:

 

/* 计算水平横角度 */ FLOAT AimbotAngle_X; if (X_Target > X_MyPlayer && Y_Target > Y_MyPlayer)//第一象限 { AimbotAngle_X = (FLOAT)(0 - atan2(Y_Target - Y_MyPlayer, X_Target - X_MyPlayer) - 3.1415926 / 2); } if (X_Target < X_MyPlayer && Y_Target > Y_MyPlayer)//第二象限 { AimbotAngle_X = (FLOAT)(atan2(Y_Target - Y_MyPlayer, X_MyPlayer - X_Target) + 3.1415926 / 2); } if (X_Target < X_MyPlayer && Y_Target < Y_MyPlayer)//第三象限 { AimbotAngle_X = (FLOAT)(3.1415926 / 2 - atan2(Y_MyPlayer- Y_Target, X_MyPlayer - X_Target)); } if (X_Target > X_MyPlayer && Y_Target < Y_MyPlayer)//第四象限 { AimbotAngle_X = (FLOAT)(atan2(Y_MyPlayer - Y_Target, X_Target - X_MyPlayer) - 3.1415926 / 2); }

 

 

至此,我们分析完了鼠标的X横角度,那么我们带着愉悦的心情继续分析鼠标的Y角度吧!

 

-----------------------------------------------------------------------------------------------------------------------------------------------------

                                                                                             ⑥分析自瞄的鼠标Y坐标

 

 

自瞄的Y坐标相对简单,用一张图大家就明白了:

 

 

依然,绿色标注的角度为我们的瞄准的Y角度,那么如何计算呢,这一次需要用到勾股定理:

 

首先我们把上面三角形的临边计算出来:也就是X的平方 + Y的平方 ,然后开平方,我们把这个值设为P

 

得知了P,得知Z = 敌人的Z-我们的Z,那么我们就可以计算角度了:atan2(Z,P),取值范围为0--π/2  逐渐增大

 

那么游戏中的变化规律呢,我们看一下:

 

当鼠标Y为0时,朝向中心位置:

 

 

当鼠标向最上方时,大致值为π/2:

 

 

当鼠标向最下方时,大致值为-π/2: 

 

 

那么也就是说如果敌人Z高于我们Z,那么游戏角度处于0--->π/2,生活中角度也为:0-π/2,无需转换

 

如果敌人Z小于我们Z,游戏角度为:0- -π/2,生活中角度要进行取反,也就是 -atan2(Z,P)

 

注意此时的Z,也进行了变化,因为我们位于坐标原点,为保证值为正数  所以Z = 我们Z - 敌人Z

 

所以最终横角度大致代码如下:

 

/* 计算上下俯仰角 */ FLOAT AimbotAngle_Y; FLOAT Distance; Distance = sqrt((X_Target - X_MyPlayer)*(X_Target - X_MyPlayer) + (Y_Target - Y_MyPlayer)*(Y_Target - Y_MyPlayer)); //敌人高度 > 自己高度 if (Z_Target > Z_MyPlayer) { AimbotAngle_Y = atan2(Z_Target - Z_MyPlayer, Distance); } //敌人高度 < 自己高度 if (Z_Target < Z_MyPlayer) { AimbotAngle_Y = 0 - atan2(Z_MyPlayer - Z_Target, Distance); }

 

 

最终,我们的算法就结束了,还差最后一步,那就是源源不断的写入敌人的角度数据到我们的鼠标角度中,就可以实现锁定敌人的功能

 

另外还需要注意一点,该游戏在分析阵营时,在人物结构下未发现阵营数据,通过观察,得知阵营在数组地址 减去 0x38的位置

 

 

任意人物的阵营:数组下标*7C0+Crossout.exe+194FD80+2BE8 - 0x38    敌方跟我方的阵营是不同的

 

我们现在已经做完了几乎全部的铺垫,大致的逻辑如下:

 

自瞄() { 得出人物信息() { 得到自己的属性:坐标XYZ 血量 阵营 是否死亡 鼠标角度; 得到其他人的属性:坐标XYZ 血量 阵营 是否死亡 } 计算角度坐标 瞄准() { 判断死亡 是否在房间 判断阵营 选择最近的敌人瞄准 10米 100米 威胁最大的 } }

 

再总结一下:

 

 

任意人物的阵营:数组下标*7C0+Crossout.exe+194FD80+2BE8 - 0x38    敌方跟我方的阵营是不同的 

 

 

人物血量 : [[1C6E1F0]+(([n*7c0+2BE8+23CFD80]&0FFF)+2aad)*c]+0c0   通过判断敌人血量可以确定敌人是否死亡

 

 

人物名称 :[[1C6E1F0]+(([n*7c0+2BE8+23CFD80]&0FFF)+2aad)*c]+068  

人物X坐标 :[[1C6E1F0]+(([n*7c0+2BE8+23CFD80]&0FFF)+2aad)*c]+02B0  

 

 

人物Y坐标 :[[1C6E1F0]+(([n*7c0+2BE8+23CFD80]&0FFF)+2aad)*c]+02B8  

 

人物Z坐标 :[[1C6E1F0]+(([n*7c0+2BE8+23CFD80]&0FFF)+2aad)*c]+02B4  

 

人物对象地址:[0143e1f0]+(([01B9FD80+0*07c0+2BE8]&0FFF)+2AAD)*0c    通过判断对象地址值是否有效可以判断是否在房间内

 

 

那么,通过这些数据,我们就可以知道FPS游戏自瞄漏洞的利用方式了。

 

 

 

-----------------------------------------------------------------------------------------------------------------------------------------------------

                                                                                            ⑦修改内存实现自瞄

 

大致代码如下,由于我做了些封装,所以,大家明白写法逻辑就可以了:

 

//写自瞄X WriteMemeryFloat(_hGameHandle, GetProcessBaseAddress(ProcessId) + MouseX, 水平角); //写自瞄Y WriteMemeryFloat(_hGameHandle, GetProcessBaseAddress(ProcessId) + MouseY, 俯视角);

 

//写内存小数型 BOOL WriteMemeryFloat(HANDLE hGameHandle, DWORD _address, FLOAT Data) { return WriteProcessMemory(hGameHandle, LPVOID(_address), &Data, sizeof(Data), NULL); }

 

由于该游戏的地址以模块地址 + 模块偏移形式存放,所以,我封装了获取本模块基地址的函数:

 

//取本程序模块地址 DWORD_PTR GetProcessBaseAddress(DWORD processID) { DWORD_PTR baseAddress = 0; HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID); HMODULE *moduleArray; LPBYTE moduleArrayBytes; DWORD bytesRequired; if (processHandle) { if (EnumProcessModules(processHandle, NULL, 0, &bytesRequired)) { if (bytesRequired) { moduleArrayBytes = (LPBYTE)LocalAlloc(LPTR, bytesRequired); if (moduleArrayBytes) { unsigned int moduleCount; moduleCount = bytesRequired / sizeof(HMODULE); moduleArray = (HMODULE *)moduleArrayBytes; if (EnumProcessModules(processHandle, moduleArray, bytesRequired, &bytesRequired)) { baseAddress = (DWORD_PTR)moduleArray[0]; } LocalFree(moduleArrayBytes); } } } CloseHandle(processHandle); } return baseAddress; }

 

0x3. 总结

 

至此,FPS游戏自瞄游戏漏洞分析完成

 

全部FPS游戏均存在内存自动瞄准的漏洞,在这里,并不是希望大家去破坏游戏,而是我希望大家能够知道原理,学到知识,希望大家不要做破坏游戏平衡的事情.

 

写完了,不知道大家喜不喜欢,如果喜欢的话,我会抽出时间写一下方框透视的绘制和算法,感谢看雪这个黄埔军校!

 

不知道管理员大哥能不能加精,其实我是奔着做看雪讲师所以写点东西的,

 

目前大三了,也打算读研究生了,如果能当讲师,也能为面试提供优势,其实内心还是非常渴望这个机会的

 

希望大家好好学习,新的一年里,更上一层楼!

 

相关课程:

网易云课堂:https://study.163.com/course/courseMain.htm?courseId=1006267004&share=2&shareId=1020678503

看雪课堂:https://www.kanxue.com/book-brief-39.htm

相关搜索
网友推荐
军婚的秘密txtrain stops, good-bye 事務員G verGhostXP_SP3等还珠楼主九寨沟320K 百度黄永灿贴吧好木望天txtwangzhanRealflow奶油流体模拟教程1任海涛考前预测《酷酷国君的小公主》将夏未泯txt
17-02DAT咏春视频mpg生日快乐歌伴奏你的今天 我的昨天office2021ProQQ透明头像 半透明头像制作圆形小餐桌的SU模型-www52edycomskp创世战神1120-17日更新死神在校园txt绝傲孤烟(共三部) txt