# 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
# def show_info():
# def verify_samples(num_threads, samples, target_cmd, timeout_secs=60):
# def remove_samples(crash_samples, quiet=True):
# def build_target_cmd(target_cmdline):
# def main(argv):
# 
# 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/AflPrettyPrint.py
# class clr:
#     # taken from AFL's debug.h
#     BLK = "\x1b[0;30m"
#     RED = "\x1b[0;31m"
#     GRN = "\x1b[0;32m"
#     BRN = "\x1b[0;33m"
#     BLU = "\x1b[0;34m"
#     MGN = "\x1b[0;35m"
#     CYA = "\x1b[0;36m"
#     NOR = "\x1b[0;37m"
#     GRA = "\x1b[1;30m"
#     LRD = "\x1b[1;31m"
#     LGN = "\x1b[1;32m"
#     YEL = "\x1b[1;33m"
#     LBL = "\x1b[1;34m"
#     PIN = "\x1b[1;35m"
#     LCY = "\x1b[1;36m"
#     BRI = "\x1b[1;37m"
#     RST = "\x1b[0m"
# 
# def print_ok(msg_str):
#     print("{0}[*] {1}{2}".format(clr.LGN, clr.RST, msg_str))
# 
# def print_warn(msg_str):
#     print("{0}[!] {1}{2}".format(clr.YEL, clr.RST, msg_str))
# 
# def print_err(msg_str):
#     print("{0}[!] {1}{2}".format(clr.LRD, clr.RST, msg_str))


import argparse
import os
import shutil
import subprocess
import sys
import threading
import time
import queue
import afl_utils
from afl_utils import afl_collect, afl_vcrash, AflThread
from afl_utils.AflPrettyPrint import clr, print_ok, print_warn, print_err
                        help="Collect all samples from the synchronisation dir and store them in the collection dir.",
                        default=None)
    parser.add_argument("--cmin", dest="invoke_cmin", action="store_const", const=True,
                        default=False, help="Run afl-cmin on collection dir. Has no effect without '-c'.")
    parser.add_argument("--cmin-mem-limit", dest="cmin_mem_limit", default=None, help="Set memory limit for afl-cmin.")
    parser.add_argument("--cmin-timeout", dest="cmin_timeout", default=None, help="Set timeout for afl-cmin.")
    parser.add_argument("--cmin-qemu", dest="cmin_qemu", default=False, action="store_const", const=True,
                        help="Enable qemu mode afl-cmin.")
    parser.add_argument("--reseed", dest="reseed", default=False, action="store_const", const=True, help="Reseed afl-fuzz with the \
collected (and optimized) corpus. This replaces all sync_dir queues with the newly generated corpus.")
    parser.add_argument("--tmin", dest="invoke_tmin", action="store_const", const=True,
                        default=False, help="Run afl-tmin on minimized collection dir if used together with '--cmin'\
or on unoptimized collection dir otherwise. Has no effect without '-c'.")
    parser.add_argument("--tmin-mem-limit", dest="tmin_mem_limit", default=None, help="Set memory limit for afl-tmin.")
    parser.add_argument("--tmin-timeout", dest="tmin_timeout", default=None, help="Set timeout for afl-tmin.")
    parser.add_argument("--tmin-qemu", dest="tmin_qemu", default=False, action="store_const", const=True,
                        help="Enable qemu mode afl-tmin.")
    parser.add_argument("-d", "--dry-run", dest="dry_run", action="store_const", const=True,
                        default=False, help="Perform dry-run on collection dir, if '-c' is provided or on \
synchronisation dir otherwise. Dry-run will move intermittent crashes out of the corpus.")
    parser.add_argument("-j", "--threads", dest="num_threads", default=1,
                        help="Enable parallel dry-run and t-minimization step by specifying the number of threads \
afl-minimize will utilize.")
    parser.add_argument("sync_dir", help="afl synchronisation directory containing multiple fuzzers and their queues.")
    parser.add_argument("target_cmd", nargs="+", help="Path to the target binary and its command line arguments. \
Use '@@' to specify crash sample input file position (see afl-fuzz usage).")

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

    if not args.collection_dir and not args.dry_run:

# 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
# def show_info():
# def verify_samples(num_threads, samples, target_cmd, timeout_secs=60):
# def remove_samples(crash_samples, quiet=True):
# def build_target_cmd(target_cmdline):
# def main(argv):
# 
# 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/AflPrettyPrint.py
# class clr:
#     # taken from AFL's debug.h
#     BLK = "\x1b[0;30m"
#     RED = "\x1b[0;31m"
#     GRN = "\x1b[0;32m"
#     BRN = "\x1b[0;33m"
#     BLU = "\x1b[0;34m"
#     MGN = "\x1b[0;35m"
#     CYA = "\x1b[0;36m"
#     NOR = "\x1b[0;37m"
#     GRA = "\x1b[1;30m"
#     LRD = "\x1b[1;31m"
#     LGN = "\x1b[1;32m"
#     YEL = "\x1b[1;33m"
#     LBL = "\x1b[1;34m"
#     PIN = "\x1b[1;35m"
#     LCY = "\x1b[1;36m"
#     BRI = "\x1b[1;37m"
#     RST = "\x1b[0m"
# 
# def print_ok(msg_str):
#     print("{0}[*] {1}{2}".format(clr.LGN, clr.RST, msg_str))
# 
# def print_warn(msg_str):
#     print("{0}[!] {1}{2}".format(clr.YEL, clr.RST, msg_str))
# 
# def print_err(msg_str):
#     print("{0}[!] {1}{2}".format(clr.LRD, clr.RST, msg_str))


# Path: afl_utils/afl_minimize.py
import argparse
import os
import shutil
import subprocess
import sys
import threading
import time
import queue
import afl_utils
from afl_utils import afl_collect, afl_vcrash, AflThread
from afl_utils.AflPrettyPrint import clr, print_ok, print_warn, print_err

                        help="Collect all samples from the synchronisation dir and store them in the collection dir.",
                        default=None)
    parser.add_argument("--cmin", dest="invoke_cmin", action="store_const", const=True,
                        default=False, help="Run afl-cmin on collection dir. Has no effect without '-c'.")
    parser.add_argument("--cmin-mem-limit", dest="cmin_mem_limit", default=None, help="Set memory limit for afl-cmin.")
    parser.add_argument("--cmin-timeout", dest="cmin_timeout", default=None, help="Set timeout for afl-cmin.")
    parser.add_argument("--cmin-qemu", dest="cmin_qemu", default=False, action="store_const", const=True,
                        help="Enable qemu mode afl-cmin.")
    parser.add_argument("--reseed", dest="reseed", default=False, action="store_const", const=True, help="Reseed afl-fuzz with the \
collected (and optimized) corpus. This replaces all sync_dir queues with the newly generated corpus.")
    parser.add_argument("--tmin", dest="invoke_tmin", action="store_const", const=True,
                        default=False, help="Run afl-tmin on minimized collection dir if used together with '--cmin'\
or on unoptimized collection dir otherwise. Has no effect without '-c'.")
    parser.add_argument("--tmin-mem-limit", dest="tmin_mem_limit", default=None, help="Set memory limit for afl-tmin.")
    parser.add_argument("--tmin-timeout", dest="tmin_timeout", default=None, help="Set timeout for afl-tmin.")
    parser.add_argument("--tmin-qemu", dest="tmin_qemu", default=False, action="store_const", const=True,
                        help="Enable qemu mode afl-tmin.")
    parser.add_argument("-d", "--dry-run", dest="dry_run", action="store_const", const=True,
                        default=False, help="Perform dry-run on collection dir, if '-c' is provided or on \
synchronisation dir otherwise. Dry-run will move intermittent crashes out of the corpus.")
    parser.add_argument("-j", "--threads", dest="num_threads", default=1,
                        help="Enable parallel dry-run and t-minimization step by specifying the number of threads \
afl-minimize will utilize.")
    parser.add_argument("sync_dir", help="afl synchronisation directory containing multiple fuzzers and their queues.")
    parser.add_argument("target_cmd", nargs="+", help="Path to the target binary and its command line arguments. \
Use '@@' to specify crash sample input file position (see afl-fuzz usage).")

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

    if not args.collection_dir and not args.dry_run:

        print_err("No operation requested. You should at least provide '-c'")