undo adjustments to cmdhf14a.c and cmdhfmf.c

as these will be adjusted with the magic command adjustments
This commit is contained in:
marshmellow42 2016-02-14 18:37:09 -05:00
commit 7c5e0ebe7a
2 changed files with 173 additions and 216 deletions

View file

@ -352,16 +352,16 @@ int CmdHF14AReader(const char *Cmd)
PrintAndLog(" x0 -> <1 kByte"); PrintAndLog(" x0 -> <1 kByte");
break; break;
case 0x01: case 0x01:
PrintAndLog(" x0 -> 1 kByte"); PrintAndLog(" x1 -> 1 kByte");
break; break;
case 0x02: case 0x02:
PrintAndLog(" x0 -> 2 kByte"); PrintAndLog(" x2 -> 2 kByte");
break; break;
case 0x03: case 0x03:
PrintAndLog(" x0 -> 4 kByte"); PrintAndLog(" x3 -> 4 kByte");
break; break;
case 0x04: case 0x04:
PrintAndLog(" x0 -> 8 kByte"); PrintAndLog(" x4 -> 8 kByte");
break; break;
} }
switch (card.ats[pos + 3] & 0xf0) { switch (card.ats[pos + 3] & 0xf0) {
@ -458,110 +458,86 @@ int CmdHF14ACUIDs(const char *Cmd)
return 1; return 1;
} }
int usage_hf_14a_sim(void) {
PrintAndLog("\n Emulating ISO/IEC 14443 type A tag with 4 or 7 byte UID\n");
PrintAndLog("Usage: hf 14a sim t <type> u <uid> x");
PrintAndLog(" Options : ");
PrintAndLog(" h : this help");
PrintAndLog(" t : 1 = MIFARE Classic");
PrintAndLog(" 2 = MIFARE Ultralight");
PrintAndLog(" 3 = MIFARE Desfire");
PrintAndLog(" 4 = ISO/IEC 14443-4");
PrintAndLog(" 5 = MIFARE Tnp3xxx");
PrintAndLog(" 6 = MIFARE Mini");
PrintAndLog(" 7 = NTAG 215 from emu mem");
PrintAndLog(" u : 4 or 7 byte UID");
PrintAndLog(" x : (Optional) performs the 'reader attack', nr/ar attack against a legitimate reader");
PrintAndLog("\n sample : hf 14a sim t 1 u 1122344");
PrintAndLog(" : hf 14a sim t 1 u 1122344 x\n");
return 0;
}
// ## simulate iso14443a tag // ## simulate iso14443a tag
// ## greg - added ability to specify tag UID // ## greg - added ability to specify tag UID
int CmdHF14ASim(const char *Cmd) int CmdHF14ASim(const char *Cmd)
{ {
bool errors = FALSE; UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,{0,0,0}};
uint8_t flags = 0;
uint8_t tagtype = 1;
uint64_t uid = 0;
uint8_t cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00) // Retrieve the tag type
{ uint8_t tagtype = param_get8ex(Cmd,0,0,10);
switch(param_getchar(Cmd, cmdp))
{
case 'h':
case 'H':
return usage_hf_14a_sim();
case 't':
case 'T':
// Retrieve the tag type
tagtype = param_get8ex(Cmd, cmdp+1, 0, 10);
if (tagtype == 0)
errors = true;
cmdp += 2;
break;
case 'u':
case 'U':
// Retrieve the full 4 or 7 byte long uid
uid = param_get64ex(Cmd, cmdp+1, 0, 16);
if (uid == 0 )
errors = TRUE;
if (uid > 0xffffffff) { // When no argument was given, just print help message
PrintAndLog("Emulating ISO/IEC 14443 type A tag with 7 byte UID (%014"llx")",uid); if (tagtype == 0) {
flags |= FLAG_7B_UID_IN_DATA; PrintAndLog("");
} else { PrintAndLog(" Emulating ISO/IEC 14443 type A tag with 4 or 7 byte UID");
PrintAndLog("Emulating ISO/IEC 14443 type A tag with 4 byte UID (%08x)",uid); PrintAndLog("");
flags |= FLAG_4B_UID_IN_DATA; PrintAndLog(" syntax: hf 14a sim <type> <uid>");
} PrintAndLog(" types: 1 = MIFARE Classic");
cmdp += 2; PrintAndLog(" 2 = MIFARE Ultralight");
break; PrintAndLog(" 3 = MIFARE Desfire");
case 'x': PrintAndLog(" 4 = ISO/IEC 14443-4");
case 'X': PrintAndLog(" 5 = MIFARE Tnp3xxx");
flags |= FLAG_NR_AR_ATTACK; PrintAndLog("");
cmdp++; return 1;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
if(errors) break;
} }
//Validations // Store the tag type
if (errors) return usage_hf_14a_sim(); c.arg[0] = tagtype;
PrintAndLog("Press pm3-button to abort simulation"); // Retrieve the full 4 or 7 byte long uid
uint64_t long_uid = param_get64ex(Cmd,1,0,16);
UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,{ tagtype, flags, 0 }}; // Are we handling the (optional) second part uid?
if (long_uid > 0xffffffff) {
num_to_bytes(uid, 7, c.d.asBytes); PrintAndLog("Emulating ISO/IEC 14443 type A tag with 7 byte UID (%014"llx")",long_uid);
clearCommandBuffer(); // Store the second part
SendCommand(&c); c.arg[2] = (long_uid & 0xffffffff);
long_uid >>= 32;
//uint8_t data[40]; // Store the first part, ignore the first byte, it is replaced by cascade byte (0x88)
//uint8_t key[6]; c.arg[1] = (long_uid & 0xffffff);
UsbCommand resp; } else {
while(!ukbhit()){ PrintAndLog("Emulating ISO/IEC 14443 type A tag with 4 byte UID (%08x)",long_uid);
if ( WaitForResponseTimeout(CMD_ACK,&resp,1500)) { // Only store the first part
if ( (resp.arg[0] & 0xffff) == CMD_SIMULATE_MIFARE_CARD ){ c.arg[1] = long_uid & 0xffffffff;
// attempt to get key:
// TODO:
//memset(data, 0x00, sizeof(data));
//memset(key, 0x00, sizeof(key));
//int len = (resp.arg[1] > sizeof(data)) ? sizeof(data) : resp.arg[1];
//memcpy(data, resp.d.asBytes, len);
//tryMfk32(uid, data, key);
//tryMfk32_moebius(uid, data, key);
//tryMfk64(uid, data, key);
//PrintAndLog("--");
}
}
} }
return 0; /*
// At lease save the mandatory first part of the UID
c.arg[0] = long_uid & 0xffffffff;
if (c.arg[1] == 0) {
PrintAndLog("Emulating ISO/IEC 14443 type A tag with UID %01d %08x %08x",c.arg[0],c.arg[1],c.arg[2]);
}
switch (c.arg[0]) {
case 1: {
PrintAndLog("Emulating ISO/IEC 14443-3 type A tag with 4 byte UID");
UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,param_get32ex(Cmd,0,0,10),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16)};
} break;
case 2: {
PrintAndLog("Emulating ISO/IEC 14443-4 type A tag with 7 byte UID");
} break;
default: {
PrintAndLog("Error: unkown tag type (%d)",c.arg[0]);
PrintAndLog("syntax: hf 14a sim <uid>",c.arg[0]);
PrintAndLog(" type1: 4 ",c.arg[0]);
return 1;
} break;
}
*/
/*
unsigned int hi = 0, lo = 0;
int n = 0, i = 0;
while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
hi= (hi << 4) | (lo >> 28);
lo= (lo << 4) | (n & 0xf);
}
*/
// UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a,param_get32ex(Cmd,0,0,10),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16)};
// PrintAndLog("Emulating ISO/IEC 14443 type A tag with UID %01d %08x %08x",c.arg[0],c.arg[1],c.arg[2]);
SendCommand(&c);
return 0;
} }
int CmdHF14ASnoop(const char *Cmd) { int CmdHF14ASnoop(const char *Cmd) {
@ -729,9 +705,8 @@ int CmdHF14ACmdRaw(const char *cmd) {
if(topazmode) if(topazmode)
c.arg[0] |= ISO14A_TOPAZMODE; c.arg[0] |= ISO14A_TOPAZMODE;
// Max buffer is USB_CMD_DATA_SIZE // Max buffer is USB_CMD_DATA_SIZE
datalen = (datalen > USB_CMD_DATA_SIZE) ? USB_CMD_DATA_SIZE : datalen; c.arg[1] = (datalen & 0xFFFF) | (numbits << 16);
c.arg[1] = (datalen & 0xFFFF) | ( (uint32_t)(numbits) << 16);
memcpy(c.d.asBytes,data,datalen); memcpy(c.d.asBytes,data,datalen);
SendCommand(&c); SendCommand(&c);

View file

@ -121,11 +121,10 @@ int CmdHF14AMfWrBl(const char *Cmd)
PrintAndLog("--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6)); PrintAndLog("--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6));
PrintAndLog("--data: %s", sprint_hex(bldata, 16)); PrintAndLog("--data: %s", sprint_hex(bldata, 16));
UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};
memcpy(c.d.asBytes, key, 6); memcpy(c.d.asBytes, key, 6);
memcpy(c.d.asBytes + 10, bldata, 16); memcpy(c.d.asBytes + 10, bldata, 16);
clearCommandBuffer(); SendCommand(&c);
SendCommand(&c);
UsbCommand resp; UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
@ -166,10 +165,9 @@ int CmdHF14AMfRdBl(const char *Cmd)
} }
PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6)); PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6));
UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};
memcpy(c.d.asBytes, key, 6); memcpy(c.d.asBytes, key, 6);
clearCommandBuffer(); SendCommand(&c);
SendCommand(&c);
UsbCommand resp; UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
@ -222,7 +220,6 @@ int CmdHF14AMfRdSc(const char *Cmd)
UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}}; UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};
memcpy(c.d.asBytes, key, 6); memcpy(c.d.asBytes, key, 6);
clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
PrintAndLog(" "); PrintAndLog(" ");
@ -242,7 +239,7 @@ int CmdHF14AMfRdSc(const char *Cmd)
PrintAndLog("Command execute timeout"); PrintAndLog("Command execute timeout");
} }
return 0; return 0;
} }
uint8_t FirstBlockOfSector(uint8_t sectorNo) uint8_t FirstBlockOfSector(uint8_t sectorNo)
@ -329,7 +326,6 @@ int CmdHF14AMfDump(const char *Cmd)
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 0, 0}}; UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 0, 0}};
memcpy(c.d.asBytes, keyA[sectorNo], 6); memcpy(c.d.asBytes, keyA[sectorNo], 6);
clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
@ -364,7 +360,6 @@ int CmdHF14AMfDump(const char *Cmd)
if (blockNo == NumBlocksPerSector(sectorNo) - 1) { // sector trailer. At least the Access Conditions can always be read with key A. if (blockNo == NumBlocksPerSector(sectorNo) - 1) { // sector trailer. At least the Access Conditions can always be read with key A.
UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}}; UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}};
memcpy(c.d.asBytes, keyA[sectorNo], 6); memcpy(c.d.asBytes, keyA[sectorNo], 6);
clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
received = WaitForResponseTimeout(CMD_ACK,&resp,1500); received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
} else { // data block. Check if it can be read with key A or key B } else { // data block. Check if it can be read with key A or key B
@ -372,7 +367,6 @@ int CmdHF14AMfDump(const char *Cmd)
if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work
UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 1, 0}}; UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 1, 0}};
memcpy(c.d.asBytes, keyB[sectorNo], 6); memcpy(c.d.asBytes, keyB[sectorNo], 6);
clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
received = WaitForResponseTimeout(CMD_ACK,&resp,1500); received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
} else if (rights[sectorNo][data_area] == 0x07) { // no key would work } else if (rights[sectorNo][data_area] == 0x07) { // no key would work
@ -381,7 +375,6 @@ int CmdHF14AMfDump(const char *Cmd)
} else { // key A would work } else { // key A would work
UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}}; UsbCommand c = {CMD_MIFARE_READBL, {FirstBlockOfSector(sectorNo) + blockNo, 0, 0}};
memcpy(c.d.asBytes, keyA[sectorNo], 6); memcpy(c.d.asBytes, keyA[sectorNo], 6);
clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
received = WaitForResponseTimeout(CMD_ACK,&resp,1500); received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
} }
@ -525,7 +518,6 @@ int CmdHF14AMfRestore(const char *Cmd)
PrintAndLog("Writing to block %3d: %s", FirstBlockOfSector(sectorNo) + blockNo, sprint_hex(bldata, 16)); PrintAndLog("Writing to block %3d: %s", FirstBlockOfSector(sectorNo) + blockNo, sprint_hex(bldata, 16));
memcpy(c.d.asBytes + 10, bldata, 16); memcpy(c.d.asBytes + 10, bldata, 16);
clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
UsbCommand resp; UsbCommand resp;
@ -875,7 +867,6 @@ int CmdHF14AMfChk(const char *Cmd)
break; break;
default: default:
PrintAndLog("Key type must be A , B or ?"); PrintAndLog("Key type must be A , B or ?");
free(keyBlock);
return 1; return 1;
}; };
@ -927,7 +918,6 @@ int CmdHF14AMfChk(const char *Cmd)
if (!p) { if (!p) {
PrintAndLog("Cannot allocate memory for defKeys"); PrintAndLog("Cannot allocate memory for defKeys");
free(keyBlock); free(keyBlock);
fclose(f);
return 2; return 2;
} }
keyBlock = p; keyBlock = p;
@ -1079,7 +1069,6 @@ int CmdHF14AMf1kSim(const char *Cmd)
UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {flags, exitAfterNReads,0}}; UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {flags, exitAfterNReads,0}};
memcpy(c.d.asBytes, uid, sizeof(uid)); memcpy(c.d.asBytes, uid, sizeof(uid));
clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
if(flags & FLAG_INTERACTIVE) if(flags & FLAG_INTERACTIVE)
@ -1088,7 +1077,7 @@ int CmdHF14AMf1kSim(const char *Cmd)
PrintAndLog("Press pm3-button to abort simulation"); PrintAndLog("Press pm3-button to abort simulation");
while(! WaitForResponseTimeout(CMD_ACK,&resp,1500)) { while(! WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
//We're waiting only 1.5 s at a time, otherwise we get the //We're waiting only 1.5 s at a time, otherwise we get the
//annoying message about "Waiting for a response... " // annoying message about "Waiting for a response... "
} }
} }
@ -1155,6 +1144,7 @@ int CmdHF14AMfEClear(const char *Cmd)
return 0; return 0;
} }
int CmdHF14AMfESet(const char *Cmd) int CmdHF14AMfESet(const char *Cmd)
{ {
uint8_t memBlock[16]; uint8_t memBlock[16];
@ -1182,6 +1172,7 @@ int CmdHF14AMfESet(const char *Cmd)
return 0; return 0;
} }
int CmdHF14AMfELoad(const char *Cmd) int CmdHF14AMfELoad(const char *Cmd)
{ {
FILE * f; FILE * f;
@ -1191,13 +1182,13 @@ int CmdHF14AMfELoad(const char *Cmd)
uint8_t buf8[64] = {0x00}; uint8_t buf8[64] = {0x00};
int i, len, blockNum, numBlocks; int i, len, blockNum, numBlocks;
int nameParamNo = 1; int nameParamNo = 1;
uint8_t blockWidth = 32;
char ctmp = param_getchar(Cmd, 0); char ctmp = param_getchar(Cmd, 0);
if ( ctmp == 'h' || ctmp == 0x00) { if ( ctmp == 'h' || ctmp == 0x00) {
PrintAndLog("It loads emul dump from the file `filename.eml`"); PrintAndLog("It loads emul dump from the file `filename.eml`");
PrintAndLog("Usage: hf mf eload [card memory] <file name w/o `.eml`> [numblocks]"); PrintAndLog("Usage: hf mf eload [card memory] <file name w/o `.eml`>");
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL"); PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
PrintAndLog(""); PrintAndLog("");
PrintAndLog(" sample: hf mf eload filename"); PrintAndLog(" sample: hf mf eload filename");
PrintAndLog(" hf mf eload 4 filename"); PrintAndLog(" hf mf eload 4 filename");
@ -1210,18 +1201,15 @@ int CmdHF14AMfELoad(const char *Cmd)
case '\0': numBlocks = 16*4; break; case '\0': numBlocks = 16*4; break;
case '2' : numBlocks = 32*4; break; case '2' : numBlocks = 32*4; break;
case '4' : numBlocks = 256; break; case '4' : numBlocks = 256; break;
case 'U' : // fall through
case 'u' : numBlocks = 255; blockWidth = 8; break;
default: { default: {
numBlocks = 16*4; numBlocks = 16*4;
nameParamNo = 0; nameParamNo = 0;
} }
} }
uint32_t numblk2 = param_get32ex(Cmd,2,0,10);
if (numblk2 > 0) numBlocks = numblk2;
len = param_getstr(Cmd,nameParamNo,filename); len = param_getstr(Cmd,nameParamNo,filename);
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
fnameptr += len; fnameptr += len;
@ -1247,18 +1235,19 @@ int CmdHF14AMfELoad(const char *Cmd)
return 2; return 2;
} }
if (strlen(buf) < blockWidth){ if (strlen(buf) < 32){
if(strlen(buf) && feof(f)) if(strlen(buf) && feof(f))
break; break;
PrintAndLog("File content error. Block data must include %d HEX symbols", blockWidth); PrintAndLog("File content error. Block data must include 32 HEX symbols");
fclose(f); fclose(f);
return 2; return 2;
} }
for (i = 0; i < blockWidth; i += 2) { for (i = 0; i < 32; i += 2) {
sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]); sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
} }
if (mfEmlSetMem_xt(buf8, blockNum, 1, blockWidth/2)) {
if (mfEmlSetMem(buf8, blockNum, 1)) {
PrintAndLog("Cant set emul block: %3d", blockNum); PrintAndLog("Cant set emul block: %3d", blockNum);
fclose(f); fclose(f);
return 3; return 3;
@ -1279,6 +1268,7 @@ int CmdHF14AMfELoad(const char *Cmd)
return 0; return 0;
} }
int CmdHF14AMfESave(const char *Cmd) int CmdHF14AMfESave(const char *Cmd)
{ {
FILE * f; FILE * f;
@ -1318,7 +1308,7 @@ int CmdHF14AMfESave(const char *Cmd)
len = param_getstr(Cmd,nameParamNo,filename); len = param_getstr(Cmd,nameParamNo,filename);
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
// user supplied filename? // user supplied filename?
if (len < 1) { if (len < 1) {
@ -1364,6 +1354,7 @@ int CmdHF14AMfESave(const char *Cmd)
return 0; return 0;
} }
int CmdHF14AMfECFill(const char *Cmd) int CmdHF14AMfECFill(const char *Cmd)
{ {
uint8_t keyType = 0; uint8_t keyType = 0;
@ -1403,6 +1394,7 @@ int CmdHF14AMfECFill(const char *Cmd)
return 0; return 0;
} }
int CmdHF14AMfEKeyPrn(const char *Cmd) int CmdHF14AMfEKeyPrn(const char *Cmd)
{ {
int i; int i;
@ -1410,9 +1402,7 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
uint8_t data[16]; uint8_t data[16];
uint64_t keyA, keyB; uint64_t keyA, keyB;
char cmdp = param_getchar(Cmd, 0); if (param_getchar(Cmd, 0) == 'h') {
if ( cmdp == 'h' || cmdp == 'H') {
PrintAndLog("It prints the keys loaded in the emulator memory"); PrintAndLog("It prints the keys loaded in the emulator memory");
PrintAndLog("Usage: hf mf ekeyprn [card memory]"); PrintAndLog("Usage: hf mf ekeyprn [card memory]");
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K"); PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
@ -1421,6 +1411,8 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
return 0; return 0;
} }
char cmdp = param_getchar(Cmd, 0);
switch (cmdp) { switch (cmdp) {
case '0' : numSectors = 5; break; case '0' : numSectors = 5; break;
case '1' : case '1' :
@ -1447,6 +1439,7 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
return 0; return 0;
} }
int CmdHF14AMfCSetUID(const char *Cmd) int CmdHF14AMfCSetUID(const char *Cmd)
{ {
uint8_t wipeCard = 0; uint8_t wipeCard = 0;
@ -1520,7 +1513,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
{ {
uint8_t memBlock[16] = {0x00}; uint8_t memBlock[16] = {0x00};
uint8_t blockNo = 0; uint8_t blockNo = 0;
uint8_t params = MAGIC_SINGLE; bool wipeCard = FALSE;
int res; int res;
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
@ -1539,12 +1532,10 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
} }
char ctmp = param_getchar(Cmd, 2); char ctmp = param_getchar(Cmd, 2);
if (ctmp == 'w' || ctmp == 'W') wipeCard = (ctmp == 'w' || ctmp == 'W');
params |= MAGIC_WIPE;
PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16)); PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16));
res = mfCSetBlock(blockNo, memBlock, NULL, params); res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER);
if (res) { if (res) {
PrintAndLog("Can't write block. error=%d", res); PrintAndLog("Can't write block. error=%d", res);
return 1; return 1;
@ -1552,21 +1543,18 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
return 0; return 0;
} }
int CmdHF14AMfCLoad(const char *Cmd) int CmdHF14AMfCLoad(const char *Cmd)
{ {
FILE * f; FILE * f;
char filename[FILE_PATH_SIZE]; char filename[FILE_PATH_SIZE] = {0x00};
char * fnameptr = filename; char * fnameptr = filename;
char buf[64] = {0x00}; char buf[64] = {0x00};
uint8_t buf8[64] = {0x00}; uint8_t buf8[64] = {0x00};
uint8_t fillFromEmulator = 0; uint8_t fillFromEmulator = 0;
int i, len, blockNum, flags=0; int i, len, blockNum, flags=0;
memset(filename, 0, sizeof(filename)); if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
char ctmp = param_getchar(Cmd, 0);
if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) {
PrintAndLog("It loads magic Chinese card from the file `filename.eml`"); PrintAndLog("It loads magic Chinese card from the file `filename.eml`");
PrintAndLog("or from emulator memory (option `e`)"); PrintAndLog("or from emulator memory (option `e`)");
PrintAndLog("Usage: hf mf cload <file name w/o `.eml`>"); PrintAndLog("Usage: hf mf cload <file name w/o `.eml`>");
@ -1575,6 +1563,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
return 0; return 0;
} }
char ctmp = param_getchar(Cmd, 0);
if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1; if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
if (fillFromEmulator) { if (fillFromEmulator) {
@ -1583,11 +1572,11 @@ int CmdHF14AMfCLoad(const char *Cmd)
PrintAndLog("Cant get block: %d", blockNum); PrintAndLog("Cant get block: %d", blockNum);
return 2; return 2;
} }
if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence 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 == 1) flags = 0; // just write
if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Magic Halt and switch off field. if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Magic Halt and switch off field.
if (mfCSetBlock(blockNum, buf8, NULL, flags)) { if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
PrintAndLog("Cant set magic card block: %d", blockNum); PrintAndLog("Cant set magic card block: %d", blockNum);
return 3; return 3;
} }
@ -1595,7 +1584,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
return 0; return 0;
} else { } else {
len = strlen(Cmd); len = strlen(Cmd);
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
memcpy(filename, Cmd, len); memcpy(filename, Cmd, len);
fnameptr += len; fnameptr += len;
@ -1630,11 +1619,11 @@ int CmdHF14AMfCLoad(const char *Cmd)
for (i = 0; i < 32; i += 2) for (i = 0; i < 32; i += 2)
sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]); sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence 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 == 1) flags = 0; // just write
if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Switch off field. if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Switch off field.
if (mfCSetBlock(blockNum, buf8, NULL, flags)) { if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
PrintAndLog("Can't set magic card block: %d", blockNum); PrintAndLog("Can't set magic card block: %d", blockNum);
return 3; return 3;
} }
@ -1655,13 +1644,12 @@ int CmdHF14AMfCLoad(const char *Cmd)
} }
int CmdHF14AMfCGetBlk(const char *Cmd) { int CmdHF14AMfCGetBlk(const char *Cmd) {
uint8_t data[16]; uint8_t memBlock[16];
uint8_t blockNo = 0; uint8_t blockNo = 0;
int res; int res;
memset(data, 0x00, sizeof(data)); memset(memBlock, 0x00, sizeof(memBlock));
char ctmp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') { if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
PrintAndLog("Usage: hf mf cgetblk <block number>"); PrintAndLog("Usage: hf mf cgetblk <block number>");
PrintAndLog("sample: hf mf cgetblk 1"); PrintAndLog("sample: hf mf cgetblk 1");
PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n"); PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n");
@ -1672,24 +1660,23 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
PrintAndLog("--block number:%2d ", blockNo); PrintAndLog("--block number:%2d ", blockNo);
res = mfCGetBlock(blockNo, data, MAGIC_SINGLE); res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER);
if (res) { if (res) {
PrintAndLog("Can't read block. error=%d", res); PrintAndLog("Can't read block. error=%d", res);
return 1; return 1;
} }
PrintAndLog("block data:%s", sprint_hex(data, sizeof(data))); PrintAndLog("block data:%s", sprint_hex(memBlock, 16));
return 0; return 0;
} }
int CmdHF14AMfCGetSc(const char *Cmd) { int CmdHF14AMfCGetSc(const char *Cmd) {
uint8_t data[16]; uint8_t memBlock[16] = {0x00};
uint8_t sectorNo = 0; uint8_t sectorNo = 0;
int i, res, flags; int i, res, flags;
memset(data, 0x00, sizeof(data));
char ctmp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') { if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
PrintAndLog("Usage: hf mf cgetsc <sector number>"); PrintAndLog("Usage: hf mf cgetsc <sector number>");
PrintAndLog("sample: hf mf cgetsc 0"); PrintAndLog("sample: hf mf cgetsc 0");
PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n"); PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n");
@ -1703,37 +1690,37 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
} }
PrintAndLog("--sector number:%d ", sectorNo); PrintAndLog("--sector number:%d ", sectorNo);
PrintAndLog("block | data");
flags = MAGIC_INIT + MAGIC_WUPC; flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (i == 1) flags = 0; if (i == 1) flags = 0;
if (i == 3) flags = MAGIC_HALT + MAGIC_OFF; if (i == 3) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
res = mfCGetBlock(sectorNo * 4 + i, data, flags); res = mfCGetBlock(sectorNo * 4 + i, memBlock, flags);
if (res) { if (res) {
PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res); PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res);
return 1; return 1;
} }
PrintAndLog(" %3d | %s", sectorNo * 4 + i, sprint_hex(data, sizeof(data)));
PrintAndLog("block %3d data:%s", sectorNo * 4 + i, sprint_hex(memBlock, 16));
} }
return 0; return 0;
} }
int CmdHF14AMfCSave(const char *Cmd) { int CmdHF14AMfCSave(const char *Cmd) {
FILE * f; FILE * f;
char filename[FILE_PATH_SIZE]; char filename[FILE_PATH_SIZE] = {0x00};
char * fnameptr = filename; char * fnameptr = filename;
uint8_t fillFromEmulator = 0; uint8_t fillFromEmulator = 0;
uint8_t buf[64]; uint8_t buf[64] = {0x00};
int i, j, len, flags; int i, j, len, flags;
memset(filename, 0, sizeof(filename)); // memset(filename, 0, sizeof(filename));
memset(buf, 0, sizeof(buf)); // memset(buf, 0, sizeof(buf));
char ctmp = param_getchar(Cmd, 0);
if ( ctmp == 'h' || ctmp == 'H' ) { if (param_getchar(Cmd, 0) == 'h') {
PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`"); PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");
PrintAndLog("or into emulator memory (option `e`)"); PrintAndLog("or into emulator memory (option `e`)");
PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e]"); PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e]");
@ -1742,14 +1729,16 @@ int CmdHF14AMfCSave(const char *Cmd) {
PrintAndLog(" hf mf esave e \n"); PrintAndLog(" hf mf esave e \n");
return 0; return 0;
} }
char ctmp = param_getchar(Cmd, 0);
if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1; if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
if (fillFromEmulator) { if (fillFromEmulator) {
// put into emulator // put into emulator
flags = MAGIC_INIT + MAGIC_WUPC; flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
for (i = 0; i < 16 * 4; i++) { for (i = 0; i < 16 * 4; i++) {
if (i == 1) flags = 0; if (i == 1) flags = 0;
if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
if (mfCGetBlock(i, buf, flags)) { if (mfCGetBlock(i, buf, flags)) {
PrintAndLog("Cant get block: %d", i); PrintAndLog("Cant get block: %d", i);
@ -1764,16 +1753,16 @@ int CmdHF14AMfCSave(const char *Cmd) {
return 0; return 0;
} else { } else {
len = strlen(Cmd); len = strlen(Cmd);
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
// get filename based on UID
if (len < 1) { if (len < 1) {
// get filename
if (mfCGetBlock(0, buf, MAGIC_SINGLE)) { if (mfCGetBlock(0, buf, CSETBLOCK_SINGLE_OPER)) {
PrintAndLog("Cant get block: %d", 0); PrintAndLog("Cant get block: %d", 0);
len = sprintf(fnameptr, "dump"); len = sprintf(fnameptr, "dump");
fnameptr += len; fnameptr += len;
} else { }
else {
for (j = 0; j < 7; j++, fnameptr += 2) for (j = 0; j < 7; j++, fnameptr += 2)
sprintf(fnameptr, "%02x", buf[j]); sprintf(fnameptr, "%02x", buf[j]);
} }
@ -1782,7 +1771,6 @@ int CmdHF14AMfCSave(const char *Cmd) {
fnameptr += len; fnameptr += len;
} }
// add .eml extension
sprintf(fnameptr, ".eml"); sprintf(fnameptr, ".eml");
// open file // open file
@ -1794,10 +1782,10 @@ int CmdHF14AMfCSave(const char *Cmd) {
} }
// put hex // put hex
flags = MAGIC_INIT + MAGIC_WUPC; flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
for (i = 0; i < 16 * 4; i++) { for (i = 0; i < 16 * 4; i++) {
if (i == 1) flags = 0; if (i == 1) flags = 0;
if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
if (mfCGetBlock(i, buf, flags)) { if (mfCGetBlock(i, buf, flags)) {
PrintAndLog("Cant get block: %d", i); PrintAndLog("Cant get block: %d", i);
@ -1807,13 +1795,15 @@ int CmdHF14AMfCSave(const char *Cmd) {
fprintf(f, "%02x", buf[j]); fprintf(f, "%02x", buf[j]);
fprintf(f,"\n"); fprintf(f,"\n");
} }
fflush(f);
fclose(f); fclose(f);
PrintAndLog("Saved to file: %s", filename); PrintAndLog("Saved to file: %s", filename);
return 0; return 0;
} }
} }
int CmdHF14AMfSniff(const char *Cmd){ int CmdHF14AMfSniff(const char *Cmd){
bool wantLogToFile = 0; bool wantLogToFile = 0;
@ -1883,10 +1873,7 @@ int CmdHF14AMfSniff(const char *Cmd){
uint16_t traceLen = resp.arg[1]; uint16_t traceLen = resp.arg[1];
len = resp.arg[2]; len = resp.arg[2];
if (res == 0) { if (res == 0) return 0; // we are done
free(buf);
return 0; // we are done
}
if (res == 1) { // there is (more) data to be transferred if (res == 1) { // there is (more) data to be transferred
if (pckNum == 0) { // first packet, (re)allocate necessary buffer if (pckNum == 0) { // first packet, (re)allocate necessary buffer
@ -1908,11 +1895,6 @@ int CmdHF14AMfSniff(const char *Cmd){
bufsize = traceLen; bufsize = traceLen;
memset(buf, 0x00, traceLen); memset(buf, 0x00, traceLen);
} }
if (bufPtr == NULL) {
PrintAndLog("Cannot allocate memory for trace");
free(buf);
return 2;
}
memcpy(bufPtr, resp.d.asBytes, len); memcpy(bufPtr, resp.d.asBytes, len);
bufPtr += len; bufPtr += len;
pckNum++; pckNum++;
@ -1970,7 +1952,7 @@ int CmdHF14AMfSniff(const char *Cmd){
} }
//needs nt, ar, at, Data to decrypt //needs nt, ar, at, Data to decrypt
int CmdHf14MfDecryptBytes(const char *Cmd){ int CmdDecryptTraceCmds(const char *Cmd){
uint8_t data[50]; uint8_t data[50];
int len = 0; int len = 0;
param_gethex_ex(Cmd,3,data,&len); param_gethex_ex(Cmd,3,data,&len);
@ -2004,7 +1986,7 @@ static command_t CommandTable[] =
{"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"}, {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"},
{"cload", CmdHF14AMfCLoad, 0, "Load dump into 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"}, {"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"},
{"decrypt", CmdHf14MfDecryptBytes,1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"}, {"decrypt", CmdDecryptTraceCmds,1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };