def playback(filename): ''' Can play back a trace manually, allowing the user to attach a debugger and step through the trace at their own leisure. This function was developed to aid a reverse engineer after they have run L{Morpher} and wish to investigate the reported crashs and hangs in more detail. L{Morpher} stores a copy of the L{Trace} file that caused a crash or hang along with the crash report. This function takes the trace file and replays the L{Snapshot}s one at a time, reporting the PID so the engineer can attach a debugger of his own and follow along. @param filename: The path to the L{Trace} file to be replayed @type filename: string ''' cfg = config.Config() dlltype = cfg.get('fuzzer', 'dll_type') path = cfg.get('fuzzer', 'target') print "Attach your debugger to PID %d" % os.getpid() # Load the target DLL if dlltype == "cdecl": dll = ctypes.cdll else: dll = ctypes.windll print "Loading " + dlltype + " DLL at " + path target = dll.LoadLibrary(path) # Load the target trace file print "Replaying trace: " + filename f = open(filename, "rb") trace = pickle.load(f) f.close() # Run each function capture in order for s in trace.snapshots: name = s.name cmd = "s" while not cmd == "": print "Calling function %s" % name cmd = raw_input( "[Enter to continue, s to show snapshot, q to quit]:") if cmd == "s": print s.toString() elif cmd == "q": print "Quitting..." return args = s.replay(trace.type_manager) func = getattr(target, name) result = func(*args) print "Function returned result: %s" % str(result) print "Trace complete"
def testFuzzing(): cfg = config.Config() cfg.setupLogging("morpher") # The logging object used for reporting log = cfg.getLogger("morpher.morpher") log.info(cfg.toString()) print "Calling Fuzzer" fuzz = fuzzer.Fuzzer(cfg) fuzz.fuzz() print "Exiting"
def testCountValues(): cfg = config.Config() print "Calling Mutator" mut = mutator.Mutator(cfg) print "Mutating char" print len(mut._getChars("c", "A")) print "Mutating int" print len(mut._getInts("i", 32)) print "Mutating unsigned int" print len(mut._getUints("i", 32)) print "Mutating floats" print len(mut._getFloats("f", 32)) print "Mutating pointers" print len(mut._getPointers("P", 32))
def testMonitorCrash(): trace = [] lst = [] k = block.Block(0x1000, "\x00\x00\x00\x00\x05\x00\x00\x00") lst.append(k) m = memory.Memory(2, lst) m.setArgs(0x1000, "II") trace.append(m) lst = [] k = block.Block(0x1000, "\x00\x00\x00\x00\x05\x00\x00\x00") lst.append(k) k = block.Block(0x2000, "\x11\x00\x00\x00\x08\x00\x00\x00") lst.append(k) m = memory.Memory(2, lst) m.setArgs(0x1000, "II") trace.append(m) cfg = config.Config() cfg.setupLogging("morpher") # The logging object used for reporting log = cfg.getLogger("morpher.morpher") log.info(cfg.toString()) print "Calling fuzzer" fuzz = monitor.Monitor(cfg) fuzz.run(trace) trace = [] lst = [] k = block.Block(0x1000, "\x00\x00\x00\x00\x04\x00\x00\x00") lst.append(k) k = block.Block(0x2000, "\x11\x00\x00\x00\x08\x00\x00\x00") lst.append(k) m = memory.Memory(2, lst) m.setArgs(0x1000, "II") trace.append(m) fuzz.setTraceNum(1) fuzz.run(trace) print "Exiting"
def testHarness(): lst = [] k = block.Block(0x1000, "\x05\x00\x00\x00\x06\x00\x00\x00") lst.append(k) k = block.Block(0x2000, "\x11\x00\x00\x00\x08\x00\x00\x00") lst.append(k) m = memory.Memory(2, lst) m.setArgs(0x2000, "II") path = os.getcwd() path = os.path.join(path, "data", "fuzzed.pkl") f = open(path, "wb") pickle.dump(m, f) f.close() # run the test path = os.getcwd() path = os.path.join(path, "data", "cfg.pkl") cfg = config.Config() cfg.setupLogging("morpher") # The logging object used for reporting log = cfg.getLogger("morpher.morpher") log.info(cfg.toString()) f = open(path, "wb") pickle.dump(cfg, f) f.close() h = harness.Harness(cfg) print "IsAlive: " + str(h.is_alive()) print "Pid: " + str(h.pid) h.start() time.sleep(2) print "started harness and slept 2 secs" print "IsAlive: " + str(h.is_alive()) print "Pid: " + str(h.pid) h.terminate() h.join() # Need to do this to collect exit code print h.exitcode
def testMonitorHang(): trace = [] lst = [] k = block.Block(0x1000, "\x03\x00\x00\x00\x41\x00\x00\x00") lst.append(k) m = memory.Memory(1, lst) m.setArgs(0x1000, "Ic") trace.append(m) lst = [] k = block.Block(0x1000, "\x30\x00\x00\x00\x00\x00\x00\x00") lst.append(k) k = block.Block(0x2000, "\x30\x00\x00\x00\x00\x00\x00\x00") lst.append(k) m = memory.Memory(1, lst) m.setArgs(0x2000, "Ic") trace.append(m) lst = [] k = block.Block(0x1000, "\x01\x00\x00\x00\x42\x00\x00\x00") lst.append(k) m = memory.Memory(1, lst) m.setArgs(0x1000, "Ic") trace.append(m) cfg = config.Config() cfg.setupLogging("morpher") # The logging object used for reporting log = cfg.getLogger("morpher.morpher") log.info(cfg.toString()) print "Calling fuzzer" fuzz = monitor.Monitor(cfg, 1) fuzz.run(trace) print "Exiting"
def testMutator(): cfg = config.Config() cfg.setupLogging("morpher") # The logging object used for reporting log = cfg.getLogger("morpher.morpher") log.info(cfg.toString()) print "Calling Mutator" mut = mutator.Mutator(cfg) print "Mutating c, A" print mut.mutate("c", "A") print "Mutating I, 32" print mut.mutate("I", 32) print "Mutating i, 32" print mut.mutate("i", 32) print "Mutating h, 32" print mut.mutate("h", 32) print "Mutating Q, 4000000000000" print mut.mutate("Q", 4000000000000) print "Mutating f, 3.14" print mut.mutate("f", 3.14) print "Mutating P, 0xdeadbeef" print mut.mutate("P", 0xdeadbeef) print "Exiting"
def testPatching(): trace = [] lst = [] k = block.Block(0x1000, "\x04\x20\x00\x00\x05\x00\x00\x00") lst.append(k) k = block.Block(0x2000, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF") lst.append(k) m = memory.Memory(2, lst) m.registerPointer(0x1000) m.setArgs(0x1000, "PI") trace.append(m) cfg = config.Config() cfg.setupLogging("morpher") # The logging object used for reporting log = cfg.getLogger("morpher.morpher") log.info(cfg.toString()) print "Calling monitor" fuzz = monitor.Monitor(cfg) fuzz.run(trace) print "Exiting"