Поделиться через


Порядок поиска библиотеки динамических ссылок

Обычно для нескольких версий одной библиотеки динамической компоновки (DLL) существуют в разных расположениях файловой системы в операционной системе (ОС). Вы можете управлять определенным расположением, из которого загружается любая определенная библиотека DLL, указав полный путь. Но если этот метод не используется, система выполняет поиск библиотеки DLL во время загрузки, как описано в этом разделе. Загрузчик DLL является частью операционной системы ( ОС), которая загружает библиотеки DLL и /или разрешает ссылки на библиотеки DLL.

Кончик

Определения упакованных и распакованных приложений см. в разделе Преимущества и недостатки упаковки приложения.

Факторы, влияющие на поиск

Ниже приведены некоторые специальные факторы поиска, которые рассматриваются в этом разделе. Их можно считать частью порядка поиска библиотеки DLL. В последующих разделах этого раздела перечислены эти факторы в соответствующем порядке поиска для определенных типов приложений вместе с другими расположениями поиска. В этом разделе описаны основные понятия и их имена, которые мы будем использовать для их ссылки далее в этом разделе.

  • перенаправление БИБЛИОТЕК DLL. Дополнительные сведения см. в перенаправлении библиотеки dynamic-link.
  • API задает. Дополнительные сведения см. в разделе наборов API Windows.
  • перенаправление параллельного манифеста (SxS)— классические приложения только (не приложения UWP). Вы можете перенаправить с помощью манифеста приложения (также называемого параллельным манифестом приложения или манифестом fusion). Дополнительные сведения см. в разделе Манифесты.
  • список загруженных модулей. Система может проверить, загружена ли библиотека DLL с тем же именем модуля в память (независимо от папки, из которой она была загружена).
  • известные библиотеки DLL. Если библиотека DLL находится в списке известных библиотек DLL для версии Windows, в которой выполняется приложение, система использует ее копию известной библиотеки DLL (и зависимые библиотеки DLL, если таковые есть). Список известных библиотек DLL в текущей системе см. в разделе реестра HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.

Если библиотека DLL имеет зависимости, система ищет зависимые библиотеки DLL, как если бы они были загружены с помощью только их имен модулей. Это верно, даже если первая библиотека DLL была загружена, указав полный путь.

Порядок поиска упакованных приложений

Когда упаковаемое приложение загружает упакованный модуль (в частности, модуль библиотеки — файл .dll), вызывая функцию LoadPackagedLibrary, библиотека DLL должна находиться в графе зависимостей пакета процесса. Дополнительные сведения см. в разделе LoadPackagedLibrary. Когда упаковаемое приложение загружает модуль другими средствами и не указывает полный путь, система выполняет поиск библиотеки DLL и его зависимостей во время загрузки, как описано в этом разделе.

При поиске модуля или зависимостей система всегда использует порядок поиска упакованных приложений; даже если зависимость не упакована в код приложения.

Стандартный порядок поиска упакованных приложений

Система выполняет поиск в этом порядке:

  1. Перенаправление библиотеки DLL.
  2. Наборы API.
  3. классические приложения (не приложения UWP). Перенаправление манифеста SxS.
  4. Список загруженных модулей.
  5. Известные библиотеки DLL.
  6. Граф зависимостей пакета процесса. Это пакет приложения и все зависимости, указанные как <PackageDependency> в разделе <Dependencies> манифеста пакета приложения. Зависимости выполняются в том порядке, в который они отображаются в манифесте.
  7. Папка, из которую был загружен вызывающий процесс (папка исполняемого файла).
  8. Системная папка (%SystemRoot%\system32).

Если библиотека DLL имеет зависимости, система ищет зависимые библиотеки DLL, как если бы они были загружены только именами модулей (даже если первая библиотека DLL была загружена, указав полный путь).

Альтернативный порядок поиска упакованных приложений

Если модуль изменяет стандартный порядок поиска, вызывая функцию LoadLibraryEx с LOAD_WITH_ALTERED_SEARCH_PATH, то порядок поиска совпадает с стандартным порядком поиска, за исключением того, что на шаге 7 система выполняет поиск в папке, из которую был загружен указанный модуль (папка верхнего модуля) вместо папки исполняемого файла.

Порядок поиска для распакованных приложений

Когда распаковка приложения загружает модуль и не указывает полный путь, система выполняет поиск библиотеки DLL во время загрузки, как описано в этом разделе.

Важный

Если злоумышленник получает контроль над одним из каталогов, которые выполняется поиск, он может поместить вредоносную копию библиотеки DLL в этой папке. Способы предотвращения таких атак см. в безопасности библиотеки Dynamic-link.

Стандартный порядок поиска для распакованных приложений

Стандартный порядок поиска библиотек DLL, используемый системой, зависит от того, включен ли безопасный режим поиска БИБЛИОТЕК DLL.

Режим безопасного поиска DLL (который включен по умолчанию) перемещает текущую папку пользователя позже в порядке поиска. Чтобы отключить безопасный режим поиска библиотеки DLL, создайте значение реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode и задайте для него значение 0. Вызов функции SetDllDirectory эффективно отключает безопасный режим поиска БИБЛИОТЕК DLL (в то время как указанная папка находится в пути поиска) и изменяет порядок поиска, как описано в этом разделе.

Если включен безопасный режим поиска библиотеки DLL, порядок поиска выглядит следующим образом:

  1. Перенаправление библиотеки DLL.
  2. Наборы API.
  3. Перенаправление манифеста SxS.
  4. Список загруженных модулей.
  5. Известные библиотеки DLL.
  6. Windows 11 версии 21H2 (10.0; Сборка 22000), а затем. Граф зависимостей пакета процесса. Это пакет приложения и все зависимости, указанные как <PackageDependency> в разделе <Dependencies> манифеста пакета приложения. Зависимости выполняются в том порядке, в который они отображаются в манифесте.
  7. Папка, из которой загружено приложение.
  8. Системная папка. Используйте функцию getSystemDirectory, чтобы получить путь к этой папке.
  9. 16-разрядная системная папка. Нет функции, которая получает путь к этой папке, но выполняется поиск.
  10. Папка Windows. Используйте функцию GetWindowsDirectory, чтобы получить путь к этой папке.
  11. Текущая папка.
  12. Каталоги, перечисленные в переменной среды PATH. Это не включает путь для каждого приложения, указанный пути к приложению раздел реестра. Ключ пути приложения не используется при вычислении пути поиска библиотеки DLL.

Если режим безопасного поиска библиотеки DLL отключен, то порядок поиска одинаков, за исключением того, что текущей папке перемещается с позиции 11 на позицию 8 в последовательности (сразу после шага 7. Папка, из которой приложение загружается).

Альтернативный порядок поиска для распакованных приложений

Чтобы изменить стандартный порядок поиска, используемый системой, можно вызвать функцию LoadLibraryEx с LOAD_WITH_ALTERED_SEARCH_PATH. Вы также можете изменить стандартный порядок поиска, вызвав функцию SetDllDirectory.

Заметка

Стандартный порядок поиска процесса также будет затронут путем вызова функции SetDllDirectory в родительском процессе до начала текущего процесса.

Если указать альтернативную стратегию поиска, ее поведение продолжается до тех пор, пока не будут размещены все связанные исполняемые модули. После того как система начнет обработку подпрограмм инициализации DLL, система переходит к стандартной стратегии поиска.

Функция LoadLibraryEx поддерживает альтернативный порядок поиска, если вызов задает LOAD_WITH_ALTERED_SEARCH_PATH, а параметр lpFileName задает абсолютный путь.

  • Стандартная стратегия поиска начинается (после начальных шагов) в папке вызывающего приложения.
  • Альтернативная стратегия поиска, указанная LoadLibraryEx с LOAD_WITH_ALTERED_SEARCH_PATH начинается (после начальных шагов) в папке исполняемого модуля, LoadLibraryEx.

Это единственный способ, в котором они отличаются.

Если включен безопасный режим поиска dll, альтернативный порядок поиска выглядит следующим образом:

Шаги 1–6 совпадают со стандартным порядком поиска.

  1. Папка, указанная lpFileName.
  2. Системная папка. Используйте функцию getSystemDirectory, чтобы получить путь к этой папке.
  3. 16-разрядная системная папка. Нет функции, которая получает путь к этой папке, но выполняется поиск.
  4. Папка Windows. Используйте функцию GetWindowsDirectory, чтобы получить путь к этой папке.
  5. Текущая папка.
  6. Каталоги, перечисленные в переменной среды PATH. Это не включает путь для каждого приложения, указанный пути к приложению раздел реестра. Ключ пути приложения не используется при вычислении пути поиска библиотеки DLL.

Если режим безопасного поиска библиотеки DLL отключен, альтернативный порядок поиска совпадает, за исключением того, что текущей папке перемещается с позиции 11 на позицию 8 в последовательности (сразу после шага 7. Папка, указанная lpFileName).

Функция setDllDirectoryподдерживает альтернативный порядок поиска, если параметр lpPathName указывает путь. Альтернативный порядок поиска выглядит следующим образом:

Шаги 1–6 совпадают со стандартным порядком поиска.

  1. Папка, из которой загружено приложение.
  2. Папка, указанная параметром lpPathNameSetDllDirectory.
  3. Системная папка.
  4. 16-разрядная системная папка.
  5. Папка Windows.
  6. Каталоги, перечисленные в переменной среды PATH.

Если параметр lpPathName является пустой строкой, вызов удаляет текущую папку из порядка поиска.

SetDllDirectory эффективно отключает безопасный режим поиска DLL, а указанная папка находится в пути поиска. Чтобы восстановить безопасный режим поиска DLL на основе значения реестра SafeDllSearchMod e, а затем восстановить текущую папку в порядке поиска, вызовите SetDllDirectory с lpPathName значение NULL.

Порядок поиска с помощью флагов LOAD_LIBRARY_SEARCH

Порядок поиска можно указать с помощью одного или нескольких флагов LOAD_LIBRARY_SEARCH с функцией LoadLibraryEx. Вы также можете использовать флаги LOAD_LIBRARY_SEARCH с функцией setDefaultDllDirectory, чтобы установить порядок поиска библиотек DLL для процесса. Дополнительные каталоги для порядка поиска библиотеки DLL процесса можно указать с помощью функций AddDllDirectory или SetDllDirectory.

Каталоги, которые выполняются в поиске, зависят от флагов, указанных с SetDefaultDllDirectory или LoadLibraryEx. При использовании нескольких флагов соответствующие каталоги выполняются в этом порядке:

  1. LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR. Папка, содержащая библиотеку DLL, выполняется поиск. Эта папка выполняется поиск только для зависимостей библиотеки DLL для загрузки.
  2. LOAD_LIBRARY_SEARCH_APPLICATION_DIR. Выполняется поиск в папке приложения.
  3. LOAD_LIBRARY_SEARCH_USER_DIRS. Пути, явно добавленные с помощью функции AddDllDirectory или функции setDllDirectorySetDllDirectory. При добавлении нескольких путей порядок поиска путей не определен.
  4. LOAD_LIBRARY_SEARCH_SYSTEM32. Выполняется поиск в системной папке.

Если вы вызываете LoadLibraryEx без флагов LOAD_LIBRARY_SEARCH или устанавливаете порядок поиска библиотек DLL для процесса, система ищет библиотеки DLL, используя стандартный порядок поиска или альтернативный порядок поиска.