文章目录
一、项目中配置 OpenSSL 开源库
二、OpenSSL 开源库解密参考代码
三、解密 dex 文件的 Java 代码
四、解密 dex 文件的 Jni 代码
参考博客 :
【Android 安全】DEX 加密 ( 常用 Android 反编译工具 | apktool | dex2jar | enjarify | jd-gui | jadx )
【Android 安全】DEX 加密 ( Proguard 简介 | Proguard 相关网址 | Proguard 混淆配置 )
【Android 安全】DEX 加密 ( Proguard 简介 | 默认 ProGuard 分析 )
【Android 安全】DEX 加密 ( Proguard keep 用法 | Proguard 默认混淆结果 | 保留类及成员混淆结果 | 保留注解以及被注解修饰的类/成员/方法 )
【Android 安全】DEX 加密 ( Proguard 混淆 | 混淆后的报错信息 | Proguard 混淆映射文件 mapping.txt )
【Android 安全】DEX 加密 ( Proguard 混淆 | 将混淆后的报错信息转为原始报错信息 | retrace.bat 命令执行目录 | 暴露更少信息 )
【Android 安全】DEX 加密 ( DEX 加密原理 | DEX 加密简介 | APK 文件分析 | DEX 分割 )
【Android 安全】DEX 加密 ( 多 DEX 加载 | 65535 方法数限制和 MultiDex 配置 | PathClassLoader 类加载源码分析 | DexPathList )
【Android 安全】DEX 加密 ( 不同 Android 版本的 DEX 加载 | Android 8.0 版本 DEX 加载分析 | Android 5.0 版本 DEX 加载分析 )
【Android 安全】DEX 加密 ( DEX 加密使用到的相关工具 | dx 工具 | zipalign 对齐工具 | apksigner 签名工具 )
【Android 安全】DEX 加密 ( 支持多 DEX 的 Android 工程结构 )
【Android 安全】DEX 加密 ( 代理 Application 开发 | multiple-dex-core 依赖库开发 | 配置元数据 | 获取 apk 文件并准备相关目录 )
【Android 安全】DEX 加密 ( 代理 Application 开发 | 解压 apk 文件 | 判定是否是第一次启动 | 递归删除文件操作 | 解压 Zip 文件操作 )
【Android 安全】DEX 加密 ( 代理 Application 开发 | 加载 dex 文件 | 反射获取系统的 Element[] dexElements )
【Android 安全】DEX 加密 ( 代理 Application 开发 | 加载 dex 文件 | 使用反射获取方法创建本应用的 dexElements | 各版本创建 dex 数组源码对比 )
【Android 安全】DEX 加密 ( Java 工具开发 | 加密解密算法 API | 编译代理 Application 依赖库 | 解压依赖库 aar 文件 ) )
【Android 安全】DEX 加密 ( Java 工具开发 | 生成 dex 文件 | Java 命令行执行 )
【Android 安全】DEX 加密 ( Java 工具开发 | 解压 apk 文件 | 加密生成 dex 文件 | 打包未签名 apk 文件 | 文件解压缩相关代码 )
【Android 安全】DEX 加密 ( Java 工具开发 | apk 文件对齐 )
【Android 安全】DEX 加密 ( Java 工具开发 | apk 文件签名 )
【Android 安全】DEX 加密 ( 代理 Application 开发 | 交叉编译 OpenSSL 开源库 )
在 【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 文件 ;
在 【Android 安全】DEX 加密 ( Java 工具开发 | 生成 dex 文件 | Java 命令行执行 ) 博客中介绍 使用 SDK 中的 dx 工具生成 dex 文件 ;
在 【Android 安全】DEX 加密 ( Java 工具开发 | 解压 apk 文件 | 加密生成 dex 文件 | 打包未签名 apk 文件 | 文件解压缩相关代码 ) 博客中讲解 将 app 主应用的 apk 文件解压 , 加密其中的 classes.dex 文件 , 并将代理 Application 依赖库中的 classes.dex 打包到未签名的 apk 文件中 ;
在 【Android 安全】DEX 加密 ( Java 工具开发 | apk 文件对齐 ) 博客中讲解 apk 文件对齐操作 ;
在 【Android 安全】DEX 加密 ( Java 工具开发 | apk 文件签名 ) 博客中讲解 apk 签名 ;
在 【Android 安全】DEX 加密 ( 代理 Application 开发 | 交叉编译 OpenSSL 开源库 ) 博客中 交叉编译了 Android 平台使用的密码库 OpenSSL ;
本博客中开始使用 交叉编译后的 OpenSSL 密码库 解码 被加密的 dex 文件 ;
一、项目中配置 OpenSSL 开源库
拷贝头文件与函数库到 代理 Application 依赖库中 , 拷贝到 src/main/cpp 目录下即可 ;
配置 CMakeLists.txt 构建脚本
cmake_minimum_required(VERSION 3.4.1)
# 配置编译选项, 编译类型 动态库, C++ 源码为 native-lib.c add_library( openssl SHARED native-lib.c ) # 设置 openssl 函数库的静态库地址 set(LIB_DIR ${CMAKE_SOURCE_DIR}/lib/${ANDROID_ABI}) add_library(crypto STATIC IMPORTED) # 预编译 openssl 静态库 set_target_properties(crypto PROPERTIES IMPORTED_LOCATION ${LIB_DIR}/libcrypto.a) # 指定头文件路径 include_directories(include) # 链接动态库 target_link_libraries( openssl crypto log )
在 Module 下的 build.gradle 中配置 NDK 编译选项 , 主要是配置两个 externalNativeBuild , 一个在 android 下 , 一个在 defaultConfig 下 ;
apply plugin: 'com.android.library' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 29 buildToolsVersion "30.0.2" defaultConfig { minSdkVersion 16 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' externalNativeBuild{ cmake{ // 配置要编译动态库的 CPU 架构, 这里编译 arm 和 x86 两个版本的动态库 // arm64-v8a, armeabi-v7a, x86, x86_64 abiFilters 'armeabi-v7a','x86' } } } externalNativeBuild{ cmake{ // 配置编译的 CMake 脚本位置, 默认当前目录是 app 目录 // build.gradle 构建脚本所在目录 path 'src/main/cpp/CMakeLists.txt' } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.core:core-ktx:1.3.2' implementation project(path: ':multiple-dex-tools') testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' }