HOOK,n.钩, 吊钩,通常称钩子。


在计算机中,是Windows消息处理机制的一个平台,应用程序能够在上面设置子程以监视指定窗体的某种消息,并且所监视的窗体能够是其它进程所创建的。当消息到达后,在目标窗体处理函数之前处理它。钩子机制同意应用程序截获处理window消息或特定事件。
      钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗体前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即能够加工处理(改变)该消息,也能够不作处理而继续传递该消息,还能够强制结束消息的传递。


Hook原理
      每个Hook都有一个与之相关联的指针列表,称之为钩子链表,由系统来维护。这个列表的指针指向指定的,应用程序定义的,被Hook子程调用的回调函数,也就是该钩子的各个处理子程。当与指定的Hook类型关联的消息发生时,系统就把这个消息传递到Hook子程。一些Hook子程能够仅仅监视消息,或者改动消息,或者停止消息的前进,避免这些消息传递到下一个Hook子程或者目的窗体。近期安装的钩子放在链的開始,而最早安装的钩子放在最后,也就是后增加的先获得控制权。
      Windows 并不要求钩子子程的卸载顺序一定得和安装顺序相反。每当有一个钩子被卸载,Windows 便释放其占用的内存,并更新整个Hook链表。假设程序安装了钩子,可是在尚未卸载钩子之前就结束了,那么系统会自己主动为它做卸载钩子的操作。
  钩子子程是一个应用程序定义的回调函数(CALLBACK Function),不能定义成某个类的成员函数,仅仅能定义为普通的C函数。用以监视系统或某一特定类型的事件,这些事件能够是与某一特定线程关联的,也能够是系统中全部线程的事件。
  系统钩子与线程钩子
      SetWindowsHookEx()函数的最后一个參数决定了此钩子是系统钩子还是线程钩子。
      线程勾子用于监视指定线程的事件消息。线程勾子一般在当前线程或者当前线程派生的线程内。
      系统勾子监视系统中的全部线程的事件消息。由于系统勾子会影响系统中全部的应用程序,所以勾子函数必须放在独立的动态链接库(DLL) 中。系统自己主动将包括“钩子回调函数”的DLL映射到受钩子函数影响的全部进程的地址空间中,即将这个DLL注入了那些进程。


//MSDN

HHOOK SetWindowsHookEx(
int
idHook, // hook type
HOOKPROC lpfn, // hook procedure
HINSTANCE hMod, // handle to application instance
DWORD dwThreadId // thread identifier
);
当中第四个參数:
dwThreadId
[in] Specifies the identifier of the thread with which the hook procedure is to be associated.
If this parameter is zero, the hook procedure is associated with all existing threads running
in the same desktop as the calling thread.

//For example


DLL中设置HOOK


void SetHook(HWND hwnd)
{
 g_hWnd=hwnd;//这样的传递调用它的进程的句柄的方法非常巧妙
 g_hMouse=SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("Hook"),0);//第四个參数为0,表示此钩子关系当前桌面的全部进程,系统自己主动将包括“钩子回调函数”的DLL映射到受钩子函数影响的全部进程的地址空间中,即将这个DLL注入了那些进程。
 g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,GetModuleHandle("Hook"),0);
}


HOOK的应用:
  观察模式
  最为常常使用,像Windows提供的SetWindowHook就是典型地为这类应用准备的。并且这也是最普遍的使用方法。
  这个模式的特点是,在事情发生的时候,发出一个通知信息。观察者仅仅能够查看过程中的信息,依据自己关心的内容处理自己的业务,可是不能够更改原来的流程。
  如全局钩子中,常常使用的鼠标消息、键盘消息的监视等应用。金山词霸屏幕取词的功能是一个典型的应用(详细技术能够參考此类文章)。
  注入模式
  这个模式和观察模式最大的不一样的地方在于,注入的代码是为了扩展原始代码的功能业务。插件模式是此类模式的典型案例。
  无论瘦核心的插件系统(如Eclipse)还是胖核心的插件系统(如Delphi、Visual Studio等IDE环境),其对外提供的插件接口都是为了扩展本身系统的功能的。
  这样的扩展的应用方式的典型特点,就是新的扩展代码和原来的代码会协调处理同类业务。
  替换模式
  假设针相应用目的不同,能够叫修复模式或破解模式。前者是为了改动系统中的BUG,后者是为了破解原有系统的限制。
  非常多黑客使用此种模式,将訪问加密锁的DLL中的导出表,替换成自己的函数,这样跳过对软件的控制代码。这类应用的难点是,找出函数的參数。
  这类模式的特点是,原有的代码会被新的代码所替换。
  前面三个是基本模式,还有非常多和实际应用相关的模式。
  集权模式
  此类模式的出现,大都是为了在全部系统中,统一处理某类事情。它的特点不在于注入的方式,而在于处理的模式。
  这个模式,大都应用到某类服务上,比方键盘服务,鼠标服务,打印机服务等等特定服务上。通过统一接管此类服务的訪问,限制或者协调对服务的訪问。
  比方键盘锁功能的实现,就是临时关闭键盘的全部应用。
  这类模式的特点主要会和特点服务有关联。
  修复模式
  替换模式的一种,这里强调的是其应用的目的是为了修复或扩展原有系统的功能。
  破解模式
  替换模式的一种,这里强调的是其应用的目的是为了跳过原有系统的一部分代码。如加密检測代码,网络检測代码等等。
  插件模式
  注入模式的一种,在系统的内部直接依靠HOOK机制进行扩展业务功能。
  共享模式
  这类应用中,常常是为了获取对方的数据。必定我希望获取对方系统中,全部字符串的值。能够通过替换对方的内存管理器,导出全部字符串。
  这个应用比較特殊。只是其特点在于,目的是达到系统之间的数据共享。
  事实上现,可能是观察模式,也可能是替换模式。

MFC中的HOOK编程的更多相关文章

  1. 多线程编程之二 ---MFC中的多线程开发

    下载源代码 五.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消 ...

  2. 总结《二》MFC中WinMain和CALLBACK

    MFC中WinMain和回调函数CALLBACK 一,路线        1.一般普通窗口或控件建立调用的CWnd :: CreateEx函数        2.经过资源对话框创建的即不调用的CWnd ...

  3. 让你轻松掌握 Python 中的 Hook 钩子函数

    1. 什么是Hook 经常会听到钩子函数(hook function)这个概念,最近在看目标检测开源框架mmdetection,里面也出现大量Hook的编程方式,那到底什么是hook?hook的作用是 ...

  4. 转:MFC中创建多线程

    MFC中创建多线程   MFC的多线程函数必须声明为静态的或者是全局函数(不同的在于全局函数不能访问类的私有静态成员,而静态类函数可以):但这样的线程函数只能访问静态的成员变量,要实现访问类的其他成员 ...

  5. php hook编程机制

    说明 hook,中文翻译为钩子,编程中的钩子类似我们现实中的钩子,需要挂在东西的时候    直接挂载到上面即可.程序中也是,需要运行的代码挂载到上面即可.         具体思想就是:在项目代码中, ...

  6. MFC中线程相关知识

    MFC中把线程分为两种类型,UI线程和工作者线程. MFC中启动一个线程的最好方法是调用AfxBeginThread,有两个版本,一个用于启动Ui线程,另外一个用于启动工作者线程.在MFC程序中,只有 ...

  7. MFC控件GDI编程

    MFC控件GDI编程 一丶学习内容 1.了解常用的GDI函数绘图. 2.使用常用的画笔画刷. 二丶常用的GDI函数绘图 上方则为我们常用的GDI函数了. 画线 矩形. 以及圆 等等. 2.1 画线代码 ...

  8. MFC中创建多线程

    1.   列举几种进程的同步机制,并比较其优缺点. 原子操作    信号量机制   自旋锁    管程,会合,分布式系统 2.   进程之间通信的途径 共享存储系统       消息传递系统      ...

  9. MFC中的一般经验之谈2

    MFC一般类成员m_iAge,命名原则,且MFC中类定义以C开头原则,这些原则便于理解以及增强代码的可读性.MFC是一个用窗口作为用户交互的方式,一般框架类.视图类.以及窗口上的控件都是继承CWnd类 ...

随机推荐

  1. Hibernate-----5、持久化对象

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGVrZXdhbmd6aQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  2. C# - is

     Checks if an object is compatible with a given type. An is expression evaluates to true if the pr ...

  3. LeetCode——Add Binary

    Given two binary strings, return their sum (also a binary string). For example, a = "11" b ...

  4. uav 11258 String Partition (DP)

    Problem F - String Partition                                                                         ...

  5. 文章13称号 Add Two Numbers

    You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...

  6. Python学习笔记23:Django构建一个简单的博客网站(一个)

    在说如何下载和安装Django,本节将重点讨论如何使用Django站点. 一 新建project 命令:django-admin startproject mysite # 有的须要输入:django ...

  7. hdu 3572 Task Schedule (dinic算法)

    pid=3572">Task Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  8. Python网络02 Python服务器进化

    原文:Python网络02 Python服务器进化 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! **注意,在Python 3. ...

  9. Javascript入门视频教程

    1,第一节 http://pan.baidu.com/play/video#video/path=%2F%E6%95%99%E5%AD%A61.mov&t=-1 2,第二节 http://pa ...

  10. 4.4、Libgdx用法查询执行环境相关性

    (原版的:http://www.libgdx.cn/topic/46/4-4-libgdx%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%E6%9F%A5%E8%AF%A2% ...