利用jclasslib工具直接修改第三方jar包里面的class文件(亲测可用)

如果出于某些原因,需要修改第三方jar包里的class文件,我们能有什么办法呢?

直接修改肯定是运行不了的,这里我给大家介绍一个小工具jclasslib,因为我的电脑是64位的,所以这里就安装64位版

下载地址:https://github.com/ingokegel/jclasslib/releases/download/5.5.1/jclasslib_win64_5_5_1.exe

源码:https://github.com/ingokegel/jclasslib

版本系列:https://github.com/ingokegel/jclasslib/releases

jclasslib引用包,主要用在修改class的项目工程里

https://download.youkuaiyun.com/download/suwei825/15893593

一、安装

一路选择next,最后安装成功 Finish!

二、使用

接下来介绍下怎么使用这个工具,我准备了一个测试程序,我们熟悉的hello world

我们新建一个maven项目,添加一个类,里面是一个main主方法

public class testjclass {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String str="Hello World!";
        System.out.println(str);
    }
}

执行maven打包后,我们得到一个jar包

命令行执行

我们把jar用压缩软件解压

接下来我们运行刚才安装好的jclasslib_win64_5_5_1

我们打开刚才解压的class文件

得到如下界面,我们展开methods菜单

我们点击code

就会显示java类的字节码了,我们看第一行,实际就是我们的hello world

我们点击 #2,可以转到常量池

我们再点击cp info #23,就找到hello world了

以后遇到第三方jar需要修改,我们编写一个新的java文件

引用的包,从我上面提供的jclasslib引用包下载地址下载,我们在项目根目录建一个lib目录,把包放进去,我这里用的IDEA Java编程工具

pom文件加依赖,注意引用的是本地项目目录${project.basedir}

        <dependency>
            <groupId>org.gjt.browser</groupId>
            <artifactId>jclasslib-browser</artifactId>
            <version>5.5.1</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/jclasslib-browser.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.gjt.jclasslib</groupId>
            <artifactId>jclasslib-browser</artifactId>
            <version>5.5.1</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/jclasslib-library.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.gjt.kotlin-runtime</groupId>
            <artifactId>kotlin</artifactId>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/kotlin-runtime-1.0.6.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.gjt.kotlin-stdlib</groupId>
            <artifactId>kotlin</artifactId>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/kotlin-stdlib-1.0.6.jar</systemPath>
        </dependency>

下面贴出修改代码

import com.sun.org.apache.bcel.internal.util.ClassPath;

import java.io.*;

import org.gjt.jclasslib.io.ClassFileWriter;
import org.gjt.jclasslib.structures.ClassFile;
import org.gjt.jclasslib.structures.Constant;
import org.gjt.jclasslib.structures.constants.ConstantDoubleInfo;
import org.gjt.jclasslib.structures.constants.ConstantUtf8Info;
import org.gjt.jclasslib.structures.constants.ConstantStringInfo;
public class edit {
    public static void main(String[] args) throws Exception {

        String filePath = "D:\\swjava\\ss-1.0-SNAPSHOT\\testjclass.class";
        FileInputStream fis = new FileInputStream(filePath);

        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==23){
                    ConstantUtf8Info uInfo = (ConstantUtf8Info) infos[i]; //刚刚那里是CONSTANT_Utf-8_info所以这里要用这个
                    uInfo.setString("你好程序世界!");
                    infos[i] = uInfo;
                }
            }
        }
        cf.setConstantPool(infos);
        fis.close();
        File f = new File(filePath);
        ClassFileWriter.writeToFile(f, cf);
    }
}

这里我把helloworld改成了你好程序世界!

我们编译后不报错就可以了,在代码中配置的 filePath 目录D:\\swjava\\ss-1.0-SNAPSHOT\\里,我们看testjclass.class这个文件的修改日期,就会发现这个文件已经被修改了

接下来就简单了,我们把testjclass.class替换原来jar包的class文件,有2种方式

1、解压被修改的jar包,在相应class位置覆盖原来class文件,然后把解压目录再压缩为zip格式的压缩包,把zip后缀改jar后缀

2、用压缩工具直接打开要修改的jar包,把修改了的class文件直接拖进去覆盖

这里我推荐第2种方法,因为第一种我测试会报错,而且发现第一种解压后再压缩,jar的大小变化很大,可能破坏了结构和压缩率之类的,导致不能运行。

我们再执行java -jar ss-1.0-SNAPSHOT.jar,就会输出修改后的内容了

修改jar中变量 或者长量 步骤如下: 1.用jd-gui打开该jar 怎么打开不用我说了吧? 打开之后找到 要修改提示信息 的class文件 这里找到的是GenEntity 找到对应需要修改的代码所在的方法名 我这里含提示信息的这段代码在方法 getAllDataBase() 如下图: 2.用jd-gui或者winrar把GenEntity.class 解压出来到C盘 (目录无所谓) 3.双击桌面上安装好了的 jc lasslib bytecode viewer ,点击软件的 File -- Open Class File 打开你刚解压出来的class文件 4.点击methods--getAllDataBase--Code methods是表示方法不用说吧 getAllDataBase是刚在jd-gui里面找到的方法名 Code含了getAllDataBase方法里所有的信息 找到"不能打开数据库连接,请检查!" 这里这个工具没有提供搜索功能 如果这里很多内容 那么你可以点击 copy to clipboard把这里的内容复制到一个文本文件里面然后再搜索 这里找到的是第82行 5.点击第 82行后面的 #34 会跳转到Constant Pool常量池的第34个常量 6.再点右边的 cp info #362 会跳转到第362个常量 这里能看到String: 不能打开数据库连接,请检查! 也就是最后输出的信息 7.找到GenEntity.class的关键常量了现在就该修改它了 在eclipse里面新建一个Test来处理GenEntity.class [java] view plain copy import java.io.*; import org.gjt.jclasslib.io.ClassFileWriter; import org.gjt.jclasslib.structures.CPInfo; import org.gjt.jclasslib.structures.ClassFile; import org.gjt.jclasslib.structures.constants.ConstantUtf8Info; public class Test { public static void main(String[] args) throws Exception { String filePath = "C:\\GenEntity.class"; FileInputStream fis = new FileInputStream(filePath); DataInput di = new DataInputStream(fis); ClassFile cf = new ClassFile(); cf.read(di); CPInfo[] infos = cf.getConstantPool(); int count = infos.length; for (int i = 0; i < count; i++) { if (infos[i] != null) { System.out.print(i); System.out.print(" = "); System.out.print(infos[i].getVerbose()); System.out.print(" = "); System.out.println(infos[i].getTagVerbose()); if(i == 362){ ConstantUtf8Info uInfo = (ConstantUtf8Info)infos[i]; uInfo.setBytes("芝麻不开门!".getBytes()); infos[i]=uInfo; } } } cf.setConstantPool(infos); fis.close(); File f = new File(filePath); ClassFileWriter.writeToFile(f, cf); } } 这里需要注意"C:\\GenEntity.class"是我存放class的目录 if(i == 362) 这里是刚我在第七步找到的常量序号 "芝麻不开门!"这里是我想修改的文字信息! 运行Test.java 会有如下提示信息 没有报错就证明正常的 如果报错那么就有问题 9.把C盘刚修改后的GenEntity.class替换掉原来的GenEntity.class 怎么替换不用我说了吧.. 用winrar打开.jar 然后把GenEntity.class拖进去覆盖就行了 10.运行效果..
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

终极量化数据

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值