]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmdlfhitag.c
Potential fix for 0-length usb packets seen on OSX
[proxmark3-svn] / client / cmdlfhitag.c
index 61a7d3b3d81887f8c8ef760fcaab87abc66992ce..fe5ba587617a502d9b8a0b2ee43dd82619c1e376 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include "data.h"
-#include "proxusb.h"
+#include "proxmark3.h"
 #include "ui.h"
 #include "cmdparser.h"
 #include "common.h"
 #include "util.h"
 #include "hitag2.h"
+#include "sleep.h"
+#include "cmdmain.h"
 
 static int CmdHelp(const char *Cmd);
 
+size_t nbytes(size_t nbits) {
+       return (nbits/8)+((nbits%8)>0);
+}
+
 int CmdLFHitagList(const char *Cmd)
 {
-  uint8_t got[3000];
-  GetFromBigBuf(got,sizeof(got),0);
-  char filename[256];
-  FILE* pf;
-
-  param_getstr(Cmd,0,filename);
-  
-  if (strlen(filename) > 0) {
-      if ((pf = fopen(filename,"w")) == NULL) {
-           PrintAndLog("Error: Could not open file [%s]",filename);
-           return 1;
-         }
-  }
-
-  PrintAndLog("recorded activity:");
-  PrintAndLog(" ETU     :rssi: who bytes");
-  PrintAndLog("---------+----+----+-----------");
+       uint8_t *got = malloc(USB_CMD_DATA_SIZE);
 
-  int i = 0;
-  int prev = -1;
+       // Query for the actual size of the trace
+       UsbCommand response;
+       GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
+       WaitForResponse(CMD_ACK, &response);
+       uint16_t traceLen = response.arg[2];
+       if (traceLen > USB_CMD_DATA_SIZE) {
+               uint8_t *p = realloc(got, traceLen);
+               if (p == NULL) {
+                       PrintAndLog("Cannot allocate memory for trace");
+                       free(got);
+                       return 2;
+               }
+               got = p;
+               GetFromBigBuf(got, traceLen, 0);
+               WaitForResponse(CMD_ACK,NULL);
+       }
+       
+       PrintAndLog("recorded activity (TraceLen = %d bytes):");
+       PrintAndLog(" ETU     :nbits: who bytes");
+       PrintAndLog("---------+-----+----+-----------");
 
-  for (;;) {
-    if(i >= 1900) {
-      break;
-    }
+       int i = 0;
+       int prev = -1;
+       int len = strlen(Cmd);
 
-    bool isResponse;
-    int timestamp = *((uint32_t *)(got+i));
-    if (timestamp & 0x80000000) {
-      timestamp &= 0x7fffffff;
-      isResponse = 1;
-    } else {
-      isResponse = 0;
-    }
+       char filename[FILE_PATH_SIZE]  = { 0x00 };
+       FILE* pf = NULL;
+       
+       if (len > FILE_PATH_SIZE) 
+               len = FILE_PATH_SIZE;
+       memcpy(filename, Cmd, len);
+   
+       if (strlen(filename) > 0) {
+               if ((pf = fopen(filename,"wb")) == NULL) {
+                       PrintAndLog("Error: Could not open file [%s]",filename);
+                       return 1;
+               }
+       }
 
-    int metric = 0;
-    int parityBits = *((uint32_t *)(got+i+4));
-    // 4 bytes of additional information...
-    // maximum of 32 additional parity bit information
-    //
-    // TODO:
-    // at each quarter bit period we can send power level (16 levels)
-    // or each half bit period in 256 levels.
+       for (;;) {
+  
+               if(i > traceLen) { break; }
 
-    int len = got[i+8];
+               bool isResponse;
+               int timestamp = *((uint32_t *)(got+i));
+               if (timestamp & 0x80000000) {
+                       timestamp &= 0x7fffffff;
+                       isResponse = 1;
+               } else {
+                       isResponse = 0;
+               }
 
-    if (len > 100) {
-      break;
-    }
-    if (i + len >= 1900) {
-      break;
-    }
+               int parityBits = *((uint32_t *)(got+i+4));
+               // 4 bytes of additional information...
+               // maximum of 32 additional parity bit information
+               //
+               // TODO:
+               // at each quarter bit period we can send power level (16 levels)
+               // or each half bit period in 256 levels.
 
-    uint8_t *frame = (got+i+9);
+               int bits = got[i+8];
+               int len = nbytes(got[i+8]);
 
-    // Break and stick with current result if buffer was not completely full
-    if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
+               if (len > 100) {
+                 break;
+               }
+               if (i + len > traceLen) { break;}
 
-    char line[1000] = "";
-    int j;
-    for (j = 0; j < len; j++) {
-      int oddparity = 0x01;
-      int k;
+               uint8_t *frame = (got+i+9);
 
-      for (k=0;k<8;k++) {
-        oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
-      }
+               // Break and stick with current result if buffer was not completely full
+               if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
 
-      //if((parityBits >> (len - j - 1)) & 0x01) {
-      if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
-        sprintf(line+(j*4), "%02x!  ", frame[j]);
-      }
-      else {
-        sprintf(line+(j*4), "%02x   ", frame[j]);
-      }
-    }
+               char line[1000] = "";
+               int j;
+               for (j = 0; j < len; j++) {
+                 int oddparity = 0x01;
+                 int k;
 
-    char metricString[100];
-    if (isResponse) {
-      sprintf(metricString, "%3d", metric);
-    } else {
-      strcpy(metricString, "   ");
-    }
+                 for (k=0;k<8;k++) {
+                       oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
+                 }
 
-    PrintAndLog(" +%7d: %s: %s %s",
-      (prev < 0 ? 0 : (timestamp - prev)),
-      metricString,
-      (isResponse ? "TAG" : "   "),
-      line);
+                 //if((parityBits >> (len - j - 1)) & 0x01) {
+                 if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
+                       sprintf(line+(j*4), "%02x!  ", frame[j]);
+                 }
+                 else {
+                       sprintf(line+(j*4), "%02x   ", frame[j]);
+                 }
+               }
 
+               PrintAndLog(" +%7d:  %3d: %s %s",
+                       (prev < 0 ? 0 : (timestamp - prev)),
+                       bits,
+                       (isResponse ? "TAG" : "   "),
+                       line);
 
-       if (strlen(filename) > 0) {
-      fprintf(pf," +%7d: %s: %s %s %s",
-                                       (prev < 0 ? 0 : (timestamp - prev)),
-                                       metricString,
-                                       (isResponse ? "TAG" : "   "),
-                                       line,
-                                       "\n");
-    }
-       
-    prev = timestamp;
-    i += (len + 9);
-  }
+               if (pf) {
+                       fprintf(pf," +%7d:  %3d: %s %s\n",
+                               (prev < 0 ? 0 : (timestamp - prev)),
+                               bits,
+                               (isResponse ? "TAG" : "   "),
+                               line);
+               }
+               
+               prev = timestamp;
+               i += (len + 9);
+       }
   
-  if (strlen(filename) > 0) {
-         PrintAndLog("Recorded activity succesfully written to file: %s", filename);
-    fclose(pf);
-  }
-       
-  return 0;
+       if (pf) {
+               fclose(pf);
+               PrintAndLog("Recorded activity succesfully written to file: %s", filename);
+       }
+
+       free(got);
+       return 0;
 }
 
 int CmdLFHitagSnoop(const char *Cmd) {
@@ -142,12 +157,14 @@ int CmdLFHitagSnoop(const char *Cmd) {
 }
 
 int CmdLFHitagSim(const char *Cmd) {
+    
   UsbCommand c = {CMD_SIMULATE_HITAG};
-       char filename[256];
+       char filename[FILE_PATH_SIZE] = { 0x00 };
        FILE* pf;
        bool tag_mem_supplied;
-
-       param_getstr(Cmd,0,filename);
+       int len = strlen(Cmd);
+       if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+       memcpy(filename, Cmd, len);
        
        if (strlen(filename) > 0) {
                if ((pf = fopen(filename,"rb+")) == NULL) {
@@ -155,7 +172,11 @@ int CmdLFHitagSim(const char *Cmd) {
                        return 1;
                }
                tag_mem_supplied = true;
-               fread(c.d.asBytes,48,1,pf);
+               if (fread(c.d.asBytes,48,1,pf) == 0) {
+      PrintAndLog("Error: File reading error");
+      fclose(pf);
+                       return 1;
+    }
                fclose(pf);
        } else {
                tag_mem_supplied = false;
@@ -184,18 +205,23 @@ int CmdLFHitagReader(const char *Cmd) {
                        num_to_bytes(param_get32ex(Cmd,1,0,16),4,htd->auth.NrAr);
                        num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4);
                } break;
+               case RHT2F_CRYPTO: {
+                       num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key);
+//                     num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4);
+               } break;
                case RHT2F_TEST_AUTH_ATTEMPTS: {
                        // No additional parameters needed
                } break;
                default: {
                        PrintAndLog("Error: unkown reader function %d",htf);
-                       PrintAndLog("Hitag reader functions",htf);
-                       PrintAndLog(" HitagS (0*)",htf);
-                       PrintAndLog(" Hitag1 (1*)",htf);
-                       PrintAndLog(" Hitag2 (2*)",htf);
-                       PrintAndLog("  21 <password> (password mode)",htf);
-                       PrintAndLog("  22 <nr> <ar> (authentication)",htf);
-                       PrintAndLog("  25 (test recorded authentications)",htf);
+                       PrintAndLog("Hitag reader functions");
+                       PrintAndLog(" HitagS (0*)");
+                       PrintAndLog(" Hitag1 (1*)");
+                       PrintAndLog(" Hitag2 (2*)");
+                       PrintAndLog("  21 <password> (password mode)");
+                       PrintAndLog("  22 <nr> <ar> (authentication)");
+                       PrintAndLog("  23 <key> (authentication) key is in format: ISK high + ISK low");
+                       PrintAndLog("  25 (test recorded authentications)");
                        return 1;
                } break;
        }
@@ -203,28 +229,52 @@ int CmdLFHitagReader(const char *Cmd) {
        // Copy the hitag2 function into the first argument
        c.arg[0] = htf;
 
+  // Send the command to the proxmark
   SendCommand(&c);
+  
+  UsbCommand resp;
+  WaitForResponse(CMD_ACK,&resp);
+  
+  // Check the return status, stored in the first argument
+  if (resp.arg[0] == false) return 1;
+    
+  uint32_t id = bytes_to_num(resp.d.asBytes,4);
+  char filename[256];
+  FILE* pf = NULL;
+
+  sprintf(filename,"%08x_%04x.ht2",id,(rand() & 0xffff));
+  if ((pf = fopen(filename,"wb")) == NULL) {
+    PrintAndLog("Error: Could not open file [%s]",filename);
+    return 1;
+  }
+  
+  // Write the 48 tag memory bytes to file and finalize
+  fwrite(resp.d.asBytes,1,48,pf);
+  fclose(pf);
+
+  PrintAndLog("Succesfully saved tag memory to [%s]",filename);
+  
   return 0;
 }
 
-static command_t CommandTableHitag[] = 
+static command_t CommandTable[] = 
 {
   {"help",    CmdHelp,           1, "This help"},
-  {"list",    CmdLFHitagList,    1, "List Hitag trace history"},
+  {"list",    CmdLFHitagList,    1, "<outfile> List Hitag trace history"},
   {"reader",  CmdLFHitagReader,  1, "Act like a Hitag Reader"},
-  {"sim",     CmdLFHitagSim,     1, "Simulate Hitag transponder"},
+  {"sim",     CmdLFHitagSim,     1, "<infile> Simulate Hitag transponder"},
   {"snoop",   CmdLFHitagSnoop,   1, "Eavesdrop Hitag communication"},
                {NULL, NULL, 0, NULL}
 };
 
 int CmdLFHitag(const char *Cmd)
 {
-  CmdsParse(CommandTableHitag, Cmd);
+  CmdsParse(CommandTable, Cmd);
   return 0;
 }
 
 int CmdHelp(const char *Cmd)
 {
-  CmdsHelp(CommandTableHitag);
+  CmdsHelp(CommandTable);
   return 0;
 }
Impressum, Datenschutz