一、概述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進行初始化操作、卸載操作、攔截操作、線程攔截等操作方法,同時附上了相應的代碼示例。
原創文章,作者:FIPUD,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/334764.html