]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmdhfmf.c
PCF7931: Print found single/consecutive block(s), fixes to block 1 check
[proxmark3-svn] / client / cmdhfmf.c
index 38b7f988ac52a569957d1f60eaf3d94bd2d73672..c38e276ed51515d75ed8ef342feb1df3a26b34cb 100644 (file)
@@ -1054,7 +1054,7 @@ int CmdHF14AMfChk(const char *Cmd)
                PrintAndLog("Usage:  hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t|d|s|ss] [<key (12 hex symbols)>] [<dic (*.dic)>]");\r
                PrintAndLog("          * - all sectors");\r
                PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");\r
-               PrintAndLog("d  - write keys to binary file\n");\r
+               PrintAndLog("d  - write keys to binary file (not used when <block number> supplied)");\r
                PrintAndLog("t  - write keys to emulator memory");\r
                PrintAndLog("s  - slow execute. timeout 1ms");\r
                PrintAndLog("ss - very slow execute. timeout 5ms");\r
@@ -1066,27 +1066,27 @@ int CmdHF14AMfChk(const char *Cmd)
                return 0;\r
        }\r
 \r
-       FILE * f;\r
-       char filename[FILE_PATH_SIZE]={0};\r
-       char buf[13];\r
-       uint8_t *keyBlock = NULL, *p;\r
-       uint16_t stKeyBlock = 20;\r
-\r
-       int i, res;\r
-       int keycnt = 0;\r
-       char ctmp   = 0x00;\r
-       int clen = 0;\r
-       uint8_t blockNo = 0;\r
-       uint8_t SectorsCnt = 0;\r
-       uint8_t keyType = 0;\r
-       uint64_t key64 = 0;\r
+       FILE     * f;\r
+       char     filename[FILE_PATH_SIZE]={0};\r
+       char     buf[13];\r
+       uint8_t  *keyBlock      = NULL, *p;\r
+       uint16_t stKeyBlock     = 20;\r
+       int      i, res;\r
+       int      keycnt         = 0;\r
+       char     ctmp           = 0x00;\r
+       int      clen           = 0;\r
+       uint8_t  blockNo        = 0;\r
+       uint8_t  SectorsCnt     = 0;\r
+       uint8_t  keyType        = 0;\r
+       uint64_t key64          = 0;\r
        // timeout in units. (ms * 106)/10 or us*0.0106\r
-       uint8_t btimeout14a = MF_CHKKEYS_DEFTIMEOUT; // fast by default\r
-       bool param3InUse = false;\r
-\r
-       bool transferToEml = 0;\r
-       bool createDumpFile = 0;\r
-\r
+       uint8_t  btimeout14a    = MF_CHKKEYS_DEFTIMEOUT; // fast by default\r
+       bool     param3InUse    = false;\r
+       bool     transferToEml  = 0;\r
+       bool     createDumpFile = 0;\r
+       bool     singleBlock    = false;     // Flag to ID if a single or multi key check\r
+       uint8_t  keyFoundCount  = 0;         // Counter to display the number of keys found/transfered to emulator\r
+    \r
        sector_t *e_sector = NULL;\r
 \r
        keyBlock = calloc(stKeyBlock, 6);\r
@@ -1099,9 +1099,19 @@ int CmdHF14AMfChk(const char *Cmd)
 \r
        if (param_getchar(Cmd, 0)=='*') {\r
                SectorsCnt = ParamCardSizeSectors(param_getchar(Cmd + 1, 0));\r
-       }\r
-       else\r
+       } else {   \r
                blockNo = param_get8(Cmd, 0);\r
+               // Singe Key check, so Set Sector count to cover sectors (1 to sector that contains the block)\r
+               // 1 and 2 Cards : Sector = blockNo/4 + 1\r
+               // Sectors  0 - 31  :  4 blocks per sector : Blocks 0 - 127\r
+               // Sectors 32 - 39  : 16 blocks per sector : Blocks 128 - 255 (4K)\r
+               if (blockNo < 128) {\r
+                       SectorsCnt = (blockNo / 4) + 1;\r
+               } else {\r
+                       SectorsCnt = 32 + ((blockNo-128)/16) + 1;\r
+               }\r
+               singleBlock  = true;              // Set flag for single key check\r
+       }\r
 \r
        ctmp = param_getchar(Cmd, 1);\r
        clen = param_getlength(Cmd, 1);\r
@@ -1122,13 +1132,19 @@ int CmdHF14AMfChk(const char *Cmd)
                        return 1;\r
                };\r
        }\r
-\r
+       \r
        parseParamTDS(Cmd, 2, &transferToEml, &createDumpFile, &btimeout14a);\r
 \r
+       if (singleBlock & createDumpFile) {\r
+               PrintAndLog (" block key check (<block no>) and write to dump file (d) combination is not supported ");\r
+               PrintAndLog (" please remove option d and try again");\r
+               return 1;\r
+       }\r
+\r
        param3InUse = transferToEml | createDumpFile | (btimeout14a != MF_CHKKEYS_DEFTIMEOUT);\r
 \r
        PrintAndLog("--chk keys. sectors:%2d, block no:%3d, key type:%c, eml:%c, dmp=%c checktimeout=%d us",\r
-                       SectorsCnt, blockNo, keyType?'B':'A', transferToEml?'y':'n', createDumpFile?'y':'n', ((int)btimeout14a * 10000) / 106);\r
+                       SectorsCnt, blockNo, keyType==0?'A':keyType==1?'B':'?', transferToEml?'y':'n', createDumpFile?'y':'n', ((int)btimeout14a * 10000) / 106);\r
 \r
        for (i = param3InUse; param_getchar(Cmd, 2 + i); i++) {\r
                if (!param_gethex(Cmd, 2 + i, keyBlock + 6 * keycnt, 12)) {\r
@@ -1142,7 +1158,7 @@ int CmdHF14AMfChk(const char *Cmd)
                                keyBlock = p;\r
                        }\r
                        PrintAndLog("chk key[%2d] %02x%02x%02x%02x%02x%02x", keycnt,\r
-                       (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],\r
+                       (keyBlock + 6*keycnt)[0], (keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],\r
                        (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6);\r
                        keycnt++;\r
                } else {\r
@@ -1153,8 +1169,8 @@ int CmdHF14AMfChk(const char *Cmd)
                                return 2;\r
                        }\r
 \r
-                       if ( (f = fopen( filename , "r")) ) {\r
-                               while( fgets(buf, sizeof(buf), f) ){\r
+                       if ((f = fopen( filename , "r"))) {\r
+                               while (fgets(buf, sizeof(buf), f)) {\r
                                        if (strlen(buf) < 12 || buf[11] == '\n')\r
                                                continue;\r
 \r
@@ -1162,14 +1178,20 @@ int CmdHF14AMfChk(const char *Cmd)
 \r
                                        if( buf[0]=='#' ) continue; //The line start with # is comment, skip\r
 \r
-                                       if (!isxdigit((unsigned char)buf[0])){\r
-                                               PrintAndLog("File content error. '%s' must include 12 HEX symbols",buf);\r
+                                       bool content_error = false;\r
+                                       for (int i = 0; i < 12; i++) {\r
+                                               if (!isxdigit((unsigned char)buf[i])) {\r
+                                                       content_error = true;\r
+                                               }\r
+                                       }\r
+                                       if (content_error) {\r
+                                               PrintAndLog("File content error. '%s' must include 12 HEX symbols", buf);\r
                                                continue;\r
                                        }\r
 \r
                                        buf[12] = 0;\r
 \r
-                                       if ( stKeyBlock - keycnt < 2) {\r
+                                       if (stKeyBlock - keycnt < 2) {\r
                                                p = realloc(keyBlock, 6*(stKeyBlock+=10));\r
                                                if (!p) {\r
                                                        PrintAndLog("Cannot allocate memory for defKeys");\r
@@ -1190,7 +1212,6 @@ int CmdHF14AMfChk(const char *Cmd)
                                PrintAndLog("File: %s: not found or locked.", filename);\r
                                free(keyBlock);\r
                                return 1;\r
-\r
                        }\r
                }\r
        }\r
@@ -1200,7 +1221,7 @@ int CmdHF14AMfChk(const char *Cmd)
                PrintAndLog("No key specified, trying default keys");\r
                for (;keycnt < defaultKeysSize; keycnt++)\r
                        PrintAndLog("chk default key[%2d] %02x%02x%02x%02x%02x%02x", keycnt,\r
-                               (keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],\r
+                               (keyBlock + 6*keycnt)[0], (keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],\r
                                (keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4], (keyBlock + 6*keycnt)[5], 6);\r
        }\r
 \r
@@ -1219,14 +1240,18 @@ int CmdHF14AMfChk(const char *Cmd)
        printf("\n");\r
 \r
        bool foundAKey = false;\r
-       uint32_t max_keys = keycnt > USB_CMD_DATA_SIZE / 6 ? USB_CMD_DATA_SIZE / 6 : keycnt;\r
-       if (SectorsCnt) {\r
+       bool clearTraceLog = true;\r
+       uint32_t max_keys  = keycnt > USB_CMD_DATA_SIZE / 6 ? USB_CMD_DATA_SIZE / 6 : keycnt;\r
+\r
+       // !SingleKey, so all key check (if SectorsCnt > 0)\r
+       if (!singleBlock) { \r
                PrintAndLog("To cancel this operation press the button on the proxmark...");\r
                printf("--");\r
                for (uint32_t c = 0; c < keycnt; c += max_keys) {\r
 \r
                        uint32_t size = keycnt-c > max_keys ? max_keys : keycnt-c;\r
-                       res = mfCheckKeysSec(SectorsCnt, keyType, btimeout14a, true, size, &keyBlock[6 * c], e_sector); // timeout is (ms * 106)/10 or us*0.0106\r
+                       res = mfCheckKeysSec(SectorsCnt, keyType, btimeout14a, clearTraceLog, size, &keyBlock[6 * c], e_sector); // timeout is (ms * 106)/10 or us*0.0106\r
+                       clearTraceLog = false;\r
 \r
                        if (res != 1) {\r
                                if (!res) {\r
@@ -1240,18 +1265,26 @@ int CmdHF14AMfChk(const char *Cmd)
                                PrintAndLog("Command execute timeout");\r
                        }\r
                }\r
-       } else {\r
+       } else { \r
                int keyAB = keyType;\r
                do {\r
-                       for (uint32_t c = 0; c < keycnt; c+=max_keys) {\r
+                       for (uint32_t c = 0; c < keycnt; c += max_keys) {\r
 \r
                                uint32_t size = keycnt-c > max_keys ? max_keys : keycnt-c;\r
                                res = mfCheckKeys(blockNo, keyAB & 0x01, true, size, &keyBlock[6 * c], &key64);\r
+                               clearTraceLog = false;\r
 \r
                                if (res != 1) {\r
-                                       if (!res) {\r
-                                               PrintAndLog("Found valid key:[%d:%c]%012" PRIx64, blockNo, (keyAB & 0x01)?'B':'A', key64);\r
+                                       if (!res) {      \r
+                                               // Use the common format below\r
+                                               // PrintAndLog("Found valid key:[%d:%c]%012" PRIx64, blockNo, (keyAB & 0x01)?'B':'A', key64);\r
                                                foundAKey = true;\r
+                       \r
+                                               // Store the Single Key for display list\r
+                                               // For a single block check, SectorsCnt = Sector that contains the block\r
+                                               e_sector[SectorsCnt-1].foundKey[(keyAB & 0x01)] = true;  // flag key found \r
+                                               e_sector[SectorsCnt-1].Key[(keyAB & 0x01)]      = key64; // Save key data  \r
+                                               \r
                                        }\r
                                } else {\r
                                        PrintAndLog("Command execute timeout");\r
@@ -1262,17 +1295,25 @@ int CmdHF14AMfChk(const char *Cmd)
 \r
        // print result\r
        if (foundAKey) {\r
-               if (SectorsCnt) {\r
-                       PrintAndLog("");\r
-                       PrintAndLog("|---|----------------|---|----------------|---|");\r
-                       PrintAndLog("|sec|key A           |res|key B           |res|");\r
-                       PrintAndLog("|---|----------------|---|----------------|---|");\r
-                       for (i = 0; i < SectorsCnt; i++) {\r
-                               PrintAndLog("|%03d|  %012" PRIx64 "  | %d |  %012" PRIx64 "  | %d |", i,\r
-                                       e_sector[i].Key[0], e_sector[i].foundKey[0], e_sector[i].Key[1], e_sector[i].foundKey[1]);\r
+               PrintAndLog("");\r
+               PrintAndLog("|---|----------------|----------------|");\r
+               PrintAndLog("|sec|key A           |key B           |");\r
+               PrintAndLog("|---|----------------|----------------|");\r
+               for (i = 0; i < SectorsCnt; i++) {\r
+                       // If a block key check, only print a line if a key was found.\r
+                       if (!singleBlock || e_sector[i].foundKey[0] || e_sector[i].foundKey[1]) {\r
+                               char keyAString[13] = "      ?     ";\r
+                               char keyBString[13] = "      ?     ";\r
+                               if (e_sector[i].foundKey[0]) {\r
+                                       sprintf(keyAString, "%012" PRIx64, e_sector[i].Key[0]);\r
+                               }\r
+                               if (e_sector[i].foundKey[1]) {\r
+                                       sprintf(keyBString, "%012" PRIx64, e_sector[i].Key[1]);\r
+                               }\r
+                               PrintAndLog("|%03d|  %s  |  %s  |", i, keyAString, keyBString);\r
                        }\r
-                       PrintAndLog("|---|----------------|---|----------------|---|");\r
                }\r
+               PrintAndLog("|---|----------------|----------------|");\r
        } else {\r
                PrintAndLog("");\r
                PrintAndLog("No valid keys found.");\r
@@ -1286,15 +1327,17 @@ int CmdHF14AMfChk(const char *Cmd)
                                for (uint16_t t = 0; t < 2; t++) {\r
                                        if (e_sector[sectorNo].foundKey[t]) {\r
                                                num_to_bytes(e_sector[sectorNo].Key[t], 6, block + t * 10);\r
+                        keyFoundCount++; // Key found count for information\r
                                        }\r
                                }\r
                                mfEmlSetMem(block, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);\r
                        }\r
                }\r
-               PrintAndLog("Found keys have been transferred to the emulator memory");\r
+               // Updated to show the actual number of keys found/transfered.\r
+               PrintAndLog("%d keys(s) found have been transferred to the emulator memory",keyFoundCount);\r
        }\r
 \r
-       if (createDumpFile) {\r
+       if (createDumpFile && !singleBlock) {\r
                FILE *fkeys = fopen("dumpkeys.bin","wb");\r
                if (fkeys == NULL) {\r
                        PrintAndLog("Could not create file dumpkeys.bin");\r
@@ -1312,13 +1355,14 @@ int CmdHF14AMfChk(const char *Cmd)
                fclose(fkeys);\r
                PrintAndLog("Found keys have been dumped to file dumpkeys.bin. 0xffffffffffff has been inserted for unknown keys.");\r
        }\r
-\r
+    \r
        free(e_sector);\r
        free(keyBlock);\r
        PrintAndLog("");\r
        return 0;\r
 }\r
 \r
+\r
 void readerAttack(nonces_t ar_resp[], bool setEmulatorMem, bool doStandardAttack) {\r
        #define ATTACK_KEY_COUNT 7 // keep same as define in iso14443a.c -> Mifare1ksim()\r
                                                           // cannot be more than 7 or it will overrun c.d.asBytes(512)\r
@@ -1516,8 +1560,11 @@ int CmdHF14AMfSim(const char *Cmd) {
                        break;\r
                case 'u':\r
                case 'U':\r
-                       param_gethex_ex(Cmd, cmdp+1, uid, &uidlen);\r
-                       switch(uidlen) {\r
+                       uidlen = 14;\r
+                       if (param_gethex_ex(Cmd, cmdp+1, uid, &uidlen)) {\r
+                               return usage_hf14_mfsim();\r
+                       }\r
+                       switch (uidlen) {\r
                                case 14: flags = FLAG_7B_UID_IN_DATA; break;\r
                                case  8: flags = FLAG_4B_UID_IN_DATA; break;\r
                                default: return usage_hf14_mfsim();\r
@@ -2726,9 +2773,9 @@ int CmdHF14AMfSniff(const char *Cmd){
 //needs nt, ar, at, Data to decrypt\r
 int CmdDecryptTraceCmds(const char *Cmd){\r
        uint8_t data[50];\r
-       int len = 0;\r
-       param_gethex_ex(Cmd,3,data,&len);\r
-       return tryDecryptWord(param_get32ex(Cmd,0,0,16),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),data,len/2);\r
+       int len = 100;\r
+       param_gethex_ex(Cmd, 3, data, &len);\r
+       return tryDecryptWord(param_get32ex(Cmd, 0, 0, 16), param_get32ex(Cmd, 1, 0, 16), param_get32ex(Cmd, 2, 0, 16), data, len/2);\r
 }\r
 \r
 int CmdHF14AMfAuth4(const char *cmd) {\r
Impressum, Datenschutz