繁体   English   中英

如何在C / C ++中将非ASCII字符注入字符串文字

[英]How to inject non-ASCII characters into a string literal in C/C++

我有一个读取字符数组的程序。 我需要内存中字符串的值等于所有非ASCII字符的十六进制0x01020304。 所以问题是,如何在运行时将非ASCII字符传递到字符串文字变量中?

使用转义序列。 确保按正确的顺序放置字符。

"\x01\x02\x03\x04"

编辑:如果需要将序列放入现有的char数组中,只需将其分配即可。

char s[4];

// ... later ...
s[0] = 0x01;
s[1] = 0x02;
s[2] = 0x03;
s[3] = 0x04;

不要尝试通过将s强制转换为(int32_t *)来分配数字,char数组的对齐方式不正确。

在C语言中,最简单的方法可能是使用十六进制转义符号: "\\x01\\x02\\x03\\x04" (没有x的值是八进制的,这在当今并不流行或不易理解。)

或者,

char x[] = {1, 2, 3, 4, 0};

应该起作用(注意,像这样初始化时必须包含空终止符)。

我需要内存中字符串的值等于所有非ASCII字符的十六进制0x01020304。

请注意,如何在内存中安排4个连续的字节,这取决于您的系统是big-endian还是little-endian。 如果您关心32位字段的工作方式,则仅将内容放入字符串文字中是行不通的。

例如:

您可以尝试使用av​​akar建议的方法:

char cString[5] = "\x01\x02\x03\x04";

甚至只是做

cString[0] = 0x01;
cString[1] = 0x02;
...

但是如果您希望内存中的实际物理布局有意义:

// assuming unsigned int is 32 bits
unsigned int* cStringAlias = rentirpret_cast<int*>(&cString[0]);
std::cout << (*cStringAlias)

请注意 ,根据最高有效字节是放置在第0位还是第3位,输出将有所不同。

输出可能是

0x01020304

要么

0x04030201

有关更多信息,请阅读有关耐力的信息

好吧,您确定需要字符串文字吗?

这些都很相似:

const char* blah = "test";
char blah[] = "test";
char blah[] = { 't','e','s','t',0 };

当然,您可以很轻松地使用第三种形式来满足您的需求。

由于您正在谈论注入,因此我将为您提供一个线索(这对于出于学术目的利用缓冲区溢出漏洞的代码注入很有用)...您必须将终端配置为接受unicode(在我的Mac中,可以默认写入)。 因此,您编写了例如∫这样的东西,当您输入unicode字符时,它不像常规char那样仅占用一个字节的内存,它将占用更多字节(可以是2、3或4个字节),因此如果您有一个数组

char v[4];

如果您使用

gets(v); //insecure function to read

并输入∫,将占用v的4个字节用以下值填充(十进制):

-30
-120
-85
0

如果看到这些位置中的任何一个,则它们都不是可打印的ASCII,这可能是一些代码,您可以进入内存并通过黑客修改堆栈中的返回目录来使程序执行它,也可以利用相同的缓冲区溢出漏洞允许gets()。 (要获取代码,请在HEX编辑器中打开程序,以查看编译时的外观)!

因此,您只需通过在文件中打印来找到与所需字符相匹配的正确unicode字符

在此链接中,任何人都可以了解如何在堆栈中分配内存http://eli.thegreenplace.net/2011/02/04/ where- the-top-of-the-stack-is-on- x86 /

(似乎@Ben甚至都没有帐户,但是对于正在学习需要它的安全编程的任何人而言)

将源代码保存在UTF8中,并将所有字符串都视为UTF-8(或使用StringFromUTF()行)。

每次您不在通用代码页中工作时(是的,UTF-8并不是真正的代码页...),您都会遇到麻烦。

编写C代码时,可以使用memcpy()复制二进制数据:

memcpy(dest + offset, src, 4);

如果src是字符串,则大概以正确的顺序获取它。 如果它是整数(例如uint32_t),并且需要特定的字节序,则可能需要在执行memcpy()之前反转字节的顺序:

uint32_t src;

...

swap((unsigned char *) &src, 0, 3);
swap((unsigned char *) &src, 1, 2);

其中swap()由您定义。 当计算机字节序与所需的输出字节序不匹配时, 必须执行此操作。

您可以通过查看由编译器或C库设置的某些定义来发现字节序。 至少在glibc(Linux)上, endian.h提供了这样的定义, byteswap.h也提供了字节交换功能。

您可能要尝试使用std::hex

int temp;
char sentMessage[10];
        for(int i = 0; i < 10; ++i)
        {
            std::cin >> std::hex >> temp;
            sentMessage[i] = temp;   
        } 

然后,您将键入每个字符的十六进制值,例如。 01 11 7F AA

您可以将std::wcinstd::wcout用于控制台的unicode支持。 但是,我不确定它们是否是标准的一部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM