☰
Jellyfin 如何搭建 AFL++ 与 SharpFuzz 环境并运行模糊测试用例?
2026/10/19 10:12:01 网站建设 项目流程

Jellyfin 如何搭建 AFL++ 与 SharpFuzz 环境并运行模糊测试用例?

【免费下载链接】jellyfinThe Free Software Media System - Server Backend & API项目地址: https://gitcode.com/GitHub_Trending/je/jellyfin

Jellyfin 仓库的fuzz/目录下内置了两个基于 SharpFuzz 的模糊测试工程,用来对Jellyfin.Api与Emby.Server.Implementations中的特定函数做 AFL++ 驱动的模糊测试。本文按 fuzz/README.md 的流程,说明如何安装 AFL++ 与 SharpFuzz 工具、选择仓库已有的模糊测试用例并实际运行,以及如何判断运行是否按预期进行。

仓库中已有哪些模糊测试用例

两个 fuzz 工程各提供一组入口,用例名在 Program.cs 与 Program.cs 的switch分支中定义,fuzz.sh的第一个参数就是这些用例名:

工程目录可用用例名被测对象
fuzz/Jellyfin.Api.FuzzUrlDecodeQueryFeatureUrlDecodeQueryFeature 中间件
fuzz/Emby.Server.Implementations.FuzzPathExtensions.TryReplaceSubPathPathExtensions.TryReplaceSubPath
fuzz/Emby.Server.Implementations.FuzzSqliteItemRepository.ItemImageInfoFromValueStringSqliteItemRepository.ItemImageInfoFromValueString

每个用例在对应工程的Testcases/<用例名>/下带有种子输入文件(如 test1.txt),例如UrlDecodeQueryFeature的种子是一段 URL 编码字符串a%3D1%26b%3D2%26c%3D3。

环境前提

  • 两个 fuzz 工程均面向net10.0(见 Jellyfin.Api.Fuzz.csproj),且 global.json 固定要求 .NET SDK10.0.0(rollForward: latestMinor),因此运行环境需要 .NET 10 SDK。
  • 仓库通过 Directory.Packages.props 统一管理SharpFuzz包版本(2.3.0),构建 fuzz 工程时会自动还原。
  • AFL++ 需要从源码编译安装,使用make与 root 权限(sudo)。

第一步:安装 AFL++

按 fuzz/README.md 的 Setup 说明执行:

git clone https://github.com/AFLplusplus/AFLplusplus cd AFLplusplus make all sudo make install

注意sudo make install会以管理员权限把 AFL++ 安装到系统目录(含afl-fuzz等命令),这是一次影响系统环境的操作;如果当前账号没有 sudo 权限,需要先向环境管理员申请或改用具备权限的机器。

第二步:安装 SharpFuzz.CommandLine 全局工具

dotnet tool install --global SharpFuzz.CommandLine

这个全局工具提供sharpfuzz命令,fuzz 脚本用它对目标程序集做插桩。

第三步:进入目标 fuzz 工程目录并运行脚本

fuzz/README.md 说明:在对应工程的目录中运行fuzz.sh,并传入要执行的模糊测试用例名。以Jellyfin.Api.Fuzz的UrlDecodeQueryFeature为例,从仓库根目录切入后执行:

cd fuzz/Jellyfin.Api.Fuzz sh fuzz.sh UrlDecodeQueryFeature

其他用例同理,在 fuzz/Emby.Server.Implementations.Fuzz 目录下运行:

sh fuzz.sh PathExtensions.TryReplaceSubPath # 或 sh fuzz.sh SqliteItemRepository.ItemImageInfoFromValueString

用例名必须与Program.cs中switch分支的字符串完全一致,传入未知名称时进程会抛出ArgumentException: Unknown fuzzing function: <你传入的名称>。

脚本内部做了哪些事

以 fuzz/Jellyfin.Api.Fuzz/fuzz.sh 为例,脚本内容很短,执行顺序为:

dotnet build -c Release ../../Jellyfin.Api/Jellyfin.Api.csproj --output bin sharpfuzz bin/Jellyfin.Api.dll cp bin/Jellyfin.Api.dll . dotnet build mkdir -p Findings AFL_SKIP_BIN_CHECK=1 afl-fuzz -i "Testcases/$1" -o "Findings/$1" -t 5000 ./bin/Debug/net10.0/Jellyfin.Api.Fuzz "$1"
  • 第一行:Release 构建被测工程(Jellyfin.Api),输出到脚本同级的bin目录。
  • 第二行:用sharpfuzz对bin/Jellyfin.Api.dll插桩,生成可供 AFL++ 在进程外调用的版本。
  • 第三行:把插桩后的Jellyfin.Api.dll复制回工程目录。这一步是必要的,因为 Jellyfin.Api.Fuzz.csproj 通过<HintPath>Jellyfin.Api.dll</HintPath>本地引用工程目录下的Jellyfin.Api.dll,复制后 fuzz 工程才会链接到插桩版本。
  • 第四行:构建 fuzz 工程本身(Debug)。
  • 最后一行:启动afl-fuzz,种子输入目录为Testcases/<用例名>,结果输出到Findings/<用例名>,-t 5000是脚本为单次执行设置的超时参数,AFL_SKIP_BIN_CHECK=1是脚本设置的 AFL++ 环境变量,用于跳过其对二进制的检查。

Emby.Server.Implementations.Fuzz的 fuzz.sh 结构完全相同,只是构建对象换成了Emby.Server.Implementations工程、harness 路径换成了./bin/Debug/net10.0/Emby.Server.Implementations.Fuzz。

脚本开头有set -e,任何一步失败(例如sharpfuzz未安装、目标工程构建失败)都会立即中止,所以“脚本一路跑完并进入afl-fuzz前台运行”本身就说明前几步成功。

如何判断运行结果

  • afl-fuzz在前台持续运行,把发现的用例写入Findings/<用例名>/目录;脚本不会自动生成该目录之外的其他产物。
  • 传错用例名时,进程会直接抛出上面提到的ArgumentException,这是脚本流程中最快的失败信号。
  • 种子输入需要符合各用例期望的格式:PathExtensions.TryReplaceSubPath的输入按:切分且必须恰好得到 3 段(见 Program.cs 中data.Split(':')的判断),不满足时该输入会被跳过;仓库自带的种子 test1.txt 中夹带了原作者的本地路径(/home/bond/dev/jellyfin/),只作为种子示例存在。

边界与限制

  • 仓库当前只提供上表列出的三个用例;harness 中没有的函数无法直接模糊测试,需要自行在对应工程的Program.cs中新增分支。
  • 运行依赖 .NET 10 SDK(global.json),在低版本 SDK 上构建会直接失败。
  • 本文只覆盖fuzz/README.md给出的安装与运行流程,未涉及如何向 AFL++ 添加自定义编译器选项或使用托管版 AFL 编译器,仓库文档中没有对应说明。

【免费下载链接】jellyfinThe Free Software Media System - Server Backend & API项目地址: https://gitcode.com/GitHub_Trending/je/jellyfin

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询