pythonpython-3.xwinapictypesgetprocaddress

Python- GetProcAddress using ctypes returns NULL


Problem:

I am trying to get the address of LoadLibraryW but gets NULL.

Research effort:

The function successfully retrieves the kernel32.dll address that is mapped to the python process, but returns NULL for the LoadLibraryW address with 126 error code. When I check the function address in process hacker (under the python process) I see a valid address.

from ctypes import *
kernel32 = windll.kernel32

def resolve_function(dll, func):
    handle = kernel32.GetModuleHandleA(dll.encode("ascii"))
    address = kernel32.GetProcAddress(handle, func.encode("ascii"))
    kernel32.CloseHandle(handle)
    return address


address = resolve_function('kernel32.dll', 'LoadLibraryW')
print(address)

I tried other libraries and other functions but it always returns NULL.


Solution

  • You need to set the argtypes and restype attributes on the functions you call so that ctypes is able to match the prototypes. I guess this is the main problem in your code.

    You should also use the Unicode API as a general rule, in my view. And you must not call CloseHandle on the handle returned by GetModuleHandle.

    Put it all together like so:

    from ctypes import *
    kernel32 = windll.kernel32
    
    def resolve_function(dll, func):
        kernel32.GetModuleHandleW.argtypes = [c_wchar_p]
        kernel32.GetModuleHandleW.restype = c_void_p
        kernel32.GetProcAddress.argtypes = [c_void_p, c_char_p]
        kernel32.GetProcAddress.restype = c_void_p
        handle = kernel32.GetModuleHandleW(dll)
        address = kernel32.GetProcAddress(handle, func)
        return address
    
    address = resolve_function('kernel32.dll', b'LoadLibraryW')
    print(address)