本文已授权微信公众号「玉刚说」独家发布。

这篇「Java 混淆那些事」的第二篇,我们先把我们的测试环境以及用到的各种工具介绍一下,然后动手去尝试各种命令并且验证它们的效果,这样有助于我们理解。

配置测试环境

首先需要在电脑上配置好 Java 环境。然后需要的主角 ProGuard,然后还有反编译软件 jadx。

下载链接在下面。
ProGuard 下载地址
jadx 反编译工具
两个的工具备用下载地址

简单描述我们的测试流程

第一步:写出测试代码,打成一个 Jar 包(在文章结尾会介绍 intellij 和 Eclipse 怎么导出 jar 包)。
第二步:配置 ProGuard 的混淆规则
第三步:使用 jadx 去查看混淆完的类文件的内容。
第四步:一直重复上面三个步骤,搞明白具体的命令。

简单实用的 ProGuard GUI

1、把下载的 ProGuard 解压,打开终端进入 proguard/bin 目录,输入 ./proguardgui.sh 打开 ProGuard 的 GUI 客户端。

Windows 电脑直接进入 proguard/bin 目录双击运行 proguardgui.bat 即可。注:需要 JDK 环境

如图:点击 Load configuration 按钮可以读取配置文件。暂时忽略这个地方,等我们有了配置文件或者需要编写混淆规则的时候,就可以在这里导入了。

2、我们首先准备一个简单的 Java 项目的 Jar 包,在 Input/Output 选项卡,点击 Add input 设置需要混淆的 Jar 包,点击 Add output 设置类文件处理完成之后输出的位置。

注:Mac 版 GUI 有个 BUG,设置 output 时需要选定一个文件,而没有办法直接输入路径,我们可以先把未混淆的 Jar 包复制一份改个名字,混淆完成之后他会自动覆盖 Jar 包。

3、切换到 Process 选项卡,直接点击 Process 即可输出处理之后的 Jar 到 output 目录。点击 Save configuration 按钮,可以保存配置文件,以 .pro、.txt 结尾即可。之后我们就能够直接在配置文件中修改和编写混淆规则了。然后就通过第一步直接导入配置了。

配置 ProGuard 的调试选项

以上虽然可以进行混淆,但是删除了哪个类,那个方法,对哪个方法改了名字等等,我们都无从知晓。接下来我们继续配置一下。接下来我们配置一下这三个东西,来帮助我们理解混淆过程。

usage.txt :经过压缩过程被删除的类、方法、字段。
mapping.txt :存储经过混淆过程,新旧类名、方法名、字段名的映射,软件发布一定要保留此文件,不然收集上来的报错信息,不知道具体是哪个类或方法,你将会很是头疼。
seeds.txt :被 Keep 规则匹配到的类、方法、字段,来验证我们的 keep 规则是否合我们的需求。

usage.txt 的配置

点开 Shrinker 选项卡,在 Print usage 前面打钩,并选择 usage.txt 的输出路径。

mapping.txt 的配置

点开 Obfuscator 选项卡,在 Print mapping 前面打钩,并选择 mapping.txt 的输出路径。

seeds.txt 的配置

点开 Information 选项卡,在 Print seeds 前面打钩,并选择 seeds.txt 的输出路径。

使用 jadx 来查看混淆过的 Jar

通过上述方法保留的相关文件能够验证我们的混淆规则,但是我们调试起来比较麻烦并且不够直观,所以我们使用一个开源工具 jadx 来观察混淆后的代码,来验证我们的混淆规则。

解压下载完成后的 jadx.zip 然后进入 bin 目录,双击 jadx-gui 打开 jadx 软件。

Windows 双击 jadx-gui.bat 打开软件

可以打开混淆完成后 Jar 包,然后比较自己的源代码,查看不同地方。

认识一下配置文件

#输入需要混淆的 Jar
-injars JavaProGuardDemo.jar
#输出混淆完成的 Jar
-outjars 'JavaProGuardDemo 2.jar'

-libraryjars /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/rt.jar

# 打印 usage
-printusage usage.txt
# 打印 mapping
-printmapping mapping.txt
# 打印 seeds
-printseeds seeds.txt

# Keep - Applications. Keep all application classes, along with their 'main' methods.
-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}

# Also keep - Enumerations. Keep the special static methods that are required in
# enumeration classes.
-keepclassmembers enum  * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# Also keep - Database drivers. Keep all implementations of java.sql.Driver.
-keep class * extends java.sql.Driver

# Also keep - Swing UI L&F. Keep all extensions of javax.swing.plaf.ComponentUI,
# along with the special 'createUI' method.
-keep class * extends javax.swing.plaf.ComponentUI {
    public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent);
}

# Keep - Native method names. Keep all native class/method names.
-keepclasseswithmembers,includedescriptorclasses,allowshrinking class * {
    native <methods>;
}
...

这是最基本的配置文件,除了写注释的那几句是我们自己在 GUI 的操作中添加的,其它都是 ProGuard 自己默认添加的。

常用 IDE 导出 Jar 包

IntelliJ IDEA

此方法只适用于最普通的 Java SE 项目,如果使用了 Maven 等工具,可以使用 Maven 打包。

1、点击 File => Project Structure

2、点击 Artifacts 选项卡,然后点击 + 号

3、选择 JAR => From modules with dependencies...

4、选择 main 方法,然后点击 OK。

5、选择 Build => Build Artifacts...

6、选择 Build 即可

7、在项目根目录 out/artifacts/项目名_jar,就可以看到打包的 Jar 包了

Eclipse

1、在项目上点击右键,点击 Export

2、点开 java 选择 JAR file

3、选择 Jar 的存放位置点击 Finish 即可。

这篇文章上次修改于 304 天前,可能其部分内容已经发生变化,如有疑问可询问作者。