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

从正在运行的java程序的内存中查找并读取特定类型的对象,java,unix,memory,jvm,jvm-hotspot,Java,Unix,Memory,Jvm,Jvm Hotspot,我必须评估从正在运行的java程序的内存中提取某些对象(例如,java.security.PrivateKey)有多困难 我不太喜欢这种低级内存的东西,所以我从小型C程序开始,熟悉了gdb、/proc//maps、/proc//mem和转储所有内存区域的a 但是,当切换到java时,情况会发生变化。由于垃圾收集,java对内存的分配和管理非常不同。在C程序中,我会查看堆栈地址并确定它包含我想要提取的变量 因此,我的问题是: Java对象是否有某种类型的ID,以便我可以在内存转储中找到该类型的对象

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

我不太喜欢这种低级内存的东西,所以我从小型C程序开始,熟悉了
gdb
/proc//maps
/proc//mem
和转储所有内存区域的a

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

因此,我的问题是:

  • Java对象是否有某种类型的ID,以便我可以在内存转储中找到该类型的对象
  • 如果是,我如何找到类型的ID(例如,
    字符串的ID是什么?
  • 如果没有这样的类型ID,那么攻击者还可能从java进程中提取(比如)java.security.PrivateKey
  • 假设该选项已关闭


    感谢您的帮助

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

    他会变魔术。它可以使用打开一个核心转储或附加到一个实时Java进程,然后提取JVM结构和所有Java对象的布局。不需要目标JVM的合作。即使在禁用JMX和附加机制的情况下,这也可以工作

    下面是一个如何在远程JVM中检查给定类的实例的示例。
    sa jdi.jar
    必须在类路径中才能使用可服务性代理

    最后是有史以来最简单的解决方案。跑
    jmap-F-dump:format=b,file=heap.bin PID

    注意
    -F
    参数-它强制
    jmap
    使用可维护性代理进行堆转储


    如果您想知道SA在发动机罩下是如何工作的,这里有一些SA。

    请参阅。可能会有帮助。VisualVM是一个很好的指针。老实说,我有点震惊:visualvm怎么能在没有根权限的情况下给我提供所有这些信息呢?啊,我明白了,这就是为什么:“Java应用程序会自动公开,以便由JMX代理进行监视和管理”[1]默认情况下,这对于任何在内存中存储敏感数据的应用程序来说都是非常糟糕的。在我看来这应该改变。。。[1] 乍一看,情况似乎更糟:我甚至找不到在Java 6+中禁用监视的选项…@HannoBinder您可以使用以下标志禁用它:
    -XX:+disableattachmentechanism
    (发现)我以前试过
    jmap-F-dump:format=b,file=heap.bin PID
    ,但我总是得到一个InvocationTargetException()。然而,这是一个伟大的指针!如果我成功了,我会尝试标记为已接受。谢谢大家!@S1lentSt0rm请注意,sa-jdi.jar和jmap必须属于与目标进程完全相同的Java版本(因为VM结构的布局可能因版本而异)。如果情况并非如此,并且如果您有一个重复的示例,
    jmap-F
    总是失败,请向我们展示它,因为它可能是一个JDK错误。我做了一些研究,发现ptrace_scope必须设置为0,但这并没有帮助。但它在另一台机器上工作,所以我将接受这个答案,因为它正是我想要的。我将尝试隔离和解决我的机器出现的问题,并报告我的发现。再次感谢!