]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmdhf14a.c
ADD: Holimans new changes in master.
[proxmark3-svn] / client / cmdhf14a.c
index 46720d44e6321a2dcd102e8f6458f73549fa3236..62d95b4b0dafe2a816529b6c56f4d6196ee65f8f 100644 (file)
@@ -40,9 +40,7 @@ int CmdHF14AList(const char *Cmd)
                return 0;
        }       
 
-       if (param == 'f') {
-               ShowWaitCycles = true;
-       }
+       ShowWaitCycles = (param == 'f');
                
 // for the time being. Need better Bigbuf handling.    
 #define TRACE_SIZE 3000        
@@ -56,8 +54,8 @@ int CmdHF14AList(const char *Cmd)
        PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
        PrintAndLog("All times are in carrier periods (1/13.56Mhz)");
        PrintAndLog("");
-       PrintAndLog("     Start |       End | Src | Data");
-       PrintAndLog("-----------|-----------|-----|--------");
+       PrintAndLog("     Start |       End | Src | Data (! denotes parity error)                                   | CRC ");
+       PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------------");
 
        uint16_t tracepos = 0;
        uint16_t duration;
@@ -70,44 +68,40 @@ int CmdHF14AList(const char *Cmd)
        
        for (;;) {
        
-               if(tracepos >= TRACE_SIZE) {
-                       break;
-               }
+               if(tracepos >= TRACE_SIZE) break;
        
                timestamp = *((uint32_t *)(trace + tracepos));
+               
+               // Break and stick with current result if buffer was not completely full
+               if (timestamp == 0x44444444) break; 
+
                if(tracepos == 0) {
                        first_timestamp = timestamp;
                }
+               
                tracepos += 4;
                duration = *((uint16_t *)(trace + tracepos));
                tracepos += 2;
                data_len = *((uint16_t *)(trace + tracepos));
                tracepos += 2;
 
+               isResponse = false;
                if (data_len & 0x8000) {
                        data_len &= 0x7fff;
                        isResponse = true;
-               } else {
-                       isResponse = false;
                }
-
+               
                parity_len = (data_len-1)/8 + 1;
-
-               if (tracepos + data_len + parity_len >= TRACE_SIZE) {
-                       break;
-               }
+               
+               if (tracepos + data_len + parity_len >= TRACE_SIZE) break;
 
                uint8_t *frame = trace + tracepos;
                tracepos += data_len;
                uint8_t *parityBytes = trace + tracepos;
                tracepos += parity_len;
-
-               // Break and stick with current result if buffer was not completely full
-               if (timestamp == 0x44444444) break; 
-
-               char line[1000] = "";
-               int j;
-               for (j = 0; j < data_len; j++) {
+               
+               char line[16][110];
+               for (int j = 0; j < data_len; j++) {
                        int oddparity = 0x01;
                        int k;
 
@@ -117,47 +111,53 @@ int CmdHF14AList(const char *Cmd)
 
                        uint8_t parityBits = parityBytes[j>>3];
                        if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
-                               sprintf(line+(j*4), "%02x! ", frame[j]);
+                               sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
                        } else {
-                               sprintf(line+(j*4), "%02x ", frame[j]);
+                               sprintf(line[j/16]+((j%16)*4), "%02x  ", frame[j]);     
                        }
                }
-                       
-               char crc[6] = ""
+               
+               char crc[5] = {0x00}
                if (data_len > 2) {
                        uint8_t b1, b2;
                        ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2);
                        if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
-                               sprintf(crc, (isResponse & (data_len < 6)) ? "" : " !crc");
-                       } else {
-                               sprintf(crc, "");
-                       }
+                               sprintf(crc, (isResponse & (data_len < 6)) ? "" : "!crc");
+                       } 
                }
                
                EndOfTransmissionTimestamp = timestamp + duration;
-               
-               PrintAndLog(" %9d | %9d | %s | %s %s",
-                       (timestamp - first_timestamp),
-                       (EndOfTransmissionTimestamp - first_timestamp),
-                       (isResponse ? "Tag" : "Rdr"),
-                       line,
-                       crc);
+               int num_lines = (data_len - 1)/16 + 1;
+                               
+               for (int j = 0; j < num_lines; j++) {
+                       if (j == 0) {
+                               PrintAndLog(" %9d | %9d | %s | %-64s| %s",
+                                       (timestamp - first_timestamp),
+                                       (EndOfTransmissionTimestamp - first_timestamp),
+                                       (isResponse ? "Tag" : "Rdr"),
+                                       line[j], 
+                                       (j == num_lines-1)?crc:""
+                                       );
+                       } else {
+                               PrintAndLog("           |           |     | %-64s| %s",
+                                       line[j], 
+                                       (j == num_lines-1)?crc:"");
+                       }
+               }                               
        
                bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
                
                if (ShowWaitCycles && !isResponse && next_isResponse) {
                        uint32_t next_timestamp = *((uint32_t *)(trace + tracepos));
                        if (next_timestamp != 0x44444444) {
-                       PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
-                               (EndOfTransmissionTimestamp - first_timestamp),
-                               (next_timestamp - first_timestamp),
-                               " ",
-                               (next_timestamp - EndOfTransmissionTimestamp));
-                               }
+                               PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
+                                       (EndOfTransmissionTimestamp - first_timestamp),
+                                       (next_timestamp - first_timestamp),
+                                       " ",
+                                       (next_timestamp - EndOfTransmissionTimestamp));                         
                        }
-                       
+               }       
        }
-       
        return 0;
 }
 
@@ -168,8 +168,7 @@ void iso14a_set_timeout(uint32_t timeout) {
 
 int CmdHF14AReader(const char *Cmd)
 {
-       //UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
-       UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT , 0, 0}};
+       UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
        SendCommand(&c);
 
        UsbCommand resp;
@@ -182,6 +181,11 @@ int CmdHF14AReader(const char *Cmd)
        
        if(select_status == 0) {
                PrintAndLog("iso14443a card select failed");
+               // disconnect
+               c.arg[0] = 0;
+               c.arg[1] = 0;
+               c.arg[2] = 0;
+               SendCommand(&c);
                return 0;
        }
 
@@ -221,13 +225,6 @@ int CmdHF14AReader(const char *Cmd)
            memcpy(&card.ats, resp.d.asBytes, resp.arg[0]);
                card.ats_len = resp.arg[0];                             // note: ats_len includes CRC Bytes
        } 
-
-       // disconnect
-       c.arg[0] = 0;
-       c.arg[1] = 0;
-       c.arg[2] = 0;
-       SendCommand(&c);
-
        
        if(card.ats_len >= 3) {                 // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes
                bool ta1 = 0, tb1 = 0, tc1 = 0;
@@ -367,6 +364,24 @@ int CmdHF14AReader(const char *Cmd)
                PrintAndLog("proprietary non iso14443-4 card found, RATS not supported");
        }
 
+       
+       // try to see if card responses to "chinese magic backdoor" commands.
+       c.cmd = CMD_MIFARE_CIDENT;
+       c.arg[0] = 0;
+       c.arg[1] = 0;
+       c.arg[2] = 0;   
+       SendCommand(&c);
+       WaitForResponse(CMD_ACK,&resp);
+       uint8_t isOK  = resp.arg[0] & 0xff;
+       PrintAndLog(" Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
+       
+       // disconnect
+       c.cmd = CMD_READER_ISO_14443a;
+       c.arg[0] = 0;
+       c.arg[1] = 0;
+       c.arg[2] = 0;
+       SendCommand(&c);
+       
        return select_status;
 }
 
@@ -494,7 +509,7 @@ int CmdHF14ASnoop(const char *Cmd) {
        
        if (param_getchar(Cmd, 0) == 'h') {
                PrintAndLog("It get data from the field and saves it into command buffer.");
-               PrintAndLog("Buffer accessible from command hf 14a list.");
+               PrintAndLog("Buffer accessible from command hf list 14a.");
                PrintAndLog("Usage:  hf 14a snoop [c][r]");
                PrintAndLog("c - triggered by first data from card");
                PrintAndLog("r - triggered by first 7-bit request from reader (REQ,WUP,...)");
@@ -679,7 +694,7 @@ static void waitCmd(uint8_t iSelect)
 static command_t CommandTable[] = 
 {
   {"help",   CmdHelp,              1, "This help"},
-  {"list",   CmdHF14AList,         0, "List ISO 14443a history"},
+  {"list",   CmdHF14AList,         0, "[Deprecated] List ISO 14443a history"},
   {"reader", CmdHF14AReader,       0, "Act like an ISO14443 Type A reader"},
   {"cuids",  CmdHF14ACUIDs,        0, "<n> Collect n>0 ISO14443 Type A UIDs in one go"},
   {"sim",    CmdHF14ASim,          0, "<UID> -- Fake ISO 14443a tag"},
Impressum, Datenschutz