安卓 APK/AAB 保护指引
#
安卓应用的安全性问题#
二次打包风险安卓原生应用一般使用 Java/Kotlin 语言编写,编译打包后生成Dex文件存放在APK中。Dex文件包含了类、方法、成员等信息,甚至包含了源文件名,使用jadx/jd-gui等工具可以轻松反编译出源代码。代码被反编译后,可以很容易使用apktool等工具修改代码,破解应用或者植入广告,再重新打包发布。
#
代码和资源易被窃取由于Dex文件可以完整地反编译出源代码,未经保护的代码发布后与开源无异,可能会被竞争对手无成本地直接窃取使用,包内的音视频和图片等资源文件也容易被直接窃取使用,严重损害开发者利益。
#
Virbox Protector功能介绍Virbox Protector对APK和AAB程序提供了运行时自保护、防逆向、防篡改、代码和资源加密等功能,全方位保护APK和AAB程序。
#
运行时自保护运行时自保护,是在应用启动时保护自身,防止应用被恶意调试分析、动态注入,防止在一些开启了高权限的自定义设备或模拟器中运行,进而破解应用程序的行为。
功能 | 描述 |
---|---|
防调试 | 防止应用被 IDA Pro,gdb,lldb,jeb 等工具调试,检测到被调试后退出。 |
防注入 | 防止应用被 ptrace 附加,so 库注入,检测 xposed 等 hook 框架。 |
模拟器检测 | 检测到应用在模拟器中运行时退出。 |
Root 检测 | 检测到应用在 Root 环境下运行时退出。 |
多开检测 | 检测到应用多开(分身)时退出。 |
#
防逆向防止应用中的 Dex、SO库、脚本语言代码被反编译或窃取,防止逆向分析。
功能 | 描述 |
---|---|
Dex 加密 | 加密并隐藏 APK 中的所有 Dex 文件,防止 jadx, jeb 等工具反编译。 |
Dex 虚拟化 | 对指定的 Dex 中的方法进行虚拟化保护,将代码转换成自定义的 Native 层虚拟机中执行,可以防止一切内存截取方式还原代码。 |
资源加密 | 加密 apk 中的资源、脚本等文件,防止资源被提取。 |
SO 库保护 | 对 apk 中指定的 so 库保护,加密代码段,防止 IDA Pro 等工具反汇编、反编译。 |
SO 库保护(隐藏符号表) | 隐藏 SO 库中的导出函数、加密 SO 库中的 ELF 重定位,防止脱壳。 |
Dex 虚拟化效果
保护前:
保护后:
保护后跳转到自定义的解释器中执行(见上图 vm_void 方法)。
#
防篡改运行时校验代码及应用的完整性,防止应用被篡改,防止二次打包。
功能 | 描述 |
---|---|
签名校验 | 校验 APK 中的开发者签名,防止 APK 被第三方二次打包重签名。 |
文件校验 | 校验 APK 中的资源、脚本、SO 库等文件,防止 APK 中的文件被篡改进行二次打包。 |
#
支持范围#
操作系统和架构兼容性- 支持 Android 4.0 以上系统
- 支持 arm32/arm64/x86/x64 架构
#
保护指引#
保护前的准备#
JDK配置对APK/AAB签名,需要用到jdk中的 jarsigner
工具(位于jdk bin目录)和 java
命令,Windows平台需要将jdk的 bin目录加入环境变量,Linux/macOS 一般安装jdk后即可直接调用。
配置完毕后,在命令行终端下输入 jarsigner
即可验证环境是否生效。
#
生成 Keystore如果开发者尚未生成 Keystore,可以安装 jdk 后手动生成,生成命令如下:
keytool -genkeypair -keyalg RSA -keysize 1024 -sigalg SHA256withRSA -validity <validity_days> -alias <key_alias> -storepass <ks_pass> -keystore <keystore_path>
生成Keystore需要记录KeyStore路径
,KeyStore密钥
,密钥别名
,别名密码
,在保护过程中的签名设置
里需要填写。
举例:
# -validity :有效期天数,这里随便填写个足够长的数据即可# -keystore :KeyStore路径# -storepass :KeyStore密码# -alias :密钥别名# (别名密码可以在执行命令后的交互提示中填写)
keytool -genkeypair -keyalg RSA -keysize 1024 -sigalg SHA256withRSA -validity 500000 -alias MyCert -storepass MyCert.jks
#
反编译工具推荐反编译工具可以用于保护效果的评估。
对于APK中的 Java/Kotlin代码部分,推荐使用免费开源 Jadx:
Jadx 下载地址: Releases · skylot/jadx · GitHub
对 APK包的中 Native库,推荐使用 IDA Pro(收费),或 Ghidra(免费开源):
Ghidra 下载地址: Releases · NationalSecurityAgency/ghidra (github.com)
#
常规的保护方式Virbox Protector 的默认选项,可以防止程序被反编译、防资源窃取、防脱壳、防逆向、防二次打包等。一般可以满足大部分的安全性需求,以下是APK和AAB程序的保护选项和推荐。
功能 | 保护建议 | 保护效果 |
---|---|---|
Dex 加密 | 勾选 | 加密隐藏Dex文件,防止反编译 |
文件校验 | 勾选 | 校验APK包内除签名信息外的所有文件,防止被篡改 |
签名校验 | APK格式勾选;AAB格式如果由Google管理证书请勿勾选 | 校验开发者签名,防止被第三方重签名打包 |
反注入 | 勾选 | 防止内存Dump,防止调试器附加 |
调试器检测 | 勾选 | 检测到调试器调试,则退出进程 |
模拟器检测 | 按需选择 | 检测到运行环境为模拟器,则退出进程 |
Root检测 | 按需选择 | 检测到运行环境为Root环境,则退出进程 |
多开检测 | 按需选择 | 检测到运行环境为手机分身或应用分身,则退出进程 |
[V] 代码虚拟化 |
函数选项
Virbox Protector 默认会将入口Application和Activity类中的方法虚拟化,防止代码被还原脱壳,建议使用默认。
资源加密
按需选择是否加密。
SO库保护
按需选择是否保护,保护后可以防止反编译。
#
自定义虚拟化Virbox Protector 会默认对App 入口类和Activity类虚拟化保护,也支持自由选择类方法进行虚拟化保护,保护关键代码逻辑,用于应对高安全性的保护场景。
代码虚拟化,是将函数原本的汇编指令,转换自定义的虚拟机指令。函数被虚拟化保护后,运行时内存中不会出现原始字节码,而是以伪代码的形式出现,由自定义的解释器解释执行,安全性极高。如果一个加密方案可以逼迫破解者去分析虚拟化的代码,说明这个方案是非常成功的,需要分析的代码(破解点)越多,破解的难度就越大
。
代码虚拟化对程序的性能影响较大,不可大面积使用,常用于以下几类函数:
- 对安全性要求较高的一些自定义算法。
- 可能被篡改或者逆向的函数(如关键的授权验证逻辑、协议封装加密逻辑)。
#
自动化集成#
命令行工具Virbox Protector
的命令行工具 virboxprotector_con
的默认路径位于:
Windows:C:\Program Files\senseshield\Virbox Protector 3\bin
Linux:/usr/share/virboxprotector/bin
macOS:/Applications/Virbox Protector 3.app/Contents/MacOS/bin
#
使用配置文件保护使用工具界面进行保护,在被保护的程序旁边会生成 .ssp
文件,然后调用virboxprotector_con
:
virboxprotector_con <input_file> -o <output_file>
virboxprotector_con
会自动查找 <input_file>.ssp 作为配置文件开始保护。
#
无配置文件保护如果没有配置文件,virboxprotector_con
会使用默认参数保护,可以传入具体参数覆盖默认选项,参考命令行选项。
#
命令行选项#
保护选项选项 | 命令行 | 默认选项 |
---|---|---|
Dex 加密 | --dex-enc= | APK:1 , AAB:0 |
文件校验 | --file-check= | 1 |
签名校验 | --sign-check= | 0 |
反注入 | --anti-inject= | 1 |
调试器检测 | --detect-dbg= | 0 |
模拟器检测 | --detect-emu= | 0 |
Root检测 | --detect-root= | 0 |
多开检测 | --detect-multi= | 0 |
输出 apks (AAB启用签名时生效) | --apks=<apks_path> | N/A |
#
函数选项选项 | 命令行 |
---|---|
代码虚拟化 | -v |
支持指定函数名称或规则保护,使用 ;
号隔开,支持通配符 *
,举例:
-v "class1.method2;class2.*"
资源加密
使用 --res-enc=1
开启资源加密,资源列表使用 ;
隔开,支持通配符 *
。
选项 | 命令行 | 默认选项 |
---|---|---|
启用 | --res-enc= | 0 |
资源列表 | -res <resource_list> | 默认所有资源 |
举例:
--res-enc=1 -res "file1;file2;assets/file1;assets2/*"
SO 保护
选项 | 命令行 | 默认选项 |
---|---|---|
隐藏符号表 | --hide-symtab= | 0 |
资源列表 | -lib <nativelib_list> | N/A |
举例:
--hide-symtab=0 -lib "lib/armeabi-v7a/libhello.so;/lib/arm64-v8a/*"
命令行保护举例
对 APK 进行保护,开启部分功能并设置签名:
virboxprotector_con app-release.apk --dex-enc=1 --file-check=1 --detect-dbg=1 --sign-check=1 --res-enc=1 -res "assets/*" --hide-symtab=0 -lib "lib/armeabi-v7a/libhello.so;/lib/arm64-v8a/*" --sign=1 --ks="test/android.ks" --ks-pass=mypass --ks-key-alias=CERT --key-pass=mykeypass -o app-release-protected.apk