add afl-fuzz.c comment about function main

dev-suhongye
Satori5ama 9 months ago
parent 3d48adf43c
commit 03730ec4cc

@ -7775,6 +7775,7 @@ static void save_cmdline(u32 argc, char** argv) {
/* Main entry point */
// 主函数,程序的入口点
int main(int argc, char** argv) {
s32 opt;
@ -7788,94 +7789,114 @@ int main(int argc, char** argv) {
struct timeval tv;
struct timezone tz;
SAYF(cCYA "afl-fuzz " cBRI VERSION cRST " by <lcamtuf@google.com>\n");
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
gettimeofday(&tv, &tz);
srandom(tv.tv_sec ^ tv.tv_usec ^ getpid());
// argv 处理
while ((opt = getopt(argc, argv, "+i:o:f:m:b:t:T:dnCB:S:M:x:QV")) > 0)
switch (opt) {
case 'i': /* input dir */
// 初始 corpus 目录
if (in_dir) FATAL("Multiple -i options not supported");
in_dir = optarg;
// 若使用 "-i -",则表示 in-place resume
if (!strcmp(in_dir, "-")) in_place_resume = 1;
break;
case 'o': /* output dir */
if (out_dir) FATAL("Multiple -o options not supported");
out_dir = optarg;
break;
case 'M': { /* master sync ID */
u8* c;
if (sync_id) FATAL("Multiple -S or -M options not supported");
sync_id = ck_strdup(optarg);
if ((c = strchr(sync_id, ':'))) {
*c = 0;
if (sscanf(c + 1, "%u/%u", &master_id, &master_max) != 2 ||
!master_id || !master_max || master_id > master_max ||
master_max > 1000000) FATAL("Bogus master ID passed to -M");
SAYF(cCYA "afl-fuzz " cBRI VERSION cRST " by <lcamtuf@google.com>\n");
}
/***************************************************************
* /:
* : ID
***************************************************************/
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
gettimeofday(&tv, &tz);
srandom(tv.tv_sec ^ tv.tv_usec ^ getpid());
// argv 处理
while ((opt = getopt(argc, argv, "+i:o:f:m:b:t:T:dnCB:S:M:x:QV")) > 0)
switch (opt) {
case 'i': /* input dir */
// 初始 corpus 目录
if (in_dir) FATAL("Multiple -i options not supported");
in_dir = optarg;
// 若使用 "-i -",则表示 in-place resume
if (!strcmp(in_dir, "-")) in_place_resume = 1;
break;
/* 处理输出目录的命令行选项 */
case 'o': /* output dir */
if (out_dir) FATAL("Multiple -o options not supported");
out_dir = optarg;
break;
case 'M': { /* master sync ID */
// 处理选项 'M',用于设定主同步 ID
u8* c;
if (sync_id) FATAL("Multiple -S or -M options not supported");
sync_id = ck_strdup(optarg);
if ((c = strchr(sync_id, ':'))) {
// 解析同步ID中的主ID和最大ID
*c = 0;
if (sscanf(c + 1, "%u/%u", &master_id, &master_max) != 2 ||
!master_id || !master_max || master_id > master_max ||
master_max > 1000000) FATAL("Bogus master ID passed to -M");
}
force_deterministic = 1;
// 强制使用确定性执行
}
force_deterministic = 1;
}
break;
case 'S':
if (sync_id) FATAL("Multiple -S or -M options not supported");
sync_id = ck_strdup(optarg);
break;
case 'f': /* target file */
if (out_file) FATAL("Multiple -f options not supported");
out_file = optarg;
break;
case 'x': /* dictionary */
if (extras_dir) FATAL("Multiple -x options not supported");
extras_dir = optarg;
break;
case 't': { /* timeout */
u8 suffix = 0;
if (timeout_given) FATAL("Multiple -t options not supported");
if (sscanf(optarg, "%u%c", &exec_tmout, &suffix) < 1 ||
optarg[0] == '-') FATAL("Bad syntax used for -t");
if (exec_tmout < 5) FATAL("Dangerously low value of -t");
if (suffix == '+') timeout_given = 2; else timeout_given = 1;
break;
}
// 处理-S选项的代码逻辑
/************************************************************************************
* ID *
* FATAL *
************************************************************************************/
case 'S':
if (sync_id) FATAL("Multiple -S or -M options not supported");
sync_id = ck_strdup(optarg);
break;
case 'f': /* target file */
if (out_file) FATAL("Multiple -f options not supported");
out_file = optarg;
break;
case 'x': /* dictionary */
if (extras_dir) FATAL("Multiple -x options not supported");
extras_dir = optarg;
break;
/**************************************
*
* -t
**************************************/
case 't': { /* timeout */
u8 suffix = 0;
if (timeout_given) FATAL("Multiple -t options not supported");
if (sscanf(optarg, "%u%c", &exec_tmout, &suffix) < 1 ||
optarg[0] == '-') FATAL("Bad syntax used for -t");
if (exec_tmout < 5) FATAL("Dangerously low value of -t");
if (suffix == '+') timeout_given = 2; else timeout_given = 1;
break;
}
case 'm': { /* mem limit */
// 处理内存限制选项的相关逻辑
u8 suffix = 'M';
@ -7883,15 +7904,16 @@ int main(int argc, char** argv) {
mem_limit_given = 1;
if (!strcmp(optarg, "none")) {
// 如果选项参数为"none"则将内存限制设置为0
mem_limit = 0;
break;
}
// 解析命令行参数,获取内存限制和单位后缀
if (sscanf(optarg, "%llu%c", &mem_limit, &suffix) < 1 ||
optarg[0] == '-') FATAL("Bad syntax used for -m");
// 根据单位后缀调整内存限制的值
switch (suffix) {
case 'T': mem_limit *= 1024 * 1024; break;
@ -7903,8 +7925,10 @@ int main(int argc, char** argv) {
}
// 检查内存限制值是否低于安全阈值
if (mem_limit < 5) FATAL("Dangerously low value of -m");
// 在32位系统上检查内存限制的范围
if (sizeof(rlim_t) == 4 && mem_limit > 2000)
FATAL("Value of -m out of range on 32-bit systems");
@ -7913,10 +7937,11 @@ int main(int argc, char** argv) {
break;
case 'b': { /* bind CPU core */
// 处理 CPU 绑定选项,确保只能使用一次
if (cpu_to_bind_given) FATAL("Multiple -b options not supported");
cpu_to_bind_given = 1;
// 解析用户输入的 CPU 核心编号,检查输入合法性
if (sscanf(optarg, "%u", &cpu_to_bind) < 1 ||
optarg[0] == '-') FATAL("Bad syntax used for -b");
@ -7924,6 +7949,7 @@ int main(int argc, char** argv) {
}
/* 处理命令行参数,选择跳过确定性测试的选项 */
case 'd': /* skip deterministic */
if (skip_deterministic) FATAL("Multiple -d options not supported");
@ -7932,24 +7958,19 @@ int main(int argc, char** argv) {
break;
case 'B': /* load bitmap */
/* This is a secret undocumented option! It is useful if you find
an interesting test case during a normal fuzzing process, and want
to mutate it without rediscovering any of the test cases already
found during an earlier run.
To use this mode, you need to point -B to the fuzz_bitmap produced
by an earlier run for the exact same binary... and that's it.
I only used this once or twice to get variants of a particular
file, so I'm not making this an official setting. */
/*
使 -B fuzz_bitmap
使
*/
if (in_bitmap) FATAL("Multiple -B options not supported");
in_bitmap = optarg;
read_bitmap(in_bitmap);
break;
/* 处理命令行参数选项 'C',用于设置崩溃模式 */
case 'C': /* crash mode */
if (crash_mode) FATAL("Multiple -C options not supported");
@ -7957,27 +7978,34 @@ int main(int argc, char** argv) {
break;
case 'n': /* dumb mode */
// 处理-dumb模式的选项当程序收到'-n'时触发
if (dumb_mode) FATAL("Multiple -n options not supported");
if (getenv("AFL_DUMB_FORKSRV")) dumb_mode = 2; else dumb_mode = 1;
break;
/* 处理命令行选项 */
case 'T': /* banner */
/* 检查是否支持多个 -T 选项 */
if (use_banner) FATAL("Multiple -T options not supported");
use_banner = optarg;
break;
// 处理QEMU模式的代码段
// 如果启用QEMU模式检查是否已指定多个-Q选项
// 如果未指定内存限制则使用默认的QEMU内存限制
// 在处理完成后退出switch语句
case 'Q': /* QEMU mode */
if (qemu_mode) FATAL("Multiple -Q options not supported");
qemu_mode = 1;
if (!mem_limit_given) mem_limit = MEM_LIMIT_QEMU;
break;
case 'Q': /* QEMU mode */
if (qemu_mode) FATAL("Multiple -Q options not supported");
qemu_mode = 1;
if (!mem_limit_given) mem_limit = MEM_LIMIT_QEMU;
break;
/* 处理选项 'V' 的情况,显示版本号 */
case 'V': /* Show version number */
/* Version number has been printed already, just quit. */
@ -7989,44 +8017,57 @@ int main(int argc, char** argv) {
}
if (optind == argc || !in_dir || !out_dir) usage(argv[0]);
setup_signal_handlers();
check_asan_opts();
if (sync_id) fix_up_sync();
if (!strcmp(in_dir, out_dir))
FATAL("Input and output directories can't be the same");
if (dumb_mode) {
if (crash_mode) FATAL("-C and -n are mutually exclusive");
if (qemu_mode) FATAL("-Q and -n are mutually exclusive");
}
if (getenv("AFL_NO_FORKSRV")) no_forkserver = 1;
if (getenv("AFL_NO_CPU_RED")) no_cpu_meter_red = 1;
if (getenv("AFL_NO_ARITH")) no_arith = 1;
if (getenv("AFL_SHUFFLE_QUEUE")) shuffle_queue = 1;
if (getenv("AFL_FAST_CAL")) fast_cal = 1;
if (getenv("AFL_HANG_TMOUT")) {
hang_tmout = atoi(getenv("AFL_HANG_TMOUT"));
if (!hang_tmout) FATAL("Invalid value of AFL_HANG_TMOUT");
}
if (dumb_mode == 2 && no_forkserver)
FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
// 检查命令行参数以及输入输出目录是否有效,若无效则显示使用方法
if (optind == argc || !in_dir || !out_dir) usage(argv[0]);
// 设置信号处理函数
setup_signal_handlers();
// 检查地址卫生选项
check_asan_opts();
// 处理同步ID和目录检查的逻辑
// 该段代码主要用于验证输入输出目录及模式的有效性
// 在不同的运行模式下进行相应的错误处理
if (sync_id) fix_up_sync();
if (!strcmp(in_dir, out_dir))
FATAL("Input and output directories can't be the same");
if (dumb_mode) {
if (crash_mode) FATAL("-C and -n are mutually exclusive");
if (qemu_mode) FATAL("-Q and -n are mutually exclusive");
}
if (getenv("AFL_PRELOAD")) {
setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
}
// 该代码段用于读取环境变量并根据其值设置相应的标志和超时值
// 主要功能是启动时配置这些参数以调整程序的行为
if (getenv("AFL_NO_FORKSRV")) no_forkserver = 1;
if (getenv("AFL_NO_CPU_RED")) no_cpu_meter_red = 1;
if (getenv("AFL_NO_ARITH")) no_arith = 1;
if (getenv("AFL_SHUFFLE_QUEUE")) shuffle_queue = 1;
if (getenv("AFL_FAST_CAL")) fast_cal = 1;
if (getenv("AFL_HANG_TMOUT")) {
hang_tmout = atoi(getenv("AFL_HANG_TMOUT"));
if (!hang_tmout) FATAL("Invalid value of AFL_HANG_TMOUT");
}
if (getenv("AFL_LD_PRELOAD"))
FATAL("Use AFL_PRELOAD instead of AFL_LD_PRELOAD");
// 此函数用于检查环境变量和启动模式的合法性
// 如果在不支持的模式下使用互斥选项,则会引发致命错误
// 处理环境变量以确保正确的库加载
if (dumb_mode == 2 && no_forkserver)
FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
if (getenv("AFL_PRELOAD")) {
setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1);
setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1);
}
if (getenv("AFL_LD_PRELOAD"))
FATAL("Use AFL_PRELOAD instead of AFL_LD_PRELOAD");
save_cmdline(argc, argv);
@ -8037,6 +8078,7 @@ int main(int argc, char** argv) {
get_core_count();
#ifdef HAVE_AFFINITY
// 将当前进程绑定到一个空闲的CPU上以优化性能
bind_to_free_cpu();
#endif /* HAVE_AFFINITY */

Loading…
Cancel
Save