commit on Dec31st 1914

林睿健_branch
LRJ 3 months ago
parent 281f185cab
commit 9582ee8012

@ -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

Loading…
Cancel
Save