首页
社区
课程
招聘
[原创]模拟按键所有方法技术实现
发表于: 2015-1-16 14:55 20891

[原创]模拟按键所有方法技术实现

2015-1-16 14:55
20891
收藏
免费 0
支持
分享
最新回复 (50)
雪    币: 49
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
26
没了。。。
2015-1-19 17:45
0
雪    币: 44
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
27
看下。。。。。。。。。。。。
2015-1-19 17:48
0
雪    币: 172
活跃值: (1628)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
28
怎么没了
2015-1-19 18:19
0
雪    币: 188
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
29
内容难道楼主删了?
2015-1-19 18:28
0
雪    币: 52
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
30
楼主为何删帖啊
2015-1-19 18:41
0
雪    币: 80
活跃值: (109)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
31
为什么我什么都看不到
2015-1-19 18:55
0
雪    币: 58
活跃值: (1145)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
32
删了!!
2015-1-19 19:32
0
雪    币: 691
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
33
????
2015-1-19 20:44
0
雪    币: 171
活跃值: (92)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
34
内容怎么没有了
2015-1-19 22:27
0
雪    币: 16505
活跃值: (2528)
能力值: ( LV9,RANK:147 )
在线值:
发帖
回帖
粉丝
35
- -楼主删除了.
2015-1-19 22:30
0
雪    币: 11
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
36
看不到啊!晕死,为啥?
2015-1-19 22:35
0
雪    币: 146
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
37
模拟按键方法总结

Reference
[1] http://km.oa.com/articles/show/107987?kmref=search 作者dlchu
[2] http://km.oa.com/group/526/articles/show/6060?kmref=search 作者pazuluo
[3] http://km.oa.com/group/870/articles/show/160719?kmref=search 作者damonhu
[4] http://www.hookbase.com/Article/webaq/200707/15109.html 获取KeyboardClassServiceCallback函数的地址
[5] http://bbs.pediy.com/showthread.php?t=101653 系统底层模拟按键方法介绍

SendMessage/PostMessage
是Ring3层的一种方法,SendMessage和PostMessage是User32.dll中的函数。可以直接在程序中调用,实现对另一个软件上的按钮的点击。
发消息给固定HWND的窗口,不需要窗口是处于顶层。

SendInput
这个函数发消息给Active window, 发消息之前需要将窗口置顶。
主要使用结构体INPUT, 头文件#include <winable.h>
这个结构是一个联合体,可以发送KEYBOARD和MOUSE两种事件。MOUSE事件的结构体如下:

keybd_event/mouse_event
这两个函数头文件include<windows.h>
在MFC程序中,可以直接使用keybd_event和mouse_event这两个函数。
这两个函数keybd_event和mouse_event内部是调用SendInput函数实现的,所以消息是发给Active window的。所以,使用这两个函数发消息给窗口的时候,同样需要将窗口程序置顶。

Kbdclass.sys-KeyboardClassServiceCallback/mouclass.sys-MouseClassServiceCallback
这个是底层的键盘鼠标事件回调函数。
通过直接调用这两个函数可以实现模拟键盘鼠标输入的效果。
代码是从看雪上下载的代码的基础上修改实现的。
主要思想:
Step1:找到KeyboardClassServiceCallback/MouseClassServiceCallback函数在内核中的地址,采用特征码搜索的方法;
使用ZwQuerySystemInformation函数,其参数为SystemModuleInformation = 11时,用于获取系统所有内核模块的相关信息,放在PSYSTEM_MODULE_INFORMATION结构体中,这个结构体中包含了模块名(module[Index].ImageName + module[Index].ModuleNameOffset),模块基址(module[Index].Base)的相关信息,这样就可以找到kbdclass.sys 和 mouclass.sys的基址。然后根据特征码搜索的方法,找到KeyboardClassServiceCallback/MouseClassServiceCallback的入口地址。
Step2:构造函数的参数,直接调用这两个函数实现模拟按键。
KEYBOARD_INPUT_DATA结构在ntddkbd.h中;MOUSE_INPUT_DATA结构在ntddmou.h中。这两个头文件都在WDM的目录中可以找到。要使用这两个结构就需要将对应的头文件加入。
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542403(v=vs.85).aspx MOUSE_INPUT_DATA
http://msdn.microsoft.com/en-us/library/windows/hardware/ff542337(v=vs.85).aspx KEYBOARD_INPUT_DATA
但是对这两个结构体的赋值,还是需要去查一下键盘的键值,鼠标的坐标表示方式等信息。我这里没有去查这些信息,特别是对应鼠标的坐标,查了一些资料,感觉不太好确定。所以还是从逆向分析的角度,获取要模拟的事件对应的该结构的值,然后用这个值进行模拟测试。对于键盘的模拟。
[ATTACH][/ATTACH]构造KeyboardClassServiceCallback函数的参数,调用该函数实现鼠标左键Click事件。
这两个函数的调用都是在DriverEntry中直接实现的,所以最终的表现形式是:只在驱动加载的时候模拟点击一次,要实现重复多次的模拟,就需要将内核函数的调用写在IRP的分派函数中,然后在Ring3层读写驱动设备。

遇到的问题
[1] 双机调试过程中内核符号表的配置
要了解系统内核中的函数,需要配置双机调试环境,查看内核中的实现。其中我自己觉得比较难的一点是内核符号表的配置。如果内核符号表配置不好的话,无法在WinDBG中查看内核函数与对应的数据结构。
http://msdn.microsoft.com/en-us/windows/hardware/gg463028.aspx  
可以在这个地址下载对应的内核符号表,然后安装到对应的目录,如E:\Windows\Symbils.然后在WinDBG的Symbol File Path目录中输入该目录E:\\Windows\\Symbils,.reload加载符号表。
我这里一直加载不到符号表的问题出在了转义字符“\”上。
[2]如何获取MOUSE_INPUT_DATA与KEYBOARD_INPUT_DATA参数的问题
在MSDN上面可以查到这两个数据结构,对于参数的赋值还是需要仔细研究。我使用的方法是在系统的MouseClassServiceCallback和KeyboardClassServiceCallback函数的地址处下断点,然后获取实际按键过程中这两个数据结构的值,然后用这个数据做模拟按键。
[3] 内核函数的调用方式
这里考虑到驱动编写的过程中,是采用过滤驱动还是直接调用内核函数两种方式。过滤驱动就是在原有的驱动对象的基础上,在设备堆栈上注册自己的驱动对象,实现自己的驱动回调函数,但是过滤驱动也是在当IRP发生的时候,调用的。模拟按键的话,我认为是要绕过硬件触发,绕过IRP,直接调用底层的函数来实现对应的功能。所以,最后还是选择的是直接调用内核函数。
[4] 设备对象:DEVICE_OBJECT的获取
键盘和鼠标驱动函数MouseClassServiceCallback和KeyboardClassServiceCallback的第一个参数是DEVICE_OBJECT对象。所以,需要在调用之前创建对应的设备对象。键盘设备对象的符号名:L”\\Device\\KeyboardClass0”;鼠标设备对象的符号名:L”\\Device\\PointerClass0”;理论上这个值是跟MOUSE_INPUT_DATA与KEYBOARD_INPUT_DATA中的UintID参数对应的,但是好像没有那么严格。

缓存出来一部分,兄弟们看吧
2015-1-19 22:38
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
38
没啥特别的东西 有什么好删的
应该是引用了TX内部文章 所以删除了
但这技术含量也没啥啊
2015-1-20 10:49
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
39
mark
2015-1-20 14:12
0
雪    币: 1085
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
40
谢谢,怎么看不到内容了呢?
2015-1-20 16:11
0
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
41
tx内部文章就这个水平啊?
2015-1-20 16:18
0
雪    币: 251
活跃值: (301)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
42
[QUOTE=ozone;1347360]模拟按键方法总结

Reference
[1] http://km.oa.com/articles/show/107987?kmref=search 作者dlchu
[2] http://km.oa.com/group/526/articles/show/6060?kmref=search 作者p...[/QUOTE]

有没有大神写个如何跟踪KeyboardClassServiceCallBack的特征码的教程。我想大家很需要这个。
2015-1-25 21:40
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
43
貌似怎么看不到?
2015-1-27 11:31
0
雪    币: 1443
活跃值: (101)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
44
突然发现lz是女生 :-)
2015-1-27 12:00
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
45
内容怎么没了,难道只有我瞎了?
2015-1-27 23:18
0
雪    币: 211
活跃值: (118)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
46
顶你个肺。。。。
2015-1-29 12:24
0
雪    币: 26
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
47
efwwwwwwwwwwwwwwwwwww
2015-1-30 15:34
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
48
谢什么呢?空的!
2015-2-2 16:58
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
49
怎么没有看见??
2015-2-3 10:29
0
雪    币: 206
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
50
什么都没有,骗人的!!
2015-2-3 10:31
0
游客
登录 | 注册 方可回帖
返回
//