Dll search client как пользоваться

Обновлено: 04.07.2024

Ниже мы рассмотрим проблемы с работой DDL файлов в самых популярных версиях операционной системы Windows, разберем почему возникают проблемы с DLL, а также предоставим способы их устранения.

Содержание:

  • Почему возникают ошибки с DLL?
  • Решение проблем с DDL файлами.
  • Недостающие компоненты C++ Runtime Library и DirectX.
  • Удаление сбойного приложения.
  • Обновление драйверов устройства.
  • Другие проблемы с DLL библиотеками.
  • Что делать если важный файл или DLL библиотека были случайно удалены?

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

Почему возникают ошибки с DLL?

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

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

Одними из основных причин возникновения ошибок DLL является простое отсутствие библиотек , которые требуются для работы приложений. Недостающие файлы могут быть удалены самим пользователем, уничтожены вирусами или перезаписанными более старыми версиями в процессе установки программных компонентов. Помимо этого, ошибки могут возникать из-за неправильной работы драйверов , недостающего программного обеспечения таких, как NET Framework, DirectX и т.д.

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

Решение проблем с DDL файлами

DLL библиотеки тесно вплетены в различные системные процессы, поэтому при повреждении некоторых из них, операционная система может попросту перестать запускаться. Если это произошло, следует прибегнуть к встроенным средствам восстановления системы . Что бы попасть в среду восстановления достаточно вставить загрузочную флешку или диск с Windows, либо автоматически попасть в среду после трех неудачных попыток загрузки .

Пункты "Восстановление системы" "Восстановление образа системы" и "Восстановление при загрузке" подойдут для решения большинства логических проблем операционной системы. Пункты "Восстановление системы" "Восстановление образа системы" и "Восстановление при загрузке" подойдут для решения большинства логических проблем операционной системы.

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

Если проблема кроется в некорректной работе загрузчика, рекомендуем ознакомится со способами исправления в статье «Как восстановить загрузчик Windows 10» .

Недостающие компоненты C++ Runtime Library и DirectX

Чаще всего пользователи сталкиваются с проблемой ошибок DLL, которые связаны с отсутствием необходимых компонентов C++ Runtime Library либо DirectX .

Существует два способа решения проблем с недостающими компонентами DLL. Первый и более правильный – полная переустановка сбоящего ПО. Второй – скачивание непосредственного одного компонента, вызывающего ошибку.

Ошибка msvcr100.dll – сбойный компонент в системе безопасности.

Ошибки dxgi.* , d3dx9_25.*, d3d11.*, d3dx9.*, d3dx9_43.*, xinput1_3.*, d3dx9_31.*, xinput1_2.*, d3dx9_31.*, d3dx9_34.*, d3dx9_42.*, x3daudio1_7.*, x3daudio1_6.*, xrsound.* d3dx10_43.*, d3dx9_26.*, d3dx9_30.*, d3dx9_27.*, d3dx11_43.*, d3dcompiler_43.*, d3d10.*.

Ошибка steam_api.dll – распространённая ошибка среди геймеров и пользователей магазина цифровой дистрибуции Steam. Часто возникает при установке пиратских сборок игр и взломанных клиентов Steam.

Важно: мы настоятельно не рекомендуем скачивать отдельные недостающие файлы steam_api.dll, которые можно часто встретить на просторах интернета. Это обусловлено тем, что многие злоумышленники специально распространяют зараженные файлы или шпионские утилиты под видом dll-файлов. Если такой файл попадет на компьютер пользователя, существует большая вероятность утери доступа к аккаунту.

Ошибка uplay_r1_loader.* , Uplay.exe, uplay.*, ubiorbitapi_r2_loader.* — аналогичная ошибка, как и с со Steam.

Ошибка xlive – проблемы с файлами цифрового магазина Microsoft.

Ошибка msvcrt.* , msvcr71.*, msvcrt.*, msvcp120.*, msvcp110.* x64 msvcr90.*, msvcr110.*, msvcr100.*, msvcr80.*, msvcr120.*.

Ошибка physxcudart_20.* , physxloader.* и т.д.- проблемы с файлами NVIDIA PHYSX SYSTEM.

Удаление сбойного приложения

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

Чтобы определить сбойное приложение, необходимо:

Шаг 1. Нажимаем левой кнопкой мыши по иконке «Поиск» (изображение лупы возле кнопки «Пуск») и вводим в строку фразу «Панель управления» , после чего переходим в непосредственно сам пункт «Панель управления» .

Зачем нужна регистрация DLL

Перед использованием некоторых DLL систему необходимо “проинформировать” о том, какой файл добавлен в систему, что он делает и из чего состоит. Без этих сведений файлом будет пользоваться сложнее, а зачастую некоторые возможности останутся закрытыми.

Как узнать, какая программа использует DLL

Как узнать, какая программа использует DLL

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

Что такое DL_

Одним из способов уменьшения размеров DLL-файлов является сжатие неиспользуемых библиотек. Microsoft делает это с помощью службы MakeCAB, именно благодаря ей также происходит обратная “распаковка”.

Как найти DLL-файл на компьютере

Как найти DLL-файл на компьютере

Зачастую требуется определить местонахождение того или иного DLL-файла на компьютере, например, для определения его полного адреса при удалении из системы.

Что делать, если “Точка входа не найдена”

Что делать, если “Точка входа не найдена”

Такая ошибка чаще всего возникает при несовпадении версии dll файла и версии приложения, которое ее использует. Одной из частых причин может быть неправильная установка пакетов Visual C++.

Одним из самых популярных способов является переустановка программы или системы, однако можно решить проблему кудаа менее радикально. Для начала необходимо определить, какой именно DLL-файл поврежден.


В этой статье мы рассмотрим концепцию перехвата порядка поиска динамически подключаемых библиотек (DLL hijacking) и то, как она может быть использована для достижения устойчивости (persistence) в юзерленде в системах Windows. Этот метод описан в MITER ATT&CK в разделе: «Перехват порядка поиска DLL (T1038)».

Подмена DLL может быть использована злоумышленниками для множества разных целей, но в этой статье основное внимание будет уделено достижению устойчивости с помощью приложений с автозапуском. Например, поскольку Slack и Microsoft Teams запускаются при загрузке (по умолчанию), подмена DLL в одном из этих приложений позволит злоумышленнику получить устойчивый доступ к своей цели — всякий раз, когда пользователь входит в систему.

После представления концепции DLL, порядка поиска DLL, и подмены DLL, я раскрою процесс автоматизации обнаружения возможности перехвата DLL. В этой статье будет рассказано об обнаружении путей перехвата DLL в Slack, Microsoft Teams и Visual Studio Code.

Наконец, я обнаружил несколько путей перехвата DLL, которые использовались разными приложениями, исследовал основную причину и обнаружил, что приложения, использующие определенные вызовы API Windows, подвержены перехвату DLL, когда не работают из C:\Windows\System32\ .

Я хочу поблагодарить своего коллегу Джозайю Массари ( @Airzero24 ) за то, что он первым обнаружил некоторые из этих перехватов DLL, объяснил их методологию и вдохновил меня автоматизировать обнаружение.

Что такое DLL?

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

Функциональные возможности DLL могут быть использованы приложением Windows с помощью одной из функций LoadLibrary* . Приложения могут ссылаться на DLL, разработанные специально для этих приложений, или DLL Windows, уже находящиеся на диске в System32. Разработчики могут загружать DLL из System32, чтобы использовать в своих приложениях функционал, уже реализованный в Windows, без необходимости писать этот функционал с нуля.

Порядок поиска DLL и перехват

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

Начиная с Windows XP SP2, безопасный режим поиска DLL включен по умолчанию ( HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode ). При включенном безопасном режиме порядок поиска DLL следующий:

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

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

Если разработчик приложения предполагает загрузку DLL из C:\Windows\System32 , но явно не прописал это в приложении, вредоносная DLL, помещенная в каталог приложения, будет загружена раньше, чем легитимная DLL из System32. Загрузка вредоносной DLL называется подменой (или перехватом) DLL и используется злоумышленниками для загрузки вредоносного кода в доверенные/подписанные приложения.

Использование подмены DLL для достижения устойчивости

Подмена DLL может использоваться для достижения устойчивости, когда уязвимое приложение/служба запускается и вредоносная DLL размещается в уязвимом месте. Мой коллега, @Airzero24 , обнаружил подмену DLL в Microsoft OneDrive, Microsoft Teams и Slack в виде userenv.dll .

Именно эти программы стали целью перехвата, потому что по умолчанию они настроены на запуск при загрузке Windows. Это можно увидеть ниже в диспетчере задач:



Приложения Windows, настроенные на автозапуск

Чтобы проверить подмену DLL, я создал загрузчик шеллкода DLL, который запускал Cobalt Strike Beacon. Я переименовал вредоносную DLL в userenv.dll и скопировал ее в каталог уязвимого приложения. Я запустил приложение и увидел свой новый Beacon коллбек.



Cobalt Strike Beacon через перехват DLL

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



Обозреватель процессов, показывающий загруженную вредоносную DLL

Автоматическое обнаружение возможности перехвата DLL

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

Код, использованный в моих проверка, можно найти здесь.

На примере Slack

Чтобы начать этот процесс, я запустил Process Monitor (ProcMon) со следующими фильтрами:

Затем я запустил Slack и изучил ProcMon на предмет любых DLL, которые Slack искал, но не смог найти.



Возможные пути перехвата DLL, обнаруженные с помощью ProcMon

Я экспортировал эти данные из ProcMon в виде CSV файла для облегчения парсинга в PowerShell.

С моей текущей DLL загрузчика шелл-кода я не смог бы легко определить имена DLL, которые были успешно загружены Slack. Я создал новую DLL, которая использовала GetModuleHandleEx и GetModuleFileName для определения имени загруженной DLL и записи его в текстовый файл.

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

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

Всю магию в моем проекте DLLHijackTest творит скрипт PowerShell. Он принимает путь к CSV-файлу, сгенерированному ProcMon, путь к вашей вредоносной DLL, путь к процессу, который вы хотите запустить, и любые аргументы, которые вы хотите передать процессу.



Параметры Get-PotentialDLLHijack



Get-PotentialDLLHijack.ps1

Через несколько минут я проверяю текстовый файл, указанный в моей «вредоносной» DLL, на предмет возможных перехватов DLL. Я обнаружил следующие возможные пути перехвата для Slack:

На примере Microsoft Teams

Выполняем описанный выше процесс еще раз:

  1. Используйте ProcMon для выявления потенциальных путей перехвата DLL, экспортируйте эти данные в виде CSV файла.
  2. Определите путь запуска процесса.
  3. Определите любые аргументы, которые вы хотите передать процессу.
  4. Запустите Get-PotentialDLLHijack.ps1 с соответствующими аргументами.
Примечание: Мне пришлось внести небольшие изменения в скрипт PowerShell, чтобы завершить Teams.exe , так как мой скрипт пытается завершить процесс, который он пытался запустить, в данном случае это Update.exe .

На примере Visual Studio Code

Повторяя описанный выше процесс, я обнаружил следующие потенциальные пути перехвата для Visual Studio Code:

Подмена общих (shared) DLL

Я заметил, что Slack, Microsoft Teams и Visual Studio Code совместно используют следующие DLL:

  • WINSTA.dll
  • LINKINFO.dll
  • ntshrui.dll
  • srvcli.dll
  • cscapi.dll

Методология: понимание путей перехвата общих DLL

Я следил за стек трейсом, когда Slack пытался загрузить WINSTA.dll , LINKINFO.dll , ntshrui.dll , srvcli.dll и cscapi.dll .

DLL с отложенной загрузкой

Я заметил сходство в стек трейсе при загрузке WINSTA.dll , LINKINFO.dll , ntshrui.dll и srvcli.dll .



Стек трейс, когда Code.exe пытается загрузить WINSTA.dll



Стек трейс, когда Teams.exe пытается загрузить LINKINFO.dll ,



Стек трейс, когда Slack пытается загрузить ntshrui.dll

Стек трейс постоянно содержит вызов _tailMerge_< dllname>_dll , delayLoadHelper2 за которым следует LdrResolveDelayLoadedAPI . Такое поведение было одинаковым для всех трех приложений.

Я определил, что это поведение связано с отложенной загрузкой DLL. Из стек трейса при загрузке WINSTA.dll я мог видеть, что модулем, ответственным за эту отложенную загрузку, был wtsapi32.dll .

Я открыл wtsapi32.dll в Ghidra и использовал Search -> For Strings -> Filter: WINSTA.dll . Двойной клик по найденной строке приведет вас к ее локации в памяти.



Строка « WINSTA.dll » в wtsapi32.dll

Кликнув правой кнопкой мыши по локации в памяти, мы сможем найти любые ссылки на этот адрес.



Ссылки на WINSTA.dll

Следуя ссылкам, мы видим, что строка WINSTA.dll передается в структуру с именем ImgDelayDescr . Глядя на документацию по этой структуре, мы можем подтвердить, что она связана с отложенной загрузкой DLL.


Эту структуру можно передать в __delayLoadHelper2 , который будет использовать LoadLibrary / GetProcAddress для загрузки указанной DLL и исправления адреса импортируемой функции в таблице адресов импорта отложенной загрузки (IAT).


Найдя другие ссылки на нашу структуру ImgDelayDescr , мы можем найти вызов __delayLoadHelper2 , который затем вызывает ResolveDelayLoadedAPI . Я переименовал имя функции, типы и переменные, чтобы облегчить понимание.


__delayLoadHelper2 и ResolveDelayLoadedAPI в Ghidra

Отлично! Это соответствует тому, что мы видели в нашем ProcMon стек трейсе, когда Slack пытался загрузить WINSTA.dll .



__delayLoadHelper2 и ResolveDelayLoadedAPI в ProcMon.

Такое поведение было единообразно для WINSTA.dll , LINKINFO.dll , ntshrui.dll и srvcli.dll . Основным отличием каждой DLL с отложенной загрузкой была «родительская» DLL. Во всех трех приложениях:

  • wtsapi32.dll отложено загружала WINSTA.dll
  • shell32.dll отложенно загружала LINKINFO.dll
  • LINKINFO.dll отложено загружала ntshrui.dll
  • ntshrui.dll отложено загружала srvcli.dll

Подмена DLL в NetShareGetInfo и NetShareEnum

Я следил за стек трейсом, когда Slack пытался загрузить cscapi.dll и видел вызов LoadLibraryExW , который, по-видимому, исходил из srvcli.dll .



Стек трейс при загрузке cscapi.dll

Я открыл srvcli.dll в Ghidra и использовал Search -> For Strings -> Filter: cscapi.dll . Двойной клик по найденной строке и переход по ссылкам приводит к ожидаемому LoadLibrary вызову.



srvcli.dll вызывает LoadLibrary для cscapi.dll

Переименовав функцию, содержащую вызов LoadLibrary , и проследовав по ссылкам, я получил два места использования функции:



NetShareGetInfo загружает cscapi.dll

Я проверил это с помощью РоС программ, которые вызывали NetShareEnum и NetShareGetInfo :



NetShareEnum.exe загружает cscapi.dll



NetShareGetInfo.exe загружает cscapi.dll

Результаты

В Slack доступны следующие пути подмены DLL:


В Microsoft Teams доступны следующие пути подмены DLL:


В Visual Studio Code доступны следующие пути подмены DLL:


Кроме того, я обнаружил, что программы, использующие NetShareEnum и NetShareGetInfo , предоставляют возможность подмены DLL в форме cscapi.dll из-за жестко захардкоженного вызова LoadLibrary . Я подтвердил это поведение с помощью Ghidra и PoC.

Заключение

Напомним, что перехват DLL — это метод, с помощью которого злоумышленники могут повлиять на выполнение кода в подписанных/доверенных приложениях. Я создал инструменты, помогающие автоматизировать обнаружение путей перехвата DLL. Используя этот инструмент, я обнаружил пути перехвата DLL в Slack, Microsoft Teams и Visual Studio Code.

Я заметил, что пути перехвата DLL этих трех приложений частично совпадают, и исследовал причину. Я осветил свою методику понимания данного совпадения. Я узнал о DLL с отложенной загрузкой и обнаружил два вызова API, которые делают возможным перехват DLL в любой программе, которая их вызывает:

  • NetShareEnum загружает cscapi.dll
  • NetShareGetInfo загружает cscapi.dll

Ссылки

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

  • если DLL с тем же самым именем модуля уже загружена в память, система проверит только [следует ли выполнить] перенаправление [перенаправление включается наличием в папке с исполняемым файлом приложения пустого файла с таким же именем, как у приложения, и расширением .local и указывает системе начать поиск DLL с папки, в которой находится этот файл .local ] и манифест [на наличие указаний о местонахождении нужной DLL] и [при отсутствии перенаправления и манифеста] будет считать результатом поиска загруженную DLL, при этом не будет иметь значения, в каком каталоге эта загруженная DLL находится. Система не станет выполнять других действий по поиску DLL;
  • если DLL есть в списке библиотек DLL, известных той версии операционной системы Windows, в которой запущено приложение, система использует свою копию известной DLL (и свои копии библиотек DLL, от которых эта известная DLL зависит, если таковые имеются) вместо того, чтобы искать эту DLL. Увидеть список известных текущей системе DLL можно, обратившись к следующему ключу реестра: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControl Set\Control\Session Manager\KnownDLLs;
  • если DLL имеет зависимости [от других DLL] , система будет искать библиотеки DLL, от которых зависит исходная, так, как если бы эти библиотеки загружались с указанием только имен их модулей. Это правило остается верным, даже если исходная DLL загружалась с указанием полного пути к ней.

Когда приложение «Windows Store» загружает упакованный модуль [DLL] посредством вызова функции LoadPackagedLibrary, DLL должна находиться в графе зависимостей пакета для процесса. Подробнее об этом читайте в описании функции LoadPackagedLibrary. Когда приложение «Windows Store» загружает модуль [DLL] другими средствами и не указывает полный путь к нему, система ищет DLL и ее зависимости [модули, от которых эта DLL зависит] во время запуска программы так, как описано в этом разделе.

Замечание для пользователей предыдущих по отношению к свежим на дату написания статьи версиям операционных систем Windows (Windows 7 (вики: с 22.10.2009 г.), Windows Server 2008 R2 (вики: с 22.10.2009 г.), Windows Vista (вики: с 30.11.2006 г.), Windows Server 2008 (вики: с 12.12.2008 г.), Windows Server 2003 (вики: с 24.04.2003 г.) и Windows XP (вики: с 24.08.2001 г.)): приложения «Windows Store» поддерживаются, начиная с операционных систем «Windows 8» (вики: с 26.10.2012 г.) и «Windows Server 2012» (вики: с 04.09.2012 г.).

  • если DLL с таким же именем модуля уже загружена в память, система будет использовать загруженную DLL, при этом не будет иметь значения, в каком каталоге эта загруженная DLL находится. Система не станет выполнять других действий по поиску DLL;
  • если DLL есть в списке библиотек DLL, известных той версии операционной системы Windows, в которой запущено приложение, система использует свою копию известной DLL (и свои копии библиотек DLL, от которых эта известная DLL зависит, если таковые имеются) вместо того, чтобы искать эту DLL. Увидеть список известных текущей системе DLL можно, обратившись к следующему ключу реестра: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControl Set\Control\Session Manager\KnownDLLs.

Стандартный порядок поиска DLL для приложений «Windows Store»

  1. Граф зависимостей пакета для процесса. Местом поиска является пакет приложения плюс любые зависимости, отмеченные как <PackageDependency> в разделе <Dependencies> манифеста пакета приложения. Зависимости ищутся системой в том порядке, в котором они появляются в манифесте;
  2. Каталог, из которого был загружен вызывающий DLL процесс;
  3. Системный каталог ( %SystemRoot%\system32 ).

Альтернативный порядок поиска DLL для приложений «Windows Store»

  1. Граф зависимостей пакета для процесса. Местом поиска является пакет приложения плюс любые зависимости, отмеченные как <PackageDependency> в разделе <Dependencies> манифеста пакета приложения. Зависимости ищутся системой в том порядке, в котором они появляются в манифесте;
  2. Каталог, из которого указанный [в параметре функции LoadLibraryEx] модуль был загружен;
  3. Системный каталог ( %SystemRoot%\system32 ).

Приложения настольного компьютера [desktop applications] могут указывать место, из которого будет загружена DLL, посредством указания полного пути к DLL, могут использовать перенаправление поиска DLL, либо могут использовать манифест. Если ни один из этих методов не используется, система ищет DLL во время загрузки программы так, как описано в этом разделе.

  • если DLL с таким же именем модуля уже загружена в память, система будет использовать загруженную DLL, при этом не будет иметь значения, в каком каталоге эта загруженная DLL находится. Система не станет выполнять других действий по поиску DLL;
  • если DLL есть в списке библиотек DLL, известных той версии операционной системы Windows, в которой запущено приложение, система использует свою копию известной DLL (и свои копии библиотек DLL, от которых эта известная DLL зависит, если таковые имеются) вместо того, чтобы искать эту DLL. Увидеть список известных текущей системе DLL можно, обратившись к следующему ключу реестра: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControl Set\Control\Session Manager\KnownDLLs.

Важное замечание. Если злоумышленник получит доступ к одному из каталогов, в которых выполняется поиск DLL, он может поместить в этот каталог вредоносную копию искомой DLL. Чтобы узнать способы предотвращения таких атак, читайте статью «Безопасность DLL».


Стандартный порядок поиска DLL для приложений настольного компьютера

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

Безопасный режим поиска DLL по умолчанию включен. Чтобы его выключить, следует создать в реестре параметр HKEY_LOCAL_MACHINE\System\CurrentControl Set\Control\Session Manager\SafeDllSearchMode и установить его значение в 0 (ноль). Вызов функции SetDllDirectory при ее успешном завершении отключает параметр реестра SafeDllSearchMode, в то время как указанный [в параметре функции SetDllDirectory] каталог находится в поисковом списке каталогов и изменяет порядок поиска так, как описано [далее] в этой статье.

Замечание для пользователей операционной системы Windows XP (вики: с 24.08.2001 г.; поддержка этой системы прекращена корпорацией «Microsoft» c 08.04.2014 г.): безопасный режим поиска DLL по умолчанию выключен. Чтобы включить его, следует создать параметр реестра SafeDllSearchMode и установить его значение в 1. Безопасный режим поиска DLL включен по умолчанию, начиная с «Windows XP» с установленным пакетом обновления SP2.

  1. Каталог, из которого загружено приложение;
  2. Системный каталог [обычно это каталог ..\Windows\System32\ , но не всегда] . Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу;
  3. Системный каталог для 16-разрядных библиотек DLL [обычно это каталог ..\Windows\System\ , но не всегда] . Не существует функции [из набора Windows API] , которая получала бы путь к этому каталогу, но поиск в этом каталоге всё равно выполняется;
  4. Каталог операционной системы Windows [обычно это каталог ..\Windows\ , но не всегда] . Используйте функцию GetWindowsDirectory, чтобы получить путь к этому каталогу;
  5. Текущий каталог;
  6. Каталоги, перечисленные в переменной среды PATH. Заметим, что эта переменная не включает путь, определенный в разрезе каждого приложения ключом реестра App Paths [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\W indows\CurrentVersion\App Paths] . Ключ реестра App Paths не используется при поиске DLL.
  1. Каталог, из которого загружено приложение;
  2. Текущий каталог;
  3. Системный каталог [обычно это каталог ..\Windows\System32\ , но не всегда] . Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу;
  4. Системный каталог для 16-разрядных библиотек DLL [обычно это каталог ..\Windows\System\ , но не всегда] . Не существует функции [из набора Windows API] , которая получала бы путь к этому каталогу, но поиск в этом каталоге всё равно выполняется;
  5. Каталог операционной системы Windows [обычно это каталог ..\Windows\ , но не всегда] . Используйте функцию GetWindowsDirectory, чтобы получить путь к этому каталогу;
  6. Каталоги, перечисленные в переменной среды PATH. Заметим, что эта переменная не включает путь, определенный в разрезе каждого приложения ключом реестра App Paths [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\W indows\CurrentVersion\App Paths] . Ключ реестра App Paths не используется при поиске DLL.

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

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

Замечание для пользователей операционной системы Windows XP (вики: с 24.08.2001 г.; поддержка этой системы прекращена корпорацией «Microsoft» c 08.04.2014 г.): изменение стандартного порядка поиска DLL с помощью вызова функции SetDllDirectory не поддерживалось до «Windows XP» с установленным пакетом обновления SP1.

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

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

Заметим, что стратегия стандартного порядка поиска DLL и стратегия альтернативного порядка поиска DLL, установленная функцией LoadLibraryEx с флагом LOAD_WITH_ALTERED_SEARCH_PATH, различаются только в одном: стандартный порядок поиска DLL начинается с каталога вызывающего приложения, а альтернативный порядок поиска DLL начинается с каталога исполняемого модуля, загружаемого функцией LoadLibraryEx.

  1. Каталог, определенный параметром lpFileName функции LoadLibraryEx;
  2. Системный каталог [обычно это каталог ..\Windows\System32\ , но не всегда] . Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу;
  3. Системный каталог для 16-разрядных библиотек DLL [обычно это каталог ..\Windows\System\ , но не всегда] . Не существует функции [из набора Windows API] , которая получала бы путь к этому каталогу, но поиск в этом каталоге всё равно выполняется;
  4. Каталог операционной системы Windows [обычно это каталог ..\Windows\ , но не всегда] . Используйте функцию GetWindowsDirectory, чтобы получить путь к этому каталогу;
  5. Текущий каталог;
  6. Каталоги, перечисленные в переменной среды PATH. Заметим, что эта переменная не включает путь, определенный в разрезе каждого приложения ключом реестра App Paths [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\W indows\CurrentVersion\App Paths] . Ключ реестра App Paths не используется при поиске DLL.
  1. Каталог, определенный параметром lpFileName функции LoadLibraryEx;
  2. Текущий каталог;
  3. Системный каталог [обычно это каталог ..\Windows\System32\ , но не всегда] . Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу;
  4. Системный каталог для 16-разрядных библиотек DLL [обычно это каталог ..\Windows\System\ , но не всегда] . Не существует функции [из набора Windows API] , которая получала бы путь к этому каталогу, но поиск в этом каталоге всё равно выполняется;
  5. Каталог операционной системы Windows [обычно это каталог ..\Windows\ , но не всегда] . Используйте функцию GetWindowsDirectory, чтобы получить путь к этому каталогу;
  6. Каталоги, перечисленные в переменной среды PATH. Заметим, что эта переменная не включает путь, определенный в разрезе каждого приложения ключом реестра App Paths [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\W indows\CurrentVersion\App Paths] . Ключ реестра App Paths не используется при поиске DLL.
  1. Каталог, из которого загружено приложение;
  2. Каталог, указанный в параметре lpPathName функции SetDllDirectory;
  3. Системный каталог [обычно это каталог ..\Windows\System32\ , но не всегда] . Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу;
  4. Системный каталог для 16-разрядных библиотек DLL [обычно это каталог ..\Windows\System\ , но не всегда] . Не существует функции [из набора Windows API] , которая получала бы путь к этому каталогу, но поиск в этом каталоге всё равно выполняется;
  5. Каталог операционной системы Windows [обычно это каталог ..\Windows\ , но не всегда] . Используйте функцию GetWindowsDirectory, чтобы получить путь к этому каталогу;
  6. Каталоги, перечисленные в переменной среды PATH. Заметим, что эта переменная не включает путь, определенный в разрезе каждого приложения ключом реестра App Paths [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\W indows\CurrentVersion\App Paths] . Ключ реестра App Paths не используется при поиске DLL.

Функция SetDllDirectory в случае своей успешной отработки выключает безопасный режим поиска DLL, а указанный в ее параметре каталог включается в поисковый список каталогов. Чтобы восстановить безопасный режим поиска DLL, основанный на параметре реестра SafeDllSearchMode, и вернуть текущий каталог в поисковый список каталогов, следует вызвать функцию SetDllDirectory с ее параметром lpPathName, установленным в значение NULL.

Порядок поиска DLL с использованием флагов LOAD_LIBRARY_SEARCH

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

Замечание для пользователей предыдущих по отношению к свежим на дату написания статьи версиям операционных систем Windows (Windows 7 (вики: с 22.10.2009 г.), Windows Server 2008 R2 (вики: с 22.10.2009 г.), Windows Vista (вики: с 30.11.2006 г.), Windows Server 2008 (вики: с 12.12.2008 г.)): флаги LOAD_LIBRARY_SEARCH доступны на этих системах, если установлено обновление KB2533623.

Замечание для пользователей операционных систем Windows Server 2003 (вики: с 24.04.2003 г.) и Windows XP (вики: с 24.08.2001 г.): флаги LOAD_LIBRARY_SEARCH в этих системах не поддерживаются.

Читайте также: