1

我创建了一个 JVMTI 代理,它在高级别执行以下操作:

  • onClassLoadHook 将加载类的字节码发送到一个单独的 Java 进程,该进程将使用 ASM 检测类

  • 取回字节码并加载它们

在我对加载的 Java 类进行检测的单独 Java 进程中,我执行以下操作:

......

    cr = new ClassReader(inBytes, offset, inLen);
    cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

    ClassAdapter ca = new ClassAdapter(cw) {
    ..
    ..

        @Override
        public MethodVisitor visitMethod(final int access,
                                         final String name,
                                         final String desc,
                                         String signature,
                                         String[] exceptions) {

            return new MethodAdapter(mv) {

                @Override
                public void visitCode() {

                    mv.visitVarInsn(Opcodes.ALOAD, 0);
                    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/amir/Tester", "callTestStatic3", "(Ljava/lang/Object;)V");
                    mv.visitCode();

                }

            }
        }

当我尝试使用 Java Decompiler 反编译在此检测之后编写的类时 - 我看到以下我知道是错误的反编译函数:

  public void func1(int arg1, int arg2)
  {
    int b;
    Tester.callTestStatic3(???); 
    System.out.println("arg = " + a + " b = " + b);

  }

因为我的函数实际上是这样的:

public void func1(int a, int b) 
{

    System.out.println("arg = " +a + " b = " +b);

}

谁能告诉我我在这里做错了什么?我唯一的线索是,如果不是将 THIS 指针作为参数传递给我的函数,而是传入原始类型,那么一切都会顺利进行。我需要管理的 THIS 指针有什么特别之处吗?我已经比较了字节码,并使用了 ASMIFIER 来了解我需要使用哪些语句来生成正确的字节码。

4

2 回答 2

1

也许没关系,但你不应该打电话super.visitCode()吗?

@Override
public void visitCode() {
  super.visitCode();
  ...

我会使用TraceClassVisitor来准确检查正在生成的内容。

于 2009-08-11T23:12:44.163 回答
1

使用 mv.visitCode() 看起来您的代码是正确的。javap 显示预期的字节码。我猜你原来的反编译器只是没有做正确的事情。

于 2009-08-22T01:05:13.410 回答