#!/usr/bin/env sh # # honggfuzz stackhash blocklist file create script # ----------------------------------------- # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. set -e # fail on unhandled error set -u # fail on undefined variable #set -x # debug readonly tmpFile=$(pwd)/.hf.bl.txt declare -a sysTools=("perl" "cut" "sort" "paste" "wc" "tr" "cat") usage() { cat <<_EOF Usage: $(basename $0) [options] OPTIONS: -i|--input : input crash(es) directory / file -B|--bl-file : output file to save found hashes (merge if exists) -e|--ext : file extension of fuzzer files (e.g. fuzz) -a|--arch : arch fuzzer have run against ('MAC' or 'LINUX') INFO: * Blacklist file sort mode only requires [-B/--bl-file] argument * Hashes gather mode requires all argument to be set _EOF exit 1 } command_exists () { type "$1" &> /dev/null ; } # Check that system tools exist for i in "${sysTools[@]}" do if ! command_exists $i; then echo "[-] '$i' command not found" exit 1 fi done INPUT_DIR="" BL_FILE="" FILE_EXT="" ARCH="" nArgs=$# while [[ $# > 1 ]] do arg="$1" case $arg in -i|--input) INPUT_DIR="$2" shift ;; -B|--bl-file) BL_FILE="$2" shift ;; -e|--ext) FILE_EXT="$2" shift ;; -a|--arch) ARCH="$2" shift ;; *) echo "[-] Invalid argument '$1'" usage ;; esac shift done gatherMode=false # Sort only mode if [[ "$BL_FILE" == "" ]]; then echo "[-] Missing blocklist file" usage fi # Hashes gather mode if [ $nArgs -gt 2 ]; then if [[ "$INPUT_DIR" == "" || ! -e "$INPUT_DIR" ]]; then echo "[-] Missing or invalid input directory" usage fi if [[ "$FILE_EXT" == "" ]]; then echo "[-] Missing file extension" usage fi if [[ "$ARCH" != "MAC" && "$ARCH" != "LINUX" ]]; then echo "[-] Invalid architecture, expecting 'MAC' or 'LINUX'" usage fi if [[ "$ARCH" == "LINUX" ]]; then STACKHASH_FIELD=5 elif [[ "$ARCH" == "MAC" ]]; then STACKHASH_FIELD=6 else echo "[-] Unsupported architecture" exit 1 fi gatherMode=true fi # save old data if [ -f $BL_FILE ]; then cat $BL_FILE > $tmpFile oldCount=$(cat $BL_FILE | wc -l | tr -d " ") else oldCount=0 fi if $gatherMode; then echo "[*] Processing files from '$INPUT_DIR' ..." find $INPUT_DIR -type f -iname "*.$FILE_EXT" | while read -r FILE do fileName=$(basename $FILE) if ! echo $fileName | grep -qF ".STACK."; then echo "[!] Skipping '$FILE'" continue fi stackHash=$(echo $fileName | cut -d '.' -f$STACKHASH_FIELD) # We don't want to lose crashes where unwinder failed if [[ "$stackHash" != "0" && ! "$stackHash" =~ ^badbad.* ]]; then echo $stackHash >> $tmpFile fi done fi # sort hex values echo "[*] Sorting blocklist file entries" perl -lpe '$_=hex' $tmpFile | \ paste -d" " - $tmpFile | sort -nu | cut -d" " -f 2- \ > $BL_FILE entries=$(cat $BL_FILE | wc -l | tr -d " ") echo "[*] $BL_FILE contains $entries blocklisted stack hashes" rm $tmpFile