我在使用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/

10-11 18:20