]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
magic Chinese card fully supported. Added commands:csetuid-set card uid and wipe...
authorMerlokbr@gmail.com <Merlokbr@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Thu, 5 Jul 2012 10:59:15 +0000 (10:59 +0000)
committerMerlokbr@gmail.com <Merlokbr@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Thu, 5 Jul 2012 10:59:15 +0000 (10:59 +0000)
armsrc/mifarecmd.c
client/cmdhfmf.c
client/mifarehost.c
client/mifarehost.h

index 848207309783a82a5e156e1bdc8902c7c8029865..4f4ce64d96dd2f0791ba9748be835a8f29900dcd 100644 (file)
@@ -735,7 +735,12 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
   \r
   // params\r
        uint8_t needWipe = arg0;\r
-       uint8_t needGetUID = arg1;\r
+       // bit 0 - need get UID\r
+       // bit 1 - need wupC\r
+       // bit 2 - need HALT after sequence\r
+       // bit 3 - need init FPGA and field before sequence\r
+       // bit 4 - need reset FPGA and LED\r
+       uint8_t workFlags = arg1;\r
        uint8_t blockNo = arg2;\r
        \r
        // card commands\r
@@ -752,24 +757,26 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
        memset(uid, 0x00, 8);\r
        uint8_t* receivedAnswer = mifare_get_bigbufptr();\r
        \r
-       // clear trace\r
-       iso14a_clear_tracelen();\r
-  iso14a_set_tracing(TRUE);\r
+       if (workFlags & 0x08) {\r
+               // clear trace\r
+               iso14a_clear_tracelen();\r
+               iso14a_set_tracing(TRUE);\r
 \r
-       iso14443a_setup();\r
+               iso14443a_setup();\r
 \r
-       LED_A_ON();\r
-       LED_B_OFF();\r
-       LED_C_OFF();\r
+               LED_A_ON();\r
+               LED_B_OFF();\r
+               LED_C_OFF();\r
        \r
-       SpinDelay(300);\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-       SpinDelay(100);\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
+               SpinDelay(300);\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               SpinDelay(100);\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
+       }\r
 \r
        while (true) {\r
                // get UID from chip\r
-               if (needGetUID) {\r
+               if (workFlags & 0x01) {\r
                        if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
                                break;\r
@@ -802,17 +809,19 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                };      \r
 \r
                // write UID block\r
-               ReaderTransmitShort(wupC1);\r
-               if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("wupC1 error");\r
-                       break;\r
-               };\r
+               if (workFlags & 0x02) {\r
+                       ReaderTransmitShort(wupC1);\r
+                       if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("wupC1 error");\r
+                               break;\r
+                       };\r
 \r
-               ReaderTransmit(wupC2, sizeof(wupC2));\r
-               if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("wupC2 error");\r
-                       break;\r
-               };\r
+                       ReaderTransmit(wupC2, sizeof(wupC2));\r
+                       if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("wupC2 error");\r
+                               break;\r
+                       };\r
+               }\r
 \r
                if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {\r
                        if (MF_DBGLEVEL >= 1)   Dbprintf("write block send command error");\r
@@ -828,10 +837,12 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                        break;\r
                };      \r
        \r
-               if(mifare_classic_halt(NULL, cuid)) {\r
-                       if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
-                       break;\r
-               };\r
+               if (workFlags & 0x04) {\r
+                       if (mifare_classic_halt(NULL, cuid)) {\r
+                               if (MF_DBGLEVEL >= 1)   Dbprintf("Halt error");\r
+                               break;\r
+                       };\r
+               }\r
                \r
                isOK = 1;\r
                break;\r
@@ -848,7 +859,9 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
        UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
        LED_B_OFF();\r
 \r
-  // Thats it...\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-       LEDsoff();\r
+       if (workFlags & 0x10) {\r
+               // Thats it...\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               LEDsoff();\r
+       }\r
 }\r
index 8c91e84cb9f3015510841735467a514a27bffae4..eafb29197592bc7801e6d0433b8eeb3e0ef17964 100644 (file)
@@ -1282,7 +1282,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
 \r
        PrintAndLog("--block number:%02x data:%s", blockNo, sprint_hex(memBlock, 16));\r
 \r
-       res = mfCSetBlock(blockNo, memBlock, uid, 0);\r
+       res = mfCSetBlock(blockNo, memBlock, uid, 0, CSETBLOCK_SINGLE_OPER);\r
        if (res) {\r
                        PrintAndLog("Can't write block. error=%d", res);\r
                        return 1;\r
@@ -1294,7 +1294,97 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
 \r
 int CmdHF14AMfCLoad(const char *Cmd)\r
 {\r
-       return 0;\r
+       FILE * f;\r
+       char filename[20];\r
+       char * fnameptr = filename;\r
+       char buf[64];\r
+       uint8_t buf8[64];\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
+\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
+               PrintAndLog("or from emulator memory (option `e`)");\r
+               PrintAndLog("Usage:  hf mf cload <file name w/o `.eml`>");\r
+               PrintAndLog("   or:  hf mf cload e ");\r
+               PrintAndLog(" sample: hf mf cload filename");\r
+               return 0;\r
+       }       \r
+\r
+       char ctmp = param_getchar(Cmd, 0);\r
+       if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;\r
+       \r
+       if (fillFromEmulator) {\r
+               flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;\r
+               for (blockNum = 0; blockNum < 16 * 4; blockNum += 1) {\r
+                       if (mfEmlGetMem(buf8, blockNum, 1)) {\r
+                               PrintAndLog("Cant get block: %d", blockNum);\r
+                               return 2;\r
+                       }\r
+                       \r
+                       if (blockNum == 2) flags = 0;\r
+                       if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;\r
+\r
+                       if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {\r
+                               PrintAndLog("Cant set magic card block: %d", blockNum);\r
+                               return 3;\r
+                       }\r
+               }\r
+               return 0;\r
+       } else {\r
+               len = strlen(Cmd);\r
+               if (len > 14) len = 14;\r
+\r
+               memcpy(filename, Cmd, len);\r
+               fnameptr += len;\r
+\r
+               sprintf(fnameptr, ".eml"); \r
+       \r
+               // open file\r
+               f = fopen(filename, "r");\r
+               if (f == NULL) {\r
+                       PrintAndLog("File not found or locked.");\r
+                       return 1;\r
+               }\r
+       \r
+               blockNum = 0;\r
+               flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;\r
+               while(!feof(f)){\r
+                       memset(buf, 0, sizeof(buf));\r
+                       fgets(buf, sizeof(buf), f);\r
+\r
+                       if (strlen(buf) < 32){\r
+                               if(strlen(buf) && feof(f))\r
+                                       break;\r
+                               PrintAndLog("File content error. Block data must include 32 HEX symbols");\r
+                               return 2;\r
+                       }\r
+                       for (i = 0; i < 32; i += 2)\r
+                               sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);\r
+\r
+                       if (blockNum == 2) flags = 0;\r
+                       if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;\r
+\r
+                       if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {\r
+                               PrintAndLog("Cant set magic card block: %d", blockNum);\r
+                               return 3;\r
+                       }\r
+                       blockNum++;\r
+               \r
+                       if (blockNum >= 16 * 4) break;  // magic card type - mifare 1K\r
+               }\r
+               fclose(f);\r
+       \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("Loaded from file: %s", filename);\r
+               return 0;\r
+       }\r
 }\r
 \r
 static command_t CommandTable[] =\r
@@ -1319,7 +1409,7 @@ static command_t CommandTable[] =
   {"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
-  {"cload",            CmdHF14AMfCLoad,                0, "(n/a)Load dump into magic Chinese card"},\r
+  {"cload",            CmdHF14AMfCLoad,                0, "Load dump into magic Chinese card"},\r
   {NULL, NULL, 0, NULL}\r
 };\r
 \r
index 2ce0b5e2c02188e501752b42b49f8679adbdbd9a..399f494a93ef3e940589279713df7553c6a6fd7e 100644 (file)
@@ -222,13 +222,13 @@ int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe) {
        memcpy(block0, uid, 4); \r
        block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC\r
        \r
-       return mfCSetBlock(0, block0, oldUID, wantWipe);\r
+       return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);\r
 }\r
 \r
-int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe) {\r
+int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint8_t params) {\r
        uint8_t isOK = 0;\r
 \r
-  UsbCommand c = {CMD_MIFARE_EML_CSETBLOCK, {wantWipe, 1, blockNo}};\r
+  UsbCommand c = {CMD_MIFARE_EML_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};\r
        memcpy(c.d.asBytes, data, 16); \r
   SendCommand(&c);\r
 \r
@@ -236,8 +236,7 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe) {
 \r
        if (resp != NULL) {\r
                isOK  = resp->arg[0] & 0xff;\r
-               PrintAndLog("isOk:%02x", isOK);\r
-               memcpy(uid, resp->d.asBytes, 4); \r
+               if (uid != NULL) memcpy(uid, resp->d.asBytes, 4); \r
                if (!isOK) return 2;\r
        } else {\r
                PrintAndLog("Command execute timeout");\r
index 4a107fd0cba0f39aa76539989eb4212636150a3e..1d6e0bec8196593bd6e5459f5396bdeb38803bd7 100644 (file)
 #define MEM_CHUNK               1000000\r
 #define NESTED_SECTOR_RETRY     10\r
 \r
+// mfCSetBlock work flags\r
+#define CSETBLOCK_UID                                  0x01\r
+#define CSETBLOCK_WUPC                                 0x02\r
+#define CSETBLOCK_HALT                                 0x04\r
+#define CSETBLOCK_INIT_FIELD           0x08\r
+#define CSETBLOCK_RESET_FIELD          0x10\r
+#define CSETBLOCK_SINGLE_OPER          0x1F\r
+\r
 typedef struct fnVector { uint8_t blockNo, keyType; uint32_t uid, nt, ks1; } fnVector;\r
 \r
 typedef struct {\r
@@ -45,5 +53,5 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * key
 int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);\r
 int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);\r
 int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe);\r
-int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe);\r
+int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint8_t params);\r
 \r
Impressum, Datenschutz