2011-07-09 36 views
2

我玩弄缓冲区溢出,但我在Mac OS上运行以下简单的C程序时发现我所困惑的。期待它没有得到一个分段错误

#include <stdio.h> 

int main(void) { 

     char buf[2]; 

     scanf("%s", buf); 

     printf("%s\n", buf); 

} 

通过BUF的长度设置为2个字节,我希望输入字符串“CCC”时,导致段错误,但这并没有发生。只有输入长度为24个字符的字符串时,才会产生分段错误。

发生了什么事?这与字符编码有关吗?

谢谢。

回答

5

只要溢出缓冲区,程序的行为就不确定。任何事情都可能发生。你无法预测它。

你的缓冲区后面可能有或没有一些填充字节,这对你的代码执行来说并不重要。你不能依靠那个。一个不同的编译器,以32位和64位编译,调试设置......所有这些都可能会在溢出之后改变你的代码执行。

+0

我明白了。我认为便士已经下降。一个恶意的攻击者会试图溢出堆栈的其余部分,并因此覆盖寄存器?但是,他们如何预测剩余的筹码?操作系统每次都会分配固定数量的内存吗? –

+0

查看装配输出和试错法是确定“剩余堆叠”的最佳选择。这是可能的,但不能保证,在_same environment_中执行_same binary_时,这将保持不变。缓冲区溢出不会覆盖寄存器。他们覆盖堆栈或堆。 – Mat

+0

@Martin典型的想法是溢出堆栈中的缓冲区,以便覆盖堆栈上的一些数据,指示CPU从函数返回后将返回的位置。有关更多详细信息,请尝试使用Google搜索“粉碎堆栈”。 –

1

猜想它与内存布局有关。如果你的进程可以访问你的进程(映射为writable的页面),那么操作系统就没有机会看到你正在做一些“错误的事情”。

事实上,当做这样的事情时,从C程序员的眼中看来“这是完全错误的!”。但在操作系统的眼中,“好吧,他正在写东西到某个页面,页面是否具有足够的权限映射?如果是,OKAY”。

1

不能保证你会得到分段错误。 char buf[2]覆盖后有更多的数据可能会或可能不会导致分段错误。

1

buf被分配到堆栈上,你只是覆盖了一个未被使用的区域,很有可能没有人会抱怨它。在某些平台上,您的代码将接受整个段落。

2

因为buf在堆栈上。当你开始覆盖它时,你将开始覆盖属于OS不会捕获的程序的堆栈,这取决于在那里分配了哪些内容(例如编译器创建的寄存器的溢出插槽)。只有当您跨越分配的堆栈边界时,操作系统才有机会引发段错误。

相关问题