2011-08-25 124 views
1

如何才能找到正在运行的java程序在内存中存储正在运行的字节码?我很欣赏这可能会或可能不会令人难以忍受。寻找字节码

+1

字节代码存储在.class文件。你具体是什么意思? – AlexR

+0

当程序运行时它从磁盘加载到内存中,不是吗?如何找到存储在这个'.class'文件中的字节码? – providence

+0

看来你并不是在问你的“真实”问题。你想解决什么问题?如果你想拦截类加载,可能会有更好更简单的解决方案。 – AlexR

回答

2

看的源代码的本机函数java.lang.ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String, boolean)

这是一个VM specfic,所以没有通用的解决方案。

如果您想查看字节码,只需将该类加载为资源(例如getClass().getClassLoader().getResourceAsStream('java/lang/String.class'))并使用类似ASM或类似工具分析该流。

如果您想在运行时修改字节码:祝您好运。虚拟机已经针对这种攻击进行了强化,所以即使你能够获得内存位置,也有可能发生这种变化。

请注意,调试器不会修改内存,它们使用特殊的类加载器(或内置的类加载器的功能)在IDE中更改源代码时有人要求类时返回不同的结果。但是这是有限的。例如,一个虚拟机在类加载一次后不能更改方法的数量和/或参数。

+0

嗯..我不需要这个在我自己以外的任何机器上工作,真的。有没有一个JVM,我可以叉/扩展来允许这个? – providence

+0

当然:http://openjdk.java.net/ –

1

您可以尝试使用调试器运行jvm,然后在加载类后立即在分配的内存中搜索字节代码模式,该模式可以在加载的类文件中找到。

jvm可能决定及时编译字节码,然后它可能决定释放为字节码分配的内存(因为它不再需要)。所以你可能会也可能不会在内存中找到字节码。

+0

是否可以采用相同的方法开发调试工具以在调试模式之外访问这些内容? – providence

1

当JVM读取字节码时,它会多次处理它,直到它最终生成本地代码(它可能会执行多次)。尝试查找某处是存储字节码并更改它可能不会做任何事情,因为它可能不直接使用字节代码(甚至不保留它)

如果您想要更改字节代码,建议您在加载之前检查它,或者使用Instrumentation旨在改变字节码,并在这种情况发生时触发正确的行为。

字节码实际上是用,也不能保证它意味着什么真机(这是你所看到的“C”级)

+0

数据+数据结构(可以说是一个数组)的字节码表示如何传递到正在运行的程序中?这些表示是否可以在运行时从外部生成并从外部传入? – providence

+0

@providence:对此 –

+0

@providence打开一个新问题,执行此操作的方法是按照我的建议进行更改。你采取的方法极不可能工作。 JVM在运行时会执行大量的优化,并且代码的概念远比您所认为的更流畅。 –