原生 Java 字节码检测
对于 Java 中的字节码检测,有 asm 框架以及 bcel 和 javaassist 库。
但是,我需要在本机代码中进行检测,因为在 javaagent 运行时已经加载了一些 java 类,例如 java.lang.Thread、java.lang.Class 等,
是否有任何库可以在本机代码中检测 java 类?
编辑: 似乎有一点混乱。
我想要的是: 创建一个本机 java 代理,它使用 JVMTI api 在加载类时使用 OnClassLoad 事件挂钩更改该类的字节码。
for bytecode instrumentation in java, there is the asm framework and the bcel and javaassist libraries.
However I need to do instrumentation in native code, since some java classes are already loaded by the time the javaagent runs, eg java.lang.Thread, java.lang.Class, etc
is there any library for instrumenting java classes in native code?
Edit:
Seems there is a bit of confusion.
What I want is:
Create a native java agent, which uses JVMTI apis to change the bytecode of a class while its being loaded, using the OnClassLoad event hook.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我在博士研究期间就遇到了这个问题。对我来说最有效的答案是使用 java 库(我使用 ASM)在单独的 JVM 中执行字节码修改。
我使用 JVMTI 类加载挂钩来捕获类文件,并使用 tcp 连接将其传输到单独的 JVM。在单独的 JVM 中修改该类后,我将其返回给 JVMTI 代理,后者将其复制到 VM 内存中,并将指向修改后的类文件的指针返回给 JVM。
我发现在正在分析的同一个 JVM 中编织类太困难了,因为必须先加载我想要修改的系统类文件(例如 java.lang.Object),然后才能执行编织所需的任何类文件。在选择最终使用的单独 JVM 方法之前,我寻找了 c/c++ 字节码库,但没有取得太大成功。
您可以使用编织器 JVM 的主机名/端口来参数化 JVMTI 代理,也可以使用某种形式的发现,具体取决于您的要求。
I encountered this problem during my doctoral research. The answer that worked best for me was to perform the byte-code modification in a separate JVM using a java library (I used ASM).
I used the JVMTI class load hook to capture the class file and transmit it to the separate JVM using a tcp connection. Once the class had been modified within the separate JVM I returned it to the JVMTI Agent, which copies it into VM memory and returns a pointer to the modified class file to the JVM.
I found that it was too difficult to weave classes within the same JVM as was being profiled as the system class files I wanted to modify (java.lang.Object, for example) had to be loaded before any class files I needed to perform weaving. I hunted for c/c++ bytecode libraries without much success, before settling on the separate JVM approach I finally used.
You can parameterize the JVMTI agent with the hostname/port of the weaver JVM, or you could use some form of discovery, depending on your requirements.
JIT 会将字节码转换为本机代码。如果要生成本机代码,则需要让 JIT 来完成或编写通过 JNI 调用的本机代码。
也许您想要实现的目标可以通过另一种更简单的方式来完成。
虽然你不需要做你想做的事。为什么要让解决方案变得比需要的更复杂(并且不太可能有效)?
The JIT will turn byte code into native code. If you want to produce native code, you need to let the JIT do it or write native code which is called via JNI.
Perhaps what you are trying to achieve can be done simpler another way.
Though you don't need to do what you want. Why make the solution more complicated (and less likely to work) than it needs to be?
一旦类被加载,就不能更改它的字节码。您可以确保您的检测在加载之前运行,也可以创建一个新的 ClassLoader,并通过不询问父类来重新加载其中的类。但是,您不能将这些类与在 ClassLoader 外部加载的代码一起使用,因为该代码将引用较早加载的未更改的类。
You cannot change the byte code of a class once it has been loaded. You can either make sure your instrumentation runs before it is loaded, or you can create a new ClassLoader, and re-load the classes inside of it by not asking the parent class. You can't use those classes with code loaded outside of the ClassLoader though, as that code will refer to the earlier loaded, non-altered class.