【问题标题】:C copies into two buffers though just one should be filledC 复制到两个缓冲区,但应该只填充一个
【发布时间】:2016-04-26 13:31:17
【问题描述】:

我用 C 语言编写了一些代码,应该 strcpy 一些输入数据到声明的缓冲区。代码如下:

#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;
}

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

./main (perl -e 'print "A"x15')
buff_1: AAAAAAAAAAAAAAA 
buff_2 :ABCAAAAAAAAAAAAAAA

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

(gdb) x/1s buff_1
0xffffd284: 'A' <repeats 11 times>
(gdb) x/1s buff_2
0xffffd281: "ABC", 'A' <repeats 11 times>

我使用以下命令编译了代码:gcc -m32 -O0 -g -fno-stack-protector -o main main.c using gcc (Ubuntu 5.2.1-22ubuntu2)

谁能解释一下这怎么可能?

【问题讨论】:

  • 你认为缓冲区溢出的结果应该是什么?
  • 如果您打印出变量的地址(使用%p),您会看到它们神奇地彼此对齐,所以“ABC”(没有缺少的零在end) 将跟随 buff_2 的内容。
  • 或者根本不计算,char buff_2[] = "ABC";。并启用编译器警告。
  • 我并没有真正得到所有的反对意见。我只是坚持使用我在我目前正在阅读的关于缓冲区溢出的书中找到的一些代码。此代码的主要目标是在后续步骤中导致缓冲区溢出以及分析汇编代码。我认为在知识平台上提出问题会产生有用的 cmets 和答案,如下所示。因提出问题而被讨厌并没有真正的动力。
  • 显然 GCC 对这个特定错误的警告很糟糕。可能是因为某些 C 标准迷信者对这部分进行了编码,C 标准 6.7.9/14 中存在一个微妙的缺陷:“字符类型的数组可以由字符串文字或 UTF-8 字符串文字初始化,可选用大括号括起来. 字符串文字的连续字节(包括终止空字符如果有空间或如果数组大小未知)初始化数组的元素。"这个无意义的异常仅适用于字符串字面量初始化器,而不适用于常规数组初始化器。

标签: c gcc gdb buffer-overflow


【解决方案1】:

您没有足够的空间来为 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

【讨论】:

  • 我的编译器在这一行抛出错误:char buff_2[3] = "ABC";: 'ABC' : array bounds overflow
【解决方案2】:

向缓冲区写入的字符多于空间的字符会引发未定义的行为。没有可预测的结果;当你这样做时,你不能假设任何事情。你不能期望总是得到一个确定性的运行时错误。

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

附带说明一下,这里有一个错误:char buff_2[3] = "ABC";。空终止没有足够的空间。这意味着当您尝试打印该数组时将调用未定义的行为,因为它不是有效的、以空值结尾的 C 字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    • 2014-04-03
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多