键盘监控的实现Ⅰ——Keyboard Hook API函数

  在实际应用中,键盘监控是一种很常见的技术,它包括按键的记录、按键的过滤、按键的修改(映射)等。比方说,我们想统计用户的击键情况,这个就是按键的记录;我们想屏蔽某些系统键(例如Alt键、Win键),这个是按键的过滤;我们想改变按键的值,例如按下A,出来的是Z,在例如按下A,出来按键的组合SDFG等(貌似这个在游戏中比较多,有些游戏的大绝招都比较难按,用这个一劳永逸),这个是按键的修改。

  键盘监控的具体实现,用的是微软的Keyboard Hook API函数。

  首先解释下,什么是Hook函数。

  WINDOW的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供了挂接各种反调函数(HOOK)的功能。这种挂钩函数(HOOK)类似扩充中断驱动程序,挂钩上可以挂接多个反调函数构成一个挂接函数链。系统产生的各种消息首先被送到各种挂接函数,挂接函数根据各自的功能对消息进行监视、修改和控制等,然后交还控制权或将消息传递给下一个挂接函数以致最终达到窗口函数。WINDOW系统的这种反调函数挂接方法虽然会略加影响到系统的运行效率,但在很多场合下是非常有用的,通过合理有效地利用键盘事件的挂钩函数监控机制可以达到预想不到的良好效果。

  简单的说,就是在消息到达Window之前,系统允许你安装Hook函数来拦截消息,并对消息进行处理。Hook函数也是有类别的,不同的函数实现不同的功能。

  先看下函数的申明:

  Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" ( _

    ByVal idHook As Integer,  _       '安装的钩子的类型

    ByVal lpfn As HookProc,  _       '消息的处理函数

    ByVal hMod As IntPtr, _        '应用程序事例句柄

    ByVal dwThreadId As Integer _     '线程ID

    ) As Integer
  

  钩子卸载函数

  Private Declare Function UnhookWindowsHookEx Lib "user32" ( _

    ByVal idHook As Integer _      '要卸载的HOOK函数的句柄

    ) As Integer
  

  调用下一个HOOK函数

  Private Declare Function CallNextHookEx Lib "user32" ( _

    ByVal idHook As Integer,  _      '本HOOK函数的句柄

    ByVal nCode As Integer,  _      '消息的类型

    ByVal wParam As Integer,  _      '消息的参数

    ByVal lParam As IntPtr _        '消息的参数

    ) As Integer

  

  消息函数的委托

  Private Delegate Function HookProc( _

    ByVal nCode As Integer,  _      '消息的类型

    ByVal wParam As Integer, _      '消息的参数

    ByVal lParam As IntPtr _        '消息的参数

    ) As Integer
  

  钩子类型的常数

  Private Const  WH_KEYBOARD_LL  As  Integer= 13    '全局键盘钩子(又称为底层)
  Private Const  WH_KEYBOARD As  Integer = 2      '普通键盘钩子

 

  按键信息结构

  Public Structure KeyboardHookStruct
    Dim vkCode As Integer
    Dim ScanCode As Integer
    Dim Flags As Integer
    Dim Time As Integer
    Dim DwExtraInfo As Integer
  End Structure

 

  我们用一个类来实现键盘的监控。

  首先定义两个变量

  Private hKeyboardHook As Integer
  Private KeyboardHookProcedure As HookProc

  

  装载钩子的函数

  Public Sub Hook()
    If hKeyboardHook = 0 Then
    KeyboardHookProcedure = New HookProc(AddressOf KeyboardHookProc)
    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly.GetModules()(0)), 0)

      If hKeyboardHook = 0 Then
        UnHook()
        Throw New Win32Exception(Marshal.GetLastWin32Error)
      End If
         End If
  End Sub

  注:函数执行后,会安装Hook,所有的按键消息在到达window前都会被函数KeyboardHookProc拦截到。我们在后面的KeyboardHookProc函数中处理拦截的消息。

 

  卸载钩子的函数

  Public Sub UnHook()
    If hKeyboardHook <> 0 Then
      Dim retKeyboard As Integer = UnhookWindowsHookEx(hKeyboardHook)
      hKeyboardHook = 0
      If retKeyboard = 0 Then Throw New Win32Exception(Marshal.GetLastWin32Error)
    End If
  End Sub

 

  按键消息的处理函数

  Private Function KeyboardHookProc(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
      Dim MyKeyboardHookStruct As KeyboardHookStruct = DirectCast(Marshal.PtrToStructure(lParam, GetType(KeyboardHookStruct)), KeyboardHookStruct)

  

  自己处理的一些代码,例如:记录、屏蔽、映射等

 

  Return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam)
  End Function

 

  以上就是基本的按键监控类的代码。不过要注意以下几点:

  1、Keyboard的HOOK函数分为两种,WH_KEYBOARD_LL和WH_KEYBOARD。我们一般用第一种,全局的键盘钩子,能拦截所有的键盘按键的消息。

  2、网上有人说,全局的钩子要放在单独的DLL中才能使用。我试了一下,不放在单独的DLL中,在XP+VS2005下,调试和运行都没有问题;在XP+VS2008下,调试会出错,不过编译后能运行;在WIN7+VS2010下,调试会出错,编译后能运行。这方面有研究的网友,望不吝赐教。

  3、WH_KEYBOARD_LL和WH_KEYBOARD,这是两种不同的钩子,虽然最后都是KeyboardHookProc函数处理拦截的消息,但是具体的每个参数的意义却完全不一样。

    WH_KEYBOARD钩子。KeyboardHookProc函数的各个参数意义如下:

    nCode    消息的类型,分HC_ACTION和HC_NOREMOVE

    wParam    按键的虚拟键码 

    lParam    按键的相关参数信息,包括重复时间、按键的状态(按下或弹起)等

 

    WH_KEYBOARD_LL钩子。KeyboardHookProc函数的各个参数意义如下:

     nCode    消息的类型,有HC_ACTION

    wParam    按键的状态(按下或弹起)WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN、WM_SYSKEYUP

    lParam    指向KeyboardHookStruct结构的指针,该结构包含了按键的详细信息。     

    可以看出,这两种钩子的参数的定义是完全不一样的。而在之前的代码中:Dim MyKeyboardHookStruct As KeyboardHookStruct = DirectCast(Marshal.PtrToStructure(lParam, GetType(KeyboardHookStruct)), KeyboardHookStruct)就是将该指针指向的内容复制到指定的结构中。

 

  本文介绍了全局键盘钩子的实现中的一些基本的HOOK API函数的介绍。具体的实现留待后文详解。

时间: 2024-07-30 17:57:40

键盘监控的实现Ⅰ——Keyboard Hook API函数的相关文章

键盘监控的实现Ⅲ——按键消息的修改(映射)

在"键盘监控的实现Ⅰ--Keyboard Hook API函数"中,介绍了基本的Key Hook API函数 在"键盘监控的实现Ⅱ--容易产生误解的CallNextHookEx函数"中,提到按键消息的修改是不能通过更改参数调用CallNextHookEx函数来实现的. 本文就是要解决这个问题,如何来实现按键消息的修改.这里我们要引入一个函数 Private Declare Sub keybd_event Lib "user32" (ByVal b

windows常用 API函数

系统API查询 http://www.vbgood.com/api.html http://hi.baidu.com/3582077/item/9cc3483b581f53c5392ffae3 第一个:FindWindow根据窗口类名或窗口标题名来获得窗口的句柄,该函数返回窗口的句柄, 这个函数的定义是这样的 HWND WINAPI FindWindow(LPCSTR lpClassName,LPCSTR lpWindowName);第一个参数填窗口的类名,第二个填窗口的标题名,其实是不需要同时

windows常用API函数

系统API查询 http://www.vbgood.com/api.html http://hi.baidu.com/3582077/item/9cc3483b581f53c5392ffae3 第一个:FindWindow根据窗口类名或窗口标题名来获得窗口的句柄,该函数返回窗口的句柄, 这个函数的定义是这样的 HWND WINAPI FindWindow(LPCSTR lpClassName,LPCSTR lpWindowName);第一个参数填窗口的类名,第二个填窗口的标题名,其实是不需要同时

用API函数实现串行通讯

以往的DOS系统是通过DOS中断和BIOS中断向用户提供串行接口的通讯能力.在Windows环境下,C++的开发工具既没有提供象DOS和BIOS中那样专门的串行通讯控制方法,也不允许用户直接控制串口的中断. 为了保证资源共享,Windows系统完全接管了各种硬件资源,使用中断来控制端口将破坏系统的多任务性,使系统的稳定性受到影响.但Windows同时也提供了功能强大的API函数使用户能间接的控制串行通讯. 1.实现串行通讯的相关API函数 API函数不仅提供了打开和读写通讯端口的操作方法,还提供

如何截获API函数

我曾经写过一个截获MessageBoxW的程序,可以看看,或许对你有一些帮助. 该程序是基于HOOK原理,主要是将自己的函数放到目标PROCESS的地址空间,这里是使用HOOK实现.首先建立一个MOUSE的HOOK程序,然后在全局鼠标HOOK的DLL中做截获动作,可以在PROCESS_ATTACH时做,也可以在鼠标的HOOK链函数中做. 建立全局HOOK我就不说了,可以在网上很多地方看到.主要是截获动作.我是通过PE格式(使用IMAGE)改变API函数在调用时的地址.DLL部分参考如下代码: s

使用Game API函数制作二维动作游戏

MIDP 2.0里面包括一个用来简化编写二维游戏的API函数.这个API函数是非常简凑的,只包括javax.microedition.lcdui.game包里的五个类.这五个类主要提供了两个重要的功能: 新的GameCanvas类使得在一个游戏循环体内画一个screen和响应键盘输入成为可能,而不需要调用系统的paint和input线程. 功能强大而复杂的图层(layer)API函数可以轻松高效地建立复杂的场景. muTank Example 利用GameCanvas类创建一个游戏循环(game

Windows API 函数列表 附帮助手册

原文:Windows API 函数列表 附帮助手册 所有Windows API函数列表,为了方便查询,也为了大家查找,所以整理一下贡献出来了.   帮助手册:700多个Windows API的函数手册 免费下载   API之网络函数 API之消息函数 API之文件处理函数 API之打印函数 API之文本和字体函数 API之菜单函数 API之位图.图标和光栅运算函数 API之绘图函数 API之设备场景函数 API之硬件与系统函数 API之进程和线程函数 API之控件与消息函数     1. API

ndroid 安全-Android accessibility 键盘监控 界面变化

问题描述 Android accessibility 键盘监控 界面变化 最近在研究Georgia理工的一篇论文,论文中,他们开发了一个app,那个app能够覆盖 在目标app上,并且模仿目标app的界面,这样,用户会在我伪装的app中进行输入操作, 从而监控到用户的所有输入和动作,再通过Android accessibility api来将用户的操作输入 到目标app中,从而实现继续监控 关于Android accessibility来讲用户操作输入到目标app已经实现了,但是模仿目标app

python中使用pyhook实现键盘监控的例子_python

pyhook下载:http://sourceforge.net/projects/pyhook/files/pyhook/1.5.1/ pyhookAPI手册:http://pyhook.sourceforge.net/doc_1.5.0/ 以上网站上提供了几个使用的例子,另外安装pyhooks后,也会有一个例子的文件.于是拿来学习了一下,第一次运行时,提示没有pythoncom模块,就安装了pywin32,安装后,可以正常运行,但是会导致机器发卡,特别是中断程序运行后,鼠标会出现一段时间的自由