mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-22 06:13:27 -07:00
Merge/Update from Original
Merge branch 'master' of https://github.com/Proxmark/proxmark3
This commit is contained in:
commit
e9ded95ca8
51 changed files with 621 additions and 251 deletions
|
@ -82,7 +82,9 @@ POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d
|
|||
CORESRCS = uart_posix.c \
|
||||
uart_win32.c \
|
||||
util.c \
|
||||
util_posix.c
|
||||
util_posix.c \
|
||||
ui.c \
|
||||
comms.c
|
||||
|
||||
CMDSRCS = crapto1/crapto1.c\
|
||||
crapto1/crypto1.c\
|
||||
|
@ -106,7 +108,6 @@ CMDSRCS = crapto1/crapto1.c\
|
|||
iso14443crc.c \
|
||||
iso15693tools.c \
|
||||
graph.c \
|
||||
ui.c \
|
||||
cmddata.c \
|
||||
lfdemod.c \
|
||||
emv/crypto_polarssl.c\
|
||||
|
@ -169,8 +170,7 @@ CMDSRCS = crapto1/crapto1.c\
|
|||
cmdscript.c\
|
||||
pm3_binlib.c\
|
||||
pm3_bitlib.c\
|
||||
protocols.c\
|
||||
comms.c
|
||||
protocols.c
|
||||
|
||||
cpu_arch = $(shell uname -m)
|
||||
ifneq ($(findstring 86, $(cpu_arch)), )
|
||||
|
|
|
@ -8,14 +8,15 @@
|
|||
// Data and Graph commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmddata.h"
|
||||
|
||||
#include <stdio.h> // also included in util.h
|
||||
#include <string.h> // also included in util.h
|
||||
#include <inttypes.h>
|
||||
#include <limits.h> // for CmdNorm INT_MIN && INT_MAX
|
||||
#include "cmddata.h"
|
||||
#include "util.h"
|
||||
#include "cmdmain.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h" // for show graph controls
|
||||
#include "graph.h" // for graph data
|
||||
#include "cmdparser.h"// already included in cmdmain.h
|
||||
|
|
|
@ -9,17 +9,18 @@
|
|||
// High frequency commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdhf.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "util.h"
|
||||
#include "ui.h"
|
||||
#include "iso14443crc.h"
|
||||
#include "parity.h"
|
||||
#include "cmdmain.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhf.h"
|
||||
#include "cmdhf14a.h"
|
||||
#include "cmdhf14b.h"
|
||||
#include "cmdhf15.h"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "util.h"
|
||||
#include "util_posix.h"
|
||||
#include "iso14443crc.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "common.h"
|
||||
|
|
|
@ -8,18 +8,19 @@
|
|||
// High frequency ISO14443B commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdhf14b.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "iso14443crc.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "graph.h"
|
||||
#include "util.h"
|
||||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhf14b.h"
|
||||
#include "cmdmain.h"
|
||||
#include "cmdhf14a.h"
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#ifndef CMDHF14B_H__
|
||||
#define CMDHF14B_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
int CmdHF14B(const char *Cmd);
|
||||
int CmdHF14BList(const char *Cmd);
|
||||
int CmdHF14BInfo(const char *Cmd);
|
||||
|
|
|
@ -22,17 +22,18 @@
|
|||
// the client. Signal Processing & decoding is done on the pc. This is the slowest
|
||||
// variant, but offers the possibility to analyze the waveforms directly.
|
||||
|
||||
#include "cmdhf15.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "graph.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhf15.h"
|
||||
#include "iso15693tools.h"
|
||||
#include "cmdmain.h"
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#ifndef CMDHF15_H__
|
||||
#define CMDHF15_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
int CmdHF15(const char *Cmd);
|
||||
|
||||
int CmdHF15Demod(const char *Cmd);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <stdio.h>
|
||||
#include "util.h"
|
||||
#include "util_posix.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "common.h"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhficlass.h"
|
||||
|
|
|
@ -8,15 +8,17 @@
|
|||
// High frequency Legic commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdhflegic.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhflegic.h"
|
||||
#include "cmdmain.h"
|
||||
#include "util.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static command_t CommandTable[] =
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "cmdmain.h"
|
||||
#include "cmdhfmfhard.h"
|
||||
#include "parity.h"
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <locale.h>
|
||||
#include <math.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "cmdmain.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "usb_cmd.h"
|
||||
#include "cmdmain.h"
|
||||
#include "ui.h"
|
||||
|
|
|
@ -8,17 +8,18 @@
|
|||
// High frequency Topaz (NFC Type 1) commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdhftopaz.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "cmdmain.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhftopaz.h"
|
||||
#include "cmdhf14a.h"
|
||||
#include "ui.h"
|
||||
#include "mifare.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "iso14443crc.h"
|
||||
#include "protocols.h"
|
||||
|
||||
|
|
|
@ -8,14 +8,15 @@
|
|||
// Hardware commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdhw.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "ui.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhw.h"
|
||||
#include "cmdmain.h"
|
||||
#include "cmddata.h"
|
||||
|
||||
|
|
|
@ -8,14 +8,15 @@
|
|||
// Low frequency commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "proxmark3.h"
|
||||
#include "cmdlf.h"
|
||||
#include "comms.h"
|
||||
#include "lfdemod.h" // for psk2TOpsk1
|
||||
#include "util.h" // for parsing cli command utils
|
||||
#include "ui.h" // for show graph controls
|
||||
|
|
|
@ -11,10 +11,11 @@
|
|||
// FSK2a, RF/50, 96 bits (complete)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfawid.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h> // sscanf
|
||||
#include "proxmark3.h" // Definitions, USB controls, etc
|
||||
#include "cmdlfawid.h"
|
||||
#include "comms.h" // Definitions, USB controls, etc
|
||||
#include "ui.h" // PrintAndLog
|
||||
#include "cmdparser.h" // CmdsParse, CmdsHelp
|
||||
#include "lfdemod.h" // parityTest +
|
||||
|
|
|
@ -7,13 +7,15 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Low frequency COTAG commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfcotag.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "cmddata.h"
|
||||
#include "cmdlfcotag.h"
|
||||
#include "lfdemod.h"
|
||||
#include "usb_cmd.h"
|
||||
#include "cmdmain.h"
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
// Low frequency EM4x commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfem4x.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "cmdlfem4x.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h" // for PrintAndLog
|
||||
#include "util.h"
|
||||
#include "cmdparser.h"
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
// Low frequency HID commands (known)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfhid.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "cmdlfhid.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "graph.h"
|
||||
#include "cmdparser.h"
|
||||
|
|
|
@ -8,10 +8,12 @@
|
|||
// Low frequency Hitag support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfhitag.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "common.h"
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
// PSK1, rf/32, 64 or 224 bits (known)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfindala.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "cmdlfindala.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "graph.h"
|
||||
#include "cmdparser.h"
|
||||
|
|
|
@ -8,13 +8,14 @@
|
|||
// FSK2a, rf/64, 64 bits (complete)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include "cmdlfio.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "graph.h"
|
||||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfjablotron.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
// Low frequency Honeywell NexWatch tag commands
|
||||
// PSK1 RF/16, RF/2, 128 bits long (known)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfnexwatch.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include "cmdlfnexwatch.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
// Low frequency Noralsy tag commands
|
||||
// ASK/Manchester, STT, RF/32, 96 bits long (some bits unknown)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfnoralsy.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
// Low frequency Stanley/PAC tag commands
|
||||
// NRZ, RF/32, 128 bits long (unknown cs)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfpac.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
|
|
|
@ -8,9 +8,12 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Low frequency PCF7931 commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfpcf7931.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
|
@ -18,7 +21,6 @@
|
|||
#include "cmddata.h"
|
||||
#include "cmdmain.h"
|
||||
#include "cmdlf.h"
|
||||
#include "cmdlfpcf7931.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#ifndef CMDLFPCF7931_H__
|
||||
#define CMDLFPCF7931_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct pcf7931_config{
|
||||
uint8_t Pwd[7];
|
||||
uint16_t InitDelay;
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
// Low frequency Presco tag commands
|
||||
// ASK/Manchester, rf/32, 128 bits (complete)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfpresco.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include "cmdlfpresco.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
// Low frequency Farpoint / Pyramid tag commands
|
||||
// FSK2a, rf/50, 128 bits (complete)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfpyramid.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include "cmdlfpyramid.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
// Low frequency Securakey tag commands
|
||||
// ASK/Manchester, RF/40, 96 bits long (unknown cs)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfsecurakey.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
|
|
|
@ -7,19 +7,20 @@
|
|||
// Low frequency T55xx commands
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlft55xx.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "graph.h"
|
||||
#include "cmdmain.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmddata.h"
|
||||
#include "cmdlf.h"
|
||||
#include "cmdlft55xx.h"
|
||||
#include "util.h"
|
||||
#include "lfdemod.h"
|
||||
#include "cmdhf14a.h" //for getTagInfo
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#ifndef CMDLFT55XX_H__
|
||||
#define CMDLFT55XX_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t bl1;
|
||||
uint32_t bl2;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include "crc16.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "graph.h"
|
||||
#include "cmdparser.h"
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
// Low frequency Viking tag commands (AKA FDI Matalec Transit)
|
||||
// ASK/Manchester, RF/32, 64 bits (complete)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfviking.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include "proxmark3.h"
|
||||
#include "cmdlfviking.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
|
|
|
@ -50,13 +50,13 @@ command_t* getTopLevelCommandTable()
|
|||
return CommandTable;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd)
|
||||
static int CmdHelp(const char *Cmd)
|
||||
{
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdQuit(const char *Cmd)
|
||||
static int CmdQuit(const char *Cmd)
|
||||
{
|
||||
return 99;
|
||||
}
|
||||
|
|
|
@ -11,12 +11,7 @@
|
|||
#ifndef CMDMAIN_H__
|
||||
#define CMDMAIN_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "usb_cmd.h"
|
||||
#include "cmdparser.h"
|
||||
#include "comms.h"
|
||||
|
||||
|
||||
extern int CommandReceived(char *Cmd);
|
||||
extern command_t* getTopLevelCommandTable();
|
||||
|
|
216
client/comms.c
216
client/comms.c
|
@ -9,33 +9,42 @@
|
|||
// Code for communicating with the proxmark3 hardware.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "comms.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#ifdef __linux__
|
||||
#include <unistd.h> // for unlink()
|
||||
#endif
|
||||
#include "uart.h"
|
||||
#include "ui.h"
|
||||
#include "common.h"
|
||||
#include "util_posix.h"
|
||||
|
||||
// Declare globals.
|
||||
|
||||
// Serial port that we are communicating with the PM3 on.
|
||||
static serial_port sp;
|
||||
static serial_port sp = NULL;
|
||||
static char *serial_port_name = NULL;
|
||||
|
||||
// If TRUE, then there is no active connection to the PM3, and we will drop commands sent.
|
||||
static bool offline;
|
||||
|
||||
typedef struct {
|
||||
bool run; // If TRUE, continue running the uart_communication thread
|
||||
bool block_after_ACK; // if true, block after receiving an ACK package
|
||||
} communication_arg_t;
|
||||
|
||||
static communication_arg_t conn;
|
||||
static pthread_t USB_communication_thread;
|
||||
|
||||
// Transmit buffer.
|
||||
// TODO: Use locks and execute this on the main thread, rather than the receiver
|
||||
// thread. Running on the main thread means we need to be careful in the
|
||||
// flasher, as it means SendCommand is no longer async, and can't be used as a
|
||||
// buffer for a pending command when the connection is re-established.
|
||||
static UsbCommand txcmd;
|
||||
volatile static bool txcmd_pending = false;
|
||||
static UsbCommand txBuffer;
|
||||
static bool txBuffer_pending = false;
|
||||
static pthread_mutex_t txBufferMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t txBufferSig = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
// Used by UsbReceiveCommand as a ring buffer for messages that are yet to be
|
||||
// processed by a command handler (WaitForResponse{,Timeout})
|
||||
static UsbCommand cmdBuffer[CMD_BUFFER_SIZE];
|
||||
static UsbCommand rxBuffer[CMD_BUFFER_SIZE];
|
||||
|
||||
// Points to the next empty position to write to
|
||||
static int cmd_head = 0;
|
||||
|
@ -43,8 +52,8 @@ static int cmd_head = 0;
|
|||
// Points to the position of the last unread command
|
||||
static int cmd_tail = 0;
|
||||
|
||||
// to lock cmdBuffer operations from different threads
|
||||
static pthread_mutex_t cmdBufferMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
// to lock rxBuffer operations from different threads
|
||||
static pthread_mutex_t rxBufferMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
// These wrappers are required because it is not possible to access a static
|
||||
// global variable outside of the context of a single file.
|
||||
|
@ -57,38 +66,6 @@ bool IsOffline() {
|
|||
return offline;
|
||||
}
|
||||
|
||||
bool OpenProxmark(char *portname, bool waitCOMPort, int timeout) {
|
||||
if (!waitCOMPort) {
|
||||
sp = uart_open(portname);
|
||||
} else {
|
||||
printf("Waiting for Proxmark to appear on %s ", portname);
|
||||
fflush(stdout);
|
||||
int openCount = 0;
|
||||
do {
|
||||
sp = uart_open(portname);
|
||||
msleep(1000);
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
} while(++openCount < timeout && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// check result of uart opening
|
||||
if (sp == INVALID_SERIAL_PORT) {
|
||||
printf("ERROR: invalid serial port\n");
|
||||
return false;
|
||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
||||
printf("ERROR: serial port is claimed by another process\n");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void CloseProxmark(void) {
|
||||
uart_close(sp);
|
||||
}
|
||||
|
||||
void SendCommand(UsbCommand *c) {
|
||||
#ifdef COMMS_DEBUG
|
||||
printf("Sending %04x cmd\n", c->cmd);
|
||||
|
@ -98,15 +75,22 @@ void SendCommand(UsbCommand *c) {
|
|||
PrintAndLog("Sending bytes to proxmark failed - offline");
|
||||
return;
|
||||
}
|
||||
/**
|
||||
The while-loop below causes hangups at times, when the pm3 unit is unresponsive
|
||||
or disconnected. The main console thread is alive, but comm thread just spins here.
|
||||
Not good.../holiman
|
||||
**/
|
||||
while(txcmd_pending);
|
||||
|
||||
txcmd = *c;
|
||||
txcmd_pending = true;
|
||||
pthread_mutex_lock(&txBufferMutex);
|
||||
/**
|
||||
This causes hangups at times, when the pm3 unit is unresponsive or disconnected. The main console thread is alive,
|
||||
but comm thread just spins here. Not good.../holiman
|
||||
**/
|
||||
while (txBuffer_pending) {
|
||||
pthread_cond_wait(&txBufferSig, &txBufferMutex); // wait for communication thread to complete sending a previous commmand
|
||||
}
|
||||
|
||||
txBuffer = *c;
|
||||
txBuffer_pending = true;
|
||||
pthread_cond_signal(&txBufferSig); // tell communication thread that a new command can be send
|
||||
|
||||
pthread_mutex_unlock(&txBufferMutex);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,18 +103,18 @@ void SendCommand(UsbCommand *c) {
|
|||
void clearCommandBuffer()
|
||||
{
|
||||
//This is a very simple operation
|
||||
pthread_mutex_lock(&cmdBufferMutex);
|
||||
pthread_mutex_lock(&rxBufferMutex);
|
||||
cmd_tail = cmd_head;
|
||||
pthread_mutex_unlock(&cmdBufferMutex);
|
||||
pthread_mutex_unlock(&rxBufferMutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief storeCommand stores a USB command in a circular buffer
|
||||
* @param UC
|
||||
*/
|
||||
void storeCommand(UsbCommand *command)
|
||||
static void storeCommand(UsbCommand *command)
|
||||
{
|
||||
pthread_mutex_lock(&cmdBufferMutex);
|
||||
pthread_mutex_lock(&rxBufferMutex);
|
||||
if( (cmd_head+1) % CMD_BUFFER_SIZE == cmd_tail)
|
||||
{
|
||||
// If these two are equal, we're about to overwrite in the
|
||||
|
@ -139,11 +123,11 @@ void storeCommand(UsbCommand *command)
|
|||
}
|
||||
|
||||
// Store the command at the 'head' location
|
||||
UsbCommand* destination = &cmdBuffer[cmd_head];
|
||||
UsbCommand* destination = &rxBuffer[cmd_head];
|
||||
memcpy(destination, command, sizeof(UsbCommand));
|
||||
|
||||
cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE; //increment head and wrap
|
||||
pthread_mutex_unlock(&cmdBufferMutex);
|
||||
pthread_mutex_unlock(&rxBufferMutex);
|
||||
}
|
||||
|
||||
|
||||
|
@ -152,22 +136,22 @@ void storeCommand(UsbCommand *command)
|
|||
* @param response location to write command
|
||||
* @return 1 if response was returned, 0 if nothing has been received
|
||||
*/
|
||||
int getCommand(UsbCommand* response)
|
||||
static int getCommand(UsbCommand* response)
|
||||
{
|
||||
pthread_mutex_lock(&cmdBufferMutex);
|
||||
pthread_mutex_lock(&rxBufferMutex);
|
||||
//If head == tail, there's nothing to read, or if we just got initialized
|
||||
if (cmd_head == cmd_tail){
|
||||
pthread_mutex_unlock(&cmdBufferMutex);
|
||||
pthread_mutex_unlock(&rxBufferMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Pick out the next unread command
|
||||
UsbCommand* last_unread = &cmdBuffer[cmd_tail];
|
||||
UsbCommand* last_unread = &rxBuffer[cmd_tail];
|
||||
memcpy(response, last_unread, sizeof(UsbCommand));
|
||||
//Increment tail - this is a circular buffer, so modulo buffer size
|
||||
cmd_tail = (cmd_tail + 1) % CMD_BUFFER_SIZE;
|
||||
|
||||
pthread_mutex_unlock(&cmdBufferMutex);
|
||||
pthread_mutex_unlock(&rxBufferMutex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -202,35 +186,54 @@ static void UsbCommandReceived(UsbCommand *UC)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
#ifdef __has_attribute
|
||||
#if __has_attribute(force_align_arg_pointer)
|
||||
__attribute__((force_align_arg_pointer))
|
||||
#endif
|
||||
#endif
|
||||
*uart_receiver(void *targ) {
|
||||
receiver_arg *conn = (receiver_arg*)targ;
|
||||
*uart_communication(void *targ) {
|
||||
communication_arg_t *conn = (communication_arg_t*)targ;
|
||||
size_t rxlen;
|
||||
uint8_t rx[sizeof(UsbCommand)];
|
||||
uint8_t *prx = rx;
|
||||
UsbCommand rx;
|
||||
UsbCommand *prx = ℞
|
||||
|
||||
while (conn->run) {
|
||||
rxlen = 0;
|
||||
if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-rx), &rxlen) && rxlen) {
|
||||
bool ACK_received = false;
|
||||
if (uart_receive(sp, (uint8_t *)prx, sizeof(UsbCommand) - (prx-&rx), &rxlen) && rxlen) {
|
||||
prx += rxlen;
|
||||
if (prx-rx < sizeof(UsbCommand)) {
|
||||
if (prx-&rx < sizeof(UsbCommand)) {
|
||||
continue;
|
||||
}
|
||||
UsbCommandReceived((UsbCommand*)rx);
|
||||
UsbCommandReceived(&rx);
|
||||
if (rx.cmd == CMD_ACK) {
|
||||
ACK_received = true;
|
||||
}
|
||||
prx = rx;
|
||||
}
|
||||
prx = ℞
|
||||
|
||||
if(txcmd_pending) {
|
||||
if (!uart_send(sp, (uint8_t*) &txcmd, sizeof(UsbCommand))) {
|
||||
|
||||
pthread_mutex_lock(&txBufferMutex);
|
||||
|
||||
if (conn->block_after_ACK) {
|
||||
// if we just received an ACK, wait here until a new command is to be transmitted
|
||||
if (ACK_received) {
|
||||
while (!txBuffer_pending) {
|
||||
pthread_cond_wait(&txBufferSig, &txBufferMutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(txBuffer_pending) {
|
||||
if (!uart_send(sp, (uint8_t*) &txBuffer, sizeof(UsbCommand))) {
|
||||
PrintAndLog("Sending bytes to proxmark failed");
|
||||
}
|
||||
txcmd_pending = false;
|
||||
txBuffer_pending = false;
|
||||
pthread_cond_signal(&txBufferSig); // tell main thread that txBuffer is empty
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&txBufferMutex);
|
||||
}
|
||||
|
||||
pthread_exit(NULL);
|
||||
|
@ -238,7 +241,6 @@ __attribute__((force_align_arg_pointer))
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Data transfer from Proxmark to client. This method times out after
|
||||
* ms_timeout milliseconds.
|
||||
|
@ -290,6 +292,66 @@ bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *respon
|
|||
}
|
||||
|
||||
|
||||
bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode) {
|
||||
char *portname = (char *)port;
|
||||
if (!wait_for_port) {
|
||||
sp = uart_open(portname);
|
||||
} else {
|
||||
printf("Waiting for Proxmark to appear on %s ", portname);
|
||||
fflush(stdout);
|
||||
int openCount = 0;
|
||||
do {
|
||||
sp = uart_open(portname);
|
||||
msleep(1000);
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
} while(++openCount < timeout && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// check result of uart opening
|
||||
if (sp == INVALID_SERIAL_PORT) {
|
||||
printf("ERROR: invalid serial port\n");
|
||||
sp = NULL;
|
||||
serial_port_name = NULL;
|
||||
return false;
|
||||
} else if (sp == CLAIMED_SERIAL_PORT) {
|
||||
printf("ERROR: serial port is claimed by another process\n");
|
||||
sp = NULL;
|
||||
serial_port_name = NULL;
|
||||
return false;
|
||||
} else {
|
||||
// start the USB communication thread
|
||||
serial_port_name = portname;
|
||||
conn.run = true;
|
||||
conn.block_after_ACK = flash_mode;
|
||||
pthread_create(&USB_communication_thread, NULL, &uart_communication, &conn);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CloseProxmark(void) {
|
||||
conn.run = false;
|
||||
pthread_join(USB_communication_thread, NULL);
|
||||
|
||||
if (sp) {
|
||||
uart_close(sp);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
// Fix for linux, it seems that it is extremely slow to release the serial port file descriptor /dev/*
|
||||
if (serial_port_name) {
|
||||
unlink(serial_port_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Clean up our state
|
||||
sp = NULL;
|
||||
serial_port_name = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Waits for a certain response type. This method waits for a maximum of
|
||||
* ms_timeout milliseconds for a specified response command.
|
||||
|
|
|
@ -22,24 +22,14 @@
|
|||
#define CMD_BUFFER_SIZE 50
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
// If TRUE, continue running the uart_receiver thread
|
||||
bool run;
|
||||
|
||||
// Lock around serial port receives
|
||||
pthread_mutex_t recv_lock;
|
||||
} receiver_arg;
|
||||
|
||||
|
||||
void SetOffline(bool new_offline);
|
||||
bool IsOffline();
|
||||
|
||||
bool OpenProxmark(char *portname, bool waitCOMPort, int timeout);
|
||||
bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode);
|
||||
void CloseProxmark(void);
|
||||
|
||||
void SendCommand(UsbCommand *c);
|
||||
|
||||
void *uart_receiver(void *targ);
|
||||
void clearCommandBuffer();
|
||||
bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning);
|
||||
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
|
||||
|
|
|
@ -20,12 +20,7 @@
|
|||
#include "elf.h"
|
||||
#include "proxendian.h"
|
||||
#include "usb_cmd.h"
|
||||
#include "uart.h"
|
||||
|
||||
void SendCommand(UsbCommand* txcmd);
|
||||
void ReceiveCommand(UsbCommand* rxcmd);
|
||||
|
||||
serial_port sp;
|
||||
#include "comms.h"
|
||||
|
||||
#define FLASH_START 0x100000
|
||||
#define FLASH_SIZE (256*1024)
|
||||
|
@ -42,22 +37,6 @@ static const uint8_t elf_ident[] = {
|
|||
EV_CURRENT
|
||||
};
|
||||
|
||||
void CloseProxmark(const char *serial_port_name) {
|
||||
// Clean up the port
|
||||
uart_close(sp);
|
||||
// Fix for linux, it seems that it is extremely slow to release the serial port file descriptor /dev/*
|
||||
unlink(serial_port_name);
|
||||
}
|
||||
|
||||
bool OpenProxmark(size_t i, const char *serial_port_name) {
|
||||
sp = uart_open(serial_port_name);
|
||||
if (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT) {
|
||||
//poll once a second
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent
|
||||
// unaligned segments if needed
|
||||
|
@ -207,7 +186,7 @@ static int check_segs(flash_file_t *ctx, int can_write_bl) {
|
|||
}
|
||||
|
||||
// Load an ELF file and prepare it for flashing
|
||||
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl)
|
||||
int flash_load(flash_file_t *ctx, const char *name, bool can_write_bl)
|
||||
{
|
||||
FILE *fd = NULL;
|
||||
Elf32_Ehdr ehdr;
|
||||
|
@ -295,7 +274,7 @@ static int get_proxmark_state(uint32_t *state)
|
|||
c.cmd = CMD_DEVICE_INFO;
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
ReceiveCommand(&resp);
|
||||
WaitForResponse(CMD_UNKNOWN, &resp); // wait for any response. No timeout.
|
||||
|
||||
// Three outcomes:
|
||||
// 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK
|
||||
|
@ -355,17 +334,16 @@ static int enter_bootloader(char *serial_port_name)
|
|||
}
|
||||
|
||||
msleep(100);
|
||||
CloseProxmark(serial_port_name);
|
||||
|
||||
fprintf(stderr,"Waiting for Proxmark to reappear on %s",serial_port_name);
|
||||
do {
|
||||
sleep(1);
|
||||
fprintf(stderr, ".");
|
||||
} while (!OpenProxmark(0, serial_port_name));
|
||||
CloseProxmark();
|
||||
|
||||
bool opened = OpenProxmark(serial_port_name, true, 120, true); // wait for 2 minutes
|
||||
if (opened) {
|
||||
fprintf(stderr," Found.\n");
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr,"Error: Proxmark not found.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Error: Unknown Proxmark mode\n");
|
||||
|
@ -375,7 +353,7 @@ static int enter_bootloader(char *serial_port_name)
|
|||
static int wait_for_ack(void)
|
||||
{
|
||||
UsbCommand ack;
|
||||
ReceiveCommand(&ack);
|
||||
WaitForResponse(CMD_UNKNOWN, &ack);
|
||||
if (ack.cmd != CMD_ACK) {
|
||||
printf("Error: Unexpected reply 0x%04" PRIx64 " (expected ACK)\n", ack.cmd);
|
||||
return -1;
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
#define __FLASH_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "elf.h"
|
||||
#include "uart.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
void *data;
|
||||
|
@ -26,14 +25,10 @@ typedef struct {
|
|||
flash_seg_t *segments;
|
||||
} flash_file_t;
|
||||
|
||||
int flash_load(flash_file_t *ctx, const char *name, int can_write_bl);
|
||||
int flash_load(flash_file_t *ctx, const char *name, bool can_write_bl);
|
||||
int flash_start_flashing(int enable_bl_writes, char *serial_port_name);
|
||||
int flash_write(flash_file_t *ctx);
|
||||
void flash_free(flash_file_t *ctx);
|
||||
int flash_stop_flashing(void);
|
||||
void CloseProxmark(const char *serial_port_name);
|
||||
bool OpenProxmark(size_t i, const char *serial_port_name);
|
||||
|
||||
extern serial_port sp;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -10,18 +10,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <pthread.h>
|
||||
#include "proxmark3.h"
|
||||
#include "util.h"
|
||||
#include "util_posix.h"
|
||||
#include "flash.h"
|
||||
#include "uart.h"
|
||||
#include "comms.h"
|
||||
#include "usb_cmd.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# define unlink(x)
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
void cmd_debug(UsbCommand* UC) {
|
||||
// Debug
|
||||
|
@ -37,29 +33,6 @@ void cmd_debug(UsbCommand* UC) {
|
|||
printf("...\n");
|
||||
}
|
||||
|
||||
void SendCommand(UsbCommand* txcmd) {
|
||||
// printf("send: ");
|
||||
// cmd_debug(txcmd);
|
||||
if (!uart_send(sp,(uint8_t*)txcmd,sizeof(UsbCommand))) {
|
||||
printf("Sending bytes to proxmark failed\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void ReceiveCommand(UsbCommand* rxcmd) {
|
||||
uint8_t* prxcmd = (uint8_t*)rxcmd;
|
||||
uint8_t* prx = prxcmd;
|
||||
size_t rxlen;
|
||||
while (true) {
|
||||
if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-prxcmd), &rxlen)) {
|
||||
prx += rxlen;
|
||||
if ((prx-prxcmd) >= sizeof(UsbCommand)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(char *argv0)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <port> [-b] image.elf [image.elf...]\n\n", argv0);
|
||||
|
@ -77,7 +50,7 @@ static void usage(char *argv0)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int can_write_bl = 0;
|
||||
int can_write_bl = false;
|
||||
int num_files = 0;
|
||||
int res;
|
||||
flash_file_t files[MAX_FILES];
|
||||
|
@ -92,7 +65,7 @@ int main(int argc, char **argv)
|
|||
for (int i = 2; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
if (!strcmp(argv[i], "-b")) {
|
||||
can_write_bl = 1;
|
||||
can_write_bl = true;
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
|
@ -110,12 +83,12 @@ int main(int argc, char **argv)
|
|||
|
||||
char* serial_port_name = argv[1];
|
||||
|
||||
fprintf(stderr,"Waiting for Proxmark to appear on %s", serial_port_name);
|
||||
do {
|
||||
msleep(1000);
|
||||
fprintf(stderr, ".");
|
||||
} while (!OpenProxmark(0, serial_port_name));
|
||||
if (!OpenProxmark(serial_port_name, true, 120, true)) { // wait for 2 minutes
|
||||
fprintf(stderr, "Could not find Proxmark on %s.\n\n", serial_port_name);
|
||||
return -1;
|
||||
} else {
|
||||
fprintf(stderr," Found.\n");
|
||||
}
|
||||
|
||||
res = flash_start_flashing(can_write_bl, serial_port_name);
|
||||
if (res < 0)
|
||||
|
@ -137,7 +110,8 @@ int main(int argc, char **argv)
|
|||
if (res < 0)
|
||||
return -1;
|
||||
|
||||
CloseProxmark(serial_port_name);
|
||||
// Stop the command thread.
|
||||
CloseProxmark();
|
||||
|
||||
fprintf(stderr, "All done.\n\n");
|
||||
fprintf(stderr, "Have a nice day!\n");
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <pthread.h>
|
||||
|
||||
#include "crapto1/crapto1.h"
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "usb_cmd.h"
|
||||
#include "cmdmain.h"
|
||||
#include "ui.h"
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
// Main binary
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "proxmark3.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -17,7 +19,6 @@
|
|||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
#include "proxmark3.h"
|
||||
#include "util_posix.h"
|
||||
#include "proxgui.h"
|
||||
#include "cmdmain.h"
|
||||
|
@ -26,7 +27,7 @@
|
|||
#include "cmdparser.h"
|
||||
#include "cmdhw.h"
|
||||
#include "whereami.h"
|
||||
|
||||
#include "comms.h"
|
||||
|
||||
void
|
||||
#ifdef __has_attribute
|
||||
|
@ -35,18 +36,12 @@ __attribute__((force_align_arg_pointer))
|
|||
#endif
|
||||
#endif
|
||||
main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
||||
receiver_arg conn;
|
||||
char *cmd = NULL;
|
||||
pthread_t reader_thread;
|
||||
bool execCommand = (script_cmd != NULL);
|
||||
bool stdinOnPipe = !isatty(STDIN_FILENO);
|
||||
|
||||
memset(&conn, 0, sizeof(receiver_arg));
|
||||
|
||||
if (usb_present) {
|
||||
conn.run = true;
|
||||
SetOffline(false);
|
||||
pthread_create(&reader_thread, NULL, &uart_receiver, &conn);
|
||||
// cache Version information now:
|
||||
CmdVersion(NULL);
|
||||
} else {
|
||||
|
@ -137,11 +132,6 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) {
|
|||
|
||||
write_history(".history");
|
||||
|
||||
if (usb_present) {
|
||||
conn.run = false;
|
||||
pthread_join(reader_thread, NULL);
|
||||
}
|
||||
|
||||
if (script_file) {
|
||||
fclose(script_file);
|
||||
script_file = NULL;
|
||||
|
@ -294,7 +284,7 @@ int main(int argc, char* argv[]) {
|
|||
set_my_executable_path();
|
||||
|
||||
// try to open USB connection to Proxmark
|
||||
usb_present = OpenProxmark(argv[1], waitCOMPort, 20);
|
||||
usb_present = OpenProxmark(argv[1], waitCOMPort, 20, false);
|
||||
|
||||
#ifdef HAVE_GUI
|
||||
#ifdef _WIN32
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
void SendCommand(UsbCommand *c);
|
||||
const char *get_my_executable_path(void);
|
||||
const char *get_my_executable_directory(void);
|
||||
void main_loop(char *script_cmds_file, char *script_cmd, bool usb_present);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include "proxmark3.h"
|
||||
#include "comms.h"
|
||||
#include "usb_cmd.h"
|
||||
#include "cmdmain.h"
|
||||
#include "util.h"
|
||||
|
|
340
client/scripts/mifarePlus.lua
Normal file
340
client/scripts/mifarePlus.lua
Normal file
|
@ -0,0 +1,340 @@
|
|||
local cmds = require('commands')
|
||||
local lib14a = require('read14a')
|
||||
getopt = require('getopt') -- Used to get command line arguments
|
||||
|
||||
example = "script run mifarePlus"
|
||||
author = "Dominic Celiano"
|
||||
desc =
|
||||
[[
|
||||
Purpose: Lua script to communicate with the Mifare Plus EV1, including personalization (setting the keys) and proximity check. Manually edit the file to add to the commands you can send the card.
|
||||
|
||||
Please read the NXP manual before running this script to prevent making irreversible changes. Also note:
|
||||
- The Mifare Plus must start in SL0 for personalization. Card can then be moved to SL1 or SL3.
|
||||
- The keys are hardcoded in the script to "00...". Unless you change this, only use this script for testing purposes.
|
||||
- Make sure you choose your card size correctly (2kB or 4kB).
|
||||
|
||||
Small changes can be to made this script to communicate with the Mifare Plus S, X, or SE.
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
]]
|
||||
|
||||
SIXTEEN_BYTES_ZEROS = "00000000000000000000000000000000"
|
||||
|
||||
GETVERS_INIT = "0360" -- Begins the GetVersion command
|
||||
GETVERS_CONT = "03AF" -- Continues the GetVersion command
|
||||
POWEROFF = "OFF"
|
||||
WRITEPERSO = "03A8"
|
||||
COMMITPERSO = "03AA"
|
||||
AUTH_FIRST = "0370"
|
||||
AUTH_CONT = "0372"
|
||||
AUTH_NONFIRST = "0376"
|
||||
PREPAREPC = "03F0"
|
||||
PROXIMITYCHECK = "03F2"
|
||||
VERIFYPC = "03FD"
|
||||
READPLAINNOMACUNMACED = "0336"
|
||||
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
|
||||
---
|
||||
-- Used to send raw data to the firmware to subsequently forward the data to the card.
|
||||
function sendRaw(rawdata, crc, power)
|
||||
print(("<sent>: %s"):format(rawdata))
|
||||
|
||||
local flags = lib14a.ISO14A_COMMAND.ISO14A_RAW
|
||||
if crc then
|
||||
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC
|
||||
end
|
||||
if power then
|
||||
flags = flags + lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT
|
||||
end
|
||||
|
||||
local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
|
||||
arg1 = flags, -- Send raw
|
||||
arg2 = string.len(rawdata) / 2, -- arg2 contains the length, which is half the length of the ASCII-string rawdata
|
||||
data = rawdata}
|
||||
local ignore_response = false
|
||||
local result, err = lib14a.sendToDevice(command, ignore_response)
|
||||
if result then
|
||||
--unpack the first 4 parts of the result as longs, and the last as an extremely long string to later be cut down based on arg1, the number of bytes returned
|
||||
local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',result)
|
||||
returned_bytes = string.sub(data, 1, arg1 * 2)
|
||||
if returned_bytes ~= "" then
|
||||
print(("<recvd>: %s"):format(returned_bytes)) -- need to multiply by 2 because the hex digits are actually two bytes when they are strings
|
||||
end
|
||||
return returned_bytes
|
||||
else
|
||||
err = "Error sending the card raw data."
|
||||
oops(err)
|
||||
end
|
||||
end
|
||||
|
||||
function writePerso()
|
||||
-- Used to write any data, including the keys (Key A and Key B), for all the sectors.
|
||||
-- writePerso() command parameters:
|
||||
-- 1 byte - 0xA8 - Command Code
|
||||
-- 2 bytes - Address of the first block or key to be written to (40 blocks are numbered from 0x0000 to 0x00FF)
|
||||
-- X bytes - The data bytes to be written, starting from the first block. Amount of data sent can be from 16 to 240 bytes in 16 byte increments. This allows
|
||||
-- up to 15 blocks to be written at once.
|
||||
-- response from PICC:
|
||||
-- 0x90 - OK
|
||||
-- 0x09 - targeted block is invalid for writes, i.e. block 0, which contains manufacturer data
|
||||
-- 0x0B - command invalid
|
||||
-- 0x0C - unexpected command length
|
||||
|
||||
|
||||
|
||||
cardsize = 4 --need to set to 4 for 4k or 2 for 2k
|
||||
if(cardsize == 4) then
|
||||
numsectors = 39
|
||||
elseif(cardsize == 2) then
|
||||
numsectors = 31
|
||||
else
|
||||
oops("Invalid card size")
|
||||
end
|
||||
|
||||
-- Write to the AES sector keys
|
||||
print("Setting AES Sector keys")
|
||||
for i=0,numsectors do --for each sector number
|
||||
local keyA_block = "40" .. string.format("%02x", i * 2)
|
||||
local keyB_block = "40" .. string.format("%02x", (i * 2) + 1)
|
||||
--Can also calculate the keys fancily to make them unique, if desired
|
||||
keyA = SIXTEEN_BYTES_ZEROS
|
||||
keyB = SIXTEEN_BYTES_ZEROS
|
||||
writeBlock(keyA_block, keyA)
|
||||
writeBlock(keyB_block, keyB)
|
||||
end
|
||||
print("Finished setting AES Sector keys")
|
||||
|
||||
print("Setting misc keys which haven't been set yet.")
|
||||
--CardMasterKey
|
||||
blocknum = "9000"
|
||||
writeBlock(blocknum, SIXTEEN_BYTES_ZEROS)
|
||||
--CardConfigurationKey
|
||||
blocknum = "9001"
|
||||
writeBlock(blocknum, SIXTEEN_BYTES_ZEROS)
|
||||
--L3SwitchKey
|
||||
blocknum = "9003"
|
||||
writeBlock(blocknum, SIXTEEN_BYTES_ZEROS)
|
||||
--SL1CardAuthKey
|
||||
blocknum = "9004"
|
||||
writeBlock(blocknum, SIXTEEN_BYTES_ZEROS)
|
||||
--L3SectorSwitchKey
|
||||
blocknum = "9006"
|
||||
writeBlock(blocknum, SIXTEEN_BYTES_ZEROS)
|
||||
--L1L3MixSectorSwitchKey
|
||||
blocknum = "9007"
|
||||
writeBlock(blocknum, SIXTEEN_BYTES_ZEROS)
|
||||
--VC Keys
|
||||
--VCProximityKey
|
||||
blocknum = "A001"
|
||||
writeBlock(blocknum, SIXTEEN_BYTES_ZEROS)
|
||||
--VCSelectENCKey
|
||||
blocknum = "A080"
|
||||
writeBlock(blocknum, SIXTEEN_BYTES_ZEROS)
|
||||
--VCSelectMACKey
|
||||
blocknum = "A081"
|
||||
writeBlock(blocknum, SIXTEEN_BYTES_ZEROS)
|
||||
--TransactionMACKey1
|
||||
blocknum = "C000"
|
||||
writeBlock(blocknum, SIXTEEN_BYTES_ZEROS)
|
||||
--TransactionMACConfKey1
|
||||
blocknum = "C001"
|
||||
writeBlock(blocknum, SIXTEEN_BYTES_ZEROS)
|
||||
print("Finished setting misc keys.")
|
||||
|
||||
print("WritePerso finished! Card is ready to move into new security level.")
|
||||
end
|
||||
|
||||
function writeBlock(blocknum, data)
|
||||
-- Method writes 16 bytes of the string sent (data) to the specified block number
|
||||
-- The block numbers sent to the card need to be in little endian format (i.e. block 0x0001 is sent as 0x1000)
|
||||
blocknum_little_endian = string.sub(blocknum, 3, 4) .. string.sub(blocknum, 1, 2)
|
||||
commandString = WRITEPERSO .. blocknum_little_endian .. data --Write 16 bytes (32 hex chars).
|
||||
response = sendRaw(commandString, true, true) --0x90 is returned upon success
|
||||
if string.sub(response, 3, 4) ~= "90" then
|
||||
oops(("error occurred while trying to write to block %s"):format(blocknum))
|
||||
end
|
||||
end
|
||||
|
||||
function authenticateAES()
|
||||
-- Used to try to authenticate with the AES keys we programmed into the card, to ensure the authentication works correctly.
|
||||
commandString = AUTH_FIRST
|
||||
commandString = commandString .. ""
|
||||
end
|
||||
|
||||
function getVersion()
|
||||
sendRaw(GETVERS_INIT, true, true)
|
||||
sendRaw(GETVERS_CONT, true, true)
|
||||
sendRaw(GETVERS_CONT, true, true)
|
||||
end
|
||||
|
||||
function commitPerso(SL)
|
||||
--pass SL as "01" to move to SL1 or "03" to move to SL3.
|
||||
commandString = COMMITPERSO .. SL
|
||||
response = sendRaw(commandString, true, true) --0x90 is returned upon success
|
||||
if string.sub(response, 3, 4) ~= "90" then
|
||||
oops("error occurred while trying to switch security level")
|
||||
end
|
||||
end
|
||||
|
||||
function calculateMAC(MAC_input)
|
||||
-- Pad the input if it is not a multiple of 16 bytes (32 nibbles).
|
||||
if(string.len(MAC_input) % 32 ~= 0) then
|
||||
MAC_input = MAC_input .. "80"
|
||||
end
|
||||
while(string.len(MAC_input) % 32 ~= 0) do
|
||||
MAC_input = MAC_input .. "0"
|
||||
end
|
||||
print("Padded MAC Input = " .. MAC_input .. ", length (bytes) = " .. string.len(MAC_input) / 2)
|
||||
|
||||
--The MAC would actually be calculated here, and the output stored in raw_output
|
||||
raw_output = "00010203040506070001020304050607" -- Dummy filler for now of 16-byte output. To be filled with actual MAC for testing purposes.
|
||||
|
||||
-- The final 8-byte MAC output is a concatenation of every 2nd byte starting from the second MSB.
|
||||
final_output = ""
|
||||
j = 3
|
||||
for i = 1,8 do
|
||||
final_output = final_output .. string.sub(RndR, j, j + 1) .. string.sub(RndC, j, j + 1)
|
||||
j = j + 4
|
||||
end
|
||||
return final_output
|
||||
end
|
||||
|
||||
function proximityCheck()
|
||||
--PreparePC--
|
||||
commandString = PREPAREPC
|
||||
response = sendRaw(commandString, true, true)
|
||||
if(response == "") then
|
||||
print("ERROR: This card does not support the Proximity Check command.")
|
||||
return
|
||||
end
|
||||
OPT = string.sub(response, 5, 6)
|
||||
if(tonumber(OPT) == 1) then
|
||||
pps_present = true
|
||||
else
|
||||
pps_present = false
|
||||
end
|
||||
pubRespTime = string.sub(response, 7, 10)
|
||||
if(pps_present == true) then
|
||||
pps = string.sub(response, 11, 12)
|
||||
else
|
||||
pps = nil
|
||||
end
|
||||
print("OPT = " .. OPT .. " pubRespTime = " .. pubRespTime .. " pps = " .. pps)
|
||||
|
||||
--PC--
|
||||
RndC = "0001020304050607" --Random Challenge
|
||||
num_rounds = 8 --Needs to be 1, 2, 4, or 8
|
||||
part_len = 8 / num_rounds
|
||||
j = 1
|
||||
RndR = ""
|
||||
for i = 1,num_rounds do
|
||||
pRndC = ""
|
||||
for q = 1,(part_len*2) do
|
||||
pRndC = pRndC .. string.sub(RndC,j,j)
|
||||
j = j + 1
|
||||
end
|
||||
commandString = PROXIMITYCHECK .. "0" .. tostring(part_len) .. pRndC
|
||||
pRndR = string.sub(sendRaw(commandString, true, true), 3, 3+part_len)
|
||||
RndR = RndR .. pRndR
|
||||
end
|
||||
print("RndC = " .. RndC .. " RndR = " .. RndR)
|
||||
|
||||
--VerifyPC--
|
||||
MAC_input = "FD" .. OPT .. pubRespTime
|
||||
if(pps_present == true) then
|
||||
MAC_input = MAC_input .. pps
|
||||
end
|
||||
rnum_concat = ""
|
||||
rnum_concat = RndR .. RndC --temporary (only works for when a single random challenge (8 bytes) is sent)
|
||||
-- j = 1
|
||||
-- for i = 1,8 do
|
||||
-- rnum_concat = rnum_concat .. string.sub(RndR, j, j + 1) .. string.sub(RndC, j, j + 1)
|
||||
-- j = j + 2
|
||||
-- end
|
||||
MAC_input = MAC_input .. rnum_concat
|
||||
print("Concatenation of random numbers = " .. rnum_concat)
|
||||
print("Final PCD concatenation before input into MAC function = " .. MAC_input)
|
||||
MAC_tag = calculateMAC(MAC_input)
|
||||
print("8-byte PCD MAC_tag (placeholder - currently incorrect) = " .. MAC_tag)
|
||||
commandString = VERIFYPC .. MAC_tag
|
||||
response = sendRaw(commandString, true, true)
|
||||
print(response)
|
||||
PICC_MAC = string.sub(response, 5, 20)
|
||||
print("8-byte MAC returned by PICC = " .. PICC_MAC)
|
||||
MAC_input = "90" .. string.sub(MAC_input, 3)
|
||||
print("Final PICC concatenation before input into MAC function = " .. MAC_input)
|
||||
MAC_tag = calculateMAC(MAC_input)
|
||||
print("8-byte PICC MAC_tag (placeholder - currently incorrect) = " .. MAC_tag)
|
||||
|
||||
end
|
||||
|
||||
---
|
||||
-- The main entry point
|
||||
function main(args)
|
||||
print("") -- Print a blank line to make things look cleaner
|
||||
for o, a in getopt.getopt(args, 'h') do -- Populate command line arguments
|
||||
if o == "h" then help() return end
|
||||
end
|
||||
|
||||
-- Initialize the card using the already-present read14a library
|
||||
info,err = lib14a.read14443a(true, false)
|
||||
--Perform RATS and PPS (Protocol and Parameter Selection) check to finish the ISO 14443-4 protocol.
|
||||
response = sendRaw("e050", true, true)
|
||||
if(response == "") then
|
||||
print("No response from RATS.")
|
||||
end
|
||||
response = sendRaw("D01100", true, true)
|
||||
if(response == "") then
|
||||
print("No response from PPS check.")
|
||||
end
|
||||
if err then
|
||||
oops(err)
|
||||
sendRaw(POWEROFF, false, false)
|
||||
return
|
||||
else
|
||||
print(("Connected to card with a UID of %s."):format(info.uid))
|
||||
end
|
||||
|
||||
|
||||
-- Now, the card is initialized and we can do more interesting things.
|
||||
|
||||
--writePerso()
|
||||
--commitPerso("03") --move to SL3
|
||||
--getVersion()
|
||||
proximityCheck()
|
||||
|
||||
--commandString = VERIFYPC .. "186EFDE8DDC7D30B"
|
||||
-- MAC = f5180d6e 40fdeae8 e9dd6ac7 bcd3350b
|
||||
-- response = sendRaw(commandString, true, true)
|
||||
|
||||
-- attempt to read VCProximityKey at block A001
|
||||
-- commandString = READPLAINNOMACUNMACED .. "01A0" .. "01"
|
||||
-- response = sendRaw(commandString, true, true)
|
||||
|
||||
-- authenticate with CardConfigurationKey
|
||||
-- commandString = AUTH_FIRST .. "0190" .. "00"
|
||||
-- response = sendRaw(commandString, true, true)
|
||||
|
||||
-- Power off the Proxmark
|
||||
sendRaw(POWEROFF, false, false)
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
main(args) -- Call the main function
|
Loading…
Add table
Add a link
Reference in a new issue