Windows键盘驱动结构与消息机制--转
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里的工作情况。
Windows键盘驱动结构与消息机制--转的更多相关文章
- 【转】深入Windows内核——C++中的消息机制
上节讲了消息的相关概念,本文将进一步聊聊C++中的消息机制. 从简单例子探析核心原理 在讲之前,我们先看一个简单例子:创建一个窗口和两个按钮,用来控制窗口的背景颜色.其效果 图1.效果图 Win32 ...
- windows程序消息机制(Winform界面更新有关)
windows程序消息机制(Winform界面更新有关) 转自:http://www.cnblogs.com/blosaa/archive/2013/05/31/3109586.html 1. Win ...
- windows程序消息机制(Winform界面更新有关)--转
1. Windows程序消息机制 Windows GUI程序是基于消息机制的,有个主线程维护着消息泵.这个消息泵让windows程序生生不息. Windows程序有个消息队列,窗体上的所有消息是这个队 ...
- C#中的WinForm的消息机制简述,及消息机制下Invoke,和BeginInvoke的使用和区别
在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate,至于委托的本质请参考我的另一随笔:对.net事件的看法. 一.为什么Control类提供了Invoke和Begin ...
- Windows消息机制详解
消息是指什么? 消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用 ...
- Windows消息机制知识点总结
1.windows消息类型 以下四种,前三种是系统消息,范围在[0x0000, 0x03ff],第四种是用户自定义消息. 1.1 窗口消息 与窗口的内部运作有关,如创建窗口,绘制窗口,销毁窗口等.可以 ...
- Windows消息机制概述
消息是指什么? 消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用程 ...
- 基础篇-Windows消息机制
1在介绍Windows 消息运行机制之前,首先介绍一下消息的概念: 消息(Message)指的就是Windows 操作系统发给应用程序的一个通告[5],它告诉应用程序某个特定的事件发生了.比如,用户单 ...
- Windows消息机制要点
1. 窗口过程 每个窗口会有一个称为窗口过程的回调函数(WndProc),它带有四个参数,分别为:窗口句柄(Window Handle),消息ID(Message ID),和两个消息参数(wP ...
随机推荐
- 洛谷 1017 进制转换 (NOIp2000提高组T1)
[题解] 纯模拟题. 我们都知道十进制数化成m进制数可以用短除法,即除m取余.逆序排列.而m进制数化为十进制数,按权展开求和即可. 但在本题中进制的基数R可能为负数,我们知道a%R的符号与R一致,也就 ...
- hihocoder 1032 最长回文子串(Manacher)
传送门 #include<queue> #include<cmath> #include<cstdio> #include<cstring> #incl ...
- CSS3制作404立体字体
CSS3制作404立体字体页面效果 鼠标移动上去,背景色变白. 动态效果: .demo p:first-child span:hover { text-shadow:0px ...
- Oracle 关于几个随机函数sys_guid、dbms_random.random、dbms_random.value(取随机的结果集)
sys_guid():SYS_GUID (),是Oracle 8i 后提供的函数.SYS_GUID产生并返回一个全球唯一的标识符(原始值)由16个字节组成.更适合多个数据库数据集成时使用(--源自百度 ...
- MaxScale初探
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://mrcto.blog.51cto.com/1923168/1437287 内容预览 ...
- kafka 在阿里云部署
https://blog.csdn.net/chenyulancn/article/details/79499401 https://www.cnblogs.com/yangtianle/p/8761 ...
- 【Android 开发实例】时间管理APP开发之数据库设计
当然也能够先写界面什么的.可是,总认为先把数据库后台写好在写界面比較放心. 对于数据库的设计,我一開始没什么概念.甚至不知道怎样下手,一開始想着设计成几个表?有哪些字段? 最后用了两天时间,还是一无所 ...
- FloatingActionMenu 向上弹出菜单
本人在github上找到了一个FloatingActionsMenu,精简了其效果(原效果有上下左右四个方向)仅仅保留向上的效果,并做了一定的优化. github上的源代码:地址 ,精简后的源代码地址 ...
- MapR CEO对2016大数据的5个预測
本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2016/02/mapr-ceo-5-big-data-predictions MapR ...
- Android Studio VS Eclipse (还在用Eclipse?你OUT了!)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990).谢谢支持! 公司派来一个去美国參加完AnDevCon大会的来给我们分享大会上学习的内容. AnDevC ...