使用32位JVM运行时JNA内存访问无效

时间:2015-09-17 22:26:39

标签: java memory jna

你好我最近遇到了一个我正在写的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位操作系统并且他们彼此不同意。

所以新的问题是,是否可以通过JNA直接映射指定使用32位kernel32(在syswow64中)如果它们使用32位JVM运行,或者使用64位kernel32(在system32中)如果它们正在使用64位JVM?

1 个答案:

答案 0 :(得分:3)

我通过将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);