转载AFL(American Fuzzy Lop)源码详细解读(1)
AFL(American Fuzzy Lop)源码详细解读(1)
多亏大佬们的文章,对读源码帮助很大:
https://eternalsakura13.com/2020/08/23/afl/
http://rk700.github.io/
最近在读AFL的源码,主要是主文件 afl-fuzz.c, 里面还是有很多细节需要注意,对一些重要的函数做了详细解读,部分函数大概知道是做什么的就可以了。其中还有些小问题没有理解,欢迎有兴趣的同学纠正以及讨论。
由于有些重要的函数在不同阶段有不同的作用,所以是分阶段记录的,本篇只是一部分,后续还会更新。

一、准备阶段

1.获取命令行参数

-i:设置输入文件夹, 如果in_dir = “-”, 设置 in_place_resume = 1。
-o: 设置输出文件夹。
-M: 用于并行fuzz,设置主fuzzer的sync_id。
-S: 用于并行fuzz,设置从fuzzer的sync_id。
-f: 模糊程序读取case的位置,out_file变量在这一步被赋值。
-x: 设置自定义的token,token就是一些容易触发漏洞的输入,(比如边界值,很大的数等),用于后面变异过程中的替换和插入,extras_dir被赋值。
-t: 设置被测程序的运行时间限制,exec_tmout被赋值为时间;如果后缀为’+‘ ,timeout_given=2,否则timeout_given=1,表示已经设置了运行时间限制。
-m:设置被测程序的内存空间大小,单位为M,mem_limit被赋值为内存大小;mem_limit_given = 1,表示已经设置了运行内存。
-b:应该是设置绑定CPU核心数量?基本用不到。
-d:跳过变异时的确定性变异阶段,skip_deterministic = 1; use_splicing = 1(重新组合输入文件)。
-B:也是基本用不到,大概就是发现了一个有趣的测试用例,并且想要单独对它变异进行测试。紧跟的输入参数是一个位图,in_bitmap被赋值。
-C:将一个导致crash测试用例作为afl-fuzz的输入,可以快速地产生很多和输入crash相关、但稍有些不同的crashes。crash_mode = 2。
-n:非插桩模式 dumb_mode = 1。
-T:还没注意到这个参数有什么用,基本上用不到。
-Q:QEMU模式,qemu_mode = 1,在此模式下,如果输入参数没有设置被测程序的内存空间大小,则设置mem_limit = 200。
-V:版本信息。
default:usage() 函数显示使用提示,各个参数的作用。

2. setup_signal_handlers 注册信号处理函数

setup_signal_handlers();某些情况下(如 stop、timeout)会终止子进程和forkserver。

3. check_asan_opts 检查内存

check_asan_opts(); 读取环境变量 ASAN_OPTIONS 和 MSAN_OPTIONS,做一些必要性检查。ASAN是一个快速的内存错误检测工具。

4.检查环境变量

no_forkserver = 0

no_cpu_meter_red = 0

no_arith = 0

shuffle_queue = 0

fast_cal = 0

5. save_cmdline 保存命令行参数至内存

orig_cmdline 被赋值为保存命令行参数的内存首地址。

如:命令行参数为:afl-fuzz -i ./in -o ./out ./test

argc = 6
argv[0] = afl-fuzz
argv[1] = -i
argv[2] = ./in
argv[3] = -o
argv[4] = ./out
argv[5] = ./test

6. fix_up_banner 修剪并创建运行标语

use_banner 被赋值,长度不超过40。

如输入的命令行参数为:afl-fuzz -i ./in -o ./out ./test,则use_banner = test。

(目前还不知道use_banner有啥用)。

7. check_if_tty 检查是否运行UI界面

not_on_tty = 1时不运行UI界面,但是一般not_on_tty = 0

8. get_core_count 获取CPU内核数量

没细看,知道是干啥的就行了。

9. check_crash_handling 确保核心转储不会进入程序

如果系统配置为将核心转储文件(core)通知发送到外部程序,会导致将崩溃信息发送到Fuzzer之间的延迟增大,进而可能将崩溃被误报为超时,所以我们得临时修改core_pattern文件。

就是第一次运行时报错让你去执行的那句话(echo core > /proc/sys/kernel/core_pattern)就是因为这个函数。

10. check_cpu_governor 检查CPU管理者

检查一些环境变量,具体没细看,不是核心函数

11. setup_post 加载后置处理器

目前看来没啥用。

12. setup_shm 设置trace_bits 和 virgin_bits

trace_bits 记录当前用例的路径信息
virgin_bits 记录总的路径信息
virgin_tmout 记录超时用例的路径信息
virgin_crash 记录崩溃用例的路径信息
将virgin_bits、virgin_tmout、virgin_crash 每个数组的所有位全部置为1。

为trace_bits 注册一块共享内存(共享内存创建后,每次执行目标程序前会清0),并注册结束处理函数 atexit(remove_shm) 程序结束时,用于删除共享内存。

将共享内存的标志符会保存到环境变量中,从而之后fork()得到的子进程可以通过该环境变量,得到这块共享内存的标志符

使用变量trace_bits来保存共享内存的地址

13. init_count_class16 路径命中次数规整

规整规则如下,

[0] = 0,
[1] = 1,
[2] = 2,
[3] = 4,
[4 … 7] = 8,
[8 … 15] = 16,
[16 … 31] = 32,
[32 … 127] = 64,
[128 … 255] = 128

trace_bits是用一个字节来记录是否到达这个路径,和这个路径被命中了多少次的,即 count_class_lookup8[256]。

而在实际的规整过程中是一次规整两个字节, 即count_class_lookup16[65536]。

14. setup_dirs_fds 准备输出文件夹

out_dir/queue/
out_dir/queue/.state/
out_dir/queue/.state/deterministic_done/
out_dir/queue/.state/auto_extras/
out_dir/queue/.state/redundant_edges/
out_dir/queue/.state/variable_behavior/
out_dir/testcases
out_dir/crashes
out_dir/hangs
out_dir/plot_data

15. read_testcases() 将输入文件夹下的测试用例扫描到队列中

尝试访问 in_dir/queue 文件夹,如果存在就重新设置in_dir 为 in_dir/queue,直白点讲就是你是将自己准备的种子用例直接放在了 in_dir 下,还是放在了 indir/queue 下。

shuffle_queue = 0, 不执行这个判断代码块。

通过文件属性过滤掉 . 和 … 以及readme 和 空文件。

检查文件大小,不能超过1M。

判断是否经过确定性模糊测试。如果 out/queue/.state/deterministic_done/ 文件夹下已经存在了该文件,即已经经过确定性模糊测试,直接跳过。

最后判断如果queued_paths = 0,说明没有可用的种子。

设置 last_path_time = 0 该全局记录最新路径的时间,在add_to_queue 中被置为当前用例加入队列中的时间。在这里应该是由于是将初始种子读到队列中,还未开始执行以及发现路径,所以置 0;而后续再加入队列中的种子是提前判断发现了新路径的。

queued_at_start = queued_paths 记录初始种子的数量。

16. add_to_queue 添加到队列

创建queue_entry 结构体,设置name,len,depth,passed_det,全局变量max_depth。
如果队列为空,即第一个添加的用例,q_prev100 = queue = queue_top 都指向当前用例;否则,直接追加到队列中。
更新全局变量 queued_paths(当前队列中的用例数量)和 pending_not_fuzzed (待测试的用例数量)。
cycles_wo_finds = 0,目前还不知道这个全局变量的作用。
队列中每100个用例做个标记 ,如当前队列中有230个用例,则第一个的 1.next_100 指向 101,101.nex_100 指向 201, 201.next_100 = null。
last_path_time = get_cur_time()

17. load_auto 加载自动生成的tokens

token就是一些容易触发漏洞的输入,比如边界值等等,除了用户自己可以准备token外,AFL也会自动生成一些token

out_dir/.state/auto_extras/auto_i 该文件不存在,所以fd < 0,直接break了。

18. pivot_inputs 创建硬链接

遍历队列,将队列中的所有用例都在 out_dir/queue/ 下创建硬链接。准备阶段队列中只有 in_dir 下的种子用例。
nfn, rsl 都赋值为文件名
判断 rsl 的前三个字符是否为 id: ,并且取出来的orig_id是否等于 id,如果满足条件,说明当前在resume阶段,置resuming_fuzz = 1。查看queue文件夹下的文件,可以看到命名为id:000001,src:000000,op:havoc,rep:32+cov (这个if代码块好像从头到尾都不执行,其中一个 resuming_fuzz 变量就一直不会被赋值为1,这个变量的大概意思应该是把之前fuzz过程中变异生成的用例当作本次fuzz的种子用例,此时会执行这个代码块,resuming_fuzz才会被赋值为1,不确定这里理解的对不对)。
接着取出文件的src_id ,找到其父亲用例,即该用例是在谁的基础上演变来的。更新当前用例的深度以及最大深度
如果是在准备阶段, use_name 赋值为文件名, nfn = out_dir/queue/id:…,orig:use_name
调用 link_or_copy ,尝试创建链接,失败则直接拷贝。
修改q->fname 为nfn,如 case 改为 id:xxxxxx,orig:case
如果要跳过确定性变异阶段,则调用mark_as_det_done 在 out_dir/queue/.state/deterministic_done/ 下创建相应的文件,只是创建空文件。
如果in_place_resume 不为0,即输入命令行参数时 in_idr = “-”, 则不保留 out_dir/_resume/.state/ 各个文件夹下对应的文件。
19. load_extras 加载用户提供的tokens
将用户提供的token读取到 extra_data 结构体中保存,并且按照从大到小排序,每个token不能超过128字节,extras_cnt记录数量。

20. find_timeout

命令行参数没有给-t,并且是在resume阶段,设置exec_tmout,但是由于resuming_fuzz = 0 ,这个函数直接return了,所以timeout_given还是等于0。

21. detect_file_args 识别@@

获取当前工作目录。
进入循环,查看每一个参数,其实正常情况下这里就传过来了一个参数 “@@”。
查找当前参数中是否有@@,如果有
如果输入命令行参数没有-f,则out_file = null, 所以这里out_file 会被赋一个默认值, out_file = out_dir/.cur_input
不管是绝对路径还是相对路径,都规整成绝对路径
argv[0] = “” , aa_loc + 2 = “” , aa_subst = /home/…/./out_dir/.cur_input(…是自己所在的文件夹)
构造新的参数并赋值 @@ -> /home/…/./out_dir/.cur_input(…是自己所在的文件夹)
将aa_loc 在 改成 ‘@’ ,不知道这一步有什么用
否则,查看下一个参数

23. setup_stdio_file

如果没有入命令行参数没有-f, 并且也没有@@,执行该函数

在out_dir 下创建 .cur_input 文件,并将文件描述符赋值给 out_fd, 执行完这个函数后,out_file 还是null

24. check_binary 检查目标文件

检查指定路径要执行的程序是否存在,是否为shell脚本,同时检查elf文件头是否合法及程序是否被插桩

25. get_cur_time 记录开始时间

26. 检查是否是qemu_mode

AFL(American Fuzzy Lop)-afl-fuzz.c相关推荐

  1. AFL(american fuzzy lop)学习一

    AFL(american fuzzy lop)学习一 @sizaf AFL 的模糊方法 基于改进的边缘覆盖 插桩法引导的遗传算法 流程: 插桩 从源码编译程序时进行插桩,以记录代码覆盖率(Code C ...

  2. AFL——American Fuzzy Lop的基础使用

    AFL--American Fuzzy Lop的基础使用 因为某些奇怪的原因,我一个没搞过pwn的得来搞代码fuzz,只好学一下,顺便记一下. AFL的安装 在部分源有的情况下可以直接使用apt-ge ...

  3. AFL(American Fuzzy Lop)源码详细解读(1)

    AFL(American Fuzzy Lop)源码详细解读(1) 多亏大佬们的文章,对读源码帮助很大: https://eternalsakura13.com/2020/08/23/afl/ http ...

  4. AFL(American Fuzzy Lop)源码详细解读(3)

    AFL(American Fuzzy Lop)源码详细解读(3) 本篇是关于主循环阶段的内容,整个AFL最核心的部分,篇幅较长.最后简述一下afl_fuzz整体流程. 多亏大佬们的文章,对读源码帮助很 ...

  5. AFL(American Fuzzy Lop)源码详细解读(2)

    AFL(American Fuzzy Lop)源码详细解读(2) 本篇是关于 dry run (空跑.演练) 阶段的内容,一直到主循环之前. 多亏大佬们的文章,对读源码帮助很大: https://et ...

  6. AFL(american fuzzy lop)学习二

    AFL(american fuzzy lop)学习二 @sizaif @2022-04-10 设计思想 覆盖率计算 改进边缘覆盖: 向目标程序注入以下工具来捕获分支(边缘)覆盖率和分支命中计数 一条边 ...

  7. AFL(american fuzzy lop)学习三

    AFL(american fuzzy lop)学习三 @sizaif @2022-04-11 fork Server 为了提高性能,afl-fuzz 使用"fork server" ...

  8. American Fuzzy Lop(AFL)的安装与简单使用

    American Fuzzy Lop 1.AFL安装与试用 AFL不支持在Windows下使用,所以安装在Linux下,我的是Ubuntu系统. 安装LLVM 和 CLANG $ sudo apt-g ...

  9. AFL(American Fuzzy Lop)源码详细解读(8)

    这篇记录 llvm mode 中的 afl-llvm-pass.so.cc 文件和 afl-llvm-rt.o.c 文件,以及整体流程的简述. 对llvm这部分理解还比较浅. 可以阅读大佬的这篇文章: ...

最新文章

  1. “互联网+”的时代,易佳互联也随着时代步伐前进着
  2. 一年有几个月几个季度_胎教几个月开始 注意事项有哪些?
  3. 关于OC-省市区习题
  4. Spring中DispacherServlet、WebApplicationContext、ServletContext的关系
  5. oracle groupq by,oracle group by 性能优化
  6. 我国企业对开源社区的贡献度_开源社区对我意味着什么
  7. 中文命名之Hibernate 5演示 - 使用注解(annotation)而非xml定义映射
  8. c# 循环com,分别对串口写入与读取,获取需要的串口信息
  9. 等参元:平面四节点四边形等参元的刚度矩阵的计算
  10. 加权平均数的例子_加权平均数定义和实例
  11. 《达芬奇•科学第一人》麦克•怀特
  12. 在计算机上如何打开资源管理器,资源管理器怎么打开?打开资源管理器的5种方法...
  13. 8路sdi(DVI)多媒体分布式互动录播主机4K输出
  14. 正则表达式常用的校验方法
  15. FOP生成PDF中文乱码问题解决
  16. 联想拯救者 独显模式下亮度无法调节 解决方法记录
  17. iPhoneX上必须要有的几款手机APP
  18. 大疆自动驾驶,首次官宣即交货
  19. 交互媒体专题设计------《The Wiley Handbook of Human Computer Interaction》
  20. linux挂载移动硬盘乱码

热门文章

  1. 三维电子沙盘 虚拟数字沙盘 M3D GIS开发教程
  2. 后台管理UI皮肤的选择
  3. 将doc转存为docx
  4. php中utf8是什么意思,php – 什么是标准化UTF-8关于?
  5. python输入一个三位数的整数、求该数的3个数字之和_Python3 数字(Number)
  6. 二十不惑的年纪,竟靠着这份前端面试指南,有幸拿到字节跳动实习offer,简直在起飞
  7. CSS 文本字体怎么设置颜色
  8. 访客一体机 新一代科技门卫
  9. python用matplotlib画表格_Python图表绘制工具:Matplotlib_Part 1
  10. 键盘记录工具的制作 qq密码键盘记录器