首页
社区
课程
招聘
[原创]CS2外部静默原理剖析及实现
发表于: 2024-7-24 21:30 9877

[原创]CS2外部静默原理剖析及实现

2024-7-24 21:30
9877

现在CS2外挂层出不穷,基本大部分的外挂功能都已被实现,其中在我研究过程中比较有意思的就是外部静默自瞄。当然静默自瞄在注入游戏后是很容易实现的,只需要Hook CreateMove这个函数进行拦截CMD这个结构数据,然后进行视角的修改即可,但外部比较难实现这种方法,但也可以从此函数入手来研究,所以就有接下来的分析过程。
注:此文章仅分享逆向过程以供学习参考,并无传播、提供外挂等非法程序。

由于游戏是3D世界,所以方向大部分是用欧拉角来表达,即Pitch(俯仰角)、Yaw(偏航角)、Roll(翻滚角)三个数据,静默就是修改开枪旋转角,在本地相机旋转角不变的情况下修改开枪旋转角,就可以实现不瞄准目标但又可以射击到目标的功能。
Angle_
而在CS2中CreateMove函数参与移动相关的所有操作,例如:相机旋转角改变、人物移动、人物动作等等,
函数原型如下:

其中"CCSGOInput"类包含了所有相关数据,具体实现功能就是拦截并修改此指针数据,所以我的入手点就在这个函数。

首先使用IDA分析"client.dll"此文件,在String窗口中直接搜索"CreateMove",可以在String窗口看到这些文本。
IDA-StringView
选中第二个,查看交叉调用可以发现有且仅有一个函数
IDA-FunctionView
这个函数就是CreateMove
IDA-FunctionView2

静默最主要的数据就是相机的旋转角数据,因为开枪的旋转角与相机旋转角数据一致,注:Rotation{Pitch,Yaw,Roll},所以先去Github上的cs2-dumper项目中找到ViewAngle的地址,添加到CE以便对照寄存器数据进行调试定位。
CE-ViewAngle
然后在Memory Viewer里面跳转到CreateMove函数,直接下断F8单步走一遍,过程中打开着FPU窗口观察XMM寄存器数据,因为旋转角数据是浮点数,所以在调试代码过程中观察是否能看到旋转角相关数据,就可以快速定位相关代码段,发现在这行汇编代码后的一片地址都没有执行过 CE-JNG
所以我们直接略过下面一片代码,直接跟着跳转过去继续单步执行下去。
当执行完这个Call后,XMM1寄存器出现了一个熟悉的数据
CE-FPU
可以和旋转角数据对照,发现是相机的Yaw数据。
CE-ViewAngle
这个Call有点嫌疑,直接NOP后,在游戏中开枪,发现射出的子弹方向和实际相机方向不一致。 Shooting
基本可以确定开枪角度的写入是在这个Call内部,所以打标签记录一下这个函数,直接跳转到函数内部进行继续分析。(这个函数后面发现是之前IDA String列表的第一个文本交叉调用中的函数。注:图三
开着寄存器窗口继续F8单步走跟代码,跟到这一行代码发现XMM0首次出现了Pitch数据,与我们ViewAngle的数据一致 Pitch
继续执行后可以看到XMM0、XMM1分别就是旋转角Pitch和Yaw。 PitchAndYaw
所以就可以确定是上面这两个关键代码获取到旋转角数据,并分别赋值给[rcx+18]和[rcx+1C],可以猜测下一个的XMM0赋值代码便是Roll数据,但是Roll数据一般是0,所以这里不讨论下面部分的代码。所以就可以在这附近进行拦截修改rcx相关寄存器地址的值,达到修改开枪角度的效果,下面进行验证。

我们在0x87C37C偏移处进行简单的Hook来验证,看看修改[rcx+18]以及[rcx+1C]后是否能成功修改开枪视角。这里先直接使用CE的自动汇编来快速的写一个Hook脚本,将[rcx+18]以及[rcx+1C]拦截修改为[newmem+50]和[newmem+54]两个地址的浮点值。
Asm
执行脚本后射击发现子弹射击角度和相机角度不一致,修改[newmem+50]以及[newmem+54]后发现可以正确的修改子弹射击角度,那就可以确定这是我们所需要的效果。
Shooting2

我和好友在人机房间进行测试,让好友看我观战视角,然后我这边启动Hook脚本,发现在线观战是有效果的,并且在其他玩家的第三人称视角也是有效果的,在其他视角我的人物开枪方向和实际子弹射出方向不一致,由此可得出结论此功能效果是在线有效,而并非仅本地有效。

最后于 2024-7-25 10:07 被Liv_T编辑 ,原因: 增添内容
收藏
免费 7
支持
分享
最新回复 (14)
雪    币: 1449
活跃值: (4483)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
跳起来不咋准整
2024-7-24 23:50
0
雪    币: 9744
活跃值: (6522)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
逆向爱好者 跳起来不咋准整
把空格抠了
2024-7-25 00:16
0
雪    币: 252
活跃值: (386)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
逆向爱好者 跳起来不咋准整
需要配合RCS系统来调整,这个仅供修改开枪视角。
2024-7-25 00:19
0
雪    币: 1449
活跃值: (4483)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
Liv_T 需要配合RCS系统来调整,这个仅供修改开枪视角。
他子弹碰撞运算逻辑是服务器运算的还是本地运算
2024-7-25 10:49
0
雪    币: 252
活跃值: (386)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
逆向爱好者 他子弹碰撞运算逻辑是服务器运算的还是本地运算
仅子弹出射角度是本地,子弹坐标、碰撞之类是服务器运算
2024-7-25 11:06
0
雪    币: 222
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
这支枪弹道偏左,这是谁的枪
2024-7-25 13:20
1
雪    币: 2661
活跃值: (2463)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
8
mb_snqzioxv 这支枪弹道偏左,这是谁的枪
2024-7-25 13:51
0
雪    币: 1449
活跃值: (4483)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
Liv_T 仅子弹出射角度是本地,子弹坐标、碰撞之类是服务器运算
看来游戏为了遏制变态挂专门整了个服务器运算
2024-7-26 10:13
0
雪    币: 4661
活跃值: (4066)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
逆向爱好者 看来游戏为了遏制变态挂专门整了个服务器运算
这个从cs起源开始就是这样设计,服务器会继续模拟客户端的子弹在走一遍相同的逻辑。最终执行的结果以服务端的结果为准。
2024-7-26 19:50
0
雪    币: 4661
活跃值: (4066)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
例如客户端的子弹击中了敌人,然后服务端收到数据包之后,把数据取出传给射击函数,服务端的射击函数就使用客户端上传的数据在执行一遍,而这个射击函数的实现和客户端完全一样,最终如果真的命中了敌人,则会以服务端执行的结果。虽然服务器采用了客户端上传的数据,但是对于这些数据都是有条件限制,在传给射击函数执行的过程中会对这些数据进行各种检查,因为客户端和服务端这个射击函数是一样的所以,客户端也会对这些数据进行检查,但是可以通过修改客户端的这些检查的if逻辑,但修改了也没什么用,因为服务端的这些if逻辑没有被修改,还是会进行严格的数据检查。
2024-7-26 19:59
0
雪    币: 202
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
可以看一下netchan相关结构,有一个bSendPacket,当你写入0的时候,你这个usercmd会被choke住不发送,这时候你可以修改该usercmd的pitch和yaw,然后取消choke,可以实现slientaim
2024-7-27 12:57
1
雪    币: 252
活跃值: (386)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
veryluckko 可以看一下netchan相关结构,有一个bSendPacket,当你写入0的时候,你这个usercmd会被choke住不发送,这时候你可以修改该usercmd的pitch和yaw,然后取消choke, ...
好的,研究一下这个结构的数据,学习了
2024-7-27 19:02
0
雪    币: 1449
活跃值: (4483)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
木志本柯 这个从cs起源开始就是这样设计,服务器会继续模拟客户端的子弹在走一遍相同的逻辑。最终执行的结果以服务端的结果为准。
看来cf也是够lj的随随便便就能整变态挂
2024-7-27 19:16
0
雪    币: 7
活跃值: (82)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
哪位大佬可以帮我做个软件破解,谢谢!昵称是威,重金酬谢!
2024-9-29 02:40
0
游客
登录 | 注册 方可回帖
返回
//