github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/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 73 PATTERN=${SEARCH_FOR:-$VERSION} 74 75 echo "Using binary file: $BINARY_FILE" 76 echo "Searching for pattern: $PATTERN" 77 echo "Capture length: $LENGTH bytes" 78 echo "Capture prefix length: $PREFIX_LENGTH bytes" 79 80 PATTERN_RESULTS=$(strings -t d "$BINARY_FILE" | grep "$PATTERN") 81 RESULT_COUNT=$(echo "$PATTERN_RESULTS" | wc -l) 82 83 CONTINUE_LOOP=true 84 85 while $CONTINUE_LOOP; do 86 87 # if there are multiple matches, prompt the user to select one 88 if [ $RESULT_COUNT -gt 1 ]; then 89 echo "Multiple string matches found in the binary:" 90 echo "" 91 92 # show result lines one at a time (in a numbered list) 93 # but only show everything after the first field (not the offset) 94 echo "$PATTERN_RESULTS" | cut -d ' ' -f 2- | nl -w 1 -s ') ' 95 96 97 echo "" 98 read -p "Please select a match: " SELECTION 99 100 # if the selection is not a number, exit 101 if ! [[ "$SELECTION" =~ ^[0-9]+$ ]]; then 102 echo "Invalid selection." 103 exit 1 104 fi 105 106 # if the selection is out of bounds, exit 107 if [ "$SELECTION" -gt $(echo "$PATTERN_RESULTS" | wc -l) ]; then 108 echo "Invalid selection." 109 exit 1 110 fi 111 112 # select the line from the results 113 SELECTED_RESULT=$(echo "$PATTERN_RESULTS" | sed -n "${SELECTION}p") 114 else 115 SELECTED_RESULT="$PATTERN_RESULTS" 116 fi 117 118 # search for the pattern in the binary file and capture the offset 119 OFFSET=$(echo "${SELECTED_RESULT}" | cut -d ' ' -f 1) 120 121 if [ -z "$OFFSET" ]; then 122 echo "Pattern not found." 123 exit 1 124 fi 125 126 # adjust the offset to capture prefix length before the match 127 OFFSET=$(expr "$OFFSET" - "$PREFIX_LENGTH") 128 129 # use xxd to capture the specified length from the calculated offset 130 SNIPPET=$(xxd -l "$LENGTH" -s "$OFFSET" "$BINARY_FILE") 131 132 # display the output and prompt the user 133 echo "" 134 echo "$SNIPPET" 135 echo "" 136 read -p "Does this snippet capture what you need? (Y/n/q) " RESPONSE 137 138 RESPONSE=${RESPONSE:-y} 139 140 if [ "$RESPONSE" == "y" ]; then 141 CONTINUE_LOOP=false 142 elif [ $RESULT_COUNT -eq 1 ] || [ "$RESPONSE" == "q" ]; then 143 echo "Exiting with no action taken." 144 exit 0 145 fi 146 147 done 148 149 go run ./manager write-snippet "$BINARY_FILE" --offset "$OFFSET" --length "$LENGTH" --name "$GROUP_NAME" --version "$VERSION"