C 我不知道';我不理解将4字节地址插入数组的代码的数据类型

C 我不知道';我不理解将4字节地址插入数组的代码的数据类型,c,C,我不理解将4字节地址插入数组的代码的数据类型。我们正在进行缓冲区溢出攻击,并从提供的源向数组中插入一个四字节地址 请注意,如果缺少*(long*)&buf[]中的任何一个,则会发生错误。但是,我不理解这个代码。如果你能帮助我,我将不胜感激 *(long *) &test[0] = 0x12345678; *(long *) &test[4] = 0x12345678; *(long *) &test[8] = 0x12345678; 我不知道这里的*(long*)和

我不理解将4字节地址插入数组的代码的数据类型。我们正在进行缓冲区溢出攻击,并从提供的源向数组中插入一个四字节地址

请注意,如果缺少
*(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.