莱芜找工作网站,360建筑网撤销自己的简历怎么撤销,企业邮箱 腾讯,网站维护员招聘C#环境下的钩子详解 摘自网上供自己备查: http://www.csharpwin.com/csharpspace/2423.shtml 1、 WINDOWS的消息机制 2、 HOOK介绍 3、 HOOK链 4、 HOOK钩子的作用范围 5、 HOOK类型 6、 回调函数 7、 HOOK钩子的安装与卸载 8、 HOOK实例演示  WINDOWS的消息机制  Windows系统是…   C#环境下的钩子详解    摘自网上供自己备查: http://www.csharpwin.com/csharpspace/2423.shtml   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它对应于窗口的Activate事件。对于窗口来说诸如Load,MouseDown等事件实际上对应的是窗口内部的消息处理程序这些程序对于用户来讲是不可见的。 类似地命令按钮也有消息处理程序它的处理程序响应诸如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共有14种HOOKS每一种类型的Hook可以使应用程序能够监视不同 类型的系统消息处理机制。下面描述所有可以利用的Hook类型的发生时机。这些常 数值均可以API浏览器里查到 1、WH_CALLWNDPROC和WH_CALLWNDPROCRET Hooks       WH_CALLWNDPROC和WH_CALLWNDPROCRET Hooks使你可以监视发送到 窗口过程的消息。系统在消息发送到接收窗口过程之前调用WH_CALLWNDPROC Hook子过程并且在窗口过程处理完消息之后调用WH_CALLWNDPROCRET Hook 子过程。       WH_CALLWNDPROCRET Hook传递指针到CWPRETSTRUCT结构再传递到 Hook子过程。CWPRETSTRUCT结构包含了来自处理消息的窗口过程的返回值同 样也包括了与这个消息关联的消息参数。 2、WH_CBT Hook       在以下事件之前系统都会调用WH_CBT Hook子过程这些事件包括       1. 激活建立销毁最小化最大化移动改变尺寸等窗口事件       2. 完成系统指令       3. 来自系统消息队列中的移动鼠标键盘事件       4. 设置输入焦点事件       5. 同步系统消息队列事件。            Hook子过程的返回值确定系统是否允许或者防止这些操作中的一个。 3、WH_DEBUG Hook       在系统调用系统中与其它Hook关联的Hook子过程之前系统会调用 WH_DEBUG Hook子过程。你可以使用这个Hook来决定是否允许系统调用与其它 Hook关联的Hook子过程。 4、WH_FOREGROUNDIDLE Hook       当应用程序的前台线程处于空闲状态时可以使用WH_FOREGROUNDIDLE Hook执行低优先级的任务。当应用程序的前台线程大概要变成空闲状态时系统就 会调用WH_FOREGROUNDIDLE Hook子过程。 5、WH_GETMESSAGE Hook       应用程序使用WH_GETMESSAGE Hook来监视从GetMessage or PeekMessage函 数返回的消息。你可以使用WH_GETMESSAGE Hook去监视鼠标和键盘输入以及 其它发送到消息队列中的消息。 6、WH_JOURNALPLAYBACK Hook       WH_JOURNALPLAYBACK Hook使应用程序可以插入消息到系统消息队列。可 以使用这个Hook回放通过使用WH_JOURNALRECORD Hook记录下来的连续的鼠 标和键盘事件。只要WH_JOURNALPLAYBACK Hook已经安装正常的鼠标和键盘 事件就是无效的。WH_JOURNALPLAYBACK Hook是全局Hook它不能象线程特定 Hook一样使用。WH_JOURNALPLAYBACK Hook返回超时值这个值告诉系统在处 理来自回放Hook当前消息之前需要等待多长时间毫秒。这就使Hook可以控制实 时事件的回放。WH_JOURNALPLAYBACK是system-wide local hooks它们不会被 注射到任何行程地址空间。 7、WH_JOURNALRECORD Hook      WH_JOURNALRECORD Hook用来监视和记录输入事件。典型的可以使用这 个Hook记录连续的鼠标和键盘事件然后通过使用WH_JOURNALPLAYBACK Hook 来回放。WH_JOURNALRECORD Hook是全局Hook它不能象线程特定Hook一样 使用。WH_JOURNALRECORD是system-wide local hooks它们不会被注射到任何行 程地址空间。 8、WH_KEYBOARD Hook       在应用程序中WH_KEYBOARD Hook用来监视WM_KEYDOWN and WM_KEYUP消息这些消息通过GetMessage or PeekMessage function返回。可以使 用这个Hook来监视输入到消息队列中的键盘消息。 9、WH_KEYBOARD_LL Hook       WH_KEYBOARD_LL Hook监视输入到线程消息队列中的键盘消息。 10、WH_MOUSE Hook       WH_MOUSE Hook监视从GetMessage 或者 PeekMessage 函数返回的鼠标消息。 使用这个Hook监视输入到消息队列中的鼠标消息。 11、WH_MOUSE_LL Hook       WH_MOUSE_LL Hook监视输入到线程消息队列中的鼠标消息。 12、WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks       WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以监视菜单滚动 条消息框对话框消息并且发现用户使用ALTTAB or ALTESC 组合键切换窗口。 WH_MSGFILTER Hook只能监视传递到菜单滚动条消息框的消息以及传递到通 过安装了Hook子过程的应用程序建立的对话框的消息。WH_SYSMSGFILTER Hook 监视所有应用程序消息。            WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks使我们可以在模式循环期间 过滤消息这等价于在主消息循环中过滤消息。      通过调用CallMsgFilter function可以直接的调用WH_MSGFILTER Hook。通过使用这 个函数应用程序能够在模式循环期间使用相同的代码去过滤消息如同在主消息循 环里一样。 13、WH_SHELL Hook       外壳应用程序可以使用WH_SHELL Hook去接收重要的通知。当外壳应用程序是 激活的并且当顶层窗口建立或者销毁时系统调用WH_SHELL Hook子过程。     WH_SHELL 共有钟情况 1. 只要有个top-level、unowned 窗口被产生、起作用、或是被摧毁 2. 当Taskbar需要重画某个按钮 3. 当系统需要显示关于Taskbar的一个程序的最小化形式 4. 当目前的键盘布局状态改变 5. 当使用者按CtrlEsc去执行Task Manager或相同级别的程序。       按照惯例外壳应用程序都不接收WH_SHELL消息。所以在应用程序能够接 收WH_SHELL消息之前应用程序必须调用SystemParametersInfo function注册它自 己。  回调函数HOOK处理子过程  为了拦截和处理特定的消息你可以使用SetWindowsHookEx函数下面将具体 说明这些函数的声明及各种参数在该类型的HOOK链中安装你自己的处理HOOK 的子过程回调函数。只要您安装的钩子的消息事件类型发生WINDOWS就将调 用钩子函数。譬如您安装的钩子是WH_MOUSE类型那么只要有一个鼠标事件发生 时该钩子函数就会被调用。不管您安装的是那一类型钩子钩子函数的原型都时是 一样的语法如下 public int MyHook(int nCode, Int32 wParam, IntPtr lParam){ //处理代码 } 其中MyHook可以随便命名其它不能变。该函数必须放在模块段。 参数说明 nCode指定HOOK传入的信息类型。Hook子过程使用这个参数来确定任务。这个 参数的值依赖于Hook类型每一种Hook都有自己的Hook代码特征字符集。 wParam短整型参数。 lParam长整型参数。 wParam,iParam的取值随nCode不同而不同它代表了某种类型的HOOK的某个特 定的动作。它们的典型值是包含了关于发送或者接收消息的信息。 至于以上的几个参数及返回值的具体含义各种类型的钩子都不相同所以您必须查询WIN32 API 指南来得到不同类型钩子参数的详细定义以及它们返回值的意 义。譬如 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函数的C#声明及参数解释 public delegate int HookProc(int nCode, int wParam, IntPtr lParam);[DllImport(user32.dll, CharSet  CharSet.Auto,CallingConvention  CallingConvention.StdCall, SetLastError  true)]public static extern int SetWindowsHookEx(int idHook,HookProc lpfn,IntPtr hMod,int dwThreadId); SetWindowHookEx函数参数说明 idHook代表是何种Hook也就是上面讲的14种Hook HookProc:代表处理Hook的过程的委托这是一个CallBack Fucnction(也就是上 面讲的回调函数)当挂上某个Hook时我们便得定义一个Function来当作某个信 息产生时来处理它的Functionhmod代表.DLL的hInstance如果是Local Hook该值可以是Null而如果是Remote Hook则可以使用System.Reflection.GetModule(.dll名称)来传入。 dwThreadId代表执行这个Hook的ThreadId线程ID如果是全局钩子则传0ThreadID是您安装该钩子函数后想监控的线程的ID号。该参数可以决定该钩子是局部的还 是系统范围的。如果该值为NULL那么该钩子将被解释成系统范围内的那它就 可以监控所有的进程及它们的线程。如果您指定了您自己进程中的某个线程ID 号 那该钩子是一个局部的钩子。如果该线程ID是另一个进程中某个线程的ID那该 钩子是一个全局的远程钩子。这里有两个特殊情况WH_JOURNALRECORD 和 WH_JOURNALPLAYBACK总是代表局部的系统范围的钩子之所以说是局部是 因为它们没有必要放到一个DLL中。WH_SYSMSGFILTER 总是一个系统范围内 的远程钩子。其实它和WH_MSGFILTER钩子类似如果把参数ThreadID设成0 的话它们就完全一样了。 SetWindowHookEx函数回值 如果SetWindowsHookEx()成功它会传回一个值 代表目前的Hook的Handle否则返回NULL。您必须保存该句柄因为后面我们 还要它来卸载钩子。 CallNextHookEx函数的C#声明及参数解释 [DllImport(user32.dll, CharSet  CharSet.Auto,CallingConvention  CallingConvention.StdCall)]public static extern int CallNextHookEx(int idHook,int nCode,int wParam,IntPtr lParam);hHook值是SetWindowsHookEx()的传回值nCode, wParam, lParam则是回调函数 中的三个参数。 在钩子子程中调用得到控制权的钩子函数在完成对消息的处理后如果想要该消 息继续传递那么它必须调用另外一个API函数CallNextHookEx来传递它以执行 钩子链表所指的下一个钩子子过程。这个函数成功时返回钩子链中下一个钩子过程的 返回值返回值的类型依赖于钩子的类型。   ◆ 卸载钩子 要卸载一个钩子非常简单只需要使用UnhookWindowsHookEx函数来卸载创建 的钩子。 函数声明 [DllImport(user32.dll, CharSet  CharSet.Auto,CallingConvention  CallingConvention.StdCall, SetLastError  true)]public static extern int UnhookWindowsHookEx(int idHook); 参数说明 hHook是SetWindowsHookEx()的传回值。          posted on 2013-01-17 14:23 Alfa 阅读(...) 评论(...) 编辑 收藏   转载于:https://www.cnblogs.com/wuyifu/archive/2013/01/17/2864399.html