Skip to content

Latest commit

 

History

History
108 lines (73 loc) · 10.9 KB

README_zh.md

File metadata and controls

108 lines (73 loc) · 10.9 KB

XServiceManager

English

这是什么

一个系统服务注入框架,允许绕过SELinux策略以添加自定义服务到系统服务。

使用场景

  • 系统开发可以集成到aosp中作为framework的一部分
  • Xposed开发将服务注入到framework层供其他应用调用

工作原理

在Android 5.0之后受限于SELinux强制策略影响,因此在系统中添加服务需要修改sepolicy策略这对毫无经验的开发者来说变的非常困难,因此有了XServiceManager项目。你可以非常容易的添加自定义服务到系统中用来提供给其他应用使用。 XServiceManager通过劫持托管了系统clipboard服务,你的服务实际上是由XServiceManager托管而不是真正的添加到系统的ServiceManager中,因此当需要使用自定义服务必须通过XServiceManager接口调用。

支持版本

Android 5.0+

如何使用

这里仅介绍xposed集成的方法aosp集成的方法类似请自行研究

  1. XServiceManager项目克隆至项目根目录下git clone https://github.com/kaisar945/XServiceManager.git libxservicemanager

  2. 打开主工程中的build.gradle文件在dependencies部分添加implementation project(path: ':libxservicemanager')依赖

  3. 编写自定义服务

  4. Xposed初始化类中确认当前进程为system_server进程后添加初始化代码并添加自定义服务

    1. 不依赖系统服务和Context

      public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) {
          if("android".equals(lpparam.packageName)){
              XServiceManager.initForSystemServer();
              XServiceManager.addService("simple", new SimpleService());
          }
      }
    2. 依赖系统服务和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);
                  }
              });    
          }
      }
  5. 在其他应用中使用自定义服务

    提示:在注入失败的情况下获取到的服务对象为null,因此在使用服务之前请始终检查服务对象

    • 使用XServiceManager类的getServicegetServiceInterface获取服务对象
    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();
    }

注意事项

因为自定义服务在system_server进程中运行因此拥有系统最高权限,请确保在设计之初考虑到服务的安全性和稳定性否则可能会导致设备运行不稳定

常见问题

  • 无法调用自定义服务

    过滤XServiceManager日志检查是否有如下log

    XServiceManager inject success
    

    如未发现注入成功提示应该会有一些其他的异常提示请检查是否是因为自定义服务引起的如果不是恭喜你发现了一个BUG请提交issue给我

  • 自定义服务中存储数据文件

    自定义服务默认属于system用户组受SELinux限制无法/data/system以外的路径存储数据,因此你可以选择在该目录创建一个专有目录用于存放数据。

  • 调用服务出现TransactionTooLargeException

    该错误是由IPC数据缓冲区限制引起该限制大约为1Mb请避免大数据交换