通过直接调用Kbdclass的回调函数KeyboardClassServiceCallback直接给上层发送键盘驱动。这个方法网上已经公开,参考Hook KeyboardClassServiceCallback实现键盘 Logger,其他的还有很多,可以到网上去查。

简单说一下没有公开的部分,就是按下和松开的模拟,已经扩展键的模拟。

模拟主要是构造KEYBOARD_INPUT_DATA结构,按下和松开的Flags分别对应KEY_MAKE、KEY_BREAK,然后调用KeyboardClassServiceCallback。这里直接用的sudami的代码,在此谢过,懒得改了。代码如下:

case IOCTL_KEY_DOWN :

{

if (ioBuf)

{

lKeyCode = *(ULONG*)ioBuf;

dprintf("[KeyMouse] KeymouseDispatchDeviceControl IOCTL_KEY_DOWN = 0x%x/n", lKeyCode);

dwSize = sizeof(KEYBOARD_INPUT_DATA);

__asm {

push eax

mov kid.UnitId,0 ; 构造 KEYBOARD_INPUT_DATA

mov eax,lKeyCode

mov kid.MakeCode,ax

mov kid.Flags,KEY_MAKE ;模拟按下

mov kid.Reserved,0

mov kid.ExtraInformation,0

lea eax,dwRet

push eax

lea eax,kid

add eax,dwSize

push eax

lea eax,kid

push eax

push g_kbDeviceObject

call orig_KeyboardClassServiceCallback ;利用 KeyboardClassServiceCallback 模拟按键

pop eax

}

status = STATUS_SUCCESS;

}

break;

}

case IOCTL_KEY_UP:

{

if (ioBuf)

{

lKeyCode = *(ULONG*)ioBuf;

dprintf("[KeyMouse] KeymouseDispatchDeviceControl IOCTL_KEY_UP = 0x%x/n", lKeyCode);

dwSize = sizeof(KEYBOARD_INPUT_DATA);

__asm {

push eax

mov kid.UnitId,0 ; 构造 KEYBOARD_INPUT_DATA

mov eax,lKeyCode

mov kid.MakeCode,ax

mov kid.Flags,KEY_BREAK ;模拟松开

mov kid.Reserved,0

mov kid.ExtraInformation,0

lea eax,dwRet

push eax

lea eax,kid

add eax,dwSize

push eax

lea eax,kid

push eax

push g_kbDeviceObject

call orig_KeyboardClassServiceCallback ;利用 KeyboardClassServiceCallback 模拟按键

pop eax

}

status = STATUS_SUCCESS;

}

break;

}

扩展键的区别是按下和松开的Flags分别对应KEY_E0、KEY_E1。其他和上面的一样,这里就不贴代码出来了。主要说一下扩展键有哪几个:(前面是MakeCode,后面代表按钮)

0x1D-RIGHT CONTROL 0x38-RIGHT ALT 0x48-↑ 键 0x50-↓ 键 0x4b-← 键 0x4d-→ 键 0x5B-LEFT WIN 0x5C-RIGHT WIN

重点说一下鼠标的模拟,原理和键盘的一样。查找驱动mouclass.sys中的MouseClassServiceCallback函数,然后获取//Device//PointerClass0设备对象指针,构造MOUSE_INPUT_DATA结构,然后调用MouseClassServiceCallback。难点就在与构造MOUSE_INPUT_DATA结构上面。

typedef struct _MOUSE_INPUT_DATA {

USHORT UnitId;

USHORT Flags;

union {

ULONG Buttons;

struct {

USHORT ButtonFlags;

USHORT ButtonData;

};

};

ULONG RawButtons;

LONG LastX;

LONG LastY;

ULONG ExtraInformation;

} MOUSE_INPUT_DATA, *PMOUSE_INPUT_DATA;

通过调试操作系统调用MouseClassServiceCallback的参数,主要的标示有3个。

Flags标志是标示鼠标的坐标属性(即相对坐标、绝对坐标等)

ButtonFlags标志是左右中键按下和松开的标志

LastX是鼠标X坐标,与Flags标志有关

LastY是鼠标Y坐标,与Flags标志有关

其他几项可以填0。

具体模拟代码如下:

case IOCTL_MOUSE_LEFT_BUTTON_DOWN:

{

MouseFlags = MOUSE_LEFT_BUTTON_DOWN;

goto __MouseCallBack;

}

case IOCTL_MOUSE_LEFT_BUTTON_UP:

{

MouseFlags = MOUSE_LEFT_BUTTON_UP;

goto __MouseCallBack;

}

case IOCTL_MOUSE_RIGHT_BUTTON_DOWN:

{

MouseFlags = MOUSE_RIGHT_BUTTON_DOWN;

goto __MouseCallBack;

}

case IOCTL_MOUSE_RIGHT_BUTTON_UP:

{

MouseFlags = MOUSE_RIGHT_BUTTON_UP;

goto __MouseCallBack;

}

case IOCTL_MOUSE_MIDDLE_BUTTON_DOWN:

{

MouseFlags = MOUSE_MIDDLE_BUTTON_DOWN;

goto __MouseCallBack;

}

case IOCTL_MOUSE_MIDDLE_BUTTON_UP:

{

MouseFlags = MOUSE_MIDDLE_BUTTON_UP;

__MouseCallBack:

mid.UnitId = 0;

mid.Flags = MOUSE_MOVE_RELATIVE;

mid.Buttons = 0;

mid.ButtonFlags = MouseFlags;

mid.RawButtons = 0;

mid.LastX = *((ULONG*)ioBuf);

mid.LastY = *((ULONG*)ioBuf+1);

mid.ExtraInformation = 0;

InputDataStart = ∣

InputDataEnd = InputDataStart+1;

orig_MouseClassServiceCallback(

g_mouDeviceObject,

InputDataStart,

InputDataEnd,

&InputDataConsumed

);

status = STATUS_SUCCESS;

break;

}

case IOCTL_MOUSE_MOVE_RELATIVE:

{

mid.Flags = MOUSE_MOVE_RELATIVE; //相对坐标

goto __MouseMoveCallBack;

}

case IOCTL_MOUSE_MOVE_ABSOLUTE:

{

mid.Flags = MOUSE_MOVE_ABSOLUTE; //绝对坐标

goto __MouseMoveCallBack;

}

case IOCTL_MOUSE_VIRTUAL_DESKTOP:

{

mid.Flags = MOUSE_VIRTUAL_DESKTOP; //虚拟桌面

__MouseMoveCallBack:

mid.UnitId = 1;

mid.Buttons = 0;

mid.RawButtons = 0;

mid.LastX = *((ULONG*)ioBuf);

mid.LastY = *((ULONG*)ioBuf+1);

mid.ExtraInformation = 0;

InputDataStart = ∣

InputDataEnd = InputDataStart+1;

orig_MouseClassServiceCallback(

g_mouDeviceObject,

InputDataStart,

InputDataEnd,

&InputDataConsumed

);

status = STATUS_SUCCESS;

break;

}

驱动在windows XP SP2上测试通过。

linux ps2键盘驱动,通用键盘鼠标模拟(包括USB和PS2)相关推荐

  1. 通用键盘鼠标模拟(包括USB和PS2)

    2019独角兽企业重金招聘Python工程师标准>>> 通过直接调用Kbdclass的回调函数KeyboardClassServiceCallback直接给上层发送键盘驱动.这个方法 ...

  2. linux GPIO模拟PS2 键盘驱动

    背景:公司有一个PS2键盘驱动的项目,没有控制器,需要模拟PS2协议,检测按键并通过input子系统将按键时间上报 一.准备: 1.PS2协议: PS2有两个控制线,时钟线和数据线.当按键按下或抬起, ...

  3. verilog语言的ps2键盘驱动设计

    PS/2接口是目前最常见的鼠标接口,最初是IBM公司的专利,俗称"小口".这是一种鼠标和键盘的专用接口,是一种6针的圆型接口.本设计完成了ps2键盘驱动,并将键盘对应的16进制as ...

  4. 基于GD32VF103 的vga显示器 和ps2键盘 驱动

    基于GD32VF103的vga和ps2键盘驱动 前言 gd32vf103 是国内一款很不错的riscv架构微处理器,但是网上gd32vf103的应用还比较少,这里我决定分享一下利用这个微处理器制作的v ...

  5. Linux GPIO键盘驱动开发记录_OMAPL138

    Linux GPIO键盘驱动开发记录_OMAPL138 Linux基本配置完毕了,这几天开始着手Linux驱动的开发,从一个最简单的键盘驱动开始,逐步的了解开发驱动的过程有哪些.看了一下Linux3. ...

  6. 进阶项目(12)PS2键盘驱动程序设计讲解

    写在前面的话 我们从小就开始接触电脑,曾经多么羡慕那些在键盘上洋洋洒洒的人,手指轻柔的飞舞,刻画出一章章美丽的篇幅-那么作为工程师的我们,同样拥有着属于我们的情怀.如果曾经的向往变成我们喜欢的玩具:如 ...

  7. Linux 下wifi 驱动开发(四)—— USB接口WiFi驱动浅析

    前面学习了SDIO接口的WiFi驱动,现在我们来学习一下USB接口的WiFi驱动,二者的区别在于接口不同.而USB接口的设备驱动,我们前面也有学习,比如USB摄像头驱动.USB鼠标驱动,同样都符合Li ...

  8. linux wifi设置端口号,Linux 下wifi 驱动开发(四)—— USB接口WiFi驱动浅析

    前面学习了SDIO接口的WiFi驱动,现在我们来学习一下USB接口的WiFi驱动,二者的区别在于接口不同.而USB接口的设备驱动,我们前面也有学习,比如USB摄像头驱动.USB鼠标驱动,同样都符合Li ...

  9. linux ps2键盘驱动,Linux下USB模拟ps2鼠标驱动

    在linu-kernel/drivers/input/mouse/psmouse-base.c是ps2鼠标驱动的主体,如psmouse_reset.psmouse_connect等函数具体实现在此文件 ...

最新文章

  1. 2021年大数据Flink(三十三):​​​​​​​Table与SQL相关概念
  2. Spring Boot thymeleaf模版支持,css,js等静态文件添加
  3. java报错误设置属性值_java – 设置属性值时出错;嵌套异常是org.springframework.beans.NotWritablePropertyException:...
  4. 计算机辅助药物设计局限,计算机辅助药物设计高效低耗
  5. Hive的索引操作【小结】
  6. Tomcat 之 启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099;...
  7. AttributeError: ‘pyltp.Postagger‘ object has no attribute ‘load‘
  8. B2B电子商务网站杂谈
  9. 可以学计算机再学美术,想学习板绘?教你如何在电脑学习绘画!
  10. mysql 中国省份城市数据库表
  11. 如何把高版本unity资源导入Laya
  12. html中用于超链接的标签,html中,超链接用的是什么标签
  13. linux – signal 信号列表
  14. 高质量的视频播放往往只需要一个m3u8文件 视频流搞起来
  15. 2022年河北省高职单招(综合素质)考试冲刺试题及答案
  16. R语言旋转扇形图的绘制
  17. 成功男人背后的女人——马云漂亮老婆张瑛简介及珍贵照片曝光
  18. 数据分析——Kettle插件开发异常信息总结
  19. void value not ignored as it ought to be解决方法
  20. android相机保存文件为空,android 调用系统相机拍照,返回的data为null

热门文章

  1. cad钣金展开插件_钣金折弯展开的计算方法汇总
  2. CVPR 2021 | 跨模态点云补全新框架ViPC:用单一视图推断完整信息
  3. Linux的10个最危险的命令
  4. 算法动画 - 理解函数曲线
  5. 27岁姑娘,去世前一天,留给世界这封信,看哭众多网友
  6. lucene中write.lock索引锁机制的原理
  7. 关于在头文件中定义变量
  8. output.properties data exceeds its limit [2048] HUE执行脚本异常
  9. ubuntu 安装cmake
  10. ubunut安装分区建议