项目需求:特定应用需要用到root权限运行部分命令,如iptables等;
分解两部分:
1、开启系统服务,接收到cmd,然后调用xxxsu(私有root程序);
2、系统底层实现xxxsu服务,供上层调用
我这里负责系统底层实现;
1、先说明下root相关的内容在4.3的变化:
由于在Android4.3中,从如下的open Source Code :
dalvik_system_Zygote.cpp-》forkAndSpecializeCommon:
注意红色斜体的代码,这是4.3新加入的。新加入的这些代码,会导致setuid()接口不再起作用;
那么接下来,我使用的是现在主流的方法,就是在init进程中以root用户启动su --daemon进程,然后通过本地socket接收命令:
1、第一步,移植cm-13代码中的su,该su带有--daemon参数,支持服务的方式代理执行root权限的命令;
下载cm-13,将system/extras/su目录移植过来;改名xxxsu,直接覆盖更新su也行,以下以改名xxxsu为例说明;
2、修改system/core/include/private/android_filesystem_config.h文件,按照自己的权限控制要求修改可执行文件权限
{ 00750, AID_ROOT, AID_SHELL, 0, "system/xbin/xxxsu" },
3、在init.rc中增加启动root代理服务:
# su daemon
service xxxsu_daemon /system/xbin/xxxsu --daemon
seclabel u:r:xxxsudaemon:s0
on property:persist.sys.root_access=0
stop xxxsu_daemon
on property:persist.sys.root_access=1
start xxxsu_daemon
然后在需要的位置通过setprop persist.sys.root_access 1 启动root服务
4、在external/sepolicy目录中增加xxxsu.te,增加对应的运行规则如下
type xxxsu_exec, exec_type, file_type;
type xxxsudaemon, domain;
# Domain used for su processes, as well as for adbd and adb shell
# after performing an adb root command. The domain definition is
# wrapped to ensure that it does not exist at all on -user builds.
type xxxsu, domain, mlstrustedsubject;
domain_auto_trans(xxxxxx, xxxsu_exec, xxxsu) #允许xxxxxx域执行xxxsu
# Make sure that dumpstate runs the same from the "su" domain as
# from the "init" domain.
# domain_auto_trans(su, dumpstate_exec, dumpstate)
# su is also permissive to permit setenforce.
permissive xxxsu;
permissive xxxsudaemon;
5、至此,编译userdebug版本,在Android app上,应该已经能够能够通过以下代码运行命令了
String [] finalcmd={"xxxsu","-c",cmd};
Runtime runtime = Runtime.getRuntime();
当切换至user版本时,由于各种sepolicy规则限制,APP方面会出现运行失败的情况,这就需要我们根据自己的App的用户类型,制定不同的规则,让指定类型的app能够有运行权限;