If you want to detect the busybox binary in your app you can
use checkForBinary(BINARY_BUSYBOX) to detect it alone, or as part of the
complete root detection method:
[Link]();
Root Beer Checks
flutter_jailbreak_detection
import 'package:flutter_jailbreak_detection/flutter_jailbreak_detection.dart';
bool jailbroken = await [Link];
bool developerMode = await [Link]; // android only.
1. SU Directory / file / dangerous Apk Exists
2. isPathExist("su")
3. isHaveReadWritePermission - for SU
4. isHaveRootManagementApps - whether there packages installed or
exists
5. isHaveDangerousProperties
6. isHaveRootHideApps
7. DebuggerDetector
When detecting root access on an Android device, one common method is to check for the
presence of certain files or directories that are typically associated with root access. Here's a
list of some of the commonly checked root files or directories:
1. su binary locations:
o /system/bin/su
o /system/xbin/su
o /sbin/su
These locations are where the su binary (Superuser) is often found on rooted
o
devices. Checking for the existence of any of these files can indicate root
access.
2. Superuser/SuperSU app directories:
o /system/app/[Link]
o /system/app/SuperSU/
These directories may contain files related to Superuser management apps like
o
SuperSU. Checking for the presence of these files can also indicate root
access.
3. BusyBox binary:
o /system/xbin/busybox
BusyBox is often installed on rooted devices to provide additional Unix
o
utilities. Checking for the existence of BusyBox binaries can be a sign of root
access.
4. Magisk related files:
o /sbin/.magisk
o /sbin/magisk
Magisk is a popular root method that modifies the boot image. Checking for
o
directories or files related to Magisk can indicate root access.
5. Xposed framework directories:
o /data/data/[Link]/
oXposed Framework requires root access and modifications to the system.
Checking for directories related to Xposed can indicate root access.
6. Custom recovery directories:
o /system/recovery-from-boot.p
oThis file can indicate that a custom recovery has been flashed on the device,
which is often done on rooted devices.
7. Read-only system partition remounted as writable:
o Check if the system partition (/system) is mounted as read-write (rw) instead
of read-only (ro). Rooted devices often allow modification of the system
partition.
These files and directories are commonly used for root detection because they are indicative
of modifications made to the Android system that typically require root privileges. However,
it's important to note that determined users can hide or modify these indicators, so root
detection should be part of a broader security strategy rather than the sole method of ensuring
app security.
Blocking and detecting of the following applications
Detecting and bypassing root detection in Android apps is a cat-and-mouse
game between developers trying to secure their apps and users attempting
to gain root access. Here are some common applications and tools that users
may employ to bypass root detection:
1. **Magisk Manager**:
- Magisk is a popular tool for rooting Android devices, and Magisk Manager
is used to manage root permissions and modules. Users often employ Magisk
Hide feature to hide root status from apps.
2. **SuperSU**:
- SuperSU is another well-known root management app that allows users to
manage root permissions. It has features to hide root status from apps that
perform root detection.
3. **Xposed Framework**:
- Xposed Framework is used for modifying the behavior of Android at
runtime, including bypassing root detection methods implemented by apps.
4. **RootCloak**:
- RootCloak is an Xposed module specifically designed to hide root access
from other apps. It intercepts requests from apps and hides the fact that the
device is rooted.
5. **Hide My Root**:
- This app disguises root access from other apps by changing the responses
returned by the system when an app checks for root.
6. **Suhide**:
- Suhide is a Magisk module that attempts to hide the presence of root from
apps that perform root detection.
7. **Systemless Root**:
- Some users modify their devices with systemless root methods (like
Magisk) which can avoid detection by traditional root detection mechanisms.
8. **BusyBox**:
- BusyBox is a collection of Unix utilities often installed on rooted devices. It
can be used to perform various operations, including hiding root status.
9. **Custom ROMs and Kernels**:
- Users may install custom ROMs or kernels that either hide root status or
provide additional features to bypass root detection.
10. **Virtualization**:
- Some users run apps in a virtualized environment (like Shelter, Island, or
VMOS) where the primary environment is not rooted, effectively bypassing
root detection.
It's important to note that the effectiveness of these methods can vary
depending on the app's implementation of root detection and the
sophistication of the root-hiding technique used by the user. Developers
looking to secure their apps against rooted devices should consider
implementing multiple layers of security checks beyond simple root
detection, such as tamper detection and integrity verification.
While there is no way to know whether the device is rooted with
100% certainty, you can use the CN1JailbreakDetect cn1lib to to
make a good guess.
This cn1lib acts as a thin wrapper around the RootBeer Android
library, and DTTJailbreakDetection iOS library, which employ
heuristics to determine whether the device has likely been
jailbroken.
Example
package [Link];
import [Link];
import static [Link].*;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class JailbreakDetectionSample {
private Form current;
private Resources theme;
public void init(Object context) {
// use two network threads instead of one
updateNetworkThreadCount(2);
theme = [Link]("/theme");
// Enable Toolbar on all Forms by default
[Link](true);
// Pro only feature
[Link](true);
addNetworkErrorListener(err -> {
// prevent the event from propagating
[Link]();
if([Link]() != null) {
Log.e([Link]());
}
[Link]();
[Link]("Connection Error", "There was a networking
error in the connection to " + [Link]().getUrl(),
"OK", null);
});
}
public void start() {
if(current != null){
[Link]();
return;
}
Form hi = new Form("Jailbreak Detection", BoxLayout.y());
Button detect = new Button("Detect Jailbreak");
[Link](evt->{
if ([Link]()) {
if ([Link]()) {
[Link]("Jailbroken","This device is
jailbroken", new Command("OK") );
} else {
[Link]("Not Jailbroken", "Probably not
jailbroken. But can't be 100% sure.", new Command("OK"));
}
} else {
[Link]("No Idea", "No support for jailbreak
detection on this device.", new Command("OK"));
}
});
[Link](detect);
[Link]();
}
public void stop() {
current = getCurrentForm();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = getCurrentForm();
}
}
public void destroy() {
}
Copy
Tip:
This sample is part of the Codename One samples project, and can be run
directly from the Codename One SampleRunner.
Discussion
The CN1JailbreakDetect provides two useful static methods for
jailbreak detection:
1. isJailbreakDetectionSupported() – This checks if the jailbreak
detection is even supported on this platform.
2. isJailBroken() – This checks if the device is jailbroken. If detection
is not supported, then this will always return false.
Currently jailbreak detection is only supported on Android and iOS.
/** @author Kevin Kowalewski */
public class RootUtil {
public static boolean isDeviceRooted() {
return checkRootMethod1() || checkRootMethod2() || checkRootMethod3();
}
private static boolean checkRootMethod1() {
String buildTags = [Link];
return buildTags != null && [Link]("test-keys");
}
private static boolean checkRootMethod2() {
String[] paths = { "/system/app/[Link]", "/sbin/su", "/system/bin/su",
"/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su",
"/system/bin/failsafe/su", "/data/local/su", "/su/bin/su"};
for (String path : paths) {
if (new File(path).exists()) return true;
}
return false;
}
private static boolean checkRootMethod3() {
Process process = null;
try {
process = [Link]().exec(new String[] { "/system/xbin/which",
"su" });
BufferedReader in = new BufferedReader(new
InputStreamReader([Link]()));
if ([Link]() != null) return true;
return false;
} catch (Throwable t) {
return false;
} finally {
if (process != null) [Link]();
}
}
}
If you are already using Fabric/Firebase Crashlytics you can call
[Link](context)
This is the current implementation of that method:
public static boolean isRooted(Context context) {
boolean isEmulator = isEmulator(context);
String buildTags = [Link];
if (!isEmulator && buildTags != null && [Link]("test-keys")) {
return true;
} else {
File file = new File("/system/app/[Link]");
if ([Link]()) {
return true;
} else {
file = new File("/system/xbin/su");
return !isEmulator && [Link]();
}
}
}
public static boolean isEmulator(Context context) {
String androidId = [Link]([Link](), "android_id");
return "sdk".equals([Link]) || "google_sdk".equals([Link]) ||
androidId == null;
}
android - Determine if running on a rooted device - Stack Overflow
How to detect Jailbroken or Rooted device and hide sensitive data in background?
([Link])
GitHub - shannah/CN1JailbreakDetect: Codename One library to detect if devices if
rooted/jailbroken
How to Implement Root Detection in Android? | Indusface
GitHub - apkunpacker/MagiskDetection: Collection of Some Publically Available POC Apps to
Detect Root/Magisk presence.
[Link]
[Link]