一键修改JAR包内文件:JarEditor 插件详细指南

6,375 阅读8分钟

背景

在开发中我们有时会遇到这样的场景,需要修改jar包内某个class,常见的方法就是先解压缩,然后反编译这个class,新建java修改再编译,最后再打包,整个过程是非常耗时的。

这里向大家介绍一款IDEA插件:JarEditor,可以一键修改JAR包内文件,无需解压。

插件安装

首先在插件商城搜索JarEditor,可直接安装插件

JarEditor_install.png

插件使用

1. 修改class文件

安装完后,任意打开一个jar的class,可以看到反编译后的class内容,选中Jar Editor的tab页签,就可以直接编辑class了

JarEditor_main.png

修改完代码后先点击 Save,这个过程会编译class,编译成功后点击Build Jar就修改jar完成了,是不是很简单?下面是一个修改的例子。

JarEditor_demo.gif

SDK可以选择需要的JDK或者其他SDK,Target为编译class的目标版本,默认是和反编译的class前的版本保持一致。

附:修改外部jar

选择File->Project Structure->Libraries,然后添加工程外的jar即可打开jar内文件修改

image.png

也可以将jar包粘贴到本项目中,然后右键->Add as Library...

image.png

2. 修改配置和资源文件

操作流程同修改class 文件,不要勾选Compile,改完文本后以此点击 Save -> Build Jar 即可修改配置文件和资源文件。

image.png

3. JAR包内新增文件

在工程视图jar包内某个文件夹上右键->JarEditor->New,可以新建Class/Kotlin/File/Directory

JarEditor_new_delete.png

选择后输入文件名即可在jar内新增文件,默认是空文件

image.png

新增后打开可以写入内容,Class和Kotlin新建完文件是有模版的,无需后缀名,如果是JarEditor->New->File则需要写文件后缀名。

image.png

4. 删除JAR包内文件

在工程视图jar包内某个文件或者文件夹上右键->JarEditor->Delete,则会删除选择的目录或者文件,支持多选。

image.png

5. 重命名文件

在工程视图jar包内某个文件或者文件夹上右键->JarEditor->Rename,输入名字后即可将原来的名字修改为新的名字,修改完立即生效。

image.png

6. 拷贝JAR包内文件到外部文件夹

在工程视图jar包内某个文件或者文件夹上右键->JarEditor->Copy,可以将jar包内文件拷贝到剪切板(支持多选)

image.png

然后在外部任意一个文件夹内,使用Ctrl+V,即可将刚才复制的文件拷贝到这个目录

image.png

7. 粘贴外部文件到JAR包内

外部文件使用Ctrl+C复制后,在jar内某个文件夹上右键->JarEditor->Paste(不能直接用Ctrl+V,Ctrl+V被IDEA默认占用了),即可将剪切板的文件粘贴到jar包内,一气呵成。

image.png

8. JAR包内搜索字符串

工具栏有一个搜索图标,点击后输入需要搜索的字符串,可搜索到jar包内的文件,包括class和普通文件。

image.png

点击搜索后的文件列表,可跳转到具体的文件。

搜索的class如果是class jar的话取决于反编译的内容,如果是source jar取决于java文本。

9. Source jar的支持

IDEA内打开的jar分两种,class jar和source jar,如果下载了源码的话,打开的是source jar,即打开的是一个java文件,而不是class文件,这里一定要注意

image.png

此时如果修改代码的话,生效的是source jar,比如这里改的是FindInstancesOfClass-1.0.3-sources.jar。

image.png

那如何修改class jar呢?

点击 JarEditor Tools上面的跳转链接:Click hear to open class jar 即可跳转到class文件

image.png

此时展示的class为反编译的代码,可修改class 文件,按 修改class文件 的流程操作即可。

也可以从source jar中导入代码:Import from source jar

image.png

Import from source jar 和直接在souce jar中的java修改的区别是:前者修改的是class jar后者是source jar。

10. 导出source jar

在class jar上面右键->JarEditor->Export->source jar,即可导出反编译源码到新的jar

截屏aaa

11. 字节码修改工具

以上修改jar的方式依赖于jdk编译,有时混淆过的jar只有变量和函数a,b,c,d这样的名称,反编译的效果不是很好不适合再次源码修改和文件编译(普通编译校验非常严格,混淆代码往往编译失败),这个时候就可以使用Class bytes tool了。

点击JarEditor面板的 Class bytes tool 图标,可以选择直接修改字节码的工具。

11.1 Javassist

使用Class bytes tool中的Javassist可以对字段和函数进行增/删/改,用接近原生java代码的风格修改字节码,非常适合修改混淆jar,注意javassist和原生java的语法有一定区别,比如参数名为$1,$2,$3...而不是具体的变量名,不支持泛型,不支持增强for循环,不支持lambda表达式等高级特性。

JarEditor_javassist.png

选择具体的Modify/Add可在Code中修改代码,导入的包在import编辑器中填写,点击 Run 执行javassist操作修改字节码并保存,点击 Build Jar 即可使修改的jar生效。

11.2 Visual ClassBytes

Visual ClassBytes是一个字节码编辑器,基于ASM和BCEL,可修改字节码的类、字段、内部类、常量池,以及方法信息:字节码指令、行号表、异常表和本地变量表等。

vcb_main.png

12. 反编译工具选择

SDK setting框中可以选择反编译工具来反编译class文件,默认是IDEA自带的反编译器Fernflower,也可以选择 CFRProcyon 等反编译器来反编译class文件。

截屏asdasd

:任何反编译工具都只是尽可能接近源码,但不一定等同于源码,和源码有一定区别,真正编译的时候取决于Jar Editor编辑页 中的代码内容,有时反编译的代码没有任何改动编译不通过也属于正常现象,简单改下语法错误即可编译通过

13. 嵌套jar的修改

针对jar中嵌套jar,比如SpringBoot的FatJar就存在嵌套jar的情况(BOOT-INF/lib/),正常情况下嵌套jar是打不开的,JarEditor从v2.1.5开始兼容了嵌套jar,只需要在嵌套jar或上层目录右键->JarEditor->Structure->Expand Nested Jar 就能展开嵌套jar的文件并修改了。

image.png

修改完嵌套jar并Save编译保存后,点击Build Jar会弹出一个对话框,需要选择构建的jar,这里构建的jar是包括嵌套jar和上层jar,支持多层嵌套jar。

image.png

选择最后一个jar则是最外部的jar,也是最终的Build目标。

Nested Jar Method 是选择嵌套jar在jar中entry的压缩方式,建议保持STORED。

友情提醒:SpringBoot中的嵌套jar是采用STORED方式(即不压缩嵌套jar)。

14. 修改entry压缩方式

jar中的entry有两种压缩方式,STORED(不压缩)DEFLATED(压缩)

在jar内文件或者文件夹上 右键->JarEditor->Structure->Compression Method,即修改压缩方式,可自由切换STORED和DEFLATED两种压缩方式。

image.png

常见的不压缩的entry有:

  • jar内目录
  • 嵌套jar

其余的文件包括class一般是DEFLATED压缩的方式。


一些机制和原理

SDK的选择

目前支持java和kotlin两种文件编译,后续可能会增加更多的编译文件支持。

选择 SDK Default 时,是使用的IDEA运行时自带编译器,即 javax.tools.JavaCompiler,详细可阅读源码。

选择其他JDK时,默认使用的是javac外部命令编译。

image.png

编译时选择的Target的范围是1.1~所有JDK的版本最大值。

Save(Compile)

考虑到可能会修改多个文件,点击 Save 会将当前修改的内容(编译)保存到所在jar包目录的临时目录 jar名_temp/jar_edit_out 下,当点击Build Jar将增量文件写入jar后,会删除临时目录。

image.png

也可点击清理图标的icon手动清理临时目录。

image.png

编译依赖

在编译时,依赖的jar为当前工程的Libraries,如果编译时提示依赖包找不到,可以添加依赖即可。

另外class文件的内容取决于反编译的结果,如果混淆的代码建议直接用上文的字节码修改工具

SDK Default

当选择SDK Default编译时,使用的是Jetbrains集成的运行时JDK(JBR),如果不选SDK Default则是具体用户安装的JDK

IDEAJDK
IDEA 2020.3 ~ IDEA 2022.1JBR JDK11
IDEA 2022.2 ~ IDEA 2024.1JBR JDK17
IDEA 2024.2 及更高版本JBR JDK21

总结

本文主要介绍了使用JarEditor直接对jar包文件进行增删改查操作,简化了修改jar的流程,感兴趣的朋友可以去试试。

本文篇幅有限,具体原理和实现细节可阅读源码

源码:github.com/Liubsyy/Jar…