格式化字符串攻击,pif的%什么意思( 二 )


z对于整数类型 , printf期待一个size_t尺寸的整型参数 。
j对于整数类型 , printf期待一个intmax_t尺寸的整型参数 。
t对于整数类型 , printf期待一个ptrdiff_t尺寸的整型参数 。
Type , 也称转换说明(conversion specification/specifier) , 可以是:
d,i有符号十进制数值int 。'%d'与'%i'对于输出是同义;但对于scanf()输入二者不同 , 其中%i在输入值有前缀0x或0时 , 分别表示16进制或8进制的值 。如果指定了精度 , 则输出的数字不足时在左侧补0 。默认精度为1 。精度为0且值为0 , 则输出为空 。
u十进制unsigned int 。
f,Fdouble型输出10进制定点表示 。'f'与'F'差异是表示无穷与NaN时 , 'f'输出'inf', 'infinity'与'nan';'F'输出'INF', 'INFINITY'与'NAN' 。小数点后的数字位数等于精度 , 最后一位数字四舍五入 。精度默认为6 。如果精度为0且没有#标记 , 则不出现小数点 。小数点左侧至少一位数字 。
e,Edouble值 , 输出形式为10进制的([-]d.ddd e[+/-]ddd). E版本使用的指数符号为E(而不是e) 。指数部分至少包含2位数字 , 如果值为0 , 则指数部分为00 。Windows系统 , 指数部分至少为3位数字 , 例如1.5e002 , 也可用Microsoft版的运行时函数_set_output_format 修改 。小数点前存在1位数字 。小数点后的数字位数等于精度 。精度默认为6 。如果精度为0且没有#标记 , 则不出现小数点 。
g,Gdouble型数值 , 当指数部分在闭区间 [-4,精度] 内 , 输出为指数形式;否则输出为定点形式 。'g'使用小写字母 , 'G'使用大写字母 。小数点右侧的尾数0不被显示;显示小数点仅当输出的小数部分不为0 。
x,X16进制unsigned int 。'x'使用小写字母;'X'使用大写字母 。
o8进制unsigned int
s如果没有用l标志 , 输出null结尾字符串直到精度规定的上限;如果没有指定精度 , 则输出所有字节 。如果用了l标志 , 则对应函数参数指向wchar_t型的数组 , 输出时把每个宽字符转化为多字节字符 , 相当于调用wcrtomb函数 。
c如果没有用l标志 , 把int参数转为unsigned char型输出;如果用了l标志 , 把wint_t参数转为包含两个元素的wchart_t数组 , 其中第一个元素包含要输出的字符 , 第二个元素为null宽字符 。
pvoid *型
a,Adouble型的16进制表示 , "[?]0xh.hhhh p±d" 。其中指数部分为10进制表示的形式 。例如:102410输出为0x1.004000p+10 。'a'使用小写字母 , 'A'使用大写字母 。[2][3] (C++11流使用hexfloat输出16进制浮点数)
n不输出字符 , 但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量 。
%'%'字面值 , 不接受任何flags, width, precision or length 。
宽度与精度格式化参数可以忽略 , 或者直接指定 , 或者用星号"*"表示取对应函数参数的值 。例如printf("%*d", 5, 10)输出"10";printf("%.*s", 3, "abcdef") 输出"abc" 。
如果函数参数太少 , 不能匹配所有的格式参数说明符 , 或者函数参数的类型不匹配 , 将导致未定义(undefined)行为 。过多的函数参数被忽略 。许多时候 , 未定义的行为将导致格式化字符串攻击 。
某些编译器 , 如GCC , 会静态检查printf这一类函数的格式化参数并编译警告存在的问题(当使用编译标志-Wall或-Wformat) 。GCC也会对用户自定义的printf风格函数做静态检查 , 如果在函数定义时使用了非标准的"format" __attribute__ 。