halfempty 的一些使用说明

本文最后更新于 2023年11月29日 凌晨

https://github.com/googleprojectzero/halfempty

google P0 @taviso 提供的 testcase 并行快速精简工具 (A fast, parallel test case minimization tool)
需要注意的是 halfempty 只能精简导致目标程序 crash 的 testcase,如果 testcase 不导致目标程序 crash, 还是需要使用 afl-tmin 类似的工具根据 coverage 来精简。

halfempty 工具向测试脚本传递内容时使用的是 pipe, 如果测试的程序只接受文件路径作为参数时,需要一些技巧,README 虽然有提及但是说的比较晦涩。

以 upx 为例,upx 的命令行帮助如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
root@fuzzing-5:/mnt/disk/halfempty# ./upx.out_x86-64
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2020
UPX git-d7ba31+ Markus Oberhumer, Laszlo Molnar & John Reiser Jan 23rd 2020

Usage: upx.out_x86-64 [-123456789dlthVL] [-qvfk] [-o file] file..

Commands:
-1 compress faster -9 compress better
-d decompress -l list compressed file
-t test compressed file -V display version number
-h give more help -L display software license
Options:
-q be quiet -v be verbose
-oFILE write output to 'FILE'
-f force compression of suspicious files
-k keep backup files
file.. executables to (de)compress

Type 'upx.out_x86-64 --help' for more detailed help.

UPX comes with ABSOLUTELY NO WARRANTY; for details visit https://upx.github.io

upx 只能使用文件路径作为参数, 比如像这样执行命令。 ./upx.out_x86-64 crash.upx

按照 README 中的例子编写测试脚本 test.sh

1
2
3
4
5
6
7
8
9
#!/bin/sh

./upx.out_x86-64 $1

if test $? -eq 139; then
exit 0
else
exit 1
fi

执行的时候会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
./halfempty ./test.sh  crash.upx
╭│ │ ── halfempty ───────────────────────────────────────────────── v0.30 ──
╰│ 16│ A fast, parallel testcase minimization tool
╰───╯ ───────────────────────────────────────────────────────── by @taviso ──

Input file "crash.upx" is now 19088 bytes, starting strategy "bisect"...
Verifying the original input executes successfully... (skip with --noverify)
** Message: This program expected `./test1.sh` to return successfully
** Message: for the original input (i.e. exitcode zero).
** Message: Try it yourself to verify it's working.
** Message: Use a command like: `cat crash.upx | ./test.sh || echo failed`

** (halfempty:2477): WARNING **: Strategy "bisect" failed, cannot continue.

正确的方法是使用临时文件,因为 halfempty 是一个并行的工具,每次使用的临时文件都应该不一样。

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh

tempfile=`mktemp` && cat > ${tempfile}

./upx.out_x86-64 ${tempfile}

if test $? -eq 139; then
exit 0
else
exit 1
fi

运行后的输出,大致如下

1
2
3
4
5
6
7
8
9
10
root@fuzzing-5:/mnt/disk/halfempty# ./halfempty  ./test.sh  crash.upx 
╭│ │ ── halfempty ───────────────────────────────────────────────── v0.30 ──
╰│ 16│ A fast, parallel testcase minimization tool
╰───╯ ───────────────────────────────────────────────────────── by @taviso ──

Input file "crash.upx" is now 19088 bytes, starting strategy "bisect"...
Verifying the original input executes successfully... (skip with --noverify)
The original input file succeeded after 0.0 seconds.
New finalized size: 19088 (depth=2) real=0.0s, user=0.0s, speedup=~-0.0s
treesize=6654, height=6376, unproc=0, real=4.4^C user=19.3s, speedup=~14.9s

已经可以正常运行了。如果执行过程中遇上长时间的卡顿,需要使用 --timeout 参数设置超时时间。

1
2
./halfempty --help-all | grep timeout
-T, --timeout=seconds Maximum child execution time (default=unlimited).

halfempty 的一些使用说明
https://usmacd.com/cn/halfempty/
作者
henices
发布于
2021年2月25日
许可协议