当前位置: 首页 > news >正文

windows DLL技术-动态链接库搜索

动态链接库搜索规则

同一动态链接库 (DLL) 的多个版本通常存在于操作系统 (OS) 内的不同文件系统位置。 可以通过指定完整路径来控制从中加载任何给定 DLL 的特定位置。 但是,如果不使用该方法,则系统会在加载时搜索 DLL。 DLL 加载程序是操作系统 的一部分,用于加载 DLL 和/或解析对 DLL 的引用。

打包应用的搜索顺序

当打包的应用专门加载打包的模块时,DLL 必须位于进程的包依赖项关系图中。 当打包的应用通过其他方式加载模块并且未指定完整路径时,系统会在加载时搜索 DLL 及其依赖项,如本部分所述。

当系统搜索模块或其依赖项时,它始终使用打包应用的搜索顺序;即使依赖项不是打包的应用代码。

打包应用的系统按以下顺序搜索:

  1. DLL 加载器的 重定向;
  2. API 集,打包应用指定;
  3. 桌面应用仅 (UWP 应用) , SxS 清单重定向;
  4. Loaded-module 列表;
  5. 已知 DLL;
  6. 进程的包依赖项关系图。 这是应用程序的包,以及应用程序包清单的 节<Dependencies>中指定的任何依赖项<PackageDependency>。 依赖项按它们在清单中的出现顺序进行搜索;
  7. 调用进程从加载的文件夹 (可执行文件的文件夹) 。
  8. 系统文件夹 (%SystemRoot%\system32) ;

如果 DLL 具有依赖项,则系统会搜索依赖 DLL,就好像只加载了其模块名称,即使第一个 DLL 是通过指定完整路径加载的。

打包应用的备用搜索顺序,如果模块通过使用 LOAD_WITH_ALTERED_SEARCH_PATH 调用 LoadLibraryEx 函数更改标准搜索顺序,则搜索顺序与标准搜索顺序相同,只是在步骤 7 中,系统搜索从加载指定模块的文件夹 (顶部加载模块的文件夹) ,而不是可执行文件的文件夹。

未打包应用的搜索顺序

当未打包的应用加载模块且未指定完整路径时,系统会在加载时搜索 DLL。注意如果攻击者控制了搜索的某个目录,则可以在该文件夹中放置 DLL 的恶意副本。 系统使用的标准 DLL 搜索顺序取决于是否启用了 安全 DLL 搜索模式 。

默认情况下启用的安全 DLL 搜索模式按搜索顺序移动用户的当前文件夹。 若要禁用安全 DLL 搜索模式,请 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode 创建注册表值并将其设置为 0。 当指定文件夹位于搜索路径 时,调用 SetDllDirectory 函数可有效地禁用安全 DLL 搜索模式,并更改这部分中所述的搜索顺序。

如果启用了安全 DLL 搜索模式,则搜索顺序如下所示:

  • DLL 加载器的 重定向;
  • API 集合;
  • SxS 清单重定向 ;
  • Loaded-module 链表;
  • 已知的DLLs;
  • Windows 11,版本 21H2 (10.0;内部版本 22000) 及更高版本。 流程的包依赖关系图。这是应用程序的包加上在应用程序包清单的< dependencies >部分中指定为<PackageDependency>的任何依赖项。依赖项按照它们在清单中出现的顺序进行搜索;
  • 从中加载应用程序的文件夹;
  • 系统文件夹。 使用 GetSystemDirectory 函数检索此文件夹的路径;
  • 16 位系统文件夹。 没有获取此文件夹路径的函数,但会对其进行搜索;
  • Windows 文件夹。 使用 GetWindowsDirectory 函数获取此文件夹的路径;
  • 当前文件夹;
  • 环境变量中列出的 PATH 目录。 这不包括由应用路径注册表项指定的每 应用程序路径 。 计算 DLL 搜索路径时,不使用 应用 路径键;
  • 如果 禁用安全 DLL 搜索模式,则搜索顺序相同,只是 当前文件夹 在步骤 7 之后立即从序列 (从位置 11 移动到位置 8 。应用程序从中加载) 的文件夹 ;
未打包应用的备用搜索顺序

若要更改系统使用的标准搜索顺序,可以使用 LOAD_WITH_ALTERED_SEARCH_PATH调用 LoadLibraryEx 函数。 还可以通过调用 SetDllDirectory 函数来更改标准搜索顺序。

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

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

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

  • 在调用应用程序的文件夹中初始步骤后,标准搜索策略开始;
  • 在 LoadLibraryEx 正在加载的可执行模块的文件夹中的初始步骤后,使用 LOAD_WITH_ALTERED_SEARCH_PATH 的LoadLibraryEx  指定的备用搜索策略开始 ;

如果启用了安全 DLL 搜索模式,则备用搜索顺序如下所示:

  1. 步骤 1-6 与标准搜索顺序相同;
  2. 由 lpFileName 指定的文件夹;
  3. 系统文件夹,使用 GetSystemDirectory 可以获取;
  4. 16 位系统文件夹。 没有获取此文件夹路径的函数,但会对其进行搜索;
  5. Windows 文件夹. 使用 GetWindowsDirectory 函数获取此文件夹的路径;
  6. 当前文件夹;
  7. 环境变量中列出的 PATH 目录。 这不包括应用路径注册表项指定的每 应用程序路径 。 计算 DLL 搜索路径时,不使用 应用 路径密钥;

如果 禁用安全 DLL 搜索模式,则备用搜索顺序是相同的,只是 当前文件夹 在步骤 7 后,顺序从位置 11 移动到位置 8 ,由 lpFileName 指定的文件夹。

如果 lpPathName 参数指定路径,SetDllDirectory 函数支持备用搜索顺序。 备用搜索顺序如下:

  • 步骤 1-6 与标准搜索顺序相同;
  • 从中加载应用程序的文件夹;
  • 由 SetDllDirectory 的 lpPathName 参数指定的文件夹;
  • 系统文件夹;
  • 16 位系统文件夹;
  • Windows 文件夹;
  • 环境变量中列出的 PATH 目录;

如果 lpPathName 参数为空字符串,则调用将从搜索顺序中删除当前文件夹;

当指定文件夹位于搜索路径中时,SetDllDirectory 可有效地禁用安全 DLL 搜索模式。 若要基于 SafeDllSearchMode 注册表值还原安全 DLL 搜索模式,并将当前文件夹还原到搜索顺序,请调用 SetDllDirectory , lpPathName 为 NULL。

使用LOAD_LIBRARY_SEARCH标志搜索顺序

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

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

  1. LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR。 搜索包含 DLL 的文件夹。 此文件夹仅搜索要加载的 DLL 的依赖项;
  2. LOAD_LIBRARY_SEARCH_APPLICATION_DIR。 搜索应用程序文件夹;
  3. LOAD_LIBRARY_SEARCH_USER_DIRS。 搜索使用 AddDllDirectory 函数或 SetDllDirectory 函数显式添加的路径。 如果添加多个路径,则未指定搜索路径的顺序;
  4. LOAD_LIBRARY_SEARCH_SYSTEM32。 搜索“系统”文件夹;

如果调用 LoadLibraryEx 时没有 LOAD_LIBRARY_SEARCH 标志,或者为进程建立 DLL 搜索顺序,则系统将使用标准搜索顺序或备用搜索顺序搜索 DLL。


http://www.mrgr.cn/news/58735.html

相关文章:

  • 【程序分享】PCB元件坐标对齐工具 V1.3
  • 【JavaEE】【多线程】单例模式
  • mysql 安装
  • Mybatis 直接传入sql执行, 并且传入参数List<Object> params
  • useEffect简单介绍
  • 无需多言,简单粗暴上手MybatisPlus
  • LeetCode904.水果成篮
  • uniapp 发起post和get请求!uni.request(OBJECT)
  • Typora 、 Minio and PicGo 图床搭建
  • 【高级IO】IO多路转接之select
  • 代码随想录第九天|151.翻转字符串里的单词、卡码网:55.右旋转字符串、28. 实现 strStr() 、459.重复的子字符串
  • 《西安科技大学学报》
  • 我谈Canny算子
  • windows中git无法通过ssh连接github
  • 【Git】将本地代码提交到github仓库
  • electron 监听窗口高端变化
  • 基础知识总结-因果分析-dayone-辛普森悖论 因果关系
  • Spring Boot 中应用单元测试(UT):结合 Mock 和 H2 讲解和案例示范
  • Openlayers高级交互(8/20):选取feature,平移feature
  • Linux中安装配置SQLite3,并实现C语言与SQLite3的交互。
  • 活着就好20241026
  • Nature Communications|一种3D打印和激光诱导协同策略用于定制功能化器件(3D打印/激光直写/柔性电子/人机交互/柔性电路)
  • react项目因eslint检测未通过而Failed to compile编译失败
  • Go操作Redis
  • 智创 AI 新视界 -- 探秘 AIGC 中的生成对抗网络(GAN)应用
  • Java项目实战II基于微信小程序的智慧旅游平台(开发文档+数据库+源码)