mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
added support for loading flipper MFC/MFU dump files.\nFixed NFC DECODE to identify and handle MFU dump files properly
This commit is contained in:
parent
ca04f03cb1
commit
ae6ba395b4
5 changed files with 394 additions and 28 deletions
|
@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
- Fixed `nfc decode` - now properly handles MFU dump files (@iceman1001)
|
||||||
|
- Added support for loading Flipper MCT/MFU dump files (@iceman1001)
|
||||||
- Changed `data bmap` - now default `-m` is 8 (@iceman1001)
|
- Changed `data bmap` - now default `-m` is 8 (@iceman1001)
|
||||||
- Added support for NTAG424 cards. (@dankar)
|
- Added support for NTAG424 cards. (@dankar)
|
||||||
- Additional fixes to configcard code for keyroll mode based on nfc-iclass output (@Antiklesys)
|
- Additional fixes to configcard code for keyroll mode based on nfc-iclass output (@Antiklesys)
|
||||||
|
|
|
@ -113,26 +113,45 @@ static int CmdNfcDecode(const char *Cmd) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert from MFC dump file to a pure NDEF byte array
|
uint8_t *tmp = dump;
|
||||||
if (HasMADKey(dump)) {
|
|
||||||
PrintAndLogEx(SUCCESS, "MFC dump file detected. Converting...");
|
|
||||||
uint8_t ndef[4096] = {0};
|
|
||||||
uint16_t ndeflen = 0;
|
|
||||||
|
|
||||||
if (convert_mad_to_arr(dump, bytes_read, ndef, &ndeflen) != PM3_SUCCESS) {
|
// if not MIFARE Classic default sizes, assume its Ultralight/NTAG
|
||||||
PrintAndLogEx(FAILED, "Failed converting, aborting...");
|
if (bytes_read != 4096 || bytes_read != 2048 || bytes_read != 1024 || bytes_read != 320) {
|
||||||
free(dump);
|
|
||||||
return PM3_ESOFT;
|
uint8_t **pd = &tmp;
|
||||||
|
mfu_df_e df = detect_mfu_dump_format(pd, verbose);
|
||||||
|
if (df == MFU_DF_OLDBIN) {
|
||||||
|
tmp += OLD_MFU_DUMP_PREFIX_LENGTH + (4 * 4);
|
||||||
|
bytes_read -= OLD_MFU_DUMP_PREFIX_LENGTH + ( 4 * 4);
|
||||||
|
} else if (df == MFU_DF_NEWBIN) {
|
||||||
|
tmp += MFU_DUMP_PREFIX_LENGTH + (4 * 4);
|
||||||
|
bytes_read -= MFU_DUMP_PREFIX_LENGTH + ( 4 * 4);
|
||||||
}
|
}
|
||||||
|
pd = NULL;
|
||||||
|
|
||||||
memcpy(dump, ndef, ndeflen);
|
} else {
|
||||||
bytes_read = ndeflen;
|
|
||||||
|
// convert from MFC dump file to a pure NDEF byte array
|
||||||
|
if (HasMADKey(tmp)) {
|
||||||
|
PrintAndLogEx(SUCCESS, "MFC dump file detected. Converting...");
|
||||||
|
uint8_t ndef[4096] = {0};
|
||||||
|
uint16_t ndeflen = 0;
|
||||||
|
|
||||||
|
if (convert_mad_to_arr(tmp, bytes_read, ndef, &ndeflen) != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(FAILED, "Failed converting, aborting...");
|
||||||
|
free(dump);
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(tmp, ndef, ndeflen);
|
||||||
|
bytes_read = ndeflen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = NDEFDecodeAndPrint(dump, bytes_read, verbose);
|
res = NDEFDecodeAndPrint(tmp, bytes_read, verbose);
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header");
|
PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header");
|
||||||
res = NDEFRecordsDecodeAndPrint(dump, bytes_read, verbose);
|
res = NDEFRecordsDecodeAndPrint(tmp, bytes_read, verbose);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(dump);
|
free(dump);
|
||||||
|
|
|
@ -86,6 +86,8 @@ DumpFileType_t getfiletype(const char *filename) {
|
||||||
o = DICTIONARY;
|
o = DICTIONARY;
|
||||||
} else if (str_endswith(s, "mct")) {
|
} else if (str_endswith(s, "mct")) {
|
||||||
o = MCT;
|
o = MCT;
|
||||||
|
} else if (str_endswith(s, "nfc")) {
|
||||||
|
o = NFC;
|
||||||
} else {
|
} else {
|
||||||
// mfd, trc, trace is binary
|
// mfd, trc, trace is binary
|
||||||
o = BIN;
|
o = BIN;
|
||||||
|
@ -1001,6 +1003,195 @@ int loadFileEML_safe(const char *preferredName, void **pdata, size_t *datalen) {
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int loadFileNFC_safe(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, nfc_df_e ft) {
|
||||||
|
|
||||||
|
if (data == NULL) return PM3_EINVARG;
|
||||||
|
|
||||||
|
*datalen = 0;
|
||||||
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
|
char *path;
|
||||||
|
int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, "", false);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *f = fopen(path, "r");
|
||||||
|
if (!f) {
|
||||||
|
PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path);
|
||||||
|
free(path);
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
// 256 + 2 newline chars + 1 null terminator
|
||||||
|
char line[256 + 2 + 1];
|
||||||
|
memset(line, 0, sizeof(line));
|
||||||
|
|
||||||
|
udata_t udata = (udata_t)data;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
while (!feof(f)) {
|
||||||
|
|
||||||
|
memset(line, 0, sizeof(line));
|
||||||
|
|
||||||
|
if (fgets(line, sizeof(line), f) == NULL) {
|
||||||
|
if (feof(f))
|
||||||
|
break;
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
PrintAndLogEx(FAILED, "File reading error.");
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
strcleanrn(line, sizeof(line));
|
||||||
|
str_lower(line);
|
||||||
|
|
||||||
|
|
||||||
|
if (str_startswith(line, "uid:")) {
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
param_gethex_to_eol(line + 4, 0, udata.mfc->card_info.uid, sizeof(udata.mfc->card_info.uid), &n);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_startswith(line, "atqa:")) {
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
param_gethex_to_eol(line + 5, 0, udata.mfc->card_info.atqa, sizeof(udata.mfc->card_info.atqa), &n);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_startswith(line, "sak:")) {
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
int sak = 0;
|
||||||
|
sscanf(line, "sak: %d", &sak);
|
||||||
|
udata.mfc->card_info.sak = sak & 0xFF;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_startswith(line, "signature:")) {
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
} else if (ft == NFC_DF_MFU) {
|
||||||
|
param_gethex_to_eol(line + 11, 0, udata.mfu->signature, sizeof(udata.mfu->signature), &n);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_startswith(line, "mifare version:")) {
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
} else if (ft == NFC_DF_MFU) {
|
||||||
|
param_gethex_to_eol(line + 16, 0, udata.mfu->version, sizeof(udata.mfu->version), &n);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_startswith(line, "counter 0:")) {
|
||||||
|
int no = 0;
|
||||||
|
sscanf(line, "counter 0: %d", &no);
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
} else if (ft == NFC_DF_MFU) {
|
||||||
|
udata.mfu->counter_tearing[0][0] = no & 0xFF;
|
||||||
|
udata.mfu->counter_tearing[0][1] = no & 0xFF;
|
||||||
|
udata.mfu->counter_tearing[0][2] = no & 0xFF;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_startswith(line, "tearing 0:")) {
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
} else if (ft == NFC_DF_MFU) {
|
||||||
|
sscanf(line, "tearing 0: %02x", &n);
|
||||||
|
udata.mfu->counter_tearing[0][3] = n & 0xFF;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_startswith(line, "counter 1:")) {
|
||||||
|
int no = 0;
|
||||||
|
sscanf(line, "counter 1: %d", &no);
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
} else if (ft == NFC_DF_MFU) {
|
||||||
|
udata.mfu->counter_tearing[1][0] = no & 0xFF;
|
||||||
|
udata.mfu->counter_tearing[1][1] = no & 0xFF;
|
||||||
|
udata.mfu->counter_tearing[1][2] = no & 0xFF;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_startswith(line, "tearing 1:")) {
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
} else if (ft == NFC_DF_MFU) {
|
||||||
|
sscanf(line, "tearing 1: %02x", &n);
|
||||||
|
udata.mfu->counter_tearing[1][3] = n & 0xFF;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_startswith(line, "counter 2:")) {
|
||||||
|
int no = 0;
|
||||||
|
sscanf(line, "counter 2: %d", &no);
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
} else if (ft == NFC_DF_MFU) {
|
||||||
|
udata.mfu->counter_tearing[2][0] = no & 0xFF;
|
||||||
|
udata.mfu->counter_tearing[2][1] = no & 0xFF;
|
||||||
|
udata.mfu->counter_tearing[2][2] = no & 0xFF;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_startswith(line, "tearing 2:")) {
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
} else if (ft == NFC_DF_MFU) {
|
||||||
|
sscanf(line, "tearing 2: %02x", &n);
|
||||||
|
udata.mfu->counter_tearing[2][3] = n & 0xFF;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str_startswith(line, "pages total:")) {
|
||||||
|
sscanf(line, "pages total: %d", &n);
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
} else if (ft == NFC_DF_MFU) {
|
||||||
|
udata.mfu->pages = n;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Page 0: 04 10 56 CA
|
||||||
|
if (str_startswith(line, "page ")) {
|
||||||
|
int pageno = 0;
|
||||||
|
sscanf(line, "page %d:", &pageno);
|
||||||
|
|
||||||
|
char *p = line;
|
||||||
|
while (*p++ != ':') {};
|
||||||
|
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
param_gethex_to_eol(p, 0, udata.mfc->dump + (pageno * MFBLOCK_SIZE), MFBLOCK_SIZE, &n);
|
||||||
|
udata.mfc->dumplen += MFBLOCK_SIZE;
|
||||||
|
} else if (ft == NFC_DF_MFU) {
|
||||||
|
param_gethex_to_eol(p, 0, udata.mfu->data + (pageno * MFU_BLOCK_SIZE), MFU_BLOCK_SIZE, &n);
|
||||||
|
*datalen += MFU_BLOCK_SIZE;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add header length
|
||||||
|
if (ft == NFC_DF_MFC) {
|
||||||
|
} else if (ft == NFC_DF_MFU) {
|
||||||
|
*datalen += MFU_DUMP_PREFIX_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " bytes from NFC file `" _YELLOW_("%s") "`", *datalen, preferredName);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
int loadFileMCT_safe(const char *preferredName, void **pdata, size_t *datalen) {
|
int loadFileMCT_safe(const char *preferredName, void **pdata, size_t *datalen) {
|
||||||
char *path;
|
char *path;
|
||||||
int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, "", false);
|
int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, "", false);
|
||||||
|
@ -1926,7 +2117,7 @@ int loadFileBinaryKey(const char *preferredName, const char *suffix, void **keya
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
mfu_df_e detect_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose) {
|
mfu_df_e detect_mfu_dump_format(uint8_t **dump, bool verbose) {
|
||||||
|
|
||||||
mfu_df_e retval = MFU_DF_UNKNOWN;
|
mfu_df_e retval = MFU_DF_UNKNOWN;
|
||||||
uint8_t bcc0, bcc1;
|
uint8_t bcc0, bcc1;
|
||||||
|
@ -1979,6 +2170,99 @@ mfu_df_e detect_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose) {
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfc_df_e detect_nfc_dump_format(const char *preferredName, bool verbose) {
|
||||||
|
|
||||||
|
char *path;
|
||||||
|
int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, "", false);
|
||||||
|
if (res != PM3_SUCCESS) {
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *f = fopen(path, "r");
|
||||||
|
if (!f) {
|
||||||
|
PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path);
|
||||||
|
free(path);
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
|
|
||||||
|
nfc_df_e retval = NFC_DF_UNKNOWN;
|
||||||
|
|
||||||
|
char line[256];
|
||||||
|
memset(line, 0, sizeof(line));
|
||||||
|
|
||||||
|
while (!feof(f)) {
|
||||||
|
|
||||||
|
memset(line, 0, sizeof(line));
|
||||||
|
|
||||||
|
if (fgets(line, sizeof(line), f) == NULL) {
|
||||||
|
if (feof(f)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
PrintAndLogEx(FAILED, "File reading error.");
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcleanrn(line, sizeof(line));
|
||||||
|
str_lower(line);
|
||||||
|
|
||||||
|
if (str_startswith(line, "device type: ntag")) {
|
||||||
|
retval = NFC_DF_MFU;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (str_startswith(line, "device type: mifare classic")) {
|
||||||
|
retval = NFC_DF_MFC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (str_startswith(line, "device type: mifare desfire")) {
|
||||||
|
retval = NFC_DF_MFDES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (str_startswith(line, "device type: iso14443-3a")) {
|
||||||
|
retval = NFC_DF_14_3A;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (str_startswith(line, "device type: iso14443-3b")) {
|
||||||
|
retval = NFC_DF_14_3B;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (str_startswith(line, "device type: iso14443-4a")) {
|
||||||
|
retval = NFC_DF_14_4A;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
switch (retval) {
|
||||||
|
case NFC_DF_MFU:
|
||||||
|
PrintAndLogEx(INFO, "detected MIFARE Ultralight / NTAG based dump format");
|
||||||
|
break;
|
||||||
|
case NFC_DF_MFC:
|
||||||
|
PrintAndLogEx(INFO, "detected MIFARE Classic based dump format");
|
||||||
|
break;
|
||||||
|
case NFC_DF_MFDES:
|
||||||
|
PrintAndLogEx(INFO, "detected MIFARE DESFire based dump format");
|
||||||
|
break;
|
||||||
|
case NFC_DF_14_3A:
|
||||||
|
PrintAndLogEx(INFO, "detected ISO14443-3A based dump format. No data available");
|
||||||
|
break;
|
||||||
|
case NFC_DF_14_3B:
|
||||||
|
PrintAndLogEx(INFO, "detected ISO14443-3B based dump format. No data available");
|
||||||
|
break;
|
||||||
|
case NFC_DF_14_4A:
|
||||||
|
PrintAndLogEx(INFO, "detected ISO14443-4A based dump format. No data available");
|
||||||
|
break;
|
||||||
|
case NFC_DF_UNKNOWN:
|
||||||
|
PrintAndLogEx(WARNING, "failed to detected dump format");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static int convert_plain_mfu_dump(uint8_t **dump, size_t *dumplen, bool verbose) {
|
static int convert_plain_mfu_dump(uint8_t **dump, size_t *dumplen, bool verbose) {
|
||||||
|
|
||||||
mfu_dump_t *mfu = (mfu_dump_t *) calloc(sizeof(mfu_dump_t), sizeof(uint8_t));
|
mfu_dump_t *mfu = (mfu_dump_t *) calloc(sizeof(mfu_dump_t), sizeof(uint8_t));
|
||||||
|
@ -2055,7 +2339,7 @@ int convert_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
mfu_df_e res = detect_mfu_dump_format(dump, dumplen, verbose);
|
mfu_df_e res = detect_mfu_dump_format(dump, verbose);
|
||||||
|
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case MFU_DF_NEWBIN:
|
case MFU_DF_NEWBIN:
|
||||||
|
@ -2419,15 +2703,38 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DICTIONARY: {
|
case DICTIONARY: {
|
||||||
PrintAndLogEx(ERR, "Only BIN/EML/JSON formats allowed");
|
PrintAndLogEx(ERR, "Only <BIN|EML|JSON|MCT|NFC formats allowed");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
case MCT: {
|
case MCT: {
|
||||||
res = loadFileMCT_safe(fn, pdump, dumplen);
|
res = loadFileMCT_safe(fn, pdump, dumplen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
case NFC: {
|
||||||
|
nfc_df_e foo = detect_nfc_dump_format(fn, true);
|
||||||
|
if (foo == NFC_DF_MFC || foo == NFC_DF_MFU) {
|
||||||
|
|
||||||
|
*pdump = calloc(maxdumplen, sizeof(uint8_t));
|
||||||
|
if (*pdump == NULL) {
|
||||||
|
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||||
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
res = loadFileNFC_safe(fn, *pdump, maxdumplen, dumplen, foo);
|
||||||
|
if (res == PM3_SUCCESS) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(*pdump);
|
||||||
|
|
||||||
|
if (res == PM3_ESOFT) {
|
||||||
|
PrintAndLogEx(WARNING, "NFC objects failed to load");
|
||||||
|
} else if (res == PM3_EMALLOC) {
|
||||||
|
PrintAndLogEx(WARNING, "Wrong size of allocated memory. Check your parameters");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,26 @@ typedef enum {
|
||||||
JSON,
|
JSON,
|
||||||
DICTIONARY,
|
DICTIONARY,
|
||||||
MCT,
|
MCT,
|
||||||
|
NFC,
|
||||||
} DumpFileType_t;
|
} DumpFileType_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MFU_DF_UNKNOWN,
|
||||||
|
MFU_DF_PLAINBIN,
|
||||||
|
MFU_DF_OLDBIN,
|
||||||
|
MFU_DF_NEWBIN
|
||||||
|
} mfu_df_e;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NFC_DF_UNKNOWN,
|
||||||
|
NFC_DF_MFC,
|
||||||
|
NFC_DF_MFU,
|
||||||
|
NFC_DF_MFDES,
|
||||||
|
NFC_DF_14_3A,
|
||||||
|
NFC_DF_14_3B,
|
||||||
|
NFC_DF_14_4A
|
||||||
|
} nfc_df_e;
|
||||||
|
|
||||||
int fileExists(const char *filename);
|
int fileExists(const char *filename);
|
||||||
|
|
||||||
// set a path in the path list g_session.defaultPaths
|
// set a path in the path list g_session.defaultPaths
|
||||||
|
@ -185,6 +203,19 @@ int loadFileEML_safe(const char *preferredName, void **pdata, size_t *datalen);
|
||||||
*/
|
*/
|
||||||
int loadFileMCT_safe(const char *preferredName, void **pdata, size_t *datalen);
|
int loadFileMCT_safe(const char *preferredName, void **pdata, size_t *datalen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Utility function to load data from a textfile (NFC). This method takes a preferred name.
|
||||||
|
* E.g. dumpdata-15.nfc
|
||||||
|
*
|
||||||
|
* @param preferredName
|
||||||
|
* @param data The data array to store the loaded bytes from file
|
||||||
|
* @param maxdatalen maximum size of data array in bytes
|
||||||
|
* @param datalen the number of bytes loaded from file
|
||||||
|
* @param ft
|
||||||
|
* @return 0 for ok, 1 for failz
|
||||||
|
*/
|
||||||
|
int loadFileNFC_safe(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen, nfc_df_e ft);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Utility function to load data from a JSON textfile. This method takes a preferred name.
|
* @brief Utility function to load data from a JSON textfile. This method takes a preferred name.
|
||||||
* E.g. dumpdata-15.json
|
* E.g. dumpdata-15.json
|
||||||
|
@ -244,12 +275,6 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key
|
||||||
|
|
||||||
int loadFileBinaryKey(const char *preferredName, const char *suffix, void **keya, void **keyb, size_t *alen, size_t *blen);
|
int loadFileBinaryKey(const char *preferredName, const char *suffix, void **keya, void **keyb, size_t *alen, size_t *blen);
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
MFU_DF_UNKNOWN,
|
|
||||||
MFU_DF_PLAINBIN,
|
|
||||||
MFU_DF_OLDBIN,
|
|
||||||
MFU_DF_NEWBIN
|
|
||||||
} mfu_df_e;
|
|
||||||
/**
|
/**
|
||||||
* @brief Utility function to check and convert plain mfu dump format to new mfu binary format.
|
* @brief Utility function to check and convert plain mfu dump format to new mfu binary format.
|
||||||
* plain dumps doesn't have any extra data, like version, signature etc.
|
* plain dumps doesn't have any extra data, like version, signature etc.
|
||||||
|
@ -259,7 +284,8 @@ typedef enum {
|
||||||
* @return PM3_SUCCESS for ok, PM3_ESOFT for fails
|
* @return PM3_SUCCESS for ok, PM3_ESOFT for fails
|
||||||
*/
|
*/
|
||||||
int convert_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose);
|
int convert_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose);
|
||||||
mfu_df_e detect_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose);
|
mfu_df_e detect_mfu_dump_format(uint8_t **dump, bool verbose);
|
||||||
|
nfc_df_e detect_nfc_dump_format(const char *preferredName, bool verbose);
|
||||||
|
|
||||||
int searchAndList(const char *pm3dir, const char *ext);
|
int searchAndList(const char *pm3dir, const char *ext);
|
||||||
int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent);
|
int searchFile(char **foundpath, const char *pm3dir, const char *searchname, const char *suffix, bool silent);
|
||||||
|
|
|
@ -649,7 +649,7 @@ static int ndefDecodeMime_wifi_wsc(NDEFHeader_t *ndef) {
|
||||||
|
|
||||||
if (ndef->Payload[pos] != 0x10) {
|
if (ndef->Payload[pos] != 0x10) {
|
||||||
n -= 1;
|
n -= 1;
|
||||||
pos -= 1;
|
pos += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,6 +775,16 @@ static int ndefDecodeMime_wifi_wsc(NDEFHeader_t *ndef) {
|
||||||
pos += 2;
|
pos += 2;
|
||||||
pos += len;
|
pos += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unknown the length.
|
||||||
|
if (memcmp(&ndef->Payload[pos], "\x10\x3C", 2) == 0) {
|
||||||
|
uint8_t len = 3;
|
||||||
|
PrintAndLogEx(INFO, "Unknown......... %s", sprint_hex(&ndef->Payload[pos + 2], len));
|
||||||
|
n -= 2;
|
||||||
|
n -= len;
|
||||||
|
pos += 2;
|
||||||
|
pos += len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1182,6 +1192,7 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("NDEF parsing") " ----------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("NDEF parsing") " ----------------");
|
||||||
while (indx < ndefLen) {
|
while (indx < ndefLen) {
|
||||||
|
|
||||||
switch (ndef[indx]) {
|
switch (ndef[indx]) {
|
||||||
case 0x00: {
|
case 0x00: {
|
||||||
indx++;
|
indx++;
|
||||||
|
@ -1246,8 +1257,9 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) {
|
||||||
PrintAndLogEx(SUCCESS, "Found NDEF message ( " _YELLOW_("%u") " bytes )", len);
|
PrintAndLogEx(SUCCESS, "Found NDEF message ( " _YELLOW_("%u") " bytes )", len);
|
||||||
|
|
||||||
int res = NDEFRecordsDecodeAndPrint(&ndef[indx], len, verbose);
|
int res = NDEFRecordsDecodeAndPrint(&ndef[indx], len, verbose);
|
||||||
if (res != PM3_SUCCESS)
|
if (res != PM3_SUCCESS) {
|
||||||
return res;
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
indx += len;
|
indx += len;
|
||||||
|
@ -1269,9 +1281,9 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
if (verbose)
|
if (verbose) {
|
||||||
PrintAndLogEx(ERR, "unknown tag 0x%02x", ndef[indx]);
|
PrintAndLogEx(ERR, "unknown tag 0x%02x", ndef[indx]);
|
||||||
|
}
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue