# Conflicts:
#	src/afl-showmap.c
main
BagPipeOuO 2 months ago
commit 34e563f83c

@ -172,7 +172,11 @@ static void setup_shm(void) {// 创建共享内存,分配给 trace_bits 用于
}
<<<<<<< HEAD
/* 写入测试结果 */
=======
/* 配置共享内存。 */
>>>>>>> 31b9bf56f4cc249d8b6bb414203bff28d8cf724a
static u32 write_results(void) { //将插桩结果输出到文件,支持二进制和文本模式。
@ -242,7 +246,13 @@ static u32 write_results(void) { //将插桩结果输出到文件,支持二进
}
<<<<<<< HEAD
/* 处理超时信号 */
=======
/* 处理超时信号。 */
>>>>>>> 31b9bf56f4cc249d8b6bb414203bff28d8cf724a
static void handle_timeout(int sig) {
@ -252,8 +262,14 @@ static void handle_timeout(int sig) {
}
<<<<<<< HEAD
/* 执行目标程序 */
=======
/* 执行目标应用程序。 */
/* 运行目标程序并等待其结束。 */
/* 处理超时和信号。 */
>>>>>>> 31b9bf56f4cc249d8b6bb414203bff28d8cf724a
static void run_target(char** argv) {
static struct itimerval it;/* 定时器结构 */
@ -428,8 +444,9 @@ static void setup_signal_handlers(void) {
}
/* Detect @@ in args. */
/* 检测@@在参数中。 */
/* 检测并替换@@参数。 */
/* 用于处理传递给目标程序的文件路径参数。 */
static void detect_file_args(char** argv) {
// 获取当前工作目录,用于构造绝对路径。
@ -473,15 +490,20 @@ static void detect_file_args(char** argv) {
}
<<<<<<< HEAD
/* Show banner. */
// 打印工具的名称和版本信息。
=======
>>>>>>> 31b9bf56f4cc249d8b6bb414203bff28d8cf724a
static void show_banner(void) {
SAYF(cCYA "afl-showmap " cBRI VERSION cRST " by <lcamtuf@google.com>\n");
}
/* Display usage hints. */
/* 显示使用提示。 */
static void usage(u8* argv0) {
@ -516,8 +538,14 @@ static void usage(u8* argv0) {
}
<<<<<<< HEAD
/* Find binary. */
// 找到目标程序的可执行文件路径 (target_path)。
=======
/* 查找二进制文件。 */
/* 查找并验证二进制文件。 */
/* 如果二进制文件不存在或不可执行,则打印错误信息并退出。 */
>>>>>>> 31b9bf56f4cc249d8b6bb414203bff28d8cf724a
static void find_binary(u8* fname) {
// fname目标程序的文件名。如果 fname 包含斜杠(表明是路径)或没有设置 PATH 环境变量,则直接检查 fname 是否是一个可执行文件。否则,遍历 PATH 环境变量中定义的路径,尝试找到 fname。
u8* env_path = 0;
@ -569,8 +597,15 @@ static void find_binary(u8* fname) {
}
<<<<<<< HEAD
/* Fix up argv for QEMU. */
// 为在 QEMU 模式下执行目标程序,调整参数列表 argv。
=======
/*修正argv以用于QEMU*/
/* 为QEMU模式修正参数*/
/* 返回新的参数数组*/
>>>>>>> 31b9bf56f4cc249d8b6bb414203bff28d8cf724a
static char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
// own_loc当前程序的路径用于寻找 afl-qemu-trace。argv原始参数列表。argc参数个数。
char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
@ -635,7 +670,8 @@ static char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
/* Main entry point */
/*解析命令行参数并执行目标程序 */
/*根据参数执行不同的操作 */
int main(int argc, char** argv) {
//opt用于存储当前解析的命令行选项。
//mem_limit_given标志是否设置了内存限制选项。

@ -1,82 +1,88 @@
// 如果是Android平台且尚未定义_ANDROID_ASHMEM_H则定义它
#ifdef __ANDROID__
#ifndef _ANDROID_ASHMEM_H
#define _ANDROID_ASHMEM_H
// 包含所需的头文件
#include <fcntl.h>
#include <linux/ashmem.h>
#include <linux/ashmem.h> // 包含ashmem相关的ioctl操作
#include <linux/shm.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/mman.h> // 包含内存映射函数
// 如果Android API级别大于或等于26Android 8.0则使用Bionic的shm*函数
#if __ANDROID_API__ >= 26
#define shmat bionic_shmat
#define shmctl bionic_shmctl
#define shmdt bionic_shmdt
#define shmget bionic_shmget
#endif
#include <sys/shm.h>
#include <sys/shm.h> // 包含标准的共享内存函数
#undef shmat
#undef shmctl
#undef shmdt
#undef shmget
#undef shmget // 取消对Bionic函数的重定义
#include <stdio.h>
// 定义ashmem设备的路径
#define ASHMEM_DEVICE "/dev/ashmem"
static inline int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf) {
int ret = 0;
if (__cmd == IPC_RMID) {
int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL);
struct ashmem_pin pin = {0, length};
ret = ioctl(__shmid, ASHMEM_UNPIN, &pin);
close(__shmid);
}
return ret;
// 定义shmctl函数的封装用于删除共享内存
static inline int shmctl(int __shmid, int __cmd, struct shmid_ds* __buf) {
int ret = 0;
if (__cmd == IPC_RMID) {
int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL);
struct ashmem_pin pin = { 0, length };
ret = ioctl(__shmid, ASHMEM_UNPIN, &pin);
close(__shmid);
}
return ret;
}
// 定义shmget函数的封装用于创建共享内存
static inline int shmget(key_t __key, size_t __size, int __shmflg) {
(void) __shmflg;
int fd, ret;
char ourkey[11];
(void)__shmflg;
int fd, ret;
char ourkey[11];
fd = open(ASHMEM_DEVICE, O_RDWR);
if (fd < 0)
return fd;
fd = open(ASHMEM_DEVICE, O_RDWR);
if (fd < 0)
return fd;
sprintf(ourkey, "%d", __key);
ret = ioctl(fd, ASHMEM_SET_NAME, ourkey);
if (ret < 0)
goto error;
sprintf(ourkey, "%d", __key);
ret = ioctl(fd, ASHMEM_SET_NAME, ourkey);
if (ret < 0)
goto error;
ret = ioctl(fd, ASHMEM_SET_SIZE, __size);
if (ret < 0)
goto error;
ret = ioctl(fd, ASHMEM_SET_SIZE, __size);
if (ret < 0)
goto error;
return fd;
return fd;
error:
close(fd);
return ret;
close(fd);
return ret;
}
static inline void *shmat(int __shmid, const void *__shmaddr, int __shmflg) {
(void) __shmflg;
int size;
void *ptr;
// 定义shmat函数的封装用于将共享内存附加到进程地址空间
static inline void* shmat(int __shmid, const void* __shmaddr, int __shmflg) {
(void)__shmflg;
int size;
void* ptr;
size = ioctl(__shmid, ASHMEM_GET_SIZE, NULL);
if (size < 0) {
return NULL;
}
size = ioctl(__shmid, ASHMEM_GET_SIZE, NULL);
if (size < 0) {
return NULL;
}
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, __shmid, 0);
if (ptr == MAP_FAILED) {
return NULL;
}
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, __shmid, 0);
if (ptr == MAP_FAILED) {
return NULL;
}
return ptr;
return ptr;
}
#endif /* !_ANDROID_ASHMEM_H */
#endif /* !__ANDROID__ */
#endif /* !__ANDROID__ */

@ -27,8 +27,7 @@
#include "types.h"
/* Version string: */
#define VERSION "2.57b"
#define VERSION "2.57b" // 定义版本号字符串
/******************************************************
* *
@ -36,228 +35,196 @@
* *
******************************************************/
/* Comment out to disable terminal colors (note that this makes afl-analyze
a lot less nice): */
#define USE_COLOR
/* Comment out to disable terminal colors (note that this makes afl-analyze
a lot less nice): */
#define USE_COLOR // 启用终端颜色
/* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */
#define FANCY_BOXES
/* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */
#define FANCY_BOXES // 启用ANSI框绘制
/* Default timeout for fuzzed code (milliseconds). This is the upper bound,
also used for detecting hangs; the actual value is auto-scaled: */
#define EXEC_TIMEOUT 1000 // 默认超时时间(毫秒)
#define EXEC_TIMEOUT 1000
/* Timeout rounding factor when auto-scaling (milliseconds): */
#define EXEC_TM_ROUND 20
/* Timeout rounding factor when auto-scaling (milliseconds): */
#define EXEC_TM_ROUND 20 // 自动缩放时的超时舍入因子(毫秒)
/* 64bit arch MACRO */
#if (defined (__x86_64__) || defined (__arm64__) || defined (__aarch64__))
#define WORD_SIZE_64 1
#define WORD_SIZE_64 1 // 定义64位架构宏
#endif
/* Default memory limit for child process (MB): */
#ifndef WORD_SIZE_64
# define MEM_LIMIT 25
# define MEM_LIMIT 25 // 非64位架构的默认内存限制MB
#else
# define MEM_LIMIT 50
# define MEM_LIMIT 50 // 64位架构的默认内存限制MB
#endif /* ^!WORD_SIZE_64 */
/* Default memory limit when running in QEMU mode (MB): */
#define MEM_LIMIT_QEMU 200
#define MEM_LIMIT_QEMU 200 // QEMU模式下的默认内存限制MB
/* Number of calibration cycles per every new test case (and for test
cases that show variable behavior): */
#define CAL_CYCLES 8 // 每个新测试用例的校准周期数
#define CAL_CYCLES_LONG 40 // 长校准周期数
#define CAL_CYCLES 8
#define CAL_CYCLES_LONG 40
/* Number of subsequent timeouts before abandoning an input file: */
#define TMOUT_LIMIT 250
/* Number of subsequent timeouts before abandoning an input file: */
#define TMOUT_LIMIT 250 // 超时次数限制
/* Maximum number of unique hangs or crashes to record: */
#define KEEP_UNIQUE_HANG 500
#define KEEP_UNIQUE_CRASH 5000
#define KEEP_UNIQUE_HANG 500 // 最大记录的唯一挂起数
#define KEEP_UNIQUE_CRASH 5000 // 最大记录的唯一崩溃数
/* Baseline number of random tweaks during a single 'havoc' stage: */
#define HAVOC_CYCLES 256
#define HAVOC_CYCLES_INIT 1024
#define HAVOC_CYCLES 256 // 'havoc'阶段的随机调整基数
#define HAVOC_CYCLES_INIT 1024 // 'havoc'阶段的初始随机调整数
/* Maximum multiplier for the above (should be a power of two, beware
of 32-bit int overflows): */
#define HAVOC_MAX_MULT 16 // 'havoc'阶段的最大乘数
#define HAVOC_MAX_MULT 16
/* Absolute minimum number of havoc cycles (after all adjustments): */
#define HAVOC_MIN 16
/* Absolute minimum number of havoc cycles (after all adjustments): */
#define HAVOC_MIN 16 // 'havoc'阶段的绝对最小周期数
/* Maximum stacking for havoc-stage tweaks. The actual value is calculated
like this:
like this:
n = random between 1 and HAVOC_STACK_POW2
stacking = 2^n
In other words, the default (n = 7) produces 2, 4, 8, 16, 32, 64, or
128 stacked tweaks: */
#define HAVOC_STACK_POW2 7 // 'havoc'阶段的最大堆叠指数
#define HAVOC_STACK_POW2 7
/* Caps on block sizes for cloning and deletion operations. Each of these
ranges has a 33% probability of getting picked, except for the first
two cycles where smaller blocks are favored: */
#define HAVOC_BLK_SMALL 32
#define HAVOC_BLK_MEDIUM 128
#define HAVOC_BLK_LARGE 1500
/* Caps on block sizes for cloning and deletion operations. Each of these
ranges has a 33% probability of getting picked, except for the first
two cycles where smaller blocks are favored: */
#define HAVOC_BLK_SMALL 32 // 小块大小限制
#define HAVOC_BLK_MEDIUM 128 // 中块大小限制
#define HAVOC_BLK_LARGE 1500 // 大块大小限制
/* Extra-large blocks, selected very rarely (<5% of the time): */
#define HAVOC_BLK_XL 32768
/* Extra-large blocks, selected very rarely (<5% of the time): */
#define HAVOC_BLK_XL 32768 // 特大块大小限制
/* Probabilities of skipping non-favored entries in the queue, expressed as
percentages: */
#define SKIP_TO_NEW_PROB 99 // 跳过非优先队列项的概率(有新的待处理优先项)
#define SKIP_NFAV_OLD_PROB 95 // 跳过非优先队列项的概率(没有新的优先项,当前项已测试)
#define SKIP_NFAV_NEW_PROB 75 // 跳过非优先队列项的概率(没有新的优先项,当前项未测试)
#define SKIP_TO_NEW_PROB 99 /* ...when there are new, pending favorites */
#define SKIP_NFAV_OLD_PROB 95 /* ...no new favs, cur entry already fuzzed */
#define SKIP_NFAV_NEW_PROB 75 /* ...no new favs, cur entry not fuzzed yet */
/* Splicing cycle count: */
#define SPLICE_CYCLES 15
/* Splicing cycle count: */
#define SPLICE_CYCLES 15 // 拼接周期数
/* Nominal per-splice havoc cycle length: */
#define SPLICE_HAVOC 32
#define SPLICE_HAVOC 32 // 每次拼接的'havoc'周期长度
/* Maximum offset for integer addition / subtraction stages: */
#define ARITH_MAX 35
#define ARITH_MAX 35 // 整数加减阶段的最大偏移量
/* Limits for the test case trimmer. The absolute minimum chunk size; and
the starting and ending divisors for chopping up the input file: */
#define TRIM_MIN_BYTES 4 // 测试用例修剪器的最小块大小
#define TRIM_START_STEPS 16 // 测试用例修剪器的起始除数
#define TRIM_END_STEPS 1024 // 测试用例修剪器的结束除数
#define TRIM_MIN_BYTES 4
#define TRIM_START_STEPS 16
#define TRIM_END_STEPS 1024
/* Maximum size of input file, in bytes (keep under 100MB): */
#define MAX_FILE (1 * 1024 * 1024)
/* Maximum size of input file, in bytes (keep under 100MB): */
#define MAX_FILE (1 * 1024 * 1024) // 输入文件的最大大小(字节)
/* The same, for the test case minimizer: */
#define TMIN_MAX_FILE (10 * 1024 * 1024)
#define TMIN_MAX_FILE (10 * 1024 * 1024) // 测试用例最小化器的最大文件大小
/* Block normalization steps for afl-tmin: */
#define TMIN_SET_MIN_SIZE 4
#define TMIN_SET_STEPS 128
#define TMIN_SET_MIN_SIZE 4 // afl-tmin的块归一化最小大小
#define TMIN_SET_STEPS 128 // afl-tmin的块归一化步数
/* Maximum dictionary token size (-x), in bytes: */
#define MAX_DICT_FILE 128
#define MAX_DICT_FILE 128 // 最大字典令牌大小(字节)
/* Length limits for auto-detected dictionary tokens: */
#define MIN_AUTO_EXTRA 3
#define MAX_AUTO_EXTRA 32
#define MIN_AUTO_EXTRA 3 // 自动检测的字典令牌的最小长度
#define MAX_AUTO_EXTRA 32 // 自动检测的字典令牌的最大长度
/* Maximum number of user-specified dictionary tokens to use in deterministic
steps; past this point, the "extras/user" step will be still carried out,
but with proportionally lower odds: */
#define MAX_DET_EXTRAS 200 // 最大用户指定字典令牌数
#define MAX_DET_EXTRAS 200
/* Maximum number of auto-extracted dictionary tokens to actually use in fuzzing
(first value), and to keep in memory as candidates. The latter should be much
higher than the former. */
#define USE_AUTO_EXTRAS 50
#define MAX_AUTO_EXTRAS (USE_AUTO_EXTRAS * 10)
/* Scaling factor for the effector map used to skip some of the more
expensive deterministic steps. The actual divisor is set to
2^EFF_MAP_SCALE2 bytes: */
/* Maximum number of auto-extracted dictionary tokens to actually use in fuzzing
(first value), and to keep in memory as candidates. The latter should be much
higher than the former. */
#define USE_AUTO_EXTRAS 50 // 实际用于模糊测试的自动提取字典令牌数
#define MAX_AUTO_EXTRAS (USE_AUTO_EXTRAS * 10) // 内存中候选的自动提取字典令牌数
#define EFF_MAP_SCALE2 3
/* Scaling factor for the effector map used to skip some of the more
expensive deterministic steps. The actual divisor is set to
2^EFF_MAP_SCALE2 bytes: */
#define EFF_MAP_SCALE2 3 // 效应器映射的缩放因子
/* Minimum input file length at which the effector logic kicks in: */
#define EFF_MIN_LEN 128
/* Minimum input file length at which the effector logic kicks in: */
#define EFF_MIN_LEN 128 // 效应器逻辑触发的最小输入文件长度
/* Maximum effector density past which everything is just fuzzed
unconditionally (%): */
#define EFF_MAX_PERC 90 // 最大效应器密度(%
#define EFF_MAX_PERC 90
/* UI refresh frequency (Hz): */
#define UI_TARGET_HZ 5
/* UI refresh frequency (Hz): */
#define UI_TARGET_HZ 5 // UI刷新频率Hz
/* Fuzzer stats file and plot update intervals (sec): */
#define STATS_UPDATE_SEC 60
#define PLOT_UPDATE_SEC 5
#define STATS_UPDATE_SEC 60 // 模糊统计文件更新间隔(秒)
#define PLOT_UPDATE_SEC 5 // 模糊统计图表更新间隔(秒)
/* Smoothing divisor for CPU load and exec speed stats (1 - no smoothing). */
#define AVG_SMOOTHING 16
#define AVG_SMOOTHING 16 // CPU负载和执行速度统计的平滑除数
/* Sync interval (every n havoc cycles): */
#define SYNC_INTERVAL 5
#define SYNC_INTERVAL 5 // 同步间隔每n个havoc周期
/* Output directory reuse grace period (minutes): */
#define OUTPUT_GRACE 25
#define OUTPUT_GRACE 25 // 输出目录重用宽限期(分钟)
/* Uncomment to use simple file names (id_NNNNNN): */
// #define SIMPLE_FILES
// #define SIMPLE_FILES // 取消注释以使用简单文件名
/* List of interesting values to use in fuzzing. */
// 定义一系列有趣的值,用于模糊测试
/* 定义一组有趣的8位值用于模糊测试包括边界值和常见缓冲区大小 */
#define INTERESTING_8 \
-128, /* Overflow signed 8-bit when decremented */ \
-1, /* */ \
0, /* */ \
1, /* */ \
16, /* One-off with common buffer size */ \
32, /* One-off with common buffer size */ \
64, /* One-off with common buffer size */ \
100, /* One-off with common buffer size */ \
127 /* Overflow signed 8-bit when incremented */
-128, /* 减1时溢出的有符号8位值 */ \
-1, /* 通用的有趣值 */ \
0, /* 零值,常用于测试 */ \
1, /* 通用的有趣值 */ \
16, /* 常用缓冲区大小的偏移量 */ \
32, /* 常用缓冲区大小的偏移量 */ \
64, /* 常用缓冲区大小的偏移量 */ \
100, /* 常用缓冲区大小的偏移量 */ \
127 /* 加1时溢出的有符号8位值 */
/* 定义一组有趣的16位值用于模糊测试包括边界值和常见缓冲区大小 */
#define INTERESTING_16 \
-32768, /* Overflow signed 16-bit when decremented */ \
-129, /* Overflow signed 8-bit */ \
128, /* Overflow signed 8-bit */ \
255, /* Overflow unsig 8-bit when incremented */ \
256, /* Overflow unsig 8-bit */ \
512, /* One-off with common buffer size */ \
1000, /* One-off with common buffer size */ \
1024, /* One-off with common buffer size */ \
4096, /* One-off with common buffer size */ \
32767 /* Overflow signed 16-bit when incremented */
-32768, /* 减1时溢出的有符号16位值 */ \
-129, /* 溢出的有符号8位值 */ \
128, /* 溢出的有符号8位值 */ \
255, /* 增1时溢出的无符号8位值 */ \
256, /* 溢出的无符号8位值 */ \
512, /* 常用缓冲区大小的偏移量 */ \
1000, /* 常用缓冲区大小的偏移量 */ \
1024, /* 常用缓冲区大小的偏移量 */ \
4096, /* 常用缓冲区大小的偏移量 */ \
32767 /* 加1时溢出的有符号16位值 */
/* 定义一组有趣的32位值用于模糊测试包括边界值和大数值 */
#define INTERESTING_32 \
-2147483648LL, /* Overflow signed 32-bit when decremented */ \
-100663046, /* Large negative number (endian-agnostic) */ \
-32769, /* Overflow signed 16-bit */ \
32768, /* Overflow signed 16-bit */ \
65535, /* Overflow unsig 16-bit when incremented */ \
65536, /* Overflow unsig 16 bit */ \
100663045, /* Large positive number (endian-agnostic) */ \
2147483647 /* Overflow signed 32-bit when incremented */
-2147483648LL, /* 减1时溢出的有符号32位值 */ \
-100663046, /* 大的负数(与字节序无关) */ \
-32769, /* 溢出的有符号16位值 */ \
32768, /* 溢出的有符号16位值 */ \
65535, /* 增1时溢出的无符号16位值 */ \
65536, /* 溢出的无符号16位值 */ \
100663045, /* 大的正数(与字节序无关) */ \
2147483647 /* 加1时溢出的有符号32位值 */
/***********************************************************
* *
@ -265,98 +232,66 @@
* *
***********************************************************/
/* Call count interval between reseeding the libc PRNG from /dev/urandom: */
/* 定义 libc 伪随机数生成器重新播种的调用计数间隔 */
#define RESEED_RNG 10000
/* Maximum line length passed from GCC to 'as' and used for parsing
configuration files: */
/* 定义从 GCC 传递给 'as' 的最大行长度,并用于解析配置文件 */
#define MAX_LINE 8192
/* Environment variable used to pass SHM ID to the called program. */
/* 定义用于传递共享内存ID给被调用程序的环境变量 */
#define SHM_ENV_VAR "__AFL_SHM_ID"
/* Other less interesting, internal-only variables. */
/* 定义其他不太有趣,仅内部使用的变量 */
#define CLANG_ENV_VAR "__AFL_CLANG_MODE"
#define AS_LOOP_ENV_VAR "__AFL_AS_LOOPCHECK"
#define PERSIST_ENV_VAR "__AFL_PERSISTENT"
#define DEFER_ENV_VAR "__AFL_DEFER_FORKSRV"
/* In-code signatures for deferred and persistent mode. */
/* 定义代码中用于延迟和持久模式的签名 */
#define PERSIST_SIG "##SIG_AFL_PERSISTENT##"
#define DEFER_SIG "##SIG_AFL_DEFER_FORKSRV##"
/* Distinctive bitmap signature used to indicate failed execution: */
/* 定义用于表示执行失败的独特位图签名 */
#define EXEC_FAIL_SIG 0xfee1dead
/* Distinctive exit code used to indicate MSAN trip condition: */
/* 定义用于表示MSAN内存sanitizer触发条件的独特退出代码 */
#define MSAN_ERROR 86
/* Designated file descriptors for forkserver commands (the application will
use FORKSRV_FD and FORKSRV_FD + 1): */
/* 定义用于fork服务器命令的指定文件描述符 */
#define FORKSRV_FD 198
/* Fork server init timeout multiplier: we'll wait the user-selected
timeout plus this much for the fork server to spin up. */
/* 定义fork服务器初始化超时乘数 */
#define FORK_WAIT_MULT 10
/* Calibration timeout adjustments, to be a bit more generous when resuming
fuzzing sessions or trying to calibrate already-added internal finds.
The first value is a percentage, the other is in milliseconds: */
/* 定义校准超时调整,恢复模糊测试会话或校准已添加的内部发现时更加宽松 */
#define CAL_TMOUT_PERC 125
#define CAL_TMOUT_ADD 50
/* Number of chances to calibrate a case before giving up: */
/* 定义校准一个案例前放弃的机会数 */
#define CAL_CHANCES 3
/* Map size for the traced binary (2^MAP_SIZE_POW2). Must be greater than
2; you probably want to keep it under 18 or so for performance reasons
(adjusting AFL_INST_RATIO when compiling is probably a better way to solve
problems with complex programs). You need to recompile the target binary
after changing this - otherwise, SEGVs may ensue. */
/* 定义跟踪二进制文件的映射大小 */
#define MAP_SIZE_POW2 16
#define MAP_SIZE (1 << MAP_SIZE_POW2)
/* Maximum allocator request size (keep well under INT_MAX): */
/* 定义最大分配请求大小 */
#define MAX_ALLOC 0x40000000
/* A made-up hashing seed: */
/* 定义一个虚构的哈希种子 */
#define HASH_CONST 0xa5b35705
/* Constants for afl-gotcpu to control busy loop timing: */
/* 定义 afl-gotcpu 控制忙循环计时的常量 */
#define CTEST_TARGET_MS 5000
#define CTEST_CORE_TRG_MS 1000
#define CTEST_BUSY_CYCLES (10 * 1000 * 1000)
/* Uncomment this to use inferior block-coverage-based instrumentation. Note
that you need to recompile the target binary for this to have any effect: */
/* 如果需要使用基于块覆盖的仪器,取消注释此宏 */
// #define COVERAGE_ONLY
/* Uncomment this to ignore hit counts and output just one bit per tuple.
As with the previous setting, you will need to recompile the target
binary: */
/* 如果需要忽略命中计数并且每个元组只输出一个位,取消注释此宏 */
// #define SKIP_COUNTS
/* Uncomment this to use instrumentation data to record newly discovered paths,
but do not use them as seeds for fuzzing. This is useful for conveniently
measuring coverage that could be attained by a "dumb" fuzzing algorithm: */
/* 如果需要使用仪器数据记录新发现的路径,但不使用它们作为模糊测试的种子,取消注释此宏 */
// #define IGNORE_FINDS
#endif /* ! _HAVE_CONFIG_H */
#endif /* ! _HAVE_CONFIG_H */

@ -155,54 +155,50 @@
* Misc terminal codes *
***********************/
#define TERM_HOME "\x1b[H"
#define TERM_CLEAR TERM_HOME "\x1b[2J"
#define cEOL "\x1b[0K"
#define CURSOR_HIDE "\x1b[?25l"
#define CURSOR_SHOW "\x1b[?25h"
// 定义一些额外的终端控制代码
#define TERM_HOME "\x1b[H" // 移动光标到终端左上角
#define TERM_CLEAR TERM_HOME "\x1b[2J" // 清除终端屏幕
#define cEOL "\x1b[0K" // 清除当前行从光标位置到行尾的内容
#define CURSOR_HIDE "\x1b[?25l" // 隐藏光标
#define CURSOR_SHOW "\x1b[?25h" // 显示光标
/************************
* Debug & error macros *
************************/
/* Just print stuff to the appropriate stream. */
// 定义一些宏用于调试和错误处理
// 如果配置中定义了MESSAGES_TO_STDOUT则使用printf否则使用fprintf(stderr, ...)
#ifdef MESSAGES_TO_STDOUT
# define SAYF(x...) printf(x)
#else
# define SAYF(x...) fprintf(stderr, x)
#endif /* ^MESSAGES_TO_STDOUT */
/* Show a prefixed warning. */
// 显示带前缀的警告信息
#define WARNF(x...) do { \
SAYF(cYEL "[!] " cBRI "WARNING: " cRST x); \
SAYF(cRST "\n"); \
} while (0)
/* Show a prefixed "doing something" message. */
// 显示带前缀的“正在执行”信息
#define ACTF(x...) do { \
SAYF(cLBL "[*] " cRST x); \
SAYF(cRST "\n"); \
} while (0)
/* Show a prefixed "success" message. */
// 显示带前缀的成功信息
#define OKF(x...) do { \
SAYF(cLGN "[+] " cRST x); \
SAYF(cRST "\n"); \
} while (0)
/* Show a prefixed fatal error message (not used in afl). */
// 显示带前缀的严重错误信息不在afl中使用
#define BADF(x...) do { \
SAYF(cLRD "\n[-] " cRST x); \
SAYF(cRST "\n"); \
} while (0)
/* Die with a verbose non-OS fatal error message. */
// 以详细非操作系统致命错误消息退出程序
#define FATAL(x...) do { \
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] PROGRAM ABORT : " \
cBRI x); \
@ -211,8 +207,7 @@
exit(1); \
} while (0)
/* Die by calling abort() to provide a core dump. */
// 通过调用abort()退出程序以便提供core dump
#define ABORT(x...) do { \
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] PROGRAM ABORT : " \
cBRI x); \
@ -221,8 +216,7 @@
abort(); \
} while (0)
/* Die while also including the output of perror(). */
// 以包含perror()输出的方式退出程序
#define PFATAL(x...) do { \
fflush(stdout); \
SAYF(bSTOP RESET_G1 CURSOR_SHOW cRST cLRD "\n[-] SYSTEM ERROR : " \
@ -233,16 +227,12 @@
exit(1); \
} while (0)
/* Die with FAULT() or PFAULT() depending on the value of res (used to
interpret different failure modes for read(), write(), etc). */
// 根据res的值调用FAULT()或PFAULT()用于解释read()、write()等的不同失败模式
#define RPFATAL(res, x...) do { \
if (res < 0) PFATAL(x); else FATAL(x); \
} while (0)
/* Error-checking versions of read() and write() that call RPFATAL() as
appropriate. */
// 定义ck_write和ck_read宏用于检查write和read操作是否成功并在失败时调用RPFATAL
#define ck_write(fd, buf, len, fn) do { \
u32 _len = (len); \
s32 _res = write(fd, buf, _len); \
@ -255,4 +245,4 @@
if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \
} while (0)
#endif /* ! _HAVE_DEBUG_H */
#endif /* !_HAVE_DEBUG_H */

@ -31,81 +31,94 @@
Other code written and maintained by Michal Zalewski <lcamtuf@google.com>
*/
// 检查_HAVE_HASH_H宏是否已定义如果没有则定义它以防止头文件被重复包含
#ifndef _HAVE_HASH_H
#define _HAVE_HASH_H
// 包含types.h头文件可能包含一些基本类型的定义
#include "types.h"
// 如果编译目标是x86_64架构则定义64位循环左移宏ROL64
#ifdef __x86_64__
#define ROL64(_x, _r) ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))
// 定义一个内联函数hash32用于计算32位哈希值x86_64架构专用
static inline u32 hash32(const void* key, u32 len, u32 seed) {
const u64* data = (u64*)key;
u64 h1 = seed ^ len;
len >>= 3;
while (len--) {
u64 k1 = *data++;
k1 *= 0x87c37b91114253d5ULL;
k1 = ROL64(k1, 31);
k1 *= 0x4cf5ad432745937fULL;
h1 ^= k1;
h1 = ROL64(h1, 27);
h1 = h1 * 5 + 0x52dce729;
}
h1 ^= h1 >> 33;
h1 *= 0xff51afd7ed558ccdULL;
h1 ^= h1 >> 33;
h1 *= 0xc4ceb9fe1a85ec53ULL;
h1 ^= h1 >> 33;
return h1;
// 将key转换为u64指针
const u64* data = (u64*)key;
// 初始化哈希值h1种子与长度异或
u64 h1 = seed ^ len;
// 将长度除以8因为u64是8字节
len >>= 3;
// 循环处理每个u64数据块
while (len--) {
// 读取下一个u64数据
u64 k1 = *data++;
// 应用MurmurHash算法的步骤
k1 *= 0x87c37b91114253d5ULL;
k1 = ROL64(k1, 31);
k1 *= 0x4cf5ad432745937fULL;
// 将k1合并到h1
h1 ^= k1;
h1 = ROL64(h1, 27);
h1 = h1 * 5 + 0x52dce729;
}
// 最后的哈希值处理步骤
h1 ^= h1 >> 33;
h1 *= 0xff51afd7ed558ccdULL;
h1 ^= h1 >> 33;
h1 *= 0xc4ceb9fe1a85ec53ULL;
h1 ^= h1 >> 33;
// 返回最终的哈希值
return h1;
}
// 如果编译目标不是x86_64架构则定义32位循环左移宏ROL32
#else
#define ROL32(_x, _r) ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r))))
// 定义一个内联函数hash32用于计算32位哈希值非x86_64架构专用
static inline u32 hash32(const void* key, u32 len, u32 seed) {
const u32* data = (u32*)key;
u32 h1 = seed ^ len;
len >>= 2;
while (len--) {
u32 k1 = *data++;
k1 *= 0xcc9e2d51;
k1 = ROL32(k1, 15);
k1 *= 0x1b873593;
h1 ^= k1;
h1 = ROL32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
h1 ^= h1 >> 16;
return h1;
// 将key转换为u32指针
const u32* data = (u32*)key;
// 初始化哈希值h1种子与长度异或
u32 h1 = seed ^ len;
// 将长度除以4因为u32是4字节
len >>= 2;
// 循环处理每个u32数据块
while (len--) {
// 读取下一个u32数据
u32 k1 = *data++;
// 应用MurmurHash算法的步骤
k1 *= 0xcc9e2d51;
k1 = ROL32(k1, 15);
k1 *= 0x1b873593;
// 将k1合并到h1
h1 ^= k1;
h1 = ROL32(h1, 13);
h1 = h1 * 5 + 0xe6546b64;
}
// 最后的哈希值处理步骤
h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
h1 ^= h1 >> 16;
// 返回最终的哈希值
return h1;
}
#endif /* ^__x86_64__ */
// 结束宏定义_HAVE_HASH_H
#endif /* !_HAVE_HASH_H */

@ -26,20 +26,28 @@
#include <stdlib.h>
#include <unistd.h>
// 定义程序的主函数接收命令行参数个数argc和参数值argv
int main(int argc, char** argv) {
char buf[8];
if (read(0, buf, 8) < 1) {
printf("Hum?\n");
exit(1);
}
if (buf[0] == '0')
printf("Looks like a zero to me!\n");
else
printf("A non-zero value? How quaint!\n");
exit(0);
// 定义一个字符数组buf大小为8用于存储从标准输入读取的数据
char buf[8];
// 尝试从文件描述符0标准输入读取最多8个字节的数据到buf中
if (read(0, buf, 8) < 1) {
// 如果读取的字节数小于1即读取失败则打印消息并退出程序
printf("Hum?\n");
exit(1);
}
// 检查buf的第一个字符是否为'0'
if (buf[0] == '0')
// 如果是'0',则打印一条消息表示检测到零值
printf("Looks like a zero to me!\n");
else
// 如果不是'0',则打印一条消息表示检测到非零值
printf("A non-zero value? How quaint!\n");
// 正常退出程序
exit(0);
}

@ -28,14 +28,20 @@
// TODO(metzman): Create a test/ directory to store this and other similar
// files.
// 定义一个名为LLVMFuzzerTestOneInput的函数用于接收一个字节数组buf和其大小size
int LLVMFuzzerTestOneInput(uint8_t* buf, size_t size) {
if (size < 2)
// 检查输入数据的大小是否小于2如果是则返回0表示测试不通过或无需进一步处理
if (size < 2)
return 0;
// 检查输入数据的第一个字节是否为'0'
if (buf[0] == '0')
// 如果是'0',则打印一条消息表示检测到零值
printf("Looks like a zero to me!\n");
else
// 如果不是'0',则打印一条消息表示检测到非零值
printf("A non-zero value? How quaint!\n");
// 函数返回0表示测试通过或没有发现异常
return 0;
if (buf[0] == '0')
printf("Looks like a zero to me!\n");
else
printf("A non-zero value? How quaint!\n");
return 0;
}

@ -48,27 +48,32 @@ typedef uint32_t u32;
*/
// 条件编译指令用于定义64位无符号整数类型
#ifdef __x86_64__
typedef unsigned long long u64;
typedef unsigned long long u64; // 在x86_64架构下使用unsigned long long作为u64
#else
typedef uint64_t u64;
typedef uint64_t u64; // 否则使用标准库中的uint64_t作为u64
#endif /* ^__x86_64__ */
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
// 定义有符号整数类型
typedef int8_t s8; // 8位有符号整数
typedef int16_t s16; // 16位有符号整数
typedef int32_t s32; // 32位有符号整数
typedef int64_t s64; // 64位有符号整数
// 如果没有定义MIN则定义宏MIN和MAX
#ifndef MIN
# define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a))
# define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b))
# define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a)) // 取两个值中的最小值
# define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b)) // 取两个值中的最大值
#endif /* !MIN */
// 宏定义SWAP16用于交换16位值的字节序
#define SWAP16(_x) ({ \
u16 _ret = (_x); \
(u16)((_ret << 8) | (_ret >> 8)); \
})
// 宏定义SWAP32用于交换32位值的字节序
#define SWAP32(_x) ({ \
u32 _ret = (_x); \
(u32)((_ret << 24) | (_ret >> 24) | \
@ -76,19 +81,23 @@ typedef int64_t s64;
((_ret >> 8) & 0x0000FF00)); \
})
// 条件编译指令,用于定义随机数宏
#ifdef AFL_LLVM_PASS
# define AFL_R(x) (random() % (x))
# define AFL_R(x) (random() % (x)) // 在AFL_LLVM_PASS模式下使用
#else
# define R(x) (random() % (x))
# define R(x) (random() % (x)) // 否则使用
#endif /* ^AFL_LLVM_PASS */
// 宏定义STRINGIFY_INTERNAL和STRINGIFY用于将宏参数转换为字符串
#define STRINGIFY_INTERNAL(x) #x
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
// 内存屏障用于阻止编译器和CPU对指令重排
#define MEM_BARRIER() \
__asm__ volatile("" ::: "memory")
#define likely(_x) __builtin_expect(!!(_x), 1)
#define unlikely(_x) __builtin_expect(!!(_x), 0)
// 宏定义likely和unlikely用于优化分支预测
#define likely(_x) __builtin_expect(!!(_x), 1) // 预期_x为真
#define unlikely(_x) __builtin_expect(!!(_x), 0) // 预期_x为假
#endif /* ! _HAVE_TYPES_H */

Loading…
Cancel
Save