github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/binary/test-fixtures/capture-snippet.sh (about)

     1  #!/bin/bash
     2  
     3  # Default values for length and prefix length
     4  LENGTH=100
     5  PREFIX_LENGTH=20
     6  SEARCH_FOR=''
     7  GROUP_NAME=''
     8  
     9  # Function to show usage
    10  usage() {
    11      echo "Usage: $0 <path-to-binary> <version> [--search-for <pattern>] [--length <length>] [--prefix-length <prefix_length>] [--group <name>]"
    12      exit 1
    13  }
    14  
    15  # Parse arguments
    16  while [[ $# -gt 0 ]]; do
    17      key="$1"
    18  
    19      case $key in
    20  	--search-for)
    21  	    SEARCH_FOR="$2"
    22  	    shift # past argument
    23              shift # past value
    24  	    ;;
    25          --length)
    26              LENGTH="$2"
    27              shift # past argument
    28              shift # past value
    29              ;;
    30          --group)
    31              GROUP_NAME="$2"
    32              shift # past argument
    33              shift # past value
    34              ;;
    35          --prefix-length)
    36              PREFIX_LENGTH="$2"
    37              shift # past argument
    38              shift # past value
    39              ;;
    40          *)
    41              if [ -z "$BINARY_FILE" ]; then
    42                  BINARY_FILE="$1"
    43              elif [ -z "$VERSION" ]; then
    44                  VERSION="$1"
    45              else
    46                  echo "Unknown option: $1"
    47                  usage
    48              fi
    49              shift # past argument
    50              ;;
    51      esac
    52  done
    53  
    54  LENGTH=$(expr "$LENGTH" + "$PREFIX_LENGTH")
    55  
    56  # check if binary file and pattern are provided
    57  if [ -z "$BINARY_FILE" ] || [ -z "$VERSION" ]; then
    58      usage
    59  fi
    60  
    61  # if group name is empty use the binary filename
    62  if [ -z "$GROUP_NAME" ]; then
    63      GROUP_NAME=$(basename "$BINARY_FILE")
    64  fi
    65  
    66  # check if xxd is even installed
    67  if ! command -v xxd &> /dev/null; then
    68      echo "xxd not found. Please install xxd."
    69      exit 1
    70  fi
    71  
    72  # check if xargs is even installed
    73  if ! command -v xargs &> /dev/null; then
    74      echo "xargs not found. Please install xargs."
    75      exit 1
    76  fi
    77  
    78  PATTERN=${SEARCH_FOR:-$VERSION}
    79  
    80  echo "Using binary file:      $BINARY_FILE"
    81  echo "Searching for pattern:  $PATTERN"
    82  echo "Capture length:         $LENGTH bytes"
    83  echo "Capture prefix length:  $PREFIX_LENGTH bytes"
    84  
    85  PATTERN_RESULTS=$(strings -t d "$BINARY_FILE" | grep "$PATTERN")
    86  RESULT_COUNT=$(echo "$PATTERN_RESULTS" | wc -l)
    87  
    88  CONTINUE_LOOP=true
    89  
    90  while $CONTINUE_LOOP; do
    91  
    92    # if there are multiple matches, prompt the user to select one
    93    if [ $RESULT_COUNT -gt 1 ]; then
    94        echo "Multiple string matches found in the binary:"
    95        echo ""
    96  
    97        # show result lines one at a time (in a numbered list)
    98        # but only show everything after the first field (not the offset)
    99        echo "$PATTERN_RESULTS" | cut -d ' ' -f 2- | nl -w 1 -s ') '
   100  
   101  
   102        echo ""
   103        read -p "Please select a match: " SELECTION
   104  
   105        # if the selection is not a number, exit
   106        if ! [[ "$SELECTION" =~ ^[0-9]+$ ]]; then
   107            echo "Invalid selection."
   108            exit 1
   109        fi
   110  
   111        # if the selection is out of bounds, exit
   112        if [ "$SELECTION" -gt $(echo "$PATTERN_RESULTS" | wc -l) ]; then
   113            echo "Invalid selection."
   114            exit 1
   115        fi
   116  
   117        # select the line from the results
   118        SELECTED_RESULT=$(echo "$PATTERN_RESULTS" | sed -n "${SELECTION}p")
   119    else
   120      SELECTED_RESULT="$PATTERN_RESULTS"
   121    fi
   122  
   123    # search for the pattern in the binary file and capture the offset
   124    OFFSET=$(echo "${SELECTED_RESULT}" | xargs | cut -d ' ' -f 1)
   125  
   126    if [ -z "$OFFSET" ]; then
   127        echo "Pattern not found."
   128        exit 1
   129    fi
   130  
   131    # adjust the offset to capture prefix length before the match
   132    OFFSET=$(expr "$OFFSET" - "$PREFIX_LENGTH")
   133  
   134    # use xxd to capture the specified length from the calculated offset
   135    SNIPPET=$(xxd -l "$LENGTH" -s "$OFFSET" "$BINARY_FILE")
   136  
   137    # display the output and prompt the user
   138    echo ""
   139    echo "$SNIPPET"
   140    echo ""
   141    read -p "Does this snippet capture what you need? (Y/n/q) " RESPONSE
   142  
   143    RESPONSE=${RESPONSE:-y}
   144  
   145    if [ "$RESPONSE" == "y" ]; then
   146      CONTINUE_LOOP=false
   147    elif [ $RESULT_COUNT -eq 1 ] || [ "$RESPONSE" == "q" ]; then
   148      echo "Exiting with no action taken."
   149      exit 0
   150    fi
   151  
   152  done
   153  
   154  go run ./manager write-snippet "$BINARY_FILE" --offset "$OFFSET" --length "$LENGTH" --name "$GROUP_NAME" --version "$VERSION"