随着Android版本的不断升级,系统的安全性逐渐增强,导致之前在app或系统服务中可以被执行的sh脚本现在也无法运行了。本文总结了Android平台执行sh脚本的一种通用方式。
1、添加sh文件到 /system/bin 或 /vendor/bin 目录
#!/vendor/bin/sh
echo "preload color config start"
chmod 777 /data/local/config.xml
chown system.system /data/local/config.xml
...
2、在 /device/qcom/sepolicy/vendor/file_contexts 中给sh文件打安全标签(type)
# For preload color config xml
/(vendor|system/vendor)/bin/init\.preload\.colorconfig\.sh u:object_r:qti_init_shell_exec:s0
3、添加服务运行时的对应的安全域 (domain)
高通平台的sh脚本文件通常运行在 qti_init_shell 安全域,如果希望添加的脚本服务运行在这个安全域中,打安全标签时按照步骤2执行即可。
如果添加的脚本服务需要执行比较特殊的操作,就需要运行在自定义的安全域中,如 foo_domain,此时sh脚本文件的安全标签就应该是修改为 u:object_r:foo_domain_exec:s0。
# For preload color config xml
/(vendor|system/vendor)/bin/init\.preload\.colorconfig\.sh u:object_r:foo_domain_exec:s0
4、添加安全域 foo_domain
添加文件 /device/qcom/sepolicy/vendor/foo_domain.te
# foo domain
type foo_domain, domain;
type foo_domain_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(foo_domain)
#permissive foo_domain;
5、在 rc 文件中添加运行sh脚本的服务
# Exec init.preload.colorconfig.sh
service preload-cc-sh /vendor/bin/sh /vendor/bin/init.preload.colorconfig.sh
class late_start
user root
group system graphics
oneshot
disabled
6、启动脚本服务
在rc文件中启动 preload-cc-sh 服务
on property:sys.bootcompleted=1
start preload-cc-sh
在java文件中启动服务
SystemProperties.set("ctl.start", "preload-cc-sh");
7、添加te权限
步骤4中,在 foo_domain.te 文件中添加了 permissive foo_domain;语句,该语句使得脚本服务运行在permissive模式,同时输出脚本服务运行时的avc审计。然后我们就可以按照avc语句来添加te权限到 foo_domain.te 中。
调试完成后,记得注释掉 permissive 语句。
8、最后,不同Android平台和版本可能存在差异,不过这也是正常的,我们可以参考谷歌自带的sh服务。
在 /system/core/rootdir/init.rc 文件中。(源码才是最好的老师)
service flash_recovery /system/bin/install_recovery.sh
class main
oneshot