将stdin参数传递给使用gdb调试的可执行文件

时间:2017-11-08 17:03:56

标签: bash macos gdb escaping pipe

我已经在这个主题上阅读了很多问题/答案,但没有一个解决方案有效......我想把perl生成的字符串传递给由gdb调试的可执行文件。但我甚至无法传递一个转义的十六进制字符......我尝试过以下“解决方案”:

1:

from tempfile import NamedTemporaryFile
import runpy, traceback

with NamedTemporaryFile('w') as temp:
    print(fn_str, file=temp, flush=True)
    fn = runpy.run_path(temp.name)['fn']
    try:
        fn()
    except:
        traceback.print_exc()

2:

$ gdb ./a.out
(gdb) r "\x41"

3:

perl -e 'print "\x41"' > input.cmd
$ gdb ./a.out
(gdb) r < input.cmd

4:

$ gdb --args ./a.out "\x41"
(gdb) r

我也尝试了许多不同的转义字符组合“,/,\,',`......没有用。解决方案编号2在SO上的很多帖子中讨论但是我得到”&lt;“作为参数( gdb将所有内容转义为字符串)

我甚至试图无法调试bash并将可执行文件设置为次要但bash崩溃...

我错过了什么?我在macOS 10.13上使用gdb 8.0.1

更新:

刚试了一台linux机器,上面的解决方案正常工作。我猜这个问题是关于macOS上的bash / gdb交互......有什么想法吗?

UPDATE2:

解决

在macOS上的gdb内部进行bash调用肯定是个问题,设法解决了这个问题:

$ gdb ./a.out
(gdb) set args "\x41"
(gdb) r

2 个答案:

答案 0 :(得分:0)

  

perl -e 'print "\x41"' > input.cmd

您可以echo A > input.cmd

此:

2
(gdb) r < input.cmd

完全 你要求的内容(./a.outA上运行并收到一个字符stdin

  

但没有一个解决方案有效......

你必须告诉我们你是如何得出这个结论的。

<强>更新

  

当我(gdb) r < input.cmd gdb传递两个字符串作为参数<input.cmd

如果是这种情况,您的GDB已损坏,或者(更有可能)损坏$SHELL

GDB只调用$SHELL -c './a.out < input.cmd',并期望您的$SHELL执行重定向。如果你的shell不这样做,那么所有的赌注都会被取消。

你可以在dtruss -f下运行GDB,看看GDB做了什么,以及你的shell做了什么。

答案 1 :(得分:0)

<击>的解决

在macOS上的gdb内部进行bash调用肯定存在问题,设法解决方法就像这样:

$ gdb --args ./a.out $(perl -e 'print "\x41"')

更新 - 现在真的解决了

@EmployedRussian是对的,问题是在stdin中通过bash传递给gdb:

这是macOS Sierra的一个问题: 如果启用了SIP,gdb无法以shell(bash)启动,因此有两种方法可以在Sierra上使用gdb:

  

在Sierra上使用gdb 8.0.1:

     

选项1:在gdb上禁用shell启动:

echo "set startup-with-shell off" >> ~/.gdbinit

当我安装和编码签名的gdb时,我按照官方维基(https://sourceware.org/gdb/wiki/BuildingOnDarwin)执行此操作,因此忘记了。这就是我无法将stdin传递给gdb的原因。

  

选项2:禁用SIP并保留启动shell启动

echo "set startup-with-shell on" >> ~/.gdbinit

重启进入Recovery并:

csrutil disable

这显然不推荐,但它可以说明问题与Sierra上的gdb 8.0.1用法有关。希望gdb更新能解决这个问题。