Example #1
0
def generate_binary_file(byte_array, seed_file_path, gen_file_path=None):
    byte_list = []
    modified_index_list = []
    with open(seed_file_path, "rb") as poc_file:
        byte = poc_file.read(1)
        while byte:
            number = int(struct.unpack('>B', byte)[0])
            byte_list.append(number)
            byte = poc_file.read(1)
    mask_byte_list = values.MASK_BYTE_LIST[seed_file_path]
    emitter.data("Masked Byte List", mask_byte_list)
    for index in byte_array:
        if index not in mask_byte_list:
            byte_list[index] = byte_array[index]
            modified_index_list.append(index)
    emitter.data("Modified Byte List", modified_index_list)
    file_extension = ""
    if "." in seed_file_path:
        file_extension = str(seed_file_path).split(".")[-1]
    if not gen_file_path:
        gen_file_path = definitions.DIRECTORY_OUTPUT + "/input-" + str(values.ITERATION_NO)
    values.FILE_POC_GEN = gen_file_path
    if file_extension:
        values.FILE_POC_GEN = values.FILE_POC_GEN + "." + file_extension
    with open(values.FILE_POC_GEN, "wb") as new_input_file:
        new_input_file.write(bytearray(byte_list))
Example #2
0
def generate_mask_bytes(klee_out_dir, poc_path):
    mask_byte_list = list()
    log_path = klee_out_dir + "/concrete.log"
    concretized_byte_list = reader.collect_concretized_bytes(log_path)
    smt2_file_path = klee_out_dir + "/test000001.smt2"
    control_byte_list = reader.collect_bytes_from_smt2(smt2_file_path)
    emitter.data("Control Byte List", control_byte_list)
    fixed_byte_list = list()
    if "A-data" in concretized_byte_list:
        influence_byte_list = sorted(list(concretized_byte_list["A-data"]))
        emitter.data("Influencing Byte List", influence_byte_list)
    fixed_byte_list = control_byte_list
    if poc_path:
        byte_length = os.path.getsize(poc_path)
        for i in range(0, byte_length):
            if i not in fixed_byte_list:
                mask_byte_list.append(i)
    return sorted(mask_byte_list)
Example #3
0
def check_path_feasibility(chosen_control_loc, new_path, index):
    """
    This function will check if a selected path is feasible
           ppc : partial path conditoin at chosen control loc
           chosen_control_loc: branch location selected for flip
           returns satisfiability of the negated path
    """
    result = False
    if chosen_control_loc != values.CONF_LOC_PATCH:
        result = not is_unsat(new_path)
    else:
        result = is_sat(new_path)

    if result:
        return True, index
    else:
        emitter.data("Path is not satisfiable at " + str(chosen_control_loc), new_path)
        return False, index
Example #4
0
def generate_constant_value_list(sym_path):
    gen_const_list = dict()
    gen_var_list = dict()
    const_val_list = dict()
    model = generate_model(sym_path)
    if model is None:
        return None
    for var_name in model:
        var_byte_list = model[var_name]
        if "const" in var_name:
            gen_const_list[var_name] = var_byte_list
        else:
            gen_var_list[var_name] = var_byte_list

    for const_name in gen_const_list:
        bit_vector = gen_const_list[const_name]
        const_value = utilities.get_signed_value(bit_vector)
        print(const_name, const_value)
        const_val_list[const_name] = const_value

    emitter.data("Generated Constant List", const_val_list)
    return const_val_list
Example #5
0
def generate_new_input(sym_path, argument_list=None, poc_path=None, gen_path=None):
    gen_arg_list = dict()
    gen_var_list = dict()
    input_var_list = list()
    input_arg_dict = dict()
    input_arg_list = list()
    model = generate_model(sym_path)
    if model is None:
        return None, None
    for var_name in model:
        var_byte_list = model[var_name]
        if "arg" in var_name:
            gen_arg_list[var_name] = var_byte_list
        else:
            gen_var_list[var_name] = var_byte_list
    mask_list = values.CONF_MASK_ARG
    mask_map = dict()
    if values.CONF_MASK_ARG:
        min_val = 0
        new_idx = 0
        max_val = len(argument_list)
        for idx in range(min_val, max_val):
            if str(idx) not in mask_list:
                mask_map[new_idx] = idx
                new_idx = new_idx + 1

    for arg_name in gen_arg_list:
        bit_vector = gen_arg_list[arg_name]
        arg_index = int(str(arg_name).replace("arg", ""))
        arg_str = utilities.get_str_value(bit_vector)
        arg_value = utilities.get_signed_value(bit_vector) - 48
        arg_index_orig = arg_index
        if values.CONF_MASK_ARG:
            arg_index_orig = mask_map[arg_index_orig]
        # print(arg_name, arg_index, arg_value)
        if str(argument_list[arg_index_orig]).isnumeric() or \
                (not str(argument_list[arg_index_orig]).isalpha() and any(op in str(argument_list[arg_index_orig]) for op in ["+", "-", "/", "*"])):
            input_arg_dict[arg_index] = str(arg_value)
            # emitter.debug(arg_name, arg_value)
        else:
            arg_str_filtered = str(arg_str).replace("<", "a").replace("&", "s").replace(">", "a").replace("'", "a")
            input_arg_dict[arg_index] = arg_str_filtered
            # emitter.debug(arg_name, arg_str)

    # fill random values if not generated
    offset = 0
    for arg in argument_list:
        index = list(argument_list).index(arg) - offset
        if "$POC" in arg:
            input_arg_list.append(str(argument_list[index]))
            offset = 1
        elif str(index) in values.CONF_MASK_ARG:
            input_arg_list.append(arg)
        elif index in input_arg_dict:
            input_arg_list.append(input_arg_dict[index])
        else:
            arg_len = len(str(argument_list[index]))
            random_value = ""
            for j in range(0, arg_len):
                random_value += chr(random.randint(32, 128))
            input_arg_list.append(random_value)

    for var_name in gen_var_list:
        bit_vector = gen_var_list[var_name]
        var_value = 0
        var_size = len(bit_vector)
        if var_name in ["A-data", "A-data-stat"]:
            if var_name == "A-data":
                generate_binary_file(bit_vector, poc_path, gen_path)
            continue
        if bit_vector:
            var_value = utilities.get_signed_value(bit_vector)
        # emitter.debug(var_name, var_value)
        if "angelic" in var_name:
            input_var_list.append({"identifier": var_name, "value": var_value, "size": 4})
        # input_var_list.append({"identifier": var_name, "value": var_value, "size": 4})

    # for var_tuple in second_var_list:
    #     var_name = var_tuple['identifier']
    #     if var_name not in gen_var_list:
    #         emitter.warning("\t[warning] variable " + var_name + " assigned random value")
    #         var_size = var_tuple['size']
    #         var_value = 0
    #         for i in range(1, var_size):
    #             var_value += ((2 << 7) << (int(i) - 1)) * random.randint(0, 255)
    #         input_var_list.append({"identifier": var_name, "value": var_value, "size": var_size})
    emitter.data("Generated Arg List", input_arg_list)
    emitter.data("Generated Var List", input_var_list)
    return input_arg_list, input_var_list
Example #6
0
def generate_model(formula):
    """
           This function will invoke PySMT APIs to solve the provided formula and return the byte list of the model
           Arguments:
               formula: smtlib formatted formula
    """
    emitter.debug("extracting z3 model")
    model = get_model(formula)
    if model is None:
        return None
    path_script = "/tmp/z3_script_model"
    write_smtlib(formula, path_script)
    with open(path_script, "r") as script_file:
        script_lines = script_file.readlines()
    script = "".join(script_lines)
    var_list = set(re.findall("\(declare-fun (.+?) \(\)", script))
    sym_var_list = dict()
    for var_name in var_list:
        # sym_var_list[var_name] = dict()
        if "const_" in var_name and not "const_arr" in var_name:
            sym_def = Symbol(var_name, BV32)
            if sym_def not in model:
                continue
            x = model[sym_def]
            byte_list = dict()
            default_value = x.bv_signed_value()
            byte_list[0] = default_value
        else:
            sym_def = Symbol(var_name, ArrayType(BV32, BV8))
            if sym_def not in model:
                continue
            x = model[sym_def].simplify()
            byte_list = dict()
            value_array_map = x.array_value_assigned_values_map()
            default_value = int(str(x.array_value_default()).split("_")[0])
            if not value_array_map:
                byte_list[0] = default_value
            else:
                for idx, val in value_array_map.items():
                    index = int(str(idx).split("_")[0])
                    value = int(str(val).split("_")[0])
                    byte_list[index] = value

                max_index = max(list(byte_list.keys()))
                if var_name in values.LIST_BIT_LENGTH:
                    array_size = values.LIST_BIT_LENGTH[var_name] - 1
                    if var_name in ["A-data"]:
                        array_size = max_index

                else:
                    array_size = max_index + 1  # TODO: this could be wrong calculation

                if max_index == 0:
                    array_size = 2

                if var_name not in ["A-data"]:
                    for i in range(0, array_size):
                        if i not in byte_list:
                            byte_list[i] = default_value

                if var_name not in ["A-data", "A-data-stat"]:
                    for i in range(array_size - 1, -1, -1):
                        if byte_list[i] == 0:
                            byte_list.pop(i)
                        else:
                            break
        sym_var_list[var_name] = byte_list
    emitter.data("model var list", sym_var_list)
    return sym_var_list