为什么缓冲区溢出不会影响此代码?
我有以下代码:
int main(int argc, char *argv[]) { char ch[10]; printf("String 10 max. :: "); gets( ch ); printf("String: %s\n", ch); return 0; }
当我使用"12345678"
运行时,它运行良好。 奇怪的是当我用"123456789012345678901234567890"
运行时! 第二个printf
所有字符串(30个字符)打印到屏幕上。
为什么会这样? 为什么我的代码没有崩溃?
谢谢你的时间,
阿兹台克
您没有看到任何效果,因为您没有任何更多的局部变量,将代码更改为此,您将会
int main(int argc, char *argv[]) { char ch[10]; int i=42; printf("String 10 max. :: "); gets( ch ); printf("String: %s\n", ch); printf("i: %d\n", i); return 0; }
缓冲区溢出是未定义的行为。 它可能会崩溃,但没有人保证。 在大多数编译器中,堆栈会逐渐减少,因此您可能会覆盖main
的返回地址,但是对printf
的调用不会覆盖您的字符串。
如果您尝试从尚未映射的页面读取/写入,则缓冲区溢出仅导致“崩溃”(即,分段错误)。 在这种情况下,内存管理单元捕获错误。
如果你还没有到达页面末尾,就像在你的例子中那样,从操作系统/处理器的角度来看,那时的内存仍然有效 – 你只是覆盖了另一个变量可能使用的内存。
通过使用您不应该使用的内存,您将进入未定义行为的领域。 它今天不会在你的机器上崩溃。 但这种行为可能会在没有警告的情
对于它的价值,当我在我的cygwin shell上运行相同的代码时,我得到了
Segmentation fault (core dumped)
缓冲区溢出的影响完全取决于您覆盖的内容,覆盖它的内容以及随后使用的覆盖数据的方式。
缓冲区溢出利用的方法涉及使用溢出来修改函数的返回地址; 但是从main()
返回到OS可能与从函数返回完全不同。