AFL源码分析之afl-fuzz.c
作为 AFL 中最重要的一个部分,也就是 fuzzer 实现的关键步骤。因为篇幅太长,会将源码分成好几个模块来介绍
准备工作
gettimeofday() 用来获取当前准确时间,接着用 srandom 根据当前时间与当前进程异或之后获取随机种子。
getopt() 函数读取参数并作出相应处理。
setup_signal_handlers()
调用sigaction
,设置信号处理函数
信号 | 作用 |
---|---|
SIGHUP/SIGINT/SIGTERM | 处理各种“stop”情况 |
SIGALRM | 处理超时的情况 |
SIGWINCH | 处理窗口大小 |
SIGUSER1 | 用户自定义信号,这里定义为skip request |
SIGSTP/SIGPIPE | 不是很重要的一些信号,可以不用关心 |
1 | EXP_ST void setup_signal_handlers(void) { |
check_asan_opts()
读取环境变量ASAN_OPTIONS
和MSAN_OPTIONS
,并做相应的检查
1 | static void check_asan_opts(void) { |
fix_up_sync()
如果通过 -M
或者-S
指定了 sync_id
,则更新 out_dir
和 sync_dir
的值:设置 sync_dir
的值为 out_dir
,设置 out_dir
的值为out_dir/sync_id
1 | static void fix_up_sync(void) { |
save_cmdline()
Copy 当前命令行参数
1 | static void save_cmdline(u32 argc, char** argv) { |
fix_up_banner()
获取目标程序名称或程序路径或路径+省略号
1 | static void fix_up_banner(u8* name) { |
check_if_tty()
检查是否在 tty 终端上面运行
1 | static void check_if_tty(void) { |
几个CPU检查相关的函数
get_core_count()
:获取 CPU 数量check_crash_handling()
:确保核心转储不会进入程序check_cpu_governor()
:检查CPU管理者
setup_post()
如果设置AFL_POST_LIBRARY
环境变量,则加载 afl_postprocess() 函数
1 | static void setup_post(void) { |
setup_shm()(very important)
用于设置共享内存和 virgin_bits
1 | EXP_ST void setup_shm(void) { |
init_count_class16()
统计 AFL 遍历路径的次数
1 | static const u8 count_class_lookup8[256] = { |
setup_dirs_fds()
准备输出文件夹和文件描述符
1 | /* Prepare output directories and fds. */ |
read_testcases()
从输入文件夹中读取所有文件,然后将它们排队进行测试。
1 | static void read_testcases(void) { |
load_auto()
load自动生成的提取出来的词典token
1 | static void load_auto(void) { |