Table of Contents

Code integrity and platform helpers

Anti-cheat solutions work best when they are part of a broader hardening strategy. Use the tools below to make reverse engineering harder, validate that the shipped code matches your trusted build, and leverage platform APIs for additional safety nets.

Harden your builds

ACTk does not obfuscate or encrypt your managed assemblies on its own. Combine it with additional hardening layers to slow down reverse engineers and keep managed injections out of your builds.

  • Prefer IL2CPP over Mono so your scripts are compiled into native binaries. IL2CPP removes the intermediate IL that dnSpy and similar tools rely on, blocks managed assembly injection, and forces attackers to use native disassemblers instead.
  • Remember that IL2CPP still emits metadata for reflection. Attackers can recover class and method names with tools such as IL2CPP Dumper. Run a Unity-aware obfuscator before the IL2CPP step so symbol names become meaningless in the generated metadata.
  • Evaluate native protectors when your threat model includes professional cheat makers. Solutions like Denuvo or VMProtect add runtime checks, while Unity-focused tools such as Mfuscator can encrypt IL2CPP metadata and add additional anti-tamper layers.
  • Use CodeHashGenerator to confirm the shipped build matches the hashes produced in CI. Pair the client-side check with server validation for sensitive game flows.

Code hash pipeline

ACTk validates build integrity by generating hashes both in the editor and at runtime. This system helps ensure your shipped code matches your trusted build and hasn't been tampered with.

Note

Only Android and Windows PC builds are supported so far.

How hash generation works

Hash generation produces two types of hashes:

  • Per-file hashes: Individual hashes for each file in the build
  • Summary hash: A single hash derived from all per-file hashes

Both editor (via CodeHashGeneratorPostprocessor) and runtime (via CodeHashGenerator) operations produce these same hash types, though summary hashes may differ in some cases (e.g., Android App Bundle splits with platform-specific files).

Generate trusted hashes during builds

CodeHashGeneratorPostprocessor hooks into the build pipeline and produces reference hashes for each generated file. Enable Generate code hash on build completion in the settings window to automatically run it after every build.

You can also manually calculate external build hashes using:

  • Menu item: Tools > Code Stage > Anti-Cheat Toolkit > Calculate external build hashes
  • Code: CodeHashGeneratorPostprocessor.CalculateExternalBuildHashes(buildPath, printToConsole)

Validate builds at runtime

CodeHashGenerator computes hashes on the player device using two approaches:

Async approach (recommended):

// Note: This must be called from an async method
var result = await CodeHashGenerator.GenerateAsync();
if (result.Success)
    Debug.Log($"Summary Hash: {result.SummaryHash}");

Event-based approach:

CodeHashGenerator.HashGenerated += OnHashGenerated;
CodeHashGenerator.Generate();

private void OnHashGenerated(HashGeneratorResult result)
{
    if (result.Success)
        Debug.Log($"Summary Hash: {result.SummaryHash}");
}
  1. Compare summary hashes first - if they match, the build is likely intact
  2. If summary hashes differ, check per-file hashes against your pre-generated whitelist
  3. Treat unknown hashes as build alteration triggers while ignoring absent files
  4. Implement server-side validation for maximum security - send hashes to your server for comparison against trusted whitelist

CI/CD integration

For CI environments (like GitHub Actions) that don't properly wait for build completion:

// Use synchronous generation instead of relying on HashesGenerated event
CodeHashGeneratorPostprocessor.CalculateExternalBuildHashes(buildPath, printToConsole);

Platform considerations

  • Android App Bundles: Summary hashes may differ per device split due to platform-specific files
  • Per-file hashes: Should remain consistent between editor and runtime builds
  • Server validation: Recommended for production use to prevent client-side tampering

For detailed API reference and examples, see CodeHashGenerator API documentation.

Example implementations

  • Basic usage: See GenuineChecksExamples.cs in Examples/API Examples/Scripts/Runtime/UsageExamples/
  • Advanced validation: See GenuineValidatorExample.cs in Examples/Code Genuine Validation/Scripts/Runtime/
  • DOTS integration: See UIActionSystem.cs in Examples/DOTS ECS Examples/Scripts/UI/Systems/

Android installation source validation

AppInstallationSourceValidator helps you track the store that delivered your APK. Use it to detect installations from unofficial sources or device backups.

Basic Usage

var source = AppInstallationSourceValidator.GetAppInstallationSource();
if (source.DetectedSource == AndroidAppSource.Sideloaded)
    Debug.LogWarning("Sideloaded app detected!");

Advanced Features

  • Trust validation: Check against trusted sources (Google Play, Galaxy Store, Amazon)
  • Security response: Enable restricted mode for untrusted sources
  • Analytics integration: Report installation sources to your backend
  • Error handling: Detect access errors that may indicate security issues

For detailed API reference, see AppInstallationSourceValidator API documentation.

Example implementation

See AndroidExamples.cs in Examples/API Examples/Scripts/Runtime/UsageExamples/ for complete usage examples.

Android screen recording blocker

AndroidScreenRecordingBlocker toggles the system-wide flag that prevents screenshots and screen recording on most stock ROMs. Use it to frustrate basic bots and discourage tool-assisted speed runs on non-rooted devices.

Basic Usage

AndroidScreenRecordingBlocker.PreventScreenRecording();
AndroidScreenRecordingBlocker.AllowScreenRecording();

Advanced Features

  • State-based control: Block recording during sensitive gameplay, allow in menus
  • Platform detection: Use #if UNITY_ANDROID && !UNITY_EDITOR for Android-only code
  • Lifecycle management: Always allow recording when app is paused or destroyed

For detailed API reference, see AndroidScreenRecordingBlocker API documentation.

Example implementation

See AndroidExamples.cs in Examples/API Examples/Scripts/Runtime/UsageExamples/ for complete usage examples.

Tip

Blocking is best-effort. Custom ROMs and rooted devices can bypass the flag, and the app preview disappears from the Android task switcher while prevention is active.