您现在的位置:首页 >> 绿色生活

干货 | 关于Android root绕过的学问,你知道多少?

时间:2023-04-17 12:17:59

续性:root可以胜过任何的硬件和民间一组织来对文档或概要资料透过加载、变愈来愈或删减(在系由统设计经常持续性的许可范围内);对可拒绝执行前提的拒绝执行、取消;对硬件电子系由统的填充、创建者和移除等;也可以对文档和概要资料透过属主和职责透过变愈来愈,以适当系由统设计管理的必需(因为root是系由统设计中会职责最低的合法持续性的硬件);root是胜过任何的硬件和民间一组织的,基于的硬件ID的职责前提的沙盒是封闭不住它的

除了监标定(test-keys(标定试版本)、release-keys(发表版本))系由统设计是不是标定试版本、监标定Root应用领域硬件的配置方向,纸制名(特有刷root应用领域硬件的纸制名称)是不是带有su、activity、BusyBox、supersu或superuser等词条之外,还有如下监标定法则:

检标定su号令是不是共存检标定近似于概要资料是不是共存su(或监标定是不是共存s职责的文档)可用which号令查询是不是共存su及早登记root职责拒绝执行busybox检标定Android属持续性(加载build.prop中会更为重要属持续性,如ro.build.tags和ro.build.type)检标定特定方向是不是有念过到职责(在Android系由统设计中会,有些概要资料是都是的硬件能够会面时的,例如/data、/system、/etc 等)检标定一时间边缘化的实时器监标定frida、xposed等hook构建的基本特征

在此前看来绝大多数的应用领域都是对侧面几个监标定法则一组合可用,甚至有很多只但会借助于其中会的一项或者两项。另之外,侧面的法则也不用囊括所有的确实,比如有些应用领域还但会监标定“Magisk”或者"Superuser"等是不是共存来透过Root监标定。回顾来话说,在此前边缘化的Root监标定就是对Root此后的Android有别于的一些基本特征透过有效性,如基本特征文档是不是共存、是不是共存不当、更为重要属持续性是不是被变愈来愈等等

补充知识: 1)标准文档职责

都是文档职责是往还过十位透过对此的,如所示

第一位都是的“ 文档” 类型,其确实的倍数有:-(文档)、d(概要资料)、b(块电子系由统)、l (link文档)、c (罗马字母字母电子系由统,如串口)、s(socket套接字)。

第2~4位对此文档归属于的职责第5~7位对此文档属一组的职责第8~10位对此其他的硬件和一组较强的职责

linux系由统设计内有档案有三种身为

u:仅有者(user,文档的属主)g:群一组 (group,文档的属主所在的一组,属一组)o:其他人(other,其它的的硬件)a:纸制括属主、属一组、其它的硬件(all,以上所有人)

2)rwx职责分设

文档或概要资料每三位用rwx对此煽动之亦然的职责倍数,其中会r倍数为4、w倍数为2、x倍数为1 ,可以可用chmod 对文档或概要资料透过职责愈来愈改。对于文档近似于的有下面职责:

r:念过职责,的硬件可以加载文档的具体内容内容,如用cat,more查询w:念过到职责,的硬件可以编辑文档x:该概要资料较强可以被系由统设计拒绝执行的职责

职责的分设有两种对此方的单:

职责倍数记法,如下:# chmod 777 file1大念过到倍数记法,如下:# chmod a+x file1

号令

结果

含义

chmod a-x myfile

rw- rw- rw-

出让所有的硬件拒绝执行职责

chmod og-w myfile

rw- r;还有 r;还有

出让同一组的硬件和其它的硬件的念过到职责

chmod g+w myfile

rw- rw- r;还有

赋予同一组的硬件念过到职责

chmod u+x myfile

rwx rw- r;还有

赋予文档属主拒绝执行职责

chmod go+x myfile

rwx rwx r-x

赋予同一组的硬件和其它的硬件拒绝执行职责

3)umask

在/etc/profile文档有umask倍数的当前分设,当前倍数为022,该倍数互换的是当前文档和概要资料创建者后的职责倍数:

概要资料的当前职责是:777-umask文档的当前职责是:666-umask

所以umask为022的完全,当前创建者的概要资料的职责是755 ,当前创建者的文档职责为644

4)特殊性职责

除了侧面的提到的rwx职责之外,除了念过取拒绝执行职责之外,系由统设计还有三个特殊性职责 s s t 职责(冒险位与可压缩位) 【强制位(s职责)和可压缩位(t职责)】,具体内容叙述如下:

职责

对文档的受到影响

对概要资料的受到影响

suid

以文档的从属概要资料身为拒绝执行,而非拒绝执行文档的的硬件

sgid

以文档从属一组身为拒绝执行

该概要资料中会创建者的煽动之亦然从新文档的从属一组与该概要资料的从属一组不同

sticky

对概要资料仅有念过到入职责的的硬件极其少可以删减其仅有的文档,不用删减其它的硬件所仅有的文档

这三个特殊性职责也可以用大念过到和数字对此,具体内容如下:

分设suid: chmodu+stestchmod u+s testchmodu+stest分设sgid:分设sgid:分设sgid: chmod g+s test分设sticky: $ chmod o+t testsuid:4sgid:2sticky:1

s即(SUID,Set UID)分设使文档在拒绝执行下一阶段较强文档持有者的职责,相当于临时仅有文档持有者的身为. 典型的文档是passwd. 如果一般的硬件拒绝执行该文档, 则在拒绝执行过程中会, 该文档可以授予root职责, 从而可以愈来愈改的硬件的加密

在一些特殊性完全但会来作特殊性职责位,如passwd号令,如果不用s职责,其他的硬件但会不用可用passwd号令变愈来愈自己的加密

# ls -l /usr/bin/passwd-rwSr-xr-x. 1 root root 27832 Jun 10 2014 /usr/bin/passwd

给一个增高了s s t 职责的示例:

# touch test# ll test-rw-r;还有r;还有. 1 root root 0 Aug 5 01:03 test# chmod 7777 test# ll test-rwsrwsrwt. 1 root root 0 Aug 5 01:03 test# su - usera

侧面由于增高了t职责,所以都是的硬件usera,可以往还文档念过到入和愈来愈改,不用删减文档

唯:

在分设s职责时文档属主、属一组必需先以分设煽动之亦然的x职责,否则s职责并能够正真有效期(c h m o d号令不透过必要的倍数得唯意持续性检标定,即使不分设x职责就分设s职责,chmod也不能报拢,当我们ls -l时看不到rwS,大念过到S话说明s职责未有效期)必需唯意的是特殊性职责是把双刃剑,很多棍子提可让者也但会利来作s 职责位,所以经常在匹配DS棍子时,我们但会用find匹配所有4777 和 6777文档;假如本来在该位上有x, 则这些都有徽标 (suid, sgid, sticky) 表明为小念过到大念过到 (s, s, t) ,否则,表明为大念过到大念过到 (S, S, T)还有一个大X职责,后面在ACL时也但会提到s或S(SUID,Set UID):可拒绝执行的文档搭配这个职责,立刻能得不到合法持续性,煽动之亦然存储该文档的持有者能可用的全部系由统设计资源。请唯意较强SUID职责的文档,黒客经常利用这种职责,以SUID配搭root帐号仅有者,无声无息地在系由统设计中会开扇后门,可让自此外可用。T或T(Sticky):/tmp和 /var/tmp概要资料可让所有的硬件不再存储文档,亦即每位的硬件皆仅有倍数得唯意的职责进入该概要资料,去上网、删减和移动文档

请唯意:BusyBox是很多标准 Linux 应用领域硬件的一个单个可拒绝执行借助于。BusyBox 纸制涵了一些简立刻的应用领域硬件,例如 cat 和 echo,还纸制涵了一些愈来愈多、愈来愈有用的应用领域硬件,例如 grep、find、moun)

root方的单细分两种:

不或许 root或许 root

在此前给与Android root 职责近似于法则是往还过各种系由统设计漏洞,换成或填充SU前提到电子系由统,给与Root职责,而在给与root职责以后,但会装一个前提用以提醒的硬件是不是给予前提最低职责,可以一定持续性上尽量减少防火墙,往还常但会可用Superuser或者 SuperSU ,这种法则往还常叫想到“不或许Root”。

而 “或许Root”是仅指,换成电子系由统原先的ROM,以借助于取消secure分设

如何横越Root监标定前提呢?这里面提可让者两个高约处,其一是互换用行凶,干预应用领域的Root监标定行径;另之外一个高约处则是对系由统设计行凶,伪装系由统设计自身Root之外的基本特征。我们可以依靠jadx等逆向应用领域硬件互换用软件包透过系由统持续性,Hook之外的借助于参数横越;也可以给与AOSP软件包,往还过选用ROM来伪装Root的基本特征

Hook

在此前边缘化的Hook构建有frida和xposed,可以用frida的可见构建RMS透过流到。相对来话说,往还过Hook的方的单来横越Root监标定前提操作法则极其简立刻、立刻利,但Hook本身但会受到很多的约束。一方面,受限于应用领域自身的加固手段,确实容易相对于ROOT监标定的借助于参数;另一方面,Hook构建自身也但会较强一些易于被监标定到的基本特征,确实但会受到这些基本特征的约束而容易完成文书工作。

选用ROM

选用ROM的手段有很多种,可以往还过对官方网站纸制透过解纸制、变愈来愈后重打纸制。我破例的方的单是给与AOSP软件包,自己载入后制作ROM纸制。这样可以借助于愈来愈高持续性的选用化,与基于原先以纸制变愈来愈的方的单相对于该方的单的操作法则密闭愈来愈多,但是同样的它但会带给愈来愈好的载入运输成本、变愈来愈精准度也愈来愈多

高热翻修

高热翻修借助于的本质就是将翻修bug后的载入器生成的dex放到在该数一组的头部

基于电子系由统的造假监标定:

监标定小心的APP纸制名主要监标定hook构建,实时上网者应用领域硬件,magisk,supersu等root应用领域硬件标定是不是共存root职责一般往还过是不是共存bin、sbin概要资料里面的su文档,kingroot职责管理apk监标定是不是有试验持续性稳定状态default.prop文档的ro.secure=1、ro.debuggable=1稳定状态,/proc/self/status文档的TracerPid倍数监标定是不是电子系由统是不是出厂ROM一般往还过android.os.Build的各类表达式倍数来确实,如Build.fingerprint一些电子系由统常规文档,比如电量稳定状态,usb稳定状态,图标亮度,邻近地区,wifi或者sim托文档,ip、mac等一般此前操作法则或者抹机操作法则的时候这些倍数愈来愈改精准度和运输成本极其大,所以这些仅测试方法能假造但会大大降低被风控

基于行径的造假监标定:

Log摘要取材android开发设计时有Log.i、Log.e等行驶摘要,基本上APP用这个来试验持续性或者监标定APP的行驶情形,并且release版本本一般往还过boolean倍数来滚轮,如果能hook掉这个滚轮就容易监标定APPException栈文档取材基本上APP的摘要但会取材Exception,如果栈里面有hook构建的纸制方向就但会把自己给杀掉,让hook容易高约久拒绝执行,责怪APP变成一个微型链接抓纸制应用领域硬件统计数字sdk的文档,如talkingdata、umeng等一般阿里面系由的但会用umeng来想到统计数字应用领域硬件,一般这些sdk都有自己的唯一编号,有些app提到这个编号来想到一个仅测试方法去确实app的配置唯一持续性,有的但会往还过统计数字样本来确实此前造假行径,因为这些sdk但会取材一些电子系由统血迹并且应用领域和破译催化精准度极其大的持续性汇报sdk,比如buggly,友盟sdk等等持续性汇报sdk一般详细叙述行驶时所有的持续性情形,并且但会详细叙述电子系由统血迹,往还过这些也能监标定到造假的一些电子系由统

APP的煽动造假策略和高约处:

电子系由统血迹的Android如数美、易盾或一些大厂的app都但会自带取材电子系由统血迹的计算机系统,往还过电子系由统血迹来确定电子系由统的唯一持续性,如imei、android_id、mac、其他电子系由统文档紧密结合起来就能变成一个唯一的徽标取材IP、MACIP、蓝牙MAC、WIFI等网络平台血迹大量的取材后跟其他取材的文档紧密结合并且不断地完善改由IP或黒ip、mac坎,就能不断地能相对于造假源头邻近地区、串流从中、认可登录邻近地区和ip是不是互换、网络连接文档是不是互换、或者电子系由统型号跟串流从中互换、一般小米Android的硬件基本上一定会小米商城串流的,比如微信认可登录,QQ认可登录等、如果实时认可登录必需破译其他自带到APP的一些备忘录表达式收件、表达式加密一般APP但会把get或者post的表达式往还过某种搜索算法去收件,并且这个收件难催化。比如抖音的x-gorgon,有的把post或者get表达式同样加密,一般往还过aes、rsa、des等持有者网络平台备忘录、protobuf等备忘录、持有者网络平台学位证书、煽动改由抓纸制在此前盛行protobuf备忘录替代json,还有一些持有者TCP/Socket备忘录,这些备忘录不可同样念过,必需一个类比应用领域硬件或者系由统持续性催化。持有者网络平台学位证书必需学位证书加密配合改由抓纸制应用领域硬件才能抓纸制系由统持续性,这种似乎精准度在于认出学位证书加密和确实是不是用了持有者学位证书,一般聊APP的IM备忘录近似于。还有煽动改由抓纸制,比如集成OkHttp构建等的时候用Proxy.NO_Proxy来尽量减少抓纸制dex载入器联想,native层ollvm载入、webview的js联想互换dex载入器联想催化或者系由统持续性精准度极其容易,并且各种煽动载入硬件来系由统持续性精准度不是那么大,主要精准度在于rxjava等异步构建,连接器借助于类匹配搭。native层的话主要精准度是催化基于ollvm的各种联想的载入器,其他催化或者理解精准度似乎不一定大,并且基本上APP把一些加解密和收件等搜索算法用native方的单借助于能用ollvm联想,其他的native层的都是一些电子媒体或者网络平台等坎。webview一般用在的硬件名上,并且用js的java层连接器独自可用,把滑动或者相片次序相对于之类的方向摘要往还过贾母方的单网络平台审批的,javascript载入器一般联想的极其厉害,不过AST煽动联想等法则或者串流后nginx本地搭设并chrome自行试验持续性归纳后往还过剧本也能催化,如极验、易盾等的硬件名该硬件APP加壳、必需sdk、持有者必需该硬件加壳愈来愈多是为了过合规,Skype里面dex文档总能行驶内存中会dump出来的,除非操作法则系由统设计从底层设计上愈来愈改了,所有hook或者fart等变愈来愈的ROM都能搞定。360,腾讯,梆梆等等必需sdk也可以纸老虎这么话说,不过必需sdk一般跟机器学习,大样本比如话说等之外,日渐有精准度去应付,不过一般在SNS电商类的煽动虚拟世界登录时用,这些SDK取材血迹电子系由统,并留有到自己的链接,但会相对于改由IP,打码平台的托号,可能性电子系由统,不过把加解密搜索算法催化后可以假造电子系由统和其他样本,能横越还有一些大APP有自己开发设计的必需之外的计算机系统,这些似乎跟必需sdk十分相似,主要还是电子系由统文档假造和加解密搜索算法破译后都能横越。数美、易盾等

APP的煽动造假应用领域硬件和策略:

逆向应用领域硬件java:dex2jar、jadx、jeb、android-killer等等so文档:IDA、jeb、Gidrajs:似乎nodejs加网易或者火狐就能搞定其他:unicorn、unidibug等基于qemu虚拟世界机的应用领域硬件抓纸制应用领域硬件Charles、Fillder:这两个似乎差不多,使用http、websocket等应用领域层抓纸制WireShark:各种备忘录都能支持者,必需愈来愈深入的网络平台备忘录应用领域基础性BurpSuite:可以开发设计一些该硬件,但会开发设计就各种神操作法则把hook构建xposed:的硬件极其多,都有云控、群控、那些化妆品,文化教育类、被保险人等销售类的都在用,市场需求量大frida:一般开发设计者可用的多,快,不必重从新激活,但会js就但会玩吧cydia:hook Native层的时候多一点,老开发设计者用的多inlinehook,xhook:这两个十分相似,inlinehook多使用hook b跳转的,xhook多使用系由统设计参数magisk:Skype8以上xposed或者其他一些学位证书配置等应用领域硬件都基于这个,这个似乎下一代研究成果的外面实时上网者uiautomator:很多实时上网者硬件基于这个,跟xposed紧密结合开发设计极其适当于,理解Skype开发设计的初学极其简立刻还有按键精灵,键倍数精灵,碰触精灵等等餐饮业精准度ollvm联想:逆向餐饮业在此前一定会最奇怪的是的就这个吧,主要数学模型时if-else改成while(true){switch() case:}了,但是逆向运输成本变高了,并且各种延申的外面日渐多,必需知识和应用领域积累才能100%催化或破译机器学习风控策略:这个不用多年知识或者不用相当高约的间隔时间去为了让或者没跟班一个APP的成高约的话能够互换,并且基本上都是往还过养育号,养育电子系由统等方的单去互换,还有的是破译备忘录,并且假造大量的电子系由统文档,往还过IP改由池,托商和打码平台等第三方服务来确保。不过随着法规的完善和APP自身的风控体系由健全互换运输成本日渐高,那时候能够借助于大此前账户登录唯册0x02 横越root监标定实验

1)检标定su号令是不是共存

往还常要给与Root职责,是可用su号令来借助于的,因此可以往还过检标定这个号令是不是共存,来确实行驶生态环境是不是Root

2)检标定Android属持续性

检标定ro.debuggable、ro.secure 两个属持续性是不是为true,为true的话APP所行驶生态环境很确实是Root生态环境

3)检标定特定方向是不是有念过到职责

具体内容方向纸制括:/system、/system/bin、/system/sbin、/system/xbin、/vendor/bin、/sys、/sbin、/etc、/proc、/dev

往还过mount号令确认互换分组的职责是不是为"rw"

adb shell mount | grep -w /sysfs on /sys type sysfs (rw,seclabel,relatime)

下面从几种被操作法则系由统设计广泛应用可用的监标定应用领域开始话说起,如果电子系由统仍然root,但会增高一些从新的文档,所以可以往还过监标定这些文档是不是共存来确实,还有一些开发设计者往还过检标定能否拒绝执行只有root职责下才能行驶的号令来确实,当然还有一些其他的手段

前几年最盛行(那时候已中断维护许久了)的root应用领域硬件是Superuser.apk,是一个被广泛应用可用的用来rootSkype电子系由统的硬件,所以可以检标定这个app是不是共存,但在监标定前,我们先以补救配置纸制拢的情形

补救方案:

SuperSU 纸制涵一个 su 可拒绝执行文档和一个 Superuser.apk,只必需把 SuperSU 提可让者的 su 可拒绝执行文档换成系由统设计的 su 文档,并且给予职责 -rwsr-sr-x (6755) 亦可。

一般在仅仅电子系由统上有两种方的单换成文档:

手动将 SuperSU 的 su 文档换成系由统设计文档,必需 Root 职责;往还过 Recovery 模的单同样将 su 文档已补丁纸制的形的单刷入。对于实时器来话说,它不用 Recovery 模的单,是同样可用 img 比如话说激活的,所以不用可用第一种法则

官网串流:,自由选择 Recovery V2.82 Flashable.zip 透过串流,里面面纸制涵各个虚拟世界化所需的 su 文档,以及 Superuser.apk 配置纸制

查询实时器的 su 号令所在的方向adb shellwhich su关上一个cmd窗口,拒绝执行如下号令adb remount 是为了将 /system 挂载为可念过到,然后我们将su透过换成adb rootadb remountadb push su /system/bin/su

请唯意:对于 Android 5.0 版本本及最上层的电子系由统来话说,必需可用 su.pie 文档,它是可用 -fPIE 标识载入的位置无关的可拒绝执行文档,较强IP密闭随机化特持续性

其后关上一个cmd窗口拒绝执行如下号令adb shellchmod 6755 /system/bin/suls -al /system/bin/susu ;还有installsu ;还有daemonMaxsetenforce 0

侧面号令解释如下:

分设职责,使 SuperSU 提可让者的 su 可拒绝执行文档能够被所有应用领域拒绝执行;初始化配置 su;分设 su 主意味着;关闭 SELinux 必需策略,免除 Root 职责的限制

上网者重从新激活手柄确实但会托住,同样关闭实时器重从新激活亦可,其后关上不能再预设su被占用的情形

adb shellls -l /system/app/ | grep 'Super'

SuperSU 文书工作数学模型:

daemonsu 为 su 激活的主意味着那时候第三方应用领域开始调用 su 号令,恳求登记 Root 职责su 是一个可拒绝执行文档,之下与 daemonsu 透过往还信,转发拒绝执行号令恳求daemonsu 创建者 sush 子意味着,sush 意味着可用 am(Activity Manager)号令激活 Superuser 应用领域,恳求认可,用到的硬件认可图形认可往还过,Superuser 应用领域往还过 socket 返国给 sush 的硬件认可结果,往还过认可,则 sush 自由选择是不是拒绝执行恳求的号令

SuperSU 文书工作数学模型连续持续性图如下:

SuperSu,往还过recovery将其文档刷入系由统设计亦可可用。然而那时候Skype但会对系由统设计的倍数得唯意持续性透过有效性,这一法则就亦非行得往还了。愈来愈何况很多厂商但会对bootloader透过绕过,这不一定一定Skype各分组不用被强行变愈来愈,能够往还过fastboot来刷入Su文档,也不用可用第三方的recovery,su的刷入也就无从谈起,root职责成为了遥不可及的传话说。

大家可以无论如何Magisk应用领域硬件,跟SuperSu一样的,但比SuperSu要香多了,而且SuperSu在2021年时仍然不出透过维护了。

串流IP:

Magisk 是一套使用选用 Android 的Ubuntu硬件,支持者大于 Android 5.0 的电子系由统。 一些突出特点:

MagiskSU:为操作法则系由统设计提可让者 root 会面时职责Magisk Modules:往还过配置计算机系统变愈来愈格式化分组MagiskBoot:最倍数得唯意的Skype激活比如话说解纸制和重从新打纸制应用领域硬件Zygisk:在每个 Android 操作法则系由统设计的意味着中会行驶载入器还可以搜索一些特殊性的package,比如所示所展出的pm list packages | grep 'shell' 有一些操作法则系由统设计不用在root的电子系由统上行驶,所以检标定他们是不是共存也是一个优异的法则。比如比如说的Busybox:busybox pwd

行驶“su”和“id”,然后查询uid来检标定

suid 正的单横越root监标定

配置了SuperSU的监标定:

没配置SuperSU的监标定:

标定试载入器如下:CheckRoot.java载入器 package com.example.testpoc4;import android.util.Log;import java.io.File;public class CheckRoot { // 概念TAG常量 private static String TAG = CheckRoot.class.getName(); // 检标定确实是不是共存SuperSU.apk文档,共存的话就是root,并在摘要里面打印偷偷地文档,若不是返国false public static boolean checkSuperuserApk() { try{ File file = new File("/system/app/SuperSU/SuperSU.apk"); if (file.exists()){ Log.w(TAG, "/system/app/SuperSU/SuperSU.apk exist"); return true; } }catch (Exception e){ } return false; }}MainActivity.java载入器 package com.example.testpoc4;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); boolean root = CheckRoot.checkSuperuserApk(); ((TextView) findViewById(R.id.text)).setText("Device Root:"+root); }}activity_main.xm载入器

为了横越这个检标定,让我们将操作法则系由统设计“Superuser.apk”重命名为“Superuser0.apk”,先以将/system概要资料从可念过变成可念过到先以可用remout,如所示所示

将其名称改变亦可横越,其后行驶监标定该硬件的前提时已不再预设为true

0x03 近似于root监标定法则

常规监标定法则:监标定(test-keys(标定试版本)、release-keys(发表版本))系由统设计是不是标定试版本、监标定提权为root的应用领域纸制名、监标定近似于或极其用su共存的概要资料、监标定是不是可用which 匹配su、监标定Busybox是不是共存、监标定/data概要资料,是不是有念过取职责等,下面详列近似于的一些监标定法则的简述:

查询系由统设计是不是标定试版本

可以查询发表的系由统设计版本本,是test-keys(标定试版本),还是release-keys(发表版本)。

public static boolean checkDeviceDebuggable() { String buildTags = android.os.Build.TAGS; if (buildTags != null MaxMax buildTags.contains("test-keys")) { Log.i(TAG, "buildTags=" + buildTags); return true; } return false; }

仅仅完全,某些厂家的正的单发表版本本,也是test-keys,确实大家对这个标识也不是都有唯意吧。所以具体内容是不是可用,要多权衡权衡。

检标定是不是共存Superuser.apk

Superuser.apk是一个被广泛应用可用的用来rootSkype电子系由统的硬件,所以可以检标定这个app是不是共存。

监标定法则如下:

public static boolean checkSuperuserApk() { try{ File file = new File("/system/app/SuperSU/SuperSU.apk"); if (file.exists()){ Log.w(TAG, "/system/app/SuperSU/SuperSU.apk exist"); return true; } }catch (Exception e){ } return false; }检标定su号令

su是Linux下翻转的硬件的号令,在可用时不带表达式,就是翻转到超级的硬件。往还常我们给与root职责,就是可用su号令来借助于的,所以可以检标定这个号令是不是共存。

监标定在近似于概要资料下是不是共存su:

public static boolean checkRootPathSU() { File f = null; final String kSuSearchPaths[] = {"/system/bin/", "/system/xbin/", "/system/sbin/", "/sbin/", "/vendor/bin/"}; try { for (int i = 0; i < kSuSearchPaths.length; i++) { f = new File(kSuSearchPaths[i] + "su"); if (f != null MaxMax f.exists()) { Log.i(TAG, "find su in : " + kSuSearchPaths[i]); return true; } } } catch (Exception e) { e.printStackTrace(); } return false; }拒绝执行su,看能否给与到root职责

拒绝执行这个号令su。这样,系由统设计就但会在PATH方向中会搜索su,如果认出,就但会拒绝执行,拒绝执行成功后,就是给与到根本的超级职责了。

public static synchronized boolean checkGetRootAuth() { Process process = null; DataOutputStream os = null; try { Log.i(TAG, "to exec su"); process = Runtime.getRuntime().exec("su"); os = new DataOutputStream(process.getOutputStream()); os.writeBytes("exit"); os.flush(); int exitValue = process.waitFor(); Log.i(TAG, "exitValue=" + exitValue); if (exitValue == 0) { return true; } else { return false; } } catch (Exception e) { Log.i(TAG, "Unexpected error - Here is what I know: " + e.getMessage()); return false; } finally { try { if (os != null) { os.close(); } process.destroy(); } catch (Exception e) { e.printStackTrace(); } } }会面时/data概要资料,查询念过取职责

在Android系由统设计中会,有些概要资料是都是的硬件能够会面时的,例如 /data、/system、/etc 等。 我们就已/data为例,来透过念过取会面时。本着谨慎的态度,我是先以念过到入一个文档,然后念过出,查询具体内容内容是不是比如话说,若比如话说,才显然系由统设计仍然root了。

public static synchronized boolean checkAccessRootData() { try { Log.i(TAG, "to write /data"); String fileContent = "test_ok"; Boolean writeFlag = writeFile("/data/su_test", fileContent); if (writeFlag) { Log.i(TAG, "write ok"); } else { Log.i(TAG, "write failed"); } Log.i(TAG, "to read /data"); String strRead = readFile("/data/su_test"); Log.i(TAG, "strRead=" + strRead); if (fileContent.equals(strRead)) { return true; } else { return false; } } catch (Exception e) { Log.i(TAG, "Unexpected error - Here is what I know: " + e.getMessage()); return false; } } //念过到文档 public static Boolean writeFile(String fileName, String message) { try { FileOutputStream fout = new FileOutputStream(fileName); byte[] bytes = message.getBytes(); fout.write(bytes); fout.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } //念过文档 public static String readFile(String fileName) { File file = new File(fileName); try { FileInputStream fis = new FileInputStream(file); byte[] bytes = new byte[1024]; ByteArrayOutputStream bos = new ByteArrayOutputStream(); int len; while ((len = fis.read(bytes))> 0) { bos.write(bytes, 0, len); } String result = new String(bos.toByteArray()); Log.i(TAG, result); return result; } catch (Exception e) { e.printStackTrace(); return null; } }

将上述话说的监标定作成载入器想到为监标定,此处就不预览了,大家自行操作法则:

CheckRoot.java载入器:

package com.example.testpoc4;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.util.ArrayList;import android.util.Log;public class CheckRoot { // 概念TAG常量 private static String TAG = CheckRoot.class.getName(); public static boolean isDeviceRooted() { if (checkDeviceDebuggable()) { return true; }//check buildTags if (checkSuperuserApk()) { return true; }//Superuser.apk if (checkRootPathSU()) { return true; }//find su in some path if (checkRootWhichSU()) { return true; }//find su use 'which' if (checkBusybox()) { return true; }//find su use 'which' if (checkAccessRootData()) { return true; }//find su use 'which' if (checkGetRootAuth()) { return true; }//exec su return false; } // 检标定确实是不是共存SuperSU.apk文档,共存的话就是root public static boolean checkSuperuserApk() { try{ File file = new File("/system/app/SuperSU/SuperSU.apk"); if (file.exists()){ Log.w(TAG, "/system/app/SuperSU/SuperSU.apk exist"); return true; } }catch (Exception e){ } return false; } public static boolean checkDeviceDebuggable() { String buildTags = android.os.Build.TAGS; if (buildTags != null MaxMax buildTags.contains("test-keys")) { Log.i(TAG, "buildTags=" + buildTags); return true; } return false; } public static boolean checkRootPathSU() { File f = null; final String kSuSearchPaths[] = {"/system/bin/", "/system/xbin/", "/system/sbin/", "/sbin/", "/vendor/bin/"}; try { for (int i = 0; i < kSuSearchPaths.length; i++) { f = new File(kSuSearchPaths[i] + "su"); if (f != null MaxMax f.exists()) { Log.i(TAG, "find su in : " + kSuSearchPaths[i]); return true; } } } catch (Exception e) { e.printStackTrace(); } return false; } public static boolean checkRootWhichSU() { String[] strCmd = new String[]{"/system/xbin/which", "su"}; ArrayList execResult = executeCommand(strCmd); if (execResult != null) { Log.i(TAG, "execResult=" + execResult.toString()); return true; } else { Log.i(TAG, "execResult=null"); return false; } } public static ArrayList executeCommand(String[] shellCmd) { String line = null; ArrayList fullResponse = new ArrayList(); Process localProcess = null; try { Log.i(TAG, "to shell exec which for find su :"); localProcess = Runtime.getRuntime().exec(shellCmd); } catch (Exception e) { return null; } BufferedWriter out = new BufferedWriter(new OutputStreamWriter(localProcess.getOutputStream())); BufferedReader in = new BufferedReader(new InputStreamReader(localProcess.getInputStream())); try { while ((line = in.readLine()) != null) { Log.i(TAG, "–> Line received: " + line); fullResponse.add(line); } } catch (Exception e) { e.printStackTrace(); } Log.i(TAG, "–> Full response was: " + fullResponse); return fullResponse; } public static synchronized boolean checkGetRootAuth() { Process process = null; DataOutputStream os = null; try { Log.i(TAG, "to exec su"); process = Runtime.getRuntime().exec("su"); os = new DataOutputStream(process.getOutputStream()); os.writeBytes("exit"); os.flush(); int exitValue = process.waitFor(); Log.i(TAG, "exitValue=" + exitValue); if (exitValue == 0) { return true; } else { return false; } } catch (Exception e) { Log.i(TAG, "Unexpected error - Here is what I know: " + e.getMessage()); return false; } finally { try { if (os != null) { os.close(); } process.destroy(); } catch (Exception e) { e.printStackTrace(); } } } public static synchronized boolean checkBusybox() { try { Log.i(TAG, "to exec busybox df"); String[] strCmd = new String[]{"busybox", "df"}; ArrayList execResult = executeCommand(strCmd); if (execResult != null) { Log.i(TAG, "execResult=" + execResult.toString()); return true; } else { Log.i(TAG, "execResult=null"); return false; } } catch (Exception e) { Log.i(TAG, "Unexpected error - Here is what I know: " + e.getMessage()); return false; } } public static synchronized boolean checkAccessRootData() { try { Log.i(TAG, "to write /data"); String fileContent = "test_ok"; Boolean writeFlag = writeFile("/data/su_test", fileContent); if (writeFlag) { Log.i(TAG, "write ok"); } else { Log.i(TAG, "write failed"); } Log.i(TAG, "to read /data"); String strRead = readFile("/data/su_test"); Log.i(TAG, "strRead=" + strRead); if (fileContent.equals(strRead)) { return true; } else { return false; } } catch (Exception e) { Log.i(TAG, "Unexpected error - Here is what I know: " + e.getMessage()); return false; } } //念过到文档 public static Boolean writeFile(String fileName, String message) { try { FileOutputStream fout = new FileOutputStream(fileName); byte[] bytes = message.getBytes(); fout.write(bytes); fout.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } //念过文档 public static String readFile(String fileName) { File file = new File(fileName); try { FileInputStream fis = new FileInputStream(file); byte[] bytes = new byte[1024]; ByteArrayOutputStream bos = new ByteArrayOutputStream(); int len; while ((len = fis.read(bytes))> 0) { bos.write(bytes, 0, len); } String result = new String(bos.toByteArray()); Log.i(TAG, result); return result; } catch (Exception e) { e.printStackTrace(); return null; } }}

MainActivity.java载入器

package com.example.testpoc4;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); boolean deviceRoot = CheckRoot.isDeviceRooted(); ((TextView) findViewById(R.id.text)).setText("Device Root:" +deviceRoot); }}

概要链接:

_47883636/article/details/108687059

你以为你有很多北路可以自由选择,似乎你只有一条北路可以放

益生菌和肠炎宁哪个止泻效果好
阿莫西林颗粒对咽炎有效吗
医药信息
广东儿科医院哪个好
手指类风湿性关节炎怎么治疗
相关阅读