YinkoShield

Knowledge Center / Mobile runtime attacks / mobile runtime attacks · 2026·01

Root cloaking — hiding root state from in-app checks

Root cloaking is the family of techniques that present a clean device profile to in-app integrity probes while the device is, in fact, rooted. Magisk's Hide (legacy) and DenyList (current) hide the rooted state from heuristic checks and from many platform-level probes. They do not, and cannot, hide the rooted state from hardware-backed attestation — the chip signs the bootloader state, and the bootloader was unlocked.

[ root cloaking — what each layer still sees ] in-app heuristic probe checks: /system/bin/su · ro.debuggable prop · Magisk paths · BusyBox · build tags vs. Magisk Hide / DenyList: defeated · the probes return clean values Play Integrity DEVICE / STRONG checks: device profile match · CTS-passing · for STRONG, hardware-backed verdict vs. Magisk DenyList + custom profile: partially defeated for DEVICE · STRONG usually fails hardware attestation · RootOfTrust checks: TEE-signed RootOfTrust (verifiedBootKey, verifiedBootState, deviceLocked) vs. cloaking: not defeated · the bootloader unlock is signed by the chip substrate signal: device.integrity { verified_boot_state · device_locked · root_of_trust_intact }
Root cloaking defeats heuristic probes; it usually defeats Play Integrity DEVICE; it does not defeat hardware-backed attestation, which reads the bootloader state directly from the chip.

1. Mechanism

Magisk’s DenyList [1] is the modern packaging of root cloaking on Android (Magisk Hide was removed in Magisk v24, January 2022; the DenyList + Zygisk + optional Shamiko stack replaced it). It maintains a list of packages from which Magisk’s modifications to the system should be hidden. When a process on the list starts, Magisk arranges for it to run in a mount namespace where:

  • The Magisk binary is not visible in /proc/<pid>/maps.
  • Magisk-installed paths (the randomised su path under /data/adb on modern Magisk; the module directories) do not appear when enumerated by the target.
  • System properties Magisk normally modifies are presented with their original values to the target.
  • The Magisk daemon socket is renamed at random and hidden from the target’s view of the filesystem.

The effect is that an in-app heuristic probe — checking for an su path, reading ro.debuggable, listing /data/adb/modules, calling Runtime.exec("which su") — sees a clean device. The probe is not lying; the platform genuinely returns the clean values to that process’s view.

2. Where in the runtime it operates

DenyList is a userspace mechanism: the magiskd daemon and Zygisk (a Zygote-injected runtime) cooperate to give denylisted processes an isolated mount namespace that does not contain Magisk’s bind-mounted overlays. There is no kernel module on modern Magisk and no syscall interception — the isolation is at the VFS / mount-namespace layer. Because the denylisted process sees an unmodified namespace, libc-level filesystem and property probes that route through the standard mount table return clean values; many libc-level checks therefore fail to detect the rooted state. (Sufficiently well-targeted detection — checking for SELinux context drift, parent-process anomalies, or attestation-state mismatch — can still surface signal.)

What DenyList cannot reach: the Trusted Execution Environment. The TEE runs in a separate execution context and is not addressable by code running in the Linux kernel space. When the TEE signs an attestation that includes the RootOfTrust block [2] — verifiedBootKey, verifiedBootState, deviceLocked, verifiedBootHash — those values come from the chip’s view of the boot chain. The chip knows whether the bootloader was unlocked. Magisk cannot rewrite that.

3. Which checkpoints it bypasses

  • In-app heuristic probes. Defeated for most file / property / process probes that route through the standard filesystem view; defeated for Runtime.exec("which su") and similar shell-out checks. Probes that look at SELinux context, parent-process anomalies, or attestation-state mismatch can still surface signal.
  • MEETS_DEVICE_INTEGRITY. Often defeated when DenyList is paired with a current device-profile workaround. Google iterates against this; the workaround is a moving target.
  • MEETS_STRONG_INTEGRITY. Generally not defeated [3]. This verdict requires hardware-backed evaluation, which reads the RootOfTrust block.
  • Android Key Attestation. Not defeated. The chain validates against Google and OEM intermediate roots, but the embedded RootOfTrust block declares the unlocked bootloader, and an operator that checks verifiedBootState != Verified rejects the device.

4. Which signals make it observable

device.integrity. The Trusted Runtime Primitive includes the hardware-attestation chain (where available) on each Evidence Token, with the RootOfTrust block decoded and surfaced as discrete fields. The substrate also collects multi-layered heuristic probes — but treats them as supporting evidence, not as authority. The authority is the chip-signed RootOfTrust.

5. Evidence Token shape when observed

The following example is illustrative; field names, type values, and schema are defined in YEI-001 §4 (available through the spec-access process).

{
  "ev": [{
    "ts":   "2026-06-15T10:23:14Z",
    "class": "device.integrity",
    "type":  "root_of_trust.read",
    "data": {
      "verified_boot_state": "Unverified",
      "device_locked":       false,
      "verified_boot_key":   "f8:23:…:ce",
      "heuristic_probes": {
        "su_binary_present": false,
        "magisk_paths_visible": false,
        "comment": "probes clean — but RootOfTrust says unlocked"
      }
    }
  }]
}

The discrepancy between the (cloaked) heuristic probes and the (uncloaked) RootOfTrust is itself a useful signal — and the discrepancy is what Execution Evidence Infrastructure (EEI) — the device-identity infrastructure layer for banking and payments — surfaces in the signed evidence record.

6. Cross-references

7. External references

[1] Magisk. User documentation — DenyList. topjohnwu.github.io/Magisk/install.html. Cited 2026-01-28.

[2] AOSP. Keymaster Tag specification — RootOfTrust. source.android.com/docs/security/features/keystore/tags. Cited 2026-01-28.

[3] Google. Play Integrity STRONG verdict requirements. developer.android.com/google/play/integrity/verdicts-and-remediation. Cited 2026-01-28.