从 运行 java 程序的内存中定位并读取特定类型的对象
Locate and read objects of a specific type from memory of a running java program
我必须评估从 运行 java 程序的内存中提取某些对象(例如 java.security.PrivateKey
)的难度。
我不太喜欢这种低级内存的东西,所以我从小的 C 程序开始,熟悉了 gdb
、/proc/<pid>/maps
、/proc/<pid>/mem
和 script 转储所有内存区域。
但是,当切换到 java 时,情况发生了变化。由于垃圾收集,内存的分配和管理与 java 截然不同。在 C 程序中,我会查看堆栈地址并确定它包含我想要提取的变量。
所以我的问题是:
- Java 对象是否具有某种类型 ID,以便我可以在内存转储中找到该类型的对象?
- 如果是这样,我如何找出类型的 ID(例如
String
的 ID 是什么)?
- 如果没有这样的类型 ID,攻击者还有哪些其他可能性必须从 java 进程中提取
java.security.PrivateKey
?
假设JMX关闭。
感谢您的帮助
这比您想象的还要容易:)
HotSpot Serviceability Agent does the magic. It can open a core dump or attach to a live Java process using ptrace 然后提取 JVM 结构和所有 Java 对象的布局。不需要目标 JVM 的合作。即使禁用 JMX 和附加机制,这仍然有效。
这里是 example 如何检查远程 JVM 中给定 class 的实例。
sa-jdi.jar
必须在 class 路径中才能使用可服务性代理。
终于找到有史以来最简单的解决方案。 运行
jmap -F -dump:format=b,file=heap.bin PID
注意 -F
参数 - 它强制 jmap
使用 Serviceability Agent 进行堆转储。
P.S. 如果您想了解 SA 的幕后工作原理,请查看 the sources。
我必须评估从 运行 java 程序的内存中提取某些对象(例如 java.security.PrivateKey
)的难度。
我不太喜欢这种低级内存的东西,所以我从小的 C 程序开始,熟悉了 gdb
、/proc/<pid>/maps
、/proc/<pid>/mem
和 script 转储所有内存区域。
但是,当切换到 java 时,情况发生了变化。由于垃圾收集,内存的分配和管理与 java 截然不同。在 C 程序中,我会查看堆栈地址并确定它包含我想要提取的变量。
所以我的问题是:
- Java 对象是否具有某种类型 ID,以便我可以在内存转储中找到该类型的对象?
- 如果是这样,我如何找出类型的 ID(例如
String
的 ID 是什么)? - 如果没有这样的类型 ID,攻击者还有哪些其他可能性必须从 java 进程中提取
java.security.PrivateKey
?
假设JMX关闭。
感谢您的帮助
这比您想象的还要容易:)
HotSpot Serviceability Agent does the magic. It can open a core dump or attach to a live Java process using ptrace 然后提取 JVM 结构和所有 Java 对象的布局。不需要目标 JVM 的合作。即使禁用 JMX 和附加机制,这仍然有效。
这里是 example 如何检查远程 JVM 中给定 class 的实例。
sa-jdi.jar
必须在 class 路径中才能使用可服务性代理。
终于找到有史以来最简单的解决方案。 运行
jmap -F -dump:format=b,file=heap.bin PID
注意 -F
参数 - 它强制 jmap
使用 Serviceability Agent 进行堆转储。
P.S. 如果您想了解 SA 的幕后工作原理,请查看 the sources。