GCC在缓冲区的末尾添加了一些填充,如何禁用它

时间:2014-05-31 14:27:55

标签: c

我正在学习如何利用堆栈。以下代码:

/* bofvulcode.c */
#include <unistd.h>

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

  /* declare a buffer with max 512 bytes in size*/
  char mybuff[512];

  /* verify the input */
  if(argc < 2)
  {
    printf("Usage: %s <string_input_expected>\n", argv[0]);
    exit (0);
  }

  /* else if there is an input, copy the string into the buffer */
  strcpy(mybuff, argv[1]);

  /* display the buffer's content */
  printf("Buffer's content: %s\n", mybuff);
  return 0;
}

我已使用以下功能禁用ASLR:

echo 0 > /proc/sys/kernel/randomize_va_space

我使用以下代码编译代码:

gcc -fno-stack-protector -z execstack -g -w bofvulcode.c -o bofvulcode

缓冲区的大小为512,因此超过512个字节足以导致分段错误。 但我发现我必须使用至少520个字节才能使程序崩溃。

jack@jack-VirtualBox:~/workspace$ ./bofvulcode `perl -e 'print "A"x519'`
Buffer's content:   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


jack@jack-VirtualBox:~/workspace$ ./bofvulcode `perl -e 'print "A"x520'`
Buffer's content: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)

所以我假设GCC已经在缓冲区的末尾添加了某种填充。我目前正在运行Ubuntu 14.04 x64。

2 个答案:

答案 0 :(得分:2)

传统的堆栈从上到下增长。推送堆栈意味着减少堆栈指针。 所以然后输入你的主要功能。返回地址,参数传递给堆栈。参数是8bytes,下一个元素是你的512byte数组。所以堆栈看起来像这样。

| 0 | 1 | 2.. 512 array-bytes | argv | argC | return adress | 

所以你的前512个字节只是正确写入数组缓冲区。接下来的8个字节会覆盖你的函数参数,然后写入会破坏返回地址。当主例程退出时,这最终导致程序崩溃,因为返回尝试跳转到无效的地址。

答案 1 :(得分:1)

不正确的是,因为您要求512字节以上访问超过512字节会导致段错误。存储器按页面(例如,每次4K)分配给进程,并且不能以较少的量分配。