text: import shellphish_afl
  import subprocess
  import distutils.spawn #pylint:disable=no-name-in-module,import-error
  import logging
  import signal
  import shutil
  import time
  import angr
  import sys
  import os
  
  l = logging.getLogger("phuzzer.phuzzers")
  
  class Phuzzer:
      """ Phuzzer object, spins up a fuzzing job on a binary """
  
      def __init__(self, target, seeds=None, dictionary=None, create_dictionary=False, timeout=None):
          """
          :param target: the target (i.e., path to the binary to fuzz, or a docker target)
          :param seeds: list of inputs to seed fuzzing with
          :param dictionary: a list of bytes objects to seed the dictionary with
          :param create_dictionary: create a dictionary from the string references in the binary
          """
  
          self.target = target
          self.seeds = seeds or [ ]
  
          # processes spun up
          self.processes            = [ ]
  
          self.start_time = None
          self.end_time = None
          self.timeout = timeout
  
          self.check_environment()
  
          # token dictionary
          self.dictionary = dictionary or (self.create_dictionary() if create_dictionary else [])
  
      #
      # Some convenience functionality.
      #
  
      def found_crash(self):
          return len(self.crashes()) > 0
  
      def add_cores(self, n):
          for _ in range(n):
              self.add_core()
  
      def remove_cores(self, n):
          """
          remove multiple fuzzers
          """
          for _ in range(n):
              self.remove_core()
  
      def timed_out(self):
          if self.timeout is None:
              return False
          return time.time() - self.start_time > self.timeout
  
      def start(self):
          self.start_time = int(time.time())
          return self
      __enter__ = start
  
      def stop(self):
          self.end_time = int(time.time())
          if self.start_time is not None:
              l.info("Phuzzer %s shut down after %d seconds.", self, self.end_time - self.start_time)
          for p in self.processes:
              p.terminate()
              p.wait()
      __exit__ = stop
  
      @classmethod
      def check_environment(cls):
          try:
              cls._check_environment()
          except InstallError as e:
              tmp = ""
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              tmp += "############# ATTENTION: YOUR SYSTEM IS MISCONFIGURED FOR FUZZING #############\n"
              tmp += "############# ATTENTION: YOUR SYSTEM IS MISCONFIGURED FOR FUZZING #############\n"
              tmp += "############# ATTENTION: YOUR SYSTEM IS MISCONFIGURED FOR FUZZING #############\n"
              tmp += "############# ATTENTION: YOUR SYSTEM IS MISCONFIGURED FOR FUZZING #############\n"
              tmp += "############# ATTENTION: YOUR SYSTEM IS MISCONFIGURED FOR FUZZING #############\n"
              tmp += "############# ATTENTION: YOUR SYSTEM IS MISCONFIGURED FOR FUZZING #############\n"
              tmp += "############# ATTENTION: YOUR SYSTEM IS MISCONFIGURED FOR FUZZING #############\n"
              tmp += "############# ATTENTION: YOUR SYSTEM IS MISCONFIGURED FOR FUZZING #############\n"
              tmp += "############# ATTENTION: YOUR SYSTEM IS MISCONFIGURED FOR FUZZING #############\n"
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              tmp += "####### THE FUZZER WILL NOT RUN. AND IT IS ***YOUR FAULT***!!!!!!!!!!!!  ######\n"
              tmp += "####### DIRECTLY BELOW THIS, THERE ARE CONCRETE REASONS FOR WHY THIS IS  ######\n"
              tmp += "####### IF YOU COMPLAIN TO US ON GITHUB ABOUT THIS NOT WORKING, AND YOU  ######\n"
              tmp += "####### DON'T RESOLVE THESE ISSUES FIRST, WE WILL NOT HELP YOU!!!!!!!!!  ######\n"
              tmp += "####### PLEASE RESOLVE THE ISSUES BELOW.    THEY LITERALLY TELL YOU WHAT ######\n"
              tmp += "####### YOU HAVE TO EXECUTE. DO NOT ASK FOR HELP IF YOU ARE SEEING THIS  ######\n"
              tmp += "####### MESSAGE; JUST FIX THE PROBLEM WITH YOUR SYSTEM!!!!!!!!!!!!!!!!!  ######\n"
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              tmp += e.args[0]
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              tmp += "####### FIX THE ABOVE ISSUES BEFORE ASKING FOR HELP. THE TEXT LITERALLY  ######\n"
              tmp += "####### TELLS YOU HOW TO DO IT. DO NOT ASK FOR HELP ABOUT THIS BEFORE    ######\n"
              tmp += "####### FIXING THE ABOVE ISSUES. IF YOU ARE SEEING THIS MESSAGE, YOUR    ######\n"
              tmp += "####### SYSTEM MISCONFIGURATION IS *******YOUR FAULT*********!!!!!!!!!!! ######\n"
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              tmp += "#######                                                                  ######\n"
              tmp += "#######                                                                  ######\n"
              tmp += "#######                GET YOUR SYSTEM SETUP FIXED!!!!!!!!!!             ######\n"
              tmp += "#######                                                                  ######\n"
              tmp += "#######                                                                  ######\n"
              tmp += "###############################################################################\n"
              tmp += "###############################################################################\n"
              e.args = (tmp,)
              xmsg = distutils.spawn.find_executable("xmessage") #pylint:disable=no-member
              if xmsg:
                  subprocess.Popen([xmsg, tmp]).wait()
              l.critical(tmp)
              print(tmp)
              sys.stderr.write(tmp)
              sys.stdout.write(tmp)
              raise
  
  
      #
      # Dictionary creation
      #
  
      def create_dictionary(self):
          l.warning("creating a dictionary of string references within target \"%s\"", self.target)
  
          b = angr.Project(self.target, load_options={'auto_load_libs': False})
          cfg = b.analyses.CFG(resolve_indirect_jumps=True, collect_data_references=True)
          state = b.factory.blank_state()
  
          string_references = []
          for v in cfg._memory_data.values():
              if v.sort == "string" and v.size > 1:
                  st = state.solver.eval(state.memory.load(v.address, v.size), cast_to=bytes)
                  string_references.append((v.address, st))
  
          strings = [] if len(string_references) == 0 else list(list(zip(*string_references))[1])
          return strings
  
  
      #
      # Subclasses should override this.
      #
  
      @staticmethod
      def _check_environment():
          raise NotImplementedError()
  
      def crashes(self, signals=(signal.SIGSEGV, signal.SIGILL)):
          """
          Retrieve the crashes discovered by AFL. Since we are now detecting flag
          page leaks (via SIGUSR1) we will not return these leaks as crashes.
          Instead, these 'crashes' can be found with the leaks function.
  
          :param signals: list of valid kill signal numbers to override the default (SIGSEGV and SIGILL)
          :return: a list of strings which are crashing inputs
          """
          raise NotImplementedError()
  
      def queue(self, fuzzer='fuzzer-master'):
          """
          retrieve the current queue of inputs from a fuzzer
          :return: a list of strings which represent a fuzzer's queue
          """
          raise NotImplementedError()
  
      def pollenate(self, *testcases):
          """
          pollenate a fuzzing job with new testcases
  
          :param testcases: list of bytes objects representing new inputs to introduce
          """
          raise NotImplementedError()
  
      def add_core(self):
          raise NotImplementedError()
  
      def remove_core(self):
          raise NotImplementedError()
  
      def __del__(self):
          self.stop()
  
  from ..errors import InstallError
  from .afl import AFL
  from .afl_multicb import AFLMultiCB
  