Esempio n. 1
0
def extract_byte_code(binary_path):
    emitter.normal("\textracting bytecode")
    directory_path = "/".join(binary_path.split("/")[:-1])
    binary_name = binary_path.split("/")[-1]
    extract_command = "cd " + directory_path + ";"
    extract_command += "extract-bc " + binary_name
    utilities.execute_command(extract_command)
Esempio n. 2
0
def soft_restore_project(project_path):
    restore_command = "cd " + project_path + ";"
    if os.path.exists(project_path + "/.git"):
        restore_command += "git reset --hard HEAD"
    elif os.path.exists(project_path + "/.svn"):
        restore_command += "svn revert -R .; "
    elif os.path.exists(project_path + "/.hg"):
        restore_command += "hg update --clean"
    else:
        return
    # print(restore_command)
    execute_command(restore_command)
Esempio n. 3
0
def restore_project(project_path):
    restore_command = "cd " + project_path + ";"
    if os.path.exists(project_path + "/.git"):
        restore_command += "git clean -fd; git reset --hard HEAD"
    elif os.path.exists(project_path + "/.svn"):
        restore_command += "svn revert -R .; svn status --no-ignore | grep '^\?' | sed 's/^\?     //'  | xargs rm -rf"
    elif os.path.exists(project_path + "/.hg"):
        restore_command += "hg update --clean; hg st -un0 | xargs -0 rm"
    else:
        return
    # print(restore_command)
    execute_command(restore_command)
Esempio n. 4
0
def clean_project(project_path, binary_path):
    emitter.normal("\tcleaning files")
    binary_dir_path = "/".join(str(binary_path).split("/")[:-1])

    if values.CONF_COMMAND_BUILD != "skip":
        clean_command = "cd " + project_path
        clean_command += "; make clean"
        clean_command += "; rm compile_commands.json"
        clean_command += "; rm CMakeCache.txt"
        clean_command += "; rm -rf CMakeFiles"
        execute_command(clean_command)
    clean_residues = "cd " + binary_dir_path + ";" + "rm -rf ./patches/*;" + "rm -rf ./klee*"
    execute_command(clean_residues)
Esempio n. 5
0
def build_project(project_path, build_command=None):
    emitter.normal("\tbuilding program")
    dir_command = "cd " + project_path + ";"
    if build_command is None:
        build_command = "CC=" + CC + " CXX=" + CXX + " "
        if values.CONF_BUILD_FLAGS == "disable":
            build_command += "bear make -j`nproc`  "
        else:
            build_command += "bear make CFLAGS=\"" + C_FLAGS + "\" "
            build_command += "CXXFLAGS=\"" + CXX_FLAGS + " LDFLAGS=" + LD_FLAGS + "\" -j`nproc` > "
    else:
        if build_command == "skip":
            emitter.warning("\t[warning] skipping build")
            return
        if not os.path.isfile(project_path + "/compile_commands.json"):
            build_command = build_command.replace("make ", "bear make ")
        if CC == "wllvm":
            build_command = remove_fsanitize(build_command)
        build_command = apply_flags(build_command)
    if not build_command:
        error_exit("[Not Found] Build Command")

    build_command = dir_command + build_command
    build_command = build_command + " > " + definitions.FILE_MAKE_LOG
    ret_code = execute_command(build_command)
    if int(ret_code) != 0:
        emitter.error(build_command)
        error_exit("BUILD FAILED!!\nExit Code: " + str(ret_code))
Esempio n. 6
0
def generate_model_cli(formula):
    """
           This function will invoke the Z3 Cli interface to solve the provided formula and return the model byte list
           Arguments:
               formula: smtlib formatted formula
    """
    emitter.normal("\textracting z3 model")
    path_script = "/tmp/z3_script_model_cli"
    path_result = "/tmp/z3_output_model_cli"
    write_smtlib(formula, path_script)
    with open(path_script, "a") as script_file:
        script_file.writelines(["(get-model)\n", "(exit)\n"])
    z3_command = "z3 " + path_script + " > " + path_result
    utilities.execute_command(z3_command)
    with open(path_result, "r") as result_file:
        z3_output = result_file.readlines()

    model_byte_list = parser.parse_z3_output(z3_output)
    return model_byte_list
Esempio n. 7
0
def run_concrete_execution(program,
                           argument_list,
                           print_output=False,
                           output_dir=None):
    """
    This function will execute the program in concrete mode using the concrete inputs
        program: the absolute path of the bitcode of the program
        argument_list : a list containing each argument in the order that should be fed to the program
        second_var_list: a list of tuples where a tuple is (var identifier, var size, var value)
    """
    logger.info("running concolic execution")
    emitter.normal("\texecuting klee in concrete mode")
    global File_Log_Path
    current_dir = os.getcwd()
    directory_path = "/".join(str(program).split("/")[:-1])
    emitter.debug("changing directory:" + directory_path)
    os.chdir(directory_path)
    binary_name = str(program).split("/")[-1]
    input_argument = ""
    runtime_lib_path = definitions.DIRECTORY_LIB + "/libtrident_runtime.bca"
    for argument in argument_list:
        if "$POC" in argument:
            argument = values.FILE_POC_GEN
        #     if "_" in argument:
        #         file_index = "_".join(str(argument).split("_")[1:])
        #         argument = values.LIST_TEST_FILES[file_index]
        #     else:
        #         argument = values.CONF_PATH_POC
        #         if values.FILE_POC_GEN:
        #             argument = values.FILE_POC_GEN
        input_argument += " " + str(argument)
    if output_dir:
        klee_command = "klee --output-dir=" + str(output_dir) + " "
    else:
        klee_command = "klee "
    klee_command += "--posix-runtime " \
                    "--libc=uclibc " \
                    "--search=dfs " \
                    "--write-smt2s " \
                    "--external-calls=all " \
                    "--max-forks {0} ".format(values.DEFAULT_MAX_FORK) \
                    + values.CONF_KLEE_FLAGS + " " \
                    + "--link-llvm-lib={0} ".format(runtime_lib_path) \
                    + "{0} ".format(binary_name) \
                    + input_argument
    if not print_output:
        klee_command += " > " + File_Log_Path + " 2>&1 "
    return_code = utilities.execute_command(klee_command)
    emitter.debug("changing directory:" + current_dir)
    os.chdir(current_dir)
    return return_code
Esempio n. 8
0
def build_normal():
    global CC, CXX, CXX_FLAGS, C_FLAGS, LD_FLAGS

    emitter.sub_title("Building Program")
    emitter.normal("\tsetting environment variables")
    execute_command("export TRIDENT_CC=" + definitions.DIRECTORY_TOOLS +
                    "/trident-cc")
    execute_command("export TRIDENT_CXX=" + definitions.DIRECTORY_TOOLS +
                    "/trident-cxx")

    clean_project(values.CONF_DIR_SRC, values.CONF_PATH_PROGRAM)
    CC = "$TRIDENT_CC"
    CXX = "$TRIDENT_CXX"
    C_FLAGS = "-g -O0"
    CXX_FLAGS = "-g -O0"
    config_project(values.CONF_DIR_SRC, False, values.CONF_COMMAND_CONFIG)
    C_FLAGS = ""
    LD_FLAGS = ""
    CXX_FLAGS = C_FLAGS
    if values.CONF_STATIC:
        C_FLAGS += " -static"
        CXX_FLAGS += " -static"
    build_project(values.CONF_DIR_SRC, values.CONF_COMMAND_BUILD)
Esempio n. 9
0
def generate_ktest(argument_list, second_var_list, print_output=False):
    """
    This function will generate the ktest file provided the argument list and second order variable list
        argument_list : a list containing each argument in the order that should be fed to the program
        second_var_list: a list of tuples where a tuple is (var identifier, var size, var value)
    """
    global File_Ktest_Path
    emitter.normal("\tgenerating ktest file")
    ktest_path = File_Ktest_Path
    ktest_command = "gen-bout --out-file {0}".format(ktest_path)

    for argument in argument_list:
        index = list(argument_list).index(argument)
        if "$POC" in argument:
            binary_file_path = values.FILE_POC_GEN
            # if "_" in argument:
            #     file_index = "_".join(str(argument).split("_")[1:])
            #     binary_file_path = values.LIST_TEST_FILES[file_index]
            # else:
            #     binary_file_path = values.CONF_PATH_POC
            #     if values.FILE_POC_GEN:
            #         binary_file_path = values.FILE_POC_GEN
            #     elif values.FILE_POC_SEED:
            #         binary_file_path = values.FILE_POC_SEED
            ktest_command += " --sym-file " + binary_file_path
        elif str(index) in values.CONF_MASK_ARG:
            continue
        else:
            if argument in ["''"]:
                argument = ""
            if "\"" in argument:
                ktest_command += " --sym-arg '" + str(argument) + "'"
                continue
            ktest_command += " --sym-arg \"" + str(argument) + "\""

    for var in second_var_list:
        ktest_command += " --second-var \'{0}\' {1} {2}".format(
            var['identifier'], var['size'], var['value'])
    return_code = utilities.execute_command(ktest_command)
    return ktest_path, return_code
Esempio n. 10
0
def run_concolic_execution(program,
                           argument_list,
                           second_var_list,
                           print_output=False,
                           klee_out_dir=None):
    """
    This function will execute the program in concolic mode using the generated ktest file
        program: the absolute path of the bitcode of the program
        argument_list : a list containing each argument in the order that should be fed to the program
        second_var_list: a list of tuples where a tuple is (var identifier, var size, var value)
    """
    logger.info("running concolic execution")

    global File_Log_Path
    current_dir = os.getcwd()
    directory_path = "/".join(str(program).split("/")[:-1])
    emitter.debug("changing directory:" + directory_path)
    project_path = values.CONF_DIR_SRC
    os.chdir(directory_path)
    binary_name = str(program).split("/")[-1]
    input_argument = ""
    # argument_list = str(argument_str).split(" ")
    for argument in argument_list:
        index = list(argument_list).index(argument)
        if "$POC" in argument:
            file_path = values.FILE_POC_GEN
            # if "_" in argument:
            #     file_index = "_".join(str(argument).split("_")[1:])
            #     file_path = values.LIST_TEST_FILES[file_index]
            # else:
            #     file_path = values.CONF_PATH_POC
            #     if values.FILE_POC_GEN:
            #         file_path = values.FILE_POC_GEN
            #     elif values.FILE_POC_SEED:
            #         file_path = values.FILE_POC_SEED
            concrete_file = open(file_path, 'rb')
            bit_size = os.fstat(concrete_file.fileno()).st_size
            input_argument += " A --sym-files 1 " + str(bit_size) + " "
        elif str(index) in values.CONF_MASK_ARG:
            input_argument += " " + argument
        else:
            input_argument += " --sym-arg " + str(len(str(argument)))
    ktest_path, return_code = generator.generate_ktest(argument_list,
                                                       second_var_list)
    ktest_log_file = "/tmp/ktest.log"
    ktest_command = "ktest-tool " + ktest_path + " > " + ktest_log_file
    utilities.execute_command(ktest_command)
    bit_length_list = reader.read_bit_length(ktest_log_file)
    if values.LIST_BIT_LENGTH:
        for var in bit_length_list:
            if var in values.LIST_BIT_LENGTH:
                if values.LIST_BIT_LENGTH[var] < bit_length_list[var]:
                    values.LIST_BIT_LENGTH[var] = bit_length_list[var]
            else:
                values.LIST_BIT_LENGTH[var] = bit_length_list[var]
    else:
        values.LIST_BIT_LENGTH = bit_length_list
    emitter.normal("\texecuting klee in concolic mode")
    # hit_location_flag = " "
    runtime_lib_path = definitions.DIRECTORY_LIB + "/libtrident_runtime.bca"
    # if values.CONF_DISTANCE_METRIC == "control-loc":
    hit_location_flag = "--hit-locations " + values.CONF_LOC_BUG + "," + values.CONF_LOC_PATCH
    if values.CONF_LOC_LIST_CRASH:
        crash_locations = ', '.join(
            ['{}'.format(loc) for loc in values.CONF_LOC_LIST_CRASH])
        hit_location_flag += "," + crash_locations + " "
    else:
        hit_location_flag += " "
    ppc_log_flag = ""
    if values.DEFAULT_DISTANCE_METRIC != values.OPTIONS_DIST_METRIC[2]:
        ppc_log_flag = "--log-ppc "

    klee_command = "timeout " + str(values.DEFAULT_TIMEOUT_KLEE_CONCOLIC) + " "
    if klee_out_dir:
        klee_command += "klee --output-dir=" + str(klee_out_dir) + " "
        values.KLEE_LAST_DIR = klee_out_dir
    else:
        klee_command += "klee "
    klee_command += "--posix-runtime " \
                    "--libc=uclibc " \
                    "--write-smt2s " \
                    "-allow-seed-extension " \
                    "-named-seed-matching " \
                    "--log-trace " \
                    + "--external-calls=all " \
                    + "--link-llvm-lib={0} " .format(runtime_lib_path) \
                    + "--max-time={0} ".format(values.DEFAULT_TIMEOUT_KLEE_CONCOLIC) \
                    + "{0}".format(ppc_log_flag) \
                    + "{0}".format(hit_location_flag) \
                    + "--max-forks {0} ".format(values.DEFAULT_MAX_FORK) \
                    + values.CONF_KLEE_FLAGS + " " \
                    + "--seed-out={0} ".format(ktest_path) \
                    + "{0} ".format(binary_name) \
                    + input_argument
    if not print_output:
        klee_command += " > " + File_Log_Path + " 2>&1 "
    return_code = utilities.execute_command(klee_command)
    emitter.debug("changing directory:" + current_dir)
    os.chdir(current_dir)

    # collect artifacts
    ppc_log_path = klee_out_dir + "/ppc.log"
    trace_log_path = klee_out_dir + "/trace.log"
    if values.DEFAULT_DISTANCE_METRIC != values.OPTIONS_DIST_METRIC[2]:
        ppc_list, path_formula = reader.collect_symbolic_path(
            ppc_log_path, project_path)
        values.LIST_PPC = values.LIST_PPC = ppc_list
        values.LAST_PPC_FORMULA = path_formula
        values.PREFIX_PPC_STR = reader.collect_symbolic_path_prefix(
            ppc_log_path, project_path)
    else:
        values.LAST_PPC_FORMULA = extractor.extract_largest_path_condition(
            klee_out_dir)
        if values.LAST_PPC_FORMULA:
            ppc_list = generator.generate_ppc_from_formula(
                values.LAST_PPC_FORMULA)
            values.LIST_PPC = values.LIST_PPC + ppc_list
        # else:
        #     values.LIST_PPC = []
    values.PREFIX_PPC_FORMULA = generator.generate_formula(
        values.PREFIX_PPC_STR)
    values.LIST_TRACE = reader.collect_trace(trace_log_path, project_path)
    if oracle.is_loc_in_trace(values.CONF_LOC_BUG) and oracle.is_loc_in_trace(
            values.CONF_LOC_PATCH):
        if values.DEFAULT_DISTANCE_METRIC != values.OPTIONS_DIST_METRIC[2]:
            values.NEGATED_PPC_FORMULA = generator.generate_path_for_negation()
        else:
            if values.LAST_PPC_FORMULA:
                values.NEGATED_PPC_FORMULA = generator.generate_negated_path(
                    values.LAST_PPC_FORMULA)
    else:
        values.NEGATED_PPC_FORMULA = None
    return return_code
Esempio n. 11
0
def config_project(project_path, is_llvm, custom_config_command=None):
    emitter.normal("\tconfiguring program")
    dir_command = "cd " + project_path + ";"

    config_command = None
    if custom_config_command is not None:
        if custom_config_command == "skip":
            emitter.warning("\t[warning] skipping configuration")
            return
        else:
            if os.path.exists(project_path + "/" + "aclocal.m4"):
                pre_config_command = "rm aclocal.m4;aclocal"
                execute_command(pre_config_command)

            if CC == "wllvm":
                custom_config_command = remove_fsanitize(custom_config_command)
                if "cmake" in custom_config_command:
                    custom_config_command = custom_config_command.replace(
                        "clang", "wllvm")
                    custom_config_command = custom_config_command.replace(
                        "clang++", "wllvm++")
                # print(custom_config_command)
            # config_command = "CC=" + CC + " "
            # config_command += "CXX=" + CXX + " "
            config_command = custom_config_command
            if "--cc=" in config_command:
                config_command = config_command.replace(
                    "--cc=clang-7", "--cc=" + CC)
            # print(config_command)

    elif os.path.exists(project_path + "/autogen.sh"):
        config_command = "./autogen.sh;"
        config_command += "CC=" + CC + " "
        config_command += "CXX=" + CXX + " "
        config_command += "./configure "
        config_command += "CFLAGS=\"" + C_FLAGS + "\" "
        config_command += "CXXFLAGS=\"" + CXX_FLAGS + "\""

    elif os.path.exists(project_path + "/configure.ac"):
        config_command = "autoreconf -i;"
        config_command += "CC=" + CC + " "
        config_command += "CXX=" + CXX + " "
        config_command += "./configure "
        config_command += "CFLAGS=\"" + C_FLAGS + "\" "
        config_command += "CXXFLAGS=\"" + CXX_FLAGS + "\""

    elif os.path.exists(project_path + "/configure.in"):
        config_command = "autoreconf -i;"
        config_command += "CC=" + CC + " "
        config_command += "CXX=" + CXX + " "
        config_command += "./configure "
        config_command += "CFLAGS=\"" + C_FLAGS + "\" "
        config_command += "CXXFLAGS=\"" + CXX_FLAGS + "\""

    elif os.path.exists(project_path + "/configure"):
        config_command = "CC=" + CC + " "
        config_command += "CXX=" + CXX + " "
        config_command += "./configure "
        config_command += "CFLAGS=\"" + C_FLAGS + "\" "
        config_command += "CXXFLAGS=\"" + CXX_FLAGS + "\""

    elif os.path.exists(project_path + "/CMakeLists.txt"):
        config_command = "cmake -DCMAKE_C_COMPILER=" + CC + " "
        config_command += "-DCMAKE_CPP_COMPILER=" + CXX + " "
        config_command += "-DCMAKE_C_FLAGS=\"" + C_FLAGS + "\" "
        config_command += "-DCMAKE_CXX_FLAGS=\"" + CXX_FLAGS + "\" . "

    if is_llvm:
        config_command = "LLVM_COMPILER=clang;" + config_command

    if not config_command:
        error_exit("[Not Found] Configuration Command")

    config_command = dir_command + config_command
    ret_code = execute_command(config_command)
    if int(ret_code) != 0:
        emitter.error(config_command)
        error_exit("CONFIGURATION FAILED!!\nExit Code: " + str(ret_code))