【发布时间】: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