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

SetWindowsHookEx实现过程

实现过程

如果创建的是全局钩子,那么钩子函数必须在一个DLL中。这是因为进程的地址空间是独立的,发生对应事件的进程不能调用其他进程地址空间的钩子函数。如果钩子函数的实现代码在DLL中,则在对应事件发生时,系统会把这个DLL加载到发生事件的进程地址空间中,使它能够调用钩子函数进行处理。

在操作系统中安装全局钩子后,只要进程接收到可以发出钩子的消息,全局钩子的DLL文件就会由操作系统自动或强行地加载到该进程中。因此,设置全局钩子可以达到DLL注入的目的。创建一个全局钩子后,在对应事件发生的时候,系统就会把DLL加载到发生事件的进程中,这样,便实现了DLL注入。

为了能够让DLL注入到所有的进程中,程序设置WH_GETMESSAGE消息的全局钩子。因为WH_GETMESSAGE类型的钩子会监视消息队列,并且Windows系统是基于消息驱动的,所有进程都会有自己的一个消息队列,都会加载WH_GETMESSAGE类型的全局钩子DLL

// 设置全局钩子
BOOL SetGlobalHook()
{g_hHook = ::SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc,g_hDllModule, 0);if (NULL == g_hHook){return FALSE;}return TRUE;
}

在上述代码中,SetWindowsHookEx的第一个参数表示钩子的类型,WH_GETMESSAGE表示安装消息队列的消息钩子,它可以监视发送到消息队列的消息。第二个参数表示钩子回调函数,尽管回调函数的名称可以是任意的,但是函数参数和返回值的数据类型是固定的。第三个参数表示包含钩子回调函数的DLL模块句柄,如果要设置全局钩子,则该参数必须指定DLL模块句柄。第四个参数表示与钩子关联的线程ID,0表示为全局钩子,它关联所有线程。返回值是钩子的句柄,这个值需要保存,因为回调钩子函数以及卸载钩子都需要用到该句柄作为参数。

当成功设置全局钩子之后,只有进程有消息发送到消息队列中,系统才会自动将指定的DLL模块加载到进程中,实现DLL注入。

// 钩子回调函数
LRESULT GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
{return ::CallNextHookEx(g_hHook, code, wParam, lParam);
}

回调函数的参数和返回值的数据类型是固定的。其中,CallNextHookEx函数表示将当前钩子传递给钩子链中的下一个钩子,第一个参数要指定当前钩子的句柄。如果直接返回0,则表示中断钩子传递,对钩子进行拦截。

// 卸载钩子
BOOL UnsetGlobalHook()
{if (g_hHook){::UnhookWindowsHookEx(g_hHook);}return TRUE;
}

UnsetGlobalHook函数用来卸载指定钩子,参数便是卸载钩子的句柄。卸载成功后,所有加载了全局钩子DLL模块的进程,都会释放该DLL模块

总结

主要通过调用SetWindowsHookEx函数设置全局钩子,完成DLL注入。通过调用CallNextHookEx函数传递钩子,使得进程继续运行。通过调用UnhookWindowsHookEx函数卸载钩子,实现DLL释放。在调用SetWindowsHookEx函数设置全局钩子的时候,一定要将钩子回调函数编写在DLL模块中,并指定该DLL模块的句柄。在DLL中利用#pragma data_seg指令创建共享内存,加载该DLL的进程,共享内存。只要一个进程修改了内存中的数据,则其他进程对应内存的数据也会改变。

http://www.lryc.cn/news/2417922.html

相关文章:

  • 美拍解析去水印原理,sign签名算法,获得无水印播放地址
  • Win10/11系统修复不求人,FixWin11.1系统修复小工具。
  • 龙将加速浏览器_《命运2》“凌光之刻”各版本内容介绍,迅游加速流畅开玩全新DLC...
  • BUUCTF 每日打卡 2021-7-18
  • 巨丝滑 —— 自己动手撸一个图片编辑器(支持长图)
  • 2020年有寓意的领证日期_2020有寓意的领证日期 2020热门领证日期
  • 8小时理解go - 基本语法
  • PC端分享至QQ空间、新浪、微信
  • PHP实现Trim函数功能(附完整源码)
  • .net core 请求外部接口;ABP HttpClientFactory的使用
  • vuex结合mixin在实际项目中的使用(超详细)
  • 前端缓存详解
  • 学习记录333@MySQL问题之server name is already exists解决方案
  • kernel panic 分析解决方法
  • 基于Java游戏论坛平台设计和实现(源码+LW+调试文档+讲解等)
  • Picasa生成图片幻灯片页面图文教程
  • Java集合详解(超详细)
  • 什么是CSharp
  • c语言常量详细解释及简单应用
  • 入门MySQL--0基础,操作详图,简单易懂
  • CDB(ContainerDatabase)与PDB(PluggableDatabase)
  • 【EVPN】EVPN名词简介
  • java环境变量详解_JAVA环境变量配置详解
  • php中file_get_contents如何读取大容量文件
  • 为什么下载的.msi安装文件打不开、运行不了?用mysql的.msi安装文件为例
  • 学习使用Python执行P4操作
  • 8Uftp连接服务器错误
  • 自学电脑编程_有哪些高质量的自学网站
  • javaSE(完整版)
  • 精进不休丨MogDB 数据库预读特性进一步提升20%+查询性能