mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
backward compatibility, on load converter for old mfu dump format
This commit is contained in:
parent
8793a9e596
commit
a8c1fa7a3b
6 changed files with 96 additions and 10 deletions
|
@ -1318,6 +1318,9 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) {
|
|||
p_response = NULL;
|
||||
}
|
||||
}
|
||||
} else if (receivedCmd[0] == MIFARE_ULEV1_VCSL) {
|
||||
EmSend4bit(CARD_NACK_NA);
|
||||
p_response = NULL;
|
||||
} else {
|
||||
// Check for ISO 14443A-4 compliant commands, look at left nibble
|
||||
switch (receivedCmd[0]) {
|
||||
|
@ -1371,8 +1374,10 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) {
|
|||
default: {
|
||||
// Never seen this command before
|
||||
LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||
Dbprintf("Received unknown command (len=%d):", len);
|
||||
Dbhexdump(len, receivedCmd, false);
|
||||
if (MF_DBGLEVEL >= 3) {
|
||||
Dbprintf("Received unknown command (len=%d):", len);
|
||||
Dbhexdump(len, receivedCmd, false);
|
||||
}
|
||||
// Do not respond
|
||||
dynamic_response_info.response_n = 0;
|
||||
}
|
||||
|
@ -1388,7 +1393,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) {
|
|||
dynamic_response_info.response_n += 2;
|
||||
|
||||
if (prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE) == false) {
|
||||
DbpString("Error preparing tag response");
|
||||
if (MF_DBGLEVEL >= 3) DbpString("Error preparing tag response");
|
||||
LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2590,6 +2590,16 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
|||
return 2;
|
||||
}
|
||||
|
||||
// convert old mfu format to new
|
||||
if (blockWidth == 4) {
|
||||
res = convertOldMfuDump(&data, &datalen);
|
||||
if (res) {
|
||||
PrintAndLogEx(FAILED, "Failed convert on load to new Ultralight/NTAG format");
|
||||
free(data);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "Copying to emulator memory");
|
||||
|
||||
blockNum = 0;
|
||||
|
|
|
@ -1973,7 +1973,7 @@ static int CmdHF14AMfUDump(const char *Cmd) {
|
|||
fptr += sprintf(fptr, "hf-mfu-");
|
||||
FillFileNameByUID(fptr, card.uid, "-dump", card.uidlen);
|
||||
}
|
||||
uint16_t datalen = pages * 4 + DUMP_PREFIX_LENGTH;
|
||||
uint16_t datalen = pages * 4 + MFU_DUMP_PREFIX_LENGTH;
|
||||
saveFile(filename, "bin", (uint8_t *)&dump_file_data, datalen);
|
||||
saveFileJSON(filename, "json", jsfMfuMemory, (uint8_t *)&dump_file_data, datalen);
|
||||
|
||||
|
@ -2094,14 +2094,22 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
|||
// read all data
|
||||
size_t bytes_read = fread(dump, 1, fsize, f);
|
||||
fclose(f);
|
||||
if (bytes_read < DUMP_PREFIX_LENGTH) {
|
||||
if (bytes_read < MFU_DUMP_PREFIX_LENGTH) {
|
||||
PrintAndLogEx(WARNING, "Error, dump file is too small");
|
||||
free(dump);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// convert old format to new format, if need
|
||||
int res = convertOldMfuDump(&dump, &bytes_read);
|
||||
if (res) {
|
||||
PrintAndLogEx(WARNING, "Failed convert on load to new Ultralight/NTAG format");
|
||||
free(dump);
|
||||
return res;
|
||||
}
|
||||
|
||||
mfu_dump_t *mem = (mfu_dump_t *)dump;
|
||||
uint8_t pages = (bytes_read - DUMP_PREFIX_LENGTH) / 4;
|
||||
uint8_t pages = (bytes_read - MFU_DUMP_PREFIX_LENGTH) / 4;
|
||||
|
||||
if (pages - 1 != mem->pages) {
|
||||
PrintAndLogEx(WARNING, "Error, invalid dump, wrong page count");
|
||||
|
@ -2142,7 +2150,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
|||
|
||||
if (read_key) {
|
||||
// try reading key from dump and use.
|
||||
memcpy(c.d.asBytes, mem->data + (bytes_read - DUMP_PREFIX_LENGTH - 8), 4);
|
||||
memcpy(c.d.asBytes, mem->data + (bytes_read - MFU_DUMP_PREFIX_LENGTH - 8), 4);
|
||||
} else {
|
||||
memcpy(c.d.asBytes, p_authkey, 4);
|
||||
}
|
||||
|
@ -2160,7 +2168,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
|
|||
|
||||
// pack now stored in dump
|
||||
c.arg[0] = MFU_NTAG_SPECIAL_PACK;
|
||||
memcpy(c.d.asBytes, mem->data + (bytes_read - DUMP_PREFIX_LENGTH - 4), 2);
|
||||
memcpy(c.d.asBytes, mem->data + (bytes_read - MFU_DUMP_PREFIX_LENGTH - 4), 2);
|
||||
c.d.asBytes[2] = 0;
|
||||
c.d.asBytes[3] = 0;
|
||||
PrintAndLogEx(NORMAL, "special PACK block written 0x%X - %s\n", MFU_NTAG_SPECIAL_PACK, sprint_hex(c.d.asBytes, 4));
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
#include "comms.h"
|
||||
#include "loclass/fileutils.h"
|
||||
|
||||
|
||||
// New Ultralight/NTAG dump file format
|
||||
// Length must be aligned to 4 bytes (UL/NTAG page)
|
||||
#define DUMP_PREFIX_LENGTH 56
|
||||
#define MFU_DUMP_PREFIX_LENGTH 56
|
||||
|
||||
typedef struct {
|
||||
uint8_t version[8];
|
||||
|
@ -25,6 +27,22 @@ typedef struct {
|
|||
uint8_t data[1024];
|
||||
} mfu_dump_t;
|
||||
|
||||
// Old Ultralight/NTAG dump file format
|
||||
// It is used only for converting
|
||||
#define OLD_MFU_DUMP_PREFIX_LENGTH 48
|
||||
|
||||
typedef struct {
|
||||
uint8_t version[8];
|
||||
uint8_t tbo[2];
|
||||
uint8_t tearing[3];
|
||||
uint8_t pack[2];
|
||||
uint8_t tbo1[1];
|
||||
uint8_t signature[32];
|
||||
//uint8_t counter[3];
|
||||
uint8_t data[1024];
|
||||
} old_mfu_dump_t;
|
||||
|
||||
|
||||
uint32_t GetHF14AMfU_Type(void);
|
||||
int ul_print_type(uint32_t tagtype, uint8_t spaces);
|
||||
|
||||
|
|
|
@ -233,7 +233,7 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty
|
|||
}
|
||||
|
||||
// size of header 56b
|
||||
size_t len = (datalen - DUMP_PREFIX_LENGTH) / 4;
|
||||
size_t len = (datalen - MFU_DUMP_PREFIX_LENGTH) / 4;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
sprintf(path, "$.blocks.%zu", i);
|
||||
|
@ -568,6 +568,41 @@ out:
|
|||
return retval;
|
||||
}
|
||||
|
||||
int convertOldMfuDump(uint8_t **dump, size_t *dumplen) {
|
||||
if (!dump || !dumplen || *dumplen < OLD_MFU_DUMP_PREFIX_LENGTH)
|
||||
return 1;
|
||||
// try to check new file format
|
||||
mfu_dump_t *mfu_dump = (mfu_dump_t *) *dump;
|
||||
if ((*dumplen - MFU_DUMP_PREFIX_LENGTH) / 4 - 1 == mfu_dump->pages)
|
||||
return 0;
|
||||
// convert old format
|
||||
old_mfu_dump_t *old_mfu_dump = (old_mfu_dump_t *) *dump;
|
||||
|
||||
size_t old_data_len = *dumplen - OLD_MFU_DUMP_PREFIX_LENGTH;
|
||||
size_t new_dump_len = old_data_len + MFU_DUMP_PREFIX_LENGTH;
|
||||
|
||||
mfu_dump = (mfu_dump_t *) calloc(new_dump_len, sizeof(uint8_t));
|
||||
|
||||
memcpy(mfu_dump->version, old_mfu_dump->version, 8);
|
||||
mfu_dump->tbo[0] = old_mfu_dump->tbo[0];
|
||||
mfu_dump->tbo[1] = old_mfu_dump->tbo[1];
|
||||
mfu_dump->tbo1[0] = old_mfu_dump->tbo1[0];
|
||||
memcpy(mfu_dump->signature, old_mfu_dump->signature, 32);
|
||||
mfu_dump->counter_tearing[0][3] = old_mfu_dump->tearing[0];
|
||||
mfu_dump->counter_tearing[1][3] = old_mfu_dump->tearing[1];
|
||||
mfu_dump->counter_tearing[2][3] = old_mfu_dump->tearing[2];
|
||||
|
||||
memcpy(mfu_dump->data, old_mfu_dump->data, old_data_len);
|
||||
mfu_dump->pages = old_data_len / 4 - 1;
|
||||
// free old buffer, return new buffer
|
||||
*dumplen = new_dump_len;
|
||||
free(*dump);
|
||||
*dump = (uint8_t *) mfu_dump;
|
||||
PrintAndLogDevice(SUCCESS, "old mfu dump format, was converted on load to " _GREEN_("%d") " pages", mfu_dump->pages + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#else //if we're on ARM
|
||||
|
||||
#endif
|
||||
|
|
|
@ -158,6 +158,15 @@ int loadFileJSON(const char *preferredName, const char *suffix, void *data, size
|
|||
*/
|
||||
int loadFileDICTIONARY(const char *preferredName, const char *suffix, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt);
|
||||
|
||||
/**
|
||||
* @brief Utility function to check and convert old mfu dump format to new
|
||||
*
|
||||
* @param dump pointer to loaded dump to check and convert format
|
||||
* @param dumplen the number of bytes loaded dump and converted
|
||||
* @return 0 for ok, 1 for fails
|
||||
*/
|
||||
int convertOldMfuDump(uint8_t **dump, size_t *dumplen);
|
||||
|
||||
#define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args)
|
||||
#else
|
||||
|
||||
|
@ -171,6 +180,7 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void *data
|
|||
#define PrintAndLogDevice(level, format, args...) { }
|
||||
|
||||
|
||||
|
||||
#endif //ON_DEVICE
|
||||
|
||||
#endif // FILEUTILS_H
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue