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"