Python程序输出到命名管道

时间:2013-11-29 17:11:46

标签: python pipe output stdout named

我使用压缩和提取打包的可执行文件的程序(upx.exe)。当我解压缩可执行文件时,唯一的选择是写一个文件。我不希望提取的代码触摸硬盘驱动器。

所以我考虑编写一个启动可执行文件的python包装器,并从命名管道读取解压缩的代码。

我想

  1. 在python中创建命名管道,
  2. 让外部程序将该管道用作输出文件和
  3. 将已写入该管道的内容读入字符串。
  4. 我尝试了以下内容:

    import win32pipe, win32file
    import win32file
    
    p = win32pipe.CreateNamedPipe(r'\\.\pipe\upx',
        win32pipe.PIPE_ACCESS_DUPLEX,
        win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT,
        1, 65536, 65536,300,None)
    
    os.system("upx -d -o\\\\.\\pipe\\upx nbtscan-1.0.35.exe")
    
    win32pipe.ConnectNamedPipe(p, None)
    
    fileHandle = win32file.CreateFile(r'\\.\pipe\upx',
                                  win32file.GENERIC_READ | win32file.GENERIC_WRITE,
                                  0, None,
                                  win32file.OPEN_EXISTING,
                                  0, None)
    
    
    data = win32file.ReadFile(fileHandle, 4096)
    print data
    

    这就是:

    enter image description here

    我没有使用命名管道的经验,现在感到非常绝望。 也许你有一个想法或教程给我一些例子。 (MSDN参考对我没有多大帮助)
    我的代码基于this code,但是当我在“系统”调用之前使用“ConnectNamedPipe”函数时,程序只是挂起并等待该管道上的某些操作。
    请帮忙。

1 个答案:

答案 0 :(得分:0)

我这样解决了:

class Decompress(object):

    # Maximum to read from the decompressed stream
    maxsize = 2097152
    data = ""

    def __init__(self, application_path, type, filePath):

        # UPX Decompression
        if type == "UPX":

            print "Checking UPX file %s" % filePath 

            try:   
                p = win32pipe.CreateNamedPipe(r'\\.\pipe\upx', win32pipe.PIPE_ACCESS_DUPLEX, win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT, 1, 2097152, 2097152, 300, None)

                phandle = p.handle

                success, stdout, stderr = run_popen_with_timeout(application_path + r'tools\upx.exe -d --no-color --no-progress --no-backup -o\\.\pipe\upx ' + filePath, 3, "")
                #print stdout
                #print stderr   

                data = win32file.ReadFile(phandle, self.maxsize)

                p.close()

                #print "Read " + str(len(data[1])) + " bytes from decompressed EXE"

                self.data = data[1]
                #print self.data[:10]

            except Exception, e:
                traceback.print_exc()

def run_popen_with_timeout(command_string, timeout, input_data):
    """
    Run a sub-program in subprocess.Popen, pass it the input_data,
    kill it if the specified timeout has passed.
    returns a tuple of success, stdout, stderr
    """
    kill_check = threading.Event()
    def _kill_process_after_a_timeout(pid):
        os.kill(pid, signal.SIGTERM)
        kill_check.set() # tell the main routine that we had to kill
        # use SIGKILL if hard to kill...
        return
    p = Popen(command_string, stderr=STDOUT, stdout=PIPE)
    #print p.communicate()[0]
    print command_string
    pid = p.pid
    watchdog = threading.Timer(timeout, _kill_process_after_a_timeout, args=(pid, ))
    watchdog.start()
    (stdout, stderr) = p.communicate()
    watchdog.cancel() # if it's still waiting to run
    success = not kill_check.isSet()
    kill_check.clear()
    return (success, stdout, stderr)