C复制到两个缓冲区,但只应填写一个缓冲区

时间:2016-04-26 13:31:17

标签: c gcc gdb buffer-overflow

我在C中编写了一些代码,它应该//p[@class='ch_title'][contains(.,'Tip')]/following-sibling::p[@class='ch_spec'][1] 一些输入数据到声明的缓冲区。这是代码:

<p class="ch_spec">Smartphone</p>

如果我现在运行二进制文件,我会假设超过11个输入参数的所有内容都会导致缓冲区溢出,但事实上它将我的输入附加到两个缓冲区:

strcpy

使用gdb检查变量也表明我的输入参数存储在两个缓冲区中:

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

void function(char *args) {
  char buff_1[12];
  char buff_2[3] = "ABC";

  strcpy(buff_1, args);
  printf("buff_1: %s \n", buff_1);
  printf("buff_2: %s \n", buff_2);
}

int main(int argc, char *argv[]) {
  printf("Input: ");

  if(argc > 1)
    function(argv[1]);

  return 0;
}

我使用以下命令编译代码:./main (perl -e 'print "A"x15') buff_1: AAAAAAAAAAAAAAA buff_2 :ABCAAAAAAAAAAAAAAA 使用(gdb) x/1s buff_1 0xffffd284: 'A' <repeats 11 times> (gdb) x/1s buff_2 0xffffd281: "ABC", 'A' <repeats 11 times>

有人能解释一下这是怎么回事吗?

2 个答案:

答案 0 :(得分:4)

buff_2没有足够的空间来终止空终止。因此printf("buff_2: %s \n", buff_2);将溢出缓冲区,导致未定义的行为

char buff_2[3] = "ABC"; // Not enough space for \0 
char buff_2[4] = "ABC"; // OK
char buff_2[] = "ABC";  // OK, Size will be 4

答案 1 :(得分:3)

将更多字符写入缓冲区而不是空间调用未定义的行为。没有可预测的结果;当你这样做时,你不能假设任何事情。您不能期望总是得到确定的运行时错误。

这就是为什么你需要在将参数传递给strcpy之前检查它的大小。没有这样做是一个错误。

作为旁注,您在此处有一个错误:char buff_2[3] = "ABC";。空终止没有足够的空间。这意味着当您尝试打印该数组时,您将调用未定义的行为,因为它不是有效的,以null结尾的C字符串。