MFC中的HOOK编程
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
);
当中第四个參数:
//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编程的更多相关文章
- 多线程编程之二 ---MFC中的多线程开发
下载源代码 五.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消 ...
- 总结《二》MFC中WinMain和CALLBACK
MFC中WinMain和回调函数CALLBACK 一,路线 1.一般普通窗口或控件建立调用的CWnd :: CreateEx函数 2.经过资源对话框创建的即不调用的CWnd ...
- 让你轻松掌握 Python 中的 Hook 钩子函数
1. 什么是Hook 经常会听到钩子函数(hook function)这个概念,最近在看目标检测开源框架mmdetection,里面也出现大量Hook的编程方式,那到底什么是hook?hook的作用是 ...
- 转:MFC中创建多线程
MFC中创建多线程 MFC的多线程函数必须声明为静态的或者是全局函数(不同的在于全局函数不能访问类的私有静态成员,而静态类函数可以):但这样的线程函数只能访问静态的成员变量,要实现访问类的其他成员 ...
- php hook编程机制
说明 hook,中文翻译为钩子,编程中的钩子类似我们现实中的钩子,需要挂在东西的时候 直接挂载到上面即可.程序中也是,需要运行的代码挂载到上面即可. 具体思想就是:在项目代码中, ...
- MFC中线程相关知识
MFC中把线程分为两种类型,UI线程和工作者线程. MFC中启动一个线程的最好方法是调用AfxBeginThread,有两个版本,一个用于启动Ui线程,另外一个用于启动工作者线程.在MFC程序中,只有 ...
- MFC控件GDI编程
MFC控件GDI编程 一丶学习内容 1.了解常用的GDI函数绘图. 2.使用常用的画笔画刷. 二丶常用的GDI函数绘图 上方则为我们常用的GDI函数了. 画线 矩形. 以及圆 等等. 2.1 画线代码 ...
- MFC中创建多线程
1. 列举几种进程的同步机制,并比较其优缺点. 原子操作 信号量机制 自旋锁 管程,会合,分布式系统 2. 进程之间通信的途径 共享存储系统 消息传递系统 ...
- MFC中的一般经验之谈2
MFC一般类成员m_iAge,命名原则,且MFC中类定义以C开头原则,这些原则便于理解以及增强代码的可读性.MFC是一个用窗口作为用户交互的方式,一般框架类.视图类.以及窗口上的控件都是继承CWnd类 ...
随机推荐
- 因host命令导致无法正常SHUTDOWN的实验
SHUTDOWN有几个參数能够使用: SHUTDOWN NORMAL:NORMAL也是默认的子句,运行的条件是 No new connections are allowed after the sta ...
- Java泛型Restletclient
写一个与restletserver通信的client类.用于測试通信是否成功.而且进行交互.为了方便其它人使用.于是,写一个通用的方法封装起来,但是中途却放生了一些问题. 依照正常写法,顺序走下来是这 ...
- Java的socket服务UDP协议
练习1 接收类 package com.socket.demo; import java.io.IOException; import java.net.DatagramPacket; import ...
- HDU 4946 Area of Mushroom 凸包
链接:pid=4946">http://acm.hdu.edu.cn/showproblem.php?pid=4946 题意:有n个人.在位置(xi,yi),速度是vi,假设对于某个点 ...
- StackExchange.Redis 使用 (一)
在StackExchange.Redis中最重要的对象是ConnectionMultiplexer类, 它存在于StackExchange.Redis命名空间中.这个类隐藏了Redis服务的操作细节, ...
- JavaScript变量作用域和内存问题(二)
执行环境是js中特别重要的概念,是指变量或者函数可以访问其他数据,定义自己的行为.每个执行环境都有一个与之相对应的变量对象,执行环境中定义的所有变量和函数都保存在这个变量中,我们看不到这个变量,但是后 ...
- Java TCP/UDP网络通信编程
本文转自:http://www.cnblogs.com/cdtarena/archive/2013/04/10/3012282.html 网络应用中基本上都是TCP(Transmission Cont ...
- JAVA: httpclient 详细说明——第四章;
httpclient 具体解释--第一章. httpclient 具体解释--第二章: httpclient 具体解释--第三章: httpclient 具体解释--第四章: httpclient 具 ...
- C# 闭包问题
C# 闭包问题-你被”坑“过吗? 引言 闭包是什么?以前看面试题的时候才发现这个名词. 闭包在实际项目中会有什么问题?现在就让我们一起来看下这个不太熟悉的名词. 如果在实际工作中用到了匿名函数和lam ...
- JavaScript 初识Promise 对象
什么是Promise? 其实, Promise就是一个类,而且这个类已经成为ES6的标准,是 ECMAScript 6 规范的重要特性之一.这个类目前在chrome32.Opera19.Firefox ...