• Stars
    star
    139
  • Rank 262,954 (Top 6 %)
  • Language
  • License
    MIT License
  • Created over 1 year ago
  • Updated over 1 year ago

Reviews

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

Repository Details

Anticheat code found in Counter-Strike 2 binaries.

Counter-Strike 2 Anticheat

Anticheat measures found in the binaries of Counter-Strike 2. The analysis is based on the 6 June 2023 update.

What's new

6 June 2023

  • new functionality added to CUserMessage_Inventory_Response to collect VMT pointers of entities from entity system
  • new CUserMessageRequestDiagnostic / CUserMessage_Diagnostic_Response to detect debuggers

Detections which use protobufs

Request proto Response proto What is does
CUserMessageRequestDllStatus CUserMessage_DllStatus Trusted Mode
CUserMessageRequestUtilAction CUserMessage_UtilMsg_Response Checks ConVars for unathorized modifications
CUserMessageRequestInventory CUserMessage_Inventory_Response Checks VMT pointers of global interfaces, checks if read-only sections of game DLLs were modified, checks VMT pointers of game entities
CUserMessageRequestDiagnostic CUserMessage_Diagnostic_Response Debugger detection

CUserMessage_Inventory_Response

VMT pointer check of global interfaces

// E8 ? ? ? ? 48 8D 8C 24 ? ? ? ? E8 ? ? ? ? F6 43 20 02 (relative jump) @ client.dll
void collectInterfacesData(CUserMessage_Inventory_Response& protobuf);

This function iterates over g_pInterfaceGlobals array (name from Source 1 engine) and for every interface fills InventoryDetail protobuf:

message InventoryDetail {
    optional int32 index = 1; // index in the g_pInterfaceGlobals array
    optional int64 primary = 2; // *g_pInterfaceGlobals[index] (address of the interface)
    optional int64 offset = 3; // **g_pInterfaceGlobals[index] (address of virtual method table of the interface)
    optional int64 first = 4; // address of the first function in the VMT
    optional int64 base = 5;
    optional string name = 6;
    optional string base_name = 7;
    optional int32 base_detail = 8;
    optional int32 base_time = 9;
    optional int32 base_hash = 10; // interface name hash
}
(fields without a comment are unused)
List of checked interfaces
VApplication001
VEngineCvar007
VStringTokenSystem001
TestScriptMgr001
VProcessUtils002
VFileSystem017
VAsyncFileSystem2_001
ResourceSystem013
ResourceManifestRegistry001
ResourceHandleUtils001
SchemaSystem_001
ResourceCompilerSystem001
VMaterialSystem2_001
PostProcessingSystem_001
InputSystemVersion001
InputStackSystemVersion001
RenderDeviceMgr001
RenderUtils_001
SoundSystem001
SoundOpSystemEdit001
SoundOpSystem001
SteamAudio001
VP4003
Localize_001
VMediaFoundation001
VAvi001
VBik001
MeshSystem001
MeshUtils001
RenderDevice003
VRenderDeviceSetupV001
RenderHardwareConfig002
SceneSystem_002
SceneUtils_001
WorldRendererMgr001
AssetSystem001
AssetSystemTest001
ParticleSystemMgr003
VScriptManager010
PropertyEditorSystem_001
MATCHFRAMEWORK_001
Source2V8System001
PanoramaUIEngine001
PanoramaUIClient001
PanoramaTextServices001
ToolFramework2_002
PhysicsBuilderMgr001
VisBuilder_001
BakedLODBuilderMgr001
HelpSystem_001
ToolSceneNodeFactory_001
EconItemToolModel_001
SchemaTestExternal_Two_001
SchemaTestExternal_One_001
AnimationSystem_001
AnimationSystemUtils_001
HammerMapLoader001
MaterialUtils_001
FontManager_001
TextLayout_001
AssetPreviewSystem_001
AssetBrowserSystem_001
AssetRenameSystem_001
VConComm001
MODEL_PROCESSING_SERVICES_INTERFACE_001
NetworkSystemVersion001
NetworkMessagesVersion001
FlattenedSerializersVersion001
SerializedEntitiesVersion001
DemoUpconverterVersion001
Source2Client002
Source2ClientUI001
Source2ClientPrediction001
Source2Server001
Source2Host001
Source2GameClients001
Source2GameEntities001
EngineServiceMgr001
HostStateMgr001
NetworkService_001
NetworkClientService_001
NetworkP2PService_001
NetworkServerService_001
ToolService_001
RenderService_001
StatsService_001
VProfService_001
InputService_001
MapListService_001
GameUIService_001
SoundService_001
BenchmarkService001
KeyValueCache001
GameResourceServiceClientV001
GameResourceServiceServerV001
Source2EngineToClient001
Source2EngineToServer001
Source2EngineToServerStringTable001
Source2EngineToClientStringTable001
VPhysics2_Interface_001
VPhysics2_Handle_Interface_001
ModelDocUtils001
AnimGraphEditorUtils001
MODEL_PROCESSING_SCRIPT_INTERFACE_001
EXPORTSYSTEM_INTERFACE_VERSION_001
NavSystem001

Integrity of read-only sections of game DLLs

This check is present in client.dll under the name "ComputeInventory2". Game DLLs register themselves by calling Plat_RegisterModule(moduleHandle) function from tier0.dll. The list of registered modules can be retrieved by calling Plat_GetRegisteredModules().

When game server sends CUserMessageRequestInventory protobuf message to the client, the client responds with CUserMessage_Inventory_Response message containing info about registered modules.

For every registered dll:

struct DllSectionsResult {
    void* baseOfDll;
    IMAGE_NT_HEADERS* ntHeaders;
    void* buffer; // allocated with VirtualAlloc in processDllSections()
    DWORD timestamp; // from IMAGE_FILE_HEADER::TimeDateStamp
    DWORD pad; // padding
    CSHA1 sha1; // sizeof(CSHA1) == 192, seems not to be computed currently
    CRC32 readOnlySectionsHash;
};

// E8 ? ? ? ? 8B 8C 24 ? ? ? ? 0F B6 D8 (relative jump) @ client.dll
bool processDllSections(DllSectionsResult& output, HMODULE dll);

processDllSections() allocates the buffer of size IMAGE_OPTIONAL_HEADER::SizeOfImage and does the following:

  • copies the headers to the buffer (IMAGE_OPTIONAL_HEADER::SizeOfHeaders bytes at dll base)
  • copies every unwritable section ((IMAGE_SECTION_HEADER::Characteristics & IMAGE_SCN_MEM_WRITE) == 0) to the buffer
  • iterates over base relocation table (IMAGE_DIRECTORY_ENTRY_BASERELOC) and undoes relocations in the buffer (only IMAGE_REL_BASED_DIR64 relocations)
  • zeroes import address table (IMAGE_DIRECTORY_ENTRY_IAT) and export directory (IMAGE_DIRECTORY_ENTRY_EXPORT) in the buffer
  • computes CRC32 of read-only sections in the buffer

processDllSections() is called by another function:

// E8 ? ? ? ? 0F B6 C0 85 C0 74 7B (relative jump) @ client.dll
bool processDll(
    HMODULE dll,
    CRC32& readOnlySectionsHash,
    char* pdbPath,
    DWORD& sizeOfImage,
    DWORD& timestamp,
    void** imageBase
);

processDll() does the following:

  • calls processDllSections() and copies the fields of returned DllSectionsResult to the output parameters
  • copies PDB path from debug directory to pdbPath output buffer

Later PDB file name is extracted from path and hashed.

InventoryDetail protobuf is filled with the gathered info.

message InventoryDetail {
    optional int32 index = 1; // index in the array of registered modules
    optional int64 primary = 2; // image base from IMAGE_OPTIONAL_HEADER
    optional int64 offset = 3; // size of image
    optional int64 first = 4;
    optional int64 base = 5; // dll handle
    optional string name = 6;
    optional string base_name = 7;
    optional int32 base_detail = 8; // crc32 of read-only sections
    optional int32 base_time = 9; // timestamp from IMAGE_FILE_HEADER
    optional int32 base_hash = 10; // PDB filename hash
}
(fields without a comment are unused)

CUserMessage_Diagnostic_Response

At first Plat_GetDebugMonitor() from tier0.dll is called and the response is filled with data from DebugMonitor.

Then a thread of id provided through a parameter is opened (OpenThread(THREAD_ALL_ACCESS, 0, threadId)) and suspended. Thread context is then queried and the thread is resumed.

Following values are copied from thread context into response:

  • Dr0
  • Dr1
  • Dr2
  • Dr3
  • DebugControl
  • Rsp
  • Rip

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

Source code of Valve Anti-Cheat obtained from disassembly of compiled modules
C
678
star
3

VAC-Bypass

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

VAC-Bypass-Loader

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

MemJect

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

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
7

Anubis

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

OneByteWallhack

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

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
10

vac-hooks

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

OneByteLdr

Bypass for CS:GO's LoadLibrary injection prevention mechanism, achieved by patching one byte of game memory.
Python
156
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