CHG: a major remake of the "hf mf c*" commands. Ie chinese magic tags. Tried to make them consistent in parameter calls and simplified. And fixed the annoying gen1 tags that answers with a ACK/NACK on HALT commands..
This commit is contained in:
@@ -136,8 +136,8 @@ int CmdHF14AList(const char *Cmd)
|
||||
int CmdHF14AReader(const char *Cmd)
|
||||
{
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
||||
UsbCommand resp;
|
||||
WaitForResponse(CMD_ACK,&resp);
|
||||
|
||||
@@ -185,6 +185,7 @@ int CmdHF14AReader(const char *Cmd)
|
||||
c.arg[1] = 0;
|
||||
c.arg[2] = 0;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
||||
UsbCommand resp;
|
||||
@@ -248,6 +249,7 @@ int CmdHF14AReader(const char *Cmd)
|
||||
c.arg[1] = 2;
|
||||
c.arg[2] = 0;
|
||||
memcpy(c.d.asBytes, rats, 2);
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
WaitForResponse(CMD_ACK,&resp);
|
||||
|
||||
@@ -345,16 +347,16 @@ int CmdHF14AReader(const char *Cmd)
|
||||
PrintAndLog(" x0 -> <1 kByte");
|
||||
break;
|
||||
case 0x01:
|
||||
PrintAndLog(" x0 -> 1 kByte");
|
||||
PrintAndLog(" x1 -> 1 kByte");
|
||||
break;
|
||||
case 0x02:
|
||||
PrintAndLog(" x0 -> 2 kByte");
|
||||
PrintAndLog(" x2 -> 2 kByte");
|
||||
break;
|
||||
case 0x03:
|
||||
PrintAndLog(" x0 -> 4 kByte");
|
||||
PrintAndLog(" x3 -> 4 kByte");
|
||||
break;
|
||||
case 0x04:
|
||||
PrintAndLog(" x0 -> 8 kByte");
|
||||
PrintAndLog(" x4 -> 8 kByte");
|
||||
break;
|
||||
}
|
||||
switch (card.ats[pos + 3] & 0xf0) {
|
||||
@@ -395,14 +397,17 @@ int CmdHF14AReader(const char *Cmd)
|
||||
|
||||
|
||||
// try to see if card responses to "chinese magic backdoor" commands.
|
||||
uint8_t isOK = 0;
|
||||
clearCommandBuffer();
|
||||
c.cmd = CMD_MIFARE_CIDENT;
|
||||
c.arg[0] = 0;
|
||||
c.arg[1] = 0;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
WaitForResponse(CMD_ACK,&resp);
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
PrintAndLog("Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500))
|
||||
isOK = resp.arg[0] & 0xff;
|
||||
|
||||
PrintAndLog("Answers to magic commands (GEN1): %s", (isOK ? "YES" : "NO") );
|
||||
|
||||
// disconnect
|
||||
c.cmd = CMD_READER_ISO_14443a;
|
||||
|
||||
@@ -1543,7 +1543,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||
{
|
||||
uint8_t memBlock[16] = {0x00};
|
||||
uint8_t blockNo = 0;
|
||||
bool wipeCard = FALSE;
|
||||
uint8_t params = MAGIC_SINGLE;
|
||||
int res;
|
||||
|
||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||
@@ -1562,10 +1562,12 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||
}
|
||||
|
||||
char ctmp = param_getchar(Cmd, 2);
|
||||
wipeCard = (ctmp == 'w' || ctmp == 'W');
|
||||
if (ctmp == 'w' || ctmp == 'W')
|
||||
params |= MAGIC_WIPE;
|
||||
|
||||
PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16));
|
||||
|
||||
res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER);
|
||||
res = mfCSetBlock(blockNo, memBlock, NULL, params);
|
||||
if (res) {
|
||||
PrintAndLog("Can't write block. error=%d", res);
|
||||
return 1;
|
||||
@@ -1576,13 +1578,15 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||
int CmdHF14AMfCLoad(const char *Cmd)
|
||||
{
|
||||
FILE * f;
|
||||
char filename[FILE_PATH_SIZE] = {0x00};
|
||||
char filename[FILE_PATH_SIZE];
|
||||
char * fnameptr = filename;
|
||||
char buf[64] = {0x00};
|
||||
uint8_t buf8[64] = {0x00};
|
||||
uint8_t fillFromEmulator = 0;
|
||||
int i, len, blockNum, flags=0;
|
||||
|
||||
memset(filename, 0, sizeof(filename));
|
||||
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
|
||||
if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) {
|
||||
@@ -1602,11 +1606,11 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||
PrintAndLog("Cant get block: %d", blockNum);
|
||||
return 2;
|
||||
}
|
||||
if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence
|
||||
if (blockNum == 0) flags = MAGIC_INIT + MAGIC_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 (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Magic Halt and switch off field.
|
||||
|
||||
if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
|
||||
if (mfCSetBlock(blockNum, buf8, NULL, flags)) {
|
||||
PrintAndLog("Cant set magic card block: %d", blockNum);
|
||||
return 3;
|
||||
}
|
||||
@@ -1649,11 +1653,11 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||
for (i = 0; i < 32; i += 2)
|
||||
sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
|
||||
|
||||
if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence
|
||||
if (blockNum == 0) flags = MAGIC_INIT + MAGIC_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 (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Switch off field.
|
||||
|
||||
if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
|
||||
if (mfCSetBlock(blockNum, buf8, NULL, flags)) {
|
||||
PrintAndLog("Can't set magic card block: %d", blockNum);
|
||||
return 3;
|
||||
}
|
||||
@@ -1663,6 +1667,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
// 64 or 256blocks.
|
||||
if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){
|
||||
PrintAndLog("File content error. There must be 64 blocks");
|
||||
return 4;
|
||||
@@ -1674,12 +1679,13 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||
}
|
||||
|
||||
int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||
uint8_t memBlock[16];
|
||||
uint8_t data[16];
|
||||
uint8_t blockNo = 0;
|
||||
int res;
|
||||
memset(memBlock, 0x00, sizeof(memBlock));
|
||||
memset(data, 0x00, sizeof(data));
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
|
||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == '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 such cards)\n");
|
||||
@@ -1690,22 +1696,24 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||
|
||||
PrintAndLog("--block number:%2d ", blockNo);
|
||||
|
||||
res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER);
|
||||
res = mfCGetBlock(blockNo, data, MAGIC_SINGLE);
|
||||
if (res) {
|
||||
PrintAndLog("Can't read block. error=%d", res);
|
||||
return 1;
|
||||
}
|
||||
PrintAndLog("Can't read block. error=%d", res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("block data:%s", sprint_hex(memBlock, 16));
|
||||
PrintAndLog("data:%s", sprint_hex(data, sizeof(data)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||
uint8_t memBlock[16] = {0x00};
|
||||
uint8_t data[16];
|
||||
uint8_t sectorNo = 0;
|
||||
int i, res, flags;
|
||||
|
||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||
memset(data, 0x00, sizeof(data));
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
|
||||
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == '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 such cards)\n");
|
||||
@@ -1719,19 +1727,19 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||
}
|
||||
|
||||
PrintAndLog("--sector number:%d ", sectorNo);
|
||||
PrintAndLog("block | data");
|
||||
|
||||
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
||||
flags = MAGIC_INIT + MAGIC_WUPC;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (i == 1) flags = 0;
|
||||
if (i == 3) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
||||
if (i == 3) flags = MAGIC_HALT + MAGIC_OFF;
|
||||
|
||||
res = mfCGetBlock(sectorNo * 4 + i, memBlock, flags);
|
||||
res = mfCGetBlock(sectorNo * 4 + i, data, flags);
|
||||
if (res) {
|
||||
PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("block %3d data:%s", sectorNo * 4 + i, sprint_hex(memBlock, 16));
|
||||
}
|
||||
PrintAndLog(" %3d | %s", sectorNo * 4 + i, sprint_hex(data, sizeof(data)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1739,14 +1747,14 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||
int CmdHF14AMfCSave(const char *Cmd) {
|
||||
|
||||
FILE * f;
|
||||
char filename[FILE_PATH_SIZE] = {0x00};
|
||||
char filename[FILE_PATH_SIZE];
|
||||
char * fnameptr = filename;
|
||||
uint8_t fillFromEmulator = 0;
|
||||
uint8_t buf[64] = {0x00};
|
||||
uint8_t buf[64];
|
||||
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));
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
|
||||
if ( ctmp == 'h' || ctmp == 'H' ) {
|
||||
@@ -1762,10 +1770,10 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||
|
||||
if (fillFromEmulator) {
|
||||
// put into emulator
|
||||
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
||||
flags = MAGIC_INIT + MAGIC_WUPC;
|
||||
for (i = 0; i < 16 * 4; i++) {
|
||||
if (i == 1) flags = 0;
|
||||
if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
||||
if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF;
|
||||
|
||||
if (mfCGetBlock(i, buf, flags)) {
|
||||
PrintAndLog("Cant get block: %d", i);
|
||||
@@ -1782,9 +1790,10 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||
len = strlen(Cmd);
|
||||
if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
|
||||
|
||||
// get filename based on UID
|
||||
if (len < 1) {
|
||||
// get filename
|
||||
if (mfCGetBlock(0, buf, CSETBLOCK_SINGLE_OPER)) {
|
||||
|
||||
if (mfCGetBlock(0, buf, MAGIC_SINGLE)) {
|
||||
PrintAndLog("Cant get block: %d", 0);
|
||||
len = sprintf(fnameptr, "dump");
|
||||
fnameptr += len;
|
||||
@@ -1797,6 +1806,7 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||
fnameptr += len;
|
||||
}
|
||||
|
||||
// add .eml extension
|
||||
sprintf(fnameptr, ".eml");
|
||||
|
||||
// open file
|
||||
@@ -1808,10 +1818,10 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||
}
|
||||
|
||||
// put hex
|
||||
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
||||
flags = MAGIC_INIT + MAGIC_WUPC;
|
||||
for (i = 0; i < 16 * 4; i++) {
|
||||
if (i == 1) flags = 0;
|
||||
if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
||||
if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF;
|
||||
|
||||
if (mfCGetBlock(i, buf, flags)) {
|
||||
PrintAndLog("Cant get block: %d", i);
|
||||
@@ -1821,10 +1831,9 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||
fprintf(f, "%02x", buf[j]);
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
fflush(f);
|
||||
fclose(f);
|
||||
|
||||
PrintAndLog("Saved to file: %s", filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -2031,13 +2040,12 @@ int CmdHFMF(const char *Cmd)
|
||||
{
|
||||
// flush
|
||||
WaitForResponseTimeout(CMD_ACK,NULL,100);
|
||||
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHelp(const char *Cmd)
|
||||
{
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1199,32 +1199,32 @@ int CmdLFfind(const char *Cmd)
|
||||
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"},
|
||||
{"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"},
|
||||
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
|
||||
{"hitag", CmdLFHitag, 1, "{ HITAG RFIDs... }"},
|
||||
{"io", CmdLFIO, 1, "{ IOPROX RFIDs... }"},
|
||||
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 RFIDs... }"},
|
||||
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
|
||||
{"t55xx", CmdLFT55XX, 1, "{ T55X7 RFIDs... }"},
|
||||
{"viking", CmdLFViking, 1, "{ Viking RFIDs... }"},
|
||||
{"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"},
|
||||
|
||||
{"cmdread", CmdLFCommandRead, 0, "<off period> <'0' period> <'1' period> <command> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"},
|
||||
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
|
||||
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
|
||||
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
|
||||
{"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
|
||||
{"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t-- 'u' to search for unknown tags"},
|
||||
{"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
|
||||
{"simask", CmdLFaskSim, 0, "[clock] [invert <1|0>] [biphase/manchester/raw <'b'|'m'|'r'>] [msg separator 's'] [d <hexdata>] \n\t\t-- Simulate LF ASK tag from demodbuffer or input"},
|
||||
{"simfsk", CmdLFfskSim, 0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] \n\t\t-- Simulate LF FSK tag from demodbuffer or input"},
|
||||
{"simpsk", CmdLFpskSim, 0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] \n\t\t-- Simulate LF PSK tag from demodbuffer or input"},
|
||||
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
||||
{"snoop", CmdLFSnoop, 0, "['l'|'h'|<divisor>] [trigger threshold] -- Snoop LF (l:125khz, h:134khz)"},
|
||||
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
{"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"},
|
||||
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
|
||||
{"hitag", CmdLFHitag, 1, "{ HITAG RFIDs... }"},
|
||||
{"io", CmdLFIO, 1, "{ IOPROX RFIDs... }"},
|
||||
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 RFIDs... }"},
|
||||
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
|
||||
{"t55xx", CmdLFT55XX, 1, "{ T55X7 RFIDs... }"},
|
||||
{"viking", CmdLFViking, 1, "{ Viking RFIDs... }"},
|
||||
{"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"},
|
||||
|
||||
{"cmdread", CmdLFCommandRead, 0, "<off period> <'0' period> <'1' period> <command> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"},
|
||||
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
|
||||
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
|
||||
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
|
||||
{"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
|
||||
{"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t-- 'u' to search for unknown tags"},
|
||||
{"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
|
||||
{"simask", CmdLFaskSim, 0, "[clock] [invert <1|0>] [biphase/manchester/raw <'b'|'m'|'r'>] [msg separator 's'] [d <hexdata>] \n\t\t-- Simulate LF ASK tag from demodbuffer or input"},
|
||||
{"simfsk", CmdLFfskSim, 0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] \n\t\t-- Simulate LF FSK tag from demodbuffer or input"},
|
||||
{"simpsk", CmdLFpskSim, 0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] \n\t\t-- Simulate LF PSK tag from demodbuffer or input"},
|
||||
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
||||
{"snoop", CmdLFSnoop, 0, "Snoop LF"},
|
||||
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
int CmdLF(const char *Cmd)
|
||||
|
||||
@@ -237,14 +237,16 @@ int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidt
|
||||
|
||||
// "MAGIC" CARD
|
||||
|
||||
int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe) {
|
||||
uint8_t oldblock0[16] = {0x00};
|
||||
uint8_t block0[16] = {0x00};
|
||||
int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard) {
|
||||
|
||||
int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER);
|
||||
uint8_t params = MAGIC_SINGLE;
|
||||
uint8_t block0[16];
|
||||
memset(block0, 0x00, sizeof(block0));
|
||||
|
||||
|
||||
int old = mfCGetBlock(0, block0, params);
|
||||
if (old == 0) {
|
||||
memcpy(block0, oldblock0, 16);
|
||||
PrintAndLog("old block 0: %s", sprint_hex(block0,16));
|
||||
PrintAndLog("old block 0: %s", sprint_hex(block0, sizeof(block0)));
|
||||
} else {
|
||||
PrintAndLog("Couldn't get old data. Will write over the last bytes of Block 0.");
|
||||
}
|
||||
@@ -255,26 +257,30 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool w
|
||||
// Mifare UID BCC
|
||||
block0[4] = block0[0]^block0[1]^block0[2]^block0[3];
|
||||
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)
|
||||
if (sak!=NULL)
|
||||
if ( sak != NULL )
|
||||
block0[5]=sak[0];
|
||||
if (atqa!=NULL) {
|
||||
|
||||
if ( atqa != NULL ) {
|
||||
block0[6]=atqa[1];
|
||||
block0[7]=atqa[0];
|
||||
}
|
||||
PrintAndLog("new block 0: %s", sprint_hex(block0,16));
|
||||
return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);
|
||||
|
||||
if ( wipecard ) params |= MAGIC_WIPE;
|
||||
if ( oldUID == NULL) params |= MAGIC_UID;
|
||||
|
||||
return mfCSetBlock(0, block0, oldUID, params);
|
||||
}
|
||||
|
||||
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params) {
|
||||
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) {
|
||||
|
||||
uint8_t isOK = 0;
|
||||
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
|
||||
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {params, blockNo, 0}};
|
||||
memcpy(c.d.asBytes, data, 16);
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||
isOK = resp.arg[0] & 0xff;
|
||||
if (uid != NULL)
|
||||
memcpy(uid, resp.d.asBytes, 4);
|
||||
@@ -289,9 +295,7 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uin
|
||||
|
||||
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
|
||||
uint8_t isOK = 0;
|
||||
|
||||
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
|
||||
|
||||
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
UsbCommand resp;
|
||||
|
||||
@@ -19,28 +19,21 @@
|
||||
#include "nonce2key/nonce2key.h"
|
||||
#include "nonce2key/crapto1.h"
|
||||
#include "iso14443crc.h"
|
||||
#include "protocols.h"
|
||||
|
||||
#define MEM_CHUNK 1000000
|
||||
#define NESTED_SECTOR_RETRY 10
|
||||
|
||||
// mfCSetBlock work flags
|
||||
#define CSETBLOCK_UID 0x01
|
||||
#define CSETBLOCK_WUPC 0x02
|
||||
#define CSETBLOCK_HALT 0x04
|
||||
#define CSETBLOCK_INIT_FIELD 0x08
|
||||
#define CSETBLOCK_RESET_FIELD 0x10
|
||||
#define CSETBLOCK_SINGLE_OPER 0x1F
|
||||
|
||||
// mifare tracer flags
|
||||
#define TRACE_IDLE 0x00
|
||||
#define TRACE_AUTH1 0x01
|
||||
#define TRACE_AUTH2 0x02
|
||||
#define TRACE_AUTH_OK 0x03
|
||||
#define TRACE_READ_DATA 0x04
|
||||
#define TRACE_WRITE_OK 0x05
|
||||
#define TRACE_WRITE_DATA 0x06
|
||||
#define TRACE_IDLE 0x00
|
||||
#define TRACE_AUTH1 0x01
|
||||
#define TRACE_AUTH2 0x02
|
||||
#define TRACE_AUTH_OK 0x03
|
||||
#define TRACE_READ_DATA 0x04
|
||||
#define TRACE_WRITE_OK 0x05
|
||||
#define TRACE_WRITE_DATA 0x06
|
||||
|
||||
#define TRACE_ERROR 0xFF
|
||||
#define TRACE_ERROR 0xFF
|
||||
|
||||
typedef struct {
|
||||
uint64_t Key[2];
|
||||
@@ -56,8 +49,8 @@ int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||
int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth);
|
||||
|
||||
int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe);
|
||||
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params);
|
||||
int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard);
|
||||
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params);
|
||||
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);
|
||||
|
||||
int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile);
|
||||
|
||||
Reference in New Issue
Block a user