【Windows核心编程笔记】第二十章 DLL高级技术

本文深入探讨DLL模块的加载与卸载机制,包括LoadLibrary、FreeLibrary等API的使用,DLL_PROCESS_ATTACH/DLL_PROCESS_DETACH等通知的处理,以及延迟载入、函数转发器和DLL重定向等高级特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DLL模块的显示载入和符号链接

LoadLibrary/Ex      显示加载dll,映射到进程的地址空间

FreeLibrary    显示卸载dll

FreeLibraryAndExitThread   适用dll中创建线程的情况

 

同一进程中多次加载一个dll会递增使用计数

不同进程之间维护各自的dll使用计数

 

可以使用GetModuleHanle检测dll是否被映射到进程的地址空间

 

GetProcAddress 获取符号地址(对应函数)

第二个参数可以是函数名(ANSI,而不是UNICODE)或者序号

比如

GetProcAddress(hDll,”Func”);

GetProcAddress(hDll,MAKEINTRESOURCE(2));  虽然快,但是不建议用~

 

DLL的入口点函数

需要在dll中接收通知(用以进行初始化或者清理工作)时,可以实现入口函数,否则无需

 

DllMain 区分大小写~

 

避免在DllMain中调用LoadLibrary,循环依赖

 

DllMain应该执行简单初始化:设置线程局部存储区、创建内核对象、打开文件等,避免调用User、Shell、ODBC、COM、RPC以及套接字函数,因为他们可能尚未初始化完毕或者内部调用LoadLibrary

 

DLL_PROCESS_ATTACH通知:

只有第一次进程映射dll时才会触发此通知,之后的会增加dll的使用计数

此时DllMain的返回值表示初始化是否成功

 

DLL_PROCESS_DETACH通知:

Dll从进程空间撤销映射时触发此通知,执行与进程相关的清理工作

如果是因为进程中的一个线程调用FreeLibrary而撤销映射,此线程将执行DllMain中的代码,处理完此通知之前,线程不会返回

Dll可能阻止进程的终止,只有当每个dll处理完此通知之后,进程才会终止

TerminateProcess 不会触发此通知调用dll的DllMain,从而没有机会进行清理共工作,所以应该避免使用此函数终止进程

 

DLL_THREAD_ATTACH通知:

进程创建线程时,映射到此进程的所有dll文件,会触发此通知调用DllMain,执行线程相关的初始化,而之后映射的dll(在创建线程之后)不会再触发此通知

另外,主线程不会调用此通知

 

DLL_THREAD_DETACH通知:

ExitThread中止线程前会触发此通知执行与线程相关的清理工作

同理Dll可能会妨碍线程的终止,只有当每个dll处理完此通知,线程终止

同理TerminateThread尽量避免使用

 

由于DllMain的序列化调用,不要在DllMain中调用WaitForSingleObject

 

如果不提供自己的Dllmain,编译器会链接C/C++运行库的DllMain

 

延迟载入DLL

延迟载入dll是隐式链接,只有当我们引用其中符号时才会载入dll,而不是一开始就载入

延迟载入的dll可以被卸载

延迟载入可以得到通知或覆盖默认的行为

 

函数转发器

将一个函数调用转发到另一个dll中的另一个函数

#pragma comment(linker,”/export:func=Dll2.Func2”)

 

已知的DLL

系统对操作系统提供的某些dll进行了特殊处理,这些dll在同一个目录中,可以在注册表中查看:HCM\SYSTEM\CurrentControlSet\Control\Session Manager\KnowDlls

 

LoadLibrary加载前先判断后缀名是否有.dll,没有就正常规则搜索,有的话就先去掉再在KnowDlls中查找,找到加载,找不到按正常规则搜索

 

DLL重定向

强制操作系统的加载程序首先从程序的目录中载入模块,找不到再去其他目录找

XXXXXX.exe.local放到程序目录

这个特性对COM对象来说很有用

 

模块的基地址重定位

能够显著提高系统性能

ReBase.exe

ReBaseImage

 

模块的绑定

进一步提高性能~

用该模块导入的所有符号的虚拟地址对该模块的导入段进行预处理

Bind.exe

BindImageEx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值