天天看點

[Windows程式設計] 監視DLL裝載/解除安裝

Windows 驅動開發庫裡面提供了函數 LdrRegisterDllNotification , LdrUnregisterDllNotification , 可以讓你監視程序裝載/解除安裝DLL 的事件。 當你想在某個DLL被加載的時候Hook它的函數; 或者當你想在某個DLL推出之前做一些儲存清理工作; 或者當你想阻止某個DLL 被加載(比如外挂) .... 這個機制正可以派上用場 。

以下是代碼示例如何使用 LdrRegisterDllNotification , LdrUnregisterDllNotification 監聽DLL裝載/解除安裝。

 view plaincopy to clipboardprint?

#include <Ntsecapi.h> // DDK   

typedef const UNICODE_STRING* PCUNICODE_STRING;   

typedef struct _LDR_DLL_LOADED_NOTIFICATION_DATA {   

    ULONG Flags;                    //Reserved.   

    PCUNICODE_STRING FullDllName;   //The full path name of the DLL module.   

    PCUNICODE_STRING BaseDllName;   //The base file name of the DLL module.   

    PVOID DllBase;                  //A pointer to the base address for the DLL in memory.   

    ULONG SizeOfImage;              //The size of the DLL image, in bytes.   

} LDR_DLL_LOADED_NOTIFICATION_DATA, *PLDR_DLL_LOADED_NOTIFICATION_DATA;   

typedef struct _LDR_DLL_UNLOADED_NOTIFICATION_DATA {   

} LDR_DLL_UNLOADED_NOTIFICATION_DATA, *PLDR_DLL_UNLOADED_NOTIFICATION_DATA;   

typedef union _LDR_DLL_NOTIFICATION_DATA {   

    LDR_DLL_LOADED_NOTIFICATION_DATA Loaded;   

    LDR_DLL_UNLOADED_NOTIFICATION_DATA Unloaded;   

} LDR_DLL_NOTIFICATION_DATA, *PLDR_DLL_NOTIFICATION_DATA;   

typedef const PLDR_DLL_NOTIFICATION_DATA PCLDR_DLL_NOTIFICATION_DATA;   

typedef VOID (NTAPI *PLDR_DLL_NOTIFICATION_FUNCTION)(ULONG NotificationReason, PCLDR_DLL_NOTIFICATION_DATA NotificationData, PVOID Context);   

typedef NTSTATUS (NTAPI *pfnLdrRegisterDllNotification)(ULONG Flags, PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction, void* Context, void **Cookie);   

typedef NTSTATUS (NTAPI *pfnLdrUnregisterDllNotification)(void *Cookie);   

#define LDR_DLL_NOTIFICATION_REASON_LOADED 1    

#define LDR_DLL_NOTIFICATION_REASON_UNLOADED 2   

VOID NTAPI MyLdrDllNotification(   

  ULONG NotificationReason,   

  PCLDR_DLL_NOTIFICATION_DATA NotificationData,   

  PVOID Context   

)   

{   

    switch (NotificationReason)   

    {   

    case LDR_DLL_NOTIFICATION_REASON_LOADED:   

        printf ("Dll Loaded: %S\n", NotificationData->Loaded.FullDllName->Buffer);   

        break;   

    case LDR_DLL_NOTIFICATION_REASON_UNLOADED:   

        printf ("Dll Unloaded: %S\n", NotificationData->Unloaded.FullDllName->Buffer);   

    }   

}   

int _tmain(int argc, _TCHAR* argv[])   

    HMODULE hModule = GetModuleHandleW(L"NTDLL.DLL");   

         // 取得函數指針   

    pfnLdrRegisterDllNotification pLdrRegisterDllNotification = (pfnLdrRegisterDllNotification)GetProcAddress(hModule, "LdrRegisterDllNotification");   

    pfnLdrUnregisterDllNotification pLdrUnregisterDllNotification = (pfnLdrUnregisterDllNotification)GetProcAddress(hModule, "LdrUnregisterDllNotification");   

    void *pvCookie = NULL;   

         // 初始化   

    pLdrRegisterDllNotification(0, MyLdrDllNotification, NULL, &pvCookie);   

    // 測試DLL 裝載   

    HMODULE hLoad = ::LoadLibraryW(L"mshtml.dll");   

    Sleep(1000);   

         // 測試 DLL 解除安裝   

    ::FreeLibrary(hLoad);   

         // 清除   

    if (pvCookie)   

        pLdrUnregisterDllNotification(pvCookie);   

        pvCookie = NULL;   

    return 0;   

}  

#include <Ntsecapi.h> // DDK

typedef const UNICODE_STRING* PCUNICODE_STRING;

typedef struct _LDR_DLL_LOADED_NOTIFICATION_DATA {

    ULONG Flags;                    //Reserved.

    PCUNICODE_STRING FullDllName;   //The full path name of the DLL module.

    PCUNICODE_STRING BaseDllName;   //The base file name of the DLL module.

    PVOID DllBase;                  //A pointer to the base address for the DLL in memory.

    ULONG SizeOfImage;              //The size of the DLL image, in bytes.

} LDR_DLL_LOADED_NOTIFICATION_DATA, *PLDR_DLL_LOADED_NOTIFICATION_DATA;

typedef struct _LDR_DLL_UNLOADED_NOTIFICATION_DATA {

} LDR_DLL_UNLOADED_NOTIFICATION_DATA, *PLDR_DLL_UNLOADED_NOTIFICATION_DATA;

typedef union _LDR_DLL_NOTIFICATION_DATA {

    LDR_DLL_LOADED_NOTIFICATION_DATA Loaded;

    LDR_DLL_UNLOADED_NOTIFICATION_DATA Unloaded;

} LDR_DLL_NOTIFICATION_DATA, *PLDR_DLL_NOTIFICATION_DATA;

typedef const PLDR_DLL_NOTIFICATION_DATA PCLDR_DLL_NOTIFICATION_DATA;

typedef VOID (NTAPI *PLDR_DLL_NOTIFICATION_FUNCTION)(ULONG NotificationReason, PCLDR_DLL_NOTIFICATION_DATA NotificationData, PVOID Context);

typedef NTSTATUS (NTAPI *pfnLdrRegisterDllNotification)(ULONG Flags, PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction, void* Context, void **Cookie);

typedef NTSTATUS (NTAPI *pfnLdrUnregisterDllNotification)(void *Cookie);

#define LDR_DLL_NOTIFICATION_REASON_LOADED 1 

#define LDR_DLL_NOTIFICATION_REASON_UNLOADED 2

VOID NTAPI MyLdrDllNotification(

  ULONG NotificationReason,

  PCLDR_DLL_NOTIFICATION_DATA NotificationData,

  PVOID Context

)

{

 switch (NotificationReason)

 {

 case LDR_DLL_NOTIFICATION_REASON_LOADED:

  printf ("Dll Loaded: %S\n", NotificationData->Loaded.FullDllName->Buffer);

  break;

 case LDR_DLL_NOTIFICATION_REASON_UNLOADED:

  printf ("Dll Unloaded: %S\n", NotificationData->Unloaded.FullDllName->Buffer);

 }

}

int _tmain(int argc, _TCHAR* argv[])

 HMODULE hModule = GetModuleHandleW(L"NTDLL.DLL");

         // 取得函數指針

 pfnLdrRegisterDllNotification pLdrRegisterDllNotification = (pfnLdrRegisterDllNotification)GetProcAddress(hModule, "LdrRegisterDllNotification");

 pfnLdrUnregisterDllNotification pLdrUnregisterDllNotification = (pfnLdrUnregisterDllNotification)GetProcAddress(hModule, "LdrUnregisterDllNotification");

 void *pvCookie = NULL;

         // 初始化

 pLdrRegisterDllNotification(0, MyLdrDllNotification, NULL, &pvCookie);

 // 測試DLL 裝載

 HMODULE hLoad = ::LoadLibraryW(L"mshtml.dll");

 Sleep(1000);

         // 測試 DLL 解除安裝

 ::FreeLibrary(hLoad);

         // 清除

 if (pvCookie)

  pLdrUnregisterDllNotification(pvCookie);

  pvCookie = NULL;

 return 0;

運作程式, 輸出如下。可以證明以上代碼監聽了 mshtml.dll 的裝載和解除安裝。 而且系統自動裝載的其他DLL也被監視到。

Dll Loaded: C:\Windows\system32\mshtml.dll

Dll Loaded: C:\Windows\system32\msls31.dll

Dll Loaded: C:\Windows\system32\VERSION.dll

Dll Unloaded: C:\Windows\system32\mshtml.dll

Dll Unloaded: C:\Windows\system32\VERSION.dll

Dll Unloaded: C:\Windows\system32\msls31.dll

 本文轉自 陳本峰 51CTO部落格,原文連結:http://blog.51cto.com/wingeek/274017,如需轉載請自行聯系原作者

繼續閱讀