X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/f5ed4d12de19dcf59a3d5ecdcd9f75f5c747dd3e..593fc3c9a334aec3a21d289cec9c8f760239c058:/client/cmdhfmf.c?ds=sidebyside

diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c
index 748e9c45..1b815326 100644
--- a/client/cmdhfmf.c
+++ b/client/cmdhfmf.c
@@ -7,7 +7,7 @@
 //-----------------------------------------------------------------------------
 // High frequency MIFARE commands
 //-----------------------------------------------------------------------------
-#include "../include/mifare.h"
+
 #include "cmdhfmf.h"
 
 static int CmdHelp(const char *Cmd);
@@ -34,7 +34,7 @@ start:
     SendCommand(&c);
 	
 	//flush queue
-	while (ukbhit()) getchar();
+	while (ukbhit())	getchar();
 
 	// wait cycle
 	while (true) {
@@ -71,14 +71,14 @@ start:
 		PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);	
 	} else {
 		printf("------------------------------------------------------------------\n");
-		PrintAndLog("Key found :%012"llx" \n", r_key);
+		PrintAndLog("Key found:%012"llx" \n", r_key);
 
 		num_to_bytes(r_key, 6, keyBlock);
 		isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key);
 	}
 	
 	if (!isOK) 
-		PrintAndLog("Found valid key :%012"llx, r_key);
+		PrintAndLog("Found valid key:%012"llx, r_key);
 	else
 	{
 		if (isOK != 2) PrintAndLog("Found invalid key. ");	
@@ -278,14 +278,7 @@ int CmdHF14AMfDump(const char *Cmd)
 	
 	UsbCommand resp;
 
-	int size = GetCardSize();		
 	char cmdp = param_getchar(Cmd, 0);
-
-	if  ( size > -1) 
-		cmdp = (char)(48+size);
-
-	PrintAndLog("Got %d",cmdp);
-		
 	switch (cmdp) {
 		case '0' : numSectors = 5; break;
 		case '1' : 
@@ -305,7 +298,7 @@ int CmdHF14AMfDump(const char *Cmd)
 	}
 	
 	if ((fin = fopen("dumpkeys.bin","rb")) == NULL) {
-		PrintAndLog("Could not find file dumpkeys.bin");		
+		PrintAndLog("Could not find file dumpkeys.bin");
 		return 1;
 	}
 	
@@ -328,7 +321,7 @@ int CmdHF14AMfDump(const char *Cmd)
 	}
 	
 	fclose(fin);
-	
+
 	PrintAndLog("|-----------------------------------------|");
 	PrintAndLog("|------ Reading sector access bits...-----|");
 	PrintAndLog("|-----------------------------------------|");
@@ -381,12 +374,12 @@ int CmdHF14AMfDump(const char *Cmd)
 					received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
 				} else if (rights[sectorNo][data_area] == 0x07) {										// no key would work
 					isOK = false;
-						PrintAndLog("Access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo);
+					PrintAndLog("Access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo);
 				} else {																				// key A would work
-						UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}};
-						memcpy(c.d.asBytes, keyA[sectorNo], 6);
-						SendCommand(&c);
-						received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
+					UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}};
+					memcpy(c.d.asBytes, keyA[sectorNo], 6);
+					SendCommand(&c);
+					received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
 				}
 			}
 
@@ -433,7 +426,7 @@ int CmdHF14AMfDump(const char *Cmd)
 		fclose(fout);
 		PrintAndLog("Dumped %d blocks (%d bytes) to file dumpdata.bin", numblocks, 16*numblocks);
 	}
-	
+		
 	return 0;
 }
 
@@ -441,7 +434,7 @@ int CmdHF14AMfRestore(const char *Cmd)
 {
 	uint8_t sectorNo,blockNo;
 	uint8_t keyType = 0;
-	uint8_t key[6] = {0xFF};
+	uint8_t key[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
 	uint8_t bldata[16] = {0x00};
 	uint8_t keyA[40][6];
 	uint8_t keyB[40][6];
@@ -460,7 +453,7 @@ int CmdHF14AMfRestore(const char *Cmd)
 		default:   numSectors = 16;
 	}	
 
-	if (cmdp == 'h' || cmdp == 'H') {
+	if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {
 		PrintAndLog("Usage:   hf mf restore [card memory]");
 		PrintAndLog("  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
 		PrintAndLog("");
@@ -468,7 +461,7 @@ int CmdHF14AMfRestore(const char *Cmd)
 		PrintAndLog("         hf mf restore 4");
 		return 0;
 	}
-	
+
 	if ((fkeys = fopen("dumpkeys.bin","rb")) == NULL) {
 		PrintAndLog("Could not find file dumpkeys.bin");
 		return 1;
@@ -477,6 +470,8 @@ int CmdHF14AMfRestore(const char *Cmd)
 	for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
 		if (fread(keyA[sectorNo], 1, 6, fkeys) == 0) {
 			PrintAndLog("File reading error (dumpkeys.bin).");
+
+			fclose(fkeys);
 			return 2;
 		}
 	}
@@ -484,12 +479,13 @@ int CmdHF14AMfRestore(const char *Cmd)
 	for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
 		if (fread(keyB[sectorNo], 1, 6, fkeys) == 0) {
 			PrintAndLog("File reading error (dumpkeys.bin).");
+			fclose(fkeys);
 			return 2;
 		}
 	}
 
 	fclose(fkeys);
-	
+
 	if ((fdump = fopen("dumpdata.bin","rb")) == NULL) {
 		PrintAndLog("Could not find file dumpdata.bin");
 		return 1;
@@ -551,7 +547,7 @@ int CmdHF14AMfNested(const char *Cmd)
 	uint8_t trgKeyType = 0;
 	uint8_t SectorsCnt = 0;
 	uint8_t key[6] = {0, 0, 0, 0, 0, 0};
-	uint8_t keyBlock[13*6];
+	uint8_t keyBlock[14*6];
 	uint64_t key64 = 0;
 	bool transferToEml = false;
 	
@@ -697,13 +693,6 @@ int CmdHF14AMfNested(const char *Cmd)
 		bool calibrate = true;
 		for (i = 0; i < NESTED_SECTOR_RETRY; i++) {
 			for (uint8_t sectorNo = 0; sectorNo < SectorsCnt; sectorNo++) {
-
-				if (ukbhit()) {
-					printf("\naborted via keyboard!\n");
-					free(e_sector);
-					return 2;
-				}			
-			
 				for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) { 
 					if (e_sector[sectorNo].foundKey[trgKeyType]) continue;
 					PrintAndLog("-----------------------------------------------");
@@ -780,7 +769,7 @@ int CmdHF14AMfNested(const char *Cmd)
 			}
 			fclose(fkeys);
 		}
-
+		
 		free(e_sector);
 	}
 	return 0;
@@ -792,14 +781,14 @@ int CmdHF14AMfChk(const char *Cmd)
 		PrintAndLog("Usage:  hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t|d] [<key (12 hex symbols)>] [<dic (*.dic)>]");
 		PrintAndLog("          * - all sectors");
 		PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
-		PrintAndLog("d - write keys to binary file\n");
-		PrintAndLog("t - write keys to emulator memory");
+		PrintAndLog("d - write keys to binary file");
+		PrintAndLog("t - write keys to emulator memory\n");
 		PrintAndLog("      sample: hf mf chk 0 A 1234567890ab keys.dic");
 		PrintAndLog("              hf mf chk *1 ? t");
 		PrintAndLog("              hf mf chk *1 ? d");
 		return 0;
-	}
-	
+	}	
+
 	FILE * f;
 	char filename[FILE_PATH_SIZE]={0};
 	char buf[13];
@@ -944,8 +933,8 @@ int CmdHF14AMfChk(const char *Cmd)
 		PrintAndLog("No key specified, trying default keys");
 		for (;keycnt < defaultKeysSize; keycnt++)
 			PrintAndLog("chk default key[%2d] %02x%02x%02x%02x%02x%02x", keycnt,
-			(keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],
-			(keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4],	(keyBlock + 6*keycnt)[5], 6);
+				(keyBlock + 6*keycnt)[0],(keyBlock + 6*keycnt)[1], (keyBlock + 6*keycnt)[2],
+				(keyBlock + 6*keycnt)[3], (keyBlock + 6*keycnt)[4],	(keyBlock + 6*keycnt)[5], 6);
 	}
 	
 	// initialize storage for found keys
@@ -990,13 +979,13 @@ int CmdHF14AMfChk(const char *Cmd)
 				for (uint16_t t = 0; t < 2; t++) {
 					if (validKey[t][sectorNo]) {
 						memcpy(block + t*10, foundKey[t][sectorNo], 6);
-		}
-			}
+					}
+				}
 				mfEmlSetMem(block, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
 			}
 		}
 		PrintAndLog("Found keys have been transferred to the emulator memory");
-			}
+	}
 
 	if (createDumpFile) {
 		FILE *fkeys = fopen("dumpkeys.bin","wb");
@@ -1004,7 +993,7 @@ int CmdHF14AMfChk(const char *Cmd)
 			PrintAndLog("Could not create file dumpkeys.bin");
 			free(keyBlock);
 			return 1;
-			}
+		}
 		for (uint16_t t = 0; t < 2; t++) {
 			fwrite(foundKey[t], 1, 6*SectorsCnt, fkeys);
 		}
@@ -1014,7 +1003,7 @@ int CmdHF14AMfChk(const char *Cmd)
 
 	free(keyBlock);
 	PrintAndLog("");
-  return 0;
+	return 0;
 }
 
 int CmdHF14AMf1kSim(const char *Cmd)
@@ -1023,12 +1012,16 @@ int CmdHF14AMf1kSim(const char *Cmd)
 	uint8_t exitAfterNReads = 0;
 	uint8_t flags = 0;
 
-	if (param_getchar(Cmd, 0) == 'h') {
+	uint8_t cmdp = param_getchar(Cmd, 0);
+	
+	if (cmdp == 'h' || cmdp == 'H') {
 		PrintAndLog("Usage:  hf mf sim  u <uid (8 hex symbols)> n <numreads> i x");
+		PrintAndLog("           h    this help");
 		PrintAndLog("           u    (Optional) UID. If not specified, the UID from emulator memory will be used");
 		PrintAndLog("           n    (Optional) Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite");
 		PrintAndLog("           i    (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted");
 		PrintAndLog("           x    (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)");
+		PrintAndLog("");
 		PrintAndLog("           sample: hf mf sim u 0a0a0a0a ");
 		return 0;
 	}
@@ -1109,7 +1102,7 @@ int CmdHF14AMfDbg(const char *Cmd)
 int CmdHF14AMfEGet(const char *Cmd)
 {
 	uint8_t blockNo = 0;
-	uint8_t data[16];
+	uint8_t data[16] = {0x00};
 
 	if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
 		PrintAndLog("Usage:  hf mf eget <block number>");
@@ -1176,14 +1169,11 @@ int CmdHF14AMfELoad(const char *Cmd)
 	FILE * f;
 	char filename[FILE_PATH_SIZE];
 	char *fnameptr = filename;
-	char buf[64];
-	uint8_t buf8[64];
+	char buf[64] = {0x00};
+	uint8_t buf8[64] = {0x00};
 	int i, len, blockNum, numBlocks;
 	int nameParamNo = 1;
 	
-	memset(filename, 0, sizeof(filename));
-	memset(buf, 0, sizeof(buf));
-
 	char ctmp = param_getchar(Cmd, 0);
 		
 	if ( ctmp == 'h' || ctmp == 0x00) {
@@ -1212,7 +1202,7 @@ int CmdHF14AMfELoad(const char *Cmd)
 	
 	if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
 
-	fnameptr += len;
+	fnameptr += len-4;
 
 	sprintf(fnameptr, ".eml"); 
 	
@@ -1223,9 +1213,6 @@ int CmdHF14AMfELoad(const char *Cmd)
 		return 1;
 	}
 	
-//		for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
-//		for(blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
-	
 	blockNum = 0;
 	while(!feof(f)){
 		memset(buf, 0, sizeof(buf));
@@ -1243,6 +1230,7 @@ int CmdHF14AMfELoad(const char *Cmd)
 			if(strlen(buf) && feof(f))
 				break;
 			PrintAndLog("File content error. Block data must include 32 HEX symbols");
+			fclose(f);
 			return 2;
 		}
 		
@@ -1252,17 +1240,19 @@ int CmdHF14AMfELoad(const char *Cmd)
 		
 		if (mfEmlSetMem(buf8, blockNum, 1)) {
 			PrintAndLog("Cant set emul block: %3d", blockNum);
+			fclose(f);
 			return 3;
 		}
+		printf(".");
 		blockNum++;
 		
 		if (blockNum >= numBlocks) break;
 	}
 	fclose(f);
+	printf("\n");
 	
 	if ((blockNum != numBlocks)) {
 		PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);
-		fclose(f);
 		return 4;
 	}
 	PrintAndLog("Loaded %d blocks from file: %s", blockNum, filename);
@@ -1284,8 +1274,8 @@ int CmdHF14AMfESave(const char *Cmd)
 
 	char ctmp = param_getchar(Cmd, 0);
 	
-	if ( ctmp == 'h') {
-		PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`");		
+	if ( ctmp == 'h' || ctmp == 'H') {
+		PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`");
 		PrintAndLog(" Usage:  hf mf esave [card memory] [file name w/o `.eml`]");
 		PrintAndLog("  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
 		PrintAndLog("");
@@ -1294,7 +1284,7 @@ int CmdHF14AMfESave(const char *Cmd)
 		PrintAndLog("         hf mf esave 4 filename");
 		return 0;
 	}	
-	
+
 	switch (ctmp) {
 		case '0' : numBlocks = 5*4; break;
 		case '1' : 
@@ -1321,7 +1311,7 @@ int CmdHF14AMfESave(const char *Cmd)
 		for (j = 0; j < 7; j++, fnameptr += 2)
 			sprintf(fnameptr, "%02X", buf[j]); 
 	} else {
-		fnameptr += len;
+		fnameptr += len-4;
 	}
 
 	// add file extension
@@ -1330,6 +1320,11 @@ int CmdHF14AMfESave(const char *Cmd)
 	// open file
 	f = fopen(filename, "w+");
 
+	if ( !f ) {
+		PrintAndLog("Can't open file %s ", filename);
+		return 1;
+	}
+	
 	// put hex
 	for (i = 0; i < numBlocks; i++) {
 		if (mfEmlGetMem(buf, i, 1)) {
@@ -1438,49 +1433,82 @@ int CmdHF14AMfCSetUID(const char *Cmd)
 	uint8_t wipeCard = 0;
 	uint8_t uid[8] = {0x00};
 	uint8_t oldUid[8] = {0x00};
+	uint8_t atqa[2] = {0x00};
+	uint8_t sak[1] = {0x00};
+	uint8_t atqaPresent = 1;
 	int res;
-
-	if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
-		PrintAndLog("Usage:  hf mf csetuid <UID 8 hex symbols> <w>");
-		PrintAndLog("sample:  hf mf csetuid 01020304 w");
-		PrintAndLog("Set UID for magic Chinese card (only works with!!!)");
-		PrintAndLog("If you want wipe card then add 'w' into command line. \n");
+	char ctmp;
+	int argi=0;
+
+	if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h') {
+		PrintAndLog("Usage:  hf mf csetuid <UID 8 hex symbols> [ATQA 4 hex symbols SAK 2 hex symbols] [w]");
+		PrintAndLog("sample:  hf mf csetuid 01020304");
+		PrintAndLog("sample:  hf mf csetuid 01020304 0004 08 w");
+		PrintAndLog("Set UID, ATQA, and SAK for magic Chinese card (only works with such cards)");
+		PrintAndLog("If you also want to wipe the card then add 'w' at the end of the command line.");
 		return 0;
-	}	
+	}
 
-	if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 8)) {
+	if (param_getchar(Cmd, argi) && param_gethex(Cmd, argi, uid, 8)) {
 		PrintAndLog("UID must include 8 HEX symbols");
 		return 1;
 	}
+	argi++;
 
-	char ctmp = param_getchar(Cmd, 1);
-	if (ctmp == 'w' || ctmp == 'W') wipeCard = 1;
-	
-	PrintAndLog("--wipe card:%02x uid:%s", wipeCard, sprint_hex(uid, 4));
+	ctmp = param_getchar(Cmd, argi);
+	if (ctmp == 'w' || ctmp == 'W') {
+		wipeCard = 1;
+		atqaPresent = 0;
+	}
 
-	res = mfCSetUID(uid, oldUid, wipeCard);
+	if (atqaPresent) {
+		if (param_getchar(Cmd, argi)) {
+			if (param_gethex(Cmd, argi, atqa, 4)) {
+				PrintAndLog("ATQA must include 4 HEX symbols");
+				return 1;
+			}
+			argi++;
+			if (!param_getchar(Cmd, argi) || param_gethex(Cmd, argi, sak, 2)) {
+				PrintAndLog("SAK must include 2 HEX symbols");
+				return 1;
+			}
+			argi++;
+		} else
+			atqaPresent = 0;
+	}
+
+	if(!wipeCard) {
+		ctmp = param_getchar(Cmd, argi);
+		if (ctmp == 'w' || ctmp == 'W') {
+			wipeCard = 1;
+		}
+	}
+
+	PrintAndLog("--wipe card:%s  uid:%s", (wipeCard)?"YES":"NO", sprint_hex(uid, 4));
+
+	res = mfCSetUID(uid, (atqaPresent)?atqa:NULL, (atqaPresent)?sak:NULL, oldUid, wipeCard);
 	if (res) {
 			PrintAndLog("Can't set UID. error=%d", res);
 			return 1;
 		}
 	
 	PrintAndLog("old UID:%s", sprint_hex(oldUid, 4));
+	PrintAndLog("new UID:%s", sprint_hex(uid, 4));
 	return 0;
 }
 
 int CmdHF14AMfCSetBlk(const char *Cmd)
 {
-	uint8_t uid[8];
-	uint8_t memBlock[16];
+	uint8_t memBlock[16] = {0x00};
 	uint8_t blockNo = 0;
+	bool wipeCard = FALSE;
 	int res;
-	memset(memBlock, 0x00, sizeof(memBlock));
 
 	if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
-		PrintAndLog("Usage:  hf mf csetblk <block number> <block data (32 hex symbols)>");
+		PrintAndLog("Usage:  hf mf csetblk <block number> <block data (32 hex symbols)> [w]");
 		PrintAndLog("sample:  hf mf csetblk 1 01020304050607080910111213141516");
-		PrintAndLog("Set block data for magic Chinese card (only works with!!!)");
-		PrintAndLog("If you want wipe card then add 'w' into command line. \n");
+		PrintAndLog("Set block data for magic Chinese card (only works with such cards)");
+		PrintAndLog("If you also want wipe the card then add 'w' at the end of the command line");
 		return 0;
 	}	
 
@@ -1491,15 +1519,15 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
 		return 1;
 	}
 
+	char ctmp = param_getchar(Cmd, 2);
+	wipeCard = (ctmp == 'w' || ctmp == 'W');
 	PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16));
 
-	res = mfCSetBlock(blockNo, memBlock, uid, 0, CSETBLOCK_SINGLE_OPER);
+	res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER);
 	if (res) {
-			PrintAndLog("Can't write block. error=%d", res);
-			return 1;
-		}
-	
-	PrintAndLog("UID:%s", sprint_hex(uid, 4));
+		PrintAndLog("Can't write block. error=%d", res);
+		return 1;
+	}
 	return 0;
 }
 
@@ -1507,18 +1535,15 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
 int CmdHF14AMfCLoad(const char *Cmd)
 {
 	FILE * f;
-	char filename[FILE_PATH_SIZE];
+	char filename[FILE_PATH_SIZE] = {0x00};
 	char * fnameptr = filename;
-	char buf[64];
-	uint8_t buf8[64];
+	char buf[64] = {0x00};
+	uint8_t buf8[64] = {0x00};
 	uint8_t fillFromEmulator = 0;
-	int i, len, blockNum, flags;
+	int i, len, blockNum, flags=0;
 	
-	memset(filename, 0, sizeof(filename));
-	memset(buf, 0, sizeof(buf));
-
 	if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
-		PrintAndLog("It loads magic Chinese card (only works with!!!) from the file `filename.eml`");
+		PrintAndLog("It loads magic Chinese card from the file `filename.eml`");
 		PrintAndLog("or from emulator memory (option `e`)");
 		PrintAndLog("Usage:  hf mf cload <file name w/o `.eml`>");
 		PrintAndLog("   or:  hf mf cload e ");
@@ -1530,15 +1555,14 @@ int CmdHF14AMfCLoad(const char *Cmd)
 	if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
 	
 	if (fillFromEmulator) {
-		flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
 		for (blockNum = 0; blockNum < 16 * 4; blockNum += 1) {
 			if (mfEmlGetMem(buf8, blockNum, 1)) {
 				PrintAndLog("Cant get block: %d", blockNum);
 				return 2;
 			}
-			
-			if (blockNum == 2) flags = 0;
-			if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
+			if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;				// switch on field and send magic sequence
+			if (blockNum == 1) flags = 0;													// just write
+			if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;		// Done. Magic Halt and switch off field.
 
 			if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
 				PrintAndLog("Cant set magic card block: %d", blockNum);
@@ -1551,7 +1575,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
 		if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
 
 		memcpy(filename, Cmd, len);
-		fnameptr += len;
+		fnameptr += len-4;
 
 		sprintf(fnameptr, ".eml"); 
 	
@@ -1563,25 +1587,29 @@ int CmdHF14AMfCLoad(const char *Cmd)
 		}
 	
 		blockNum = 0;
-		flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
 		while(!feof(f)){
+		
 			memset(buf, 0, sizeof(buf));
+			
 			if (fgets(buf, sizeof(buf), f) == NULL) {
 				PrintAndLog("File reading error.");
+				fclose(f);
 				return 2;
 			}
 
-			if (strlen(buf) < 32){
+			if (strlen(buf) < 32) {
 				if(strlen(buf) && feof(f))
 					break;
 				PrintAndLog("File content error. Block data must include 32 HEX symbols");
+				fclose(f);
 				return 2;
 			}
 			for (i = 0; i < 32; i += 2)
 				sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
 
-			if (blockNum == 2) flags = 0;
-			if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
+			if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;				// switch on field and send magic sequence
+			if (blockNum == 1) flags = 0;													// just write
+			if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;		// Done. Switch off field.
 
 			if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
 				PrintAndLog("Can't set magic card block: %d", blockNum);
@@ -1600,6 +1628,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
 		PrintAndLog("Loaded from file: %s", filename);
 		return 0;
 	}
+	return 0;
 }
 
 int CmdHF14AMfCGetBlk(const char *Cmd) {
@@ -1611,7 +1640,7 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
 	if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
 		PrintAndLog("Usage:  hf mf cgetblk <block number>");
 		PrintAndLog("sample:  hf mf cgetblk 1");
-		PrintAndLog("Get block data from magic Chinese card (only works with!!!)\n");
+		PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n");
 		return 0;
 	}	
 
@@ -1631,15 +1660,14 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
 
 
 int CmdHF14AMfCGetSc(const char *Cmd) {
-	uint8_t memBlock[16];
+	uint8_t memBlock[16] = {0x00};
 	uint8_t sectorNo = 0;
 	int i, res, flags;
-	memset(memBlock, 0x00, sizeof(memBlock));
 
 	if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
 		PrintAndLog("Usage:  hf mf cgetsc <sector number>");
 		PrintAndLog("sample:  hf mf cgetsc 0");
-		PrintAndLog("Get sector data from magic Chinese card (only works with!!!)\n");
+		PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n");
 		return 0;
 	}	
 
@@ -1671,14 +1699,14 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
 int CmdHF14AMfCSave(const char *Cmd) {
 
 	FILE * f;
-	char filename[FILE_PATH_SIZE];
+	char filename[FILE_PATH_SIZE] = {0x00};
 	char * fnameptr = filename;
 	uint8_t fillFromEmulator = 0;
-	uint8_t buf[64];
+	uint8_t buf[64] = {0x00};
 	int i, j, len, flags;
 	
-	memset(filename, 0, sizeof(filename));
-	memset(buf, 0, sizeof(buf));
+	// memset(filename, 0, sizeof(filename));
+	// memset(buf, 0, sizeof(buf));
 
 	if (param_getchar(Cmd, 0) == 'h') {
 		PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");
@@ -1733,6 +1761,11 @@ int CmdHF14AMfCSave(const char *Cmd) {
 		// open file
 		f = fopen(filename, "w+");
 
+		if (f == NULL) {
+			PrintAndLog("File not found or locked.");
+			return 1;
+		}
+
 		// put hex
 		flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
 		for (i = 0; i < 16 * 4; i++) {
@@ -1767,18 +1800,19 @@ int CmdHF14AMfSniff(const char *Cmd){
 	int res = 0;
 	int len = 0;
 	int blockLen = 0;
-	int num = 0;
 	int pckNum = 0;
+	int num = 0;
 	uint8_t uid[7];
 	uint8_t uid_len;
-	uint8_t atqa[2];
+	uint8_t atqa[2] = {0x00};
 	uint8_t sak;
 	bool isTag;
-	uint8_t buf[3000];
-	uint8_t * bufPtr = buf;
-	memset(buf, 0x00, 3000);
+	uint8_t *buf = NULL;
+	uint16_t bufsize = 0;
+	uint8_t *bufPtr = NULL;
 	
-	if (param_getchar(Cmd, 0) == 'h') {
+	char ctmp = param_getchar(Cmd, 0);
+	if ( ctmp == 'h' || ctmp == 'H' ) {
 		PrintAndLog("It continuously gets data from the field and saves it to: log, emulator, emulator file.");
 		PrintAndLog("You can specify:");
 		PrintAndLog("    l - save encrypted sequence to logfile `uid.log`");
@@ -1791,7 +1825,7 @@ int CmdHF14AMfSniff(const char *Cmd){
 	}	
 	
 	for (int i = 0; i < 4; i++) {
-		char ctmp = param_getchar(Cmd, i);
+		ctmp = param_getchar(Cmd, i);
 		if (ctmp == 'l' || ctmp == 'L') wantLogToFile = true;
 		if (ctmp == 'd' || ctmp == 'D') wantDecrypt = true;
 		//if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO
@@ -1818,32 +1852,47 @@ int CmdHF14AMfSniff(const char *Cmd){
 			break;
 		}
 		
-    UsbCommand resp;
-    if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
+		UsbCommand resp;
+		if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
 			res = resp.arg[0] & 0xff;
-			len = resp.arg[1];
-			num = resp.arg[2];
-			
-			if (res == 0) return 0;
-			if (res == 1) {
-				if (num ==0) {
+			uint16_t traceLen = resp.arg[1];
+			len = resp.arg[2];
+
+			if (res == 0) return 0;						// we are done
+
+			if (res == 1) {								// there is (more) data to be transferred
+				if (pckNum == 0) {						// first packet, (re)allocate necessary buffer
+					if (traceLen > bufsize) {
+						uint8_t *p;
+						if (buf == NULL) {				// not yet allocated
+							p = malloc(traceLen);
+						} else {						// need more memory
+							p = realloc(buf, traceLen);
+						}
+						if (p == NULL) {
+							PrintAndLog("Cannot allocate memory for trace");
+							free(buf);
+							return 2;
+						}
+						buf = p;
+					}
 					bufPtr = buf;
-					memset(buf, 0x00, 3000);
+					bufsize = traceLen;
+					memset(buf, 0x00, traceLen);
 				}
 				memcpy(bufPtr, resp.d.asBytes, len);
 				bufPtr += len;
 				pckNum++;
 			}
-			if (res == 2) {
+
+			if (res == 2) {								// received all data, start displaying
 				blockLen = bufPtr - buf;
 				bufPtr = buf;
 				printf(">\n");
 				PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);
-				num = 0;
 				while (bufPtr - buf < blockLen) {
-					bufPtr += 6;
+					bufPtr += 6;						// skip (void) timing information
 					len = *((uint16_t *)bufPtr);
-
 					if(len & 0x8000) {
 						isTag = true;
 						len &= 0x7fff;
@@ -1852,12 +1901,10 @@ int CmdHF14AMfSniff(const char *Cmd){
 					}
 					bufPtr += 2;
 					if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) {
-					
 						memcpy(uid, bufPtr + 2, 7);
 						memcpy(atqa, bufPtr + 2 + 7, 2);
 						uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4;
 						sak = bufPtr[11];
-						
 						PrintAndLog("tag select uid:%s atqa:0x%02x%02x sak:0x%02x", 
 							sprint_hex(uid + (7 - uid_len), uid_len),
 							atqa[1], 
@@ -1875,118 +1922,26 @@ int CmdHF14AMfSniff(const char *Cmd){
 							AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);
 						if (wantDecrypt) 
 							mfTraceDecode(bufPtr, len, wantSaveToEmlFile);
+						num++;	
 					}
 					bufPtr += len;
-					bufPtr += ((len-1)/8+1); // ignore parity
-					num++;
+					bufPtr += ((len-1)/8+1);	// ignore parity
 				}
+				pckNum = 0;
 			}
 		} // resp not NULL
 	} // while (true)
-	
+
+	free(buf);
 	return 0;
 }
 
-// Tries to identify cardsize.
-// Returns <num>  where num is:
-// -1  unidentified
-//  0 - MINI (320bytes)
-//  1 - 1K
-//  2 - 2K
-//  4 - 4K
-int GetCardSize()
-{
-	UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
-	SendCommand(&c);
-
-	UsbCommand resp;
-	WaitForResponse(CMD_ACK,&resp);
-
-	if(resp.arg[0] == 0) {
-		PrintAndLog("iso14443a card select failed");
-		return -1;
-	}
-	
-	iso14a_card_select_t *card = (iso14a_card_select_t *)resp.d.asBytes;
-
-	PrintAndLog("Trying to detect card size.");
-	
-	uint16_t atqa = 0;
-	uint8_t sak = 0;
-	atqa = (card->atqa[1] & 0xff) << 8;
-    atqa += card->atqa[0] & 0xff;
-	sak = card->sak;
-	
-	// https://code.google.com/p/libnfc/source/browse/libnfc/target-subr.c
-	
-	PrintAndLog("found ATAQ: %04X SAK: %02X", atqa, sak);
-	
-	
-	// NXP MIFARE Mini 0.3k
-	if ( ( (atqa & 0xff0f) == 0x0004) && (sak == 0x09) ) return 0;
-	
-	// MIFARE Classic 1K
-	if ( ((atqa & 0xff0f) == 0x0004) && (sak == 0x08) ) return 1;
-	
-	// MIFARE Classik 4K
-	if ( ((atqa & 0xff0f) == 0x0002) && (sak == 0x18) ) return 4;
-	
-	// SmartMX with MIFARE 1K emulation 
-	if ( ((atqa & 0xf0ff) == 0x0004) ) return 1;
-
-	// SmartMX with MIFARE 4K emulation 
-	if ( ((atqa & 0xf0ff) == 0x0002) ) return 4;	
-	
-	// Infineon MIFARE CLASSIC 1K
-	if ( ((atqa & 0xffff) == 0x0004) && (sak == 0x88) ) return 1;
-	
-	// MFC 4K emulated by Nokia 6212 Classic
-	if ( ((atqa & 0xffff) == 0x0002) && (sak == 0x38) ) return 4;
-
-	// MFC 4K emulated by Nokia 6131 NFC
-	if ( ((atqa & 0xffff) == 0x0008) && (sak == 0x38) ) return 4;
-
-	
-	PrintAndLog("BEFOOO  1K %02X",  (atqa & 0xff0f));
-	
-	// MIFARE Plus (4 Byte UID or 4 Byte RID)
-	// MIFARE Plus (7 Byte UID)
-	if (
-			((atqa & 0xffff) == 0x0002) |
-			((atqa & 0xffff) == 0x0004) |
-			((atqa & 0xffff) == 0x0042) |	
-			((atqa & 0xffff) == 0x0044) 
-		)
-	{
-		switch(sak){
-			case 0x08:
-			case 0x10: {
-			//case 0x20:
-				PrintAndLog("2");
-				return 2;
-				break;
-				}
-			case 0x11:
-			case 0x18:{
-			//case 0x20:
-				PrintAndLog("4");
-				return 4;
-				break;
-				}
-		}
-	}
-	
-	return -1;
-}
 
 static command_t CommandTable[] =
 {
   {"help",		CmdHelp,				1, "This help"},
   {"dbg",		CmdHF14AMfDbg,			0, "Set default debug mode"},
   {"rdbl",		CmdHF14AMfRdBl,			0, "Read MIFARE classic block"},
-  //{"urdbl",              CmdHF14AMfURdBl,                 0, "Read MIFARE Ultralight block"},
-  //{"urdcard",           CmdHF14AMfURdCard,               0,"Read MIFARE Ultralight Card"},
-  //{"uwrbl",		CmdHF14AMfUWrBl,		0,"Write MIFARE Ultralight block"},
   {"rdsc",		CmdHF14AMfRdSc,			0, "Read MIFARE classic sector"},
   {"dump",		CmdHF14AMfDump,			0, "Dump MIFARE classic tag to binary file"},
   {"restore",	CmdHF14AMfRestore,		0, "Restore MIFARE classic binary file to BLANK tag"},
@@ -2004,9 +1959,9 @@ static command_t CommandTable[] =
   {"ecfill",	CmdHF14AMfECFill,		0, "Fill simulator memory with help of keys from simulator"},
   {"ekeyprn",	CmdHF14AMfEKeyPrn,		0, "Print keys from simulator memory"},
   {"csetuid",	CmdHF14AMfCSetUID,		0, "Set UID for magic Chinese card"},
-  {"csetblk",	CmdHF14AMfCSetBlk,		0, "Write block into magic Chinese card"},
-  {"cgetblk",	CmdHF14AMfCGetBlk,		0, "Read block from magic Chinese card"},
-  {"cgetsc",	CmdHF14AMfCGetSc,		0, "Read sector from magic Chinese card"},
+  {"csetblk",	CmdHF14AMfCSetBlk,		0, "Write block - Magic Chinese card"},
+  {"cgetblk",	CmdHF14AMfCGetBlk,		0, "Read block - Magic Chinese card"},
+  {"cgetsc",	CmdHF14AMfCGetSc,		0, "Read sector - Magic Chinese card"},
   {"cload",		CmdHF14AMfCLoad,		0, "Load dump into magic Chinese card"},
   {"csave",		CmdHF14AMfCSave,		0, "Save dump from magic Chinese card into file or emulator"},
   {NULL, NULL, 0, NULL}