From b18920b9f9b72fba0fe476c4356688a8e9a4669e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 26 Sep 2017 17:04:25 +0200 Subject: [PATCH] CHG: enables proxmark3 client to reconnect to serial port without exiting / restarting. --- client/flasher.c | 19 +++++----- client/proxmark3.c | 91 +++++++++++++++++++++++++++++++++++----------- uart/uart_win32.c | 20 +++++----- 3 files changed, 89 insertions(+), 41 deletions(-) diff --git a/client/flasher.c b/client/flasher.c index 788d23485..d07dbd9e1 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -27,15 +27,15 @@ static char* serial_port_name; void cmd_debug(UsbCommand* UC) { // Debug - printf("UsbCommand length[len=%zd]\n",sizeof(UsbCommand)); - printf(" cmd[len=%zd]: %016" PRIx64"\n",sizeof(UC->cmd),UC->cmd); - printf(" arg0[len=%zd]: %016" PRIx64"\n",sizeof(UC->arg[0]),UC->arg[0]); - printf(" arg1[len=%zd]: %016" PRIx64"\n",sizeof(UC->arg[1]),UC->arg[1]); - printf(" arg2[len=%zd]: %016" PRIx64"\n",sizeof(UC->arg[2]),UC->arg[2]); - printf(" data[len=%zd]: ",sizeof(UC->d.asBytes)); + printf("UsbCommand length[len=%zd]\n", sizeof(UsbCommand)); + printf(" cmd[len=%zd]: %016" PRIx64"\n", sizeof(UC->cmd), UC->cmd); + printf(" arg0[len=%zd]: %016" PRIx64"\n", sizeof(UC->arg[0]), UC->arg[0]); + printf(" arg1[len=%zd]: %016" PRIx64"\n", sizeof(UC->arg[1]), UC->arg[1]); + printf(" arg2[len=%zd]: %016" PRIx64"\n", sizeof(UC->arg[2]), UC->arg[2]); + printf(" data[len=%zd]: ", sizeof(UC->d.asBytes)); for (size_t i=0; i<16; i++) - printf("%02x",UC->d.asBytes[i]); + printf("%02x", UC->d.asBytes[i]); printf("...\n"); } @@ -43,7 +43,7 @@ void cmd_debug(UsbCommand* UC) { void SendCommand(UsbCommand* txcmd) { // printf("send: "); // cmd_debug(txcmd); - if (!uart_send(sp,(byte_t*)txcmd,sizeof(UsbCommand))) { + if (!uart_send(sp,(byte_t*)txcmd, sizeof(UsbCommand))) { printf("Sending bytes to proxmark failed\n"); exit(1); } @@ -80,8 +80,7 @@ int OpenProxmark(size_t i) { return 1; } -static void usage(char *argv0) -{ +static void usage(char *argv0) { fprintf(stderr, "Usage: %s [-b] image.elf [image.elf...]\n\n", argv0); fprintf(stderr, "\t-b\tEnable flashing of bootloader area (DANGEROUS)\n\n"); fprintf(stderr, "\nExample (Linux):\n\n\t %s /dev/ttyACM0 armsrc/obj/fullimage.elf\n", argv0); diff --git a/client/proxmark3.c b/client/proxmark3.c index f3b073a18..e6f239329 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -28,9 +28,10 @@ // a global mutex to prevent interlaced printing from different threads extern pthread_mutex_t print_lock; - static serial_port sp; static UsbCommand txcmd; +static char comport[255]; + volatile static bool txcmd_pending = false; void SendCommand(UsbCommand *c) { @@ -77,10 +78,31 @@ static void showBanner(void){ } #endif +static bool hookUpPM3() { + bool ret = false; + sp = uart_open( comport ); + if (sp == INVALID_SERIAL_PORT) { + printf("ERROR: invalid serial port\n"); + ret = false; + offline = 1; + } else if (sp == CLAIMED_SERIAL_PORT) { + printf("ERROR: serial port is claimed by another process\n"); + ret = false; + offline = 1; + } else { + //printf("OK: connected to serial port %s\n", comport); + ret = true; + offline = 0; + } + return ret; +} + +// (iceman) if uart_receiver fails a command three times, we conside the device to be offline. static void *uart_receiver(void *targ) { struct receiver_arg *arg = (struct receiver_arg*)targ; size_t rxlen; - + int counter_to_offline = 0; + while (arg->run) { rxlen = 0; if (uart_receive(sp, prx, sizeof(UsbCommand) - (prx-rx), &rxlen)) { @@ -98,24 +120,36 @@ static void *uart_receiver(void *targ) { if ( tmpsignal ) { bool res = uart_send(sp, (byte_t*) &txcmd, sizeof(UsbCommand)); if (!res) { + counter_to_offline++; PrintAndLog("Sending bytes to proxmark failed"); } __atomic_clear(&txcmd_pending, __ATOMIC_SEQ_CST); //txcmd_pending = false; + + // set offline flag + if ( counter_to_offline == 3 ) { + __atomic_test_and_set(&offline, __ATOMIC_SEQ_CST); + break; + } } } + + // when this reader thread dies, we close the serial port. + uart_close(sp); + pthread_exit(NULL); return NULL; } - void main_loop(char *script_cmds_file, bool usb_present) { + struct receiver_arg rarg; - char *cmd = NULL; pthread_t reader_thread; - + char *cmd = NULL; + if (usb_present) { rarg.run = 1; + // pthread_create(&reader_thread, NULL, &uart_receiver, &rarg); // cache Version information now: CmdVersion(NULL); @@ -133,7 +167,23 @@ void main_loop(char *script_cmds_file, bool usb_present) { read_history(".history"); - while(1) { + // loops everytime enter is pressed... + while(1) { + + // this should hook up the PM3 again. + if (offline) { + + // sets the global variable, SP and offline) + usb_present = hookUpPM3(); + + // usb and the reader_thread is NULL, create a new reader thread. + if (usb_present && !offline) { + rarg.run = 1; + pthread_create(&reader_thread, NULL, &uart_receiver, &rarg); + // cache Version information now: + CmdVersion(NULL); + } + } // If there is a script file if (script_file) { @@ -245,7 +295,8 @@ int main(int argc, char* argv[]) { if (argc < 2) { printf("syntax: %s \n\n",argv[0]); - printf("\tLinux example:'%s /dev/ttyACM0'\n\n", argv[0]); + printf("\tLinux example:'%s /dev/ttyACM0'\n", argv[0]); + printf("\tWindows example:'%s com3'\n\n", argv[0]); printf("help: %s -h\n\n", argv[0]); printf("\tDump all interactive help at once\n"); printf("markdown: %s -m\n\n", argv[0]); @@ -254,7 +305,8 @@ int main(int argc, char* argv[]) { } if (strcmp(argv[1], "-h") == 0) { printf("syntax: %s \n\n",argv[0]); - printf("\tLinux example:'%s /dev/ttyACM0'\n\n", argv[0]); + printf("\tLinux example:'%s /dev/ttyACM0'\n", argv[0]); + printf("\tWindows example:'%s com3'\n\n", argv[0]); dumpAllHelp(0); return 0; } @@ -270,25 +322,20 @@ int main(int argc, char* argv[]) { set_my_executable_path(); - bool usb_present = false; char *script_cmds_file = NULL; - sp = uart_open(argv[1]); - 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; - } + // lets copy the comport string. + memset(comport, 0, sizeof(comport)); + memcpy(comport, argv[1], strlen(argv[1])); + + // sets the global variable, SP and offline) + bool usb_present = hookUpPM3(); // If the user passed the filename of the 'script' to execute, get it if (argc > 2 && argv[2]) { + + printf("Num of args: %d -- %s\n", argc, argv[2]); + if (argv[2][0] == 'f' && //buzzy, if a word 'flush' passed, flush the output after every log entry. argv[2][1] == 'l' && argv[2][2] == 'u' && diff --git a/uart/uart_win32.c b/uart/uart_win32.c index 9213753d5..0927a427d 100644 --- a/uart/uart_win32.c +++ b/uart/uart_win32.c @@ -62,11 +62,11 @@ serial_port uart_open(const char* pcPortName) { serial_port_windows* sp = malloc(sizeof(serial_port_windows)); // Copy the input "com?" to "\\.\COM?" format - sprintf(acPortName,"\\\\.\\%s",pcPortName); + sprintf(acPortName,"\\\\.\\%s", pcPortName); upcase(acPortName); // Try to open the serial port - sp->hPort = CreateFileA(acPortName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); + sp->hPort = CreateFileA(acPortName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (sp->hPort == INVALID_HANDLE_VALUE) { uart_close(sp); return INVALID_SERIAL_PORT; @@ -75,13 +75,13 @@ serial_port uart_open(const char* pcPortName) { // Prepare the device control memset(&sp->dcb, 0, sizeof(DCB)); sp->dcb.DCBlength = sizeof(DCB); - if(!BuildCommDCBA("baud=115200 parity=N data=8 stop=1",&sp->dcb)) { + if (!BuildCommDCBA("baud=115200 parity=N data=8 stop=1",&sp->dcb)) { uart_close(sp); return INVALID_SERIAL_PORT; } // Update the active serial port - if(!SetCommState(sp->hPort,&sp->dcb)) { + if (!SetCommState(sp->hPort, &sp->dcb)) { uart_close(sp); return INVALID_SERIAL_PORT; } @@ -92,7 +92,7 @@ serial_port uart_open(const char* pcPortName) { sp->ct.WriteTotalTimeoutMultiplier = 0;//1; sp->ct.WriteTotalTimeoutConstant = 30; - if(!SetCommTimeouts(sp->hPort,&sp->ct)) { + if (!SetCommTimeouts(sp->hPort, &sp->ct)) { uart_close(sp); return INVALID_SERIAL_PORT; } @@ -107,18 +107,20 @@ serial_port uart_open(const char* pcPortName) { } void uart_close(const serial_port sp) { - CloseHandle(((serial_port_windows*)sp)->hPort); - free(sp); + if (!sp) return; + if (((serial_port_windows*)sp)->hPort != NULL ) + CloseHandle(((serial_port_windows*)sp)->hPort); + free(sp); } bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen) { - ReadFile(((serial_port_windows*)sp)->hPort,pbtRx,pszMaxRxLen,(LPDWORD)pszRxLen,NULL); + ReadFile(((serial_port_windows*)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL); return (*pszRxLen != 0); } bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen) { DWORD dwTxLen = 0; - return WriteFile(((serial_port_windows*)sp)->hPort,pbtTx,szTxLen,&dwTxLen,NULL); + return WriteFile(((serial_port_windows*)sp)->hPort, pbtTx, szTxLen, &dwTxLen, NULL); return (dwTxLen != 0); }