DroidPlugin Hook机制之AMS&PMS简述

java中反射的作用

从源码分析一个应用中有多少个Context实例

DroidPlugin Hook机制之AMS&PMS简述_第1张图片
image.png

概述


ActivityManagerService对于FrameWork层的重要性不言而喻,Android的四大组件无一不与它打交道:

  • startActivity最终调用了AMS的startActivity系列方法,实现了Activity的启动;Activity的生命周期回调,也在AMS中完成;
  • startService,bindService最终调用到AMS的startService和bindService方法;
  • 动态广播的注册和接收在AMS中完成(静态广播在PMS中完成)
  • getContentResolver最终从AMS的getContentProvider获取到ContentProvider

而PMS则完成了诸如权限校捡(checkPermission,checkUidPermission),Apk meta信息获取(getApplicationInfo等),四大组件信息获取(query系列方法)等重要功能。

AMS


一篇AMS介绍

DroidPlugin Hook机制之AMS&PMS简述_第2张图片
2279655-b6048677817fb7fc.png

IActivityManager对应自定义的接口,ActivityManagerNative对应Stub,

涉及的关键类:

Context的启动流程:

  • Context.startActivity
  • ContextWrapper.startActivity
  • ContextImpl.startActivity
  • Instrumentation.execStartActivity
  • ActivityManagerNative.getDefault().startActivity

Activity的启动流程:

  • Activity.startActivity
  • Activity.startActivityForResult
  • Instrumentation.execStartActivity(同上)
  • 之后同Context方式
Hook过程
  • ActivityManagerNative.class中反射得到静态属性:gDefault,它是Singleton
            Class activityManagerNativeClass = Class.forName("android.app.ActivityManagerNative");

            // 获取 gDefault 这个字段, 想办法替换它
            Field gDefaultField = activityManagerNativeClass.getDeclaredField("gDefault");
            gDefaultField.setAccessible(true);

            Object gDefault = gDefaultField.get(null);
  • gDefault中反射得到IAcitvityManager实例
            Class singleton = Class.forName("android.util.Singleton");
            Field mInstanceField = singleton.getDeclaredField("mInstance");
            mInstanceField.setAccessible(true);

            // ActivityManagerNative 的gDefault对象里面原始的 IActivityManager对象
            Object rawIActivityManager = mInstanceField.get(gDefault);
  • 动态代理
  • 将hook过的IActivityManager重新设置到Singleton中

PMS


同Activity一样,也是有两种方式获取:Context 和 Activity
ContextImpl.java

public PackageManager getPackageManager() {
    if (mPackageManager != null) {
        return mPackageManager;
    }

    IPackageManager pm = ActivityThread.getPackageManager();
    if (pm != null) {
        // Doesn't matter if we make more than one instance.
        return (mPackageManager = new ApplicationPackageManager(this, pm));
    }
    return null;
}

ActivityThread.java

public static IPackageManager getPackageManager() {
    if (sPackageManager != null) {
        return sPackageManager;
    }
    IBinder b = ServiceManager.getService("package");
    sPackageManager = IPackageManager.Stub.asInterface(b);
    return sPackageManager;
}

那么需要hook的,就是ActivityThread的静态属性sPackageManager和ContextImpl的mPackageManager属性了。

你可能感兴趣的:(DroidPlugin Hook机制之AMS&PMS简述)