LoadLibrary函数详细说明

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xinqingwuji/article/details/78597439

将指定的模块加载到调用进程的地址空间中。指定的模块可能会导致其他模块被加载。对于其他加载选项,请使用 LoadLibraryEx函数。
使用语法
C ++

HMODULE WINAPI LoadLibrary(
  _In_ LPCTSTR lpFileName
);

参数

lpFileName [in]
模块的名称。这可以是库模块(.dll文件)或可执行模块(.exe文件)。指定的名称是模块的文件名,与模块定义(.def)文件中的LIBRARY关键字所指定的与库模块本身中存储的名称无关。
如果字符串指定完整路径,则该函数仅搜索该模块的路径。
如果字符串指定一个没有路径的模块名称或者相对路径,则该函数使用标准搜索策略来查找模块;
如果该功能找不到该模块,则该功能失败。指定路径时,一定要使用反斜杠(\),而不是正斜杠(/)。

如果字符串指定了没有路径的模块名称,并且省略了文件扩展名,则函数会将缺省库扩展名.dll附加到模块名称。要防止函数将.dll附加到模块名称,请在模块名称字符串中包含尾随点字符(.)。


返回值

如果函数成功,则返回值是模块的句柄。

如果函数失败,则返回值为NULL。要获得扩展错误信息,请调用 GetLastError。


备注

要在DLL加载期间启用或禁用加载器显示的错误消息,请使用 SetErrorMode函数。
LoadLibrary可用于将库模块加载到进程的地址空间中,并返回可在GetProcAddress中使用的句柄 以获取DLL函数的地址。 LoadLibrary也可以用来加载其他可执行模块。例如,该函数可以指定一个.exe文件来获取可以在FindResource或 LoadResource中使用的 句柄。但是,不要使用 LoadLibrary运行.exe文件。而是使用CreateProcess函数。

如果指定的模块是一个尚未为调用进程加载的DLL,则系统将使用DLL_PROCESS_ATTACH值调用DLL的DllMain函数 。如果 DllMain返回TRUE,则 LoadLibrary将返回模块的句柄。如果 DllMain返回FALSE,则系统从进程地址空间卸载DLL,并且 LoadLibrary返回NULL。


模块句柄不是全局的或可继承的。一个进程调用 LoadLibrary不会产生另一个进程可以使用的句柄 - 例如,调用 GetProcAddress。在调用GetProcAddress之前 ,另一个进程必须自己调用LoadLibrary。
如果lpFileName不包含路径,并且有多个具有相同基本名称和扩展名的已加载模块,则该函数将返回首先加载的模块的句柄。
如果在lpFileName参数中未指定文件扩展名,则会附加默认库扩展名.dll。但是,文件名称字符串可以包含尾随点字符(.),以指示模块名称没有扩展名。当没有指定路径时,函数搜索加载的模块,其基本名称与要加载的模块的基本名称相匹配。如果名称匹配,则加载成功。否则,该功能将搜索该文件。
搜索到的第一个目录是包含用于创建调用过程的映像文件的目录(有关更多信息,请参阅 CreateProcess函数)。这样做可以在不将进程的安装目录添加到PATH环境变量的情况下找到与进程关联的私有动态链接库(DLL)文件。如果指定了相对路径,则整个相对路径将附加到DLL搜索路径列表中的每个标记。要从相对路径加载模块而不搜索任何其他路径,请使用GetFullPathName获取非相对路径,并使用 非相对路径调用 LoadLibrary。有关DLL搜索顺序的更多信息,请参阅 动态链接库搜索顺序。
搜索路径可以使用SetDllDirectory函数进行更改 。建议使用此解决方案,而不是使用SetCurrentDirectory或硬编码DLL的完整路径。
如果指定了路径并且存在应用程序的重定向文件,则该函数将搜索应用程序目录中的模块。如果模块存在于应用程序的目录中,则 LoadLibrary将忽略指定的路径并从应用程序的目录加载该模块。如果模块不在应用程序的目录中,则 LoadLibrary将从指定的目录加载模块。有关更多信息,请参阅 动态链接库重定向。
如果使用程序集名称调用LoadLibrary而不指定路径,并且程序集列在系统兼容清单中,则调用会自动重定向到并行程序集。
系统在所有加载的模块上维护每个进程的引用计数。调用LoadLibrary会 增加引用计数。调用FreeLibrary或 FreeLibraryAndExitThread函数会减少引用计数。系统在其引用计数达到零或过程终止时(不管引用计数是多少)卸载模块。
Windows Server 2003和Windows XP:   Visual C ++编译器支持使您能够声明线程局部变量的语法: _declspec(thread)。如果在DLL中使用此语法,则无法在Windows Vista之前的Windows版本上使用LoadLibrary显式加载DLL 。如果您的DLL将被显式加载,则必须使用线程本地存储函数而不是_declspec(thread)。有关示例,请参阅 动态链接库中的使用线程本地存储。
安全备注
不要使用SearchPath函数为后续的LoadLibrary调用检索DLL的路径。该 SearchPath中的功能比使用不同的搜索顺序 调用LoadLibrary和不使用过程中的安全搜索模式,除非明确调用启用 SetSearchPathMode与 BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE。因此, SearchPath可能首先搜索用户的当前工作目录中指定的DLL。如果攻击者已经将恶意版本的DLL复制到当前工作目录中,则SearchPath将检索到该路径会指向恶意的DLL,LoadLibrary将会加载。

不要根据搜索DLL 的LoadLibrary调用对操作系统版本进行假设 。如果应用程序运行在DLL合法不存在,但恶意版本的DLL在搜索路径中的环境中,则可能会加载DLL的恶意版本。


最小支持的客户端
Windows XP [仅适用于桌面应用程序]
最低支持的服务器
Windows Server 2003 [仅适用于桌面应用程序]

Winbase.h(包括Windows.h)
图书馆
KERNEL32.LIB
DLL
KERNEL32.DLL
Unicode和ANSI名称
LoadLibraryW(Unicode)和LoadLibraryA(ANSI)
展开阅读全文

没有更多推荐了,返回首页