最近研究了好几天su+Superuser的源码,感觉大概梳理通了整个大体的思路框架,mark一下。
一.su和Suepruser进行root授权的处理流程
对于su命令行程序在对来自Android应用的Root权限请求处理流程大致如下图所示(因为快要找工作了,为了节约时间花了一副丑到哭的图片
图中Android应用是申请Root权限的申请者,su命令行程序时Root权限拥有者,因su设置了suid位,因此任何执行它的进程都会获得和它一样的权限,这个好像在之前的文章中提到过,其实细节上并非这么容易,和Superuser用户权限管理apk结合起来使用的话还会有一些仲裁的过程。
描述起来就是:
1.Android应用调用su程序,来申请root权限;
2.su启动LocalSocket服务,LocalSocket的功能和通常我们进程通信的Socket类似,其实是在本地共享一块内存来实现和本地其他进程之间进行通信的Socket服务;
3.su命令行程序通过am命令请求显示Superuser应用的RequestActivity窗口,这个窗口里面显示哪个uid的和user的应用申请权限;
4.Superuser连接到由su进程建立的LocalSocket服务上,至此LocalSocket连接成功,之后进程和Superuser对应的进程可以通过这个LocalSocket来进行信息传递了;
5.LocalSocket的数据通道成功连接库,su程序通过socket传递调用者(申请root权限的Android应用)的一些信息。
6.Superuser将用户的仲裁结果数据返回给su程序,如果用户允许授权则,则 ALLOW root授权,反之DENY。(其中还有用户在一定时间内未作出选择的情况,默认为DENY)
这是从Android应用申请root权限到su和Superuser配合实现用户选择后的仲裁的整个过程。
下面我一步一步分析一下这些过程中的细节
二:从su的main函数开始,分析细节
因为su是一个linux命令行程序,故我们首先在Superuser的源码的jni目录下找到su.c文件,定位到main函数处:
main函数中主要完成了三个主要的工作:
1.初始化调用者数据和效验
| 1)获取调用者调用su命令的命令行参数-from_init函数
| 2)获取su命令的链接路径-user_init函数
| 3)获取调用者的名称
2.通过SQLlite数据库检查申请“Root授权”的Android应用程序是否还需要进一步效验
3.建立LocalSocket服务,并进行相应的数据通信
由于代码比较长,而且联系紧密因此在源码中我对相应的部分进行了注释,建议下载后面我给出的注释后的源码来对照理解,如果你懒得下,没关系,相关的长长的代码我给你贴上老 ~~