+int CmdHF14AMfDump(const char *Cmd)\r
+{\r
+ int i, j;\r
+ \r
+ uint8_t keyA[40][6];\r
+ uint8_t keyB[40][6];\r
+ uint8_t rights[40][4];\r
+ \r
+ FILE *fin;\r
+ FILE *fout;\r
+ \r
+ UsbCommand *resp;\r
+ \r
+ if ((fin = fopen("dumpkeys.bin","rb")) == NULL) {\r
+ PrintAndLog("Could not find file dumpkeys.bin");\r
+ return 1;\r
+ }\r
+ \r
+ if ((fout = fopen("dumpdata.bin","wb")) == NULL) { \r
+ PrintAndLog("Could not create file name dumpdata.bin");\r
+ return 1;\r
+ }\r
+ \r
+ // Read key file\r
+ \r
+ for (i=0 ; i<16 ; i++) {\r
+ fread ( keyA[i], 1, 6, fin );\r
+ }\r
+ for (i=0 ; i<16 ; i++) {\r
+ fread ( keyB[i], 1, 6, fin );\r
+ }\r
+ \r
+ // Read access rights to sectors\r
+ \r
+ PrintAndLog("|-----------------------------------------|");\r
+ PrintAndLog("|------ Reading sector access bits...-----|");\r
+ PrintAndLog("|-----------------------------------------|");\r
+ \r
+ for (i = 0 ; i < 16 ; i++) {\r
+ UsbCommand c = {CMD_MIFARE_READBL, {4*i + 3, 0, 0}};\r
+ memcpy(c.d.asBytes, keyA[i], 6);\r
+ SendCommand(&c);\r
+ resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+\r
+ if (resp != NULL) {\r
+ uint8_t isOK = resp->arg[0] & 0xff;\r
+ uint8_t *data = resp->d.asBytes;\r
+ if (isOK){\r
+ rights[i][0] = ((data[7] & 0x10)>>4) | ((data[8] & 0x1)<<1) | ((data[8] & 0x10)>>2);\r
+ rights[i][1] = ((data[7] & 0x20)>>5) | ((data[8] & 0x2)<<0) | ((data[8] & 0x20)>>3);\r
+ rights[i][2] = ((data[7] & 0x40)>>6) | ((data[8] & 0x4)>>1) | ((data[8] & 0x40)>>4);\r
+ rights[i][3] = ((data[7] & 0x80)>>7) | ((data[8] & 0x8)>>2) | ((data[8] & 0x80)>>5);\r
+ }\r
+ else{\r
+ PrintAndLog("Could not get access rights for block %d", i);\r
+ }\r
+ }\r
+ else {\r
+ PrintAndLog("Command execute timeout");\r
+ }\r
+ }\r
+ \r
+ // Read blocks and print to file\r
+ \r
+ PrintAndLog("|-----------------------------------------|");\r
+ PrintAndLog("|----- Dumping all blocks to file... -----|");\r
+ PrintAndLog("|-----------------------------------------|");\r
+ \r
+ for (i=0 ; i<16 ; i++) {\r
+ for (j=0 ; j<4 ; j++) {\r
+ if (j == 3){\r
+ UsbCommand c = {CMD_MIFARE_READBL, {i*4 + j, 0, 0}};\r
+ memcpy(c.d.asBytes, keyA[i], 6);\r
+ SendCommand(&c);\r
+ resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+ }\r
+ else{\r
+ if ((rights[i][j] == 6) | (rights[i][j] == 5)) {\r
+ UsbCommand c = {CMD_MIFARE_READBL, {i*4+j, 1, 0}};\r
+ memcpy(c.d.asBytes, keyB[i], 6);\r
+ SendCommand(&c);\r
+ resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+ }\r
+ else if (rights[i][j] == 7) {\r
+ PrintAndLog("Access rights do not allow reading of sector %d block %d",i,j);\r
+ }\r
+ else {\r
+ UsbCommand c = {CMD_MIFARE_READBL, {i*4+j, 0, 0}};\r
+ memcpy(c.d.asBytes, keyA[i], 6);\r
+ SendCommand(&c);\r
+ resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+ }\r
+ }\r
+\r
+ if (resp != NULL) {\r
+ uint8_t isOK = resp->arg[0] & 0xff;\r
+ uint8_t *data = resp->d.asBytes;\r
+ if (j == 3) {\r
+ data[0] = (keyA[i][0]);\r
+ data[1] = (keyA[i][1]);\r
+ data[2] = (keyA[i][2]);\r
+ data[3] = (keyA[i][3]);\r
+ data[4] = (keyA[i][4]);\r
+ data[5] = (keyA[i][5]);\r
+ data[10] = (keyB[i][0]);\r
+ data[11] = (keyB[i][1]);\r
+ data[12] = (keyB[i][2]);\r
+ data[13] = (keyB[i][3]);\r
+ data[14] = (keyB[i][4]);\r
+ data[15] = (keyB[i][5]);\r
+ }\r
+ if (isOK) {\r
+ fwrite ( data, 1, 16, fout );\r
+ }\r
+ else {\r
+ PrintAndLog("Could not get access rights for block %d", i);\r
+ }\r
+ }\r
+ else {\r
+ PrintAndLog("Command execute timeout");\r
+ }\r
+ }\r
+ }\r
+ \r
+ fclose(fin);\r
+ fclose(fout);\r
+ \r
+ return 0;\r
+}\r
+\r
+int CmdHF14AMfRestore(const char *Cmd)\r
+{\r
+\r
+ int i,j;\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 keyA[16][6];\r
+ uint8_t keyB[16][6];\r
+ \r
+ FILE *fdump;\r
+ FILE *fkeys;\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
+ return 1;\r
+ }\r
+ \r
+ for (i=0 ; i<16 ; i++) {\r
+ fread(keyA[i], 1, 6, fkeys);\r
+ }\r
+ for (i=0 ; i<16 ; i++) {\r
+ fread(keyB[i], 1, 6, fkeys);\r
+ }\r
+ \r
+ PrintAndLog("Restoring dumpdata.bin to card");\r
+\r
+ for (i=0 ; i<16 ; i++) {\r
+ for( j=0 ; j<4 ; j++) {\r
+ UsbCommand c = {CMD_MIFARE_WRITEBL, {i*4 + j, keyType, 0}};\r
+ memcpy(c.d.asBytes, key, 6);\r
+ \r
+ fread(bldata, 1, 16, fdump);\r
+ \r
+ if (j == 3) {\r
+ bldata[0] = (keyA[i][0]);\r
+ bldata[1] = (keyA[i][1]);\r
+ bldata[2] = (keyA[i][2]);\r
+ bldata[3] = (keyA[i][3]);\r
+ bldata[4] = (keyA[i][4]);\r
+ bldata[5] = (keyA[i][5]);\r
+ bldata[10] = (keyB[i][0]);\r
+ bldata[11] = (keyB[i][1]);\r
+ bldata[12] = (keyB[i][2]);\r
+ bldata[13] = (keyB[i][3]);\r
+ bldata[14] = (keyB[i][4]);\r
+ bldata[15] = (keyB[i][5]);\r
+ } \r
+ \r
+ PrintAndLog("Writing to block %2d: %s", i*4+j, sprint_hex(bldata, 16));\r
+ \r
+ /*\r
+ PrintAndLog("Writing to block %2d: %s Confirm? [Y,N]", i*4+j, sprint_hex(bldata, 16));\r
+ \r
+ scanf("%c",&ch);\r
+ if ((ch != 'y') && (ch != 'Y')){\r
+ PrintAndLog("Aborting !");\r
+ return 1;\r
+ }\r
+ */\r
+ \r
+ memcpy(c.d.asBytes + 10, bldata, 16);\r
+ SendCommand(&c);\r
+ UsbCommand *resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+\r
+ if (resp != NULL) {\r
+ uint8_t isOK = resp->arg[0] & 0xff;\r
+ PrintAndLog("isOk:%02x", isOK);\r
+ } else {\r
+ PrintAndLog("Command execute timeout");\r
+ }\r
+ }\r
+ }\r
+ \r
+ fclose(fdump);\r
+ fclose(fkeys);\r
+ return 0;\r
+}\r
+\r