Python GetModuleHandleW OSError:[WinError 126]找不到指定的模块

时间:2015-11-18 12:07:40

标签: windows python-3.x x86-64 ctypes

以下代码生成错误:

OSError: [WinError 126] The specified module could not be found
windll.kernel32.GetModuleHandleW.restype = wintypes.HMODULE
windll.kernel32.GetModuleHandleW.argtypes = [wintypes.LPCWSTR]
KERNEL32 = windll.GetModuleHandleW("C:\\Windows\\System32\\kernel32.dll")

但是,如果我使用

KERNEL32 = windll.LoadLibrary("C:\\Windows\\System32\\kernel32.dll")

找到了dll但是我遇到了以下代码的不同错误:

LoadLibAddy = windll.kernel32.GetProcAddress(KERNEL32, "LoadLibraryA")

产生的错误是:

ctypes.ArgumentError: argument 1:  Don't know how to convert parameter 1

我希望有人能够知道如何修复这些错误。 完整的脚本:

from ctypes import *
from ctypes import wintypes

def dllinjector(processID, DLL_NAME):
    KERNEL32 = WinDLL('kernel32.dll', use_last_error=True)
    KERNEL32.GetProcAddress.restype = c_void_p
    KERNEL32.GetProcAddress.argtypes = (wintypes.HMODULE, wintypes.LPCSTR)
    PROCESS_CREATE_THREAD = 0x0002
    PROCESS_QUERY_INFORMATION = 0x0400
    PROCESS_VM_OPERATION = 0x0008
    PROCESS_VM_WRITE = 0x0020
    PROCESS_VM_READ = 0x0010
    openHandle = KERNEL32.OpenProcess(PROCESS_CREATE_THREAD|
                                             PROCESS_QUERY_INFORMATION|
                                             PROCESS_VM_OPERATION|
                                             PROCESS_VM_WRITE|
                                             PROCESS_VM_READ, False, processID)
    MEM_RESERVE = 0x00002000
    MEM_COMMIT = 0x00001000
    PAGE_READWRITE = 0x04

    if not openHandle:
        print("OpenProcess failed.")
        print("GetLastError: ", KERNEL32.GetLastError())
        return False
    print("openProcess GetLastError: ", KERNEL32.GetLastError())
    #print("Successfully opened process.")

    LoadLibAddy = KERNEL32.GetProcAddress(KERNEL32._handle, b"LoadLibraryA")
    if not LoadLibAddy:
        raise WinError(ctypes.get_last_error())
    print("LoadLibAddy: ", LoadLibAddy)
    print("LoadLibAddy GetLastError: ", KERNEL32.GetLastError())

    # Allocate space in the process for the dll
    RemoteString = KERNEL32.VirtualAllocEx(openHandle, None, len(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)
    print("RemoteString GetLastError: ", KERNEL32.GetLastError())
    if not RemoteString:
        print("VirtualAllocEx failed.")
        return False

    # Write the string name of the dll in the memory allocated
    if not KERNEL32.WriteProcessMemory(openHandle, RemoteString, DLL_NAME, len(DLL_NAME), None):
        print("WriteProcessMemory failed.")
        return False
    print("WriteProcessMemory GetLastError: ", KERNEL32.GetLastError())

    #Load the dll
    if not KERNEL32.CreateRemoteThread(openHandle, None, None, c_longlong(LoadLibAddy), RemoteString, None, None):
        print("CreateRemoteThread failed.")
        return False
    print("CreateRemotedThread GetLastError: ", windll.kernel32.GetLastError())
    #print("CreateRemoteThread: ", windll.kernel32.CreateRemoteThread(openHandle, None, None, LoadLibAddy, RemoteString, None, None))

    KERNEL32.CloseHandle(openHandle)
    print("CloseHandle GetLastError: ", KERNEL32.GetLastError())

    return True

def main():
    processID = 25408
    DLL_NAME = "mydll32.dll"

    dllinjector(processID, DLL_NAME)

    print("program completed.")

main()

1 个答案:

答案 0 :(得分:2)

应该是windll.kernel32.GetModuleHandleW("kernel32.dll")。但是在定义函数原型时请不要使用windll,因为它对所有使用ctypes的模块都是全局的,这会导致原型冲突。使用kernel32 = WinDLL('kernel32', use_last_error=True)。 DLL句柄是kernel32._handle

对于您的第二个问题,首先,在使用ctypes时,没有理由直接调用GetProcAddress(或POSIX系统上的dlsym)。但原则上它将如下:

kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)   
kernel32.GetProcAddress.restype = ctypes.c_void_p
kernel32.GetProcAddress.argtypes = (wintypes.HMODULE, wintypes.LPCSTR)

LoadLibAddy = kernel32.GetProcAddress(kernel32._handle, b'LoadLibraryA')
if not LoadLibAddy:
    raise ctypes.WinError(ctypes.get_last_error())

请注意,函数名称将作为bytes传递。无论如何,您不需要这个,因为kernel32.LoadLibraryA(或kernel32.LoadLibraryW)是一个函数指针,您可以将其作为参数传递或转换为c_void_p等。