我必须评估从正在运行的 java 程序的内存中提取某些对象(例如 java.security.PrivateKey
)有多困难。
我不太喜欢这种低级内存的东西,所以我从小型 C 程序开始,并熟悉 gdb
, /proc/<pid>/maps
, /proc/<pid>/mem
和一个script转储所有内存区域。
但是,当切换到 java 时,情况就会发生变化。由于垃圾收集,内存的分配和管理与 Java 非常不同。在 C 程序中,我会查看堆栈地址并确定它包含我想要提取的变量。
所以我的问题是:
- Java 对象是否具有某种类型 ID,以便我可以在内存转储中定位该类型的对象?
- 如果是这样,我如何找到类型的 ID(例如
String
的 ID 是什么)? - 如果没有这样的类型 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/