Java:方法 Hook 和查找对象实例

标签 java jvm reverse-engineering heap-memory jdi

情况

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

目标与问题

从这里我有两个目标:

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

所以我总结存在的问题如下:

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

备注

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

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

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

场景

这会派上用场的场景:
目标是作为 jar 部署的游戏。它使用 BufferStrategy 类以 Double-Buffer-Strategy 呈现。它使用 BufferStrategy#show() 显示图像。我们将我们的 jar 注入(inject)游戏中,并喜欢绘制带有附加信息的叠加层。为此,我们获得对使用过的 BufferStrategy 的引用,并连接到它的 show 方法。以便它每次被调用时都调用我们的 drawOverlay 方法,然后我们返回到原始的 show-method

最佳答案

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

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

  1. 要获取给定类的所有实例,请使用 JVMTI IterateOverInstancesOfClass功能。
    查看related question了解详情。

  2. 要拦截外部类的方法,您需要 JVMTI RetransformClasses应用程序接口(interface)。同样可以通过使用 Java 级别的检测 API 来实现,参见 Instrumentation.retransformClasses .

JVMTI级方法拦截的例子引用Oracle JDK demos and samples包中的demo/jvmti/mtrace

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

关于Java:方法 Hook 和查找对象实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38042962/

相关文章:

java - @Produces 在 JavaEE 上下文中如何工作?

java - hibernate @OnDelete(action = OnDeleteAction.CASCADE) 不工作

java - 在 web.xml 中声明 JSP taglib 指令

Java:关于调用 Runtime.freeMemory()、Runtime.totalMemory() 和 Runtime.maxMemory() 的成本

java - 为什么jetpack compose中没有热重载?理论上他们将来是否有可能在 compose 中添加类似热重载的 flutter 功能?

java - Spring Boot Mongodb 按 ID 搜索返回 null

JTable char[]、字符串和对象消耗 Java 堆空间

c - 逆向工程时结构中的数据类型

algorithm - 成功解密的秘诀

javascript - 调试反混淆的 javascript