[Windows编程] 监视DLL装载/卸载

Windows 驱动开发库里面提供了函数 LdrRegisterDllNotification , LdrUnregisterDllNotification , 可以让你监视进程装载/卸载DLL 的事件。 当你想在某个DLL被加载的时候Hook它的函数; 或者当你想在某个DLL推出之前做一些保存清理工作; 或者当你想阻止某个DLL 被加载(比如外挂) .... 这个机制正可以派上用场 。

 

 

以下是代码示例如何使用 LdrRegisterDllNotification , LdrUnregisterDllNotification 监听DLL装载/卸载。

 

 #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 { 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_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); break; } } 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

 

 

>> 原创文章的版权属于作者,转载请注明出处和作者信息(http://blog.csdn.net/WinGeek/), 谢谢。 <<

 

 

你可能感兴趣的:(编程,windows,String,struct,function,dll)