C++ 如何在C/C+中向字符串文本中注入非ASCII字符+;

C++ 如何在C/C+中向字符串文本中注入非ASCII字符+;,c++,c,C++,C,我有一个读取字符数组的程序。我需要内存中字符串的值等于十六进制0x01020304,它们都是非ASCII字符。所以问题是,如何在运行时将非ASCII字符传递到字符串文本变量中?使用转义序列。确保按正确的顺序排列字符 "\x01\x02\x03\x04" 编辑:如果需要将序列放入现有的字符数组中,只需将其分配到 char s[4]; // ... later ... s[0] = 0x01; s[1] = 0x02; s[2] = 0x03; s[3] = 0x04; 不要试图通过将s强制转

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

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

"\x01\x02\x03\x04"
编辑:如果需要将序列放入现有的字符数组中,只需将其分配到

char s[4];

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

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

那么,您确定需要字符串文字吗

这些都非常相似:

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

您当然可以很容易地根据需要使用第三种形式。

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

或者

char x[] = {1, 2, 3, 4, 0};
应该可以工作(注意,像这样初始化时必须包括空终止)

我需要内存中字符串的值等于十六进制0x01020304,它们都是非ASCII字符

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

例如:

正如阿瓦卡建议的那样,你可以尝试:

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)


有关更多信息,请阅读。

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


每次您不在通用代码页中工作时(是的,UTF-8不是真正的代码页…),您都是在自找麻烦。

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

int temp;
char sentMessage[10];
        for(int i = 0; i < 10; ++i)
        {
            std::cin >> std::hex >> temp;
            sentMessage[i] = temp;   
        } 
int-temp;
字符信息[10];
对于(int i=0;i<10;++i)
{
标准:cin>>标准:十六进制>>温度;
sentMessage[i]=温度;
} 
然后输入每个字符的十六进制值,例如。
01 11 7F AA

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

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

memcpy(dest + offset, src, 4);
如果src是一个字符串,您可能会按照正确的顺序得到它。如果它是一个整数(例如uint32_t),并且您需要一个特定的endianness,那么您可能需要在执行memcpy()之前颠倒字节顺序:

其中swap()由您定义。仅当机器端度与所需输出端度不匹配时,才必须执行此操作


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

既然您在谈论注入,我就给您一个线索(这对于利用缓冲区溢出漏洞的代码注入很有用,出于学术目的)。。。您必须将终端配置为接受unicode(在我的mac中,默认情况下您可以编写它们)。比如你写了这样的东西∫, 当您输入unicode字符时,它不像普通字符那样只占用内存中的一个字节,它将占用更多的字节(可以是两个、三个或四个字节),因此如果您有一个数组

char v[4];
如果你使用

gets(v); //insecure function to read
然后输入这个∫ 内存中取v的4个字节将填充此值(十进制):

如果您看到这些单一位置中的任何一个,它们都不是可打印的ASCII,那么可能是一些代码,您可以将其放入内存,并通过黑客攻击使程序执行它,更改堆栈中的返回目录,还可以利用允许gets()的相同缓冲区溢出漏洞。(要获得代码,请在十六进制编辑器中打开您的程序,查看编译时的外观)

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

在这个链接中,任何人都可以了解如何在堆栈中分配内存


(看起来@Ben甚至没有帐户了,但对于任何学习安全编程的人来说都需要它)

如果我将值编码到我的程序中,这将起作用,但我需要能够在运行时输入它们。如果问题不够具体,很抱歉。如果我将值编码到我的程序中,这会起作用,但我需要能够在运行时输入它们。对不起,如果问题不够具体。那么,你的问题是什么?如何让他们加入该计划?(这可能意味着更多地描述你的环境)如何在程序中移动它们一次?这不是C或C++问题,而是一个终端问题。您必须了解如何使用特定的终端。0x03可能被证明是特别有问题的,因为发送它通常会导致进程终止。@堂:直接交给控制终端的0x03可能会导致进程终止,但取决于数据输入方法(如通过键盘键入值),可能不会。OP希望如何接收输入的问题有点模糊。
uint32_t src;

...

swap((unsigned char *) &src, 0, 3);
swap((unsigned char *) &src, 1, 2);
char v[4];
gets(v); //insecure function to read
-30
-120
-85
0