加载错误的DLL的LoadLibraryEx(...,LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)的变通方法错误

时间:2017-02-05 10:59:59

标签: windows winapi dll ntdll

情况如下。 这些dll在一个过程中加载:

ac.txt

该流程位于c:\abc\foo.dll c:\abc\bar.dll c:\zxc\foo.dll 。 我正在加载c:\abc\。它隐含地链接到c:\zxc\bar.dll。它应链接到foo.dll,它位于同一个文件夹中。 我用

加载它
c:\zxc\foo.dll

如果未加载LoadLibraryExA("c:\\zxc\\bar.dll", NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR) ,则c:\abc\foo.dll会正确加载,c:\zxc\foo.dll会链接到该c:\zxc\bar.dll。 但是,如果加载了c:\abc\foo.dll,则c:\\zxc\\bar.dll会链接到c:\abc\foo.dll而不是c:\zxc\foo.dll(即使过程中已加载c:\zxc\foo.dll)。这是在" Show loader snaps"的帮助下确认的。 Global Flags复选框。

我该如何解决?

bar.dll是第三方,所以我无法在其中实现DELAYLOAD。

我无法阻止将c:\abc\foo.dll加载到流程中。

我正在考虑挂钩ntdll!LdrpFindOrMapDll,但似乎不可靠,我必须在所有受支持的Windows版本中彻底测试,所以我首先要寻找更简单的解决方法。

1 个答案:

答案 0 :(得分:2)

我认为您可以尝试使您的foo.dll成为并排程序集,并在您的dll清单中引用它。 例如,5和6版本的Common Controls以及Visual Studio不同的C运行时版本应该在同一个进程中共存。

如果这样做,不一定需要将你的foo.dll安装到WinSxS文件夹,也许你可以使用私人程序集。

如果并排组件不适合您,那么任何挂钩解决方案都是复杂且有风险的。 想一想:GetModuleHandleW(L" foo.dll")等调用的数量应该在每个上下文中返回正确的一个DLL句柄! (如果bar.dll代码是在定义了ISOLATION_AWARE_ENABLED的情况下编译的,那么并排程序集会执行此操作)