diff --git a/src/AFLplusplus-stable/src/afl-tmin.c b/src/AFLplusplus-stable/src/afl-tmin.c index b4d4e07..fe5a3e7 100644 --- a/src/AFLplusplus-stable/src/afl-tmin.c +++ b/src/AFLplusplus-stable/src/afl-tmin.c @@ -898,186 +898,266 @@ static void usage(u8 *argv0) { 该函数会解析命令行参数,设置环境,执行测试用例最小化,并处理退出清理。 */ int main(int argc, char **argv_orig, char **envp) { - +//程序的主入口点,接收命令行参数和环境变量 s32 opt; + //用于存储getopt函数返回的当前选项字符。 u8 mem_limit_given = 0, timeout_given = 0, unicorn_mode = 0, use_wine = 0, del_limit_given = 0; + //定义了一些标志变量,用于记录是否已经设置了内存限制、超时时间、unicorn模式、wine模式和删除长度限制。 char **use_argv; - + //用于存储处理后的参数列表,可能会根据模式不同而进行修改。 char **argv = argv_cpy_dup(argc, argv_orig); - + //复制命令行参数,以便在解析选项时修改参数列表。 afl_forkserver_t fsrv_var = {0}; + //初始化一个afl_forkserver_t类型的变量,用于管理forkserver。 if (getenv("AFL_DEBUG")) { debug = 1; } fsrv = &fsrv_var; afl_fsrv_init(fsrv); map_size = get_map_size(); fsrv->map_size = map_size; - + //设置forkserver的共享内存区域大小。 doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; - + //尝试访问文档路径,如果不存在,则使用默认的“docs”路径。 SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n"); - + //打印程序的欢迎信息和版本号。 while ((opt = getopt(argc, argv, "+i:o:f:m:t:l:B:xeAOQUWXYHh")) > 0) { - + //循环处理命令行参数,getopt会解析短选项和长选项。 switch (opt) { - + //根据getopt返回的选项字符,执行相应的操作。 case 'i': - + //如果选项是'i',表示输入文件。 if (in_file) { FATAL("Multiple -i options not supported"); } + //检查是否已经设置了输入文件,如果设置了多次,则报错。 in_file = optarg; + //将输入文件的路径设置到in_file变量。 break; case 'o': + //如果选项是'o',表示输出文件。 if (output_file) { FATAL("Multiple -o options not supported"); } + //检查是否已经设置了输出文件,如果设置了多次,则报错。 output_file = optarg; + //将输出文件的路径设置到output_file变量。 break; case 'f': + //如果选项是'f',表示被测试程序读取的输入文件(标准输入)。 if (out_file) { FATAL("Multiple -f options not supported"); } + //检查是否已经设置了输入文件,如果设置了多次,则报错。 fsrv->use_stdin = 0; + //设置标志,表示不使用标准输入。 out_file = ck_strdup(optarg); + //复制输入文件的路径到out_file变量。 break; case 'e': + //如果选项是'e',表示仅考虑边缘覆盖,忽略命中次数。 if (edges_only) { FATAL("Multiple -e options not supported"); } + //检查是否已经设置了仅考虑边缘覆盖,如果设置了多次,则报错。 if (hang_mode) { + //检查是否已经设置了挂起模式,如果同时设置了仅考虑边缘覆盖和挂起模式,则报错。 FATAL("Edges only and hang mode are mutually exclusive."); + //报错,因为仅考虑边缘覆盖和挂起模式不能同时设置。 } edges_only = 1; + //设置标志,表示仅考虑边缘覆盖。 break; case 'x': + //如果选项是'x',表示将非零退出代码视为崩溃。 if (exit_crash) { FATAL("Multiple -x options not supported"); } + //检查是否已经设置了将非零退出代码视为崩溃,如果设置了多次,则报错。 exit_crash = 1; + //设置标志,表示将非零退出代码视为崩溃。 break; case 'm': { + //如果选项是'm',表示设置子进程的内存限制。 + //使用花括号创建一个新的作用域,用于存储局部变量。 u8 suffix = 'M'; + //定义一个变量suffix,默认值为'M',表示内存单位是兆字节。 if (mem_limit_given) { FATAL("Multiple -m options not supported"); } + //检查是否已经设置了内存限制,如果设置了多次,则报错。 mem_limit_given = 1; + //设置标志,表示已经设置了内存限制。 if (!optarg) { FATAL("Wrong usage of -m"); } + //检查是否提供了内存限制的参数,如果没有提供,则报错。 if (!strcmp(optarg, "none")) { + //检查参数是否是“none”,表示不设置内存限制。 fsrv->mem_limit = 0; + //设置内存限制为0。 break; + //跳出内存限制设置。 } + //结束内存限制设置的条件判断。 if (sscanf(optarg, "%llu%c", &fsrv->mem_limit, &suffix) < 1 || optarg[0] == '-') { + //尝试解析内存限制的参数,如果解析失败或参数以负号开头,则报错。 FATAL("Bad syntax used for -m"); + //报错,因为内存限制的参数语法不正确。 } + //结束内存限制设置的条件判断。 switch (suffix) { + //根据解析出的后缀,转换内存限制的单位。 case 'T': fsrv->mem_limit *= 1024 * 1024; break; + //如果后缀是'T',表示内存限制的单位是太字节,转换为兆字节。 case 'G': fsrv->mem_limit *= 1024; break; + //如果后缀是'G',表示内存限制的单位是吉字节,转换为兆字节。 case 'k': fsrv->mem_limit /= 1024; break; + //如果后缀是'k',表示内存限制的单位是千字节,转换为兆字节。 case 'M': break; + //如果后缀是'M',表示内存限制的单位是兆字节,不需要转换。 default: FATAL("Unsupported suffix or bad syntax for -m"); + //如果后缀不支持或语法错误,则报错。 } + //结束单位转换的switch语句。 if (fsrv->mem_limit < 5) { FATAL("Dangerously low value of -m"); } + //检查内存限制是否过低,如果低于5兆字节,则报错。 if (sizeof(rlim_t) == 4 && fsrv->mem_limit > 2000) { + //检查在32位系统上,内存限制是否过高,如果超过2000兆字节,则报错。 FATAL("Value of -m out of range on 32-bit systems"); + //报错,因为32位系统上内存限制过高。 } + //结束内存限制设置。 } + //结束内存限制设置的局部作用域。 break; + //结束'm'选项的处理。 case 't': + //如果选项是't',表示设置每次运行的超时时间。 if (timeout_given) { FATAL("Multiple -t options not supported"); } + //检查是否已经设置了超时时间,如果设置了多次,则报错。 timeout_given = 1; + //设置标志,表示已经设置了超时时间。 if (!optarg) { FATAL("Wrong usage of -t"); } + //检查是否提供了超时时间的参数,如果没有提供,则报错。 fsrv->exec_tmout = atoi(optarg); - + //将超时时间的参数转换为整数,并设置到fsrv->exec_tmout。 if (fsrv->exec_tmout < 10 || optarg[0] == '-') { + //检查超时时间是否过低或参数以负号开头,如果是,则报错。 FATAL("Dangerously low value of -t"); + //报错,因为超时时间过低。 } + //结束超时时间设置的条件判断。 break; + //结束't'选项的处理。 case 'A': /* CoreSight mode */ + //如果选项是'A',表示使用ARM CoreSight模式。 #if !defined(__aarch64__) || !defined(__linux__) FATAL("-A option is not supported on this platform"); #endif +//检查是否在支持的平台上,如果不是,则报错。 if (fsrv->cs_mode) { FATAL("Multiple -A options not supported"); } +//检查是否已经设置了CoreSight模式,如果设置了多次,则报错。 fsrv->cs_mode = 1; + //设置标志,表示使用CoreSight模式。 break; + //结束'A'选项的处理。 case 'O': /* FRIDA mode */ + //如果选项是'O',表示使用FRIDA模式。 if (fsrv->frida_mode) { FATAL("Multiple -O options not supported"); } - + //检查是否已经设置了FRIDA模式,如果设置了多次,则报错。 fsrv->frida_mode = 1; + //设置标志,表示使用FRIDA模式。 setenv("AFL_FRIDA_INST_SEED", "1", 1); + //设置环境变量,用于FRIDA模式。 break; + //结束'O'选项的处理。 case 'Q': + //如果选项是'Q',表示使用QEMU模式。 if (fsrv->qemu_mode) { FATAL("Multiple -Q options not supported"); } + //检查是否已经设置了QEMU模式,如果设置了多次,则报错。 if (!mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_QEMU; } + //如果未设置内存限制,则使用QEMU模式的默认内存限制。 fsrv->qemu_mode = 1; + //设置标志,表示使用QEMU模式。 break; + //结束'Q'选项的处理。 case 'U': + //如果选项是'U',表示使用Unicorn模式。 if (unicorn_mode) { FATAL("Multiple -Q options not supported"); } + //检查是否已经设置了Unicorn模式,如果设置了多次,则报错。 if (!mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_UNICORN; } + //如果未设置内存限制,则使用Unicorn模式的默认内存限制。 unicorn_mode = 1; + //设置标志,表示使用Unicorn模式。 break; + //结束'U'选项的处理。 case 'W': /* Wine+QEMU mode */ + //如果选项是'W',表示使用Wine+QEMU模式。 if (use_wine) { FATAL("Multiple -W options not supported"); } + //检查是否已经设置了Wine+QEMU模式,如果设置了多次,则报错。 fsrv->qemu_mode = 1; + //设置标志,表示使用QEMU模式。 use_wine = 1; + //设置标志,表示使用Wine。 if (!mem_limit_given) { fsrv->mem_limit = 0; } + //如果未设置内存限制,则设置为0。 break; + //结束'W'选项的处理。 case 'Y': // fallthough #ifdef __linux__ case 'X': /* NYX mode */ + // if (fsrv->nyx_mode) { FATAL("Multiple -X options not supported"); } @@ -1088,6 +1168,7 @@ int main(int argc, char **argv_orig, char **envp) { break; #else case 'X': + //如果选项是'X',表示使用Nyx模式。 FATAL("Nyx mode is only availabe on linux..."); break; #endif