Hooks

来源:互联网 发布:广州数据分析培训机构 编辑:程序博客网 时间:2024/05/01 12:14

关于Hooks

1.         概述

一个Hook(钩子)Windows系统消息处理机制当中的一个点,用户可以在这个点设置自己的例程来侦测系统的消息通道并可以在这些消息到达它们的目标窗口函数之前有选择的处理某些消息。

处理过了的消息最终仍然会到达它们的窗口函数,也就是说Hooks并不影响消息的路由。但是Hooks却可能会降低系统的效率,因为它们增加了系统必须处理的消息的数量,实际上安装了Hook之后,系统需要过滤每个消息。因此,你应当只在需要Hooks的时候安装它们,而使用完了之后就立即卸载。

 

2.         Hook Chains

Windows系统支持许多种不同类型的Hooks,每一种类型的Hook能够访问消息处理机制的某一个不同的方面。比如,程序可以使用WM_MOUSE Hook来侦测消息通道中有关鼠标的消息。

系统维护为每个类型的Hook维护着一个单独的Hook Chain。一个Hook Chain其实是一个指针列表,每个指针都指向一个hook函数,hook函数是特殊的用户自定义的回调函数。当一个消息发生了时,系统会找到与这个消息相关的那个Hook类型的Hook chain,然后将该消息传递给hook chain中的每个hook函数。Hook函数对消息能够采取一个怎么的反应这取决于hook的类型。有些类型的HookHook函数只能侦测消息,在些则能改变消息或者停止消息的路由,阻止消息到达下一个Hook函数甚至到达目标窗口。

3.         Hook函数

要利用某种类型的Hook,开发人员需要提供一个Hook函数,然后利用

SetWindowsHookEx函数来把它安装到该类型HookHook chain中。

Hook函数的原型必须如下:

LRESULT CALLBACK HookProc(
  int nCode, 
  WPARAM wParam, 
  LPARAM lParam
);
      当然Hook函数的名称是可以自定义的,并不一定是HookProc
      参数nCode是一个hook代码,Hook函数使用它来决定执行一个什么样的行动。nCode的值取决于Hook的类型,每个类型的HooknCode都有自己独特的特征。wParam和的lParam值又依赖于nCode,在一般情况下,它们包含了消息的信息。
SetWindowsHookEx函数总是将一个Hook函数安装在Hook chain的起始端。当一个消息发生时,系统就会找到该消息对应的Hook Chain,并把该消息传递给Hook chain的起始Hook函数。Hook chain中的每个Hook函数决定是否将该消息传递给下一个Hook函数。Hook函数可以调用CallNextHookEx函数来将消息传递给Hook chain中的下一个函数。
   注意:有些类型HookHook函数只能够侦测消息。对于这种类型的Hook,系统会将消息传递给该Hook Chain中的每一个Hook函数,而不管其中的Hook函数是否调用了CallNextHookEx函数。

4.         Hook类型

1)        WH_CALLWNDPROCWH_CALLWNDPROCRET Hooks

2)        WH_CBT Hook

3)        WH_DEBUG Hook

4)        WH_FOREGROUNDIDLE Hook

5)        WH_GETMESSAGE Hook

6)         

7)         

8)         

9)         

5.          

6.          

   

使用Hooks

1.         安装和释放Hook函数

可以调用SetWindowsHookEx来安装一个Hook函数并指定调用该Hook函数的Hook类型,还可以指定该函数是和所有的线程关联,还是只和某一个线程关联,又或者只指向一个函数的入口点。

必须将Hook函数放置在一个单独的DLL中,而不要放到需要安装Hook函数的应用程序中。应用程序必须先取得Dll的句柄才能够安装dll中的Hook函数。函数LoadLibrary可以依据Dll的名称来取得dll的句柄。一旦取得Dll的句柄之后,就可以调用GetProcAddress函数来获取Hook函数的地址,最后使用SetWindowsHookExHook函数的指针(地址)放到Hook chain中。整个流程如下面的所示:

HOOKPROC hkprcSysMsg; 
static HINSTANCE hinstDLL; 
static HHOOK hhookSysMsg; 
 
hinstDLL = LoadLibrary((LPCTSTR) "c://windows//sysmsg.dll"); 
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc"); 
hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER, 
    hkprcSysMsg, hinstDLL, 0); 

说明:参数0,表示该Hook函数与系统中的所有线程关联。

可以调用UnHookWindowsHookEx来释放一个线程相关的Hook函数。

虽然可以使用UnHookWindowsHookEx函数来释放一个全局Hook函数,但是该函数却无法释放包含Hook函数的Dll。因为全局Hook函数是在系统中的每个程序的进程上下文被调用的,这引起了系统的所有的进程都隐含地调用了LoadLibrary函数。而FreeLibrary函数不能够够释放其它进程所使用的dll,这样就没有办法释放该dll了。系统会在所有与该Dll相关的进程都结束了或都调用了FreeLibrary之后来自动释放该Dll

另一个安装全局Hook函数的方法是在Dll中提供一个安装函数。。。

2.          

3.          

4.          

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

原创粉丝点击