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 的命令行帮助如下
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
#!/bin/sh
./upx.out_x86-64 $1
if test $? -eq 139; then
exit 0
else
exit 1
fi
执行的时候会报错
./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 是一个并行的工具,每次使用的临时文件都应该不一样。
#!/bin/sh
tempfile=`mktemp` && cat > ${tempfile}
./upx.out_x86-64 ${tempfile}
if test $? -eq 139; then
exit 0
else
exit 1
fi
运行后的输出,大致如下
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
参数设置超时时间。
./halfempty --help-all | grep timeout
-T, --timeout=seconds Maximum child execution time (default=unlimited).
halfempty 的一些使用说明
https://usmacd.com/cn/halfempty/