Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383
Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383
模拟键盘是一个简单的话题,随便普通程序猿都能说出好多种方式。不同的方式应用于不同场合,总的来说分为三大类:
1、用户层模拟键盘
这个层来模拟是最方便的,但也是最容易无效的。总的来说有三种方式,第一种是直接往目标窗口发送按键消息;第二种是使用剪贴板复制待粘贴消息然后在目标窗口模拟Ctrl+V;第三种是用户层触发按键事件
这儿贴一个模拟输入一个字节的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | bool input (char ch) { DWORD KeyScan = ::OemKeyScan (ch); bool bShift = !!(KeyScan >> 16); UINT uCode = KeyScan & 0xFFFF; UINT uScanCode = ::MapVirtualKey (uCode, MAPVK_VK_TO_VSC); UINT uShiftScanCode = ::MapVirtualKey (VK_SHIFT, MAPVK_VK_TO_VSC); if (bShift) { ::keybd_event (VK_SHIFT, (BYTE) uShiftScanCode, KEYEVENTF_EXTENDEDKEY, 0); std::this_thread::sleep_for (std::chrono::milliseconds (20)); } ::keybd_event (uCode, (BYTE) uScanCode, KEYEVENTF_EXTENDEDKEY, 0); std::this_thread::sleep_for (std::chrono::milliseconds (20)); ::keybd_event (uCode, (BYTE) uScanCode, KEYEVENTF_KEYUP, 0); std::this_thread::sleep_for (std::chrono::milliseconds (20)); if (bShift) { ::keybd_event (VK_SHIFT, (BYTE) uShiftScanCode, KEYEVENTF_KEYUP, 0); std::this_thread::sleep_for (std::chrono::milliseconds (20)); } return true; } |
这个函数很可能在一些有简单安全措施的软件里面失效。软件屏蔽键盘模拟按键一般是使用钩子,那么可以dll注入然后反钩子,挂钩SetWindowsHookEx即可。注意反钩子必须和目标在同一个进程里,否则M$的Copy-On-Write会让反钩子失效。示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | BOOL func_unhook (LPVOID func_ptr, WORD param_num, DWORD ret_val) { // mov eax, 12345678h // ret 0004h BYTE bBuf [] = { '\xB8', '\x00', '\x00', '\x00', '\x00', '\xC2', '\x00', '\x00' }; *(DWORD*) (&bBuf [1]) = ret_val; *(WORD*) (&bBuf [6]) = param_num * 4; DWORD dw = 0, dw2 = 0; BOOL bRet = ::VirtualProtect (func_ptr, 8, PAGE_EXECUTE_READWRITE, &dw); if (!bRet) return FALSE; ::memcpy (func_ptr, bBuf, 8); if (func_ptr != ::VirtualProtect) ::VirtualProtect (func_ptr, 8, dw, &dw2); return TRUE; } func_unhook (::SetWindowsHookA, 2, 1); func_unhook (::SetWindowsHookW, 2, 1); func_unhook (::UnhookWindowsHook, 2, 1); func_unhook (::SetWindowsHookExA, 4, 1); func_unhook (::SetWindowsHookExW, 4, 1); func_unhook (::UnhookWindowsHookEx, 1, 1); |
反钩子后模拟键盘事件差不多可以过绝大部分弱保护的安全措施了,不过这也不完全总是灵的。如果以上方法都不行,可以试试其他方案。
继续阅读C++:模拟键盘