Release v4.9237 - Ice Coffee :coffee:
[RRG-proxmark3.git] / pm3
blob31ed0695b31da3c02f385171660ddb824c5c345f
1 #!/usr/bin/env bash
3 # Usage: run option -h to get help
5 # BT auto detection
6 # Shall we look for white HC-06-USB dongle ?
7 FINDBTDONGLE=true
8 # Shall we look for rfcomm interface ?
9 FINDBTRFCOMM=true
10 # Shall we look for registered BT device ? (Linux only)
11 FINDBTDIRECT=true
13 PM3PATH=$(dirname "$0")
14 FULLIMAGE="fullimage.elf"
15 BOOTIMAGE="bootrom.elf"
16 # try pm3 dirs in current repo workdir
17 if [ -d "$PM3PATH/client/" ]; then
18 CLIENT="$PM3PATH/client/proxmark3"
19 # try install dir
20 elif [ -x "$PM3PATH/proxmark3" ]; then
21 CLIENT="$PM3PATH/proxmark3"
22 else
23 # hope it's installed somehow, still not sure where fw images are...
24 CLIENT="proxmark3"
27 PM3LIST=()
28 SHOWLIST=false
30 function get_pm3_list_Linux {
31 N=$1
32 PM3LIST=()
33 if [ ! -c "/dev/tty0" ]; then
34 echo >&2 "[!!] Script cannot access /dev/ttyXXX files, insufficient privileges"
35 exit 1
37 for DEV in $(find /dev/ttyACM* 2>/dev/null); do
38 if which udevadm >/dev/null; then
39 if udevadm info -q property -n "$DEV" | grep -q "ID_VENDOR=proxmark.org"; then
40 PM3LIST+=("$DEV")
41 if [ ${#PM3LIST[*]} -ge "$N" ]; then
42 return
45 else
46 if grep -q "proxmark.org" "/sys/class/tty/${DEV#/dev/}/../../../manufacturer" 2>/dev/null; then
47 PM3LIST+=("$DEV")
48 if [ ${#PM3LIST[*]} -ge "$N" ]; then
49 return
53 done
54 if $FINDBTDONGLE; then
55 # check if the HC-06-USB white dongle is present (still, that doesn't tell us if it's paired with a Proxmark3...)
56 for DEV in $(find /dev/ttyUSB* 2>/dev/null); do
57 if which udevadm >/dev/null; then
58 if udevadm info -q property -n "$DEV" | grep -q "ID_MODEL=CP2104_USB_to_UART_Bridge_Controller"; then
59 PM3LIST+=("$DEV")
60 if [ ${#PM3LIST[*]} -ge "$N" ]; then
61 return
64 else
65 if grep -q "DRIVER=cp210x" "/sys/class/tty/${DEV#/dev/}/../../uevent" 2>/dev/null; then
66 PM3LIST+=("$DEV")
67 if [ ${#PM3LIST[*]} -ge "$N" ]; then
68 return
72 done
74 if $FINDBTRFCOMM; then
75 # check if the MAC of a Proxmark3 was bound to a local rfcomm interface
76 # (on OSes without deprecated rfcomm and hcitool, the loop will be simply skipped)
77 for DEVMAC in $(rfcomm -a 2>/dev/null | grep " 20:19:0[45]" | sed 's/^\(.*\): \([0-9:]*\) .*/\1@\2/'); do
78 DEV=${DEVMAC/@*/}
79 MAC=${DEVMAC/*@/}
80 # check which are Proxmark3 and, side-effect, if they're actually present
81 if hcitool name "$MAC" | grep -q "PM3"; then
82 PM3LIST+=("/dev/$DEV")
83 if [ ${#PM3LIST[*]} -ge "$N" ]; then
84 return
87 done
89 if $FINDBTDIRECT; then
90 # check if the MAC of a Proxmark3 was registered in the known devices
91 for MAC in $(dbus-send --system --print-reply --type=method_call --dest='org.bluez' '/' org.freedesktop.DBus.ObjectManager.GetManagedObjects 2>/dev/null|\
92 awk '/"Address"/{getline;gsub(/"/,"",$3);a=$3}/Name/{getline;if (/PM3_RDV4/) print a}'); do
93 PM3LIST+=("bt:$MAC")
94 done
95 # we don't probe the device so there is no guarantee the device is actually present
99 function get_pm3_list_macOS {
100 N=$1
101 PM3LIST=()
102 for DEV in $(ioreg -r -c "IOUSBHostDevice" -l | awk -F '"' '
103 $2=="USB Vendor Name"{b=($4=="proxmark.org")}
104 b==1 && $2=="IODialinDevice"{print $4}'); do
105 PM3LIST+=("$DEV")
106 if [ ${#PM3LIST[*]} -ge "$N" ]; then
107 return
109 done
112 function get_pm3_list_Windows {
113 N=$1
114 PM3LIST=()
115 # Need to look for this first, the call to Win32_serialport "crashes" then native bt serial port. Don't ask why.
116 #BT direct SERIAL PORTS (COM)
117 if $FINDBTRFCOMM; then
118 for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_PnPEntity | Where-Object Caption -like 'Standard Serial over Bluetooth link (COM*' | Select Name" 2> /dev/null | awk '$0 ~ /COM/{print substr($6,2,4)}'); do
119 DEV=${DEV/ */}
120 PM3LIST+=("$DEV")
121 if [ ${#PM3LIST[*]} -ge "$N" ]; then
122 return
124 done
127 # Normal SERIAL PORTS (COM)
128 for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_9AC4&PID_4B8F*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do
129 DEV=${DEV/ */}
130 PM3LIST+=("$DEV")
131 if [ ${#PM3LIST[*]} -ge "$N" ]; then
132 return
134 done
136 #white BT dongle SERIAL PORTS (COM)
137 if $FINDBTDONGLE; then
138 for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_10C4&PID_EA60*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do
139 DEV=${DEV/ */}
140 PM3LIST+=("$DEV")
141 if [ ${#PM3LIST[*]} -ge "$N" ]; then
142 return
144 done
148 function get_pm3_list_WSL {
149 N=$1
150 PM3LIST=()
152 # Need to look for this first, the call to Win32_serialport "crashes" then native bt serial port. Don't ask why.
153 #BT direct SERIAL PORTS (COM)
154 if $FINDBTRFCOMM; then
155 for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_PnPEntity | Where-Object Caption -like 'Standard Serial over Bluetooth link (COM*' | Select Name" 2> /dev/null | awk '$0 ~ /COM/{print substr($6,2,4)}'); do
157 DEV=${DEV/ */}
158 DEV="/dev/ttyS${DEV#COM}"
159 # ttyS counterpart takes some more time to appear
160 if [ -e "$DEV" ]; then
161 PM3LIST+=("$DEV")
162 if [ ! -w "$DEV" ]; then
163 echo "[!] Let's give users read/write access to $DEV"
164 sudo chmod 666 "$DEV"
166 if [ ${#PM3LIST[*]} -ge "$N" ]; then
167 return
171 done
174 # Normal SERIAL PORTS (COM)
175 for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_9AC4&PID_4B8F*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do
176 DEV=${DEV/ */}
177 DEV="/dev/ttyS${DEV#COM}"
178 # ttyS counterpart takes some more time to appear
179 if [ -e "$DEV" ]; then
180 PM3LIST+=("$DEV")
181 if [ ! -w "$DEV" ]; then
182 echo "[!] Let's give users read/write access to $DEV"
183 sudo chmod 666 "$DEV"
185 if [ ${#PM3LIST[*]} -ge "$N" ]; then
186 return
189 done
191 #white BT dongle SERIAL PORTS (COM)
192 if $FINDBTDONGLE; then
193 for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_10C4&PID_EA60*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do
194 DEV=${DEV/ */}
195 DEV="/dev/ttyS${DEV#COM}"
196 # ttyS counterpart takes some more time to appear
197 if [ -e "$DEV" ]; then
198 PM3LIST+=("$DEV")
199 if [ ! -w "$DEV" ]; then
200 echo "[!] Let's give users read/write access to $DEV"
201 sudo chmod 666 "$DEV"
203 if [ ${#PM3LIST[*]} -ge "$N" ]; then
204 return
208 done
212 SCRIPT=$(basename -- "$0")
214 if [ "$SCRIPT" = "pm3" ]; then
215 CMD() { $CLIENT "$@"; }
216 HELP() {
217 cat << EOF
218 Quick helper script for proxmark3 client when working with a Proxmark3 device connected via USB
220 Description:
221 The usage is the same as for the proxmark3 client, with the following differences:
222 * the correct port name will be automatically guessed;
223 * the script will wait for a Proxmark to be connected (same as option -w of the client).
224 You can also specify a first option -n N to access the Nth Proxmark3 connected on USB.
225 Don't use this script if you want to work offline or with the BT addon.
226 To see a list of available ports, use --list.
228 Usage:
229 $SCRIPT [-n <N>] [-f] [-c <command>]|[-l <lua_script_file>]|[-s <cmd_script_file>] [-i]
230 $SCRIPT --list
232 See "$CLIENT -h" for more details on options.
235 elif [ "$SCRIPT" = "pm3-flash" ]; then
236 FINDBTDONGLE=false
237 FINDBTRFCOMM=false
238 FINDBTDIRECT=false
239 CMD() {
240 ARGS=("--port" "$1" "--flash")
241 shift;
242 while [ "$1" != "" ]; do
243 if [ "$1" == "-b" ]; then
244 ARGS+=("--unlock-bootloader")
245 else
246 ARGS+=("--image" "$1")
248 shift;
249 done
250 $CLIENT "${ARGS[@]}";
252 HELP() {
253 cat << EOF
254 Quick helper script for flashing a Proxmark device via USB
256 Description:
257 The usage is similar to the old proxmark3-flasher binary, except that the correct port name will be automatically guessed.
258 You can also specify a first option -n N to access the Nth Proxmark3 connected on USB.
259 If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h".
260 To see a list of available ports, use --list.
262 Usage:
263 $SCRIPT [-n <N>] [-b] image.elf [image.elf...]
264 $SCRIPT --list
266 Options:
267 -b Enable flashing of bootloader area (DANGEROUS)
269 Example:
270 $SCRIPT -b bootrom.elf fullimage.elf
273 elif [ "$SCRIPT" = "pm3-flash-all" ]; then
274 FINDBTDONGLE=false
275 FINDBTRFCOMM=false
276 FINDBTDIRECT=false
277 CMD() { $CLIENT "--port" "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE" "--image" "$FULLIMAGE"; }
278 HELP() {
279 cat << EOF
280 Quick helper script for flashing a Proxmark device via USB
282 Description:
283 The correct port name will be automatically guessed and the stock bootloader and firmware image will be flashed.
284 You can also specify a first option -n N to access the Nth Proxmark3 connected on USB.
285 If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h".
286 To see a list of available ports, use --list.
288 Usage:
289 $SCRIPT [-n <N>]
290 $SCRIPT --list
293 elif [ "$SCRIPT" = "pm3-flash-fullimage" ]; then
294 FINDBTDONGLE=false
295 FINDBTRFCOMM=false
296 FINDBTDIRECT=false
297 CMD() { $CLIENT "--port" "$1" "--flash" "--image" "$FULLIMAGE"; }
298 HELP() {
299 cat << EOF
300 Quick helper script for flashing a Proxmark device via USB
302 Description:
303 The correct port name will be automatically guessed and the stock firmware image will be flashed.
304 You can also specify a first option -n N to access the Nth Proxmark3 connected on USB.
305 If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h".
306 To see a list of available ports, use --list.
308 Usage:
309 $SCRIPT [-n <N>]
310 $SCRIPT --list
313 elif [ "$SCRIPT" = "pm3-flash-bootrom" ]; then
314 FINDBTDONGLE=false
315 FINDBTRFCOMM=false
316 FINDBTDIRECT=false
317 CMD() { $CLIENT "--port" "$1" "--flash" "--unlock-bootloader" "--image" "$BOOTIMAGE"; }
318 HELP() {
319 cat << EOF
320 Quick helper script for flashing a Proxmark device via USB
322 Description:
323 The correct port name will be automatically guessed and the stock bootloader will be flashed.
324 You can also specify a first option -n N to access the Nth Proxmark3 connected on USB.
325 If this doesn't work, you'll have to use manually the proxmark3 client, see "$CLIENT -h".
326 To see a list of available ports, use --list.
328 Usage:
329 $SCRIPT [-n <N>]
330 $SCRIPT --list
333 else
334 echo >&2 "[!!] Script ran under unknown name, abort: $SCRIPT"
335 exit 1
337 if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
338 HELP
339 exit 0
342 # if a port is already provided, let's just run the command as such
343 for ARG in "$@"; do
344 if [ "$ARG" == "-p" ]; then
345 CMD "$@"
346 exit $?
348 done
350 if [ "$1" == "--list" ]; then
351 shift
352 if [ "$1" != "" ]; then
353 echo >&2 "[!!] Option --list must be used alone"
354 exit 1
356 SHOWLIST=true
359 # Number of the proxmark3 we're interested in
361 if [ "$1" == "-n" ]; then
362 shift
363 if [ "$1" -ge 1 ] && [ "$1" -lt 10 ]; then
364 N=$1
365 shift
366 else
367 echo >&2 "[!!] Option -n requires a number between 1 and 9, got \"$1\""
368 exit 1
372 HOSTOS=$(uname | awk '{print toupper($0)}')
373 if [ "$HOSTOS" = "LINUX" ]; then
374 if uname -a|grep -q Microsoft; then
375 # Test presence of wmic
376 if ! wmic.exe computersystem get name >/dev/null 2>&1; then
377 echo >&2 "[!!] Cannot run wmic.exe, are you sure your WSL is authorized to run Windows processes? (cf WSL interop flag)"
378 exit 1
380 GETPM3LIST=get_pm3_list_WSL
381 else
382 GETPM3LIST=get_pm3_list_Linux
384 elif [ "$HOSTOS" = "DARWIN" ]; then
385 GETPM3LIST=get_pm3_list_macOS
386 elif [[ "$HOSTOS" =~ MINGW(32|64)_NT* ]]; then
387 GETPM3LIST=get_pm3_list_Windows
388 else
389 echo >&2 "[!!] Host OS not recognized, abort: $HOSTOS"
390 exit 1
393 if $SHOWLIST; then
394 # Probe for up to 9 devs
395 $GETPM3LIST 9
396 if [ ${#PM3LIST} -lt 1 ]; then
397 echo >&2 "[!!] No port found"
398 exit 1
401 for DEV in "${PM3LIST[@]}"
403 echo "$n: $DEV"
404 n=$((n+1))
405 done
406 exit 0
409 # Wait till we get at least N proxmark3 devices
410 $GETPM3LIST "$N"
411 if [ ${#PM3LIST} -lt "$N" ]; then
412 echo >&2 "[=] Waiting for Proxmark3 to appear..."
414 while true; do
415 if [ ${#PM3LIST[*]} -ge "$N" ]; then
416 break
418 sleep .1
419 $GETPM3LIST "$N"
420 done
422 if [ ${#PM3LIST} -lt "$N" ]; then
423 echo >&2 "[!!] No port found, abort"
424 exit 1
427 CMD "${PM3LIST[$((N-1))]}" "$@"
428 exit $?