C 我不知道';我不理解将4字节地址插入数组的代码的数据类型
我不理解将4字节地址插入数组的代码的数据类型。我们正在进行缓冲区溢出攻击,并从提供的源向数组中插入一个四字节地址 请注意,如果缺少C 我不知道';我不理解将4字节地址插入数组的代码的数据类型,c,C,我不理解将4字节地址插入数组的代码的数据类型。我们正在进行缓冲区溢出攻击,并从提供的源向数组中插入一个四字节地址 请注意,如果缺少*(long*)&buf[]中的任何一个,则会发生错误。但是,我不理解这个代码。如果你能帮助我,我将不胜感激 *(long *) &test[0] = 0x12345678; *(long *) &test[4] = 0x12345678; *(long *) &test[8] = 0x12345678; 我不知道这里的*(long*)和
*(long*)&buf[]
中的任何一个,则会发生错误。但是,我不理解这个代码。如果你能帮助我,我将不胜感激
*(long *) &test[0] = 0x12345678;
*(long *) &test[4] = 0x12345678;
*(long *) &test[8] = 0x12345678;
我不知道这里的*(long*)和test[]的含义。让我们分析一下*(long*)和test[0]=0x12345678代码>分步执行(后缀运算符的优先级高于前缀运算符):
test
是字节数组或指向字节数组的指针。代码以相同的方式处理这两种情况
test[0]
是左值:字节数组test
的第一个元素(或者可能是指针test
指向的字节数组)
&测试[0]
是此字节的地址
(long*)&test[0]
是相同的地址,强制转换为指向long
的指针
*(long*)&test[0]=0x12345678
向该地址写入一个长值,覆盖test[0]
、test[1]
、test[2]
和test[3]
(在具有8位字节和32位长的系统上)
总而言之:代码片段将sizeof(long)
字节写入字节数组test
的开头
然而,请注意一些隐含的假设:
long
的大小可以不同于4。对于同一处理器,它甚至可能因操作系统而异:sizeof(long)
在64位Windows上为4字节,但在64位linux系统上为8字节
- 将
long
写入内存时的字节顺序可能因体系结构而异:小端32位CPU将按此顺序写入字节0x78
、0x56
、0x34
和0x12
,而大端CPU将按相反顺序写入相同的字节
- 无法保证
test[0]
在写入long
值时正确对齐。默认情况下,英特尔CPU配置为接受标准整数大小的未对齐访问,但大多数CPU不能以这种方式配置,且未对齐访问具有未定义的行为
- 编译器可以利用严格的别名规则优化对
test
数组的访问。由于您是通过不同的有效类型进行修改,因此可能会被愚弄,无法从内存中重新加载值:
char test[12] = { 0 };
*(long *)test[0] = 0x12345678;
if (test[0] == 0) {
// the compiler could assume that `test[0]` is still `0`.
}
第四个假设:编译器上未启用基于类型的别名优化。感谢您对我的解释。你好。@chqrlie在这种情况下这是个问题。你可以从一种类型转换到另一种类型,但不能从另一种类型转换到另一种类型。@Lundin:这确实是个问题。答案已修改。这几乎肯定是一个bug,无法可靠地工作。
//an example as follows
int test[5] = {0,1,2,3,4};
//test[0]-->It'value is 0,it's type is int.
//&test[0]-->Its value is the address of test[0],what is its type? int*.
//* &test[0]-->how about it?Its value is 0, its type is int too.
//*(long*)&test[0] -->Its value is 0,but its type is long.