日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

發布時間:2024/9/27 linux 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux ps2键盘驱动,通用键盘鼠标模拟(包括USB和PS2) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

通過直接調用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)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。