`
javasogo
  • 浏览: 1845307 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

钩子及其应用(四)

阅读更多

{三}简单的消息Spy的实现

凡写过一些程序的人,大都用过VSSpy++工具,非常好用。Delphi也有一个类似的工具叫WinSignt32,说实话,比Spy++可是差远了。这一篇将介绍如何实现一个简单的消息Spy工具,其功能大概类似于Spy++Spy Message,以此来学习全局钩子的用法。说点题外话,这些知识都是笔者经过实践学习而得来,其间不乏屡遭碰壁者,因此想写出来,帮助有兴趣者更快地学习这些知识。

首先得介绍于消息相关的几个钩子,主要是:

WH_GETMESSAGE:应用程序使用WH_GETMESSAGE Hook来监视从GetMessage 或者 PeekMessage函数返回的消息。你可以使用WH_GETMESSAGE Hook去监视鼠标和键盘输入,以及其他发送到消息队列中的消息。

WH_CALLWNDPROCWH_CALLWNDPROCRETWH_CALLWNDPROCWH_CALLWNDPROCRET Hooks使你可以监视发送到窗口过程的消息。系统在消息发送到接收窗口过程之前调用WH_CALLWNDPROC函数过程,并且在窗口过程处理完消息之后调用WH_CALLWNDPROCRET函数过程。

上面说得很明白了,WH_GETMESSAGE相当于钩住了PostMessage发送的消息,而另外两个相当于钩住了SendMessage发送的消息。

有了这三个钩子,已经足够Spy所有的消息了。至于三个钩子的钩子过滤函数,可以参见MSDNGetMsgProcCallWndProc以及CallWndRetProc的说明,相信通过上面的讲解,应用容易这几个过程的参数的含义。而这并不是这一篇的重点。

我们知道的一点常识是,全局钩子必须安装在DLL中,但说到实际的应用,其实也并非这么简单。最好了解一下一些运行机制:

Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的;而在Win32环境中,情况却发生了变化,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。当进程在载入DLL时,操作系统自动把DLL地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。

好好的理解一下上面的这一段话。全局钩子安装在DLL中,我们假设DLL中有一个APIStartHook,其中调用了SetWindowsHookEx函数。当某一个进程调用DLL中的StartHook时,钩子开始安装,实际上它是把DLL注入到了所有的进程中(DLL注入中的一个方法即是利用全局钩子的技术。详见《Window高级编程》),这样全局钩子才能够监视到系统级别的消息。而上面的话说得很明白,每一个进程都自己的地址空间,且互不干涉。

这就带来了一个难题,即数据共享。让我来举个例子。假设我们要监视某一个窗口的消息,则假设调用DLL中的一个函数:StartSpyMessage,向这个函数传入将被监视的窗口的句柄。而StartSpyMessage函数中将该句柄保存在DLL中的一个全局变量中,接着在钩子过程里判断截获的消息结构中的句柄值是否和该全局变量相等,相等则发送消息通知外部。这一个操作过程是在某一个进程中完成的。现在问题来了,当DLL被注入到其他进程中时,保存窗口句柄的变量并没有得到共享,它是0。因此,就形成了一个现象:当监视自已程序的窗口时,没有问题,因为自己进程的DLL的句柄变量得到赋值,所以可以判断;但监视其他程序的窗口时,不行,因为其他进程的该变量是0,判断时就不对了。就好象不是全局钩子一样。

说了这么多,不知读者是否明白。总之,我们需要一种共享技术,让DLL中的变量在所有进程中都是一样的。另人羡慕的是:C++#pragma data_seg预处理指令用于设置共享数据段。但Delphi没有,我们只能用内存映射文件来达到目的。

利用CreateFileMappingOpenFileMappingMapViewOfFile等几个API取得一段共享内存(具体用法看帮助说明吧,这里实在没有篇幅来讲了),让所有进程都能共享它们。最后用完,要用UnMapViewOfFileCloseHandleAPI释放共享内存。

解决了第一个数据共享问题,还有另一个问题等解决。当截获了一个消息时,怎么样把这个消息包成一个数据包发送到显示的窗口呢。如果是同一进程,那倒好办,因为都在同一地址空间中吗,你New了一个内存,然后用一个自定义消息发送过去没有问题。但如果是截获其他进程的消息呢。此时New的内存地址只是相对于该进程而言,而当发送消息到显示的进程时,那个内存地址已经完成不同了。所以我们还需要一个进程间通信的技术。好在并不是很难。

WM_COPYDATA消息即可以完成,wParam表示传递该消息的窗口,这个参数我们可以忽略。lParam是指向COPYDATASTRUCT结构的指针。看看其声明:

typedef struct tagCOPYDATASTRUCT { // cds

DWORD dwData;

DWORD cbData;

PVOID lpData;

} COPYDATASTRUCT;

dwData指定一个32的值传递过去。这个对于我们不重要。

cbData确定lpData指向的内存的大小

lpData指向一块内存。

这里最重要的无疑就是lpData了,可以设定一个消息结构来保存截获得到的消息的信息,然后将其挂到lpData上面,让WM_COPYDATA消息载着这一块内存送到显示的窗口去。OK了。

所有重点技术都解决了,其他的就没有什么了。希望读者能够看得懂。

分享到:
评论

相关推荐

    钩子源码钩子源码

    以下是对钩子机制及其应用的详细解释: 一、钩子的基本概念: 钩子是Windows操作系统提供的一种机制,允许开发者注册函数来接收并处理特定的消息或事件。当特定的事件发生时,如键盘输入、窗口消息、系统事件等,...

    键盘钩子hook键盘钩子

    本地钩子仅在安装它的进程上下文中运行,只能捕获该进程及其子进程中的键盘事件。而全局钩子则更为强大,可以在整个系统范围内工作,监听所有进程中发生的键盘事件。 实现键盘钩子通常涉及以下步骤: 1. 定义钩子...

    Hook钩子\钩子程序.pdf

    下面将详细介绍几种常用的钩子类型及其应用场景: ##### 1. 键盘钩子与低级键盘钩子 **键盘钩子**(Keyboard Hook)用于监控所有键盘消息,包括按键按下与释放等事件。通过这种钩子,开发者可以实现对用户键盘输入...

    键盘钩子、鼠标钩子应用组件示例及 源码

    在IT领域,尤其是在Windows应用程序开发中,"键盘钩子"和"鼠标钩子"是用于监控和处理系统级输入事件的重要技术。这些技术通常涉及到低级别编程,特别是使用C#语言时,EventHook库提供了方便的接口来实现这一功能。本...

    hook_钩子程序-delphi

    总结起来,"hook_钩子程序-delphi"的主题涵盖了一个广泛的Delphi编程领域,涉及到Windows系统中的Hook技术及其在Delphi中的实现,这对于任何希望增强其应用程序功能或进行系统监控的开发者来说都是极其宝贵的资源。...

    古老的钩子艺术-详细讲解钩子的教程

    本文重点介绍用户空间钩子的技术细节及其应用场景。 #### 三、用户空间钩子(User Space Hook) 用户空间钩子是在用户态下实现的一种Hook技术,主要用于拦截和修改应用程序的行为。这种技术通常不涉及对操作系统核心...

    VC++钩子函数

    ### 钩子函数在VC++中的应用 #### 一、引言 在软件开发过程中,特别是对于Windows应用程序而言,钩子(Hook)技术是一种非常有用的工具,...希望本文能够帮助初学者更好地理解和掌握钩子函数的基本原理及其应用场景。

    完整版键盘钩子.rar

    在这个“完整版键盘钩子.rar”压缩包中,我们将会深入探讨键盘钩子的核心原理、实现方式及其在实际应用中的具体运用。 键盘钩子,简单来说,是一种操作系统级别的机制,允许程序拦截并处理键盘输入事件。这一技术...

    简单的钩子函数

    这种实践可以帮助理解钩子的工作原理及其在实际项目中的应用。 在文件"钩子函数"中,可能包含了创建和使用钩子函数的代码示例。通过阅读和分析这些代码,你可以更深入地了解如何在实际编程中设置和管理钩子,以及...

    一个 钩子程序DLL和用来调用的控制台

    【标题】:深入理解钩子程序DLL及其在控制台中的应用 在Windows操作系统中,钩子(Hook)是一种系统机制,允许程序员监控特定事件的发生,例如键盘输入、鼠标操作等。钩子程序通常是一个动态链接库(DLL),它包含...

    钩子资料整理,个人感觉不错

    2. **应用程序级钩子**:局部钩子,只对创建它的进程及其子进程有效。 3. **线程级钩子**:针对特定线程的钩子,只会在指定线程中被调用。 二、钩子工作原理 当一个事件发生时,如键盘输入、鼠标点击,Windows会...

    用VC_c全局钩子.pdf

    #### 一、全局钩子的概念及其重要性 在Windows操作系统中,全局钩子是一种强大的工具,它允许开发者在系统范围内捕获和处理各种消息。这对于创建诸如自动演示程序、程序日志、辅助调试工具等特殊功能极为有用。此外...

    消息钩子代码实现

    本篇文章将深入探讨消息钩子的实现及其在拦截`WM_COMMAND`消息中的应用。 首先,我们需要理解什么是`WM_COMMAND`消息。`WM_COMMAND`是Windows消息的一种,它在用户与菜单、快捷键、控件交互时产生,传递控制ID和...

    全局键盘钩子获取扫描枪输入

    全局键盘钩子是Windows操作系统提供的一种机制,允许应用程序在系统层面捕获键盘事件,即使焦点不在该应用程序上。这种技术通常用于实现系统级...通过分析和学习这段代码,可以加深对全局键盘钩子及其实现细节的理解。

    系统钩子示例程序.rar

    全局钩子在所有当前运行于同一台计算机上的线程间共享,而本地钩子只对创建它的进程及其子进程有效。此外,还有WH_JOURNALPLAYBACK、WH_JOURNALRECORD、WH_KEYBOARD_LL、WH_MOUSE_LL等不同类型的钩子,它们分别针对...

    MFC --进程中的钩子

    本文将详细探讨MFC中的进程钩子及其使用方法。 首先,让我们理解什么是进程钩子。进程钩子是安装在特定进程中的,当该进程中发生特定事件时,钩子函数会被调用。这使得开发者可以在事件发生时进行干预,实现自定义...

    详解Vue3生命周期及其 Composition API 钩子应用与对比

    内容概要:本文介绍了 Vue3 的生命周期各个阶段以及各周期钩子的功能与调用时机,并详细讲解了这些生命周期的变化情况及与Vue2的区别,特别是对新增Composition API形式的生命周期做了细致解析和示例代码说明。...

    鼠标键盘钩子截获密码的代码

    ### 鼠标键盘钩子技术详解及其应用 #### 一、钩子技术概述 钩子(Hook)技术是Windows操作系统提供的一种高级编程接口,它允许开发者捕获、拦截或修改系统中的各种消息和事件。通过钩子技术,开发者可以实现一些...

    钩子函数中文版,翻译的很详细

    钩子函数在Windows编程中是一种强大的机制,它允许开发者插入自定义代码到系统或应用程序的特定事件处理流程中,以实现对特定事件的监控或控制。在中文环境中,理解钩子函数的概念和使用方法对于Windows应用程序开发...

    C++键盘钩子

    以下是几种常见的钩子类型及其作用: 1. **WH_CALLWNDPROC** 和 **WH_CALLWNDPROCRET Hooks**:这两个钩子允许你监控发送到窗口过程的消息。WH_CALLWNDPROC在消息被发送到接收窗口之前调用,WH_CALLWNDPROCRET则在...

Global site tag (gtag.js) - Google Analytics