Skip to main content
 首页 » 编程设计

python之为什么在 Python 中为 msvcr100 调用 kernel32.GetModuleHandleA() 失败

2025年05月04日20bluestorm

我在使用 Python 调用 GetModuleHandleA() 时遇到问题。我有一个模块作为调试器附加到进程。我正在研究一个函数,该函数将返回特定 DLL 模块中函数的地址。 GetModuleHandleA("msvcr100") 总是失败。

from ctypes import * 
kernel32 = windll.kernel32 

作为更大的调试 类的一部分声明的函数。那是函数声明的一部分:

   def resolve_function(self,dll,function):  
        handle = kernel32.GetModuleHandleA(dll) 
        if handle == False: 
            print "kernel32.GetModuleNameA() failed!!!" 
            return False 
        address = kernel32.GetProcAddress(handle, function) 
        if address == False: 
            print "kernel32.GetProcAddress() failed!!!" 
            return False 
        kernel32.CloseHandle(handle) 
        return address 

调用如下函数:

function_address = debug.resolve_function("msvcr100", "printf") 

我运行使用 printf() 的单独进程,然后附加到它。一切正常,直到我到达始终返回 False 的 GetModuleHandleA()。

运行 printf() 的代码:

from ctypes import * 
import time 
msvcr100 = cdll.msvcr100 
counter = 0 
while 1: 
    msvcr100.printf("Counter = %d\n" % counter) 
    time.sleep(1) 
    counter += 1 

有什么想法吗?

请您参考如下方法:

You've found the solution针对您的问题,但无论如何我都会回答以解释为什么您最初的努力失败了(以及为什么您的修复有效)。

首先,msvcrt/msvcr100 是 Microsoft C 运行时库的两个不同版本。还有其他版本,它们都包含它们自己的 printf() 定义。给定的进程可能加载了其中任何一个,或加载了多个版本,或者加载了没有版本 - 可能会产生控制台输出 using only WinAPI functions !简而言之,如果这不是您的进程,您就不能依赖于 任何 可用的 C 运行时的给定版本。

其次, GetModuleHandle()不加载任何东西。 仅当已加载时,它才返回指定模块的句柄。 msvcr100.dll 可以位于磁盘上那里,但如果进程尚未加载它,则 GetModuleHandle 不会为您提供句柄。 LoadLibrary()是你要调用的函数,如果你想同时加载 和 检索命名模块的句柄......但是你可能不想在不属于您的进程。

FWIW,Process Explorer是一个方便的工具,用于查看进程已加载的 DLL。