From 0675f200e6d52728457664e5e127af2496af9bdd Mon Sep 17 00:00:00 2001 From: "Merlokbr@gmail.com" Date: Thu, 5 Jul 2012 07:31:56 +0000 Subject: [PATCH] Added work with "magic Chinese" card (card from: ouyangweidaxian@live.cn) with wipe support). Change UID and wipe only. --- armsrc/appmain.c | 5 ++ armsrc/apps.h | 1 + armsrc/mifarecmd.c | 126 ++++++++++++++++++++++++++++++++++++++++++++ armsrc/mifareutil.c | 2 +- client/cmdhfmf.c | 48 +++++++++++++++++ client/mifarehost.c | 24 +++++++++ client/mifarehost.h | 1 + include/usb_cmd.h | 1 + 8 files changed, 207 insertions(+), 1 deletion(-) 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 "); + 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 -- 2.39.2