【发布时间】:2020-04-19 04:16:35
【问题描述】:
如何获取我拥有 JNI MethodID 的方法的内存位置?
我想通过使用 JNI 来挂钩或操作 Java 方法,因为众所周知,JVM 会重新定位此类方法,因此无法使用指向方法的静态指针。
所以我使用 C++ 和 JNI 从 JVM 中获取 MethodID。
MethodID 可以转换为整数,即十六进制内存地址。
我已经发现,在 MethodID 的内存位置,有一个指向 HEAP 地址的指针。这个堆地址指向一个
“jvm.dll.53A14DE8 方法:元数据:MetaspaceObj”
(这就是我的反向工具“ReClass.NET”所说的)
所以 jvm.dll.xxx 方法得到了一些函数指针,但这些不能是方法,因为它们由 3 个字节组成(太小)或者真的太大(30 条指令+)。 我想找到的方法只返回 1.0 的浮点数
这就是 ReClass.NET 中的 jvm.dll.xxx 方法:
或者有没有其他方法可以在没有 JVMTI 的情况下本地挂钩/操作 Java 方法?
【问题讨论】:
-
您可以查看 JNA (github.com/java-native-access/jna) 如何获取回调地址
-
为什么不是 JVM TI?这是操作 Java 方法的正确方式(我会说,唯一方式)。
-
我试图通过获取方法的地址来找出另一种操作方式。 JNA 和 JVM TI 已打补丁,会导致我想要操作的内容崩溃。
-
“JVM TI 已打补丁,会崩溃”是什么意思?这是标准 JVM 的基本部分,应该像 JNI 一样可用。
-
再说一遍:没有“方法地址”这样的东西。 Java 方法可能有一个字节码的地址,以及多个(可能为零)已编译的条目。即使您将它们全部修补,这仍然不能保证行为发生变化,因为该方法可能已经内联到其他一些编译方法中。后者尤其适用于像“return 1.0”这样的简单方法。在这种情况下,您必须找到该方法的所有调用站点,递归地修补它们等等......理论上这是可能的,但这是一项远远超出您最初问题的巨大研究。
标签: java c++ jvm java-native-interface reverse-engineering