【问题标题】:ASM bytecode instrumentation for method entry / exit用于方法进入/退出的 ASM 字节码检测
【发布时间】:2009-08-11 22:39:52
【问题描述】:

我创建了一个 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 来了解我需要使用哪些语句来生成正确的字节码。

【问题讨论】:

    标签: java assembly bytecode instrumentation java-bytecode-asm


    【解决方案1】:

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

    【讨论】:

    • 感谢您的回复。事实证明你是对的,反编译器是免费的,而不是最好的指标。自从写了这个原帖后,我就开始使用JAD反编译器了,看起来靠谱。
    【解决方案2】:

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

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

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

    【讨论】:

    • 我确实有 super.visitCode() 调用 - 我只是忘记将它添加到示例中。接得好。还有其他想法吗?当我运行它的检测代码时,它的反编译效果很差。感谢您的回复。
    • 我做的是 mv.visitCode,而不是 super.visitCode。不过我不认为这是个问题。
    • 另一个发现——DJ Decompiler 报告了正确的反编译代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-06
    • 1970-01-01
    • 2016-06-03
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多