65.9K
CodeProject 正在变化。 阅读更多。
Home

使用VC++进行鼠标和键盘挂钩实用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (37投票s)

2010年3月21日

CPL

4分钟阅读

viewsIcon

193237

downloadIcon

27169

测试自动化软件的代码,通过鼠标和键盘挂钩揭示!!!

引言

良好的白盒测试对于软件的成功至关重要。测试通常通过人工进行,这既缓慢又昂贵。测试是一个漫长的过程,需要极大的耐心和敏锐的观察力。如果它是白盒测试,那么我们需要遵循一些步骤,并在软件代码的每次微小更改时运行大量场景。通常,测试人员会重复执行相同的步骤。为了克服这个问题,市面上有许多自动化测试工具。一些著名的GUI测试工具包括IBM的IBM Rational Functional Tester和Microsoft的Phantom Automation Language。

本文主要关注使用鼠标和键盘挂钩创建一个微型自动化测试工具。键盘和鼠标挂钩不再是未公开的活动。互联网上有很多关于它的信息。我们知道,每当引入一项好技术时,它都有优缺点。如果我们未经用户知情就记录鼠标和键盘事件,那么它就是木马、键盘记录器或病毒。但如果是有意为之,那么它就是自动化。下面几节将完全专注于使用全局鼠标和键盘挂钩创建自动化测试的微型版本。因此,挂钩是一项简单的活动,通过它,我们就能在应用程序中获取键盘和鼠标事件。让我们详细了解一下。

背景

键盘和鼠标的挂钩通常有两种方式

  1. 线程级别的挂钩

    顾名思义,它仅限于进程中的一个线程。这在我们的软件中可能很有用。因此,钩子过程可以放在EXE或DLL中。

  2. 全局挂钩

    全局挂钩是系统范围的挂钩。整个键盘或鼠标事件都会被重定向到我们的钩子过程。在这种情况下,挂钩函数必须放在一个单独的DLL中。

我们通过Windows提供的SetWindowHookEx WINAPI(挂钩多种事件)来实现鼠标和键盘挂钩。要取消挂钩事件,我们需要调用UnhookWindowsHookEx WINAPI

为了演示挂钩的用法,我创建了一个应用程序RecordPlayer.exe。下面我来介绍一下这个应用程序。它主要由三个组件组成。

  • RecordPlayer.exe
    • 管理来自相应DLL的键盘和鼠标挂钩事件的应用程序。记录步骤的播放操作。
  • KeyBoardHook.dll
    • 挂钩键盘事件
  • HookDll.dll
    • 挂钩鼠标事件

我们的应用程序包含两个操作:录制和播放。录制通过DLL完成,播放主要通过两个API完成——keybd_eventmouse_event。现在让我们深入了解一下。我将通过键盘挂钩来演示挂钩活动。

Using the Code

要开始键盘挂钩,首先创建一个WIN32 DLL。让我们从DLL的头文件开始。

然后从DLL导出函数,以便我们的本机应用程序能够访问它,从而从挂钩过程中获取数据。

KeyBoardHookLib.h中的代码

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#define LIBSPEC __declspec(dllexport)
// Our install Hook procedure.
 LIBSPEC BOOL InstallKeyBoardHook(HWND hWndParent);
// Our uninstall hook procedure.
LIBSPEC BOOL UnInstallKeyBoardHook(HWND hWndParent);
#undef LIBSPEC

用于注册将窗口消息发送到RecordPlayer.exe的命名事件。

#define UWM_KEYBOARD_MSG ("UWM_KEYBOARD_USER_MSG")

让我们熟悉一下KeyBoardHookLib.cpp

执行以下步骤以共享DLL内部或从该DLL共享到本机应用程序的#pragma中提到的HANDLE。

#pragma data_seg(".SHARE")

UINT UWN_KEYSTROKE;
HWND hWndServer = NULL;
#pragma data_seg()

#pragma comment(linker,
"/section:.SHARE,rws")

执行以下步骤以注册窗口消息,以便我们可以将Hook函数内部接收到的键盘事件发送到本机可执行文件。

  UWN_KEYSTROKE= ::RegisterWindowMessage(UWM_KEYBOARD_MSG);

以下提到的static函数是一个键盘过程,它接收全局键盘事件。

static LRESULT CALLBACK KeyBoardMsgProc( int nCode, WPARAM wParam, LPARAM lParam)

一旦父可执行文件调用InstallKeyBoardHook,我们就开始挂钩键盘事件。

SetWindowHookEx中,我们将第一个参数指定为WH_KEYBOARD以挂钩键盘事件。

   hook= SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)KeyBoardMsgProc, hInst, 0);

CallNextHookEx是一个可选过程,但微软强烈推荐使用它。如果不调用它,其他已安装钩子的进程可能无法正确接收事件。

CallNextHookEx(hook, nCode, wParam,lParam);

要卸载挂钩过程,我们需要调用UnhookWindowsHookEx,并指定SetWindowHookEx返回的句柄。

 BOOL unhooked = UnhookWindowsHookEx(hook);

关注点

此工具是自动化测试软件的一个微型实现。但我相信,它能让你了解鼠标和键盘挂钩。SetWindowsHookEx可用于将DLL注入另一个进程。在本文中,我们处理的是监视按键消息的WH_KEYBOARD。键盘输入可以来自本地键盘驱动程序,也可以来自对keybd_event函数的调用。如果输入来自对keybd_event的调用,则输入被“注入”。WH_KEYBOARD_LL钩子不会注入到另一个进程中,所以它更好。WH_SHELL可用于获取shell事件的通知。SetWindowHookEx是一个非常有用的API,但好的工作需要付出代价,所以让我们这样做。钩子往往会减慢系统速度,因为它们增加了系统必须为每个消息执行的处理量。所以要谨慎使用。如果我的真主允许,我将撰写更多文章。

历史

  • 版本 1.0
© . All rights reserved.