Skip to content

Instantly share code, notes, and snippets.

@stefanhoth
Last active August 29, 2015 14:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stefanhoth/d52cd6cb2174bf6e395d to your computer and use it in GitHub Desktop.
Save stefanhoth/d52cd6cb2174bf6e395d to your computer and use it in GitHub Desktop.
How to detect if an app is launched on a potentially rooted phone in an non-invasive way. It could be improved by checking existence of known super user apk in the package manager and certain build tags of the ROM.
package com.yourapp;
import java.io.File;
public final class RootStatus {
private static RootStatus instance;
private final boolean rooted;
private RootStatus(final boolean rooted) {
this.rooted = rooted;
}
private static synchronized RootStatus getInstance() {
if (instance == null) {
final boolean rooted = hasSuExecutable();
instance = new RootStatus(rooted);
}
return instance;
}
private static boolean hasSuExecutable() {
return binaryExists("su");
}
private static boolean binaryExists(final String binaryName) {
final String[] places = {"/sbin/", "/system/bin/", "/system/xbin/", "/data/local/xbin/",
"/data/local/bin/", "/system/sd/xbin/", "/system/bin/failsafe/", "/data/local/"};
for (final String where : places) {
if (new File(where, binaryName).exists()) {
return true;
}
}
return false;
}
public static boolean isRooted() {
return getInstance().rooted;
}
}
package com.yourapp;
// imports
public class YourActivity extends Activity {
public void onCreate(Bundle savedInstance) {
if(Rootstatus.isRooted() ){
// OH NO!
} else {
// All good.
}
}
}
@cgollner
Copy link

cgollner commented Mar 5, 2015

Did you try this on Lollipop? Doing File.exists() doesn't work on some system files, even if those have files have chmod 777. Only works if you are using a rooted process.

@ChristophPech
Copy link

You can easily circumvent this kind of root detection by simply replacing the File.exists() method with xposed.

findAndHookMethod("java.io.File", lpparam.classLoader, "exists", new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        if (param.thisObject == null) {return;}
        File f = (File) param.thisObject;
        String sName = f.getPath();
        if (!sName.equals("/system/app/Superuser.apk") &&
                !sName.endsWith("/su"))
            return;
        param.setResult(false);
    }
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment