2011-03-10 wcdj
在printf的使用说明 中讲到有关 %n 的用法:
n
Nothing printed. The argument must be a pointer to a signed int, where the number of characters written so far is stored.
运行如下代码:
- #include <cstdio>
- int main()
- {
- int first_count=0, second_count=0;
- printf("12345%n6789%n/n", &first_count, &second_count);// 123456789
- printf("First count %d Second count %d/n", first_count, second_count);// 5 9
- return 0;
- }
结果发现在VS2008在Debug或Release下运行抛出了断言错误:"Expression: ("n' format specifier disabled", 0)。而在gcc下可以正确输出结果。
在VS2008下可以正确运行的解决方法:
From MSDN:
- _set_printf_count_output
- Enable or disable support of the %n format in printf, _printf_l, wprintf, _wprintf_l-family functions.
- int _set_printf_count_output( int enable );
Parameters
enable
A non-zero value to enable %n support, 0 to disable %n support.
Property Value/Return Value
The state of %n support before calling this function: non-zero if %n support was enabled, 0 if it was disabled.
Remarks (这里解释了为什么要这样做)
Because of security reasons, support for the %n format specifier is disabled by default in printf and all its variants. If %n is encountered in a printf format specification, the default behavior is to invoke the invalid parameter handler as described in Parameter Validation. Calling _set_printf_count_output with a non-zero argument will cause printf-family functions to interpret %n as described in printf Type Field Characters.
printf函数在使用%n存在安全问题,所以VS2008在默认的情况下禁止这样使用。因为 %n 可以停止打印,并将当前printf已打印的字符数写入一个int指针,这让printf正常情况下也能修改别的变量的值。当然这个是有安全隐患的,但错不在 %n 而是printf允许参数是字符串指针,%n只是更加方便了黑客向内存写shellcode而已。
Required header
<stdio.h>
Example
Output
%n support was disabled.
%n support is now enabled.
123456789
i = 5
参考:
[1] http://social.msdn.microsoft.com/Forums/is/vclanguage/thread/11a127f2-778c-4685-9054-c05645a48a65
Hello,
When running the little program below:
#include <stdio.h>
int main (void)
{
int c1 = 100;
int c2 = 101;
printf ("/nPointers:/n");
printf ("This %n is fun.%n/n", &c1, &c2);
printf ("c1 = %i, c2 = %i/n", c1, c2);
return 0;
}
I get a "Debug Assertion Failed!" message box. Additional information in the box is:
"Expression: ("n' format specifier disabled", 0)
I'm guessing that the %n format specifier being disabled is causing the assertion. If that is the case, how do I enable the n format specifier ? If the assertion is failing due to some other reason, I'd be grateful to be enlightened.
Thank you for your help,
John.
Answer:
Reading the printf type field characters MSDN page:
http://msdn.microsoft.com/en-us/library/hf4y5e3w(v=VS.90).aspx
in the bottom of the page there is a paragraph "Security Note" about %n:
"To enable %n support, see _set_printf_count_output."
http://msdn.microsoft.com/en-us/library/ms175782(v=VS.90).aspx
Giovanni