diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c11a806..d22d88d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -5542,390 +5542,414 @@ skip_bitflip: } + // 计算新命中计数,是排队路径和唯一崩溃的总和 new_hit_cnt = queued_paths + unique_crashes; + // 更新当前阶段的发现计数和周期 stage_finds[STAGE_ARITH8] += new_hit_cnt - orig_hit_cnt; stage_cycles[STAGE_ARITH8] += stage_max; - /* 16-bit arithmetics, both endians. */ + /* 16位算术运算,支持两种字节序。 */ + // 如果长度小于2,跳过算术操作 if (len < 2) goto skip_arith; + // 设置当前阶段的名称与短名称 stage_name = "arith 16/8"; stage_short = "arith16"; - stage_cur = 0; - stage_max = 4 * (len - 1) * ARITH_MAX; + stage_cur = 0; // 当前计数器初始化为0 + stage_max = 4 * (len - 1) * ARITH_MAX; // 最大操作数计算 + // 保存原始的命中计数 orig_hit_cnt = new_hit_cnt; + // 遍历每个字节,进行算术操作 for (i = 0; i < len - 1; i++) { + // 读取当前字节和下一个字节作为16位数 u16 orig = *(u16*)(out_buf + i); - /* Let's consult the effector map... */ - + // 查看效应映射表 if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) { - stage_max -= 4 * ARITH_MAX; - continue; + stage_max -= 4 * ARITH_MAX; // 减少最大值 + continue; // 继续下一次循环 } + // 当前操作的字节索引 stage_cur_byte = i; + // 尝试进行加法和减法操作 for (j = 1; j <= ARITH_MAX; j++) { + // 进行加法和异或操作 u16 r1 = orig ^ (orig + j), r2 = orig ^ (orig - j), r3 = orig ^ SWAP16(SWAP16(orig) + j), r4 = orig ^ SWAP16(SWAP16(orig) - j); - /* Try little endian addition and subtraction first. Do it only - if the operation would affect more than one byte (hence the - & 0xff overflow checks) and if it couldn't be a product of - a bitflip. */ - + // 尝试小端加法 stage_val_type = STAGE_VAL_LE; + // 判断加法是否溢出,并且结果不应该是位翻转 if ((orig & 0xff) + j > 0xff && !could_be_bitflip(r1)) { + stage_cur_val = j; // 设置当前值为j + *(u16*)(out_buf + i) = orig + j; // 更新输出缓冲区 - stage_cur_val = j; - *(u16*)(out_buf + i) = orig + j; - + // 执行模糊测试 if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; - - } else stage_max--; + stage_cur++; // 成功计数 - if ((orig & 0xff) < j && !could_be_bitflip(r2)) { + } else stage_max--; // 若不成功,则减少最大周期 - stage_cur_val = -j; - *(u16*)(out_buf + i) = orig - j; + // 尝试小端减法 + if ((orig & 0xff) < j && !could_be_bitflip(r2)) { + stage_cur_val = -j; // 设置当前值为-j + *(u16*)(out_buf + i) = orig - j; // 更新输出缓冲区 + // 执行模糊测试 if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; + stage_cur++; // 成功计数 - } else stage_max--; - - /* Big endian comes next. Same deal. */ + } else stage_max--; // 若不成功,则减少最大周期 + // 尝试大端加法 stage_val_type = STAGE_VAL_BE; - + // 判断加法是否溢出,并且结果不应该是位翻转 if ((orig >> 8) + j > 0xff && !could_be_bitflip(r3)) { + stage_cur_val = j; // 设置当前值为j + *(u16*)(out_buf + i) = SWAP16(SWAP16(orig) + j); // 更新输出缓冲区 - stage_cur_val = j; - *(u16*)(out_buf + i) = SWAP16(SWAP16(orig) + j); - + // 执行模糊测试 if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; + stage_cur++; // 成功计数 - } else stage_max--; + } else stage_max--; // 若不成功,则减少最大周期 + // 尝试大端减法 if ((orig >> 8) < j && !could_be_bitflip(r4)) { + stage_cur_val = -j; // 设置当前值为-j + *(u16*)(out_buf + i) = SWAP16(SWAP16(orig) - j); // 更新输出缓冲区 - stage_cur_val = -j; - *(u16*)(out_buf + i) = SWAP16(SWAP16(orig) - j); - + // 执行模糊测试 if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; + stage_cur++; // 成功计数 - } else stage_max--; + } else stage_max--; // 若不成功,则减少最大周期 + // 恢复原值 *(u16*)(out_buf + i) = orig; } } + // 更新命中计数 new_hit_cnt = queued_paths + unique_crashes; + // 更新当前阶段的发现计数和周期 stage_finds[STAGE_ARITH16] += new_hit_cnt - orig_hit_cnt; stage_cycles[STAGE_ARITH16] += stage_max; - /* 32-bit arithmetics, both endians. */ + /* 32位算术运算,支持两种字节序。 */ + // 如果长度小于4,跳过算术操作 if (len < 4) goto skip_arith; + // 设置当前阶段的名称与短名称 stage_name = "arith 32/8"; stage_short = "arith32"; - stage_cur = 0; - stage_max = 4 * (len - 3) * ARITH_MAX; + stage_cur = 0; // 当前计数器初始化为0 + stage_max = 4 * (len - 3) * ARITH_MAX; // 最大操作数计算 + // 保存原始的命中计数 orig_hit_cnt = new_hit_cnt; + // 遍历每个字节,进行算术操作 for (i = 0; i < len - 3; i++) { + // 读取当前字节和接下来三个字节作为32位数 u32 orig = *(u32*)(out_buf + i); - /* Let's consult the effector map... */ - + // 查看效应映射表 if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] && !eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) { - stage_max -= 4 * ARITH_MAX; - continue; + stage_max -= 4 * ARITH_MAX; // 减少最大值 + continue; // 继续下一次循环 } + // 当前操作的字节索引 stage_cur_byte = i; + // 尝试进行加法和减法操作 for (j = 1; j <= ARITH_MAX; j++) { + // 进行加法和异或操作 u32 r1 = orig ^ (orig + j), r2 = orig ^ (orig - j), r3 = orig ^ SWAP32(SWAP32(orig) + j), r4 = orig ^ SWAP32(SWAP32(orig) - j); - /* Little endian first. Same deal as with 16-bit: we only want to - try if the operation would have effect on more than two bytes. */ - + // 尝试小端加法 stage_val_type = STAGE_VAL_LE; + // 判断加法是否溢出,并且结果不应该是位翻转 if ((orig & 0xffff) + j > 0xffff && !could_be_bitflip(r1)) { - stage_cur_val = j; - *(u32*)(out_buf + i) = orig + j; + stage_cur_val = j; // 设置当前值为j + *(u32*)(out_buf + i) = orig + j; // 更新输出缓冲区 + // 执行模糊测试 if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; + stage_cur++; // 成功计数 - } else stage_max--; + } else stage_max--; // 若不成功,则减少最大周期 + // 尝试小端减法 if ((orig & 0xffff) < j && !could_be_bitflip(r2)) { - stage_cur_val = -j; - *(u32*)(out_buf + i) = orig - j; + stage_cur_val = -j; // 设置当前值为-j + *(u32*)(out_buf + i) = orig - j; // 更新输出缓冲区 + // 执行模糊测试 if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; + stage_cur++; // 成功计数 - } else stage_max--; - - /* Big endian next. */ + } else stage_max--; // 若不成功,则减少最大周期 + // 尝试大端加法 stage_val_type = STAGE_VAL_BE; + // 判断加法是否溢出,并且结果不应该是位翻转 if ((SWAP32(orig) & 0xffff) + j > 0xffff && !could_be_bitflip(r3)) { - stage_cur_val = j; - *(u32*)(out_buf + i) = SWAP32(SWAP32(orig) + j); + stage_cur_val = j; // 设置当前值为j + *(u32*)(out_buf + i) = SWAP32(SWAP32(orig) + j); // 更新输出缓冲区 + // 执行模糊测试 if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; + stage_cur++; // 成功计数 - } else stage_max--; + } else stage_max--; // 若不成功,则减少最大周期 + // 尝试大端减法 if ((SWAP32(orig) & 0xffff) < j && !could_be_bitflip(r4)) { - stage_cur_val = -j; - *(u32*)(out_buf + i) = SWAP32(SWAP32(orig) - j); + stage_cur_val = -j; // 设置当前值为-j + *(u32*)(out_buf + i) = SWAP32(SWAP32(orig) - j); // 更新输出缓冲区 + // 执行模糊测试 if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; + stage_cur++; // 成功计数 - } else stage_max--; + } else stage_max--; // 若不成功,则减少最大周期 + // 恢复原值 *(u32*)(out_buf + i) = orig; } } + // 更新命中计数 new_hit_cnt = queued_paths + unique_crashes; + // 更新当前阶段的发现计数和周期 stage_finds[STAGE_ARITH32] += new_hit_cnt - orig_hit_cnt; stage_cycles[STAGE_ARITH32] += stage_max; + skip_arith: /********************** * INTERESTING VALUES * **********************/ - stage_name = "interest 8/8"; - stage_short = "int8"; - stage_cur = 0; - stage_max = len * sizeof(interesting_8); + stage_name = "interest 8/8"; // 当前阶段名称:8位整数的有趣值 + stage_short = "int8"; // 当前阶段缩写 + stage_cur = 0; // 当前阶段计数器 + stage_max = len * sizeof(interesting_8); // 当前阶段最大操作次数 - stage_val_type = STAGE_VAL_LE; + stage_val_type = STAGE_VAL_LE; // 当前值类型:小端 - orig_hit_cnt = new_hit_cnt; + orig_hit_cnt = new_hit_cnt; // 记录原始命中计数 - /* Setting 8-bit integers. */ + /* 设置8位整数。 */ - for (i = 0; i < len; i++) { + for (i = 0; i < len; i++) { // 遍历输入缓冲区的每个字节 - u8 orig = out_buf[i]; + u8 orig = out_buf[i]; // 保存原始字节值 - /* Let's consult the effector map... */ + /* 咨询效应地图... */ - if (!eff_map[EFF_APOS(i)]) { - stage_max -= sizeof(interesting_8); - continue; + if (!eff_map[EFF_APOS(i)]) { // 如果当前字节位置没有效应 + stage_max -= sizeof(interesting_8); // 减少最大操作次数 + continue; // 跳过当前循环 } - stage_cur_byte = i; + stage_cur_byte = i; // 设置当前字节位置 - for (j = 0; j < sizeof(interesting_8); j++) { + for (j = 0; j < sizeof(interesting_8); j++) { // 遍历8位有趣值 - /* Skip if the value could be a product of bitflips or arithmetics. */ + /* 如果值可能是经过位翻转或算术操作的结果,则跳过。 */ - if (could_be_bitflip(orig ^ (u8)interesting_8[j]) || - could_be_arith(orig, (u8)interesting_8[j], 1)) { - stage_max--; - continue; + if (could_be_bitflip(orig ^ (u8)interesting_8[j]) || // 检查位翻转 + could_be_arith(orig, (u8)interesting_8[j], 1)) { // 检查算术 + stage_max--; // 减少最大操作次数 + continue; // 跳过当前循环 } - stage_cur_val = interesting_8[j]; - out_buf[i] = interesting_8[j]; + stage_cur_val = interesting_8[j]; // 设置当前值为有趣值 + out_buf[i] = interesting_8[j]; // 更新输出缓冲区 - if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; + if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; // 进行模糊测试,若失败则放弃当前条目 - out_buf[i] = orig; - stage_cur++; + out_buf[i] = orig; // 恢复原始字节 + stage_cur++; // 当前阶段计数器增加 } } - new_hit_cnt = queued_paths + unique_crashes; + new_hit_cnt = queued_paths + unique_crashes; // 更新新的命中计数 - stage_finds[STAGE_INTEREST8] += new_hit_cnt - orig_hit_cnt; - stage_cycles[STAGE_INTEREST8] += stage_max; + stage_finds[STAGE_INTEREST8] += new_hit_cnt - orig_hit_cnt; // 记录阶段发现的次数 + stage_cycles[STAGE_INTEREST8] += stage_max; // 更新阶段循环次数 - /* Setting 16-bit integers, both endians. */ + /* 设置16位整数,支持两种字节序。 */ - if (no_arith || len < 2) goto skip_interest; + if (no_arith || len < 2) goto skip_interest; // 如果禁止算术或长度小于2,跳过 - stage_name = "interest 16/8"; - stage_short = "int16"; - stage_cur = 0; - stage_max = 2 * (len - 1) * (sizeof(interesting_16) >> 1); + stage_name = "interest 16/8"; // 当前阶段名称:16位整数的有趣值 + stage_short = "int16"; // 当前阶段缩写 + stage_cur = 0; // 当前阶段计数器 + stage_max = 2 * (len - 1) * (sizeof(interesting_16) >> 1); // 最大操作次数 - orig_hit_cnt = new_hit_cnt; + orig_hit_cnt = new_hit_cnt; // 记录原始命中计数 - for (i = 0; i < len - 1; i++) { + for (i = 0; i < len - 1; i++) { // 遍历输入缓冲区的每两个字节 - u16 orig = *(u16*)(out_buf + i); + u16 orig = *(u16*)(out_buf + i); // 保存原始16位值 - /* Let's consult the effector map... */ + /* 咨询效应地图... */ - if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) { - stage_max -= sizeof(interesting_16); - continue; + if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) { // 如果两个字节位置没有效应 + stage_max -= sizeof(interesting_16); // 减少最大操作次数 + continue; // 跳过当前循环 } - stage_cur_byte = i; + stage_cur_byte = i; // 设置当前字节位置 - for (j = 0; j < sizeof(interesting_16) / 2; j++) { + for (j = 0; j < sizeof(interesting_16) / 2; j++) { // 遍历16位有趣值 - stage_cur_val = interesting_16[j]; + stage_cur_val = interesting_16[j]; // 设置当前值为有趣值 - /* Skip if this could be a product of a bitflip, arithmetics, - or single-byte interesting value insertion. */ + /* 如果这可能是位翻转、算术、或单字节有趣值插入的结果,则跳过。 */ - if (!could_be_bitflip(orig ^ (u16)interesting_16[j]) && - !could_be_arith(orig, (u16)interesting_16[j], 2) && - !could_be_interest(orig, (u16)interesting_16[j], 2, 0)) { + if (!could_be_bitflip(orig ^ (u16)interesting_16[j]) && // 检查位翻转 + !could_be_arith(orig, (u16)interesting_16[j], 2) && // 检查算术 + !could_be_interest(orig, (u16)interesting_16[j], 2, 0)) { // 检查有趣值插入 - stage_val_type = STAGE_VAL_LE; + stage_val_type = STAGE_VAL_LE; // 设置值类型为小端 - *(u16*)(out_buf + i) = interesting_16[j]; + *(u16*)(out_buf + i) = interesting_16[j]; // 更新输出缓冲区 - if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; + if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; // 进行模糊测试 + stage_cur++; // 当前阶段计数器增加 - } else stage_max--; + } else stage_max--; // 否则减少最大操作次数 - if ((u16)interesting_16[j] != SWAP16(interesting_16[j]) && - !could_be_bitflip(orig ^ SWAP16(interesting_16[j])) && - !could_be_arith(orig, SWAP16(interesting_16[j]), 2) && - !could_be_interest(orig, SWAP16(interesting_16[j]), 2, 1)) { + if ((u16)interesting_16[j] != SWAP16(interesting_16[j]) && // 检查是否需要交换字节 + !could_be_bitflip(orig ^ SWAP16(interesting_16[j])) && // 检查位翻转 + !could_be_arith(orig, SWAP16(interesting_16[j]), 2) && // 检查算术 + !could_be_interest(orig, SWAP16(interesting_16[j]), 2, 1)) { // 检查有趣值插入 - stage_val_type = STAGE_VAL_BE; + stage_val_type = STAGE_VAL_BE; // 设置值类型为大端 - *(u16*)(out_buf + i) = SWAP16(interesting_16[j]); - if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; + *(u16*)(out_buf + i) = SWAP16(interesting_16[j]); // 更新为交换字节的有趣值 + if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; // 进行模糊测试 + stage_cur++; // 当前阶段计数器增加 - } else stage_max--; + } else stage_max--; // 否则减少最大操作次数 } - *(u16*)(out_buf + i) = orig; + *(u16*)(out_buf + i) = orig; // 恢复原始16位值 } - new_hit_cnt = queued_paths + unique_crashes; + new_hit_cnt = queued_paths + unique_crashes; // 更新新的命中计数 - stage_finds[STAGE_INTEREST16] += new_hit_cnt - orig_hit_cnt; - stage_cycles[STAGE_INTEREST16] += stage_max; + stage_finds[STAGE_INTEREST16] += new_hit_cnt - orig_hit_cnt; // 记录阶段发现的次数 + stage_cycles[STAGE_INTEREST16] += stage_max; // 更新阶段循环次数 - if (len < 4) goto skip_interest; + if (len < 4) goto skip_interest; // 如果长度小于4,跳过 - /* Setting 32-bit integers, both endians. */ + /* 设置32位整数,支持两种字节序。 */ - stage_name = "interest 32/8"; - stage_short = "int32"; - stage_cur = 0; - stage_max = 2 * (len - 3) * (sizeof(interesting_32) >> 2); + stage_name = "interest 32/8"; // 当前阶段名称:32位整数的有趣值 + stage_short = "int32"; // 当前阶段缩写 + stage_cur = 0; // 当前阶段计数器 + stage_max = 2 * (len - 3) * (sizeof(interesting_32) >> 2); // 最大操作次数 - orig_hit_cnt = new_hit_cnt; + orig_hit_cnt = new_hit_cnt; // 记录原始命中计数 - for (i = 0; i < len - 3; i++) { + for (i = 0; i < len - 3; i++) { // 遍历输入缓冲区的每四个字节 - u32 orig = *(u32*)(out_buf + i); + u32 orig = *(u32*)(out_buf + i); // 保存原始32位值 - /* Let's consult the effector map... */ + /* 咨询效应地图... */ if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] && - !eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) { - stage_max -= sizeof(interesting_32) >> 1; - continue; + !eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) { // 如果四个字节位置没有效应 + stage_max -= sizeof(interesting_32) >> 1; // 减少最大操作次数 + continue; // 跳过当前循环 } - stage_cur_byte = i; + stage_cur_byte = i; // 设置当前字节位置 - for (j = 0; j < sizeof(interesting_32) / 4; j++) { + for (j = 0; j < sizeof(interesting_32) / 4; j++) { // 遍历32位有趣值 - stage_cur_val = interesting_32[j]; + stage_cur_val = interesting_32[j]; // 设置当前值为有趣值 - /* Skip if this could be a product of a bitflip, arithmetics, - or word interesting value insertion. */ + /* 如果这可能是位翻转、算术、或字有趣值插入的结果,则跳过。 */ - if (!could_be_bitflip(orig ^ (u32)interesting_32[j]) && - !could_be_arith(orig, interesting_32[j], 4) && - !could_be_interest(orig, interesting_32[j], 4, 0)) { + if (!could_be_bitflip(orig ^ (u32)interesting_32[j]) && // 检查位翻转 + !could_be_arith(orig, interesting_32[j], 4) && // 检查算术 + !could_be_interest(orig, interesting_32[j], 4, 0)) { // 检查有趣值插入 - stage_val_type = STAGE_VAL_LE; + stage_val_type = STAGE_VAL_LE; // 设置值类型为小端 - *(u32*)(out_buf + i) = interesting_32[j]; + *(u32*)(out_buf + i) = interesting_32[j]; // 更新输出缓冲区 - if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; + if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; // 进行模糊测试 + stage_cur++; // 当前阶段计数器增加 - } else stage_max--; + } else stage_max--; // 否则减少最大操作次数 - if ((u32)interesting_32[j] != SWAP32(interesting_32[j]) && - !could_be_bitflip(orig ^ SWAP32(interesting_32[j])) && - !could_be_arith(orig, SWAP32(interesting_32[j]), 4) && - !could_be_interest(orig, SWAP32(interesting_32[j]), 4, 1)) { + if ((u32)interesting_32[j] != SWAP32(interesting_32[j]) && // 检查是否需要交换字节 + !could_be_bitflip(orig ^ SWAP32(interesting_32[j])) && // 检查位翻转 + !could_be_arith(orig, SWAP32(interesting_32[j]), 4) && // 检查算术 + !could_be_interest(orig, SWAP32(interesting_32[j]), 4, 1)) { // 检查有趣值插入 - stage_val_type = STAGE_VAL_BE; + stage_val_type = STAGE_VAL_BE; // 设置值类型为大端 - *(u32*)(out_buf + i) = SWAP32(interesting_32[j]); - if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; - stage_cur++; + *(u32*)(out_buf + i) = SWAP32(interesting_32[j]); // 更新为交换字节的有趣值 + if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; // 进行模糊测试 + stage_cur++; // 当前阶段计数器增加 - } else stage_max--; + } else stage_max--; // 否则减少最大操作次数 } - *(u32*)(out_buf + i) = orig; + *(u32*)(out_buf + i) = orig; // 恢复原始32位值 } - new_hit_cnt = queued_paths + unique_crashes; + new_hit_cnt = queued_paths + unique_crashes; // 更新新的命中计数 - stage_finds[STAGE_INTEREST32] += new_hit_cnt - orig_hit_cnt; - stage_cycles[STAGE_INTEREST32] += stage_max; + stage_finds[STAGE_INTEREST32] += new_hit_cnt - orig_hit_cnt; // 记录阶段发现的次数 + stage_cycles[STAGE_INTEREST32] += stage_max; // 更新阶段循环次数 skip_interest: @@ -5933,161 +5957,210 @@ skip_interest: * DICTIONARY STUFF * ********************/ - if (!extras_cnt) goto skip_user_extras; + if (!extras_cnt) goto skip_user_extras; // 如果没有用户提供的额外数据,跳过用户额外数据的处理 /* Overwrite with user-supplied extras. */ - stage_name = "user extras (over)"; - stage_short = "ext_UO"; - stage_cur = 0; - stage_max = extras_cnt * len; + stage_name = "user extras (over)"; // 设置当前阶段的名称 + stage_short = "ext_UO"; // 设置当前阶段的简称 + stage_cur = 0; // 初始化当前阶段的计数器 + stage_max = extras_cnt * len; // 设置当前阶段的最大迭代次数 - stage_val_type = STAGE_VAL_NONE; + stage_val_type = STAGE_VAL_NONE; // 设置当前阶段的值类型为无 - orig_hit_cnt = new_hit_cnt; + orig_hit_cnt = new_hit_cnt; // 保存当前的命中计数 - for (i = 0; i < len; i++) { + for (i = 0; i < len; i++) { // 遍历输入缓冲区的每个字节 - u32 last_len = 0; + u32 last_len = 0; // 记录上一次写入的额外数据长度 - stage_cur_byte = i; + stage_cur_byte = i; // 设置当前处理的字节位置 /* Extras are sorted by size, from smallest to largest. This means that we don't have to worry about restoring the buffer in between writes at a particular offset determined by the outer loop. */ - for (j = 0; j < extras_cnt; j++) { + for (j = 0; j < extras_cnt; j++) { // 遍历所有用户提供的额外数据 /* Skip extras probabilistically if extras_cnt > MAX_DET_EXTRAS. Also skip them if there's no room to insert the payload, if the token is redundant, or if its entire span has no bytes set in the effector map. */ - if ((extras_cnt > MAX_DET_EXTRAS && UR(extras_cnt) >= MAX_DET_EXTRAS) || - extras[j].len > len - i || - !memcmp(extras[j].data, out_buf + i, extras[j].len) || - !memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, extras[j].len))) { + if ((extras_cnt > MAX_DET_EXTRAS && UR(extras_cnt) >= MAX_DET_EXTRAS) || // 如果额外数据过多,随机跳过 + extras[j].len > len - i || // 如果额外数据长度超出剩余缓冲区长度,跳过 + !memcmp(extras[j].data, out_buf + i, extras[j].len) || // 如果额外数据与当前缓冲区内容相同,跳过 + !memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, extras[j].len))) { // 如果额外数据所在的区域没有有效字节,跳过 - stage_max--; - continue; + stage_max--; // 减少最大迭代次数 + continue; // 跳过当前额外数据 } - last_len = extras[j].len; - memcpy(out_buf + i, extras[j].data, last_len); + last_len = extras[j].len; // 记录当前额外数据的长度 + memcpy(out_buf + i, extras[j].data, last_len); // 将额外数据复制到输出缓冲区 - if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; + if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; // 执行模糊测试,如果失败则跳转到abandon_entry - stage_cur++; + stage_cur++; // 增加当前阶段的计数器 } /* Restore all the clobbered memory. */ - memcpy(out_buf + i, in_buf + i, last_len); + memcpy(out_buf + i, in_buf + i, last_len); // 恢复被覆盖的内存 } - new_hit_cnt = queued_paths + unique_crashes; + new_hit_cnt = queued_paths + unique_crashes; // 更新命中计数 - stage_finds[STAGE_EXTRAS_UO] += new_hit_cnt - orig_hit_cnt; - stage_cycles[STAGE_EXTRAS_UO] += stage_max; + stage_finds[STAGE_EXTRAS_UO] += new_hit_cnt - orig_hit_cnt; // 更新当前阶段的发现计数 + stage_cycles[STAGE_EXTRAS_UO] += stage_max; // 更新当前阶段的循环计数 /* Insertion of user-supplied extras. */ - stage_name = "user extras (insert)"; - stage_short = "ext_UI"; - stage_cur = 0; - stage_max = extras_cnt * (len + 1); + stage_name = "user extras (insert)"; // 设置当前阶段的名称 + stage_short = "ext_UI"; // 设置当前阶段的简称 + stage_cur = 0; // 初始化当前阶段的计数器 + stage_max = extras_cnt * (len + 1); // 设置当前阶段的最大迭代次数 - orig_hit_cnt = new_hit_cnt; + orig_hit_cnt = new_hit_cnt; // 保存当前的命中计数 - ex_tmp = ck_alloc(len + MAX_DICT_FILE); + ex_tmp = ck_alloc(len + MAX_DICT_FILE); // 分配临时缓冲区 - for (i = 0; i <= len; i++) { + for (i = 0; i <= len; i++) { // 遍历输入缓冲区的每个字节 - stage_cur_byte = i; + stage_cur_byte = i; // 设置当前处理的字节位置 - for (j = 0; j < extras_cnt; j++) { + for (j = 0; j < extras_cnt; j++) { // 遍历所有用户提供的额外数据 - if (len + extras[j].len > MAX_FILE) { + if (len + extras[j].len > MAX_FILE) { // 如果插入额外数据后超出最大文件大小,跳过 stage_max--; continue; } /* Insert token */ - memcpy(ex_tmp + i, extras[j].data, extras[j].len); + memcpy(ex_tmp + i, extras[j].data, extras[j].len); // 将额外数据插入到临时缓冲区 /* Copy tail */ - memcpy(ex_tmp + i + extras[j].len, out_buf + i, len - i); + memcpy(ex_tmp + i + extras[j].len, out_buf + i, len - i); // 复制剩余的数据到临时缓冲区 - if (common_fuzz_stuff(argv, ex_tmp, len + extras[j].len)) { + if (common_fuzz_stuff(argv, ex_tmp, len + extras[j].len)) { // 执行模糊测试,如果失败则跳转到abandon_entry ck_free(ex_tmp); goto abandon_entry; } - stage_cur++; + stage_cur++; // 增加当前阶段的计数器 } /* Copy head */ - ex_tmp[i] = out_buf[i]; + ex_tmp[i] = out_buf[i]; // 复制当前字节到临时缓冲区 } - ck_free(ex_tmp); + ck_free(ex_tmp); // 释放临时缓冲区 - new_hit_cnt = queued_paths + unique_crashes; + new_hit_cnt = queued_paths + unique_crashes; // 更新命中计数 - stage_finds[STAGE_EXTRAS_UI] += new_hit_cnt - orig_hit_cnt; - stage_cycles[STAGE_EXTRAS_UI] += stage_max; + stage_finds[STAGE_EXTRAS_UI] += new_hit_cnt - orig_hit_cnt; // 更新当前阶段的发现计数 + stage_cycles[STAGE_EXTRAS_UI] += stage_max; // 更新当前阶段的循环计数 skip_user_extras: - if (!a_extras_cnt) goto skip_extras; + if (!a_extras_cnt) goto skip_extras; // 如果没有自动生成的额外数据,跳过自动额外数据的处理 - stage_name = "auto extras (over)"; - stage_short = "ext_AO"; - stage_cur = 0; - stage_max = MIN(a_extras_cnt, USE_AUTO_EXTRAS) * len; + stage_name = "auto extras (over)"; // 设置当前阶段的名称 + stage_short = "ext_AO"; // 设置当前阶段的简称 + stage_cur = 0; // 初始化当前阶段的计数器 + stage_max = MIN(a_extras_cnt, USE_AUTO_EXTRAS) * len; // 设置当前阶段的最大迭代次数 - stage_val_type = STAGE_VAL_NONE; + stage_val_type = STAGE_VAL_NONE; // 设置当前阶段的值类型为无 - orig_hit_cnt = new_hit_cnt; + orig_hit_cnt = new_hit_cnt; // 保存当前的命中计数 - for (i = 0; i < len; i++) { + for (i = 0; i < len; i++) { // 遍历输入缓冲区的每个字节 - u32 last_len = 0; + u32 last_len = 0; // 记录上一次写入的额外数据长度 - stage_cur_byte = i; + stage_cur_byte = i; // 设置当前处理的字节位置 - for (j = 0; j < MIN(a_extras_cnt, USE_AUTO_EXTRAS); j++) { + for (j = 0; j < MIN(a_extras_cnt, USE_AUTO_EXTRAS); j++) { // 遍历所有自动生成的额外数据 /* See the comment in the earlier code; extras are sorted by size. */ - if (a_extras[j].len > len - i || - !memcmp(a_extras[j].data, out_buf + i, a_extras[j].len) || - !memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, a_extras[j].len))) { + if (a_extras[j].len > len - i || // 如果额外数据长度超出剩余缓冲区长度,跳过 + !memcmp(a_extras[j].data, out_buf + i, a_extras[j].len) || // 如果额外数据与当前缓冲区内容相同,跳过 + !memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, a_extras[j].len))) { // 如果额外数据所在的区域没有有效字节,跳过 - stage_max--; - continue; + stage_max--; // 减少最大迭代次数 + continue; // 跳过当前额外数据 } - last_len = a_extras[j].len; - memcpy(out_buf + i, a_extras[j].data, last_len); + last_len = a_extras[j].len; // 记录当前额外数据的长度 + memcpy(out_buf + i, a_extras[j].data, last_len); // 将额外数据复制到输出缓冲区 - if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; + if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; // 执行模糊测试,如果失败则跳转到abandon_entry - stage_cur++; + stage_cur++; // 增加当前阶段的计数器 } /* Restore all the clobbered memory. */ - memcpy(out_buf + i, in_buf + i, last_len); + memcpy(out_buf + i, in_buf + i, last_len); // 恢复被覆盖的内存 } + new_hit_cnt = queued_paths + unique_crashes; // 更新命中计数 + + stage_finds[STAGE_EXTRAS_AO] += new_hit_cnt - orig_hit_cnt; // 更新当前阶段的发现计数 + stage_cycles[STAGE_EXTRAS_AO] += stage_max; // 更新当前阶段的循环计数 + + /* Insertion of auto-generated extras. */ + + stage_name = "auto extras (insert)"; // 设置当前阶段的名称 + stage_short = "ext_AI"; // 设置当前阶段的简称 + stage_cur = 0; // 初始化当前阶段的计数器 + stage_max = MIN(a_extras_cnt, USE_AUTO_EXTRAS) * (len + 1); // 设置当前阶段的最大迭代次数 + + orig_hit_cnt = new_hit_cnt; // 保存当前的命中计数 + + ex_tmp = ck_alloc(len + MAX_DICT_FILE); // 分配临时缓冲区 + + for (i = 0; i <= len; i++) { // 遍历输入缓冲区的每个字节 + + stage_cur_byte = i; // 设置当前处理的字节位置 + + for (j = 0; j < MIN(a_extras_cnt, USE_AUTO_EXTRAS); j++) { // 遍历所有自动生成的额外数据 + + if (len + a_extras[j].len > MAX_FILE) { // 如果插入额外数据后超出最大文件大小,跳过 + stage_max--; + continue; + } + + /* Insert token */ + memcpy(ex_tmp + i, a_extras[j].data, a_extras[j].len); // 将额外数据插入到临时缓冲区 + + /* Copy tail */ + memcpy(ex_tmp + i + a_extras[j].len, out_buf + i, len - i); // 复制剩余的数据到临时缓冲区 + + if (common_fuzz_stuff(argv, ex_tmp, len + a_extras[j].len)) { // 执行模糊测试,如果失败则跳转到abandon_entry + ck_free(ex_tmp); + goto abandon_entry; + } + + stage_cur++; // 增加当前阶段的计数器 + + } + + /* Copy head */ + ex_tmp[i] = out_buf[i]; // 复制当前字节到临时缓冲区 + + } + + ck_free(ex_tmp); // 释放临时缓冲区 + new_hit_cnt = queued_paths + unique_crashes; stage_finds[STAGE_EXTRAS_AO] += new_hit_cnt - orig_hit_cnt; // 更新STAGE_EXTRAS_AO阶段的发现计数