您的位置:

从多个方面详细阐述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进行初始化操作、卸载操作、拦截操作、线程拦截等操作方法,同时附上了相应的代码示例。