95 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| #compdef hashcat
 | |
| #
 | |
| #
 | |
| tokens=(${(z)LBUFFER})
 | |
| 
 | |
| if [[ "${LBUFFER[-1]}" == " " ]]; then
 | |
| 	previousArg="${tokens[-1]}"
 | |
| else
 | |
| 	previousArg="${tokens[-2]}"
 | |
| fi
 | |
| 
 | |
| 
 | |
| trim(){
 | |
| 	cat - | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//'
 | |
| }
 | |
| 
 | |
| _args(){
 | |
| 	hashcat --help | sed -n '/Options/,/Hash modes/p' | tail -n +5 | head -n -2 | while read line; do
 | |
| 		op="$(echo "$line" | cut -d"|" -f1 | trim)"
 | |
| 		description="$(echo "$line" | cut -d"|" -f3 | trim)"
 | |
| 		ty="$(echo "$line" | cut -d"|" -f2 | trim)"
 | |
| 		echo "$op" | sed 's/,/\n/' | trim | awk "{print \$1 \":$description:$ty\"}"
 | |
| 	done
 | |
| }
 | |
| 
 | |
| _hashes(){
 | |
| 	if $(type fzf > /dev/null); then
 | |
| 		# If fzf if available, use it for hash completion
 | |
| 
 | |
| 		hashcat --example-hashes | awk -v RS="\n\n" -F "\t" '{gsub("\n","\t",$0); print $1 "\t" $2 "\t" $3}' | sed 's/MODE: //; s/TYPE: //' | fzf -d "\t" --header="Mode	Type" --with-nth='1,2' --preview='echo {3}' --preview-window=up:1 | cut -d'	' -f1
 | |
| 	else
 | |
| 		hashcat --example-hashes | awk -v RS="\n\n" -F "\t" '{gsub("\n","\t",$0); print $1 ":" $2 }' | sed 's/MODE: //; s/TYPE: //'
 | |
| 	fi
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| _basic_section(){
 | |
| 	hashcat --help | sed -n '/'"$1"'/,/- \[/p' | tail -n +5 | head -n -2 | awk -F '|' '{gsub(/ /, "", $1); print $1 ":" $2}'
 | |
| }
 | |
| _modes(){
 | |
| 	hashcat --help | sed -n '/Attack Modes/,/- \[/p' | tail -n +5 | head -n -2 | awk -F '|' '{gsub(/ /, "", $1); print $1 ":" $2}'
 | |
| }
 | |
| 
 | |
| _brain_client_features(){
 | |
| 	hashcat --help | sed -n '/Attack Modes/,/- \[/p' | tail -n +5 | head -n -2 | awk -F '|' '{gsub(/ /, "", $1); print $1 ":" $2}'
 | |
| }
 | |
| 
 | |
| best_guess(){
 | |
| 	# This get all possible arguments in the form argument:description:type
 | |
| 	allArgs="$(_args)"
 | |
| 	curr="$(echo "$allArgs" | grep -E "^$previousArg:")"
 | |
| 	if [ -z  "$(echo "$curr" | cut -d':' -f3)" ]; then
 | |
| 		# If the type is empty, there should be no positional options
 | |
| 		# Complete full list of arguments
 | |
| 		args=("${(f)$(echo "$allArgs" | cut -d':' -f1-2)}")
 | |
| 		_describe "Help" args
 | |
| 	else
 | |
| 		case "$(echo "$curr" | cut -d':' -f3)" in
 | |
| 			# If it takes a file, prompt to choose a file
 | |
| 			File) _files ;;
 | |
| 			# Otherwise, just show a message containing the description
 | |
| 			*) _message -r "$(echo "$curr" | cut -d':' -f2)" ;;
 | |
| 		esac
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| case "$previousArg" in
 | |
| 	-m|--hash-type)
 | |
| 		# hashes=("${(f)$(_hashes)}")
 | |
| 		# _describe "Hashes" hashes ;;
 | |
| 		compadd -- "$(_hashes)" ;;
 | |
| 	-a|--attack-mode)
 | |
| 		ops=("${(f)$(_basic_section "Attack Modes")}")
 | |
| 		_describe "Modes" ops ;;
 | |
| 	--brain-client-features)
 | |
| 		ops=("${(f)$(_basic_section "Brain Client Features")}")
 | |
| 		_describe "Modes" ops ;;
 | |
| 	--outfile-format)
 | |
| 		ops=("${(f)$(_basic_section "Outfile Formats")}")
 | |
| 		_describe "Modes" ops ;;
 | |
| 	--debug-mode)
 | |
| 		ops=("${(f)$(_basic_section "Rule Debugging Modes")}")
 | |
| 		_describe "Modes" ops ;;
 | |
| 	#--)
 | |
| 	#	ops=("${(f)$(_basic_section "Built-in Charsets")}")
 | |
| 	#	_describe "Modes" ops ;;
 | |
| 	-D|--opencl-device-types)
 | |
| 		ops=("${(f)$(_basic_section "OpenCL Device Types")}")
 | |
| 		_describe "Modes" ops ;;
 | |
| 	-w|--workload-profile)
 | |
| 		ops=("${(f)$(_basic_section "Workload Profiles")}")
 | |
| 		_describe "Modes" ops ;;
 | |
| 
 | |
| 	*) best_guess ;;
 | |
| esac
 |