Я изучаю Win32 API и C ++, и я хотел сделать простой кейлоггер. Вот что я придумал:
#include <Windows.h>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
LRESULT CALLBACK kbLog1(int code, WPARAM wParam, LPARAM lParam);
void initKbLogger();
void kbLog2(int code, WPARAM wParam, LPARAM lParam);
HHOOK keyHook;
void Hworld() {
initKbLogger();
}
void initKbLogger() {
keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, kbLog1, NULL, NULL);
bool caps;
if ((GetKeyState(VK_CAPITAL) & 0x0001) != 0) {
caps = true;
}
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL) != 0);
UnhookWindowsHookEx(keyHook);
}
// from https://stackoverflow.com/a/3999597
// will convert LPCWSTR to std::string
std::string utf8_encode(const std::wstring& wstr)
{
if (wstr.empty()) return std::string();
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
return strTo;
}
// main hook fn, supposed to run CallNextHookEx no matter what happens in kbLog2
LRESULT CALLBACK kbLog1(int code, WPARAM wParam, LPARAM lParam) {
OutputDebugStringA("heya");
kbLog2(code, wParam, lParam);
OutputDebugStringA("heya2");
return CallNextHookEx(keyHook, code, wParam, lParam);
}
void kbLog2(int code, WPARAM wParam, LPARAM lParam) {
if ((code != 0) || (wParam != WM_KEYDOWN)) {
return;
}
LPKBDLLHOOKSTRUCT kbHookData = (LPKBDLLHOOKSTRUCT)lParam;
BYTE keyboard_state[256];
GetKeyboardState(keyboard_state);
WCHAR wChar[4];
int ret = ToUnicode((UINT)kbHookData->vkCode, kbHookData->scanCode, keyboard_state, wChar, 4, 0);
if (ret == -1) {
return;
}
string lol = utf8_encode(wChar);
std::ostringstream out;
out << wChar;
string ss = "hello, you typed the following key: " + lol + " " + out.str();
MessageBoxA(0, ss.c_str(), "Heya", 0);
}
Однако проблема в том, что этот код не может отображать акцентированные символы, которые я печатаю на клавиатуре. Например, нажатие «A» работает просто отлично, но нажатие «é» не отображает реальный символ. Что не так? Я предполагаю, что что-то не так с преобразованием vkCode в строку, но я не вижу, что я сделал неправильно ... Любая помощь? Спасибо