https://www.douban.com/note/318793892/

本文主要介绍按键消息是如何传递到窗口并转化为具体的按键消息的。

Windows系统是事件驱动的多任务系统,其中按键和鼠标是主要的事件。按键是由键盘驱动获得并转换,然后广播给各个窗口。

整个架构的核心是csrss.exe这个进程,对于“一般”的窗口,收到的消息都是由这个任务产生的。该任务负责用CreateFile方式打开键盘设备并读取信息,获得对应的键码并发送给特定的进程,csrss.exe的启动的输入线程为win32k!RawInputThread,具体要把键盘消息发送给哪个线程,以及如何发送,是由csrss来控制的。

所以,每个进程的MessageLoop实际上是从这里读取的,于是SetWindowHook之类的函数有些是挂到各个进程里,有些实际上是挂到了csrss里,达到监控键盘的目的。但对于加密的控件(如网银等),SetWindowHook不管用,但如果hook到RawInpuThread里,那么还是有可能读到信息的。

csrss访问的是键盘设备,具体这个设备是一个kbdclass设备,以下部分就是内核的代码空间了。

因为一个系统里可能不只一个键盘(同理,鼠标也是),所以需要一个统一的驱动去管理所有的键盘设备,这个驱动就是kbdclass.sys,键盘设备类驱动,对应的设备名是L"\\Driver\\Kdbclass",RawInpuThread实际上访问的是这个设备,而对于每个键盘,则是有各自的驱动,对于PS/2键盘是i8042prt.sys,对于USB键盘,这是另外的驱动,这些驱动称为port驱动,是真正的设备驱动,对应的设备是KeyboadClass0、KeyboardClass1等等(有几个键盘,数字就排到多少),RawInpuThread把请求发送到kbdclass,kbdclass把请求(IRP)pend到这一层,等待下层port驱动返回。

这里需要特别提出的一个函数是KeyboardClassServiceCallback,这个函数是kbdclass一层的callback,下层设备驱动的所有返回值都需要经过它。所以,如果钩子挂到这里,那么理论上所有的输入都可以被拦截的,已经亲自测试过网银控件的密码会在此被泄露,但QQ不会,QQ2013会启动失败,估计是检查了这个驱动。

顺便说一句,早期的QQ加密没那么恐怖,但它是启动一个线程不停的SetWindowHook,使得自己的hook永远在第一个,然后过滤掉所有的消息防止被人监听。后来的QQ可能是修改IDT里的键盘中断实现的。

当然病毒也可以通过filter驱动注入到kbdclass和port驱动之间,来实现监听键盘,这也是一种常见的情况。

所以,一个按键的消息产生流程如下:

1)硬件中断/硬件端口数据
//WinIO能模拟,或者修改IDT是在这一层
2)键盘Port驱动(USB or PS/2)
//Filter驱动在此
//KeyboardClassServiceCallback也在这一层被调用
3)kbdclass驱动
//处理键盘布局和键盘语言
4)Windows内核边界(zwCreate/zwReadFile)
----------------------(系统调用)----------------------
5)Windows内核边界(zwCreate/zwReadFile)
6)csrss.exe的win32k!RawInputThread读取,完成scancode和vk的转换
//SetWindowHook工作在这里(全局)
//kbd_event工作在这里
7)csrss.exe调用DispatchMessage等函数分发消息
//SetWindowHook工作在这里(进程)
//PostMessage和SendMessage在这里
8)各个进程处理消息

WinIO这个驱动比较特殊,它提供接口可以允许应用层直接写端口,但只能写PS/2端口,所以有些模拟按键程序通过WinIO来模拟按键。

对于标准的程序,PostMessage等函数可以完成模拟,但对于不太标准的软件,只能用kbd_event来模拟,但有些软件(如网银控件)就只能在更靠近内核的区域模拟了。

同时,有一种输入是很特殊的,就是DirectInput,这是DirectX提供的一种方法,大型游戏中很常见的用法,因为DirectInput的输入速度很快,绕过了消息层。但对于这种软件,在kbdclass一层甚至都无法模拟。目前还不确定DirectInput工作在哪一层,猜测可能是在kbdclass和port驱动之间,也许是一种filter驱动。对于这种输入方法,可以WinIO来模拟,但对于USB键盘则没有办法。

Windows提供了一套API:SendInput,这个驱动发送按键消息时有两种类型,一种是VK模式的,实际上跟kbd_event一样,工作在csrss这一层,而另一种是ScanCode模式,MSDN里有这样的描述:

Windows 2000/XP: Set the KEYEVENTF_SCANCODE flag to define keyboard input in terms of the scan code. This is useful to simulate a physical keystroke regardless of which keyboard is currently being used.

可以看出,这是能够模拟更底层的按键的,理论上说是可以模拟DirectInput的按键的,实际测试也是这样,但文档中没有说明在vista以后的版本是什么状态,所以暂时也无法知道在WIN7里的工作情况。

转载于:https://www.cnblogs.com/davidwang456/p/8708619.html

Windows键盘驱动结构与消息机制--转相关推荐

  1. windows程序消息机制(Winform界面更新有关)--转

    1. Windows程序消息机制 Windows GUI程序是基于消息机制的,有个主线程维护着消息泵.这个消息泵让windows程序生生不息. Windows程序有个消息队列,窗体上的所有消息是这个队 ...

  2. windows程序消息机制(Winform界面更新有关)

    1. Windows程序消息机制 Windows GUI程序是基于消息机制的,有个主线程维护着消息泵.这个消息泵让windows程序生生不息. Windows程序有个消息队列,窗体上的所有消息是这个队 ...

  3. 如何编写Linux 下的 USB 键盘驱动

     如何编写Linux 下的 USB 键盘驱动 1. 指定 USB 键盘驱动所需的头文件: #include <linux/kernel.h>/*内核头文件,含有内核一些常用函数的原型定 ...

  4. windows 键盘消息的机制

    在Microsoft Windows 98中,键盘和鼠标是两个标准的使用者输入来源,在一些连贯操作中常产生互补作用.当然,鼠标在今天的应用程序中比十年前使用得更为广泛.甚至在一些应用程序中,我们更习惯 ...

  5. Windows消息机制要点

    1. 窗口过程     每个窗口会有一个称为窗口过程的回调函数(WndProc),它带有四个参数,分别为:窗口句柄(Window Handle),消息ID(Message ID),和两个消息参数(wP ...

  6. Windows消息机制详解

    消息是指什么?      消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用 ...

  7. Windows消息机制-PreTranslateMessage

    PreTranslateMessage作用和使用方法 Windows消息机制的流程: A. 操作系统接收应用程序的窗口消息,将消息投递到该应用程序的消息队列中 B. 应用程序在消息循环中调用GetMe ...

  8. Windows消息机制详解-6

    消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用程序某个事情发生了.例如, ...

  9. Windows消息机制详解-5

    一. 什么是消息 在解释什么是消息之前,我们先讨论一下程序的执行机制问题.大体上说,程序按照执行机制可以分为两类: 第一类是过程驱动.比如我们最早接触编程时写的C程序,又或者单片机程序.这类程序往往预 ...

最新文章

  1. Java的calendar类用法
  2. spring 事务隔离级别和传播行为_Java工程师面试1000题146-Spring数据库事务传播属性和隔离级别...
  3. 库克遭一名自称其妻子的陌生女子威胁 苹果紧急申请限制令
  4. MYCAT 安装(转)
  5. python所有软件-太牛逼!一款软件几乎可以操作所有的数据库!
  6. 业界总结 | 如何改进双塔模型,才能更好的提升你的算法效果?
  7. php调用一个c语言写的接口问题
  8. 线性插值 多项式插值 样条插值 牛顿插值总结
  9. java图书销售系统_基于Java Web的图书销售管理系统
  10. Linux 系统查看网卡配置信息
  11. Vue 富文本编辑器的使用
  12. 【每日一题】一起冲击蓝桥杯吧——Day1【蓝桥真题】
  13. 《银杏,银杏》原文小说
  14. insmod 加载模块的过程
  15. SpringBoot HATEOAS用法简介(入门)
  16. seurattogiotto中的python环境设置
  17. zscore标准化步骤_z-score的标准化究竟怎么弄?
  18. 病毒分析与防护实验2—— 搭建反病毒实验室
  19. 铁电存储器耐久性设计要求
  20. 【Python数列、数列和问题】

热门文章

  1. 后端开发开发mac装机和开发环境指南(新手版)
  2. php通过QQ号获取QQ信息,通过openId能获取到QQ号码吗?
  3. Shell中的分支语句
  4. Qt中的QMainWindow
  5. 任务的定义、任务切换的原理及实现
  6. file 选择的文件胖多有多大_「HTML5 进阶」FileAPI 文件操作实战,内附详细案例,建议收藏...
  7. 添加softmax层_PyTorch入门之100行代码实现softmax回归分类
  8. android 之多线程详解
  9. change事件判断ajax,jquery中change事件里面if语句失效
  10. 知识图谱(历史回顾及技术挑战)