如果钩子函数定义于当前进程相关的线程中,则钩子函数只能处理当前进程的线程的消息,如果要想处理当前正在运行的所有进程的鼠标消息和键盘消息,那么安装钩子函数的代码必须实现在动态链接库中。所以如果想让安装的钩子过程与所有进程相关,则应该讲SetWindowsHookEx函数的第四个参数设置为0,第三个参数hMod设置为安装钩子函数的代码所在的DLL的句柄。

  下面是创建全局钩子的步骤:

  1 创建一个名为GloabHookMFC的MFCDLL工程。

  2 在GlobalHookMFC.cpp的开头声明钩子函数句柄、DLL模块句柄和窗口句柄

  

#pragma data_seg(".SHARDAT")
static HHOOK m_hMouseHook = NULL; //鼠标钩子句柄
static HHOOK m_hKeyBoardHook = NULL; //键盘钩子句柄
HWND  g_hWnd = NULL; //窗口句柄
#pragma data_seg()
HINSTANCE hInstanceHandle; //DLL模块句柄

  当DLL被多个进程使用时,这些进程可以共享DLL的代码和数据。因此在GloabHookMFC中定义了全局句柄变量g_hWnd,这个应该是被所有进程所共享的。#pragma data_seg(".SHARDAT")是在此DLL中创建一个节,此节为共享节,将g_hWnd放入其中能让此全部变量被多进程所共享。“.SHARDAT”是这个节的名称,这个字符串的最大长度限制为8字节,如果超过8个,系统自动截断为8个。一个新节的定义的最后必须以#pragma data_seg()结束,表明新节的结尾。需要注意的是,节中的变量必须初始化。

  

  3 在 CGlobalHookMFCApp::InitInstance()中获取当前DLL模块的句柄

//获取DLL的句柄
hInstanceHandle = AfxGetInstanceHandle();

  4 实现钩子函数

//鼠标钩子函数
LRESULT CALLBACK MouseProc( int nCode, WPARAM wParam, LPARAM lParam )
{
...
} //键盘钩子函数
LRESULT CALLBACK KeyBoardProc( int nCode, WPARAM wParam, LPARAM lParam )
{
...
}

  

  5 添加钩子

extern "C" _declspec(dllexport) BOOL SetMouseHook( )
{
if (hInstanceHandle == NULL)
return FALSE; m_hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, hInstanceHandle,);
if (m_hMouseHook)
return TRUE;
else
return FALSE; } extern "C" _declspec(dllexport) BOOL SetKeyboardHook()
{
if (hInstanceHandle == NULL)
return FALSE; m_hKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, KeyBoardProc, hInstanceHandle,); if (m_hKeyBoardHook)
return TRUE;
else
return FALSE;
} extern "C" _declspec(dllexport) BOOL StartAllHook(HWND hwnd)
{
g_hWnd = hwnd;
return SetMouseHook() && SetKeyboardHook();
}

  

  6 卸载钩子

  

extern "C" _declspec(dllexport) BOOL StopMouseHook()
{
return UnhookWindowsHookEx( m_hMouseHook );
} extern "C" _declspec(dllexport) BOOL StopKeyHook()
{
return UnhookWindowsHookEx(m_hKeyBoardHook);
} extern "C" _declspec(dllexport) BOOL StopAllHook()
{
return StopKeyHook() && StopMouseHook();
}

  7 编译生成GlobalHookMFC.DLL。

8 我们在新建一个基于对话框的MFC工程GlobalHookTestDlg。在其头文件GlobalHookTestDlg.h中加入

#pragma  comment(lib, "GlobalHookMFC.lib")
extern "C" _declspec(dllimport) BOOL StopAllHook();
extern "C" _declspec(dllimport) BOOL StartAllHook( HWND hwnd);

9 在BOOL CGlobalHookTestDlg::OnInitDialog()中添加钩子

BOOL CGlobalHookTestDlg::OnInitDialog()
{
... // TODO: 在此添加额外的初始化代码
if (StartAllHook(GetSafeHwnd()))
MessageBox(_T("全局钩子启动成功"),NULL, MB_OK);
else
MessageBox(_T("全局钩子启动失败"),NULL, MB_OK); return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}

  10 在CGlobalHookTestDlg::OnSysCommand()中卸载钩子

  

void CGlobalHookTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
...
StopAllHook();
}

  编译运行后,当我们双击右键的时候会弹出显示当前窗口名称的对话框,当我们敲击键盘时候会弹出显示当前按下键的对话框。结束之后一定要记得卸载钩子。

HOOK函数(二)——全局HOOK的更多相关文章

  1. [PyTorch 学习笔记] 5.2 Hook 函数与 CAM 算法

    本章代码: https://github.com/zhangxiann/PyTorch_Practice/blob/master/lesson5/hook_fmap_vis.py https://gi ...

  2. Android so注入(inject)和Hook技术学习(二)——Got表hook之导入表hook

    全局符号表(GOT表)hook实际是通过解析SO文件,将待hook函数在got表的地址替换为自己函数的入口地址,这样目标进程每次调用待hook函数时,实际上是执行了我们自己的函数. GOT表其实包含了 ...

  3. 简单全局HOOK拦截大部分键盘消息

    前言:学习HOOK中,万一老师讲解HOOK入门教程:http://www.cnblogs.com/del/category/124150.html http://www.cnblogs.com/del ...

  4. 利用Objective-C运行时hook函数的三种方法

    版权声明:转载请注明出处:http://blog.csdn.net/hursing 方法一,hook已有公开头文件的类: 首先写一个Utility函数: #import <objc/runtim ...

  5. 利用Cydia Substrate进行Android HOOK(二)

    在前面关于Substrate的介绍中我们已经讲了用Substrate hook java代码,现在我们讲下怎么用它hook native代码.hook native代码我们需要编写Substrate ...

  6. HOOK函数(一)——进程内HOOK

    什么是HOOK呢?其实很简单,HOOK就是对Windows消息进行拦截检查处理的一个函数.在Windows的消息机制中,当用户产生消息时,应用程序通过调用GetMessage函数取出消息,然后把消息放 ...

  7. HOOK API(二)—— HOOK自己程序的 MessageBox

    HOOK API(二) —— HOOK自己程序的 MessageBox 0x00 前言 以下将给出一个简单的例子,作为HOOK API的入门.这里是HOOK 自己程序的MessageBox,即将自己程 ...

  8. 插件开发之360 DroidPlugin源码分析(二)Hook机制

    转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52124397 前言:新插件的开发,可以说是为插件开发者带来了福音,虽然还很多坑要填补, ...

  9. HOOK API(二) —— HOOK自己程序的 MessageBox

    转载来源:https://www.cnblogs.com/hookjc/ 0x00 前言 以下将给出一个简单的例子,作为HOOK API的入门.这里是HOOK 自己程序的MessageBox,即将自己 ...

随机推荐

  1. 尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。

    从10G开始,Oracle提供了一个较为轻量级的客户包,叫做Instant Client. 将它安装好后,就不用再安装庞大的Oracle Client了. 这样一来,只要客户端下载Instant Cl ...

  2. Class.forName()数据库驱动

    在学习jdbc中,用到Class.forName(驱动);,当时学习的时候知道Class.forName就是加载一个类到虚拟机,在加载一个类的时候,这个类的信息会被放到一个方法区,一个CLass 在J ...

  3. 集成电路中的assert和deassert应该如何翻译?

    转载自:http://m.blog.csdn.net/blog/code_robot/37663085 我每次看到电路中的assert与deassert时,总是感觉别扭,因为词典翻译总是"断 ...

  4. POJ2891 - Strange Way to Express Integers(模线性方程组)

    题目大意 求最小整数x,满足x≡a[i](mod m[i])(没有保证所有m[i]两两互质) 题解 中国剩余定理显然不行....只能用方程组两两合并的方法求出最终的解,刘汝佳黑书P230有讲~~具体证 ...

  5. php5.5 yum源

    PHP官网在下载页面中只有源代码下载,当然使用编译安装也是可以的,但是使用二进制包安装会非常快速.虽然PHP官网没有提供二进制安装包,但是它推荐了两个第三方的YUM源(CentOS中默认的YUM安装的 ...

  6. Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Discuz!

    Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Disc ...

  7. gridview合并单元格

    记录用,以前写过,忘记了转自:http://marss.co.ua/MergingCellsInGridView.aspx public class GridDecorator { public st ...

  8. MyCat集群部署(HAProxy + MyCat)

    本文档内容的依赖龙果学院<基于Dubbo的分布式系统架构实战>课程 二.软件版本 操作系统:CentOS-6.6-x86_64 JDK版本:jdk1.7.0_72 HAProxy版本:ha ...

  9. oc学习之路----QQ聊天界面

    用到的技术:自定义cell,通知机制,代理模式 transform 1.自定义cell(通过代码自定义cell) ①首先新建一个类继承UITableViewCell ②重写initWithStyle: ...

  10. 13 引用WINAPI

            [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWind ...