mirror of https://github.com/n1nj4sec/pupy.git
Revert "Bug fix for having a shell on Android"
This reverts commit 73eaccf343
.
This commit is contained in:
parent
96ff38e523
commit
40e164b966
|
@ -1,158 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Nicolas VERDIER (contact@n1nj4.eu)
|
||||
# Pupy is under the BSD 3-Clause license. see the LICENSE file at the root of the project for the detailed licence terms
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import termios
|
||||
import pty
|
||||
import tty
|
||||
import fcntl
|
||||
import subprocess
|
||||
import time
|
||||
import threading
|
||||
import select
|
||||
import rpyc
|
||||
import logging
|
||||
import array
|
||||
|
||||
def prepare():
|
||||
os.setsid()
|
||||
fcntl.ioctl(sys.stdin, termios.TIOCSCTTY, 0)
|
||||
|
||||
class PtyShell(object):
|
||||
def __init__(self):
|
||||
self.prog = None
|
||||
self.master = None
|
||||
self.real_stdout = sys.stdout
|
||||
|
||||
def close(self):
|
||||
if self.prog is not None and self.prog.returncode is None:
|
||||
self.prog.terminate()
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
def spawn(self, argv=None, term=None):
|
||||
if argv is None:
|
||||
if 'SHELL' in os.environ:
|
||||
argv = [os.environ['SHELL']]
|
||||
elif 'PATH' in os.environ: #searching sh in the path. It can be unusual like /system/bin/sh on android
|
||||
for shell in ["bash","sh","ksh","zsh","csh","ash"]:
|
||||
for path in os.environ['PATH'].split(':'):
|
||||
fullpath=os.path.join(path.strip(),shell)
|
||||
if os.path.isfile(fullpath):
|
||||
argv=[fullpath]
|
||||
break
|
||||
if argv:
|
||||
break
|
||||
if not argv:
|
||||
argv= ['/bin/sh']
|
||||
|
||||
if term is not None:
|
||||
os.environ['TERM']=term
|
||||
|
||||
master, slave = pty.openpty()
|
||||
self.master = os.fdopen(master, 'rb+wb', 0) # open file in an unbuffered mode
|
||||
flags = fcntl.fcntl(self.master, fcntl.F_GETFL)
|
||||
assert flags >= 0
|
||||
flags = fcntl.fcntl(self.master, fcntl.F_SETFL , flags | os.O_NONBLOCK)
|
||||
assert flags >= 0
|
||||
self.prog = subprocess.Popen(
|
||||
shell=False,
|
||||
args=argv,
|
||||
stdin=slave,
|
||||
stdout=slave,
|
||||
stderr=subprocess.STDOUT,
|
||||
preexec_fn=prepare
|
||||
)
|
||||
os.close(slave)
|
||||
|
||||
def write(self, data):
|
||||
try:
|
||||
self.master.write(data)
|
||||
self.master.flush()
|
||||
except:
|
||||
self.master.close()
|
||||
|
||||
def set_pty_size(self, p1, p2, p3, p4):
|
||||
buf = array.array('h', [p1, p2, p3, p4])
|
||||
#fcntl.ioctl(pty.STDOUT_FILENO, termios.TIOCSWINSZ, buf)
|
||||
fcntl.ioctl(self.master, termios.TIOCSWINSZ, buf)
|
||||
|
||||
def _read_loop(self, print_callback, close_callback):
|
||||
cb = rpyc.async(print_callback)
|
||||
close_cb = rpyc.async(close_callback)
|
||||
not_eof = True
|
||||
|
||||
while not_eof:
|
||||
r, _, x = select.select([self.master], [], [self.master], None)
|
||||
if r:
|
||||
try:
|
||||
data = self.master.read(8192)
|
||||
except:
|
||||
data = None
|
||||
|
||||
if data:
|
||||
cb(data)
|
||||
else:
|
||||
not_eof = False
|
||||
|
||||
if x:
|
||||
not_eof = False
|
||||
|
||||
self.prog.poll()
|
||||
|
||||
if not_eof:
|
||||
not_eof = self.prog.returncode is None
|
||||
|
||||
close_cb()
|
||||
|
||||
def start_read_loop(self, print_callback, close_callback):
|
||||
t=threading.Thread(
|
||||
target=self._read_loop,
|
||||
args=(print_callback, close_callback)
|
||||
)
|
||||
|
||||
t.daemon=True
|
||||
t.start()
|
||||
|
||||
def interact(self):
|
||||
""" doesn't work remotely with rpyc. use read_loop and write instead """
|
||||
try:
|
||||
mfd = self.master.fileno()
|
||||
fd = sys.stdin.fileno()
|
||||
fdo = sys.stdout.fileno()
|
||||
f = os.fdopen(fd,'r')
|
||||
old_settings = termios.tcgetattr(fd)
|
||||
try:
|
||||
tty.setraw(fd)
|
||||
not_eof = True
|
||||
while not_eof:
|
||||
r, _, x = select.select([sys.stdin, self.master], [], [sys.stdin, self.master], None)
|
||||
if self.master in r:
|
||||
data = os.read(mfd, 1024)
|
||||
if data:
|
||||
os.write(fdo, data)
|
||||
else:
|
||||
not_eof = False
|
||||
if sys.stdin in r:
|
||||
ch = os.read(fd, 1)
|
||||
if ch:
|
||||
os.write(mfd, ch)
|
||||
else:
|
||||
not_eof = False
|
||||
|
||||
self.prog.poll()
|
||||
if self.prog.returncode is not None:
|
||||
not_eof = False
|
||||
sys.stdout.write("\n")
|
||||
finally:
|
||||
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
||||
finally:
|
||||
self.close()
|
||||
|
||||
if __name__=="__main__":
|
||||
ps=PtyShell()
|
||||
ps.spawn(['/bin/bash'])
|
||||
ps.interact()
|
Loading…
Reference in New Issue