我有一个Linux x86二进制文件,要求输入密码,并会打印出密码是正确还是不正确。我想使用python来模糊输入。
下面是我运行二进制文件,然后给它提供字符串“ asdf”并收到字符串“ incorrect”的屏幕快照
屏幕截图:
到目前为止,我已经尝试使用Python3子流程模块来进行
这是我的剧本
p = subprocess.Popen("/home/pj/Desktop/L1/lab1",stdin=subprocess.PIPE, stdout=subprocess.PIPE)
print (p.communicate()[0])
运行该脚本的结果是
b'Please supply the code: \nIncorrect\n'
我希望只收到提示,但是在我有机会发送输入信息之前,二进制文件也会返回错误的响应。
如何改进脚本以成功与此二进制文件进行交互?
答案 0 :(得分:1)
仔细阅读documentation(强调我的意思):
Popen.communicate(input=None)
与进程交互:将数据发送到stdin。从stdout读取数据并 stderr,直到到达文件末尾。等待进程终止。 可选的输入参数应该是要发送给子级的字符串 处理,如果没有数据发送给孩子,则为无。
communicate()
返回一个元组(stdoutdata, stderrdata)
。请注意,如果要将数据发送到流程的标准输入,则需要 用
stdin=PIPE
创建Popen对象。同样,得到任何东西 结果元组中除“无”外,您需要给stdout=PIPE
和/或stderr=PIPE
。
因此,您没有向进程发送任何内容,并且一次读取了stdout
的 all 。
在您的情况下,您真的不需要等待提示将数据发送到流程,因为流是异步工作的:流程只有在尝试读取其STDIN
时才会获取您的输入:>
In [10]: p=subprocess.Popen(("bash", "-c","echo -n 'prompt: '; read -r data; echo $data"),stdin=subprocess.PIPE,stdout=subprocess.PIPE)
In [11]: p.communicate('foobar')
Out[11]: ('prompt: foobar\n', None)
如果您出于任何原因坚持等待提示(例如,您的进程也在提示之前检查输入,还期望其他内容),you need to read STDOUT
manually and be VERY careful how much you read:由于Python的file.read
被阻止,因此很简单read()
将死锁,因为它等待EOF且子进程不会关闭STDOUT
-因此不会产生EOF -直到它得到您的输入。如果输入或输出长度可能超过stdio的缓冲区长度(在您的特定情况下不太可能),请you also need to do stdout reading and stdin writing in separate threads。
下面是一个使用pexpect
的示例,它可以为您解决这个问题(我使用的是pexpect.fdexpect
而不是pexpect.spawn
suggested in the doc,因为它适用于所有平台):
In [1]: import pexpect.fdpexpect
In [8]: p=subprocess.Popen(("bash", "-c","echo -n 'prom'; sleep 5; echo 'pt: '; read -r data; echo $data"),stdin=subprocess.PIPE,stdout=subprocess.PIPE)
In [10]: o=pexpect.fdpexpect.fdspawn(p.stdout.fileno())
In [12]: o.expect("prompt: ")
Out[12]: 0
In [16]: p.stdin.write("foobar") #you can communicate() here, it does the same as
# these 3 steps plus protects from deadlock
In [17]: p.stdin.close()
In [18]: p.stdout.read()
Out[18]: 'foobar\n'