缓冲区溢出不影响常量变量

buffer overflow not affecting const variable?

本文关键字:常量 变量 影响 溢出 缓冲区      更新时间:2023-10-16

我对黑客,c,汇编,内存和所有这些东西了解不多,所以我无法自己解决我的问题。

因此,缓冲区溢出溢出到变量的其他地址并损坏它们。所以我测试了,它确实如此。而且我认为,如果它可以溢出恒定变量缓冲区溢出必须是超级强大的,我测试过,但它不会溢出常量变量。

为什么?

int a;
char buffer[8];

const int a;
char buffer[8];
变量"缓冲区"的地址

位于变量"a"的地址前面,按"缓冲区"的大小。当分配给内存时,const 变量中有什么特殊之处吗?

我的示例代码:

#include <stdio.h>
#include <string.h>
int main() {
    char buffer1[8];
    const int a=0;                      //vs int a=0;
    char buffer2[8];
    strcpy(buffer1,"one");
    strcpy(buffer2,"two");
    printf("Buffer 2    [%p]: %sn",buffer2,buffer2);
    printf("a           [%p]: %dn",&a,a);
    printf("Buffer 1    [%p]: %sn",buffer1,buffer1);
    printf("nCopy Buffernn");
    strcpy(buffer2,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
    printf("Buffer 2    [%p]: %sn",buffer2,buffer2);
    printf("a           [%p]: %dn",&a,a);
    printf("Buffer 1    [%p]: %sn",buffer1,buffer1);
    return 0;
}

我想到了三件事:

  1. 这是未定义的行为,因此所有赌注都不在桌面上。
  2. 编译器甚至不必查看a是什么。如果我是一个编译器,我只会看着代码并说" a总是零,所以我将继续用0替换a 。问题是,当你说printf("%p %d", &a, a);时,编译器甚至不必获取a的内容。它知道它将永远为零。 因此,它可以将该代码更改为printf("%p %d", &a, 0);
  3. 即使a没有const,编译器也会被允许在寄存器中"缓存"a的值。它只需要查找一次值,然后它知道a永远不会更改*,因此它可以重用以前查找的值。

*编译器会做出很多假设,比如"此代码不会调用未定义的行为"。如果调用未定义的行为,编译器可能会做出一些"错误"的假设。在这种情况下,它可能确实如此。

缓冲区溢出是 UB,所以任何事情都可能发生。

此外,编译器可以优化 const 变量,因为它具有在编译时确定的常量值。

允许实现将 const 限定的对象完全放在不同的内存段中,因此这可能是它不受影响的原因(强调 may;由于缓冲区溢出的行为未定义,因此可能有很多原因)。

在线 C 2011 标准,第 6.7.3 节,脚注 132:

该实现可能会将未volatileconst对象放置在 存储。此外,如果此类对象的地址为 从未使用过。