当前位置: 首页 > news >正文

Syzkaller实战教程10: MoonShine复现Trace2syz功能演示

Moonshine 是 Syzkaller 的改进项目,由哥伦比亚大学团队开发,是一种为操作系统模糊测试工具提供紧凑且多样化种子的策略与工具,旨在提升模糊测试的效率和效果,更好地发现内核级别的漏洞。相关内容如下:

  1. 核心功能:通过分析现实世界程序的系统调用跟踪来生成种子。它利用轻量级静态分析检测不同系统调用之间的依赖关系,能够移除不必要的调用,保留最有可能触发漏洞的部分,从而生成更高效的测试种子。
  2. 实现方式:通过扩展 strace 实现了 tracer,以捕捉系统调用的名称、参数和返回值,并采用 kcov 进行代码覆盖率测量。同时,使用 smatch,一个对 C 进行静态分析的框架,来进行控制流分析,通过注册不同的 hook 来检测条件语句和赋值语句,以此确定系统调用之间的显式依赖(explicit dependencies)和隐式依赖(implicit dependencies)。
  3. 效果:从包含 280 万个系统调用的 3220 个真实世界程序跟踪中,可将其精炼到 14000 个左右的调用,同时保留 86% 的原始代码覆盖率。基于这些精炼的种子系统调用序列,Moonshine 平均可将 Syzkaller 对 Linux 内核的代码覆盖率提高 13%,还发现了 17 个 Syzkaller 未发现的 Linux 内核新漏洞。
  4. 技术栈:主要使用 Go 语言开发,借助 Ragel(状态机编译器)和 Goyacc(解析器生成器)将原始的跟踪数据转换为可用的格式。
  5. 使用限制:目前 Moonshine 只能为 Linux 上的 Syzkaller 生成种子,且只能解析通过 strace 收集的跟踪,建议使用版本大于等于 4.16 的 strace。

.Moonshine复现

SQL
# 本机复现采用环境配置版本
Moonshine:最新版
Syzkaller: commit f48c20b8f9b2a6c26629f11cc15e1c9c316572c8
Ubuntu 20.04
Go 1.11.13

安装tips:

SQL
1.保证moonshine和syzkaller的相对路径为如下:
# moonshine路径
/home/ubuntu2004/go_projects/src/github.com/shankarapailoor/moonshine
# syzkaller路径
/home/ubuntu2004/go_projects/src/github.com/google/syzkaller

2.moonshine和syzkaller的版本应该匹配:如旧版moonshine配合旧版syzkaller
本机采用moonshine配合18年syzkaller

3.moonshine和syzkaller均合适版本go编译(本机采用go1.11.13编译,采用高版本go会报错(go1.22.1))

4.安装trace2syz工具的注意事项和上述一样,git clone在moonshine相同文件夹下即可。
trace2syz和moonshine转换的效果并不相同,trace2syz更加简短

1. 安装Go

MoonShine主要是用Go编写的,所以需要先安装Go。请按照以下步骤进行:

Bash
1.安装Go,在go_projects路径下下载解压指定版本的Go
# 此版本的Go采用go.mod安装依赖,适合新版sykzlaller(20年以后),本机命名为goroot
wget https://dl.google.com/go/go1.22.1.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.22.1.linux-amd64.tar.gz
# 此版本的Go未采用go.mod管理依赖,适合旧版syzkaller(20年以前),本机命名为go
wget https://dl.google.com/go/go1.11.13.linux-amd64.tar.gz
tar -xzf go1.11.13.linux-amd64.tar.gz

2.配置go工作目录路径
# 适用于新版syzkaller的1.22.1Go的路径:
export GOROOT=~/go_projects/go
export PATH=$GOROOT/bin:$PATH

# 旧版syzkaller和moonshine需要安装1.11.13Go路径,复现moonshine采用这版
# 这些命令只是让当前路径的环境变量做修改,是一次性的,重启或者更换到其它路径,都会
# 采用配置文件的默认设置,因此时刻注意此时的go版本是哪一个
export GOROOT=~/go_projects/go
export GOPATH=~/go_projects
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
source ~/.bashrc

# 验证 Go 安装成功
go version

确保Go已正确安装并运行go version来确认版本。

2. 安装Ragel

Ragel用于扫描和解析MoonShine中的trace。通过以下命令安装Ragel:

Bash
sudo apt-get update
sudo apt-get install ragel
ragel --version

3. 安装Goyacc

MoonShine使用Goyacc来解析trace。安装Goyacc:

Bash
# 本机设置ssh连接github仓库后
# 使用ssh克隆仓库,采用http可能导致错误
git clone git@github.com:golang/tools.git
# 或者在go1.22.1版本下直接安装
go install golang.org/x/tools/cmd/goyacc@latest
export GOPATH=~/go_projects
export PATH=$GOPATH/bin:$PATH

然后确保Goyacc所在目录在你的PATH中,完成安装:

Bash
export GOPATH=$HOME/go
export PATH=$GOPATH/bin:$PATH
echo $PATH
echo $GOPATH
export PATH=$PATH:$HOME/go/bin

#
进入 Goyacc 目录,编译并安装 goyacc
cd ~/go_projects/tools/cmd/goyacc
# 将项目放入 $GOPATH/src 下
mkdir -p $GOPATH/src/golang.org/x
mv ~/go_projects/tools $GOPATH/src/golang.org/x/
# 进入新路径下的 goyacc 目录并安装:
cd $GOPATH/src/golang.org/x/tools/cmd/goyacc
go install

# 以下三种方法查看是否安装成功,注意goyacc并不提供版本号
goyacc --version
which goyacc
goyacc

# 未查询到路径时,添加$GOPATH/bin 是否包含在 $PATH
# 1.确认 goyacc 是否安装在 $GOPATH/bin
ls $GOPATH/bin/goyacc
# 2.添加路径:
export PATH=$PATH:~/go/bin
echo 'export PATH=$PATH:~/go/bin'
source ~/.bashrc
# 检查是否已经添加
echo $PATH
# 验证:
goyacc

# 2. 使环境变量永久生效:将上述环境变量的配置添加到你的 ~/.profile 文件中,以确保在每次重启系统后,环境变量都能自动加载。
# 编辑 ~/.profile 文件:
nano ~/.profile
# 在文件末尾添加同样的内容:
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
# 保存文件并退出,之后再执行一次 source ~/.profile 让配置立即生效。
source ~/.profile

4. 下载和编译MoonShine

获取MoonShine的代码并构建:

Bash
# 调整代理
go env -w GOPROXY=https://goproxy.cn
# 克隆 MoonShine 项目
mkdir -p github.com/shankarapailoor/
git clone git@github.com:shankarapailoor/moonshine.git

cd $GOPATH/src/github.com/shankarapailoor/moonshine
make

克隆syzkaller项目到本地并指定版本:

SQL
# 克隆 Syzkaller
mkdir -p ~/go/src/github.com/google

# ssh获取,http容易失败
git clone git@github.com:google/syzkaller.git $GOPATH/src/github.com/google/syzkaller/

# 验证
ls ~/go/src/github.com/google/syzkaller

# 进入克隆的 Syzkaller 项目目录,并切换到指定的提交版本 《f48c20b8f9b2a6c26629f11cc15e1c9c316572c8》
cd $GOPATH/src/github.com/google/syzkaller/
git checkout f48c20b8f9b2a6c26629f11cc15e1c9c316572c8
go mod edit -require=github.com/google/syzkaller@v0.0.0-20180519084834-f48c20b8f9b2
# 确认切换成功,可以运行以下命令查看当前版本:
git log -1

 

编译moonshine

SQL
# 返回 moonshine 项目目录并再次运行 make
cd ~/go/src/github.com/shankarapailoor/moonshine

# 初始化 Go Modules
export GO111MODULE=auto
go mod init github.com/shankarapailoor/moonshine
go mod init github.com/google/syzkallerOLD

# 下载并解析项目的所有依赖:
go mod tidy
go mod vendor

make -j4

SQL
"github.com/google/syzkaller/prog"
"github.com/google/syzkallerOLD/prog"
#
使用 sed 进行全局替换: 在项目根目录下执行以下命令
find . -type f -exec sed -i 's|github.com/google/syzkaller|github.com/google/syzkallerOLD|g' {} +

 

5. 运行MoonShine

构建完成后,可以参考如下命令模板运行MoonShine并生成Syzkaller所需的种子:

Bash
./bin/moonshine -dir [tracedir] -distill [distillConfig.json]

  • -dir [tracedir]:要解析的日志文件目录。目录内应包含使用 strace 生成的系统调用日志文件。
  • -distill [distillConfig.json]:指定配置文件,用于设定提取策略(例如“隐式依赖(implicit)”或“仅显式依赖(explicit)”)。
  • 如果日志文件中不包含调用覆盖信息或不需要提取,可以省略此参数,trace2syz 将按原样生成 Syzkaller 程序。
  • 示例配置文件 distill.json 可以在 getting-started/ 目录中找到。
  • 示例trace文件getting-started/sampletraces则需要通过moonshine的github项目给出的google云盘去下载作者提供的示例trace文件,也可以采用作者指定版本和补丁修改后的strace手动捕获示例。如果没有样例日志,可以从 Google Drive 上下载官方提供的样例日志压缩包,将其解压到 getting-started/ 目录中,以便进行示例测试。

google drive

  • 如果指定了 -deserialize 参数,trace2syz 还会将解析的 Syzkaller 程序存储在指定目录下,以便手动检查转换效果。
  • 如果不使用 -distill 参数,则 trace2syz 会直接转换日志内容,无需进行额外提取处理。经测试,不使用参数去蒸馏trace时,corpus.db的大小从80kb上升到360kb

6. 运行实例分析

  1. 运行记录:

trace内容

文件数量

蒸馏策略

转换后数量

转换后corpus.db大小

分析

样例trace

346

显式+隐式

385

80kb

已验证可用

样例trace

346

485

361kb

SQL
# trace2syz工具提取结果:
mmap(&(0x7f0000000000/0x1000)=nil, 0x1000, 0x3, 0x32, 0xffffffffffffffff, 0x0)
r0 = open(&(0x7f0000000000)='/etc/ld.so.cache\x00', 0x80000, 0x0)
fstat(r0, &(0x7f0000000011))
close(r0)
r1 = open(&(0x7f0000000055)='/lib/x86_64-linux-gnu/libc.so.6\x00', 0x80000, 0x0)
read(r1, &(0x7f0000000075)=""/833, 0x341)
fstat(r1, &(0x7f00000003b6))
close(r1)
accept(0x190, &(0x7f00000003fa), &(0x7f000000047a)=0x80)
ioctl(0x1, 0x5401, &(0x7f000000047e))
fstat(0x1, &(0x7f000000047e))
r2 = open(&(0x7f00000004c2)='/dev/null\x00', 0x1, 0x0)
accept(r2, &(0x7f00000004cc), &(0x7f000000054c)=0x80)
r3 = socket$inet_tcp(0x2, 0x1, 0x0)
bind$inet(r3, &(0x7f0000000550)={0x2, 0x0, @rand_addr}, 0x10)
accept$inet(r3, &(0x7f0000000560), &(0x7f0000000570)=0x10)
close(r3)
r4 = socket$inet_tcp(0x2, 0x1, 0x0)
bind$inet(r4, &(0x7f0000000574)={0x2, 0x0, @rand_addr}, 0x10)
accept$inet(r4, &(0x7f0000000584), &(0x7f0000000594)=0x10)
close(r4)
r5 = socket$inet_tcp(0x2, 0x1, 0x0)
bind$inet(r5, &(0x7f0000000598)={0x2, 0x0, @rand_addr}, 0x10)
accept$inet(r5, &(0x7f00000005a8), &(0x7f00000005b8)=0x10)
close(r5)
r6 = socket$inet_tcp(0x2, 0x1, 0x0)
bind$inet(r6, &(0x7f00000005bc)={0x2, 0x0, @rand_addr}, 0x10)
ioctl$int_in(r6, 0x5421, &(0x7f00000005cc)=0x1)
accept$inet(r6, &(0x7f00000005d4), &(0x7f00000005e4)=0x10)
close(r6)
r7 = socket$inet_udp(0x2, 0x2, 0x0)
bind$inet(r7, &(0x7f00000005e8)={0x2, 0x0, @rand_addr}, 0x10)
accept$inet(r7, &(0x7f00000005f8), &(0x7f0000000608)=0x10)
close(r7)
exit_group(0x0)

SQL
# moonshine提取结果:
mmap(&(0x7f0000000000/0x1000)=nil, 0x1000, 0x3, 0x32, 0xffffffffffffffff, 0x0)
mmap(&(0x7f0000001000/0x4000)=nil, 0x4000, 0x3, 0x32, 0xffffffffffffffff, 0x0)
r0 = open(&(0x7f0000000000)='/etc/ld.so.cache\x00', 0x80000, 0x0)
fstat(r0, &(0x7f0000000011))
mmap(&(0x7f0000005000/0x4000)=nil, 0x4000, 0x1, 0x12, r0, 0x0)
close(r0)
r1 = open(&(0x7f0000000055)='/lib/x86_64-linux-gnu/libc.so.6\x00', 0x80000, 0x0)
read(r1, &(0x7f0000000075)=""/833, 0x341)
fstat(r1, &(0x7f00000003b6))
mmap(&(0x7f0000009000/0x39d000)=nil, 0x39d000, 0x5, 0x812, r1, 0x0)
mprotect(&(0x7f000019c000/0x1000)=nil, 0x1000, 0x0)
mmap(&(0x7f00003a6000/0x7000)=nil, 0x7000, 0x3, 0x812, r1, 0x0)
mmap(&(0x7f00003ad000/0x4000)=nil, 0x4000, 0x3, 0x32, 0xffffffffffffffff, 0x0)
close(r1)
mmap(&(0x7f00003b1000/0x3000)=nil, 0x3000, 0x3, 0x32, 0xffffffffffffffff, 0x0)
mprotect(&(0x7f00003a6000/0x1000)=nil, 0x1000, 0x1)
mprotect(&(0x7f0000ffe000/0x1000)=nil, 0x1000, 0x1)
mprotect(&(0x7f0000004000/0x1000)=nil, 0x1000, 0x1)
munmap(&(0x7f00003b3000/0x1000)=nil, 0x1000)
accept(0x190, &(0x7f00000003fa), &(0x7f000000047a)=0x80)
ioctl$TCGETS(0x1, 0x5401, &(0x7f000000047e))
fstat(0x1, &(0x7f00000004a2))
r2 = open(&(0x7f00000004e6)='/dev/null\x00', 0x1, 0x0)
accept(r2, &(0x7f00000004f0), &(0x7f0000000570)=0x80)
r3 = socket$inet(0x2, 0x1, 0x0)
bind$inet(r3, &(0x7f0000000574)={0x2}, 0x10)
accept$inet(r3, &(0x7f0000000584), &(0x7f0000000594)=0x10)
close(r3)
r4 = socket$inet(0x2, 0x1, 0x0)
bind$inet(r4, &(0x7f0000000598)={0x2}, 0x10)
accept$inet(r4, &(0x7f00000005a8), &(0x7f00000005b8)=0x10)
close(r4)
r5 = socket$inet(0x2, 0x1, 0x0)
bind$inet(r5, &(0x7f00000005bc)={0x2}, 0x10)
accept$inet(r5, &(0x7f00000005cc), &(0x7f00000005dc)=0x10)
close(r5)
r6 = socket$inet(0x2, 0x1, 0x0)
bind$inet(r6, &(0x7f00000005e0)={0x2}, 0x10)
ioctl$int_in(r6, 0x5421, &(0x7f00000005f0)=0x1)
accept$inet(r6, &(0x7f00000005f8), &(0x7f0000000608)=0x10)
close(r6)
r7 = socket$inet(0x2, 0x2, 0x0)
bind$inet(r7, &(0x7f000000060c)={0x2}, 0x10)
accept$inet(r7, &(0x7f000000061c), &(0x7f000000062c)=0x10)
close(r7)
exit_group(0x0)

1. 运行如下命令来处理作者提供的示例trace:

Bash
# 不蒸馏
./bin/moonshine -dir getting-started/sampletraces/
./bin/trace2syz -dir getting-started/sampletraces/
# 蒸馏策略:显示+隐式
./bin/moonshine -dir getting-started/sampletraces/ -distill getting-started/distill.json

成功执行后,trace2syz 将输出类似以下内容:

Plain Text
Total number of Files: 346
Parsing File 1/346: ltp_accept4_01
Parsing File 2/346: ltp_accept_01
...
Total Distilled Progs: 385
Average Program Length: 10
Total contributing calls: 639 out of 43480 in 383 implicitly-distilled programs. Total calls: 3342

生成的corpus.db文件可以用于Syzkaller进行模糊测试,deserialize保存了反序列后的文本格式的系统调用序列。

转换前后的结果如下:

2. 若采用非指定strace(为进行trace2syz的转换,作者对strace进行了修改,指定了采用的strace版本和补丁号)获取的trace实例:

SQL
./bin/moonshine -dir getting-started/test1

./bin/moonshine -dir getting-started/test1/ -distill getting-started/distill.json

转换后的结果如下:

3. 使用 strace 跟踪 ls 命令: 在终端中运行以下命令,以生成系统调用跟踪文件 trace

SQL
strace -o trace -a 1 -s 65500 -v -xx -f -Xraw ls

这个命令将会跟踪 ls 命令的系统调用,并将结果保存到 trace 文件中。

运行 syz-trace2syz 转换 trace 文件: 假设 syz-trace2syz 已编译完成并可以执行,请运行以下命令以将 trace 文件转换为 Syzkaller 格式:

SQL
./bin/moonshine -file trace
./bin/moonshine -dir getting-started/ls

此命令会解析 trace 文件,并将其转化为 Syzkaller 测试用例格式,适合作为 Syzkaller 的种子输入。

7. 收集带有覆盖率trace

SQL
此步骤是为了完成moonshine的蒸馏,所以需要带有覆盖率的trace。如果只是为了转换格式,不需要采用特意的strace工具收集带有覆盖率的trace。使用默认的strace即可。

1. 安装Strace并应用补丁。克隆strace仓库并切换到指定的commit:

Bash
cd ~
git clone https://github.com/strace/strace strace
cd strace
git checkout a8d2417e97e71ae01095bee1a1e563b07f2d6b41

2. 应用MoonShine的kcov补丁:

Bash
git apply $GOPATH/src/github.com/shankarapailoor/moonshine/strace_kcov.patch

3. 构建strace

Bash
# 初始化项目的构建环境,它会生成必要的配置文件和脚本
./bootstrap
# 配置项目以适应当前系统的环境
./configure
make

4. 使用Strace采集trace

通过以下命令来使用patched strace采集带有覆盖率的trace:

Bash
strace -o tracefile -s 65500 -v -xx -f -k /path/to/executable arg1 arg2 .. argN

采集不带有覆盖率的trace,即仅进行格式转换,去掉-k参数:

SQL
strace -o tracefile -s 65500 -v -xx -f /path/to/executable arg1 arg2 .. argN

-o tracefile: 将输出写入到指定的文件中。

/path/to/executable arg1 arg2 .. argN: 指定要跟踪的可执行文件及其参数。

必需参数

① -s [val]:

  • 作用:指定每个调用的最大数据写入量。
  • 默认值:通常设置为 65500 字节。
  • 意义:控制输出的字节数,以防止过多数据导致输出难以处理。

② -v:

  • 作用:要求 strace 输出未缩写的参数信息。
  • 意义:提供更详细的输出,便于分析每个系统调用的参数。

③ -xx:

  • 作用:以十六进制格式输出字符串。
  • 意义:有助于以更可读的形式查看二进制数据和字符串,适合调试。

可选参数

① -f:

  • 作用:捕获子进程的跟踪信息(支持在 fork 后继续跟踪)。
  • 意义:对于需要分析多进程应用的情况非常有用,可以提供完整的执行跟踪。

② -k:

  • 作用:捕获每个调用的覆盖率。
  • 限制:仅在经过补丁的 strace 中支持,需要内核编译时启用 CONFIG_KCOV=y
  • 意义:用于分析测试覆盖率,特别是在调试或性能分析时。

.trace2syz复现

1. 蒸馏与Syzkaller模糊器最小化程序有何不同?


乍一看,他们也是这样做的:拿一个大项目,然后制作一个或多个
较小的项目来保持覆盖率。

作者有两个主要好处:

1 它允许我们将来自真实程序的非常大的跟踪序列化为紧凑的 Syzkaller 跟踪。即使是几秒钟的跟踪(比如 Chrome?)也太大了,甚至无法序列化为有效的 Syzkaller 程序。蒸馏可以预先创建紧凑而有趣的种子。

2 现有的 fuzzer 最小化效果很好,因为 Syzkaller 自然会生成紧凑的程序;但是,根据我的经验,这无法有效地扩展即使是 100 个调用的程序(例如这些)。例如,Syzkaller 似乎试图预先减少起始种子,对吗?我记得只提供了少数几个这些转换后的程序,在我杀死它之前,最小化还持续了一天半。


moonshine作者将trace2syz的过程单独分离为工具集成到了syzkaller官方项目中,可在syzkaller项目的tools文件夹下找到syz-trace2syz,即代表了该工具。可在编译后按照上述流程同样完成trace2syz的过程,但注意,此时的工具没有蒸馏效果,只能进行格式转换。


moonshine作者提供的单独的trace2syz可按照第一部分的内容正常编译使用,但集成到syzkaller中的trace2syz工具则在编译后无法转换任何trace,且18年到24年的syzkaller版本均会出现相同的错误。错误类型和内容可参考“复现配置记录部分”内容

moonshine工具被分为 2 个独立的工具:

一个将 strace 转换为 syzkaller 程序,一个用于实现trace的蒸馏。

第一个工具被重构为两个包:parser 和 proggen。parser 只是将 strace 输出转换为中间表示,而 proggen 将 IR 转换为 syzkaller 程序。

使用步骤:

要运行 trace2syz 并生成 Syzkaller 的种子,可以按照以下步骤操作:

2. 编译trace2syz

trace2syz已经被合并至syzkaller项目tools文件夹内,该文件夹内包含了多种syzkaller扩展工具,例如syz-db用户管理corpus.db。

1.首先,需要构建 syz-trace2syz 工具,步骤如下:

切换到 syzkaller 的源代码目录。

第一种方法:使用 make trace2syz 命令构建 trace2syz 工具:

Bash
# 临时配置路径
export PATH=~/go_projects/goroot/bin:$PATH
# 永久配置路径
# 打开 ~/.bashrc 文件
nano ~/.bashrc
# 在文件末尾添加以下行,设置 GOROOT 为你的 Go 安装路径
export GOROOT=/home/ubuntu2004/go_projects/goroot
export PATH=$GOROOT/bin:$PATH
# 保存并退出编辑器。让配置立即生效:
source ~/.bashrc

# 依据Makefile中的定义的 trace2syz 伪目标编译,完成在bin/目录下出现
make trace2syz -j2

第二种方法:手动切换到 tools/syz-trace2syz 目录,然后运行:(并未奏效)

Bash
go mod vendor
go mod tidy
#
本机给了4G内存不够,增加到8G
go build
# 内存还不够时:
GOMAXPROCS=2 go build

确保 trace2syz 已经成功构建。trace2syz 应位于 ./bin/trace2syz(采用第二种方式时,需要将可执行文件复制到/bin目录下),并且 distillConfig.json 配置文件也已准备好(在moonshine仓库中的getting_started文件下找到)。

3. 运行命令

使用以下命令运行 syz-trace2syz 来解析日志目录并生成 Syzkaller 程序种子:

./bin/syz-trace2syz -dir tracedir -distill getting-started/distill.json

参数说明:

  1. -dir [tracedir]:要解析的日志文件目录。目录内应包含使用 strace 生成的系统调用日志文件。
  2. -distill [distillConfig.json]:指定配置文件,用于设定提取策略(例如“隐式依赖”或“仅显式依赖”)。
  3. 如果日志文件中不包含调用覆盖信息或不需要提取,可以省略此参数,trace2syz 将按原样生成 Syzkaller 程序。
  4. 示例配置文件 distill.json 可以在 getting-started/ 目录中找到。
  5. 如果指定了 -deserialize 参数,trace2syz 还会将解析的 Syzkaller 程序存储在指定目录下,以便手动检查转换效果。
  6. 如果不使用 -distill 参数,则 trace2syz 会直接转换日志内容,无需进行额外提取处理。

4. 示例

运行示例命令:

./bin/syz-trace2syz -dir getting-started/sampletraces/ -distill getting-started/distill.json
./bin/syz-trace2syz -dir getting-started/sampletraces
./bin/syz-trace2syz -dir getting-started/test1

成功执行后,trace2syz 将输出类似以下内容:

Plain Text
Total number of Files: 346
Parsing File 1/346: ltp_accept4_01
Parsing File 2/346: ltp_accept_01
...
Total Distilled Progs: 391
Average Program Length: 10
Total contributing calls: 639 out of 43480 in 388 implicitly-distilled programs. Total calls: 3250

5. 生成的输出文件

生成的 corpus.db 文件包含已序列化的 Syzkaller 程序,准备好用于 Syzkaller 的模糊测试。生成的 corpus.db 文件将存放在运行 trace2syz 命令的当前目录下。在运行过程中,trace2syz 会将所有转换生成的 Syzkaller 程序序列化为 corpus.db,默认不支持指定存储位置,因此确保运行命令的工作目录具有写权限,方便保存生成的 corpus.db 文件

https://github.com/google/syzkaller/issues/3508

SQL
我使用您的示例 (tools/syz-trace2syz/trace2syz.go) 来调用 strace:
strace -o trace -a 1 -s 65500 -v -xx -f -Xraw ./a.out
我在一个简单的脚本上运行它,该脚本启用了环回接口(具有提升的权限):
#!/bin/sh ip link set dev lo up

使用 strace 跟踪 ls 命令: 在终端中运行以下命令,以生成系统调用跟踪文件 trace

SQL
strace -o trace -a 1 -s 65500 -v -xx -f -Xraw ls

这个命令将会跟踪 ls 命令的系统调用,并将结果保存到 trace 文件中。

运行 syz-trace2syz 转换 trace 文件: 假设 syz-trace2syz 已编译完成并可以执行,请运行以下命令以将 trace 文件转换为 Syzkaller 格式:

SQL
./bin/syz-trace2syz -file trace

此命令会解析 trace 文件,并将其转化为 Syzkaller 测试用例格式,适合作为 Syzkaller 的种子输入。

6. 复现配置记录

检查它的提交历史

SQL
git log --oneline -- tools/syz-trace2syz

Bash
./bin/syz-trace2syz -dir getting-started/sampletraces -distill getting-started/distill.json
./bin/syz-trace2syz -dir getting-started/sampletraces
./bin/syz-trace2syz -dir getting-started/test1
./bin/syz-trace2syz -dir getting-started/testsample

两个版本go的路径都在go_projects下,goroot是1.22.1,go是1.11.13.

SQL
nano ~/.bashrc
source ~/.bashrc

#
旧版Go配置:
# GOROOT 是 Go 安装目录的路径
# GOPATH 是工作空间路径
# PATH 定义了操作系统如何找到可执行程序 
export GOROOT=~/go_projects/go
export GOPATH=~/go_projects
export GOPATH=/home/ubuntu2004/go/src
export PATH=$GOROOT/bin:$PATH
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH

# 新版Go配置
export GOROOT=~/go_projects/goroot
export GOROOT=/home/ubuntu2004/go_projects/goroot
export PATH=$GOROOT/bin:$PATH

 

参考文献

moonshine仓库

trace2syz仓库

http://www.dtcms.com/a/319547.html

相关文章:

  • 手动开发一个TCP服务器调试工具(三):使用 QWidget 构建 TCP 服务控制界面
  • 强化学习详解:从理论到前沿的全面解析
  • 【Redis面试精讲 Day 15】Redis分布式锁实现与挑战
  • C++ 类和对象(2)
  • Kubernetes学习
  • 安卓开发:网络状态监听封装的奥秘
  • 根据浏览器语言判断wordpress访问不同语言的站点
  • 计算机视觉前言-----OpenCV库介绍与计算机视觉入门准备
  • Python 偏函数(functools.partial)详解
  • MySQL ORDER BY 语句详细说明
  • SVG组件
  • 96-基于Flask的酷狗音乐数据可视化分析系统
  • 微信小程序常见功能实现
  • OpenCV 入门教程:开启计算机视觉之旅
  • uwsgi 启动 django 服务
  • Next.js 15 重磅发布:React 19 集成 + 性能革命,开发者必看新特性指南
  • CentOS 7 安装 Anaconda
  • 秋招笔记-8.7
  • Redis的三种特殊类型
  • 硬盘哨兵pe版本 v25.70.6 中文免费版
  • 【R语言】 高清美观的 MaxEnt 刀切图(Jackknife)绘制——提升论文质量
  • 基于Qt的Live2D模型显示以及控制
  • DAY33打卡
  • 【Unity输入系统】自定义与双击不冲突的单击Interaction
  • 【第八章】函数进阶宝典:参数、返回值与作用域全解析
  • RedisBloom使用
  • 任务进度状态同步 万能版 参考 工厂+策略+观察者设计模式 +锁设计 springboot+redission
  • itextPdf获取pdf文件宽高不准确
  • 设计模式-装饰模式 Java
  • 客户端利用MinIO对服务器数据进行同步