summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2022-03-14 00:17:08 -0400
committerMalfurious <m@lfurio.us>2022-03-14 00:17:08 -0400
commit6e24dc3d70b9e915c89d47dc8d7c816f1ba8ffab (patch)
tree3495e18ec3171d3155c9f0a3430ea2b869243a03
parent13ad3d5d41fec4042a35424e0b21c0f8136ed690 (diff)
parent38a8b3f528d9e02fd08d7d98a5c4beb530700cc2 (diff)
downloadlib-des-gnux-6e24dc3d70b9e915c89d47dc8d7c816f1ba8ffab.tar.gz
lib-des-gnux-6e24dc3d70b9e915c89d47dc8d7c816f1ba8ffab.zip
Merge branch 'sploit/repl-qol'
This branch addresses some user experience issues when attempting to use Sploit interactively, in the Python REPL (or iPython). In particular: - Target output is more responsive - Setting up io plumbing is simplified * sploit/repl-qol: sploit: Clean up function Comm.interact() sploit: Add function popen() sploit: Add Comm property 'readonwrite' sploit: Add function Comm.readall_nonblock()
-rw-r--r--tools/sploit/sploit/comm.py77
1 files changed, 45 insertions, 32 deletions
diff --git a/tools/sploit/sploit/comm.py b/tools/sploit/sploit/comm.py
index 604045c..265ab96 100644
--- a/tools/sploit/sploit/comm.py
+++ b/tools/sploit/sploit/comm.py
@@ -11,6 +11,8 @@ class Comm:
logonread = True
logonwrite = False
flushonwrite = True
+ readonwrite = False
+ timeout = 0.25 # seconds
def __init__(self, backend):
self.back = backend
@@ -42,6 +44,16 @@ class Comm:
pass
return data
+ def readall_nonblock(self):
+ try:
+ os.set_blocking(self.back.stdin.fileno(), False)
+ poll = select.poll()
+ poll.register(self.back.stdin, select.POLLIN)
+ poll.poll(self.timeout)
+ return self.readall()
+ finally:
+ os.set_blocking(self.back.stdin.fileno(), True)
+
def readuntil(self, pred, /, *args, **kwargs):
data = b''
pred = bind(pred, *args, **kwargs)
@@ -70,46 +82,47 @@ class Comm:
self.back.stdout.write(data)
if self.flushonwrite : self.back.stdout.flush()
if self.logonwrite : ilog(data, file=sys.stdout, color=ALT)
+ if self.readonwrite : self.readall_nonblock()
def writeline(self, data):
self.write(data + b'\n')
def interact(self):
- ilog("<--Interact Mode-->")
stdin = sys.stdin.buffer
- os.set_blocking(self.back.stdin.fileno(), False)
- os.set_blocking(stdin.fileno(), False)
- poll = select.poll()
- poll.register(self.back.stdin, select.POLLIN)
- poll.register(stdin, select.POLLIN)
- brk = False
- def readall(read, write):
- while(True):
- data = read()
- if(data == b''):
- break
- write(data)
- def writeinput(write):
- ilog(write, file=sys.stdout, color=NORMAL)
+ event = select.POLLIN
+
+ def readall_stdin():
+ for line in stdin:
+ self.write(line)
+
readtable = {
- stdin.fileno() : lambda : readall(stdin.readline, self.write),
- self.back.stdin.fileno() : lambda : readall(self.back.stdin.readline, writeinput)
+ self.back.stdin.fileno(): self.readall_nonblock,
+ stdin.fileno(): readall_stdin,
}
- readtable[self.back.stdin.fileno()]()
- while(not brk):
- try:
- ioevents = poll.poll(100)
- for ev in ioevents:
- if(ev[1] & select.POLLIN):
- readtable[ev[0]]()
- else:
- brk = True
- break
- except KeyboardInterrupt:
- break
- os.set_blocking(self.back.stdin.fileno(), True)
- os.set_blocking(stdin.fileno(), True)
- ilog("<--Interact Mode Done-->")
+
+ try:
+ ilog("<--Interact Mode-->")
+ os.set_blocking(stdin.fileno(), False)
+
+ poll = select.poll()
+ poll.register(self.back.stdin, event)
+ poll.register(stdin, event)
+
+ while True:
+ for fd, e in poll.poll(self.timeout):
+ if not e & event: return
+ readtable[fd]()
+ except KeyboardInterrupt:
+ pass
+ finally:
+ os.set_blocking(stdin.fileno(), True)
+ ilog("<--Interact Mode Done-->")
+
+def popen(cmdline=''):
+ io = Comm((Process(cmdline.split()) if len(cmdline) > 0 else Pipes()))
+ io.readall_nonblock()
+ io.readonwrite = True
+ return io
class Process:
def __init__(self, args):