【Android 安全】DEX 加密 ( 代理 Application 开发 | 交叉编译 OpenSSL 开源库 )
文章目錄
- 一、OpenSSL 開源庫簡介
- 二、OpenSSL 源碼及環境變量腳本下載
- 三、修改環境變量腳本
- 四、OpenSSL 交叉編譯
- 五、OpenSSL 交叉編譯相關資源下載
參考博客 :
- 【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 加密 ( 支持多 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 簽名 ;
一、OpenSSL 開源庫簡介
OpenSSL 是開源密碼庫 , 其中封裝了常用的 密碼算法 , 常用密鑰 , 證書封裝管理 , SSL 協議 ;
SSL : 全稱 Secure Sockets Layer , 安全套接層協議 , 提供網絡中的保密傳輸功能 ;
參考簡介 : 百度百科-OpenSSL
OpenSSL 官網 : https://www.openssl.org/
OpenSSL Wiki 頁面 : https://wiki.openssl.org/index.php/Main_Page
OpenSSL Wiki Android 編譯頁面 : https://wiki.openssl.org/index.php/Android
OpenSSL 源碼下載地址 : https://www.openssl.org/source/
GitHub 地址 : https://www.openssl.org/source/
二、OpenSSL 源碼及環境變量腳本下載
參考 OpenSSL Wiki Android 編譯頁面 : https://wiki.openssl.org/index.php/Android ;
需要準備兩個文件 :
- 源碼文件 : 文檔中提示下載 openssl-1.0.1g.tar.gz 版本的 OpenSSL , 在 https://www.openssl.org/source/old/1.0.1/ 頁面可以查看 1.0.1 版本的歷史源碼 ; 也可以嘗試下載其它版本進行交叉編譯 ;
- 編譯腳本 : setenv-android.sh , 以下是編譯腳本內容 , 編譯腳本中主要是進行一些環境變量配置 ;
將上述兩個文件都放在同一個目錄中 ;
三、修改環境變量腳本
修改 Setenv-android.sh 腳本中的如下選項 :
_ANDROID_NDK : NDK 版本 , 如 android-ndk-r8e ; 如果設置了 ANDROID_NDK_ROOT 環境變量 , 該選項可以不用設置 ;
_ANDROID_NDK="android-ndk-r17c"ANDROID_NDK_ROOT : 指定 NDK 路徑 , 如果配置了該路徑 , 可以忽略上面的 _ANDROID_NDK 配置 ;
# 這里如果用戶沒有指定 ANDROID_NDK_ROOT NDK 工具根目錄 , 就執行下面的邏輯, # 如果指定了, 就沒有下面代碼什么事了 # 這里指定下該環境變量 , 上面的 _ANDROID_NDK 變量也失去了相應作用 export ANDROID_NDK_ROOT=/root/NDK/android-ndk-r17c_ANDROID_ARCH : 編譯的 CPU 架構 , arch-x86 , arch-arm ;
_ANDROID_ARCH=arch-arm_ANDROID_EABI : 交叉編譯器 , 如 arm-linux-androideabi-4.6, arm-linux-androideabi-4.8, x86-4.6 or x86-4.8 ; 配置前到 NDK 目錄下的 toolchains 中查看要使用哪個版本的交叉編譯工具 , 該配置一定要從 NDK 目錄中查找 ;
_ANDROID_EABI="arm-linux-androideabi-4.9"_ANDROID_API : 最低 Android 版本 , 如 android-14 , android-18 ;
_ANDROID_API="android-18"修改后的 setenv-android.sh 腳本 :
#!/bin/bash # Cross-compile environment for Android on ARMv7 and x86 # # Contents licensed under the terms of the OpenSSL license # http://www.openssl.org/source/license.html # # See http://wiki.openssl.org/index.php/FIPS_Library_and_Android # and http://wiki.openssl.org/index.php/Android###################################################################### Set ANDROID_NDK_ROOT to you NDK location. For example, # /opt/android-ndk-r8e or /opt/android-ndk-r9. This can be done in a # login script. If ANDROID_NDK_ROOT is not specified, the script will # try to pick it up with the value of _ANDROID_NDK_ROOT below. If # ANDROID_NDK_ROOT is set, then the value is ignored. # _ANDROID_NDK="android-ndk-r8e" _ANDROID_NDK="android-ndk-r17c" # _ANDROID_NDK="android-ndk-r10"# Set _ANDROID_EABI to the EABI you want to use. You can find the # list in $ANDROID_NDK_ROOT/toolchains. This value is always used. # _ANDROID_EABI="x86-4.6" # _ANDROID_EABI="arm-linux-androideabi-4.6" _ANDROID_EABI="arm-linux-androideabi-4.9"# Set _ANDROID_ARCH to the architecture you are building for. # This value is always used. # _ANDROID_ARCH=arch-x86 _ANDROID_ARCH=arch-arm# Set _ANDROID_API to the API you want to use. You should set it # to one of: android-14, android-9, android-8, android-14, android-5 # android-4, or android-3. You can't set it to the latest (for # example, API-17) because the NDK does not supply the platform. At # Android 5.0, there will likely be another platform added (android-22?). # This value is always used. # _ANDROID_API="android-14" _ANDROID_API="android-18" # _ANDROID_API="android-19"###################################################################### If the user did not specify the NDK location, try and pick it up. # We expect something like ANDROID_NDK_ROOT=/opt/android-ndk-r8e # or ANDROID_NDK_ROOT=/usr/local/android-ndk-r8e.# 這里如果用戶沒有指定 ANDROID_NDK_ROOT NDK 工具根目錄 , 就執行下面的邏輯, # 如果指定了, 就沒有下面代碼什么事了 # 這里指定下該環境變量 , 上面的 _ANDROID_NDK 變量也失去了相應作用 export ANDROID_NDK_ROOT=/root/NDK/android-ndk-r17cif [ -z "$ANDROID_NDK_ROOT" ]; then_ANDROID_NDK_ROOT=""if [ -z "$_ANDROID_NDK_ROOT" ] && [ -d "/usr/local/$_ANDROID_NDK" ]; then_ANDROID_NDK_ROOT="/usr/local/$_ANDROID_NDK"fiif [ -z "$_ANDROID_NDK_ROOT" ] && [ -d "/opt/$_ANDROID_NDK" ]; then_ANDROID_NDK_ROOT="/opt/$_ANDROID_NDK"fiif [ -z "$_ANDROID_NDK_ROOT" ] && [ -d "$HOME/$_ANDROID_NDK" ]; then_ANDROID_NDK_ROOT="$HOME/$_ANDROID_NDK"fiif [ -z "$_ANDROID_NDK_ROOT" ] && [ -d "$PWD/$_ANDROID_NDK" ]; then_ANDROID_NDK_ROOT="$PWD/$_ANDROID_NDK"fi# If a path was set, then export itif [ ! -z "$_ANDROID_NDK_ROOT" ] && [ -d "$_ANDROID_NDK_ROOT" ]; thenexport ANDROID_NDK_ROOT="$_ANDROID_NDK_ROOT"fi fi# Error checking # ANDROID_NDK_ROOT should always be set by the user (even when not running this script) # http://groups.google.com/group/android-ndk/browse_thread/thread/a998e139aca71d77 if [ -z "$ANDROID_NDK_ROOT" ] || [ ! -d "$ANDROID_NDK_ROOT" ]; thenecho "Error: ANDROID_NDK_ROOT is not a valid path. Please edit this script."# echo "$ANDROID_NDK_ROOT"# exit 1 fi# Error checking if [ ! -d "$ANDROID_NDK_ROOT/toolchains" ]; thenecho "Error: ANDROID_NDK_ROOT/toolchains is not a valid path. Please edit this script."# echo "$ANDROID_NDK_ROOT/toolchains"# exit 1 fi# Error checking if [ ! -d "$ANDROID_NDK_ROOT/toolchains/$_ANDROID_EABI" ]; thenecho "Error: ANDROID_EABI is not a valid path. Please edit this script."# echo "$ANDROID_NDK_ROOT/toolchains/$_ANDROID_EABI"# exit 1 fi###################################################################### Based on ANDROID_NDK_ROOT, try and pick up the required toolchain. We expect something like: # /opt/android-ndk-r83/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86_64/bin # Once we locate the toolchain, we add it to the PATH. Note: this is the 'hard way' of # doing things according to the NDK documentation for Ice Cream Sandwich. # https://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.htmlANDROID_TOOLCHAIN="" for host in "linux-x86_64" "linux-x86" "darwin-x86_64" "darwin-x86" doif [ -d "$ANDROID_NDK_ROOT/toolchains/$_ANDROID_EABI/prebuilt/$host/bin" ]; thenANDROID_TOOLCHAIN="$ANDROID_NDK_ROOT/toolchains/$_ANDROID_EABI/prebuilt/$host/bin"breakfi done# Error checking if [ -z "$ANDROID_TOOLCHAIN" ] || [ ! -d "$ANDROID_TOOLCHAIN" ]; thenecho "Error: ANDROID_TOOLCHAIN is not valid. Please edit this script."# echo "$ANDROID_TOOLCHAIN"# exit 1 ficase $_ANDROID_ARCH inarch-arm) ANDROID_TOOLS="arm-linux-androideabi-gcc arm-linux-androideabi-ranlib arm-linux-androideabi-ld";;arch-x86) ANDROID_TOOLS="i686-linux-android-gcc i686-linux-android-ranlib i686-linux-android-ld";; *)echo "ERROR ERROR ERROR";; esacfor tool in $ANDROID_TOOLS do# Error checkingif [ ! -e "$ANDROID_TOOLCHAIN/$tool" ]; thenecho "Error: Failed to find $tool. Please edit this script."# echo "$ANDROID_TOOLCHAIN/$tool"# exit 1fi done# Only modify/export PATH if ANDROID_TOOLCHAIN good if [ ! -z "$ANDROID_TOOLCHAIN" ]; thenexport ANDROID_TOOLCHAIN="$ANDROID_TOOLCHAIN"export PATH="$ANDROID_TOOLCHAIN":"$PATH" fi###################################################################### For the Android SYSROOT. Can be used on the command line with --sysroot # https://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.html export ANDROID_SYSROOT="$ANDROID_NDK_ROOT/platforms/$_ANDROID_API/$_ANDROID_ARCH" export CROSS_SYSROOT="$ANDROID_SYSROOT" export NDK_SYSROOT="$ANDROID_SYSROOT"# Error checking if [ -z "$ANDROID_SYSROOT" ] || [ ! -d "$ANDROID_SYSROOT" ]; thenecho "Error: ANDROID_SYSROOT is not valid. Please edit this script."# echo "$ANDROID_SYSROOT"# exit 1 fi###################################################################### If the user did not specify the FIPS_SIG location, try and pick it up # If the user specified a bad location, then try and pick it up too. if [ -z "$FIPS_SIG" ] || [ ! -e "$FIPS_SIG" ]; then# Try and locate it_FIPS_SIG=""if [ -d "/usr/local/ssl/$_ANDROID_API" ]; then_FIPS_SIG=`find "/usr/local/ssl/$_ANDROID_API" -name incore`fiif [ ! -e "$_FIPS_SIG" ]; then_FIPS_SIG=`find $PWD -name incore`fi# If a path was set, then export itif [ ! -z "$_FIPS_SIG" ] && [ -e "$_FIPS_SIG" ]; thenexport FIPS_SIG="$_FIPS_SIG"fi fi# Error checking. Its OK to ignore this if you are *not* building for FIPS if [ -z "$FIPS_SIG" ] || [ ! -e "$FIPS_SIG" ]; thenecho "Error: FIPS_SIG does not specify incore module. Please edit this script."# echo "$FIPS_SIG"# exit 1 fi###################################################################### Most of these should be OK (MACHINE, SYSTEM, ARCH). RELEASE is ignored. export MACHINE=armv7 export RELEASE=2.6.37 export SYSTEM=android export ARCH=arm export CROSS_COMPILE="arm-linux-androideabi-"if [ "$_ANDROID_ARCH" == "arch-x86" ]; thenexport MACHINE=i686export RELEASE=2.6.37export SYSTEM=androidexport ARCH=x86export CROSS_COMPILE="i686-linux-android-" fi# For the Android toolchain # https://android.googlesource.com/platform/ndk/+/ics-mr0/docs/STANDALONE-TOOLCHAIN.html export ANDROID_SYSROOT="$ANDROID_NDK_ROOT/platforms/$_ANDROID_API/$_ANDROID_ARCH" export SYSROOT="$ANDROID_SYSROOT" export NDK_SYSROOT="$ANDROID_SYSROOT" export ANDROID_NDK_SYSROOT="$ANDROID_SYSROOT" export ANDROID_API="$_ANDROID_API"# CROSS_COMPILE and ANDROID_DEV are DFW (Don't Fiddle With). Its used by OpenSSL build system. # export CROSS_COMPILE="arm-linux-androideabi-" export ANDROID_DEV="$ANDROID_NDK_ROOT/platforms/$_ANDROID_API/$_ANDROID_ARCH/usr" export HOSTCC=gccVERBOSE=1 if [ ! -z "$VERBOSE" ] && [ "$VERBOSE" != "0" ]; thenecho "ANDROID_NDK_ROOT: $ANDROID_NDK_ROOT"echo "ANDROID_ARCH: $_ANDROID_ARCH"echo "ANDROID_EABI: $_ANDROID_EABI"echo "ANDROID_API: $ANDROID_API"echo "ANDROID_SYSROOT: $ANDROID_SYSROOT"echo "ANDROID_TOOLCHAIN: $ANDROID_TOOLCHAIN"echo "FIPS_SIG: $FIPS_SIG"echo "CROSS_COMPILE: $CROSS_COMPILE"echo "ANDROID_DEV: $ANDROID_DEV" fi四、OpenSSL 交叉編譯
準備源碼和環境變量腳本 ,
# 如果之前有該目錄, 刪除 rm -rf openssl-1.1.0g/ # 解壓源碼 tar xvf openssl-1.1.0g.tar.gz # 修改 shell 腳本權限 chmod a+x setenv-android.sh初始化環境變量 , 并進入源碼根目錄 ;
# 初始化環境變量 source ./setenv-android.sh # 進入源碼根目錄 cd openssl-1.1.0g/在源碼根目錄中運行如下命令 , --openssldir 指定輸出目錄 , --prefix 指定編譯后的動態庫輸出目錄 ;
# 生成 Makefile 編譯腳本 ./config shared no-ssl2 no-ssl3 no-comp no-hw no-engine --openssldir=`pwd`/android/arm/openssl --prefix=`pwd`/android/arm編譯源碼 : 執行下面的代碼 , 完成交叉編譯工作 ;
# 編譯源碼 make depend make all將生成的庫安裝到 指定的目錄中 ; 該步驟的作用是將編譯后的結果 , 輸出到 --prefix=pwd/android/arm 指定的目錄中 ;
# 安裝源碼到指定目錄 sudo -E make install CC=/root/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc RANLIB=/root/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ranlib編譯結果 :
五、OpenSSL 交叉編譯相關資源下載
下載地址 : https://download.csdn.net/download/han1202012/13133929
總結
以上是生活随笔為你收集整理的【Android 安全】DEX 加密 ( 代理 Application 开发 | 交叉编译 OpenSSL 开源库 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 安全】DEX 加密 (
- 下一篇: 【Android 安全】DEX 加密 (