def havoc_insert_line(data): alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy" num = "0123456789.,x" special = "!\"$%&/()=?`'#+*+-_,.;:\\{[]}<>" terminator = ["\n", " ", "\0", '""', "'", "", " ADF\n"] return insert_word(data, rand.select([alpha, num, special]), rand.select(terminator))
def havoc_perform_insert_interesting_value_32(data): if len(data) < 4: return data order = rand.select(("big", "little")) pos = rand.int(len(data) - 3) value = rand.select(interesting_32_Bit) return b''.join( [data[:pos], value.to_bytes(4, order, signed=True), data[pos + 4:]])
def mutate_recursive_replacement(generalized_input, func, grimoire_inference): depth = rand.select(RECURSIVE_REPLACEMENT_DEPTH) generalized_input = recursive_replacement(generalized_input, grimoire_inference, depth) data = grimoire_inference.generalized_to_string(generalized_input) func(data)
def mutate_replace_strings(generalized_input, func, grimoire_inference, string_matches): if len(string_matches) == 0 or len(grimoire_inference.strings) == 0: return payload = grimoire_inference.generalized_to_string(generalized_input) match = rand.select(string_matches) rand_str = rand.select(grimoire_inference.strings) # replace single instance data = payload[0:match.start()] + rand_str + payload[match.end():] func(data) # replace all instances data = payload.replace(payload[match.start():match.end()], rand_str) func(data)
def havoc_perform_insert_interesting_value_8(data): if len(data) < 1: return data pos = rand.int(len(data)) value = rand.select(interesting_8_Bit) return b''.join( [data[:pos], value.to_bytes(1, 'little', signed=True), data[pos + 1:]])
def havoc_dict_replace(data): global redqueen_dict global dict_import has_redq = len(redqueen_dict) > 0 has_dict = len(dict_import) > 0 coin = rand.int(2) if not has_dict and has_redq and coin: addr = rand.select(redqueen_addr_list) dict_values = list(redqueen_dict[addr]) dict_entry = rand.select(dict_values) return dict_replace_sequence(data, dict_entry) elif has_dict: dict_entry = rand.select(dict_import) #dict_entry = dict_entry[:len(data)] return dict_replace_sequence(data, dict_entry) return data
def random_generalized(grimoire_inference): rand_generalized = list( grimoire_inference.generalized_inputs.keys())[rand.int( len(grimoire_inference.generalized_inputs))] rand_generalized = pad_generalized_input(rand_generalized) if rand.int(100) > CHOOSE_SUBINPUT and len(rand_generalized) > 0: if rand.int(100) < 50 and len(rand_generalized) > 0: gap_indices = filter_gap_indices(rand_generalized) min_index, max_index = rand.select(gap_indices), rand.select( gap_indices) min_index, max_index = min(min_index, max_index), max(min_index, max_index) rand_generalized = rand_generalized[min_index:max_index + 1] else: random_token = list(grimoire_inference.tokens.keys())[rand.int( len(grimoire_inference.tokens))] rand_generalized = pad_generalized_input(random_token) assert rand_generalized[0] == b'' and rand_generalized[-1] == b'' return rand_generalized
def havoc_perform_byte_addition_32(data): if len(data) < 4: return data order = rand.select(("big", "little")) pos = rand.int(len(data) - 3) value = int.from_bytes(data[pos:pos + 4], order, signed=False) value = (value + 1 + rand.int(AFL_ARITH_MAX)) % 0xffffffff return b''.join( [data[:pos], value.to_bytes(4, order, signed=False), data[pos + 4:]])
def havoc_perform_byte_subtraction_16(data): if len(data) < 2: return data order = rand.select(("big", "little")) pos = rand.int(len(data) - 1) value = int.from_bytes(data[pos:pos + 2], order, signed=False) value = (value - 1 - rand.int(AFL_ARITH_MAX)) % 0xffff return b''.join( [data[:pos], value.to_bytes(2, order, signed=False), data[pos + 2:]])
def mutate_seq_havoc_array(data, func, max_iterations, resize=False): if resize: data = data + data else: data = data stacking = rand.int(AFL_HAVOC_STACK_POW2) stacking = 1 << (stacking) for _ in range(1+max_iterations//stacking): for _ in range(stacking): handler = rand.select(havoc_handler) data = handler(data)[:KAFL_MAX_FILE] func(data)
def insert_word(data, chars, term): if len(data) < 2: return data offset = rand.int(len(data)) if rand.int(2) > 1: replen = 0 # plain insert else: replen = rand.int(len(data) - offset) word_length = min(len(data) - offset, rand.int(10) + 1) body = ''.join([term] + [rand.select(chars) for _ in range(word_length - 1)] + [term]) return b''.join([data[:offset], body.encode(), data[offset + replen:]])
def recursive_replacement(generalized_input, grimoire_inference, depth): for _ in range(depth): if len(generalized_input) >= 64 << 10: return generalized_input gap_indices = filter_gap_indices(generalized_input) if len(gap_indices) == 0: return generalized_input random_index = rand.select(gap_indices) generalized_input = generalized_input[ 0:random_index] + random_generalized( grimoire_inference) + generalized_input[random_index + 1:] return generalized_input
def havoc_perform_clone_random_byte(data): data_len = len(data) if data_len < 1 or data_len + HAVOC_BLK_XL >= KAFL_MAX_FILE: return data # clone bytes with p=3/4, else insert block of constant bytes if rand.int(4): clone_len = AFL_choose_block_len(data_len) clone_from = rand.int(data_len - clone_len + 1) body = data[clone_from:clone_from + clone_len] else: clone_len = AFL_choose_block_len(HAVOC_BLK_XL) val = rand.int(256) if rand.int(2) else rand.select(data) body = b''.join([ val.to_bytes(1, 'little', signed=False) for _ in range(clone_len) ]) clone_to = rand.int(data_len) return b''.join([data[:clone_to], body, data[clone_to:]])
def havoc_perform_byte_seq_override(data): if len(data) < 2: return data copy_len = AFL_choose_block_len(len(data) - 1) copy_from = rand.int(len(data) - copy_len + 1) copy_to = rand.int(len(data) - copy_len + 1) body = b'' if rand.int(4): if copy_from != copy_to: body = data[copy_from:copy_from + copy_len] else: if rand.int(2): value = rand.int(256) else: value = rand.select(data) body = b''.join( value.to_bytes(1, 'little', signed=False) for _ in range(copy_len)) return b''.join([data[:copy_to], body, data[copy_to + copy_len:]])