pwn栈溢出学习格式化字符串
1. 格式化字符串简介
格式化字符串函数可以接受可变数量的参数,并将第一个参数作为格式化字符串,根据其来解析之后的参数。通俗来说,格式化字符串函数就是将计算机内存中表示的数据转化为我们人类可读的字符串格式。几乎所有的 C/C++ 程序都会利用格式化字符串函数来输出信息,调试程序,或者处理字符串。一般来说,格式化字符串在利用的时候主要分为三个部分
- 格式化字符串函数
- 格式化字符串
- 后续参数,可选
2. 格式化字符串函数
2.1 输入
- scanf()
2.2 输出
函数 | 基本介绍 |
---|---|
printf | 输出到 stdout |
fprintf | 输出到指定 FILE 流 |
vprintf | 根据参数列表格式化输出到 stdout |
vfprintf | 根据参数列表格式化输出到指定 FILE 流 |
sprintf | 输出到字符串 |
snprintf | 输出指定字节数到字符串 |
vsprintf | 根据参数列表格式化输出到字符串 |
vsnprintf | 根据参数列表格式化输出指定字节到字符串 |
setproctitle | 设置 argv |
syslog | 输出日志 |
err, verr, warn, vwarn 等 | 。。。 |
3.格式化字符串的基本原理
以ctfwiki上的例子来说
- c语言编译printf函数后会把数据push进栈
- 那么栈空间在进入printf函数之前是这样的
some value
3.14
123456
addr of "red"
addr of format string: Color %s...
- 那么函数执行的时候就会就会读取这串格式化字符串
- 如果读到的不是%就会直接输出
- 如果%之后接着往下读一位
- 如果是%就输出%
- 否则根据相应的字符,获取相应的参数,对其进行解析并输出
那如果编写printf函数的时候没有参数会怎样
printf("Color %s, Number %d, Float %4.2f");
- 程序会照样执行
- 只不过在读到第一个%s的时候会直接直接解析储存格式化字符串上面的变量
- 这就是格式化字符串漏洞的基本原理