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 *

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章