Permalink
Browse files

fixed verifier

  • Loading branch information...
dobin committed Oct 12, 2017
1 parent 4e205aa commit 9344c6c4f394e9b3d370621d5f12218243d0af68
@@ -4,6 +4,8 @@
import pprint
import sys
#from verifier import verifierresult
def printpickle():
pp = pprint.PrettyPrinter(indent=4)
@@ -12,6 +14,5 @@ def printpickle():
p = pickle.load(f)
pp.pprint(p)
if __name__ == '__main__':
printpickle()
@@ -9,17 +9,15 @@
import logging
import signal
import os
import subprocess
import serverutils
from ptrace.debugger.debugger import PtraceDebugger
from ptrace.debugger.child import createChild
from ptrace.debugger.process_event import ProcessExit
from ptrace.debugger.ptrace_signal import ProcessSignal
import serverutils
import verifycrashdata
from servermanager import ServerManager, StdoutQueue
from servermanager import ServerManager
class DebugServerManager(ServerManager):
@@ -163,8 +161,7 @@ def _getCrashDetails(self):
print("GetCrashDetails exception: " + str(e))
vCrashData = verifycrashdata.VerifyCrashData()
vCrashData.setData(
vCrashData = verifycrashdata.VerifyCrashData(
faultAddress=faultAddress,
faultOffset=faultOffset,
module=module,
@@ -29,10 +29,9 @@ def _getCrashDetails(self):
res.append(backtraceFrames[i].rstrip("\n\r"))
i += 1
crashData = verifycrashdata.VerifyCrashData()
crashData.setData(
crashData = verifycrashdata.VerifyCrashData(
backtrace=res,
output=ret,
analyzerOutput=ret,
cause="GDBSERVERMANAGER: n/a"
)
gdbOutput = serverutils.getAsanOutput(self.config, self.pid)
@@ -8,12 +8,14 @@
import logging
import signal
import pickle
import copy
import debugservermanager
import gdbservermanager
import networkmanager
import utils
import asanparser
import verifierresult
"""
Crash Verifier
@@ -53,12 +55,8 @@ def __init__(self, config):
self.p = None # serverManager
def handleNoCrash(self):
logging.info("Verifier: Waited long enough, NO crash. ")
def startChild(self):
p = multiprocessing.Process(target=self.debugServerManager.startAndWait, args=())
def startChild(self, debugServerManager):
p = multiprocessing.Process(target=debugServerManager.startAndWait, args=())
p.start()
self.p = p
@@ -84,7 +82,7 @@ def stopChild(self):
def verifyFile(self, filename):
"""Verify a single file."""
targetPort = self.config["baseport"] + 100
self.verifyOutcome(targetPort, filename)
self._verifyOutcome(targetPort, filename)
def verifyOutDir(self):
@@ -103,7 +101,7 @@ def verifyOutDir(self):
for outcomeFile in outcomesFiles:
print("Now processing: " + str(n) + ": " + outcomeFile)
targetPort = self.config["baseport"] + n + 100
self.verifyOutcome(targetPort, outcomeFile)
self._verifyOutcome(targetPort, outcomeFile)
n += 1
except KeyboardInterrupt:
@@ -120,20 +118,17 @@ def verifyOutDir(self):
print "Number of no crashes: " + str(noCrash)
def verifyOutcome(self, targetPort, outcomeFile):
def _verifyOutcome(self, targetPort, outcomeFile):
outcome = utils.readPickleFile(outcomeFile)
crashData = None
crashDataDebug = None
crashDataGdb = None
crashDataAsan = None
outputAsan = ""
outputGdb = ""
# get normal PTRACE / ASAN output
self.debugServerManager = debugservermanager.DebugServerManager(self.config, self.queue_sync, self.queue_out, targetPort)
crashDataDebug = self.ver(outcome, targetPort)
debugServerManager = debugservermanager.DebugServerManager(self.config, self.queue_sync, self.queue_out, targetPort)
crashDataDebug = self._verify(outcome, targetPort, debugServerManager)
crashDataDebug.printMe("CrashDataDebug")
# get ASAN (if available), and CORE (if available)
@@ -146,39 +141,46 @@ def verifyOutcome(self, targetPort, outcomeFile):
crashDataAsan.printMe("CrashDataAsan")
# get GDB output
self.debugServerManager = gdbservermanager.GdbServerManager(self.config, self.queue_sync, self.queue_out, targetPort)
crashDataGdb = self.ver(outcome, targetPort)
gdbServerManager = gdbservermanager.GdbServerManager(self.config, self.queue_sync, self.queue_out, targetPort)
crashDataGdb = self._verify(outcome, targetPort, gdbServerManager)
if crashDataGdb is not None:
crashDataGdb.printMe("CrashDataGdb")
# Default: Lets use crashDataDebug
logging.info("V: Use crashDataDebug")
crashData = crashDataDebug
crashData = copy.copy(crashDataDebug)
# add backtrace from Gdb
if crashDataGdb and crashDataGdb.backtrace is not None:
logging.info("V: BT: Use crashDataGdb")
crashData.backtrace = crashDataGdb.backtrace
crashData.cause = crashDataGdb.cause
outputGdb = crashDataGdb.output
# add backtrace from ASAN if exists
if crashDataAsan and crashDataAsan.backtrace is not None:
logging.info("V: BT: Use crashDataAsan")
crashData.backtrace = crashDataAsan.backtrace
crashData.cause = crashDataAsan.cause
outputAsan = crashDataAsan.output
self.handleCrash(outcome, crashData, outputAsan, outputGdb)
verifierResult = verifierresult.VerifierResult(
crashDataDebug,
crashDataAsan,
crashDataGdb,
crashData
)
outcome["verifierResult"] = verifierResult
def ver(self, outcome, targetPort):
self._handleCrash(outcome)
def _verify(self, outcome, targetPort, debugServerManager):
# start server in background
# TODO move this to verifyOutDir (more efficient?)
#self.debugServerManager = debugservermanager.DebugServerManager(self.config, self.queue_sync, self.queue_out, targetPort)
self.networkManager = networkmanager.NetworkManager(self.config, targetPort)
self.startChild()
self.startChild(debugServerManager)
# wait for ok (pid) from child that the server has started
data = self.queue_sync.get()
@@ -202,69 +204,84 @@ def ver(self, outcome, targetPort):
# empty result. has to be handled.
if crashData:
logging.info("Verifier: I've got a crash: ")
crashData.setStdOutput(serverStdout)
crashData.setProcessStdout(serverStdout)
else:
logging.error("Verifier: Some server error:")
logging.error("Verifier: Output: " + serverStdout)
return crashData
except Queue.Empty:
self.handleNoCrash()
self._handleNoCrash()
self.stopChild()
return None
return None
def handleCrash(self, outcome, vCrashData, outputAsan, outputGdb):
print "Handlecrash"
crashData = vCrashData.getData()
crashData["outputAsan"] = outputAsan
crashData["outputGdb"] = outputGdb
outcome["verifyCrashData"] = crashData
def _handleCrash(self, outcome):
logging.info("Handle a crash")
self._savePickle(outcome)
self._saveTxt(outcome)
def _savePickle(self, outcome):
# write pickle file
fileName = os.path.join(self.config["verified_dir"],
str(outcome["fuzzIterData"]["seed"]) + ".ffw")
with open(fileName, "w") as f:
pickle.dump(outcome, f)
def _saveTxt(self, outcome):
verifierResult = outcome["verifierResult"]
crashData = verifierResult.verifyCrashData
gdbVerifyCrashData = verifierResult.gdbVerifyCrashData
asanVerifyCrashData = verifierResult.asanVerifyCrashData
# write text file
fileName = os.path.join(self.config["verified_dir"],
str(outcome["fuzzIterData"]["seed"]) + ".txt")
# handle registers
if crashData["registers"] is not None:
registerStr = ''.join('{}={} '.format(key, val) for key, val in crashData["registers"].items())
if crashData.registers is not None:
registerStr = ''.join('{}={} '.format(key, val) for key, val in crashData.registers.items())
else:
registerStr = ""
# handle backtrace
if crashData["backtrace"] is not None:
backtraceStr = '\n'.join(map(str, crashData["backtrace"]))
if crashData.backtrace is not None:
backtraceStr = '\n'.join(map(str, crashData.backtrace))
else:
backtraceStr = ""
asanOutput = ""
gdbOutput = ""
if asanVerifyCrashData is not None:
asanOutput = asanVerifyCrashData.analyzerOutput
if gdbVerifyCrashData is not None:
gdbOutput = gdbVerifyCrashData.analyzerOutput
with open(fileName, "w") as f:
f.write("Address: %s\n" % hex(crashData["faultAddress"]))
f.write("Offset: %s\n" % hex(crashData["faultOffset"]))
f.write("Module: %s\n" % crashData["module"])
f.write("Signature: %s\n" % crashData["sig"])
f.write("Details: %s\n" % crashData["details"])
f.write("Stack Pointer: %s\n" % hex(crashData["stackPointer"]))
f.write("Stack Addr: %s\n" % crashData["stackAddr"])
f.write("Address: %s\n" % hex(crashData.faultAddress))
f.write("Offset: %s\n" % hex(crashData.faultOffset))
f.write("Module: %s\n" % crashData.module)
f.write("Signature: %s\n" % crashData.sig)
f.write("Details: %s\n" % crashData.details)
f.write("Stack Pointer: %s\n" % hex(crashData.stackPointer))
f.write("Stack Addr: %s\n" % crashData.stackAddr)
f.write("Registers: %s\n" % registerStr)
f.write("Time: %s\n" % time.strftime("%c"))
f.write("\n")
f.write("Child Output:\n %s\n" % crashData["stdOutput"])
f.write("Child Output:\n %s\n" % crashData.processStdout)
f.write("Backtrace: %s\n" % backtraceStr)
f.write("\n")
f.write("ASAN Output:\n %s\n" % outputAsan)
f.write("ASAN Output:\n %s\n" % asanOutput)
f.write("\n")
f.write("GDB Output:\n %s\n" % outputGdb)
f.write("GDB Output:\n %s\n" % gdbOutput)
f.close()
def _handleNoCrash(self):
logging.info("Verifier: Waited long enough, NO crash. ")
@@ -0,0 +1,16 @@
#!/usr/bin/env python2
import logging
class VerifierResult(object):
def __init__(self,
debugVerifyCrashData,
asanVerifyCrashData,
gdbVerifyCrashData,
verifyCrashData):
self.debugVerifyCrashData = debugVerifyCrashData
self.asanVerifyCrashData = asanVerifyCrashData
self.gdbVerifyCrashData = gdbVerifyCrashData
self.verifyCrashData = verifyCrashData
Oops, something went wrong.

0 comments on commit 9344c6c

Please sign in to comment.