Python subprocess hangs

2019-09-11 01:27发布

问题:

I'm executing the following subprocess...

p.call(["./hex2raw", "<", "exploit4.txt", "|", "./rtarget"])

...and it hangs.

But if I execute kmwe236@kmwe236:~/CS485/prog3/target26$ ./hex2raw < exploit4.txt | ./rtarget then it executes fine. Is there something wrong with using the input or piping operator?

I also tried sp.call(["./hex2raw", "<", "exploit4.txt", "|", "./rtarget"], shell=True)

The entire code looks like this UPDATED WITH SUGGESTIONS

import subprocess as sp
import pdb

for i in range(4201265,4201323):
    pdb.set_trace()
    d = hex(i)[2:]
    output = " "
    for i in range(len(d),0,-2):
        output = output + d[i-2:i] + " "

    out_buffer = "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" + output + "00 00 00 00"

    text_file = open("exploit4.txt", "w")
    text_file.write("%s" % out_buffer)

 #   sp.call(["./hex2raw", "<", "exploit4.txt", "|", "./rtarget"], shell=True)
    with open("exploit4.txt") as inhandle:
        p = sp.Popen("./hex2raw",stdin=inhandle,stdout=sp.PIPE)
        p2 = sp.Popen("./rtarget",stdin=p.stdout,stdout=sp.PIPE)
        [output,error] = p2.communicate()

I'm getting an error is

  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
OSError: [Errno 8] Exec format error

After debugging it occurs at the fire subprocess call p = sp.Popen("./hex2raw",stdin=inhandle,stdout=sp.PIPE)

回答1:

Since you're using redirection and piping, you have to enable shell=True

sp.call(["./hex2raw", "<", "exploit4.txt", "|", "./rtarget"],shell=True)

but it would be much cleaner to use Popen on both executables and feeding the contents of exploit4.txt as input. Example below, adapted to your case:

import subprocess

    with open("exploit4.txt") as inhandle:
        p = subprocess.Popen("./hex2raw",stdin=inhandle,stdout=subprocess.PIPE)
        p2 = subprocess.Popen("./rtarget",stdin=p.stdout,stdout=subprocess.PIPE)
        [output,error] = p2.communicate()
        print(output)
        # checking return codes is also a good idea
        rc2 = p2.wait()
        rc = p.wait()

Explanation:

  1. open the input file, get its handle inhandle
  2. open the first subprocess, redirecting stdin with inhandle, and stdout to an output stream. Get the pipe handle (p)
  3. open the second subprocess, redirecting stdin with previous process stdout, and stdout to an output stream
  4. let the second process communicate. It will "pull" the first one by consuming its output: both processes work in a pipe fashion
  5. get return codes and print the result

Note: you get "format error" because one or both executables are actually shell or other non-native executables. In that case, just add the shell=True option to the relevant Popen calls.