363 Stimmen

Feststellen, ob ein gerootetes Gerät verwendet wird

Meine App hat eine bestimmte Funktionalität, die nur auf einem Gerät funktioniert, auf dem Root verfügbar ist. Anstatt diese Funktion bei der Verwendung fehlschlagen zu lassen (und dem Benutzer dann eine entsprechende Fehlermeldung anzuzeigen), würde ich eine Möglichkeit bevorzugen, zuerst stillschweigend zu prüfen, ob Root verfügbar ist, und wenn nicht, die entsprechenden Optionen von vornherein auszublenden.

Gibt es eine Möglichkeit, dies zu tun?

4voto

Sami Kanafani Punkte 11341

Die Verwendung von C++ mit dem ndk ist der beste Ansatz, um Root zu erkennen, selbst wenn der Benutzer Anwendungen verwendet, die seine Root verbergen, wie z. B. RootCloak. Ich habe diesen Code mit RootCloak getestet und war in der Lage, den Root zu erkennen, selbst wenn der Benutzer versucht, ihn zu verstecken. Ihre cpp-Datei würde also so aussehen:

#include <jni.h>
#include <string>

/**
 *
 * function that checks for the su binary files and operates even if 
 * root cloak is installed
 * @return integer 1: device is rooted, 0: device is not 
 *rooted
*/
extern "C"
JNIEXPORT int JNICALL

Java_com_example_user_root_1native_rootFunction(JNIEnv *env,jobject thiz){
const char *paths[] ={"/system/app/Superuser.apk", "/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"};

int counter =0;
while (counter<9){
    if(FILE *file = fopen(paths[counter],"r")){
        fclose(file);
        return 1;
    }
    counter++;
}
return 0;
}

Und Sie rufen die Funktion in Ihrem Java-Code wie folgt auf

public class Root_detect {

   /**
    *
    * function that calls a native function to check if the device is 
    *rooted or not
    * @return boolean: true if the device is rooted, false if the 
    *device is not rooted
   */
   public boolean check_rooted(){

        int checker = rootFunction();

        if(checker==1){
           return true;
        }else {
           return false;
        }
   }
   static {
    System.loadLibrary("cpp-root-lib");//name of your cpp file
   }

   public native int rootFunction();
}

4voto

Guardian Project Punkte 109

Zwei weitere Ideen, wenn Sie von Ihrer App aus prüfen wollen, ob ein Gerät Root-fähig ist:

  1. Prüfen Sie, ob das 'su'-Binary vorhanden ist: Führen Sie "which su" aus Runtime.getRuntime().exec()
  2. Suchen Sie die SuperUser.apk in /system/app/Superuser.apk Standort

3voto

android developer Punkte 111449

Basierend auf einigen der Antworten hier, habe ich sie zusammengeführt und auch eine Prüfung hinzugefügt, ob eine bekannte Root-Manager-App installiert ist:

fun isProbablyRooted(context: Context, alsoIncludeCheckingRootManagerApp: Boolean = false): Boolean {
    return hasRootManagerSystemApp(context) || (alsoIncludeCheckingRootManagerApp && hasRootManagerSystemApp(context))
}

fun hasRootManagerSystemApp(context: Context): Boolean {
    val rootAppsPackageNames = arrayOf("com.topjohnwu.magisk", "eu.chainfire.supersu", "com.koushikdutta.superuser", "com.noshufou.android.su", "me.phh.superuser")
    rootAppsPackageNames.forEach { rootAppPackageName ->
        try {
            context.packageManager.getApplicationInfo(rootAppPackageName, 0)
            return true
        } catch (e: Exception) {
        }
    }
    return false
}

fun hasSuBinary(): Boolean {
    return try {
        findBinary("su")
    } catch (e: Exception) {
        e.printStackTrace()
        false
    }
}

private fun findBinary(binaryName: String): Boolean {
    val paths = System.getenv("PATH")
    if (!paths.isNullOrBlank()) {
        val systemPlaces: List<String> = paths.split(":")
        return systemPlaces.firstOrNull { File(it, binaryName).exists() } != null
    }
    val places = arrayOf("/sbin/", "/system/bin/", "/system/xbin/", "/data/local/xbin/", "/data/local/bin/",
            "/system/sd/xbin/", "/system/bin/failsafe/", "/data/local/")
    return places.firstOrNull { File(it, binaryName).exists() } != null
}

manifestieren:

<queries>
    <package android:name="com.topjohnwu.magisk" />
    <package android:name="eu.chainfire.supersu" />
    <package android:name="com.koushikdutta.superuser" />
    <package android:name="com.noshufou.android.su" />
    <package android:name="me.phh.superuser" />
</queries>

Natürlich ist dies, wie alle anderen Lösungen auch, nur eine Vermutung. Benutzer können Magisk installieren, ohne dass das Gerät verwurzelt ist, zum Beispiel.

3voto

Wicaledon Punkte 568

Als letztes Vierteljahr 2021 habe ich heute versucht, SafetyNet in Bezug auf @HimanshiThakur 's Antwort zu verwenden. Aber ich bekam ein Problem und öffnete eine Frage in aquí . Immer noch keine Antwort.

Ich beschloss also, Folgendes zu verwenden RootBeer . Es funktioniert perfekt, aber wenn Magisk die Wurzel ausblendet, funktioniert es nicht.

Wenn Sie sich nicht um diesen Fall kümmern (und viele Bankanwendungen können dieses Problem auch nicht lösen), können Sie diese Schritte verwenden:

  1. Fügen Sie dies zu Gradle hinzu:

    implementation 'com.scottyab:rootbeer-lib:0.1.0'

  2. Verwenden Sie diese Zeilen:

    RootBeer rootBeer = new RootBeer(context); if (rootBeer.isRooted()) { //we found indication of root } else { //we didn't find indication of root }

2voto

ESSPEE Punkte 21
if [[ "`adb shell which su | grep -io "permission denied"`" != "permission denied" ]]; then
   echo "Yes. Rooted device."
 else
   echo "No. Device not rooted. Only limited tasks can be performed. Done."
    zenity --warning --title="Device Not Rooted" --text="The connected Android Device is <b>NOT ROOTED</b>. Only limited tasks can be performed." --no-wrap
fi

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X