Skip to content

Repository files navigation

Rootect

Rootect

Environment-integrity evidence for Android apps.

Root, runtime instrumentation, repackaging, debuggers and emulators — reported as evidence your app can weigh, not a verdict it has to accept.

License API Dependencies

The Android library has no third-party dependencies — the Kotlin standard library and nothing else. No permissions. No Google Play requirement. minSdk 24.

implementation("io.github.rootect:rootect-core:1.0.0")
val report = Rootect.analyze(context)

report.risk      // SAFE | LOW | MEDIUM | HIGH | CRITICAL
report.score     // 0..100
report.signals   // the evidence

What it looks for

Root Magisk, KernelSU, APatch — artefacts, mounts, and kernel-side probes
Instrumentation Frida, objection, Xposed / LSPosed, and inline hooks in our own code
App integrity Repackaging, resigning, debuggable builds, unexpected installers
Environment Unlocked bootloader, permissive SELinux, emulators, debuggers
Hardware attestation A signed statement from the device's secure element, for your server to verify

Checks live in native code behind raw syscalls with no readable strings, because a check written in Kotlin can be switched off in a single line.

What it does not do

Rootect runs inside your app, on a device the attacker may own. No on-device check survives an attacker with enough privilege, and any library claiming otherwise is overselling. What Rootect does is raise the cost of a bypass from trivial to genuinely difficult, and give you one signal that does not depend on the device being honest:

val challenge = api.requestChallenge()              // from your server, used once
val chain = RootectAttestation.chain(challenge)     // signed by secure hardware
api.submitAttestation(challenge, chain, Rootect.analyze(context)) // server gates on the chain

The signing key normally stays in hardware. Your server validates the chain, revocation, freshness and app identity before using it as evidence. How it works, and how to verify it →

Honest limits

  • Actively hidden root (DenyList + Shamiko) defeats the filesystem signals
  • isRooted can read false on a rooted device — use risk or score, and see scoring.md
  • Attestation can be forged with leaked hardware keys; revocation checking catches the known ones
  • Rooted is not the same as malicious, and blocking those users is a product decision with a real cost

Every signal is documented with what defeats it in signals.md, including three ideas that were built, measured, and did not work.

Documentation

integration.md Full API, configuration, common mistakes
attestation.md Hardware-backed evidence and server verification
signals.md Every signal, what it catches, and its limits
scoring.md How signals become a 0–100 score
threat-model.md What Rootect can and cannot promise

Sample

./gradlew :sample:installDebug

A live dashboard of every signal plus a separate server-gated attestation card. The card fails closed when the verifier is unavailable; the local dashboard remains diagnostic only.

Building

Requires the Android NDK (28.2.13676358) and CMake. The Gradle daemon JVM is pinned by the project, so a clone provisions it automatically.

./gradlew :rootect-core:test                       # unit tests
./gradlew :rootect-core:connectedDebugAndroidTest  # instrumented, needs a device

Native code builds for arm64-v8a, armeabi-v7a and x86_64. The emulator ABI stays in that list deliberately — it is the false-positive control.

Per-distribution native diversity

The published AAR is necessarily identical for every Maven consumer. A company or fork that builds Rootect from source can give its native string obfuscation a distinct build seed without changing code:

./gradlew :rootect-core:generateRootectObfuscationSeed -q
./gradlew :rootect-core:assembleRelease --project-prop=rootect.obfuscationSeed=0xYOURSEED

The seed is a diversity input, not a secret. Keep it stable for reproducible builds or rotate it deliberately per release. Different seeds produce different native result tags and encrypted strings, making byte-for-byte patches less reusable across apps; they do not make an on-device detector impossible to reverse.

License

Apache 2.0

About

Root, Frida, Xposed, repackaging and emulator detection for Android — native checks that report evidence your app can weigh, not a verdict it has to accept. Zero third-party dependencies, no permissions, hardware-backed attestation.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages