從多個方面詳細闡述dllmain

一、概述dllmain函數

DllMain是Windows中用於動態鏈接庫(DLL)的主函數,是DLL在加載、卸載、附加和分離時被系統自動調用的入口點。DllMain是在DLL被裝載或卸載時自動執行的。它可以用於在DLL被調用前和被調用後執行一些初始化或資源釋放操作。

二、DllMain的原型和參數

BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved);

DllMain函數的原型和參數如上所示,一般情況下,我們只需要使用第二個參數dwReason。

dwReason:

  1. DLL_PROCESS_ATTACH: 當 DLL 被進程裝載成功時,系統將會調用 DllMain 函數,並將 dwReason 值設置為 DLL_PROCESS_ATTACH。
  2. DLL_PROCESS_DETACH: 當使用 FreeLibrary 卸載 DLL 後,系統將會調用 DllMain 函數,並將 dwReason 值設置為 DLL_PROCESS_DETACH。
  3. DLL_THREAD_ATTACH: 當一個進程創建一個新線程時,系統將會調用 DllMain 函數,並將 dwReason 值設置為 DLL_THREAD_ATTACH。
  4. 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-hant/n/334764.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
FIPUD的頭像FIPUD
上一篇 2025-02-05 13:05
下一篇 2025-02-05 13:05

相關推薦

發表回復

登錄後才能評論