簡體   English   中英

在Windows注冊表中正確將字符串添加到REG_BINARY類型

[英]Correctly add string to a REG_BINARY type in Windows Registry

我正在嘗試自動化將軟件策略哈希規則添加到Windows的過程,並且當前在向注冊表中添加有效哈希時遇到問題。 此代碼創建一個密鑰,並將哈希添加到注冊表中:

HKEY* m_hKey;
string md5Digest;
string valueName = "ItemData";
vector<BYTE> itemData;

/*
use Crypto++ to get file hash
*/

//convert string to format that can be loaded into registry
for (int i = 1; i < md5Digest.length(); i += 2)
    itemData.push_back('0x' + md5Digest[i - 1] + md5Digest[i]);

// Total data size, in bytes
const DWORD dataSize = static_cast<DWORD>(itemData.size());

::RegSetValueEx(
    m_hKey,
    valueName.c_str(),
    0, // reserved
    REG_BINARY,
    &itemData[0],
    dataSize
);

這可以正常工作,並將密鑰添加到注冊表:

我的哈希規則

但是,當將注冊表項與組策略添加的規則進行比較時,您會發現一個非常重要的區別:

Windows添加了哈希規則

它們之間的“ ItemData”值不同。 底部圖片的ItemData值是正確的輸出。 在調試程序時,我可以清楚地看到md5Digest具有正確的值,因此問題出在md5Digest字符串到BYTE的ItemData向量或無符號字符的轉換上。

Visual Studio調試

我的代碼有什么問題,為什么將數據錯誤地輸入注冊表?

您將'0x'兩個字母的char文字與md5Digest[i - 1] + md5Digest[i]相加,然后綁定到BYTE 看起來您正在嘗試從中構建“ 0xFF”字節值。 您應該直接存儲md5字符串:

const DWORD dataSize = static_cast<DWORD>(md5Digest.size());

::RegSetValueEx(
    m_hKey,
    valueName.c_str(),
    0, // reserved
    REG_BINARY,
    reinterpret_cast< BYTE const *>(md5Digest.data()),
    dataSize
);

如果您實際上需要存儲來自md5的十六進制數字的二進制表示形式,則需要將其轉換為以下字節:

BYTE char_to_halfbyte(char const c)
{
    if(('0' <= c) && (c <= '9'))
    {
        return(static_cast<BYTE>(c - `0`));
    }
    else
    {
        assert(('A' <= c) && (c <= 'F'));
        return(static_cast<BYTE>(10 + c - `A`));
    }
}

for(std::size_t i = 0; i < md5Digest.length(); i += 2)
{
    assert((i + 1) < md5Digest.length());
    itemData.push_back
    (
       (char_to_halfbyte(md5Digest[i    ]) << 4)
       |
       (char_to_halfbyte(md5Digest[i + 1])     )
    );
}

您有一個要轉換為字節數組的字符串。 您可以編寫一個輔助函數,將2個字符轉換為BYTE:

using BYTE = unsigned char;

BYTE convert(char a, char b)
{
    // Convert hex char to byte
    // Needs fixin for lower case
    if (a >= '0' && a <= '9') a -= '0';
    else a -= 55;  // 55 = 'A' - 10
    if (b >= '0' && b <= '9') b -= '0';
    else b -= 55;

    return (a << 4) | b;
}
....
vector<BYTE> v;
string s = "3D65B8EBDD0E";
for (int i = 0; i < s.length(); i+=2) {
    v.push_back(convert(s[i], s[i+1]));
}

v現在包含{0x3D, 0x65, 0xB8, 0xEB, 0xDD, 0x0E}

或者,如@RbMm所述,您可以使用CryptStringToBinary Windows函數:

#include <wincrypt.h>
...
std::string s = "3D65B8EBDD0E";
DWORD hex_len = s.length() / 2;
BYTE *buffer = new BYTE[hex_len];
CryptStringToBinary(s.c_str(),
    s.length(),
    CRYPT_STRING_HEX,
    buffer, 
    &hex_len,
    NULL,
    NULL
    );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM