【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 反射获取 IActivityManager 对象 )
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 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | Hook 点分析 ) 中分析了 Activity 启动过程中的 Hook 点 ;
本篇博客中开始进行 Hook Activity 的操作 ;
一、反射相关源码说明
1、Instrumentation
在 Instrumentation 中的 execStartActivity 方法 , 在最后 , 通过如下代码 , 启动 Activity ;
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 ;
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 类是单例的实现 , 注意该类只能由系统使用 , 应用开发者不能调用 ;
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 类 ;
反射代码 :
// 获取 android.app.ActivityManager 类
Class<?> activityManagerClass = null;
try {
activityManagerClass = Class.forName("android.app.ActivityManager");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2、反射获取 IActivityManagerSingleton 字段
获取 ActivityManager 类中的 的 IActivityManagerSingleton 成员字段 , 下面是该字段的完整声明 ; 注意凡是涉及到字段获取 , 一般都要设置其可见性为 true ; ( 一般情况下 , 只有非 public 的字段才需要使用反射方式获取 )
private static final Singleton<IActivityManager> IActivityManagerSingleton
反射代码 :
// 获取 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 即可获取 ;
// 获取 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> 类型的 ,
private static final Singleton<IActivityManager> IActivityManagerSingleton
通过反射获取 android.util.Singleton 类 ;
// 获取 Singleton 类
// ActivityManager 中的 IActivityManagerSingleton 成员是 Singleton<IActivityManager> 类型的
Class<?> singletonClass = null;
try {
singletonClass = Class.forName("android.util.Singleton");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
5、反射获取 mInstance 字段
// 反射获取 Singleton 类中的 mInstance 字段
Field mInstanceField = null;
try {
mInstanceField = singletonClass.getDeclaredField("mInstance");
// 设置字段的可访问性
mInstanceField.setAccessible(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
6、反射获取 mInstance 字段
反射获取 Singleton 类中的 mInstance 成员对象 , 该 mInstanceObject 成员对象就是 IActivityManager ;
// 反射获取 Singleton 类中的 mInstance 成员对象
// 该 mInstanceObject 成员对象就是 IActivityManager
// private static final Singleton<IActivityManager> IActivityManagerSingleton
Object mInstanceObject = null;
try {
mInstanceObject = mInstanceField.get(iActivityManagerSingletonObject);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
三、完整代码
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();
}
}
}
四、博客资源
博客资源 :
相关文章
- Android系统启动流程 -- 学习笔记
- android 常用加密,分享一下Android各种类型的加密
- (七十)Android O Service启动流程梳理——bindService
- android deeplink流程,Android Deeplink探究[通俗易懂]
- android进阶之了解Android系统与开机过程
- android 定时器实例,Android定时器和Handler用法实例分析
- android短信验证码方案,Android开发之属于你的短信验证码(一)
- android scaleanimation动画,Android 的ScaleAnimation 缩放动画基本运用
- android触摸屏事件,Android Touch事件分析
- android activitymanager 系统api_Android view
- eclipse中android开发_Android开发教程
- Android Services Library_android freeware
- Android 数据库加密 android-database-sqlcipher 开源版本编译过程
- Android 用户态启动流程分析
- 【Android 性能优化】应用启动优化 ( 启动白屏问题 | 应用启动时间测量 | 冷启动 | 热启动 | 应用启动时间计算源码分析 )
- 【Android 高性能音频】Oboe 开发流程 ( 导入 Oboe 库 | 使用预构建的二进制库和头文件 | 编译 Oboe 源码 )
- 【Android 异步操作】线程池 ( Worker 简介 | 线程池中的工作流程 runWorker | 从线程池任务队列中获取任务 getTask )
- 【Android 高性能音频】Oboe 开发流程 ( Oboe 音频帧简介 | AudioStreamCallback 中的数据帧说明 )
- 【Android 安装包优化】资源混淆 ( 资源混淆效果 | APK 构建流程简介 | 资源 ID 组成 )
- 【Android 逆向】Android 系统中文件的用户和分组 ( 文件所有者与分组 | /sdcard/ 的文件分组 | /data/ 目录分析 | 用户类型 )
- 【Android 逆向】加壳的 Android 应用启动流程 | 使用反射替换 LoadedApk 中的类加载器流程
- 【错误记录】Android Studio 集成 ARoute 编译报错 ( 兼容 support 库和 androidx 库 | add ‘tools:replace=“android:appCo )
- WiFi协议曝安全漏洞,影响Linux、Android和iOS
- [android] 看博客学习Android常见的几种RuntimeException详解手机开发
- 基于Android-28 的源码 Activity 启动流程分析详解手机开发
- 亚马逊应用商店太拉胯:Win11的Android应用支持计划前景不明朗
- Android获取通话时间实例分析
- 解析Android中实现滑动翻页之ViewFlipper的使用详解
- Android执行shell命令详解
- android工程下不能运行javamain程序的解决方法
- Android中扫描多媒体文件操作详解