save and load raw NDEF in hf * ndefread and in nfc decode

This commit is contained in:
Philippe Teuwen 2021-09-22 21:33:37 +02:00
commit b5b946edfe
9 changed files with 111 additions and 22 deletions

View file

@ -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]
- Added option to load raw NDEF to `nfc decode` command (@doegox)
- Added option to save raw NDEF to all `hf * ndefread` commands (@doegox)
- Changed `hf 14a info` - different FUDAN clone detection (@iceman1001) - Changed `hf 14a info` - different FUDAN clone detection (@iceman1001)
- Added `CROSS_CC` and similar args for maintainers, see Maintainers.md (@doegox) - Added `CROSS_CC` and similar args for maintainers, see Maintainers.md (@doegox)
- Fix crack5opencl: fix deadlock in wu_queue_destroy() + minor changes on threads.c (@matrix) - Fix crack5opencl: fix deadlock in wu_queue_destroy() + minor changes on threads.c (@matrix)

View file

@ -32,6 +32,7 @@
#include "iso7816/apduinfo.h" // GetAPDUCodeDescription #include "iso7816/apduinfo.h" // GetAPDUCodeDescription
#include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint #include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint
#include "cmdnfc.h" // print_type4_cc_info #include "cmdnfc.h" // print_type4_cc_info
#include "fileutils.h" // saveFile
static bool APDUInFramingEnable = true; static bool APDUInFramingEnable = true;
@ -2382,13 +2383,19 @@ int CmdHF14ANdefRead(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a ndefread", CLIParserInit(&ctx, "hf 14a ndefread",
"Read NFC Data Exchange Format (NDEF) file on Type 4 NDEF tag", "Read NFC Data Exchange Format (NDEF) file on Type 4 NDEF tag",
"hf 14a ndefread\n"); "hf 14a ndefread\n"
"hf 14a ndefread -f myfilename -> save raw NDEF to file"
);
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_str0("f", "file", "<fn>", "save raw NDEF to file"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
CLIParserFree(ctx); CLIParserFree(ctx);
bool activate_field = true; bool activate_field = true;
@ -2468,7 +2475,6 @@ int CmdHF14ANdefRead(const char *Cmd) {
DropField(); DropField();
return res; return res;
} }
sw = get_sw(response, resplen); sw = get_sw(response, resplen);
if (sw != 0x9000) { if (sw != 0x9000) {
PrintAndLogEx(ERR, "reading CC file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); PrintAndLogEx(ERR, "reading CC file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
@ -2561,6 +2567,9 @@ int CmdHF14ANdefRead(const char *Cmd) {
} }
memcpy(ndef_file + (i - offset), response, segment_size); memcpy(ndef_file + (i - offset), response, segment_size);
} }
if (fnlen != 0) {
saveFile(filename, ".bin", ndef_file, ndef_size);
}
NDEFRecordsDecodeAndPrint(ndef_file, ndef_size); NDEFRecordsDecodeAndPrint(ndef_file, ndef_size);
free(ndef_file); free(ndef_file);
return PM3_SUCCESS; return PM3_SUCCESS;

View file

@ -25,6 +25,7 @@
#include "iso7816/apduinfo.h" // GetAPDUCodeDescription #include "iso7816/apduinfo.h" // GetAPDUCodeDescription
#include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint #include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint
#include "aidsearch.h" #include "aidsearch.h"
#include "fileutils.h" // saveFile
#define MAX_14B_TIMEOUT_MS (4949U) #define MAX_14B_TIMEOUT_MS (4949U)
@ -1921,13 +1922,18 @@ int CmdHF14BNdefRead(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14b ndefread", CLIParserInit(&ctx, "hf 14b ndefread",
"Print NFC Data Exchange Format (NDEF)", "Print NFC Data Exchange Format (NDEF)",
"hf 14b ndefread" "hf 14b ndefread\n"
"hf 14b ndefread -f myfilename -> save raw NDEF to file"
); );
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_str0("f", "file", "<fn>", "save raw NDEF to file"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
CLIParserFree(ctx); CLIParserFree(ctx);
bool activate_field = true; bool activate_field = true;
@ -2011,6 +2017,9 @@ int CmdHF14BNdefRead(const char *Cmd) {
goto out; goto out;
} }
if (fnlen != 0) {
saveFile(filename, ".bin", response + 2, resplen - 4);
}
res = NDEFRecordsDecodeAndPrint(response + 2, resplen - 4); res = NDEFRecordsDecodeAndPrint(response + 2, resplen - 4);
out: out:

View file

@ -5331,7 +5331,9 @@ int CmdHFMFNDEFRead(const char *Cmd) {
"Prints NFC Data Exchange Format (NDEF)", "Prints NFC Data Exchange Format (NDEF)",
"hf mf ndefread -> shows NDEF parsed data\n" "hf mf ndefread -> shows NDEF parsed data\n"
"hf mf ndefread -vv -> shows NDEF parsed and raw data\n" "hf mf ndefread -vv -> shows NDEF parsed and raw data\n"
"hf mf ndefread --aid e103 -k ffffffffffff -b -> shows NDEF data with custom AID, key and with key B\n"); "hf mf ndefread --aid e103 -k ffffffffffff -b -> shows NDEF data with custom AID, key and with key B\n"
"hf mf ndefread -f myfilename -> save raw NDEF to file"
);
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
@ -5339,6 +5341,7 @@ int CmdHFMFNDEFRead(const char *Cmd) {
arg_str0(NULL, "aid", "<aid>", "replace default aid for NDEF"), arg_str0(NULL, "aid", "<aid>", "replace default aid for NDEF"),
arg_str0("k", "key", "<key>", "replace default key for NDEF"), arg_str0("k", "key", "<key>", "replace default key for NDEF"),
arg_lit0("b", "keyb", "use key B for access sectors (by default: key A)"), arg_lit0("b", "keyb", "use key B for access sectors (by default: key A)"),
arg_str0("f", "file", "<fn>", "save raw NDEF to file"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -5352,6 +5355,9 @@ int CmdHFMFNDEFRead(const char *Cmd) {
int keylen; int keylen;
CLIGetHexWithReturn(ctx, 3, key, &keylen); CLIGetHexWithReturn(ctx, 3, key, &keylen);
bool keyB = arg_get_lit(ctx, 4); bool keyB = arg_get_lit(ctx, 4);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
CLIParserFree(ctx); CLIParserFree(ctx);
@ -5433,6 +5439,9 @@ int CmdHFMFNDEFRead(const char *Cmd) {
print_buffer(data, datalen, 1); print_buffer(data, datalen, 1);
} }
if (fnlen != 0) {
saveFile(filename, ".bin", data, datalen);
}
NDEFDecodeAndPrint(data, datalen, verbose); NDEFDecodeAndPrint(data, datalen, verbose);
PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -vv`") " for more details"); PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -vv`") " for more details");

View file

@ -1465,7 +1465,9 @@ int CmdHFMFPNDEFRead(const char *Cmd) {
"Prints NFC Data Exchange Format (NDEF)", "Prints NFC Data Exchange Format (NDEF)",
"hf mfp ndefread \n" "hf mfp ndefread \n"
"hf mfp ndefread -vv -> shows NDEF parsed and raw data\n" "hf mfp ndefread -vv -> shows NDEF parsed and raw data\n"
"hf mfp ndefread --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key"); "hf mfp ndefread --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key\n"
"hf mfp ndefread -f myfilename -> save raw NDEF to file"
);
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
@ -1473,6 +1475,7 @@ int CmdHFMFPNDEFRead(const char *Cmd) {
arg_str0(NULL, "aid", "<aid>", "replace default aid for NDEF"), arg_str0(NULL, "aid", "<aid>", "replace default aid for NDEF"),
arg_str0("k", "key", "<key>", "replace default key for NDEF"), arg_str0("k", "key", "<key>", "replace default key for NDEF"),
arg_lit0("b", "keyb", "use key B for access sectors (by default: key A)"), arg_lit0("b", "keyb", "use key B for access sectors (by default: key A)"),
arg_str0("f", "file", "<fn>", "save raw NDEF to file"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -1487,6 +1490,9 @@ int CmdHFMFPNDEFRead(const char *Cmd) {
CLIGetHexWithReturn(ctx, 3, key, &keylen); CLIGetHexWithReturn(ctx, 3, key, &keylen);
bool keyB = arg_get_lit(ctx, 4); bool keyB = arg_get_lit(ctx, 4);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
CLIParserFree(ctx); CLIParserFree(ctx);
uint16_t ndefAID = 0xe103; uint16_t ndefAID = 0xe103;
@ -1568,6 +1574,9 @@ int CmdHFMFPNDEFRead(const char *Cmd) {
print_buffer(data, datalen, 1); print_buffer(data, datalen, 1);
} }
if (fnlen != 0) {
saveFile(filename, ".bin", data, datalen);
}
NDEFDecodeAndPrint(data, datalen, verbose); NDEFDecodeAndPrint(data, datalen, verbose);
PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfp ndefread -vv`") " for more details"); PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfp ndefread -vv`") " for more details");
return PM3_SUCCESS; return PM3_SUCCESS;

View file

@ -25,6 +25,7 @@
#include "cmdmain.h" #include "cmdmain.h"
#include "amiibo.h" // amiiboo fcts #include "amiibo.h" // amiiboo fcts
#include "base64.h" #include "base64.h"
#include "fileutils.h" // saveFile
#define MAX_UL_BLOCKS 0x0F #define MAX_UL_BLOCKS 0x0F
#define MAX_ULC_BLOCKS 0x2F #define MAX_ULC_BLOCKS 0x2F
@ -3810,17 +3811,23 @@ int CmdHF14MfuNDEFRead(const char *Cmd) {
CLIParserInit(&ctx, "hf mfu ndefread", CLIParserInit(&ctx, "hf mfu ndefread",
"Prints NFC Data Exchange Format (NDEF)", "Prints NFC Data Exchange Format (NDEF)",
"hf mfu ndefread -> shows NDEF data\n" "hf mfu ndefread -> shows NDEF data\n"
"hf mfu ndefread -k ffffffff -> shows NDEF data with key"); "hf mfu ndefread -k ffffffff -> shows NDEF data with key\n"
"hf mfu ndefread -f myfilename -> save raw NDEF to file"
);
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_str0("k", "key", "replace default key for NDEF", NULL), arg_str0("k", "key", "replace default key for NDEF", NULL),
arg_lit0("l", NULL, "swap entered key's endianness"), arg_lit0("l", NULL, "swap entered key's endianness"),
arg_str0("f", "file", "<fn>", "save raw NDEF to file"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIGetHexWithReturn(ctx, 1, key, &keylen); CLIGetHexWithReturn(ctx, 1, key, &keylen);
swapEndian = arg_get_lit(ctx, 2); swapEndian = arg_get_lit(ctx, 2);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
CLIParserFree(ctx); CLIParserFree(ctx);
switch (keylen) { switch (keylen) {
@ -3901,6 +3908,9 @@ int CmdHF14MfuNDEFRead(const char *Cmd) {
} }
DropField(); DropField();
if (fnlen != 0) {
saveFile(filename, ".bin", records, (size_t)maxsize);
}
status = NDEFRecordsDecodeAndPrint(records, (size_t)maxsize); status = NDEFRecordsDecodeAndPrint(records, (size_t)maxsize);
if (status != PM3_SUCCESS) { if (status != PM3_SUCCESS) {
status = NDEFDecodeAndPrint(records, (size_t)maxsize, true); status = NDEFDecodeAndPrint(records, (size_t)maxsize, true);

View file

@ -278,15 +278,21 @@ int CmdHFST25TANdefRead(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf st25ta ndefread", CLIParserInit(&ctx, "hf st25ta ndefread",
"Read NFC Data Exchange Format (NDEF) file on ST25TA", "Read NFC Data Exchange Format (NDEF) file on ST25TA",
"hf st25ta ndefread -p 82E80053D4CA5C0B656D852CC696C8A1\n"); "hf st25ta ndefread -p 82E80053D4CA5C0B656D852CC696C8A1\n"
"hf st25ta ndefread -f myfilename -> save raw NDEF to file"
);
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_str0("p", "pwd", "<hex>", "16 byte read password"), arg_str0("p", "pwd", "<hex>", "16 byte read password"),
arg_str0("f", "file", "<fn>", "save raw NDEF to file"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIGetHexWithReturn(ctx, 1, pwd, &pwdlen); CLIGetHexWithReturn(ctx, 1, pwd, &pwdlen);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
CLIParserFree(ctx); CLIParserFree(ctx);
if (pwdlen == 0) { if (pwdlen == 0) {
@ -394,6 +400,9 @@ int CmdHFST25TANdefRead(const char *Cmd) {
return PM3_ESOFT; return PM3_ESOFT;
} }
if (fnlen != 0) {
saveFile(filename, ".bin", response + 2, resplen - 4);
}
NDEFRecordsDecodeAndPrint(response + 2, resplen - 4); NDEFRecordsDecodeAndPrint(response + 2, resplen - 4);
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -23,6 +23,7 @@
#include "crc16.h" #include "crc16.h"
#include "protocols.h" #include "protocols.h"
#include "nfc/ndef.h" #include "nfc/ndef.h"
#include "fileutils.h" // saveFile
#define TOPAZ_STATIC_MEMORY (0x0f * 8) // 15 blocks with 8 Bytes each #define TOPAZ_STATIC_MEMORY (0x0f * 8) // 15 blocks with 8 Bytes each
@ -388,10 +389,6 @@ static void topaz_print_lifecycle_state(uint8_t *data) {
// to be done // to be done
} }
static int topaz_print_NDEF(uint8_t *data, size_t maxsize) {
return NDEFDecodeAndPrint(data, maxsize, true);
}
static int CmdHFTopazReader(const char *Cmd) { static int CmdHFTopazReader(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf topaz reader", CLIParserInit(&ctx, "hf topaz reader",
@ -417,16 +414,22 @@ int CmdHFTopazInfo(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf topaz info", CLIParserInit(&ctx, "hf topaz info",
"Get info from Topaz tags", "Get info from Topaz tags",
"hf topaz info"); "hf topaz info\n"
"hf topaz info -f myfilename -> save raw NDEF to file\n"
);
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_str0("f", "file", "<fn>", "save raw NDEF to file"),
arg_lit0("v", "verbose", "verbose output"), arg_lit0("v", "verbose", "verbose output"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
bool verbose = arg_get_lit(ctx, 1); int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
bool verbose = arg_get_lit(ctx, 2);
CLIParserFree(ctx); CLIParserFree(ctx);
@ -482,7 +485,10 @@ int CmdHFTopazInfo(const char *Cmd) {
topaz_print_lifecycle_state(&topaz_tag.data_blocks[1][0]); topaz_print_lifecycle_state(&topaz_tag.data_blocks[1][0]);
topaz_print_NDEF(&topaz_tag.data_blocks[1][0], TOPAZ_STATIC_MEMORY); if (fnlen != 0) {
saveFile(filename, ".bin", &topaz_tag.data_blocks[1][0], TOPAZ_STATIC_MEMORY);
}
NDEFDecodeAndPrint(&topaz_tag.data_blocks[1][0], TOPAZ_STATIC_MEMORY, true);
PrintAndLogEx(INFO, "-------------------------------------------------------------"); PrintAndLogEx(INFO, "-------------------------------------------------------------");
topaz_switch_off_field(); topaz_switch_off_field();

View file

@ -19,6 +19,7 @@
#include "cmdhfthinfilm.h" #include "cmdhfthinfilm.h"
#include "cmdhftopaz.h" #include "cmdhftopaz.h"
#include "cmdnfc.h" #include "cmdnfc.h"
#include "fileutils.h"
void print_type4_cc_info(uint8_t *d, uint8_t n) { void print_type4_cc_info(uint8_t *d, uint8_t n) {
if (n < 0x0F) { if (n < 0x0F) {
@ -60,14 +61,17 @@ static int CmdNfcDecode(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "nfc decode", CLIParserInit(&ctx, "nfc decode",
"Decode and print NFC Data Exchange Format (NDEF)", "Decode and print NFC Data Exchange Format (NDEF)\n"
"You must provide either data in hex or a filename, but not both",
"nfc decode -d 9101085402656e48656c6c6f5101085402656e576f726c64\n" "nfc decode -d 9101085402656e48656c6c6f5101085402656e576f726c64\n"
"nfc decode -d 0103d020240203e02c040300fe\n" "nfc decode -d 0103d020240203e02c040300fe\n"
"nfc decode -f myfilename"
); );
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_strx0("d", "data", "<hex>", "NDEF data to decode"), arg_strx0("d", "data", "<hex>", "NDEF data to decode"),
arg_str0("f", "file", "<fn>", "file to load"),
arg_lit0("v", "verbose", "verbose mode"), arg_lit0("v", "verbose", "verbose mode"),
arg_param_end arg_param_end
}; };
@ -76,16 +80,38 @@ static int CmdNfcDecode(const char *Cmd) {
int datalen = 0; int datalen = 0;
uint8_t data[MAX_NDEF_LEN] = {0}; uint8_t data[MAX_NDEF_LEN] = {0};
CLIGetHexWithReturn(ctx, 1, data, &datalen); CLIGetHexWithReturn(ctx, 1, data, &datalen);
bool verbose = arg_get_lit(ctx, 2);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
bool verbose = arg_get_lit(ctx, 3);
CLIParserFree(ctx); CLIParserFree(ctx);
if (datalen == 0) if (((datalen != 0) && (fnlen != 0)) || ((datalen == 0) && (fnlen == 0))){
PrintAndLogEx(ERR, "You must provide either data in hex or a filename");
return PM3_EINVARG; return PM3_EINVARG;
}
int res = NDEFDecodeAndPrint(data, datalen, verbose); int res = PM3_SUCCESS;
if (res != PM3_SUCCESS) { if (fnlen != 0) {
PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header"); size_t dumplen = 0;
res = NDEFRecordsDecodeAndPrint(data, datalen); uint8_t *dump = NULL;
if (loadFile_safe(filename, ".bin", (void **)&dump, &dumplen) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "error, something went wrong when loading file");
free(dump);
return PM3_EFILE;
}
res = NDEFDecodeAndPrint(dump, dumplen, verbose);
if (res != PM3_SUCCESS) {
PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header");
res = NDEFRecordsDecodeAndPrint(dump, dumplen);
}
free(dump);
} else {
res = NDEFDecodeAndPrint(data, datalen, verbose);
if (res != PM3_SUCCESS) {
PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header");
res = NDEFRecordsDecodeAndPrint(data, datalen);
}
} }
return res; return res;
} }