LoadLibray FileNotFound 取决于哪个应用程序调用

LoadLibray FileNotFound depending on which application calls

本文关键字:应用程序 调用 FileNotFound 取决于 LoadLibray      更新时间:2023-10-16

我正在尝试嵌入一个名为(比方说(name.dll的C++dll,它加载另一个同样名为name.dll的dll(不是我的(。

以我的名义.dll实现我正在加载真实姓名.dll使用以下行:

driver_library = LoadLibrary(_T("c:\windows\system32\name.dll"));

我的dll位于程序.exe.local文件夹中,以便程序在System32中的真实文件夹之前加载我的。

根据哪个程序.exe使用我的dll,LoadLibrary要么工作正常,要么返回我自己的名称.dll句柄作为driver_library,GetLastError((返回"找不到文件"。

在 https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85(中.aspx明确指出"如果字符串指定了完整路径,则函数仅搜索该路径的模块。为什么以及如何为某些应用程序加载自身?

程序中.exe应用程序中的哪些内容会影响LoadLibrary的行为?

@Franck博因评论道: "你有两个程序 - 让我们称它们为fine.exe和own.exe。精细.exe程序加载您自己的名称.dll然后从 System32 加载另一个名称.dll。own.exe程序加载你自己的名称.dll但是当它调用LoadLibrary时,你会得到另一个你自己名字的句柄.dll而不是System32的句柄。

关于自己的.exe(这根本不是我的"自己的"应用程序(: -> 名称.dll位于我创建的 own.exe.local 文件夹中,该文件夹位于 own.exe 目录中。

->自己.exe有一个我删除的应用程序.manifest文件(如果不使用我的dll,应用程序仍然在没有它的情况下启动更正(。 own.exe 没有嵌入式清单(使用 sigcheck 检查(。

->名称.dll不是来自HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs的Windows"已知dll"之一

-> own.exe 不使用 LoadLibrary(( 加载名称.dll(通过在 LoadLibrary/A/W/Ex 函数中设置断点来检查(

-> own.exe 和 name.dll 都是 64 位。

关于很好.exe(这是一个示例,我可以访问代码(:

->名称.dll位于精细.exe应用程序目录中。

-> 没有清单文件(嵌入或文本(。

您的问题程序是否可能正在使用 DLL 重定向?

从加载库文档(强调添加(...

如果指定了路径并且存在应用程序的重定向文件,则该函数将在应用程序的目录中搜索模块。如果模块存在于应用程序的目录中,则 LoadLibrary 将忽略指定的路径并从应用程序的目录加载模块。如果应用程序的目录中不存在该模块,则 LoadLibrary 将从指定目录加载该模块。有关详细信息,请参阅动态链接库重定向。


更新 6/4/2018

这就是我认为正在发生的事情。

您的两个程序都使用加载时动态链接(有时称为隐式链接(链接到名为name.dll的 DLL。 我假设两个程序都只指定name.dll而没有完整的路径名。 如果要检查,我认为可以针对fine.exe运行dumpbin /imports,并own.exe检查DLL名称。

很好.exe

对于执行预期操作的程序(从 \Windows\System32 加载第二个name.dll(,则不涉及 DLL 重定向,因此在隐式链接期间遵循标准 DLL 搜索顺序。 在系统目录之前搜索应用程序目录,以便加载name.dll的副本。

然后,您的name.dll执行一个LoadLibrary调用,指定文件C:WindowsSystem32name.dll的完整路径。 由于没有进行重定向,因此name.dll的系统目录版本将按预期加载。

自己.exe

如果程序没有执行预期操作(两次获取您自己的name.dll版本的句柄(,则会发生DLL重定向,因为应用程序文件夹中有一个名为own.exe.local的目录。 由于正在进行重定向,因此在隐式链接期间,将忽略标准搜索顺序,并从own.exe.local加载name.dll

然后,您的name.dll执行一个loadlibrary调用,指定文件C:WindowsSystem32name.dll的完整路径。但这一次正在进行重定向。 将忽略LoadLibrary调用中指定的完整路径,并从重定向文件夹own.exe.local加载模块。

由于该name.dll副本已经由隐式链接加载,因此您只需获得模块的另一个句柄即可。

正如评论中指出的那样,GetLastError结果具有误导性。LoadLibrary调用未返回 NULL(它返回了你自己的name.dll的句柄(,因此GetLastError返回的值不适用于LoadLibrary调用。