android的 root权限

摘要:
1、 ROOT权限II简介。为什么我需要ROOT权限III?ADBD的ROOT权限IV。深入源代码ROOT权限简介:ROOT权限是Linux内核中最高的权限。如果恶意程序获得了ROOT权限,它将不会为用户提供ROOT权限。用户在一生中也不会使用或卸载垃圾软件(我相信使用Android的学生理解我的意思)。苹果用户获得ROOT权限,而普通Android用户获得ROOT权限,Android开发者获得日志文件。

本文将从几个方面,由浅至深地讲述ROOT到底是什么东西?

一. ROOT权限简单介绍

二.为什么需要ROOT

三. ADBD的ROOT权限

四.深入源代码

ROOT权限简介:

ROOT权限是Linux内核中的最高权限,如果你的身份是ROOT,那么你就具有了ROOT权限。有了最高权限,你就可以为所欲为,换句话说,如果恶意程序获取到了ROOT权限,那么就可以肆意地破坏你的手机,获取的隐私...所以厂商一般在生产手机的时候,不会提供给用户ROOT权限,官方宣称是为了保护用户手机的安全,然后装了一堆开机自动启动,而用户这辈子也用不到也卸载不了垃圾软件(相信使用安卓的同学们都懂我的意思),而苹果所说的越狱,也就是获取ROOT权限。

为什么需要获取ROOT权限?

苹果用户获取ROOT权限,是为了可以免费安装各种软件,以及为了获取更加灵活的操作体验,苹果不会安装一堆恶心的软件;而安卓普通用户获取ROOT权限,最大的目的就是为了卸载这些恶心的自带软件,安卓极客用户则是为了各种折腾安卓手机,安卓开发人员是为了得到日志文件,分析BUG。

ADBD的ROOT权限:

ADBD是什么?相信大家都看过,IT男把手机连上电脑,然后不知怎么的弹出一个黑乎乎的窗口,上面有一排排白色的英文字母,然后帅气的敲击着键盘(一般敲击 adb shell,然后进入手机),啪啪几下,可以帮你解决一些手机的问题。这个可以和手机交互的进程就是ADBD。这就好比,你去朋友家玩,然后你朋友家比较高端,进大门之前有个可视对讲机,那么你首先通过对讲机呼叫朋友(敲击adb shell),看看在不在家(手机是否相应adb shell这个命令),如果朋友在家,那么就会通过对讲机为你开门(成功进入手机中),提供这个服务的可视对讲机就相当于ADBD。说白了,ADBD就是可以为你提供一种进入手机内部的服务通道。

那么为什么需要ADBD具有ROOT权限?这就涉及到另一个与ROOT息息相关的东西——su。

我们开机之后,使用手机的身份就是一个普通用户(user),如果执行su,那么就可以直接切换到ROOT身份。就像仙剑奇侠传三里面的景天,是个凡人,法力有限,但是大家都知道,他的前世是飞蓬将军,法力高强,天界无人能敌,只有魔界至尊重楼可以与他一较高下,当他们来到天庭的时候,玉帝施法,让景天直接切换成飞蓬将军,于是他就有了飞蓬将军的记忆和法力,与重楼又一次大战。su就是这样一个神奇的命令。

高通平台上,su的相关代码位于: LINUX/android/system/extras/su/su.c中

其实我们所说的越狱或者ROOT,就是把su安装到手机里面 /system/bin目录下,并把它的权限设置为4755,那么某些程序需要ROOT权限的时候,就可以通过su切换到ROOT身份,然后去执行,因此一般被ROOT的手机都会安装一个“超级用户”这样的应用,就是用于管理哪些软件可以切换到ROOT身份,哪些不可以,保证用户安全,这个想法是很好很天真,对于正规的软件,人家按照你的路子来,不正规的软件,你一个小小的超级用户的应用,岂能挡我获取ROOT,虐不死你。

那么为什么需要ADBD获取ROOT权限呢?经过上面的讲解大家应该能猜到,如果ADBD有ROOT权限,就可以通过adb 工具,为所欲为,而又不留下痕迹(不安装su),可以删除自带垃圾软件,获取任意目录的文件,安全性较高。笔者就是通过这种方式获取一些系统级别文件。

深入代码:

看了上面的文字,也许很多人会有这样的想法,原来ROOT一个手机这么简单?错!一点也不简单。

首先:/system分区是只读的文件系统,即你无法往system分区中写入任何东西,其次就算你侥幸把su安装到/system/bin下,你也没法修改它的权限为4755,再者,即使你侥幸把su的权限设为4755,你也逃不过有些手机的反root机制(即检测到有文件的权限为4755,就删除)。

首先我们来看看su的部分代码:

 /* Until we have something better, only root and the shell can use su. */
   myuid = getuid();
    if (myuid != AID_ROOT && myuid != AID_SHELL) {
        fprintf(stderr,"su: uid %d not allowed to su
", myuid);
        return 1;
    }
这句话告诉我们,如果执行su的不是ROOT或者SHELL用户,那就直接退出,说明切换身份时候,你必须是这两个用户,还好我们用adb shell进入,是SHELL用户,好险啊。
if(argc < 2) {
        uid = gid = 0;
    } else {
        int gids_count = sizeof(gids)/sizeof(gids[0]);
        extract_uidgids(argv[1], &uid, &gid, gids, &gids_count);
        if(gids_count) {
            if(setgroups(gids_count, gids)) {
                fprintf(stderr, "su: failed to set groups
");
                return 1;
            }
        }
    }
判断执行su的时候,有没有其它参数,我们只是执行su,即argc < 2成立,su也可以切换成其它用户(argc > 2,详细看su命令的使用),这时候,uid 和 gid 都被设置为0 。即ROOT用户的ID号和组号
if(setgid(gid) || setuid(uid)) {
        fprintf(stderr,"su: permission denied
");
        return 1;
   }
来了来了,就是它,这就是我们最终的目的,把我变身成飞蓬将军,如果一切顺利,你就可以变身成功了(切换ROOT成功)
/* Default exec shell. */
    execlp("/system/bin/sh", "sh", NULL);
每次su之后,就会变成root#,然后就可以通过控制台继续敲命令,但是不同的是,你已经是ROOT了,权限已经很大了。

Android系统启动的时候,ADBD是ROOT权限,只是后来被降级了,判断是否降级的函数是should_drop_privileges()这个函数:

static int should_drop_privileges() {
#ifndef ALLOW_ADBD_ROOT
    return 1;
#else /* ALLOW_ADBD_ROOT */
首先判断是否定义了ALLOW_ADBD_ROOT,如果系统都不允许你ROOT,就直接返回1,下面什么都不看了,就像找工作的时候,不管你多么厉害,如果你第一条要求都不符合,就直接把你pass了,说什么都没用,够狠的。
    int secure = 0;
    char value[PROPERTY_VALUE_MAX];

  /* run adbd in secure mode if ro.secure is set and
    ** we are not in the emulator
    */
   property_get("ro.kernel.qemu", value, "");
    if (strcmp(value, "1") != 0) {
        property_get("ro.secure", value, "1");
        if (strcmp(value, "1") == 0) {
            // don't run as root if ro.secure is set...
            secure = 1;
下面就是获取系统的属性,判断是否打开ROOT权限,可以看到如果ro.kernel.qumu 这个属性被置为了,没关系再给你一次机会,判断ro.secure是否也是1,如果是,对不起你无法获得root权限,我要把secure置为1了(secure为1意味着要降级,后面会讲解),接着:
           // ... except we allow running as root in userdebug builds if the
            // service.adb.root property has been set by the "adb root" command
            property_get("ro.debuggable", value, "");
            if (strcmp(value, "1") == 0) {
                property_get("service.adb.root", value, "");
                if (strcmp(value, "1") == 0) {
		    secure = 0;
            	}
            }
        }
    }
哈哈,又给了你一次机会,我再来判断ro.debuggable是不是1,如果不是,对不起,我必须要降级,否则再给你一次机会,判断service.adb.root这个属性的值,如果也是1,那么就不降级,一般在编译ROM版本的时候,会同事编译两个版本,一个是工程版本,是具有ROOT权限的ADBD,这样方便开发者调试系统,另一个就是我们用户用的版本,叫user版本,这个是没有ROOT权限的,可以看到,就是通过property_get一系列属性来判断是否降级。
    return secure;
#endif /* ALLOW_ADBD_ROOT */
}
最后,返回secure即可。可以看到最后决定是否降级的变量就是secure,所有如果有源代码的话,只有最后将secure赋值为0,不管什么版本,最后都是ROOT权限。
if (should_drop_privileges()) {
        drop_capabilities_bounding_set_if_needed();

        gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET,
                           AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
                           AID_NET_BW_STATS };
        if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
            exit(1);

        /* then switch user and group to "shell" */
        if (setgid(AID_SHELL) != 0) {<span style="white-space:pre">			</span>//曾经的漏洞,被封住了
            exit(1);
        }
        if (setuid(AID_SHELL) != 0) {<span style="white-space:pre">			</span>//曾经的漏洞
            exit(1);
        }

        D("Local port disabled
");
    } 
从这段代码可以看到,如果should_drop_privileges返回1,那么就可以降级了,降级函数为setgid(AID_SHELL)和setuid(AID_SHELL),曾经有黑客利用一些方法,使得setgid和setuid执行失败,即降级失败,以前的代码中是没有exit的,那么当setuid和setgid执行失败之后,就不会降级。

ROOT不是那么轻易的,现在有很多已知的漏洞,但是都被封锁了,所有不是每个root工具都能root成功的,要看它采用的是什么方法来ROOT。



免责声明:文章转载自《android的 root权限》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇攻防世界-crypto-你猜猜(常用文件的文件头、Ziperello爆破压缩包密码)Spring Boot在aop中获取request对象下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

物理像素,ppi,逻辑分辨率和物理分辨率

1 明确几个概念:物理像素:屏幕物理像素屏幕像素密度ppi:pixels per inch,屏幕上每英寸可以显示的像素点的数量,即屏幕像素密度。顺便一提,ppi就是dpi,只不过有文章里说苹果喜欢用ppi,dpi安卓喜欢用,emmmm,所以还是用ppi吧。ppi的计算:屏幕对角线的屏幕物理像素密度除以屏幕尺寸。 以 iphone6 为例子,屏幕是 1334...

asp.net core 集成JWT(二)token的强制失效,基于策略模式细化api权限

【前言】   上一篇我们介绍了什么是JWT,以及如何在asp.net core api项目中集成JWT权限认证。传送门:https://www.cnblogs.com/7tiny/p/11012035.html   很多博友在留言中提出了疑问: 如何结合jwt认证对用户进行API授权? token过期了怎么办? 如何自动刷新token? 如何强制toke...

AirtestIDE基本功能(二)

上期回顾:AirtestIDE基本功能(一) 以下基于python3.7;airtest1.1.8;pocoui1.0.81;airtestIDE1.2.8 上期介绍了AirtestIDE主界面,这次我们来看看AirtestIDE的菜单和工具栏。 文件菜单-对应工具栏的前4个按钮:新建、打开、保存、另存为 新建 点击后会让你选建.air后缀的脚本还是.p...

lin-cms-dotnetcore.是如何方法级别的权限控制的?

方法级别的权限控制(API级别) 直接上lin-cms-dotnetcore的demo http://vvlog.baimocore.cn/#/post/5ecf592e-cc24-9f01-004e-6c0a548f2784 Lin的定位在于实现一整套 CMS的解决方案,它是一个设计方案,提供了不同的后端,不同的前端,而且也支持不同的数据库 目前官方团...

Nexus3.x帐号权限配置

一、使用admin登录后,点击上方齿轮图标 二、打开左侧导航,Security Privileges:具体的权限明细,比如我创建一个test仓库,这里就会生成 Roles:添加角色,设置每个角色可看到的页面或者仓库,每个角色也可拥有其他的角色 Users:添加帐号密码,帐号密码邮箱这些必填信息不说了,这里要选择一个角色 Anonymous:这个打开后对...

adb 连接 Android 手机的两种方式

前言 // 随着现在移动端技术的突飞猛进,导致现在市场上,APP应用数不胜数,那对于测试工程师而言,对于APP的测试,那基本就是一个必修课了。 今天,我就来给大家介绍一下,adb 连接 Android 手机的两种方式。 1 USB线连接手机 1、先使用USB线,连接PC和手机 2、通过PC给手机安装adb驱动,下载好安装驱动的工具,并打开,此时,工具是没有...