Hook解释 Hook是Windows中提供的一种用以替换DOS下“中断”的系统机制,中文译为“挂钩”或“钩子”。在对特定的系统事件进行hook后,一旦发生已hook事件,对该事件进行hook的程序就会受到系统的通知,这时程序就能在第一时间对该事件做出响应。 另一解释: 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。 钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。 Hook原理 每一个Hook都有一个与之相关联的指针列表,称之为钩子链表,由系统来维护。这个列表的指针指向指定的,应用程序定义的,被Hook子程调用的回调函数,也就是该钩子的各个处理子程。当与指定的Hook类型关联的消息发生时,系统就把这个消息传递到Hook子程。一些Hook子程可以只监视消息,或者修改消息,或者停止消息的前进,避免这些消息传递到下一个Hook子程或者目的窗口。最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。 Windows 并不要求钩子子程的卸载顺序一定得和安装顺序相反。每当有一个钩子被卸载,Windows 便释放其占用的内存,并更新整个Hook链表。如果程序安装了钩子,但是在尚未卸载钩子之前就结束了,那么系统会自动为它做卸载钩子的操作。 钩子子程是一个应用程序定义的回调函数(CALLBACK Function),不能定义成某个类的成员函数,只能定义为普通的C函数。用以监视系统或某一特定类型的事件,这些事件可以是与某一特定线程关联的,也可以是系统中所有线程的事件。 系统钩子与线程钩子 SetWindowsHookEx()函数的最后一个参数决定了此钩子是系统钩子还是线程钩子。 线程勾子用于监视指定线程的事件消息。线程勾子一般在当前线程或者当前线程派生的线程内。 系统勾子监视系统中的所有线程的事件消息。因为系统勾子会影响系统中所有的应用程序,所以勾子函数必须放在独立的动态链接库(DLL) 中。系统自动将包含“钩子回调函数”的DLL映射到受钩子函数影响的所有进程的地址空间中,即将这个DLL注入了那些进程。 几点说明: (1)如果对于同一事件(如鼠标消息)既安装了线程勾子又安装了系统勾子,那么系统会自动先调用线程勾子,然后调用系统勾子。 (2)对同一事件消息可安装多个勾子处理过程,这些勾子处理过程形成了勾子链。当前勾子处理结束后应把勾子信息传递给下一个勾子函数。 (3)勾子特别是系统勾子会消耗消息处理时间,降低系统性能。只有在必要的时候才安装勾子,在使用完毕后要及时卸载。 Hook的应用模式 观察模式 最为常用,像Windows提供的SetWindowHook就是典型地为这类应用准备的。而且这也是最普遍的用法。 这个模式的特点是,在事情发生的时候,发出一个通知信息。观察者只可以查看过程中的信息,根据自己关心的内容处理自己的业务,但是不可以更改原来的流程。 如全局钩子中,经常使用的鼠标消息、键盘消息的监视等应用。金山词霸屏幕取词的功能是一个典型的应用(具体技术可以参考此类文章)。 注入模式 这个模式和观察模式最大的不一样的地方在于,注入的代码是为了扩展原始代码的功能业务。插件模式是此类模式的典型案例。 不管瘦核心的插件系统(如Eclipse)还是胖核心的插件系统(如Delphi、Visual Studio等IDE环境),其对外提供的插件接口都是为了扩展本身系统的功能的。 这种扩展的应用方式的典型特点,就是新的扩展代码和原来的代码会协调处理同类业务。 替换模式 如果针对应用目的不同,可以叫修复模式或破解模式。前者是为了修改系统中的BUG,后者是为了破解原有系统的限制。 很多黑客使用此种模式,将访问加密锁的DLL中的导出表,替换成自己的函数,这样跳过对软件的控制代码。这类应用的难点是,找出函数的参数。 这类模式的特点是,原有的代码会被新的代码所替换。 前面三个是基本模式,还有很多和实际应用相关的模式。 集权模式 此类模式的出现,大都是为了在全部系统中,统一处理某类事情。它的特点不在于注入的方式,而在于处理的模式。 这个模式,大都应用到某类服务上,比如键盘服务,鼠标服务,打印机服务等等特定服务上。通过统一接管此类服务的访问,限制或者协调对服务的访问。 比如键盘锁功能的实现,就是暂时关闭键盘的所有应用。 这类模式的特点主要会和特点服务有关联。 修复模式 替换模式的一种,这里强调的是其应用的目的是为了修复或扩展原有系统的功能。 破解模式 替换模式的一种,这里强调的是其应用的目的是为了跳过原有系统的一部分代码。如加密检测代码,网络检测代码等等。 插件模式 注入模式的一种,在系统的内部直接依靠HOOK机制进行扩展业务功能。 共享模式 这类应用中,经常是为了获取对方的数据。必然我希望获取对方系统中,所有字符串的值。可以通过替换对方的内存管理器,导出所有字符串。 这个应用比较特殊。不过其特点在于,目的是达到系统之间的数据共享。 其实现,可能是观察模式,也可能是替换模式。 VB中的Hook技术应用 一、Hook简介 Hook这个东西有时令人又爱又怕,Hook是用来拦截系统某些讯息之用,例如说,我们想 让系统不管在什么地方只要按个Ctl-B便执行NotePad,或许您会使用Form的KeyPreview ,设定为True,但在其他Process中按Ctl-B呢?那就没有用,这是就得设一个Keyboard Hook来拦截所有Key in的键;再如:MouseMove的Event只在该Form或Control上有效,如果希望在Form的外面也能得知Mouse Move的讯息,那只好使用Mouse Hook来栏截Mouse 的讯息。再如:您想记录方才使用者的所有键盘动作或Mosue动作,以便录巨集,那就 使用JournalRecordHook,如果想停止所有Mosue键盘的动作,而放(执行)巨集,那就 使用JournalPlayBack Hook;Hook呢,可以是整个系统为范围(Remote Hook),即其他 Process的动作您也可以拦截,也可以是LocalHook,它的拦截范围只有Process本身。 Remote Hook的Hook Function要在.Dll之中,Local Hook则在.Bas中。 在VB如何设定Hook呢?使用SetWindowsHookEx() 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 idHook代表是何种Hook,有以下几种 Public Const WH_CALLWNDPROC = 4 Public Const WH_CALLWNDPROCRET = 12 Public Const WH_CBT = 5 Public Const WH_DEBUG = 9 Public Const WH_FOREGROUNDIDLE = 11 Public Const WH_GETMESSAGE = 3 Public Const WH_HARDWARE = 8 Public Const WH_JOURNALPLAYBACK = 1 Public Const WH_JOURNALRECORD = 0 Public Const WH_KEYBOARD = 2 Public Const WH_MOUSE = 7 Public Const WH_MSGFILTER = (-1) Public Const WH_SHELL = 10 Public Const WH_SYSMSGFILTER = 6 lpfn代表Hook Function所在的Address,这是一个CallBack Fucnction,当挂上某个 Hook时,我们便得定义一个Function来当作某个讯息产生时,来处理它的Function ,这个Hook Function有一定的叁数格式 Private Function HookFunc(ByVal ncode As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long nCode 代表是什么请况之下所产生的Hook,随Hook的不同而有不同组的可能值 wParam lParam 传回值则随Hook的种类和nCode的值之不同而不同。 因这个叁数是一个 Function的Address所以我们固定将Hook Function放在.Bas中, 并以AddressOf HookFunc传入。至于Hook Function的名称我们可以任意给定,不一 定叫 HookFunc hmod 代表.DLL的hInstance,如果是Local Hook,该值可以是Null(VB中可传0进去), 而如果是Remote Hook,则可以使用GetModuleHandle('.dll名称')来传入。 dwThreadId 代表执行这个Hook的ThreadId,如果不设定是那个Thread来做,则传0(所以 一般来说,Remote Hook传0进去),而VB的Local Hook一般可传App.ThreadId进去 值回值如果SetWindowsHookEx()成功,它会传回一个值,代表目前的Hook的Handle, 这个值要记录下来。 因为A程式可以有一个System Hook(Remote Hook),如KeyBoard Hook,而B程式也来设一 个Remote的KeyBoard Hook,那么到底KeyBoard的讯息谁所拦截?答案是,最后的那一个 所拦截,也就是说A先做keyboard Hook,而后B才做,那讯息被B拦截,那A呢?就看B的 Hook Function如何做。如果B想让A的Hook Function也得这个讯息,那B就得呼叫 CallNextHookEx()将这讯息Pass给A,于是产生Hook的一个连线。如果B中不想Pass这讯息 给A,那就不要呼叫CallNextHookEx()。 Declare Function CallNextHookEx Lib 'user32' _ (ByVal hHook As Long, _ ByVal ncode As Long, _ ByVal wParam As Long, _ lParam As Any) As Long hHook值是SetWindowsHookEx()的传回值,nCode, wParam, lParam则是Hook Procedure 中的三个叁数。 最后是将这Hook去除掉,请呼叫UnHookWindowHookEx() Declare Function UnhookWindowsHookEx Lib 'user32' (ByVal hHook As Long) As Long hHook便是SetWindowsHookEx()的传回值。此时,以上例来说,B程式结束Hook,则换A可 以直接拦截讯息。 KeyBoard Hook的范例 Hook Function的三个叁数 nCode wParam lParam 传回值 HC_ACTION 表按键Virtual Key 与WM_KEYDOWN同 若讯息要被处理传0 或 反之传1 HC_NOREMOVE Public hHook As Long Public Sub UnHookKBD() If hnexthookproc <;>; 0 Then UnhookWindowsHookEx hHook hHook = 0 End If End Sub Public Function EnableKBDHook() If hHook <;>; 0 Then Exit Function End If hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf MyKBHFunc, App.hInstance, App.ThreadID) End Function Public Function MyKBHFunc(ByVal iCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long MyKBHFunc = 0 '表示要处理这个讯息 If wParam = vbKeySnapshot Then '侦测 有没有按到PrintScreen键 MyKBHFunc = 1 '在这个Hook便吃掉这个讯息 End If Call CallNextHookEx(hHook, iCode, wParam, lParam) '传给下一个Hook End Function 只要将上面代码放在VB的模块中,用标准VB程序就可以了,当运行该程序后,就能拦截所有键盘操作。
参考资料:http://baike.baidu.com/view/107096.html?wtp=tt
其他回答
共 4 条
我不懂,可是如果没有回答你这个问题的话,你就把分给我吧,至少我还进来看了一下咯。谢谢啦!
回答者:匿名 2008-6-3 11:31
其实现在黑客程序中用的比较多的就是hook 文件操作和注册表操作的相应API, 比如:操作注册表打开调用RegOpenKey, 那么你用跨进程hook该API,在该API头 写一个jmp YourCodeAddress,在 YourCodeAddress地址所指的程序中完成你的操作. 其中涉及到比较多的知识,不过如果你一旦会做了, 那么以后所有的hook你也就能做了.
hook是什么? windows系统下的编程,消息message的传递是贯穿其始终的。这个消息我们可以简单理解为一个有特定意义的整数,正如我们看过的老故事片中的“长江长江,我是黄河”一个含义。windows中定义的消息给初学者的印象似乎是“不计其数”的,常见的一部分消息在winuser.h头文件中定义。hook与消息有着非常密切的联系,它的中文含义是“钩子”,这样理解起来我们不难得出“hook是消息处理中的一个环节,用于监控消息在系统中的传递,并在这些消息到达最终的消息处理过程前,处 理某些特定的消息”。这也是hook分为不同种类的原因。 hook的这个本领,使它能够将自身的代码“融入”被hook住的程序的进程中,成为目标进程的一个部分。我们也知道,在windows2000以后的系统中,普通用户程序的进程空间都是独立的,程序的运行彼此间都不受干扰。这就使我们希望通过一个程序改变其他程序的某些行为的想法不能直接实现,但是hook的出现给我们开拓了解决此类问题的道路。 api hook是什么? 在windows系统下编程,应该会接触到api函数的使用,常用的api函数大概有2000个左右。今天随着控件,stl等高效编程技术的出现,api的使用概率在普通的用户程序上就变得越来越小了。当诸如控件这些现成的手段不能实现的功能时,我们还需要借助api。最初有些人对某些api函数的功能不太满意,就产生了如何修改这些api,使之更好的服务于程序的想法,这样api hook就自然而然的出现了。我们可以通过api hook,改变一个系统api的原有功能。基本的方法就是通过hook“接触”到需要修改的api函数入口点,改变它的地址指向新的自定义的函数。api hook并不属于msdn上介绍的13类hook中的任何一种。所以说,api hook并不是什么特别不同的hook,它也需要通过基本的hook提高自己的权限,跨越不同进程间访问的限制,达到修改api函数地址的目的。对于自身进程空间下使用到的api函数地址的修改,是不需要用到api hook技术就可以实现的 http://tech.ddvip.com/2008-01/119991954140197.html