一个系统服务注入框架,允许绕过SELinux
策略以添加自定义服务到系统服务。
- 系统开发可以集成到
aosp
中作为framework
的一部分 - Xposed开发将服务注入到
framework
层供其他应用调用
在Android 5.0之后受限于SELinux
强制策略影响,因此在系统中添加服务需要修改sepolicy
策略这对毫无经验的开发者来说变的非常困难,因此有了XServiceManager
项目。你可以非常容易的添加自定义服务到系统中用来提供给其他应用使用。 XServiceManager
通过劫持托管了系统clipboard
服务,你的服务实际上是由XServiceManager
托管而不是真正的添加到系统的ServiceManager
中,因此当需要使用自定义服务必须通过XServiceManager
接口调用。
Android 5.0+
这里仅介绍
xposed
集成的方法aosp
集成的方法类似请自行研究
-
将
XServiceManager
项目克隆至项目根目录下git clone https://github.com/kaisar945/XServiceManager.git libxservicemanager
-
打开主工程中的
build.gradle
文件在dependencies
部分添加implementation project(path: ':libxservicemanager')
依赖 -
编写自定义服务
-
在
Xposed
初始化类中确认当前进程为system_server
进程后添加初始化代码并添加自定义服务-
不依赖系统服务和
Context
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) { if("android".equals(lpparam.packageName)){ XServiceManager.initForSystemServer(); XServiceManager.addService("simple", new SimpleService()); } }
-
依赖系统服务和
Context
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) { if("android".equals(lpparam.packageName)){ XServiceManager.initForSystemServer(); XServiceManager.registerService("simple2", new XServiceManager.ServiceFetcher<Binder>() { @Override public Binder createService(Context ctx) { return new SimpleService2(ctx); } }); } }
-
-
在其他应用中使用自定义服务
提示:在注入失败的情况下获取到的服务对象为
null
,因此在使用服务之前请始终检查服务对象- 使用XServiceManager类的
getService
或getServiceInterface
获取服务对象
IBinder binder = XServiceManager.getService("simple"); if(binder != null){ ISimpleService service = ISimpleService.Stub.asInterface(binder); service.doSomething(); }
// 使用getServiceInterface函数获取服务请确保服务接口未被混淆 -keep class com.your.ISimpleService$* {*;} ISimpleService service = XServiceManager.getServiceInterface("simple"); if(service != null){ service.doSomething(); }
- 使用XServiceManager类的
因为自定义服务在system_server
进程中运行因此拥有系统最高权限,请确保在设计之初考虑到服务的安全性和稳定性否则可能会导致设备运行不稳定
-
无法调用自定义服务
过滤
XServiceManager
日志检查是否有如下logXServiceManager inject success
如未发现注入成功提示应该会有一些其他的异常提示请检查是否是因为自定义服务引起的如果不是恭喜你发现了一个BUG请提交issue给我
-
自定义服务中存储数据文件
自定义服务默认属于
system
用户组受SELinux
限制无法/data/system
以外的路径存储数据,因此你可以选择在该目录创建一个专有目录用于存放数据。 -
调用服务出现
TransactionTooLargeException
该错误是由
IPC
数据缓冲区限制引起该限制大约为1Mb
请避免大数据交换