Гайд CS2 anti cheat - how it works

C++ Certified Professional Programmer
Пользователь
Статус
Оффлайн
Регистрация
3 Янв 2019
Сообщения
149
Реакции[?]
56
Поинты[?]
19K
Hello, this is not a cheat guide this is just how the cs2 anti-cheat works it can be useful if you are making a cheat.

Пожалуйста, авторизуйтесь для просмотра ссылки.
, 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
Пожалуйста, авторизуйтесь для просмотра ссылки.
protobufs

Request protoResponse protoWhat is doing
CUserMessageRequestDllStatusCUserMessage_DllStatusTrusted Mode
CUserMessageRequestUtilActionCUserMessage_UtilMsg_ResponseChecks ConVars for unathorized modifications
CUserMessageRequestInventory
Пожалуйста, авторизуйтесь для просмотра ссылки.
Checks VMT pointers of global interfaces, checks if read-only sections of game DLLs were modified, checks VMT pointers of game entities
CUserMessageRequestDiagnostic
Пожалуйста, авторизуйтесь для просмотра ссылки.
Debugger detection
CUserMessage_Inventory_Response
Пожалуйста, авторизуйтесь для просмотра ссылки.
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
Пожалуйста, авторизуйтесь для просмотра ссылки.
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
Пожалуйста, авторизуйтесь для просмотра ссылки.
protobuf message to the client, the client responds with
Пожалуйста, авторизуйтесь для просмотра ссылки.
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

DWORDpad; // 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.


Пожалуйста, авторизуйтесь для просмотра ссылки.
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.

The following values are copied from thread context into response:


  • Dr0
  • Dr1
  • Dr2
  • Dr3
  • DebugControl
  • Rsp
  • Rip
Credits to danielkrupinski.
 
Последнее редактирование:
Сверху Снизу