Skip to content

Instantly share code, notes, and snippets.

@stong
Last active April 29, 2022 04:48
Show Gist options
  • Save stong/2c10462619d3fd8f3f753460e9c5e0c0 to your computer and use it in GitHub Desktop.
Save stong/2c10462619d3fd8f3f753460e9c5e0c0 to your computer and use it in GitHub Desktop.
Duplicate pwntools process output to stdout with tee(2) syscall
import sys
import os
from pwn import *
def tee_process(p):
import threading
import ctypes
libc = ctypes.CDLL(None)
splice = libc.splice
tee = libc.tee
read_fd, write_fd = os.pipe2(os.O_NONBLOCK)
saved_stdout_fd = os.dup(p.stdout.fileno())
os.dup2(read_fd, p.stdout.fileno())
p.proc.stdout = os.fdopen(p.stdout.fileno(), 'rb', 0) # force reopen
def do_tee_splice():
while not p.poll():
n = tee(saved_stdout_fd, write_fd, 0x7ffffff, 0)
if n < 0:
continue
if n == 0:
break
splice(saved_stdout_fd, 0, sys.stdout.fileno(), 0, n, 0)
os.close(saved_stdout_fd)
os.close(read_fd)
os.close(write_fd)
threading.Thread(target=do_tee_splice, daemon=True).start()
# There may be issues with input buffering of the subprocess. If thats the case run python with -u so the entire process tree is unbuffered
p = process('/bin/cat', stdout=PIPE) # IMPORTANT: stdout=PIPE is required
tee_process(p)
p.sendline(b'1234')
p.sendline(b'12345')
p.sendline(b'123456')
p.sendline(b'1234567')
p.sendline(b'12345678')
p.stdin.close()
p.stream()
print('Bye')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment