ProGuard 进阶系列(一)源码运行
在前面的文章深入 Android 混淆实践:ProGuard 通关秘籍和深入 Android 混淆实践:多模块打包爬坑之旅中,已经讲到了如何在 Android 中使用 ProGuard,以及如何自定义实现混淆规则的生成。为了更深入地理解 ProGuard 的细节,本系列文章从我感兴趣的点出发,记录在阅读 ProGuard 源码过程中的思考与启发,希望对你也有所帮助。本文为此系列文章的开篇,将最基础的讲起,使用 ProGuard 源码去实现代码混淆。
在之前的文章中,使用 ProGuard 的流程已经融入到 Android Gradle Tools 中了。除了自带的流程,我们也可以直接使用 android-sdk/tools/proguard/libs
里面的 proguard.jar
。在 android-sdk/tools/proguard/bin
下有 proguard.sh
这个可执行文件:
PROGUARD_HOME=`dirname "$0"`/..
java -jar $PROGUARD_HOME/lib/proguard.jar "$@"
可以看到,就是使用 java -jar
进行执行的,并且将参数直接透传。除了使用这个可执行脚本执行外,我们也可以直接使用如下命令直接运行:
java -jar proguard.jar [options ...]
根据使用混淆的经验,你应该可以想到,加固过程中,主要需要以下四部份内容:
在执行命令中,必须包含这些内容,我们可以使用以下几条参数来指定:
-injars
一致, 一般情况下,此处仅有一个可输出的 classpath 路径-injars
一致,如有多个 library 依赖,写多行就可以指定@filename
替代我们所编写的 混淆配置
通过 -include filename
即可指定。当然,-injars
、-outjars
、-libraryJars
和 -keep 规则
放到同一个配置文件中,运行时,指定对应配置文件即可,使用起来更方便,比如我将配置信息写到 debug_proguard.pro
文件中,即可按如下方式进行运行:
java -jar proguard.jar @debug_proguard.pro
当写好配置后,运行如上命令,就能将混淆后的内容输出到 -outjars
指定的路径中。
前面的内容中,可以了解到 ProGuard 的使用,而 ProGuard 是一个开源项目,它使用的是 GPL 协议,而其还依赖了ProGuard-core
,此项目也为开源项目。为了了解其实现细节,可以将代码下载下来,如下所示:
git clone git@github.com:Guardsquare/proguard.git
git clone git@gitcode.net:mirrors/Guardsquare/proguard.git
代码下载好后,可以直接使用 Intellij IDEA
打开它并且运行起来,这样我们就可以直接进行运行调试,能够更方便的去读懂 ProGuard 中的逻辑。
在 ProGuard 代码仓库中写到,要编译源码,需要使用 JDK 8 , 此处需要注意你当前使用的 JDK 版本。
首先,要运行代码,就需要找到 main()
方法所在的类,才能执行运行。在第一节的内容中,使用 java -jar proguard.jar
就可以执行,从 jar 包中的 MANIFEST.MF
文件中,可以看到, main()
方法在 proguard.ProGuard
中, 如下图所示:
在源码中,我们也能看到 proguard/ProGuard.java
的类中,正好有一个 main()
方法。在 Intellij IDEA
可以直接运行此 main
方法:
如果直接点击绿色的 ▶︎ ,运行肯定会报错。在这里,我们还需要手动将第一部分中使用的 debug_proguard.pro
文件路径放到参数列表中去,具体操作方法如下图所示:
配置完成后,直接点击 Intellij IDEA
中的 ▶︎ ,输出的产物与用命令行执行出来的结果一致。
当拿到源码后,第一步就是将源码跑起来,这能够有助于我们对源码理解,以及后续分析源码时进行调试。本文内容很简单,但纸上得来终觉浅,绝知此事要躬行。朋友们可以自己去将源码下载下来,并使用你所熟知的 IDE
将其运行起来,相信你也有很多的收获,也欢迎各位与我交流。