钩子及其应用(一)

来源:互联网 发布:mimo app学编程下载 编辑:程序博客网 时间:2024/05/07 12:08

作者:  linzhenqun()

时间:  2005-10-6

Blog: http://blog.csdn.net/linzhengqun

-----------------------------------------------------------------------------------------------------

前言

这不是关于钩子的长篇大论,而更关注于其实际应用。

不过实践总要有理论作为基础。因此本文第一部分给出了关于钩子的基本理论。大部分都直接翻译于MSDN,大家如果有兴趣可以找MDSN中的Win32 Hooks这篇文章来看,非常详尽的说明了钩子的应用,再看看对于那些API的声明,基本就OK了。

第二部分给出一个实际的程序,关于宏的实现,从这部分可以学到钩子的具体应用。第三部分会给出一个简单的SPY程序,理解全局钩子的应用。

 

(一)基本理论

钩子是Windows中是一项非常有用的技术。钩子是这样的一种机制:它允许一个函数在事件(消息,鼠标动作,键盘)到达应用程序之前截获它们。该函数可以作用于事件,某些情况下,可以修改和丢弃它们。接收事件的函数称为过滤函数,它将依照所截获事件的类型来分类。例如,一个过滤函数可能想要接收所有的键盘和鼠标事件。Windows要调用一个过滤函数,该函数必须被安装到一个Windows 钩子(比如,一个键盘钩子)上面。如果一个钩子附带有多个过滤函数,Windows维护一个过滤函数的链,最近安装的函数在链的前面,最先安装的则在链的后面。

钩子有很多种,这里不能一一列出,其他可以看MSDN

  • WH_CALLWNDPROC

  • WH_CALLWNDPROCRET

  • WH_GETMESSAGE

  • WH_JOURNALPLAYBACK

  • WH_JOURNALRECORD

  • WH_KEYBOARD

  • WH_MOUSE

这些钩子分别对应于系统中不同的事件,我们的程序可以使用钩子做很多的事情,比如:

l          处理和修改系统中的所有消息,无论GetMessagePeekMessage何时被调用(WH_GETMESSAGE)

l          处理和修改所有消息,无论SendMessage何时被调用(WH_CALLWNDPROC)

l          记录和回放键盘和鼠标事件(WH_JOURNALRECORD, WH_JOURNALPLAYBACK)

l          处理,修改或移除键盘事件(WH_KEYBOARD)

l          处理,修改或丢弃鼠标事件(WH_MOUSE)

等等。

对于我们的程序,要使用钩子,将用到下面几个重要的API函数:

SetWindowsHook, UnhookWindowsHookCallNextHookExWindows使用这几个函数管理钩子的过滤函数链。下面我们将详细介绍:

SetWindowsHookEx

SetWindowsHookEx增加一个过滤函数到一个钩子中。该函数带有四个参数:

l         一个整型编码描述了那种过滤函数被附带上。这些码定义在WINUSER.H中。。

l         过滤函数的地址。在应用程序或DLL的模块定义文件中。

l         包含过滤函数的模块的实例句柄。

l         钩子被安装到某个线程的线程ID,如果线程ID不为零,安装了的过滤函数将只在特定线程的上下文中被调用。如果线程ID为空,则线程将在系统范围内或任何的线程上下文中被调用。一个库或应用程序可以使用GetCurrentThreadId获得当前线程ID

SetWindowsHookEx返回安装的钩子的句柄(HHook), 程序在随后调用UnhookWindowsHookEx时要使用该句柄。

SetWindowsHookEx也返回一个值标识为什么调用失败,可以查看MSDN

 

UnhookWindowsHookEx

要从一个钩子链中移除一个过滤函数,调用UnhookWindowsHookEx。该函数需要从SetWindowsHookEx中返回的句柄作为参数,并返回一个值以确定钩子是否删除。

 

过滤函数

钩子过滤函数是被附带到钩子的函数。过滤函数是由系统而不是由程序调用。

所有过滤函数必须有如下的形式:

LRESULT CALLBACK FilterFunc( nCode, wParam, lParam )

int nCode;

WORD wParam;

DWORD lParam;

所有过滤函数都返回一个LONG值。FilterFunc只是实际的过滤函数名的一个符号。

 

参数

过滤函数接收三个参数:nCode wParamtlParamnCode是一个整值,它通知过滤函数任何应该知道附加数据。

Windows传递一个负值的nCode给过滤函数时,应该调用CallNextHookEx并传递三个过滤函数的参数。过滤函数也必须返回CallNextHookEx返回的值。

第二个传递给过滤函数的参数,一个WPARAM类型,而第三个参数是LPARAM类型。这些参数传递过滤函数需要的信息。wParamlParam对不同的钩子意义不同。

钩子

过滤函数

WH_CALLWNDPROC

CallWndProc

WH_GETMESSAGE

GetMsgProc

WH_JOURNALRECORD

JournalRecordProc

WH_JOURNALPLAYBACK

JournalPlaybackProc

WH_KEYBOARD

KeyboardProc

WH_MOUSE

MouseProc

WH_CALLWNDPROCRET

CallWndRetProc

其本质的差别就在于函数带的参数表示的意义。可以根据函数名查阅MSDN,以获得更详尽的描述。