运行 32 位 JVM 时 JNA 无效内存访问
JNA Invalid memory access When Running With 32bit JVM
你好,我最近 运行 遇到了我正在编写的 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 位 os 并且它们彼此不一致。
所以新的问题是,如果它们是 运行 32 位 JVM,是否可以通过 JNA 直接映射指定使用 32 位内核32(在 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);
你好,我最近 运行 遇到了我正在编写的 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 位 os 并且它们彼此不一致。
所以新的问题是,如果它们是 运行 32 位 JVM,是否可以通过 JNA 直接映射指定使用 32 位内核32(在 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);