Mon application a une certaine fonctionnalité qui ne fonctionnera que sur un appareil où root est disponible. Plutôt que de voir cette fonctionnalité échouer lorsqu'elle est utilisée (puis afficher un message d'erreur approprié à l'utilisateur), je préférerais avoir la possibilité de vérifier en silence si la racine est disponible en premier, et sinon, masquer les options respectives en premier lieu .
Y a-t-il un moyen de faire cela?
Réponses:
Voici une classe qui vérifiera la racine de l'une des trois manières suivantes.
la source
su
binaire sans être rooté.Si vous utilisez déjà Fabric / Firebase Crashlytics, vous pouvez appeler
Voici l'implémentation actuelle de cette méthode:
la source
La bibliothèque RootTools propose des méthodes simples pour vérifier la racine:
Référence
la source
Dans mon application, je vérifiais si le périphérique était enraciné ou non en exécutant la commande "su". Mais aujourd'hui, j'ai supprimé cette partie de mon code. Pourquoi?
Parce que mon application est devenue un tueur de mémoire. Comment? Permettez-moi de vous raconter mon histoire.
Il y avait quelques plaintes que mon application ralentissait les appareils (bien sûr, je pensais que cela ne pouvait pas être vrai). J'ai essayé de comprendre pourquoi. J'ai donc utilisé MAT pour obtenir des vidages de tas et analyser, et tout semblait parfait. Mais après avoir relancé mon application à plusieurs reprises, je me suis rendu compte que l'appareil devenait vraiment plus lent et l'arrêt de mon application ne le rendait pas plus rapide (à moins que je ne redémarre l'appareil). J'ai à nouveau analysé les fichiers de vidage alors que l'appareil est très lent. Mais tout était toujours parfait pour le fichier de vidage. Ensuite, j'ai fait ce qui devait être fait au début. J'ai énuméré les processus.
Surprize; il y avait de nombreux processus pour mon application (avec la balise de processus de mon application au manifeste). Certains d'entre eux étaient des zombies, d'autres non.
Avec un exemple d'application qui a une seule activité et exécute simplement la commande "su", je me suis rendu compte qu'un processus zombie était créé à chaque lancement d'application. Au début, ces zombies allouent 0 Ko, mais il se passe quelque chose et les processus zombies contiennent presque les mêmes Ko que le processus principal de mon application et ils sont devenus des processus standard.
Il existe un rapport de bogue pour le même problème sur bugs.sun.com: http://bugs.sun.com/view_bug.do?bug_id=6474073 cela explique si la commande n'est pas trouvée, des zombies vont être créés avec la méthode exec () . Mais je ne comprends toujours pas pourquoi et comment peuvent-ils devenir des processus standard et contenir des Ko importants. (Cela ne se produit pas tout le temps)
Vous pouvez essayer si vous le souhaitez avec l'exemple de code ci-dessous;
Méthode d'exécution de commande simple;
Pour résumer; Je n'ai aucun conseil à vous donner pour déterminer si l'appareil est enraciné ou non. Mais si j'étais vous, je n'utiliserais pas Runtime.getRuntime (). Exec ().
Au fait; RootTools.isRootAvailable () provoque le même problème.
la source
Bon nombre des réponses énumérées ici ont des problèmes inhérents:
La bibliothèque RootTools de Stericson semble rechercher la racine plus légitimement. Il dispose également de nombreux outils et utilitaires supplémentaires, je le recommande vivement. Cependant, il n'y a aucune explication sur la façon dont il vérifie spécifiquement la racine, et il peut être un peu plus lourd que la plupart des applications n'en ont vraiment besoin.
J'ai créé quelques méthodes utilitaires qui sont vaguement basées sur la bibliothèque RootTools. Si vous souhaitez simplement vérifier si l'exécutable "su" se trouve sur le périphérique, vous pouvez utiliser la méthode suivante:
Cette méthode parcourt simplement les répertoires répertoriés dans la variable d'environnement "PATH" et vérifie s'il existe un fichier "su" dans l'un d'eux.
Afin de vraiment vérifier l'accès root, la commande "su" doit être exécutée. Si une application comme SuperUser est installée, à ce stade, elle peut demander un accès root, ou si son déjà accordé / refusé un toast peut être affiché indiquant si l'accès a été accordé / refusé. Une bonne commande à exécuter est "id" afin que vous puissiez vérifier que l'ID utilisateur est bien 0 (root).
Voici un exemple de méthode pour déterminer si l'accès root a été accordé:
Il est important de tester l'exécution de la commande "su" car certains émulateurs ont l'exécutable "su" préinstallé, mais ne permettent à certains utilisateurs d'y accéder que le shell adb.
Il est également important de vérifier l'existence de l'exécutable "su" avant d'essayer de l'exécuter, car Android est connu pour ne pas disposer correctement des processus qui tentent d'exécuter des commandes manquantes. Ces processus fantômes peuvent augmenter la consommation de mémoire au fil du temps.
la source
Mise à jour 2017
Vous pouvez le faire maintenant avec l' API Google Safetynet . L'API SafetyNet fournit l'API d'attestation qui vous aide à évaluer la sécurité et la compatibilité des environnements Android dans lesquels vos applications s'exécutent.
Cette attestation peut aider à déterminer si l'appareil particulier a été falsifié ou modifié d'une autre manière.
L'API d'attestation renvoie une réponse JWS comme celle-ci
L'analyse de cette réponse peut vous aider à déterminer si le périphérique est enraciné ou non
Vous pouvez le faire côté client mais l'analyse de la réponse côté serveur est recommandée. Une architecture client-serveur de base avec une API de filet de sécurité ressemblera à ceci: -
la source
La vérification des racines au niveau Java n'est pas une solution sûre. Si votre application a des problèmes de sécurité à exécuter sur un appareil rooté, veuillez utiliser cette solution.
La réponse de Kevin fonctionne à moins que le téléphone ne dispose également d'une application comme RootCloak. De telles applications ont une API Handle over Java une fois que le téléphone est enraciné et elles se moquent de ces API pour renvoyer le téléphone n'est pas enraciné.
J'ai écrit un code de niveau natif basé sur la réponse de Kevin, cela fonctionne même avec RootCloak! De plus, cela ne provoque aucun problème de fuite de mémoire.
Dans votre code Java, vous devez créer la classe wrapper RootUtils pour effectuer les appels natifs
la source
http://code.google.com/p/roottools/
Si vous ne souhaitez pas utiliser le fichier jar, utilisez simplement le code:
Le programme essaiera de trouver le dossier su:
Exemple:
la source
checkRootMethod4()
avec la réponse de Kevin .== true
à un booléen, il n'ajoute rien et n'a pas l'air bien.if (isRooted())
vérifiez au lieu d'écrire explicitement vrai. Il est préférable de suivre les modèles d'écriture de codeAu lieu d'utiliser isRootAvailable (), vous pouvez utiliser isAccessGiven (). Directement à partir du wiki RootTools :
Référence
la source
Certaines versions modifiées utilisées pour définir la propriété système
ro.modversion
à cet effet. Les choses semblent avoir évolué; ma construction de TheDude il y a quelques mois a ceci:L'émulateur du SDK 1.5 d'autre part, exécutant l'image 1.5, a également la racine, est probablement similaire à Android Dev Phone 1 (que vous voulez probablement autoriser) et a ceci:
En ce qui concerne les constructions de vente au détail, je n'en ai pas sous la main, mais diverses recherches sous
site:xda-developers.com
sont informatives. Voici un G1 aux Pays-Bas , vous pouvez voir qu'ilro.build.tags
n'en a pastest-keys
, et je pense que c'est probablement la propriété la plus fiable à utiliser.la source
RootBeer est une bibliothèque Android de vérification de racine par Scott et Matthew. Il utilise diverses vérifications pour indiquer si le périphérique est enraciné ou non.
la source
Je suggère d'utiliser du code natif pour la détection des racines. Voici un exemple de travail complet .
Emballage JAVA :
Wrapper JNI (native-lib.c) :
constantes:
détections root du code natif:
la source
Voici mon code basé sur quelques réponses ici:
la source
Suite à la réponse de @Kevins, j'ai récemment découvert en utilisant son système, que le Nexus 7.1 revenait
false
pour les trois méthodes - Aucunewhich
commande, nontest-keys
etSuperSU
n'était pas installé dans/system/app
.J'ai ajouté ceci:
Ceci est légèrement moins utile dans certaines situations (si vous avez besoin d'un accès root garanti) car il est tout à fait possible que SuperSU soit installé sur des appareils qui n'ont pas d'accès SU.
Cependant, puisqu'il est possible d'avoir SuperSU installé et fonctionnel mais pas dans le
/system/app
répertoire, ce cas supplémentaire déracinera (haha) de tels cas.la source
la source
Deux idées supplémentaires, si vous souhaitez vérifier si un appareil est capable de rooter depuis votre application:
Runtime.getRuntime().exec()
/system/app/Superuser.apk
emplacementla source
L'utilisation de C ++ avec le ndk est la meilleure approche pour détecter root même si l'utilisateur utilise des applications qui cachent sa racine telles que RootCloak. J'ai testé ce code avec RootCloak et j'ai pu détecter la racine même si l'utilisateur essayait de la cacher. Votre fichier cpp souhaite donc:
Et vous appellerez la fonction à partir de votre code java comme suit
la source
la source
Il existe une API d'attestation de filet de sécurité des services Google Play par laquelle nous pouvons évaluer l'appareil et déterminer s'il est enraciné / falsifié.
Veuillez parcourir ma réponse pour traiter les appareils enracinés:
https://stackoverflow.com/a/58304556/3908895
la source
Oubliez tout ce qui détecte les applications root et les binaires su. Recherchez le processus du démon racine. Cela peut être fait à partir du terminal et vous pouvez exécuter des commandes de terminal dans une application. Essayez cette doublure.
Vous n'avez pas non plus besoin de l'autorisation root pour y parvenir.
la source
En effet, c'est une question intéressante et jusqu'à présent, personne n'a mérité de récompense. J'utilise le code suivant:
Le code n'est certainement pas à l'épreuve des balles, car le réseau peut ne pas être disponible, vous obtenez donc une exception. Si cette méthode retourne vrai, alors 99% vous pouvez être sûr, sinon seulement 50% que non. L'autorisation de mise en réseau peut également gâcher la solution.
la source
En utilisant ma bibliothèque sur rootbox , c'est assez facile. Vérifiez le code requis ci-dessous:
la source