0%

Xposed注册系统服务

我们知道像 ClipboardManager, ActivityManager 实际上底层都是通过 Binder 以 aidl 接口的形式实现的,对应的服务端类名都是 xxxService 的形式,例如 ClipboardService, ActivityManagerService。幸运的是,在 Xposed 框架支持下,我们也可以注册自定义的系统服务。

系统服务注册流程分析

不想看源码分析过程的,可以直接跳到 自定义系统服务实现。

在这里以 API 27(Android 8.1) 的 ActivityManagerService 为例,ActivityManagerService 是系统主进程的开端,这个类是 “核心Java系统” 开始以及 “系统上下文” 创建的地方。

SystemServer 由 Zygote 进程 fork 而来,其进程名为 system_server,大概流程为:
ZygoteInit#main()
 -> Zygote#forkSystemServer()
  -> com_android_internal_os_Zygote#nativeForkSystemServer()
   -> com_android_internal_os_Zygote#ForkAndSpecializeCommon()
    -> ZygoteInit#handleSystemServerProcess()
     -> ZygoteInit#zygoteInit()
      -> RuntimeInit#applicationInit()
       -> RuntimeInit#findStaticMain()
        -> SystemServer#main()

关于 SystemServer 更详细的生成过程分析,请参看 Android系统启动-SystemServer上篇

下面分析 SystemServer 方法都做了什么:

  • SystemServer#main():

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public static void main(String[] args) {
    new SystemServer().run();
    }

    private void run() {
    // 创建主线程 Looper
    Looper.prepareMainLooper();
    // 创建系统Context
    createSystemContext();
    // 创建SystemServiceManager
    mSystemServiceManager = new SystemServiceManager(mSystemContext);

    // 启动各种系统服务
    // 1. 启动引导服务
    startBootstrapServices();
    // 2. 启动核心服务
    startCoreServices();
    // 3. 启动其他服务
    startOtherServices();

    Looper.loop();
    }
  • 创建系统Context - createSystemContext()

    1
    2
    3
    4
    5
    6
    7
    8
    private void createSystemContext() {
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

    final Context systemUiContext = activityThread.getSystemUiContext();
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    }

    关于 ActivityThread#systemMain() 中创建了 ActivityThread 对象,并调用其 attach 方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public static ActivityThread systemMain() {
    ActivityThread thread = new ActivityThread();
    thread.attach(true);
    }

    ActivityThread() {
    mResoureceManager = ResoureceManager.getInstance();
    }

    private void attach(boolean attach) {
    if(!system) {
    ...
    } else {
    // 系统Context
    android.ddm.DdmHandleAppName.setAppName("system_process",UserHandle.myUserId());
    mInstrumentation = new Instrumentation();
    ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
    mInitialApplication = context.mPackageInfo.makeApplication(true, null);
    mInitialApplication.onCreate();
    }
    }

    关于 Application 的创建过程,就不再分析了。

  • 启动引导服务 - startBootstrapServices()

    1
    2
    3
    4
    5
    // 初始化 ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
    ...
    // 设置系统进程
    mActivityManagerService.setSystemProcess();

    追踪 SystemServiceManager#startService:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public <T extends SystemService> T startService(Class<T> serviceClass) {
    final String name = serviceClass.getName();
    final T service;
    Constructor<T> constructor = serviceClass.getConstructor(Context.class);
    service = constructor.newInstance(mContext);
    startService(service);
    return service;
    }

    public void startService(final SystemService service) {
    service.onStart();
    }

    SystemServiceManager#startService() 最终会调用 SystemService 实现类的 onStart() 方法。

    也就是说,会调用 ActivityManagerService.Lifecycle#onStart() 方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public static final class Lifecycle extends SystemService {
    private final ActivityManagerService mService;
    public Lifecycle(Context context) {
    super(context);
    mService = new ActivityManagerService();
    }

    @Override
    public void onStart() {
    mService.start();
    }

    public ActivityManagerService getService() {
    return mService();
    }
    }

    最终会调用 ActivityManagerService 的构造方法和 start 方法,完成其初始化和初步配置。

    再看一下 ActivityManagerService#setSystemProcess():

    1
    2
    3
    4
    public void setSystemProcess() {
    ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
    ...
    }

    至此,ActivityServiceManager 作为系统服务被注册添加到 ServiceManager 当中。

自定义系统服务实现

  1. 自定义 ICustomService.aidl:

    1
    2
    3
    4
    5
    6
    7
    8
    package com.tianma.customsystemservice.aidl;

    interface ICustomService {
    /* toUppercase */
    String toUpperCase(String str);
    /* add numbers */
    int add(int num1, int num2);
    }
  2. 创建 ICustomService.aidl 的实现类 CustomService.java:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class CustomService extends ICustomService.Stub {
    @Override
    public String toUpperCase(String str) throws RemoteException {
    return str.toUpperCase();
    }

    @Override
    public int add(int num1, int num2) throws RemoteException {
    return num1 + num2;
    }
    }
  3. 创建 CustomServiceHook 类实现 IXposedHookZygoteInit,用来注册系统服务:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public class CustomServiceHook implements IXposedHookZygoteInit {
    @Override
    public void initZygote(StartupParam startupParam) throws Throwable {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // android 5.0+
    Class<?> activityThread = Class.forName("android.app.ActivityThread");
    XposedBridge.hookAllMethods(activityThread, "systemMain", new XC_MethodHook() {
    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    Class<?> ams = XposedHelpers.findClass("com.android.server.am.ActivityManagerService", classLoader);

    XposedHelpers.findAndHookConstructor(ams,
    Context.class,
    new XC_MethodHook() {
    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
    CustomService.register((Context) param.args[0], classLoader);
    }
    });
    }
    });
    } else {
    final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    Class<?> ams = XposedHelpers.findClass("com.android.server.am.ActivityManagerService", classLoader);
    XposedBridge.hookAllMethods(ams,
    "main",
    new XC_MethodHook() {
    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
    CustomService.register((Context) param.getResult(), classLoader);
    }
    });
    }
    }
    }

    上述代码中,ActivityManagerService 是系统主进程的开端,这个类是 “核心Java系统” 开始以及 “系统上下文” 创建的地方。在 Android L 之前,可以直接访问 ActivityManagerService 这个类;从 Android L 起系统使用了独立的类加载器(ClassLoader),需要先 Hook ActivityThread,因为 ActivityThread 中创建了可以用来访问 ActivityManagerService 的类加载器。

  4. CustomService 的 register() 方法用来注册系统服务:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public static void register(Context context, ClassLoader classLoader) {
    Class<?> svcManager = XposedHelpers.findClass("android.os.ServiceManager", classLoader);

    CustomService customService = new CustomService(context);
    XposedHelpers.callStaticMethod(svcManager,
    /* methodName */"addService",
    /* name */getServiceName(),
    /* service */ customService,
    /* allowIsolated */ true);

    log("register service succeed");
    }

    private static String getServiceName() {
    // 5.0 之后,selinux "user." 前缀
    return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? "user." : "") + "customservice";
    }

    其实就是通过调用 ServiceManager#addService() 来实现,需要注意的是,Android L 起,系统服务名需要加 user. 前缀。

完整的 CustomService 实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package com.tianma.customsystemservice.aidl;

import android.content.Context;
import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import java.lang.reflect.Method;

import de.robv.android.xposed.XposedHelpers;

public class CustomService extends ICustomService.Stub {
private static final String TAG = "CustomService";

private Context mContext;
private static ICustomService mClient;

private CustomService(Context context) {
mContext = context;
}

@Override
public String toUpperCase(String str) throws RemoteException {
return str.toUpperCase();
}

@Override
public int add(int num1, int num2) throws RemoteException {
return num1 + num2;
}

public static void register(Context context, ClassLoader classLoader) {
Class<?> svcManager = XposedHelpers.findClass("android.os.ServiceManager", classLoader);

CustomService customService = new CustomService(context);
XposedHelpers.callStaticMethod(svcManager,
/* methodName */"addService",
/* name */getServiceName(),
/* service */ customService,
/* allowIsolated */ true);

log("register service succeed");
}

private static String getServiceName() {
// 5.0 之后,selinux "user." 前缀
return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? "user." : "") + "customservice";
}

public static ICustomService getService() {
if (mClient == null) {
try {
Class<?> svcManager = Class.forName("android.os.ServiceManager");
Method getServiceMethod = svcManager.getDeclaredMethod("getService", String.class);
IBinder binder = (IBinder) getServiceMethod.invoke(null, getServiceName());
mClient = ICustomService.Stub.asInterface(binder);
} catch (Exception e) {
e.printStackTrace();
log(e);
}
}
return mClient;
}

private static void log(String text) {
Log.d(TAG, text);
}

private static void log(Throwable t) {
Log.e(TAG, Log.getStackTraceString(t));
}
}

调用:

1
2
3
4
5
ICustomService customService = CustomService.getService();
if (customService != null) {
int sum = customService.add(1, 2);
String upper = customService.toUpperCase("hello world");
}

完整示例源码:CustomSystemService

参考

Custom System Service using XposedBridge
XPrivacy - XPrivacy.java
Xposed Issue - classLoader ClassNotFoundException
Android系统启动-SystemServer上篇
Android系统启动-SystemServer下篇
基于xposed实现android注册系统服务,解决跨进程共享数据问题
使用Xposed添加自定义系统服务