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

PSS*_*PSS 1 python winapi

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

from ctypes import *
kernel32 = windll.kernel32
Run Code Online (Sandbox Code Playgroud)

函数声明为更大的调试类的一部分.这是函数声明的一部分:

   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
Run Code Online (Sandbox Code Playgroud)

调用以下函数:

function_address = debug.resolve_function("msvcr100", "printf")
Run Code Online (Sandbox Code Playgroud)

我运行使用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
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Sho*_*og9 5

你找到了问题的解决方案,但无论如何我都在回答你为什么原来的努力失败了(以及为什么你的修复工作).

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

其次,GetModuleHandle()加载任何东西.只有在已经加载的情况下,才会返回指定模块的句柄.msvcr100.dll可以位于磁盘上,但如果进程尚未加载,则GetModuleHandle将不会为您提供句柄.LoadLibrary()如果你想加载检索命名模块的句柄,你可以调用的函数......但是你可能不希望在你不拥有的进程中执行此操作.

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