afl-fuzz
2023-09-14 09:37:25 0 举报
关于afl 2.52b版本代码阅读进行的流程图总结
作者其他创作
大纲/内容
queue_cur
rlen == 4
init_count_class16
find_timeout
环境变量一些读写
N
如果通过 -M或者-S指定了 sync_id,则更新 out_dir 和 sync_dir 的值:设置 sync_dir 的值为 out_dir,设置 out_dir 的值为out_dir/sync_id
copy to use_mem
其他情形
确保核心转储不会进入程序检查当进程崩溃时系统如何dump文件,这也是为啥没有设置好/proc/sys/kernel/core_pattern的时候,afl会提醒设置echo core >/proc/sys/kernel/core_pattern的函数。 这样设置的原因是因为core_pattern指定了当发生崩溃的时候如何处理崩溃,系统中默认会将崩溃信息通过管道发送给外部程序,运行效率很低,影响fuzz效率, 因此需要将它保存为本地的文件以提高效率。
将每个种子文件作为输入,运行目标程序一次,查看系统运行的状态是否正确
fork()
queue_cur = queue_cur->next; current_entry++;
T
save_if_interesting
cksum=hash32()
check_cpu_governor
show_init_stats
destroy_queue
AFL 的突变分为两类:span style=\
pivot_inputs
...
q->exec_cksum = cksumfirst_trace=trace_bits
Y
结束
open fd
perform_dry_run
cull_queue
处理超时操作并返回
main
q->exec_cksum != cksum
如果指定了resuming_fuzz即从输出目录当中恢复模糊测试状态,会从之前的模糊测试状态fuzzer_stats文件中计算中timeout值,保存在exec_tmout中
如果目标程序的输入不是来源于文件而是来源于标准输入的话,则将目录文件\"%s/.cur_input\"文件打开保存在out_fd文件句柄中,后续将标准输入重定向到该文件中
calibrate_case
common_fuzz_stuff
创建所有的输出目录,打开部分全局的文件句柄。创建输出目录queue、crashes、hangs等,打开文件句柄dev_null_fd、dev_urandom_fd以及plot_file等。
queue_cur = queue_cur->next
orig_in,in_buf,out_buf
调用 sigaction ,注册信号处理函数,设置信号句柄。
在输出目录中为输入测试用例创建硬链接,选择好名字,并据此进行调整
q->exec_cksum
timeout_given
read_testcases
SPLICING拼接操作
初始化样例路径覆盖状态变量virgin_bits、超时样例路径覆盖状态变量virgin_tmout、崩溃样例路径覆盖状态变量virgin_crash, 用于后续存储样例覆盖目标程序运行路径的状态;使用SYSTEM V申请共享内存trace_bits,用于后续存储每次样例运行所覆盖的路径
copy当前命令行参数,保存
len = queue_cur->len
检查cpu的调节器,来使得cpu可以处于高效的运行状态
更新var_bytes
RITHMETIC INC/DEC算术操作
F
读取环境变量 ASAN_OPTIONS 和 MSAN_OPTIONS,做一些必要性检查
setup_shm
trim_case修剪
dumb_mode == 1 || no_forkserver
q->has_new_cov = 1;queued_with_cov++;
FAULT_TMOUT
如果指定了环境变量AFL_POST_LIBRARY,则会从指定的动态链接库so中加载函数afl_postprocess并将函数指针存储到post_handler当中, 每次在运行样例前都会尝试调用该函数。这样做的内涵是提供一个接口来让用户hook模糊测试,在模糊测试过程中执行自定义的功能代码。
计算加入队列的节点sksum
fix_up_sync
统计q信息
setup_post
waitpid
RANDOM HAVOC随机操作
update_bitmap_score
逐个读取种子目录下的输入文件列表,并调用add_to_queue函数将相关信息(文件名称、大小等)存入到全局的种子队列queue当中,作为后续模糊测试的种子来源。单个种子信息保存在结构体queue_entry当中,形成单链表。
extras_dir
check_if_tty
!hnb
T, 没有新路径
out_file
get_core_count
检查是否在tty终端上面运行:读取环境变量 AFL_NO_UI ,如果存在,设置 not_on_tty 为1,并返回;通过 ioctl 读取window size,如果报错为 ENOTTY,表示当前不在一个tty终端运行,设置 not_on_tty。
setup_dirs_fds
精简队列
destroy_extras
calculate_score打分
处理crash
T, 循环停止
异常错误处理
check_binary
write_to_testcase
fuzz_one
FAULT_ERROR,default
stage_cur < stage_max
子进程?
fault
write_stats_file
find_start_position
DICTIONARY STUFF附加变异
解析命令行参数
check_asan_opts
FAULT_CRASH
自动更新token,目录/queue/.state/autoextras/auto
尝试在输入目录下寻找自动生成的字典文件,调用maybe_add_auto将相应的字典加入到全局变量a_extras中,用于后续字典模式的变异当中
bind_to_free_cpu
新的一次轮询初始化工作
继续
total_crashes 加1
save_cmdline
detect_file_args
add_to_queue
!child_pid
开始
stop_soon
init_forkserver
check_crash_handling
fault == FAULT_TMOUT
AFL
INTERESTING VALUES变形操作
run_target
save_auto
q = queue
Start
变异完后均会调用
post_handler
fsrv_ctl_fd = ctl_pipe[1]
hnb = has_new_bits(virgin_bits)
N,父进程
queue_cur->cal_failed
保存hang or crash test case
load_extras
收尾工作
写入文件并执行,然后处理结果,如果出现错误,就返回1 没有错误,则判断这个变异是否为一个感兴趣的变异(save_if_interesting)
获取CPU核心数量
// 检测输入的命令行中是否包含@@参数,如果包含的话需要将@@替换成目录文件\"%s/.cur_input\
这个函数评估input文件夹下的case,来发现这些testcase的行为是否异常;以及在发现新的路径bits时,用以评估这个新发现的testcase的行为是否是可变variable(这里的可变是指多次执行这个case,发现的路径不同)等等
write_bitmap
q!=null
dumb_mode != 1 && !no_forkserver && !forksrv_pid
queue_cycle++queue_cur = queue............
处理超时情况
SIMPLE BITFLIP翻转位操作
fsrv_st_fd = st_pipe[0]
dumb_mode == 1 || no_forkserver
res = calibrate_case(*)
setup_stdio_file
forksrv_pid = fork()
是否显示stats
如果指定了-x参数(字典模式),加载对应的字典到全局变量extras当中,用于后续字典模式的变异当中
load_auto
end
use_argv 构建
q = q->next
skip_requested是否跳过当前输入的执行
state_namestage_max
!queue_cur
skip_requested = 0; cur_skipped_paths++; return 1;
setup_signal_handlers
classify_counts((u64*)trace_bits)
Y 子进程
new_bits == 2 && !q->has_new_cov
crash_mode
fault == crash_mode
!dumb_mode && !queue_cur->trim_done
show_stats
has_new_bits
0 条评论
下一页