+ PrintAndLog("Couldn't get old data. Will write over the last bytes of Block 0.");\r
+ }\r
+\r
+ // fill in the new values\r
+ // UID\r
+ memcpy(block0, uid, 4);\r
+ // Mifare UID BCC\r
+ block0[4] = block0[0] ^ block0[1] ^ block0[2] ^ block0[3];\r
+ // mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)\r
+ if (sak != NULL)\r
+ block0[5] = sak[0];\r
+ if (atqa != NULL) {\r
+ block0[6] = atqa[1];\r
+ block0[7] = atqa[0];\r
+ }\r
+ PrintAndLog("new block 0: %s", sprint_hex(block0, 16));\r
+\r
+ res = mfCSetBlock(0, block0, oldUID, false, cmdParams);\r
+ if (res) {\r
+ PrintAndLog("Can't set block 0. Error: %d", res);\r
+ return res;\r
+ }\r
+ \r
+ return 0;\r
+}\r
+\r
+int mfCIdentify()\r
+{\r
+ UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};\r
+ SendCommand(&c);\r
+\r
+ UsbCommand resp;\r
+ WaitForResponse(CMD_ACK,&resp);\r
+\r
+ // iso14a_card_select_t card;\r
+ // memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));\r
+\r
+ // uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision\r
+\r
+ // if(select_status != 0) {\r
+ // uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0\r
+ // c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT;\r
+ // c.arg[1] = 2;\r
+ // c.arg[2] = 0;\r
+ // memcpy(c.d.asBytes, rats, 2);\r
+ // SendCommand(&c);\r
+ // WaitForResponse(CMD_ACK,&resp);\r
+ // }\r
+\r
+ c.cmd = CMD_MIFARE_CIDENT;\r
+ c.arg[0] = 0;\r
+ c.arg[1] = 0;\r
+ c.arg[2] = 0;\r
+ SendCommand(&c);\r
+ WaitForResponse(CMD_ACK,&resp);\r
+\r
+ uint8_t isGeneration = resp.arg[0] & 0xff;\r
+ switch( isGeneration ){\r
+ case 1: PrintAndLog("Chinese magic backdoor commands (GEN 1a) detected"); break;\r
+ case 2: PrintAndLog("Chinese magic backdoor command (GEN 1b) detected"); break;\r
+ default: PrintAndLog("No chinese magic backdoor command detected"); break;\r
+ }\r
+\r
+ // disconnect\r
+ c.cmd = CMD_READER_ISO_14443a;\r
+ c.arg[0] = 0;\r
+ c.arg[1] = 0;\r
+ c.arg[2] = 0;\r
+ SendCommand(&c);\r
+\r
+ return (int) isGeneration;\r
+}\r
+\r
+\r
+// SNIFFER\r
+\r
+// constants\r
+static uint8_t trailerAccessBytes[4] = {0x08, 0x77, 0x8F, 0x00};\r
+\r
+// variables\r
+char logHexFileName[FILE_PATH_SIZE] = {0x00};\r
+static uint8_t traceCard[4096] = {0x00};\r
+static char traceFileName[FILE_PATH_SIZE] = {0x00};\r
+static int traceState = TRACE_IDLE;\r
+static uint8_t traceCurBlock = 0;\r
+static uint8_t traceCurKey = 0;\r
+\r
+struct Crypto1State *traceCrypto1 = NULL;\r
+\r
+struct Crypto1State *revstate;\r
+uint64_t lfsr;\r
+uint32_t ks2;\r
+uint32_t ks3;\r
+\r
+uint32_t uid; // serial number\r
+uint32_t nt; // tag challenge\r
+uint32_t nr_enc; // encrypted reader challenge\r
+uint32_t ar_enc; // encrypted reader response\r
+uint32_t at_enc; // encrypted tag response\r
+\r
+int isTraceCardEmpty(void) {\r
+ return ((traceCard[0] == 0) && (traceCard[1] == 0) && (traceCard[2] == 0) && (traceCard[3] == 0));\r
+}\r
+\r
+int isBlockEmpty(int blockN) {\r
+ for (int i = 0; i < 16; i++)\r
+ if (traceCard[blockN * 16 + i] != 0) return 0;\r
+\r
+ return 1;\r
+}\r
+\r
+int isBlockTrailer(int blockN) {\r
+ return ((blockN & 0x03) == 0x03);\r
+}\r
+\r
+int saveTraceCard(void) {\r
+ FILE * f;\r
+\r
+ if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0;\r
+\r
+ f = fopen(traceFileName, "w+");\r
+ if ( !f ) return 1;\r
+\r
+ for (int i = 0; i < 64; i++) { // blocks\r
+ for (int j = 0; j < 16; j++) // bytes\r
+ fprintf(f, "%02x", *(traceCard + i * 16 + j));\r
+ fprintf(f,"\n");\r
+ }\r
+ fclose(f);\r
+ return 0;\r
+}\r
+\r
+int loadTraceCard(uint8_t *tuid) {\r
+ FILE * f;\r
+ char buf[64] = {0x00};\r
+ uint8_t buf8[64] = {0x00};\r
+ int i, blockNum;\r
+\r
+ if (!isTraceCardEmpty())\r
+ saveTraceCard();\r
+\r
+ memset(traceCard, 0x00, 4096);\r
+ memcpy(traceCard, tuid + 3, 4);\r
+\r
+ FillFileNameByUID(traceFileName, tuid, ".eml", 7);\r
+\r
+ f = fopen(traceFileName, "r");\r
+ if (!f) return 1;\r
+\r
+ blockNum = 0;\r
+\r
+ while(!feof(f)){\r
+\r
+ memset(buf, 0, sizeof(buf));\r
+ if (fgets(buf, sizeof(buf), f) == NULL) {\r
+ PrintAndLog("File reading error.");\r
+ fclose(f);\r
+ return 2;\r
+ }\r
+\r
+ if (strlen(buf) < 32){\r
+ if (feof(f)) break;\r
+ PrintAndLog("File content error. Block data must include 32 HEX symbols");\r
+ fclose(f);\r
+ return 2;\r
+ }\r
+ for (i = 0; i < 32; i += 2)\r
+ sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);\r
+\r
+ memcpy(traceCard + blockNum * 16, buf8, 16);\r
+\r
+ blockNum++;\r
+ }\r
+ fclose(f);\r
+\r
+ return 0;\r
+}\r
+\r
+int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) {\r
+\r
+ if (traceCrypto1)\r
+ crypto1_destroy(traceCrypto1);\r
+\r
+ traceCrypto1 = NULL;\r
+\r
+ if (wantSaveToEmlFile)\r
+ loadTraceCard(tuid);\r
+\r
+ traceCard[4] = traceCard[0] ^ traceCard[1] ^ traceCard[2] ^ traceCard[3];\r
+ traceCard[5] = sak;\r
+ memcpy(&traceCard[6], atqa, 2);\r
+ traceCurBlock = 0;\r
+ uid = bytes_to_num(tuid + 3, 4);\r
+\r
+ traceState = TRACE_IDLE;\r
+\r
+ return 0;\r
+}\r
+\r
+void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted){\r
+ uint8_t bt = 0;\r
+ int i;\r
+\r
+ if (len != 1) {\r
+ for (i = 0; i < len; i++)\r
+ data[i] = crypto1_byte(pcs, 0x00, isEncrypted) ^ data[i];\r
+ } else {\r
+ bt = 0;\r
+ for (i = 0; i < 4; i++)\r
+ bt |= (crypto1_bit(pcs, 0, isEncrypted) ^ BIT(data[0], i)) << i;\r
+\r
+ data[0] = bt;\r
+ }\r
+ return;\r
+}\r
+\r
+\r
+int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {\r
+ uint8_t data[64];\r
+\r
+ if (traceState == TRACE_ERROR) return 1;\r
+ if (len > 64) {\r
+ traceState = TRACE_ERROR;\r