| #!/usr/bin/env sh |
| # |
| # honggfuzz stackhash blacklist 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 blacklist 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 blacklist 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 blacklisted stack hashes" |
| |
| rm $tmpFile |