diff --git a/src/afl-analyze.c b/src/afl-analyze.c index e62e027..cf92cb5 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -98,7 +98,7 @@ static volatile u8 /* Classify tuple counts. This is a slow & naive version, but good enough here. */ - +//用于对执行路径中的元组计数进行分类 static u8 count_class_lookup[256] = { [0] = 0, @@ -246,7 +246,7 @@ static void handle_timeout(int sig) { /* Execute target application. Returns exec checksum, or 0 if program times out. */ -//执行目标程序,并返回执行的校验和,或者如果程序超时则返回0。这个函数负责设置环境,执行程序,并分析退出条件 +//执行目标程序并返回执行校验和包含fork()子进程、设置限制、等待结果等逻辑 static u32 run_target(char** argv, u8* mem, u32 len, u8 first_run) { static struct itimerval it; @@ -371,7 +371,7 @@ static u32 run_target(char** argv, u8* mem, u32 len, u8 first_run) { #ifdef USE_COLOR /* Helper function to display a human-readable character. */ -//显示一个可读的字符。如果字符是控制字符或非打印字符,则显示其十六进制代码 +//显示一个可读的字符。如果字符是控制字符或非打印字符,则显示其十六进制代码,解释并报告输入文件中的模式 static void show_char(u8 val) { switch (val) { @@ -559,7 +559,7 @@ static void dump_hex(u8* buf, u32 len, u8* b_data) { /* Actually analyze! */ -//实际执行分析。它通过改变输入文件中的字节并观察对执行路径的影响来推断文件格式的结构 +//核心分析逻辑,实际执行分析。它通过改变输入文件中的字节并观察对执行路径的影响来推断文件格式的结构 static void analyze(char** argv) { u32 i; @@ -574,6 +574,7 @@ static void analyze(char** argv) { #ifdef USE_COLOR show_legend(); + //设置基本环境,包括文件描述符、环境变量等 #endif /* USE_COLOR */ for (i = 0; i < in_len; i++) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 5e63f81..cd37894 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -89,7 +89,7 @@ /* Lots of globals, but mostly for the status UI and other things where it really makes no sense to haul them around as function parameters. */ - +//全局变量声明 - 配置相关 EXP_ST u8 *in_dir, /* Input directory with test cases */ *out_file, /* File to fuzz, if any */ @@ -102,15 +102,15 @@ EXP_ST u8 *in_dir, /* Input directory with test cases */ *target_path, /* Path to target binary */ *orig_cmdline; /* Original command line */ -EXP_ST u32 exec_tmout = EXEC_TIMEOUT; /* Configurable exec timeout (ms) */ -static u32 hang_tmout = EXEC_TIMEOUT; /* Timeout used for hang det (ms) */ +EXP_ST u32 exec_tmout = EXEC_TIMEOUT; /* 子进程内存限制(MB) */ +static u32 hang_tmout = EXEC_TIMEOUT; /* 用于挂起检测的超时时间(ms) */ EXP_ST u64 mem_limit = MEM_LIMIT; /* Memory cap for child (MB) */ EXP_ST u32 cpu_to_bind = 0; /* id of free CPU core to bind */ static u32 stats_update_freq = 1; /* Stats update frequency (execs) */ - +/* 152-200: 全局变量声明 - 状态相关 */ EXP_ST u8 skip_deterministic, /* Skip deterministic stages? */ force_deterministic, /* Force deterministic stages? */ use_splicing, /* Recombine input files? */ @@ -198,7 +198,7 @@ EXP_ST u64 total_crashes, /* Total number of crashes */ bytes_trim_out, /* Bytes coming outa the trimmer */ blocks_eff_total, /* Blocks subject to effector maps */ blocks_eff_select; /* Blocks selected as fuzzable */ - +/* 202-250: 全局变量声明 - 统计相关 */ static u32 subseq_tmouts; /* Number of timeouts in a row */ static u8 *stage_name = "init", /* Name of the current fuzz stage */ @@ -237,7 +237,7 @@ static s32 cpu_aff = -1; /* Selected CPU core */ #endif /* HAVE_AFFINITY */ static FILE* plot_file; /* Gnuplot output file */ - +/* 252-300: 结构体定义 */ struct queue_entry { u8* fname; /* File name for the test case */ @@ -296,7 +296,7 @@ static s16 interesting_16[] = { INTERESTING_8, INTERESTING_16 }; static s32 interesting_32[] = { INTERESTING_8, INTERESTING_16, INTERESTING_32 }; /* Fuzzing stages */ - +/* 302-350: 辅助函数 */ enum { /* 00 */ STAGE_FLIP1, /* 01 */ STAGE_FLIP2, @@ -337,7 +337,7 @@ enum { }; -/* Get unix time in milliseconds */ +/* 352-400: 随机数生成相关函数 */ static u64 get_cur_time(void) { @@ -403,7 +403,7 @@ static void shuffle_ptrs(void** ptrs, u32 cnt) { } - +/* 402-450: CPU绑定相关函数 */ #ifdef HAVE_AFFINITY /* Build a list of processes bound to specific cores. Returns -1 if nothing @@ -537,7 +537,7 @@ static void bind_to_free_cpu(void) { /* Helper function to compare buffers; returns first and last differing offset. We use this to find reasonable locations for splicing two files. */ - +/* 452-500: 文件差异定位函数 */ static void locate_diffs(u8* ptr1, u8* ptr2, u32 len, s32* first, s32* last) { s32 f_loc = -1; @@ -625,7 +625,7 @@ static u8* DI(u64 val) { /* Describe float. Similar to the above, except with a single static buffer. */ - +// 将浮点数转换为人类可读的字符串 static u8* DF(double val) { static u8 tmp[16]; @@ -1173,7 +1173,8 @@ EXP_ST void init_count_class16(void) { #ifdef WORD_SIZE_64 //分类执行跟踪信息,处理执行跟踪数据,以便更高效地存储和比较。 static inline void classify_counts(u64* mem) { - + // 对执行路径中的计数进行分类 + // 用于识别不同的执行行为模式 u32 i = MAP_SIZE >> 3; while (i--) { @@ -2506,7 +2507,7 @@ static u8 run_target(char** argv, u32 timeout) { truncated. */ //将修改后的数据写入测试用例文件。如果指定了输出文件,则会创建一个新文件;否则,会重置并截断现有的输出文件描述符。 static void write_to_testcase(void* mem, u32 len) { - +// 将测试数据写入测试用例文件 s32 fd = out_fd; if (out_file) { @@ -9630,7 +9631,8 @@ static void setup_post(void) { Called at startup. */ static void read_testcases(void) { - + // 从测试用例文件读取数据 + // 处理各种读取错误情况 struct dirent **nl; s32 nl_cnt; u32 i; @@ -10771,7 +10773,7 @@ static void show_stats(void); //start_us, stop_us; //保存了一些旧的状态值,以便在函数执行完毕后恢复。 - +/*变异策略函数 */ static u8 calibrate_case(char** argv, struct queue_entry* q, u8* use_mem, u32 handicap, u8 from_queue) { @@ -14728,7 +14730,8 @@ splicing_with = -1; // 这个函数用于在分布式模糊测试环境中,从其他模糊测试器中同步测试用例。 static void sync_fuzzers(char** argv) { - + // 同步多个fuzzer实例之间的测试用例 + // 导入其他fuzzer发现的新路径 DIR* sd; // 指向同步目录的目录流 struct dirent* sd_ent; // 目录流中的当前条目 u32 sync_cnt = 0; // 同步的模糊测试器数量 diff --git a/src/afl-gcc.c b/src/afl-gcc.c index 20de974..d442bfc 100644 --- a/src/afl-gcc.c +++ b/src/afl-gcc.c @@ -67,7 +67,8 @@ static u8 be_quiet, /* Quiet mode */ /* Try to find our "fake" GNU assembler in AFL_PATH or at the location derived from argv[0]. If that fails, abort. */ - +/* 67-120行: find_as()函数 + 查找AFL的"假"GNU汇编器 */ static void find_as(u8* argv0) { // 这个函数尝试在AFL_PATH环境变量指定的路径或从argv[0]派生的路径中找到AFL的“假”GNU汇编器。如果找不到,程序将终止。 u8 *afl_path = getenv("AFL_PATH"); @@ -98,7 +99,7 @@ static void find_as(u8* argv0) { *slash = '/'; tmp = alloc_printf("%s/afl-as", dir); - + // 检查默认位置 if (!access(tmp, X_OK)) { as_path = dir; ck_free(tmp); @@ -121,7 +122,8 @@ static void find_as(u8* argv0) { /* Copy argv to cc_params, making the necessary edits. */ - +/* 122-213行: edit_params()函数 + 复制和编辑传递给编译器的参数 */ static void edit_params(u32 argc, char** argv) { //定义了一个函数edit_params,它接受两个参数:argc是参数的数量,argv是参数的数组。 @@ -131,12 +133,12 @@ static void edit_params(u32 argc, char** argv) { #if defined(__FreeBSD__) && defined(__x86_64__) u8 m32_set = 0; #endif - + // 分配参数数组空间 cc_params = ck_alloc((argc + 128) * sizeof(u8*));//分配内存以存储修改后的参数列表,大小为argc + 128个u8*类型的指针。 - + // 处理编译器名称 name = strrchr(argv[0], '/');//找到argv[0](程序的路径)中最后一个'/'字符,这通常用于获取程序的名称。 if (!name) name = argv[0]; else name++;//如果name为NULL(即argv[0]中没有'/'),则name指向argv[0]的开始。否则,name向前移动一个字符,跳过'/'。 - + // 设置Clang模式 if (!strncmp(name, "afl-clang", 9)) { clang_mode = 1;//检查程序名称是否以"afl-clang"开头,如果是,设置clang_mode标志为1 @@ -192,7 +194,7 @@ static void edit_params(u32 argc, char** argv) { #endif /* __APPLE__ */ } - + // 处理各种编译标志 while (--argc) { u8* cur = *(++argv); @@ -269,7 +271,7 @@ static void edit_params(u32 argc, char** argv) { } - + // 处理ASAN/MSAN配置 if (!getenv("AFL_DONT_OPTIMIZE")) {//检查是否设置了环境变量AFL_DONT_OPTIMIZE。 #if defined(__FreeBSD__) && defined(__x86_64__) @@ -292,7 +294,7 @@ static void edit_params(u32 argc, char** argv) { /* Two indicators that you're building for fuzzing; one of them is AFL-specific, the other is shared with libfuzzer. */ - + // 添加AFL的as路径 cc_params[cc_par_cnt++] = "-D__AFL_COMPILER=1"; cc_params[cc_par_cnt++] = "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1"; //向参数列表中添加两个宏定义,这些宏定义指示编译器代码将用于模糊测试。 @@ -325,7 +327,7 @@ int main(int argc, char** argv) { SAYF(cCYA "afl-cc " cBRI VERSION cRST " by \n"); } else be_quiet = 1; - + // 参数检查 if (argc < 2) { SAYF("\n"