Функция LoadLibraryExA (libloaderapi.h)
Загружает указанный модуль в адресное пространство вызывающего процесса. Указанный модуль может привести к загрузке других модулей.
Синтаксис
HMODULE LoadLibraryExA(
[in] LPCSTR lpLibFileName,
HANDLE hFile,
[in] DWORD dwFlags
);
Параметры
[in] lpLibFileName
Строка, указывающая имя файла модуля для загрузки. Это имя не связано с именем, хранящимся в модуле библиотеки, как указано ключевым словом библиотеки
Модуль может быть модулем библиотеки (файлом .dll) или исполняемым модулем (файлом .exe). Если указанный модуль является исполняемым модулем, статические импорты не загружаются; Вместо этого модуль загружается так, как если бы DONT_RESOLVE_DLL_REFERENCES был указан. Дополнительные сведения см. в параметре dwFlags.
Если строка указывает имя модуля без пути и расширение имени файла опущено, функция добавляет расширение библиотеки по умолчанию ".DLL" в имя модуля. Чтобы не допустить добавления функции ".DLL" в имя модуля, добавьте в строку имени модуля символ конечную точку (.).
Если строка задает полный путь, функция выполняет поиск только этого пути для модуля. При указании пути обязательно используйте обратные косые черты (\), а не косой черты (/). Дополнительные сведения о путях см. в именовании файлов, путей и пространств имен.
Если строка задает имя модуля без пути, а несколько загруженных модулей имеют то же базовое имя и расширение, функция возвращает дескриптор модулю, который был загружен первым.
Если строка указывает имя модуля без пути и модуль того же имени еще не загружен или если строка задает имя модуля с относительным путем, функция выполняет поиск указанного модуля. Функция также ищет модули, если загрузка указанного модуля приводит к загрузке системы других связанных модулей (то есть, если модуль имеет зависимости). Каталоги, которые находятся в поиске, и порядок их поиска зависят от указанного пути и параметра dwFlags. Дополнительные сведения см. в разделе "Примечания".
Если функция не может найти модуль или одну из его зависимостей, функция завершается ошибкой.
hFile
Этот параметр зарезервирован для дальнейшего использования. Он должен быть null.
[in] dwFlags
Действие, выполняемое при загрузке модуля. Если флаги не указаны, поведение этой функции идентично функции LoadLibrary. Этот параметр может быть одним из следующих значений.
Ценность | Значение |
---|---|
|
Если это значение используется, и исполняемый модуль является библиотекой DLL, система не вызывает DllMain для инициализации процесса и завершения потоков. Кроме того, система не загружает дополнительные исполняемые модули, на которые ссылается указанный модуль.
примечание не использовать это значение; он предоставляется только для обратной совместимости. Если вы планируете получить доступ только к данным или ресурсам в библиотеке DLL, используйте LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE или LOAD_LIBRARY_AS_IMAGE_RESOURCE или обоих. В противном случае загрузите библиотеку в виде dll или исполняемого модуля с помощью функции LoadLibrary.
|
|
Если это значение используется, система не проверяет правила AppLocker или применяет политики ограничений программного обеспечения для библиотеки DLL. Это действие применяется только к загружаемой библиотеке DLL, а не к его зависимостям. Это значение рекомендуется использовать в программах установки, которые должны запускать извлеченные библиотеки DLL во время установки.
Windows Server 2008 R2 и Windows 7: в системах с установленными KB2532445, вызывающий объект должен работать как LocalSystem или TrustedInstaller; в противном случае система игнорирует этот флаг. Дополнительные сведения см. в статье "Вы можете обойти правила AppLocker с помощью макроса Office на компьютере под управлением Windows 7 или Windows Server 2008 R2" в базе знаний справки и поддержки в https://support.microsoft.com/kb/2532445. Windows Server 2008, Windows Vista, Windows Server 2003 и Windows XP: AppLocker появилась в Windows 7 и Windows Server 2008 R2. |
|
Если это значение используется, система сопоставляет файл с виртуальным адресным пространством вызывающего процесса, как если бы он был файлом данных. Ничего не делается для выполнения или подготовки к выполнению сопоставленного файла. Таким образом, нельзя вызывать такие функции, как GetModuleFileName, GetModuleHandle или GetProcAddress с помощью этой библиотеки DLL. Использование этого значения приводит к тому, что запись в память только для чтения вызывает нарушение доступа. Используйте этот флаг, если вы хотите загрузить библиотеку DLL только для извлечения сообщений или ресурсов из него.
Это значение можно использовать с LOAD_LIBRARY_AS_IMAGE_RESOURCE. Дополнительные сведения см. в разделе "Примечания". |
|
Аналогично LOAD_LIBRARY_AS_DATAFILE, за исключением того, что DLL-файл открыт с эксклюзивным доступом на запись для вызывающего процесса. Другие процессы не могут открыть DLL-файл для доступа на запись во время его использования. Однако библиотека DLL по-прежнему может быть открыта другими процессами.
Это значение можно использовать с LOAD_LIBRARY_AS_IMAGE_RESOURCE. Дополнительные сведения см. в разделе "Примечания". Windows Server 2003 и Windows XP: Это значение не поддерживается до Windows Vista. |
|
Если это значение используется, система сопоставляет файл с виртуальным адресным пространством процесса как файл изображения.
Однако загрузчик не загружает статические импорты или выполняет другие обычные шаги инициализации. Используйте этот флаг, если вы хотите загрузить библиотеку DLL только для извлечения сообщений или ресурсов из него.
Если приложение не зависит от файла с макетом изображения в памяти, это значение следует использовать либо с LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE, либо с LOAD_LIBRARY_AS_DATAFILE. Дополнительные сведения см. в разделе "Примечания". Windows Server 2003 и Windows XP: Это значение не поддерживается до Windows Vista. |
|
Если это значение используется, каталог установки приложения выполняет поиск библиотеки DLL и его зависимостей. Каталоги в стандартном пути поиска не выполняются. Это значение нельзя объединить с LOAD_WITH_ALTERED_SEARCH_PATH.
Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Это значение требует установки KB2533623. Windows Server 2003 и Windows XP: это значение не поддерживается. |
|
Это значение представляет собой сочетание LOAD_LIBRARY_SEARCH_APPLICATION_DIR, LOAD_LIBRARY_SEARCH_SYSTEM32и LOAD_LIBRARY_SEARCH_USER_DIRS. Каталоги в стандартном пути поиска не выполняются. Это значение нельзя объединить с LOAD_WITH_ALTERED_SEARCH_PATH.
Это значение представляет рекомендуемое максимальное количество каталогов, которые приложение должно включать в путь поиска библиотеки DLL. Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Это значение требует установки KB2533623. Windows Server 2003 и Windows XP: это значение не поддерживается. |
|
Если это значение используется, каталог, содержащий библиотеку DLL, временно добавляется в начало списка каталогов, которые ищут зависимости библиотеки DLL. Каталоги в стандартном пути поиска не выполняются.
Параметр lpFileName должен указать полный путь. Это значение нельзя объединить с LOAD_WITH_ALTERED_SEARCH_PATH. Например, если Lib2.dll является зависимостью C:\Dir1\Lib1.dll, loading Lib1.dll with this value causes the system to search for Lib2.dll только в C:\Dir1. Чтобы найти Lib2.dll в C:\Dir1 и всех каталогах в пути поиска библиотеки DLL, объедините это значение с LOAD_LIBRARY_SEARCH_DEFAULT_DIRS. Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Это значение требует установки KB2533623. Windows Server 2003 и Windows XP: это значение не поддерживается. |
|
Если это значение используется, %windows%\system32 выполняется поиск библиотеки DLL и ее зависимостей.
Каталоги в стандартном пути поиска не выполняются. Это значение нельзя объединить с LOAD_WITH_ALTERED_SEARCH_PATH.
Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Это значение требует установки KB2533623. Windows Server 2003 и Windows XP: это значение не поддерживается. |
|
Если это значение используется, каталоги, добавленные с помощью AddDllDirectory или функции SetDllDirectory выполняют поиск библиотеки DLL и ее зависимостей. Если добавлено несколько каталогов, порядок поиска каталогов не указан. Каталоги в стандартном пути поиска не выполняются. Это значение нельзя объединить с LOAD_WITH_ALTERED_SEARCH_PATH.
Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Это значение требует установки KB2533623. Windows Server 2003 и Windows XP: это значение не поддерживается. |
|
Если это значение используется и lpFileName указывает абсолютный путь, система использует альтернативную стратегию поиска файлов, описанную в разделе "Примечания", чтобы найти связанные исполняемые модули, которые указанный модуль вызывает загрузку. Если это значение используется и lpFileName указывает относительный путь, поведение не определено.
Если это значение не используется или если lpFileName не указывает путь, система использует стандартную стратегию поиска, описанную в разделе "Примечания", чтобы найти связанные исполняемые модули, которые указанный модуль вызывает загрузку. Это значение нельзя объединить с любым флагом LOAD_LIBRARY_SEARCH. |
|
Указывает, что цифровая подпись двоичного образа должна быть проверена во время загрузки.
Для этого значения требуется Windows 8.1, Windows 10 или более поздней версии. |
|
Если это значение используется, загрузка библиотеки DLL для выполнения из текущего каталога разрешена только в том случае, если он находится под каталогом в списке безопасной загрузки. |
Возвращаемое значение
Если функция выполнена успешно, возвращаемое значение является дескриптором загруженного модуля.
Если функция завершается ошибкой, возвращаемое значение равно NULL. Чтобы получить расширенные сведения об ошибке, вызовите GetLastError.
Замечания
Функция LoadLibraryEx очень похожа на функцию LoadLibrary. Различия состоят из набора необязательных действий, которые LoadLibraryEx:
- LoadLibraryEx может загрузить модуль DLL без вызова функции dll DllMain библиотеки DLL.
- LoadLibraryEx может загружать модуль так, как это оптимизировано для случая, когда модуль никогда не будет выполняться, загружая модуль, как если бы он был файлом данных.
- LoadLibraryEx может находить модули и связанные с ними модули с помощью двух стратегий поиска или выполнять поиск по определенному процессу набору каталогов.
Процесс вызова может использовать дескриптор, возвращенный LoadLibraryEx для идентификации модуля в вызовах GetProcAddress, FindResourceи функции LoadResource.
Чтобы включить или отключить сообщения об ошибках, отображаемые загрузчиком во время загрузки DLL, используйте функцию SetErrorMode.
Небезопасно вызывать LoadLibraryEx из DllMain. Дополнительные сведения см. в разделе "Примечания" в DllMain.
Visual C++: компилятор Visual C++ поддерживает синтаксис, позволяющий объявлять локальные переменные потока: _declspec(thread). Если этот синтаксис используется в библиотеке DLL, вы не сможете явно загрузить библиотеку DLL с помощью LoadLibraryEx в версиях Windows до Windows Vista. Если библиотека DLL будет загружена явным образом, необходимо использовать функции локального хранилища потока вместо _declspec(thread). Пример см. в разделе Использование локального хранилища потоков вбиблиотеки динамических ссылок.
загрузка библиотеки DLL в виде файла данных или ресурса изображения
Значения LOAD_LIBRARY_AS_DATAFILE, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVEи LOAD_LIBRARY_AS_IMAGE_RESOURCE влияют на количество ссылок на процесс и загрузку указанного модуля. Если для параметра dwFlags задано любое из этих значений, загрузчик проверяет, был ли модуль уже загружен процессом в виде исполняемой библиотеки DLL. Если это так, это означает, что модуль уже сопоставлен с виртуальным адресным пространством вызывающего процесса. В этом случае LoadLibraryEx возвращает дескриптор библиотеке DLL и увеличивает число ссылок на библиотеку DLL. Если модуль DLL еще не загружен в виде библиотеки DLL, система сопоставляет модуль как данные или файл изображения, а не как исполняемую библиотеку DLL. В этом случае LoadLibraryEx возвращает дескриптор загруженным файлам данных или изображения, но не увеличивает число ссылок для модуля и не делает модуль видимым для функций, таких как CreateToolhelp32Snapshot или EnumProcessModules.Если LoadLibraryEx вызывается дважды для одного файла с LOAD_LIBRARY_AS_DATAFILE, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVEили LOAD_LIBRARY_AS_IMAGE_RESOURCE, для файла создаются два отдельных сопоставления.
При использовании значения LOAD_LIBRARY_AS_IMAGE_RESOURCE модуль загружается в виде изображения с помощью расширения выравнивания разделов переносимого исполняемого файла (PE). Относительные виртуальные адреса (RVA) не нужно сопоставлять с адресами дисков, поэтому ресурсы можно быстрее извлекать из модуля. Указание LOAD_LIBRARY_AS_IMAGE_RESOURCE запрещает другим процессам изменять модуль во время загрузки.
Если приложение не зависит от конкретных характеристик сопоставления изображений, значение LOAD_LIBRARY_AS_IMAGE_RESOURCE должно использоваться либо с LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE, либо с LOAD_LIBRARY_AS_DATAFILE. Это позволяет загрузчику выбрать, следует ли загружать модуль в качестве ресурса изображения или файла данных, выбрав любой параметр, позволяющий системе предоставлять доступ к страницам более эффективно. Функции ресурсов, такие как FindResource, могут использовать любое сопоставление.
Чтобы определить, как был загружен модуль, используйте один из следующих макросов для проверки дескриптора, возвращаемого LoadLibraryEx.
#define LDR_IS_DATAFILE(handle) (((ULONG_PTR)(handle)) & (ULONG_PTR)1)
#define LDR_IS_IMAGEMAPPING(handle) (((ULONG_PTR)(handle)) & (ULONG_PTR)2)
#define LDR_IS_RESOURCE(handle) (LDR_IS_IMAGEMAPPING(handle) || LDR_IS_DATAFILE(handle))
В следующей таблице описаны эти макросы.
Макрос | Описание |
---|---|
LDR_IS_DATAFILE(дескриптор) | Если этот макрос возвращает TRUE, модуль был загружен в виде файла данных (LOAD_LIBRARY_AS_DATAFILE или LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE). |
LDR_IS_IMAGEMAPPING(дескриптор) | Если этот макрос возвращает TRUE, модуль был загружен в виде файла изображения (LOAD_LIBRARY_AS_IMAGE_RESOURCE). |
LDR_IS_RESOURCE(дескриптор) | Если этот макрос возвращает TRUE, модуль был загружен как файл данных или файл изображения. |
Используйте функцию FreeLibrary, чтобы освободить загруженный модуль, независимо от того, была ли загрузка модуля вызвана добавочным числом ссылок. Если модуль был загружен в виде файла данных или изображения, сопоставление уничтожается, но количество ссылок не уменьшается. В противном случае число ссылок dll уменьшается. Поэтому вызов FreeLibrary с любым дескриптором, возвращаемым LoadLibraryEx.
поиск библиотек DLL и зависимостей
Путь поиска — это набор каталогов, которые ищут библиотеку DLL. Функция LoadLibraryEx может искать библиотеку DLL, используя стандартный путь поиска или измененный путь поиска, или использовать путь поиска для конкретного процесса, установленный с помощью SetDefaultDllDirectory и функций AddDllDirect ory. Список каталогов и порядок их поиска см. в Dynamic-Link порядке поиска библиотеки.Функция LoadLibraryEx использует стандартный путь поиска в следующих случаях:
- Имя файла указано без пути, а имя базового файла не совпадает с именем базового файла загруженного модуля, и ни один из флагов LOAD_LIBRARY_SEARCH не используется.
- Указан путь, но LOAD_WITH_ALTERED_SEARCH_PATH не используется.
- Приложение не указало путь поиска библиотеки DLL по умолчанию для процесса с помощью SetDefaultDllDirectory.
Если lpFileName указывает относительный путь, весь относительный путь добавляется к каждому токену в пути поиска DLL. Чтобы загрузить модуль из относительного пути без поиска другого пути, используйте GetFullPathName для получения нерелятивного пути и вызова LoadLibraryEx с нерелятивным путем. Если модуль загружается в виде файла данных, а относительный путь начинается с "." или ".", относительный путь рассматривается как абсолютный путь.
Если lpFileName указывает абсолютный путь и dwFlags задано значение LOAD_WITH_ALTERED_SEARCH_PATH, LoadLibraryEx использует измененный путь поиска. Поведение не определено при установке флага LOAD_WITH_ALTERED_SEARCH_PATH и lpFileName указывает относительный путь.
Функцию SetDllDirectory можно использовать для изменения пути поиска. Это решение лучше, чем использовать SetCurrentDirectory или жестко закодировать полный путь к библиотеке DLL. Однако помните, что использование SetDllDirectory эффективно отключает безопасный режим поиска DLL, пока указанный каталог находится в пути поиска, и он не является потокобезопасным. По возможности рекомендуется использовать AddDllDirectory для изменения пути поиска по умолчанию. Дополнительные сведения см. в Dynamic-Link порядке поиска библиотеки.
Приложение может указать каталоги для поиска одного вызова LoadLibraryEx с помощью флагов LOAD_LIBRARY_SEARCH_** . Если задано несколько флагов LOAD_LIBRARY_SEARCH, каталоги выполняются в следующем порядке:
- Каталог, содержащий библиотеку DLL (LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR). Этот каталог выполняется поиск только для зависимостей библиотеки DLL для загрузки.
- Каталог приложения (LOAD_LIBRARY_SEARCH_APPLICATION_DIR).
- Пути явно добавлены в путь поиска приложения с функцией
AddDllDirectory ( LOAD_LIBRARY_SEARCH_USER_DIRS ) или функцией setDllDirectorySetDllDirectory. Если добавлено несколько путей, порядок поиска путей не определен. - Каталог System32 (LOAD_LIBRARY_SEARCH_SYSTEM32).
Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Флаги LOAD_LIBRARY_SEARCH_ доступны в системах с установленными KB2533623. Чтобы определить, доступны ли флаги, используйте GetProcAddress для получения адреса AddDllDirectory, RemoveDllDirectoryили Функции SetDefaultDllDirectory. Если GetProcAddress успешно, флаги LOAD_LIBRARY_SEARCH_ можно использовать с LoadLibraryEx.
Если приложение использовало функцию SetDefaultDllDirectory для установки пути поиска библиотеки DLL для процесса и ни одного из флагов LOAD_LIBRARY_SEARCH_* *, функция LoadLibraryEx использует путь поиска библиотеки DLL процесса вместо стандартного пути поиска.
Если указан путь и есть файл перенаправления, связанный с приложением, функция LoadLibraryEx выполняет поиск модуля в каталоге приложения. Если модуль существует в каталоге приложения, LoadLibraryEx игнорирует спецификацию пути и загружает модуль из каталога приложения. Если модуль не существует в каталоге приложения, функция загружает модуль из указанного каталога. Дополнительные сведения см. в разделе перенаправление библиотеки динамического канала.
При вызове LoadLibraryEx с именем сборки без спецификации пути, а сборка указана в манифесте, совместимом с системой, вызов автоматически перенаправляется в параллельной сборке.
Замечания по безопасности
LOAD_LIBRARY_AS_DATAFILE не запрещает другим процессам изменять модуль во время загрузки. Так как это может сделать приложение менее безопасным, следует использовать LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE вместо LOAD_LIBRARY_AS_DATAFILE при загрузке модуля в виде файла данных, если вам не нужно использовать LOAD_LIBRARY_AS_DATAFILE. Указание LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE запрещает другим процессам изменять модуль во время загрузки. Не указывайте LOAD_LIBRARY_AS_DATAFILE и LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE в том же вызове.Не используйте функцию SearchPath для получения пути к библиотеке DLL для последующего вызова LoadLibraryEx. Функция searchPath SearchPath использует другой порядок поиска, отличный от LoadLibraryEx, и он не использует режим безопасного поиска процессов, если только это не включено явным образом путем вызова SetSearchPathMode с BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE. Таким образом, SearchPath, скорее всего, сначала выполните поиск текущего рабочего каталога пользователя для указанной библиотеки DLL. Если злоумышленник скопировал вредоносную версию библиотеки DLL в текущий рабочий каталог, путь, полученный SearchPath будет указывать на вредоносную библиотеку DLL, которая LoadLibraryEx будет загружена.
Не предполагайте версию операционной системы на основе вызова loadLibrary Ex
Общие сведения о проблемах с безопасностью библиотеки DLL см. в разделе Dynamic-Link Безопасность библиотеки.
Примеры
В следующем примере кода показан вызов LoadLibraryExA.
//Load the FMAPI DLL
hLib = ::LoadLibraryEx(L"fmapi.dll", NULL, NULL);
if ( !hLib )
{
wprintf(L"Could not load fmapi.dll, Error #%d.\n", GetLastError());
return;
}
Дополнительные примеры см. в
Заметка
Заголовок libloaderapi.h определяет LoadLibraryEx как псевдоним, который автоматически выбирает версию ANSI или Юникод этой функции на основе определения константы препроцессора ЮНИКОДа. Сочетание использования псевдонима, нейтрального для кодирования, с кодом, не зависящим от кодирования, может привести к несоответствиям, которые приводят к ошибкам компиляции или среды выполнения. Дополнительные сведения см. в соглашениях о прототипах функций.
Требования
Требование | Ценность |
---|---|
минимальные поддерживаемые клиентские | Windows XP [только классические приложения] |
минимальный поддерживаемый сервер | Windows Server 2003 [только классические приложения] |
целевая платформа | Виндоус |
заголовка | libloaderapi.h (включая Windows.h) |
библиотеки |
Kernel32.lib |
DLL | Kernel32.dll |
См. также
Функции библиотеки Dynamic-Link
порядка поиска библиотеки
безопасности библиотеки