Anti-Cheat

How Unity SpeedHack Works, and a Native-Based Detection Strategy

A single SpeedHack can break your game economy

In an idle RPG, a player running the game at 10x speed sweeps up months of currency in a single day. The leaderboards of a rhythm or action game fill with impossible play-times and scores. In a competitive game, one player moving just 1.2x faster destroys fair matchmaking on the spot.

SpeedHack is the most common — and most underestimated — cheat. Instead of editing a specific value like memory tampering does, it warps the very flow of "time" that the game perceives. Reactive defenses like "verify currency gain" or "verify movement coordinates" can't fundamentally catch this time distortion, and the damage spreads to revenue, player retention, and leaderboard trust.

This article looks at how SpeedHack actually manipulates time behind the Unity engine, why common C#-level defenses are easily broken, and how to detect it at the Native (C++) layer.

What SpeedHack manipulates — the mechanics

A Unity game's core loop constantly computes "how much time has passed since the previous frame." That value is Time.deltaTime, and movement speed, cooldowns, physics, animation, and currency accrual all depend on it.

The principle of SpeedHack is simple: artificially inflate or shrink this time measurement so the engine believes "more time has passed than really did." The key is that Unity doesn't create time itself — it calls OS timer APIs to obtain it, and attackers intercept those calls.

[ Normal time flow ]
OS hardware timer ──> OS timer API ──> Unity (Time.deltaTime) ──> game logic

[ With SpeedHack ]
OS hardware timer ──> OS timer API ──> [SpeedHack hook: x10] ──> Unity ──> game logic runs 10x faster

1) PC (Windows) SpeedHacks like Cheat Engine inject a DLL into the game process, then hook the time-measurement APIs — typically QueryPerformanceCounter, timeGetTime, and GetTickCount / GetTickCount64. The hooked function multiplies the real tick value by a factor (e.g., x10). The game simply called the API honestly, yet perceives that 10x the time elapsed in a single frame.

2) Mobile (Android) Tools like GameGuardian use the same mechanism: they intercept libc functions such as gettimeofday and clock_gettime (PLT/GOT hooking), or run the app inside a Virtual Space to manipulate the time baseline itself. On rooted environments they can reach even lower layers.

On every platform the pattern is identical: warp the bottom of the trust chain (the OS timer), and fool the entire engine and game logic stacked on top of it at once.

The limits of common C#-level defenses

Teams that hit SpeedHack usually add their own defense at the C# level. The direction is right, but in practice they run into these limits.

1) Comparing Time.deltaTime vs Time.unscaledDeltaTime — meaningless Both derive from the same OS timer. Once the timer is hooked, both values are distorted by the same ratio, so there's no difference. It's like holding two manipulated clocks against each other to check if they're correct.

2) Cross-checking against a C# clock (DateTime.UtcNow, Stopwatch) — removed by reverse engineering The idea of cross-checking against a separate reference is correct. The problem is that the check code is exposed in managed code (C#). Even with an IL2CPP build, global-metadata.dat plus Il2CppDumper recovers much of the class and method structure, so an attacker finds the detection method and neutralizes the branch with a NOP/JMP patch.

// An attacker finds this method via IL2CPP reverse engineering
// and patches the binary so the branch is never taken.
bool CheckSpeedHack() {
    if (MySystemTime != UnityTime) {
        return true; // <-- JMP-patched to skip this branch
    }
    return false;
}

3) Server timestamp validation — strong, but can't cover everything Cross-checking the interval between client actions against server time is a solid last line of defense. But validating every single-player element, idle progression, and fine-grained movement on the server is costly in bandwidth and compute, and impossible for offline-capable games.

In short, when the attack comes in at the Native layer where the OS timer runs, but the watching eye stays one level above it in C# managed code, you've handed the attacker the upper hand.

Detecting SpeedHack at the Native (C++) layer

For reliable detection, you need an independent monitoring system at — or below — the layer the attacker is warping. There are three core principles.

(1) Secure a low-level independent clock resistant to hooking Step away from the high-level APIs cheats love to target (QueryPerformanceCounter, etc.) and read a lower time source directly to form a baseline. On Windows, that's the CPU cycle counter (rdtsc) or a user-readable system time field; on Android, a monotonic clock from the syscall path (CLOCK_MONOTONIC / CLOCK_BOOTTIME) bypassing the library interface. Cross-check the ratio between this baseline and the time the game actually uses; if it diverges beyond a threshold, flag it as time-axis manipulation.

That said, rdtsc isn't a silver bullet either. Hypervisor-based tools can trap/virtualize RDTSC itself, and if the app runs inside a virtual space, even direct syscalls can be intercepted by the container. So treat the low-level clock as "one axis that's strong against high-level API hooking," and combine it with (2), (3), and server-side trusted time to be robust.

(2) Directly detect hooking traces on time APIs To apply a multiplier, a tool must tamper with the prologue of a time function to jump (JMP, e.g., 0xE9) or swap the function address table (IAT/EAT). Native detection checks whether the first bytes of key time functions are altered, or whether addresses point to an unauthorized module — catching the tool's traces directly.

(3) Decouple security logic from C# The most important design principle. The detection loop, clock comparison, and response logic must not be exposed in C# memory or the IL2CPP output. Run the core logic on a separate thread inside an obfuscated Native C++ binary (.dll / .so). Even if an attacker analyzes the entire C# codebase, they can't locate the watcher — raising the difficulty of reverse engineering and patching dramatically.

OZero Security's response to SpeedHack

Building a Native anti-cheat yourself requires deep OS internals knowledge, multi-platform coverage, and maintenance against frequent OS updates — a heavy burden for small studios. OZero Security provides a Native C++ anti-cheat that drops into Unity immediately.

  • Trusted-time validation (OZero's key differentiator): Rather than relying on the local clock alone, it cross-checks multiple webTime endpoints in round-robin with a quorum to establish a trustworthy reference time. You can even register your own self-hosted webTime endpoint, so even if the local timer is manipulated, the mismatch against external trusted time reveals the tampering.
  • Native C++ detection: Performs low-level clock cross-checking and time-API hook-trace detection outside managed code.
  • Performance design: Security logic lives in the Native C++ layer rather than C#, and protected values are designed to incur no GC allocation.
  • Flexible response: Detection behavior is policy-configurable — log, restrict features, terminate the process, or send encrypted detection logs to your server/back-office for real-time enforcement (Pro Add-on telemetry).
  • Integration: Applied with no code — import the .unitypackage, toggle modules on the dashboard, and save the config.

Real-time detection demos

OZero Security detecting SpeedHack in real time:

Windows (PC) — real-time SpeedHack detection
Android (mobile) — real-time SpeedHack detection

Summary

  • A cheat that steals time: SpeedHack fools the entire system's time axis rather than an individual value, paralyzing the economy and fairness.
  • The limit of C# security: Even through IL2CPP, check logic exposed in C# is neutralized in front of reverse-engineering tools.
  • The proper solution: Combine a low-level independent clock, time-API hook-trace detection, and Native separation of the check logic — and cover the limits of the local clock with server-side trusted time (webTime quorum).

Blocking even a single SpeedHack demands knowledge spanning OS architecture, the assembly layer, and reverse-engineering evasion. If you're tired of the endless chase against cheat patterns, consider a proven solution so you can focus on building your game.

See how OZero Security detects and responds to SpeedHack.

Related reading