先要知道Java编译、执行流程,才能找到切入点反编译,知道从哪些点儿进行反编译,才能找到准确的点进行防护。
按照这个思路,先看编译执行过程。
Java编译与执行过程
- 创建java文件并添加测试代码
1 | touch Simple.java |
1 | public class Simple { |
- 然后编译此文件并执行查看效果
1 | javac Simple.java |
编译: What happens at compile time in java
执行javac
命令时发生了什么呢?如图
或精简为下图
本质上是将.java编译成为了字节码(byte code).class文件
此时我们使用vi
命令查看时,看到的是如下乱码
1 | vi Simple.class |
执行: What happens at runtime in java
class文件的执行流程可以参考如下两图
至此,我们基本了解了Java从编译到运行的全过程。从中我们可以看出,因为class文件最终是要在JVM中执行的,中间无论是经过了怎样的加密,最终执行前都要解密,所以加密只会推迟被反编的时间,但是不能完全防止。
混淆会改变类、接口、枚举的名称,以及其中的方法、属性名称,以降低可读性的方式来保护我们的源码,这种方式目前是非常普遍的。
反编译
常见的反编译工具有很多
比较老牌的如JD-Core,对应的GUI工具为JD-GUI,但是这款工具已经很久不更新了
在MacOS Monterey上已经无法使用JD,所以此处使用的是jadx,可以下载对应的系统版本
如图为解压后的目录结构,cd
至bin
目录后,执行./jadx-gui
即可启动
选中Sample.class
和Inner.class
后,OpenFile即可
如此,反编译完成
Jar包
What is JAR?
JAR(Java ARchive)本质上是一个ZIP文档,其中包含了class文件,也可以包含资源文件。
创建JAR包
新建manifest.txt
文件,并添加如下内容
1 | Manifest-Version: 1.0 |
使用jar cmf Simple.jar manifest.txt *.class
命令将上述步骤中的两个class文件生成Simple.jar
文件
添加manifest
是为了让jar包可执行(manifest指明了jar包执行入口)
1 | 已添加清单 |
此时生成的jar包可以使用同样的方法进行反编译。
使用java -jar Simple.jar
可以执行jar包,效果与Simple.class
相同
混淆 Obfuscation
此处使用ProGuard进行jar包混淆,可以从sourceforge下载或者Github下载相应的包。
切换至lib
目录后,新建配置文件touch myconfig.pro
1 | -injar /Users/liyanqing/Documents/Test/JavaTest/Simple.jar |
在混淆后,再反编译出的内容就会变的可读性极差。
Reference
Compile
Java 代码编译和执行的整个过程
Anti-Decompile
有哪些防止反编译 Java 类库 jar 文件的办法?
Protect Your Java Code From Reverse Engineering
jar
JAR File Overview
JAR (file format)
Modifying a Manifest File
Create JAR with manifest
ProGuard
ProGuard使用手册