diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c32d4c3e..82d32525c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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... ## [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) - 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) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 21541ba13..7c06a2487 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -32,6 +32,7 @@ #include "iso7816/apduinfo.h" // GetAPDUCodeDescription #include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint #include "cmdnfc.h" // print_type4_cc_info +#include "fileutils.h" // saveFile static bool APDUInFramingEnable = true; @@ -2382,13 +2383,19 @@ int CmdHF14ANdefRead(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 14a ndefread", "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[] = { arg_param_begin, + arg_str0("f", "file", "", "save raw NDEF to file"), arg_param_end }; 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); bool activate_field = true; @@ -2468,7 +2475,6 @@ int CmdHF14ANdefRead(const char *Cmd) { DropField(); return res; } - sw = get_sw(response, resplen); if (sw != 0x9000) { 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); } + if (fnlen != 0) { + saveFile(filename, ".bin", ndef_file, ndef_size); + } NDEFRecordsDecodeAndPrint(ndef_file, ndef_size); free(ndef_file); return PM3_SUCCESS; diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 24713c229..bd085210d 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -25,6 +25,7 @@ #include "iso7816/apduinfo.h" // GetAPDUCodeDescription #include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint #include "aidsearch.h" +#include "fileutils.h" // saveFile #define MAX_14B_TIMEOUT_MS (4949U) @@ -1921,13 +1922,18 @@ int CmdHF14BNdefRead(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 14b ndefread", "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[] = { arg_param_begin, + arg_str0("f", "file", "", "save raw NDEF to file"), arg_param_end }; 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); bool activate_field = true; @@ -2011,6 +2017,9 @@ int CmdHF14BNdefRead(const char *Cmd) { goto out; } + if (fnlen != 0) { + saveFile(filename, ".bin", response + 2, resplen - 4); + } res = NDEFRecordsDecodeAndPrint(response + 2, resplen - 4); out: diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 016e749f1..0f12be2ee 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5331,7 +5331,9 @@ int CmdHFMFNDEFRead(const char *Cmd) { "Prints NFC Data Exchange Format (NDEF)", "hf mf ndefread -> shows NDEF parsed 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[] = { arg_param_begin, @@ -5339,6 +5341,7 @@ int CmdHFMFNDEFRead(const char *Cmd) { arg_str0(NULL, "aid", "", "replace default aid for NDEF"), arg_str0("k", "key", "", "replace default key for NDEF"), arg_lit0("b", "keyb", "use key B for access sectors (by default: key A)"), + arg_str0("f", "file", "", "save raw NDEF to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -5352,6 +5355,9 @@ int CmdHFMFNDEFRead(const char *Cmd) { int keylen; CLIGetHexWithReturn(ctx, 3, key, &keylen); 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); @@ -5433,6 +5439,9 @@ int CmdHFMFNDEFRead(const char *Cmd) { print_buffer(data, datalen, 1); } + if (fnlen != 0) { + saveFile(filename, ".bin", data, datalen); + } NDEFDecodeAndPrint(data, datalen, verbose); PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -vv`") " for more details"); diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 83423320b..01a59830c 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -1465,7 +1465,9 @@ int CmdHFMFPNDEFRead(const char *Cmd) { "Prints NFC Data Exchange Format (NDEF)", "hf mfp ndefread \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[] = { arg_param_begin, @@ -1473,6 +1475,7 @@ int CmdHFMFPNDEFRead(const char *Cmd) { arg_str0(NULL, "aid", "", "replace default aid for NDEF"), arg_str0("k", "key", "", "replace default key for NDEF"), arg_lit0("b", "keyb", "use key B for access sectors (by default: key A)"), + arg_str0("f", "file", "", "save raw NDEF to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1487,6 +1490,9 @@ int CmdHFMFPNDEFRead(const char *Cmd) { CLIGetHexWithReturn(ctx, 3, key, &keylen); 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); uint16_t ndefAID = 0xe103; @@ -1568,6 +1574,9 @@ int CmdHFMFPNDEFRead(const char *Cmd) { print_buffer(data, datalen, 1); } + if (fnlen != 0) { + saveFile(filename, ".bin", data, datalen); + } NDEFDecodeAndPrint(data, datalen, verbose); PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfp ndefread -vv`") " for more details"); return PM3_SUCCESS; diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index f723480ea..2b12f3845 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -25,6 +25,7 @@ #include "cmdmain.h" #include "amiibo.h" // amiiboo fcts #include "base64.h" +#include "fileutils.h" // saveFile #define MAX_UL_BLOCKS 0x0F #define MAX_ULC_BLOCKS 0x2F @@ -3810,17 +3811,23 @@ int CmdHF14MfuNDEFRead(const char *Cmd) { CLIParserInit(&ctx, "hf mfu ndefread", "Prints NFC Data Exchange Format (NDEF)", "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[] = { arg_param_begin, arg_str0("k", "key", "replace default key for NDEF", NULL), arg_lit0("l", NULL, "swap entered key's endianness"), + arg_str0("f", "file", "", "save raw NDEF to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); CLIGetHexWithReturn(ctx, 1, key, &keylen); 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); switch (keylen) { @@ -3901,6 +3908,9 @@ int CmdHF14MfuNDEFRead(const char *Cmd) { } DropField(); + if (fnlen != 0) { + saveFile(filename, ".bin", records, (size_t)maxsize); + } status = NDEFRecordsDecodeAndPrint(records, (size_t)maxsize); if (status != PM3_SUCCESS) { status = NDEFDecodeAndPrint(records, (size_t)maxsize, true); diff --git a/client/src/cmdhfst25ta.c b/client/src/cmdhfst25ta.c index aa737304c..6695d46b4 100644 --- a/client/src/cmdhfst25ta.c +++ b/client/src/cmdhfst25ta.c @@ -278,15 +278,21 @@ int CmdHFST25TANdefRead(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf st25ta ndefread", "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[] = { arg_param_begin, arg_str0("p", "pwd", "", "16 byte read password"), + arg_str0("f", "file", "", "save raw NDEF to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); 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); if (pwdlen == 0) { @@ -394,6 +400,9 @@ int CmdHFST25TANdefRead(const char *Cmd) { return PM3_ESOFT; } + if (fnlen != 0) { + saveFile(filename, ".bin", response + 2, resplen - 4); + } NDEFRecordsDecodeAndPrint(response + 2, resplen - 4); return PM3_SUCCESS; } diff --git a/client/src/cmdhftopaz.c b/client/src/cmdhftopaz.c index 9dc7d2257..6523cb356 100644 --- a/client/src/cmdhftopaz.c +++ b/client/src/cmdhftopaz.c @@ -23,6 +23,7 @@ #include "crc16.h" #include "protocols.h" #include "nfc/ndef.h" +#include "fileutils.h" // saveFile #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 } -static int topaz_print_NDEF(uint8_t *data, size_t maxsize) { - return NDEFDecodeAndPrint(data, maxsize, true); -} - static int CmdHFTopazReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf topaz reader", @@ -417,16 +414,22 @@ int CmdHFTopazInfo(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf topaz info", "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[] = { arg_param_begin, + arg_str0("f", "file", "", "save raw NDEF to file"), arg_lit0("v", "verbose", "verbose output"), arg_param_end }; 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); @@ -482,7 +485,10 @@ int CmdHFTopazInfo(const char *Cmd) { 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, "-------------------------------------------------------------"); topaz_switch_off_field(); diff --git a/client/src/cmdnfc.c b/client/src/cmdnfc.c index 27c662e45..c131f6b4c 100644 --- a/client/src/cmdnfc.c +++ b/client/src/cmdnfc.c @@ -19,6 +19,7 @@ #include "cmdhfthinfilm.h" #include "cmdhftopaz.h" #include "cmdnfc.h" +#include "fileutils.h" void print_type4_cc_info(uint8_t *d, uint8_t n) { if (n < 0x0F) { @@ -60,14 +61,17 @@ static int CmdNfcDecode(const char *Cmd) { CLIParserContext *ctx; 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 0103d020240203e02c040300fe\n" + "nfc decode -f myfilename" ); void *argtable[] = { arg_param_begin, arg_strx0("d", "data", "", "NDEF data to decode"), + arg_str0("f", "file", "", "file to load"), arg_lit0("v", "verbose", "verbose mode"), arg_param_end }; @@ -76,16 +80,38 @@ static int CmdNfcDecode(const char *Cmd) { int datalen = 0; uint8_t data[MAX_NDEF_LEN] = {0}; 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); - 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; - - int res = NDEFDecodeAndPrint(data, datalen, verbose); - if (res != PM3_SUCCESS) { - PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header"); - res = NDEFRecordsDecodeAndPrint(data, datalen); + } + int res = PM3_SUCCESS; + if (fnlen != 0) { + size_t dumplen = 0; + 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; }