关闭堆栈保护

时间:2017-04-03 15:02:31

标签: c stack buffer-overflow

我只是想知道,因为我有这个C代码:

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

int fillBuffer(int argc, char *argv[]) {
  char bufferA[4] = "aaa";
  char bufferB[4] = "bbb";

  if(argc > 1)
    strcpy(bufferB, argv[1]);

  printf("bufferA: %s\n", bufferA);
  printf("bufferB: %s\n", bufferB);

  return 0;
}

int main(int argc, char *argv[]) {
  fillBuffer(argc, argv);
  return 0;
}

我尝试使用:-fno-stack-protector

关闭堆栈保护

当我尝试运行它:./ program(escape key)5f时,程序输出到:

bufferA:f

bufferB:fffff

我只是不确定bufferA是如何成为f的。任何人都可以向我解释这个吗?

2 个答案:

答案 0 :(得分:1)

本地缓冲区A和B以相反的顺序存储在堆栈中。因此,在内存中,您有8个字节,启动缓冲区B,然后是缓冲区A.

当你敲打你的5&#34; f&#34;缓冲B,前4个进入缓冲区B,最后一个结束字符串&#39; \ 0&#39;缓冲A。

然后当你打印缓冲区时,缓冲区A包含1&#34; f&#34;和字符串终止符。它来自哪里。

答案 1 :(得分:0)

你的strcpy调用是不安全的,如果argv [1]包含超过3个字符(加上一个空终止字符),它将损坏你的堆栈。不要逃脱,只是空间和5f,你得到正确的输出:

scott> a.out 5f
bufferA: aaa
bufferB: 5f

当你点击转义时,shell可以在字符串参数中添加其他字符,并且由于你的strcpy不安全(不检查长度),它将超出缓冲区的末尾并破坏你的堆栈。您的缓冲区只有4个字符长,因此如果输入的参数超过3个字符,您的程序将损坏堆栈。

要修复它,请将缓冲区大小从4增加到更合理的值(如60),如果参数太长,请使用strncpy确保不超过缓冲区:

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

#define MAX_PARM_LEN  60

int fillBuffer(int argc, char *argv[]) {
  char bufferA[MAX_PARM_LEN] = "aaa";
  char bufferB[MAX_PARM_LEN] = "bbb";

  if(argc > 1)
    strncpy(bufferB, argv[1], MAX_PARM_LEN);

  printf("bufferA: %s\n", bufferA);
  printf("bufferB: %s\n", bufferB);

  return 0;
}

int main(int argc, char *argv[]) {
  fillBuffer(argc, argv);
  return 0;
}

最后一点:不要关闭堆栈保护。