From 83b63bea29f982d0b99d8d2c89e7cff466d24492 Mon Sep 17 00:00:00 2001 From: "Thomas J L. Harkness" Date: Tue, 3 Apr 2018 12:56:37 +1000 Subject: [PATCH 1/9] more fixes for parity bits --- client/scripts/lf_bulk_program.lua | 38 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/client/scripts/lf_bulk_program.lua b/client/scripts/lf_bulk_program.lua index 274f7510..6d402dc1 100644 --- a/client/scripts/lf_bulk_program.lua +++ b/client/scripts/lf_bulk_program.lua @@ -9,7 +9,7 @@ bit32 = require('bit32') usage = [[ script run lf_bulk_program.lua -f facility -b base_id_num -c count - e.g: + e.g: script run lf_bulk_program.lua -f 1 -b 1000 -c 10 ]] author = "Brian Redbeard" @@ -32,12 +32,12 @@ function toBits(num,bits) end --[[Likely, I'm an idiot, but I couldn't find any parity functions in Lua - This can also be done with a combination of bitwise operations (in fact, + This can also be done with a combination of bitwise operations (in fact, is the canonically "correct" way to do it, but my brain doesn't just default to this and so counting some ones is good enough for me]]-- local function evenparity(s) local _, count = string.gsub(s, "1", "") - + local p = count % 2 if (p == 0) then return(false) @@ -45,7 +45,7 @@ local function evenparity(s) return(true) end end - + local function isempty(s) return s == nil or s == '' @@ -57,7 +57,7 @@ end local function cardHex(i,f) fac = bit32.lshift(f,16) id = bit32.bor(i, fac) - stream=toBits(id,26) + stream=toBits(id,24) --As the function defaults to even parity and returns a boolean, --perform a 'not' function to get odd parity @@ -71,13 +71,13 @@ local function cardHex(i,f) --to create a higher order and lower order component which we will --then assemble in the return. The math above defines the proper --encoding as per HID/Weigand/etc. These bit flips are due to the - --format length check on bit 38 (cmdlfhid.c:64) and + --format length check on bit 38 (cmdlfhid.c:64) and --bit 31 (cmdlfhid.c:66). preamble = bit32.bor(0, bit32.lshift(1,5)) bits = bit32.bor(bits, bit32.lshift(1,26)) return ("%04x%08x"):format(preamble,bits) - + end local function main(args) @@ -86,22 +86,22 @@ local function main(args) --long arguments, but it seems this library was chosen for BSD style --compatibility for o, a in getopt.getopt(args, 'f:b:c:h') do - if o == 'f' then - if isempty(a) then + if o == 'f' then + if isempty(a) then print("You did not supply a facility code, using 0") facility = 0 - else + else facility = a end - elseif o == 'b' then - if isempty(a) then + elseif o == 'b' then + if isempty(a) then print("You must supply the flag -b (base id)") return else baseid = a end - elseif o == 'c' then - if isempty(a) then + elseif o == 'c' then + if isempty(a) then print("You must supply the flag -c (count)") return else @@ -118,22 +118,22 @@ local function main(args) --works, specifying ":" does not enforce supplying a value, thus we --need to do these checks all over again. - if isempty(baseid) then + if isempty(baseid) then print("You must supply the flag -b (base id)") print(usage) return end - if isempty(count) then + if isempty(count) then print("You must supply the flag -c (count)") print(usage) return end --If the facility ID is non specified, ensure we code it as zero - if isempty(facility) then + if isempty(facility) then print("Using 0 for the facility code as -f was not supplied") - facility = 0 + facility = 0 end --The next baseid + count function presents a logic/UX conflict @@ -144,7 +144,7 @@ local function main(args) endid = baseid + count - for cardnum = baseid,endid do + for cardnum = baseid,endid do local card = cardHex(cardnum, facility) print("Press enter to program card "..cardnum..":"..facility.." (hex: "..card..")") --This would be better with "press any key", but we'll take From 24fe17e9e9a67ac558891c84f2b46f82fdf1e259 Mon Sep 17 00:00:00 2001 From: "Thomas J L. Harkness" Date: Tue, 3 Apr 2018 15:44:39 +1000 Subject: [PATCH 2/9] Fix for bulk HID card programming and parity issues --- client/scripts/lf_bulk_program.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/scripts/lf_bulk_program.lua b/client/scripts/lf_bulk_program.lua index 6d402dc1..81fb96db 100644 --- a/client/scripts/lf_bulk_program.lua +++ b/client/scripts/lf_bulk_program.lua @@ -61,8 +61,9 @@ local function cardHex(i,f) --As the function defaults to even parity and returns a boolean, --perform a 'not' function to get odd parity - high = not evenparity(string.sub(stream,0,12)) and 1 or 0 - low = evenparity(string.sub(stream,13)) and 1 or 0 + high = evenparity(string.sub(stream,1,12)) and 1 or 0 + low = not evenparity(string.sub(stream,13)) and 1 or 0 + bits = bit32.bor(bit32.lshift(id,1), low) bits = bit32.bor(bits, bit32.lshift(high,25)) From fdde89cf9ef5e358c0d4fae4ca9b837895350a04 Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Tue, 3 Apr 2018 08:13:31 +0200 Subject: [PATCH 3/9] Update lf_bulk_program.lua --- client/scripts/lf_bulk_program.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/scripts/lf_bulk_program.lua b/client/scripts/lf_bulk_program.lua index 81fb96db..2556f8a5 100644 --- a/client/scripts/lf_bulk_program.lua +++ b/client/scripts/lf_bulk_program.lua @@ -61,8 +61,8 @@ local function cardHex(i,f) --As the function defaults to even parity and returns a boolean, --perform a 'not' function to get odd parity - high = evenparity(string.sub(stream,1,12)) and 1 or 0 - low = not evenparity(string.sub(stream,13)) and 1 or 0 + high = evenparity(string.sub(stream,1,12)) and 1 or 0 + low = not evenparity(string.sub(stream,13)) and 1 or 0 bits = bit32.bor(bit32.lshift(id,1), low) bits = bit32.bor(bits, bit32.lshift(high,25)) From cbce5db9aa383f448cdd501d8c128fa34e7f5a80 Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Tue, 24 Apr 2018 08:27:29 +0200 Subject: [PATCH 4/9] USB comms: part 2 towards @micolous PR#463 (#595) * change variable 'offline' from global to static * change variable 'FlushAfterWrite' from global to static * remove unused global variable 'current_command' * WaitForResponseTimeoutW(CMD_UNKNOWN, ...) waits for any command * #include "printf.h" or in iso15693tools.c to define sprintf() * and some minor changes/comments --- client/cmdlf.c | 8 ++++---- client/cmdmain.c | 2 -- client/cmdparser.c | 2 +- client/comms.c | 28 +++++++++++++++++++++++----- client/comms.h | 6 +++++- client/flash.c | 12 ++++++------ client/flash.h | 2 +- client/hid-flasher/proxusb.c | 2 -- client/proxmark3.c | 12 ++++++------ client/ui.c | 10 +++++++--- client/ui.h | 2 +- common/Makefile.common | 2 +- common/iso15693tools.c | 8 ++++++-- 13 files changed, 61 insertions(+), 35 deletions(-) diff --git a/client/cmdlf.c b/client/cmdlf.c index 42f73fa1..63dd737e 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -327,7 +327,7 @@ int CmdLFSetConfig(const char *Cmd) } bool lf_read(bool silent, uint32_t samples) { - if (offline) return false; + if (IsOffline()) return false; UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {silent,samples,0}}; clearCommandBuffer(); //And ship it to device @@ -870,7 +870,7 @@ int CmdVchDemod(const char *Cmd) int CheckChipType(char cmdp) { uint32_t wordData = 0; - if (offline || cmdp == '1') return 0; + if (IsOffline() || cmdp == '1') return 0; save_restoreGB(GRAPH_SAVE); save_restoreDB(GRAPH_SAVE); @@ -915,7 +915,7 @@ int CmdLFfind(const char *Cmd) return 0; } - if (!offline && (cmdp != '1')) { + if (!IsOffline() && (cmdp != '1')) { lf_read(true, 30000); } else if (GraphTraceLen < minLength) { PrintAndLog("Data in Graphbuffer was too small."); @@ -931,7 +931,7 @@ int CmdLFfind(const char *Cmd) // only run if graphbuffer is just noise as it should be for hitag/cotag if (graphJustNoise(GraphBuffer, testLen)) { // only run these tests if we are in online mode - if (!offline && (cmdp != '1')) { + if (!IsOffline() && (cmdp != '1')) { // test for em4x05 in reader talk first mode. if (EM4x05Block0Test(&wordData)) { PrintAndLog("\nValid EM4x05/EM4x69 Chip Found\nUse lf em 4x05readword/dump commands to read\n"); diff --git a/client/cmdmain.c b/client/cmdmain.c index 10948c97..a45e3430 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -29,8 +29,6 @@ #include "cmdscript.h" -unsigned int current_command = CMD_UNKNOWN; - static int CmdHelp(const char *Cmd); static int CmdQuit(const char *Cmd); diff --git a/client/cmdparser.c b/client/cmdparser.c index f4d3c404..34230d52 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -25,7 +25,7 @@ void CmdsHelp(const command_t Commands[]) int i = 0; while (Commands[i].Name) { - if (!offline || Commands[i].Offline) + if (!IsOffline() || Commands[i].Offline) PrintAndLog("%-16s %s", Commands[i].Name, Commands[i].Help); ++i; } diff --git a/client/comms.c b/client/comms.c index 5b8266fe..2dd5534c 100644 --- a/client/comms.c +++ b/client/comms.c @@ -24,7 +24,7 @@ serial_port sp; // If TRUE, then there is no active connection to the PM3, and we will drop commands sent. -bool offline; +static bool offline; // Transmit buffer. // TODO: Use locks and execute this on the main thread, rather than the receiver @@ -47,10 +47,20 @@ static int cmd_tail = 0; // to lock cmdBuffer operations from different threads static pthread_mutex_t cmdBufferMutex = 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. + +void SetOffline(bool new_offline) { + offline = new_offline; +} + +bool IsOffline() { + return offline; +} void SendCommand(UsbCommand *c) { - #if 0 - printf("Sending %d bytes\n", sizeof(UsbCommand)); + #ifdef COMMS_DEBUG + printf("Sending %04x cmd\n", c->cmd); #endif if (offline) { @@ -153,6 +163,8 @@ void UsbCommandReceived(UsbCommand *UC) } break; case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: { + // FIXME: This does unsanitised copies into memory when we don't know + // the size of the buffer. memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]); return; } break; @@ -205,15 +217,20 @@ __attribute__((force_align_arg_pointer)) * Waits for a certain response type. This method waits for a maximum of * ms_timeout milliseconds for a specified response command. *@brief WaitForResponseTimeout - * @param cmd command to wait for + * @param cmd command to wait for, or CMD_UNKNOWN to take any command. * @param response struct to copy received command into. * @param ms_timeout + * @param show_warning * @return true if command was returned, otherwise false */ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning) { UsbCommand resp; + #ifdef COMMS_DEBUG + printf("Waiting for %04x cmd\n", cmd); + #endif + if (response == NULL) { response = &resp; } @@ -223,7 +240,7 @@ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeo // Wait until the command is received while (true) { while(getCommand(response)) { - if(response->cmd == cmd){ + if (cmd == CMD_UNKNOWN || response->cmd == cmd) { return true; } } @@ -233,6 +250,7 @@ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeo } if (msclock() - start_time > 2000 && show_warning) { + // 2 seconds elapsed (but this doesn't mean the timeout was exceeded) PrintAndLog("Waiting for a response from the proxmark..."); PrintAndLog("You can cancel this operation by pressing the pm3 button"); show_warning = false; diff --git a/client/comms.h b/client/comms.h index 40576018..51a1467d 100644 --- a/client/comms.h +++ b/client/comms.h @@ -30,6 +30,11 @@ typedef struct { pthread_mutex_t recv_lock; } receiver_arg; + +// Wrappers required as static variables can only be used in one file. +void SetOffline(bool new_offline); +bool IsOffline(); + void SendCommand(UsbCommand *c); void *uart_receiver(void *targ); @@ -40,6 +45,5 @@ bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeou bool WaitForResponse(uint32_t cmd, UsbCommand* response); extern serial_port sp; -extern bool offline; #endif // COMMS_H_ diff --git a/client/flash.c b/client/flash.c index 894095e7..e3714185 100644 --- a/client/flash.c +++ b/client/flash.c @@ -27,9 +27,6 @@ void ReceiveCommand(UsbCommand* rxcmd); serial_port sp; -// FIXME: what the fuckity fuck -unsigned int current_command = CMD_UNKNOWN; - #define FLASH_START 0x100000 #define FLASH_SIZE (256*1024) #define FLASH_END (FLASH_START + FLASH_SIZE) @@ -52,13 +49,14 @@ void CloseProxmark(const char *serial_port_name) { unlink(serial_port_name); } -int OpenProxmark(size_t i, const char *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 0; + return false; } - return 1; + + return true; } // Turn PHDRs into flasher segments, checking for PHDR sanity and merging adjacent @@ -355,6 +353,7 @@ static int enter_bootloader(char *serial_port_name) SendCommand(&c); fprintf(stderr,"Press and hold down button NOW if your bootloader requires it.\n"); } + msleep(100); CloseProxmark(serial_port_name); @@ -363,6 +362,7 @@ static int enter_bootloader(char *serial_port_name) sleep(1); fprintf(stderr, "."); } while (!OpenProxmark(0, serial_port_name)); + fprintf(stderr," Found.\n"); return 0; diff --git a/client/flash.h b/client/flash.h index 7f365924..f8ffd221 100644 --- a/client/flash.h +++ b/client/flash.h @@ -32,7 +32,7 @@ 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); -int OpenProxmark(size_t i, const char *serial_port_name); +bool OpenProxmark(size_t i, const char *serial_port_name); extern serial_port sp; #endif diff --git a/client/hid-flasher/proxusb.c b/client/hid-flasher/proxusb.c index 04dbb784..364b21a3 100644 --- a/client/hid-flasher/proxusb.c +++ b/client/hid-flasher/proxusb.c @@ -31,7 +31,6 @@ usb_dev_handle *devh = NULL; static unsigned int claimed_iface = 0; unsigned char return_on_error = 0; unsigned char error_occured = 0; -extern unsigned int current_command; void SendCommand(UsbCommand *c) { @@ -40,7 +39,6 @@ void SendCommand(UsbCommand *c) #if 0 printf("Sending %d bytes\n", sizeof(UsbCommand)); #endif - current_command = c->cmd; ret = usb_bulk_write(devh, 0x01, (char*)c, sizeof(UsbCommand), 1000); if (ret<0) { error_occured = 1; diff --git a/client/proxmark3.c b/client/proxmark3.c index fc258609..6587bcff 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -41,14 +41,17 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) { 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 { + SetOffline(true); } // file with script @@ -64,7 +67,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool usb_present) { read_history(".history"); - while (1) { + while (1) { // If there is a script file if (script_file) { @@ -235,7 +238,7 @@ int main(int argc, char* argv[]) { if(strcmp(argv[i],"-f") == 0 || strcmp(argv[i],"-flush") == 0){ printf("Output will be flushed after every print.\n"); - flushAfterWrite = 1; + SetFlushAfterWrite(true); } if(strcmp(argv[i],"-w") == 0 || strcmp(argv[i],"-wait") == 0){ @@ -311,14 +314,11 @@ int main(int argc, char* argv[]) { if (sp == INVALID_SERIAL_PORT) { printf("ERROR: invalid serial port\n"); usb_present = false; - offline = 1; } else if (sp == CLAIMED_SERIAL_PORT) { printf("ERROR: serial port is claimed by another process\n"); usb_present = false; - offline = 1; } else { usb_present = true; - offline = 0; } #ifdef HAVE_GUI diff --git a/client/ui.c b/client/ui.c index b0669a22..50a6ec7d 100644 --- a/client/ui.c +++ b/client/ui.c @@ -22,8 +22,7 @@ double CursorScaleFactor = 1; int PlotGridX=0, PlotGridY=0, PlotGridXdefault= 64, PlotGridYdefault= 64, CursorCPos= 0, CursorDPos= 0; -int offline; -int flushAfterWrite = 0; //buzzy +bool flushAfterWrite = false; //buzzy int GridOffset = 0; bool GridLocked = false; bool showDemod = true; @@ -93,7 +92,7 @@ void PrintAndLog(char *fmt, ...) } va_end(argptr2); - if (flushAfterWrite == 1) //buzzy + if (flushAfterWrite) //buzzy { fflush(NULL); } @@ -106,3 +105,8 @@ void SetLogFilename(char *fn) { logfilename = fn; } + +void SetFlushAfterWrite(bool flush_after_write) { + flushAfterWrite = flush_after_write; +} + diff --git a/client/ui.h b/client/ui.h index 28512ca9..1273fe9e 100644 --- a/client/ui.h +++ b/client/ui.h @@ -20,10 +20,10 @@ void ShowGraphWindow(void); void RepaintGraphWindow(void); void PrintAndLog(char *fmt, ...); void SetLogFilename(char *fn); +void SetFlushAfterWrite(bool flush_after_write); extern double CursorScaleFactor; extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, CursorCPos, CursorDPos, GridOffset; -extern int flushAfterWrite; //buzzy extern bool GridLocked; extern bool showDemod; diff --git a/common/Makefile.common b/common/Makefile.common index 29b72a4c..f31ff7bb 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -29,7 +29,7 @@ GZIP=gzip OBJDIR = obj -INCLUDE = -I../include -I../common +INCLUDE = -I../include -I../common -I. TAR=tar TARFLAGS = -C .. -rvf diff --git a/common/iso15693tools.c b/common/iso15693tools.c index 26e636ca..f1214458 100644 --- a/common/iso15693tools.c +++ b/common/iso15693tools.c @@ -11,6 +11,12 @@ #include #include //#include "iso15693tools.h" +#ifdef ON_DEVICE +#include "printf.h" +#else +#include +#endif + #define POLY 0x8408 @@ -51,8 +57,6 @@ int Iso15693AddCrc(uint8_t *req, int n) { } -int sprintf(char *str, const char *format, ...); - // returns a string representation of the UID // UID is transmitted and stored LSB first, displayed MSB first // target char* buffer, where to put the UID, if NULL a static buffer is returned From be303b4c740c121f486aa80e50c5f8af600d1596 Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Sat, 28 Apr 2018 10:09:16 +0200 Subject: [PATCH 5/9] USB comms: part 3 towards @micolous PR#463 * change variable 'sp' from global to static * move code to open and close USB port to comms.c (OpenProxmark() and CloseProxmark()) * change scope of USBCommandReceived() to static * (flasher still unchanged) --- client/comms.c | 47 +++++++++++++++++++++++++++++++++++++--------- client/comms.h | 7 +++---- client/proxmark3.c | 33 ++++---------------------------- 3 files changed, 45 insertions(+), 42 deletions(-) diff --git a/client/comms.c b/client/comms.c index 2dd5534c..97d58ef9 100644 --- a/client/comms.c +++ b/client/comms.c @@ -21,7 +21,7 @@ // Declare globals. // Serial port that we are communicating with the PM3 on. -serial_port sp; +static serial_port sp; // If TRUE, then there is no active connection to the PM3, and we will drop commands sent. static bool offline; @@ -58,6 +58,38 @@ 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); @@ -73,6 +105,7 @@ void SendCommand(UsbCommand *c) { Not good.../holiman **/ while(txcmd_pending); + txcmd = *c; txcmd_pending = true; } @@ -140,11 +173,7 @@ int getCommand(UsbCommand* response) } -//----------------------------------------------------------------------------- -// Entry point into our code: called whenever we received a packet over USB -// that we weren't necessarily expecting, for example a debug print. -//----------------------------------------------------------------------------- -void UsbCommandReceived(UsbCommand *UC) +static void UsbCommandReceived(UsbCommand *UC) { switch(UC->cmd) { // First check if we are handling a debug message @@ -170,7 +199,7 @@ void UsbCommandReceived(UsbCommand *UC) } break; default: - storeCommand(UC); + storeCommand(UC); break; } @@ -184,12 +213,12 @@ __attribute__((force_align_arg_pointer)) #endif #endif *uart_receiver(void *targ) { - receiver_arg *arg = (receiver_arg*)targ; + receiver_arg *conn = (receiver_arg*)targ; size_t rxlen; uint8_t rx[sizeof(UsbCommand)]; uint8_t *prx = rx; - while (arg->run) { + while (conn->run) { rxlen = 0; if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-rx), &rxlen) && rxlen) { prx += rxlen; diff --git a/client/comms.h b/client/comms.h index 51a1467d..616f7ddb 100644 --- a/client/comms.h +++ b/client/comms.h @@ -31,19 +31,18 @@ typedef struct { } receiver_arg; -// Wrappers required as static variables can only be used in one file. void SetOffline(bool new_offline); bool IsOffline(); +bool OpenProxmark(char *portname, bool waitCOMPort, int timeout); +void CloseProxmark(void); + void SendCommand(UsbCommand *c); void *uart_receiver(void *targ); -void UsbCommandReceived(UsbCommand *UC); 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); bool WaitForResponse(uint32_t cmd, UsbCommand* response); -extern serial_port sp; - #endif // COMMS_H_ diff --git a/client/proxmark3.c b/client/proxmark3.c index 6587bcff..88cb5fa7 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -21,7 +21,6 @@ #include "util_posix.h" #include "proxgui.h" #include "cmdmain.h" -#include "uart.h" #include "ui.h" #include "util.h" #include "cmdparser.h" @@ -137,7 +136,7 @@ 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); @@ -293,33 +292,9 @@ int main(int argc, char* argv[]) { // set global variables set_my_executable_path(); - - // open uart - if (!waitCOMPort) { - sp = uart_open(argv[1]); - } else { - printf("Waiting for Proxmark to appear on %s ", argv[1]); - fflush(stdout); - int openCount = 0; - do { - sp = uart_open(argv[1]); - msleep(1000); - printf("."); - fflush(stdout); - } while(++openCount < 20 && (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"); - usb_present = false; - } else if (sp == CLAIMED_SERIAL_PORT) { - printf("ERROR: serial port is claimed by another process\n"); - usb_present = false; - } else { - usb_present = true; - } + // try to open USB connection to Proxmark + usb_present = OpenProxmark(argv[1], waitCOMPort, 20); #ifdef HAVE_GUI #ifdef _WIN32 @@ -344,7 +319,7 @@ int main(int argc, char* argv[]) { // Clean up the port if (usb_present) { - uart_close(sp); + CloseProxmark(); } exit(0); From 30c2c67fe1e9128b3b503d2c26ffe2214da50ce9 Mon Sep 17 00:00:00 2001 From: Tom Harkness Date: Thu, 12 Jul 2018 16:01:23 +1000 Subject: [PATCH 6/9] Changed to LF Standalone --- armsrc/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index dea5d06c..c763c559 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -10,7 +10,7 @@ APP_INCLUDES = apps.h #remove one of the following defines and comment out the relevant line #in the next section to remove that particular feature from compilation -APP_CFLAGS = -DWITH_ISO14443a_StandAlone -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE -DWITH_HFSNOOP \ +APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE -DWITH_HFSNOOP \ -fno-strict-aliasing -ffunction-sections -fdata-sections #-DWITH_LCD @@ -118,4 +118,3 @@ help: @echo Possible targets: @echo + all - Build the full image $(OBJDIR)/fullimage.s19 @echo + clean - Clean $(OBJDIR) - From 618e97b1d1ab2f5cc249bad9ecb31c3051aaaab8 Mon Sep 17 00:00:00 2001 From: TomHarkness Date: Sat, 14 Jul 2018 22:08:27 +1000 Subject: [PATCH 7/9] Fixe for mfkeys.lua crashing. Adition of hardauto script (not working yet - almost) --- client/scripts/hardpwn.lua | 196 +++++++++++++++++++++++++++++++++++++ client/scripts/mfkeys.lua | 2 +- 2 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 client/scripts/hardpwn.lua diff --git a/client/scripts/hardpwn.lua b/client/scripts/hardpwn.lua new file mode 100644 index 00000000..3a8ddd41 --- /dev/null +++ b/client/scripts/hardpwn.lua @@ -0,0 +1,196 @@ + +local cmds = require('commands') +local getopt = require('getopt') +local utils = require('utils') +local reader = require('read14a') + +example = "script iterates over all possible sectors for a tag and runs hardnested attack against them to collect the keys." +author = "Iceman (modified to work with latest client by TomHarkness)" +desc = +[[ +This script iterates over all possible sectors for a tag and runs hardnested attack against them to collect the keys. +Arguments: + -k Known key, 6 bytes (12 hex digits) + -a key A + -b key B + -s Blocknumber for known key +Examples : + script hard -k 112233445566 +]] + +local numBlocks = 64 +local numSectors = 16 +local DEBUG = TRUE +--- +-- A debug printout-function +function dbg(args) + if not DEBUG then return end + + if type(args) == "table" then + local i = 1 + while result[i] do + dbg(result[i]) + i = i+1 + end + else + print("###", args) + end +end +--- +-- This is only meant to be used when errors occur +function oops(err) + print("ERROR: ",err) + return nil,err +end +--- +-- Usage help +function help() + print(desc) + print("Example usage") + print(example) +end +-- +-- Exit message +function ExitMsg(msg) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print(msg) + print() +end +-- A little helper to place an item first in the list +local function placeFirst(akey, list) + akey = akey:lower() + if list[1] == akey then + -- Already at pole position + return list + end + local result = {akey} + --print(("Putting '%s' first"):format(akey)) + for i,v in ipairs(list) do + if v ~= akey then + result[#result+1] = v + end + end + return result +end +-- A function to display the results +-- TODO: iceman 2016, still screws up output when a key is not found. +local function displayresults(results) + local sector, blockNo, keyA, keyB, succA, succB, _ + + print("|---|----------------|---|----------------|---|") + print("|sec|key A |res|key B |res|") + print("|---|----------------|---|----------------|---|") + + for sector,_ in pairs(results) do + succA, succB, keyA, keyB = unpack(_) + print(("|%03d| %s | %s | %s | %s |"):format(sector, keyA, succA, keyB, succB)) + end + print("|---|----------------|---|----------------|---|") + +end + +--[[ +The mifare Classic 1k card has 16 sectors of 4 data blocks each. +The first 32 sectors of a mifare Classic 4k card consists of 4 data blocks and the remaining +8 sectors consist of 16 data blocks. +--]] +local function GetTargetBlockNo(sector) + local trgblockno = sector * 4 - 1 + if sector > 32 then + trgblockno = 32 * 4 + (sector-32) * 16 -1 + end + return ("%02x"):format(trgblockno) +end + +--- +-- The main entry point +function main(args) + + local blockno = '00' + local keytype + local key = 'fc00018778f7' + local trgkey = '' + local numSectors = 16 + + -- Read the parameters + for o, a in getopt.getopt(args, 'hk:abs:') do + if o == "h" then return help() end + if o == "k" then key = a end + if o == "a" then keytype = '0' end + if o == "b" then keytype = '1' end + if o == "s" then blockno = a end + end + + keytype = keytype or '0' + + -- Turn off Debug + local cmdSetDbgOff = "hf mf dbg 0" + core.console( cmdSetDbgOff) + core.clearCommandBuffer() + -- identify tag + result, err = reader.read14443a(true, false) + if res then return res end + + -- Show tag info + print((' Found tag %s'):format(result.name)) + + if 0x18 == result.sak then --NXP MIFARE Classic 4k | Plus 4k + -- IFARE Classic 4K offers 4096 bytes split into forty sectors, + -- of which 32 are same size as in the 1K with eight more that are quadruple size sectors. + numSectors = 40 + elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k + -- 1K offers 1024 bytes of data storage, split into 16 sector + numSectors = 16 + elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k + -- MIFARE Classic mini offers 320 bytes split into five sectors. + numSectors = 5 + elseif 0x10 == result.sak then-- "NXP MIFARE Plus 2k" + numSectors = 32 + else + print("I don't know how many sectors there are on this type of card, defaulting to 16") + end + + result = {} + for sector=1,numSectors do + + local trgblockno = GetTargetBlockNo(sector) + local succA = 1 + local succB = 1 + local keyA = '' + local keyB = '' + + for targetkeytype=0,1 do + + -- skip first sector, KeyA... + -- or actually blockNo and keytype + -- just try default for now + if sector == 1 and targetkeytype == 0 then + keyA = utils.ConvertHexToAscii(key) + else + local err, foundkey = cmds.CMD_HF_MF_HARD, arg1 = blockno, arg2 = keytype, arg3 = key, arg4 = trgblockno tostring(targetkeytype), arg5 = trgkey, 0,0,0,0 + foundkey = foundkey or "" + + if targetkeytype == 0 then + if err == nil or err > 0 then succA = 0 else keyA = foundkey end + else + if err == nil or err > 0 then succB = 0 else keyB = foundkey end + end + end + + -- clearing BigBuff between hardnested executions seems to make it more stable. + core.clearCommandBuffer() + core.console('data buffclear') + end + -- Check if user aborted + if core.ukbhit() then + print("Aborted by user") + break + end + -- log + result[sector] = { succA, succB, utils.ConvertAsciiToHex(keyA), utils.ConvertAsciiToHex(keyB) } + end + displayresults(result) +end + +main(args) diff --git a/client/scripts/mfkeys.lua b/client/scripts/mfkeys.lua index 671ce03d..c3271996 100644 --- a/client/scripts/mfkeys.lua +++ b/client/scripts/mfkeys.lua @@ -68,7 +68,7 @@ function checkBlock(blockNo, keys, keyType) data = data} local status = checkCommand(command) if status then return status, blockNo end - start = start+n+1 + start = start+n remaining = remaining - n end return nil From 2fcc4ec49719b343148bbded5ca9d1816f767a76 Mon Sep 17 00:00:00 2001 From: TomHarkness Date: Wed, 18 Jul 2018 08:26:04 +1000 Subject: [PATCH 8/9] Removal of unwanted script --- client/scripts/hardpwn.lua | 196 ------------------------------------- 1 file changed, 196 deletions(-) delete mode 100644 client/scripts/hardpwn.lua diff --git a/client/scripts/hardpwn.lua b/client/scripts/hardpwn.lua deleted file mode 100644 index 3a8ddd41..00000000 --- a/client/scripts/hardpwn.lua +++ /dev/null @@ -1,196 +0,0 @@ - -local cmds = require('commands') -local getopt = require('getopt') -local utils = require('utils') -local reader = require('read14a') - -example = "script iterates over all possible sectors for a tag and runs hardnested attack against them to collect the keys." -author = "Iceman (modified to work with latest client by TomHarkness)" -desc = -[[ -This script iterates over all possible sectors for a tag and runs hardnested attack against them to collect the keys. -Arguments: - -k Known key, 6 bytes (12 hex digits) - -a key A - -b key B - -s Blocknumber for known key -Examples : - script hard -k 112233445566 -]] - -local numBlocks = 64 -local numSectors = 16 -local DEBUG = TRUE ---- --- A debug printout-function -function dbg(args) - if not DEBUG then return end - - if type(args) == "table" then - local i = 1 - while result[i] do - dbg(result[i]) - i = i+1 - end - else - print("###", args) - end -end ---- --- This is only meant to be used when errors occur -function oops(err) - print("ERROR: ",err) - return nil,err -end ---- --- Usage help -function help() - print(desc) - print("Example usage") - print(example) -end --- --- Exit message -function ExitMsg(msg) - print( string.rep('--',20) ) - print( string.rep('--',20) ) - print(msg) - print() -end --- A little helper to place an item first in the list -local function placeFirst(akey, list) - akey = akey:lower() - if list[1] == akey then - -- Already at pole position - return list - end - local result = {akey} - --print(("Putting '%s' first"):format(akey)) - for i,v in ipairs(list) do - if v ~= akey then - result[#result+1] = v - end - end - return result -end --- A function to display the results --- TODO: iceman 2016, still screws up output when a key is not found. -local function displayresults(results) - local sector, blockNo, keyA, keyB, succA, succB, _ - - print("|---|----------------|---|----------------|---|") - print("|sec|key A |res|key B |res|") - print("|---|----------------|---|----------------|---|") - - for sector,_ in pairs(results) do - succA, succB, keyA, keyB = unpack(_) - print(("|%03d| %s | %s | %s | %s |"):format(sector, keyA, succA, keyB, succB)) - end - print("|---|----------------|---|----------------|---|") - -end - ---[[ -The mifare Classic 1k card has 16 sectors of 4 data blocks each. -The first 32 sectors of a mifare Classic 4k card consists of 4 data blocks and the remaining -8 sectors consist of 16 data blocks. ---]] -local function GetTargetBlockNo(sector) - local trgblockno = sector * 4 - 1 - if sector > 32 then - trgblockno = 32 * 4 + (sector-32) * 16 -1 - end - return ("%02x"):format(trgblockno) -end - ---- --- The main entry point -function main(args) - - local blockno = '00' - local keytype - local key = 'fc00018778f7' - local trgkey = '' - local numSectors = 16 - - -- Read the parameters - for o, a in getopt.getopt(args, 'hk:abs:') do - if o == "h" then return help() end - if o == "k" then key = a end - if o == "a" then keytype = '0' end - if o == "b" then keytype = '1' end - if o == "s" then blockno = a end - end - - keytype = keytype or '0' - - -- Turn off Debug - local cmdSetDbgOff = "hf mf dbg 0" - core.console( cmdSetDbgOff) - core.clearCommandBuffer() - -- identify tag - result, err = reader.read14443a(true, false) - if res then return res end - - -- Show tag info - print((' Found tag %s'):format(result.name)) - - if 0x18 == result.sak then --NXP MIFARE Classic 4k | Plus 4k - -- IFARE Classic 4K offers 4096 bytes split into forty sectors, - -- of which 32 are same size as in the 1K with eight more that are quadruple size sectors. - numSectors = 40 - elseif 0x08 == result.sak then -- NXP MIFARE CLASSIC 1k | Plus 2k - -- 1K offers 1024 bytes of data storage, split into 16 sector - numSectors = 16 - elseif 0x09 == result.sak then -- NXP MIFARE Mini 0.3k - -- MIFARE Classic mini offers 320 bytes split into five sectors. - numSectors = 5 - elseif 0x10 == result.sak then-- "NXP MIFARE Plus 2k" - numSectors = 32 - else - print("I don't know how many sectors there are on this type of card, defaulting to 16") - end - - result = {} - for sector=1,numSectors do - - local trgblockno = GetTargetBlockNo(sector) - local succA = 1 - local succB = 1 - local keyA = '' - local keyB = '' - - for targetkeytype=0,1 do - - -- skip first sector, KeyA... - -- or actually blockNo and keytype - -- just try default for now - if sector == 1 and targetkeytype == 0 then - keyA = utils.ConvertHexToAscii(key) - else - local err, foundkey = cmds.CMD_HF_MF_HARD, arg1 = blockno, arg2 = keytype, arg3 = key, arg4 = trgblockno tostring(targetkeytype), arg5 = trgkey, 0,0,0,0 - foundkey = foundkey or "" - - if targetkeytype == 0 then - if err == nil or err > 0 then succA = 0 else keyA = foundkey end - else - if err == nil or err > 0 then succB = 0 else keyB = foundkey end - end - end - - -- clearing BigBuff between hardnested executions seems to make it more stable. - core.clearCommandBuffer() - core.console('data buffclear') - end - -- Check if user aborted - if core.ukbhit() then - print("Aborted by user") - break - end - -- log - result[sector] = { succA, succB, utils.ConvertAsciiToHex(keyA), utils.ConvertAsciiToHex(keyB) } - end - displayresults(result) -end - -main(args) From 9d30a5f7c04388f42b9e372a08d4a15daa2da5db Mon Sep 17 00:00:00 2001 From: TomHarkness Date: Wed, 18 Jul 2018 08:33:10 +1000 Subject: [PATCH 9/9] Fix for issue #628 --- client/scripts/mfkeys.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/scripts/mfkeys.lua b/client/scripts/mfkeys.lua index c3271996..c7170c2f 100644 --- a/client/scripts/mfkeys.lua +++ b/client/scripts/mfkeys.lua @@ -68,7 +68,7 @@ function checkBlock(blockNo, keys, keyType) data = data} local status = checkCommand(command) if status then return status, blockNo end - start = start+n + start = start+n --fixed base on pwpiwi's reccomendation remaining = remaining - n end return nil