当前位置:首页 > CN2资讯 > 正文内容

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

2天前CN2资讯
Android 插件化系列文章目录

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

【Android 插件化】“ 插桩式 “ 插件化框架 ( 原理与实现思路 )
【Android 插件化】“ 插桩式 “ 插件化框架 ( 类加载器创建 | 资源加载 )
【Android 插件化】“ 插桩式 “ 插件化框架 ( 注入上下文的使用 )
【Android 插件化】“ 插桩式 “ 插件化框架 ( 获取插件入口 Activity 组件 | 加载插件 Resources 资源 )
【Android 插件化】“ 插桩式 “ 插件化框架 ( 运行应用 | 代码整理 )

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


文章目录

  • Android 插件化系列文章目录
  • 前言
  • 一、Hook 技术简介
  • 二、代理机制
    • 1、静态代理示例
    • 2、动态代理示例
  • 三、博客资源

前言

在之前的系列博客中 , 介绍了 " 插桩式 " 插件化框架 , 该框架存在一些问题 :

开发需要定制 : " 插件 " 模块中的 Activity 必须集成 BaseActivity , 其中很多操作都需要针对该方式进行 定制化开发 , 与开发普通的应用完全不同 ;

没有真正的上下文环境 : " 插件 " 模块内部 , 调用 Activity 组件的 getApplicationContext 方法会出现问题 , 因为 插件内部没有真正的供应用运行的上下文环境 ;

( 之前的 " 插桩式 " 插件化框架 , 只是简单示例 , 远远达不到能在项目中使用的复杂程度 )


插件化框架 的最终目的是让 " 插件 " 模块的开发和使用 , 与正常的应用开发和使用达到完全一致的效果 , " 宿主 " 模块 与 " 插件 " 模块 之间可以 无障碍通信 ;






一、Hook 技术简介

Hook 技术 又称为 钩子技术 , 同样 Hook 函数 也称为 钩子函数 ; 钩子技术 在 系统入侵 中 , 广泛使用 ;

Hook 技术 没有硬性规定技术标准 , 只是一种 技术概念 ; 在某一段代码的运行流程中 , 挂入自定义的钩子 , 在钩子的 前面 , 后面 , 可以 插入任意自定义的操作代码 , 达到 业务注入 的目的 ;


Hook 技术可以理解为 面向切面编程思想 , 想办法在不修改源码的前提下 , 在某个方法调用之前 , 插入自己的代码 , 业务逻辑 ,


Android 中的 Hook 技术 : 通过分析 Android 系统源码执行 , 通过 动态注入技术 , 在代码运行的某个阶段 , 注入开发者自定义的代码 ;


常用的动态注入技术 :

① 编译时修改字节码数据 : 代码编译时修改 Class 字节码数据 , 如 Dagger ;

② 运行时修改字节码数据 : 运行时可以修改字节码文件数据 , 达到代码入侵的效果 ;


Android 中的 Hook 机制 , 主要涉及到下面两种技术 :

① 反射机制 : Java 反射机制 ;

② 代理机制 : 动态代理 , 静态代理 ;





二、代理机制

代理机制 :

存在一个 目标对象 Subject 和 代理者 Proxy ;

目标对象 Subject 执行一些业务逻辑 , 代理者 Proxy 持有 目标对象 Subject , 当 目标对象 Subject 要执行某个方法时 , 通过 代理者 Proxy 调用 目标对象 Subject 中的方法执行 ;

代理者 Proxy 调用 目标对象 Subject 方法 之前 , 之后 , 可以插入自己的业务逻辑 ;


下面简要介绍 静态代理 与 动态代理 ;


1、静态代理示例


定义代理方法接口 : 代理者 和 目标对象 都要实现该接口 , 代理者 和 目标对象 可以进行相互替换 ;

/** * 代理者 和 目标对象 都要实现该接口 * 代理者 可以替换 目标对象 */ public interface AInterface { void request(); }

目标对象 : 被代理的目标对象 , 实现了

/** * 被代理的目标对象 * 目标对象 Subject 执行一些业务逻辑 * 代理者 Proxy 持有 目标对象 Subject * 当目标对象 Subject 要执行某个方法时 * 通过 代理者 Proxy 调用 目标对象 Subject 中的方法执行 */ public class Subject implements AInterface { /** * 目标对象的业务逻辑 */ @Override public void request() { System.out.println("Subject request"); } }

代理者 :

/** * 代理者 * 目标对象 Subject 执行一些业务逻辑 * 代理者 Proxy 持有 目标对象 Subject * 当目标对象 Subject 要执行某个方法时 * 通过 代理者 Proxy 调用 目标对象 Subject 中的方法执行 */ public class Proxy implements AInterface { /** * 代理者 持有的 目标对象 */ private Subject subject; public Proxy(Subject subject) { this.subject = subject; } /** * 当 Subject 需要执行 request 方法时 , 自己不直接执行 * 而是通过 Proxy 的该方法调用 持有的 目标对象 Subject 来执行 */ @Override public void request() { before(); subject.request(); after(); } /** * 执行 Subject 目标对象的 request 方法前执行的业务逻辑 */ private void before() { System.out.println("Proxy before"); } /** * 执行 Subject 目标对象的 request 方法后执行的业务逻辑 */ private void after() { System.out.println("Proxy after"); } }

main 函数调用 : 通过代理者调用目标对象中的类 , 并在执行目标对象 Subject 的 request 方法时 , 对该方法进行逻辑增强 ;

① 方式一 :

public class Main { public static void main(String[] args) { // 1. 创建目标对象 Subject subject = new Subject(); // 2. 创建代理类 Proxy proxy = new Proxy(subject); // 3. 通过代理类调用目标对象的方法 proxy.request(); /* 代理类的作用 : 执行 目标对象 Subject 的 request 方法时 , 对该方法进行逻辑增强 ; */ } }

② 方式二 :

public class Main { public static void main(String[] args) { /* 下面的这种用法, 不需要关注目标对象 只需要了解 Proxy 代理者 调用者不了解目标对象的内部实现细节 目标对象也不了解调用者 */ AInterface aInterface = new Proxy(new Subject()); aInterface.request(); } }

执行结果 :

Proxy before Subject request Proxy after

2、动态代理示例


动态代理接口 :

/** * 代理者 需要实现的接口 * 该接口就是动态代理接口 */ public interface AInterface { void request(); }

目标对象 : 被代理的目标对象 , 需要实现代理接口 ;

public class Subject implements AInterface { @Override public void request() { System.out.println("Subject request"); } }

InvocationHandler 实现 : 这是 Hook 钩子 , 用于向被代理的目标对象的目标方法中注入业务逻辑 ;

import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class AInvocationHandler implements InvocationHandler { /** * 被代理的对象 */ Object target; public AInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); Object object = method.invoke(target, args); after(); return object; } /** * 被代理对象方法调用之前执行 */ private void before(){ System.out.println("AInvocationHandler before"); } /** * 被代理对象方法调用之后执行 */ private void after(){ System.out.println("AInvocationHandler after"); } }

动态代理执行 main 函数 :

import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Main { public static void main(String[] args) { // 1. 创建目标对象 Subject subject = new Subject(); // 2. 获取目标对象类加载器 ClassLoader classLoader = subject.getClass().getClassLoader(); // 3. 获取接口 Class 数组, Subject 只实现了一个 AInterface 接口 Class<?>[] interfaces = subject.getClass().getInterfaces(); // 4. 创建 InvocationHandler , 传入被代理的目标对象 , 处理该目标对象中被代理的函数 InvocationHandler invocationHandler = new AInvocationHandler(subject); // 5. 动态代理 : // ① jdk 根据传入的参数信息 , 在内存中动态的创建 与 .class 字节码文件等同的字节码数据 // ② 将字节码数据 转为 对应的 字节码类型 // ③ 使用反射调用 newInstance 创建动态代理实例 AInterface proxy = (AInterface) Proxy.newProxyInstance( classLoader, interfaces, invocationHandler); // 正式调用被动态代理的类 proxy.request(); } }

执行结果 :

AInvocationHandler before Subject request AInvocationHandler after



三、博客资源

博客资源 :

  • GitHub :
    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/24704.html

    分享给朋友:

    “【Android 插件化】Hook 插件化框架 ( Hook 技术 | 代理模式 | 静态代理 | 动态代理 )hook插件是什么” 的相关文章

    宝塔安装扩展不生效的解决方案与技巧

    在服务器管理的世界中,宝塔面板无疑是一款强大而受欢迎的工具。它让用户以更简单的方式进行服务器管理。通过宝塔,用户可以轻松管理网站、数据库和各种扩展。而PHPExcel等PHP扩展的安装显得尤为重要,因为它们提供了许多强大的功能,助力网站正常运行。 PHP扩展的重要性不言而喻。没有合适的扩展,网站可能...

    JustHost优惠码大揭秘:节省开支的绝佳办法

    JustHost概述 我对JustHost的了解始于它的多样化主机产品和用户友好的服务。JustHost成立于2006年,作为一家俄罗斯主机商,它提供虚拟主机、VPS服务器以及独立服务器,是一个值得关注的选择。JustHost不仅拥有丰富的技术背景,还致力于为用户提供高性价比的服务,这让我对它充满了...

    狗云实名认证的重要性与服务体验

    狗云简介 提起狗云(Dogyun),首先让我想起的是它在国内主机服务商中崭露头角的那段经历。成立于2019年,这家由国人创办的云服务平台,积极响应了市场对高质量、低价格VPS服务的需求。服务范围覆盖美国、日本和中国香港等地,让不少技术爱好者和企业客户看到了更多选择的可能。由于其价格相对亲民,狗云逐渐...

    PacificRack低价VPS服务评测与用户体验分析

    在云计算和虚拟主机服务日益普及的今天,PacificRack作为QuadraNET旗下的全资子品牌,逐渐在低价VPS市场中崭露头角。它的主要定位是为那些对性能要求不高,且对价格敏感的用户提供解决方案。PacificRack通过严格的资源管理,致力于为用户提供一种经济实惠的选择,适合希望以最低成本体验...

    QQ邮箱服务器完全指南:配置、安全性与优化技巧

    QQ邮箱服务器概述 QQ邮箱是由腾讯公司推出的一款广受欢迎的电子邮件服务。它的优势不仅在于强大的存储容量,还有丰富的功能,适合个人和企业用户使用。很多人都习惯使用QQ邮箱来发送、接收邮件,因此有必要了解其背后的邮件服务器。 在我使用QQ邮箱的过程中,发现它使用的是腾讯自家搭建的邮件服务器。这些服务器...

    详细指南:如何进行Linux扩容以解决存储不足问题

    什么是Linux扩容? 在使用Linux操作系统时,随着数据的增加,我们常常面临磁盘空间不足的问题。Linux扩容就是通过添加新的磁盘、扩展现有磁盘容量或利用逻辑卷管理(LVM)等方式,来增加系统的存储空间。扩容可以帮助我更好地管理数据,提高服务器的运行效率。 我记得第一次接触扩容时,面对不断增加的...