diff options
Diffstat (limited to 'fix.m4')
| -rw-r--r-- | fix.m4 | 81 |
1 files changed, 31 insertions, 50 deletions
diff --git a/fix.m4 b/fix.m4 index fc7c2ce..d896a5c 100644 --- a/fix.m4 +++ b/fix.m4 @@ -18,50 +18,51 @@ # along with taosc. If not, see <https://www.gnu.org/licenses/>. save_exit_code() { + template="${@:3}" + cmd="$(printf %s "$template" | sed "s#@@#$2#g")" set +e - timeout -k 1 $1 ${@:2} 1>/dev/null 2>&1 + AFL_USE_QASAN=1 timeout -k 0 $1 afl-qemu-trace $cmd exit_code=$? set -e } bad() { - save_exit_code $@ + save_exit_code $@ 1>/dev/null 2>&1 test $exit_code -gt 128 || test $exit_code -ge 124 -a $exit_code -le 127 # timeout } -if test $# -lt 4 +if test $# -lt 5 then - echo Usage: taosc-fix WORKDIR TIMEOUT EXECUTABLE PROOFS_OF_CONCEPT [OPTION]... + echo Usage: taosc-fix TIMEOUT WORKDIR PROOFS_OF_CONCEPT EXECUTABLE ARG... exit 1 fi +timeout=$1 set -eux -o pipefail -wd="$(realpath $1)" +wd="$(realpath "$2")" test -d "$wd" -timeout=$2 -bin="$wd/$(basename $3)" -binary="$(realpath $3)" -test -x "$binary" -poc="$(realpath $4)" +poc="$(realpath "$3")" test -d "$poc" test "$(ls -A "$poc")" -options="${@:5}" # TODO: interpolation +binary="$(realpath "$4")" +test -x "$binary" +bin="$wd/$(basename "$4")" +args="${@:5}" mkdir -p "$wd" rm -fr "$wd/poc" cp -r "$poc" "$wd/poc" for exploit in "$wd"/poc/* do - gdb --batch --ex run --ex backtrace --args\ - "$binary" $options "$exploit" 2>/dev/null | - grep '^#[0-9]\+ \+0x[0-9a-f]\+' | - awk '!$7 || $7 == bin {print $1, $2}' "bin=$binary" | - sed 's/^#//' + save_exit_code $timeout "$exploit" "$binary" $args 2>&1 1>/dev/null | + grep '^ #' | + grep -F "$binary" | + sed 's/^ #\([0-9]\+ 0x[0-9a-f]\+\).*$/\1/' done | sort -n | uniq > "$wd/stack-trace" -grep '^0 0x[0-9a-f]\+$' "$wd/stack-trace" | - sed 's/^0 0x0*//' > "$wd/call-trace" +(grep '^0 0x[0-9a-f]\+$' "$wd/stack-trace" | sed 's/^0 0x0*//' || + true) > "$wd/call-trace" # Stack trace contains return addresses, not call addresses: # https://devblogs.microsoft.com/oldnewthing?p=96116 grep -v '^0 0x[0-9a-f]\+$' "$wd/stack-trace" | @@ -83,7 +84,7 @@ taosc-scout "$binary" < "$wd/call-trace" | cp -r "$poc" "$wd/poc" for exploit in "$wd/poc"/* do - if bad $timeout env TAOSC_DEST=0x$dest "$bin.jump" $options "$exploit" + if TAOSC_DEST=0x$dest bad $timeout "$exploit" "$bin.jump" $args then continue 2 # next destination fi @@ -91,7 +92,7 @@ taosc-scout "$binary" < "$wd/call-trace" | echo $loc > "$wd/patch-location" echo $dest >> "$wd/destinations" done - done 1>/dev/null 2>&1 + done test -s "$wd/patch-location" test -s "$wd/destinations" @@ -104,42 +105,22 @@ e9tool -100 -M addr=$patch_loc -P 'if dest(state)@patch goto'\ -o "$bin.patched" "$binary" # TODO: FUZZOLIC's options -fuzzolic -kmprst 90000 -i "$poc" -o "$wd/fuzzolic" -- "$binary" $options @@ || +fuzzolic -kmprst 90000 -i "$poc" -o "$wd/fuzzolic" -- "$binary" $args || true # FIXME: failing with the same status as the target program rm -fr "$wd/input" mkdir -p "$wd/input/benign" cp -r "$poc" "$wd/input/malicious" -# TODO: use parallel -for dat in "$wd"/fuzzolic/fuzzolic-*/test_case_*.dat -do - if taosc-reach $timeout "$bin.covered" $options "$dat" 1>/dev/null 2>&1 - then - if bad $timeout "$binary" $options "$dat" - then - cp $dat "$wd/input/malicious" - else - cp $dat "$wd/input/benign" - fi - fi -done +find "$wd/fuzzolic" -name 'test_case_*.dat' -print0 | + xargs -I '{}' -0 -P$(nproc) -n1 \ + taosc-sort-inputs $timeout "$wd"/input/{malicious,benign} '{}' \ + "$bin.covered" $args rm -fr "$wd/values" -for input_dir in "$wd"/input/* -do - output_dir="$wd/values/$(basename "$input_dir")" - mkdir -p "$output_dir" - # TODO: use parallel - if test "$(ls -A "$input_dir")" - then - for input in "$input_dir"/* - do - output="$output_dir/$(basename "$input")" - save_exit_code $timeout\ - env TAOSC_STACK_SIZE=$stack_size TAOSC_OUTPUT=$output\ - "$bin.collect" $options "$input" - done - fi -done +mkdir -p "$wd"/values/{benign,malicious} +find "$wd/input" -print0 | + xargs -I '{}' -0 -P$(nproc) -n1 \ + taosc-collect-values $timeout $stack_size "$wd/values" '{}' \ + "$bin.collect" $args # TODO: split if the patch location is reached multiple times with an input taosc-synth $stack_size "$wd"/values/{benign,malicious} > "$wd/predicates" # vim: filetype=sh.m4 |
