钩子的使用

钩子的使用

钩子函数的用法和作用?

http://topic.csdn.net/t/20020625/10/827891.html

WINDOW的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供了挂接各种反调函数(HOOK)的功能。这种挂钩函数(HOOK)类似扩充中断驱动程序,挂钩上可以挂接多个反调函数构成一个挂接函数链。系统产生的各种消息首先被送到各种挂接函数,挂接函数根据各自的功能对消息进行监视、修改和控制等,然后交还控制权或将消息传递给下一个挂接函数以致最终达到窗口函数。WINDOW系统的这种反调函数挂接方法虽然会略加影响到系统的运行效率,但在很多场合下是非常有用的,通过合理有效地利用键盘事件的挂钩函数监控机制可以达到预想不到的良好效果。   
一、在WINDOWS键盘事件上挂接监控函数的方法 
WINDOW
下可进行挂接的过滤函数包括11种: 
WH_CALLWNDPROC  
窗口函数的过滤函数 
WH_CBT  
计算机培训过滤函数 
WH_DEBUG  
调试过滤函数 
WH_GETMESSAGE  
获取消息过滤函数 
WH_HARDWARE  
硬件消息过滤函数 
WH_JOURNALPLAYBACK  
消息重放过滤函数 
WH_JOURNALRECORD  
消息记录过滤函数 
WH_MOUSE  
鼠标过滤函数 
WH_MSGFILTER  
消息过滤函数 
WH_SYSMSGFILTER  
系统消息过滤函数 
WH_KEYBOARD  
键盘过滤函数 
其中键盘过滤函数是最常用最有用的过滤函数类型,不管是哪一种类型的过滤函数,其挂接的基本方法都是相同的WINDOW调用挂接的反调函数时总是先调用挂接链首的那个函数,因此必须将键盘挂钩函数利用函数SetWindowsHookEx()将其挂接在函数链首。至于消息是否传递给函数链的下一个函数是由每个具体函数功能确定的,如果消息需要传统给下一个函数,可调用API函数的CallNextHookEx()来实现,如果不传递直接返回即可。 
挂接函数可以是用来监控所有线程消息的全局性函数,也可以是单独监控某一线程的局部性函数。如果挂接函数是局部函数,可以将它放到一个.DLL动态链接库中,也可以放在一个局部模块中;如果挂接函数是全局的,那么必须将其放在一个.DLL动态链接库中。挂接函数必须严格按照下述格式进行声明,以键盘挂钩函数为例: 
int   FAR   PASCAL  
KeyboardProc

int  
nCode,WORD  wParam,DWORD   lParam) 

其中KeyboardProc为定义挂接函数名,该函数必须在模块定义文件中利用EXPORTS命令进行说明;nCode决定挂接函数是否对当前消息进行处理;wParamlParam为具体的消息内容。 

二、键盘事件挂接函数的安装与下载 

在程序中可以利用函数SetWindowsHookEx()来挂接过滤函数,在挂接函数时必须指出该挂接函数的类型、函数的入口地址以及函数是全局性还是局部性的,挂接函数的具体调用格式如下: 
SetWindowsHookEx(iType,iProc,hInst,iCode) 

其中iType为挂接函数类型,键盘类型为WH_KEYBOARD,iProc挂接函数地址hInst挂接函数链接库实例句柄iCode为监控代码0表示全局性函数。如果挂接函数需要将消息传递给下一个过滤函数,则在该挂接函数返回前还需要调用一次CallNextHookEx()函数,当需要下载挂接函数时,只要调用一次UnhookWindowsHookEx(iProc)函数即可实现。如果函数是全局性的,那么它必须放在一个.DLL动态链接库中,这时该函数调用方法可以和其它普通.DLL函数一样有三种: 
1.DEF定义文件中直接用函数名或序号说明: 
EXPORTS 

WEP   @1   RESIDENTNAME 
InitHooksDll   @2 
InstallFilter   @3 
KeyboardProc   @4 
用序号说明格式为:链接库名.函数名(如本例中说明方法为KEYDLL.KeyboardProc) 
2.在应用程序中利用函数直接调用: 
首先在应用程序中利用LoadLibrary(LPSTR   "链接库名 ")将动态链接库装入,并取得装载库模块句柄hInst,然后直接利用GetProcAddress(HINSTANCE  hInst,LPSTR   "函数过程名 ")获取函数地址,然后直接调用该地址即可,程序结束前利用函数FreeLibrary(   )释放装入的动态链接库即可。 
3.利用输入库.LIB方法 
利用IMPLIB.EXE程序在建立动态链接库的同时建立相应的输入库.LIB,然后直接在项目文件中增加该输入库。   
三、WINDOWS挂钩监控函数的实现步骤 
WINDOWS
挂钩函数只有放在动态链接库DLL中才能实现所有事件的监控功能。在.DLL中形成挂钩监控函数基本方法及其基本结构如下: 
1、首先声明DLL中的变量和过程; 
2、然后编制DLL主模块LibMain(),建立模块实例; 
3、建立系统退出DLL机制WEP()函数; 
4、完成DLL初始化函数InitHooksDll(),传递主窗口程序句柄; 
5、编制挂钩安装和下载函数InstallFilter() 
6、编制挂钩函数KeyboardProc(),在其中设置监控功能,并确定继续调下一个钩子函数还是直接返回WINDOWS应用程序。 
7、在WINDOWS主程序中需要初始化DLL并安装相应挂钩函数,由挂接的钩子函数负责与主程序通信; 
8、在不需要监控时由下载功能卸掉挂接函数。 
四、WINDOWS下键盘挂钩监控函数的应用技术  
   
目前标准的104   键盘上都有两个特殊的按键,其上分别用WINDOW程序徽标和鼠标下拉列表标识,本文暂且分别称为Micro左键和Micro右键,前者用来模拟鼠标左键激活开始菜单,后者用来模拟鼠标右键激活属性菜单。这两个特殊按键只有在按下后立即抬起即完成   CLICK过程才能实现其功能,并且没有和其它按键进行组合使用。 
  
由于WINDOWS  系统中将按键划分得更加详细,使应用程序中很难灵活定义自己的专用快捷键,比如在开发.IME等应用程序时很难找到不与WORD8.0等其它应用程序冲突的功能按键。如果将标准104键盘中的这两个特殊按键作为模拟CTRLALT   等专用按键,使其和其它按键组合,就可以在自己的应用程序中自由地设置专用功能键,为应用程序实现各种功能快捷键提供灵活性。正常情况下WINDOWS   键盘事件驱动程序 
并不将这两个按键的消息进行正常解释,这就必须利用键盘事件的挂钩监控函数来实现其特定的功能。其方法如下:
1、首先编制如下一个简单动态链接库程序,并编译成DLL文件。 
#include   "windows.h " 

int   FAR   PASCAL  LibMain(HANDLE   hModule,UINT   wDataSeg, 
UINT   cbHeapSize,LPSTR  lpszCmdLine); 
int   WINAPI   WEP(int  bSystemExit); 
int   WINAPI   InitHooksDll(HWND  hwndMainWindow); 
int   WINAPI   InstallFilter(BOOL  nCode); 
LRESULT   CALLBACK   KeyHook(int  nCode,WORD   wParam,DWORD   lParam); 
static   HANDLE   hInstance;   //  全局句柄 
static   HWND   hWndMain;   // 
主窗口句柄 
static   int   InitCalled=0;   // 
初始化标志 
static   HHOOK   hKeyHook; 

FARPROC   lpfnKeyHook=(FARPROC)KeyHook; 
BOOL   HookStates=FALSE; 
int   FAR   PASCAL   LibMain( 
HANDLE   hModule, 
UINT   wDataSeg, 
UINT   cbHeapSize, 
LPSTR   lpszCmdLine) 

if   (cbHeapSize!=0)   UnlockData(0); 
hInstance   =   hModule; 
return   1; 

int   WINAPI   WEP   (int  bSystemExit) 
{   return   1;} 
int   WINAPI   InitHooksDll(HWND  hwndMainWindow) 
{   hWndMain   =  hwndMainWindow; 
InitCalled   =   1; 
return   (0); 

int   WINAPI   InstallFilter(BOOL  nCode) 
{   if   (InitCalled==0)   return  (-1); 
if   (nCode==TRUE)   { 
hKeyHook=SetWindowsHookEx(WH_KEYBOARD, 
(HOOKPROC)lpfnKeyHook,hInstance,0); 
HookStates=TRUE; 
}   else   { 
UnhookWindowsHookEx(hKeyHook); 
HookStates=FALSE; 

return(0); 

LRESULT   CALLBACK   KeyHook(int  nCode,WORD   wParam,DWORD   lParam) 

static   BOOL   msflag=FALSE; 
if(nCode> =0)   { 
if(HookStates==TRUE){ 
if((wParam==0xff)||   //WIN3.X下按键值 
(wParam==0x5b)||(wParam==0x5c)){//WIN95
下按键值 
if((i==0x15b)||(i==0x15c)){   //
按键按下处理 
msflag=TRUE; 

PostMessage(hWndMain,0x7fff,0x1,0x3L); 
}   else  if((i==0xc15b)||(i==0xc15c)){//按键抬起处理 
msflag=FALSE; 

PostMessage(hWndMain,0x7fff,0x2,0x3L); 




return((int)CallNextHookEx(hKeyHook,nCode,wParam,lParam)); 

该程序的主要功能是监控键盘按键消息,将两个特殊按键Micro按下和抬起消息转换成自定义类型的消息,并将自定义消息发送给应用程序主窗口函数。 
2、在应用程序主函数中建立窗口后,调用InitHooksDll()函数来初始化动态链接库,并将应用程序主窗口句柄传递给链接库,然后调用InstallFilter()函数挂接键盘事件监控回调函数。 
InitHooksDll(hIMEWnd);   //
初始化DLL 
InstallFilter(TRUE);   //
安装键盘回调函数 
3、在应用程序主窗口函数处理自定义消息时,保存Micro按键的状态,供组合按键处理时判断使用。 
switch   (iMessage)   { 

case   0x7fff:   //自定义消息类型 
if(lParam==0x3L){//
设置Micro键的状态 

if(wParam==0x1)   MicroFlag=TRUE; 

else   if(wParam==0x2)  MicroFlag=FALSE; 

break; 
4、在进行按键组合处理时,首先判断Micro键是否按下,然后再进行其它按键的判断处理。 
case   WM_KEYDOWN:   //  
按键按下处理 
if(MicroFlag==TRUE){//Micro
键按下 
if((BYTE)HIBYTE(wParam)==0x5b){ 

//Micro+ "[ "组合键 
......//
按键功能处理 
}   else  if((BYTE)HIBYTE(wParam)==0x5d){ 

//Micro+ "] "组合键 
......//
按键功能处理 


break; 
5、当应用程序退出时应注意下载键盘监控函数,即调用InstallFilter(FALSE)函数一次。 
6、利用本文提供的方法设置自己的应用程序功能按键,在保证程序功能按键不会与其它系统发生冲突的同时,有效地利用了系统中现有资源,而且在实现应用程序功能的同时灵活应用了系统中提供的各种功能调用。

http://hi.baidu.com/anwyo/blog/item/882c858276107bb96d811925.html

HOOK的认识[转载]

20080926日星期五下午 3:40

本文将试图以下面的顺序讲解HOOK的大部分内容:

 

1 WINDOWS的消息机制
  2
HOOK介绍
  3
HOOK
  4
HOOK钩子的作用范围
  5
HOOK类型
  6
、回调函数
  7
HOOK钩子的安装与卸载
  8
HOOK实例演示

 

+++++++++++++++++++
  WINDOWS
的消息机制
  +++++++++++++++++++
  Windows
系统是以消息处理为其控制机制,系统通过消息为窗口过程(windows 
  procedure
)传递输入。系统和应用两者都可以产生消息。对于每个输入事件,例如用
 
户按下了键盘上的某个键、移动了鼠标、单击了一个控件上的滚动条,等等,系统都
 
将产生一系列消息。此外,对于应用带给系统的变化,如字体资源的改变、应用本身
 
窗口的改变,系统都将通过消息以响应这种变化。应用通过产生消息指示应用的窗口
 
完成特定的任务,或与其他应用的窗口进行通信。
 
每个窗口都有一个处理Windows系统发送消息的处理程序,称为窗口程序。它是
 
隐含在窗口背后的一段程序脚本,其中包含对事件进行处理的代码。
  Windows
系统为每条消息指定了一个消息编号,例如当一个窗口变为活动窗口时,它事
 
实上是收到一条来自Windows系统的WM_ACTIVATE消息,该消息的编号为6,它对
 
应于VB窗口的Activate事件。对于窗口来说,诸如OpenActivateMouseDownResize
 
等事件,实际上对应的是窗口内部的消息处理程序,这些程序对于用户来讲是不可见的。
 
类似地,命令按钮也有消息处理程序,它的处理程序响应诸如WM_LBUTTONDOWN
 
WM_RBUTTONDOWN之类的消息,即激活命令按钮的MouseDown事件。

 

WINDOWS的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供
 
了挂接各种回调函数(HOOK)的功能。这种挂钩函数(HOOK)类似扩充中断驱动程序,
 
挂钩上可以挂接多个反调函数构成一个挂接函数链。系统产生的各种消息首先被送
 
到各种挂接函数,挂接函数根据各自的功能对消息进行监视、修改和控制等,然后交
 
还控制权或将消息传递给下一个挂接函数以致最终达到窗口函数。WINDOW系统的
 
这种反调函数挂接方法虽然会略加影响到系统的运行效率,但在很多场合下是非常有
 
用的,通过合理有效地利用键盘事件的挂钩函数监控机制可以达到预想不到的良好效
 
果。

 

+++++++++++
  hook
介绍
  +++++++++++

 

Hook(钩子)是WINDOWS提供的一种消息处理机制平台,是指在程序正常运
 
行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实
 
际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,
 
在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这
 
时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还
 
可以强制结束消息的传递。
 
注意:安装钩子函数将会影响系统的性能。监测系统范围事件的系统钩子特
 
别明显。因为系统在处理所有的相关事件时都将调用您的钩子函数,这样您的系统将
 
会明显的减慢。所以应谨慎使用,用完后立即卸载。还有,由于您可以预先截获其它
 
进程的消息,所以一旦您的钩子函数出了问题的话必将影响其它的进程。记住:功能
 
强大也意味着使用时要负责任。

 

+++++++++++++
  HOOK

  +++++++++++++

 

WINDOWS提供了14种不同类型的HOOKS;不同的HOOK可以处理不同的消
 
息。例如,WH_MOUSE HOOK用来监视鼠标消息。
  WINDOWS
为这几种HOOKS维护着各自的HOOK链表。HOOK链表是一串由
 
应用程序定义的回调函数(CALLBACK Function)队列,当某种类型的消息发生时,

 

WINDOWS向此种类型的HOOK链的第一个函数(HOOK链的顶部)发送该消息,
 
在第一函数处理完该消息后由该函数向链表中的下一个函数传递消息,依次向下。如
 
果链中某个函数没有向下传送该消息,那么链表中后面的函数将得不到此消息。(对
 
于某些类型的HOOK,不管HOOK链中的函数是否向下传递消息,与此类型HOOK
 
联系的所有HOOK函数都会收到系统发送的消息)一些Hook子过程可以只监视消息,
 
或者修改消息,或者停止消息的前进,避免这些消息传递到下一个Hook子过程或者
 
目的窗口。最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加
 
入的先获得控制权。

 

+++++++++++++++++
 
钩子的作用范围
  ++++++++++++++++

 

一共有两种范围(类型)的钩子:局部的和远程的。
 
一、局部钩子仅钩挂您自己进程的事件。
 
二、远程的钩子还可以将钩挂其它进程发生的事件。
 
远程的钩子又有两种:
  1
、基于线程的它将捕获其它进程中某一特定线程的事件。简言之,就是可
 
以用来观察其它进程中的某一特定线程将发生的事件。
  2
、系统范围的将捕捉系统中所有进程将发生的事件消息。

 

+++++++++++++
  HOOK
类型
  +++++++++++++

 

Windows共有14HOOKS,每一种类型的Hook可以使应用程序能够监视不同
 
类型的系统消息处理机制。下面描述所有可以利用的Hook类型的发生时机。(这些常
 
数值均可以API浏览器里查到)

 

1WH_CALLWNDPROCWH_CALLWNDPROCRET Hooks

 

WH_CALLWNDPROCWH_CALLWNDPROCRET Hooks使你可以监视发送到
 
窗口过程的消息。系统在消息发送到接收窗口过程之前调用WH_CALLWNDPROC
  Hook
子过程,并且在窗口过程处理完消息之后调用WH_CALLWNDPROCRET Hook
 
子过程。

 

WH_CALLWNDPROCRET Hook传递指针到CWPRETSTRUCT结构,再传递到
  Hook
子过程。CWPRETSTRUCT结构包含了来自处理消息的窗口过程的返回值,同
 
样也包括了与这个消息关联的消息参数。

 

2WH_CBT Hook

 

在以下事件之前,系统都会调用WH_CBT Hook子过程,这些事件包括:
  1.
激活,建立,销毁,最小化,最大化,移动,改变尺寸等窗口事件;
  2.
完成系统指令;
  3.
来自系统消息队列中的移动鼠标,键盘事件;
  4.
设置输入焦点事件;
  5.
同步系统消息队列事件。

 

Hook子过程的返回值确定系统是否允许或者防止这些操作中的一个。

 

3WH_DEBUG Hook

 

在系统调用系统中与其它Hook关联的Hook子过程之前,系统会调用
  WH_DEBUG Hook
子过程。你可以使用这个Hook来决定是否允许系统调用与其它
  Hook
关联的Hook子过程。

 

4WH_FOREGROUNDIDLE Hook

 

当应用程序的前台线程处于空闲状态时,可以使用WH_FOREGROUNDIDLE
  Hook
执行低优先级的任务。当应用程序的前台线程大概要变成空闲状态时,系统就
 
会调用WH_FOREGROUNDIDLE Hook子过程。

 

5WH_GETMESSAGE Hook

 

应用程序使用WH_GETMESSAGE Hook来监视从GetMessage or PeekMessage
 
数返回的消息。你可以使用WH_GETMESSAGE Hook去监视鼠标和键盘输入,以及
 
其它发送到消息队列中的消息。

 

6WH_JOURNALPLAYBACK Hook

 

WH_JOURNALPLAYBACK Hook使应用程序可以插入消息到系统消息队列。可
 
以使用这个Hook回放通过使用WH_JOURNALRECORD Hook记录下来的连续的鼠
 
标和键盘事件。只要WH_JOURNALPLAYBACK Hook已经安装,正常的鼠标和键盘
 
事件就是无效的。WH_JOURNALPLAYBACK Hook全局Hook,它不能象线程特定
  Hook
一样使用。WH_JOURNALPLAYBACK Hook返回超时值,这个值告诉系统在处
 
理来自回放Hook当前消息之前需要等待多长时间(毫秒)。这就使Hook可以控制实
 
时事件的回放。WH_JOURNALPLAYBACKsystem-wide local hooks,它们不会被
 
注射到任何行程地址空间。

 

7WH_JOURNALRECORD Hook

 

WH_JOURNALRECORD Hook用来监视和记录输入事件。典型的,可以使用这
 
Hook记录连续的鼠标和键盘事件,然后通过使用WH_JOURNALPLAYBACK Hook
 
来回放。WH_JOURNALRECORD Hook全局Hook,它不能象线程特定Hook一样
 
使用。WH_JOURNALRECORDsystem-wide local hooks,它们不会被注射到任何行
 
程地址空间。

 

8WH_KEYBOARD Hook

 

在应用程序中,WH_KEYBOARD Hook用来监视WM_KEYDOWN and
  WM_KEYUP
消息,这些消息通过GetMessage or PeekMessage function返回。可以使
 
用这个Hook来监视输入到消息队列中的键盘消息。

 

9WH_KEYBOARD_LL Hook

 

WH_KEYBOARD_LL Hook监视输入到线程消息队列中的键盘消息。

 

10WH_MOUSE Hook

 

WH_MOUSE Hook监视从GetMessage 或者 PeekMessage 函数返回的鼠标消息。
 
使用这个Hook监视输入到消息队列中的鼠标消息。

 

11WH_MOUSE_LL Hook

 

WH_MOUSE_LL Hook监视输入到线程消息队列中的鼠标消息。

 

12WH_MSGFILTER WH_SYSMSGFILTER Hooks

 

WH_MSGFILTER WH_SYSMSGFILTER Hooks使我们可以监视菜单,滚动
 
条,消息框,对话框消息并且发现用户使用ALT+TAB or ALT+ESC 组合键切换窗口。
  WH_MSGFILTER Hook
只能监视传递到菜单,滚动条,消息框的消息,以及传递到通
 
过安装了Hook子过程的应用程序建立的对话框的消息。WH_SYSMSGFILTER Hook
 
监视所有应用程序消息。

 

WH_MSGFILTER WH_SYSMSGFILTER Hooks使我们可以在模式循环期间
 
过滤消息,这等价于在主消息循环中过滤消息。

 

通过调用CallMsgFilter function可以直接的调用WH_MSGFILTER Hook。通过使用这
 
个函数,应用程序能够在模式循环期间使用相同的代码去过滤消息,如同在主消息循
 
环里一样。

 

13WH_SHELL Hook

 

外壳应用程序可以使用WH_SHELL Hook去接收重要的通知。当外壳应用程序是
 
激活的并且当顶层窗口建立或者销毁时,系统调用WH_SHELL Hook子过程。
  WH_SHELL
共有5钟情况:
  1.
只要有个top-levelunowned 窗口被产生、起作用、或是被摧毁;
  2.
Taskbar需要重画某个按钮;
  3.
当系统需要显示关于Taskbar的一个程序的最小化形式;
  4.
当目前的键盘布局状态改变;
  5.
当使用者按Ctrl+Esc去执行Task Manager(或相同级别的程序)。

 

按照惯例,外壳应用程序都不接收WH_SHELL消息。所以,在应用程序能够接
 
WH_SHELL消息之前,应用程序必须调用SystemParametersInfo function注册它自
 
己。

 


  ++++++++++++++++++++++++++
 
回调函数(HOOK处理子过程)
  ++++++++++++++++++++++++++

 

为了拦截和处理特定的消息,你可以使用SetWindowsHookEx函数(下面将具体
 
说明这些函数的声明及各种参数)在该类型的HOOK链中安装你自己的处理HOOK
 
的子过程(回调函数)。只要您安装的钩子的消息事件类型发生,WINDOWS就将调
 
用钩子函数。譬如您安装的钩子是WH_MOUSE类型,那么只要有一个鼠标事件发生
 
时,该钩子函数就会被调用。不管您安装的是那一类型钩子,钩子函数的原型都时是
 
一样的,语法如下:

 

public function MyHook(ByVal nCode As Long, ByVal wParam As Long, ByVal  lParam
  As Long) as long

 

处理代码

 

end function

 

其中MyHook可以随便命名,其它不能变。该函数必须放在模块段。
 
参数说明:
  nCode
指定HOOK传入的信息类型。Hook子过程使用这个参数来确定任务。这个
 
参数的值依赖于Hook类型,每一种Hook都有自己的Hook代码特征字符集。
  wParam
:短整型参数。
  lParam
:长整型参数。
  wParam,iParam
的取值随nCode不同而不同,它代表了某种类型的HOOK的某个特
 
定的动作。它们的典型值是包含了关于发送或者接收消息的信息。
 
至于以上的几个参数及返回值的具体含义,各种类型的钩子都不相同,所以您必

 

须查询WIN32 API 指南来得到不同类型钩子参数的详细定义以及它们返回值的意
 
义。(如果哪位朋友有时间和兴趣的话,请整理一下贴出来,顺便发给我一份,我的邮箱:
  wlclass163.com

 
譬如:
  WH_CALLWNDPROC
  nCode
只能是HC_ACTION,它代表有一个消息发送给了一个窗口
  wParam
如果非0,代表正被发送的消息
  lParam
指向CWPSTRUCT型结构体变量的指针
  return value:
未使用,返回0
  WH_MOUSE
  nCode
HC_ACTION HC_NOREMOVE
  wParam
包含鼠标的事件消息
  lParam
指向MOUSEHOOKSTRUCT型结构体变量的指针
  return value:
如果不处理返回0,否则返回非0

 

++++++++++++++++++++++++++
 
钩子的安装/卸载
  ++++++++++++++++++++++++++

 

现在我们知道了一些基本的理论,接下来开始讲解如何安装和卸载一个钩子。

 


 
安装钩子

 

使用SetWindowsHookEx函数(API函数),指定一个HOOK类型、自己的HOOK
 
过程是全局还是局部HOOK,同时给出HOOK过程的进入点,就可以轻松的安装你
 
自己的HOOK过程。
  SetWindowsHookEx
总是将你的HOOK函数放置在HOOK链的顶端。你可以使用
  CallNextHookEx
函数将系统消息传递给HOOK链中的下一个函数。
  [
注意]对于某些类型的HOOK,系统将向该类的所有HOOK函数发送消息,这时,
  HOOK
函数中的CallNextHookEx语句将被忽略。

 

全局(远程钩子)HOOK函数可以拦截系统中所有线程的某个特定的消息,为了
 
安装一个全局HOOK过程,必须在应用程序外建立一个DLL,并将该HOOK函数封
 
装到其中,应用程序在安装全局HOOK过程时必须先得到该DLL模块的句柄。将DLL
 
名传递给LoadLibrary 函数,就会得到该DLL模块的句柄;得到该句柄后,使用
  GetProcAddress
函数可以得到HOOK过程的地址。最后,使用SetWindowsHookEx
  HOOK
过程的首址嵌入相应的HOOK链中,SetWindowsHookEx传递一个模块句柄,
 
它为HOOK过程的进入点,线程标识符置为0,指出:该HOOK过程同系统中的所
 
有线程关联。如果是安装局部HOOK此时该HOOK函数可以放置在DLL中,也可以
 
放置在应用程序的模块段。

 

建议只在调试时使用全局HOOK函数。全局HOOK函数将降低系统效率,并且
 
会同其它使用该类HOOK的应用程序产生冲突。

 

SetWindowsHookEx函数的VB声明及参数解释:

 

Public Declare Function SetWindowsHookEx Lib  "user32" Alias "SetWindowsHookExA"
  (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal  dwThreadId
  As Long) As Long

 

SetWindowHookEx函数参数说明:
  idHook
:代表是何种Hook(也就是上面讲的14Hook

 

lpfn:代表处理Hook的过程所在的Address,这是一个CallBack Fucnction(也就是上
 
面讲的回调函数),当挂上某个Hook时,我们便得定义一个Function来当作某个信
 
息产生时,来处理它的Function。因这个参数是一个 FunctionAddress所以我们
 
固定将Hook Function放在.Bas中,并以AddressOf  HookFunc传入

 

hmod:代表.DLLhInstance,如果是Local Hook,该值可以是Null(VB中可传0
 
进去),而如果是Remote Hook,则可以使用GetModuleHandle(".dll名称")来传入。

 

dwThreadId:代表执行这个HookThreadId(线程ID),如果不设定是那个Thread
 
(线程)来做,则传0,而VBLocal Hook一般可传App.ThreadId进去ThreadID
 
是您安装该钩子函数后想监控的线程的ID号。该参数可以决定该钩子是局部的还
 
是系统范围的。如果该值为NULL,那么该钩子将被解释成系统范围内的,那它就
 
可以监控所有的进程及它们的线程。如果您指定了您自己进程中的某个线程ID 号,
 
那该钩子是一个局部的钩子。如果该线程ID是另一个进程中某个线程的ID,那该
 
钩子是一个全局的远程钩子。这里有两个特殊情况:WH_JOURNALRECORD
  WH_JOURNALPLAYBACK
总是代表局部的系统范围的钩子,之所以说是局部,是
 
因为它们没有必要放到一个DLL中。WH_SYSMSGFILTER 总是一个系统范围内
 
的远程钩子。其实它和WH_MSGFILTER钩子类似,如果把参数ThreadID设成0
 
的话,它们就完全一样了。

 

SetWindowHookEx函数回值:如果SetWindowsHookEx()成功,它会传回一个值,
 
代表目前的HookHandle,否则返回NULL。您必须保存该句柄,因为后面我们
 
还要它来卸载钩子。

 

CallNextHookEx函数的VB声明及参数解释:

 

Declare Function CallNextHookEx Lib "user32" Alias  "CallNextHookEx" (ByVal hHook
  As Long, ByVal ncode As Long, ByVal wParam As Long,lParam As Any) As Long

 

hHook值是SetWindowsHookEx()的传回值,nCode, wParam, lParam则是回调函数
 
中的三个参数。

 

在钩子子程中调用得到控制权的钩子函数在完成对消息的处理后,如果想要该消
 
息继续传递,那么它必须调用另外一个API函数CallNextHookEx来传递它,以执行
 
钩子链表所指的下一个钩子子过程。这个函数成功时返回钩子链中下一个钩子过程的
 
返回值,返回值的类型依赖于钩子的类型。

 

卸载钩子

 

要卸载一个钩子非常简单,只需要使用UnhookWindowsHookEx函数来卸载创建
 
的钩子。
 
函数声明:

 

Declare Function UnhookWindowsHookEx Lib "user32" Alias  "UnhookWindowsHookEx"
  (ByVal hHook As Long) As Long

 

参数说明:
  hHook
:是SetWindowsHookEx()的传回值,上面告诉过你要记下来嘛。^_^

 
18实例句柄

http://zhidao.baidu.com/question/83275743.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值