为什么在 Python 中为 msvcr100 调用 kernel32.GetModuleHandleA() 失败? [英] Why does calling kernel32.GetModuleHandleA() for msvcr100 fail in Python?

查看:19
本文介绍了为什么在 Python 中为 msvcr100 调用 kernel32.GetModuleHandleA() 失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am having a problem with calling GetModuleHandleA() using Python. I have a module that attaches as debugger to the process. I'm working on a function that would return address of the function in the specific DLL module. GetModuleHandleA("msvcr100") fails all of the time.

from ctypes import *
kernel32 = windll.kernel32

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

Function declared as part of a bigger debug class. That's the part of function declaration:

   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().

I run separate process that uses printf() and then attach to it. Everything works fine until I get to GetModuleHandleA() that returns False all of the time.

运行 printf() 的代码:

Code that runs 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 to your problem, but I'm answering anyway to explain why your original effort failed (and why your fix worked).

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

First, msvcrt/msvcr100 are two different versions of Microsoft's C runtime library. There are other versions as well, and all of them contain their own definitions for printf(). A given process may have any one of them loaded, or multiple versions loaded, or no versions loaded - it's possible to produce console output using only WinAPI functions! In short, if it's not your process, you can't depend on any given version of the C runtime being available.

二、GetModuleHandle()加载任何东西.仅当它已经被加载时,它才返回一个指向命名模块的句柄.msvcr100.dll 可以位于磁盘上就在那里,但是如果进程尚未加载它,那么 GetModuleHandle 将不会为您提供句柄.LoadLibrary() 是你的函数'如果你想加载检索一个命名模块的句柄,就会调用......但是你可能不想在你不想要的过程中这样做'拥有.

Second, GetModuleHandle() doesn't load anything. It returns a handle to the named module only if it has already been loaded. msvcr100.dll can be sitting right there on disk, but if the process hasn't already loaded it then GetModuleHandle won't give a handle to you. LoadLibrary() is the function you'd call if you wanted to both load and retrieve a handle to a named module... But you probably don't want to do this in a process you don't own.

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

FWIW, Process Explorer is a handy tool for viewing the DLLs already loaded by a process.

这篇关于为什么在 Python 中为 msvcr100 调用 kernel32.GetModuleHandleA() 失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆