1、adbd daemon的启动:
adbd daemon是adb devices/emulator后台运行的一个守护进程,它是由init进程启动的。在init.rc中可以看出adbd daemon在系统一开机就已经启动,而且即使被杀掉,系统也会重新启动该进程。
前面讲到Adb Server与 adbd daemon是由同一套代码,通过一个ADB_HOST宏来控制的。也就是说,adbd daemon的入口函数依然是adb.c的main方法。下面继续来看adb.c的main方法。
从上面的分析来看,这个和Adb Server启动时的流程基本上是一致的。不过从Android.mk文件中就可以看到,Adb Server与adbd daemon编译时的文件与Adb Server有一些差别。下面就简单讲讲adbd daemon与ADB Server启动的差别之处,相同之处在此就不再分析了。
我们都知道我们手机版本有user版本和eng版本,这两个版本的一些区别想必大家都有所了解,而对于我们开发人员最直接的区别就是user版本无法执行adb remount操作,也就是user版本没有root权限。那user版本为什么会没有root权限了,想必肯定会与adbd daemon有一定的关系,下面简单看看。
如果是usr版本,adbd daemon启动时会执行如下代码。
/* then switch user and group to "shell" */
if (setgid(AID_SHELL) != 0) {
exit(1);
}
if (setuid(AID_SHELL) != 0) {
exit(1);
}
//原来在执行上述代码之前,adbd daemon还是root权限,在执行完上述代码之后,adbd daemon就运行于shell权限了。
这样一来usr版本就存在一个漏洞,执行这段代码之前运行于root权限,执行这段代码之后运行于shell权限,那么只要在系统启动时想办法屏蔽这段代码,那么就可以adbd daemon就可以一直运行于root权限了。用户可以利用这个漏洞来进行破解获取root权限,目前市场上通用的root user版本来获取root权限,基本上就是基于这个漏洞来进行的。具体的实现方法网上有很多很多,有兴趣的同学可以自行尝试。
下面继续看看Adb Server与adbd daemon启动的差异usb_init()(system/core/usb_linux_client.c)此处的usb_init和 ADB Server
端的usb_init不是同一个方法。
后面执行register_usb_transport(usb, 0, 1)的过程和ADB Server端启动的方式是一样的。
2、adbd daemon与Adb Server数据的传递
那么我们直接来看看adbd daemon接收ADB Server端数据的过程,继续以adb shell命令为例来分析。前面讲到Adb Server启动时会创建两个线程input_thread、output_thread, 同样在adbd daemon中也会创建这样两个线程,用来处理Adb Server端发送的数据,并将响应结果返回给Adb Server端。
当adbd daemon进程接收到ADB Server发送过来的”shell”命令时,output_thread线程会执行read_from_remote()方法接收ADB Server端的命令,然后执行write_packet()方法,此时会触发transports_socket_events()方法。这些步骤和ADB Server端的处理是同样的,唯一不同的是:
adbd daemon端会启动一个新的进程来专门处理adb shell命令,在这个进程中会执行/system/bin/目录下的sh可执行文件(我们也可以在
adb shell下直接执行以下这个sh文件,来看看这个执行结果)。
在adb shell下,我们到system/bin/目录下也可以找到sh这个可执行文件。
小结:本片文档主要讲解了以下几个部分
1、adbd daemon 的启动流程。
2、user版本的adbd daemon运行于shell权限的原因,root user版本的基本原理。
3、adbd daemon与adb server之间通信。
4、“adb shell”命令的执行流程。
转载于:https://blog.51cto.com/sunzeduo/1401174