From: Merlokbr@gmail.com <Merlokbr@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Date: Thu, 5 Jul 2012 07:31:56 +0000 (+0000)
Subject: Added work with "magic Chinese" card (card from: ouyangweidaxian@live.cn) with wipe... 
X-Git-Tag: v1.0.0~174
X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/0675f200e6d52728457664e5e127af2496af9bdd

Added work with "magic Chinese" card (card from: ouyangweidaxian@live.cn) with wipe support). Change UID and wipe only.
---

diff --git a/armsrc/appmain.c b/armsrc/appmain.c
index 63b8383f..820a0378 100644
--- a/armsrc/appmain.c
+++ b/armsrc/appmain.c
@@ -753,6 +753,11 @@ void UsbPacketReceived(uint8_t *packet, int len)
 		case CMD_MIFARE_EML_CARDLOAD:
 			MifareECardLoad(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
 			break;
+			
+		// Work with "magic Chinese" card
+		case CMD_MIFARE_EML_CSETBLOCK:
+			MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
+			break;
 #endif
 
 #ifdef WITH_ICLASS
diff --git a/armsrc/apps.h b/armsrc/apps.h
index ac49ccad..3723357e 100644
--- a/armsrc/apps.h
+++ b/armsrc/apps.h
@@ -149,6 +149,7 @@ void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
 void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
 void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
 void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
+void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);  // Work with "magic Chinese" card
 
 /// iso15693.h
 void RecordRawAdcSamplesIso15693(void);
diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c
index b2b38edf..84820730 100644
--- a/armsrc/mifarecmd.c
+++ b/armsrc/mifarecmd.c
@@ -726,3 +726,129 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
 // 
 //-----------------------------------------------------------------------------
 
+
+//-----------------------------------------------------------------------------
+// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)
+// 
+//-----------------------------------------------------------------------------
+void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
+  
+  // params
+	uint8_t needWipe = arg0;
+	uint8_t needGetUID = arg1;
+	uint8_t blockNo = arg2;
+	
+	// card commands
+	uint8_t wupC1[]       = { 0x40 }; 
+	uint8_t wupC2[]       = { 0x43 }; 
+	uint8_t wipeC[]       = { 0x41 }; 
+	
+	// variables
+	byte_t isOK = 0;
+	uint8_t uid[8];
+	uint8_t d_block[18];
+	uint32_t cuid;
+	
+	memset(uid, 0x00, 8);
+	uint8_t* receivedAnswer = mifare_get_bigbufptr();
+	
+	// clear trace
+	iso14a_clear_tracelen();
+  iso14a_set_tracing(TRUE);
+
+	iso14443a_setup();
+
+	LED_A_ON();
+	LED_B_OFF();
+	LED_C_OFF();
+	
+	SpinDelay(300);
+	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+	SpinDelay(100);
+	FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
+
+	while (true) {
+		// get UID from chip
+		if (needGetUID) {
+			if(!iso14443a_select_card(uid, NULL, &cuid)) {
+				if (MF_DBGLEVEL >= 1)	Dbprintf("Can't select card");
+				break;
+			};
+
+			if(mifare_classic_halt(NULL, cuid)) {
+				if (MF_DBGLEVEL >= 1)	Dbprintf("Halt error");
+				break;
+			};
+		};
+	
+		// reset chip
+		if (needWipe){
+			ReaderTransmitShort(wupC1);
+			if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
+				if (MF_DBGLEVEL >= 1)	Dbprintf("wupC1 error");
+				break;
+			};
+
+			ReaderTransmit(wipeC, sizeof(wipeC));
+			if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
+				if (MF_DBGLEVEL >= 1)	Dbprintf("wipeC error");
+				break;
+			};
+
+			if(mifare_classic_halt(NULL, cuid)) {
+				if (MF_DBGLEVEL >= 1)	Dbprintf("Halt error");
+				break;
+			};
+		};	
+
+		// write UID block
+		ReaderTransmitShort(wupC1);
+		if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
+			if (MF_DBGLEVEL >= 1)	Dbprintf("wupC1 error");
+			break;
+		};
+
+		ReaderTransmit(wupC2, sizeof(wupC2));
+		if(!ReaderReceive(receivedAnswer) || (receivedAnswer[0] != 0x0a)) {
+			if (MF_DBGLEVEL >= 1)	Dbprintf("wupC2 error");
+			break;
+		};
+
+		if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {
+			if (MF_DBGLEVEL >= 1)	Dbprintf("write block send command error");
+			break;
+		};
+	
+		memcpy(d_block, datain, 16);
+		AppendCrc14443a(d_block, 16);
+	
+		ReaderTransmit(d_block, sizeof(d_block));
+		if ((ReaderReceive(receivedAnswer) != 1) || (receivedAnswer[0] != 0x0a)) {
+			if (MF_DBGLEVEL >= 1)	Dbprintf("write block send data error");
+			break;
+		};	
+	
+		if(mifare_classic_halt(NULL, cuid)) {
+			if (MF_DBGLEVEL >= 1)	Dbprintf("Halt error");
+			break;
+		};
+		
+		isOK = 1;
+		break;
+	}
+	
+	UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
+	if (isOK) memcpy(ack.d.asBytes, uid, 4);
+	
+	// add trace trailer
+	memset(uid, 0x44, 4);
+	LogTrace(uid, 4, 0, 0, TRUE);
+
+	LED_B_ON();
+	UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
+	LED_B_OFF();
+
+  // Thats it...
+	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+	LEDsoff();
+}
diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c
index a88f21bc..c20a387a 100644
--- a/armsrc/mifareutil.c
+++ b/armsrc/mifareutil.c
@@ -311,7 +311,7 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
 	// Mifare HALT
 	uint8_t* receivedAnswer = mifare_get_bigbufptr();
 
-	len = mifare_sendcmd_short(pcs, 1, 0x50, 0x00, receivedAnswer);
+	len = mifare_sendcmd_short(pcs, pcs == NULL ? 0:1, 0x50, 0x00, receivedAnswer);
 	if (len != 0) {
 		if (MF_DBGLEVEL >= 1)	Dbprintf("halt error. response len: %x", len);  
 		return 1;
diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c
index 081d197c..9928cb1b 100644
--- a/client/cmdhfmf.c
+++ b/client/cmdhfmf.c
@@ -1218,6 +1218,51 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
 	return 0;
 }
 
+int CmdHF14AMfCSetUID(const char *Cmd)
+{
+	uint8_t wipeCard = 0;
+	uint8_t uid[8];
+	uint8_t oldUid[8];
+	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");
+		return 0;
+	}	
+
+	if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 8)) {
+		PrintAndLog("UID must include 8 HEX symbols");
+		return 1;
+	}
+
+	char ctmp = param_getchar(Cmd, 1);
+	if (ctmp == 'w' || ctmp == 'W') wipeCard = 1;
+	
+	PrintAndLog("--wipe card:%02x uid:%s", wipeCard, sprint_hex(uid, 4));
+
+	res = mfCSetUID(uid, oldUid, wipeCard);
+	if (res) {
+			PrintAndLog("Can't set UID. error=%d", res);
+			return 1;
+		}
+	
+	PrintAndLog("old UID:%s", sprint_hex(oldUid, 4));
+	return 0;
+}
+
+int CmdHF14AMfCSetBlk(const char *Cmd)
+{
+	return 0;
+}
+
+int CmdHF14AMfCLoad(const char *Cmd)
+{
+	return 0;
+}
+
 static command_t CommandTable[] =
 {
   {"help",		CmdHelp,				1, "This help"},
@@ -1238,6 +1283,9 @@ static command_t CommandTable[] =
   {"esave",		CmdHF14AMfESave,		0, "Save to file emul dump"},
   {"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, "(n/a)Write block into magic Chinese card"},
+  {"cload",		CmdHF14AMfCLoad,		0, "(n/a)Load dump into magic Chinese card"},
   {NULL, NULL, 0, NULL}
 };
 
diff --git a/client/mifarehost.c b/client/mifarehost.c
index 394d2471..529c248d 100644
--- a/client/mifarehost.c
+++ b/client/mifarehost.c
@@ -216,3 +216,27 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
 	return 0;
 }
 
+int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe) {
+	uint8_t isOK = 0;
+	uint8_t block0[16];
+	memset(block0, 0, 16);
+	memcpy(block0, uid, 4); 
+	block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC
+
+  UsbCommand c = {CMD_MIFARE_EML_CSETBLOCK, {wantWipe, 1, 0}};
+	memcpy(c.d.asBytes, block0, 16); 
+  SendCommand(&c);
+
+	UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
+
+	if (resp != NULL) {
+		isOK  = resp->arg[0] & 0xff;
+		PrintAndLog("isOk:%02x", isOK);
+		memcpy(oldUID, resp->d.asBytes, 4); 
+		if (!isOK) return 2;
+	} else {
+		PrintAndLog("Command execute timeout");
+		return 1;
+	}
+	return 0;
+}
diff --git a/client/mifarehost.h b/client/mifarehost.h
index fe506f9b..e5d7c84a 100644
--- a/client/mifarehost.h
+++ b/client/mifarehost.h
@@ -44,4 +44,5 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
 int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);
 int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
 int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
+int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe);
 
diff --git a/include/usb_cmd.h b/include/usb_cmd.h
index 7d7093b5..a0c6d8a8 100644
--- a/include/usb_cmd.h
+++ b/include/usb_cmd.h
@@ -114,6 +114,7 @@ typedef struct {
 #define CMD_MIFARE_EML_MEMSET						0x0602
 #define CMD_MIFARE_EML_MEMGET						0x0603
 #define CMD_MIFARE_EML_CARDLOAD					0x0604
+#define CMD_MIFARE_EML_CSETBLOCK				0x0605
 
 #define CMD_SIMULATE_MIFARE_CARD				0x0610