CHG: enables proxmark3 client to reconnect to serial port without exiting / restarting.

This commit is contained in:
iceman1001 2017-09-26 17:04:25 +02:00
commit b18920b9f9
3 changed files with 89 additions and 41 deletions

View file

@ -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 <port> [-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);

View file

@ -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,9 +78,30 @@ 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;
@ -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,8 +167,24 @@ void main_loop(char *script_cmds_file, bool usb_present) {
read_history(".history");
// 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 <port>\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 <port>\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' &&

View file

@ -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) {
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);
}