jclasslib,javaasist-修改.class字节码

修改字节码有jclasslib、javassist、 asm等

jclasslib修改常量很简单,但是修改方法好像行不通

javassist:修改方法特别简单,值得一试

asm:听说要学习指令

 

jclasslib的使用

具体如何使用请参照原文:http://blog.csdn.net/hexin373/article/details/6669813

github官方地址:https://github.com/ingokegel/jclasslib 

jclaslib bytecode viewer安装包下载路径:https://github.com/ingokegel/jclasslib/releases

关于类库的获取,我在Mac上使用安装包安装好以后,查看包内容,找到jclasslib-library.jar、kotlin-runtime-1.0.6.jar、kotlin-stdlib-1.0.6.jar、kotlinx.dom-0.0.10.jar等jar包

原作者的程序CPINFO类不存在了改用CONSTANT替换,下面是我的demo字符串替换程序

 

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.ConstantUtf8Info;
public class replaceConstant {   
    public static void main(String[] args) throws Exception {   
  
        String filePath = "~/Desktop/B.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) {   
                System.out.print(i);   
                System.out.print(" = ");   
                System.out.print(infos[i].getVerbose());   
                System.out.print(" = ");
                System.out.println(infos[i]);
                if(i == 55){   
                    ConstantUtf8Info uInfo = (ConstantUtf8Info)infos[i];   
                    uInfo.setString("芝麻不开门哦!");
                    infos[i]=uInfo;   
                }   
            }   
        }   
        cf.setConstantPool(infos);   
        fis.close();   
        File f = new File(filePath);   
        ClassFileWriter.writeToFile(f, cf);   
    }   
}

 

至于如何修改方法,http://www.cnblogs.com/xuelu/p/3840694.html 这篇博文介绍的很详细,但是我没有实践出来 ,感觉修改起来太麻烦了。

 

javassist的使用

官方网址:http://jboss-javassist.github.io/javassist/

github:https://github.com/jboss-javassist/javassist

官方指南:http://jboss-javassist.github.io/javassist/tutorial/tutorial.html

Javassist简单应用小结 http://blog.csdn.net/mousebaby808/article/details/37696371

下面是一个修改方法的简单demo程序

Login.java

 

public class Login {
    public boolean verify(){
        return false;
    }
}

 

ChangeMethod.java

 

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;

import java.lang.reflect.Method;

public class ChangeMethod {
    public static void main(String[] args) throws Exception {
        ClassPool pool = ClassPool.getDefault();
        //设置目标类的路径
        pool.insertClassPath("~/demo/target/classes/") ;
        //获得要修改的类
        CtClass cc =pool.get("Login");//就是对Login.class的映射
        //得到方法
        CtMethod m = cc.getDeclaredMethod("verify");
        //可以在函数的开头插入新的代码
        //m.insertBefore("{return true;}") ;
        //也可以直接将verify函数的内容设为return true;至于功能你懂的
        m.setBody("{return true;}");
        //保存到文件里,会在项目根目录下生成一个Login.class,并没有自动替换classes/Login.class,需要自己手动替换进去
        cc.writeFile() ;
        Object o=cc.toClass().newInstance();
        Method verify=o.getClass().getDeclaredMethod("verify");
        System.out.println(verify.invoke(o));
    }
}

可以看到输出结果永远都是true,直接跳过授权验证。

github大神有直接修改jar包的demo,思路就是先解压缩jar包,修改.class文件,重新压缩打包成jar包

jar包解压以后打包会变大不知道为什么,test.jar包解压到test目录,修改class文件以后执行“jar -cvf jar包名 文件”

cd test
jar -cvf test.jar *

 

 

 

你可能感兴趣的:(java)