adb调试(1)--权限与管理

说adb,所有做android开发的人都知道,我们敲这几行adb调试的命令都很娴熟。既然这样,为什么还要讲adb?不过话说在其那头,这里讲adb,还是有一定意义的,说不定能给予你一些灵感。

平时我们使用最多的命令无非:

adb connect

adb remount

adb push

adb install

这里四条命令,其中第1,3,4条都很直白:连接,推送,安装。可是,每当我们要往“system”目录推送东西的时候,都要做 adb remount 的动作。那么问题来了:为什么要adb remount ??在试行adb remount 这条命令的时候究竟做了些什么事情?

在解答这个问题之前,我们可以先来看看 system 的权限管理是怎样的。

System目录的权限由两个地方所决定:

首先是在init.rc 里面创建system目录的时候会指定system目录的权限和用户组:

mkdir /system 755 root root

从755 我们可以得知,只有root用户具备对system目录的写权限。

其次是vold里面去加载system分区的时候指定的挂载权限,其操作的目录是放在fstab.$VENDOR 里面:

dev/block/mmcblk1p5    /system      ext4    ro

从上面我们可以看到位于flash的partion  5 的就是system 分区。Vold去挂载system的时候,把它挂载成 ro 了,也就是只读。

所以平时我们去往system 目录写东西的时候会被系统提示:

Read-only file system

但是为什么我们执行一下 adb remount 就可以往system 里面写东西了呢?既然有这个疑问,我们就先来看看 adb remount 这条命令做了写什么事情。

看到adb代码里面,正确来说是adbd:

106 void remount_service(int fd, void *cookie)
107 {
108     int ret = remount_system();
109 
110     if (!ret)
111        write_string(fd, "remount succeeded\n");

我们执行adb remount 这条命令会触发到remount_service 这个函数,而在这个函数里面做了一个动作,就是“remount_system”从新挂载了system分区:

 72 static int remount_system()
 73 {
 74     char *dev;
 75     int fd;
 76     int OFF = 0;
 77 
 78     if (system_ro == 0) {
 79         return 0;
 80     }
 81 
 82     dev = find_mount("/system");
 83 
 84     if (!dev)
 85         return -1;
 86 
 87     fd = unix_open(dev, O_RDONLY);
 88     if (fd < 0)
 89         return -1;
 90 
 91     ioctl(fd, BLKROSET, &OFF);
 92     adb_close(fd);

这个函数的详细过程就不进行分析了,如果有兴趣的话可以跟进一下代码。

其实这里面做了一个动作,把system 分区从新挂载了一下,通过上面的分析我们也知道,就是把system挂载为可读写的了。

好,既然这样,那我们是否也可以这样联想:如果我们手动去从新从新挂载system,会不会也能把system分区挂载为读写呢?

于是在串口命令行执行:

mount -o rw,remount -t ext4  /dev/block/mmcblk1p5 /system

发现执行这条命令之后,我们也能拥有对system的读写权限了,证明猜想是对的。

但是,所有以上的操作都有一个约束条件:必须在root用户进行操作。也就是所adbd(这里要理清adb跟adbd的关系,一个是client端,一个是service端,具体情况可以网上查资料,这里不做详细说明)必须是运行在root用户组下面,和串口的shell必须是root。这样说,有点疑惑了吧?既然疑惑,那么接下来讲的内容是:

1、  adbd的执行与用户组管理

2、  串口终端的shell

adbd的执行与用户组管理

我们在pc机上对板子进行adb命令动作的前提条件是,板子上必须启动了adbd服务。不然会提示出错:

C:\Users\Administrator>adb connect172.21.78.160

error:

那么adbd是在哪里启动呢?是在init.rc 里面:

557 service adbd /sbin/adbd
558     class core
559     socket adbd stream 660 system system
560     disabled
561     seclabel u:r:adbd:s0

这里面可以做一个实验,如果把init.rc里面的adbd服务关闭了,那么当我们在pc机上使用adb命令对板子进行操作的时候,也会同样报错:

C:\Users\Administrator>adb connect172.21.78.160

error:

说到这里,不知道你有没有发现:在init.rc 执行的过程中都是具备所有的操作权限,但当机子启动起来,我们通过adb 或串口去操作的时候就不具备权限了呢?其实原因也在adbd启动的时候,把root权限改为shell权限了:

/* then switch user and group to "shell" */
setgid(AID_SHELL);
setuid(AID_SHELL);

好,adbd讲到这里,接下来讲:串口终端的shell

我们平时在操作串口的时候会看到:

root@$BOARD:/ #

上一行语句前面这个“root”是什么含义呢,是由哪里决定的呢?

其实这个“root”是说当前串口终端这个shell是运行在root权限下的。当然,决定这个权限的,还是我们强大的init.rc :

service console /system/bin/sh
    class core
    console
    user root
    group root

如果你把 user 和group 都换成 shell 的话,那么你在串口终端下会发现:

shell@$BOARD:/

用户组变为一般的shell 了,那边这时候在串口终端下执行:reboot,拷贝,adbd 等命令都会提示:

Operation not permitted

因为shell用户已经不具备相关的操作权限了。

但,如果执行一下su命令,再进行reboot动作,如:

shell@$BOARD:/ $ su
shell@$ BOARD:/ # reboot

那么命令及可以继续执行下去,因为su的动作让我们获取了root的权限了。

所以在网上一些提到android root 的方法:

a.        adb push su /system/bin
b.        adb push SuperUser.apk /system/app
c.       adb shell chmod 4755 /system/bin/su

以及去除root的方法:

1.    你的Android设备上要有一个深度的文件管理器应用,如ES File Explorer等
2.    打开文件管理器
3.    去/system系统目录
4.    打开/bin目录,或/xbin目录
5.    找到su
6.    删除它
7.    回到/system系统目录
8.    去/app目录
9.    找到Superuser.apk
10.   删除它
11.   重启设备
12.   完成

不过这两种方式,都有一个相同的约束条件,就是串口的shell必须是root权限。

 

介绍就到这里,如果细细阅读你会发现,如果想在android的产品上做用户权限的管理:如限定用户的某些权限,又或者做一个完全封闭的系统。那么知道这些原理,做起来也很得心应手。













  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值