Meu aplicativo tem uma certa funcionalidade que só funciona em um dispositivo em que a raiz está disponível. Em vez de fazer com que esse recurso falhe quando é usado (e depois mostre uma mensagem de erro apropriada para o usuário), prefiro verificar silenciosamente se o root está disponível primeiro e, se não, ocultar as opções respectivas em primeiro lugar .
Existe uma maneira de fazer isso?
Respostas:
Aqui está uma classe que verificará a raiz de três maneiras.
fonte
su
binário enquanto não estão enraizados.Se você já estiver usando o Fabric / Firebase Crashlytics, poderá ligar
Esta é a implementação atual desse método:
fonte
A biblioteca RootTools oferece métodos simples para verificar a raiz:
Referência
fonte
No meu aplicativo, eu estava verificando se o dispositivo está enraizado ou não, executando o comando "su". Mas hoje eu removi essa parte do meu código. Por quê?
Porque meu aplicativo se tornou um assassino de memória. Quão? Deixa-me contar-te a minha historia.
Houve algumas reclamações de que meu aplicativo estava desacelerando os dispositivos (é claro que pensei que isso não pode ser verdade). Eu tentei descobrir o porquê. Então, eu usei o MAT para obter despejos de pilha e analisar, e tudo parecia perfeito. Mas, após reiniciar o aplicativo muitas vezes, percebi que o dispositivo estava realmente ficando mais lento e a interrupção do aplicativo não o tornava mais rápido (a menos que eu reiniciasse o dispositivo). Analisei os arquivos de despejo novamente enquanto o dispositivo está muito lento. Mas tudo ainda estava perfeito para o arquivo de despejo. Então eu fiz o que deve ser feito primeiro. Eu listei processos.
Surpresa; havia muitos processos para meu aplicativo (com a tag de processo do aplicativo no manifesto). Alguns deles eram zumbis, outros não.
Com um aplicativo de amostra que possui uma única atividade e executa apenas o comando "su", percebi que um processo zumbi está sendo criado em cada inicialização do aplicativo. A princípio, esses zumbis alocam 0 KB, mas isso acontece e os processos zumbis mantêm quase os mesmos KBs que o processo principal do meu aplicativo e eles se tornaram processos padrão.
Existe um relatório de bug para o mesmo problema no bugs.sun.com: http://bugs.sun.com/view_bug.do?bug_id=6474073 isso explica se o comando não foi encontrado Os zumbis serão criados com o método exec () . Mas ainda não entendo por que e como eles podem se tornar processos padrão e conter KBs significativos. (Isso não está acontecendo o tempo todo)
Você pode tentar se quiser com o exemplo de código abaixo;
Método simples de execução de comandos;
Resumindo; Não tenho conselhos para você determinar se o dispositivo está enraizado ou não. Mas se eu fosse você, não usaria Runtime.getRuntime (). Exec ().
A propósito; RootTools.isRootAvailable () causa o mesmo problema.
fonte
Muitas das respostas listadas aqui têm problemas inerentes:
A biblioteca RootTools da Stericson parece estar verificando a raiz mais legitimamente. Ele também tem muitas ferramentas e utilitários extras, então eu recomendo. No entanto, não há explicação de como ele especificamente verifica a raiz e pode ser um pouco mais pesado do que a maioria dos aplicativos realmente precisa.
Eu criei alguns métodos utilitários que são vagamente baseados na biblioteca RootTools. Se você simplesmente deseja verificar se o executável "su" está no dispositivo, você pode usar o seguinte método:
Esse método simplesmente percorre os diretórios listados na variável de ambiente "PATH" e verifica se existe um arquivo "su" em um deles.
Para realmente verificar o acesso root, o comando "su" deve ser realmente executado. Se um aplicativo como o SuperUser estiver instalado, nesse momento, ele poderá solicitar acesso root ou se já foi concedido / negado um brinde, poderá ser mostrado indicando se o acesso foi concedido / negado. Um bom comando para executar é "id", para que você possa verificar se o ID do usuário é de fato 0 (raiz).
Aqui está um método de amostra para determinar se o acesso root foi concedido:
É importante testar a execução do comando "su" porque alguns emuladores têm o executável "su" pré-instalado, mas apenas permitem que certos usuários acessem o mesmo como o shell adb.
Também é importante verificar a existência do executável "su" antes de tentar executá-lo, porque se sabe que o Android não descarta adequadamente os processos que tentam executar os comandos ausentes. Esses processos fantasmas podem aumentar o consumo de memória ao longo do tempo.
fonte
Atualização 2017
Você pode fazer isso agora com a API do Google Safetynet . A API SafetyNet fornece API de atestado, que ajuda a avaliar a segurança e a compatibilidade dos ambientes Android nos quais seus aplicativos são executados.
Esse atestado pode ajudar a determinar se o dispositivo em particular foi violado ou modificado.
A API de atestado retorna uma resposta JWS como esta
A análise desta resposta pode ajudá-lo a determinar se o dispositivo está enraizado ou não
Você pode fazer isso no lado do cliente, mas é recomendável analisar a resposta no lado do servidor. Uma arquitetura básica de servidor cliente com API de rede de segurança terá a seguinte aparência: -
fonte
A verificação da raiz no nível do Java não é uma solução segura. Se o seu aplicativo tiver preocupações de segurança para executar em um dispositivo raiz, use esta solução.
A resposta de Kevin funciona, a menos que o telefone também tenha um aplicativo como o RootCloak. Esses aplicativos têm APIs de manipulação sobre Java, uma vez que o telefone está enraizado e eles zombam dessas APIs para retornar o telefone não está enraizado.
Eu escrevi um código de nível nativo com base na resposta de Kevin, ele funciona mesmo com o RootCloak! Também não causa problemas de vazamento de memória.
No seu código Java, você precisa criar a classe de wrapper RootUtils para fazer as chamadas nativas
fonte
http://code.google.com/p/roottools/
Se você não quiser usar o arquivo jar, use o código:
O programa tentará encontrar a pasta su:
Exemplo:
fonte
checkRootMethod4()
com Resposta de Kevin .== true
a um booleano, ele não adiciona nada e não parece bom.if (isRooted())
verifique em vez de escrever explicitamente true. O seu melhor para seguir padrões de escrita de códigoEm vez de usar isRootAvailable (), você pode usar isAccessGiven (). Direto do wiki do RootTools :
Referência
fonte
Algumas construções modificadas usadas para definir a propriedade do sistema
ro.modversion
para essa finalidade. As coisas parecem ter mudado; minha compilação do TheDude há alguns meses atrás:O emulador do SDK 1.5, por outro lado, executando a imagem 1.5, também possui raiz, provavelmente é semelhante ao Android Dev Phone 1 (que você provavelmente deseja permitir) e tem o seguinte:
Quanto às versões de varejo, não tenho uma em mãos, mas várias pesquisas abaixo
site:xda-developers.com
são informativas. Aqui está um G1 na Holanda , você pode ver quero.build.tags
não temtest-keys
, e acho que essa é provavelmente a propriedade mais confiável a ser usada.fonte
RootBeer é uma biblioteca Android de verificação de raiz de Scott e Matthew. Ele usa várias verificações para indicar se o dispositivo está enraizado ou não.
fonte
Sugiro usar código nativo para detecção de raiz. Aqui está um exemplo completo de trabalho .
Wrapper JAVA :
Wrapper JNI (native-lib.c) :
constantes:
detecções de raiz do código nativo:
fonte
Aqui está o meu código com base em algumas respostas aqui:
fonte
Após a resposta do @Kevins, descobri recentemente, enquanto usava o sistema, que o Nexus 7.1 estava retornando
false
para todos os três métodos - Semwhich
comando, nãotest-keys
eSuperSU
não foi instalado/system/app
.Eu adicionei isso:
Isso é um pouco menos útil em algumas situações (se você precisar de acesso root garantido), pois é completamente possível que o SuperSU seja instalado em dispositivos que não têm acesso à SU.
No entanto, como é possível ter o SuperSU instalado e funcionando, mas não no
/system/app
diretório, esse caso extra eliminará (haha) esses casos.fonte
fonte
Duas idéias adicionais, se você quiser verificar se um dispositivo é compatível com raiz do seu aplicativo:
Runtime.getRuntime().exec()
/system/app/Superuser.apk
localfonte
Usar C ++ com o ndk é a melhor abordagem para detectar raiz, mesmo que o usuário esteja usando aplicativos que ocultam sua raiz, como o RootCloak. Testei esse código com o RootCloak e consegui detectar a raiz mesmo que o usuário estivesse tentando ocultá-la. Portanto, seu arquivo cpp gostaria de:
E você chamará a função do seu código java da seguinte maneira
fonte
fonte
Existe a API do Safety Net Attestation dos serviços Google Play, pela qual podemos avaliar o dispositivo e determinar se ele está enraizado / violado.
Consulte a minha resposta para lidar com dispositivos enraizados:
https://stackoverflow.com/a/58304556/3908895
fonte
Esqueça tudo o que detecta aplicativos raiz e binários. Verifique o processo do daemon raiz. Isso pode ser feito no terminal e você pode executar comandos do terminal em um aplicativo. Experimente este one-liner.
Você também não precisa de permissão root para conseguir isso.
fonte
Na verdade, é uma pergunta interessante e até agora ninguém mereceu prêmio. Eu uso o seguinte código:
O código certamente não é à prova de balas, porque a rede pode não estar disponível e você recebe uma exceção. Se esse método retornar true, então 99% pode ter certeza, caso contrário, apenas 50% não. A permissão de rede também pode estragar a solução.
fonte
Usando minha biblioteca no rootbox , é bem fácil. Verifique o código necessário abaixo:
fonte