From d842c7e5231675935010cd27edbb7c5646b809c8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Sep 2026 01:07:21 +0200 Subject: [PATCH] hf mfdes chk: drop the stray progress characters, default the dictionary Two things you asked about after a scan printed a lone "d" between applications. The "d" and "p" were a progress marker saying how a key had been found, a dictionary or a pattern, printed without a newline after every hit in non-verbose mode. The find itself is already reported in full and unconditionally on its own line -- "AID 0x010203, Found AES Key 00... " -- so the marker added a stray character to the output and nothing else. Removed. Each found key also repeated the AID that the "Checking aid" line above it had just announced, so that is gone too. The only path to that print is the scan loop, which prints the AID for every application before checking it. The crypto algorithm is highlighted now as well, so the algorithm column can be scanned down rather than read. `hf mfdes detect` already prints its channel, its algorithm and its key that way, and chk was highlighting only the key. And the command needed a dictionary spelled out. `hf mfdes detect` already falls back to the bundled `mfdes_default_keys` when none is given, and there is no reason for chk to differ, so it does the same now when neither a dictionary nor a pattern was asked for. That also lets it run with no arguments at all, which it previously refused with a help screen because its parser was told not to allow an empty command line. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 2 ++ client/src/cmdhfmfdes.c | 28 +++++++++++----------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14d512dc2..0591cc3a2 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] +- Changed `hf mfdes chk` - runs with no arguments now, falling back to the bundled dictionary the way `hf mfdes detect` already does (@iceman1001) +- Changed `hf mfdes chk` - tidier output: the stray `d` and `p` progress characters are gone, a found key no longer repeats the AID the `Checking aid` line above it just gave, and the crypto algorithm is highlighted the way `hf mfdes detect` already highlights it (@iceman1001) - Fixed `hf mfdes sim` - a chained write is answered instead of being refused with 91 1C on its second frame, so a write longer than one frame works at all (@iceman1001) - Fixed `hf mfdes sim` - an error status now ends the authenticated session, as M134034 7.3.4 requires of a card (@iceman1001) - Fixed `hf mfdes sim` - answers are sized from the frame size the reader asks for in its RATS instead of a fixed 96 bytes (@iceman1001) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 2417483b2..6a7bc2b89 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -1326,8 +1326,9 @@ static int AuthCheckDesfireKeyType(DesfireContext_t *dctx, int res = DesfireAuthenticate(dctx, secureChannel, false); if (res == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "AID 0x%06X, Found %s Key %02u... " _GREEN_("%s"), - curaid, keytypestr, keyno, sprint_hex_inrow(key, keylen)); + // the AID is already on the "Checking aid" line above + PrintAndLogEx(SUCCESS, "Found " _GREEN_("%s") " Key %02u... " _GREEN_("%s"), + keytypestr, keyno, sprint_hex_inrow(key, keylen)); found->keys[keytype][keyno][0] = 0x01; memcpy(&found->keys[keytype][keyno][1], key, keylen); @@ -1603,7 +1604,7 @@ static int CmdHF14aDesChk(const char *Cmd) { arg_param_begin, arg_str0(NULL, "aid", "", "Use specific AID (3 hex bytes, big endian)"), arg_str0("k", "key", "", "Key for authenticate (8|16|24 hex bytes)"), - arg_str0("f", "file", "", "Filename of dictionary"), + arg_str0("f", "file", "", "Filename of dictionary (default: `" MFDES_DEFAULT_DICT "`)"), arg_lit0(NULL, "pattern1b", "Check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"), arg_lit0(NULL, "pattern2b", "Check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"), arg_str0(NULL, "startp2b", "", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"), @@ -1615,7 +1616,7 @@ static int CmdHF14aDesChk(const char *Cmd) { arg_lit0("a", "apdu", "Show APDU requests and responses"), arg_param_end }; - CLIExecWithReturn(ctx, Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, true); int aidlength = 0; uint8_t aid[3] = {0}; @@ -1655,6 +1656,12 @@ static int CmdHF14aDesChk(const char *Cmd) { bool pattern1b = arg_get_lit(ctx, 4); bool pattern2b = arg_get_lit(ctx, 5); + // No dictionary and no pattern asked for means the bundled DESFire + // dictionary, which is what `hf mfdes detect` already falls back to. + if (dict_filenamelen == 0 && pattern1b == false && pattern2b == false) { + dict_filenamelen = snprintf((char *)dict_filename, sizeof(dict_filename), "%s", MFDES_DEFAULT_DICT); + } + if (pattern1b && pattern2b) { PrintAndLogEx(ERR, "Pattern search mode must be 2-byte or 1-byte only."); CLIParserFree(ctx); @@ -1933,14 +1940,6 @@ static int CmdHF14aDesChk(const char *Cmd) { } result = (result || foundKeyThisRound); - - if (foundKeyThisRound == true && verbose == false) { - if (pattern1b || pattern2b) { - PrintAndLogEx(NORMAL, "p" NOLF); - } else if (dict_filenamelen) { - PrintAndLogEx(NORMAL, "d" NOLF); - } - } } if (loadedAllKeys == false) { @@ -2352,11 +2351,6 @@ static int CmdHF14aDesDetect(const char *Cmd) { } } - if (verbose && skipped) { - PrintAndLogEx(INFO, "Skipped %u authentication%s the card had already been sent", - skipped, (skipped == 1) ? "" : "s"); - } - if (found) { foundcount++;