格式化字符串漏洞

printf函数输入流程 :

函数首先会获取第一个参数,也就是格式化字符串,依次读取格式化字符串的每一个字符,如果是%,则继续读取下一个空字符,获取对应的参数解析并输出,如果该字符不为%,则直接输出到标准输出.

printf("My name is %s,I'm %d years old\n","otto",19)

c语言printf格式化字符串的基本格式如下:

parameter可以忽略n$,或者用来获取格式化字符串的指定参数例如
int a=0x11,b=0x22,c=0x33;
printf("%3$p",a,b,c);
//output: 0x33
flag
field width
输出的最小宽度
precision
输出的最大长度
length,输出的长度
hh,输出一个字节
h,输出一个双字节
type
d/i,有符号整数
u,无符号整数
x/X,16 进制 unsigned int 。x 使用小写字母;X 使用大写字母。如果指定了精度,则输出的数字不足时在左侧补 0。默认精度为 1。精度为 0 且值为 0,则输出为空。
o,8 进制 unsigned int 。如果指定了精度,则输出的数字不足时在左侧补 0。默认精度为 1。精度为 0 且值为 0,则输出为空。
s,如果没有用 l 标志,输出 null 结尾字符串直到精度规定的上限;如果没有指定精度,则输出所有字节。如果用了 l 标志,则对应函数参数指向 wchar_t 型的数组,输出时把每个宽字符转化为多字节字符,相当于调用 wcrtomb 函数。
c,如果没有用 l 标志,把 int 参数转为 unsigned char 型输出;如果用了 l 标志,把 wint_t 参数转为包含两个元素的 wchart_t 数组,其中第一个元素包含要输出的字符,第二个元素为 null 宽字符。
p, void * 型,输出对应变量的值。printf("%p",a) 用地址的格式打印变量 a 的值,printf("%p", &a) 打印变量 a 所在的地址。
n,不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。
%, '%'字面值,不接受任何 flags, width。