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

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

51Testing软件测试网]h)vM(E$w

  Windows应用程序是基于消息驱动的。各种应用程序对各种消息作出响应从而实现各种功能。

xZ0h6i&Uk*WS!\GR0

@B6UF C/`0   Windows钩子是Windows消息处理机制的一个监视点,通过安装钩子可以达到监视指定窗口某种类型的消息的功能。所谓的指定窗口并不局限于当前 进程的窗口,也可以是其他进程的窗口。当监视的某一消息到达指定的窗口时,在指定的窗口处理消息之前,钩子函数将截获此消息,钩子函数既可以加工处理该消 息,也可以不作任何处理继续传递该消息。使用钩子是实现dll注入的方法之一。其他常用的方法有:注册表注入,远程线程注入。

T4v`JsC0

bo7kHvId8g&^2P%@;x0  钩子函数是一个处理消息的程序段。是在安装钩子的时候向系统注册的。51Testing软件测试网IqlQ}bAV2n%Y

0u!j gs\ \C*k"ma+~aM0  关于Windows钩子要清楚以下三点:

d o*o _m(x,F}P051Testing软件测试网,TB6NY{2z?

  1:钩子是用来截获系统中的消息流的。利用钩子可以处理任何我们感兴趣的消息,当然包括其他进程的消息。51Testing软件测试网7n'd"P&lQ3F$K TEu

51Testing软件测试网F@2?)^.|ti$v8[

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

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

y3t5EX3?Q0

7i` q9Q]W| D0  注意:使用钩子会使系统变慢,因为它增加了系统对每个消息的处理量。所以要仅在必要的时候才安装钩子。不需要时要及时卸载。

h$U&sC~3W0

:?M1U"g*m7`.AZ0  安装钩子:

8qPB6];B w@DAF-B051Testing软件测试网-F` Q y k%LIc%X

  1:

]2v8U x3mVO0
51Testing软件测试网 oP7^9G a2hS

SetWindowsHookEx(

)y an e x^$\g,{m0

o)M9|iX]0         int idHook,                  //要安装的钩子的类型。51Testing软件测试网(B,IY'm%FbQLB

51Testing软件测试网B9C?n%I8^2X/v xb jE

         HOOKPROC lpfn,                  //钩子函数的地址。

kMj w~O051Testing软件测试网 sv|"l-{A&Y#u5o

         HINSTANCE hMode,               //钩子函数所在DLL在进程内的地址。51Testing软件测试网L2J%]{4aP&t

51Testing软件测试网6Kt8sJz@N,ik [Z

         DWORD     dwThread,            //要安装钩子的线程。如为0,则为所有线程安装钩子。51Testing软件测试网Y [3T)cvv&O#q

,X cL3[ n0         );51Testing软件测试网]&v:HV5i!a8X2Fp)nJ)k

4O\g d#b E(Cb7]wE0  idHook指定要安装钩子的类型,他可以是下面的值:51Testing软件测试网jU*P&Sz1]9FE

Fo}3ZQ#@1x J0  WH_CALLWNDPROC           //目标线程调用SendMessage发送消息时,钩子函数被调用。51Testing软件测试网)n k]|@ `$UR
  WH_CALLWNDPROCRET   //当SendMessage返回时,钩子函数被调用。
6Z8p3e7Y?5DA0  WH_KEYBOARD                 //从消息队列中查询WM_KEYUP或WM_KEYDOWN时。51Testing软件测试网b5bc4i#})Ee
  WH_GETMESSAGE           //目标线程调用GetMessage或PeekMessage时51Testing软件测试网-KXb `F#[ S0nBYe)t
  WH_MOUSE                      //查询消息队列中鼠标事件消息时。51Testing软件测试网YRU c6E
  WH_MSGFILTER              //以下请参考MSDN。
/U$Vzb:z `%o0  WH_SYSMSGFILTER51Testing软件测试网 |4?7jL~0i
  WH_JORNALRECORD51Testing软件测试网BN*r1F9PP!Q
  WHJORNALPLAYBACK51Testing软件测试网9VjfM1k\
  WH_SHELL
O)`U [es#R*@0  WH_CBT
0Vw.v_[;de Cg0  WH_FOREGROUNDIDLE51Testing软件测试网&b)oMF4_"}
  WH_DEBUG

0\'uol gv&s(X051Testing软件测试网9uf7d c,iC&} t

  2:51Testing软件测试网8n W IN[-T7F$]R8F

{$n FJr1?Y0  lpfn是钩子函数的地址。钩子安装后如果有相应的消息发生,Windows将调用此参数指向的函数。一般钩子函数都是位于一个DLL中。当为其他进程内的线程安装钩子时,如果钩子函数在DLL中,系统会把DLL映射到那个进程内,使他能在该进程内被调用。

1y-Z8^n`ZY051Testing软件测试网Y3H J B&I}S,s(ur

  注意:钩子函数多是被其他进程内的线程调用,而不一定是安装钩子的线程。

c)m-z1l2qJdGCN_0

B0w vX-C8{0  钩子函数被调用的过程:

${-{sV\051Testing软件测试网r8}zq+{4T;^v

  当进程A一个线程准备向一个窗口发送一个消息,系统检查该线程是否被安装了钩子,如果该线程被安装了钩子且该消息与钩子要截获的消息类型一致, 此消息将被截获。系统检查该钩子的钩子函数所在的DLL是否已经被映射进程A的地址空间中。如果尚未映射,系统会强制将该DLL映射到进程A的地址空间。 然后获得钩子函数在进程A的虚拟地址,并调用钩子函数。我们可以在钩子函数内定义我们对该消息处理的过程。51Testing软件测试网3_4Zcp$].b LmM

jz-vI%o.B9T g P1su0  注意:当系统把钩子函数所在的DLL映射到某个进程地址空间时,会映射整个DLL,而不仅仅是钩子函数,这也就说我们可以使用该DLL中的所有导出函数。51Testing软件测试网"t4?/B n[e,BS

3qh,S6hN0  3:hmod参数是钩子函数所在dll的实例句柄,也是该dll在进程内的虚拟地址。如果钩子函数在当前进程中,此参数应被指定为NULL.51Testing软件测试网#j'z;n Rh!B1b

51Testing软件测试网qo K P!h#C|

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

8O/@'gf'n`}$^0

*\t-g4`/|^!sqI`4~(R0  5:钩子函数

!z h"X;|+U(wMh'J[|5c0

G5?F6p yz?HX0  钩子被安装后,如果有相应的消息发生,Windows将调用钩子函数。以下为钩子函数的原型:

/fl,@)`cx8Oc051Testing软件测试网i(rM:[7[#m{

51Testing软件测试网ik P w!{r:~d"@K

51Testing软件测试网6^Ej1{{;Z+v ?)Vt*}

  LRESULT CALLBACK HookProc(int nCode,WPARAM wParam,LPARAM lParam)

O9@:ldB051Testing软件测试网cHqDOp9Yu ?

   {

h5F)Q)T@E0

OR*QYp$r0     //处理消息的代码。51Testing软件测试网H~@'tWgA

{v.kT-T ?0      return CallNextHookEx(hHook,nCode,wParam,lParam);

r0`J!f(Q5OWX051Testing软件测试网n2_^+]5i

   }

'r ^cox0
51Testing软件测试网K0xW7[8o n,Nu

  HookProc为钩子函数的名称。51Testing软件测试网J I(KJN)Vndm

51Testing软件测试网^;Q!ts%D9f

  nCode指定是否必须处理该消息。如果它为HC_ACTION,那么钩子函数就必须处理该消息。如果小于0,钩子函数就必须将该消息传递给CallNextHookEx,不对该消息进行处理,并返回CallNextHookEx的返回值。

$X7v| B3nJd0

n7m*sUb:Rt/l!gqT0  CallNextHookEx用于把消息传递到钩子链中下一个钩子函数。51Testing软件测试网D? Ie2zOr)w

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

X.x'[9o-Ro^g0

Ed)E'bFd(V%O0  卸载钩子。

*zPp0d eSHH0

8EyR:J1w6l4V0  BOOL UnhookWindowsHookEx(HHOOK hhk);51Testing软件测试网T'dD8URXyy

CLP,CG0  hhk为要卸载的钩子句柄。51Testing软件测试网c1G-^E?,y8u a/B

51Testing软件测试网jJf/N!v8t kgiD3m

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

(TeHge7{S0

P9d!u,Q8sQV%U0  程序外观:

#j2M&K@A2Dq U4t0

2fR/Vn Xn |C;kc0

TAG:

 

评分:0

我来说两句

Open Toolbar