如何在运行时从 JVM 中提取类文件
Posted
技术标签:
【中文标题】如何在运行时从 JVM 中提取类文件【英文标题】:How to extract class files at runtime from a JVM 【发布时间】:2021-01-27 14:10:59 【问题描述】:我的 JVM 上运行了一个 Jar 应用程序。应用程序在运行时会下载额外的.class
文件。这些被加载到应用程序的内存中(我通过堆和线程转储进行了验证)。我想提取类文件并反编译它们以查看发生了什么。
有谁知道任何工具可以保存 Jar 的确切当前状态,然后从 JVM 运行时反编译或反编译(或提取 .class
文件)?
【问题讨论】:
一个更好的主意:如果应用程序下载并运行神秘代码,而您没有充分的理由信任该应用程序:不要运行它。 “jar 的确切当前状态”永远不会改变。 jar 文件不受内存中的类的影响。您如何“通过堆和线程转储”验证是否有其他类加载到内存中? 我可以看到额外的包被加载到 JAR 的内存中。从服务器下载一个 zip 文件,然后在内存中解压缩(我猜)并加载到 jar/jvm/memory 中。 【参考方案1】:使用JVMTI接口,可以做一个所谓的代理。对于实际传递到类加载器进行加载的每个类文件都会调用这些文件,此时您可以选择保存它。
像往常一样制作一个主应用程序,但不是psv main(String[])
,而是public static void premain(String args, Instrumentation instrumentation)
。
用它制作一个 jar 就像你制作一个普通的 java 可运行 jar 一样,除了清单 Main-Class
条目,它是 Premain-Class
。
将其作为代理 (java -javaagent:yourjar.jar -therestofyouroptionsasnormal
) 启动,您的 premain 将在实际 main 之前被调用一次。然后,在您如此获得的Instrumentation
实例上,调用addTransformer
,传入您编写的ClassFileTransformer
实现的实例。这个转换器实际上不会转换任何东西,但它的transform
方法将被调用,让您看到正在加载的类文件。例如,如果需要,可以将它们保存到目录中。
【讨论】:
以上是关于如何在运行时从 JVM 中提取类文件的主要内容,如果未能解决你的问题,请参考以下文章