The Darwinium SDK detects signs where users have jailbroken (iOS) or rooted (Android) their devices.
What is Jailbreak / Root
The act of jailbreaking or rooting a device gives elevated system access, bypassing manufacturer restrictions:
- Allows custom apps, system modifications, and deeper control.
- May compromise security, block updates, or affect app compatibility.
As a result, you may wish to enforce a blocking policy, or limit features for rooted/jailbroken devices.
It is often a compliance requirement to block such devices too, especially for more sensitive or regulated services like financial services.
Prerequisites
Android
QUERY_ALL_PACKAGES Permission
Part of the Android root detection performs a package scan. That requires the following permission to be in AndroidManifest.xml
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />
The permission does not require user consent. Google sometimes has higher scrutiny when app requesting it, but it is explicitly permitted and justified for integrity and security use cases, which Darwinium falls under. It is especially true for sensitive applications involving financial services
Root / Jailbroken Boolean
profiling.android.system.is_jailbroken
profiling.ios.system.is_jailbroken
Darwinium supplies overall indicator for whether to treat the device as jailbroken or rooted.
Example rule/search:
profiling.ios.system.is_jailbroken = TRUE
Scanned Packages
profiling.android.scanned_packages
Result of package scan looking for existence of explicit rootkits eg. Magisk
Example value:
[ "ec.hirj"]
Example rule/search:
has(profiling.android.scanned_packages, "ec.hirj")
Frida Port
profiling.android.system.frida_port
Port scanning/interrogation for running Frida server in profiling.android.system.frida_port, eg.
"frida_port": 27042
Boot State
profiling.android.system.boot_state
Indicates the state of the boot loader. To first root the phone, one must unlock the boot loader (state orange), then load a new (rooted OS). The boot loader can then be locked again (state green).
A state of orange tells us something, but green is far less revealing. If still orange, they have left it unlocked, and good chances it was unlocked to root the phone previously.
See: https://source.android.com/docs/security/features/verifiedboot/boot-flow
Example value
["boot_orange"]
Example rule/search
has(profiling.android.system.boot_state, "boot_orange")
Root Detection Signals
profiling.android.system.root_detection_signals
Array, providing signals as to why device is suspected as rooted:
Example value:
["root_su","root_native","root_magisk"]
Example rule/search
has(profiling.android.system.root_detection_signals, "root_magisk")
| Root Signal | Description |
|---|---|
| root_magisk | GitHub - topjohnwu/Magisk: The Magic Mask for Android. Signal tested, and persists even when Magisk Hide is used |
| root_su | ADB SU root inputs location . Checks for the presence of the su binary, typically used to elevate privileges. Su binaries may be renamed or hidden by root cloaking tools, bypassing detection. |
| root_props | Checks for dangerous properties (ro.debuggable and ro.secure) that indicate this may not be a genuine Android device. Can be bypassed if properties are reset or hidden by advanced root cloaking techniques. |
| root_native | We call through to our native root checker to run some of its own checks. Native checks are typically harder to cloak, so some root cloak apps just block the loading of native libraries that contain certain keywords. Checks for the presence of the su binary, typically used to elevate privileges. |
| root_rw | Verifies if the /system partition is mounted as read-write, a sign of rooting. Some newer root methods do not require RW access to the /system partition (e.g., systemless root). |
| root_test | Verifies if the device's firmware is signed with Android's test keys, which it would be on AOSP or certain emluators. Only detects if test keys are used, and may miss rooted devices using production keys. Some cheaper device builds may come out the factory misconfigured without proper production keys |
| root_pda | Checks build properties and device identifiers associated with non-standard or unofficial firmware, such as custom ROMs or carrier-modified builds. Devices flashed with unofficial firmware often exhibit anomalous PDA (Product, Device, Area) version strings or build fingerprints that deviate from the manufacturer's expected values, which can be a strong indicator of a modified or rooted device. |
| root_rma | Needs QUERY_ALL_PACKAGES permission Checks if any apps for managing root access (like SuperSU or Magisk) are installed. May not detect newly developed or less popular root management apps. |
| root_cloak | Needs QUERY_ALL_PACKAGES permission. Scans for the presence of known root-cloaking applications (such as RootCloak or Magisk Hide) that are specifically designed to mask root status from detection. These tools intercept system calls and modify return values to hide rooting artifacts. Detection can be bypassed if the cloaking app itself is disguised under an unknown package name or if multiple cloakers are used in combination |
| root_busy | Needs QUERY_ALL_PACKAGES permission. BusyBox combines tiny versions of many common UNIX utilities into a single small executable. It provides replacements for most of the utilities you usually find in GNU fileutils, shellutils, etc. Not all rooted devices use BusyBox, and some device manufacturers may leave busybox on the ROM. |