Home | History | Annotate | Download | only in tools
      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