通过附加API检测Java类
我试图通过通过附加API检测Java类,java,bytecode,instrumentation,java-bytecode-asm,Java,Bytecode,Instrumentation,Java Bytecode Asm,我试图通过attachAPI插入java类(我想专门插入java.sql.DriverManager.getConnection()方法,并记录返回的Connection对象) 因此,我正在执行存储和加载操作,并调用在我的一个类中定义的方法(例如,foo.TestRecordingClass.myfoorrecordingmethod()) 现在,我的问题是,每当我试图调用前面提到的方法时(通过attach API:agentmain被调用),我都会得到一个NoClassDefFoundErro
attach
API插入java类(我想专门插入java.sql.DriverManager.getConnection()
方法,并记录返回的Connection
对象)
因此,我正在执行存储和加载操作,并调用在我的一个类中定义的方法(例如,foo.TestRecordingClass.myfoorrecordingmethod()
)
现在,我的问题是,每当我试图调用前面提到的方法时(通过attach API:agentmain
被调用),我都会得到一个NoClassDefFoundError
但是,同样的东西在premain
,也就是Xbootclasspath方法中完美地插入
提前感谢:-)
编辑1:
好的,我可以使用appendToBootstrapClassLoaderSearch(JarFile)
methodofinstrumentation
object解决这个问题
现在,我面临的另一个问题是,将一个对象加载到堆栈中
理论上,如果我执行aload_0
操作,应该加载当前对象,那么我可以将其传递给任何方法,对吗
在方法visitInsn
(即从方法返回时)中,我执行以下操作:
super.visitVarInsn(opcode.ALOAD,0);
super.visitMethodInsn(opcode.INVOKESTATIC,fooClassName,“fooMethodReturnInstrumentor”,“Ljava/lang/Object;)V)代码>
这应该加载对象本身,但我无法检索任何内容。如果插入一个类并插入对其他类的新引用,这些类必须能够被插入类访问,包括通过其类加载器
解析它必须成功(与)并且它必须位于相同的包中
,或者具有公共
访问修饰符。包含一些关于检测核心Java类的注释
因此,如果您的foo.TestRecordingClass
是public
并添加到引导类路径,则任何插入指令的类都可以访问它
只有当方法不是静态的且不是构造函数时,第一个变量才包含此
。在后一种情况下,第一个变量包含未初始化的this,在调用超级构造函数之前无法将其传递给方法调用
另一方面,此赋值仅在方法开始时固定。在该方法中,该变量可能会被重用用于其他目的,甚至在两个用于不同目的的分支路径连接时变得无效
因此,在不是构造函数的实例方法的开头,您确实可以放置一个aload_0
,然后是一个使用一个对象的invokestatic
,以将此
传递给该方法。您的“我无法检索任何内容”问题描述有点单薄。如果从未调用您的方法,这可能是从未调用插入指令的代码的简单标志。如果收到null
,则强烈指示第一个变量不包含此
。然后,验证插入的调用是否真正位于实例方法的开头
如果要将调用放置在其他位置,则必须检查变量0在方法调用之前是否从未被覆盖。谢谢您的回复。我故意更改了visitMethodInsn
签名/没有加载参数。在这两种情况下,我都得到了verifyerror,这意味着指令正在被调用。但是,每当我尝试加载常量值时(通过ldc
),都不会发生任何事情。好吧,如果不将值加载到堆栈中,就不能调用具有参数/使用一个对象的方法。但是获得验证错误
并不是调用代码的安全标志。JVM可能会在类加载或方法项上验证代码,这两种情况都不意味着会调用特定的指令。非常感谢您的快速回复。你真是个救命恩人。但是,我仍然面临着这个问题。让我详细解释我的问题:我想跟踪JDBC
连接何时关闭。因此,为此,我需要为实现连接的类插入指令。在close()
方法的返回块中,我想插入一些东西(比如一些常量值)。如果我收到了一些严重的错误,事情就会一帆风顺。但是,到目前为止,我还在挠头,什么也没有出现。重命名原始的close
方法并插入一个新方法更容易,该方法调用重命名的原始方法并执行post操作。因此,您不必处理原始close
方法的未知、可能非常复杂的结构。您确实是一个摇滚明星。让我试一下。如果有任何问题,我会回复你(我希望我没有太烦你:-)