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

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

文章目录

Android 插件化系列文章目录

前言

一、合并 “插件包“ 与 “宿主“ 中的 Element[] dexElements

1、获取 “插件包“ 与 “宿主“ 中的 Element[] dexElements 数组长度

2、获取数组元素类型 Element

3、计算合并后的 Element[] dexElements 数组长度

4、创建 Element[] 数组

5、拷贝 Element[] 数组元素

6、完整代码

二、设置 “宿主“ 中的 Element[] dexElements

三、完整代码示例

四、博客资源

前言

在 【Android 插件化】Hook 插件化框架 ( 通过反射获取 “插件包“ 中的 Element[] dexElements ) 博客中介绍了从 " 插件包 " APK 文件中获取 Element[] dexElements 流程 ;


在上一篇博客 【Android 插件化】Hook 插件化框架 ( 通过反射获取 “宿主“ 应用中的 Element[] dexElements ) 介绍了从 " 宿主 " 应用中获取 Element[] dexElements 流程 ;


本篇博客中开始将 " 插件包 " APK 中的 Element[] dexElements 和 “宿主“ 应用中的 Element[] dexElements 合并 ;






一、合并 “插件包“ 与 “宿主“ 中的 Element[] dexElements


将两个 Element[] dexElements 数组合并 , 合并完成后 , 设置到 PathClassLoader 中的 DexPathList pathList 成员的 Element[] dexElements 成员中 ;



1、获取 “插件包“ 与 “宿主“ 中的 Element[] dexElements 数组长度


调用 Java 提供的 Array API 中的 getLength 方法 , 获取数组长度 ;


// 获取 “宿主“ 中的 Element[] dexElements 数组长度
int host_dexElementsLength = Array.getLength(host_dexElementsObject);
// 获取 “插件包“ 中的 Element[] dexElements 数组长度
int plugin_dexElementsLength = Array.getLength(plugin_dexElementsObject);



2、获取数组元素类型 Element


获取 Element[] dexElements 数组中的 , 数组元素的 Element 类型 , 获取的是 Element.class ;


// 获取 Element[] dexElements 数组中的 , 数组元素的 Element 类型
// 获取的是 Element.class
Class<?> elementClazz = host_dexElementsObject.getClass().getComponentType();


3、计算合并后的 Element[] dexElements 数组长度


// 合并后的 Element[] dexElements 数组长度
int new_dexElementsLength = plugin_dexElementsLength + host_dexElementsLength;



4、创建 Element[] 数组


创建 Element[] 数组 , elementClazz 是 Element.class 数组元素类型 ;


// 创建 Element[] 数组 , elementClazz 是 Element.class 数组元素类型
Object newElementsArray = Array.newInstance(elementClazz, new_dexElementsLength);



5、拷贝 Element[] 数组元素


为新的 Element[] newElementsArray 数组赋值 , 先将 “插件包“ 中的 Element[] dexElements 数组放入到新数组中 , 然后将 “宿主“ 中的 Element[] dexElements 数组放入到新数组中 ;


//  为新的 Element[] newElementsArray 数组赋值
//      先将 “插件包“ 中的 Element[] dexElements 数组放入到新数组中
//      然后将 “宿主“ 中的 Element[] dexElements 数组放入到新数组中
for (int i = 0; i < new_dexElementsLength; i++) {
    if (i < plugin_dexElementsLength) {
        // “插件包“ 中的 Element[] dexElements 数组放入到新数组中
        Array.set(newElementsArray, i, Array.get(plugin_dexElementsObject, i));
    } else {
        //  “宿主“ 中的 Element[] dexElements 数组放入到新数组中
        Array.set(newElementsArray, i, Array.get(host_dexElementsObject, i - plugin_dexElementsLength));
    }
}



6、完整代码


完整代码 :


   

// 3. 合并 “插件包“ 与 “宿主“ 中的 Element[] dexElements
        // 将两个 Element[] dexElements 数组合并 ,
        //  合并完成后 , 设置到 PathClassLoader 中的
        //  DexPathList pathList 成员的 Element[] dexElements 成员中
        // 获取 “宿主“ 中的 Element[] dexElements 数组长度
        int host_dexElementsLength = Array.getLength(host_dexElementsObject);
        // 获取 “插件包“ 中的 Element[] dexElements 数组长度
        int plugin_dexElementsLength = Array.getLength(plugin_dexElementsObject);
        // 获取 Element[] dexElements 数组中的 , 数组元素的 Element 类型
        // 获取的是 Element.class
        Class<?> elementClazz = host_dexElementsObject.getClass().getComponentType();
        // 合并后的 Element[] dexElements 数组长度
        int new_dexElementsLength = plugin_dexElementsLength + host_dexElementsLength;
        // 创建 Element[] 数组 , elementClazz 是 Element.class 数组元素类型
        Object newElementsArray = Array.newInstance(elementClazz, new_dexElementsLength);
        //  为新的 Element[] newElementsArray 数组赋值
        //      先将 “插件包“ 中的 Element[] dexElements 数组放入到新数组中
        //      然后将 “宿主“ 中的 Element[] dexElements 数组放入到新数组中
        for (int i = 0; i < new_dexElementsLength; i++) {
            if (i < plugin_dexElementsLength) {
                // “插件包“ 中的 Element[] dexElements 数组放入到新数组中
                Array.set(newElementsArray, i, Array.get(plugin_dexElementsObject, i));
            } else {
                //  “宿主“ 中的 Element[] dexElements 数组放入到新数组中
                Array.set(newElementsArray, i, Array.get(host_dexElementsObject, i - plugin_dexElementsLength));
            }
        }


目录
相关文章
|
4小时前
|
监控 安全 Android开发
【新手必读】Airtest测试Android手机常见的设置问题
【新手必读】Airtest测试Android手机常见的设置问题
|
4小时前
|
存储 Java Android开发
Android系统 设置第三方应用为默认Launcher实现和原理分析
Android系统 设置第三方应用为默认Launcher实现和原理分析
51 0
|
4小时前
|
Java Shell Android开发
Android11 有线网和wifi优先级设置
Android11 有线网和wifi优先级设置
14 0
|
4小时前
|
Java Android开发
Android 设置系统时区的源码追踪
Android 设置系统时区的源码追踪
12 1
|
4小时前
|
Android开发
安卓逆向 -- Hook多个dex文件
安卓逆向 -- Hook多个dex文件
23 1
|
4小时前
|
算法 安全 Android开发
安卓逆向 -- Frida Hook某车_sign算法分析
安卓逆向 -- Frida Hook某车_sign算法分析
79 0
|
4小时前
|
Shell Android开发 数据安全/隐私保护
安卓逆向 -- Frida环境搭建(HOOK实例)
安卓逆向 -- Frida环境搭建(HOOK实例)
60 0
|
4小时前
|
存储 安全 Android开发
安卓应用开发:构建一个高效的用户登录系统
【5月更文挑战第3天】在移动应用开发中,用户登录系统的设计与实现是至关重要的一环。对于安卓平台而言,一个高效、安全且用户体验友好的登录系统能够显著提升应用的用户留存率和市场竞争力。本文将探讨在安卓平台上实现用户登录系统的最佳实践,包括对最新身份验证技术的应用、安全性考量以及性能优化策略。
|
4小时前
|
前端开发 Android开发 iOS开发
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
【4月更文挑战第30天】Flutter 框架实现跨平台移动应用,通过一致的 UI 渲染(Skia 引擎)、热重载功能和响应式框架提高开发效率和用户体验。然而,Android 和 iOS 的系统差异、渲染机制及编译过程影响性能。性能对比显示,iOS 可能因硬件优化提供更流畅体验,而 Android 更具灵活性和广泛硬件支持。开发者可采用代码、资源优化和特定平台优化策略,利用性能分析工具提升应用性能。
【Flutter前端技术开发专栏】Flutter在Android与iOS上的性能对比
|
4小时前
|
Java Android开发
Android开发--Intent-filter属性详解
Android开发--Intent-filter属性详解
10 0