def insert_input(self, node, bitmap): safe_print(repr(node.node_struct)) self.grimoire_scheduler.insert_input(node) node.set_fav_factor(self.scheduler.score_fav(node), write=True) self.id_to_node[node.get_id()] = node self.current_cycle.append(node) print("saving input") self.update_best_input_for_bitmap_entry( node, bitmap) # TODO improve performance! print("done saving input") self.sort_queue(self.current_cycle) self.statistics.event_new_node_found(node)
def __perform_redqueen(self, payload_array, metadata): if self.config.argument_values['r']: default_info = {"method": "colorization", "parent": metadata["id"]} payload_bytes = array('B', payload_array) orig_hash = self.__get_bitmap_hash_robust(payload_bytes, default_info) extension = array("B", [207, 117, 130, 107, 183, 200, 143, 154]) appended_hash = self.__get_bitmap_hash_robust( payload_bytes + extension, default_info) if orig_hash and orig_hash == appended_hash: safe_print("input can be extended") payload_bytes += extension colored_alternatives = self.__perform_coloring( payload_bytes, default_info) if colored_alternatives: payload_bytes = array('B', colored_alternatives[0]) else: safe_print("input is not stable, skip redqueen") return t = time.time() rq_info = RedqueenInfoGatherer() rq_info.make_paths( RedqueenWorkdir(self.slave.slave_id, self.config)) rq_info.verbose = False for payload in colored_alternatives: if self.execute_redqueen(payload): rq_info.get_info(payload) rq_info.get_proposals() default_info = {"method": "redqueen", "parent": metadata["id"]} rq_info.run_mutate_redqueen(payload_bytes, self.execute, default_info) if False and self.mode_fix_checksum: for addr in rq_info.get_hash_candidates(): self.redqueen_state.add_candidate_hash_addr(addr) # for addr in rq_info.get_boring_cmps(): # self.redqueen_state.blacklist_cmp_addr(addr) # self.redqueen_state.update_redqueen_blacklist(RedqueenWorkdir(0)) duration = time.time() - t
def validate(self, data, old_array): self.q.set_payload(data) self.statistics.event_exec() new_bitmap = self.q.send_payload().apply_lut() new_array = new_bitmap.copy_to_array() if new_array == old_array: print("Validate OK") return True, new_bitmap else: for i in xrange(new_bitmap.bitmap_size): if old_array[i] != new_array[i]: safe_print("found fucky bit %d (%d vs %d)" % (i, old_array[i], new_array[i])) # assert(False) print( "VALIDATE FAILED, Not returning a bitmap!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" ) return False, None
def process(self, payload, metadata): start_time = time.time() update = {} while not update or time.time( ) - start_time < 3: # keep working each input until at least one seconds passed if update != {}: safe_print("internal cycle: {} and payload {}".format( repr(update), repr(payload))) abort, cur_update, cur_payload = self.statemachine( payload, metadata) if cur_payload: payload = cur_payload if cur_update: QueueNode.apply_metadata_update(update, cur_update) QueueNode.apply_metadata_update(metadata, cur_update) if abort: break return update, payload
def maybe_insert_node(self, payload, bitmap_array, node_struct): bitmap = ExecutionResult.bitmap_from_bytearray( bitmap_array, node_struct["info"]["exit_reason"], node_struct["info"]["performance"]) bitmap.lut_applied = True # since we received the bitmap from the slave, the lut was already applied backup_data = bitmap.copy_to_array() should_store, new_bytes, new_bits = self.bitmap_storage.should_store_in_queue( bitmap) new_data = bitmap.copy_to_array() if should_store: self.insert_input( self.construct_node(payload, bitmap_array, new_bytes, new_bits, node_struct), bitmap) else: for i in xrange(len(bitmap_array)): if backup_data[i] != new_data[i]: print("diffing at {} {} {}".format(i, repr(backup_data[i]), repr(new_data[i]))) safe_print("RECIEVED BORING INPUT, NOT SAVING..")
def check_fuckyness_and_store_trace(self, data): global num_fucky exec_res = self.q.send_payload() hash = exec_res.hash() trace1 = read_binary_file(self.config.argument_values['work_dir'] + "/pt_trace_dump_%d" % self.slave_id) exec_res = self.q.send_payload() if (hash != exec_res.hash()): safe_print( "found fucky bits, dumping!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" ) num_fucky += 1 trace_folder = self.config.argument_values[ 'work_dir'] + "/traces/fucky_%d_%d" % (num_fucky, self.slave_id) os.makedirs(trace_folder) atomic_write(trace_folder + "/input", data) atomic_write(trace_folder + "/trace_a", trace1) trace2 = read_binary_file(self.config.argument_values["work_dir"] + "/pt_trace_dump_%d" % self.slave_id) atomic_write(trace_folder + "/trace_b", trace2) return exec_res
def handle_initial(self, payload, metadata): time_initial_start = time.time() center_trim = False default_info = {"method": "trim", "parent": metadata["id"]} new_payload = perform_trim(payload, metadata, self.execute_with_bitmap, default_info, self.slave.execution_exited_abnormally) if center_trim: default_info = {"method": "center_trim", "parent": metadata["id"]} new_payload = perform_center_trim( new_payload, metadata, self.execute_with_bitmap, default_info, self.slave.execution_exited_abnormally, trimming_bytes=2) self.initial_time += time.time() - time_initial_start if new_payload == payload: return None safe_print("before trim:\t\t{}".format(repr(payload))) safe_print("after trim:\t\t{}".format(repr(new_payload))) return new_payload
def log_grimoire(msg): from common.safe_syscall import safe_print safe_print(msg) logger("[GI] " + msg)
def redqueen_cov(config, qemu_verbose=False): global thread_done log_info("Starting...") q = qemu(1337, config, debug_mode=True) q.start(verbose=qemu_verbose) known_lines = set() trace_parser = TraceParser(config) inputs, input_to_timestamp = parse_input_cov_list( config.argument_values["payload"]) for input_path in inputs: name = os.path.basename(input_path) print(common.color.OKGREEN + "Running: %s" % input_path + common.color.ENDC) q.set_payload(open(input_path).read()) start = time.time() result = q.execute_in_trace_mode(debug_mode=True, timeout_detection=False) end = time.time() if result: print(common.color.OKGREEN + "Execution succeded!" + common.color.ENDC) else: print(common.color.FLUSH_LINE + common.color.FAIL + "Execution failed!" + common.color.ENDC) print("Time: " + str(end - start) + "t/s") trace_parser.parse_and_add_trace( input_path, "/tmp/kafl_debug_workdir/redqueen_workdir_1337/pt_trace_results.txt" ) input_to_new_bbs = trace_parser.input_to_new_targets if all([ input_to_timestamp.get(input_path) is not None for input_path in inputs ]): plot_bb(inputs, input_to_timestamp, input_to_new_bbs) else: for input in sorted(list(input_to_new_bbs)): safe_print("%s: %s" % (input, repr(map(hex, input_to_new_bbs[input])))) count = 0 for _, bbs in input_to_new_bbs.items(): count += len(bbs) print("total: %d" % count) print("kill qemu") os.system("killall -9 qemu-system-x86_64") q.__del__() print("fix tty") os.system("stty sane") print("kill python") os.system("killall -9 python") return 0