Play with your byte-code using Javassist
I came to know about this nice tool named javassist which is a cool java byte code manipulation tool.It provides users with a very easy to use API to modify / create java classes in the Runtime. It provides some API to do that using a Java like syntax so that we can easily hack the byte code without knowing any thing in-depth about the byte code structure.
In this blog post I'll explain you a simple example on how to use this tool.This will show how we can use javassist to change the byte code of a compiled class to change a method implementation in Runtime.
Step 1
Download javassist library from http://sourceforge.net/projects/jboss/files/Javassist/3.14.0.GA/
Step 2
Create a new directory and copy javassist.jar to that directory.
Step 3
Create Two java source file named HelloWorld.java and ByteCodeInjector.java in that directry
HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
new HelloWorld().sayHello();
}
public void sayHello(){
System.out.println("Hello!!! This is the original version!!!");
}
}
ByteCodeInjector.java
import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import java.io.IOException;
import static javassist.ClassPool.getDefault;
public class ByteCodeInjector {
public static final String CLASS_NAME = "HelloWorld";
public static final String METHOD = "sayHello";
public static void main(String[] argos) throws Exception{
modifyByteCode(CLASS_NAME,METHOD);
}
public static void modifyByteCode(String className ,String methodName)
throws NotFoundException, CannotCompileException, IOException {
//Get the Class implementation byte code
CtClass ctClass = getDefault().get(className);
//Get the method from the Class byte code
CtMethod method= ctClass.getDeclaredMethod(methodName);
/**
* Creating the new Method implementation
*/
StringBuffer content = new StringBuffer();
content.append("{\n System.out.println(\"Hello!!! This is the Modified version!!!\");\n } ");
/**
* Inserting the content
*/
method.setBody(content.toString());
System.out.println("Replacing Method \' sayHello\' s body with new implementation : " + content);
//modify the actual class File
ctClass.writeFile();
}
}
Step 4
Compile the two java sources adding the javassist.jar to your class path
$javac -cp javassist.jar:. HelloWorld.java ByteCodeInjector.java
Step 5
Run the HelloWorld class and see the out put
$java HelloWorld
Hello!!! This is the original version!!!
Step 6
Now Run the ByteCodeInjector class. That class will change the method implementation of the Helloworld:sayHello()
$java -cp javassist.jar:. ByteCodeInjector
Replacing Method ' sayHello' s body with new implementation : {
System.out.println("Hello!!! This is the Modified version!!!");
}
Now if you run the HelloWorld class you must see a output like
Hello!!! This is the Modified version!!!
Enjoy!!!
References
[1]http://www.csg.is.titech.ac.jp/~chiba/javassist/tutorial/tutorial.html
Comments
is it possible withe javassist to inject anything before calling a specific method and delete this adding also like this
m.insertBefore("method1()");
how i can delete it in other times?