先给大家分享一个小故事:
一天,我学习到了一个可以伪造系统消息的函数,然后在我的电脑上用了一下......
然后许多按键失效,重启才恢复正常......
先来认识一下这个主犯:
UINT SendInput(
_IN_ UINT cInputs,
_IN_ LPINPUT pInputs,
_IN_ int cbSize
);
有了他,我们可以“创造”出任何一个系统消息。在来了解一下另一个函数...
BOOL WINAPI SetConsoleCursorPosition(
_In_ HANDLE hConsoleOutput,
_In_ COORD dwCursorPosition
);
这个函数的作用是定位光标。
结合以上两个函数,我们甚至可以不敲键盘打字(设置光标位置+伪造键盘输入事件)
再来认识几个结构体:
typedef struct tagINPUT {
DWORD type;
union
{
MOUSEINPUT mi;
KEYBDINPUT ki;
HARDWAREINPUT hi;
} DUMMYUNIONNAME;
} INPUT, *PINPUT, FAR* LPINPUT;
typedef struct tagMOUSEINPUT {
LONG dx;
LONG dy;
DWORD mouseData;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT, FAR* LPMOUSEINPUT;
typedef struct tagKEYBDINPUT {
WORD wVk;
WORD wScan;
DWORD dwFlags;
DWORD time;
/*
* When dwFlags has KEYEVENTF_SYSTEMINJECTION specified this field may carry
* KEY_UNICODE_SEQUENCE_ITEM or KEY_UNICODE_SEQUENCE_END which are used by InputService
* to distinguish injected unicode sequences. Those flags are stored in low word.
* When dwFlags has KEYEVENTF_ATTRIBUTED_INPUT specified this field carries in its high word
* ID of attributes associated with injected input. This ID is assigned by InputService and
* recognized only by it.
* For all other usage scenarios please refer to official documentation.
*/
ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT, FAR* LPKEYBDINPUT;
typedef struct tagHARDWAREINPUT {
DWORD uMsg;
WORD wParamL;
WORD wParamH;
} HARDWAREINPUT, *PHARDWAREINPUT, FAR* LPHARDWAREINPUT;
来看一个实例
int ShowFileExplor()
{
INPUT inputs[4] = {};
ZeroMemory(inputs, sizeof(inputs));
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VK_LWIN;
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = 'E';
inputs[2].type = INPUT_KEYBOARD;
inputs[2].ki.wVk = 'E';
inputs[2].ki.dwFlags = KEYEVENTF_KEYUP;
inputs[3].type = INPUT_KEYBOARD;
inputs[3].ki.wVk = VK_LWIN;
inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;
UINT uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
if (uSent != ARRAYSIZE(inputs)){
return -1;
}
else{
return 0;
}
}
作用是打开文件资源管理器。