AFL源码阅读笔记(三)—— fuzzer 核心代码 afl-fuzz.c
创始人
2024-05-11 06:49:23
0

书接上回:AFL源码阅读笔记(二)—— llvm_mode 和 pass 源码

💬 前两个笔记,我们看了两类插桩模式(gcc 和 llvm)及其代码。尽管插桩是 fuzzer 的一个重要环节,但我们不能只看到一点而忽略整体。afl-fuzz.c 文件就撑起了 AFL 整体,包括了种子变异、种子队列、种子选择等模糊测试的核心概念。
🧭 afl-fuzz.c 代码洋洋洒洒 8900 多行,对代码的解读不可能像前两个笔记一样,一行一行读。这部分代码阅读重在捋逻辑,弄清各部分间的关系。

四、AFL 的骨架 —— afl-fuzz.c

程序作者(谷歌大佬)对整体代码的注释:

/* american fuzzy lop - fuzzer code --------------------------------由 Michael Zalewski 编写和维护;Forkserver 由 Jann Horn 设计这部分是真家伙(the real deal): 程序接受一个插桩的二进制文件,并尝试各种基本的模糊测试技巧,关注它们如何影响执行路径。
*/

4.1 头文件

头文件主要有三类来源,自定义头文件、C 标准库和 Linux C 头文件
自定义头文件有:config.htypes.hdebug.halloc-inl.hhash.handroid-ashmen.h
Linux C 的头文件格式为 ,如

4.2 准备工作(代码环境、变量定义 …)

(1)对于 Linux 环境,定义宏 HAVE_AFFINITY

#ifdef __linux__
#	define HAVE_AFFINITY 1
#endif /* __linux__ */

这个 affinity 是亲和的意思,这里指 CPU 亲和性。这样的直译让人迷惑,其实它指的就是 CPU 绑定。后面代码对 CPU 亲和性有处理。

CPU affinity 是一种调度属性, 它可以将一个进程“绑定” 到一个或一组CPU上。

(2)全局变量定义

作者对这部分做了一个描述,“许多全局变量,但它们主要是状态 UI 和其它没必要作为函数参数到处拖来拖去的东西”。
EXP_ST 是定义的宏,可以为空,可以为 static

#ifdef AFL_LIB
#	define EXP_ST			// 空
#else
#	define EXP_ST static	// 静态
#endif /* ^AFL_LIB */

至于变量类型,它们在 types.h 中定义。u 代表无符号 n 位整型,s 代表有符号 n 位整型。各变量含义见英文注释就行。

(3)测试用例队列 结构体

这是一个重要定义,测试用例队列也是 fuzzing 的核心概念之一,在整个模糊测试过程中都要维护这样一个队列。

struct queue_entry {u8* fname;		 // 测试用例的文件名 u32 len;		 // 输入长度,u8 cal_failed,	 // 校准失败?trim_done,	 // 修剪完了(即去除部分测试用例)? was_fuzzed,	 // 是否已完成过 fuzzing passed_det, 	 // Deterministic stages passed? has_new_cov,	 // 触发新的覆盖率? var_behavior, // Variable behavior?favored, 	 // Currently favored?fs_redundant; // Marked as redundant in the fs? u32 bitmap_size, // Number of bits set in bitmap exec_cksum;  // Checksum of the execution trace u64 exec_us,	 // 执行时间(微秒)handicap,	 // Number of queue cycles behind depth;		 // Path depth u8* trace_mini;  // Trace bytes, if keptu32 tc_ref; 	 // Trace bytes ref count struct queue_entry *next,	  // 队列下一结点,如果有的话*next_100; // 100 elements ahead
};

(4)额外数据 结构体

struct extra_data {u8* data;u32 len;u32 hit_cnt;
};

(5)枚举类型

代码中定义了三种枚举类型,用作 Fuzzing 的阶段标识和错误码。
第一部分是 /* Fuzzing stages */,表示 fuzzer 的种子变异策略

enum {/* 00 */ STAGE_FLIP1,	// 翻转 1 bit/* 01 */ STAGE_FLIP2,	// 翻转 2 bit.../* 16 */ STAGE_SPLICE
};

第二部分是 /* Stage value types */

enum {/* 00 */ STAGE_VAL_NONE,/* 01 */ STAGE_VAL_LE,/* 02 */ STAGE_VAL_BE
};

第三部分是/* Execution status fault codes */,对应执行过程中出现的异常。

enum {/* 00 */ FAULT_NONE,.../* 05 */ FAULT_NOBITS
};

4.3 main() 函数

上一篇:C# 装箱和拆箱

下一篇:PHP 过滤器

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...