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

情况

嗨,我有2个问题。
情况是我正在为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 ,这对我来说没有选择的 。 可以使用内存工具进行低级分析并分析堆,但我希望有人知道更高级的方法 。 使用Windows API对我来说是一个选项,因为我熟悉JNA / JNI ,但我不知道这样的工具。
  2. 最后一种方法是使用IAT挂钩 C-Code,这是一种非常低级的方法,我想避免这种情况 。 我可以假设此时有一个对象引用,也许Reflection API提供了一种更改对象方​​法的方法? 或者至少简单地提供挂钩机制?

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

脚本

这会派上用场:
目标是一个游戏 ,部署为jar。 它使用BufferStrategy类使用Double-Buffer-Strategy进行渲染。 它使用BufferStrategy#show()显示图像。 我们在游戏中注入了jar,并喜欢绘制带有附加信息的叠加层。 为此,我们获得对使用过的BufferStrategy的引用,并连接到它的show -method。 因此,每次调用它时都会调用drawOverlay方法 ,然后我们将传递回原始的show-method

您需要的是JVMTI代理 – 一个使用JVM工具接口的本机库。

可以使用Attach API将代理动态连接到正在运行的VM。
请参见VirtualMachine.loadAgentPath 。

  1. 要获取给定类的所有实例,请使用JVMTI IterateOverInstancesOfClass函数。
    有关详细信息,请参阅相关问题

  2. 要拦截外部类的方法,您需要JVMTI RetransformClasses API。 使用Java级检测API也可以实现相同的function,请参阅Instrumentation.retransformClasses 。

有关JVMTI级方法拦截的示例,请参阅Oracle JDK演示和示例包中的demo/jvmti/mtrace

使用像Byte Buddy这样的字节码操作库,Java级别的检测将更容易。