如何在类加载时调试注入VM的字节码?

时间:2010-11-13 01:01:03

标签: java debugging jvm bytecode code-injection

上下文: 在我的Java项目中,我是字节码注入一个类(比如Injected.java),也是字节码,它注入了对Injected.java中方法的引用,这样这个方法就可以设置实例成员的值。这是验证我是字节码注入正确事物的一种方法。

问题: 在运行时,实例变量的值未按预期设置 - 这意味着我的字节码注入显然不能正常工作。

问题: 1)如何在运行时检查JVM中加载的(新注入+修改)类的内容? (javap帮助现有课程执行此操作) 2)我可以通过Eclipse调试,字节码注入代码吗?是否有插件

任何建议都表示赞赏。

1 个答案:

答案 0 :(得分:1)

您可以使用javaassist

让我们一步一步走:

  1. 获取要通过字节码注入修改的类文件的内容(例如, Point.class BufferedInputStream fin = new BufferedInputStream(new FileInputStream("Point.class")); ClassFile cf = new ClassFile(new DataInputStream(fin));

  2. ClassFile提供了addField()和addMethod()来添加字段或方法(请注意,构造函数被视为字节码级别的方法)。它还提供了addAttribute(),用于向类文件添加属性。

    请注意,FieldInfo,MethodInfo和AttributeInfo对象包含指向ConstPool(常量池表)对象的链接。 ConstPool对象必须与ClassFile对象以及添加到该ClassFile对象的FieldInfo(或MethodInfo等)对象相同。换句话说,不能在不同的ClassFile对象之间共享FieldInfo(或MethodInfo等)对象。

    要从ClassFile对象中删除字段或方法,必须首先获取包含该类的所有字段的java.util.List对象。 getFields()和getMethods()返回列表。可以通过调用List对象上的remove()来删除字段或方法。可以以类似的方式删除属性。在FieldInfo或MethodInfo中调用getAttributes()以获取属性列表,并从列表中删除一个。

  3. 现在,检查注射是否真的有效:

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

    CodeAttribute ca = minfo.getCodeAttribute();

    MethodInfo / CodeAttribute 中有多种方法可以检查

  4. 如果您喜欢,请告诉我。那个案例我将在http://puspendu.wordpress.com/

    上放一个更详细的博客

    参考:here