当前位置: 首页 > news >正文

[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/), 谢谢。 <<

相关文章:

  • 那些开发中用到的模式——访问者模式
  • 浏览器的几个感悟
  • 本地配置 MongoDb
  • Symbian下获取GSM Cell信息
  • C# 操作MongoDb 错误Element '_v' does not match any field or property of class XXX
  • 双硬盘双系统WINDOWS XP Ubuntu 的启动设置
  • 使用github 配置bitbucket SSH
  • UltraWebGrid动态生成多表头
  • 服务品牌竞争:3G时代的第二战场
  • 使用attribute + 扩展方法完成 enum中field的信息映射
  • 什么是软件项目的成功
  • 在Asp.net MVC 使用bootstrap 的modal dialog 实现Popup
  • VS.NET中解决方案管理器中看不到解决方案节点的解决办法
  • MVC 中使用TreeView
  • .Net的DataSet直接与SQL2005交互
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • Android单元测试 - 几个重要问题
  • ECS应用管理最佳实践
  • HTTP--网络协议分层,http历史(二)
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Java多线程(4):使用线程池执行定时任务
  • Mybatis初体验
  • mysql中InnoDB引擎中页的概念
  • spring boot下thymeleaf全局静态变量配置
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • 服务器之间,相同帐号,实现免密钥登录
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 力扣(LeetCode)357
  • 浅谈web中前端模板引擎的使用
  • 使用common-codec进行md5加密
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 推荐一个React的管理后台框架
  • 线上 python http server profile 实践
  • 小试R空间处理新库sf
  • MyCAT水平分库
  • NLPIR智能语义技术让大数据挖掘更简单
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • #define用法
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • (04)odoo视图操作
  • (1)SpringCloud 整合Python
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (39)STM32——FLASH闪存
  • (52)只出现一次的数字III
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (力扣)循环队列的实现与详解(C语言)
  • (三)c52学习之旅-点亮LED灯
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转)用.Net的File控件上传文件的解决方案
  • (转载)虚函数剖析
  • ******IT公司面试题汇总+优秀技术博客汇总
  • .net MySql
  • .NET/C# 项目如何优雅地设置条件编译符号?