您好,我最近遇到了我正在编写的 JNA 程序的问题。
如果我使用 64 位 JVM 运行以下代码,它会运行得很有趣:
public final class UWot {
public static void main(String[] args) {
final int size = 4;
GameProcess process = Processes.get("csgo.exe");
ByteBuffer buff = Buffers.allocate(size).order(ByteOrder.nativeOrder());
Kernel32Direct.ReadProcessMemory(process.handle().getPointer(), 0x178832cc, buff, size, 0);
System.out.println(buff.getInt());
}
}
但是如果我使用 32 位 JVM 运行相同的代码,则会出现以下错误:
Exception in thread "main" java.lang.Error: Invalid memory access
at baro.natives.Kernel32Direct.ReadProcessMemory(Native Method)
at temp.hi.main(UWot.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
这是我读取进程内存的方法:
public final class Kernel32Direct {
public static native int ReadProcessMemory(Pointer process, long address, ByteBuffer memory, int size, int written);
static {
Native.register(NativeLibrary.getInstance("Kernel32", W32APIOptions.UNICODE_OPTIONS));
}
}
编辑,结果发现 32 位 jvm 试图使用 Kernel32,这是一个 64 位库,因为我使用的是 64 位操作系统,并且它们彼此不一致。
所以新的问题是,如果它们运行在 32 位 JVM 上,是否可以通过 JNA 直接映射来指定使用 32 位 kernel32(在 syswow64 中),或者如果它们使用的是 64 位 kernel32(在 system32 中) 64 位 JVM?
最佳答案
我自己通过将 address
从 long 更改为 Pointer 解决了这个问题。我认为这是由于 Java 和 C 之间的大小差异较大所致
更改:
public static native int ReadProcessMemory(Pointer process, long address, ByteBuffer memory, int size, int written);
致:
public static native boolean ReadProcessMemory(Pointer process, Pointer address, ByteBuffer memory, int size, int written);
关于java - JNA 使用 32 位 JVM 运行时内存访问无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32640921/