afl-fuzz.c 5500-6000行

pull/16/head
Satori5ama 8 months ago
parent 4d13553f82
commit ce013b31c9

@ -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阶段的发现计数

Loading…
Cancel
Save