该存储库包含从机器代码重新创建的Windows系统的Valve Anti-Cheat源代码的一部分。
阀门反陈令(VAC)是阀门开发的用户模式非侵入性反陈词系统。它以从远程服务器流的模块(DLL)的形式传递。 steamservice.dll加载到SteamService.exe中(或Steam.exe作为管理员运行)准备并运行反欺骗模块。客户VAC基础架构是使用C++构建的(由拆卸中存在的许多thiscall惯例功能表示),但是此回购包含C代码,以简单起见。抗芯片二进制文件目前为32-bit 。
| ID | 目的 | .TEXT部分原始尺寸 | 源文件夹 |
|---|---|---|---|
| 1 | 收集有关系统配置的信息。 该模块首先加载,有时甚至在启动任何VAC安全游戏之前。 | 0x5c00 | 模块/SystemInfo |
| 2 | 列举运行过程和手柄。 该模块在启动游戏后不久将加载,但后来又一再加载。 | 0x4a00 | 模块/processHandlelist |
| 3 | 从steamservice.dll创建的FileMapping收集VacProcessMonitor数据。这是使用virtual methods (polymorphism)观察到的第一个模块。 | 0x6600 | 模块/ProcessMonitor |
VAC使用多种加密 /哈希方法:
NtQuerySystemInformation 。字符串是带有^或>或& char的XOR-ED。该模块首先加载,有时甚至在启动任何VAC安全游戏之前。
首先,模块调用GetVersion函数以检索专业并构建系统版本,例如0x47BB0A00这意味着:
18363 )10 )模块调用GetNativeSystemInfo函数,并从结果SYSTEM_INFO struct中读取字段:
然后,它调用NtQuerySystemInformation API函数,并使用以下SystemInformationClass值(以代码出现):
SYSTEM_TIMEOFDAY_INFORMATION struct,vac使用两个字段:SYSTEM_CODEINTEGRITY_INFORMATION ,模块保存CodeIntegrityOptions字段SYSTEM_DEVICE_INFORMATION ,模块保存NumberOfDisks字段SYSTEM_KERNEL_DEBUGGER_INFORMATION ,vac使用整个结构SYSTEM_BOOT_ENVIRONMENT_INFORMATION ,vac副本BootIdentifier guidSYSTEM_RANGE_START_INFORMATION ,它只是void* 。反陈词保存返回的内核空间启动地址和该地址的签名位(要检查vac的可执行文件是否与LARGEADDRESSAWARE选项链接在一起)有关SYSTEM_INFORMATION_CLASS枚举的更多信息,请参见Geoff Chappell的页面。
接下来,反陈词调用GetProcessImageFileNameA函数以检索当前可执行文件的路径,并读取最后36个字符(例如Program Files (x86)SteamSteam.exe )。
后来VAC检索系统目录路径(例如C:WINDOWSsystem32 )使用GetSystemDirectoryW ,将其从宽char转换为多键字符串,然后存储它(多键字符串的最大长度-200)。反陈述查询文件夹文件ID(使用GetFileInformationByHandleEx )和音量序列号( GetVolumeInformationByHandleW )。此外,它与Windows Directory从GetWindowsDirectoryW API获取相同的操作。
模块从系统目录读取NtDll.dll文件,并在其上进行一些处理(尚未反转)。
VAC将导入系统DLL(最大16,此VAC模块加载12个DLL)的手柄(基本地址)和用于Winapi功能的指针(最大160,模块使用172个功能)。这样做是为了检测反陈词模块上的导入地址表挂钩,如果函数地址低于相应的模块底座,则函数已被挂钩。
反欺骗通过表演和返回地址( _ReturnAddress() & 0xFFFF0000 )获得自我模块基础。然后它收集:
接下来,它使用FindFirstVolumeW / FindNextVolumeW API列举了量。 VAC查询量量信息通过调用GetVolumeInformationW , GetDriveTypeW和GetVolumePathNamesForVolumeNameW函数,并使用收集的数据填充结构:
struct VolumeData {
UINT volumeGuidHash;
DWORD getVolumeInformationError;
DWORD fileSystemFlags;
DWORD volumeSerialNumber;
UINT volumeNameHash;
UINT fileSystemNameHash;
WORD driveType;
WORD volumePathNameLength;
DWORD volumePathNameHash;
}; // sizeof(VolumeData) == 32VAC收集最大数据。 10卷。
如果在VAT启用游戏开始后流式传输了此模块,则它会在处理游戏过程(使用OpenProcess API)上。
最终,模块加密数据(2048个字节),dword by dword Xoring,使用从服务器接收到的密钥(例如0x1D4855D3)
要披露...
该模块似乎是相对较new或长时间禁用的。我第一次在January 2020看到这个模块。它具有执行许多不同类型的扫描(当前3 )的能力。进一步的扫描取决于以前的扫描结果。
每种扫描类型都实现了基类的four methods 。
最初,VAC服务器指示客户端执行scan #1 。
首先扫描功能attemps打开Steam_{E9FD3C51-9B58-4DA0-962C-734882B19273}_Pid:%000008X FileMapping。映射具有以下布局:
struct VacProcessMonitorMapping {
DWORD magic; // when initialized - 0x30004
PVOID vacProcessMonitor;
}; // sizeof(VacProcessMonitorMapping) == 8 VacProcessMonitorMapping::vacProcessMonitor是指向VacProcessMonitor对象的指针(其大小为292 bytes )。
然后,VAC读取整个VacProcessMonitor对象(292个字节)及其VMT(虚拟方法表),其中包含指针至6方法(24个字节)。还收集了steamservice.dll的基础地址。
这些数据可能在VAC服务器上用于检测挂接VacProcessMonitor 。该程序可能以下是以下内容:
if (method_ptr & 0xFFFF0000 != steamservice_base)
hook_detected ();