1 #!/usr/bin/env sh 2 # 3 # honggfuzz stackhash blacklist file create script 4 # ----------------------------------------- 5 # 6 # Licensed under the Apache License, Version 2.0 (the "License"); 7 # you may not use this file except in compliance with the License. 8 # You may obtain a copy of the License at 9 # 10 # http://www.apache.org/licenses/LICENSE-2.0 11 # 12 # Unless required by applicable law or agreed to in writing, software 13 # distributed under the License is distributed on an "AS IS" BASIS, 14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 # See the License for the specific language governing permissions and 16 # limitations under the License. 17 18 set -e # fail on unhandled error 19 set -u # fail on undefined variable 20 #set -x # debug 21 22 readonly tmpFile=$(pwd)/.hf.bl.txt 23 declare -a sysTools=("perl" "cut" "sort" "paste" "wc" "tr" "cat") 24 25 usage() { 26 cat <<_EOF 27 28 Usage: $(basename $0) [options] 29 OPTIONS: 30 -i|--input : input crash(es) directory / file 31 -B|--bl-file : output file to save found hashes (merge if exists) 32 -e|--ext : file extension of fuzzer files (e.g. fuzz) 33 -a|--arch : arch fuzzer have run against ('MAC' or 'LINUX') 34 35 INFO: 36 * Blacklist file sort mode only requires [-B/--bl-file] argument 37 * Hashes gather mode requires all argument to be set 38 _EOF 39 exit 1 40 } 41 42 command_exists () { 43 type "$1" &> /dev/null ; 44 } 45 46 # Check that system tools exist 47 for i in "${sysTools[@]}" 48 do 49 if ! command_exists $i; then 50 echo "[-] '$i' command not found" 51 exit 1 52 fi 53 done 54 55 INPUT_DIR="" 56 BL_FILE="" 57 FILE_EXT="" 58 ARCH="" 59 60 nArgs=$# 61 while [[ $# > 1 ]] 62 do 63 arg="$1" 64 case $arg in 65 -i|--input) 66 INPUT_DIR="$2" 67 shift 68 ;; 69 -B|--bl-file) 70 BL_FILE="$2" 71 shift 72 ;; 73 -e|--ext) 74 FILE_EXT="$2" 75 shift 76 ;; 77 -a|--arch) 78 ARCH="$2" 79 shift 80 ;; 81 *) 82 echo "[-] Invalid argument '$1'" 83 usage 84 ;; 85 esac 86 shift 87 done 88 89 gatherMode=false 90 91 # Sort only mode 92 if [[ "$BL_FILE" == "" ]]; then 93 echo "[-] Missing blacklist file" 94 usage 95 fi 96 97 # Hashes gather mode 98 if [ $nArgs -gt 2 ]; then 99 if [[ "$INPUT_DIR" == "" || ! -e "$INPUT_DIR" ]]; then 100 echo "[-] Missing or invalid input directory" 101 usage 102 fi 103 104 if [[ "$FILE_EXT" == "" ]]; then 105 echo "[-] Missing file extension" 106 usage 107 fi 108 109 if [[ "$ARCH" != "MAC" && "$ARCH" != "LINUX" ]]; then 110 echo "[-] Invalid architecture, expecting 'MAC' or 'LINUX'" 111 usage 112 fi 113 114 if [[ "$ARCH" == "LINUX" ]]; then 115 STACKHASH_FIELD=5 116 elif [[ "$ARCH" == "MAC" ]]; then 117 STACKHASH_FIELD=6 118 else 119 echo "[-] Unsupported architecture" 120 exit 1 121 fi 122 gatherMode=true 123 fi 124 125 # save old data 126 if [ -f $BL_FILE ]; then 127 cat $BL_FILE > $tmpFile 128 oldCount=$(cat $BL_FILE | wc -l | tr -d " ") 129 else 130 oldCount=0 131 fi 132 133 if $gatherMode; then 134 echo "[*] Processing files from '$INPUT_DIR' ..." 135 find $INPUT_DIR -type f -iname "*.$FILE_EXT" | while read -r FILE 136 do 137 fileName=$(basename $FILE) 138 if ! echo $fileName | grep -qF ".STACK."; then 139 echo "[!] Skipping '$FILE'" 140 continue 141 fi 142 stackHash=$(echo $fileName | cut -d '.' -f$STACKHASH_FIELD) 143 144 # We don't want to lose crashes where unwinder failed 145 if [[ "$stackHash" != "0" && ! "$stackHash" =~ ^badbad.* ]]; then 146 echo $stackHash >> $tmpFile 147 fi 148 done 149 fi 150 151 # sort hex values 152 echo "[*] Sorting blacklist file entries" 153 perl -lpe '$_=hex' $tmpFile | \ 154 paste -d" " - $tmpFile | sort -nu | cut -d" " -f 2- \ 155 > $BL_FILE 156 157 entries=$(cat $BL_FILE | wc -l | tr -d " ") 158 echo "[*] $BL_FILE contains $entries blacklisted stack hashes" 159 160 rm $tmpFile 161