Hook function tutorial (1) What is a hook
1. What is a hook
2. A more professional technical understanding of hooks
Hook is a platform of the Windows message processing mechanism. An application can set a subroutine on it to monitor a certain message of a specified window, and the monitored window can be created by other processes. When the message arrives, it is processed before the target window handler function. The hook mechanism allows applications to intercept and process window messages or specific events.
The Windows system is built on an event-driven mechanism. To put it bluntly, the entire system is implemented through message passing. The hook is a very important system interface in the Windows system. It can be used to intercept and process messages sent to other applications to complete functions that are difficult for ordinary applications to achieve. Hooks can monitor various event messages in the system or process, intercept and process messages sent to the target window. In this way, we can install custom hooks in the system, monitor the occurrence of specific events in the system, and complete specific functions, such as intercepting keyboard and mouse input, taking words from the screen, log monitoring, and so on. It can be seen that many special and useful functions can be realized by using hooks.
A hook is actually a program segment that processes a message and hooks it into the system through a system call. Whenever a specific message is sent, before reaching the destination window, the hook program first captures the message, that is, the hook function gets control first. At this time, the hook function can process (change) the message, or continue to deliver the message without processing, or force the delivery of the message to end.
A Hook has a list of pointers associated with it, called a hook list, which is maintained by the system. The pointer of this list points to the specified, application-defined callback function called by the Hook subroutine, that is, each processing subroutine of the hook. When a message associated with the specified Hook type occurs, the system passes the message to the Hook subroutine. Some hook subroutines can only monitor the message, or modify the message, or stop the progress of the message, to avoid these messages being passed to the next hook subroutine or destination window. The most recently installed hooks are placed at the beginning of the chain, and the earliest installed hooks are placed at the end, that is, those added later gain control first. zdwork.cn
Windows does not require that hook routines be uninstalled in the reverse order of installation. Whenever a hook is unloaded, Windows releases the memory it occupies and updates the entire Hook list. If the program installs the hook, but ends before the hook is uninstalled, the system will automatically uninstall the hook for it.
大多数人或者网上文章认为全局钩子都要依赖于一个DLL才能正常工作的,常常会看到很多人在论坛上长期争论一个话题:“全局钩子一定要在DLL里面吗?”。实际上这里有一个概念的问题,究竟上面提到的全局钩子是指什么。通过对上面各种钩子的作用域的理解就会发现这个问题的答案。 本文来自智动软件zdwork.cn
上面一共提到了15种钩子,他们的作用域请看下表:
Hook |
Scope |
WH_CALLWNDPROC |
Thread or global |
WH_CALLWNDPROCRET |
Thread or global |
WH_CBT |
Thread or global |
WH_DEBUG |
Thread or global |
WH_FOREGROUNDIDLE |
Thread or global |
WH_GETMESSAGE |
Thread or global |
WH_JOURNALPLAYBACK |
Global only |
WH_JOURNALRECORD |
Global only |
WH_KEYBOARD |
Thread or global |
WH_KEYBOARD_LL |
Global only |
WH_MOUSE |
Thread or global |
WH_MOUSE_LL |
Global only |
WH_MSGFILTER |
Thread or global |
WH_SHELL |
Thread or global |
WH_SYSMSGFILTER |
Global only |
表一:钩子作用域
WH_JOURNALPLAYBACK,WH_JOURNALRECORD,WH_KEYBOARD_LL,WH_MOUSE_LL、WH_SYSMSGFILTER这5种钩子本身的作用域就是全局的,不管钩子是直接写在应用程序的代码里还是放在DLL中,他们都能够钩住系统的消息。剩下的10种钩子,他们的作用域既可以是线程的又可以是全局的,当将相应的钩子直接写在应用程序的代码中时,他们只能捕获当前线程上下文的消息。那么他们如何实现捕获全局消息的功能呢?当把钩子写入到一个单独的DLL中再引用后,系统自动将该DLL映射到受钩子函数影响的所有进程的地址空间中,即将这个DLL注入了那些进程,从而达到捕获全局消息的目的。相对来说,前面5种钩子本身就是全局的,是不需要注入的。 智动软件
因此,对于前面问题的答案就是:要实现捕获全局消息功能的钩子,是否要写在单独的DLL里面,取决于钩子的类型以及相应的作用域。
三、Hook Chain(钩子链表)
系统支持很多不同种类的钩子,每种类型提供对消息处理机制里的某一不同方面的访问。例如,应用程序可以使用WH_MOUSE Hook监视鼠标消息的传递。
系统为每类钩子维护着一个独立的钩子链表。钩子链表是一个指针的列表,其中的指针指向特定的、应用程序定义的回调函数,该函数被叫做钩子子程(hook procedure)。当与某种特定类型的钩子相关联(钩住)的消息发生时,系统将消息一个接一个地传递给钩子链中的每一个钩子子程(hook procedure),钩子子程能够采取的动作取决于涉及的钩子的类型。某些类型的钩子子程仅仅能监视消息;另外一些就能够修改消息或者终止消息在钩子链表中的前进,这样就阻止了消息到达下一个钩子子程或者目标窗体。
这里有几个概念上的翻译,主要有:
Hook Chain : 钩子链表
hook procedures : 钩子子程(即得到消息后进行处理的程序段)
如果对于同一事件既安装了线程勾子又安装了全局勾子,那么系统会自动先调用线程勾子,然后调用全局勾子。
最近学习hook,看了几个教程:
1)http://blog.sina.com.cn/s/articlelist_1585708262_3_1.html
2)http://www.lellansin.com/windows-api-%E6%95%99%E7%A8%8B%EF%BC%88%E4%B8%83%EF%BC%89-hook-%E9%92%A9%E5%AD%90%E7%9B%91%E5%90%AC%EF%BC%88%E7%BC%96%E5%86%99%E4%B8%AD%EF%BC%89.html
3)http://blog.csdn.net/camly/article/details/1752798