使用 win32 API 宽字符串将十六进制转换为字节 - matasano 挑战 #2

Converting hex to bytes using the win32 API wide string - matasano challenge #2

我已经开始做 matasano 挑战,并决定只使用 C PL 和 win32 API。

我想这样做是因为我想非常熟悉 win32 API 和恶意软件作者会使用的 obfuscation/encryption 技术。

我注意到第二个挑战将要求我使用 CryptStringToBinary (=CryptStringToBinaryW) 的宽字符串版本,因为我无法正确解码第一个十六进制字符串(只有 3 个字符正确解码,而不是第二个给定的十六进制字符串中的 18 个字符)。

这是挑战的link: https://cryptopals.com/sets/1/challenges/2

在过去的几个小时里,我一直在努力尝试将其转换为宽字符串版本,但我根本无法让它工作,这是我当前的代码(非常适合 ANSI):

LPSTR ToBinary(BYTE* test, LPSTR buffer, DWORD amount) {
if (CryptStringToBinaryA(test, strlen(test), CRYPT_STRING_HEXRAW, NULL, &amount, NULL, NULL))
{
    buffer = malloc(amount + 1);
    memset(buffer, 0, amount + 1);
    if (buffer == NULL)
    {
        printf("failed, error: %lu", GetLastError());
        return NULL;
    }
    if (CryptStringToBinaryA(test, strlen(test), CRYPT_STRING_HEXRAW, buffer, &amount, NULL, NULL))
    {
        printf("%s \n", buffer);
    }
}
else
    printf("failed, error: %lu", GetLastError());

return buffer;


 }


int main(void)
{
    BYTE * test = "1c0111001f010100061a024b53535009181c";
    LPSTR first = NULL;
    DWORD amount = 0;
    first = ToBinary(test, first, amount);


    LPSTR buffer2 = NULL;
    BYTE* test2 = "686974207468652062756c6c277320657965";
    amount = 0;
    LPSTR second = NULL;
    second = ToBinary(test2, second, amount);



    return 0;
}

我的问题是:

如何将其转换为宽字符串版本?

我已经尝试将所有 LPSTR 替换为 LPWSTR,strlen 到 wsclen,并使用 "reinterpret casting" 将 LPWSTR 转换为 BYTE*,如 winAPI 文档所要求的那样。 (像这样:foo = (BYTE*)test; 当 test 是 LPCWSTR 类型时)。

但是在我进行了所有更改之后,我的程序不再运行了。

我是 C 编程的初学者,对于这类转换问题,我可能缺少正确的 "attitude",我希望这不是与另一个问题的直接重复。

编辑:

我试过这段代码,但是当我检查第一个值的 strlen 时,它 returns 在第二个十六进制字符串上 returns 长度为 3 而不是 18:

长度为:3

正中靶心

长度为:18


这是我试过的代码:

BYTE* ToBinary(LPCWSTR test, BYTE* buffer, DWORD amount) {
    if (CryptStringToBinaryW(test, wcslen(test), CRYPT_STRING_HEXRAW, NULL, &amount, NULL, NULL))
    {
        buffer = malloc(amount + 1);
        memset(buffer, 0, amount + 1);
        if (buffer == NULL)
        {
            printf("failed, error: %lu", GetLastError());
            return NULL;
        }
        if (CryptStringToBinaryW(test, wcslen(test), CRYPT_STRING_HEXRAW, buffer, &amount, NULL, NULL))
        {
            return buffer;
        }
    }
    printf("failed, error: %lu", GetLastError());
    return 0;
}


int main(void)
{
    LPCWSTR test = L"1c0111001f010100061a024b53535009181c";
    BYTE* first = NULL;
    DWORD amount = 0;
    first = ToBinary(test, first, amount);
    printf("%hS\n", first);
    printf("length is: %d\n", strlen(first));

    LPCWSTR test2 = L"686974207468652062756c6c277320657965";
    amount = 0;
    BYTE* second = NULL;
    second = ToBinary(test2, second, amount);
    printf("%hS\n", second);
    printf("length is: %d\n", strlen(second));

    return 0;
}

I've tried this code but when I check the strlen of the first value, it returns a length of 3 rather than 18 on the second hex string:

C字符串的长度由终止空字符决定:C字符串的长度等于字符串开头和终止空字符之间的字符数(不包括终止空字符本身)。

所以原因是 first 的第四个字符是终止空字符 ('[=11=]') 导致 strlen 停止和 return 3.