%N格式说明程序上不同的编译器提供不同的输出。为什么? [英] %n format specifier program giving different outputs on different compilers. Why?

查看:165
本文介绍了%N格式说明程序上不同的编译器提供不同的输出。为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在<一个阅读用C %N 格式说明href=\"http://stackoverflow.com/questions/3401156/what-is-the-use-of-the-n-format-specifier-in-c\">this问题。但是,当我尝试不同的C ++编译器下面的程序,它给了我不同的输出。

为什么呢?是什么原因?是否有未定义或实现定义的行为发生?

 #包括LT&;&stdio.h中GT;诠释的main()
{
  INT C = -1;
  的printf(极客为%ngeeks,和C);
  的printf(%D,C);
  的getchar();
  返回0;
}

输出:

code块13.12:(正确的输出)

 怪才怪才10

的Borland / codeGear /英巴卡迪诺C ++:(正确的输出)

 怪才怪才10

奥威尔开发C ++:

 怪才-1

微软的Visual Studio 2010:

 调试断言失败('N'格式说明禁用,0)


解决方案

作为问题指出 code块确实是正确的,而奥威尔开发C ++ 不正确。另一方面Visual Studio是不合格。

像printf

CP preferences C文档说说:


  

返回由该调用函数迄今为止写入的字符的数目。


我没有看到标准草案,使这个可选的,C ++是指任何相对于C标准为的printf MSDN文档此并说:


  

由于%N格式本身不安全,它默认是禁用的。如果%N是在一个格式字符串中遇到,无效参数调用处理程序,如参数验证所述。要启用%N的支持,请_set_printf_count_output。


为什么是%N格式固有的不安全?

我假设,他们认为这是不安全的,因为安全问题,如在的格式化字符串漏洞文件的一种可能的方式来利用这一点。这是pdicated的格式字符串由用户输入控制$ P $。本文给出了下面的例子:

 字符USER_INPUT [100];
scanf函数(%S,USER_INPUT);
的printf(USER_INPUT);

退休忍者连接到 Bugtraq的帖子这表明这样一个错误的结局的一个真实的例子达在开发中 proftpd的1.2.0 pre6


  

      
  • FTP到主机

  •   
  • 登录(匿名或无)

  •   

  
  

(这应该是全部在一行,无空格)


  
  

FTP> LS aaaXXXX%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U%U% ü%U%U%U%U%U
  %U%U%U%U%U%U%U%U%U%653300u%N


  
  

(与ASCII值字符替换X的
  的0xDC,0x4f,0x07,0x08连续)


  
  

其他脏东西大量的可以很容易很容易地完成这件事。以来
  proftpd的将通过用户输入数据的snprintf,论证攻击
  容易。


与视觉工作室方法的问题是,它打破可移植性。其它方法包括使用标志像它与<$ C $海合会联合使用 Wformat安全C> -Werror 可以使一个错误,但你可以选择它作为您的构建过程的一部分。

I was reading about %n format specifier in C at this question. But when I tried the following program on different C++ compilers, it gave me different outputs.

Why? What is the reason? Is there undefined or implementation defined behavior occurring?

#include<stdio.h>

int main()
{
  int c = -1;
  printf("geeks for %ngeeks ", &c);
  printf("%d", c);
  getchar();
  return 0;
}

Output:

Code blocks 13.12: (correct output)

geeks for geeks 10

Borland/CodeGear/Embarcadero C++: (correct output)

geeks for geeks 10

Orwell Dev C++:

geeks -1

Microsoft Visual Studio 2010:

Debug assertion failed ("'n' format specifier disabled",0) 

解决方案

As noted in the question Code Blocks is indeed correct while Orwell Dev C++ is incorrect. Visual Studio on the other hand is non-conforming.

cppreferences C documentation for printf says says:

returns the number of characters written so far by this call to the function.

I don't see anything in the draft standard that makes this optional, C++ refers to the C standard with respect to printf. MSDN documents this and says:

Because the %n format is inherently insecure, it is disabled by default. If %n is encountered in a format string, the invalid parameter handler is invoked, as described in Parameter Validation. To enable %n support, see _set_printf_count_output.

Why is the %n format is inherently insecure?

I am assuming that they consider it unsafe because of security issues such as those outlined in Format String Vulnerability documents one possible way to exploit this. It is predicated on the format string being controlled by user input. The paper gives the following example:

char user_input[100];
scanf("%s", user_input); 
printf(user_input); 

Retired Ninja linked to Bugtraq post which demonstrates an real example of such a bug ending up in an exploit in proftpd 1.2.0pre6:

  • ftp to host
  • login (anonymous or no)

(this should be all on one line, no spaces)

ftp> ls aaaXXXX%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u %u%u%u%u%u%u%u%u%u%653300u%n

(replace the X's with the characters with ascii values 0xdc,0x4f,0x07,0x08 consecutively)

Lots of other nasties can easily be easily done with this. Since proftpd will pass on user input data to snprintf, argument attacks are easy.

The problem with Visual Studios approach is that it breaks portability. Other approaches include using flags like Wformat-security used by gcc which combined with -WError can make it an error but you can choose this as part of your build process.

这篇关于%N格式说明程序上不同的编译器提供不同的输出。为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆