我在使用 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。
关于python - 为什么在 Python 中为 msvcr100 调用 kernel32.GetModuleHandleA() 失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4834762/