简体   繁体   中英

JNA call works with 32-bit JRE but not with 64-bit JRE

I am trying to call system32 's CreateProcessW from my JNA interface that I have created. The problem is that it works fine when I am running the software from a 32-bit JRE but when I move over to a 64-bit JRE it crashes the JVM.

Kernel32 kernel = (Kernel32) Native.loadLibrary("kernel32",
        Kernel32.class, new HashMap<String, Object>() {
            private static final long serialVersionUID = 1L;

            {
                put(Library.OPTION_FUNCTION_MAPPER,
                        W32APIFunctionMapper.UNICODE);
                put(Library.OPTION_TYPE_MAPPER,
                        W32APITypeMapper.UNICODE);
            }
        });

ProcessInformation processInformation = new ProcessInformation();
byte[] startupInfo = new byte[67];

int num2 = BitConverter.toInt32(bytes, 60);
int num = BitConverter.toInt16(bytes, num2 + 6);
IntByReference ptr4 = new IntByReference(BitConverter.toInt32(bytes, num2 + 0x54));
kernel.CreateProcessW(surrogateProcess, null, 0, 0, false, 4, 0,
            null, startupInfo, processInformation);

My Kernel32 JNA interface:

public interface Kernel32 extends StdCallLibrary {

    boolean CreateProcessW(String appName, String commandLine, int procAttr,
        int thrAttr, boolean inherit, int creation, int env, String curDir,
        byte[] sInfo, ProcessInformation pInfo);

}

My ProcessInformation JNA structure:

public final class ProcessInformation extends Structure implements ByReference {

    public IntByReference hProcess;
    public IntByReference hThread;
    public int dwProcessId;
    public int dwThreadId;

    @Override
    protected List<String> getFieldOrder() {
        return Arrays
                .asList("hProcess", "hThread", "dwProcessId", "dwThreadId");
    }

}

Finally, here is the error that occurs when I run on a 64-bit JRE:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000077a4e711, pid=1888, tid=8968
#
# JRE version: 6.0_43-b01
# Java VM: Java HotSpot(TM) 64-Bit Server VM (20.14-b01 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [ntdll.dll+0x4e711]
#
# An error report file with more information is saved as:
# C:\Users\Thomas\workspace\trident\hs_err_pid1888.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

Your CreateProcess mapping is bogus. Where did you get the idea you could use Java int to represent pointer values? Oh, never mind, the win32 API must have taught you that.

You must use Pointer or PointerType or an equivalent to represent pointers, or if you're really stuck on using integer values, at least use long (64 bits) on a 64-bit platform.

BTW, JNA includes a platform.jar that includes kernel32 mappings, including CreateProcess .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM