这个简单的代码令我感到困惑 - 我故意打印出比传递给printf更多的整数。我预计会出错。我得到了奇怪的数字 - 它们来自哪里?
#include <stdio.h>
/* learn arrays */
void main(){
int pout;
pout = 6;
printf("%i %i %i\n%i %i %i\n%i %i %i\n", pout);
}
输出的一个例子:
6 608728840 0
-885621664 -885543392 608728816
0 0 -889304251
单个数字不会随着重复运行而改变,但是大整数会改变。
答案 0 :(得分:6)
这是printf字符串格式漏洞之一。你试图调用比实际更多的参数,所以printf在堆栈中采取他能做的任何事情。
它(并且仍然)非常习惯于利用程序来探索堆栈以访问隐藏信息或绕过身份验证。
查看堆栈
printf ("%08x %08x %08x %08x %08x\n");
此 指示printf-function从中检索五个参数 堆叠并将其显示为8位填充的十六进制数字。那么一个 可能的输出可能如下:
40012980 080628c4 bffff7a4 00000005 08059c04
有关更完整的说明,请参阅this。
答案 1 :(得分:5)
因为它是未定义的行为。如果说明符的数量大于匹配参数的数量或它们的类型不兼容,则行为未定义。
此qoute来自c11标准草案
7.21.6.1
fprintf
功能
- 醇>
fprintf
函数在format指向的字符串的控制下将输出写入stream指向的流,该格式指定后续参数如何转换为输出。 如果格式的参数不足,则行为未定义。如果参数保留时格式已用尽,则会评估多余的参数(一如既往),否则将被忽略。当遇到格式字符串的末尾时,fprintf函数返回。
- 如果转换规范无效,则行为未定义。 282) 如果任何参数不是相应转换规范的正确类型,则行为未定义。
醇>
我强调了相关部分,使它们变得粗体。
答案 2 :(得分:0)
int保留了一些内存,但你没有写任何东西,因此它会显示你RAM中随机的数字