情况
你好,我有2个问题。
情况是我正在为 Windows 编写一个 Java API,它还提供了将代码注入进程然后操作目标的工具。我已经实现了injection-part,例如将一个 jar 注入另一个 jar。此时我的 jar 被调用(而目标已经在运行时)并在一个完整的静态上下文中启动。
目标和问题
从这里我有两个目标:
- 我想与目标对象交互,因此我需要引用。对于许多对象来说,这已经成为可能,因为它们提供对其实例的静态访问。例如awt.Frames#getFrames()提供对所有创建的 Frame 对象的访问。但是如果有可能访问堆上的任意对象,那就太棒了。类似“ Heap#getAllObjectInstances() ”的东西。
- 给定一个对象实例,我想连接到该对象的任意函数。例如,每当调用BufferStrategy#show()时,我希望它首先调用另一个方法。
所以我将问题总结如下:
- 如何从静态上下文中获取任意对象引用?
- 如何连接任意函数?
评论
到目前为止我所做的,评论和想法:
- JDI (Java 调试器接口)通过VirtualMachine#allClasses() -> ReferenceType#instances(0)提供了这样的方法。但是 JDI 需要使用额外的调试参数来启动目标 JVM ,这对我来说是没有选择的。可以深入到低级别并使用内存工具分析堆,但我希望有人知道更高级的方法。使用 Windows API 对我来说是一种选择,因为我熟悉JNA/JNI,但我不知道这样的工具。
- 最后的手段是使用IAT与 C 代码挂钩,这是一种非常低级的方法,我想避免这种. 我可以假设此时有一个对象引用,也许反射 API是否提供了一种更改对象方法的方法?或者至少简单地提供一个挂钩机制?
请注意,更改目标代码当然不是我的选择。并且它已经在运行时,因此 ByteCode-Manipulation 也可能是一种选择。
设想
这会派上用场的场景:
目标是一个游戏,部署为 jar。它使用BufferStrategy类以Double-Buffer-Strategy呈现。它使用BufferStrategy#show()显示图像。我们将我们的 jar 注入到游戏中,并喜欢绘制带有附加信息的叠加层。为此,我们获得了对使用过的BufferStrategy的引用并连接到它的show方法。这样每次调用时它都会调用我们的 drawOverlay 方法,然后我们传回原始的show-method。