WEBVTT

1
00:00:00.600 --> 00:00:06.150
Welcome. This tutorial explains how the library detects a rooted Android phone.

2
00:00:06.600 --> 00:00:12.150
We cover seven signals, from the S U binary to Magisk mounts and the bootloader.

3
00:00:12.600 --> 00:00:19.750
And we finish with what hiding tools like the Magisk DenyList do to them, observed on a real rooted phone.

4
00:00:21.367 --> 00:00:27.592
Root removes the Android app sandbox. Any process can read another app's private data.

5
00:00:28.042 --> 00:00:33.492
It lets malware, or an attacker, attach debuggers and inject code into your app.

6
00:00:33.942 --> 00:00:38.017
And with a writable system, it can plant persistent backdoors.

7
00:00:38.467 --> 00:00:42.442
So the library looks for root from seven independent angles.

8
00:00:44.067 --> 00:00:52.392
First, the root_su_binary signal. It builds a set of directories from a fixed list, plus every entry in the PATH variable.

9
00:00:52.842 --> 00:00:59.942
In each directory it looks for a file named su. It also checks for the legacy Superuser.apk.

10
00:01:00.392 --> 00:01:06.817
The su binary is what root apps call to elevate a process, so finding it is strong evidence.

11
00:01:07.267 --> 00:01:12.342
But Magisk can hide it from targeted apps, so the app's own view returns false.

12
00:01:13.967 --> 00:01:20.442
Second, root management apps. The check asks the package manager about sixteen known packages.

13
00:01:20.892 --> 00:01:27.967
They include Magisk, SuperSU, KernelSU, APatch, KingRoot, RootCloak, and the LSPosed manager.

14
00:01:28.417 --> 00:01:34.542
A root manager brokers root to other apps, so its presence means root can be handed to malware.

15
00:01:34.992 --> 00:01:44.667
Magisk can be installed under a randomised package name, which defeats any lookup by name. That is exactly what its hide Magisk app feature does.

16
00:01:46.267 --> 00:01:53.992
Third, root framework artifacts. Even when S U is hidden, the framework still has to mount its files into the system.

17
00:01:54.442 --> 00:02:01.367
The check reads the app's own mount table and flags mounts whose source is magisk, KSU, or APatch.

18
00:02:01.817 --> 00:02:10.867
It also tests legacy paths, but/data/adb is root-only, so on a modern install those paths look empty to the app.

19
00:02:11.317 --> 00:02:17.692
The mount check is the stronger one, and it only goes quiet when the framework unmounts itself for your app.

20
00:02:19.300 --> 00:02:27.275
Fourth, bootloader unlocked. This one does not look for root at all. It asks whether the phone can boot unverified software.

21
00:02:27.725 --> 00:02:34.900
It reads three boot properties: the verified boot state, the flash lock flag, and the vbmeta device state.

22
00:02:35.350 --> 00:02:42.725
Green and yellow do not fire, so a locked phone running GrapheneOS stays clean. Emulators are skipped.

23
00:02:43.175 --> 00:02:50.725
Root tools can rewrite those properties with resetprop, so hardware-backed key attestation is the real confirmation.

24
00:02:52.333 --> 00:03:00.283
Fifth, test keys. If the build tags contain test keys, the system image is not the manufacturer's verified build.

25
00:03:00.733 --> 00:03:09.958
Sixth, dangerous properties. A debuggable flag set to one, or secure set to zero, means an engineering build with root adb.

26
00:03:10.408 --> 00:03:18.758
Seventh, read-write system. Any of the system partitions mounted writable lets an attacker replace binaries and libraries.

27
00:03:19.208 --> 00:03:26.258
Modern Magisk is systemless and never remounts system writable, so this last one rarely fires on it.

28
00:03:27.867 --> 00:03:40.192
Here is a real rooted OnePlus running Magisk with no hiding. Four signals fire in about forty milliseconds: the bootloader, the S U binary, the root apps, and the Magisk files.

29
00:03:40.642 --> 00:03:49.917
Now turn on Zygisk and the DenyList. The S U binary and Magisk files signals disappear, because Magisk hides them from the app.

30
00:03:50.367 --> 00:03:56.492
But bootloader unlocked and root management apps still fire, so the status stays compromised.

31
00:03:56.942 --> 00:04:06.342
Hide the Magisk app and fake the boot properties, and those would go too. That is why the documentation says to pair this with server-side attestation.

32
00:04:07.967 --> 00:04:16.842
You can tune the bootloader signal once per app at build time. The default is compromised, which matches the Play Integrity device verdict.

33
00:04:17.292 --> 00:04:24.567
Report keeps it in the signals list but never lets it set the status by itself. Useful for developer phones.

34
00:04:25.017 --> 00:04:27.367
Off skips the check entirely.

35
00:04:27.817 --> 00:04:36.492
The runtime ignore option works on top. Relaxing any of this never hides root: the root signals still make the status compromised.

36
00:04:38.100 --> 00:04:44.625
Let us recap. One: root removes the sandbox, and the library checks it from seven angles.

37
00:04:45.075 --> 00:04:53.300
Two: look for the su binary, root apps, Magisk mounts, the bootloader state, test keys, properties, and a writable system.

38
00:04:53.750 --> 00:04:58.750
Three: hiding tools silence some of these, but rarely all of them at once.

39
00:04:59.200 --> 00:05:04.925
Four: pair the signals with the Google Play Integrity API for high-value flows.

40
00:05:06.533 --> 00:05:13.658
Thanks for watching. The checks live in IntegrityChecks.kt, and the setup guides are in the README.

41
00:05:14.108 --> 00:05:18.058
Next, watch the tamper, debugger, and emulator videos.
