• Stars
    star
    678
  • Rank 66,609 (Top 2 %)
  • Language
    C
  • License
    MIT License
  • Created about 5 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Source code of Valve Anti-Cheat obtained from disassembly of compiled modules

VAC 🛡️

This repository contains parts of source code of Valve Anti-Cheat for Windows systems recreated from machine code.

Introduction

Valve Anti-Cheat (VAC) is user-mode noninvasive anti-cheat system developed by Valve. It is delivered in form of modules (dlls) streamed from the remote server. steamservice.dll loaded into SteamService.exe (or Steam.exe if run as admin) prepares and runs anti-cheat modules. Client VAC infrastructure is built using C++ (indicated by many thiscall convention functions present in disassembly) but this repo contains C code for simplicity. Anti-cheat binaries are currently 32-bit.

Modules

ID Purpose .text section raw size Source folder
1 Collect information about system configuration.
This module is loaded first and sometimes even before any VAC-secured game is launched.
0x5C00 Modules/SystemInfo
2 Enumerate running processes and handles.
This module is loaded shortly after game is launched but also repeatedly later.
0x4A00 Modules/ProcessHandleList
3 Collect VacProcessMonitor data from filemapping created by steamservice.dll. It's the first module observed to use virtual methods (polymorphism). 0x6600 Modules/ProcessMonitor

Encryption / Hashing

VAC uses several encryption / hashing methods:

  • MD5 - hashing data read from process memory
  • ICE - decryption of imported functions names and encryption of scan results
  • CRC32 - hashing table of WinAPI functions addresses
  • Xor - encryption of function names on stack, e.g NtQuerySystemInformation. Strings are xor-ed with ^ or > or & char.

Module Description

#1 - SystemInfo

This module is loaded first and sometimes even before any VAC-secured game is launched.

At first module invokes GetVersion function to retrieve major and build system version e.g 0x47BB0A00 - which means:

  • 0x47BB - build version (decimal 18363‬)
  • 0x0A00 - major version (decimal 10)

The module calls GetNativeSystemInfo function and reads fields from resultant SYSTEM_INFO struct:

  • wProcessorArchitecture
  • dwProcessorType

Then it calls NtQuerySystemInformation API function with following SystemInformationClass values (in order they appear in code):

For more information about SYSTEM_INFORMATION_CLASS enum see Geoff Chappell's page.

Next, anti-cheat calls GetProcessImageFileNameA function to retrieve path of current executable and reads last 36 characters (e.g. \Program Files (x86)\Steam\Steam.exe).

Later VAC retrieves system directory path (e.g C:\WINDOWS\system32) using GetSystemDirectoryW, converts it from wide-char to multibyte string, and stores it (max length of multibyte string - 200). Anti-cheat queries folder FileID (using GetFileInformationByHandleEx) and volume serial number (GetVolumeInformationByHandleW). Further it does the same with windows directory got from GetWindowsDirectoryW API.

Module reads NtDll.dll file from system directory and does some processing on it (not reversed yet).

VAC saves handles (base addresses) of imported system dlls (max 16, this VAC module loads 12 dlls) and pointers to WINAPI functions (max 160, module uses 172 functions‬). This is done to detect import address table hooking on anti-cheat module, if function address is lower than corresponding module base, function has been hooked.

Anti-cheat gets self module base by performing bitwise and on return address (_ReturnAddress() & 0xFFFF0000). Then it collects:

  • module base address
  • first four bytes at module base address (from DOS header)
  • DWORD at module base + 0x114
  • DWORD at module base + 0x400 (start of .text section)

Next it enumerates volumes using FindFirstVolumeW / FindNextVolumeW API. VAC queries volume information by calling GetVolumeInformationW, GetDriveTypeW and GetVolumePathNamesForVolumeNameW functions and fills following struct with collected data:

struct VolumeData {
    UINT volumeGuidHash;
    DWORD getVolumeInformationError;
    DWORD fileSystemFlags;
    DWORD volumeSerialNumber;
    UINT volumeNameHash;
    UINT fileSystemNameHash;
    WORD driveType;
    WORD volumePathNameLength;
    DWORD volumePathNameHash;
}; // sizeof(VolumeData) == 32

VAC gathers data of max. 10 volumes.

If this module was streamed after VAC-secured game had started, it attemps to get handle to the game process (using OpenProcess API).

Eventually, module encrypts data (2048 bytes), DWORD by DWORD XORing with key received from server (e.g 0x1D4855D3)

#2 - ProcessHandleList

To be disclosed...

#3 - ProcessMonitor

This module seems to be relatively new or was disabled for a long time. First time I saw this module in January 2020. It has an ability to perform many different types of scans (currently 3). Further scans depends on the results of previous ones.

Each scan type implements four methods of a base class.

Initially VAC server instructs client to perform scan #1.

Scan #1 - VacProcessMonitor filemapping

First scan function attemps to open Steam_{E9FD3C51-9B58-4DA0-962C-734882B19273}_Pid:%000008X filemapping. The mapping has following layout:

struct VacProcessMonitorMapping {
    DWORD magic; // when initialized - 0x30004
    PVOID vacProcessMonitor;
}; // sizeof(VacProcessMonitorMapping) == 8

VacProcessMonitorMapping::vacProcessMonitor is a pointer to the VacProcessMonitor object (size of which is 292 bytes).

VAC then reads the whole VacProcessMonitor object (292 bytes) and its VMT (Virtual Method Table) containing pointers to 6 methods (24 bytes). The base address of steamservice.dll is also gathered.

These data are probably used on VAC servers to detect hooking VacProcessMonitor. The procedure may be following:

if (method_ptr & 0xFFFF0000 != steamservice_base)
    hook_detected();

More Repositories

1

Osiris

Free and open-source game hack for Counter-Strike 2, written in modern C++. For Windows and Linux.
C++
3,198
star
2

VAC-Bypass

Valve Anti-Cheat bypass written in C.
C
526
star
3

VAC-Bypass-Loader

Loader for VAC Bypass written in C.
C
459
star
4

MemJect

Simple Dll injector loading from memory. Supports PE header and entry point erasure. Written in C99.
C
435
star
5

GOESP

Cross-platform streamproof ESP hack for Counter-Strike: Global Offensive, written in modern C++. Rendering and GUI powered by Dear ImGui + FreeType.
C++
432
star
6

Anubis

Free open-source training software / cheat for Counter-Strike: Global Offensive, written in C.
C
177
star
7

OneByteWallhack

CS:GO wallhack achieved by patching one byte of game memory. Written in Python 3.
Python
161
star
8

x86RetSpoof

Invoke functions with a spoofed return address. For 32-bit Windows binaries. Supports __fastcall, __thiscall, __stdcall and __cdecl calling conventions. Written in C++17.
C++
160
star
9

vac-hooks

Hook WinAPI functions used by Valve Anti-Cheat. Log calls and intercept arguments & return values. DLL written in C.
C
157
star
10

OneByteLdr

Bypass for CS:GO's LoadLibrary injection prevention mechanism, achieved by patching one byte of game memory.
Python
156
star
11

cs2-anticheat

Anticheat code found in Counter-Strike 2 binaries.
139
star
12

OneByteRadar

CS:GO radar hack achieved by patching one byte of game memory. Written in Python 3.
Python
102
star
13

Inflame

User-mode Windows DLL injector written in Assembly language (FASM syntax) with WinAPI.
Assembly
84
star
14

StringPool

A performant and memory efficient storage for immutable strings with C++17. Supports all standard char types: char, wchar_t, char16_t, char32_t and C++20's char8_t.
C++
49
star
15

KernelProcessList

Example Windows Kernel-mode Driver which enumerates running processes.
C
47
star
16

OsirisInventory

Inventory Changer for CS:GO
C++
36
star
17

Caesar

Open source cheat for Steam version of Counter-Strike 1.6.
C
29
star
18

OneByteMoney

CS:GO hack displaying enemies' money, achieved by patching one byte of game memory. Written in Python 3.
Python
26
star
19

PE2HEX

PE executable to array of bytes converter
Python
21
star
20

KernelPID

Example Windows Kernel-mode Driver which finds process ID by executable file name.
C
16
star
21

mars

An open source Counter-Strike: Global Offensive cheat for Linux.
C
16
star
22

csgo-champion

Champion - external CS:GO cheat for Linux
C++
16
star
23

KernelThread

C
13
star
24

helloworld-driver

C
11
star
25

OneByteQuickDuck

CS:GO quick duck achieved by patching one byte of game memory. Written in Python 3.
Python
9
star
26

fnv-cpp

C++
7
star
27

rusty-csgo

Attempts at internal game hacking (CS;GO) with Rust
Rust
6
star
28

windows-account-creator

Batch script to create user accounts in Windows.
Batchfile
6
star
29

FASM-DLL

Assembly
5
star
30

curiumcheat-cuphead

Curium is an open source cheat for Cuphead game.
C++
4
star
31

no-CRT

C++
4
star
32

winapi-calculator-cpp

WinAPI Calculator written in C++
C++
3
star
33

Feb

Assembly
3
star
34

lennox-engine

Lennox Game Engine
C++
3
star
35

Jector

Assembly
3
star
36

Fet

Assembly
3
star
37

cmake-demo

A collection of CMake scripts for C and C++ projects.
CMake
3
star
38

cpp-playground

C++
3
star
39

helloworld-DLL

Hello world! - DLL
C
3
star
40

helloworld-rust

Rust
2
star
41

helloworld-fasm

Hello world! - FASM
Assembly
2
star
42

zxvnme.github.io

zxvnme's site
CSS
2
star
43

RGBEngine

C
2
star
44

fnv-c

C
2
star
45

php-playground

PHP
2
star
46

ArchiveX

C++
2
star
47

opengl-base

Base OpenGL 4.6 application written in C.
C
2
star
48

snake-cpp

C++
2
star
49

cpp98-playground

C++
1
star
50

BSOD

Assembly
1
star
51

Feg

Assembly
1
star
52

curiumcheat-maxpayne

Curium is an open source cheat for Max Payne game.
C++
1
star
53

colormix-cpp

C++
1
star
54

coinflip-cpp

Coin flip simulation program.
C++
1
star
55

cout-vs-printf

Cout vs printf benchmark
C++
1
star
56

js-playground

HTML
1
star
57

binary-cpp

Binary - decimal calculator
C++
1
star