【Android 安全】DEX 加密 ( Java 工具开发 | 生成 dex 文件 | Java 命令行执行 )



参考博客 :


【Android 安全】DEX 加密 ( 支持多 DEX 的 Android 工程结构 ) 博客中介绍了 DEX 加密工程的基本结构 ,

app 是主应用 , 其 Module 类型是 “Phone & Tablet Module” ,

multiple-dex-core 是 Android 依赖库 , 其作用是解密并加载多 DEX 文件 , 其 Module 类型是 “Android Library” ,

multiple-dex-tools 是 Java 依赖库 , 其类型是 “Java or Kotlin Library” , 其作用是用于生成主 DEX ( 主 DEX 的作用就是用于解密与加载多 DEX ) , 并且还要为修改后的 APK 进行签名 ;


【Android 安全】DEX 加密 ( 代理 Application 开发 | multiple-dex-core 依赖库开发 | 配置元数据 | 获取 apk 文件并准备相关目录 ) 博客中讲解了 multiple-dex-core 依赖库开发 , 每次启动都要解密与加载 dex 文件 , 在该博客中讲解到了 获取 apk 文件 , 并准备解压目录 ;

【Android 安全】DEX 加密 ( 代理 Application 开发 | 解压 apk 文件 | 判定是否是第一次启动 | 递归删除文件操作 | 解压 Zip 文件操作 ) 博客中讲解了 apk 文件解压操作 ;

【Android 安全】DEX 加密 ( 代理 Application 开发 | 加载 dex 文件 | 反射获取系统的 Element[] dexElements )博客中讲解了 dex 文件加载第一阶段 , 获取系统中的 Element[] dexElements ;

【Android 安全】DEX 加密 ( 代理 Application 开发 | 加载 dex 文件 | 使用反射获取方法创建本应用的 dexElements | 各版本创建 dex 数组源码对比 ) 博客中讲解了讲解 dex 文件加载操作 第二阶段 , 创建本应用的 dex 文件数组 Element[] dexElements ;

【Android 安全】DEX 加密 ( 代理 Application 开发 | 加载 dex 文件 | 将系统的 dexElements 与 应用的 dexElements 合并 | 替换操作 ) 博客中讲解了剩余的两个操作 :

  • 系统加载的 Element[] dexElements 数组 与 我们 自己的 Element[] dexElements 数组 进行合并操作 ;
  • 替换 ClassLoader 加载过程中的 Element[] dexElements 数组 ( 封装在 DexPathList 中 )

【Android 安全】DEX 加密 ( Java 加密工具开发 | 加密解密算法 API | 编译代理 Application 依赖库 | 解压依赖库 aar 文件 ) ) 博客中介绍 加密解密算法 API , 编译代理 Application 依赖库 , 解压依赖库 aar 文件 ;


本博客中介绍 使用 SDK 中的 dx 工具生成 dex 文件 ;





一、生成 dex 文件



上一篇博客解压了 代理 Application 依赖库 multiple-dex-core-debug.aar , 并获取了其中的 classes.jar 文件 ;

现在开始使用 dx 命令 , 将其转为 dex 文件 ;

dx 具体用法参考 【Android 安全】DEX 加密 ( DEX 加密使用到的相关工具 | dx 工具 | zipalign 对齐工具 | apksigner 签名工具 ) 博客 ;


查看在 Android 应用 Module 下的 build.gradle 中使用的 buildToolsVersion 版本 , 30.0.2 , 之后我们要去 SDK 的 build-tools\30.0.2 目录下查找 dx.bat 工具 , 使用该工具将 classex.jar 转为 classes.dex 文件 ;

在这里插入图片描述


dx 工具的实际路径 : D:\001_Programs\001_Android\002_Sdk\Sdk\build-tools\30.0.2\dx.bat

在这里插入图片描述


在我的电脑上执行的完整命令行命令是 : D:/001_Programs/001_Android/002_Sdk/Sdk/build-tools/30.0.2/dx.bat –dex –output D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.dex D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.jar

D:/001_Programs/001_Android/002_Sdk/Sdk/build-tools/30.0.2/dx.bat --dex --output D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.dex D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.jar

上述命令中所有的 指令 文件 均没有使用环境变量 , 全部都是实际的绝对路径 ;

dx 工具路径 : D:/001_Programs/001_Android/002_Sdk/Sdk/build-tools/30.0.2/dx.bat

classes.jar 路径 ( 转换前的文件 ) : D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.jar

classes.dex 路径 ( 转换后的文件 ) : D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.dex


Windows 执行 DOS 命令行注意 : 命令之前需要加上 "cmd /c " 信息

Linux 与 MAC 命令行不用添加 , 直接使用命令即可 ;


Windows 中执行的完整命令是 :

cmd /c D:/001_Programs/001_Android/002_Sdk/Sdk/build-tools/30.0.2/dx.bat –dex –output D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.dex D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.jar





二、生成 dex 文件代码示例



创建 classes.jar ( dex 转换前的文件 ) , classes.dex ( dex转换后的文件 ) 文件对象 , 使用这两个文件对象获取完整路径 ;

    // 拿到 multiple-dex-core-debug.aar 中解压出来的 classes.jar 文件
    var classesJarFile = File(aarUnzip, "classes.jar")

    // 创建转换后的 dex 目的文件, 下面会开始创建该 dex 文件
    var classesDexFile = File(aarUnzip, "classes.dex")

Java 代码中调用命令行执行 : 使用 Runtime.getRuntime().exec("") 执行命令行 ;

    var process = Runtime.getRuntime().exec("cmd /c D:/001_Programs/001_Android/002_Sdk/Sdk/build-tools/30.0.2/dx.bat --dex --output ${classesDexFile.absolutePath} ${classesJarFile.absolutePath}")

等待命令行执行完毕 : process.waitFor() 等待执行完毕 ;

    // 等待上述命令执行完毕
    process.waitFor()

最后查看命令行执行结果 : 如果执行成功 , process.exitValue() 返回值为 0 , 反之不为 0 ;

    // 执行结果提示
    if(process.exitValue() == 0){
        println("执行成功");
    }else{
        println("执行失败");
    }

生成 dex 文件的完整代码 :

fun main() {
    /*
        1 . 生成 dex 文件 , 该 dex 文件中只包含解密 其它 dex 的功能

        编译工程
        会生成 Android 依赖库的 aar 文件
        生成目录是 module/build/outputs/aar/ 目录下

        前提是需要在 菜单栏 / File / Setting / Build, Execution, Deployment / Compiler
        设置界面中 , 勾选 Compile independent modules in parallel (may require larger )

        将 D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-core\build\outputs\aar
        路径下的 multiple-dex-core-debug.aar 文件后缀修改为 .zip
        解压上述文件
        拿到 classes.jar 文件即可 ;
     */

    // 获取 multiple-dex-core-debug.aar 文件对象
    var aarFile = File("multiple-dex-core/build/outputs/aar/multiple-dex-core-debug.aar")

    // 解压上述 multiple-dex-core-debug.aar 文件到 aarUnzip 目录中
    // 创建解压目录
    var aarUnzip = File("multiple-dex-tools/aarUnzip")
    // 解压操作
    unZipAar(aarFile, aarUnzip)

    // 拿到 multiple-dex-core-debug.aar 中解压出来的 classes.jar 文件
    var classesJarFile = File(aarUnzip, "classes.jar")

    // 创建转换后的 dex 目的文件, 下面会开始创建该 dex 文件
    var classesDexFile = File(aarUnzip, "classes.dex")

    // 打印要执行的命令
    println("cmd /c D:/001_Programs/001_Android/002_Sdk/Sdk/build-tools/30.0.2/dx.bat --dex --output ${classesDexFile.absolutePath} ${classesJarFile.absolutePath}")

    /*
        将 jar 包变成 dex 文件 
        使用 dx 工具命令

        注意 : Windows 命令行命令之前需要加上 "cmd /c " 信息 , Linux 与 MAC 命令行不用添加
     */
    var process = Runtime.getRuntime().exec("cmd /c D:/001_Programs/001_Android/002_Sdk/Sdk/build-tools/30.0.2/dx.bat --dex --output ${classesDexFile.absolutePath} ${classesJarFile.absolutePath}")
    // 等待上述命令执行完毕
    process.waitFor()

    // 执行结果提示
    if(process.exitValue() == 0){
        println("执行成功");
    }else{
        println("执行失败");
    }

}




三、生成 dex 结果



控制台打印结果 :

D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\bin\java.exe -javaagent:D:\001_Programs\001_Android\004_AndroidStudio_4.1\lib\idea_rt.jar=53488:D:\001_Programs\001_Android\004_AndroidStudio_4.1\bin -Dfile.encoding=UTF-8 -classpath D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\charsets.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\ext\access-bridge-64.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\ext\cldrdata.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\ext\dnsns.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\ext\jaccess.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\ext\localedata.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\ext\nashorn.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\ext\sunec.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\ext\sunjce_provider.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\ext\sunmscapi.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\ext\sunpkcs11.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\ext\zipfs.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\jce.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\jsse.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\management-agent.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\resources.jar;D:\001_Programs\001_Android\004_AndroidStudio_4.1\jre\jre\lib\rt.jar;D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\build\classes\kotlin\main;D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\build\libs\multiple-dex-tools.jar;C:\Users\octop\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-jdk7\1.3.61\70dffc5f8ac5ea7c34f30deac5b9d8b1d48af066\kotlin-stdlib-jdk7-1.3.61.jar;C:\Users\octop\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib\1.3.61\4702105e97f7396ae41b113fdbdc180ec1eb1e36\kotlin-stdlib-1.3.61.jar;C:\Users\octop\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib-common\1.3.61\65abb71d5afb850b68be03987b08e2c864ca3110\kotlin-stdlib-common-1.3.61.jar;C:\Users\octop\.gradle\caches\modules-2\files-2.1\org.jetbrains\annotations\13.0\919f0dfe192fb4e063e7dacadee7f8bb9a2672a9\annotations-13.0.jar kim.hsl.multiple_dex_tools.AESKt
cmd /c D:/001_Programs/001_Android/002_Sdk/Sdk/build-tools/30.0.2/dx.bat --dex --output D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.dex D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.jar
执行成功

Process finished with exit code 0

aar 文件解压及 dx 转换 :

下图中的 aarUnzip 是解压的结果 ; ( 蓝色矩形框 )

classes.dex 是将 aar 解压后的 classes.jar 转为 dex 的结果 , ( 红色矩形框 ) , 执行的命令是

cmd /c D:/001_Programs/001_Android/002_Sdk/Sdk/build-tools/30.0.2/dx.bat –dex –output D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.dex D:\002_Project\002_Android_Learn\DexEncryption\multiple-dex-tools\aarUnzip\classes.jar
在这里插入图片描述

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页