How Cheat Engine works, and what it actually does

A technical deep dive into what Cheat Engine is and how it works: Windows process memory, scanning, pointer paths, kernel drivers, and why Unity Mono and IL2CPP games are so easy to read from the outside.

By Tim UhlottFounder|Last updated: August 26, 2026|18 minutes read
game developmentcheat enginehacking
How Cheat Engine works, and what it actually does
What is Cheat Engine? It is a Windows memory scanner and debugger. What Cheat Engine does is attach to another running process, search that process's RAM for values like health or gold, and let you change those values while the program is still running. Most developers first meet Cheat Engine as a game-hacking tool. The design underneath is the interesting part. It uses user-mode APIs, optional kernel drivers, runtime metadata analysis, and sometimes a custom hypervisor. Together that is a process-introspection framework: a program that can watch, change, and control another program from outside its own security context. This article explains how Cheat Engine works in some technical depth, and why those tricks work especially well on Unity games. The goal is not to teach exploitation. The goal is to make the architecture clear enough that you can think about debugging, tooling, and security in your own projects.

How does Cheat Engine work on Windows

Every memory manipulation workflow begins with one prerequisite: access to a target process’s virtual address space. On Windows, this is mediated by the Win32 API and enforced by the kernel’s object security model. The usual first call is OpenProcess. It returns a handle. The handle is the kernel saying yes, you may talk to this process. What matters is the so called access mask you ask for. Cheat Engine typically asks for a mix of:
  • PROCESS_VM_READ and PROCESS_VM_WRITE to copy memory across address spaces
  • PROCESS_VM_OPERATION to change page protections
  • PROCESS_QUERY_INFORMATION to enumerate threads, modules, and metadata
  • PROCESS_CREATE_THREAD for remote execution or DLL injection
Once Windows gives that handle, later calls like ReadProcessMemory, WriteProcessMemory, and VirtualProtectEx are checked against it. From the kernel's point of view this is normal. Windows was built so debuggers and profilers can do this. The main idea is that no code runs inside the target process at this point. Instead, the Windows kernel just lets Cheat Engine temporarily look at and change the target’s memory from the outside, without breaking the normal memory safety rules.
Remember: Cheat Engine does not need to run inside your game to read or change it. Windows lets it open another program and edit its memory, and that is normal, allowed behavior.

Mapping the Virtual Address Space

A modern Windows process does not expose a flat block of usable memory. Instead, it sees a sparse virtual address space composed of regions with different states, protections, and backing stores. Cheat Engine navigates this space using VirtualQueryEx, which returns MEMORY_BASIC_INFORMATION structures describing each region. This metadata drives nearly all higher-level behavior:
  • State (MEM_COMMIT, MEM_RESERVE, MEM_FREE) determines whether data actually exists
  • Protection (PAGE_READWRITE, PAGE_EXECUTE_READ, etc.) distinguishes variables from code
  • Type (MEM_PRIVATE, MEM_IMAGE) separates heap allocations from modules and DLLs
For a Unity game, this distinction is important. Gameplay variables tend to live in MEM_PRIVATE heap regions, while engine logic and static data reside in MEM_IMAGE regions belonging to UnityPlayer.dll, GameAssembly.dll, or managed runtime libraries. By walking the address space region by region, the scanner builds a working map of “where things can possibly be,” which dramatically reduces noise before any value scanning even begins.
Remember: Your gameplay values sit in a predictable part of memory. A cheat tool narrows the search there before it looks for a single value.

Value Scanning: Reducing Gigabytes to One Address

How to use Cheat Engine at a basic level follows the same loop every time: scan for a value, change it, scan again. The rest is algorithmic filtering. A first scan for a common value (say, an int with value 100) can easily return tens of thousands of candidates. Subsequent scans compare the current contents of those same addresses against new constraints:
  • Increased / Decreased when the direction of change is known
  • Changed / Unchanged to eliminate static or unrelated data
  • Range-based scans for obfuscated or scaled values
From a systems perspective, the important detail is how scanning is performed efficiently. Instead of issuing thousands of small kernel calls, Cheat Engine reads large contiguous regions into local buffers and scans them in user space. Alignment heuristics (e.g., stepping by 4 bytes for 32-bit integers) further reduce workload without missing likely candidates. The result is an address that appears to correspond to a gameplay variable, but only for the current session.
Remember: Finding a value is simple: scan, change it in the game, scan again until one address is left. That address only works until the game restarts.

ASLR, Heap Allocation, and the Need for Pointers

Modern applications make heavy use of dynamic allocation, and Windows enforces Address Space Layout Randomization (ASLR) across process restarts. As a result, absolute addresses are ephemeral. To survive restarts, Cheat Engine resolves pointer paths: chains of dereferences that begin at a static base (often a module + offset) and walk through heap-allocated objects to reach the final value. Conceptually, this mirrors how the game itself accesses data:
ModuleBase
  → GlobalManager*
      → Player*
          → Stats*
              → health
Each arrow represents a pointer read plus a fixed offset. Cheat Engine’s pointer scanner automates discovery of these paths by identifying values in memory that look like pointers, that is, integers which themselves point to valid committed regions. By generating pointer maps across multiple sessions and comparing them, the tool can identify stable chains that remain valid even as individual allocations move. These chains are what ultimately get serialized into reusable cheat tables. For developers, this is a reminder that even heavily abstracted object graphs still collapse down into predictable memory layouts once compiled.
Remember: A raw address stops working after a restart, so cheat tools save a path to the value instead. No matter how your code is structured, it still ends up as a findable layout in memory.

Debugging the Target: Who Writes This Value?

Finding a variable answers what to modify. Debugging answers how it’s modified. Cheat Engine supports several breakpoint mechanisms, each with different trade-offs:

1. Software Breakpoints (INT3)

These overwrite the first byte of an instruction with 0xCC. When executed, the CPU raises an exception that the debugger intercepts. This is simple and flexible, but noisy: it modifies code pages and is trivial to detect.

2. Hardware Breakpoints (Debug Registers)

Modern CPUs expose debug registers (DR0 through DR7) that can watch execution or a memory address without changing the code. These breakpoints can trigger on a read or a write to a specific address. For reverse engineering gameplay logic “what writes to health?” hardware breakpoints are invaluable, because they reveal the exact instruction and register state responsible for a change.

3. VEH Debugging

Vectored Exception Handling (VEH) avoids attaching as a traditional debugger. Instead, injected code inside the target process registers its own exception handler, intercepting breakpoints before Windows’ standard handlers run. From the target’s point of view, no debugger is attached. From the researcher’s point of view, full breakpoint telemetry is available. This technique highlights how much flexibility Windows provides to in-process exception routing.
Remember: Finding a value shows what to change. A breakpoint shows the exact line of your code that changes it, which is how attackers learn how your systems work.

Crossing into Kernel Space (and Beyond)

As anti-cheat systems increasingly operate in kernel mode, user-mode memory tools face structural limits. Cheat Engine addresses this with optional kernel drivers and, at the extreme end, a custom hypervisor.

1. Kernel Drivers

A Ring-0 driver can bypass user-mode API hooks, access physical memory directly, and set breakpoints invisible to user-mode detection. It effectively re-implements parts of the memory manager from a more privileged vantage point.

2. Hypervisor (DBVM)

DBVM pushes this idea further by running beneath Windows itself, using Intel VT-x or AMD-V. In this configuration, Windows becomes a guest OS, and Cheat Engine operates at a higher privilege level. This enables:
  • Breakpoints that never surface to the OS
  • Page-level access control via Extended Page Tables (EPT)
  • Concealment from kernel self-protection mechanisms like PatchGuard
From an architectural standpoint, this demonstrates a blunt truth: the highest privilege layer always wins. Security is about raising cost, not achieving absolute prevention.
Remember: Whoever has the deeper system access wins in the end. Client-side security is about making cheating slow and annoying, not about a perfect lock.

Unity-Specific Analysis: Mono vs. IL2CPP

Unity’s scripting backend choice fundamentally defines how observable and malleable a game is from outside the process. Mono and IL2CPP do not merely differ in performance characteristics; they expose very different reverse-engineering surfaces.

1. Mono: Rich Metadata as Both Feature and Liability

In Mono-based Unity builds, C# assemblies are loaded largely intact. Class names, field names, method signatures, inheritance hierarchies, and field offsets remain discoverable at runtime. This metadata exists to support reflection, debugging, serialization, and garbage collection, and it is exposed through the Mono embedding API. Cheat Engine’s Mono Dissector leverages this directly by injecting a helper module that queries the runtime via functions such as mono_class_get_fields() and mono_field_get_offset(). The result is effectively a live, structured view of the managed heap: developers’ conceptual object models rendered directly into a memory inspection tool. Where Obfuscation Helps in Mono Code obfuscation does meaningfully raise the cost of analysis in Mono builds, for example:
  • Symbol obfuscation (renaming classes, fields, and methods) destroys semantic clarity. A field named PlayerHealth becoming a1b2c3 removes intent and slows manual exploration.
  • Control-flow obfuscation complicates method-level reasoning when breakpoints hit managed code paths.
  • String encryption prevents trivial discovery of logic tied to configuration keys, events, or debug output.
However, obfuscation does not eliminate structural visibility. Even fully renamed fields still:
  • Exist at fixed offsets within objects
  • Are enumerable via the Mono API
  • Can be observed changing over time
From a memory tool’s perspective, Player.currentHealth and a.b.c are equally writable once their offset is known. Obfuscation increases analyst effort, but it does not meaningfully restrict capability. In short: Mono obfuscation protects meaning, not access.

2. IL2CPP: Native Code, Reduced Introspection Surface

IL2CPP fundamentally alters the analysis model by converting managed code into native C++ ahead of time. The managed runtime disappears, taking with it reflection, JIT compilation, and most high-level metadata. Instead, Unity emits:
  • A native binary (GameAssembly.dll)
  • A serialized metadata file (global-metadata.dat) describing types, methods, and fields
At runtime, objects still exist on the heap, but there is no longer a managed API that cleanly exposes their structure. Cheat Engine cannot simply “ask the runtime” for field offsets or instances. This forces attackers into:
  • Metadata dumping and reconstruction
  • Static analysis of native code
  • API hooking of IL2CPP runtime functions
  • Traditional pointer and code analysis
The barrier to entry is significantly higher.

Where Obfuscation Helps in IL2CPP

Obfuscation is materially more effective in IL2CPP builds because it compounds existing opacity rather than merely renaming exposed metadata. Effective IL2CPP obfuscation strategies include:
  • Metadata obfuscation Renaming types and fields which then are requested inside global-metadata.dat breaking automated dumpers’ ability to produce meaningful headers.
  • Layout randomization Reordering fields within classes invalidates previously discovered offsets, forcing re-analysis after every build.
  • Control-flow flattening in native code Makes static disassembly of GameAssembly.dll significantly harder, even with full symbols reconstructed.
  • Dead-code and fake-type injection Pollutes metadata with unused or misleading structures, increasing noise during reverse engineering.
Unlike Mono, where tooling can query live runtime truth, IL2CPP attackers must reconstruct intent from binaries. Obfuscation directly targets this reconstruction phase. That said, obfuscation still does not make manipulation impossible. Once offsets and code paths are rediscovered, the same fundamental techniques apply:
  • Objects are still heap-allocated
  • Fields still live at deterministic offsets
  • Native instructions still mutate memory
What changes is time-to-capability, not end capability. If you ship Unity and want that extra cost on IL2CPP (and Mono) builds, a Unity-focused option is GuardingPearSoftware Obfuscator.
Remember: Mono builds are the easiest to read from outside. IL2CPP hides more, and obfuscation makes both slower to crack. None of it is a full stop, but it buys you time forcing attackers on another target.

Temporal Manipulation: How Speed Hacks Work

Cheat Engine’s speed hack does not accelerate the CPU or alter the system clock. Instead, it manipulates time perception inside the target process by intercepting Windows timing APIs such as QueryPerformanceCounter, GetTickCount64, and timeGetTime. Most game engines, including Unity, advance simulation based on per-frame delta time derived from these APIs. By scaling the reported elapsed time with a multiplier, the speed hack convinces the engine that more (or less) time has passed than actually has. Physics, animation, cooldowns, and AI logic then evolve faster or slower accordingly. The transformation is conceptually simple: real time is sampled once, and all subsequent time queries are linearly scaled before being returned to the game. Unity’s Time.deltaTime ultimately traces back to QueryPerformanceCounter, making it the primary interception point in modern titles. Anti-Cheat Detection Strategies Because speed hacks do not modify kernel or hardware clocks, anti-cheat systems focus on inconsistencies rather than prevention. Common detection approaches include:
  • Cross-clock validation Comparing user-mode timing results (e.g., QueryPerformanceCounter) against kernel-level timers or CPU counters (RDTSC). Diverging rates indicate manipulation.
  • Kernel-time verification Sampling time directly in Ring 0, bypassing user-mode hooks entirely. Any mismatch between kernel-observed time and client-reported deltas is grounds for suspicion.
  • Behavioral validation Detecting impossible outcomes: movement speed, cooldown completion, or simulation progress exceeding what authoritative time allows, especially in multiplayer environments.
  • API integrity checks Verifying that timing functions are unhooked, reside on image-backed pages, and match expected instruction signatures.
In server-authoritative multiplayer architectures, speed hacks are largely neutralized by design, as the server’s clock defines reality. In single-player or client-authoritative games, detection becomes a probabilistic arms race rather than a guarantee. If you do not want to wire those checks yourself, GuardingPearSoftware Anti-Cheat covers protected time, protected memory, and reactions when something looks wrong.
Remember: Do not trust time reported on the player's machine any more than you trust their memory. Check it in more than one place, and let the server decide when it matters.

Runtime Modifier vs Cheat Engine

Runtime Modifier and Cheat Engine are the same official tool, from the same author (Dark Byte) and the same codebase on cheatengine.org. Runtime Modifier is the rebrand for people who want the scanner without the word "cheat" in the process name. The practical difference is smaller than the names suggest. Runtime Modifier ships without the kernel driver and the trainer maker. That cuts some antivirus false positives. It also means name-only anti-cheat checks that look for the string Cheat Engine miss it. If you detect only that string, you are not detecting the tool. Detect the behavior this article already covers: process handles with VM access, region walks via VirtualQueryEx, timing API hooks, and Mono or IL2CPP dissectors.

What is CheatLoop?

Searching for Cheat Engine, you will find come across the name CheatLoop. CheatLoop is not Cheat Engine. It was a third-party cheat loader and shop. People paid for ready-made cheats that a launcher injected into specific games. Cheat Engine is a general memory scanner and debugger you run yourself. CheatLoop sold a product, not a scanner. The service has been terminated. The old docs still say the service is down. Treat the name as a leftover search term, not as an active tool, and do not confuse it with Cheat Engine or Runtime Modifier.

What This Means for Game Developers

Cheat Engine is not magic. It is a systematic exploitation of documented operating system features, runtime metadata, and hardware capabilities. For developers, the takeaways are practical:
  • Client-side state is never authoritative
  • Metadata is a trade-off between productivity and observability
  • Security features raise effort, not guarantees
  • Debugging infrastructure is indistinguishable from attack surface
Understanding these tools does not weaken your games, it strengthens your mental model of how software actually runs on player machines. In the end, whoever controls the highest privilege layer controls reality. Everything else is policy.
1,0121,012 views
00 shares

Discussion about this post

Comments are reviewed before they appear on the article.

No comments yet. Be the first to start the discussion.

Frequently asked questions

Newsletter

Stay in the Loop.

Subscribe to our newsletter to receive the latest news, updates, and special offers directly in your inbox. Don't miss out!