def create_population(grammars, diversification_factor=1): mutated_grams = [] for g in grammars: cmd_gram = utilityFunctions.copy_dict(g) update_current(cmd_gram) generated = 0 while generated < diversification_factor: ''' global move_command if move_command == 0: move_command = 1 if utilityFunctions.flip_coin(10) == 1 else 0 ''' # 3 steps: # 1. random crossover # check if no crossover fuzzer new_gram = utilityFunctions.copy_dict( gram_crossover(cmd_gram, move_command) ) if fuzz_type != 2 else utilityFunctions.copy_dict(cmd_gram) if fuzz_type != 3: # check if no mutation fuzz # 2. random add or delete if utilityFunctions.flip_coin() == 1: gram_random_add_delete(new_gram, move_command) # 3. random valid/invalid if utilityFunctions.flip_coin() == 1: make_gram_invalid(new_gram) if new_gram not in stored_grammar and new_gram != standard_grammar: mutated_grams.append(new_gram) generated += 1 return mutated_grams
def make_gram_invalid(cmd_gram): arg_in_struct = [] for el in cmd_gram['arg']: if el in cmd_gram['struct']: arg_in_struct.append(el) if len(arg_in_struct) > 0: arg_name = random.choice(arg_in_struct) arg = cmd_gram[arg_name] type = arg['type'] if type == 'digit' or type == 'letters': half_len, double_len = (arg['length'] / 2), (arg['length'] * 2) if utilityFunctions.flip_coin(2) > 0: if half_len < 2: arg['length'] = double_len elif double_len > 1000: arg['length'] = half_len else: arg['length'] = random.choice([half_len, double_len]) else: arg['type'] = 'string' elif type == 'string': half_len, double_len = (arg['length'] / 2), (arg['length'] * 2) if half_len < 2: arg['length'] = double_len elif double_len > 1000: arg['length'] = half_len else: arg['length'] = random.choice([half_len, double_len]) elif type == 'ranged': start, end = arg['range'][0], arg['range'][1] start_or_end = utilityFunctions.flip_coin() if start_or_end == 1: # negate start if start > MIN_INT: arg['range'] = [start - 100, start - 1] if ( start - 100 > MIN_INT) else [MIN_INT, start - 1] else: # engate end if end < MAX_INT: arg['range'] = [end + 1, end + 100] if ( end + 100 < MAX_INT) else [end + 1, MAX_INT] elif type == 'fixed': if utilityFunctions.flip_coin() == 0: new_value = ''.join( random.choice(string.ascii_letters + string.digits + string.punctuation) for x in range(10)) arg['values'].append(new_value) else: cmd_gram[arg_name] = {"type": "string", "length": 10} elif type == 'immutable': pass else: raise Exception("Error: unknow argument type")
def gram_random_add_delete(cmd_gram, move_command=0): #print ('--- gram_random_add_delete method') gram_struct = cmd_gram['struct'] if len(gram_struct) < 2 or utilityFunctions.flip_coin() == 0: add_field(cmd_gram) else: remove_field(cmd_gram, move_command)
def block_swapping(cmd): if utilityFunctions.flip_coin(2) == 0: return cmd blocks = get_blocks(cmd) i, j = random.randint(0, len(blocks)-1), random.randint(0, len(blocks)-1) blocks[i], blocks[j] = blocks[j], blocks[i] return ''.join(blocks)
def modify_grammar(cmd_gram, settings, move_command=0): #print ('--- modify_grammar') settings = settings.split(',') if settings[1] == '1': # crossover gram_crossover(cmd_gram, move_command) if settings[2] == '1' and settings[ 3] == '1': # both add_field and remove_field if utilityFunctions.flip_coin() == 1: gram_random_add_delete(cmd_gram, move_command) elif settings[2] == '1' and settings[3] == '0': # add_field if utilityFunctions.flip_coin() == 1: add_field(cmd_gram) elif settings[2] == '0' and settings[3] == '1': # remove_field if utilityFunctions.flip_coin() == 1: remove_field(cmd_gram, move_command) if settings[4] == '1': # negate_condition if utilityFunctions.flip_coin() == 1: negate_condition(cmd_gram) if settings[5] == '1': # negate_type if utilityFunctions.flip_coin() == 1: negate_type(cmd_gram) if settings[6] == '1': # fixed_integers if utilityFunctions.flip_coin() == 1: fixed_integers(cmd_gram) if settings[7] == '1': # alter_connectors if utilityFunctions.flip_coin() == 1: alter_connectors(cmd_gram)
def modify_grammar_back(gram): cmd_gram = utilityFunctions.copy_dict(gram) # 3 steps: # 1. random crossover # check if no crossover fuzzer new_gram = utilityFunctions.copy_dict( gram_crossover(cmd_gram, move_command) ) if fuzz_type != 2 else utilityFunctions.copy_dict(cmd_gram) if fuzz_type != 3: # check if no mutation fuzz # 2. random add or delete if utilityFunctions.flip_coin() == 1: gram_random_add_delete(new_gram, move_command) # 3. random valid/invalid if utilityFunctions.flip_coin() == 1: make_gram_invalid(new_gram) return new_gram
def known_integer(cmd): if utilityFunctions.flip_coin(2) == 0: return cmd MAX_INT = sys.maxint MIN_INT = -sys.maxint -1 values = [-1, 256, 1024, MAX_INT-1, MAX_INT, MIN_INT] numbers = re.findall(r'\b\d+\b', cmd) if len(numbers) > 0: elem = random.choice(numbers) cmd = cmd.replace(elem, str(random.choice(values))) return cmd
def bit_flip(line, coin=None): bit_line = bitarray.bitarray() bit_line.frombytes(line) if coin is None: coin = utilityFunctions.flip_coin(4) if coin == 0: return line flip_n_bits(bit_line, coin) try: return str(bit_line.tobytes().decode('utf-8')) except: return bit_flip(line, coin)
def byte_flip(line, l=None): if (utilityFunctions.flip_coin(2) == 0 and l is None): return line bit_line = bitarray.bitarray() bit_line.frombytes(line) flip_width= [8, 16, 32] if l is None: l = random.choice(flip_width) while l > len(bit_line): l = random.choice(flip_width) flip_n_bits(bit_line, l) try: return str(bit_line.tobytes().decode('utf-8')) except: return byte_flip(line, l-1)
def fixed_integers(cmd_gram): #print ('--- fixed_integers method') arg_in_struct = [] for el in cmd_gram['arg']: if el in cmd_gram['struct']: arg_in_struct.append(el) if len(arg_in_struct) > 0: arg_name = random.choice(arg_in_struct) arg = cmd_gram[arg_name] type = arg['type'] if type == 'digit': arg['type'] = 'fixed' arg['values'] = [MIN_INT, MAX_INT] if type == 'fixed': arg['values'].append([MIN_INT, MAX_INT]) if type == 'ranged': if utilityFunctions.flip_coin() == 0: arg['range'] = [MIN_INT, arg['range'][1]] else: arg['range'] = [arg['range'][0], MAX_INT]
def negate_condition(cmd_gram): #print('--- negate_condition method') arg_in_struct = [] for el in cmd_gram['arg']: if el in cmd_gram['struct']: arg_in_struct.append(el) if len(arg_in_struct) > 0: arg_name = random.choice(arg_in_struct) arg = cmd_gram[arg_name] type = arg['type'] if type == 'digit' or type == 'letters' or type == 'string': # condition: length - int half_len, double_len = (arg['length'] / 2), (arg['length'] * 2) arg['length'] = double_len if half_len < 2 else random.choice( [half_len, double_len]) elif type == 'ranged': start, end = arg['range'][0], arg['range'][1] start_or_end = utilityFunctions.flip_coin() if start_or_end == 1: # negate start if start > MIN_INT: arg['range'] = [start - 100, start - 1] if ( start - 100 > MIN_INT) else [MIN_INT, start - 1] else: # engate end if end < MAX_INT: arg['range'] = [end + 1, end + 100] if ( end + 100 < MAX_INT) else [end + 1, MAX_INT] elif type == 'fixed': # condition: values - [str, str, ... , str] new_value = ''.join( random.choice(string.ascii_letters + string.digits + string.punctuation) for x in range(10)) arg['values'].append(new_value) elif type == 'immutable': # condition: immutable_value - str pass else: raise Exception("Error: unknow argument type")
def try_restore_type(arg, type): if utilityFunctions.flip_coin() == 1: try: arg['values'] arg['type'] = random.choice(['string', 'letters', 'fixed']) except (KeyError): try: arg['range'] arg['type'] = random.choice(['string', 'letters', 'ranged']) except (KeyError): if type == 'digit': arg['type'] = random.choice(['string', 'letters']) elif type == 'letters': arg['type'] = random.choice(['string', 'digit']) elif type == 'string': pass else: if type == 'digit': arg['type'] = random.choice(['string', 'letters']) elif type == 'letters': arg['type'] = random.choice(['string', 'digit']) elif type == 'string': pass
def block_deletion(cmd): if utilityFunctions.flip_coin(2) == 0: return cmd blocks = get_blocks(cmd) blocks.pop(random.randint(0, len(blocks)-1)) return ''.join(blocks)
def test_fuzz(cmd): return [random.random()*5, utilityFunctions.flip_coin(10)]