`
xitong
  • 浏览: 6197457 次
文章分类
社区版块
存档分类
最新评论

Hook技术简介

 
阅读更多
钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。
钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。这和前面我博客的窗口子类化都异曲同工,但是Hook可强大多了,我是这两天才开始看的,所以略知皮毛。

/* 钩子的原理 */

我听完孙鑫老师C++教程里的解释,觉得还是把Hook讲得比较形象,加上我自己的一些理解就觉得Hook原理不是很难。windows一直都是有自己处理各种消息的函数,Hook其实就能够做到程序员自己处理自己感兴趣的事情。这样说,假设Windows的消息就是马路上的车辆,一般情况下是Windows自己派人在检查,然后呢,Hook是拥有这个能力能在Windows自己安排的检查站之前也进行抽查,Hook根据程序员的需求可以变化,比如我就感兴趣100万以上的车(可能是的(*^__^*)),Hook就能在检查的时候专门找100万以上的车,至于其他不上档次的车Hook就放行,交还给Windows自己的检查站。同样Hook可以“为所欲为”,可以擅自设立一个检查站,也可以两个,三个···换成程序来说,钩子函数的工作原理是:当我们创建一个钩子时,WINDOWS会先在内存中创建一个数据结构,该数据结构包含了钩子的相关信息,然后把该结构体加到已经存在的钩子链表中去。新的钩子将加到老的前面。当一个事件发生时,如果我们安装的是一个局部钩子(下面有解释,暂时理解为你程序本身中的),我们进程中的钩子函数将被调用。

/* 钩子链表和函数 */

每一个Hook都有一个与之相关联的指针列表,称之为钩子链表,由系统来维护。被Hook子程调用的回调函数,也就是该钩子的各个处理子程。当与指定的Hook类型关联的消息发生时,系统就把这个消息传递到Hook子程。一些Hook子程可以只监视消息,或者修改消息,或者停止消息的前进,避免这些消息传递到下一个Hook子程或者目的窗口。最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。钩子子程是一个应用程序定义的回调函数(CALLBACKFunction),不能定义成某个类的成员函数,只能定义为普通的C函数。用以监视系统或某一特定类型的事件,这些事件可以是与某一特定线程关联的,也可以是系统中所有线程的事件。
钩子子程必须按照以下的语法:

LRESULT CALLBACK HookProc
(
int nCode, //指定是否需要处理该消息
WPARAM wParam,
LPARAM lParam //包含该消息的附加消息 ,
);
这个回调函数的名字可以随你取,但形式可一定要满足以上要求,其实钩子的回调函数和Windows的差不多一个德行。看看钩子函数的返回值,若是返回非0值,表示我们已经自己处理了该消息,则消息就不被传递到目标窗口过程。
看看LRESULT CallNextHookEx
( HHOOK hhk;
int nCode;
WPARAM wParam;

LPARAM lParam;)这个函数把钩子信息传递给下一个钩子函数,也就是可以理解成把车辆放行到下一个检查站,这个可以根据自己的需要进行调用。若是我们只设定了一个钩子函数,那么我们假设把钩子消息用CallNextHookEx传给下个钩子函数,因为不存在所以就传递回了目标窗口函数。


/* 钩子的安装和释放 */

调用SetWindowHookEx函数,该函数的原型如下:
HHOOK SetWindowsHookEx( int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId );返回值是一个hook的句柄。
idHook是我们感兴趣的消息类型,比如我们对鼠标消息感兴趣就是WH_MOUSE,再者比如键盘消息WH_KEYBOARD,我们可以通过查找Win32 API使用手册来找到自己感兴趣的消息。
第二个参数是钩子函数的地址,这里就有两种情况:其实钩子有两种,一种是局部钩子,这种钩子只能关注自己所在的进程的事件,另一种钩子叫做远程钩子,这里又有两种:1.基于线程的它将捕获其它进程中某一特定线程的事件。简言之,就是可以用来观察其它进程中的某一特定线程将发生的事件。2.系统范围的 将捕捉系统中所有进程将发生的事件消息。 看上去局部钩子的功能没有远程钩子的给力,但是凡事都是要付出代价的,远程钩子会影响系统的性能,特别是监视系统范围的钩子,因为要监视系统范围的消息,明显就会影响系统的速度。
第三个参数和第四个参数相关,所以一起解释。
如果第四个参数是NULL,则说明是全局钩子,那么就是钩子子程与所有的线程关联,此时第三个参数是程序实例句柄;
如果第三个参数是NULL,则说明钩子是局部钩子,说明子程代码位于当前进程,这时候第四个参数就是当前进程的ID,可以用GetCurrentThreadID()填充,或者可以保存实例来填充,再做介绍···
再看看钩子函数的卸载,用UnHookWindowsHookEx(HHOOK hhk);参数就是SetWindowsHookEx返回的句柄。


下面是是一个小程序,大概的功能就是实现在所在进程内的鼠标消息和键盘消息的截获,一旦点击了“LockMouse”那么就在目标窗口截获了所以鼠标的消息,这里实现的是屏蔽鼠标消息,只能通过按回车键恢复鼠标功能。若是点击了“LockKeyBoard”按钮,那么只能在编辑框输入0或者1,但是在没有点击的情况下是正常的编辑框。这点可是比窗口子类化更加简单。
#include "Windows.h"
#include "tchar.h"
#include "resource.h"


HINSTANCE g_hInstance ;
static HHOOK hHook = NULL;


INT_PTR CALLBACK ProcWinMain(HWND hWnd, UINT Msg, WPARAM wParam ,LPARAM lParam);
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam,LPARAM lParam);		
LRESULT CALLBACK BoardProc(int nCode, WPARAM wParam,LPARAM lParam);		


int WINAPI WinMain(     HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nCmdShow
				   )
{
	static TCHAR DlgName[] = _T("InnerHook");
	g_hInstance = hInstance ;
	DialogBoxParam(hInstance,DlgName,NULL,( DLGPROC)ProcWinMain,NULL);
	return 0;
}


INT_PTR CALLBACK ProcWinMain(   HWND hWnd, 
							 UINT Msg, 
							 WPARAM wParam, 
							 LPARAM lParam 
							 )
{
	static TCHAR unLockStr[] = _T("Unlocking");
	static TCHAR LockStr[] = _T("Locking");
	static BOOL isLock = FALSE;
	static BOOL isLock2 = FALSE;
	static HHOOK hHook2 = NULL;
	switch(Msg)
	{
	case WM_INITDIALOG:
		{
			SetFocus(GetDlgItem(hWnd,IDC_EDITTEXT));
		}
		break;


	case WM_CLOSE:
		EndDialog(hWnd,NULL);
		break;
	case WM_COMMAND:
		{
			switch(LOWORD(wParam))
			{
				case ID_BTNHOOKBOARD :
				{
					if(isLock == FALSE)
					{
						hHook = SetWindowsHookEx(WH_KEYBOARD,BoardProc,NULL,GetCurrentThreadId());
						SetDlgItemText(hWnd,ID_BTNHOOKBOARD,LockStr);
						isLock = TRUE;
					}
					else
					{
						SetDlgItemText(hWnd,ID_BTNHOOKBOARD,unLockStr);
						isLock = FALSE;	
						UnhookWindowsHookEx(hHook);
					}
				}
				break;
				case ID_BTNHOOKMOUSE :
				{
					if(isLock2 == FALSE)
					{
						hHook2 = SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId());
						SetDlgItemText(hWnd,ID_BTNHOOKMOUSE,LockStr);
						isLock2 = TRUE;
					}
					else
					{
						SetDlgItemText(hWnd,ID_BTNHOOKMOUSE,unLockStr);
						isLock2 = FALSE;	
						UnhookWindowsHookEx(hHook2);
					}
				}
				break;
			}
		}
		break;
	default:
		return FALSE; 
	}
	return TRUE;
}


LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam,LPARAM lParam)
{
	return 1;			//返回非0值,表示处理了该消息
}


LRESULT CALLBACK BoardProc(int nCode, WPARAM wParam,LPARAM lParam)
{
	if (wParam == VK_RETURN || wParam == '1' || wParam == '0')
	{
		return CallNextHookEx(hHook,nCode,wParam,lParam);	//表示不处理该消息,交还给Windows自己处理
	}
	else
		return 1;		//表示已经处理了该消息
}

参考资料

http://www.microsoft.com/china/community/program/originalarticles/techdoc/hook.mspx

《Windows+sdk系列文章》


分享到:
评论

相关推荐

    【推荐】超全的移动安全自学资料精编合集(43份).zip

    Android安全Hook: Hook技术简介 Android安全Hook: Xposed源码分析(一) Android安全Hook: Xposed源码分析(二) Android安全Hook: Xposed源码分析(三) Android安全Hook: Xposed源码分析(四)

    易语言hook技术专题讲解视频教程

    hook简介.mp4。第一章、HOOK原理,手写HOOK.mp4。第七章、Windows消息Hook.mp4。第三章、APIHOOK_上.mp4。第二章、HOOK实现,远程HOOK.mp4。第五章、APIHOOK_下.mp4。第八章、拦截API返回值(完结).mp4。第六章、...

    移动安全系列教学下载共43份.zip

    Android安全Hook--35--Hook技术简介.pdf Android安全Hook--36--Xposed源码分析(一).pdf Android安全Hook--37--Xposed源码分析(二).pdf Android安全Hook--38--Xposed源码分析(三).pdf Android安全Hook--39--...

    浅谈HOOK技术在VC编程中的应用

    hook的基本简介,使用平台;应用的技术细节

    yoyiyi#SoleilNotes#Hook技术1

    1简介对象 A 调用 对象 B 之前做一些处理,起到欺上瞒下的作用,Hook 就是一个钩子,也称 Hook 点,有了 Hook,可以在进程间进行行为更改。Hoo

    Android上玩玩Hook:CydiaSubstrate实战

    摘要:Hook的出现为开发者希望通过一个程序改变其他程序的某些行为的想法开拓了解决道路,而作为一款基于Hook的代码修改框架,CydiaSubstrate可以修改任何...还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生

    深入Linux网络核心堆栈

    1 - 简介 1.1 - 本文涉及的内容 1.2 - 本文不涉及的内容 2 - 各种Netfilter hook及其用法 2.1 - Linux内核对数据包的处理 2.2 - Netfilter对IPv4的hook 3 - 注册和注销Netfilter hook 4 - Netfilter 基本的数据...

    Visual C++2010开发权威指南.part05

    10.7 Hook技术 446 10.7.1 Hook函数类型 446 10.7.2 使用Hook函数 449 10.7.3 Hook鼠标 449 10.7.4 Hook键盘 450 10.8 小结 452 第11章 Visual C++ 2010 MFC ActiveX 第11章 控件 454 11.1 ActiveX控件简介 454 11.2...

    JavaCompiler --JDK6 API的简介(java动态编译)

    java动态编译的几种技术介绍。JavaCompiler --JDK6 API的简介(java动态编译)

    exposed:一个无需使用root即可进行恢复或不进行恢复的Xposed库(或修改系统映像等。)

    简介 暴露的致力于为App提供Xposed运行环境。基本思想是劫持APP进程启动的入口,加载Xposed插件以及hook框架 。 暴露的本质上是一个Xposed与APP过程之间的兼容层,它给Xposed模块提供运行环境(如插件加载,hook...

    Android代码-android-advanced-decode

    第14章 Hook技术 chapter_15 第15章 插件化技术 本书内容 本书共分为17章,各章内容如下: 第1章介绍Android系统架构、系统源码目录和如何阅读源码,带领大家走进Android系统源码的世界。 第2章介绍Android系统...

    ProxyTest.zip

    Java动静态代理机制简介,尤其是动态代理,结合反射机制,为后续的java hook技术打下基础。动态代理需实现java.lang.reflect.InvocationHandler接口和 java.lang.reflect.Proxy 类的支持。

    软件加密技术内幕

    7.3.4 hook 相关的api(防止loader和调试api) 7.4 使用sdk把程序和壳溶为一体 7.4.1 sdk的意义 7.4.2 做一个带sdk的壳 7.5 后记:关于壳和程序的思考 第8章 Visual Basic 6 逆向工程 8.1 简介 8.2 P-code传奇 ...

    awesome-reverse:awesome-逆向基础入门,包括JS、安卓APPNative

    简介 主要总结个人学习逆向相关所遇到的一些技术知识点和路径,因为逆向这个技术栈没有系统的规划路径,所以想要将工作中所遇到的和面试到的一些相关知识总结,面向逆向新人提供一些微薄的帮助。 本项目将会随着我的...

    加密解密.技术内幕.chm

    7.3.3 外部检测(使用dll) 7.3.4 hook 相关的api(防止loader和调试api)7.4 使用sdk把程序和壳溶为一体 7.4.1 sdk的意义 7.4.2 做一个带sdk的壳7.5 后记:关于壳和程序的思考 第8章 Visual Basic 6 逆向工程8.1 简介8.2...

    U盘防拷精灵1.3 内存注册机.

    本软件为了适应这种要求而开发制作,软件采用Microsoft公司最新USB驱动和操作系统底层HOOK技术实现,在业界处于领先水平,有效防止非法用户访问你加密的驱动器,软件可以实现: ● 彻底禁止用户使用电脑上的USB存储...

    软件加密技术内幕 chm

    7.3.4 hook 相关的api(防止loader和调试api) 7.4 使用sdk把程序和壳溶为一体 7.4.1 sdk的意义 7.4.2 做一个带sdk的壳 7.5 后记:关于壳和程序的思考 第8章 Visual Basic 6 逆向工程 8.1 简介 8.2 P-...

Global site tag (gtag.js) - Google Analytics