《Windows核心编程系列》谈谈Windows钩子-1

上一篇 / 下一篇  2012-09-03 14:20:04 / 个人分类:杂谈

W W"T.B[uV Pp0  Windows应用程序是基于消息驱动的。各种应用程序对各种消息作出响应从而实现各种功能。

k M!bG J j8h8oF0

aHbv*xQ-^#HwR0   Windows钩子是Windows消息处理机制的一个监视点,通过安装钩子可以达到监视指定窗口某种类型的消息的功能。所谓的指定窗口并不局限于当前 进程的窗口,也可以是其他进程的窗口。当监视的某一消息到达指定的窗口时,在指定的窗口处理消息之前,钩子函数将截获此消息,钩子函数既可以加工处理该消 息,也可以不作任何处理继续传递该消息。使用钩子是实现dll注入的方法之一。其他常用的方法有:注册表注入,远程线程注入。51Testing软件测试网 A!Q Hf,o9B\d/A

5h!Ww#z4Y0  钩子函数是一个处理消息的程序段。是在安装钩子的时候向系统注册的。

z$t0E9] d"qj{ B*{)x051Testing软件测试网sq6B q d

  关于Windows钩子要清楚以下三点:51Testing软件测试网3H!K??1YD4~@Vm

!O*H jR)|$S"OS0  1:钩子是用来截获系统中的消息流的。利用钩子可以处理任何我们感兴趣的消息,当然包括其他进程的消息。

%MD&b&PM \r051Testing软件测试网 AL ~Vzf6`.x

  2:截获该消息后,用于处理该消息的程序叫做钩子函数。它是自定义的函数,在安装钩子时将此函数的地址告诉Windows。51Testing软件测试网Xo;N+OXI

51Testing软件测试网 Mjn!qy7r$rN

  3:系统同一时间可能有多个进程安装钩子,多个钩子构成钩子链。所以截获消息并处理后,应该将此消息继续传递下去,以便其他钩子处理这一消息。

6h3nZ0G;V0

qK'kR/i1rn0  注意:使用钩子会使系统变慢,因为它增加了系统对每个消息的处理量。所以要仅在必要的时候才安装钩子。不需要时要及时卸载。

/SVp's:W(l'Sy051Testing软件测试网(Rp6t+xZd.yHD)y

  安装钩子:51Testing软件测试网v*`#PZ [

51Testing软件测试网d$?S~o

  1:51Testing软件测试网t8b&|:[+WBrB

51Testing软件测试网`~ cTZe

SetWindowsHookEx(

7\1StP3r#{"B.K2n8Ab0

Vs mX1l5G;vj0         int idHook,                  //要安装的钩子的类型。

&ym eDa:x8zIgM^0

"w9d ] D5OeJ5c0         HOOKPROC lpfn,                  //钩子函数的地址。51Testing软件测试网/g\*VeZk"O

51Testing软件测试网z v3o+c#x$R5A u

         HINSTANCE hMode,               //钩子函数所在DLL在进程内的地址。51Testing软件测试网4i'R:qH%BdC7s9?V

/HWk/{M z*n7F0         DWORD     dwThread,            //要安装钩子的线程。如为0,则为所有线程安装钩子。51Testing软件测试网f-YbRg2X3d

51Testing软件测试网9D ? O:W7v

         );

2f%j?2kgY0
51Testing软件测试网6tU-A"?I

  idHook指定要安装钩子的类型,他可以是下面的值:

@g#~YN(PC1N0

@XmToR7s0  WH_CALLWNDPROC           //目标线程调用SendMessage发送消息时,钩子函数被调用。
5g`)N2q6?Kn0  WH_CALLWNDPROCRET   //当SendMessage返回时,钩子函数被调用。51Testing软件测试网v8u$fjK?u+\@
  WH_KEYBOARD                 //从消息队列中查询WM_KEYUP或WM_KEYDOWN时。51Testing软件测试网,jKS3[v Uhn
  WH_GETMESSAGE           //目标线程调用GetMessage或PeekMessage时
!sI!AD^w@0  WH_MOUSE                      //查询消息队列中鼠标事件消息时。51Testing软件测试网)u;Zkef.R
  WH_MSGFILTER              //以下请参考MSDN。51Testing软件测试网b mO?i0?J
  WH_SYSMSGFILTER
3R#rA6u%@d.Ob$c4j.B0  WH_JORNALRECORD51Testing软件测试网tj:`)lK
  WHJORNALPLAYBACK
1d%d!T b#Eo!j&{0  WH_SHELL
(R:BrBGH"IC?,i0  WH_CBT
3v9ZnbI0  WH_FOREGROUNDIDLE
v8G*O8Rsw7SHV6uZMW0  WH_DEBUG
51Testing软件测试网u_;DxA-r3v

51Testing软件测试网;ZEG%v b

  2:51Testing软件测试网 m g'q;p8{2^cw

51Testing软件测试网6Qr!z `t6l d:s

  lpfn是钩子函数的地址。钩子安装后如果有相应的消息发生,Windows将调用此参数指向的函数。一般钩子函数都是位于一个DLL中。当为其他进程内的线程安装钩子时,如果钩子函数在DLL中,系统会把DLL映射到那个进程内,使他能在该进程内被调用。51Testing软件测试网%\1S6d)A0]+gN

51Testing软件测试网&o"@#F;f8]0Q

  注意:钩子函数多是被其他进程内的线程调用,而不一定是安装钩子的线程。51Testing软件测试网w/hu]9S(xC

#a0jkN$B Z!i J0  钩子函数被调用的过程:

qFLb \V0

8_h"oI0F:H'u0  当进程A一个线程准备向一个窗口发送一个消息,系统检查该线程是否被安装了钩子,如果该线程被安装了钩子且该消息与钩子要截获的消息类型一致, 此消息将被截获。系统检查该钩子的钩子函数所在的DLL是否已经被映射进程A的地址空间中。如果尚未映射,系统会强制将该DLL映射到进程A的地址空间。 然后获得钩子函数在进程A的虚拟地址,并调用钩子函数。我们可以在钩子函数内定义我们对该消息处理的过程。

2tzy'eQ| y x0

8U i%E4Nw Q0  注意:当系统把钩子函数所在的DLL映射到某个进程地址空间时,会映射整个DLL,而不仅仅是钩子函数,这也就说我们可以使用该DLL中的所有导出函数。51Testing软件测试网"~8i D_5^3t

)_/CQ MfN0  3:hmod参数是钩子函数所在dll的实例句柄,也是该dll在进程内的虚拟地址。如果钩子函数在当前进程中,此参数应被指定为NULL.51Testing软件测试网sw@)@/cC1^

8H8A5w0L!Q s&Is1l0  4:dwThreadid指定要被安装钩子的线程的ID号。如果被设为0,就会为系统内的所有GUI线程安装钩子。

A7]/H*REf1t.t2a0

pBt eW,Q2@Cr0  5:钩子函数51Testing软件测试网7cOw CS ov{;n

51Testing软件测试网`R*_0Rm

  钩子被安装后,如果有相应的消息发生,Windows将调用钩子函数。以下为钩子函数的原型:51Testing软件测试网KrY S4Z

51Testing软件测试网M'vC"|7Fi

51Testing软件测试网+dx]j,D2A1J

51Testing软件测试网)\d!Z#_L9n

  LRESULT CALLBACK HookProc(int nCode,WPARAM wParam,LPARAM lParam)51Testing软件测试网4A{k zjD!\ ?

51Testing软件测试网t#P Z4S%nmt$h

   {

h0[vO2X3B5? JA"N}0

n*@~-hR$V j*}&?6@]0     //处理消息的代码。51Testing软件测试网2W&Pba%J|

51Testing软件测试网&Y7dR4M+X LD*DC

      return CallNextHookEx(hHook,nCode,wParam,lParam);51Testing软件测试网$L} LL\ck jFt:F

51Testing软件测试网*U!vd+T Z/Us[

   }

+^~&n)k0h F:I bQ'F {0
51Testing软件测试网TH0wX@

  HookProc为钩子函数的名称。51Testing软件测试网HB.IrKHSr

51Testing软件测试网z|&X5T'MgY.To

  nCode指定是否必须处理该消息。如果它为HC_ACTION,那么钩子函数就必须处理该消息。如果小于0,钩子函数就必须将该消息传递给CallNextHookEx,不对该消息进行处理,并返回CallNextHookEx的返回值。51Testing软件测试网3c;?D,]#q!FXnb%s

51Testing软件测试网#M3K%vGX/d"m{`

  CallNextHookEx用于把消息传递到钩子链中下一个钩子函数。

7cH&I'n5s.r$^;Kc051Testing软件测试网K2jw [ Z*{:R

  wParam和lParam的值依赖于具体的钩子类型。请参考MSDN。

9q3M!h)w/OtI051Testing软件测试网:tG:?9W0u `

  卸载钩子。51Testing软件测试网zp @.xj }t(nc

51Testing软件测试网R Y @5?R P` a

  BOOL UnhookWindowsHookEx(HHOOK hhk);

-F9s f+_5_%g*HOT Aw051Testing软件测试网9@{Hr:^'G%?#R

  hhk为要卸载的钩子句柄。

;z"| X9{6l0V2M&q-Q051Testing软件测试网;C \6?4b(L[2o8W,]\;y

  下面将要实现一个例子,实现对键盘按键的监控。一旦有键盘被按下,就在主程序窗口显示一条信息指示哪一个键被按下。

s9G)?*R1YZ"b051Testing软件测试网D1t FkolNA"p%MBd

  程序外观:

E$\7X?Rqsk0

h}7Nd9A6Pp BwZa:W0

TAG:

 

评分:0

我来说两句

Open Toolbar