+int CmdHF14AMfCSave(const char *Cmd) {\r
+\r
+ FILE * f;\r
+ char filename[FILE_PATH_SIZE];\r
+ char * fnameptr = filename;\r
+ uint8_t fillFromEmulator = 0;\r
+ uint8_t buf[64];\r
+ int i, j, len, flags;\r
+ \r
+ memset(filename, 0, sizeof(filename));\r
+ memset(buf, 0, sizeof(buf));\r
+ char ctmp = param_getchar(Cmd, 0);\r
+ \r
+ if ( ctmp == 'h' || ctmp == 'H' ) {\r
+ PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");\r
+ PrintAndLog("or into emulator memory (option `e`)");\r
+ PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e]");\r
+ PrintAndLog(" sample: hf mf esave ");\r
+ PrintAndLog(" hf mf esave filename");\r
+ PrintAndLog(" hf mf esave e \n");\r
+ return 0;\r
+ } \r
+ if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;\r
+\r
+ if (fillFromEmulator) {\r
+ // put into emulator\r
+ flags = MAGIC_INIT + MAGIC_WUPC;\r
+ for (i = 0; i < 16 * 4; i++) {\r
+ if (i == 1) flags = 0;\r
+ if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF;\r
+ \r
+ if (mfCGetBlock(i, buf, flags)) {\r
+ PrintAndLog("Cant get block: %d", i);\r
+ break;\r
+ }\r
+ \r
+ if (mfEmlSetMem(buf, i, 1)) {\r
+ PrintAndLog("Cant set emul block: %d", i);\r
+ return 3;\r
+ }\r
+ }\r
+ return 0;\r
+ } else {\r
+ len = strlen(Cmd);\r
+ if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;\r
+ \r
+ // get filename based on UID\r
+ if (len < 1) {\r
+ \r
+ if (mfCGetBlock(0, buf, MAGIC_SINGLE)) {\r
+ PrintAndLog("Cant get block: %d", 0);\r
+ len = sprintf(fnameptr, "dump");\r
+ fnameptr += len;\r
+ } else {\r
+ for (j = 0; j < 7; j++, fnameptr += 2)\r
+ sprintf(fnameptr, "%02x", buf[j]); \r
+ }\r
+ } else {\r
+ memcpy(filename, Cmd, len);\r
+ fnameptr += len;\r
+ }\r
+\r
+ // add .eml extension\r
+ sprintf(fnameptr, ".eml"); \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 = MAGIC_INIT + MAGIC_WUPC;\r
+ for (i = 0; i < 16 * 4; i++) {\r
+ if (i == 1) flags = 0;\r
+ if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF;\r
+ \r
+ if (mfCGetBlock(i, buf, flags)) {\r
+ PrintAndLog("Cant get block: %d", i);\r
+ break;\r
+ }\r
+ for (j = 0; j < 16; j++)\r
+ fprintf(f, "%02x", buf[j]); \r
+ fprintf(f,"\n");\r
+ }\r
+ fflush(f);\r
+ fclose(f);\r
+ PrintAndLog("Saved to file: %s", filename);\r
+ return 0;\r
+ }\r
+}\r
+\r
+//needs nt, ar, at, Data to decrypt\r
+int CmdHf14MfDecryptBytes(const char *Cmd){\r
+ uint8_t data[50];\r
+ uint32_t nt = param_get32ex(Cmd,0,0,16);\r
+ uint32_t ar_enc = param_get32ex(Cmd,1,0,16);\r
+ uint32_t at_enc = param_get32ex(Cmd,2,0,16);\r
+\r
+ int len = 0;\r
+ param_gethex_ex(Cmd, 3, data, &len);\r
+ \r
+ len /= 2; \r
+ int limit = sizeof(data) / 2;\r
+ \r
+ if ( len >= limit )\r
+ len = limit;\r
+ \r
+ return tryDecryptWord( nt, ar_enc, at_enc, data, len);\r
+}\r
+\r
+static command_t CommandTable[] = {\r
+ {"help", CmdHelp, 1, "This help"},\r
+ {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},\r
+ {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},\r
+ {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},\r
+ {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"},\r
+ {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},\r
+ {"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},\r
+ {"chk", CmdHF14AMfChk, 0, "Check keys"},\r
+ {"mifare", CmdHF14AMifare, 0, "Darkside attack. read parity error messages."},\r
+ {"nested", CmdHF14AMfNested, 0, "Nested attack. Test nested authentication"},\r
+ {"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"},\r
+ {"keybrute", CmdHF14AMfKeyBrute, 0, "J_Run's 2nd phase of multiple sector nested authentication key recovery"},\r
+ {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},\r
+ {"sim", CmdHF14AMf1kSim, 0, "Simulate MIFARE card"},\r
+ {"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory block"},\r
+ {"eget", CmdHF14AMfEGet, 0, "Get simulator memory block"},\r
+ {"eset", CmdHF14AMfESet, 0, "Set simulator memory block"},\r
+ {"eload", CmdHF14AMfELoad, 0, "Load from file emul dump"},\r
+ {"esave", CmdHF14AMfESave, 0, "Save to file emul dump"},\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 - 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
+ {"decrypt", CmdHf14MfDecryptBytes, 1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},\r
+ {NULL, NULL, 0, NULL}\r
+};\r
+\r
+int CmdHFMF(const char *Cmd) {\r
+ clearCommandBuffer();\r
+ CmdsParse(CommandTable, Cmd);\r
+ return 0;\r
+}\r
+\r
+int CmdHelp(const char *Cmd) {\r
+ CmdsHelp(CommandTable);\r
+ return 0;\r