Example #1
0
def main():
  if (len(sys.argv) > 2):
      cfgFile = sys.argv.pop(1)
      fuzzInst = ADBFuzz(cfgFile)
  else:
      print "Missing configuration file!"
      usage()
      exit(1)
  
  cmd = sys.argv.pop(1)
  if (cmd == "showdump"):
    print "Obtaining symbolized trace..."
    dumpFile = sys.argv[1]
    libSearchPath = sys.argv[2]
    minidump = Minidump(dumpFile, libSearchPath)
    symbolTrace = minidump.getSymbolizedCrashTrace()
    print ""
    for frame in symbolTrace:
      print "#" + frame[0] + "\t" + frame[1] + " at " + frame[2]
  elif (cmd == "reproduce"):
    fuzzInst.config.fuzzerFile = sys.argv[1]
    fuzzInst.config.runTimeout = int(sys.argv[2])
    
    isCrash = True
    
    if sys.argv[3] == 'crash':
      isCrash = True
    elif sys.argv[3] == 'abort':
      isCrash = False
    else:
      raise Exception("Unknown crash type " + sys.argv[3] + " specified!")
    
    if fuzzInst.testCrash(isCrash):
      exit(0)
    exit(1)
  elif (cmd == "run"):
    fuzzInst.remoteInit()
    if (len(sys.argv) > 2):
      fuzzInst.loopFuzz(sys.argv[1])
    else:
      fuzzInst.loopFuzz()
  elif (cmd == "deploy"):
    fuzzInst.deploy(sys.argv[1], sys.argv[2])
  elif (cmd == "reset"):
    fuzzInst.reset(sys.argv[1])
Example #2
0
  def runFuzzer(self):
    self.remoteInit()

    # Ensure Fennec isn't running
    if self.isFennecRunning():
      self.stopFennec()

    # Clean all existing minidumps
    if not self.clearMinidumps():
      raise Exception("Failed to clean existing minidumps")

    # Start our HTTP server for serving the fuzzer code
    self.HTTPProcess = self.startHTTPServer()

    # Start all loggers
    self.startLoggers()

    # Start Fennec
    self.startFennec()

    # Even though the program is already running, we should grant it
    # some extra time to load the fuzzer source and start running,
    # so it isn't directly diagnosed as hanging
    time.sleep(10);
    
    logSize = 0
    hangDetected = False
    forceRestart = False
    while(self.isFennecRunning() and not self.checkLoggingThreads()):
      time.sleep(self.config.runTimeout)

      if not os.path.exists(self.logFile):
        raise Exception("Logfile not present. If you are using websockets, this could indicate a network problem.")

      # Poor man's hang detection. Yes, this is a bad
      # idea, just for the sake of proof-of-concept
      newLogSize = os.path.getsize(self.logFile)
      if (logSize == newLogSize):
        hangDetected = True
        break
      else:
        logSize = newLogSize
        if newLogSize > self.config.maxLogSize:
          forceRestart = True
          break

    if hangDetected or forceRestart:
      self.stopFennec()
      self.stopLoggers()
      print "Hang detected or running too long, restarting..."
    else:
      try:
        # Fennec died or a logger found something
        checkCrashDump = True
        crashUUID = None
        minidump = None
        
        # If Fennec is still running, stop it now
        if self.isFennecRunning():
          checkCrashDump = False
          self.stopFennec()
        
        # Terminate our logging processes first
        self.stopLoggers()
        
        if checkCrashDump:
          dumps = self.getMinidumps()
          if (len(dumps) > 1):
            raise Exception("Multiple dumps detected!")
            
          if (len(dumps) < 1):
            raise Exception("No crash dump detected!")
    
          if not self.fetchMinidump(dumps[0]):
            raise Exception("Failed to fetch minidump with UUID " + dumps[0])
  
          crashUUID = dumps[0]
  
          # Copy logfiles
          shutil.copy2(self.syslogFile, dumps[0] + ".syslog")
          shutil.copy2(self.logFile, dumps[0] + ".log")
    
          minidump = Minidump(dumps[0] + ".dmp", self.config.libDir)
        else:
          # We need to generate an arbitrary ID here
          crashUUID = str(uuid.uuid4())
          
          # Copy logfiles
          shutil.copy2(self.syslogFile, crashUUID + ".syslog")
          shutil.copy2(self.logFile, crashUUID + ".log")
  
        print "Crash detected. Reproduction logfile stored at: " + crashUUID + ".log"
        if checkCrashDump:
          crashTrace = minidump.getCrashTrace()
          crashType = minidump.getCrashType()
          print "Crash type: " + crashType
          print "Crash backtrace:"
          print ""
          print crashTrace
        else:
          print "Crash type: Abnormal behavior (e.g. Assertion violation)"
  
        self.triager.process(crashUUID, minidump, crashUUID + ".syslog", crashUUID + ".log")
      except Exception, e:
        print "Error during crash processing: "
        print traceback.format_exc()