mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
add gdm flag to hf mf c* commands
this enables the use of hf mf c* commands with gdm/uscuid cards when the alt wake up mode 20(7)/23 is enabled rather than gen1 wake up
This commit is contained in:
parent
60c2446e27
commit
6d7fcc642a
6 changed files with 78 additions and 19 deletions
|
@ -55,7 +55,7 @@ void RunMod(void) {
|
||||||
|
|
||||||
card_clone_t uids[OPTS];
|
card_clone_t uids[OPTS];
|
||||||
iso14a_card_select_t card[OPTS];
|
iso14a_card_select_t card[OPTS];
|
||||||
uint8_t params = (MAGIC_SINGLE | MAGIC_DATAIN);
|
uint8_t params = (MAGIC_SINGLE | MAGIC_WUPC | MAGIC_DATAIN);
|
||||||
|
|
||||||
LED(selected + 1, 0);
|
LED(selected + 1, 0);
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ void RunMod(void) {
|
||||||
// Mifare UID BCC
|
// Mifare UID BCC
|
||||||
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
|
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
|
||||||
Bytes 5-7 are reserved SAK and ATQA for mifare classic
|
Bytes 5-7 are reserved SAK and ATQA for mifare classic
|
||||||
-Use mfCSetBlock(0, block0, oldUID, wantWipe, MAGIC_SINGLE) to write it
|
-Use mfCSetBlock(0, block0, oldUID, wantWipe, MAGIC_SINGLE | MAGIC_WUPC) to write it
|
||||||
*/
|
*/
|
||||||
uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0};
|
uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0};
|
||||||
// arg0 = Flags, arg1=blockNo
|
// arg0 = Flags, arg1=blockNo
|
||||||
|
|
|
@ -2552,6 +2552,7 @@ out:
|
||||||
// bit 4 - need turn off FPGA
|
// bit 4 - need turn off FPGA
|
||||||
// bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
|
// bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
|
||||||
// bit 6 - wipe tag.
|
// bit 6 - wipe tag.
|
||||||
|
// bit 7 - use USCUID/GDM (20/23) magic wakeup
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
|
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
|
||||||
|
@ -2620,6 +2621,22 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
|
||||||
mifare_classic_halt(NULL);
|
mifare_classic_halt(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (workFlags & MAGIC_GDM_ALT_WUPC) {
|
||||||
|
ReaderTransmitBitsPar(wupGDM1, 7, NULL, NULL);
|
||||||
|
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
||||||
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupGDM1 error");
|
||||||
|
errormsg = MAGIC_WUPC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReaderTransmit(wupGDM2, sizeof(wupC2), NULL);
|
||||||
|
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
||||||
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupGDM2 error");
|
||||||
|
errormsg = MAGIC_WUPC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// write block
|
// write block
|
||||||
if (workFlags & MAGIC_WUPC) {
|
if (workFlags & MAGIC_WUPC) {
|
||||||
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
||||||
|
@ -2706,6 +2723,22 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
|
||||||
|
|
||||||
//loop doesn't loop just breaks out if error or done
|
//loop doesn't loop just breaks out if error or done
|
||||||
while (true) {
|
while (true) {
|
||||||
|
if (workFlags & MAGIC_GDM_ALT_WUPC) {
|
||||||
|
ReaderTransmitBitsPar(wupGDM1, 7, NULL, NULL);
|
||||||
|
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
||||||
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupGDM1 error");
|
||||||
|
errormsg = MAGIC_WUPC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReaderTransmit(wupGDM2, sizeof(wupC2), NULL);
|
||||||
|
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
||||||
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupGDM2 error");
|
||||||
|
errormsg = MAGIC_WUPC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (workFlags & MAGIC_WUPC) {
|
if (workFlags & MAGIC_WUPC) {
|
||||||
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
||||||
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
||||||
|
|
|
@ -5166,6 +5166,7 @@ static int CmdHF14AMfCSetUID(const char *Cmd) {
|
||||||
arg_str0("u", "uid", "<hex>", "UID, 4/7 hex bytes"),
|
arg_str0("u", "uid", "<hex>", "UID, 4/7 hex bytes"),
|
||||||
arg_str0("a", "atqa", "<hex>", "ATQA, 2 hex bytes"),
|
arg_str0("a", "atqa", "<hex>", "ATQA, 2 hex bytes"),
|
||||||
arg_str0("s", "sak", "<hex>", "SAK, 1 hex byte"),
|
arg_str0("s", "sak", "<hex>", "SAK, 1 hex byte"),
|
||||||
|
arg_lit0(NULL, "gdm", "use gdm alt (20/23) magic wakeup"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
@ -5183,6 +5184,7 @@ static int CmdHF14AMfCSetUID(const char *Cmd) {
|
||||||
int slen = 0;
|
int slen = 0;
|
||||||
uint8_t sak[1] = {0x00};
|
uint8_t sak[1] = {0x00};
|
||||||
CLIGetHexWithReturn(ctx, 4, sak, &slen);
|
CLIGetHexWithReturn(ctx, 4, sak, &slen);
|
||||||
|
uint8_t gdm = arg_get_lit(ctx, 5);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
|
@ -5209,7 +5211,8 @@ static int CmdHF14AMfCSetUID(const char *Cmd) {
|
||||||
(slen) ? sak : NULL,
|
(slen) ? sak : NULL,
|
||||||
old_uid,
|
old_uid,
|
||||||
verify_uid,
|
verify_uid,
|
||||||
wipe_card
|
wipe_card,
|
||||||
|
gdm
|
||||||
);
|
);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
@ -5240,6 +5243,7 @@ static int CmdHF14AMfCWipe(const char *cmd) {
|
||||||
arg_str0("u", "uid", "<hex>", "UID, 4 hex bytes"),
|
arg_str0("u", "uid", "<hex>", "UID, 4 hex bytes"),
|
||||||
arg_str0("a", "atqa", "<hex>", "ATQA, 2 hex bytes"),
|
arg_str0("a", "atqa", "<hex>", "ATQA, 2 hex bytes"),
|
||||||
arg_str0("s", "sak", "<hex>", "SAK, 1 hex byte"),
|
arg_str0("s", "sak", "<hex>", "SAK, 1 hex byte"),
|
||||||
|
arg_lit0(NULL, "gdm", "use gdm alt (20/23) magic wakeup"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, cmd, argtable, true);
|
CLIExecWithReturn(ctx, cmd, argtable, true);
|
||||||
|
@ -5255,6 +5259,7 @@ static int CmdHF14AMfCWipe(const char *cmd) {
|
||||||
int slen = 0;
|
int slen = 0;
|
||||||
uint8_t sak[1] = {0x00};
|
uint8_t sak[1] = {0x00};
|
||||||
CLIGetHexWithReturn(ctx, 3, sak, &slen);
|
CLIGetHexWithReturn(ctx, 3, sak, &slen);
|
||||||
|
uint8_t gdm = arg_get_lit(ctx, 4);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (uidlen && uidlen != 4) {
|
if (uidlen && uidlen != 4) {
|
||||||
|
@ -5270,7 +5275,7 @@ static int CmdHF14AMfCWipe(const char *cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = mfCWipe((uidlen) ? uid : NULL, (alen) ? atqa : NULL, (slen) ? sak : NULL);
|
int res = mfCWipe((uidlen) ? uid : NULL, (alen) ? atqa : NULL, (slen) ? sak : NULL, gdm);
|
||||||
if (res) {
|
if (res) {
|
||||||
PrintAndLogEx(ERR, "Can't wipe card. error %d", res);
|
PrintAndLogEx(ERR, "Can't wipe card. error %d", res);
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
@ -5292,6 +5297,7 @@ static int CmdHF14AMfCSetBlk(const char *Cmd) {
|
||||||
arg_int1("b", "blk", "<dec>", "block number"),
|
arg_int1("b", "blk", "<dec>", "block number"),
|
||||||
arg_str0("d", "data", "<hex>", "bytes to write, 16 hex bytes"),
|
arg_str0("d", "data", "<hex>", "bytes to write, 16 hex bytes"),
|
||||||
arg_lit0("w", "wipe", "wipes card with backdoor cmd before writing"),
|
arg_lit0("w", "wipe", "wipes card with backdoor cmd before writing"),
|
||||||
|
arg_lit0(NULL, "gdm", "use gdm alt (20/23) magic wakeup"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -5303,6 +5309,7 @@ static int CmdHF14AMfCSetBlk(const char *Cmd) {
|
||||||
CLIGetHexWithReturn(ctx, 2, data, &datalen);
|
CLIGetHexWithReturn(ctx, 2, data, &datalen);
|
||||||
|
|
||||||
uint8_t wipe_card = arg_get_lit(ctx, 3);
|
uint8_t wipe_card = arg_get_lit(ctx, 3);
|
||||||
|
uint8_t gdm = arg_get_lit(ctx, 4);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (b < 0 || b >= MIFARE_1K_MAXBLOCK) {
|
if (b < 0 || b >= MIFARE_1K_MAXBLOCK) {
|
||||||
|
@ -5316,6 +5323,12 @@ static int CmdHF14AMfCSetBlk(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t params = MAGIC_SINGLE;
|
uint8_t params = MAGIC_SINGLE;
|
||||||
|
if (gdm) {
|
||||||
|
params |= MAGIC_GDM_ALT_WUPC;
|
||||||
|
} else {
|
||||||
|
params |= MAGIC_WUPC;
|
||||||
|
}
|
||||||
|
|
||||||
if (wipe_card) {
|
if (wipe_card) {
|
||||||
params |= MAGIC_WIPE;
|
params |= MAGIC_WIPE;
|
||||||
}
|
}
|
||||||
|
@ -5347,6 +5360,7 @@ static int CmdHF14AMfCLoad(const char *Cmd) {
|
||||||
arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"),
|
arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"),
|
||||||
arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"),
|
arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"),
|
||||||
arg_lit0(NULL, "emu", "from emulator memory"),
|
arg_lit0(NULL, "emu", "from emulator memory"),
|
||||||
|
arg_lit0(NULL, "gdm", "use gdm alt (20/23) magic wakeup"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -5360,6 +5374,7 @@ static int CmdHF14AMfCLoad(const char *Cmd) {
|
||||||
bool m2 = arg_get_lit(ctx, 4);
|
bool m2 = arg_get_lit(ctx, 4);
|
||||||
bool m4 = arg_get_lit(ctx, 5);
|
bool m4 = arg_get_lit(ctx, 5);
|
||||||
bool fill_from_emulator = arg_get_lit(ctx, 6);
|
bool fill_from_emulator = arg_get_lit(ctx, 6);
|
||||||
|
bool gdm = arg_get_lit(ctx, 7);
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
@ -5393,7 +5408,7 @@ static int CmdHF14AMfCLoad(const char *Cmd) {
|
||||||
|
|
||||||
if (fill_from_emulator) {
|
if (fill_from_emulator) {
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Start upload to emulator memory");
|
PrintAndLogEx(INFO, "Start upload from emulator memory");
|
||||||
PrintAndLogEx(INFO, "." NOLF);
|
PrintAndLogEx(INFO, "." NOLF);
|
||||||
|
|
||||||
for (int b = 0; b < block_cnt; b++) {
|
for (int b = 0; b < block_cnt; b++) {
|
||||||
|
@ -5408,7 +5423,7 @@ static int CmdHF14AMfCLoad(const char *Cmd) {
|
||||||
|
|
||||||
// switch on field and send magic sequence
|
// switch on field and send magic sequence
|
||||||
if (b == 0) {
|
if (b == 0) {
|
||||||
flags = MAGIC_INIT + MAGIC_WUPC;
|
flags = MAGIC_INIT | (gdm ? MAGIC_GDM_ALT_WUPC : MAGIC_WUPC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// just write
|
// just write
|
||||||
|
@ -5456,7 +5471,7 @@ static int CmdHF14AMfCLoad(const char *Cmd) {
|
||||||
|
|
||||||
// switch on field and send magic sequence
|
// switch on field and send magic sequence
|
||||||
if (blockno == 0) {
|
if (blockno == 0) {
|
||||||
flags = MAGIC_INIT + MAGIC_WUPC;
|
flags = MAGIC_INIT | (gdm ? MAGIC_GDM_ALT_WUPC : MAGIC_WUPC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// write
|
// write
|
||||||
|
@ -5511,11 +5526,13 @@ static int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_int1("b", "blk", "<dec>", "block number"),
|
arg_int1("b", "blk", "<dec>", "block number"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
|
arg_lit0(NULL, "gdm", "use gdm alt (20/23) magic wakeup"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
int b = arg_get_int_def(ctx, 1, 0);
|
int b = arg_get_int_def(ctx, 1, 0);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
|
bool gdm = arg_get_lit(ctx, 3);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (b > 255) {
|
if (b > 255) {
|
||||||
|
@ -5524,7 +5541,7 @@ static int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||||
|
|
||||||
uint8_t blockno = (uint8_t)b;
|
uint8_t blockno = (uint8_t)b;
|
||||||
uint8_t data[16] = {0};
|
uint8_t data[16] = {0};
|
||||||
int res = mfCGetBlock(blockno, data, MAGIC_SINGLE);
|
int res = mfCGetBlock(blockno, data, MAGIC_SINGLE | (gdm ? MAGIC_GDM_ALT_WUPC : MAGIC_WUPC));
|
||||||
if (res) {
|
if (res) {
|
||||||
PrintAndLogEx(ERR, "Can't read block. error=%d", res);
|
PrintAndLogEx(ERR, "Can't read block. error=%d", res);
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
@ -5553,11 +5570,13 @@ static int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_int1("s", "sec", "<dec>", "sector number"),
|
arg_int1("s", "sec", "<dec>", "sector number"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
|
arg_lit0(NULL, "gdm", "use gdm alt (20/23) magic wakeup"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
int s = arg_get_int_def(ctx, 1, 0);
|
int s = arg_get_int_def(ctx, 1, 0);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
|
bool gdm = arg_get_lit(ctx, 3);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (s >= MIFARE_4K_MAXSECTOR) {
|
if (s >= MIFARE_4K_MAXSECTOR) {
|
||||||
|
@ -5575,7 +5594,7 @@ static int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||||
start = 128 + (sector - 32) * 16;
|
start = 128 + (sector - 32) * 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flags = MAGIC_INIT + MAGIC_WUPC;
|
int flags = MAGIC_INIT + (gdm ? MAGIC_GDM_ALT_WUPC : MAGIC_WUPC);
|
||||||
uint8_t data[16] = {0};
|
uint8_t data[16] = {0};
|
||||||
for (int i = 0; i < blocks; i++) {
|
for (int i = 0; i < blocks; i++) {
|
||||||
if (i == 1) flags = 0;
|
if (i == 1) flags = 0;
|
||||||
|
@ -5612,6 +5631,7 @@ static int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"),
|
arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"),
|
||||||
arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"),
|
arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"),
|
||||||
arg_lit0(NULL, "emu", "to emulator memory"),
|
arg_lit0(NULL, "emu", "to emulator memory"),
|
||||||
|
arg_lit0(NULL, "gdm", "to emulator memory"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
@ -5625,6 +5645,7 @@ static int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
bool m2 = arg_get_lit(ctx, 4);
|
bool m2 = arg_get_lit(ctx, 4);
|
||||||
bool m4 = arg_get_lit(ctx, 5);
|
bool m4 = arg_get_lit(ctx, 5);
|
||||||
bool fill_emulator = arg_get_lit(ctx, 6);
|
bool fill_emulator = arg_get_lit(ctx, 6);
|
||||||
|
bool gdm = arg_get_lit(ctx, 7);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
// validations
|
// validations
|
||||||
|
@ -5692,7 +5713,7 @@ static int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// switch on field and send magic sequence
|
// switch on field and send magic sequence
|
||||||
uint8_t flags = MAGIC_INIT + MAGIC_WUPC;
|
uint8_t flags = MAGIC_INIT + (gdm ? MAGIC_GDM_ALT_WUPC : MAGIC_WUPC);
|
||||||
for (uint16_t i = 0; i < block_cnt; i++) {
|
for (uint16_t i = 0; i < block_cnt; i++) {
|
||||||
|
|
||||||
// read
|
// read
|
||||||
|
@ -5766,6 +5787,7 @@ static int CmdHF14AMfCView(const char *Cmd) {
|
||||||
arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"),
|
arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"),
|
||||||
arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"),
|
arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
|
arg_lit0(NULL, "gdm", "use gdm alt (20/23) magic wakeup"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
@ -5774,6 +5796,7 @@ static int CmdHF14AMfCView(const char *Cmd) {
|
||||||
bool m2 = arg_get_lit(ctx, 3);
|
bool m2 = arg_get_lit(ctx, 3);
|
||||||
bool m4 = arg_get_lit(ctx, 4);
|
bool m4 = arg_get_lit(ctx, 4);
|
||||||
bool verbose = arg_get_lit(ctx, 5);
|
bool verbose = arg_get_lit(ctx, 5);
|
||||||
|
bool gdm = arg_get_lit(ctx, 6);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
// validations
|
// validations
|
||||||
|
@ -5840,7 +5863,7 @@ static int CmdHF14AMfCView(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// switch on field and send magic sequence
|
// switch on field and send magic sequence
|
||||||
uint8_t flags = MAGIC_INIT + MAGIC_WUPC;
|
uint8_t flags = MAGIC_INIT + (gdm ? MAGIC_GDM_ALT_WUPC : MAGIC_WUPC);
|
||||||
for (uint16_t i = 0; i < block_cnt; i++) {
|
for (uint16_t i = 0; i < block_cnt; i++) {
|
||||||
// read
|
// read
|
||||||
if (i == 1) {
|
if (i == 1) {
|
||||||
|
|
|
@ -1058,9 +1058,9 @@ int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidt
|
||||||
}
|
}
|
||||||
|
|
||||||
// "MAGIC" CARD
|
// "MAGIC" CARD
|
||||||
int mfCSetUID(uint8_t *uid, uint8_t uidlen, const uint8_t *atqa, const uint8_t *sak, uint8_t *old_uid, uint8_t *verifed_uid, uint8_t wipecard) {
|
int mfCSetUID(uint8_t *uid, uint8_t uidlen, const uint8_t *atqa, const uint8_t *sak, uint8_t *old_uid, uint8_t *verifed_uid, uint8_t wipecard, uint8_t gdm) {
|
||||||
|
|
||||||
uint8_t params = MAGIC_SINGLE;
|
uint8_t params = MAGIC_SINGLE | (gdm ? MAGIC_GDM_ALT_WUPC : MAGIC_WUPC);
|
||||||
uint8_t block0[MFBLOCK_SIZE];
|
uint8_t block0[MFBLOCK_SIZE];
|
||||||
memset(block0, 0x00, sizeof(block0));
|
memset(block0, 0x00, sizeof(block0));
|
||||||
|
|
||||||
|
@ -1111,7 +1111,7 @@ int mfCSetUID(uint8_t *uid, uint8_t uidlen, const uint8_t *atqa, const uint8_t *
|
||||||
|
|
||||||
res = mfCSetBlock(0, block0, NULL, params);
|
res = mfCSetBlock(0, block0, NULL, params);
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
params = MAGIC_SINGLE;
|
params = MAGIC_SINGLE | MAGIC_WUPC;
|
||||||
memset(block0, 0, sizeof(block0));
|
memset(block0, 0, sizeof(block0));
|
||||||
res = mfCGetBlock(0, block0, params);
|
res = mfCGetBlock(0, block0, params);
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
|
@ -1123,13 +1123,13 @@ int mfCSetUID(uint8_t *uid, uint8_t uidlen, const uint8_t *atqa, const uint8_t *
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mfCWipe(uint8_t *uid, const uint8_t *atqa, const uint8_t *sak) {
|
int mfCWipe(uint8_t *uid, const uint8_t *atqa, const uint8_t *sak, uint8_t gdm) {
|
||||||
uint8_t block0[MFBLOCK_SIZE] = {0x00, 0x56, 0x78, 0xBB, 0x95, 0x08, 0x04, 0x00, 0x02, 0xB2, 0x1E, 0x24, 0x23, 0x27, 0x1E, 0x1D};
|
uint8_t block0[MFBLOCK_SIZE] = {0x00, 0x56, 0x78, 0xBB, 0x95, 0x08, 0x04, 0x00, 0x02, 0xB2, 0x1E, 0x24, 0x23, 0x27, 0x1E, 0x1D};
|
||||||
// uint8_t block0[MFBLOCK_SIZE] = {0x04, 0x03, 0x02, 0x01, 0x04, 0x08, 0x04, 0x00, 0x64, 0xB9, 0x95, 0x11, 0x4D, 0x20, 0x42, 0x09};
|
// uint8_t block0[MFBLOCK_SIZE] = {0x04, 0x03, 0x02, 0x01, 0x04, 0x08, 0x04, 0x00, 0x64, 0xB9, 0x95, 0x11, 0x4D, 0x20, 0x42, 0x09};
|
||||||
uint8_t blockD[MFBLOCK_SIZE] = {0x00};
|
uint8_t blockD[MFBLOCK_SIZE] = {0x00};
|
||||||
// default transport ACL
|
// default transport ACL
|
||||||
uint8_t blockK[MFBLOCK_SIZE] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
uint8_t blockK[MFBLOCK_SIZE] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x80, 0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
uint8_t params = MAGIC_SINGLE;
|
uint8_t params = MAGIC_SINGLE | (gdm ? MAGIC_GDM_ALT_WUPC : MAGIC_WUPC);
|
||||||
|
|
||||||
if (uid != NULL) {
|
if (uid != NULL) {
|
||||||
memcpy(block0, uid, 4);
|
memcpy(block0, uid, 4);
|
||||||
|
|
|
@ -92,8 +92,8 @@ int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||||
int mfEmlSetMem(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 mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth);
|
||||||
|
|
||||||
int mfCSetUID(uint8_t *uid, uint8_t uidlen, const uint8_t *atqa, const uint8_t *sak, uint8_t *old_uid, uint8_t *verifed_uid, uint8_t wipecard);
|
int mfCSetUID(uint8_t *uid, uint8_t uidlen, const uint8_t *atqa, const uint8_t *sak, uint8_t *old_uid, uint8_t *verifed_uid, uint8_t wipecard, uint8_t gdm);
|
||||||
int mfCWipe(uint8_t *uid, const uint8_t *atqa, const uint8_t *sak);
|
int mfCWipe(uint8_t *uid, const uint8_t *atqa, const uint8_t *sak, uint8_t gdm);
|
||||||
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params);
|
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 mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);
|
||||||
|
|
||||||
|
|
|
@ -250,6 +250,8 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
// bit 3 - turn on FPGA
|
// bit 3 - turn on FPGA
|
||||||
// bit 4 - turn off FPGA
|
// bit 4 - turn off FPGA
|
||||||
// bit 5 - set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
|
// bit 5 - set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
|
||||||
|
// bit 6 - wipe tag.
|
||||||
|
// bit 7 - use USCUID/GDM (20/23) magic wakeup
|
||||||
#define MAGIC_UID 0x01
|
#define MAGIC_UID 0x01
|
||||||
#define MAGIC_WUPC 0x02
|
#define MAGIC_WUPC 0x02
|
||||||
#define MAGIC_HALT 0x04
|
#define MAGIC_HALT 0x04
|
||||||
|
@ -257,7 +259,8 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
#define MAGIC_OFF 0x10
|
#define MAGIC_OFF 0x10
|
||||||
#define MAGIC_DATAIN 0x20
|
#define MAGIC_DATAIN 0x20
|
||||||
#define MAGIC_WIPE 0x40
|
#define MAGIC_WIPE 0x40
|
||||||
#define MAGIC_SINGLE (MAGIC_WUPC | MAGIC_HALT | MAGIC_INIT | MAGIC_OFF) //0x1E
|
#define MAGIC_GDM_ALT_WUPC 0x80
|
||||||
|
#define MAGIC_SINGLE (MAGIC_HALT | MAGIC_INIT | MAGIC_OFF) //0x1E
|
||||||
|
|
||||||
// by CMD_HF_MIFARE_CIDENT / Flags
|
// by CMD_HF_MIFARE_CIDENT / Flags
|
||||||
#define MAGIC_FLAG_NONE 0x0000
|
#define MAGIC_FLAG_NONE 0x0000
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue