吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 68044|回复: 274
上一主题 下一主题
收起左侧

[游戏安全] FPS网络游戏自动瞄准漏洞分析以及实现

    [复制链接]
头像被屏蔽
跳转到指定楼层
楼主
机智聪明的小迪 发表于 2019-2-8 21:47 回帖奖励
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内存地址

(, 下载次数: 7)
此时,我们已经得到了鼠标Y的内存地址,这个时候,我们不必去搜索鼠标X的内存地址,只需观察该地址相邻或者附近的地址值的变化即可得知鼠标X
因为鼠标XY坐标在游戏中存放是连续的,类似我们在上课写C语言结构体里面变量数据内存地址是连续的一样的道理

那么如何查看相邻地址内存呢?CE有个自带的功能:
(, 下载次数: 5)


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

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

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

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

(, 下载次数: 7)

(, 下载次数: 7)

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

-----------------------------------------------------------------------------------------------------------------------------------------------------
                                                                                               ②开始分析人物数组

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

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

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

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

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

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

(, 下载次数: 4)

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

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

(, 下载次数: 8)

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

(, 下载次数: 7)

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

(, 下载次数: 3)

(, 下载次数: 6)

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

(, 下载次数: 6)

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

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

(, 下载次数: 6)

(, 下载次数: 6)

(, 下载次数: 4)

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

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

(, 下载次数: 5)

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

人物左右X:0x2B0
人物前后Y:0x2B8
人物高度Z:0x2B4(个人习惯这个为Z)

(, 下载次数: 3)
由此,我们可以总结几个表达式了!!!


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<32

[C++] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//定义遍历Address
DWORD TempAddress, RetTemp, GetBase, ObjectAddress, ObjectValue;
  
//基地址
DWORD BaseAddress = GetProcessBaseAddress(ProcessId) + BasePtr;
  
//数组基地址
DWORD Address_Array = GetProcessBaseAddress(ProcessId) + ArrayPtr;
  
char* Name = NULL;
int Count = 1;
  
  
  
for (int i = 0; i < 32 ; i++)
{
//地址解密
TempAddress = i * 0x7c0 + Address_Array + 0x2BE8;
  
RetTemp = _ReadMemeryInt(_hGameHandle, TempAddress);
  
//计算数组遍历地址
RetTemp = ((RetTemp & 0x0fff) + 0x2AAD) * 0x0c;
  
//基地址
GetBase = _ReadMemeryInt(_hGameHandle, BaseAddress);
  
//计算人物对象地址
ObjectAddress = GetBase + RetTemp;
  
  
//读人物对象地址
ObjectValue = _ReadMemeryInt(_hGameHandle, ObjectAddress);
  
//判断对象是否存在
if (ObjectValue != NULL)
{
  
//读取人物血量
float Bloat = _ReadMemeryFloat(_hGameHandle, ObjectValue + 0xc0);
//读取人物名称
Name = _ReadMemeryString(_hGameHandle, ObjectValue + 0x68);
  
  
printf("第%d个人:   数组下标:%d   人物名称:%s     对象地址:%x   血量:%.3f\n",Count, i,Name, ObjectValue, Bloat);
  
ObjectAddress = NULL;
ObjectValue = NULL;
  
Count += 1;
}
}


游戏中的效果,我们遍历到了敌人的数据,比如重要的下标数据和对象地址:

(, 下载次数: 2)

-----------------------------------------------------------------------------------------------------------------------------------------------------
                                                                                             ⑤分析自瞄朝向

我们所有的数据基本上都分析完了,下面我们来分析一下网游自动瞄准的算法吧,在这里,我推荐大家用生活和游戏相结合的方式
也就是游戏和生活联系在一起。

古代的时候,对于我们生活的地球,人们会讲“天圆地方”这么一个概念

那么我们可以借鉴一下,把游戏中的地图看成方的,把我们看做坐标原点,然后建立一个直角坐标系,并且标注上北下南,左西右东:

(, 下载次数: 4)

然后我们先得知一个规律:

1.如果我们修正鼠标X和鼠标Y为0,那么游戏准星将指向一个东南西北的正方向
2.前后移动如果人物X坐标未变动或者变动幅度小,则我们处在坐标系Y方向
3. 前后移动如果人物Y坐标未变动或者变动幅度小,则我们处在坐标系X方向

通过规律,然后通过观察,发现人物前后走动时,Y坐标变化剧烈,说明:

1.我们小车在Y轴方向上
2.又因为向前减少,向后增加,说明我们的小车:坐北朝南,鼠标的位置此时指向了南方

(, 下载次数: 3)

那么这个时候,我们把方向分析完了,我们来分析一下,鼠标坐标的变化规律:

我们此时是指向南方的,我们从南向北顺时针旋转鼠标,观察鼠标规律:

鼠标从南向北: 鼠标值的变化大致为:0--π

(, 下载次数: 2)

继续旋转:-π  此时π和-π的位置,也就是正北方,我们发现是重合的

(, 下载次数: 3)
由此,根据游戏中的变化规律,我们可以作图:(鼠标的度数和象限和东西南北的关系)

(, 下载次数: 6)

这个时候,可能有的朋友会疑问了,画这个有什么用???

客观,且听我细细分说:

1.我们刚开始假想自己在坐标原点的位置
2.我们通过1得到了不同象限内鼠标角度的范围

那么,我们只需要知道敌人位于哪个象限就可以确定鼠标角度的范围,并且可以精确计算鼠标角度了

所以,我们应该怎么确认敌人在哪个象限呢?

解:

既然游戏为一个直角坐标系,我们位于坐标原点,因此:

1.当敌人X>自身X  敌人Y>自身Y   敌人位于第一象限
2. 当敌人X<自身X  敌人Y>自身Y   敌人位于第二象限
3. 当敌人X<自身X  敌人Y<自身Y   敌人位于第三象限
4. 当敌人X>自身X  敌人Y<自身Y   敌人位于第三象限

上面大家唯一要注意的就是正负的大小,不要搞混!

-----------------------------------------------------------------------------------------------------------------------------------------------------
                                                                                           ⑥分析自瞄的鼠标X坐标

因为我们得知了鼠标的变化规律,也得知了象限的变化,所以,我们只需要把我们和敌人的角度算出来就可以了!
那么应该怎么计算呢?

且听我细细分说!还是刚才的图:

我们以我们为起点,以敌人的坐标为终点,不考虑Z坐标,进行作图,连线,构造三角形!

那么根据几何知识,我们得知绿色的地方即为我们需要瞄准的度数,也就是我们要修改的鼠标的X角度

(, 下载次数: 5)
那么应该如何计算呢?

我想聪明人已经想到了:那就是用反正切

我们已知敌人的Y,知道我们的Y,那么

敌人Y - 我们Y = 三角形的对边
敌人X - 我们X = 三角形的临边

利用反正切,对边/临边,得知自瞄X的角度,由于C语言中提供了函数atan2,因此,我们直接用atan2函数即可,atan2函数释义如下:

C 语言里 double atan2(double y,double x) 返回的是原点至点(x,y)的方位角,即与 x 轴的夹角。也可以理解为复数 x+yi 的辐角。返回值的单位为弧度
因此,第一象限初步的角度公式为:

atan2((敌人Y-我们Y),(敌人X-我们X)),由于该角度取值范围为[0,π/2],从北到东为π/2--0,变化规律为:逐渐减小

也就是说,我们生活中来看,从北到东顺时针为,逐渐减少,但是游戏中变化为:-π->π/2,逐渐增大

所以,继续敲黑板:把生活中的转化为游戏中的,那么我们直接加个负号: atan2((敌人Y-我们Y),(敌人X-我们X))就逐渐增大了

又因为加负号后的生活中取值变化为:-π/2->0  游戏中为: -π->π/2,所以依然需要在原公式的基础上-π/2

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

以此类推,全部象限的鼠标X算法大致如下:
[C++] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
        /*
计算水平横角度
*/
FLOAT AimbotAngle_X;
if (X_Target > X_MyPlayer && Y_Target > 人物.fY)//第一象限
{
AimbotAngle_X = (FLOAT)(0 - atan2(Y_Target - 人物.fY, X_Target - X_MyPlayer) - 3.1415926 / 2);
}
if (X_Target < X_MyPlayer && Y_Target > 人物.fY)//第二象限
{
AimbotAngle_X = (FLOAT)(atan2(Y_Target - 人物.fY, X_MyPlayer - X_Target) + 3.1415926 / 2);
}
if (X_Target < X_MyPlayer && Y_Target < 人物.fY)//第三象限
{
AimbotAngle_X = (FLOAT)(3.1415926 / 2 - atan2(人物.fY - Y_Target, X_MyPlayer - X_Target));
}
if (X_Target > X_MyPlayer && Y_Target < 人物.fY)//第四象限
{
AimbotAngle_X = (FLOAT)(atan2(人物.fY - Y_Target, X_Target - X_MyPlayer) - 3.1415926 / 2);
}


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

-----------------------------------------------------------------------------------------------------------------------------------------------------
                                                                                            ⑥分析自瞄的鼠标Y坐标


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

(, 下载次数: 4)

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

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

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

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

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

(, 下载次数: 4)

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

(, 下载次数: 3)
当鼠标向最下方时,大致值为-π/2:

(, 下载次数: 2)

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

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

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

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

[C++] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
         /*
        计算上下俯仰角
        */
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    敌方跟我方的阵营是不同的

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

[C++] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
自瞄()
{
       得出人物信息()
      {
           得到自己的属性:坐标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游戏自瞄漏洞的利用方式了。

-----------------------------------------------------------------------------------------------------------------------------------------------------
                                                                                           ⑦修改内存实现自瞄

[C++] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
大致代码如下,由于我做了些封装,所以,大家明白写法逻辑就可以了:
  
//写自瞄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游戏均存在内存自动瞄准的漏洞,在这里,并不是希望大家去破坏游戏,而是我希望大家能够知道原理,学到知识,希望大家不要做破坏游戏平衡的事情.

写完了,不知道大家喜不喜欢,如果喜欢的话,我会抽出时间写一下方框透视的绘制和算法

不知道管理能不能加精,另外今年也打算读研究生了

不打广告,不留名,希望大家好好学习,新的一年里,更上一层楼!

免费评分

参与人数 246吾爱币 +250 热心值 +220 收起 理由
朝辞白帝 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
righter + 1 + 1 我很赞同!
Vicar5235 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
油桶 + 1 + 1 用心讨论,共获提升!
15048048021 + 1 + 1 用心讨论,共获提升!
Light紫星 + 1 + 1 我很赞同!
jpm822phgr2 + 1 + 1 用心讨论,共获提升!
aimabihan + 1 + 1 谢谢@Thanks!
Orekize + 1 + 1 谢谢@Thanks!
newcools521 + 1 我很赞同!
Shaiem + 1 + 1 用心讨论,共获提升!
清辞。 + 1 用心讨论,共获提升!
candlce + 1 + 1 鼓励转贴优秀软件安全工具和文档!
bing1999 + 1 + 1 谢谢@Thanks!
1008601 + 1 + 1 我很赞同!
独饮悲~ + 1 + 1 感谢您的宝贵建议,我们会努力争取做得更好!
JuDei + 1 + 1 用心讨论,共获提升!
XiroNeko + 1 + 1 热心回复!
乐乐同学 + 1 热心回复!
墨月与墨鱼 + 1 + 1 我很赞同!
爱拍阴天 + 1 + 1 我很赞同!
slaap + 1 + 1 用心讨论,共获提升!
gm0515 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
鹅妹子嘤 + 1 + 1 用心讨论,共获提升!
我吾爱破解账号 + 1 + 1 我很赞同!
Mr.Eleven + 1 谢谢@Thanks!
楚辞辞 + 1 + 1 用心讨论,共获提升!
简单单单 + 1 + 1 用心讨论,共获提升!
孙嘉隆 + 1 谢谢@Thanks!
justlll + 1 谢谢@Thanks!
a321852123 + 1 + 1 太神拉~
问题不大 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
11ewww + 1 + 1 用心讨论,共获提升!
DaveiH + 1 + 1 谢谢@Thanks!
zhs_poison + 1 + 1 我很赞同!
未来与世界 + 1 + 1 热心回复!
传火薪王古达子 + 1 + 1 我很赞同!
yyyl + 1 + 1 用心讨论,共获提升!
xiecong1998 + 1 用心讨论,共获提升!
_conceited + 1 我很赞同!
WA自动机 + 1 用心讨论,共获提升!
逆光灬流火 + 1 + 1 谢谢@Thanks!
那真的牛批 + 1 + 1 用心讨论,共获提升!
七度空间 + 1 + 1 真的厉害,小白也能稍微懂一点了,谢谢
Sm1Lin9Fac3 + 1 + 1 我很赞同!
三宅的猫子 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lc2zyq + 1 + 1 我很赞同!
琢钰 + 1 + 1 用心讨论,共获提升!
Diablita + 1 我很赞同!学习了,再也不玩CF. CS
NameQuin + 1 我很赞同!
ffqaq + 1 + 1 我很赞同!
rain21 + 1 + 1 我很赞同!
RoB1n_Ho0d + 1 + 1 热心回复!
G31001 + 1 + 1 我很赞同!
极品菜雀 + 1 + 1 厉害了!
q56535 + 1 我很赞同!
cenglou + 1 + 1 我很赞同!
zzzz7777cl + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
tdher987 + 1 + 1 用心讨论,共获提升!
gongyong728125 + 1 + 1 热心回复!
newpowersky + 1 + 1 我很赞同!
zhizhoushen + 1 + 1 谢谢@Thanks!
shixinlan + 1 + 1 用心讨论,共获提升!
doidt + 1 + 1 谢谢 加油加油!!!
cnzmg + 1 用心讨论,共获提升!
月社琉璃 + 1 我很赞同!
super鲁校长 + 1 + 1 谢谢@Thanks!
BK2011111 + 1 热心回复!
qq499216557 + 1 + 1 用心讨论,共获提升!
CrazyNut + 3 + 1 膜拜大佬
1188 + 1 + 1 勾股定理都出来了
T316huanghe + 1 我很赞同!
破天丿彡 + 1 大写 懵逼在脸上
arwel1912 + 1 用心讨论,共获提升!
Most苏 + 1 + 1 用心讨论,共获提升!
qaz003 + 1 + 1 超赞,理论实践都普及了……。
西西里公爵 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
阿吉小家伙 + 1 + 1 我很赞同!
Hansenne + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
乎乎 + 1 + 1 膜拜大神
bb8820 + 1 谢谢@Thanks!
行者小波 + 1 用心讨论,共获提升!
傻乎乎的小白 + 1 + 1 热心回复!
吾爱丶抹杀 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
593365053 + 1 + 1 用心讨论,共获提升!
qwer1193 + 1 + 1 谢谢@Thanks!
gorden + 1 + 1 热心回复!
′小手冰凉 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
panglihuan + 1 + 1 我很赞同!
流年随心荏苒 + 1 + 1 用心讨论,共获提升!
DcHeathen + 1 + 1 用心讨论,共获提升!
poisonbcat + 1 用心讨论,共获提升!
FFFGGL + 1 + 1 用心讨论,共获提升!
chinabilibili + 1 + 1 谢谢@Thanks!
SakuyaPrs + 1 + 1 热心回复!
小泡泡_ + 1 + 1 谢谢@Thanks!
瓜子吧3 + 3 + 1 我很赞同!
Minesa + 1 + 1 我很赞同!
sunzhiyang + 1 + 1 热心回复!
sunhaipeng1997 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
smile1110 发表于 2019-2-9 20:47
本帖最后由 smile1110 于 2019-2-9 20:48 编辑

这篇帖子写的真棒啊,尤其是这个视角转换,不过并不需要如此麻烦,直接调整到 4:3的分辨率 系统鼠标调整到6 这时候从枪口 或者炮口出去的这条线,开始计算 角速度和线速度 ,只要子弹沿着这条线出去,就一定会击中目标,若是还有一些类似后座力什么的随机的话,可以加入椭圆曲线的离散范围取值,而并不需要把立体变为立方体 通过这个缩放标量 ,更不需要计算三角函数或者相似三角形 这些 解析几何




免费评分

参与人数 4吾爱币 +3 热心值 +4 收起 理由
zhukai055 + 1 你写的也特别棒,但G一般都是内存精准移动,通过计算鼠标恐怕有误差。
小小少年烦恼多 + 1 + 1 大佬讲解的很清楚,就自动瞄准而言,差不多懂了,那么对于过检测呢,想了解
NOWorEVER + 1 + 1 用心讨论,共获提升!
Atreusman + 1 + 1 我很赞同!

查看全部评分

推荐
wuzeqiao 发表于 2019-2-8 23:09
沙发
我是咕噜 发表于 2019-2-8 21:51
3#
565266718 发表于 2019-2-8 21:58
先支持楼主。。其次图片全挂。。
4#
S.K 发表于 2019-2-8 21:58
图片都是直接贴过来的,看不了。。。。
5#
zqguang3708 发表于 2019-2-8 22:05
姐姐图片没了   更新一下啊
头像被屏蔽
6#
 楼主| 机智聪明的小迪 发表于 2019-2-8 22:12 |楼主
图片已经恢复了,之前我写在word的,想着顺便复制过来,没想到直接全挂了
7#
zzz995 发表于 2019-2-8 22:15
图片有啊 是你们的网络问题吧
8#
az216115 发表于 2019-2-8 22:29
哇哦,我也要考研究生了啊啊啊啊啊,小姐姐分析的很到位
9#
121890575 发表于 2019-2-8 22:41
学习了,辛苦了。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-9 05:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表