java - 从正在运行的 java 程序的内存中定位并读取特定类型的对象

标签 java unix memory jvm jvm-hotspot

我必须评估从正在运行的 java 程序的内存中提取某些对象(例如 java.security.PrivateKey )有多困难。

我不太喜欢这种低级内存的东西,所以我从小型 C 程序开始,并熟悉 gdb , /proc/<pid>/maps , /proc/<pid>/mem和一个script转储所有内存区域。

但是,当切换到 java 时,情况就会发生变化。由于垃圾收集,内存的分配和管理与 Java 非常不同。在 C 程序中,我会查看堆栈地址并确定它包含我想要提取的变量。

所以我的问题是:

  1. Java 对象是否具有某种类型 ID,以便我可以在内存转储中定位该类型的对象?
  2. 如果是这样,我如何找到类型的 ID(例如 String 的 ID 是什么)?
  3. 如果没有这样的类型 ID,攻击者还必须提取哪些其他可能性,比如说 java.security.PrivateKey来自 java 进程?

假设JMX已关闭。

感谢您的帮助

最佳答案

这比您想象的还要容易:)

HotSpot Serviceability Agent发挥魔力。它可以使用 ptrace 打开核心转储或附加到实时 Java 进程。然后提取 JVM 结构和所有 Java 对象的布局。不需要目标JVM的配合。即使 JMX 和附加机制被禁用,这仍然有效。

这是一个example如何检查远程 JVM 中给定类的实例。
sa-jdi.jar 必须位于类路径中才能与 Serviceability Agent 一起使用。

最后是有史以来最简单的解决方案。运行 jmap -F -dump:format=b,file=heap.bin PID
注意 -F 参数 - 它强制 jmap 使用 Serviceability Agent 进行堆转储。

P.S. 这里是the sources如果您想了解 SA 的幕后工作原理,请访问 SA。

关于java - 从正在运行的 java 程序的内存中定位并读取特定类型的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32605962/

相关文章:

c - 在 C 中具有函数的 realloc 结构

c++ - 二维区域的内存布局

c++ - 分配和删除指针

java - 有什么方法可以将任何数字表示为 4 个平方和?

java - Spring 启动+JPA : Column name annotation ignored

java - 双重转义 XML 实体

database - PostgreSQL : 'psql: error: could not connect to server: No such file or directory' . s.PGSQL.5432

java - 如何解析时间范围输入?

linux - 为什么各种 Linux 发行版使用不同的包管理器?

ruby - 如何使用 PUBMEDid 从 pubmed 中获取摘要