修改 java 编译后的.class 文件

前言

修改.class 文件,使用压缩工具替换 jar 中原文件

反编译查看.class

可以使用 IDEA,也可以使用 jadxjd-gui

利用 jclasslib 修改变量

下载地址 jclasslib/releases
写文章时用的是 5.8 版本,参考的文章地址是 class 文件直接修改_反编译修改 class 文件变量
不过我用的这个版本已经没有 org.gjt.jclasslib.structures.CPInfo 这个包,并且看源码像是用 kotlin 写的
使用步骤

  1. 在 build.gradle 中添加
    1
    2
    3
    4
    plugins {
    id 'java'
    id "org.jetbrains.kotlin.jvm" version "1.4.20"
    }
  2. 代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    package test;

    import java.io.DataInput;
    import java.io.DataInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;

    import org.gjt.jclasslib.io.ClassFileWriter;
    import org.gjt.jclasslib.structures.ClassFile;
    import org.gjt.jclasslib.structures.Constant;
    import org.gjt.jclasslib.structures.InvalidByteCodeException;
    import org.gjt.jclasslib.structures.constants.ConstantUtf8Info;

    /**
    * @author tsvico
    */
    public class Client
    {
    public static void main(String[] args){
    String filePath = "C:\\Users\\gwjwi\\Downloads\\xxx.class";
    FileInputStream fis = null;
    try {
    fis = new FileInputStream(filePath);
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    }

    assert fis != null;
    DataInput di = new DataInputStream(fis);
    ClassFile cf = new ClassFile();
    cf.read(di);
    Constant[] infos = cf.getConstantPool();

    int count = infos.length;
    for (int i = 0; i < count; i++) {
    if (infos[i] != null) {
    if(i == 553){
    ConstantUtf8Info uInfo = (ConstantUtf8Info)infos[i];
    // uInfo.setBytes("Admin123".getBytes());
    uInfo.setString("2099-12-17");
    infos[i]=uInfo;
    }
    }
    }
    cf.setConstantPool(infos);
    try {
    fis.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    File f = new File(filePath);
    try {
    ClassFileWriter.writeToFile(f, cf);
    } catch (InvalidByteCodeException | IOException e) {
    e.printStackTrace();
    }
    }
    }
    重新打开字节码文件,发现修改成功。

网上看到使用 jbe 可以直接修改,未能成功

利用 javassist

最新地址 javassist/releases
网上有很多相关介绍和教程

  • 例 1
  • 例 2

这里只提供解决思路,没有具体教程,因为我要修改的是内部静态变量,所以没用这个方法。

其他

利用 jd-gui.exe 或者 jadx 打开一个 jar 包,另存为项目,可以看到所有的 java 源代码,这种方法仅供参考不建议使用,因为可能会遇到无法重新打包的问题
相关文章
修改 jar 包中的源码,将 jar 包反编译重新生成一个 jar 包