asm中visitMethodInsn方法动态注入问题

们会 发布于 2020/07/09 22:14
阅读 432
收藏 0

注意:我能够确定我的其他程序是没有问题的,因为这是我从其他地方复制粘贴的代码,并且可以跑通,我的目的是实现自己的动态注入。

当我尝试通过ASM对字节码进行注入时,遇到了以下问题。

在我借助idea的 ASM Bytecode Outline 插件将代码转换后,再对照ASM进行设置。

下图是我想要注入到字节码中的代码:

下面是该代码生成的asm辅助文件:

public class cn/test/Temp {

  // compiled from: Temp.java
  // access flags 0x19
  public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup

  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 14 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcn/test/Temp; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x1
  public test()V
   L0
    LINENUMBER 16 L0
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "start==============================="
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L1
    LINENUMBER 17 L1
    INVOKESTATIC java/lang/Thread.currentThread ()Ljava/lang/Thread;
    INVOKEVIRTUAL java/lang/Thread.getStackTrace ()[Ljava/lang/StackTraceElement;
    ICONST_1
    AALOAD
    ASTORE 1
   L2
    LINENUMBER 18 L2
    ALOAD 1
    INVOKEVIRTUAL java/lang/StackTraceElement.getClassName ()Ljava/lang/String;
    ALOAD 1
    INVOKEVIRTUAL java/lang/StackTraceElement.getMethodName ()Ljava/lang/String;
    INVOKEDYNAMIC makeConcatWithConstants(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; [
      // handle kind 0x6 : INVOKESTATIC
      java/lang/invoke/StringConcatFactory.makeConcatWithConstants(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
      // arguments:
      "\u0001\u0001"
    ]
    ASTORE 2
   L3
    LINENUMBER 19 L3
    ALOAD 2
    INVOKESTATIC java/lang/System.nanoTime ()J
    INVOKESTATIC cn/util/TimeCache.setStartTime (Ljava/lang/String;J)V
   L4
    LINENUMBER 21 L4
    ALOAD 2
    INVOKESTATIC java/lang/System.nanoTime ()J
    INVOKESTATIC cn/util/TimeCache.setEndTime (Ljava/lang/String;J)V
   L5
    LINENUMBER 22 L5
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "end==============================="
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L6
    LINENUMBER 23 L6
    ALOAD 2
    INVOKESTATIC cn/util/TimeCache.getCostTime (Ljava/lang/String;)Ljava/lang/String;
    ASTORE 3
   L7
    LINENUMBER 24 L7
    GETSTATIC cn/util/TimeCache.methodMonitorBeanBOS : Ljava/util/List;
    NEW cn/entity/MethodMonitorBeanBO
    DUP
    ALOAD 2
    ALOAD 3
    ICONST_1
    INVOKESPECIAL cn/entity/MethodMonitorBeanBO.<init> (Ljava/lang/String;Ljava/lang/String;Z)V
    INVOKEINTERFACE java/util/List.add (Ljava/lang/Object;)Z (itf)
    POP
   L8
    LINENUMBER 25 L8
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ALOAD 3
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L9
    LINENUMBER 26 L9
    RETURN
   L10
    LOCALVARIABLE this Lcn/test/Temp; L0 L10 0
    LOCALVARIABLE stackTraceElement Ljava/lang/StackTraceElement; L2 L10 1
    LOCALVARIABLE methodFullName Ljava/lang/String; L3 L10 2
    LOCALVARIABLE costTime Ljava/lang/String; L7 L10 3
    MAXSTACK = 6
    MAXLOCALS = 4
}

对照该文件我对自己的ASM ClassVisitor 文件部分设置如下:

但是在我执行代码时,控制台爆出错误:

出错误的地方便是图中红框处,但是我无法找到自己的错误在哪里。

对于 currentThread 方法的参数为空,返回值为Thread:

希望有遇过的大佬能帮忙看一下,小弟在此先跪谢各位了。

加载中
0
们会
们会

问题已解决,正确的添加姿势为:

mv.visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "currentThread", "()Ljava/lang/Thread;", false);

相对于错误的添加方法,只需要在参数四最后面添加一个分号,我之前以为它只是一个分隔符,但实际上是需要添加的。

0
们会
们会

我尝试在测试类中添加

import java.lang.Thread;

但是依然报错。

OSCHINA
登录后可查看更多优质内容
返回顶部
顶部