查找字节码
如何才能找到正在运行的 Java 程序在内存中的何处存储其运行的字节码?我知道这可能会也可能不会非常困难。
How could one go about finding where in memory a running java program was storing the bytecode it was running off of? I appreciate this may or may not be excruciatingly difficult.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
查看本机函数的源代码
java.lang.ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String, boolean)
这是 VM 特定的,因此没有通用解决方案。
如果你想查看字节码,只需将类作为资源加载(例如 getClass().getClassLoader().getResourceAsStream('java/lang/String.class'))并分析使用 ASM 或类似工具进行流式传输。
如果您想在运行时修改字节码:祝您好运。虚拟机已经针对此类攻击进行了强化,因此即使您可以获得内存位置,更改也可能会被捕获。
请注意,调试器不会修改内存,当有人在 IDE 中更改源代码时请求类时,它们会使用特殊的类加载器(或内置类加载器的功能)返回不同的结果。但这是有限制的。例如,某些虚拟机在类加载一次后就无法更改方法的数量和/或参数。
Look at the source code for the native function
java.lang.ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String, boolean)
This is a VM specfic, so there is no general solution.
If you want to look at the byte code, just load the class as a resource (for example
getClass().getClassLoader().getResourceAsStream('java/lang/String.class')
) and analyze that stream with a tool like ASM or similar.If you want to modify the byte code at runtime: Good luck with that. The VM has been hardened against such attacks so even if you could get the memory location, chances are that changes would get caught.
Note that debuggers don't modify the memory, they use special class loaders (or features of the built in class loader) to return a different result when someone asks for a class when the source code has been changed in the IDE. But there are limits to that. Some VMs can't change the number and/or arguments of methods after a class has been loaded once, for example.
您可以尝试使用调试器运行 jvm,然后在加载类后立即在分配的内存中搜索字节代码模式,该字节代码模式可以在加载的类文件中找到。
jvm 可能决定及时编译字节码,然后可能决定释放为字节码分配的内存(因为不再需要它)。因此,您可能会也可能不会在内存中的某个位置找到字节码。
You could try running the jvm with a debugger and then, right after a class has been loaded, search the allocated memory for the byte code pattern, that can be found in the loaded class file.
The jvm may decide to compile the byte code just in time and then it may decide to free the memory that was allocated for the byte code (because it's not needed anymore). So you may or may not find the byte code somewhere in memory.
当 JVM 读取字节码时,它会分多个阶段对其进行处理,直到最终生成本机代码(它可能会执行多次)尝试找到存储字节码的内存,并且更改它可能不会执行任何操作因为它可能不会直接使用字节码(甚至不会保留它)
如果您想动态更改字节码,我建议您在加载之前检查它或使用旨在更改字节码并会触发的Instrumentation发生这种情况时的正确行为。
字节码是虚拟使用的,不能保证它对真实机器有任何意义(这是你在“C”级别看到的)
When the JVM reads the byte code, it massages it in a number of phases until finally it produces native code (which it may do more than once) Attempting to find somewhere is memory that the byte code is stored and altering it may not do anything because it may not use the byte code directly (nor even retain it)
If you want to change the byte code on the fly, I suggest you check it before it is loaded or use the Instrumentation which is designed to change byte code and will trigger the right behaviour when this happen.
The byte code is used virtually, there is no guarantee it means anything to the real machine (which is what you see at the "C" level)