Libfuzzer 源码阅读(一)¶
FuzzerBuiltins.h¶
定义了一些包装函数和宏
-
cstdint
是 C++11 引入的头文件,定义了一些标准的整数类型,如int8_t
、int16_t
、int32_t
、int64_t
、uint8_t
、uint16_t
、uint32_t
、uint64_t
等。 -
FuzzerPlatform.h:定义了一些平台相关的宏和函数。
部分函数及命名空间定义¶
C++
语言的命名空间是一种用于组织代码的机制,主要用于避免名称冲突。命名空间允许将标识符(如变量、函数、类等)分组,从而在不同的命名空间中可以使用相同的名称而不会产生冲突。
Bswap
系列函数:用于字节序转换,分别处理8位、16位、32位和64位整数。Clzll
:计算无符号长整型的前导零数量。Popcountll
:计算无符号长整型的位数中1的数量。
FuzzerPlatform.h¶
主要用于定义与平台相关的宏,以便在不同操作系统上进行模糊测试
__has_feature
:用于检查编译器是否支持某个特性。address_sanitizer
:地址检测器。memory_sanitizer
:内存检测器。ATTRIBUTE_NO_SANITIZE_ALL
:用于指示编译器不要对函数进行某种类型的检测。
内存/地址检测器¶
- AddressSanitizer:地址检测器,用于检测内存访问错误。
FuzzerBuiltinsMsvc.h¶
主要用于在MSVC编译器下提供一些内置函数的替代实现
C++ | |
---|---|
- FuzzerPlatform.h:定义了一些平台相关的宏和函数。
C++ | |
---|---|
定义了GET_CALLER_PC()
宏,使用_ReturnAddress()
替代__builtin_return_address()
,因为后者在MSVC中不可用。
Bswap
系列函数:用于字节序转换,分别处理8位、16位、32位和64位整数。Clzll
:计算无符号长整型的前导零数量。Popcountll
:计算无符号长整型的位数中1的数量。
FuzzerCommand.h¶
C++ | |
---|---|
- FuzzerDefs.h:定义了一些常量和数据结构。
- FuzzerIO.h:定义了一些输入输出相关的函数。
sstream
:定义了一些用于字符串流的类。algorithm
:定义了一些用于操作序列的函数。string
:定义了一些用于字符串操作的函数。vector
:定义了一些用于向量操作的函数。thread
:定义了一些用于线程操作的函数。
C++ | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
|
该段代码定义了一个 Command
类,主要用于管理命令行参数和相关操作。以下是逐部分分析:
Command类定义¶
class Command final
: 定义了一个不可继承的Command
类。
公共成员¶
- 静态方法:
static inline const char *ignoreRemainingArgs()
: 返回一个字符串,表示命令行参数的结束标志。
- 构造函数:
Command()
: 默认构造函数,初始化CombinedOutAndErr
为false
。explicit Command(const std::vector<std::string> &ArgsToAdd)
: 接受参数列表并初始化。explicit Command(const Command &Other)
: 拷贝构造函数,复制其他Command
对象的成员。
- 赋值运算符:
Command &operator=(const Command &Other)
: 赋值运算符重载,复制成员并返回当前对象的引用。
- 析构函数:
~Command()
: 默认析构函数。
成员函数¶
-
参数管理:
bool hasArgument(const std::string &Arg)
: 检查给定参数是否存在。const std::vector<std::string> &getArguments() const
: 获取当前所有命令行参数。void addArgument(const std::string &Arg)
: 在标志前添加参数。void addArguments(const std::vector<std::string> &ArgsToAdd)
: 批量添加参数。void removeArgument(const std::string &Arg)
: 移除指定参数。
-
标志管理:
bool hasFlag(const std::string &Flag)
: 检查给定标志是否存在。std::string getFlagValue(const std::string &Flag)
: 获取标志的值。void addFlag(const std::string &Flag, const std::string &Value)
: 添加带值的标志。void removeFlag(const std::string &Flag)
: 移除带值的标志。
-
输出管理:
bool hasOutputFile() const
: 检查是否有输出文件。const std::string &getOutputFile() const
: 获取当前输出文件名。void setOutputFile(const std::string &FileName)
: 设置输出文件名。bool isOutAndErrCombined() const
: 检查标准错误是否与标准输出合并。void combineOutAndErr(bool combine = true)
: 设置标准错误与标准输出的合并状态。
-
字符串表示:
std::string toString() const
: 返回命令的字符串表示,通常是命令行格式。
私有成员¶
-
成员变量:
std::vector<std::string> Args
: 存储命令行参数。bool CombinedOutAndErr
: 指示标准错误是否重定向到标准输出。std::string OutputFile
: 存储输出文件名。
-
私有方法:
std::vector<std::string>::iterator endMutableArgs()
: 返回可变参数的结束迭代器。std::vector<std::string>::const_iterator endMutableArgs() const
: 返回可变参数的结束常量迭代器。
FuzzerIO.h¶
FuzzerIO.h
文件主要用于定义模糊测试中的输入输出(IO)相关的函数接口。以下是对代码的逐行分析:
C++ | |
---|---|
-
FuzzerDefs.h:定义了一些常量和数据结构。
-
函数声明:
-
时间和文件处理(第18-27行):
GetEpoch
:获取指定路径的时间戳。FileToVector
:将文件内容读取到字节向量中。FileToString
:将文件内容读取为字符串。CopyFileToErr
:将文件内容复制到标准错误输出。WriteToFile
:重载函数,用于将数据写入文件。
-
追加和读取文件(第32-41行):
AppendToFile
:将数据追加到文件。ReadDirToVectorOfUnits
:读取目录中的文件并存储到单位向量中。
-
路径处理(第39-48行):
DirPlusFile
:返回目录和文件名的组合路径。DirName
:获取文件名的目录部分。TmpDir
:获取临时目录路径。TempPath
:生成临时文件路径。
-
文件特性检查(第51-53行):
IsInterestingCoverageFile
:检查文件是否为有趣的覆盖文件。
-
标准输出和错误处理(第53-66行):
DupAndCloseStderr
:复制并关闭标准错误输出。CloseStdout
:关闭标准输出。
-
输出文件管理(第58-59行):
GetOutputFile
和SetOutputFile
:获取和设置输出文件。
-
打印函数(第61-66行):
Puts
、Printf
、VPrintf
:用于输出字符串和格式化输出。
-
平台特定函数(第68-72行):
IsFile
、IsDirectory
、FileSize
:检查路径是否为文件或目录,并获取文件大小。
-
目录操作(第73-85行):
ListFilesInDirRecursive
:递归列出目录中的文件。MkDirRecursive
和RmDirRecursive
:递归创建和删除目录。IterateDirRecursive
:递归遍历目录,执行回调函数。
-
-
结构体定义(第87-90行):
SizedFile
:包含文件名和大小,并重载小于运算符。
-
文件处理函数(第93-112行):
GetSizedFilesFromDir
:获取目录中所有文件及其大小。OpenFile
、CloseFile
、DuplicateFile
、RemoveFile
、RenameFile
等函数用于文件的打开、关闭、复制、删除和重命名。
FuzzerDefs.h¶
FuzzerDefs.h
文件主要用于定义模糊测试中的基本数据结构和函数接口。
C++ | |
---|---|
cassert
:定义了一些宏,用于在程序中插入调试断言。cstddef
:定义了一些与C标准库相关的宏。cstdint
:定义了一些标准的整数类型,如int8_t
、int16_t
、int32_t
、int64_t
、uint8_t
、uint16_t
、uint32_t
、uint64_t
等。cstring
:定义了一些与C标准库相关的宏。memory
:定义了一些与内存操作相关的函数。set
:定义了一些与集合操作相关的函数。string
:定义了一些与字符串操作相关的函数。vector
:定义了一些与向量操作相关的函数。
C++ | |
---|---|
- 模板函数:
Min
函数:返回两个值中的较小者。Max
函数:返回两个值中的较大者。
C++ | |
---|---|
- 类和结构的前向声明:声明了多个类和结构
C++ | |
---|---|
- 类型定义:
Unit
:定义为std::vector<uint8_t>
,表示一个字节数组。UnitVector
:定义为std::vector<Unit>
,表示多个字节数组的集合。UserCallback
:定义为一个函数指针类型,接受字节数据和大小作为参数。
C++ | |
---|---|
- 函数声明:
FuzzerDriver
:主驱动函数,接受命令行参数和用户回调函数。ExtraCountersBegin
和ExtraCountersEnd
:用于获取额外计数器的起始和结束地址。ClearExtraCounters
:清除额外计数器的函数。
C++ | |
---|---|
- 全局变量:声明了一个外部布尔变量
RunningUserCallback
,可能用于指示用户回调是否正在运行。
FuzzerUtil.h¶
C++ | |
---|---|
- FuzzerBuiltins.h:定义了一些包装函数和宏。
- FuzzerBuiltinsMsvc.h:在MSVC编译器下提供一些内置函数的替代实现。
- FuzzerCommand.h:定义了一些命令行参数相关的函数。
- FuzzerDefs.h:定义了一些常量和数据结构。
函数定义:
PrintHexArray
和PrintASCII
:用于打印十六进制数组和ASCII字符。ToASCII
和IsASCII
:用于检查和转换数据为ASCII格式。Base64
:将数据编码为Base64格式。PrintPC
和DescribePC
:用于打印程序计数器信息。ExecuteCommand
:执行命令并可获取输出。CloneArgsWithoutX
:克隆参数,排除特定值。SimpleFastHash
:计算数据的快速哈希值。
内存管理:
提供了与内存相关的函数,如RoundUpByPage
和RoundDownByPage
,用于按页面大小对齐指针。
平台特定功能
SetSignalHandler
:设置信号处理程序,处理模糊测试中的特定信号。SleepSeconds
:使线程暂停指定的秒数。GetPid
:获取当前进程的ID。GetPeakRSSMb
:获取当前进程的峰值常驻集大小(RSS)。ExecuteCommand
:执行命令并可获取输出。OpenProcessPipe
:打开进程管道以执行命令。CloseProcessPipe
:关闭打开的进程管道。
C++ | |
---|---|
字节序转换:
根据字节序定义了HostToLE
模板函数。