Java:方法挂钩和查找对象实例

Java: Method hooking & Finding object instances

情况

嗨,我有两个问题。
情况是我正在为 Windows 编写 Java API,它还提供了将代码注入进程然后操纵目标的工具.我已经实现了 注入部分 ,例如将一个 jar 注入另一个 jar。此时我的 jar 被调用(而目标已经在运行时)并在 完整的静态上下文 .

中启动

目标与问题

从这里我有两个目标:

  1. 我想与目标对象进行交互,因此我需要引用。对于许多对象来说,这已经成为可能,因为它们提供对其实例的静态访问。例如 awt.Frames#getFrames() 提供对所有创建的 Frame 对象的访问。但如果有可能访问堆上的任意对象,那就太棒了。类似于'Heap#getAllObjectInstances()'。
  2. 给定一个对象实例,我想连接到这个对象的任意函数。例如,每当调用 BufferStrategy#show() 时,我希望它先调用另一个方法。

所以我总结问题如下:

  1. 如何从静态上下文中获取任意对象引用?
  2. 如何连接到任意函数?

备注

到目前为止我做了什么,评论和想法:

  1. JDI(Java 调试器接口)通过 VirtualMachine#allClasses() -> ReferenceType#instances(0)。但是 JDI 需要 目标 JVM 以额外的 调试参数 启动,这 我没有选择 .可以使用 low-level 并使用 memory tools 分析堆,但我希望有人知道更多 high-水平接近。使用 Windows API 对我来说是一个选择,因为我熟悉 JNA/JNI,但我不知道这样的工具。
  2. 最后的办法是使用 IAT hooking 和 C 代码,这是一种非常低级的方法,我想避免这种情况。正如我可以假设此时有一个对象引用,也许 Reflection API 提供了一种更改对象方​​法的方法?或者至少简单地提供一个挂钩机制?

请注意,更改目标代码对我来说当然不是一个选项。而且它已经在运行时,因此 ByteCode-Manipulation 也可以是一个选项。

场景

一个可以派上用场的场景:
目标是一个 游戏 ,部署为 jar。它使用 双缓冲策略 渲染,使用 BufferStrategy class。它使用 BufferStrategy#show() 显示图像。我们将我们的 jar 注入游戏中,并喜欢绘制带有附加信息的叠加层。为此,我们获得了对使用过的 BufferStrategy 的引用,并连接到其 show 方法。这样它每次被调用时调用我们的drawOverlay-method,然后我们传回原来的show-method.

您需要的是 JVMTI 代理 - 一个使用 JVM Tool Interface.

的本机库

可以使用 Attach API.
将代理动态附加到 运行 VM 参见 VirtualMachine.loadAgentPath

  1. 要获取给定 class 的所有实例,请使用 JVMTI IterateOverInstancesOfClass 函数。
    详情见

  2. 要拦截一个外国的方法 class 你需要 JVMTI RetransformClasses API. The same can be also achieved by using Java-level instrumentation API, see Instrumentation.retransformClasses.

有关 JVMTI 级方法拦截的示例,请参考 demo/jvmti/mtrace 来自 Oracle JDK 演示和示例包。

Java-level instrumentation 使用像 Byte Buddy.

这样的字节码操作库会更容易