only test DirectWrite write if we need to. only write block 0 if specifically requested to.

This commit is contained in:
Adam Laurie 2020-06-24 20:38:01 +01:00 committed by Unknown
parent e560689f60
commit 7b6ff73c4b

View file

@ -325,7 +325,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 (magic2 || magic3) {
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 {
@ -411,25 +411,18 @@ write_card(int write_block_zero)
//Determine if we have to unlock the card //Determine if we have to unlock the card
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 (!magic2 && !magic3) {
//need to use the W mode. We'll trigger a warning and let them proceed.
if (magic2) {
printf("Note: This card does not require an unlocked write (W) \n");
write_block_zero = 0;
} else {
//If User has requested an unlocked write, but we're unable to unlock the card, we'll error out.
if (!unlock_card()) { if (!unlock_card()) {
return false; return false;
} }
} }
} }
printf("Writing %d blocks |", uiBlocks + 1); printf("Writing %d blocks |", uiBlocks + write_block_zero);
// Completely write the card, end to start, but skipping block 0 // Completely write the card, but skipping block 0
for (uiBlock = 4; uiBlock <= uiBlocks; uiBlock++) { for (uiBlock = 1; uiBlock <= uiBlocks; uiBlock++) {
printf("{%d}",uiBlock);
// Authenticate everytime we reach the first sector of a new block // Authenticate everytime we reach the first sector of a new block
if (is_first_block(uiBlock)) { if (uiBlock == 1 || is_first_block(uiBlock)) {
if (bFailure) { if (bFailure) {
// When a failure occured we need to redo the anti-collision // When a failure occured we need to redo the anti-collision
if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) { if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
@ -439,7 +432,6 @@ write_card(int write_block_zero)
bFailure = false; bFailure = false;
} }
printf("[%d]",uiBlock);
fflush(stdout); fflush(stdout);
// Try to authenticate for the current sector // Try to authenticate for the current sector
@ -455,7 +447,6 @@ write_card(int write_block_zero)
} }
if (is_trailer_block(uiBlock)) { if (is_trailer_block(uiBlock)) {
printf("t");
if (bFormatCard) { if (bFormatCard) {
// Copy the default key and reset the access bits // Copy the default key and reset the access bits
memcpy(mp.mpt.abtKeyA, default_key, sizeof(mp.mpt.abtKeyA)); memcpy(mp.mpt.abtKeyA, default_key, sizeof(mp.mpt.abtKeyA));
@ -474,10 +465,6 @@ write_card(int write_block_zero)
bFailure = true; bFailure = true;
} }
} else { } else {
// The first block 0x00 is read only, skip this
if (uiBlock == 0 && !write_block_zero && !magic2)
continue;
// Make sure a earlier write did not fail // Make sure a earlier write did not fail
if (!bFailure) { if (!bFailure) {
// Try to write the data block // Try to write the data block
@ -486,7 +473,6 @@ write_card(int write_block_zero)
memset(mp.mpd.abtData, 0x00, sizeof(mp.mpd.abtData)); memset(mp.mpd.abtData, 0x00, sizeof(mp.mpd.abtData));
else else
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));
printf("(%d)%d",uiBlock,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 && !magic2) {
@ -511,20 +497,9 @@ write_card(int write_block_zero)
return false; return false;
} }
//Write Block 0 if necessary //Write Block 0 if requested to do so
if (write_block_zero || magic2 || magic3) { if (write_block_zero) {
for (uiBlock = 0; uiBlock < 4; uiBlock++) { for (uiBlock = 0; uiBlock < 1; uiBlock++) {
printf("-%d-",uiBlock);
// The first block 0x00 is read only, skip this
if (uiBlock == 0) {
//If the card is not magic, we're gonna skip over
if (write_block_zero || magic2 || magic3) {
//NOP
} else {
continue;
}
}
if (is_first_block(uiBlock)) { if (is_first_block(uiBlock)) {
if (bFailure) { if (bFailure) {
@ -556,15 +531,12 @@ write_card(int write_block_zero)
memset(mp.mpd.abtData, 0x00, sizeof(mp.mpd.abtData)); memset(mp.mpd.abtData, 0x00, sizeof(mp.mpd.abtData));
else else
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));
printf("<%d>",uiBlock);
// 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 ((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 && !magic2) {
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;
} }
}
if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp)) { if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp)) {
bFailure = true; bFailure = true;
printf("Failure to write to data block %i\n", uiBlock); printf("Failure to write to data block %i\n", uiBlock);
@ -574,13 +546,12 @@ write_card(int write_block_zero)
printf("Failure during write process.\n"); printf("Failure during write process.\n");
} }
// Show if the write went well for each block // Show if the write went well for block 0
print_success_or_failure(bFailure, &uiWriteBlocks); print_success_or_failure(bFailure, &uiWriteBlocks);
if ((! bTolerateFailures) && bFailure) if ((! bTolerateFailures) && bFailure)
return false; return false;
} }
} }
printf("|\n"); printf("|\n");
@ -627,7 +598,7 @@ print_usage(const char *pcProgramName)
} }
static bool is_directwrite(void) static bool is_directwrite(bool test_write)
{ {
printf("Checking if Badge is DirectWrite...\n"); printf("Checking if Badge is DirectWrite...\n");
@ -664,6 +635,9 @@ static bool is_directwrite(void)
return false; return false;
} }
if(!test_write)
return true;
printf(" Attempt to write Block 0 ...\n"); printf(" Attempt to write Block 0 ...\n");
memcpy(mp.mpd.abtData, original_b0, sizeof(original_b0)); memcpy(mp.mpd.abtData, original_b0, sizeof(original_b0));
if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, 0, &mp)) { if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, 0, &mp)) {
@ -771,6 +745,14 @@ main(int argc, const char *argv[])
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}; };
// Drop the field for a while, so can be reset
if (nfc_device_set_property_bool(pnd, NP_ACTIVATE_FIELD, true) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool activate field");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
}
// Let the reader only try once to find a tag // Let the reader only try once to find a tag
if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) { if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
@ -786,11 +768,24 @@ main(int argc, const char *argv[])
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Configure the CRC and Parity settings
if (nfc_device_set_property_bool(pnd, NP_HANDLE_CRC, true) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool crc");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
}
if (nfc_device_set_property_bool(pnd, NP_HANDLE_PARITY, true) < 0) {
nfc_perror(pnd, "nfc_device_set_property_bool parity");
nfc_close(pnd);
nfc_exit(context);
exit(EXIT_FAILURE);
}
printf("NFC reader: %s opened\n", nfc_device_get_name(pnd)); printf("NFC reader: %s opened\n", nfc_device_get_name(pnd));
// Try to find a MIFARE Classic tag // Try to find a MIFARE Classic tag
int tags; int tags;
tags = nfc_initiator_select_passive_target(pnd, nmMifare, tag_uid, tag_uid == NULL ? 0 : 4, &nt); tags = nfc_initiator_select_passive_target(pnd, nmMifare, tag_uid, tag_uid == NULL ? 0 : 4, &nt);
if (tags <= 0) { if (tags <= 0) {
printf("Error: no tag was found\n"); printf("Error: no tag was found\n");
@ -799,7 +794,8 @@ main(int argc, const char *argv[])
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Test if we are dealing with a MIFARE compatible tag // Test if we are dealing with a MIFARE compatible tag
if ((nt.nti.nai.btSak & 0x08) == 0) { if (((nt.nti.nai.btSak & 0x08) == 0) && (nt.nti.nai.btSak != 0x01)) {
// if ((nt.nti.nai.btSak & 0x08) == 0) {
printf("Warning: tag is probably not a MFC!\n"); printf("Warning: tag is probably not a MFC!\n");
} }
@ -857,12 +853,15 @@ main(int argc, const char *argv[])
//If size is 4k check for direct-write card //If size is 4k check for direct-write card
if (uiBlocks == 0xff) { if (uiBlocks == 0xff) {
if (is_directwrite()) { if (is_directwrite(atAction == ACTION_WRITE)) {
printf("Card is DirectWrite\n"); printf("Card is DirectWrite\n");
magic3 = true; magic3 = true;
unlock = 0;
} else { } else {
printf("Card is not DirectWrite\n"); printf("Card is not DirectWrite\n");
// reset after error
if (nfc_initiator_select_passive_target(pnd, nmMifare, nt.nti.nai.abtUid, nt.nti.nai.szUidLen, NULL) <= 0) {
ERR("tag was removed");
}
} }
} }
@ -871,7 +870,6 @@ main(int argc, const char *argv[])
pbtUID[2] == 0xc3 && pbtUID[3] == 0x96) { pbtUID[2] == 0xc3 && pbtUID[3] == 0x96) {
printf("Card appears to be a One Time Write Card..\n"); printf("Card appears to be a One Time Write Card..\n");
magic3 = true; magic3 = true;
unlock = 0;
} }