]> cvs.zerfleddert.de Git - proxmark3-svn/commitdiff
FIX: a solution for the issue "hf mf esave - always saves 4K"
authoriceman1001 <iceman@iuse.se>
Wed, 7 Jan 2015 21:00:29 +0000 (22:00 +0100)
committericeman1001 <iceman@iuse.se>
Wed, 7 Jan 2015 21:00:29 +0000 (22:00 +0100)
FIX: a solution for the issue "hf eload, esave, cload, save - filepath variable too short"
CHG: minor code clean up.
ADD: AES / CRC16 for lua. (and tnp3xx scripts.)
ADD: tnp3dump.lua  script to dump tnp3xx tags.
ADD: tnp3sim.lua script to let PM3 imitate an tnp3xx tag. Needs to be tested live

19 files changed:
client/cmddata.c
client/cmdhf.c
client/cmdhf14a.c
client/cmdhf14a.h
client/cmdhf14b.c
client/cmdhflegic.c
client/cmdhfmf.c
client/cmdlf.c
client/cmdlfem4x.c
client/cmdlfhitag.c
client/cmdmain.c
client/flasher.c
client/lualibs/commands.lua
client/lualibs/utils.lua
client/proxmark3.c
client/scripting.c
client/scripts/tnp3dump.lua [new file with mode: 0644]
client/scripts/tnp3sim.lua [new file with mode: 0644]
client/util.c

index 3ac8db25fb5455e00d4349fc4922d8f7b3239650..d05f3fa1572e95b16e797b049d93630a858f90d5 100644 (file)
@@ -696,7 +696,7 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
 
   int lowLen = sizeof (LowTone) / sizeof (int);
   int highLen = sizeof (HighTone) / sizeof (int);
 
   int lowLen = sizeof (LowTone) / sizeof (int);
   int highLen = sizeof (HighTone) / sizeof (int);
-  int convLen = (highLen > lowLen) ? highLen : lowLen; //if highlen > lowLen then highlen else lowlen
+  int convLen = (highLen > lowLen) ? highLen : lowLen;
   uint32_t hi = 0, lo = 0;
 
   int i, j;
   uint32_t hi = 0, lo = 0;
 
   int i, j;
@@ -942,9 +942,16 @@ int CmdTuneSamples(const char *Cmd)
 
 int CmdLoad(const char *Cmd)
 {
 
 int CmdLoad(const char *Cmd)
 {
-  FILE *f = fopen(Cmd, "r");
+   char filename[FILE_PATH_SIZE] = {0x00};
+   int len = 0;
+
+   len = strlen(Cmd);
+   if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+   memcpy(filename, Cmd, len);
+       
+   FILE *f = fopen(filename, "r");
   if (!f) {
   if (!f) {
-    PrintAndLog("couldn't open '%s'", Cmd);
+     PrintAndLog("couldn't open '%s'", filename);
     return 0;
   }
 
     return 0;
   }
 
@@ -1250,9 +1257,17 @@ int CmdPlot(const char *Cmd)
 
 int CmdSave(const char *Cmd)
 {
 
 int CmdSave(const char *Cmd)
 {
-  FILE *f = fopen(Cmd, "w");
+   char filename[FILE_PATH_SIZE] = {0x00};
+   int len = 0;
+
+   len = strlen(Cmd);
+   if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+   memcpy(filename, Cmd, len);
+   
+
+  FILE *f = fopen(filename, "w");
   if(!f) {
   if(!f) {
-    PrintAndLog("couldn't open '%s'", Cmd);
+    PrintAndLog("couldn't open '%s'", filename);
     return 0;
   }
   int i;
     return 0;
   }
   int i;
index 550f8e86d9b9e94d00aa3e9cf522ef556899334d..b53742e4d6341a6d6a39f6a3e7a8b3299ee9ca9c 100644 (file)
@@ -47,9 +47,11 @@ int CmdHFTune(const char *Cmd)
 #define iso14443_CMD_WUPA       0x52
 #define iso14443_CMD_SELECT     0x93
 #define iso14443_CMD_SELECT_2   0x95
 #define iso14443_CMD_WUPA       0x52
 #define iso14443_CMD_SELECT     0x93
 #define iso14443_CMD_SELECT_2   0x95
+#define iso14443_CMD_SELECT_3   0x97
 #define iso14443_CMD_REQ        0x26
 #define iso14443_CMD_READBLOCK  0x30
 #define iso14443_CMD_WRITEBLOCK 0xA0
 #define iso14443_CMD_REQ        0x26
 #define iso14443_CMD_READBLOCK  0x30
 #define iso14443_CMD_WRITEBLOCK 0xA0
+#define iso14443_CMD_WRITE             0xA2
 #define iso14443_CMD_INC        0xC0
 #define iso14443_CMD_DEC        0xC1
 #define iso14443_CMD_RESTORE    0xC2
 #define iso14443_CMD_INC        0xC0
 #define iso14443_CMD_DEC        0xC1
 #define iso14443_CMD_RESTORE    0xC2
@@ -57,6 +59,15 @@ int CmdHFTune(const char *Cmd)
 #define iso14443_CMD_HALT       0x50
 #define iso14443_CMD_RATS       0xE0
 
 #define iso14443_CMD_HALT       0x50
 #define iso14443_CMD_RATS       0xE0
 
+#define iso14443_CMD_AUTH_KEYA 0x60
+#define iso14443_CMD_AUTH_KEYB 0x61
+
+#define iso14443_CMD_AUTH_STEP1        0x1A
+#define iso14443_CMD_AUTH_STEP2        0xAA
+#define iso14443_CMD_AUTH_RESPONSE     0xAF
+
+#define CHINESE_BACKDOOR_INIT   0x40 
+#define CHINESE_BACKDOOR_STEP2   0x43 
 
 void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 {
 
 void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 {
@@ -76,12 +87,22 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
        case iso14443_CMD_REQ:         snprintf(exp,size,"REW"); break;
        case iso14443_CMD_READBLOCK:   snprintf(exp,size,"READBLOCK(%d)",cmd[1]); break;
        case iso14443_CMD_WRITEBLOCK:  snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]); break;
        case iso14443_CMD_REQ:         snprintf(exp,size,"REW"); break;
        case iso14443_CMD_READBLOCK:   snprintf(exp,size,"READBLOCK(%d)",cmd[1]); break;
        case iso14443_CMD_WRITEBLOCK:  snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]); break;
+       case iso14443_CMD_WRITE:           snprintf(exp,size,"WRITE"); break;
        case iso14443_CMD_INC:         snprintf(exp,size,"INC(%d)",cmd[1]); break;
        case iso14443_CMD_DEC:         snprintf(exp,size,"DEC(%d)",cmd[1]); break;
        case iso14443_CMD_RESTORE:     snprintf(exp,size,"RESTORE(%d)",cmd[1]); break;
        case iso14443_CMD_TRANSFER:    snprintf(exp,size,"TRANSFER(%d)",cmd[1]); break;
        case iso14443_CMD_HALT:        snprintf(exp,size,"HALT"); break;
        case iso14443_CMD_RATS:        snprintf(exp,size,"RATS"); break;
        case iso14443_CMD_INC:         snprintf(exp,size,"INC(%d)",cmd[1]); break;
        case iso14443_CMD_DEC:         snprintf(exp,size,"DEC(%d)",cmd[1]); break;
        case iso14443_CMD_RESTORE:     snprintf(exp,size,"RESTORE(%d)",cmd[1]); break;
        case iso14443_CMD_TRANSFER:    snprintf(exp,size,"TRANSFER(%d)",cmd[1]); break;
        case iso14443_CMD_HALT:        snprintf(exp,size,"HALT"); break;
        case iso14443_CMD_RATS:        snprintf(exp,size,"RATS"); break;
+       
+       case iso14443_CMD_AUTH_KEYA:   snprintf(exp,size,"AUTH KEY A"); break;
+       case iso14443_CMD_AUTH_KEYB:   snprintf(exp,size,"AUTH KEY B"); break;
+       case iso14443_CMD_AUTH_STEP1:  snprintf(exp,size,"AUTH REQ NONCE"); break;
+       case iso14443_CMD_AUTH_STEP2:  snprintf(exp,size,"AUTH STEP 2"); break;
+       case iso14443_CMD_AUTH_RESPONSE:  snprintf(exp,size,"AUTH RESPONSE"); break;
+       
+       case CHINESE_BACKDOOR_INIT:    snprintf(exp,size,"BACKDOOR INIT");break;
+       case CHINESE_BACKDOOR_STEP2:    snprintf(exp,size,"BACKDOOR STEP2");break;
        default:                       snprintf(exp,size,"?"); break;
        }
        return;
        default:                       snprintf(exp,size,"?"); break;
        }
        return;
@@ -89,7 +110,6 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 
 void annotateIclass(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 {
 
 void annotateIclass(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 {
-
        if(cmdsize > 1 && cmd[0] == ICLASS_CMD_READ)
        {
                  snprintf(exp,size,"READ(%d)",cmd[1]);
        if(cmdsize > 1 && cmd[0] == ICLASS_CMD_READ)
        {
                  snprintf(exp,size,"READ(%d)",cmd[1]);
@@ -112,7 +132,6 @@ void annotateIclass(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
 }
 
 
 }
 
 
-
 uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool showWaitCycles)
 {
        bool isResponse;
 uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool showWaitCycles)
 {
        bool isResponse;
@@ -178,8 +197,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
                                // Rough guess that this is a command from the reader
                                // For iClass the command byte is not part of the CRC
                                ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
                                // Rough guess that this is a command from the reader
                                // For iClass the command byte is not part of the CRC
                                ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
-                       }
-                       else {
+                       } else {
                                // For other data.. CRC might not be applicable (UPDATE commands etc.)
                                ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
                        }
                                // For other data.. CRC might not be applicable (UPDATE commands etc.)
                                ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
                        }
@@ -199,7 +217,6 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
                                }
                        }
                }
                                }
                        }
                }
-
        }
        char *crc = crcError ? "!crc" :"    ";
 
        }
        char *crc = crcError ? "!crc" :"    ";
 
@@ -207,8 +224,10 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
 
        if(!isResponse)
        {
 
        if(!isResponse)
        {
-               if(iclass)      annotateIclass(explanation,sizeof(explanation),frame,data_len);
-               else annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
+               if(iclass)
+                       annotateIclass(explanation,sizeof(explanation),frame,data_len);
+               else 
+                       annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
        }
 
        int num_lines = (data_len - 1)/16 + 1;
        }
 
        int num_lines = (data_len - 1)/16 + 1;
index 40173d83282d4ea741cfd316a1487eac5d292451..0298f509416015cadc11e26502fe662a755f3124 100644 (file)
@@ -111,7 +111,7 @@ const manufactureName manufactureMapping[] = {
 // get a product description based on the UID
 //             uid[8]  tag uid
 // returns description of the best match       
 // get a product description based on the UID
 //             uid[8]  tag uid
 // returns description of the best match       
-static char* getTagInfo(uint8_t uid) {
+char* getTagInfo(uint8_t uid) {
 
        int i, best = -1;       
        int len = sizeof(manufactureMapping) / sizeof(manufactureName);
 
        int i, best = -1;       
        int len = sizeof(manufactureMapping) / sizeof(manufactureName);
@@ -168,6 +168,7 @@ int CmdHF14AReader(const char *Cmd)
        PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]);
 
        // Double & triple sized UID, can be mapped to a manufacturer.
        PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]);
 
        // Double & triple sized UID, can be mapped to a manufacturer.
+       // HACK: does this apply for Ultralight cards?
        if ( card.uidlen > 4 ) {
                PrintAndLog("MANUFACTURER : %s", getTagInfo(card.uid[0]));
        }
        if ( card.uidlen > 4 ) {
                PrintAndLog("MANUFACTURER : %s", getTagInfo(card.uid[0]));
        }
@@ -624,7 +625,7 @@ static void waitCmd(uint8_t iSelect)
     UsbCommand resp;
     char *hexout;
 
     UsbCommand resp;
     char *hexout;
 
-    if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+    if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
         recv = resp.d.asBytes;
         uint8_t iLen = iSelect ? resp.arg[1] : resp.arg[0];
         PrintAndLog("received %i octets",iLen);
         recv = resp.d.asBytes;
         uint8_t iLen = iSelect ? resp.arg[1] : resp.arg[0];
         PrintAndLog("received %i octets",iLen);
index d2e203a10ba8a0f6131f6f1e386a618e0fca3d60..aa35dec6d18d7718ed6a1d2c3cbdb8368747f78e 100644 (file)
@@ -20,5 +20,5 @@ int CmdHF14AReader(const char *Cmd);
 int CmdHF14ASim(const char *Cmd);
 int CmdHF14ASnoop(const char *Cmd);
 
 int CmdHF14ASim(const char *Cmd);
 int CmdHF14ASnoop(const char *Cmd);
 
-
+char* getTagInfo(uint8_t uid);
 #endif
 #endif
index 7e4cbd009787452bf77f1f4a5e70c536f2634d32..713959f29745c3cc1548f7a31d8b36c5a07af1e2 100644 (file)
@@ -23,7 +23,6 @@
 #include "cmdhf14b.h"
 #include "cmdmain.h"
 
 #include "cmdhf14b.h"
 #include "cmdmain.h"
 
-
 static int CmdHelp(const char *Cmd);
 
 int CmdHF14BDemod(const char *Cmd)
 static int CmdHelp(const char *Cmd);
 
 int CmdHF14BDemod(const char *Cmd)
@@ -146,7 +145,7 @@ demodError:
 
 int CmdHF14BList(const char *Cmd)
 {
 
 int CmdHF14BList(const char *Cmd)
 {
-  uint8_t got[960];
+  uint8_t got[TRACE_BUFFER_SIZE];
   GetFromBigBuf(got,sizeof(got),0);
   WaitForResponse(CMD_ACK,NULL);
 
   GetFromBigBuf(got,sizeof(got),0);
   WaitForResponse(CMD_ACK,NULL);
 
@@ -158,9 +157,8 @@ int CmdHF14BList(const char *Cmd)
   int prev = -1;
 
   for(;;) {
   int prev = -1;
 
   for(;;) {
-    if(i >= 900) {
-      break;
-    }
+    
+       if(i >= TRACE_BUFFER_SIZE) { break; }
 
     bool isResponse;
     int timestamp = *((uint32_t *)(got+i));
 
     bool isResponse;
     int timestamp = *((uint32_t *)(got+i));
@@ -177,7 +175,7 @@ int CmdHF14BList(const char *Cmd)
     if(len > 100) {
       break;
     }
     if(len > 100) {
       break;
     }
-    if(i + len >= 900) {
+    if(i + len >= TRACE_BUFFER_SIZE) {
       break;
     }
 
       break;
     }
 
index bf874b624c40aad34a255834176233c4d1a65dbf..35ba1f28c49d6d4d64b58b774d7ce571c8feed03 100644 (file)
@@ -218,7 +218,24 @@ int CmdLegicRFRead(const char *Cmd)
 
 int CmdLegicLoad(const char *Cmd)
 {
 
 int CmdLegicLoad(const char *Cmd)
 {
-    FILE *f = fopen(Cmd, "r");
+       char filename[FILE_PATH_SIZE] = {0x00};
+       int len = 0;
+       
+       if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
+               PrintAndLog("It loads datasamples from the file `filename`");
+               PrintAndLog("Usage:  hf legic load <file name>");
+               PrintAndLog(" sample: hf legic load filename");
+               return 0;
+       }
+
+       len = strlen(Cmd);      
+       if (len > FILE_PATH_SIZE) {
+               PrintAndLog("Filepath too long (was %s bytes), max allowed is %s ", len, FILE_PATH_SIZE);
+               return 0;
+       }
+       memcpy(filename, Cmd, len);
+
+    FILE *f = fopen(filename, "r");
     if(!f) {
         PrintAndLog("couldn't open '%s'", Cmd);
         return -1;
     if(!f) {
         PrintAndLog("couldn't open '%s'", Cmd);
         return -1;
@@ -251,7 +268,7 @@ int CmdLegicSave(const char *Cmd)
   int requested = 1024;
   int offset = 0;
   int delivered = 0;
   int requested = 1024;
   int offset = 0;
   int delivered = 0;
-  char filename[1024];
+  char filename[FILE_PATH_SIZE];
   uint8_t got[1024];
   
   sscanf(Cmd, " %s %i %i", filename, &requested, &offset);
   uint8_t got[1024];
   
   sscanf(Cmd, " %s %i %i", filename, &requested, &offset);
index 46a11b56381afc947f9adda9e37699ddcee6d2e4..7ad6e0a1eee9e5cff32b1b76a7d86804d5b82a1e 100644 (file)
@@ -66,8 +66,7 @@ start:
        if (isOK != 1) return 1;\r
        \r
        // execute original function from util nonce2key\r
        if (isOK != 1) return 1;\r
        \r
        // execute original function from util nonce2key\r
-       if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key))\r
-       {\r
+       if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) {\r
                isOK = 2;\r
                PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);    \r
        } else {\r
                isOK = 2;\r
                PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);    \r
        } else {\r
@@ -512,6 +511,7 @@ int CmdHF14AMfDump(const char *Cmd)
                        return 2;\r
                }\r
        }\r
                        return 2;\r
                }\r
        }\r
+       \r
        fclose(fin);\r
        // Read access rights to sectors\r
 \r
        fclose(fin);\r
        // Read access rights to sectors\r
 \r
@@ -629,8 +629,8 @@ int CmdHF14AMfRestore(const char *Cmd)
 {\r
        uint8_t sectorNo,blockNo;\r
        uint8_t keyType = 0;\r
 {\r
        uint8_t sectorNo,blockNo;\r
        uint8_t keyType = 0;\r
-       uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\r
-       uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\r
+       uint8_t key[6] = {0xFF};\r
+       uint8_t bldata[16] = {0x00};\r
        uint8_t keyA[40][6];\r
        uint8_t keyB[40][6];\r
        uint8_t numSectors;\r
        uint8_t keyA[40][6];\r
        uint8_t keyB[40][6];\r
        uint8_t numSectors;\r
@@ -657,21 +657,14 @@ int CmdHF14AMfRestore(const char *Cmd)
                return 0;\r
        }\r
 \r
                return 0;\r
        }\r
 \r
-       if ((fdump = fopen("dumpdata.bin","rb")) == NULL) {\r
-               PrintAndLog("Could not find file dumpdata.bin");\r
-               return 1;\r
-       }\r
        if ((fkeys = fopen("dumpkeys.bin","rb")) == NULL) {\r
                PrintAndLog("Could not find file dumpkeys.bin");\r
        if ((fkeys = fopen("dumpkeys.bin","rb")) == NULL) {\r
                PrintAndLog("Could not find file dumpkeys.bin");\r
-               fclose(fdump);\r
                return 1;\r
        }\r
        \r
        for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
                if (fread(keyA[sectorNo], 1, 6, fkeys) == 0) {\r
                        PrintAndLog("File reading error (dumpkeys.bin).");\r
                return 1;\r
        }\r
        \r
        for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
                if (fread(keyA[sectorNo], 1, 6, fkeys) == 0) {\r
                        PrintAndLog("File reading error (dumpkeys.bin).");\r
-                       fclose(fdump);\r
-                       fclose(fkeys);\r
                        return 2;\r
                }\r
        }\r
                        return 2;\r
                }\r
        }\r
@@ -679,13 +672,16 @@ int CmdHF14AMfRestore(const char *Cmd)
        for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
                if (fread(keyB[sectorNo], 1, 6, fkeys) == 0) {\r
                        PrintAndLog("File reading error (dumpkeys.bin).");\r
        for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
                if (fread(keyB[sectorNo], 1, 6, fkeys) == 0) {\r
                        PrintAndLog("File reading error (dumpkeys.bin).");\r
-                       fclose(fdump);\r
-                       fclose(fkeys);\r
                        return 2;\r
                }\r
        }\r
                        return 2;\r
                }\r
        }\r
+\r
        fclose(fkeys);\r
 \r
        fclose(fkeys);\r
 \r
+       if ((fdump = fopen("dumpdata.bin","rb")) == NULL) {\r
+               PrintAndLog("Could not find file dumpdata.bin");\r
+               return 1;\r
+       }       \r
        PrintAndLog("Restoring dumpdata.bin to card");\r
 \r
        for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
        PrintAndLog("Restoring dumpdata.bin to card");\r
 \r
        for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
@@ -773,11 +769,15 @@ int CmdHF14AMfNested(const char *Cmd)
        cmdp = param_getchar(Cmd, 0);\r
        blockNo = param_get8(Cmd, 1);\r
        ctmp = param_getchar(Cmd, 2);\r
        cmdp = param_getchar(Cmd, 0);\r
        blockNo = param_get8(Cmd, 1);\r
        ctmp = param_getchar(Cmd, 2);\r
+       \r
        if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {\r
                PrintAndLog("Key type must be A or B");\r
                return 1;\r
        }\r
        if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {\r
                PrintAndLog("Key type must be A or B");\r
                return 1;\r
        }\r
-       if (ctmp != 'A' && ctmp != 'a') keyType = 1;\r
+       \r
+       if (ctmp != 'A' && ctmp != 'a') \r
+               keyType = 1;\r
+               \r
        if (param_gethex(Cmd, 3, key, 12)) {\r
                PrintAndLog("Key must include 12 HEX symbols");\r
                return 1;\r
        if (param_gethex(Cmd, 3, key, 12)) {\r
                PrintAndLog("Key must include 12 HEX symbols");\r
                return 1;\r
@@ -791,8 +791,10 @@ int CmdHF14AMfNested(const char *Cmd)
                        PrintAndLog("Target key type must be A or B");\r
                        return 1;\r
                }\r
                        PrintAndLog("Target key type must be A or B");\r
                        return 1;\r
                }\r
-               if (ctmp != 'A' && ctmp != 'a') trgKeyType = 1;\r
+               if (ctmp != 'A' && ctmp != 'a') \r
+                       trgKeyType = 1;\r
        } else {\r
        } else {\r
+                               \r
                switch (cmdp) {\r
                        case '0': SectorsCnt = 05; break;\r
                        case '1': SectorsCnt = 16; break;\r
                switch (cmdp) {\r
                        case '0': SectorsCnt = 05; break;\r
                        case '1': SectorsCnt = 16; break;\r
@@ -869,7 +871,6 @@ int CmdHF14AMfNested(const char *Cmd)
                        }\r
                }\r
                \r
                        }\r
                }\r
                \r
-               \r
                // nested sectors\r
                iterations = 0;\r
                PrintAndLog("nested...");\r
                // nested sectors\r
                iterations = 0;\r
                PrintAndLog("nested...");\r
@@ -972,7 +973,7 @@ int CmdHF14AMfChk(const char *Cmd)
        }       \r
 \r
        FILE * f;\r
        }       \r
 \r
        FILE * f;\r
-       char filename[256]={0};\r
+       char filename[FILE_PATH_SIZE]={0};\r
        char buf[13];\r
        uint8_t *keyBlock = NULL, *p;\r
        uint8_t stKeyBlock = 20;\r
        char buf[13];\r
        uint8_t *keyBlock = NULL, *p;\r
        uint8_t stKeyBlock = 20;\r
@@ -988,7 +989,6 @@ int CmdHF14AMfChk(const char *Cmd)
        int transferToEml = 0;\r
        int createDumpFile = 0;\r
 \r
        int transferToEml = 0;\r
        int createDumpFile = 0;\r
 \r
-\r
        keyBlock = calloc(stKeyBlock, 6);\r
        if (keyBlock == NULL) return 1;\r
 \r
        keyBlock = calloc(stKeyBlock, 6);\r
        if (keyBlock == NULL) return 1;\r
 \r
@@ -1065,7 +1065,7 @@ int CmdHF14AMfChk(const char *Cmd)
                        keycnt++;\r
                } else {\r
                        // May be a dic file\r
                        keycnt++;\r
                } else {\r
                        // May be a dic file\r
-                       if ( param_getstr(Cmd, 2 + i,filename) > 255 ) {\r
+                       if ( param_getstr(Cmd, 2 + i,filename) >= FILE_PATH_SIZE ) {\r
                                PrintAndLog("File name too long");\r
                                free(keyBlock);\r
                                return 2;\r
                                PrintAndLog("File name too long");\r
                                free(keyBlock);\r
                                return 2;\r
@@ -1346,26 +1346,44 @@ int CmdHF14AMfESet(const char *Cmd)
 int CmdHF14AMfELoad(const char *Cmd)\r
 {\r
        FILE * f;\r
 int CmdHF14AMfELoad(const char *Cmd)\r
 {\r
        FILE * f;\r
-       char filename[20];\r
+       char filename[FILE_PATH_SIZE];\r
        char *fnameptr = filename;\r
        char buf[64];\r
        uint8_t buf8[64];\r
        char *fnameptr = filename;\r
        char buf[64];\r
        uint8_t buf8[64];\r
-       int i, len, blockNum;\r
+       int i, len, blockNum, numBlocks;\r
+       int nameParamNo = 1;\r
        \r
        memset(filename, 0, sizeof(filename));\r
        memset(buf, 0, sizeof(buf));\r
 \r
        \r
        memset(filename, 0, sizeof(filename));\r
        memset(buf, 0, sizeof(buf));\r
 \r
-       if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {\r
+       char ctmp = param_getchar(Cmd, 0);\r
+               \r
+       if ( ctmp == 'h' || ctmp == 0x00) {\r
                PrintAndLog("It loads emul dump from the file `filename.eml`");\r
                PrintAndLog("It loads emul dump from the file `filename.eml`");\r
-               PrintAndLog("Usage:  hf mf eload <file name w/o `.eml`>");\r
+               PrintAndLog("Usage:  hf mf eload [card memory] <file name w/o `.eml`>");\r
+               PrintAndLog("  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
+               PrintAndLog("");\r
                PrintAndLog(" sample: hf mf eload filename");\r
                PrintAndLog(" sample: hf mf eload filename");\r
+               PrintAndLog("         hf mf eload 4 filename");\r
                return 0;\r
        }       \r
 \r
                return 0;\r
        }       \r
 \r
-       len = strlen(Cmd);\r
-       if (len > 14) len = 14;\r
+       switch (ctmp) {\r
+               case '0' : numBlocks = 5*4; break;\r
+               case '1' : \r
+               case '\0': numBlocks = 16*4; break;\r
+               case '2' : numBlocks = 32*4; break;\r
+               case '4' : numBlocks = 256; break;\r
+               default:  {\r
+                       numBlocks = 16*4;\r
+                       nameParamNo = 0;\r
+               }\r
+       }\r
+\r
+       len = param_getstr(Cmd,nameParamNo,filename);\r
+       \r
+       if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
 \r
 \r
-       memcpy(filename, Cmd, len);\r
        fnameptr += len;\r
 \r
        sprintf(fnameptr, ".eml"); \r
        fnameptr += len;\r
 \r
        sprintf(fnameptr, ".eml"); \r
@@ -1380,14 +1398,16 @@ int CmdHF14AMfELoad(const char *Cmd)
        blockNum = 0;\r
        while(!feof(f)){\r
                memset(buf, 0, sizeof(buf));\r
        blockNum = 0;\r
        while(!feof(f)){\r
                memset(buf, 0, sizeof(buf));\r
+               \r
                if (fgets(buf, sizeof(buf), f) == NULL) {\r
                if (fgets(buf, sizeof(buf), f) == NULL) {\r
-                       if((blockNum == 16*4) || (blockNum == 32*4 + 8*16)) {   // supports both old (1K) and new (4K) .eml files)\r
-                               break;\r
-                       }\r
+                       \r
+                       if (blockNum >= numBlocks) break;\r
+                       \r
                        PrintAndLog("File reading error.");\r
                        fclose(f);\r
                        return 2;\r
                }\r
                        PrintAndLog("File reading error.");\r
                        fclose(f);\r
                        return 2;\r
                }\r
+               \r
                if (strlen(buf) < 32){\r
                        if(strlen(buf) && feof(f))\r
                                break;\r
                if (strlen(buf) < 32){\r
                        if(strlen(buf) && feof(f))\r
                                break;\r
@@ -1395,6 +1415,7 @@ int CmdHF14AMfELoad(const char *Cmd)
                        fclose(f);\r
                        return 2;\r
                }\r
                        fclose(f);\r
                        return 2;\r
                }\r
+               \r
                for (i = 0; i < 32; i += 2) {\r
                        sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);\r
                }\r
                for (i = 0; i < 32; i += 2) {\r
                        sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);\r
                }\r
@@ -1406,12 +1427,12 @@ int CmdHF14AMfELoad(const char *Cmd)
                }\r
                blockNum++;\r
                \r
                }\r
                blockNum++;\r
                \r
-               if (blockNum >= 32*4 + 8*16) break;\r
+               if (blockNum >= numBlocks) break;\r
        }\r
        fclose(f);\r
        \r
        }\r
        fclose(f);\r
        \r
-       if ((blockNum != 16*4) && (blockNum != 32*4 + 8*16)) {\r
-               PrintAndLog("File content error. There must be 64 or 256 blocks.");\r
+       if ((blockNum != numBlocks)) {\r
+               PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);\r
                return 4;\r
        }\r
        PrintAndLog("Loaded %d blocks from file: %s", blockNum, filename);\r
                return 4;\r
        }\r
        PrintAndLog("Loaded %d blocks from file: %s", blockNum, filename);\r
@@ -1422,45 +1443,70 @@ int CmdHF14AMfELoad(const char *Cmd)
 int CmdHF14AMfESave(const char *Cmd)\r
 {\r
        FILE * f;\r
 int CmdHF14AMfESave(const char *Cmd)\r
 {\r
        FILE * f;\r
-       char filename[20];\r
+       char filename[FILE_PATH_SIZE];\r
        char * fnameptr = filename;\r
        uint8_t buf[64];\r
        char * fnameptr = filename;\r
        uint8_t buf[64];\r
-       int i, j, len;\r
+       int i, j, len, numBlocks;\r
+       int nameParamNo = 1;\r
        \r
        memset(filename, 0, sizeof(filename));\r
        memset(buf, 0, sizeof(buf));\r
 \r
        \r
        memset(filename, 0, sizeof(filename));\r
        memset(buf, 0, sizeof(buf));\r
 \r
-       if (param_getchar(Cmd, 0) == 'h') {\r
+       char ctmp = param_getchar(Cmd, 0);\r
+       \r
+       if ( ctmp == 'h' || ctmp == 'H') {\r
                PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`");\r
                PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`");\r
-               PrintAndLog("Usage:  hf mf esave [file name w/o `.eml`]");\r
+               PrintAndLog(" Usage:  hf mf esave [card memory] [file name w/o `.eml`]");\r
+               PrintAndLog("  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
+               PrintAndLog("");\r
                PrintAndLog(" sample: hf mf esave ");\r
                PrintAndLog(" sample: hf mf esave ");\r
-               PrintAndLog("         hf mf esave filename");\r
+               PrintAndLog("         hf mf esave 4");\r
+               PrintAndLog("         hf mf esave 4 filename");\r
                return 0;\r
        }       \r
 \r
                return 0;\r
        }       \r
 \r
-       len = strlen(Cmd);\r
-       if (len > 14) len = 14;\r
+       switch (ctmp) {\r
+               case '0' : numBlocks = 5*4; break;\r
+               case '1' : \r
+               case '\0': numBlocks = 16*4; break;\r
+               case '2' : numBlocks = 32*4; break;\r
+               case '4' : numBlocks = 256; break;\r
+               default:  {\r
+                       numBlocks = 16*4;\r
+                       nameParamNo = 0;\r
+               }\r
+       }\r
+\r
+       len = param_getstr(Cmd,nameParamNo,filename);\r
+       \r
+       if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
        \r
        \r
+       // user supplied filename?\r
        if (len < 1) {\r
        if (len < 1) {\r
-               // get filename\r
+               // get filename (UID from memory)\r
                if (mfEmlGetMem(buf, 0, 1)) {\r
                if (mfEmlGetMem(buf, 0, 1)) {\r
-                       PrintAndLog("Cant get block: %d", 0);\r
-                       return 1;\r
+                       PrintAndLog("Can\'t get UID from block: %d", 0);\r
+                       sprintf(filename, "dump.eml"); \r
                }\r
                for (j = 0; j < 7; j++, fnameptr += 2)\r
                }\r
                for (j = 0; j < 7; j++, fnameptr += 2)\r
-                       sprintf(fnameptr, "%02x", buf[j]); \r
+                       sprintf(fnameptr, "%02X", buf[j]); \r
        } else {\r
        } else {\r
-               memcpy(filename, Cmd, len);\r
                fnameptr += len;\r
        }\r
 \r
                fnameptr += len;\r
        }\r
 \r
+       // add file extension\r
        sprintf(fnameptr, ".eml"); \r
        \r
        // open file\r
        f = fopen(filename, "w+");\r
 \r
        sprintf(fnameptr, ".eml"); \r
        \r
        // open file\r
        f = fopen(filename, "w+");\r
 \r
+       if ( !f ) {\r
+               PrintAndLog("Can't open file %s ", filename);\r
+               return 1;\r
+       }\r
+       \r
        // put hex\r
        // put hex\r
-       for (i = 0; i < 32*4 + 8*16; i++) {\r
+       for (i = 0; i < numBlocks; i++) {\r
                if (mfEmlGetMem(buf, i, 1)) {\r
                        PrintAndLog("Cant get block: %d", i);\r
                        break;\r
                if (mfEmlGetMem(buf, i, 1)) {\r
                        PrintAndLog("Cant get block: %d", i);\r
                        break;\r
@@ -1471,7 +1517,7 @@ int CmdHF14AMfESave(const char *Cmd)
        }\r
        fclose(f);\r
        \r
        }\r
        fclose(f);\r
        \r
-       PrintAndLog("Saved to file: %s", filename);\r
+       PrintAndLog("Saved %d blocks to file: %s", numBlocks, filename);\r
        \r
   return 0;\r
 }\r
        \r
   return 0;\r
 }\r
@@ -1520,13 +1566,34 @@ int CmdHF14AMfECFill(const char *Cmd)
 int CmdHF14AMfEKeyPrn(const char *Cmd)\r
 {\r
        int i;\r
 int CmdHF14AMfEKeyPrn(const char *Cmd)\r
 {\r
        int i;\r
+       uint8_t numSectors;\r
        uint8_t data[16];\r
        uint64_t keyA, keyB;\r
        \r
        uint8_t data[16];\r
        uint64_t keyA, keyB;\r
        \r
+       if (param_getchar(Cmd, 0) == 'h') {\r
+               PrintAndLog("It prints the keys loaded in the emulator memory");\r
+               PrintAndLog("Usage:  hf mf ekeyprn [card memory]");\r
+               PrintAndLog("  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
+               PrintAndLog("");\r
+               PrintAndLog(" sample: hf mf ekeyprn 1");\r
+               return 0;\r
+       }       \r
+\r
+       char cmdp = param_getchar(Cmd, 0);\r
+       \r
+       switch (cmdp) {\r
+               case '0' : numSectors = 5; break;\r
+               case '1' : \r
+               case '\0': numSectors = 16; break;\r
+               case '2' : numSectors = 32; break;\r
+               case '4' : numSectors = 40; break;\r
+               default:   numSectors = 16;\r
+       }               \r
+       \r
        PrintAndLog("|---|----------------|----------------|");\r
        PrintAndLog("|sec|key A           |key B           |");\r
        PrintAndLog("|---|----------------|----------------|");\r
        PrintAndLog("|---|----------------|----------------|");\r
        PrintAndLog("|sec|key A           |key B           |");\r
        PrintAndLog("|---|----------------|----------------|");\r
-       for (i = 0; i < 40; i++) {\r
+       for (i = 0; i < numSectors; i++) {\r
                if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) {\r
                        PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);\r
                        break;\r
                if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) {\r
                        PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);\r
                        break;\r
@@ -1616,15 +1683,15 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
 int CmdHF14AMfCLoad(const char *Cmd)\r
 {\r
        FILE * f;\r
 int CmdHF14AMfCLoad(const char *Cmd)\r
 {\r
        FILE * f;\r
-       char filename[20];\r
+       char filename[FILE_PATH_SIZE] = {0x00};\r
        char * fnameptr = filename;\r
        char * fnameptr = filename;\r
-       char buf[64];\r
-       uint8_t buf8[64];\r
+       char buf[64] = {0x00};\r
+       uint8_t buf8[64] = {0x00};\r
        uint8_t fillFromEmulator = 0;\r
        int i, len, blockNum, flags;\r
        \r
        uint8_t fillFromEmulator = 0;\r
        int i, len, blockNum, flags;\r
        \r
-       memset(filename, 0, sizeof(filename));\r
-       memset(buf, 0, sizeof(buf));\r
+       // memset(filename, 0, sizeof(filename));\r
+       // memset(buf, 0, sizeof(buf));\r
 \r
        if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {\r
                PrintAndLog("It loads magic Chinese card (only works with!!!) from the file `filename.eml`");\r
 \r
        if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {\r
                PrintAndLog("It loads magic Chinese card (only works with!!!) from the file `filename.eml`");\r
@@ -1657,7 +1724,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
                return 0;\r
        } else {\r
                len = strlen(Cmd);\r
                return 0;\r
        } else {\r
                len = strlen(Cmd);\r
-               if (len > 14) len = 14;\r
+               if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
 \r
                memcpy(filename, Cmd, len);\r
                fnameptr += len;\r
 \r
                memcpy(filename, Cmd, len);\r
                fnameptr += len;\r
@@ -1702,7 +1769,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
                }\r
                fclose(f);\r
        \r
                }\r
                fclose(f);\r
        \r
-               if (blockNum != 16 * 4){\r
+               if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){\r
                        PrintAndLog("File content error. There must be 64 blocks");\r
                        return 4;\r
                }\r
                        PrintAndLog("File content error. There must be 64 blocks");\r
                        return 4;\r
                }\r
@@ -1780,14 +1847,14 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
 int CmdHF14AMfCSave(const char *Cmd) {\r
 \r
        FILE * f;\r
 int CmdHF14AMfCSave(const char *Cmd) {\r
 \r
        FILE * f;\r
-       char filename[20];\r
+       char filename[FILE_PATH_SIZE] = {0x00};\r
        char * fnameptr = filename;\r
        uint8_t fillFromEmulator = 0;\r
        char * fnameptr = filename;\r
        uint8_t fillFromEmulator = 0;\r
-       uint8_t buf[64];\r
+       uint8_t buf[64] = {0x00};\r
        int i, j, len, flags;\r
        \r
        int i, j, len, flags;\r
        \r
-       memset(filename, 0, sizeof(filename));\r
-       memset(buf, 0, sizeof(buf));\r
+       // memset(filename, 0, sizeof(filename));\r
+       // memset(buf, 0, sizeof(buf));\r
 \r
        if (param_getchar(Cmd, 0) == 'h') {\r
                PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");\r
 \r
        if (param_getchar(Cmd, 0) == 'h') {\r
                PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");\r
@@ -1822,7 +1889,7 @@ int CmdHF14AMfCSave(const char *Cmd) {
                return 0;\r
        } else {\r
                len = strlen(Cmd);\r
                return 0;\r
        } else {\r
                len = strlen(Cmd);\r
-               if (len > 14) len = 14;\r
+               if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
        \r
                if (len < 1) {\r
                        // get filename\r
        \r
                if (len < 1) {\r
                        // get filename\r
@@ -1842,6 +1909,11 @@ int CmdHF14AMfCSave(const char *Cmd) {
                // open file\r
                f = fopen(filename, "w+");\r
 \r
                // open file\r
                f = fopen(filename, "w+");\r
 \r
+               if (f == NULL) {\r
+                       PrintAndLog("File not found or locked.");\r
+                       return 1;\r
+               }\r
+\r
                // put hex\r
                flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;\r
                for (i = 0; i < 16 * 4; i++) {\r
                // put hex\r
                flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;\r
                for (i = 0; i < 16 * 4; i++) {\r
@@ -2021,9 +2093,9 @@ static command_t CommandTable[] =
   {"ecfill",   CmdHF14AMfECFill,               0, "Fill simulator memory with help of keys from simulator"},\r
   {"ekeyprn",  CmdHF14AMfEKeyPrn,              0, "Print keys from simulator memory"},\r
   {"csetuid",  CmdHF14AMfCSetUID,              0, "Set UID for magic Chinese card"},\r
   {"ecfill",   CmdHF14AMfECFill,               0, "Fill simulator memory with help of keys from simulator"},\r
   {"ekeyprn",  CmdHF14AMfEKeyPrn,              0, "Print keys from simulator memory"},\r
   {"csetuid",  CmdHF14AMfCSetUID,              0, "Set UID for magic Chinese card"},\r
-  {"csetblk",  CmdHF14AMfCSetBlk,              0, "Write block into magic Chinese card"},\r
-  {"cgetblk",  CmdHF14AMfCGetBlk,              0, "Read block from magic Chinese card"},\r
-  {"cgetsc",   CmdHF14AMfCGetSc,               0, "Read sector from magic Chinese card"},\r
+  {"csetblk",  CmdHF14AMfCSetBlk,              0, "Write block - Magic Chinese card"},\r
+  {"cgetblk",  CmdHF14AMfCGetBlk,              0, "Read block - Magic Chinese card"},\r
+  {"cgetsc",   CmdHF14AMfCGetSc,               0, "Read sector - Magic Chinese card"},\r
   {"cload",            CmdHF14AMfCLoad,                0, "Load dump into magic Chinese card"},\r
   {"csave",            CmdHF14AMfCSave,                0, "Save dump from magic Chinese card into file or emulator"},\r
   {NULL, NULL, 0, NULL}\r
   {"cload",            CmdHF14AMfCLoad,                0, "Load dump into magic Chinese card"},\r
   {"csave",            CmdHF14AMfCSave,                0, "Save dump from magic Chinese card into file or emulator"},\r
   {NULL, NULL, 0, NULL}\r
index 41dcca5746fbb93e607c6030f833ad3211371453..572cda6ca418a9babcd6bbc0b77f706eea0769e2 100644 (file)
@@ -380,10 +380,8 @@ static void ChkBitstream(const char *str)
   int i;
 
   /* convert to bitstream if necessary */
   int i;
 
   /* convert to bitstream if necessary */
-  for (i = 0; i < (int)(GraphTraceLen / 2); i++)
-  {
-    if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0)
-    {
+       for (i = 0; i < (int)(GraphTraceLen / 2); i++){
+               if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) {
       CmdBitstream(str);
       break;
     }
       CmdBitstream(str);
       break;
     }
@@ -556,11 +554,25 @@ int CmdVchDemod(const char *Cmd)
 int CmdLFfind(const char *Cmd)
 {
   int ans=0;
 int CmdLFfind(const char *Cmd)
 {
   int ans=0;
-  if (!offline){
+       char cmdp = param_getchar(Cmd, 0);
+       
+       if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {
+               PrintAndLog("Usage:  lf search <0|1>");
+               PrintAndLog("     <use data from Graphbuffer>, if not set, try reading data from tag.");
+               PrintAndLog("");
+               PrintAndLog("    sample: lf search");
+               PrintAndLog("          : lf search 1");
+               return 0;
+       }
+
+       if (!offline || (cmdp != '1') ){
     ans=CmdLFRead("");
     ans=CmdLFRead("");
-    ans=CmdSamples("20000");
+       ans=CmdSamples("20000");
+       } else if (GraphTraceLen < 1000) {
+               PrintAndLog("Data in Graphbuffer was too small.");
+               return 0;
   }
   }
-  if (GraphTraceLen<1000) return 0;
+
   PrintAndLog("Checking for known tags:");
   ans=Cmdaskmandemod("");
   if (ans>0) return 1;
   PrintAndLog("Checking for known tags:");
   ans=Cmdaskmandemod("");
   if (ans>0) return 1;
index 32a0ff7c68d9f55f56ece3ba7324f602219143b2..e0d88c24dfa334e80194efe2046a3a462896ecfd 100644 (file)
@@ -507,12 +507,12 @@ int CmdEM410xWrite(const char *Cmd)
 
 int CmdReadWord(const char *Cmd)
 {
 
 int CmdReadWord(const char *Cmd)
 {
-  int Word = 16; //default to invalid word
+       int Word = -1; //default to invalid word
   UsbCommand c;
   
   sscanf(Cmd, "%d", &Word);
   
   UsbCommand c;
   
   sscanf(Cmd, "%d", &Word);
   
-  if (Word > 15) {
+       if ( (Word > 15) | (Word < 0) ) {
     PrintAndLog("Word must be between 0 and 15");
     return 1;
   }
     PrintAndLog("Word must be between 0 and 15");
     return 1;
   }
@@ -530,13 +530,13 @@ int CmdReadWord(const char *Cmd)
 
 int CmdReadWordPWD(const char *Cmd)
 {
 
 int CmdReadWordPWD(const char *Cmd)
 {
-  int Word = 16; //default to invalid word
+       int Word = -1; //default to invalid word
   int Password = 0xFFFFFFFF; //default to blank password
   UsbCommand c;
   
   sscanf(Cmd, "%d %x", &Word, &Password);
   
   int Password = 0xFFFFFFFF; //default to blank password
   UsbCommand c;
   
   sscanf(Cmd, "%d %x", &Word, &Password);
   
-  if (Word > 15) {
+       if ( (Word > 15) | (Word < 0) ) {
     PrintAndLog("Word must be between 0 and 15");
     return 1;
   }
     PrintAndLog("Word must be between 0 and 15");
     return 1;
   }
@@ -565,7 +565,7 @@ int CmdWriteWord(const char *Cmd)
     return 1;
   }
   
     return 1;
   }
   
-  PrintAndLog("Writting word %d with data %08X", Word, Data);
+  PrintAndLog("Writing word %d with data %08X", Word, Data);
   
   c.cmd = CMD_EM4X_WRITE_WORD;
   c.d.asBytes[0] = 0x0; //Normal mode
   
   c.cmd = CMD_EM4X_WRITE_WORD;
   c.d.asBytes[0] = 0x0; //Normal mode
@@ -578,7 +578,7 @@ int CmdWriteWord(const char *Cmd)
 
 int CmdWriteWordPWD(const char *Cmd)
 {
 
 int CmdWriteWordPWD(const char *Cmd)
 {
-  int Word = 8; //default to invalid word
+  int Word = 16; //default to invalid word
   int Data = 0xFFFFFFFF; //default to blank data
   int Password = 0xFFFFFFFF; //default to blank password
   UsbCommand c;
   int Data = 0xFFFFFFFF; //default to blank data
   int Password = 0xFFFFFFFF; //default to blank password
   UsbCommand c;
@@ -590,7 +590,7 @@ int CmdWriteWordPWD(const char *Cmd)
     return 1;
   }
   
     return 1;
   }
   
-  PrintAndLog("Writting word %d with data %08X and password %08X", Word, Data, Password);
+  PrintAndLog("Writing word %d with data %08X and password %08X", Word, Data, Password);
   
   c.cmd = CMD_EM4X_WRITE_WORD;
   c.d.asBytes[0] = 0x1; //Password mode
   
   c.cmd = CMD_EM4X_WRITE_WORD;
   c.d.asBytes[0] = 0x1; //Password mode
@@ -601,8 +601,6 @@ int CmdWriteWordPWD(const char *Cmd)
   return 0;
 }
 
   return 0;
 }
 
-
-
 static command_t CommandTable[] =
 {
   {"help", CmdHelp, 1, "This help"},
 static command_t CommandTable[] =
 {
   {"help", CmdHelp, 1, "This help"},
index ab4a26095c6eb53ffad04489efb497c8bfc97d17..549c427c7b52150695025f4ea9ead0ee90508f07 100644 (file)
@@ -29,7 +29,7 @@ size_t nbytes(size_t nbits) {
 
 int CmdLFHitagList(const char *Cmd)
 {
 
 int CmdLFHitagList(const char *Cmd)
 {
-  uint8_t got[3000];
+  uint8_t got[TRACE_BUFFER_SIZE];
   GetFromBigBuf(got,sizeof(got),0);
   WaitForResponse(CMD_ACK,NULL);
 
   GetFromBigBuf(got,sizeof(got),0);
   WaitForResponse(CMD_ACK,NULL);
 
@@ -39,11 +39,25 @@ int CmdLFHitagList(const char *Cmd)
 
   int i = 0;
   int prev = -1;
 
   int i = 0;
   int prev = -1;
+  int len = strlen(Cmd);
+
+  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;
+       }
+  }
 
   for (;;) {
 
   for (;;) {
-    if(i >= 1900) {
-      break;
-    }
+  
+    if(i >= TRACE_BUFFER_SIZE) { break; }
 
     bool isResponse;
     int timestamp = *((uint32_t *)(got+i));
 
     bool isResponse;
     int timestamp = *((uint32_t *)(got+i));
@@ -68,9 +82,7 @@ int CmdLFHitagList(const char *Cmd)
     if (len > 100) {
       break;
     }
     if (len > 100) {
       break;
     }
-    if (i + len >= 1900) {
-      break;
-    }
+    if (i + len >= TRACE_BUFFER_SIZE) { break;}
 
     uint8_t *frame = (got+i+9);
 
 
     uint8_t *frame = (got+i+9);
 
@@ -103,18 +115,22 @@ int CmdLFHitagList(const char *Cmd)
       line);
 
 
       line);
 
 
-//   if (pf) {
-//      fprintf(pf," +%7d:  %3d: %s %s\n",
-//                                     (prev < 0 ? 0 : (timestamp - prev)),
-//                                     bits,
-//                                     (isResponse ? "TAG" : "   "),
-//                                     line);
-//    }
+   if (pf) {
+      fprintf(pf," +%7d:  %3d: %s %s\n",
+                                       (prev < 0 ? 0 : (timestamp - prev)),
+                                       bits,
+                                       (isResponse ? "TAG" : "   "),
+                                       line);
+    }
        
     prev = timestamp;
     i += (len + 9);
   }
   
        
     prev = timestamp;
     i += (len + 9);
   }
   
+  if (pf) {
+    fclose(pf);
+       PrintAndLog("Recorded activity succesfully written to file: %s", filename);
+  }
 
   return 0;
 }
 
   return 0;
 }
@@ -126,12 +142,14 @@ int CmdLFHitagSnoop(const char *Cmd) {
 }
 
 int CmdLFHitagSim(const char *Cmd) {
 }
 
 int CmdLFHitagSim(const char *Cmd) {
+    
   UsbCommand c = {CMD_SIMULATE_HITAG};
   UsbCommand c = {CMD_SIMULATE_HITAG};
-       char filename[256] = { 0x00 };
+       char filename[FILE_PATH_SIZE] = { 0x00 };
        FILE* pf;
        bool tag_mem_supplied;
        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) {
        
        if (strlen(filename) > 0) {
                if ((pf = fopen(filename,"rb+")) == NULL) {
@@ -227,9 +245,9 @@ int CmdLFHitagReader(const char *Cmd) {
 static command_t CommandTable[] = 
 {
   {"help",    CmdHelp,           1, "This help"},
 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"},
   {"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}
 };
   {"snoop",   CmdLFHitagSnoop,   1, "Eavesdrop Hitag communication"},
                {NULL, NULL, 0, NULL}
 };
index b6517caa560f86de895f7b5ca5c8e3580136711c..15cb3f9875ba23afb1c5908c0530feb300190795 100644 (file)
@@ -132,9 +132,11 @@ int getCommand(UsbCommand* response)
 bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
   
   UsbCommand resp;
 bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
   
   UsbCommand resp;
+       
        if (response == NULL)
     response = &resp;
 
        if (response == NULL)
     response = &resp;
 
+
   // Wait until the command is received
   for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) {
 
   // Wait until the command is received
   for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) {
 
index 2a24ba8fc07543cbccb82cb35deba5a1d9fc28f0..c273c1f383b759c76a008669d91f1300c30134e7 100644 (file)
@@ -52,11 +52,8 @@ void ReceiveCommand(UsbCommand* rxcmd) {
   while (true) {
     rxlen = sizeof(UsbCommand) - (prx-prxcmd);
     if (uart_receive(sp,prx,&rxlen)) {
   while (true) {
     rxlen = sizeof(UsbCommand) - (prx-prxcmd);
     if (uart_receive(sp,prx,&rxlen)) {
-//      printf("received [%zd] bytes\n",rxlen);
       prx += rxlen;
       if ((prx-prxcmd) >= sizeof(UsbCommand)) {
       prx += rxlen;
       if ((prx-prxcmd) >= sizeof(UsbCommand)) {
-//        printf("received: ");
-//        cmd_debug(rxcmd);
         return;
       }
     }
         return;
       }
     }
index e93d0a97cad525872a1871643c6a14a35462c4b0..13b9c8e74fce7aff5ce447b34e227235571a8f02 100644 (file)
@@ -104,8 +104,11 @@ local _commands = {
        CMD_MIFARE_EML_MEMSET =                                              0x0602,
        CMD_MIFARE_EML_MEMGET =                                              0x0603,
        CMD_MIFARE_EML_CARDLOAD =                                            0x0604,
        CMD_MIFARE_EML_MEMSET =                                              0x0602,
        CMD_MIFARE_EML_MEMGET =                                              0x0603,
        CMD_MIFARE_EML_CARDLOAD =                                            0x0604,
-       CMD_MIFARE_EML_CSETBLOCK =                                           0x0605,
-       CMD_MIFARE_EML_CGETBLOCK =                                           0x0606,
+       
+       --// magic chinese card commands
+       CMD_MIFARE_CSETBLOCK =                                               0x0605,
+       CMD_MIFARE_CGETBLOCK =                                               0x0606,
+       CMD_MIFARE_CIDENT =                                                  0x0607,
 
        CMD_SIMULATE_MIFARE_CARD =                                           0x0610,
 
 
        CMD_SIMULATE_MIFARE_CARD =                                           0x0610,
 
index 3d27d5b68350d1b913536c56c3f3befff15946d3..e84f70ada526e99b36b69f5077f5be8208e2c587 100644 (file)
@@ -33,9 +33,86 @@ local Utils =
 \r
                return answer\r
        end,\r
 \r
                return answer\r
        end,\r
+       \r
+       ------------ FILE READING\r
+       ReadDumpFile = function (filename)\r
+       \r
+               if filename == nil then \r
+                       return nil, 'Filename is empty'\r
+               end\r
+               if #filename == 0 then\r
+                       return nil, 'Filename length is zero'\r
+               end\r
+\r
+               infile = io.open(filename, "rb")\r
+               if infile == nil then \r
+                       return nil, string.format("Could not read file %s",filename)\r
+               end\r
+               local t = infile:read("*all")\r
+               len = string.len(t)\r
+               local  _,hex = bin.unpack(("H%d"):format(len),t)\r
+               io.close(infile)\r
+               return hex\r
+       end,\r
+       \r
+       ------------ string split function\r
+       Split = function( inSplitPattern, outResults )\r
+               if not outResults then\r
+                       outResults = {}\r
+               end\r
+               local start = 1\r
+               local splitStart, splitEnd = string.find( self, inSplitPattern, start )\r
+               while splitStart do\r
+                       table.insert( outResults, string.sub( self, start, splitStart-1 ) )\r
+                       start = splitEnd + 1\r
+                       splitStart, splitEnd = string.find( self, inSplitPattern, start )\r
+               end\r
+               table.insert( outResults, string.sub( self, start ) )\r
+               return outResults\r
+       end,\r
+       \r
+       ------------ CRC-16 ccitt checksums\r
+       \r
+       -- Takes a hex string and calculates a crc16\r
+       Crc16 = function(s)\r
+               if s == nil then return nil end\r
+               if #s == 0 then return nil end\r
+               if  type(s) == 'string' then\r
+                       local utils = require('utils')\r
+                       local asc = utils.ConvertHexToAscii(s)\r
+                       local hash = core.crc16(asc)\r
+                       return hash\r
+               end\r
+               return nil\r
+       end,\r
+\r
+       -- input parameter is a string\r
+       -- Swaps the endianess and returns a number,  \r
+       -- IE:  'cd7a' -> '7acd'  -> 0x7acd\r
+       SwapEndianness = function(s, len)\r
+               if s == nil then return nil end\r
+               if #s == 0 then return '' end\r
+               if  type(s) ~= 'string' then return nil end\r
+               \r
+               local retval = 0\r
+               if len == 16 then\r
+                       local t = s:sub(3,4)..s:sub(1,2)\r
+                       retval = tonumber(t,16)\r
+               elseif len == 24 then\r
+                       local t = s:sub(5,6)..s:sub(3,4)..s:sub(1,2)\r
+                       retval = tonumber(t,16)\r
+               elseif len == 32 then\r
+                       local t = s:sub(7,8)..s:sub(5,6)..s:sub(3,4)..s:sub(1,2)\r
+                       retval = tonumber(t,16)\r
+               end\r
+               return retval\r
+       end,\r
+       \r
+       ------------ CONVERSIONS\r
+       \r
        --\r
        -- Converts DECIMAL to HEX\r
        --\r
        -- Converts DECIMAL to HEX\r
-    ConvertDec2Hex = function(IN)\r
+    ConvertDecToHex = function(IN)\r
                local B,K,OUT,I,D=16,"0123456789ABCDEF","",0\r
                while IN>0 do\r
                        I=I+1\r
                local B,K,OUT,I,D=16,"0123456789ABCDEF","",0\r
                while IN>0 do\r
                        I=I+1\r
@@ -46,12 +123,100 @@ local Utils =
        end,\r
        ---\r
        -- Convert Byte array to string of hex\r
        end,\r
        ---\r
        -- Convert Byte array to string of hex\r
-       ConvertBytes2String = function(bytes)\r
-               s = {}\r
+       ConvertBytesToHex = function(bytes)\r
+               if #bytes == 0 then\r
+                       return ''\r
+               end\r
+               local s={}\r
                for i = 1, #(bytes) do\r
                        s[i] =   string.format("%02X",bytes[i]) \r
                end\r
                return table.concat(s)\r
        end,    \r
                for i = 1, #(bytes) do\r
                        s[i] =   string.format("%02X",bytes[i]) \r
                end\r
                return table.concat(s)\r
        end,    \r
+       -- Convert byte array to string with ascii\r
+    ConvertBytesToAscii = function(bytes)\r
+               if #bytes == 0 then\r
+                       return ''\r
+               end\r
+               local s={}\r
+               for i = 1, #(bytes) do\r
+                       s[i] = string.char(bytes[i]) \r
+               end\r
+               return table.concat(s)          \r
+       end,     \r
+       ConvertHexToBytes = function(s)\r
+               local t={}\r
+               if s == nil then return t end\r
+               if #s == 0 then return t end\r
+               for k in s:gmatch"(%x%x)" do\r
+                       table.insert(t,tonumber(k,16))\r
+               end\r
+               return t\r
+       end,\r
+       ConvertAsciiToBytes = function(s)\r
+               local t={}\r
+               if s == nil then return t end\r
+               if #s == 0 then return t end\r
+               \r
+               for k in s:gmatch"(.)" do\r
+                       table.insert(t, string.byte(k))\r
+               end\r
+               return t\r
+       end,\r
+       ConvertHexToAscii = function(s)\r
+               local t={}\r
+               if s == nil then return t end\r
+               if #s == 0 then return t end\r
+               for k in s:gmatch"(%x%x)" do\r
+                       table.insert(t, string.char(tonumber(k,16)))\r
+               end\r
+               return  table.concat(t) \r
+       end,\r
+       \r
+       -- function convertStringToBytes(str)\r
+       -- local bytes = {}\r
+       -- local strLength = string.len(str)\r
+       -- for i=1,strLength do\r
+               -- table.insert(bytes, string.byte(str, i))\r
+       -- end\r
+\r
+       -- return bytes\r
+-- end\r
+\r
+-- function convertBytesToString(bytes)\r
+       -- local bytesLength = table.getn(bytes)\r
+       -- local str = ""\r
+       -- for i=1,bytesLength do\r
+               -- str = str .. string.char(bytes[i])\r
+       -- end\r
+\r
+       -- return str\r
+-- end\r
+\r
+-- function convertHexStringToBytes(str)\r
+       -- local bytes = {}\r
+       -- local strLength = string.len(str)\r
+       -- for k=2,strLength,2 do\r
+               -- local hexString = "0x" .. string.sub(str, (k - 1), k)\r
+               -- table.insert(bytes, hex.to_dec(hexString))\r
+       -- end\r
+\r
+       -- return bytes\r
+-- end\r
+\r
+-- function convertBytesToHexString(bytes)\r
+       -- local str = ""\r
+       -- local bytesLength = table.getn(bytes)\r
+       -- for i=1,bytesLength do\r
+               -- local hexString = string.sub(hex.to_hex(bytes[i]), 3)\r
+               -- if string.len(hexString) == 1 then\r
+                       -- hexString = "0" .. hexString\r
+               -- end\r
+               -- str = str .. hexString\r
+       -- end\r
+\r
+       -- return str\r
+-- end\r
+\r
 }\r
 return Utils
\ No newline at end of file
 }\r
 return Utils
\ No newline at end of file
index 8a967c7f33577bc6120030711038429f15cc9e80..0e2a698c1b8ca3783f2a1bc16d980539c423ce22 100644 (file)
@@ -16,7 +16,7 @@
 #include <unistd.h>
 #include <readline/readline.h>
 #include <readline/history.h>
 #include <unistd.h>
 #include <readline/readline.h>
 #include <readline/history.h>
-//#include "proxusb.h"
+
 #include "proxmark3.h"
 #include "proxgui.h"
 #include "cmdmain.h"
 #include "proxmark3.h"
 #include "proxgui.h"
 #include "cmdmain.h"
index 963bb64c2b0dd616595671eb5923f5bc9c8e5049..eed5544b929b3bcce248419d7f9ab72a8827b8d6 100644 (file)
@@ -18,6 +18,8 @@
 #include "util.h"
 #include "nonce2key/nonce2key.h"
 #include "../common/iso15693tools.h"
 #include "util.h"
 #include "nonce2key/nonce2key.h"
 #include "../common/iso15693tools.h"
+#include <openssl/aes.h>   
+#include "../common/crc16.h"
 /**
  * The following params expected:
  *  UsbCommand c
 /**
  * The following params expected:
  *  UsbCommand c
@@ -224,6 +226,54 @@ static int l_iso15693_crc(lua_State *L)
     return 1;
 }
 
     return 1;
 }
 
+/*
+ Simple AES 128 cbc hook up to OpenSSL.
+ params:  key, input
+*/
+static int l_aes(lua_State *L)
+{
+       //Check number of arguments
+       int i;
+    size_t size;
+    const char *p_key = luaL_checklstring(L, 1, &size);
+    if(size != 32)  return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size);
+
+    const char *p_encTxt = luaL_checklstring(L, 2, &size);
+    
+       unsigned char indata[AES_BLOCK_SIZE] = {0x00};
+       unsigned char outdata[AES_BLOCK_SIZE] = {0x00};
+    unsigned char aes_key[AES_BLOCK_SIZE] = {0x00};
+       unsigned char iv[AES_BLOCK_SIZE] = {0x00};
+       
+       // convert key to bytearray
+       for (i = 0; i < 32; i += 2) {
+               sscanf(&p_encTxt[i], "%02x", (unsigned int *)&indata[i / 2]);
+       }
+       
+       // convert input to bytearray
+       for (i = 0; i < 32; i += 2) {
+               sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]);
+       }
+       
+       AES_KEY key;
+       AES_set_decrypt_key(aes_key, 128, &key);
+    AES_cbc_encrypt(indata, outdata, sizeof(indata), &key, iv, AES_DECRYPT);
+
+    //Push decrypted array as a string
+       lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
+       return 1;// return 1 to signal one return value
+}
+
+static int l_crc16(lua_State *L)
+{
+       size_t size;
+       const char *p_str = luaL_checklstring(L, 1, &size);
+               
+       uint16_t retval = crc16_ccitt( (uint8_t*) p_str, size);
+    lua_pushinteger(L, (int) retval);
+    return 1;
+}
+
 /**
  * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
  * able to do "require('foobar')" if foobar.lua is within lualibs folder.
 /**
  * @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
  * able to do "require('foobar')" if foobar.lua is within lualibs folder.
@@ -261,6 +311,8 @@ int set_pm3_libraries(lua_State *L)
         {"clearCommandBuffer",          l_clearCommandBuffer},
         {"console",                      l_CmdConsole},
         {"iso15693_crc",                 l_iso15693_crc},
         {"clearCommandBuffer",          l_clearCommandBuffer},
         {"console",                      l_CmdConsole},
         {"iso15693_crc",                 l_iso15693_crc},
+               {"aes",                         l_aes},
+               {"crc16",                       l_crc16},
         {NULL, NULL}
     };
 
         {NULL, NULL}
     };
 
diff --git a/client/scripts/tnp3dump.lua b/client/scripts/tnp3dump.lua
new file mode 100644 (file)
index 0000000..520161b
--- /dev/null
@@ -0,0 +1,272 @@
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local lib14a = require('read14a')
+local utils = require('utils')
+local md5 = require('md5')
+local dumplib = require('html_dumplib')
+local toyNames = require('default_toys')
+
+example =[[
+       1. script run tnp3dump
+       2. script run tnp3dump -n
+       3. script run tnp3dump -k aabbccddeeff
+       4. script run tnp3dump -k aabbccddeeff -n
+       5. script run tnp3dump -o myfile 
+       6. script run tnp3dump -n -o myfile 
+       7. script run tnp3dump -k aabbccddeeff -n -o myfile 
+]]
+author = "Iceman"
+usage = "script run tnp3dump -k <key> -n -o <filename>"
+desc =[[
+This script will try to dump the contents of a Mifare TNP3xxx card.
+It will need a valid KeyA in order to find the other keys and decode the card.
+Arguments:
+       -h             : this help
+       -k <key>       : Sector 0 Key A.
+       -n             : Use the nested cmd to find all keys
+       -o             : filename for the saved dumps
+]]
+
+local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = false -- the debug flag
+local numBlocks = 64
+local numSectors = 16
+--- 
+-- 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)
+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
+
+local function readdumpkeys(infile)
+        t = infile:read("*all")
+        len = string.len(t)
+        local len,hex = bin.unpack(("H%d"):format(len),t)
+        return hex
+end
+
+local function waitCmd()
+       local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
+       if response then
+               local count,cmd,arg0 = bin.unpack('LL',response)
+               if(arg0==1) then
+                       local count,arg1,arg2,data = bin.unpack('LLH511',response,count)
+                       return data:sub(1,32)
+               else
+                       return nil, "Couldn't read block.." 
+               end
+       end
+       return nil, "No response from device"
+end
+
+local function computeCrc16(s)
+       local hash = core.crc16(utils.ConvertHexToAscii(s))     
+       return hash
+end
+
+local function reverseCrcBytes(crc)
+       crc2 = crc:sub(3,4)..crc:sub(1,2)
+       return tonumber(crc2,16)
+end
+
+local function main(args)
+
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+       
+       local keyA
+       local cmd
+       local err
+       local useNested = false
+       local cmdReadBlockString = 'hf mf rdbl %d A %s'
+       local input = "dumpkeys.bin"
+       local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M%S");
+
+       -- Arguments for the script
+       for o, a in getopt.getopt(args, 'hk:no:') do
+               if o == "h" then return help() end              
+               if o == "k" then keyA = a end
+               if o == "n" then useNested = true end
+               if o == "o" then outputTemplate = a end         
+       end
+
+       -- validate input args.
+       keyA =  keyA or '4b0b20107ccb'
+       if #(keyA) ~= 12 then
+               return oops( string.format('Wrong length of write key (was %d) expected 12', #keyA))
+       end
+
+       -- Turn off Debug
+       local cmdSetDbgOff = "hf mf dbg 0"
+       core.console( cmdSetDbgOff) 
+       
+       result, err = lib14a.read1443a(false)
+       if not result then
+               return oops(err)
+       end
+
+       core.clearCommandBuffer()
+       
+       if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
+               return oops('This is not a TNP3xxx tag. aborting.')
+       end     
+
+       -- Show tag info
+       print((' Found tag : %s'):format(result.name))
+       print(('Using keyA : %s'):format(keyA))
+
+       --Trying to find the other keys
+       if useNested then
+         core.console( ('hf mf nested 1 0 A %s d'):format(keyA) )
+       end
+       
+       core.clearCommandBuffer()
+       
+       -- Loading keyfile
+       print('Loading dumpkeys.bin')
+       local hex, err = utils.ReadDumpFile(input)
+       if not hex then
+               return oops(err)
+       end
+
+       local akeys = hex:sub(0,12*16)
+
+       -- Read block 0
+       cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA}
+       err = core.SendCommand(cmd:getBytes())
+       if err then return oops(err) end
+       local block0, err = waitCmd()
+       if err then return oops(err) end
+       
+       -- Read block 1
+       cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA}
+       err = core.SendCommand(cmd:getBytes())
+       if err then return oops(err) end
+       local block1, err = waitCmd()
+       if err then return oops(err) end
+
+       local key
+       local pos = 0
+       local blockNo
+       local blocks = {}
+
+       print('Reading card data')
+       core.clearCommandBuffer()
+               
+       -- main loop
+       io.write('Decrypting blocks > ')
+       for blockNo = 0, numBlocks-1, 1 do
+
+               if core.ukbhit() then
+                       print("aborted by user")
+                       break
+               end
+       
+               pos = (math.floor( blockNo / 4 ) * 12)+1
+               key = akeys:sub(pos, pos + 11 )
+               cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo ,arg2 = 0,arg3 = 0, data = key}
+               local err = core.SendCommand(cmd:getBytes())
+               if err then return oops(err) end
+               local blockdata, err = waitCmd()
+               if err then return oops(err) end                
+
+               if  blockNo%4 ~= 3 then
+                       if blockNo < 8 then
+                               -- Block 0-7 not encrypted
+                               blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata) 
+                       else
+                               local base = ('%s%s%02x%s'):format(block0, block1, blockNo, HASHCONSTANT)       
+                               local baseStr = utils.ConvertHexToAscii(base)
+                               local md5hash = md5.sumhexa(baseStr)
+                               local aestest = core.aes(md5hash, blockdata)
+
+                               local hex = utils.ConvertAsciiToBytes(aestest)
+                               hex = utils.ConvertBytesToHex(hex)
+
+                               -- blocks with zero not encrypted.
+                               if string.find(blockdata, '^0+$') then
+                                       blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,blockdata) 
+                               else
+                                       blocks[blockNo+1] = ('%02d  :: %s'):format(blockNo,hex)
+                                       io.write( blockNo..',')
+                               end             
+                       end
+               else
+                       -- Sectorblocks, not encrypted
+                       blocks[blockNo+1] = ('%02d  :: %s%s'):format(blockNo,key,blockdata:sub(13,32)) 
+               end
+       end
+       io.write('\n')
+       
+       core.clearCommandBuffer()
+               
+       -- Print results
+       local bindata = {}
+       local emldata = ''
+
+       for _,s in pairs(blocks) do
+               local slice = s:sub(8,#s)
+               local str = utils.ConvertBytesToAscii(
+                                utils.ConvertHexToBytes(slice)
+                               )
+               emldata = emldata..slice..'\n'
+               for c in (str):gmatch('.') do
+                       bindata[#bindata+1] = c
+               end
+       end 
+       
+       -- Write dump to files
+       if not DEBUG then
+               local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'.bin')
+               print(("Wrote a BIN dump to the file %s"):format(foo))
+               local bar = dumplib.SaveAsText(emldata, outputTemplate..'.eml')
+               print(("Wrote a EML dump to the file %s"):format(bar))
+       end
+
+       local uid = block0:sub(1,8)
+       local itemtype = block1:sub(1,4)
+       local cardid = block1:sub(9,24)
+
+       -- Show info 
+       print( string.rep('--',20) )
+       print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
+       print( ('       UID : 0x%s'):format(uid) )
+       print( ('    CARDID : 0x%s'):format(cardid ) )  
+       print( string.rep('--',20) )
+
+end
+main(args)
\ No newline at end of file
diff --git a/client/scripts/tnp3sim.lua b/client/scripts/tnp3sim.lua
new file mode 100644 (file)
index 0000000..f43dafa
--- /dev/null
@@ -0,0 +1,355 @@
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local lib14a = require('read14a')
+local utils = require('utils')
+local md5 = require('md5')
+local toyNames = require('default_toys')
+
+example =[[
+       1. script run tnp3sim
+       2. script run tnp3sim -m
+       3. script run tnp3sim -m -i myfile
+]]
+author = "Iceman"
+usage = "script run tnp3sim -h -m -i <filename>"
+desc =[[
+This script will try to load a binary datadump of a Mifare TNP3xxx card.
+It vill try to validate all checksums and view some information stored in the dump
+For an experimental mode, it tries to manipulate some data.
+At last it sends all data to the PM3 device memory where it can be used in the command  "hf mf sim"
+
+Arguments:
+       -h             : this help
+       -m             : Maxed out items (experimental)
+       -i             : filename for the datadump to read (bin)
+]]
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = true -- the debug flag
+--- 
+-- 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)
+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
+
+
+local function writedumpfile(infile)
+        t = infile:read("*all")
+        len = string.len(t)
+        local len,hex = bin.unpack(("H%d"):format(len),t)
+        return hex
+end
+-- blocks with data
+-- there are two dataareas, in block 8 or block 36,   ( 1==8 ,
+-- checksum type =  0, 1, 2, 3
+local function GetCheckSum(blocks, dataarea, chksumtype)
+
+       local crc
+       local area = 36
+       if  dataarea == 1 then
+               area = 8
+       end
+       
+       if chksumtype == 0 then
+               crc = blocks[1]:sub(29,32)
+       elseif chksumtype == 1 then
+               crc = blocks[area]:sub(29,32)
+       elseif chksumtype == 2 then     
+               crc = blocks[area]:sub(25,28)
+       elseif chksumtype == 3 then
+               crc = blocks[area]:sub(21,24)           
+       end
+       return utils.SwapEndianness(crc,16)
+end
+
+local function SetCheckSum(blocks, chksumtype)
+
+       if blocks == nil then return nil, 'Argument \"blocks\" nil' end
+       local newcrc
+       local area1 = 8
+       local area2 = 36
+       
+       if chksumtype == 0 then
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,1,0))      
+               blocks[1] = blocks[1]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+       elseif chksumtype == 1 then
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,1,1))      
+               blocks[area1] = blocks[area1]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,2,1))      
+               blocks[area2] = blocks[area2]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+       elseif chksumtype == 2 then     
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,1,2))      
+               blocks[area1] = blocks[area1]:sub(1,24)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area1]:sub(29,32)
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,2,2))      
+               blocks[area2] = blocks[area2]:sub(1,24)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area2]:sub(29,32)
+       elseif chksumtype == 3 then
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,1,3))      
+               blocks[area1] = blocks[area1]:sub(1,20)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area1]:sub(25,32)
+               newcrc = ('%04X'):format(CalcCheckSum(blocks,2,3))      
+               blocks[area2] = blocks[area2]:sub(1,20)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area2]:sub(25,32)
+       end
+end
+
+function CalcCheckSum(blocks, dataarea, chksumtype)
+       local area = 36
+       if dataarea == 1 then
+               area = 8
+       end
+       
+       if chksumtype == 0 then
+               data = blocks[0]..blocks[1]:sub(1,28)
+       elseif chksumtype == 1 then
+               data = blocks[area]:sub(1,28)..'0500'
+       elseif chksumtype == 2 then     
+               data =  blocks[area+1]..blocks[area+2]..blocks[area+4]
+       elseif chksumtype == 3 then
+               data =  blocks[area+5]..blocks[area+6]..blocks[area+8]..string.rep('00',0xe0)   
+       end
+       return utils.Crc16(data)
+end
+
+local function ValidateCheckSums(blocks)
+
+       local isOk, crc, calc
+       -- Checksum Type 0
+       crc = GetCheckSum(blocks,1,0)
+       calc = CalcCheckSum(blocks, 1, 0)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end
+       io.write( ('TYPE 0       : %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+       -- Checksum Type 1 (DATAAREAHEADER 1)
+       crc = GetCheckSum(blocks,1,1)
+       calc = CalcCheckSum(blocks,1,1)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end
+       io.write( ('TYPE 1 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+       
+       -- Checksum Type 1 (DATAAREAHEADER 2)
+       crc = GetCheckSum(blocks,2,1)
+       calc = CalcCheckSum(blocks,2,1)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end
+       io.write( ('TYPE 1 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+       
+       -- Checksum Type 2 (DATAAREA 1)
+       crc = GetCheckSum(blocks,1,2)
+       calc = CalcCheckSum(blocks,1,2)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end   
+       io.write( ('TYPE 2 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+       -- Checksum Type 2 (DATAAREA 2)
+       crc = GetCheckSum(blocks,2,2)
+       calc = CalcCheckSum(blocks,2,2)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end   
+       io.write( ('TYPE 2 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+       -- Checksum Type 3 (DATAAREA 1)
+       crc = GetCheckSum(blocks,1,3)
+       calc = CalcCheckSum(blocks,1,3)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end   
+       io.write( ('TYPE 3 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+       -- Checksum Type 3 (DATAAREA 2)
+       crc = GetCheckSum(blocks,2,3)
+       calc = CalcCheckSum(blocks,2,3)
+       if crc == calc then isOk='Ok' else isOk = 'Error' end   
+       io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+end
+
+
+local function LoadEmulator(blocks)
+       local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+       local cmd
+       local blockdata
+       for _,b in pairs(blocks) do 
+               
+               blockdata = b
+               
+               if  _%4 ~= 3 then
+                       if (_ >= 8 and _<=21)  or  (_ >= 36 and _<=49) then
+                               local base = ('%s%s%02x%s'):format(blocks[0], blocks[1], _ , HASHCONSTANT)      
+                               local baseStr = utils.ConvertHexToAscii(base)
+                               local key = md5.sumhexa(baseStr)
+                               local enc = core.aes(key, blockdata)
+                               local hex = utils.ConvertAsciiToBytes(enc)
+                               hex = utils.ConvertBytesToHex(hex)
+                       
+                               blockdata = hex
+                               io.write( _..',')
+                       end
+               end
+
+               cmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMSET, arg1 = _ ,arg2 = 1,arg3 = 0, data = blockdata}
+               local err = core.SendCommand(cmd:getBytes())
+               if err then 
+                       return err
+               end
+       end
+       io.write('\n')
+end
+
+local function main(args)
+
+       print( string.rep('--',20) )
+       print( string.rep('--',20) )
+       
+       local result, err, hex
+       local maxed = false
+       local inputTemplate = "dumpdata.bin"
+       local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M");
+       
+               -- Arguments for the script
+       for o, a in getopt.getopt(args, 'hmi:o:') do
+               if o == "h" then return help() end              
+               if o == "m" then maxed = true end
+               if o == "o" then outputTemplate = a end         
+               if o == "i" then inputTemplate = a end
+       end
+       
+       -- Turn off Debug
+       local cmdSetDbgOff = "hf mf dbg 0"
+       core.console( cmdSetDbgOff) 
+       
+       -- Look for tag present on reader,
+       result, err = lib14a.read1443a(false)
+       if not result then return oops(err)     end
+
+       core.clearCommandBuffer()
+       
+       if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
+               return oops('This is not a TNP3xxx tag. aborting.')
+       end     
+
+       -- Show tag info
+       print((' Found tag : %s'):format(result.name))
+       
+       -- Load dump.bin file
+       print( (' Load data from %s'):format(inputTemplate))
+       hex, err = utils.ReadDumpFile(inputTemplate)
+       if not hex then return oops(err) end
+       
+       local blocks = {}
+       local blockindex = 0
+       for i = 1, #hex, 32 do
+               blocks[blockindex] = hex:sub(i,i+31)
+               blockindex = blockindex + 1
+       end
+
+       if DEBUG then
+               print('Validating checksums in the loaded datadump')
+               ValidateCheckSums(blocks)
+       end
+       
+       --
+       print( string.rep('--',20) )    
+       print(' Gathering info')
+       local uid = blocks[0]:sub(1,8)
+       local itemtype = blocks[1]:sub(1,4)
+       local cardid = blocks[1]:sub(9,24)
+
+       -- Show info 
+       print( string.rep('--',20) )
+       print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
+       print( ('       UID : 0x%s'):format(uid) )
+       print( ('    CARDID : 0x%s'):format(cardid ) )  
+       print( string.rep('--',20) )
+
+       -- lets do something.
+       -- 
+       local experience = blocks[8]:sub(1,6)
+       print(('Experience  : %d'):format(utils.SwapEndianness(experience,24)))
+       local money = blocks[8]:sub(7,10)
+       print(('Money       : %d'):format(utils.SwapEndianness(money,16)))
+       local fairy = blocks[9]:sub(1,8)
+       --FD0F = Left, FF0F = Right
+       local path = 'not choosen'
+       if fairy:sub(2,2) == 'D' then
+               path = 'Left'
+       elseif fairy:sub(2,2) == 'F' then
+               path = 'Right'
+       end
+       print(('Fairy       : %d [Path: %s] '):format(utils.SwapEndianness(fairy,24),path))
+       
+       local hat = blocks[9]:sub(8,11)
+       print(('Hat         : %d'):format(utils.SwapEndianness(hat,16)))
+       
+       --0x0D    0x29    0x0A    0x02    16-bit hero points value. Maximum 100.
+       local heropoints = blocks[13]:sub(20,23)
+       print(('Hero points : %d'):format(utils.SwapEndianness(heropoints,16)))
+
+       --0x10    0x2C    0x0C    0x04    32 bit flag value indicating heroic challenges completed.
+       local challenges = blocks[16]:sub(25,32)
+       print(('Finished hero challenges : %d'):format(utils.SwapEndianness(challenges,32)))
+       
+       if maxed then
+               print('Lets try to max out some values')
+               -- max out money, experience
+               --print (blocks[8])
+               blocks[8] = 'FFFFFF'..'FFFF'..blocks[8]:sub(11,32)
+               blocks[36] = 'FFFFFF'..'FFFF'..blocks[36]:sub(11,32)
+               --print (blocks[8])
+       
+               -- max out hero challenges
+               --print (blocks[16])
+               blocks[16] = blocks[16]:sub(1,24)..'FFFFFFFF'
+               blocks[44] = blocks[44]:sub(1,24)..'FFFFFFFF'
+               --print (blocks[16])
+               
+               -- max out heropoints
+               --print (blocks[13])
+               blocks[13] = blocks[13]:sub(1,19)..'0064'..blocks[13]:sub(24,32)
+               blocks[41] = blocks[41]:sub(1,19)..'0064'..blocks[41]:sub(24,32)
+               --print (blocks[13])
+       
+               -- Update Checksums
+               print('Updating all checksums')
+               SetCheckSum(blocks, 3)
+               SetCheckSum(blocks, 2)
+               SetCheckSum(blocks, 1)
+               SetCheckSum(blocks, 0)
+       
+               print('Validating all checksums')       
+               ValidateCheckSums(blocks)
+       end
+       
+       --Load dumpdata to emulator memory
+       if DEBUG then
+               print('Sending dumpdata to emulator memory')
+               err = LoadEmulator(blocks)
+               if err then return oops(err) end        
+               core.clearCommandBuffer()
+               print('The simulation is now prepared.\n --> run \"hf mf sim 5 '..uid..'\" <--')
+       end
+end
+main(args)
\ No newline at end of file
index a077aae9020ba053f74c7d52e5e5fc82df4a32d2..b8d5c316cf9bce03cfd4faab842d4ad1e0185423 100644 (file)
@@ -46,12 +46,18 @@ int ukbhit(void) {
 #endif
 
 // log files functions
 #endif
 
 // log files functions
-void AddLogLine(char *fileName, char *extData, char *c) {
+void AddLogLine(char *file, char *extData, char *c) {
        FILE *fLog = NULL;
        FILE *fLog = NULL;
-
-       fLog = fopen(fileName, "a");
+    char filename[FILE_PATH_SIZE] = {0x00};
+    int len = 0;
+
+    len = strlen(file);
+    if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+    memcpy(filename, file, len);
+   
+       fLog = fopen(filename, "a");
        if (!fLog) {
        if (!fLog) {
-               printf("Could not append log file %s", fileName);
+               printf("Could not append log file %s", filename);
                return;
        }
 
                return;
        }
 
@@ -103,11 +109,13 @@ void print_hex(const uint8_t * data, const size_t len)
 }
 
 char * sprint_hex(const uint8_t * data, const size_t len) {
 }
 
 char * sprint_hex(const uint8_t * data, const size_t len) {
+       
+       int maxLen = ( len > 1024/3) ? 1024/3 : len;
        static char buf[1024];
        char * tmp = buf;
        size_t i;
 
        static char buf[1024];
        char * tmp = buf;
        size_t i;
 
-       for (i=0; i < len && i < 1024/3; i++, tmp += 3)
+       for (i=0; i < maxLen; ++i, tmp += 3)
                sprintf(tmp, "%02x ", data[i]);
 
        return buf;
                sprintf(tmp, "%02x ", data[i]);
 
        return buf;
Impressum, Datenschutz