Android - App Hash - Monitor (Pro)
A hash is a fingerprint of the whole app file. Compare the hash on the device with a hash you stored. If they differ, the app file was changed.
Walkthrough: Protecting an Android build.
You need a copy of the hash somewhere the app can download it. That is why this check takes more setup than the signature check.
Monitor
AndroidPackageHashMonitor (namespace GUPS.AntiCheat.Monitor.Android) calculates the hash of the running app. It then sends an AndroidHashStatus. The detector can compare that hash with the one on your server.
Status
The monitor sends an AndroidHashStatus:
public struct AndroidHashStatus : IAndroidStatus
{
// True if the hash could not be retrieved (e.g. a JNI failure).
public bool FailedToRetrieveData { get; }
// The algorithm used to compute the hash.
public string Algorithm { get; }
// The hex-encoded hash of the running app (APK/AAB).
public string Hash { get; }
}
- FailedToRetrieveData: The hash could not be read. The other values are not valid.
- Algorithm: Which hash method was used. See the table below.
- Hash: The hash text of the whole app.
Lifecycle and timing
The monitor calculates the hash once, when it starts. It then sends one AndroidHashStatus. If the calculation fails, it still sends a status, with FailedToRetrieveData set to true.
Configuration
The hash method is set in Project Settings, not on the component. See Hash algorithm below.
Development builds
Verify development builds is off by default. While it is off, the check skips development builds and the Editor. Turn it on while you test.

Turn on Verify development builds to also check development builds and the Editor.
Supported platforms
Android only.
Requirements
Android 4.4 (API level 19) or newer.
How to use
Add AndroidPackageHashMonitor as a child of the AntiCheat-Monitor. Choose the hash method in Project Settings. Pair the monitor with AndroidPackageTamperingDetector.
Add the component
Add AndroidPackageHashMonitor from GUPS.AntiCheat.Monitor.Android. A child of the monitor is the best place.

Add the AndroidPackageHashMonitor component.
Hash algorithm
AntiCheat can use these methods:
| Method | Notes |
|---|---|
| None | No hash is calculated |
| MD5 | Not recommended |
| SHA1 | Not recommended |
| SHA256 | Recommended |
| SHA384 | Stronger than SHA-256 |
| SHA512 | Stronger than SHA-256 |
Open Edit > Project Settings > GuardingPearSoftware > AntiCheat. Go to Android - App Hash - Settings. Turn on Verify app hash and pick a method. SHA-256 is the recommended choice.

Hash settings.
Read the status in code
You can also listen yourself. Subscribe returns an IDisposable. Dispose it when you want to stop.
using System;
using GUPS.AntiCheat.Core.Watch;
using GUPS.AntiCheat.Monitor.Android;
using UnityEngine;
public class AndroidHashStatusLogger : MonoBehaviour, IObserver<IWatchedSubject>
{
private void Start()
{
var monitor = GetComponentInChildren<AndroidPackageHashMonitor>();
monitor.Subscribe(this);
}
public void OnNext(IWatchedSubject subject)
{
if (subject is AndroidHashStatus status)
{
if (status.FailedToRetrieveData)
{
Debug.LogWarning("Could not calculate the app hash.");
return;
}
Debug.Log($"App hash ({status.Algorithm}): {status.Hash}");
}
}
public void OnError(Exception error) { }
public void OnCompleted() { }
}
Detect a changed app file
To compare the hash with the one you shipped, use the Android package tampering detector.