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

时间:2016-06-26 20:38:58

标签: java jvm reverse-engineering heap-memory jdi

情况

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

目标&问题

从这里我有两个目标:

  1. 我想与目标对象互动,因此我需要引用。对于许多对象,这已经成为可能,因为它们提供对其实例的静态访问。例如, awt.Frames#getFrames()提供对所有已创建的Frame对象的访问。但如果有可能在堆上获得访问任意对象,那将是非常棒的。像' Heap#getAllObjectInstances()'。
  2. 之类的东西
  3. 给定一个对象实例,我想连接到这个对象的任意函数。例如,每当调用 BufferStrategy#show()时,我希望它首先调用另一个方法。
  4. 所以我总结问题如下:

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

      到目前为止我所做的,评论和想法:

      1. JDI (Java调试器接口)通过 VirtualMachine#allClasses() - >提供了这样的方法。引用类型#实例(0)。但是JDI需要使用调试参数启动目标JVM 对我来说没有选择。可以使用低级别进行分析,并使用内存工具分析堆,但我希望有人知道更强高级方法。使用Windows API对我来说是一个选项,因为我熟悉 JNA / JNI ,但我不知道这样的工具。
      2. 最后一种方法是使用 IAT挂钩和C-Code,这是一种非常低级的方法,我想避免这种。我可以假设此时有一个对象引用, Reflection API 可能提供了一种更改对象方​​法的方法吗?或者至少简单地提供挂钩机制?
      3. 请注意,更改目标代码肯定不适合我。并且它已经在运行时,因此ByteCode-Manipulation也可以是一个选项。

        方案

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

1 个答案:

答案 0 :(得分:4)

您需要的是JVMTI代理 - 一个使用JVM Tool Interface的本地库。

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

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

  2. 要拦截外国班级的方法,您需要JVMTI RetransformClasses API。使用Java级检测API也可以实现同样的效果,请参阅Instrumentation.retransformClasses

  3. 对于JVMTI级方法拦截的示例,请参阅Oracle JDK演示中的demo/jvmti/mtrace和示例包。

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