最简单的Windows Hook(钩子)介绍

 Hook是Windows操作系统的消息传递机制的重要组成部分。通过使用Hook,程序可以监视系统中其他进程的消息传递,并在该消息到达目的前对其进行处理。

注意,由于Hook可能访问其他进程的地址空间,故必要时应通过DLL实现。并且,全局Hook会降低系统的性能,应该尽量避免使用。

Windows为不同类型的消息提供了不同类型的Hook,并分别维护一个Hook链表。新创建的Hook将被放到链首,首先获得消息,并对其进行处理。但要注意,Hook不会自动将接收到的消息传递给链表上的下一Hook,需要在代码中显式声明。

下面看看Hook的一般使用顺序:
1、使用SetWindowsHookEx在特定Hook链首添加一个新Hook。
2、相应消息传递到SetWindowsHookEx说明的函数,并由其进行处理。该函数的原型必须为:
LRESULT CALLBACK HookProc{
  int nCode,
  WPARAM wParam,
  LPARAM lParam
};
3、在HookProc处理消息后,可以选择使用CallNextHookEx将该消息传递给链表中的下一个节点进行处理。
4、在完成Hook的使用后,用函数UnhookWindowsHookEx将其撤销。

现在来看看Windows支持的几种常用的Hook类型。
WH_CALLWNDPROC:捕获传递给窗口的消息。
WH_CBT:窗口创建、销毁、激活、最大最小化、移动、缩放,系统调用,鼠标、键盘事件等,几乎包括了所有的基本操作。
WH_GETMESSAGE:捕获使用GetMessage或PeekMessage传递的消息。
WH_KEYBOARD:捕获GetMessage或PeekMessage传递的WM_KEYDOWN或WM_KEYUP消息。
WH_MOUSE:捕获GetMessage或PeekMessage传递的鼠标相关消息。
WH_MSGFILTER和WH_SYSMSGFILTER:捕获应该由Windows标准控件处理的局部和全局消息。

Hook的基本情况就介绍到这里。最后,我再给出一段Hook的代码,用于监控键盘消息(代码用C++编写,在Windows XP SP2下调试通过)。

// DLL
#include <windows.h>
#include <strsafe.h>

#ifdef  __cplusplus
#define  EXPORT extern "C" __declspec (dllexport)
#else
#define  EXPORT __declspec (dllexport)
#endif

HHOOK hHook;
HINSTANCE hInst;

EXPORT LRESULT __stdcall KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
EXPORT void __stdcall InitHook();

int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
 MessageBox(NULL, "DLL init succeeded!", "Message", MB_ICONINFORMATION || MB_OK);
 hInst=hInstance;
 return TRUE ;
}

EXPORT void __stdcall FreeHook()
{
 if (!UnhookWindowsHookEx(hHook))
  MessageBox(NULL, "UnhookWindowsHookEx() failed!", "Error", 0x10);
}

EXPORT void __stdcall InitHook()
{
 hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInst, NULL);
 if (hHook == NULL)
  MessageBox(NULL, "SetWindowsHookEx() failed!", "Error", 0x10);
}

EXPORT LRESULT __stdcall KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
 if (nCode < 0)
  return CallNextHookEx(hHook, nCode, wParam, lParam);
 if (nCode == HC_NOREMOVE)
  MessageBox(NULL, "Message hasn't been removed!", "Message", MB_ICONINFORMATION || MB_OK);
 char buf[128];
 memset(buf, 0, 128);
 StringCchPrintf(buf, 128/sizeof(TCHAR), "KEYBOARD - nCode: %d, vk: %d", nCode, wParam);
 MessageBox(NULL, buf, "Message", MB_ICONINFORMATION || MB_OK);
 return CallNextHookEx(hHook, nCode, wParam, lParam);
}

这样,只需要再编写一段程序,调用这个DLL库里的初始化函数,并在调用结束后释放Hook就可以了。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值