使用 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.
我已经开始做 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.