为什么printf()在这段代码中打印出来?

时间:2015-07-03 12:28:08

标签: c printf

这个简单的代码令我感到困惑 - 我故意打印出比传递给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

单个数字不会随着重复运行而改变,但是大整数会改变。

3 个答案:

答案 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功能

     
      
  1. fprintf函数在format指向的字符串的控制下将输出写入stream指向的流,该格式指定后续参数如何转换为输出。 如果格式的参数不足,则行为未定义。如果参数保留时格式已用尽,则会评估多余的参数(一如既往),否则将被忽略。当遇到格式字符串的末尾时,fprintf函数返回。
  2.               
        
    1. 如果转换规范无效,则行为未定义。 282) 如果任何参数不是相应转换规范的正确类型,则行为未定义
    2.   

我强调了相关部分,使它们变得粗体。

答案 2 :(得分:0)

int保留了一些内存,但你没有写任何东西,因此它会显示你RAM中随机的数字