如何确定函数调用正在使用哪个 Windows DLL?

Posted

技术标签:

【中文标题】如何确定函数调用正在使用哪个 Windows DLL?【英文标题】:How can I determine which Windows DLL is being used for a function call? 【发布时间】:2015-03-02 16:57:14 【问题描述】:

我一直在研究 _vsnprintf 并了解到它在 ntdll.dll 和 msvcrt.dll 中可用。

我可以使用GetModuleHandleGetProcAddress访问_vsnprintf,例如:

static int(__cdecl *p__vsnprintf)(char *str, size_t count, const char *format, va_list valist);

static void init(const char *dll)

    HMODULE hmod = GetModuleHandleA(dll);
    if (hmod)
    
        printf("*** Testing %s ***\n", dll);

        p__vsnprintf = (void *)GetProcAddress(hmod, "_vsnprintf");
        if (p__vsnprintf) test__vsnprintf();
        else printf("_vsnprintf not found in %s.\n", dll);
    
    else printf("*** Unable to load %s ***\n", dll);

    printf("\n");


int main(void)

    init("ntdll.dll"); /* ntdll _vsnprintf */
    init("msvcrt.dll"); /* msvcrt _vsnprintf */

    printf("*** Testing normal function call ***\n");
    test_vsnprintf(); /* _vsnprintf in ??? */

    return 0;

对于通用调用,我如何判断 Windows 使用的是来自 ntdll.dll 还是 msvcrt.dll 的_vsnprintf

【问题讨论】:

【参考方案1】:

dumpbin /imports 会告诉你。另外,方便的depends utility。

【讨论】:

感谢您指出dumpbin 程序。输出显示 _vsnprintf 仅从 msvcrt.dll 调用。我不得不将它与 VS2010 一起使用。 VS2013 可以用吗? 如果你的意思是dumpbin 可用于 VS2013,答案是肯定的。 dumpbin 只是一个调用link /dump 的小包装程序。【参考方案2】:

要务实地做到这一点,您有两个主要选项:

    如果它是静态导入,您可以探索 IAT 并检查其导入来源的模块。 如果您是动态执行此操作(即:使用GetProcAddress),您可以使用VirtualQueryGetModuleFileName 来找出它来自的模块。还有GetModuleBaseName 用于查找模块名称。 在上面的示例中,当您有一个成功的 GetProcAddress 时,只需跟踪使用的 HMODULE

【讨论】:

感谢您的回答。我将检查您列出的 WinAPI 函数。对于第 3 点,这是对我使用的代码示例的建议吗?我不确定您跟踪 HMODULE 是什么意思。 @HughMcMaster:是的,这是对示例代码的建议。基本上,您有一个额外的全局变量以及函数指针,它保存用于(成功)获取函数指针的模块名称或模块句柄。

以上是关于如何确定函数调用正在使用哪个 Windows DLL?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式确定哪个类/模块定义了被调用的方法?

同一个类中的同名函数 - 有没有一种优雅的方法来确定调用哪个?

如何确定是哪个版本的 Windows?

如何确定函数来自哪个头文件?

如何确定正在编辑 UITableView 中的哪个节标题

如何确定我的 .NET Windows Forms 程序在哪个监视器上运行?