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



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

我想这样做,因为我想非常熟悉 win32 API 和恶意软件作者将使用的混淆/加密技术。

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

以下是挑战的链接: 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,并根据 winAPI 文档的要求使用"重新解释强制转换"从 LPWSTR 转换为 BYTE*。(像这样:foo = (BYTE*(test;当测试类型为 LPCWSTR 时(。

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

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

编辑:

我尝试过这段代码,但是当我检查第一个值的 strlen 时,它在第二个十六进制字符串上返回的长度为 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("%hSn", first);
printf("length is: %dn", strlen(first));
LPCWSTR test2 = L"686974207468652062756c6c277320657965";
amount = 0;
BYTE* second = NULL;
second = ToBinary(test2, second, amount);
printf("%hSn", second);
printf("length is: %dn", strlen(second));
return 0;
}

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

C 字符串的长度由终止空字符确定:C 字符串的长度与字符串开头和终止空字符之间的字符数一样长(不包括终止空字符本身(。

所以原因是first的第四个字符是一个终止空字符(''(导致strlen停止并返回3。

最新更新