Ethon Ethon - 4 months ago 47
Java Question

Java JNA: GetProcAddress returns null

The following code fails to find LoadLibraryW

private static FOREIGN_THREAD_START_ROUTINE getLoadLibraryWAddress() throws Win32Exception {
HMODULE module = Kernel32.INSTANCE.GetModuleHandle("KERNEL32");
if(module == null) {
Win32Exception.throwWithLastError("Failed to find KERNEL32 module");
}

FOREIGN_THREAD_START_ROUTINE address = Kernel32MissingFunctions.INSTANCE.GetProcAddress(module, "LoadLibraryW");
if(address == null) {
Win32Exception.throwWithLastError("Failed to find LoadLibraryW in KERNEL32 module");
}
return address;
}


where GetProcAddress is declared as following:

public interface Kernel32MissingFunctions extends StdCallLibrary {

Kernel32MissingFunctions INSTANCE = (Kernel32MissingFunctions) Native.loadLibrary("kernel32",
Kernel32MissingFunctions.class, W32APIOptions.UNICODE_OPTIONS);

public static final int MEM_RELEASE = 0x8000;

public LPVOID VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, long dwSize, int flAllocationType, int flProtect);

public int VirtualFreeEx(HANDLE hProcess, LPVOID lpAddress, long dwSize, int dwFreeType);

public FOREIGN_THREAD_START_ROUTINE GetProcAddress(HMODULE hModule, String lpProcName);
}


Does anyone know why? What is my mistake?
Thanks!

Answer

Martin Drab was right. Using W32APIOptions.UNICODE_OPTIONS passed an Unicode string to the Ansi function. Changing the interfaces as following fixed the problem:

public interface Kernel32MissingFunctions extends StdCallLibrary {

    Kernel32MissingFunctions INSTANCE = (Kernel32MissingFunctions) Native.loadLibrary("kernel32",
            Kernel32MissingFunctions.class, W32APIOptions.ASCII_OPTIONS);

    public static final int MEM_RELEASE = 0x8000;

    public LPVOID VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, long dwSize, int flAllocationType, int flProtect);

    public int VirtualFreeEx(HANDLE hProcess, LPVOID lpAddress, long dwSize, int dwFreeType);

    public LPVOID GetProcAddress(HMODULE hModule, String lpProcName);
}