def reproduce(self): self.q.enable_coverage_map() for program in self.repro_queue: self.q.reload_driver() for i in range(len(program.irps)): exec_res = self.q.send_irp(program.irps[i]) if exec_res.is_crash(): log("[*] %s found!!" % exec_res.exit_reason, "CRASH") self.q.reload() self.statistics.event_reload() unique = True for address in exec_res.coverage_to_array(): if self.crash_map[address]: unique = False self.crash_map[address] = True if unique and not exec_res.is_timeout(): # unique crash program.save_to_file('unique_crash') self.statistics.event_unique_findings( exec_res.exit_reason) else: program.save_to_file(exec_res.exit_reason) self.statistics.event_findings(exec_res.exit_reason) break self.q.disable_coverage_map() self.clear()
def execute_irp(self, index): """ Send IRP to qemu agent and receive a coverage. returns True if qemu has crashed. """ # send irp request. irp = self.cur_program.irps[index] exec_res = self.q.send_irp(irp) self.statistics.event_exec(self.cur_program.get_state()) is_new_input = self.bitmap_storage.should_send_to_master(exec_res) if is_new_input: new_program = self.cur_program.clone_with_irps(self.cur_program.irps[:index+1]) self.maybe_insert_program(new_program, exec_res) # restart Qemu on crash if exec_res.is_crash(): if exec_res.is_timeout(): log("Timeouted maybe? (%x)" % irp.IoControlCode, "CRASH") else: log("Crashed maybe? (%x)" % irp.IoControlCode, "CRASH") self.cur_program.save_to_file("unreproduced") self.q.reload() self.statistics.event_reload() self.reproducer.add(self.cur_program.clone_with_irps(self.cur_program.irps[:index+1])) return True return False
def main(): cfg = FuzzerConfiguration(IRPT_CONFIG) payload = read_binary_file(cfg.argument_values['payload']) q = qemu(0, cfg, debug_mode=0) if not q.start(): return i = 0 while i < len(payload): iocode = u32(payload[i:i + 4]) inlength = u32(payload[i + 4:i + 8]) outlength = u32(payload[i + 8:i + 12]) inbuffer = str(payload[i + 12:i + 12 + (inlength & 0xFFFFFF)]) log("[+] IoControlCode(%x) InBufferLength(%d)" % (iocode, inlength)) exec_res = q.send_irp(IRP(iocode, inlength, outlength, inbuffer)) if exec_res.is_crash(): if not exec_res.is_timeout(): log("Crashed!!") else: log("Timeout!!") q.shutdown() return i = i + 12 + inlength q.shutdown()
def dump(self, percent=0): log("id=%d, percent=%.2f%%, exec_count=%d, level=%d" % (self.get_id(), percent, self.get_exec_count(), self.get_level()), label="PROGRAM") for irp in self.irps: log("IoControlCode=%x, InBuffer=%s" % (irp.IoControlCode, bytes(irp.InBuffer[:0x10])), label='PROGRAM') log('', label='')
def log_current_state(self): while True: time.sleep(3) log('', label='') log("---- Corpus Database -----" ) self.database.dump() log("---- Current state (id=%d) ----" % self.cur_program.get_id()) log("exec_speed=%ds, state=%s" % (self.statistics.data["total_execs"] / (time.time() - self.statistics.data["start_time"]), self.cur_program.get_state())) log("total_paths=%d, unique=%d, pending=%d" % (self.statistics.data["paths_total"], len(self.database.get_unique_programs()), self.statistics.data["paths_pending"])) log("total_crash=%d, unique=%d, timeout=%d" % (self.statistics.data["findings"]["crash"], self.statistics.data['unique_findings']['crash'], self.statistics.data["findings"]["timeout"]))
def loop(self): # Start the QEMU if not self.q.start(): return # Start logging. t = threading.Thread(target=self.log_current_state, args=()) t.start() # basic coverage program. program = self.database.get_next() self.execute_program(program) program.irps = program.irps[::-1] self.execute_program(program) while self.optimizer.optimizable(): new_programs = self.optimizer.optimize() self.database.add(new_programs) # Import seeds. seed_directory = self.config.argument_values['seed_dir'] if len(os.listdir(seed_directory)): for (directory, _, files) in os.walk(seed_directory): for f in files: path = os.path.join(directory, f) log("Importing seed (%s)" % path) if os.path.exists(path): program = Program() program.load(path) # If a crash(or timeout) occurs, retry an execution. while True: if not self.execute_program(program): log("[!] Imported seed crashed!") break self.reproducer.clear() self.optimizer.clear() while self.optimizer.optimizable(): new_programs = self.optimizer.optimize() if new_programs: self.database.add(new_programs) log("[+] Count of initial unique programs : %d" % len(self.database.unique_programs)) if interface_manager.count() != len(self.database.unique_programs): log("[!] Some IOCTL code were ignored maybe") while True: program = self.database.get_next() programCopyed = copy.deepcopy(program) for _ in range(1): programCopyed.mutate(corpus_programs=self.database.get_programs()) # Execution if programCopyed.get_dirty(): self.execute_deterministic(programCopyed) else: self.execute_havoc(programCopyed) # Get new interesting corpus while self.optimizer.optimizable(): new_programs = self.optimizer.optimize() if new_programs: self.database.add(new_programs) # Start deterministic execution. for prog in new_programs: prog.set_state("AFLdetermin") self.execute_deterministic(copy.deepcopy(prog)) # crash reproduction self.reproducer.reproduce() # synchronization program.program_struct["dirty"] = programCopyed.program_struct["dirty"] program.program_struct["exec_count"] = programCopyed.program_struct["exec_count"] # Update update_probability_map of the corpus database. self.database.update_probability_map()
#!/usr/bin/python # encoding: utf-8 # -*- coding: utf8 -*- """ Created by PyCharm. File: LinuxBashShellScriptForOps:debug_example.py User: Guodong Create Date: 2016/11/8 Create Time: 11:56 """ from debug import log log.log().info('xx')