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/
作者
henices
发布于
2021年2月25日
许可协议