|
|
|
@ -408,7 +408,7 @@ static void shuffle_ptrs(void** ptrs, u32 cnt) {
|
|
|
|
|
|
|
|
|
|
/* Build a list of processes bound to specific cores. Returns -1 if nothing
|
|
|
|
|
can be found. Assumes an upper bound of 4k CPUs. */
|
|
|
|
|
|
|
|
|
|
//绑定到空闲CPU核心。如果可能,这个函数会将AFL的进程绑定到一个空闲的CPU核心上,以减少上下文切换和调度延迟。
|
|
|
|
|
static void bind_to_free_cpu(void) {
|
|
|
|
|
|
|
|
|
|
DIR* d;
|
|
|
|
@ -722,7 +722,7 @@ static u8* DTD(u64 cur_ms, u64 event_ms) {
|
|
|
|
|
/* Mark deterministic checks as done for a particular queue entry. We use the
|
|
|
|
|
.state file to avoid repeating deterministic fuzzing when resuming aborted
|
|
|
|
|
scans. */
|
|
|
|
|
|
|
|
|
|
//mark_as_det_done 和 mark_as_variable共同用于标记测试用例的状态,用于标记测试用例是否已经完成了确定性的测试,或者是否表现出可变的行为。
|
|
|
|
|
static void mark_as_det_done(struct queue_entry* q) {
|
|
|
|
|
|
|
|
|
|
u8* fn = strrchr(q->fname, '/');
|
|
|
|
@ -838,7 +838,7 @@ static void add_to_queue(u8* fname, u32 len, u8 passed_det) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Destroy the entire queue. */
|
|
|
|
|
|
|
|
|
|
//销毁队列的函数。它释放与测试用例队列相关的所有内存资源。
|
|
|
|
|
EXP_ST void destroy_queue(void) {
|
|
|
|
|
|
|
|
|
|
struct queue_entry *q = queue, *n;
|
|
|
|
@ -903,7 +903,7 @@ EXP_ST void read_bitmap(u8* fname) {
|
|
|
|
|
|
|
|
|
|
This function is called after every exec() on a fairly large buffer, so
|
|
|
|
|
it needs to be fast. We do this in 32-bit and 64-bit flavors. */
|
|
|
|
|
|
|
|
|
|
//检查执行路径是否带来了新的位图信息。这有助于AFL确定一个测试用例是否探索了新的代码路径。
|
|
|
|
|
static inline u8 has_new_bits(u8* virgin_map) {
|
|
|
|
|
|
|
|
|
|
#ifdef WORD_SIZE_64
|
|
|
|
@ -976,7 +976,7 @@ static inline u8 has_new_bits(u8* virgin_map) {
|
|
|
|
|
|
|
|
|
|
/* Count the number of bits set in the provided bitmap. Used for the status
|
|
|
|
|
screen several times every second, does not have to be fast. */
|
|
|
|
|
|
|
|
|
|
//计算位图中设置的位数,用于评估测试用例的覆盖率。
|
|
|
|
|
static u32 count_bits(u8* mem) {
|
|
|
|
|
|
|
|
|
|
u32* ptr = (u32*)mem;
|
|
|
|
@ -1011,7 +1011,7 @@ static u32 count_bits(u8* mem) {
|
|
|
|
|
/* Count the number of bytes set in the bitmap. Called fairly sporadically,
|
|
|
|
|
mostly to update the status screen or calibrate and examine confirmed
|
|
|
|
|
new paths. */
|
|
|
|
|
|
|
|
|
|
//计算位图中设置的字节数,用于评估测试用例的覆盖率。
|
|
|
|
|
static u32 count_bytes(u8* mem) {
|
|
|
|
|
|
|
|
|
|
u32* ptr = (u32*)mem;
|
|
|
|
@ -1077,7 +1077,7 @@ static const u8 simplify_lookup[256] = {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#ifdef WORD_SIZE_64
|
|
|
|
|
|
|
|
|
|
//简化跟踪信息,处理执行跟踪数据,以便更高效地存储和比较。
|
|
|
|
|
static void simplify_trace(u64* mem) {
|
|
|
|
|
|
|
|
|
|
u32 i = MAP_SIZE >> 3;
|
|
|
|
@ -1156,7 +1156,7 @@ static const u8 count_class_lookup8[256] = {
|
|
|
|
|
|
|
|
|
|
static u16 count_class_lookup16[65536];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//初始化计数分类表。这个函数用于设置一个查找表,该表用于快速分类和处理执行跟踪数据。
|
|
|
|
|
EXP_ST void init_count_class16(void) {
|
|
|
|
|
|
|
|
|
|
u32 b1, b2;
|
|
|
|
@ -1171,7 +1171,7 @@ EXP_ST void init_count_class16(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef WORD_SIZE_64
|
|
|
|
|
|
|
|
|
|
//分类执行跟踪信息,处理执行跟踪数据,以便更高效地存储和比较。
|
|
|
|
|
static inline void classify_counts(u64* mem) {
|
|
|
|
|
|
|
|
|
|
u32 i = MAP_SIZE >> 3;
|
|
|
|
@ -1261,7 +1261,7 @@ static void minimize_bits(u8* dst, u8* src) {
|
|
|
|
|
The first step of the process is to maintain a list of top_rated[] entries
|
|
|
|
|
for every byte in the bitmap. We win that slot if there is no previous
|
|
|
|
|
contender, or if the contender has a more favorable speed x size factor. */
|
|
|
|
|
|
|
|
|
|
//更新位图分数的函数。它根据测试用例的执行时间和覆盖率来调整其在队列中的优先级。
|
|
|
|
|
static void update_bitmap_score(struct queue_entry* q) {
|
|
|
|
|
|
|
|
|
|
u32 i;
|
|
|
|
@ -1312,7 +1312,7 @@ static void update_bitmap_score(struct queue_entry* q) {
|
|
|
|
|
previously-unseen bytes (temp_v) and marks them as favored, at least
|
|
|
|
|
until the next run. The favored entries are given more air time during
|
|
|
|
|
all fuzzing steps. */
|
|
|
|
|
|
|
|
|
|
//筛选队列的函数。它通过评估队列中的测试用例,移除那些不再需要进一步测试的案例,以优化模糊测试的效率。
|
|
|
|
|
static void cull_queue(void) {
|
|
|
|
|
|
|
|
|
|
struct queue_entry* q;
|
|
|
|
@ -1367,7 +1367,7 @@ static void cull_queue(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Configure shared memory and virgin_bits. This is called at startup. */
|
|
|
|
|
|
|
|
|
|
//设置共享内存。共享内存用于存储位图和其他状态信息,这些信息在目标程序的多个实例之间共享。
|
|
|
|
|
EXP_ST void setup_shm(void) {
|
|
|
|
|
|
|
|
|
|
u8* shm_str;
|
|
|
|
@ -1430,7 +1430,7 @@ static void setup_post(void) {
|
|
|
|
|
|
|
|
|
|
/* Read all testcases from the input directory, then queue them for testing.
|
|
|
|
|
Called at startup. */
|
|
|
|
|
|
|
|
|
|
//从输入目录中读取所有测试用例,并将它们排队以供测试。
|
|
|
|
|
static void read_testcases(void) {
|
|
|
|
|
|
|
|
|
|
struct dirent **nl;
|
|
|
|
@ -1687,7 +1687,7 @@ static void load_extras_file(u8* fname, u32* min_len, u32* max_len,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Read extras from the extras directory and sort them by size. */
|
|
|
|
|
|
|
|
|
|
//加载额外的测试用例,处理从外部源加载额外的测试用例。
|
|
|
|
|
static void load_extras(u8* dir) {
|
|
|
|
|
|
|
|
|
|
DIR* d;
|
|
|
|
@ -1905,7 +1905,7 @@ sort_a_extras:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Save automatically generated extras. */
|
|
|
|
|
|
|
|
|
|
//保存额外的测试用例,保存在模糊测试过程中自动生成的测试用例。
|
|
|
|
|
static void save_auto(void) {
|
|
|
|
|
|
|
|
|
|
u32 i;
|
|
|
|
@ -1933,7 +1933,7 @@ static void save_auto(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Load automatically generated extras. */
|
|
|
|
|
|
|
|
|
|
// 用于加载自动生成的extras的函数。
|
|
|
|
|
static void load_auto(void) {
|
|
|
|
|
|
|
|
|
|
u32 i;
|
|
|
|
@ -1976,7 +1976,7 @@ static void load_auto(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Destroy extras. */
|
|
|
|
|
|
|
|
|
|
// 用于销毁extras的函数。
|
|
|
|
|
static void destroy_extras(void) {
|
|
|
|
|
|
|
|
|
|
u32 i;
|
|
|
|
@ -2001,7 +2001,7 @@ static void destroy_extras(void) {
|
|
|
|
|
In essence, the instrumentation allows us to skip execve(), and just keep
|
|
|
|
|
cloning a stopped child. So, we just execute once, and then send commands
|
|
|
|
|
through a pipe. The other part of this logic is in afl-as.h. */
|
|
|
|
|
|
|
|
|
|
//初始化fork服务器的函数。在AFL中,fork服务器是一种优化技术,它允许AFL避免频繁地执行execve()来启动目标程序。相反,它通过克隆一个已经执行的目标程序进程来实现。
|
|
|
|
|
EXP_ST void init_forkserver(char** argv) {
|
|
|
|
|
|
|
|
|
|
static struct itimerval it;
|
|
|
|
@ -2286,7 +2286,7 @@ EXP_ST void init_forkserver(char** argv) {
|
|
|
|
|
|
|
|
|
|
/* Execute target application, monitoring for timeouts. Return status
|
|
|
|
|
information. The called program will update trace_bits[]. */
|
|
|
|
|
|
|
|
|
|
//运行目标程序并监控超时。它负责启动目标程序,等待其执行完成,并捕获任何超时或崩溃。
|
|
|
|
|
static u8 run_target(char** argv, u32 timeout) {
|
|
|
|
|
|
|
|
|
|
static struct itimerval it;
|
|
|
|
@ -2504,7 +2504,7 @@ static u8 run_target(char** argv, u32 timeout) {
|
|
|
|
|
/* Write modified data to file for testing. If out_file is set, the old file
|
|
|
|
|
is unlinked and a new one is created. Otherwise, out_fd is rewound and
|
|
|
|
|
truncated. */
|
|
|
|
|
|
|
|
|
|
//将修改后的数据写入测试用例文件。如果指定了输出文件,则会创建一个新文件;否则,会重置并截断现有的输出文件描述符。
|
|
|
|
|
static void write_to_testcase(void* mem, u32 len) {
|
|
|
|
|
|
|
|
|
|
s32 fd = out_fd;
|
|
|
|
@ -2561,13 +2561,13 @@ static void write_with_gap(void* mem, u32 len, u32 skip_at, u32 skip_len) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//显示模糊测试的统计信息,如执行速度、发现的路径数量、唯一崩溃等。
|
|
|
|
|
static void show_stats(void);
|
|
|
|
|
|
|
|
|
|
/* Calibrate a new test case. This is done when processing the input directory
|
|
|
|
|
to warn about flaky or otherwise problematic test cases early on; and when
|
|
|
|
|
new paths are discovered to detect variable behavior and so on. */
|
|
|
|
|
|
|
|
|
|
//校准测试用例的函数。它执行目标程序多次,以确定测试用例的执行时间和覆盖率,这有助于确定测试用例的优先级。
|
|
|
|
|
static u8 calibrate_case(char** argv, struct queue_entry* q, u8* use_mem,
|
|
|
|
|
u32 handicap, u8 from_queue) {
|
|
|
|
|
|
|
|
|
@ -2722,7 +2722,7 @@ abort_calibration:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Examine map coverage. Called once, for first test case. */
|
|
|
|
|
|
|
|
|
|
//检查位图覆盖率。如果位图的覆盖率不足,这个函数会提醒用户可能需要重新编译目标程序以获得更好的覆盖率。
|
|
|
|
|
static void check_map_coverage(void) {
|
|
|
|
|
|
|
|
|
|
u32 i;
|
|
|
|
@ -2739,7 +2739,7 @@ static void check_map_coverage(void) {
|
|
|
|
|
|
|
|
|
|
/* Perform dry run of all test cases to confirm that the app is working as
|
|
|
|
|
expected. This is done only for the initial inputs, and only once. */
|
|
|
|
|
|
|
|
|
|
//执行干运行。在正式开始模糊测试之前,这个函数用于验证目标程序的行为,确保它能够正确处理初始的测试用例集。
|
|
|
|
|
static void perform_dry_run(char** argv) {
|
|
|
|
|
|
|
|
|
|
struct queue_entry* q = queue;
|
|
|
|
@ -2971,7 +2971,7 @@ static void link_or_copy(u8* old_path, u8* new_path) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 用于删除用于即时会话恢复的临时目录的函数。
|
|
|
|
|
static void nuke_resume_dir(void);
|
|
|
|
|
|
|
|
|
|
/* Create hard links for input test cases in the output directory, choosing
|
|
|
|
@ -3417,7 +3417,7 @@ static void find_timeout(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Update stats file for unattended monitoring. */
|
|
|
|
|
|
|
|
|
|
// 用于更新统计文件的函数,用于无人值守的监控。
|
|
|
|
|
static void write_stats_file(double bitmap_cvg, double stability, double eps) {
|
|
|
|
|
|
|
|
|
|
static double last_bcvg, last_stab, last_eps;
|
|
|
|
@ -3516,7 +3516,7 @@ static void write_stats_file(double bitmap_cvg, double stability, double eps) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Update the plot file if there is a reason to. */
|
|
|
|
|
|
|
|
|
|
// 用于更新绘图文件的函数,如果有必要的话。
|
|
|
|
|
static void maybe_update_plot_file(double bitmap_cvg, double eps) {
|
|
|
|
|
|
|
|
|
|
static u32 prev_qp, prev_pf, prev_pnf, prev_ce, prev_md;
|
|
|
|
@ -3556,7 +3556,7 @@ static void maybe_update_plot_file(double bitmap_cvg, double eps) {
|
|
|
|
|
|
|
|
|
|
/* A helper function for maybe_delete_out_dir(), deleting all prefixed
|
|
|
|
|
files in a directory. */
|
|
|
|
|
|
|
|
|
|
// 用于删除所有以特定前缀开头的文件的辅助函数。
|
|
|
|
|
static u8 delete_files(u8* path, u8* prefix) {
|
|
|
|
|
|
|
|
|
|
DIR* d;
|
|
|
|
@ -3587,7 +3587,7 @@ static u8 delete_files(u8* path, u8* prefix) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Get the number of runnable processes, with some simple smoothing. */
|
|
|
|
|
|
|
|
|
|
// 用于获取可运行进程数量的函数,带有一定的简单平滑处理。
|
|
|
|
|
static double get_runnable_processes(void) {
|
|
|
|
|
|
|
|
|
|
static double res;
|
|
|
|
@ -3680,7 +3680,7 @@ dir_cleanup_failed:
|
|
|
|
|
|
|
|
|
|
/* Delete fuzzer output directory if we recognize it as ours, if the fuzzer
|
|
|
|
|
is not currently running, and if the last run time isn't too great. */
|
|
|
|
|
|
|
|
|
|
// 用于删除输出目录的函数,如果它被认为是我们的,并且fuzzer没有在运行,并且最后一次运行时间不是很长。
|
|
|
|
|
static void maybe_delete_out_dir(void) {
|
|
|
|
|
|
|
|
|
|
FILE* f;
|
|
|
|
@ -4646,7 +4646,7 @@ abort_trimming:
|
|
|
|
|
/* Write a modified test case, run program, process results. Handle
|
|
|
|
|
error conditions, returning 1 if it's time to bail out. This is
|
|
|
|
|
a helper function for fuzz_one(). */
|
|
|
|
|
|
|
|
|
|
//执行模糊测试的通用部分。它负责将变异后的测试用例写入文件,执行目标程序,并处理执行结果。
|
|
|
|
|
EXP_ST u8 common_fuzz_stuff(char** argv, u8* out_buf, u32 len) {
|
|
|
|
|
|
|
|
|
|
u8 fault;
|
|
|
|
@ -5000,6 +5000,7 @@ static u8 could_be_interest(u32 old_val, u32 new_val, u8 blen, u8 check_le) {
|
|
|
|
|
function is a tad too long... returns 0 if fuzzed successfully, 1 if
|
|
|
|
|
skipped or bailed out. */
|
|
|
|
|
|
|
|
|
|
// 执行一次模糊测试的函数。它接受一个测试用例,应用各种变异技术来生成新的测试用例,然后执行目标程序来检查新测试用例的效果。
|
|
|
|
|
static u8 fuzz_one(char** argv) {
|
|
|
|
|
|
|
|
|
|
s32 len, fd, temp_len, i, j;
|
|
|
|
@ -6691,7 +6692,7 @@ abandon_entry:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Grab interesting test cases from other fuzzers. */
|
|
|
|
|
|
|
|
|
|
//在分布式模糊测试中,这个函数用于同步不同fuzzer实例的进度。
|
|
|
|
|
static void sync_fuzzers(char** argv) {
|
|
|
|
|
|
|
|
|
|
DIR* sd;
|
|
|
|
@ -6829,7 +6830,7 @@ static void sync_fuzzers(char** argv) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Handle stop signal (Ctrl-C, etc). */
|
|
|
|
|
|
|
|
|
|
//处理停止信号(如Ctrl+C)的函数。它设置一个标志来告诉主循环停止执行。
|
|
|
|
|
static void handle_stop_sig(int sig) {
|
|
|
|
|
|
|
|
|
|
stop_soon = 1;
|
|
|
|
@ -6841,7 +6842,7 @@ static void handle_stop_sig(int sig) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Handle skip request (SIGUSR1). */
|
|
|
|
|
|
|
|
|
|
// 用于处理用户请求跳过当前输入的信号(SIGUSR1)的函数。
|
|
|
|
|
static void handle_skipreq(int sig) {
|
|
|
|
|
|
|
|
|
|
skip_requested = 1;
|
|
|
|
@ -6849,7 +6850,7 @@ static void handle_skipreq(int sig) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Handle timeout (SIGALRM). */
|
|
|
|
|
|
|
|
|
|
//处理超时信号的函数。它设置一个标志来指示目标程序已经超时。
|
|
|
|
|
static void handle_timeout(int sig) {
|
|
|
|
|
|
|
|
|
|
if (child_pid > 0) {
|
|
|
|
@ -6870,7 +6871,7 @@ static void handle_timeout(int sig) {
|
|
|
|
|
/* Do a PATH search and find target binary to see that it exists and
|
|
|
|
|
isn't a shell script - a common and painful mistake. We also check for
|
|
|
|
|
a valid ELF header and for evidence of AFL instrumentation. */
|
|
|
|
|
|
|
|
|
|
//检查目标二进制文件是否存在,是否可执行,以及是否具有AFL所需的 instrumentation( instrumentation是AFL用来追踪执行路径的一种技术)。
|
|
|
|
|
EXP_ST void check_binary(u8* fname) {
|
|
|
|
|
|
|
|
|
|
u8* env_path = 0;
|
|
|
|
@ -7067,7 +7068,7 @@ static void fix_up_banner(u8* name) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check if we're on TTY. */
|
|
|
|
|
|
|
|
|
|
//检查程序是否运行在TTY上。这个函数用于确定输出是否应该是交互式的,以及是否应该显示进度信息。
|
|
|
|
|
static void check_if_tty(void) {
|
|
|
|
|
|
|
|
|
|
struct winsize ws;
|
|
|
|
@ -7150,7 +7151,7 @@ static void usage(u8* argv0) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Prepare output directories and fds. */
|
|
|
|
|
|
|
|
|
|
//准备输出目录和文件描述符。它确保所有必要的目录都存在,并设置了一些文件描述符,以便在模糊测试过程中使用。
|
|
|
|
|
EXP_ST void setup_dirs_fds(void) {
|
|
|
|
|
|
|
|
|
|
u8* tmp;
|
|
|
|
@ -7273,7 +7274,7 @@ EXP_ST void setup_dirs_fds(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Setup the output file for fuzzed data, if not using -f. */
|
|
|
|
|
|
|
|
|
|
// 准备输出文件用于测试的函数。如果指定了输出文件,则会创建一个新文件;否则,会重置并截断现有的输出文件描述符。
|
|
|
|
|
EXP_ST void setup_stdio_file(void) {
|
|
|
|
|
|
|
|
|
|
u8* fn = alloc_printf("%s/.cur_input", out_dir);
|
|
|
|
@ -7356,7 +7357,7 @@ static void check_crash_handling(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check CPU governor. */
|
|
|
|
|
|
|
|
|
|
//检查CPU调速器设置的函数。确保CPU在高负载下不会降频,从而影响测试的执行速度。
|
|
|
|
|
static void check_cpu_governor(void) {
|
|
|
|
|
|
|
|
|
|
FILE* f;
|
|
|
|
@ -7412,7 +7413,7 @@ static void check_cpu_governor(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Count the number of logical CPU cores. */
|
|
|
|
|
|
|
|
|
|
//获取CPU核心数。这个函数用于确定系统中可用的CPU核心数,以便AFL可以有效地分配工作负载。
|
|
|
|
|
static void get_core_count(void) {
|
|
|
|
|
|
|
|
|
|
u32 cur_runnable = 0;
|
|
|
|
@ -7541,14 +7542,14 @@ static void fix_up_sync(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Handle screen resize (SIGWINCH). */
|
|
|
|
|
|
|
|
|
|
// 处理屏幕大小变化的信号处理函数。
|
|
|
|
|
static void handle_resize(int sig) {
|
|
|
|
|
clear_screen = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Check ASAN options. */
|
|
|
|
|
|
|
|
|
|
// 检查ASAN选项的函数。
|
|
|
|
|
static void check_asan_opts(void) {
|
|
|
|
|
u8* x = getenv("ASAN_OPTIONS");
|
|
|
|
|
|
|
|
|
@ -7579,7 +7580,7 @@ static void check_asan_opts(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Detect @@ in args. */
|
|
|
|
|
|
|
|
|
|
// 用于处理文件名中'@@'参数的函数。
|
|
|
|
|
EXP_ST void detect_file_args(char** argv) {
|
|
|
|
|
|
|
|
|
|
u32 i = 0;
|
|
|
|
@ -7628,7 +7629,7 @@ EXP_ST void detect_file_args(char** argv) {
|
|
|
|
|
/* Set up signal handlers. More complicated that needs to be, because libc on
|
|
|
|
|
Solaris doesn't resume interrupted reads(), sets SA_RESETHAND when you call
|
|
|
|
|
siginterrupt(), and does other unnecessary things. */
|
|
|
|
|
|
|
|
|
|
// 设置信号处理程序的函数。
|
|
|
|
|
EXP_ST void setup_signal_handlers(void) {
|
|
|
|
|
|
|
|
|
|
struct sigaction sa;
|
|
|
|
@ -7671,7 +7672,7 @@ EXP_ST void setup_signal_handlers(void) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Rewrite argv for QEMU. */
|
|
|
|
|
|
|
|
|
|
// 用于重写argv以用于QEMU的函数。
|
|
|
|
|
static char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
|
|
|
|
|
|
|
|
|
|
char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
|
|
|
|
@ -7774,7 +7775,7 @@ static void save_cmdline(u32 argc, char** argv) {
|
|
|
|
|
#ifndef AFL_LIB
|
|
|
|
|
|
|
|
|
|
/* Main entry point */
|
|
|
|
|
|
|
|
|
|
//程序的主入口点。它处理命令行参数,设置信号处理程序,初始化共享内存,读取测试用例,执行干运行以验证目标程序,然后进入主循环进行模糊测试。
|
|
|
|
|
int main(int argc, char** argv) {
|
|
|
|
|
|
|
|
|
|
s32 opt;
|
|
|
|
@ -8194,4 +8195,4 @@ stop_fuzzing:
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* !AFL_LIB */
|
|
|
|
|
#endif /* !AFL_LIB */
|