【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 反射获取 IActivityManager 对象 )

2023-03-29 15:22:23 浏览数 (1)

Android 插件化系列文章目录

【Android 插件化】插件化简介 ( 组件化与插件化 )

【Android 插件化】插件化原理 ( JVM 内存数据 | 类加载流程 )

【Android 插件化】插件化原理 ( 类加载器 )

【Android 插件化】“ 插桩式 “ 插件化框架 ( 原理与实现思路 )

【Android 插件化】“ 插桩式 “ 插件化框架 ( 类加载器创建 | 资源加载 )

【Android 插件化】“ 插桩式 “ 插件化框架 ( 注入上下文的使用 )

【Android 插件化】“ 插桩式 “ 插件化框架 ( 获取插件入口 Activity 组件 | 加载插件 Resources 资源 )

【Android 插件化】“ 插桩式 “ 插件化框架 ( 运行应用 | 代码整理 )

【Android 插件化】Hook 插件化框架 ( Hook 技术 | 代理模式 | 静态代理 | 动态代理 )

【Android 插件化】Hook 插件化框架 ( Hook 实现思路 | Hook 按钮点击事件 )

【Android 插件化】Hook 插件化框架 ( Hook Activity 启动过程 | 静态代理 )

【Android 插件化】Hook 插件化框架 ( 从 Hook 应用角度分析 Activity 启动流程 一 | Activity 进程相关源码 )

【Android 插件化】Hook 插件化框架 ( 从 Hook 应用角度分析 Activity 启动流程 二 | AMS 进程相关源码 | 主进程相关源码 )

【Android 插件化】Hook 插件化框架 ( hook 插件化原理 | 插件包管理 )

【Android 插件化】Hook 插件化框架 ( 通过反射获取 “插件包“ 中的 Element[] dexElements )

【Android 插件化】Hook 插件化框架 ( 通过反射获取 “宿主“ 应用中的 Element[] dexElements )

【Android 插件化】Hook 插件化框架 ( 合并 “插件包“ 与 “宿主“ 中的 Element[] dexElements | 设置合并后的 Element[] 数组 )

【Android 插件化】Hook 插件化框架 ( 创建插件应用 | 拷贝插件 APK | 初始化插件包 | 测试插件 DEX 字节码 )

【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 )

【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 反射获取 IActivityManager 对象 )


文章目录

  • Android 插件化系列文章目录
  • 前言
  • 一、反射相关源码说明
    • 1、Instrumentation
    • 2、ActivityManager
    • 3、Singleton
  • 二、反射获取 IActivityManager 对象
    • 1、反射获取 ActivityManager 类
    • 2、反射获取 IActivityManagerSingleton 字段
    • 3、反射获取 IActivityManagerSingleton 对象
    • 4、反射获取 Singleton 类
    • 5、反射获取 mInstance 字段
    • 6、反射获取 mInstance 字段
  • 三、完整代码
  • 四、博客资源

前言

在上一篇博客 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 ) 中分析了 Activity 启动过程中的 Hook 点 ;

本篇博客中开始进行 Hook Activity 的操作 ;


一、反射相关源码说明


1、Instrumentation

在 Instrumentation 中的 execStartActivity 方法 , 在最后 , 通过如下代码 , 启动 Activity ;

代码语言:javascript复制
public class Instrumentation {
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
            
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
                        
	}
}

源码路径 : /frameworks/base/core/java/android/app/Instrumentation.java

2、ActivityManager

ActivityManager.getService() 是静态方法 , 只要反射 ActivityManager 类之后 , 就可以直接调用该 getService 静态方法 ;

ActivityManager 中的 IActivityManagerSingleton 成员是 Singleton<IActivityManager> 类型的 , 其中的单例变量是 mInstance ;

代码语言:javascript复制
public class ActivityManager {
    /**
     * @hide
     */
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };
}

源码路径 : /frameworks/base/core/java/android/app/ActivityManager.java

3、Singleton

Singleton 类是单例的实现 , 注意该类只能由系统使用 , 应用开发者不能调用 ;

代码语言:javascript复制
package android.util;

/**
 * Singleton helper class for lazily initialization.
 *
 * Modeled after frameworks/base/include/utils/Singleton.h
 *
 * @hide
 */
public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

源码路径 : /frameworks/base/core/java/android/util/Singleton.java

二、反射获取 IActivityManager 对象


1、反射获取 ActivityManager 类

首先反射获取 获取 android.app.ActivityManager 类 ;

反射代码 :

代码语言:javascript复制
// 获取 android.app.ActivityManager 类
Class<?> activityManagerClass = null;
try {
    activityManagerClass = Class.forName("android.app.ActivityManager");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

2、反射获取 IActivityManagerSingleton 字段

获取 ActivityManager 类中的 的 IActivityManagerSingleton 成员字段 , 下面是该字段的完整声明 ; 注意凡是涉及到字段获取 , 一般都要设置其可见性为 true ;

( 一般情况下 , 只有非 public 的字段才需要使用反射方式获取 )

代码语言:javascript复制
private static final Singleton<IActivityManager> IActivityManagerSingleton 

反射代码 :

代码语言:javascript复制
// 获取 android.app.ActivityManager 类 中的 IActivityManagerSingleton 属性
// private static final Singleton<IActivityManager> IActivityManagerSingleton 成员变量
Field iActivityManagerSingletonField = null;
try {
    iActivityManagerSingletonField =
            activityManagerClass.getDeclaredField("IActivityManagerSingleton");
    // 设置成员字段的可访问性
    iActivityManagerSingletonField.setAccessible(true);
} catch (NoSuchFieldException e) {
    e.printStackTrace();
}

3、反射获取 IActivityManagerSingleton 对象

获取 android.app.ActivityManager 类的静态成员变量 , 直接调用 Field 字段 iActivityManagerSingletonField 的 get 方法 , 传入 null 即可获取 ;

代码语言:javascript复制
// 获取 android.app.ActivityManager 类的静态成员变量
// private static final Singleton<IActivityManager> IActivityManagerSingleton
// 直接调用 Field 字段 iActivityManagerSingletonField 的 get 方法 , 传入 null 即可获取
Object iActivityManagerSingletonObject = null;
try {
    iActivityManagerSingletonObject = iActivityManagerSingletonField.get(null);
} catch (IllegalAccessException e) {
    e.printStackTrace();
}

4、反射获取 Singleton 类

在 ActivityManager 中 , IActivityManagerSingleton 成员是 Singleton<IActivityManager> 类型的 ,

代码语言:javascript复制
private static final Singleton<IActivityManager> IActivityManagerSingleton

通过反射获取 android.util.Singleton 类 ;

代码语言:javascript复制
// 获取 Singleton 类
// ActivityManager 中的 IActivityManagerSingleton 成员是 Singleton<IActivityManager> 类型的
Class<?> singletonClass = null;
try {
    singletonClass = Class.forName("android.util.Singleton");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

5、反射获取 mInstance 字段

代码语言:javascript复制
// 反射获取 Singleton 类中的 mInstance 字段
Field mInstanceField = null;
try {
    mInstanceField = singletonClass.getDeclaredField("mInstance");
    // 设置字段的可访问性
    mInstanceField.setAccessible(true);
} catch (NoSuchFieldException e) {
    e.printStackTrace();
}

6、反射获取 mInstance 字段

反射获取 Singleton 类中的 mInstance 成员对象 , 该 mInstanceObject 成员对象就是 IActivityManager ;

代码语言:javascript复制
// 反射获取 Singleton 类中的 mInstance 成员对象
// 该 mInstanceObject 成员对象就是 IActivityManager
// private static final Singleton<IActivityManager> IActivityManagerSingleton
Object mInstanceObject = null;
try {
    mInstanceObject = mInstanceField.get(iActivityManagerSingletonObject);
} catch (IllegalAccessException e) {
    e.printStackTrace();
}

三、完整代码


代码语言:javascript复制
package kim.hsl.plugin;

import java.lang.reflect.Field;

/**
 * 主要职责 : Hook Activity 的启动过程
 * 本工具类只针对 API Level 28 实现 , 如果是完整插件化框架 , 需要实现所有版本的 Hook 过程
 * 不同的版本 , Activity 的启动过程是不同的 , 需要逐个根据 Activity 启动源码进行 Hook 适配
 */
public class HookUtils {

    /**
     * 最终目的是劫持 ActivityManagerService 的 startActivity 方法 ,
     *      修改 Intent 中药启动的 Activity 类
     */
    public static void hookAms(){
        // 获取 android.app.ActivityManager 类
        Class<?> activityManagerClass = null;
        try {
            activityManagerClass = Class.forName("android.app.ActivityManager");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        // 获取 android.app.ActivityManager 类 中的 IActivityManagerSingleton 属性
        // private static final Singleton<IActivityManager> IActivityManagerSingleton 成员变量
        Field iActivityManagerSingletonField = null;
        try {
            iActivityManagerSingletonField =
                    activityManagerClass.getDeclaredField("IActivityManagerSingleton");
            // 设置成员字段的可访问性
            iActivityManagerSingletonField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        // 获取 android.app.ActivityManager 类的静态成员变量
        // private static final Singleton<IActivityManager> IActivityManagerSingleton
        // 直接调用 Field 字段 iActivityManagerSingletonField 的 get 方法 , 传入 null 即可获取
        Object iActivityManagerSingletonObject = null;
        try {
            iActivityManagerSingletonObject = iActivityManagerSingletonField.get(null);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        // 获取 Singleton 类
        // ActivityManager 中的 IActivityManagerSingleton 成员是 Singleton<IActivityManager> 类型的
        Class<?> singletonClass = null;
        try {
            singletonClass = Class.forName("android.util.Singleton");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        // 反射获取 Singleton 类中的 mInstance 字段
        Field mInstanceField = null;
        try {
            mInstanceField = singletonClass.getDeclaredField("mInstance");
            // 设置字段的可访问性
            mInstanceField.setAccessible(true);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        // 反射获取 Singleton 类中的 mInstance 成员对象
        // 该 mInstanceObject 成员对象就是 IActivityManager
        // private static final Singleton<IActivityManager> IActivityManagerSingleton
        Object mInstanceObject = null;
        try {
            mInstanceObject = mInstanceField.get(iActivityManagerSingletonObject);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

}

四、博客资源

博客资源 :

  • GitHub : https://github.com/han1202012/Plugin_Hook

0 人点赞