首页 > 编程知识 正文

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

时间:2023-05-04 13:14:22 阅读:118101 作者:4078

Android插件化系列文章目录【Android插件化】插件化介绍(组件化和插件化) ) ) ) ) ) ) ) ) )。

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

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

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

【Android插件化】“插件表达式“插件化框架|创建类加载器|资源加载”

【安卓插件】“插件表达式”插件框架(使用注入上下文)

【Android插件】“插件表达式插件框架”(获取插件门户活动组件|加载插件资源)

【Android插件化】“插件表达式”“插件化框架|执行APP |代码整理”

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

文章目录安卓插件系列文章目录前言1、Hook技术简介2、代理机制1、静态代理范例2、动态代理范例3、博客资源

前言在以前的系列博客中,介绍了“打桩式”插件化框架,该框架存在一些问题:

开发需要定制 :'插件'模块的Activity需要与BaseActivity集成,其中许多模块需要根据这种方式定制开发,与常规的APP应用程序开发完全不同;

在33558 www.Sina.com/'插件'模块中调用Activity组件的getApplicationContext方法时,插件中为实际预配而运行的上下文

(以前的“插件表达式”插件框架只是一个简单的示例,远远不及项目中可用的复杂性。)

插件框架的最终目的是使“插件”模块的开发和使用与常规APP应用程序开发和使用完全匹配,从而可以在“主机”模块和“插件”模块之间无障碍地进行通信;

另一方面,Hook技术简介Hook技术也称为钩子技术,同样Hook函数也称为钩子函数; 挂钩技术在系统入侵中被广泛使用;

Hook技术没有硬性规定技术标准,只是技术概念; 在一个代码的执行过程中,可以挂上定制的挂钩,在挂钩的前、后,插入任意定制的操作码,达到业务注入的目的;

Hook技术可以理解为面向切片的编程思想,我们正在寻找在调用某个方法之前插入自己的代码、业务逻辑而不修改源代码的方法

通过分析33558www.Sina.com/Android系统的源代码执行,通过动态注入技术,在代码执行的某个阶段,注入开发者定制的代码;

没有真正的上下文环境 :

Android 中的 Hook 技术 :在代码编译时修改类字节码数据,如Dagger;

常用的动态注入技术 :运行时可以修改字节码文件数据,以达到代码入侵的效果;

安卓的Hook机制主要涉及以下两种技术:

编译时修改字节码数据 :Java反射机制;

运行时修改字节码数据 :动态代理、静态代理;

二、代理机构 反射机制 :

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

目标对象Subject运行一些业务逻辑,代理Proxy具有目标对象Subject,并且在尝试运行具有目标对象Subject的方法时,将代理Proxy

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

代理机制 :

1、静态代理示例代理机制 :代理和目标对象都必须实现该接口,代理和目标对象可以相互交换;

/**代理和目标对象都必须实现此接口。 *代理是目标对象*/publicinterfaceainterface { 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 beforeSubject requestProxy 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 beforeSubject requestAInvocationHandler after



三、博客资源

博客资源 :

GitHub :

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。