一.背景:

VAC全称VALVE ANTI-CHEAT,是VALVE公司V社
开发的一款作弊系统,VAC为steam平台游戏通用反作弊安全接入方案(DOTA2与CS:GO均使用VAC)。

本次CS:GO作为分析目标,对CS:GO上采取的安全方案做基础的分析。

二.分析结论:

通过采取动态调试,静态分析,hook验证等方式,发现VAC在CS:GO上方案如下:

静态保护:

所有PE文件未加壳

代码混淆:代码混淆

动态对抗:

驱动保护:发现

反调试简单异常干扰

调试检测:简单调试检测

模块检测:

窗口检测:未发现

进程检测:有枚举进程模块行为

线程检测:有感知线程创建行为

模块检测:发现

堆栈检测:有堆栈回溯检测

内存检测:发现

其他:

API关键API

VAC2.DLL存放安全方案预埋,但未
CS:GO中加载

开启检测:

发现多种调试器检测

发现多种堆栈检测

发现有对游戏状态检测

注:因为分析游戏时多采取单机对战离线分析,方案分析存在不完整性

三.分析过程:

3.1 游戏安全性分析:

3.1.1 游戏结构分析

CSGO的游戏启动器存放与根目录,根目录下同时也有steam客户端相关dll,steam 编译了32位和64位不同的版本。

steam客户端相关dll.png

游戏进程存放在.\steamapps\common\

游戏主进程存放在.\steamapps\common\下

游戏关键的模块client.dlserver.dll存放
.\ steamapps\common\Counter-Strike Global Offensive\csgo\bin

游戏关键的模块client.dl和server.dll

游戏的引擎engine.dll存放在.\steamapps\common\Counter-Strike Global Offensive\bin

游戏的引擎engine.dll

3.1.2 游戏启动分析

CS:GO目前只有32位版本
国服将steam.exe换成csgolauncher.exe,作为游戏启动器,游戏拉起进程如下:

游戏拉起进程

其中steamwebhelper仍然利用的是chrome的cef框架,进行三进程启动

进行三进程启动

游戏启动后,从行为特征上看,无驱动加载,无内核修改,无全局钩子设置,但是进程内有大量函数被hook,包括load类的,文件操作的,按键相关的,Dx
API也被hook,相关的hook跳转,
ZwOpenFilecsgo.exe接管,其他均指向了gameoverlayrender.dll

函数 1

函数 2

3.1.3 静态保护分析

选取了游戏中重要的PE文件-csgo.exe, engine.dll, client.dll, server.dll, tier0.dll, tier0_s.dll均未加壳,IDA可以正常反编译

反编译 1反编译2反编译 3反编译4

可见,VAC并未对游戏关键模块进行加壳,加花等常见PE保护

3.1.4 动态保护分析

dump

未做反dump处理,游戏模块可以直接dump

注入

做反注入处理,游戏内可以随意注入模块

调试器附加

未对常见断点类API处理,调试器可以任意附加,没有关于附加上的对抗

3.2 驱动保护及检测

Pchunter未检测到游戏VAC相关驱动加载

Pchuner未检测到内核hook

遍历目录未发现相关驱动文件

Hook ZwCreateFile,未发现有驱动文件创建

Hook NtLoadDriver,未发现驱动载入

Hook DeviceIoControl,未发现有驱动通信

综上,VAC并没有使用驱动对游戏做保护,也没有使用驱动进行检测。

3.3 调试器检测

常用api检测

hook IsDebuggerPresent,CheckRemoteDebuggerPresent,感知游戏基础检测
触发模块在tier0.dll, tier0_s.dll

api检测

游戏确实通过调用简单的api进行检测,但是这对于
32位拥有众多插件的OD来讲,这种检测的意义和效果并不大。

硬件断点检测

Hook NtGetContextThread,NtSetContextThread,NtContinue,KiUserExceptionDispatcher,未发现对dr寄存器进行相关
检测

调试器特征检测

文本暴力搜索IDA, ollydbg,windbg,CE,_Plugingetvalue

, _ODBG_Plugininit字符搜索……暂未发现对应文本

异常检测

去掉调试器的反反调试功能,发现当进入游戏时
,调试器接收到来自游戏的异常通知

异常通知

回溯异常触发点,确认在tier0_s.dll中会主动抛出异常

抛出异常

交叉引用游戏主动抛出的异常,发现除此之外,还有多处会抛出异常

多处异常

游戏运行过程期间,也会被动触发一些异常,如下

初期异常

这些异常处理,均可以被调试器忽略,或者被插件绕过

3.4 非法模块检测

3.4.1 窗口检测

常规窗体枚举:

hook 常见枚举窗口api,包括EnumWindows, FindWindow,EnumChildWindows,并未发现有对窗口进行检测

进一步深入hook ,hook EnmuWindows的底层实现api:

_InternalEnumWindow, _BuildHwndList, _NtUserBuildHwndList也未发现相关异常调用

窗口类名枚举:

Hook GetClassNameA,GetWindowsTextA,验证游戏是否通过A系类函数获取名称
类名,未感知到函数调用

触发式窗口检测

监控关键api:SetWindowsHookEx,SetEventHook,未发现有相关函数调用

综上VAC并未采取常见的窗口检测手段对可疑模块进行检测

3.4.2 进程检测

常规枚举进程

1. ToolsHelp接口枚举:Hook api:CreateToolhelp32Snapshot, Process32First,Process32Next,发现有steamclient.dll
每隔一段时间,就会枚举一次进程

ToolsHelp接口枚举

2Psapi接口枚举:hook EnumProcesses
,EnumProcessModules, GetModuleFileNameEx

Steamclient.dll进行进程枚举

Psapi接口枚举

3Wtsapi32接口枚举:hook
 WTSOpenServer, WTSEnumerateProcess

获取到相关函数调用

4. NativeAPI枚举:hook NtQuerySystemInformationZwQuerySystemInformation

跟踪至steamclient中模块enumprocess调用

NativeAPI枚举

句柄枚举进程

1. 暴力句柄枚举,OpenProcess+GetProcessImageFileName

监控到相关调用

2. 普通枚举ZwQuerySystemInformation

监控跟踪至steamclient,同enumprocess

3. 其他进程枚举句柄,OpenProcess+ GetProcessImageFileName/GetProcessId

监控到来自游戏模块的可疑调用

驱动枚举

VAC未加载驱动,此种类型检测可能性不大

触发式枚举

VAC安装全局钩子,此种类型检测可能性不大

综上,和之前dota2中安全方案类似,VAC通过感知模块创建,最调用ZwCreateFile
GetFileInformationByHandle 进行文件信息上报

触发式枚举

3.4.3 模块检测

1. 传统模块枚举hook CreateToolhelp32Snapshot
Module32FirstModule32Next
 Heap32First,GetModuleBaseName

发现相关调用

2. 遍历PEB模块,hook ZwQueryInformationProcess未发现来自游戏模块的直接
调用

3.4.4 线程检测

线程枚举

Hook线程枚举的常用api- CreateToolhelp32Snapshot Thread32First,Thread32Next
检测发现

DLL_THREAD_ATTACH感知

新线程创建时,系统会通过DLL_THREAD_ATTACH告诉进程累的dll。Hook ZwQuerySystemInformation
ZwQueryInformationThread
发现有来自steamclient的模块调用

来自steamclient的模块调用

进一步定位到代码

定位到代码

进一步分析得知,VAC通过GetModuleHandleEx和GetModuleFileName获取模块名字,最后通过CreateFile和GetFileInformationByHandle
进行上报

上报模块名字

交叉引用分析,确定来自于DLL_THREAD_ATTACH的事件感知

确定来自于DLL_THREAD_ATTACH的事件感知

3.4.5 内存检测

代码/数据完整性检测

异常感知:关键代码下断点
结合异常处理函数进行分析,验证游戏是否通过异常接管,页属性修改异常,主动读取数据计算,均未发现游戏利用这些方法进行代码校验

分析异常过程中发现游戏内异常处理
dump相关

异常处理多于 dump相关异常处理多于 dump相关

代码/数据逻辑检测

逻辑检测多通过数据采集配合安全策略等方法进行检测,此处暂未分析

3.4.6 堆栈检测

API回溯

Hook RtlCaptureStackBackTrace,检测到来自游戏模块调用

来自游戏模块的调用

紧接着进行了调用链的分析,游戏会检测是否为正常的调用链关系

调用链的分析

TLS/ThreadFrame检测

Hook RtlPushFrameRtlGetFrameRtlPopFrame
,未拦截到来自游戏的直接api调用

分析结论上来看,游戏自身模块有对关键点做基本的堆栈回溯检测,是检测频率不高,而这里也只简单
的分析了下堆栈回溯常用的api调用,不排除游戏内存在策略代码会检测返回地址的合法性参数地址的合法性。

四.其他分析

4.1 API处理:

游戏内有大量API处理,获取大量
关键API地址,在一定程度上可以
绕过 API检测工具,进行一些暗桩检测

API处理

4.2 VAC2.DLL

在游戏目录下..\\resource\\ sourceinit.dat实际为vac
2.dll

vac 2.dll

目前分析情况来看,依然发现这个dll并没有加载到内存中 

4.3 尚未开启的检测

为尽可能避免分析过程带来的被检测被封号,笔者多采用了单机游戏和离线分析,游戏的检测策略并没有全部开启,仅仅静态分析tier0.dlltier0_s
.dll 就可以发现大量检测监控的代码如对标志位的检测

对标志位的检测

堆栈的检测如下图

对堆栈的检测

选取函数跟进分析调用了RtlCaptureStackBackTrace,是这api并没有被我们
hook 监控到有调用

选取函数跟进分析

进一步分析貌似,游戏对堆栈的一些检测还不止与此采用了不同的校验方式

不同的校验方式

分析了其他的函数发现函数貌似了这些常规检测外还有对游戏自身的状态进行检测

对游戏自身的状态进行检测

后记

分析结论上来看,VAC在CS:GO上目前
感知到的只有简单的特征上报,可能考虑到
CS:GO还 采取了视频监管和实名认证安全方案
没有采取更多的对抗和监控策略,
确实能够看到 VAC仍然有不少预埋检测逻辑,可能
特定业务场景
,配合动态方案开启

 *转载自游戏安全实验室(GSLAB.QQ.COM)

发表评论

已有 8 条评论

  • 呵呵  2017-07-11
    回复
    1楼

    【和谐】,没开外挂老是玩的好好的就出现VAC什么玩意儿跳出来,竞技都不敢玩

    亮了(0)
    • s10e  2017-07-11
      回复

      @ 呵呵 聊天框里的警告?那是玩家发的233

      亮了(2)
    • 红烧茄子别加糖 
      (1级)
       2017-07-11 回复

      @ 呵呵 这是因为你的网络突然无妨访问国外,导致vac的联网检测和你断开,需要搜索vac屏蔽解决问题,

      亮了(2)
  • aten 
    (1级) Life is short,I use Python
     2017-07-11 回复
    2楼

    VAC有时网络不稳定的时候也会触发,简直是B了狗了,网络不稳定就把我踢了

    亮了(0)
    • 沃德天  2017-07-11
      回复

      @ aten  你打游戏的时候希望和瞬移的对手对枪?

      亮了(3)
  • 科科  2017-07-11
    回复
    3楼

    所以从上篇到现在,一个rss还是舍不得加

    亮了(0)
  • 科科  2017-07-11
    回复
    4楼

    找到了,前台加个图标啊 http://gslab.qq.com/?mod=rss

    亮了(1)
  • xinren  2017-07-12
    回复
    5楼

    来来来,用我鹅厂的保护来了(来我大鹅交点保护费了),不交?!!!一个一个的公开你们家的,公开你们家的保护,公开你们家的漏洞!!!加上看雪的那几篇,嗯,很符合我鹅厂无耻的流氓风格!

    亮了(0)
版权声明:本文为匿名原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: