# Path: afl_utils/AflThread.py
# class VerifyThread(threading.Thread):
# class GdbThread(threading.Thread):
# class AflTminThread(threading.Thread):
#     def __init__(self, thread_id, timeout_secs, target_cmd, in_queue, out_queue, in_queue_lock, out_queue_lock):
#     def run(self):
#     def __init__(self, thread_id, gdb_cmd, out_dir, grep_for, out_queue, out_queue_lock):
#     def run(self):
#     def __init__(self, thread_id, tmin_cmd, target_cmd, output_dir, in_queue, out_queue, in_queue_lock, out_queue_lock):
#     def run(self):
# 
# Path: afl_utils/afl_collect.py
# def show_info():
# def get_fuzzer_instances(sync_dir, crash_dirs=True):
# def get_crash_directories(sync_dir, fuzzer_instances):
# def get_queue_directories(sync_dir, fuzzer_instances):
# def get_samples_from_dir(sample_subdir, abs_path=False):
# def collect_samples(sync_dir, fuzzer_instances):
# def build_sample_index(sync_dir, out_dir, fuzzer_instances, db=None, min_filename=False, omit_fuzzer_name=False):
# def copy_samples(sample_index):
# def generate_sample_list(list_filename, files_collected):
# def stdin_mode(target_cmd):
# def generate_gdb_exploitable_script(script_filename, sample_index, target_cmd, script_id=0, intermediate=False):
# def execute_gdb_script(out_dir, script_filename, num_samples, num_threads):
# def main(argv):


import argparse
import os
import queue
import sys
import threading
import afl_utils
from afl_utils import AflThread, afl_collect
from afl_utils.AflPrettyPrint import *
def main(argv):
    show_info()

    parser = argparse.ArgumentParser(description="afl-vcrash verifies that afl-fuzz crash samples lead to crashes in \
the target binary.", usage="afl-vcrash [-f LIST_FILENAME] [-h] [-j THREADS] [-q] [-r] [-t TIMEOUT] collection_dir -- target_command")

    parser.add_argument("collection_dir",
                        help="Directory holding all crash samples that will be verified.")
    parser.add_argument("target_cmd", nargs="+", help="Target binary including command line \
options. Use '@@' to specify crash sample input file position (see afl-fuzz usage).")
    parser.add_argument("-f", "--filelist", dest="list_filename", default=None,
                        help="Writes all crash sample file names that do not lead to crashes into a file.")
    parser.add_argument("-j", "--threads", dest="num_threads", default=1,
                        help="Enable parallel verification by specifying the number of threads afl-vcrash \
will utilize.")
    parser.add_argument("-q", "--quiet", dest="quiet", action="store_const", const=True, default=False,
                        help="Suppress output of crash sample file names that do not lead to crashes. This is \
particularly useful when combined with '-r' or '-f'.")
    parser.add_argument("-r", "--remove", dest="remove", action="store_const", const=True, default=False,
                        help="Remove crash samples that do not lead to crashes.")
    parser.add_argument("-t", "--timeout", dest="timeout_secs", default=60,
                        help="Define the timeout in seconds before killing the verification of a crash sample")

    args = parser.parse_args(argv[1:])

    input_dir = os.path.abspath(os.path.expanduser(args.collection_dir))
    if not os.path.exists(input_dir):
        print_err("No valid directory provided for <collection_dir>!")
        sys.exit(1)


# Path: afl_utils/AflThread.py
# class VerifyThread(threading.Thread):
# class GdbThread(threading.Thread):
# class AflTminThread(threading.Thread):
#     def __init__(self, thread_id, timeout_secs, target_cmd, in_queue, out_queue, in_queue_lock, out_queue_lock):
#     def run(self):
#     def __init__(self, thread_id, gdb_cmd, out_dir, grep_for, out_queue, out_queue_lock):
#     def run(self):
#     def __init__(self, thread_id, tmin_cmd, target_cmd, output_dir, in_queue, out_queue, in_queue_lock, out_queue_lock):
#     def run(self):
# 
# Path: afl_utils/afl_collect.py
# def show_info():
# def get_fuzzer_instances(sync_dir, crash_dirs=True):
# def get_crash_directories(sync_dir, fuzzer_instances):
# def get_queue_directories(sync_dir, fuzzer_instances):
# def get_samples_from_dir(sample_subdir, abs_path=False):
# def collect_samples(sync_dir, fuzzer_instances):
# def build_sample_index(sync_dir, out_dir, fuzzer_instances, db=None, min_filename=False, omit_fuzzer_name=False):
# def copy_samples(sample_index):
# def generate_sample_list(list_filename, files_collected):
# def stdin_mode(target_cmd):
# def generate_gdb_exploitable_script(script_filename, sample_index, target_cmd, script_id=0, intermediate=False):
# def execute_gdb_script(out_dir, script_filename, num_samples, num_threads):
# def main(argv):


# Path: afl_utils/afl_vcrash.py
import argparse
import os
import queue
import sys
import threading
import afl_utils
from afl_utils import AflThread, afl_collect
from afl_utils.AflPrettyPrint import *

def main(argv):
    show_info()

    parser = argparse.ArgumentParser(description="afl-vcrash verifies that afl-fuzz crash samples lead to crashes in \
the target binary.", usage="afl-vcrash [-f LIST_FILENAME] [-h] [-j THREADS] [-q] [-r] [-t TIMEOUT] collection_dir -- target_command")

    parser.add_argument("collection_dir",
                        help="Directory holding all crash samples that will be verified.")
    parser.add_argument("target_cmd", nargs="+", help="Target binary including command line \
options. Use '@@' to specify crash sample input file position (see afl-fuzz usage).")
    parser.add_argument("-f", "--filelist", dest="list_filename", default=None,
                        help="Writes all crash sample file names that do not lead to crashes into a file.")
    parser.add_argument("-j", "--threads", dest="num_threads", default=1,
                        help="Enable parallel verification by specifying the number of threads afl-vcrash \
will utilize.")
    parser.add_argument("-q", "--quiet", dest="quiet", action="store_const", const=True, default=False,
                        help="Suppress output of crash sample file names that do not lead to crashes. This is \
particularly useful when combined with '-r' or '-f'.")
    parser.add_argument("-r", "--remove", dest="remove", action="store_const", const=True, default=False,
                        help="Remove crash samples that do not lead to crashes.")
    parser.add_argument("-t", "--timeout", dest="timeout_secs", default=60,
                        help="Define the timeout in seconds before killing the verification of a crash sample")

    args = parser.parse_args(argv[1:])

    input_dir = os.path.abspath(os.path.expanduser(args.collection_dir))
    if not os.path.exists(input_dir):
        print_err("No valid directory provided for <collection_dir>!")
        sys.exit(1)


    num_crashes, crash_samples = afl_collect.get_samples_from_dir(input_dir, True)