mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 13:23:51 -07:00
hf mf restore got some textual updates in order to be easier to understand if keyB writes fails. We use a default ACL when wiping a card that doesnt allow key B to be used for writing. Restore command tries key B first, so there will be several failed key b attempts normally.
This commit is contained in:
parent
1cb15c84c1
commit
e5b075ed3b
2 changed files with 28 additions and 27 deletions
|
@ -1352,7 +1352,7 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Using key file... `" _YELLOW_("%s") "`", keyfilename);
|
PrintAndLogEx(INFO, "Using key file `" _YELLOW_("%s") "`", keyfilename);
|
||||||
|
|
||||||
// try reading card uid and create filename
|
// try reading card uid and create filename
|
||||||
if (datafnlen == 0) {
|
if (datafnlen == 0) {
|
||||||
|
@ -1383,10 +1383,9 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
// default authentication key
|
// default authentication key
|
||||||
uint8_t default_key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
uint8_t default_key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "Restoring " _YELLOW_("%s")" to card", datafilename);
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(INFO, " blk | data | status");
|
||||||
PrintAndLogEx(INFO, " blk | ");
|
PrintAndLogEx(INFO, "-----+-------------------------------------------------+----------------");
|
||||||
PrintAndLogEx(INFO, "-----+------------------------------------------------------------");
|
|
||||||
|
|
||||||
// main loop for restoring.
|
// main loop for restoring.
|
||||||
// a bit more complicated than needed
|
// a bit more complicated than needed
|
||||||
|
@ -1402,6 +1401,8 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
|
|
||||||
// if sector trailer
|
// if sector trailer
|
||||||
if (mfIsSectorTrailerBasedOnBlocks(s, b)) {
|
if (mfIsSectorTrailerBasedOnBlocks(s, b)) {
|
||||||
|
|
||||||
|
// keep the current keys on the card
|
||||||
if (use_keyfile_for_auth == false) {
|
if (use_keyfile_for_auth == false) {
|
||||||
// replace KEY A
|
// replace KEY A
|
||||||
memcpy(bldata, keyA + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE);
|
memcpy(bldata, keyA + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE);
|
||||||
|
@ -1440,10 +1441,13 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
|
|
||||||
for (int8_t kt = MF_KEY_B; kt > -1; kt--) {
|
for (int8_t kt = MF_KEY_B; kt > -1; kt--) {
|
||||||
if (use_keyfile_for_auth) {
|
if (use_keyfile_for_auth) {
|
||||||
if (kt == MF_KEY_A)
|
|
||||||
|
if (kt == MF_KEY_A) {
|
||||||
memcpy(wdata, keyA + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE);
|
memcpy(wdata, keyA + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE);
|
||||||
else
|
} else {
|
||||||
memcpy(wdata, keyB + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE);
|
memcpy(wdata, keyB + (s * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// use default key to authenticate for the write command
|
// use default key to authenticate for the write command
|
||||||
memcpy(wdata, default_key, MIFARE_KEY_SIZE);
|
memcpy(wdata, default_key, MIFARE_KEY_SIZE);
|
||||||
|
@ -1451,8 +1455,6 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
|
|
||||||
uint16_t blockno = (mfFirstBlockOfSector(s) + b);
|
uint16_t blockno = (mfFirstBlockOfSector(s) + b);
|
||||||
|
|
||||||
PrintAndLogEx(INFO, " %3d | %s", blockno, sprint_hex(bldata, sizeof(bldata)));
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_MIFARE_WRITEBL, blockno, kt, 0, wdata, sizeof(wdata));
|
SendCommandMIX(CMD_HF_MIFARE_WRITEBL, blockno, kt, 0, wdata, sizeof(wdata));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
|
@ -1464,22 +1466,20 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
int isOK = resp.oldarg[0] & 0xff;
|
int isOK = resp.oldarg[0] & 0xff;
|
||||||
if (isOK == 1) {
|
if (isOK == 1) {
|
||||||
// if success, skip to next block
|
// if success, skip to next block
|
||||||
|
PrintAndLogEx(INFO, " %3d | %s| ( " _GREEN_("ok") " )", blockno, sprint_hex(bldata, sizeof(bldata)));
|
||||||
break;
|
break;
|
||||||
} else if (isOK == PM3_ETEAROFF) {
|
}
|
||||||
|
// write somehow failed. Lets determine why.
|
||||||
|
if (isOK == PM3_ETEAROFF) {
|
||||||
PrintAndLogEx(INFO, "Tear off triggerd. Recommendation is not to use tear-off with restore command");
|
PrintAndLogEx(INFO, "Tear off triggerd. Recommendation is not to use tear-off with restore command");
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
}
|
||||||
if (b == 0) {
|
|
||||||
PrintAndLogEx(INFO, "Writing to manufacture block w key " _YELLOW_("%c") " ( " _RED_("fail") " )",
|
PrintAndLogEx(INFO, " %3d | %s| ( " _RED_("fail") " ) key " _YELLOW_("%c"),
|
||||||
(kt == MF_KEY_A) ? 'A' : 'B'
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
PrintAndLogEx(FAILED, "Write to block " _YELLOW_("%u") " w key " _YELLOW_("%c") " ( " _RED_("fail") " ) ",
|
|
||||||
blockno,
|
blockno,
|
||||||
|
sprint_hex(bldata, sizeof(bldata)),
|
||||||
(kt == MF_KEY_A) ? 'A' : 'B'
|
(kt == MF_KEY_A) ? 'A' : 'B'
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
} // end loop key types
|
} // end loop key types
|
||||||
} // end loop B
|
} // end loop B
|
||||||
} // end loop S
|
} // end loop S
|
||||||
|
@ -1488,7 +1488,7 @@ out:
|
||||||
free(ref_dump);
|
free(ref_dump);
|
||||||
free(keyA);
|
free(keyA);
|
||||||
free(keyB);
|
free(keyB);
|
||||||
PrintAndLogEx(INFO, "-----+------------------------------------------------------------");
|
PrintAndLogEx(INFO, "-----+-------------------------------------------------+----------------");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "Done!");
|
PrintAndLogEx(INFO, "Done!");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
|
|
@ -215,6 +215,7 @@ char *newfilenamemcopyEx(const char *preferredName, const char *suffix, savePath
|
||||||
if (str_endswith(preferredName, suffix)) {
|
if (str_endswith(preferredName, suffix)) {
|
||||||
p_namelen -= strlen(suffix);
|
p_namelen -= strlen(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// modify filename
|
// modify filename
|
||||||
snprintf(pfn, len, "%.*s%s", (int)p_namelen, preferredName, suffix);
|
snprintf(pfn, len, "%.*s%s", (int)p_namelen, preferredName, suffix);
|
||||||
|
|
||||||
|
@ -862,7 +863,7 @@ int loadFile_safeEx(const char *preferredName, const char *suffix, void **pdata,
|
||||||
*datalen = bytes_read;
|
*datalen = bytes_read;
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from binary file " _YELLOW_("%s"), bytes_read, preferredName);
|
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from binary file `" _YELLOW_("%s") "`", bytes_read, preferredName);
|
||||||
}
|
}
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -936,7 +937,7 @@ int loadFileEML_safe(const char *preferredName, void **pdata, size_t *datalen) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from text file " _YELLOW_("%s"), counter, preferredName);
|
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from text file `" _YELLOW_("%s") "`", counter, preferredName);
|
||||||
|
|
||||||
|
|
||||||
uint8_t *newdump = realloc(*pdata, counter);
|
uint8_t *newdump = realloc(*pdata, counter);
|
||||||
|
@ -1023,7 +1024,7 @@ int loadFileMCT_safe(const char *preferredName, void **pdata, size_t *datalen) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from MCT file " _YELLOW_("%s"), counter, preferredName);
|
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from MCT file `" _YELLOW_("%s") "`", counter, preferredName);
|
||||||
|
|
||||||
|
|
||||||
uint8_t *newdump = realloc(*pdata, counter);
|
uint8_t *newdump = realloc(*pdata, counter);
|
||||||
|
@ -1059,7 +1060,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
||||||
json_error_t error;
|
json_error_t error;
|
||||||
json_t *root = json_load_file(path, 0, &error);
|
json_t *root = json_load_file(path, 0, &error);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), path);
|
PrintAndLogEx(SUCCESS, "loaded from JSON file `" _YELLOW_("%s") "`", path);
|
||||||
|
|
||||||
free(path);
|
free(path);
|
||||||
|
|
||||||
|
@ -1467,7 +1468,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") " keys from dictionary file " _YELLOW_("%s"), vkeycnt, path);
|
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") " keys from dictionary file `" _YELLOW_("%s") "`", vkeycnt, path);
|
||||||
|
|
||||||
if (datalen)
|
if (datalen)
|
||||||
*datalen = counter;
|
*datalen = counter;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue