diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 7625d8a..c11a806 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -6090,476 +6090,376 @@ skip_user_extras: 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; + stage_finds[STAGE_EXTRAS_AO] += new_hit_cnt - orig_hit_cnt; // 更新STAGE_EXTRAS_AO阶段的发现计数 + stage_cycles[STAGE_EXTRAS_AO] += stage_max; // 更新STAGE_EXTRAS_AO阶段的循环计数 -skip_extras: +skip_extras: // 跳过额外的处理步骤 /* If we made this to here without jumping to havoc_stage or abandon_entry, we're properly done with deterministic steps and can mark it as such - in the .state/ directory. */ + in the .state/ directory. */ // 如果程序执行到这里而没有跳转到havoc_stage或abandon_entry,说明我们已经完成了确定性步骤,可以在.state/目录中标记为已完成 - if (!queue_cur->passed_det) mark_as_det_done(queue_cur); + if (!queue_cur->passed_det) mark_as_det_done(queue_cur); // 如果当前队列项尚未标记为完成确定性步骤,则标记为完成 /**************** * RANDOM HAVOC * - ****************/ + ****************/ // 随机破坏阶段 -havoc_stage: +havoc_stage: // 随机破坏阶段的标签 - stage_cur_byte = -1; + stage_cur_byte = -1; // 初始化当前字节位置为-1 /* The havoc stage mutation code is also invoked when splicing files; if the - splice_cycle variable is set, generate different descriptions and such. */ + splice_cycle variable is set, generate different descriptions and such. */ // 当拼接文件时也会调用随机破坏阶段的变异代码;如果splice_cycle变量被设置,生成不同的描述等 - if (!splice_cycle) { + if (!splice_cycle) { // 如果没有进行文件拼接 - stage_name = "havoc"; - stage_short = "havoc"; + stage_name = "havoc"; // 设置阶段名称为"havoc" + stage_short = "havoc"; // 设置阶段简称为"havoc" stage_max = (doing_det ? HAVOC_CYCLES_INIT : HAVOC_CYCLES) * - perf_score / havoc_div / 100; + perf_score / havoc_div / 100; // 根据是否进行确定性测试和性能评分计算最大阶段循环次数 - } else { - - static u8 tmp[32]; + } else { // 如果进行文件拼接 - perf_score = orig_perf; + static u8 tmp[32]; // 定义一个静态的32字节缓冲区 - sprintf(tmp, "splice %u", splice_cycle); - stage_name = tmp; - stage_short = "splice"; - stage_max = SPLICE_HAVOC * perf_score / havoc_div / 100; + perf_score = orig_perf; // 恢复原始性能评分 + sprintf(tmp, "splice %u", splice_cycle); // 格式化拼接周期的描述 + stage_name = tmp; // 设置阶段名称为拼接周期的描述 + stage_short = "splice"; // 设置阶段简称为"splice" + stage_max = SPLICE_HAVOC * perf_score / havoc_div / 100; // 根据拼接周期的性能评分计算最大阶段循环次数 } - if (stage_max < HAVOC_MIN) stage_max = HAVOC_MIN; + if (stage_max < HAVOC_MIN) stage_max = HAVOC_MIN; // 如果最大阶段循环次数小于HAVOC_MIN,则将其设置为HAVOC_MIN - temp_len = len; + temp_len = len; // 将临时长度设置为输入缓冲区的长度 - orig_hit_cnt = queued_paths + unique_crashes; + orig_hit_cnt = queued_paths + unique_crashes; // 记录当前已排队的路径和唯一崩溃的总数 - havoc_queued = queued_paths; + havoc_queued = queued_paths; // 记录当前已排队的路径数 /* We essentially just do several thousand runs (depending on perf_score) - where we take the input file and make random stacked tweaks. */ + where we take the input file and make random stacked tweaks. */ // 我们基本上会进行数千次运行(取决于性能评分),对输入文件进行随机的堆叠调整 - for (stage_cur = 0; stage_cur < stage_max; stage_cur++) { + for (stage_cur = 0; stage_cur < stage_max; stage_cur++) { // 遍历最大阶段循环次数 - u32 use_stacking = 1 << (1 + UR(HAVOC_STACK_POW2)); + u32 use_stacking = 1 << (1 + UR(HAVOC_STACK_POW2)); // 随机生成一个堆叠次数,用于决定每次循环中进行多少次变异 - stage_cur_val = use_stacking; - - for (i = 0; i < use_stacking; i++) { + stage_cur_val = use_stacking; // 记录当前堆叠次数 - switch (UR(15 + ((extras_cnt + a_extras_cnt) ? 2 : 0))) { + for (i = 0; i < use_stacking; i++) { // 遍历堆叠次数 - case 0: + switch (UR(15 + ((extras_cnt + a_extras_cnt) ? 2 : 0))) { // 随机选择一个变异操作 - /* Flip a single bit somewhere. Spooky! */ + case 0: // 操作0:翻转一个随机位 - FLIP_BIT(out_buf, UR(temp_len << 3)); + /* Flip a single bit somewhere. Spooky! */ // 翻转某个随机位 + FLIP_BIT(out_buf, UR(temp_len << 3)); // 在输出缓冲区中随机翻转一个位 break; - case 1: - - /* Set byte to interesting value. */ + case 1: // 操作1:将随机字节设置为一个有趣的值 - out_buf[UR(temp_len)] = interesting_8[UR(sizeof(interesting_8))]; + /* Set byte to interesting value. */ // 将随机字节设置为一个有趣的值 + out_buf[UR(temp_len)] = interesting_8[UR(sizeof(interesting_8))]; // 从interesting_8数组中随机选择一个值并设置到随机位置 break; - case 2: - - /* Set word to interesting value, randomly choosing endian. */ + case 2: // 操作2:将随机字设置为一个有趣的值,随机选择字节序 - if (temp_len < 2) break; - - if (UR(2)) { - - *(u16*)(out_buf + UR(temp_len - 1)) = - interesting_16[UR(sizeof(interesting_16) >> 1)]; + /* Set word to interesting value, randomly choosing endian. */ // 将随机字设置为一个有趣的值,随机选择字节序 + if (temp_len < 2) break; // 如果缓冲区长度小于2,跳过 + if (UR(2)) { // 随机选择字节序 + *(u16*)(out_buf + UR(temp_len - 1)) = interesting_16[UR(sizeof(interesting_16) >> 1)]; // 使用小端序设置值 } else { - - *(u16*)(out_buf + UR(temp_len - 1)) = SWAP16( - interesting_16[UR(sizeof(interesting_16) >> 1)]); - + *(u16*)(out_buf + UR(temp_len - 1)) = SWAP16(interesting_16[UR(sizeof(interesting_16) >> 1)]); // 使用大端序设置值 } - break; - case 3: - - /* Set dword to interesting value, randomly choosing endian. */ + case 3: // 操作3:将随机双字设置为一个有趣的值,随机选择字节序 - if (temp_len < 4) break; - - if (UR(2)) { - - *(u32*)(out_buf + UR(temp_len - 3)) = - interesting_32[UR(sizeof(interesting_32) >> 2)]; + /* Set dword to interesting value, randomly choosing endian. */ // 将随机双字设置为一个有趣的值,随机选择字节序 + if (temp_len < 4) break; // 如果缓冲区长度小于4,跳过 + if (UR(2)) { // 随机选择字节序 + *(u32*)(out_buf + UR(temp_len - 3)) = interesting_32[UR(sizeof(interesting_32) >> 2)]; // 使用小端序设置值 } else { - - *(u32*)(out_buf + UR(temp_len - 3)) = SWAP32( - interesting_32[UR(sizeof(interesting_32) >> 2)]); - + *(u32*)(out_buf + UR(temp_len - 3)) = SWAP32(interesting_32[UR(sizeof(interesting_32) >> 2)]); // 使用大端序设置值 } - break; - case 4: - - /* Randomly subtract from byte. */ + case 4: // 操作4:随机减少一个字节的值 - out_buf[UR(temp_len)] -= 1 + UR(ARITH_MAX); + /* Randomly subtract from byte. */ // 随机减少一个字节的值 + out_buf[UR(temp_len)] -= 1 + UR(ARITH_MAX); // 随机减少一个字节的值 break; - case 5: - - /* Randomly add to byte. */ + case 5: // 操作5:随机增加一个字节的值 - out_buf[UR(temp_len)] += 1 + UR(ARITH_MAX); + /* Randomly add to byte. */ // 随机增加一个字节的值 + out_buf[UR(temp_len)] += 1 + UR(ARITH_MAX); // 随机增加一个字节的值 break; - case 6: + case 6: // 操作6:随机减少一个字的值,随机选择字节序 - /* Randomly subtract from word, random endian. */ - - if (temp_len < 2) break; - - if (UR(2)) { - - u32 pos = UR(temp_len - 1); - - *(u16*)(out_buf + pos) -= 1 + UR(ARITH_MAX); + /* Randomly subtract from word, random endian. */ // 随机减少一个字的值,随机选择字节序 + if (temp_len < 2) break; // 如果缓冲区长度小于2,跳过 + if (UR(2)) { // 随机选择字节序 + u32 pos = UR(temp_len - 1); // 随机选择位置 + *(u16*)(out_buf + pos) -= 1 + UR(ARITH_MAX); // 减少字的值 } else { - - u32 pos = UR(temp_len - 1); - u16 num = 1 + UR(ARITH_MAX); - - *(u16*)(out_buf + pos) = - SWAP16(SWAP16(*(u16*)(out_buf + pos)) - num); - + u32 pos = UR(temp_len - 1); // 随机选择位置 + u16 num = 1 + UR(ARITH_MAX); // 随机生成减少的值 + *(u16*)(out_buf + pos) = SWAP16(SWAP16(*(u16*)(out_buf + pos)) - num); // 使用大端序减少字的值 } - break; - case 7: - - /* Randomly add to word, random endian. */ - - if (temp_len < 2) break; + case 7: // 操作7:随机增加一个字的值,随机选择字节序 - if (UR(2)) { - - u32 pos = UR(temp_len - 1); - - *(u16*)(out_buf + pos) += 1 + UR(ARITH_MAX); + /* Randomly add to word, random endian. */ // 随机增加一个字的值,随机选择字节序 + if (temp_len < 2) break; // 如果缓冲区长度小于2,跳过 + if (UR(2)) { // 随机选择字节序 + u32 pos = UR(temp_len - 1); // 随机选择位置 + *(u16*)(out_buf + pos) += 1 + UR(ARITH_MAX); // 增加字的值 } else { - - u32 pos = UR(temp_len - 1); - u16 num = 1 + UR(ARITH_MAX); - - *(u16*)(out_buf + pos) = - SWAP16(SWAP16(*(u16*)(out_buf + pos)) + num); - + u32 pos = UR(temp_len - 1); // 随机选择位置 + u16 num = 1 + UR(ARITH_MAX); // 随机生成增加的值 + *(u16*)(out_buf + pos) = SWAP16(SWAP16(*(u16*)(out_buf + pos)) + num); // 使用大端序增加字的值 } - break; - case 8: - - /* Randomly subtract from dword, random endian. */ - - if (temp_len < 4) break; - - if (UR(2)) { + case 8: // 操作8:随机减少一个双字的值,随机选择字节序 - u32 pos = UR(temp_len - 3); - - *(u32*)(out_buf + pos) -= 1 + UR(ARITH_MAX); + /* Randomly subtract from dword, random endian. */ // 随机减少一个双字的值,随机选择字节序 + if (temp_len < 4) break; // 如果缓冲区长度小于4,跳过 + if (UR(2)) { // 随机选择字节序 + u32 pos = UR(temp_len - 3); // 随机选择位置 + *(u32*)(out_buf + pos) -= 1 + UR(ARITH_MAX); // 减少双字的值 } else { - - u32 pos = UR(temp_len - 3); - u32 num = 1 + UR(ARITH_MAX); - - *(u32*)(out_buf + pos) = - SWAP32(SWAP32(*(u32*)(out_buf + pos)) - num); - + u32 pos = UR(temp_len - 3); // 随机选择位置 + u32 num = 1 + UR(ARITH_MAX); // 随机生成减少的值 + *(u32*)(out_buf + pos) = SWAP32(SWAP32(*(u32*)(out_buf + pos)) - num); // 使用大端序减少双字的值 } - break; - case 9: - - /* Randomly add to dword, random endian. */ + case 9: // 操作9:随机增加一个双字的值,随机选择字节序 - if (temp_len < 4) break; - - if (UR(2)) { - - u32 pos = UR(temp_len - 3); - - *(u32*)(out_buf + pos) += 1 + UR(ARITH_MAX); + /* Randomly add to dword, random endian. */ // 随机增加一个双字的值,随机选择字节序 + if (temp_len < 4) break; // 如果缓冲区长度小于4,跳过 + if (UR(2)) { // 随机选择字节序 + u32 pos = UR(temp_len - 3); // 随机选择位置 + *(u32*)(out_buf + pos) += 1 + UR(ARITH_MAX); // 增加双字的值 } else { - - u32 pos = UR(temp_len - 3); - u32 num = 1 + UR(ARITH_MAX); - - *(u32*)(out_buf + pos) = - SWAP32(SWAP32(*(u32*)(out_buf + pos)) + num); - + u32 pos = UR(temp_len - 3); // 随机选择位置 + u32 num = 1 + UR(ARITH_MAX); // 随机生成增加的值 + *(u32*)(out_buf + pos) = SWAP32(SWAP32(*(u32*)(out_buf + pos)) + num); // 使用大端序增加双字的值 } - break; - case 10: + case 10: // 操作10:随机异或一个字节的值 /* Just set a random byte to a random value. Because, why not. We use XOR with 1-255 to eliminate the - possibility of a no-op. */ - - out_buf[UR(temp_len)] ^= 1 + UR(255); + possibility of a no-op. */ // 随机异或一个字节的值,避免无操作 + out_buf[UR(temp_len)] ^= 1 + UR(255); // 随机异或一个字节的值 break; - case 11 ... 12: { + case 11 ... 12: { // 操作11-12:删除随机长度的字节 /* Delete bytes. We're making this a bit more likely than insertion (the next option) in hopes of keeping - files reasonably small. */ - - u32 del_from, del_len; - - if (temp_len < 2) break; - - /* Don't delete too much. */ - - del_len = choose_block_len(temp_len - 1); - - del_from = UR(temp_len - del_len + 1); + files reasonably small. */ // 删除字节,比插入操作更频繁,以保持文件大小合理 + u32 del_from, del_len; // 定义删除的起始位置和长度 - memmove(out_buf + del_from, out_buf + del_from + del_len, - temp_len - del_from - del_len); + if (temp_len < 2) break; // 如果缓冲区长度小于2,跳过 - temp_len -= del_len; + /* Don't delete too much. */ // 不要删除太多 + del_len = choose_block_len(temp_len - 1); // 随机选择删除的长度 + del_from = UR(temp_len - del_len + 1); // 随机选择删除的起始位置 + memmove(out_buf + del_from, out_buf + del_from + del_len, temp_len - del_from - del_len); // 移动缓冲区内容以删除字节 + temp_len -= del_len; // 更新缓冲区长度 break; - } - case 13: - - if (temp_len + HAVOC_BLK_XL < MAX_FILE) { - - /* Clone bytes (75%) or insert a block of constant bytes (25%). */ - - u8 actually_clone = UR(4); - u32 clone_from, clone_to, clone_len; - u8* new_buf; - - if (actually_clone) { - - clone_len = choose_block_len(temp_len); - clone_from = UR(temp_len - clone_len + 1); + case 13: // 操作13:克隆或插入随机长度的字节 - } else { + if (temp_len + HAVOC_BLK_XL < MAX_FILE) { // 如果缓冲区长度加上最大块长度小于最大文件大小 - clone_len = choose_block_len(HAVOC_BLK_XL); - clone_from = 0; + /* Clone bytes (75%) or insert a block of constant bytes (25%). */ // 克隆字节(75%)或插入一个常量字节块(25%) + u8 actually_clone = UR(4); // 随机决定是否克隆 + u32 clone_from, clone_to, clone_len; // 定义克隆的起始位置、目标位置和长度 + u8* new_buf; // 定义新的缓冲区 + if (actually_clone) { // 如果选择克隆 + clone_len = choose_block_len(temp_len); // 随机选择克隆的长度 + clone_from = UR(temp_len - clone_len + 1); // 随机选择克隆的起始位置 + } else { // 如果选择插入常量字节块 + clone_len = choose_block_len(HAVOC_BLK_XL); // 随机选择插入的长度 + clone_from = 0; // 起始位置为0 } - clone_to = UR(temp_len); + clone_to = UR(temp_len); // 随机选择目标位置 - new_buf = ck_alloc_nozero(temp_len + clone_len); - - /* Head */ + new_buf = ck_alloc_nozero(temp_len + clone_len); // 分配新的缓冲区 + /* Head */ // 复制头部 memcpy(new_buf, out_buf, clone_to); - /* Inserted part */ - + /* Inserted part */ // 插入部分 if (actually_clone) - memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); + memcpy(new_buf + clone_to, out_buf + clone_from, clone_len); // 克隆字节 else - memset(new_buf + clone_to, - UR(2) ? UR(256) : out_buf[UR(temp_len)], clone_len); - - /* Tail */ - memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, - temp_len - clone_to); + memset(new_buf + clone_to, UR(2) ? UR(256) : out_buf[UR(temp_len)], clone_len); // 插入常量字节块 - ck_free(out_buf); - out_buf = new_buf; - temp_len += clone_len; + /* Tail */ // 复制尾部 + memcpy(new_buf + clone_to + clone_len, out_buf + clone_to, temp_len - clone_to); + ck_free(out_buf); // 释放旧的缓冲区 + out_buf = new_buf; // 更新缓冲区指针 + temp_len += clone_len; // 更新缓冲区长度 } - break; - case 14: { + case 14: { // 操作14:覆盖随机长度的字节 /* Overwrite bytes with a randomly selected chunk (75%) or fixed - bytes (25%). */ - - u32 copy_from, copy_to, copy_len; - - if (temp_len < 2) break; + bytes (25%). */ // 用随机选择的块(75%)或固定字节(25%)覆盖字节 + u32 copy_from, copy_to, copy_len; // 定义覆盖的起始位置、目标位置和长度 - copy_len = choose_block_len(temp_len - 1); + if (temp_len < 2) break; // 如果缓冲区长度小于2,跳过 - copy_from = UR(temp_len - copy_len + 1); - copy_to = UR(temp_len - copy_len + 1); - - if (UR(4)) { + copy_len = choose_block_len(temp_len - 1); // 随机选择覆盖的长度 + copy_from = UR(temp_len - copy_len + 1); // 随机选择覆盖的起始位置 + copy_to = UR(temp_len - copy_len + 1); // 随机选择目标位置 + if (UR(4)) { // 75%的概率使用随机选择的块覆盖 if (copy_from != copy_to) - memmove(out_buf + copy_to, out_buf + copy_from, copy_len); - - } else memset(out_buf + copy_to, - UR(2) ? UR(256) : out_buf[UR(temp_len)], copy_len); - + memmove(out_buf + copy_to, out_buf + copy_from, copy_len); // 移动缓冲区内容以覆盖字节 + } else { // 25%的概率使用固定字节覆盖 + memset(out_buf + copy_to, UR(2) ? UR(256) : out_buf[UR(temp_len)], copy_len); // 使用固定字节覆盖 + } break; - } /* Values 15 and 16 can be selected only if there are any extras - present in the dictionaries. */ - - case 15: { + present in the dictionaries. */ // 只有在字典中存在额外数据时,才能选择操作15和16 - /* Overwrite bytes with an extra. */ + case 15: { // 操作15:用额外数据覆盖字节 - if (!extras_cnt || (a_extras_cnt && UR(2))) { + /* Overwrite bytes with an extra. */ // 用额外数据覆盖字节 + if (!extras_cnt || (a_extras_cnt && UR(2))) { // 如果没有用户指定的额外数据,或者有自动检测的额外数据且随机选择 /* No user-specified extras or odds in our favor. Let's use an - auto-detected one. */ + auto-detected one. */ // 使用自动检测的额外数据 + u32 use_extra = UR(a_extras_cnt); // 随机选择一个自动检测的额外数据 + u32 extra_len = a_extras[use_extra].len; // 获取额外数据的长度 + u32 insert_at; // 定义插入位置 - u32 use_extra = UR(a_extras_cnt); - u32 extra_len = a_extras[use_extra].len; - u32 insert_at; + if (extra_len > temp_len) break; // 如果额外数据长度大于缓冲区长度,跳过 - if (extra_len > temp_len) break; + insert_at = UR(temp_len - extra_len + 1); // 随机选择插入位置 + memcpy(out_buf + insert_at, a_extras[use_extra].data, extra_len); // 用额外数据覆盖字节 + } else { // 如果有用户指定的额外数据且随机选择 - insert_at = UR(temp_len - extra_len + 1); - memcpy(out_buf + insert_at, a_extras[use_extra].data, extra_len); + /* No auto extras or odds in our favor. Use the dictionary. */ // 使用用户指定的额外数据 + u32 use_extra = UR(extras_cnt); // 随机选择一个用户指定的额外数据 + u32 extra_len = extras[use_extra].len; // 获取额外数据的长度 + u32 insert_at; // 定义插入位置 - } else { - - /* No auto extras or odds in our favor. Use the dictionary. */ - - u32 use_extra = UR(extras_cnt); - u32 extra_len = extras[use_extra].len; - u32 insert_at; - - if (extra_len > temp_len) break; - - insert_at = UR(temp_len - extra_len + 1); - memcpy(out_buf + insert_at, extras[use_extra].data, extra_len); + if (extra_len > temp_len) break; // 如果额外数据长度大于缓冲区长度,跳过 + insert_at = UR(temp_len - extra_len + 1); // 随机选择插入位置 + memcpy(out_buf + insert_at, extras[use_extra].data, extra_len); // 用额外数据覆盖字节 } - break; - } - case 16: { + case 16: { // 操作16:插入额外数据 - u32 use_extra, extra_len, insert_at = UR(temp_len + 1); - u8* new_buf; + u32 use_extra, extra_len, insert_at = UR(temp_len + 1); // 定义额外数据、长度和插入位置 + u8* new_buf; // 定义新的缓冲区 /* Insert an extra. Do the same dice-rolling stuff as for the - previous case. */ - - if (!extras_cnt || (a_extras_cnt && UR(2))) { + previous case. */ // 插入额外数据,与操作15类似 + if (!extras_cnt || (a_extras_cnt && UR(2))) { // 如果没有用户指定的额外数据,或者有自动检测的额外数据且随机选择 - use_extra = UR(a_extras_cnt); - extra_len = a_extras[use_extra].len; + use_extra = UR(a_extras_cnt); // 随机选择一个自动检测的额外数据 + extra_len = a_extras[use_extra].len; // 获取额外数据的长度 - if (temp_len + extra_len >= MAX_FILE) break; + if (temp_len + extra_len >= MAX_FILE) break; // 如果插入后缓冲区长度超过最大文件大小,跳过 - new_buf = ck_alloc_nozero(temp_len + extra_len); + new_buf = ck_alloc_nozero(temp_len + extra_len); // 分配新的缓冲区 - /* Head */ + /* Head */ // 复制头部 memcpy(new_buf, out_buf, insert_at); - /* Inserted part */ - memcpy(new_buf + insert_at, a_extras[use_extra].data, extra_len); + /* Inserted part */ // 插入部分 + memcpy(new_buf + insert_at, a_extras[use_extra].data, extra_len); // 插入自动检测的额外数据 + } else { // 如果有用户指定的额外数据且随机选择 - } else { + use_extra = UR(extras_cnt); // 随机选择一个用户指定的额外数据 + extra_len = extras[use_extra].len; // 获取额外数据的长度 - use_extra = UR(extras_cnt); - extra_len = extras[use_extra].len; + if (temp_len + extra_len >= MAX_FILE) break; // 如果插入后缓冲区长度超过最大文件大小,跳过 - if (temp_len + extra_len >= MAX_FILE) break; + new_buf = ck_alloc_nozero(temp_len + extra_len); // 分配新的缓冲区 - new_buf = ck_alloc_nozero(temp_len + extra_len); - - /* Head */ + /* Head */ // 复制头部 memcpy(new_buf, out_buf, insert_at); - /* Inserted part */ - memcpy(new_buf + insert_at, extras[use_extra].data, extra_len); - + /* Inserted part */ // 插入部分 + memcpy(new_buf + insert_at, extras[use_extra].data, extra_len); // 插入用户指定的额外数据 } - /* Tail */ - memcpy(new_buf + insert_at + extra_len, out_buf + insert_at, - temp_len - insert_at); - - ck_free(out_buf); - out_buf = new_buf; - temp_len += extra_len; + /* Tail */ // 复制尾部 + memcpy(new_buf + insert_at + extra_len, out_buf + insert_at, temp_len - insert_at); + ck_free(out_buf); // 释放旧的缓冲区 + out_buf = new_buf; // 更新缓冲区指针 + temp_len += extra_len; // 更新缓冲区长度 break; - } - } - } - if (common_fuzz_stuff(argv, out_buf, temp_len)) - goto abandon_entry; + if (common_fuzz_stuff(argv, out_buf, temp_len)) // 调用通用模糊测试函数处理当前缓冲区 + goto abandon_entry; // 如果返回非零值,跳转到abandon_entry /* out_buf might have been mangled a bit, so let's restore it to its - original size and shape. */ - - if (temp_len < len) out_buf = ck_realloc(out_buf, len); - temp_len = len; - memcpy(out_buf, in_buf, len); + original size and shape. */ // out_buf可能已被修改,因此将其恢复到原始大小和形状 + if (temp_len < len) out_buf = ck_realloc(out_buf, len); // 如果缓冲区长度小于原始长度,重新分配内存 + temp_len = len; // 恢复缓冲区长度 + memcpy(out_buf, in_buf, len); // 将输入缓冲区内容复制回输出缓冲区 /* If we're finding new stuff, let's run for a bit longer, limits - permitting. */ - - if (queued_paths != havoc_queued) { - - if (perf_score <= HAVOC_MAX_MULT * 100) { - stage_max *= 2; - perf_score *= 2; + permitting. */ // 如果发现了新的路径,允许在限制范围内运行更长时间 + if (queued_paths != havoc_queued) { // 如果已排队的路径数发生变化 + if (perf_score <= HAVOC_MAX_MULT * 100) { // 如果性能评分小于等于HAVOC_MAX_MULT * 100 + stage_max *= 2; // 将最大阶段循环次数翻倍 + perf_score *= 2; // 将性能评分翻倍 } - - havoc_queued = queued_paths; - + havoc_queued = queued_paths; // 更新已排队的路径数 } - } - new_hit_cnt = queued_paths + unique_crashes; + new_hit_cnt = queued_paths + unique_crashes; // 计算新的命中计数 - if (!splice_cycle) { - stage_finds[STAGE_HAVOC] += new_hit_cnt - orig_hit_cnt; - stage_cycles[STAGE_HAVOC] += stage_max; - } else { - stage_finds[STAGE_SPLICE] += new_hit_cnt - orig_hit_cnt; - stage_cycles[STAGE_SPLICE] += stage_max; + if (!splice_cycle) { // 如果没有进行文件拼接 + stage_finds[STAGE_HAVOC] += new_hit_cnt - orig_hit_cnt; // 更新HAVOC阶段的发现计数 + stage_cycles[STAGE_HAVOC] += stage_max; // 更新HAVOC阶段的循环计数 + } else { // 如果进行了文件拼接 + stage_finds[STAGE_SPLICE] += new_hit_cnt - orig_hit_cnt; // 更新SPLICE阶段的发现计数 + stage_cycles[STAGE_SPLICE] += stage_max; // 更新SPLICE阶段的循环计数 } -#ifndef IGNORE_FINDS +#ifndef IGNORE_FINDS // 如果没有定义IGNORE_FINDS + + /************ * SPLICING *