您当前的位置: 首页 >  搜索

顺其自然~

暂无认证

  • 2浏览

    0关注

    1317博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

dll搜索顺序

顺其自然~ 发布时间:2021-02-05 08:30:38 ,浏览量:2

一个系统可以包含同一动态链接库(DLL)的多个版本。应用程序可以通过指定完整路径或使用其他机制(如清单)来控制DLL的加载位置。如果未使用这些方法,则系统将如本主题中所述在加载时搜索DLL。

影响搜索的因素

以下因素影响系统是否搜索DLL:

  • 如果具有相同模块名称的DLL已在内存中加载,则系统在解析到已加载的DLL之前,仅检查重定向和清单,无论它位于哪个目录中。系统都不会搜索该DLL。
  • 如果该DLL在运行该应用程序的Windows版本的已知DLL列表中,则系统将使用其已知DLL(以及已知DLL的从属DLL,如果有)的副本代替搜索DLL。有关当前系统上已知DLL的列表,请参见以下注册表项:HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Session Manager \ KnownDLLs。
  • 如果DLL具有依赖项,则系统将搜索依赖的DLL,就好像它们仅使用其模块名加载一样。即使通过指定完整路径加载了第一个DLL,也是如此。
搜索UWP(Universal Windows Platform)应用的订单

当Windows 10的UWP应用程序(或Windows 8.x的Store应用程序)通过调用LoadPackagedLibrary函数加载打包的模块时,DLL必须位于进程的程序包依赖关系图中。有关更多信息,请参见LoadPackagedLibrary。当UWP应用通过其他方式加载模块且未指定完整路径时,系统将如本节所述在加载时搜索DLL及其依赖项。

在系统搜索DLL之前,它会检查以下内容:

  • 如果内存中已经加载了具有相同模块名称的DLL,则系统将使用已加载的DLL,无论它位于哪个目录中。系统都不会搜索该DLL。
  • 如果该DLL在运行该应用程序的Windows版本的已知DLL列表中,则系统使用其已知DLL的副本(以及已知DLL的从属DLL,如果有的话)。系统不搜索DLL。有关当前系统上已知DLL的列表,请参见以下注册表项:HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Session Manager \ KnownDLLs。

如果系统必须搜索模块或其依赖项,则即使依赖项不是UWP应用程序代码,它也始终使用UWP应用程序的搜索顺序。

UWP应用的标准搜索顺序

如果模块尚未加载或在已知DLL列表中,则系统将按以下顺序搜索这些位置:

  1. 程序的程序包依赖关系图。这是应用程序的包加上指定为任何依赖应用程序的软件包清单的部分。按照它们在清单中出现的顺序搜索依赖关系。
  2. 调用进程从中加载的目录。
  3. 系统目录(%SystemRoot%\ system32)。

如果DLL具有依赖项,则系统将搜索依赖的DLL,就好像它们仅使用其模块名加载一样。即使通过指定完整路径加载了第一个DLL,也是如此。

UWP应用的替代搜索顺序

如果模块通过使用LOAD_WITH_ALTERED_SEARCH_PATH调用LoadLibraryEx函数来更改标准搜索顺序,则系统将搜索指定模块的加载目录,而不是调用进程的目录。系统按以下顺序搜索这些位置:

  1. 程序的程序包依赖关系图。这是应用程序的包加上指定为任何依赖应用程序的软件包清单的部分。按照它们在清单中出现的顺序搜索依赖关系。
  2. 指定模块的加载目录。
  3. 系统目录(%SystemRoot%\ system32)。
桌面应用程序的搜索顺序

桌面应用程序可以通过指定完整路径,使用DLL重定向或使用manifest来控制DLL的加载位置。如果未使用这些方法,则系统将如本节所述在加载时搜索DLL。

在系统搜索DLL之前,它会检查以下内容:

  1. 如果内存中已经加载了具有相同模块名称的DLL,则系统将使用已加载的DLL,无论它位于哪个目录中。系统都不会搜索该DLL。
  2. 如果该DLL在运行该应用程序的Windows版本的已知DLL列表中,则系统使用其已知DLL的副本(以及已知DLL的从属DLL,如果有的话)。系统不搜索DLL。有关当前系统上已知DLL的列表,请参见以下注册表项:HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Session Manager \ KnownDLLs。

如果DLL具有依赖项,则系统将搜索依赖的DLL,就好像它们仅使用其模块名加载一样。即使通过指定完整路径加载了第一个DLL,也是如此。

重要

如果攻击者获得了对所搜索目录之一的控制,则可以将DLL的恶意副本放置在该目录中。有关防止此类攻击的方法,请参见Dynamic-Link Library Security。

桌面应用程序的标准搜索顺序

系统使用的标准DLL搜索顺序取决于是否启用安全DLL搜索模式。安全DLL搜索模式将用户的当前目录放在搜索顺序的后面。

默认情况下,安全DLL搜索模式处于启用状态。若要禁用此功能,请创建HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Session Manager \ SafeDllSearchMode注册表值并将其设置为0。当指定目录在搜索路径中时,调用SetDllDirectory函数可有效禁用SafeDllSearchMode并按照说明更改搜索顺序在本主题中。

如果启用了SafeDllSearchMode,则搜索顺序如下:

  1. 从加载应用程序的目录中。
  2. 系统目录。使用GetSystemDirectory函数获取此目录的路径。
  3. 16位系统目录。没有获取该目录路径的函数,但会对其进行搜索。
  4. Windows目录。使用GetWindowsDirectory函数获取此目录的路径。
  5. 用户的当前目录。
  6. PATH环境变量中列出的目录。请注意,这不包括App Paths注册表项指定的每个应用程序路径。计算DLL搜索路径时不使用App Paths键。

如果禁用SafeDllSearchMode,则搜索顺序如下:

  1. 从加载应用程序的目录中。
  2. 用户的当前目录。
  3. 系统目录。使用GetSystemDirectory函数获取此目录的路径。
  4. 16位系统目录。没有获取该目录路径的函数,但会对其进行搜索。
  5. Windows目录。使用GetWindowsDirectory函数获取此目录的路径。
  6. PATH环境变量中列出的目录。请注意,这不包括App Paths注册表项指定的每个应用程序路径。计算DLL搜索路径时不使用App Paths键。
桌面应用程序的替代搜索顺序

通过使用LOAD_WITH_ALTERED_SEARCH_PATH(将这个标志加到LoadLibraryEx中)调用LoadLibraryEx函数,可以更改系统使用的标准搜索顺序。也可以通过调用SetDllDirectory函数来更改标准搜索顺序。

备注

在当前进程开始之前,通过在父进程中调用SetDllDirectory函数也将影响该进程的标准搜索顺序。

如果指定备用搜索策略,则其行为将一直持续到找到所有关联的可执行模块为止。系统开始处理DLL初始化例程后,系统将还原为标准搜索策略。

如果调用指定LOAD_WITH_ALTERED_SEARCH_PATH且lpFileName参数指定绝对路径,则LoadLibraryEx函数支持备用搜索顺序。

请注意,LoadLibraryEx使用LOAD_WITH_ALTERED_SEARCH_PATH指定的标准搜索策略和替代搜索策略只有一种不同:标准搜索从调用应用程序的目录开始,替代搜索从LoadLibraryEx正在加载的可执行模块的目录开始。

如果启用了SafeDllSearchMode,则备用搜索顺序如下:

  1. lpFileName指定的目录。
  2. 系统目录。使用GetSystemDirectory函数获取此目录的路径。
  3. 16位系统目录。没有获取该目录路径的函数,但会对其进行搜索。
  4. Windows目录。使用GetWindowsDirectory函数获取此目录的路径。
  5. 当前目录。
  6. PATH环境变量中列出的目录。请注意,这不包括App Paths注册表项指定的每个应用程序路径。计算DLL搜索路径时不使用App Paths键。

如果SafeDllSearchMode被禁用,则替代搜索顺序如下:

  1. lpFileName指定的目录。
  2. 当前目录。
  3. 系统目录。使用GetSystemDirectory函数获取此目录的路径。
  4. 16位系统目录。没有获取该目录路径的函数,但会对其进行搜索。
  5. Windows目录。使用GetWindowsDirectory函数获取此目录的路径。
  6. PATH环境变量中列出的目录。请注意,这不包括App Paths注册表项指定的每个应用程序路径。计算DLL搜索路径时不使用App Paths键。

SetDllDirectory功能支持的替代搜索顺序如果lpPathName参数指定的路径。备用搜索顺序如下:

  1. 从加载应用程序的目录中。
  2. 由SetDllDirectory的lpPathName参数指定的目录。
  3. 系统目录。使用GetSystemDirectory函数获取此目录的路径。该目录的名称是System32。
  4. 16位系统目录。没有获取该目录路径的函数,但会对其进行搜索。该目录的名称是System。
  5. Windows目录。使用GetWindowsDirectory函数获取此目录的路径。
  6. PATH环境变量中列出的目录。请注意,这不包括App Paths注册表项指定的每个应用程序路径。计算DLL搜索路径时不使用App Paths键。

如果lpPathName参数为空字符串,则该调用将从搜索顺序中删除当前目录。

当指定目录位于搜索路径中时, SetDllDirectory有效地禁用安全DLL搜索模式。要恢复基于安全DLL搜索模式SafeDllSearchMode注册表值,并恢复当前目录搜索顺序,调用SetDllDirectory会与lpPathName为NULL。

使用LOAD_LIBRARY_SEARCH标志的搜索顺序

应用程序可以通过将一个或多个LOAD_LIBRARY_SEARCH标志与LoadLibraryEx函数一起使用来指定搜索顺序。应用程序还可以将LOAD_LIBRARY_SEARCH标志与SetDefaultDllDirectories函数一起使用,以建立进程的DLL搜索顺序。应用程序可以使用AddDllDirectory或SetDllDirectory函数为进程DLL搜索顺序指定其他目录。

搜索的目录取决于SetDefaultDllDirectories或LoadLibraryEx指定的标志。如果使用多个标志,则按以下顺序搜索相应的目录:

  1. 包含DLL的目录(LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)。仅在此目录中搜索要加载的DLL的依赖项。
  2. 应用程序目录(LOAD_LIBRARY_SEARCH_APPLICATION_DIR)。
  3. 使用AddDllDirectory函数(LOAD_LIBRARY_SEARCH_USER_DIRS)或SetDllDirectory函数显式添加的路径。如果添加了多个路径,则未指定搜索路径的顺序。
  4. 系统目录(LOAD_LIBRARY_SEARCH_SYSTEM32)。

如果应用程序未使用任何LOAD_LIBRARY_SEARCH标志调用LoadLibraryEx或未为该过程建立DLL搜索顺序,则系统将使用标准搜索顺序或替代搜索顺序搜索DLL。

关注
打赏
1662339380
查看更多评论
立即登录/注册

微信扫码登录

0.1473s