如何在GDB中为目标程序传递Python -c生成的输入?
解决GDB中传递Python生成的溢出输入问题
我明白你现在的困境——明明代码里gets(buffer)有明确的栈溢出漏洞,输入100个A应该能触发,但用你尝试的两种方法都没生效,程序还是正常退出。这是因为你没搞清楚GDB里run命令的参数和标准输入的区别,以及直接输入命令文本和执行命令生成输入的差异。
先说说你两种尝试为什么失败:
- 第一种方法:启动GDB后执行
r,然后输入python -c 'print "A" * 100'——这时候GDB只是把这个字符串原封不动地传给程序的标准输入,程序收到的是这段命令文本(长度远小于100),根本不是100个A,自然不会触发溢出。 - 第二种方法:用反引号执行
rpython -c 'print "A" * 100'——这里的反引号在GDB里并不会像shell那样执行命令并替换结果,反而会把python -c 'print "A" * 100'当成程序的**命令行参数**(也就是argv的内容),而gets`是从标准输入读取数据,完全没接触到这些参数,所以程序还是正常退出。
接下来给你几个可行的正确方法:
方法1:用shell管道提前生成输入
在启动GDB的时候就把Python生成的输入通过管道传进去:
python -c 'print "A" * 100' | gdb ./your_program
然后在GDB提示符里执行run,程序就会从管道读取到100个A,触发栈溢出。
方法2:在GDB内部用进程替换作为输入
如果你已经启动了GDB并加载了程序,可以用GDB支持的shell输入重定向语法,把Python命令的输出作为程序的标准输入:
run < <(python -c 'print "A" * 100')
这里的<(command)是bash的进程替换特性,它会把Python命令的输出当作一个临时文件,让程序从这个"文件"读取输入,这样gets就能拿到100个A了。
方法3:用GDB的输入文件(适合多次测试)
如果你需要更灵活的输入控制,也可以先生成输入文件:
python -c 'print "A" * 100' > input.txt
然后在GDB里执行:
run < input.txt
这种方法适合需要多次测试不同输入的场景,修改输入只需要重写input.txt即可。
另外要注意,如果你用的是Python3,print函数默认会加换行符,你可以用print("A"*100, end='')来避免额外的换行符影响溢出位置。
内容的提问来源于stack exchange,提问作者pantaloons
相关产品推荐
相关产品推荐

