从正在运行的Java程序的内存中查找并读取特定types的对象

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

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

但是,切换到java时,事情会改变。 由于垃圾收集,内存分配和pipe理与java非常不同。 在C程序中,我会看一个堆栈地址,并确定它包含了我想要提取的variables。

所以我的问题是:

  1. Java对象是否有某种types的ID,所以我可以在内存转储中find这种types的对象?
  2. 如果是这样,我怎么找出一个types的ID(例如,什么是一个String的ID)?
  3. 如果没有这样的typesID,那么攻击者还有什么其他的可能性,比如来自java进程的java.security.PrivateKey

假设JMX被closures。

谢谢你的帮助

这比你想象的更容易:)

HotSpot可维护性代理做到了这一点。 它可以打开核心转储或使用ptrace附加到实时Java进程,然后提取JVM结构和所有Java对象的布局。 目标JVM不需要合作。 即使JMX和Attach机制被禁用,这也可以工作。

以下是如何检查远程JVM中给定类的实例的示例 。
sa-jdi.jar必须位于类路径中才能使用可维护性代理。

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

PS这里是SA 的来源 ,如果你想知道它是如何工作的。