繁体   English   中英

为什么这个字符串不会溢出缓冲区?

[英]How come this string doesn't overflow the buffer?

我在Mac和Linux上都运行了此代码:

#include <stdio.h>
#include <string.h>

int main (int argc, char *argv[]){

int value = 5;
char buffer_one[8], buffer_two[8];

strcpy(buffer_one, "one");
strcpy(buffer_two, "two");

printf("[BEFORE] buffer_two is at %p and contains \'%s\'\n", buffer_two, buffer_two);
printf("[BEFORE] buffer_one is at %p and contains \'%s\'\n", buffer_one, buffer_one);
printf("[BEFORE] value is at %p and is %i (0x%08x)\n", &value, value, value);

printf("\n[STRCPY] copying %i bytes into buffer two\n\n", strlen(argv[1]));
strcpy(buffer_two, argv[1]); 

printf("[AFTER] buffer_two is at %p and contains \'%s\'\n", buffer_two, buffer_two);
printf("[AFTER] buffer_one is at %p and contains \'%s\'\n", buffer_one, buffer_one);
printf("[AFTER] value is at %p and is %i (0x%08x)\n", &value, value, value);
}

在Mac上,如果我作为命令行参数输入“ 1234567890”,则90会像我期望的那样溢出到缓冲区1中,因为8字节的缓冲区超出了2。

但是,如果我在Linux系统上运行它,则需要更多的字符来使缓冲区溢出。 为什么/为什么要在Linux中超过缓冲区?

另外,在两个系统上,整个字符串仍将打印在缓冲区2中,而溢出的项目仅打印在缓冲区1中。 为什么会这样? 剩下的角色怎么会不只是跳到下一个? 如果这个问题的措辞不好,请举一个例子:

如果我在Mac上输入1234567890,则1234567890将被打印在缓冲区2中,而90将被打印在缓冲区1中。 即使溢出,90仍如何容纳在缓冲区2中。 (在Linux上是相同的概念,但是溢出需要超过10个字节)

在这两种情况下,都有缓冲区溢出。 缓冲区溢出只是调用未定义的行为。 在某些情况下,它似乎可能工作得很好,不会造成崩溃或段错误。

例如,由于对齐原因,内存分配器(在这种情况下为堆栈分配)分配的内存可能比您请求的要多。 在这种情况下,您实际上可能能够溢出缓冲区而没有任何明显的副作用,但这实际上是一件非常糟糕的事情,因为它隐藏了错误,而不是消除了错误。

在这种情况下,由于它涉及堆栈,因此您将覆盖堆栈中超出分配给缓冲区的内容。 如果引入了更多的变量或开始调用函数,则可能开始注意到真正奇怪的副作用。 无论如何,这都是一个非常棘手的情况,并且您要非常小心,以避免缓冲区溢出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM