【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(二)

简介: 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(二)

三、使用 Hook 技术在主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件



1、反射获取 ActivityThread 类


     

// 反射获取 ActivityThread 类
        Class<?> activityThreadClass = null;
        try {
            activityThreadClass = Class.forName("android.app.ActivityThread");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }



2、反射获取 ActivityThread 单例对象


   

// Activity Thread 是一个单例 , 内部的单例成员是
        // private static volatile ActivityThread sCurrentActivityThread;
        // 可以直接通过 ActivityThread 类 , 获取该单例对象
        // 这也是 Hook 点优先找静态变量的原因 , 静态变量对象容易拿到 , 通过反射即可获取 , 不涉及系统源码相关操作
        Field sCurrentActivityThreadField = null;
        try {
            sCurrentActivityThreadField = activityThreadClass.getDeclaredField("sCurrentActivityThread");
            // 反射获取的字段一般都要设置可见性
            sCurrentActivityThreadField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        // 获取类的静态变量 , 使用 字段.get(null) 即可
        Object activityThreadObject = null;
        try {
            activityThreadObject = sCurrentActivityThreadField.get(null);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }



3、反射获取 mH 字段


     

// 获取 Activity Thread 中的 final H mH = new H() 成员字段 ;
        Field mHField = null;
        try {
            mHField = activityThreadClass.getDeclaredField("mH");
            // 设置该字段的可见性
            mHField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }



4、反射获取 mH 对象


     

// 通过反射获取 Activity Thread 中的 final H mH = new H() 成员实例对象
        Handler mHObject = null;
        try {
            mHObject = (Handler) mHField.get(activityThreadObject);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }



5、反射获取 Handler 中的 mCallback 字段


   

Class<?> handlerClass = null;
        try {
            handlerClass = Class.forName("android.os.Handler");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        // 通过反射获取 final H mH = new H() 成员的 mCallback 成员字段
        // Handler 中有成员变量 final Callback mCallback;
        Field mCallbackField = null;
        try {
            //mCallbackField = handlerClass.getDeclaredField("mCallback");
            mCallbackField = mHObject.getClass().getDeclaredField("mCallback");
            // 设置字段的可见性
            mCallbackField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }



6、通过反射替换 Handler 中的 mCallback 成员


   

// 使用静态代理类 HandlerProxy , 替换 final H mH = new H() 成员实例对象中的 mCallback 成员
        HandlerProxy proxy = new HandlerProxy();
        try {
            Log.i(TAG, "mCallbackField : " + mCallbackField + " , mHObject : " + mHObject + " , proxy : " + proxy);
            mCallbackField.set(mHObject, proxy);
        } catch (Exception e) {
            e.printStackTrace();
        }



7、完整代码示例


/**
     * 劫持 Activity Thread 的 final H mH = new H(); 成员
     * 该成员类型是 class H extends Handler ;
     * @param context
     */
    public static void hookActivityThread(Context context) {
        // 反射获取 ActivityThread 类
        Class<?> activityThreadClass = null;
        try {
            activityThreadClass = Class.forName("android.app.ActivityThread");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        // Activity Thread 是一个单例 , 内部的单例成员是
        // private static volatile ActivityThread sCurrentActivityThread;
        // 可以直接通过 ActivityThread 类 , 获取该单例对象
        // 这也是 Hook 点优先找静态变量的原因 , 静态变量对象容易拿到 , 通过反射即可获取 , 不涉及系统源码相关操作
        Field sCurrentActivityThreadField = null;
        try {
            sCurrentActivityThreadField = activityThreadClass.getDeclaredField("sCurrentActivityThread");
            // 反射获取的字段一般都要设置可见性
            sCurrentActivityThreadField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        // 获取类的静态变量 , 使用 字段.get(null) 即可
        Object activityThreadObject = null;
        try {
            activityThreadObject = sCurrentActivityThreadField.get(null);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        // 获取 Activity Thread 中的 final H mH = new H() 成员字段 ;
        Field mHField = null;
        try {
            mHField = activityThreadClass.getDeclaredField("mH");
            // 设置该字段的可见性
            mHField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        // 通过反射获取 Activity Thread 中的 final H mH = new H() 成员实例对象
        Handler mHObject = null;
        try {
            mHObject = (Handler) mHField.get(activityThreadObject);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        Class<?> handlerClass = null;
        try {
            handlerClass = Class.forName("android.os.Handler");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        // 通过反射获取 final H mH = new H() 成员的 mCallback 成员字段
        // Handler 中有成员变量 final Callback mCallback;
        Field mCallbackField = null;
        try {
            //mCallbackField = handlerClass.getDeclaredField("mCallback");
            mCallbackField = mHObject.getClass().getDeclaredField("mCallback");
            // 设置字段的可见性
            mCallbackField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        // 使用静态代理类 HandlerProxy , 替换 final H mH = new H() 成员实例对象中的 mCallback 成员
        HandlerProxy proxy = new HandlerProxy();
        try {
            Log.i(TAG, "mCallbackField : " + mCallbackField + " , mHObject : " + mHObject + " , proxy : " + proxy);
            mCallbackField.set(mHObject, proxy);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



目录
相关文章
|
1月前
|
SQL 人工智能 Dart
Android Studio的插件生态非常丰富
Android Studio的插件生态非常丰富
58 1
|
7月前
|
缓存 程序员 定位技术
Android Studio 插件,那些被大厂优化的程序员们
Android Studio 插件,那些被大厂优化的程序员们
|
人工智能 移动开发 Java
Android Studio插件版本与Gradle 版本对应关系
Android Studio插件版本与Gradle 版本对应关系
2569 0
Android Studio插件版本与Gradle 版本对应关系
|
Java 开发工具 Android开发
Cocos Creator 2.4.6 Android Gradle 版本升级为 6.5.1(插件4.1.0)
Cocos Creator 2.4.6 Android Gradle 版本升级为 6.5.1(插件4.1.0)
329 1
|
2月前
|
Android开发
我是一位Android工程师,用通义灵码的AS插件做开发工作助手,对比之前没有灵码,现在提效了60%
我是一位Android工程师,用通义灵码的AS插件做开发工作助手,对比之前没有灵码,现在提效了60%
80 0
|
6月前
|
Java Linux API
微信API:探究Android平台下Hook技术的比较与应用场景分析
微信API:探究Android平台下Hook技术的比较与应用场景分析
|
7月前
|
缓存 Android开发
Android插件化——高手必备的Hook技术,零基础开发android
Android插件化——高手必备的Hook技术,零基础开发android
|
7月前
|
XML Dart Java
Flutter插件开发之APK自动安装,字节跳动Android岗面试题
Flutter插件开发之APK自动安装,字节跳动Android岗面试题
|
7月前
|
Android开发
安卓逆向 -- Hook多个dex文件
安卓逆向 -- Hook多个dex文件
69 1