小Pwn手杂谈之不同输入函数之间的区别
前言
本文涉及 read函数
fgets函数
scanf函数
以及 gets函数
获取字符串后内存的区别,以及在pwntools中使用 sendline
和 send
的区别。实验过程有些冗长,嫌麻烦的师傅可以直接查看下面的总结
实验目标
read
fgets
scanf
这种可以限定大小的输入,如果输入量小于/等于/大于它们的输入量分别会出现什么情况scanf("%s",&buf)
这种情况是否存在溢出gets
输入是怎么处理\n
符号的
下面是我实验用的代码
1 |
|
下面我们开始测试:
start
开头在sleep上打断点,方便我们后续使用c快速跟进,查看到bss全局变量在 0x555555558050
这个位置上
来到第一个sleep所在的地方
查看bss段里面是什么,可以看到已经都变成22了,后面输入后改变我们就可以直观的看到
来到第二个sleep所在的地方
查看堆中内存,可以看到已经都变成22了,后面输入后改变我们就可以直观的看到
read函数
继续跟进程序,让我们看看read,分别输入 aaaaaa
aaaaaaaa
aaaaaaaaaa
这里仔细的人会发现,read a*6
后面到 read a*8
中间除了输入还空了一行,这是因为包括 \n
在内我们输入的全部东西都被读入了内存中,getchar
没有读取到\n
所以我手动敲了一个回车来结束 getchar
来到第四个sleep所在的地方
我们已经使用read输入了,下面我们来查看一下堆内存里面是什么
可以看到输入六个a的话内存里面是 六个a和一个回车符号
输入八个a的话内存里面是 八个a,回车符号没有被读入
输入是十个a的话内存里面是 十个a,回车符号没有被读入
虽然实验很简陋但是我们可以简单得出结论,read输入的话会读取指定的字节数,除非遇到\x00
,不然输入其他东西都无法阻止read停止,直到读取完后放入指定的内存中,没读取到的部分则保持原样不动
fgets函数
继续跟进程序,让我们看看fgets,再次分别输入 aaaaaa
aaaaaaaa
aaaaaaaaaa
查看对应的堆内存
我们不难简单的得出结论,fgets和read不太一样,虽然我们设定了读取8个字节,他并不会老实读取8个字节,而是只读取7个,然后再主动添加一个\x00
来作为输入的字符串的结尾
因此像read这样的输入函数,如果buf为8字节的字符串,用户输入8字节,而read傻傻的读取八字节,那么字符串结尾的\x00
就会被省略掉,如果此时有一个 buf2
和 buf
的位置相邻,那么使用puts输出buf的时候就会连同buf2一起输出出来,因为buf失去了\x00
,puts这类输出函数就没办法判断这个字符串什么时候结束,只能无脑输出,直到遇见\x00
scanf函数
继续跟进程序,让我们看看scanf,再次分别输入 aaaaaa
aaaaaaaa
aaaaaaaaaa
查看对应的堆内存
可以发现我们的scanf函数非常的聪明,他不像fgets函数偷工减料,让他读取8字节他是真读取
并且同时他读取完八字节后,会再在后面加一个\x00
来保持字符串的独立性
继续跟进程序,让我们看看gets,输入 aaaaaa
查看堆内存
scanf函数的溢出
总结
read函数
:第三个参数是几就读取几个,一旦数量超过第三个参数后就直接忽略,就只读取到第三个参数所规定的数量为止,不会自动添加\x00
,如果 允许输入长度
=
字符串长度
可能导致字符串失去结尾的\x00
fgets函数
:读取的字节数为第二个参数-1
,超出的部分会被忽略,会自动在最后添加\x00
scanf("%?s", &buf)
:读取?个字节,超出的部分会被忽略,然后在最末尾添加\x00
。scanf("%s", &buf)
没有规定读取字节数,存在溢出
gets函数
:无脑读取,一直读取,直到用户输入回车才停止,输入的数据全部读取,但是最后会把读取到的回车(\x0a
)变成\x00
对于上面函数如何选择 send
和 sendline
对于read函数
send
和sendline
都可以,但是建议使用send
,不然屁股后面多个\x0a
,有时候打入/bin/sh
字符串的时候使用sendline没发现有个\x0a
在屁股上一直打不通也是很痛苦的对于
fgets
gets
scanf
这三个函数只能使用sendline
什么?你问我上面的 send
和 sendline
是怎么总结出来的?
由于时间关系(懒得再做一遍了),直接看ZikH26师傅的博客来总结了探究pwntools中sendline的回车所造成的影响(什么时候用sendline,什么时候用send) - ZikH26 - 博客园 (cnblogs.com)
(不要喷我啊,求求了我什么都会做的Orz
)
最后感谢您的观看