为什么在Python中调用msvcr100的kernel32.GetModuleHandleA()会失败?

时间:2011-01-29 02:33:55

标签: python winapi

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

from ctypes import *
kernel32 = windll.kernel32

声明为较大的 debug 类的一部分的函数。这是函数声明的一部分:

   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()的单独进程然后附加到它。一切正常,直到我到达GetModuleHandleA(),一直返回 False

运行printf()的代码:

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

有什么想法吗?

4 个答案:

答案 0 :(得分:5)

You've found the solution你的问题,但无论如何我都要回答你原来的努力失败的原因(以及为什么你的修复有效)。

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

其次, GetModuleHandle()加载任何。只有当已加载时,它才会返回指定模块的句柄。 msvcr100.dll可以在磁盘上就位,但如果进程尚未加载,则GetModuleHandle将不会为您提供句柄。如果你想加载检索指定模块的句柄,那么LoadLibrary()就是你要调用的函数......但你可能不想要在你不拥有的过程中这样做。

FWIW,Process Explorer是查看进程已加载的DLL的便捷工具。

答案 1 :(得分:1)

修改后:


...

handle = kernel32.GetModuleHandleA(dll) if handle == False: error = GetLastError() print "ERROR: %d - %s" % (error, FormatError(error)) return False

...

我得到:错误:126 - 找不到指定的模块

我实际上在我的代码中用msvcrt.dll替换了msvcr100.dll,它完美无缺。我发现msvcrt.dll是系统dll。 msvcr100.dll随Studio 2010一起提供。它们都位于C:\ Windows \ system32中。对我来说,为什么msvcr100.dll不起作用仍然是个谜。

答案 2 :(得分:0)

使用GetLastError()中的WinError(或ctypes)来查找返回NULL的原因,然后将该信息添加到错误消息中。即使在你弄清楚这个特定问题之后,你也会想要更强大的错误报告。

有关详细信息,请参阅ctypes文档:http://docs.python.org/library/ctypes.html

答案 3 :(得分:0)

尝试致电:

msvcr100 = cdll.msvcr100

致电之前:

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

确保在您的进程中加载​​DLL。 msvcrt可能有效,因为它已经加载了。