Support for option (X)
Signed-off-by: codetector <codetector@codetector.cn>
This commit is contained in:
parent
f8b28523d7
commit
b677020350
@ -41,6 +41,9 @@ option allows writing of special MIFARE cards that can be 'unlocked' to allow bl
|
|||||||
to be overwritten. This includes UID and manufacturer data. Take care when amending UIDs to set
|
to be overwritten. This includes UID and manufacturer data. Take care when amending UIDs to set
|
||||||
the correct BCC (UID checksum). Currently only 4 byte UIDs are supported.
|
the correct BCC (UID checksum). Currently only 4 byte UIDs are supported.
|
||||||
|
|
||||||
|
Like the .B W option, the .B X option also enables block 0 write, but to some Chinese card
|
||||||
|
that allow block 0 write with a normal write command instead of needing to "unlock".
|
||||||
|
|
||||||
Similarly, the
|
Similarly, the
|
||||||
.B R
|
.B R
|
||||||
option allows an 'unlocked' read. This bypasses authentication and allows
|
option allows an 'unlocked' read. This bypasses authentication and allows
|
||||||
@ -74,7 +77,7 @@ options only work on special versions of MIFARE 1K cards (Chinese clones).
|
|||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.BR f " | " r " | " R " | " w " | " W
|
.BR f " | " r " | " R " | " w " | " W " | " X
|
||||||
Perform format (
|
Perform format (
|
||||||
.B f
|
.B f
|
||||||
) or read from (
|
) or read from (
|
||||||
@ -85,6 +88,8 @@ Perform format (
|
|||||||
.B w
|
.B w
|
||||||
) or unlocked write to (
|
) or unlocked write to (
|
||||||
.B W
|
.B W
|
||||||
|
) or normal write with block 0 to (
|
||||||
|
.B X
|
||||||
) card.
|
) card.
|
||||||
.TP
|
.TP
|
||||||
.BR a " | " A " | " b " | " B
|
.BR a " | " A " | " b " | " B
|
||||||
|
|||||||
@ -70,7 +70,7 @@ static bool bUseKeyFile;
|
|||||||
static bool bForceKeyFile;
|
static bool bForceKeyFile;
|
||||||
static bool bTolerateFailures;
|
static bool bTolerateFailures;
|
||||||
static bool bFormatCard;
|
static bool bFormatCard;
|
||||||
static bool magic2 = false;
|
static bool chinese_uid_writable_mode = false;
|
||||||
static bool magic3 = false;
|
static bool magic3 = false;
|
||||||
static bool unlocked = false;
|
static bool unlocked = false;
|
||||||
static bool bForceSizeMismatch;
|
static bool bForceSizeMismatch;
|
||||||
@ -326,7 +326,7 @@ read_card(int read_unlocked)
|
|||||||
if (read_unlocked) {
|
if (read_unlocked) {
|
||||||
//If the user is attempting an unlocked read, but has a direct-write type magic card, they don't
|
//If the user is attempting an unlocked read, but has a direct-write type magic card, they don't
|
||||||
//need to use the R mode. We'll trigger a warning and let them proceed.
|
//need to use the R mode. We'll trigger a warning and let them proceed.
|
||||||
if (magic2) {
|
if (chinese_uid_writable_mode) {
|
||||||
printf("Note: This card does not require an unlocked read (R) \n");
|
printf("Note: This card does not require an unlocked read (R) \n");
|
||||||
read_unlocked = 0;
|
read_unlocked = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -414,7 +414,7 @@ write_card(int write_block_zero)
|
|||||||
if (write_block_zero) {
|
if (write_block_zero) {
|
||||||
//If the user is attempting an unlocked write, but has a direct-write type magic card, they don't
|
//If the user is attempting an unlocked write, but has a direct-write type magic card, they don't
|
||||||
//need to use the W mode. We'll trigger a warning and let them proceed.
|
//need to use the W mode. We'll trigger a warning and let them proceed.
|
||||||
if (magic2) {
|
if (chinese_uid_writable_mode) {
|
||||||
printf("Note: This card does not require an unlocked write (W) \n");
|
printf("Note: This card does not require an unlocked write (W) \n");
|
||||||
write_block_zero = 0;
|
write_block_zero = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -472,7 +472,7 @@ write_card(int write_block_zero)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// The first block 0x00 is read only, skip this
|
// The first block 0x00 is read only, skip this
|
||||||
if (uiBlock == 0 && !write_block_zero && !magic2)
|
if (uiBlock == 0 && !write_block_zero && !chinese_uid_writable_mode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Make sure a earlier write did not fail
|
// Make sure a earlier write did not fail
|
||||||
@ -485,7 +485,7 @@ write_card(int write_block_zero)
|
|||||||
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, sizeof(mp.mpd.abtData));
|
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, sizeof(mp.mpd.abtData));
|
||||||
// do not write a block 0 with incorrect BCC - card will be made invalid!
|
// do not write a block 0 with incorrect BCC - card will be made invalid!
|
||||||
if (uiBlock == 0) {
|
if (uiBlock == 0) {
|
||||||
if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !magic2) {
|
if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !chinese_uid_writable_mode) {
|
||||||
printf("!\nError: incorrect BCC in MFD file!\n");
|
printf("!\nError: incorrect BCC in MFD file!\n");
|
||||||
printf("Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]);
|
printf("Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]);
|
||||||
return false;
|
return false;
|
||||||
@ -508,13 +508,13 @@ write_card(int write_block_zero)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Write Block 0 if necessary
|
//Write Block 0 if necessary
|
||||||
if (write_block_zero || magic2 || magic3) {
|
if (write_block_zero || chinese_uid_writable_mode || magic3) {
|
||||||
for (uiBlock = 0; uiBlock < 4; uiBlock++) {
|
for (uiBlock = 0; uiBlock < 4; uiBlock++) {
|
||||||
|
|
||||||
// The first block 0x00 is read only, skip this
|
// The first block 0x00 is read only, skip this
|
||||||
if (uiBlock == 0) {
|
if (uiBlock == 0) {
|
||||||
//If the card is not magic, we're gonna skip over
|
//If the card is not magic, we're gonna skip over
|
||||||
if (write_block_zero || magic2 || magic3) {
|
if (write_block_zero || chinese_uid_writable_mode || magic3) {
|
||||||
//NOP
|
//NOP
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
@ -553,7 +553,7 @@ write_card(int write_block_zero)
|
|||||||
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, sizeof(mp.mpd.abtData));
|
memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, sizeof(mp.mpd.abtData));
|
||||||
// do not write a block 0 with incorrect BCC - card will be made invalid!
|
// do not write a block 0 with incorrect BCC - card will be made invalid!
|
||||||
if (uiBlock == 0) {
|
if (uiBlock == 0) {
|
||||||
if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !magic2) {
|
if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !chinese_uid_writable_mode) {
|
||||||
printf("!\nError: incorrect BCC in MFD file!\n");
|
printf("!\nError: incorrect BCC in MFD file!\n");
|
||||||
printf("Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]);
|
printf("Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]);
|
||||||
return false;
|
return false;
|
||||||
@ -594,12 +594,13 @@ static void
|
|||||||
print_usage(const char *pcProgramName)
|
print_usage(const char *pcProgramName)
|
||||||
{
|
{
|
||||||
printf("Usage: ");
|
printf("Usage: ");
|
||||||
printf("%s f|r|R|w|W a|b u|U<01ab23cd> <dump.mfd> [<keys.mfd> [f]]\n", pcProgramName);
|
printf("%s f|r|R|w|W|X a|b u|U<01ab23cd> <dump.mfd> [<keys.mfd> [f]]\n", pcProgramName);
|
||||||
printf(" f|r|R|w|W - Perform format (f) or read from (r) or unlocked read from (R) or write to (w) or unlocked write to (W) card\n");
|
printf(" f|r|R|w|W|X - Perform format (f) or read from (r) or unlocked read from (R) or write to (w) or unlocked write to (W) / (X) card\n");
|
||||||
printf(" *** format will reset all keys to FFFFFFFFFFFF and all data to 00 and all ACLs to default\n");
|
printf(" *** format will reset all keys to FFFFFFFFFFFF and all data to 00 and all ACLs to default\n");
|
||||||
printf(" *** unlocked read does not require authentication and will reveal A and B keys\n");
|
printf(" *** unlocked read does not require authentication and will reveal A and B keys\n");
|
||||||
printf(" *** note that unlocked write will attempt to overwrite block 0 including UID\n");
|
printf(" *** note that unlocked write will attempt to overwrite block 0 including UID\n");
|
||||||
printf(" *** unlocking only works with special Mifare 1K cards (Chinese clones)\n");
|
printf(" *** unlocking only works with special Mifare 1K cards (Chinese clones)\n");
|
||||||
|
printf(" *** (X) works with some Chinese card that allow block 0 write with normal command.\n");
|
||||||
printf(" a|A|b|B - Use A or B keys for action; Halt on errors (a|b) or tolerate errors (A|B)\n");
|
printf(" a|A|b|B - Use A or B keys for action; Halt on errors (a|b) or tolerate errors (A|B)\n");
|
||||||
printf(" u|U - Use any (u) uid or supply a uid specifically as U01ab23cd.\n");
|
printf(" u|U - Use any (u) uid or supply a uid specifically as U01ab23cd.\n");
|
||||||
printf(" <dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
|
printf(" <dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
|
||||||
@ -696,10 +697,12 @@ main(int argc, const char *argv[])
|
|||||||
bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
|
bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
|
||||||
bUseKeyFile = (argc > 5);
|
bUseKeyFile = (argc > 5);
|
||||||
bForceKeyFile = ((argc > 6) && (strcmp((char *)argv[6], "f") == 0));
|
bForceKeyFile = ((argc > 6) && (strcmp((char *)argv[6], "f") == 0));
|
||||||
} else if (strcmp(command, "w") == 0 || strcmp(command, "W") == 0 || strcmp(command, "f") == 0) {
|
} else if (strcmp(command, "w") == 0 || strcmp(command, "W") == 0 || strcmp(command, "X") == 0 || strcmp(command, "f") == 0) {
|
||||||
atAction = ACTION_WRITE;
|
atAction = ACTION_WRITE;
|
||||||
if (strcmp(command, "W") == 0)
|
if (strcmp(command, "W") == 0)
|
||||||
unlock = 1;
|
unlock = 1;
|
||||||
|
if (strcmp(command, "X") == 0)
|
||||||
|
chinese_uid_writable_mode = true;
|
||||||
bFormatCard = (strcmp(command, "f") == 0);
|
bFormatCard = (strcmp(command, "f") == 0);
|
||||||
bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
|
bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
|
||||||
bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
|
bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
|
||||||
@ -841,7 +844,7 @@ main(int argc, const char *argv[])
|
|||||||
// Chinese magic emulation card, ATS=0978009102:dabc1910
|
// Chinese magic emulation card, ATS=0978009102:dabc1910
|
||||||
if ((res == 9) && (abtRx[5] == 0xda) && (abtRx[6] == 0xbc)
|
if ((res == 9) && (abtRx[5] == 0xda) && (abtRx[6] == 0xbc)
|
||||||
&& (abtRx[7] == 0x19) && (abtRx[8] == 0x10)) {
|
&& (abtRx[7] == 0x19) && (abtRx[8] == 0x10)) {
|
||||||
magic2 = true;
|
chinese_uid_writable_mode = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("Guessing size: seems to be a %lu-byte card\n", (uiBlocks + 1) * sizeof(mifare_classic_block));
|
printf("Guessing size: seems to be a %lu-byte card\n", (uiBlocks + 1) * sizeof(mifare_classic_block));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user