UINT SendInput( UINT nInputs, LPINPUT pInputs, int cbSize );
函数说明:
该函数合成键盘事件和鼠标事件,用来模拟鼠标或者键盘操作。事件将被插入在鼠标或者键盘处理队列里面。
参数说明:
nInputs 指定ninput 数组中元素的个数。就是插入事件的个数。
pInputs 指向一个类型为INPUT的 数组变量,该数组中的每个元素代表一个将要插入到线程事件中去的键盘或鼠标事件。
cbSize 指定INPUT结构的大小。如果cbSize不是INPUT结构的大小,则函数将失败返回
搜索框
Hook了Explorer的进程的SendInput,然后在文件的搜索框中执行右键-粘贴,通过打印log看到
00000004 36.62250900 [4492] keyboard message::wVk=0x0011,wScan=0x0000,dwFlags=0x00000000
00000005 36.62262726 [4492] keyboard message::wVk=0x0056,wScan=0x0000,dwFlags=0x00000000
00000006 36.62281036 [4492] keyboard message::wVk=0x0056,wScan=0x0000,dwFlags=0x00000002
00000007 36.62294769 [4492] keyboard message::wVk=0x0011,wScan=0x0000,dwFlags=0x00000002
dwFlags 0 代表 DOWN
dwFlags 2 代表UP
键盘虚拟码wVK对应的键盘
虚拟键盘代码 | 16进制值 | 对应键 |
VK_LBUTTON | 0x01 | 鼠标左键 |
VK_RBUTTON | 0x02 | 鼠标右键 |
VK_CANCEL | 0x03 | 用于执行Ctrl+C或Ctrl+Break |
VK_MBUTTON | 0x04 | 鼠标中键 |
VK_XBUTTON1 | 0x05 | NOT contiguous with L & RBUTTON |
VK_XBUTTON2 | 0x06 | NOT contiguous with L & RBUTTON |
NUL | 0x07 | unassigned |
VK_BACK | 0x08 | Backspace键 |
VK_TAB | 0x09 | Tab键 |
NUL | 0x0A | reserved |
NUL | 0x0B | reserved |
VK_CLEAR | 0x0C | Clear键 |
VK_RETURN | 0x0D | Enter键 |
VK_SHIFT | 0x10 | Shift键 |
VK_CONTROL | 0x11 | Ctrl键 |
VK_MENU | 0x12 | Arl键 |
VK_PAUSE | 0x13 | Pause键 |
VK_CAPITAL | 0x14 | Capslock键 |
VK_KANA | 0x15 | |
VK_HANGEUL | 0x15 | old name - should be here for compatibility |
VK_HANGUL | 0x15 | |
VK_ESCAPE | 0x1B | Ese键 |
VK_SPACE | 0x20 | SpaceBar键 |
VK_PRIOR | 0x21 | PgUp键 |
VK_NEXT | 0x22 | PgDn键 |
VK_END | 0x23 | End键 |
VK_HOME | 0x24 | Home键 |
VK_LEFT | 0x25 | LeftArrow键左 |
VK_UP | 0x26 | UpArrow键上 |
VK_RIGHT | 0x27 | RightArrow键右 |
VK_DOWN | 0x28 | DownArrow键下 |
VK_SELECT | 0x29 | Select键 |
VK_EXECUTE | 0x2B | Execute键 |
VK_SNAPSHOT | 0x2C | PrintScreen键 |
VK_INSERT | 0x2D | Ins键 |
VK_DELECT | 0x2E | Del键 |
VK_HELP | 0x2F | Help键 |
VK_0 | 0x30 | 0键 |
VK_1 | 0x31 | 1键 |
VK_2 | 0x32 | 2键 |
VK_3 | 0x33 | 3键 |
VK_4 | 0x34 | 4键 |
VK_5 | 0x35 | 5键 |
VK_6 | 0x36 | 6键 |
VK_7 | 0x37 | 7键 |
VK_8 | 0x38 | 8键 |
VK_9 | 0x39 | 9键 |
NUL | 0x40 | unassigned |
VK_A | 0x41 | A键 |
VK_B | 0x42 | B键 |
VK_C | 0x43 | C键 |
VK_D | 0x44 | D键 |
VK_E | 0x45 | E键 |
VK_F | 0x46 | F键 |
VK_G | 0x47 | G键 |
VK_H | 0x48 | H键 |
VK_I | 0x49 | I键 |
VK_J | 0x4A | J键 |
VK_K | 0x4B | K键 |
VK_L | 0x4C | L键 |
VK_M | 0x4D | M键 |
VK_N | 0x4E | N键 |
VK_O | 0x4F | O键 |
VK_P | 0x50 | P键 |
VK_Q | 0x51 | Q键 |
VK_R | 0x52 | R键 |
VK_S | 0x53 | S键 |
VK_T | 0x54 | T键 |
VK_U | 0x55 | U键 |
VK_V | 0x56 | V键 |
VK_W | 0x57 | W键 |
VK_X | 0x58 | X键 |
VK_Y | 0x59 | Y键 |
VK_Z | 0x5A | Z键 |
VK_LWIN | 0x5B | 左Win键 |
VK_RWIN | 0x5C | 右Win键 |
VK_APPS | 0x5D | |
NUL | 0x5E | reserved |
VK_NUMAPD0 | 0x60 | 数字板0键 |
VK_NUMAPD1 | 0x61 | 数字板1键 |
VK_NUMAPD2 | 0x62 | 数字板2键 |
VK_NUMAPD3 | 0x63 | 数字板3键 |
VK_NUMAPD4 | 0x64 | 数字板4键 |
VK_NUMAPD5 | 0x65 | 数字板5键 |
VK_NUMAPD6 | 0x66 | 数字板6键 |
VK_NUMAPD7 | 0x67 | 数字板7键 |
VK_NUMAPD8 | 0x68 | 数字板8键 |
VK_NUMAPD9 | 0x69 | 数字板9键 |
VK_MULTIPY | 0x6A | 乘号键 |
VK_ADD | 0x6B | 加号键 |
VK_SEPARATOR | 0x6C | Separator键 |
VK_SUBSTRACT | 0x6D | 减号键 |
VK_DECIMAL | 0x6E | 小数点键 |
VK_DIVIDE | 0x6F | 除号键 |
VK_F1 | 0x70 | F1键 |
VK_F2 | 0x71 | F2键 |
VK_F3 | 0x72 | F3键 |
VK_F4 | 0x73 | F4键 |
VK_F5 | 0x74 | F5键 |
VK_F6 | 0x75 | F6键 |
VK_F7 | 0x76 | F7键 |
VK_F8 | 0x77 | F8键 |
VK_F9 | 0x78 | F9键 |
VK_F10 | 0x79 | F10键 |
VK_F11 | 0x7A | F11键 |
VK_F12 | 0x7B | F12键 |
VK_F13 | 0x7C | F13键 |
VK_F14 | 0x7D | F14键 |
VK_F15 | 0x7E | F15键 |
VK_F16 | 0x7F | F16键 |
VK_F17 | 0x80 | F17键 |
VK_F18 | 0x81 | F18键 |
VK_F19 | 0x82 | F19键 |
VK_F20 | 0x83 | F20键 |
VK_F21 | 0x84 | F21键 |
VK_F22 | 0x85 | F22键 |
VK_F23 | 0x86 | F23键 |
VK_F24 | 0x87 | F24键 |
NUL | 0x88 | reserved |
NUL | 0x89 | reserved |
NUL | 0x8A | unassigned |
NUL | 0x8B | unassigned |
NUL | 0x8C | unassigned |
NUL | 0x8D | unassigned |
NUL | 0x8E | unassigned |
NUL | 0x8F | unassigned |
VK_NUMLOCK | 0x90 | NumLock键 |
VK_SCROLL | 0x91 | ScrollLock键 |
VK_OEM_NEC_EQUAL | 0x92 | NEC PC-9800 kbd definitions,key on numpad |
VK_OEM_FJ_JISHO | 0x92 | Fujitsu/OASYS kbd definitions,Dictionary' key |
VK_OEM_FJ_MASSHOU | 0x93 | Unregister word key |
VK_OEM_FJ_TOUROKU | 0x94 | Register word key |
VK_OEM_FJ_LOYA | 0x95 | Left OYAYUBI key |
VK_OEM_FJ_ROYA | 0x96 | Right OYAYUBI key |
NUL | 0x97 | unassigned |
NUL | 0x98 | unassigned |
NUL | 0x99 | unassigned |
NUL | 0x9A | unassigned |
NUL | 0x9B | unassigned |
NUL | 0x9C | unassigned |
NUL | 0x9D | unassigned |
NUL | 0x9E | unassigned |
NUL | 0x9F | unassigned |
VK_LSHIFT | 0xA0 | |
VK_LSHIFT | 0xA0 | |
VK_RSHIFT | 0xA1 | |
VK_LCONTROL | 0xA2 | |
VK_RCONTROL | 0xA3 | |
VK_LMENU | 0xA4 | |
VK_RMENU | 0xA5 | |
VK_BROWSER_BACK | 0xA6 | |
VK_BROWSER_FORWARD | 0xA7 | |
VK_BROWSER_REFRESH | 0xA8 | |
VK_BROWSER_STOP | 0xA9 | |
VK_BROWSER_SEARCH | 0xAA | |
VK_BROWSER_FAVORITES | 0xAB | |
VK_BROWSER_HOME | 0xAC | |
VK_VOLUME_MUTE | 0xAD | |
VK_VOLUME_DOWN | 0xAE | |
VK_VOLUME_UP | 0xAF | |
VK_MEDIA_NEXT_TRACK | 0xB0 | |
VK_MEDIA_PREV_TRACK | 0xB1 | |
VK_MEDIA_STOP | 0xB2 | |
VK_MEDIA_PLAY_PAUSE | 0xB3 | |
VK_LAUNCH_MAIL | 0xB4 | |
VK_LAUNCH_MEDIA_SELECT | 0xB5 | |
VK_LAUNCH_APP1 | 0xB6 | |
VK_LAUNCH_APP2 | 0xB7 | |
NUL | 0xB8 | reserved |
NUL | 0xB9 | reserved |
VK_OEM_1 | 0xBA | For US |
VK_OEM_PLUS | 0xBB | Any country |
VK_OEM_COMMA | 0xBC | Any country |
VK_OEM_MINUS | 0xBD | Any country |
VK_OEM_PERIOD | 0xBE | Any country |
VK_OEM_2 | 0xBF | For US |
VK_OEM_3 | 0xC0 | For US |
NUL | 0xC1 | reserved |
NUL | 0xC2 | reserved |
NUL | 0xC3 | reserved |
NUL | 0xC4 | reserved |
NUL | 0xC5 | reserved |
NUL | 0xC6 | reserved |
NUL | 0xC7 | reserved |
NUL | 0xC8 | reserved |
NUL | 0xC9 | reserved |
NUL | 0xCA | reserved |
NUL | 0xCB | reserved |
NUL | 0xCC | reserved |
NUL | 0xCD | reserved |
NUL | 0xCE | reserved |
NUL | 0xCF | reserved |
NUL | 0xD0 | reserved |
NUL | 0xD1 | reserved |
NUL | 0xD2 | reserved |
NUL | 0xD3 | reserved |
NUL | 0xD4 | reserved |
NUL | 0xD5 | reserved |
NUL | 0xD6 | reserved |
NUL | 0xD7 | reserved |
NUL | 0xD8 | unassigned |
NUL | 0xD9 | unassigned |
NUL | 0xDA | unassigned |
VK_OEM_4 | 0xDB | for US |
VK_OEM_5 | 0xDC | for US |
VK_OEM_6 | 0xDD | for US |
VK_OEM_7 | 0xDE | for US |
VK_OEM_8 | 0xDF | |
NUL | 0xE0 | reserved |
VK_OEM_AX | 0xE1 | key on Japanese AX kbd |
VK_OEM_102 | 0xE2 | on RT 102-key kbd. |
VK_ICO_HELP | 0xE3 | Help key on ICO |
VK_ICO_00 | 0xE4 | 00 key on ICO |
VK_OEM_8 | 0xDF | |
VK_PROCESSKEY | 0xE5 | |
VK_ICO_CLEAR | 0xE6 | |
VK_PACKET | 0xE7 | |
NUL | 0xE8 | unassigned |
VK_OEM_RESET | 0xE9 | |
VK_OEM_JUMP | 0xEA | |
VK_OEM_PA1 | 0xEB | |
VK_OEM_PA2 | 0xEC | |
VK_OEM_PA3 | 0xED | |
VK_OEM_WSCTRL | 0xEE | |
VK_OEM_CUSEL | 0xEF | |
VK_OEM_ATTN | 0xF0 | |
VK_OEM_FINISH | 0xF1 | |
VK_OEM_COPY | 0xF2 | |
VK_OEM_AUTO | 0xF3 | |
VK_OEM_ENLW | 0xF4 | |
VK_OEM_BACKTAB | 0xF5 | |
VK_ATTN | 0xF6 | |
VK_CRSEL | 0xF7 | |
VK_EXSEL | 0xF8 | |
VK_EREOF | 0xF9 | |
VK_PLAY | 0xFA | |
VK_ZOOM | 0xFB | |
VK_NONAME | 0xFC | |
VK_PA1 | 0xFD | |
VK_OEM_CLEAR | 0xFE | |
NUL | 0xFF | reserved |
翻译一下log的意思是
按下Contorl ---- 按下V-----抬起V----抬起Control。 完全模拟了一次粘贴的操作。
其中log代码
UINT WINAPI HOOK_SendInput(
UINT nInputs,
LPINPUT pInputs,
int cbSize)
{
for (size_t i = 0; i < nInputs; i++)
{
if (pInputs[i].type == INPUT_KEYBOARD)
{
CString stroutput;
stroutput.Format(L"keyboard message::wVk=0x%04x,wScan=0x%04x,dwFlags=0x%08x\n", pInputs[i].ki.wVk, pInputs[i].ki.wScan, pInputs[i].ki.dwFlags);
OutputDebugString(stroutput.GetBuffer());
}
else if (pInputs[i].type == INPUT_MOUSE)
{
OutputDebugString(L"mouse message\n");
}
}
return REAL_SendInput(nInputs, pInputs, cbSize);
}
往哪个窗体发我们可以获得
DWORD dwProcessId = 0;
HWND hwnd = GetForegroundWindow();
if (hwnd)
{
GetWindowThreadProcessId(hwnd, &dwProcessId);
}
最后贴几个网址
SendInput模拟鼠标
https://blog.csdn.net/u012372584/article/details/53839929
模拟键盘