joy keeps flowin'

Android代码混淆

xx
目次

在Android应用开发完成,上架前,一般是要经过加固和混淆两个步骤的,加固的原理我不懂,整理了混淆相关的知识和文档。供自己和有需要的朋友查阅。

目的 #

一定是有什么作用,否则是不会加入的。混淆的作用是什么呢?

  1. 移除运行时不是用的方法和资源,减少应用体积(缩减代码-官方介绍
  2. 用更短的无意义的名称替换类名、属性名,替换后的代码更不宜读,增加反编译难度
  3. 检查并重写代码,进一步减少应用dex大小,提高运行速度(代码优化-官方介绍

配置 #

我们知道Gradle是一套构建的工具,提供标准的流程,你可以用Gradle构建Java后端项目,可以构建Android项目。一般来说包括,Gradle需要经过初始化、配置、执行三个步骤。task是Gradle执行的最小单位,混淆task并不是流程中的一环,想要用Gradle混淆,是需要手动添加混淆task的。

Android项目之所以不需要你手动添加混淆的插件,简单的几行代码是开启混淆,是在Android项目的Gradle插件android中已经帮你做了这部分工作。你只需要修改几个配置即可。Android是用的是Google推出的R8,使用ProGuard 规则文件来修改其默认行为。

开启混淆 #

你需要在开启混淆的Android模块的build.gradle文件中,设置minifyEnabled的值为true,比如最常用的在构建release时:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
android {
    buildTypes {
        release {
            // debuggable置为false是开启混淆的前提
            debuggable false

            minifyEnabled true

            // 缩减没有用到的资源
            shrinkResources true

            // 混淆规则配置
            proguardFiles getDefaultProguardFile(
                    'proguard-android-optimize.txt'),
                    'proguard-rules.pro'
        }
    }
    ...
}

当你新建一个Android项目时,模板会帮你添加上proguardfiles这行代码,即使你不开启混淆。

虽然写在一行,其实是两个文件,你可以把多个配置列在这里,中间用英文逗号隔开。再说模板加上的两个文件含义,proguard-android-optimize.txt从Android Gradle插件生成的,其中包含了对大多数Android项目都能用的规则,当你用Android Studio创建新模块,会帮你创建proguard-rules.pro文件,默认是空的,需要你添加规则。此外还包含其他配置文件。

来源位置说明
Android Studio&lt;module-dir&gt;/<wbr/>proguard-rules.<wbr/>pro当您使用 Android Studio 创建新模块时,Android Studio 会在该模块的根目录中创建 proguard-rules.<wbr/>pro 文件。
默认情况下,此文件不会应用任何规则。因此,请在此处添加您自己的 ProGuard 规则,比如自定义保留规则
Android Gradle 插件由 Android Gradle 插件在编译时生成。Android Gradle 插件会生成 proguard-android-optimize.<wbr/>txt(其中包含了对大多数 Android 项目都有用的规则),并启用 @Keep\* 注解
默认情况下,使用 Android Studio 创建新模块时,模块级 build 脚本会将此规则文件纳入到您的发布 build 中。
注意:虽然 Android Gradle 插件包含额外的预定义 ProGuard 规则文件,但建议您使用 proguard-android-optimize.txt
库依赖项在 AAR 库中:
proguard.txt
在 JAR 库中:
META-INF/proguard/<ProGuard-rules-file>
除了这些位置之外,Android Gradle 插件 3.6 或更高版本还支持有针对性缩减规则
如果某个 AAR 或 JAR 库是使用它自己的规则文件发布的,并且您将该库作为编译时依赖项纳入到项目中,那么 R8 在编译项目时会自动应用这些规则。
除了传统的 ProGuard 规则之外,Android Gradle 插件 3.6 或更高版本还支持有针对性缩减规则。这些规则针对特定缩减器(R8 或 ProGuard)以及特定缩减器版本。
如果库需要某些规则才能正常运行,那么使用该库随附的规则文件将非常有用。也就是说,库开发者已经为您执行了问题排查步骤。
不过,您应该知道,因为这些规则是累加的,所以库依赖项包含的某些规则无法移除,并且可能会影响应用其他部分的编译。例如,如果某个库包含停用代码优化的规则,该规则将针对整个项目停用优化。
Android 资源打包工具 2 (AAPT2)使用 minifyEnabled true 构建项目后:&lt;module-dir&gt;/<wbr/>build/<wbr/>intermediates/<wbr/>aapt_<wbr/>proguard_<wbr/>file/<wbr/>.<wbr/>.<wbr/>.<wbr/>/<wbr/>aapt_<wbr/>rules.<wbr/>txtAAPT2 会根据对应用清单中的类、布局及其他应用资源的引用,生成保留规则。例如,AAPT2 会为您在应用清单中注册为入口点的每个 activity 添加一个保留规则。
自定义配置文件默认情况下,当您使用 Android Studio 创建新模块时,IDE 会创建 &lt;module-dir&gt;/<wbr/>proguard-rules.<wbr/>pro,以便您添加自己的规则。您可以添加其他配置,R8 会在编译时应用这些配置。

你可以在模块的pooguard-rules.pro文件中添加-printconfiguration ~/tmp/full-r8-config.txt以打印出所有规则。当然你可以修改路径。

规则 #

混淆规则不指定时,认为所有的类、成员变量、方法都可以缩减成a.b.c的形式,代码还在,知识名称变了。你需要指定保留哪些让你的应用能够用正常运行,(保留的越少越好,我们的目就是要把代码变成看不懂的形式)。

规则实在是多,详细的参见Configuration - Usage

还原 #

Android SDK中提供了恢复还原的工具:retrace 。路径位于SDK包的:cmdline-tools/version/bin/中。当你的应用出现崩溃时,你可以用它找到混淆混淆前的路径。

用法:

1
retrace  path-to-mapping-file [path-to-stack-trace-file] [options] 

之后终端会等你收入异常的堆栈,粘贴进去。终止:

即可看到原始堆栈信息。

参考 #

标签:
Categories: