繁体   English   中英

C-缓冲区溢出问题

[英]C - Buffer Overflow Issue

这是程序的源代码

#include <stdio.h>
% filename: test.c
int main(){
  int local = 0;
  char buff[7];
  printf("Password: ");
  gets(buff);

  if (local)
    printf("Buff: %s, local:%d\n", buff, local);
  return 0;
}

我使用“ gcc test.c -fno-stack-protector -o test”来编译该文件,并且在运行该文件时,为了使获取溢出,我需要输入至少13个字符。 我的想法是因为我只向buff声明了7个字节,这意味着当用户输入至少8个字符时,就会发生溢出。 但是似乎不是这种情况,为什么?

堆栈布局取决于实现。

无法保证local对象将在buff对象之后或之前,或者两者都将是连续的。

在您的情况下,很可能是在buff对象之后插入了5字节(1 + 4)的填充。 这种填充非常常见,并且出于性能原因通常由编译器插入。 填充的大小可以在编译器,编译器版本,编译器选项之间变化,甚至可以在不同的源代码之间变化。

为了更好地了解布局,只需打印bufflocal对象的地址即可:

printf("%p %p\n", (void *) buff, (void *) local);
gets(buff);

C中没有默认的绑定检查。最好的程序将崩溃,通常它将获得未分配的内存,因此它可以正常工作。 即使在某个时候,您超出了已经使用的内存,并且可能在遇到问题之前无法意识到它。

无法保证堆栈中的项目会紧紧分配在一起,实际上,我敢肯定,甚至不能保证它们以相同的顺序放置

如果您想了解为什么它不会像您期望的那样失败,最好的选择是使用gcc -S类的东西查看汇编器输出。

值得一提的是,CygWin下的gcc 4.8.3未能按预期的八个字符失败。 它以七个字符溢出 ,但是由于溢出字符是NUL终止符,所以local仍然为零。

底线是未定义的行为。 (对开发人员而言) 烦人的功能是有时可以正常工作,这意味着我们有时会在代码正式投入生产之前错过它。 如果UB以某种方式与连接到开发人员私人部分的电极相连,我保证不会有太多的错误:-)

暂无
暂无

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

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