三、使用 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(); } }