crazy horse
crazy horse

Reputation: 423

how to debug byte code injected into VM at class load time?

Context: In my Java project, I am byte-code injecting a class (say Injected.java) and also byte-code injecting a reference to a method in Injected.java, such that this method sets the value of an instance member. This is one way to verify that I am byte-code injecting the right thing.

Issue: At run-time, the value of the instance variable is not set as expected - meaning that my byte-code injection obviously did not work well.

Question: 1) How do I examine the contents of my (newly injected + modified) class loaded in the JVM at run-time? (javap helps do this for existing classes) 2) Can I debug via Eclipse, the byte-code injected code? Is there a plug-in

Any suggestion is appreciated.

Upvotes: 4

Views: 1427

Answers (1)

Puspendu Banerjee
Puspendu Banerjee

Reputation: 2651

You can use javaassist

Let's go step by step:

  1. Obtain the content of the class file(say, Point.class), that you want to modify by bytecode injection BufferedInputStream fin = new BufferedInputStream(new FileInputStream("Point.class")); ClassFile cf = new ClassFile(new DataInputStream(fin));

  2. ClassFile provides addField() and addMethod() for adding a field or a method (note that a constructor is regarded as a method at the bytecode level). It also provides addAttribute() for adding an attribute to the class file.

    Note that FieldInfo, MethodInfo, and AttributeInfo objects include a link to a ConstPool (constant pool table) object. The ConstPool object must be common to the ClassFile object and a FieldInfo (or MethodInfo etc.) object that is added to that ClassFile object. In other words, a FieldInfo (or MethodInfo etc.) object must not be shared among different ClassFile objects.

    To remove a field or a method from a ClassFile object, you must first obtain a java.util.List object containing all the fields of the class. getFields() and getMethods() return the lists. A field or a method can be removed by calling remove() on the List object. An attribute can be removed in a similar way. Call getAttributes() in FieldInfo or MethodInfo to obtain the list of attributes, and remove one from the list.

  3. Now, check, if injection really worked:

    MethodInfo minfo = cf.getMethod("move"); // we assume move is not overloaded.

    CodeAttribute ca = minfo.getCodeAttribute();

    there is a number of methods in MethodInfo / CodeAttribute to check

If you like it, please let me know. That case I shall put a more detailed blog at http://puspendu.wordpress.com/

Ref: here

Upvotes: 1

Related Questions