【问题标题】:Windows: Changing the DLL search order for an ExeWindows:更改 Exe 的 DLL 搜索顺序
【发布时间】:2017-08-31 03:10:30
【问题描述】:

我在应用程序目录中有一个 C++ Exe,其中包含它使用的 DLL。现在,出于某些测试目的,我需要修改现有的 DLL 并使用它而不是原始的。但是为了不修改现有的安装,我无法备份现有的 DLL 并将其替换为修改后的 DLL 或将现有的移动到别处。我也无法更改Exe。这 2 个 DLL 需要并排存在。唯一的变化应该是 Exe 应该透明地加载位于其他文件夹中的修改后的 DLL,而不是与 Exe 位于同一文件夹中的现有 DLL。有什么优雅的方法吗?

我查看了一些 MSDN 文章,但找不到这样做的方法。该解决方案应适用于 Windows XP 及更高版本。

【问题讨论】:

    标签: c++ windows dll exe


    【解决方案1】:

    Windows 最多会为每个进程加载每个 DLL 名称的一个版本。如果它加载了HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs 中列出的 DLL,它将不会在以后加载类似名称的 DLL。但是在AppInit_DLLs 中,您可以列出具有显式路径的DLL,覆盖正常的LoadLibrary() 顺序。

    因此,暂时将您的测试 DLL 放在 AppInit_DLLs 中,它将覆盖任何其他同名的 DLL。

    【讨论】:

      【解决方案2】:

      根据MSDN,它总是从应用程序目录开始(除非你用替代搜索顺序方法修改它......)所以看起来很难。您仍然可以将可执行文件及其其他依赖项复制到其他地方。不过它并不那么优雅。

      或者您可以从原始目录启动已复制到其他地方的可执行文件以及新的 DLL。根据搜索顺序,它也应该可以工作,尽管我必须承认我从未尝试过。

      【讨论】:

        【解决方案3】:

        您可以从一开始就为您的进程挂接 LoadLibrary() 调用。当您修补的 LoadLibrary() 版本看到您的 DLL 时,它会使用修改后的 DLL 路径调用原始 LoadLibrary()。即使您不使用 LoadLibrary() 调用来加载您的 DLL,Windows CRT 也会这样做。所以这个技巧一定行得通。

        【讨论】:

        • 您能否举例说明它是如何工作的,谢谢 - gg
        • MSalters 描述的方式是您应该尝试的第一种方式。这是进行 DLL 注入的最简单方法。如果它不起作用(我看不出这样做的原因),那么您应该实现一个真正的 API 挂钩。这是一个难以描述的复杂话题。您可以通过在网上搜索“Windows API Hooking”主题获得一些示例代码和实用程序库。
        【解决方案4】:

        我知道的唯一方法是使用 LoadLibrary API,包括路径,但你说你不能更改 exe。

        【讨论】:

          猜你喜欢
          • 2011-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多