import abc from pathlib import Path import subprocess import shlex class NotInstalledError(Exception): pass class BaseObfuscation(abc.ABC): def __init__(self, binary_name=None, binary_path=None, algorithm=None): assert binary_name is not None or binary_path is not None self.binary_name = binary_name if binary_name is not None else Path(binary_path).name self.binary_path = binary_path if binary_path else "" self.algorithm = algorithm def ensure_installed(self): # Attempt to find process by path binary = Path(self.binary_path) if not binary.is_file(): # Did not find by path, attempt to find using which proc_which = subprocess.Popen(["which", self.binary_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE) data = [x.decode().strip() for x in proc_which.communicate() if x != b''][0] if proc_which.returncode != 0: raise NotInstalledError("Could not find binary '%s'" % data) self.binary_path = data def execute(self, *args, kill_first=False, override_command=None, stream=False, prefix=""): if prefix != "": prefix += ": " if kill_first: # TODO try to delete by full name as we dont want to kill other processes. pattern = self.binary_name self.execute(*[pattern], override_command="pkill") #pattern = self.binary_path + " " + ' '.join(args) #print(pattern) #kill_output, kill_code = self.execute(*[pattern], override_command="pkill") command = override_command if override_command is not None else self.binary_path proc_which = subprocess.Popen([command] + list(args), stdout=subprocess.PIPE, stderr=subprocess.PIPE) if not stream: raw_data = proc_which.communicate() data = [x.decode().strip() for x in raw_data if x != b''] if len(data) == 0: data = "" else: data = data[0] return data, proc_which.returncode else: while True: output = proc_which.stdout.readline() if output == '' and proc_which.poll() is not None: break if output: print(prefix + output.strip().decode()) rc = proc_which.poll() return rc