Detects Play Integrity Fix, PlayIntegrityFork, TrickyStore, and similar tampering modules on Android. Native C++ detection engine with a custom bytecode VM, runtime string obfuscation, and Kotlin UI.
- Play Integrity Fix -maps scan for PIF classes &
InMemoryDexClassLoaderDEX regions,custom.pif.prop/custom.pif.json, module dirs, known props - TrickyStore -
keybox.xml,target.txt,security_patch.txtunder/data/adb/tricky_store/, maps artifacts - Zygisk / Magisk / KernelSU / APatch -maps scan for zygisk libs (incl. ReZygisk, ZygiskNext, Shamiko, NoHello), env vars,
rwxpanomalies, module dirs - Root Hiders -mount namespace divergence, OverlayFS on
/system, SELinux context anomalies, elevated rwxp anonymous mapping count - Frida / Xposed -unix socket scan, maps scan for gadget libs, port 27042 check,
gmain/gum-js-loopthread names, parent process cmdline, Objection - Property Spoofing -cross-validation of
ro.build.fingerprintvsro.product.*, security patch vs kernel date, property read timing analysis - Bootloader -
ro.boot.verifiedbootstate,ro.boot.flash.locked,ro.boot.veritymode,vbmeta.device_state,ro.debuggable,ro.secure,sys.oem_unlock_allowed - Debuggers -
TracerPidfrom/proc/self/status,FLAG_DEBUGGABLE - APK Tampering -signing certificate hash pinned in native code
PIF runs as a Zygisk module and:
- Hooks
__system_property_read_callbackto spoof build properties (ro.build.fingerprint,ro.build.version.security_patch, etc.) - Injects
classes.dexat runtime intocom.google.android.gms.unstableviaInMemoryDexClassLoader - Uses reflection to modify
android.os.Buildfields and inject a customKeyStoreSpiprovider - TrickyStore extends this by modifying key attestation certificate chains using stolen/leaked keybox files
MainActivity.kt triggers the native check via JNI. The native engine runs in two phases:
- Debug/instrumentation checks run first (fail-fast):
isTraced(), Frida VM + port/thread scan, parent process check, debuggable flag - Tampering checks run in randomized order each time: Zygisk VM, PIF VM, mount namespace, OverlayFS, SELinux, bootloader props, APK signature, TrickyStore paths, property consistency
The VM-based checks (Frida, Zygisk, PIF) use a custom bytecode interpreter with XOR-obfuscated opcodes -harder to hook than direct function calls. Sensitive strings are base64+XOR encoded and only decoded at runtime.
The native function returns a bitmask -0 means clean, any set bit indicates a detection:
0x001 DEBUGGER 0x010 BOOTLOADER 0x100 ROOT_HIDER
0x002 FRIDA 0x020 SIGNATURE
0x004 ZYGISK 0x040 TRICKYSTORE
0x008 PIF 0x080 PROP_SPOOF
./gradlew assembleDebug # debug build
./gradlew assembleRelease # release build (requires signing config)
./gradlew test # run unit tests
./gradlew lintDebug # run lint checksRequires NDK r25+, Android Studio Hedgehog or later, SDK 35, Kotlin 2.0+.
If you build from source with your own signing key, update
EXPECTED_SIG_HASHinnative-lib.cpp. See CONTRIBUTING.md for how.
- Android 7.0+ (API 24)
See CONTRIBUTING.md.
| Name | GitHub |
|---|---|
| Ir0nByte | @IR0NBYTE |
GPL-3.0 -derivative works must stay open source.
This tool is for defensive security research. Use it only on devices you own or have permission to test.

