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

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

文章目录

Android 插件化系列文章目录

前言

一、Hook 实现思路

二、Hook 按钮点击事件

1、按钮点击事件

2、熟悉底层源码

3、获取 View 的 ListenerInfo mListenerInfo 成员

4、分析 Hook 点

5、反射 ListenerInfo 并设置新的 OnClickListener 监听器

三、完整代码示例

四、博客资源

前言

在上一篇博客 【Android 插件化】Hook 插件化框架 ( Hook 技术 | 代理模式 | 静态代理 | 动态代理 ) 中 , 对 Hook 技术进行了简要介绍 , Android 中的 Hook 技术主要是通过


反射

代理模式 ( 动态代理 / 静态代理 )


实现的 ;



之所以使用 Hook 技术 , 是因为反射系统的源码时 , 会出现问题 , Google 官方对 Android 的反射进行了限制 ;


反射出现问题时 , 必须找到一个可以反射的反射点挂钩子 , 如在 A 位置无法进行反射 , 就在 B 位置挂 Hook 钩子 ;



最终要实现的是使用 Hook , 影响 Activity 的启动流程 , 在启动流程中注入我们想要的业务逻辑 , 干涉启动流程 , 以达到能启动插件包 APK 中的 Activity 的目的 ;






一、Hook 实现思路


Hook 点选择规则 : Hook 技术的关键是找好 Hook 点 , 将钩子挂在哪 , 勾住哪个方法 , 需要遵循一定的规则 :


静态变量 / 单例 : 优先选择 静态变量 , 单例对象 , 这些对象一旦创建 , 基本不会改变 , 容易定位 ;



Hook 点实现思路 :


① 查找 Hook 点 : 用于下钩子 ;


② 选择代理模式 : 静态代理 / 动态代理 ;


③ 代理替换 : 通过反射 , 将钩子替换成开发者自定义的代理 , 一般是在原有调用的基础上 , 不影响原来功能的前提下 , 注入新的逻辑 ;






二、Hook 按钮点击事件



1、按钮点击事件


获取布局文件的按钮 , 并为其设置点击事件 , 该点击事件 public void onClick(View v) 就是需要 Hook 的方法 , 我们使用 Hook 技术 , 使用动态代理 , 替换掉该 onClick 方法 , 注入额外的业务逻辑 ;


// 获取按钮 , 并未按钮组件设置点击事件
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.i(TAG, "Button OnClickListener onClick");
    }
});



2、熟悉底层源码


使用 Hook 的前提是 , 必须熟悉要 Hook 功能的底层源码 , 如 : Hook 按钮点击事件 , 必须熟悉 View 组件的 OnClickListener 相关源码 ;


先分析 View 的 setOnClickListener 方法的源码 , 传入 OnClickListener l 监听器 , 将该监听器赋值给 getListenerInfo().mOnClickListener 值 ;


public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {
    @UnsupportedAppUsage
    ListenerInfo mListenerInfo;
    /**
     * Register a callback to be invoked when this view is clicked. If this view is not
     * clickable, it becomes clickable.
     *
     * @param l The callback that will run
     *
     * @see #setClickable(boolean)
     */
    public void setOnClickListener(@Nullable OnClickListener l) {
        if (!isClickable()) {
            setClickable(true);
        }
        getListenerInfo().mOnClickListener = l;
    }
    @UnsupportedAppUsage
    ListenerInfo getListenerInfo() {
        if (mListenerInfo != null) {
            return mListenerInfo;
        }
        mListenerInfo = new ListenerInfo();
        return mListenerInfo;
    }
}



如果要替换 按钮点击事件 , 可以反射 View 的 getListenerInfo() 方法 , 直接设置一个新的 点击监听器 ;



getListenerInfo().mOnClickListener = l;


// 获取 View 的 getListenerInfo 方法
Method getListenerInfo = null;
try {
    getListenerInfo = View.class.getDeclaredMethod("getListenerInfo");
} catch (NoSuchMethodException e) {
    e.printStackTrace();
}

位置作为钩子的 Hook 点 , 勾住该方法 ;



3、获取 View 的 ListenerInfo mListenerInfo 成员


先使用反射获取 View 组件的 getListenerInfo 方法 ;


// 获取 View 的 getListenerInfo 方法
Method getListenerInfo = null;
try {
    getListenerInfo = View.class.getDeclaredMethod("getListenerInfo");
} catch (NoSuchMethodException e) {
    e.printStackTrace();
}


设置 getListenerInfo 方法的可见性 , 之后要调用该方法 , 否则会报错 ;


// 执行所有的反射方法 , 设置成员变量 之前 , 都要设置可见性
getListenerInfo.setAccessible(true);


执行 反射获取的 getListenerInfo 方法 , 并获取 ListenerInfo mListenerInfo 成员 ;


// 执行 View view 对象的 getListenerInfo 方法
Object object = null;
try {
    object = getListenerInfo.invoke(view);
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}



目录
相关文章
|
3月前
|
物联网 区块链 vr&ar
未来已来:探索区块链、物联网与虚拟现实技术的融合与应用安卓与iOS开发中的跨平台框架选择
【8月更文挑战第30天】在科技的巨轮下,新技术不断涌现,引领着社会进步。本文将聚焦于当前最前沿的技术——区块链、物联网和虚拟现实,探讨它们各自的发展趋势及其在未来可能的应用场景。我们将从这些技术的基本定义出发,逐步深入到它们的相互作用和集成应用,最后展望它们如何共同塑造一个全新的数字生态系统。
|
15天前
|
算法 JavaScript Android开发
|
24天前
|
Java 程序员 API
Android|集成 slf4j + logback 作为日志框架
做个简单改造,统一 Android APP 和 Java 后端项目打印日志的体验。
93 1
|
2月前
|
前端开发 Java 数据库
💡Android开发者必看!掌握这5大框架,轻松打造爆款应用不是梦!🏆
在Android开发领域,框架犹如指路明灯,助力开发者加速应用开发并提升品质。本文将介绍五大必备框架:Retrofit简化网络请求,Room优化数据库访问,MVVM架构提高代码可维护性,Dagger 2管理依赖注入,Jetpack Compose革新UI开发。掌握这些框架,助你在竞争激烈的市场中脱颖而出,打造爆款应用。
347 3
|
2月前
|
编译器 Android开发 开发者
带你了解Android Jetpack库中的依赖注入框架:Hilt
本文介绍了Hilt,这是Google为Android开发的依赖注入框架,基于Dagger构建,旨在简化依赖注入过程。Hilt通过自动化的组件和注解减少了DI的样板代码,提高了应用的可测试性和可维护性。文章详细讲解了Hilt的主要概念、基本用法及原理,帮助开发者更好地理解和应用Hilt。
77 8
|
3月前
|
设计模式 Java Android开发
探索安卓应用开发:从新手到专家的旅程探索iOS开发中的SwiftUI框架
【8月更文挑战第29天】本文旨在通过一个易于理解的旅程比喻,带领读者深入探讨安卓应用开发的各个方面。我们将从基础概念入手,逐步过渡到高级技术,最后讨论如何维护和推广你的应用。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供有价值的见解和实用的代码示例。让我们一起开始这段激动人心的旅程吧!
|
3月前
|
Android开发
基于Amlogic 安卓9.0, 驱动简说(三):使用misc框架,让驱动更简单
如何使用Amlogic T972安卓9.0系统上的misc框架来简化驱动程序开发,通过misc框架自动分配设备号并创建设备文件,从而减少代码量并避免设备号冲突。
44 0
基于Amlogic 安卓9.0, 驱动简说(三):使用misc框架,让驱动更简单
|
Android开发
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(二)
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(二)
138 0
|
Android开发
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(三)
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(三)
269 0
|
Java Android开发
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(一)
【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )(一)
295 0