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; new_hit_cnt = queued_paths + unique_crashes;
// 更新当前阶段的发现计数和周期
stage_finds[STAGE_ARITH8] += new_hit_cnt - orig_hit_cnt; stage_finds[STAGE_ARITH8] += new_hit_cnt - orig_hit_cnt;
stage_cycles[STAGE_ARITH8] += stage_max; stage_cycles[STAGE_ARITH8] += stage_max;
/* 16-bit arithmetics, both endians. */ /* 16位算术运算,支持两种字节序。 */
// 如果长度小于2跳过算术操作
if (len < 2) goto skip_arith; if (len < 2) goto skip_arith;
// 设置当前阶段的名称与短名称
stage_name = "arith 16/8"; stage_name = "arith 16/8";
stage_short = "arith16"; stage_short = "arith16";
stage_cur = 0; stage_cur = 0; // 当前计数器初始化为0
stage_max = 4 * (len - 1) * ARITH_MAX; stage_max = 4 * (len - 1) * ARITH_MAX; // 最大操作数计算
// 保存原始的命中计数
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++) {
// 读取当前字节和下一个字节作为16位数
u16 orig = *(u16*)(out_buf + i); u16 orig = *(u16*)(out_buf + i);
/* Let's consult the effector map... */ // 查看效应映射表
if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) { if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) {
stage_max -= 4 * ARITH_MAX; stage_max -= 4 * ARITH_MAX; // 减少最大值
continue; continue; // 继续下一次循环
} }
// 当前操作的字节索引
stage_cur_byte = i; stage_cur_byte = i;
// 尝试进行加法和减法操作
for (j = 1; j <= ARITH_MAX; j++) { for (j = 1; j <= ARITH_MAX; j++) {
// 进行加法和异或操作
u16 r1 = orig ^ (orig + j), u16 r1 = orig ^ (orig + j),
r2 = orig ^ (orig - j), r2 = orig ^ (orig - j),
r3 = orig ^ SWAP16(SWAP16(orig) + j), r3 = orig ^ SWAP16(SWAP16(orig) + j),
r4 = 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; stage_val_type = STAGE_VAL_LE;
// 判断加法是否溢出,并且结果不应该是位翻转
if ((orig & 0xff) + j > 0xff && !could_be_bitflip(r1)) { 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; if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;
stage_cur++; stage_cur++; // 成功计数
} else stage_max--;
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; if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;
stage_cur++; stage_cur++; // 成功计数
} else stage_max--; } else stage_max--; // 若不成功,则减少最大周期
/* Big endian comes next. Same deal. */
// 尝试大端加法
stage_val_type = STAGE_VAL_BE; stage_val_type = STAGE_VAL_BE;
// 判断加法是否溢出,并且结果不应该是位翻转
if ((orig >> 8) + j > 0xff && !could_be_bitflip(r3)) { 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; 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)) { 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; 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; *(u16*)(out_buf + i) = orig;
} }
} }
// 更新命中计数
new_hit_cnt = queued_paths + unique_crashes; new_hit_cnt = queued_paths + unique_crashes;
// 更新当前阶段的发现计数和周期
stage_finds[STAGE_ARITH16] += new_hit_cnt - orig_hit_cnt; stage_finds[STAGE_ARITH16] += new_hit_cnt - orig_hit_cnt;
stage_cycles[STAGE_ARITH16] += stage_max; stage_cycles[STAGE_ARITH16] += stage_max;
/* 32-bit arithmetics, both endians. */ /* 32位算术运算,支持两种字节序。 */
// 如果长度小于4跳过算术操作
if (len < 4) goto skip_arith; if (len < 4) goto skip_arith;
// 设置当前阶段的名称与短名称
stage_name = "arith 32/8"; stage_name = "arith 32/8";
stage_short = "arith32"; stage_short = "arith32";
stage_cur = 0; stage_cur = 0; // 当前计数器初始化为0
stage_max = 4 * (len - 3) * ARITH_MAX; stage_max = 4 * (len - 3) * ARITH_MAX; // 最大操作数计算
// 保存原始的命中计数
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++) {
// 读取当前字节和接下来三个字节作为32位数
u32 orig = *(u32*)(out_buf + i); u32 orig = *(u32*)(out_buf + i);
/* Let's consult the effector map... */ // 查看效应映射表
if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] && if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] &&
!eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) { !eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) {
stage_max -= 4 * ARITH_MAX; stage_max -= 4 * ARITH_MAX; // 减少最大值
continue; continue; // 继续下一次循环
} }
// 当前操作的字节索引
stage_cur_byte = i; stage_cur_byte = i;
// 尝试进行加法和减法操作
for (j = 1; j <= ARITH_MAX; j++) { for (j = 1; j <= ARITH_MAX; j++) {
// 进行加法和异或操作
u32 r1 = orig ^ (orig + j), u32 r1 = orig ^ (orig + j),
r2 = orig ^ (orig - j), r2 = orig ^ (orig - j),
r3 = orig ^ SWAP32(SWAP32(orig) + j), r3 = orig ^ SWAP32(SWAP32(orig) + j),
r4 = 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; stage_val_type = STAGE_VAL_LE;
// 判断加法是否溢出,并且结果不应该是位翻转
if ((orig & 0xffff) + j > 0xffff && !could_be_bitflip(r1)) { if ((orig & 0xffff) + j > 0xffff && !could_be_bitflip(r1)) {
stage_cur_val = j; stage_cur_val = j; // 设置当前值为j
*(u32*)(out_buf + i) = orig + j; *(u32*)(out_buf + i) = orig + j; // 更新输出缓冲区
// 执行模糊测试
if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; 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)) { if ((orig & 0xffff) < j && !could_be_bitflip(r2)) {
stage_cur_val = -j; stage_cur_val = -j; // 设置当前值为-j
*(u32*)(out_buf + i) = orig - j; *(u32*)(out_buf + i) = orig - j; // 更新输出缓冲区
// 执行模糊测试
if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;
stage_cur++; stage_cur++; // 成功计数
} else stage_max--; } else stage_max--; // 若不成功,则减少最大周期
/* Big endian next. */
// 尝试大端加法
stage_val_type = STAGE_VAL_BE; stage_val_type = STAGE_VAL_BE;
// 判断加法是否溢出,并且结果不应该是位翻转
if ((SWAP32(orig) & 0xffff) + j > 0xffff && !could_be_bitflip(r3)) { if ((SWAP32(orig) & 0xffff) + j > 0xffff && !could_be_bitflip(r3)) {
stage_cur_val = j; stage_cur_val = j; // 设置当前值为j
*(u32*)(out_buf + i) = SWAP32(SWAP32(orig) + j); *(u32*)(out_buf + i) = SWAP32(SWAP32(orig) + j); // 更新输出缓冲区
// 执行模糊测试
if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; 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)) { if ((SWAP32(orig) & 0xffff) < j && !could_be_bitflip(r4)) {
stage_cur_val = -j; stage_cur_val = -j; // 设置当前值为-j
*(u32*)(out_buf + i) = SWAP32(SWAP32(orig) - j); *(u32*)(out_buf + i) = SWAP32(SWAP32(orig) - j); // 更新输出缓冲区
// 执行模糊测试
if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; 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; *(u32*)(out_buf + i) = orig;
} }
} }
// 更新命中计数
new_hit_cnt = queued_paths + unique_crashes; new_hit_cnt = queued_paths + unique_crashes;
// 更新当前阶段的发现计数和周期
stage_finds[STAGE_ARITH32] += new_hit_cnt - orig_hit_cnt; stage_finds[STAGE_ARITH32] += new_hit_cnt - orig_hit_cnt;
stage_cycles[STAGE_ARITH32] += stage_max; stage_cycles[STAGE_ARITH32] += stage_max;
skip_arith: skip_arith:
/********************** /**********************
* INTERESTING VALUES * * INTERESTING VALUES *
**********************/ **********************/
stage_name = "interest 8/8"; stage_name = "interest 8/8"; // 当前阶段名称8位整数的有趣值
stage_short = "int8"; stage_short = "int8"; // 当前阶段缩写
stage_cur = 0; stage_cur = 0; // 当前阶段计数器
stage_max = len * sizeof(interesting_8); 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)]) { if (!eff_map[EFF_APOS(i)]) { // 如果当前字节位置没有效应
stage_max -= sizeof(interesting_8); stage_max -= sizeof(interesting_8); // 减少最大操作次数
continue; 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]) || if (could_be_bitflip(orig ^ (u8)interesting_8[j]) || // 检查位翻转
could_be_arith(orig, (u8)interesting_8[j], 1)) { could_be_arith(orig, (u8)interesting_8[j], 1)) { // 检查算术
stage_max--; stage_max--; // 减少最大操作次数
continue; continue; // 跳过当前循环
} }
stage_cur_val = interesting_8[j]; stage_cur_val = interesting_8[j]; // 设置当前值为有趣值
out_buf[i] = 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; out_buf[i] = orig; // 恢复原始字节
stage_cur++; 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_finds[STAGE_INTEREST8] += new_hit_cnt - orig_hit_cnt; // 记录阶段发现的次数
stage_cycles[STAGE_INTEREST8] += stage_max; 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_name = "interest 16/8"; // 当前阶段名称16位整数的有趣值
stage_short = "int16"; stage_short = "int16"; // 当前阶段缩写
stage_cur = 0; stage_cur = 0; // 当前阶段计数器
stage_max = 2 * (len - 1) * (sizeof(interesting_16) >> 1); 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)]) { if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) { // 如果两个字节位置没有效应
stage_max -= sizeof(interesting_16); stage_max -= sizeof(interesting_16); // 减少最大操作次数
continue; 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]) && if (!could_be_bitflip(orig ^ (u16)interesting_16[j]) && // 检查位翻转
!could_be_arith(orig, (u16)interesting_16[j], 2) && !could_be_arith(orig, (u16)interesting_16[j], 2) && // 检查算术
!could_be_interest(orig, (u16)interesting_16[j], 2, 0)) { !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; if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; // 进行模糊测试
stage_cur++; stage_cur++; // 当前阶段计数器增加
} else stage_max--; } else stage_max--; // 否则减少最大操作次数
if ((u16)interesting_16[j] != SWAP16(interesting_16[j]) && if ((u16)interesting_16[j] != SWAP16(interesting_16[j]) && // 检查是否需要交换字节
!could_be_bitflip(orig ^ SWAP16(interesting_16[j])) && !could_be_bitflip(orig ^ SWAP16(interesting_16[j])) && // 检查位翻转
!could_be_arith(orig, SWAP16(interesting_16[j]), 2) && !could_be_arith(orig, SWAP16(interesting_16[j]), 2) && // 检查算术
!could_be_interest(orig, SWAP16(interesting_16[j]), 2, 1)) { !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]); *(u16*)(out_buf + i) = SWAP16(interesting_16[j]); // 更新为交换字节的有趣值
if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; 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; *(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_finds[STAGE_INTEREST16] += new_hit_cnt - orig_hit_cnt; // 记录阶段发现的次数
stage_cycles[STAGE_INTEREST16] += stage_max; 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_name = "interest 32/8"; // 当前阶段名称32位整数的有趣值
stage_short = "int32"; stage_short = "int32"; // 当前阶段缩写
stage_cur = 0; stage_cur = 0; // 当前阶段计数器
stage_max = 2 * (len - 3) * (sizeof(interesting_32) >> 2); 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)] && if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] &&
!eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) { !eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) { // 如果四个字节位置没有效应
stage_max -= sizeof(interesting_32) >> 1; stage_max -= sizeof(interesting_32) >> 1; // 减少最大操作次数
continue; 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]) && if (!could_be_bitflip(orig ^ (u32)interesting_32[j]) && // 检查位翻转
!could_be_arith(orig, interesting_32[j], 4) && !could_be_arith(orig, interesting_32[j], 4) && // 检查算术
!could_be_interest(orig, interesting_32[j], 4, 0)) { !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; if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; // 进行模糊测试
stage_cur++; stage_cur++; // 当前阶段计数器增加
} else stage_max--; } else stage_max--; // 否则减少最大操作次数
if ((u32)interesting_32[j] != SWAP32(interesting_32[j]) && if ((u32)interesting_32[j] != SWAP32(interesting_32[j]) && // 检查是否需要交换字节
!could_be_bitflip(orig ^ SWAP32(interesting_32[j])) && !could_be_bitflip(orig ^ SWAP32(interesting_32[j])) && // 检查位翻转
!could_be_arith(orig, SWAP32(interesting_32[j]), 4) && !could_be_arith(orig, SWAP32(interesting_32[j]), 4) && // 检查算术
!could_be_interest(orig, SWAP32(interesting_32[j]), 4, 1)) { !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]); *(u32*)(out_buf + i) = SWAP32(interesting_32[j]); // 更新为交换字节的有趣值
if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry; 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; *(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_finds[STAGE_INTEREST32] += new_hit_cnt - orig_hit_cnt; // 记录阶段发现的次数
stage_cycles[STAGE_INTEREST32] += stage_max; stage_cycles[STAGE_INTEREST32] += stage_max; // 更新阶段循环次数
skip_interest: skip_interest:
@ -5933,161 +5957,210 @@ skip_interest:
* DICTIONARY STUFF * * DICTIONARY STUFF *
********************/ ********************/
if (!extras_cnt) goto skip_user_extras; if (!extras_cnt) goto skip_user_extras; // 如果没有用户提供的额外数据,跳过用户额外数据的处理
/* Overwrite with user-supplied extras. */ /* Overwrite with user-supplied extras. */
stage_name = "user extras (over)"; stage_name = "user extras (over)"; // 设置当前阶段的名称
stage_short = "ext_UO"; stage_short = "ext_UO"; // 设置当前阶段的简称
stage_cur = 0; stage_cur = 0; // 初始化当前阶段的计数器
stage_max = extras_cnt * len; 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 /* Extras are sorted by size, from smallest to largest. This means
that we don't have to worry about restoring the buffer in that we don't have to worry about restoring the buffer in
between writes at a particular offset determined by the outer between writes at a particular offset determined by the outer
loop. */ 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 extras probabilistically if extras_cnt > MAX_DET_EXTRAS. Also
skip them if there's no room to insert the payload, if the token 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 is redundant, or if its entire span has no bytes set in the effector
map. */ map. */
if ((extras_cnt > MAX_DET_EXTRAS && UR(extras_cnt) >= MAX_DET_EXTRAS) || if ((extras_cnt > MAX_DET_EXTRAS && UR(extras_cnt) >= MAX_DET_EXTRAS) || // 如果额外数据过多,随机跳过
extras[j].len > len - i || extras[j].len > len - i || // 如果额外数据长度超出剩余缓冲区长度,跳过
!memcmp(extras[j].data, out_buf + i, extras[j].len) || !memcmp(extras[j].data, out_buf + i, extras[j].len) || // 如果额外数据与当前缓冲区内容相同,跳过
!memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, extras[j].len))) { !memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, extras[j].len))) { // 如果额外数据所在的区域没有有效字节,跳过
stage_max--; stage_max--; // 减少最大迭代次数
continue; continue; // 跳过当前额外数据
} }
last_len = extras[j].len; last_len = extras[j].len; // 记录当前额外数据的长度
memcpy(out_buf + i, extras[j].data, last_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. */ /* 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_finds[STAGE_EXTRAS_UO] += new_hit_cnt - orig_hit_cnt; // 更新当前阶段的发现计数
stage_cycles[STAGE_EXTRAS_UO] += stage_max; stage_cycles[STAGE_EXTRAS_UO] += stage_max; // 更新当前阶段的循环计数
/* Insertion of user-supplied extras. */ /* Insertion of user-supplied extras. */
stage_name = "user extras (insert)"; stage_name = "user extras (insert)"; // 设置当前阶段的名称
stage_short = "ext_UI"; stage_short = "ext_UI"; // 设置当前阶段的简称
stage_cur = 0; stage_cur = 0; // 初始化当前阶段的计数器
stage_max = extras_cnt * (len + 1); 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--; stage_max--;
continue; continue;
} }
/* Insert token */ /* Insert token */
memcpy(ex_tmp + i, extras[j].data, extras[j].len); memcpy(ex_tmp + i, extras[j].data, extras[j].len); // 将额外数据插入到临时缓冲区
/* Copy tail */ /* 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); ck_free(ex_tmp);
goto abandon_entry; goto abandon_entry;
} }
stage_cur++; stage_cur++; // 增加当前阶段的计数器
} }
/* Copy head */ /* 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_finds[STAGE_EXTRAS_UI] += new_hit_cnt - orig_hit_cnt; // 更新当前阶段的发现计数
stage_cycles[STAGE_EXTRAS_UI] += stage_max; stage_cycles[STAGE_EXTRAS_UI] += stage_max; // 更新当前阶段的循环计数
skip_user_extras: skip_user_extras:
if (!a_extras_cnt) goto skip_extras; if (!a_extras_cnt) goto skip_extras; // 如果没有自动生成的额外数据,跳过自动额外数据的处理
stage_name = "auto extras (over)"; stage_name = "auto extras (over)"; // 设置当前阶段的名称
stage_short = "ext_AO"; stage_short = "ext_AO"; // 设置当前阶段的简称
stage_cur = 0; stage_cur = 0; // 初始化当前阶段的计数器
stage_max = MIN(a_extras_cnt, USE_AUTO_EXTRAS) * len; 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. */ /* See the comment in the earlier code; extras are sorted by size. */
if (a_extras[j].len > len - i || if (a_extras[j].len > len - i || // 如果额外数据长度超出剩余缓冲区长度,跳过
!memcmp(a_extras[j].data, out_buf + i, a_extras[j].len) || !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))) { !memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, a_extras[j].len))) { // 如果额外数据所在的区域没有有效字节,跳过
stage_max--; stage_max--; // 减少最大迭代次数
continue; continue; // 跳过当前额外数据
} }
last_len = a_extras[j].len; last_len = a_extras[j].len; // 记录当前额外数据的长度
memcpy(out_buf + i, a_extras[j].data, last_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. */ /* 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; new_hit_cnt = queued_paths + unique_crashes;
stage_finds[STAGE_EXTRAS_AO] += new_hit_cnt - orig_hit_cnt; // 更新STAGE_EXTRAS_AO阶段的发现计数 stage_finds[STAGE_EXTRAS_AO] += new_hit_cnt - orig_hit_cnt; // 更新STAGE_EXTRAS_AO阶段的发现计数

Loading…
Cancel
Save