一、概述dllmain函数
DllMain是Windows中用于动态链接库(DLL)的主函数,是DLL在加载、卸载、附加和分离时被系统自动调用的入口点。DllMain是在DLL被装载或卸载时自动执行的。它可以用于在DLL被调用前和被调用后执行一些初始化或资源释放操作。
二、DllMain的原型和参数
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved);
DllMain函数的原型和参数如上所示,一般情况下,我们只需要使用第二个参数dwReason。
dwReason:
- DLL_PROCESS_ATTACH: 当 DLL 被进程装载成功时,系统将会调用 DllMain 函数,并将 dwReason 值设置为 DLL_PROCESS_ATTACH。
- DLL_PROCESS_DETACH: 当使用 FreeLibrary 卸载 DLL 后,系统将会调用 DllMain 函数,并将 dwReason 值设置为 DLL_PROCESS_DETACH。
- DLL_THREAD_ATTACH: 当一个进程创建一个新线程时,系统将会调用 DllMain 函数,并将 dwReason 值设置为 DLL_THREAD_ATTACH。
- DLL_THREAD_DETACH: 当一个线程结束(调用 ExitThread 函数或自动结束)时,系统将会调用 DllMain 函数,并将 dwReason 值设置为 DLL_THREAD_DETACH。
三、使用DllMain进行初始化操作
DllMain 是一个用于加载 DLL 时的初始化函数,我们可以在其中进行一些初始化操作。例如定义一些全局变量,初始化一些资源等。
#include<Windows.h> #include<iostream> using namespace std; BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: // 当 DLL 被加载成功时,执行初始化操作 cout << "DLL_PROCESS_ATTACH" << endl; break; case DLL_PROCESS_DETACH: // 当 DLL 被卸载时,执行资源释放操作 cout << "DLL_PROCESS_DETACH" << endl; break; } return TRUE; }
四、使用DllMain进行卸载操作
在DLL卸载时,我们也同样可以释放一些资源、清理一些变量等操作。
#include<Windows.h> #include<iostream> using namespace std; BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: cout << "DLL_PROCESS_ATTACH" << endl; break; case DLL_PROCESS_DETACH: cout << "DLL_PROCESS_DETACH" << endl; break; } return TRUE; } void ReleaseResource() { cout << "ReleaseResource" << endl; //Todo: some resource release } extern "C" __declspec(dllexport) void Uninstall() { ReleaseResource(); }
五、使用DllMain进行拦截操作
使用DllMain可以对特定函数进行拦截,将原有的函数 '替换' 为自己所写的函数,这在HOOK中非常常见。
#include<Windows.h> #include<iostream> using namespace std; BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: cout << "DLL_PROCESS_ATTACH" << endl; break; case DLL_PROCESS_DETACH: cout << "DLL_PROCESS_DETACH" << endl; break; } return TRUE; } extern "C" __declspec(dllexport) int add(int num1, int num2) { return num1 + num2 + 100; }
六、使用DllMain进行线程拦截
使用DllMain可以捕获新线程的创建请求,并进行一系列的操作。
#include<Windows.h> #include<iostream> using namespace std; BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: cout << "DLL_PROCESS_ATTACH" << endl; break; case DLL_PROCESS_DETACH: cout << "DLL_PROCESS_DETACH" << endl; break; case DLL_THREAD_ATTACH: cout << "DLL_THREAD_ATTACH" << endl; break; case DLL_THREAD_DETACH: cout << "DLL_THREAD_DETACH" << endl; break; } return TRUE; }
七、总结
本文主要介绍了DllMain函数的概念、原型和参数,详细阐述了使用DllMain进行初始化操作、卸载操作、拦截操作、线程拦截等操作方法,同时附上了相应的代码示例。