From eef37213576aa224b8bf81f07250d3cfa76ee8ff Mon Sep 17 00:00:00 2001 From: kormax <3392860+kormax@users.noreply.github.com> Date: Sat, 9 May 2026 18:33:45 +0300 Subject: [PATCH 1/2] Clear trace before HF 14B info --- client/src/cmdhf14b.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 11533c706..1182d8574 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -3159,6 +3159,8 @@ int CmdHF14B(const char *Cmd) { // get and print all info known about any known 14b tag int infoHF14B(bool verbose, bool do_aid_search) { + clear_trace_14b(); + // try std 14b (atqb) if (HF14B_Std_Info(verbose, do_aid_search)) return PM3_SUCCESS; From 2529b16662e24d1b6f60826ca44a26402b218768 Mon Sep 17 00:00:00 2001 From: kormax <3392860+kormax@users.noreply.github.com> Date: Sat, 9 May 2026 18:33:45 +0300 Subject: [PATCH 2/2] Annotate ECP in HF 14B traces --- client/src/cmdhflist.c | 74 +++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index a5fe2ca04..5534a52ec 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -199,6 +199,46 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t *d, uint8_t n) { } +static int annotateEcp(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize) { + if (cmdsize < 7 || cmd[0] != ECP_HEADER) { + return PM3_ESOFT; + } + + // Byte 0 is a header + // Byte 1 indicates format version + // Version 0x01 format is 7 bytes long (including CRC) + // Version 0x02 format is at least 7 bytes long, including CRC. + // The low nibble of byte 2 defines extra payload length. + if (cmd[1] == 0x01 && cmdsize == 7) { + snprintf(exp, size, "ECP1"); + return PM3_SUCCESS; + } + + if (cmd[1] == 0x02 && cmdsize == (cmd[2] & 0x0F) + 7) { + // Byte 3 is the reader type + switch (cmd[3]) { + case 0x01: + snprintf(exp, size, "ECP2 (Transit)"); + break; + case 0x02: + snprintf(exp, size, "ECP2 (Access)"); + break; + case 0x03: + snprintf(exp, size, "ECP2 (Identity)"); + break; + case 0x05: + snprintf(exp, size, "ECP2 (AirDrop)"); + break; + default: + snprintf(exp, size, "ECP2"); + break; + } + return PM3_SUCCESS; + } + + return PM3_ESOFT; +} + int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool is_response) { if (is_response == false) { @@ -208,35 +248,8 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i return PM3_SUCCESS; } - if (cmdsize >= 7 && cmd[0] == ECP_HEADER) { - // Byte 0 is a header - // Byte 1 indicates format version - // Version 0x01 format is 7 bytes long (including crc) - // Version 0x02 format is at least 7 bytes long (including crc). First 4 bits of byte 2 define extra payload length - if (cmd[1] == 0x01 && cmdsize == 7) { - snprintf(exp, size, "ECP1"); - return PM3_SUCCESS; - } else if (cmd[1] == 0x02 && cmdsize == (cmd[2] & 0x0F) + 7) { - // Byte 3 is the reader type - switch (cmd[3]) { - case 0x01: - snprintf(exp, size, "ECP2 (Transit)"); - break; - case 0x02: - snprintf(exp, size, "ECP2 (Access)"); - break; - case 0x03: - snprintf(exp, size, "ECP2 (Identity)"); - break; - case 0x05: - snprintf(exp, size, "ECP2 (AirDrop)"); - break; - default: - snprintf(exp, size, "ECP2"); - break; - } - return PM3_SUCCESS; - } + if (annotateEcp(exp, size, cmd, cmdsize) == PM3_SUCCESS) { + return PM3_SUCCESS; } gs_ntag_i2c_state = 0; @@ -1746,6 +1759,9 @@ void annotateIso14443b(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { break; } default: + if (annotateEcp(exp, size, cmd, cmdsize) == PM3_SUCCESS) { + break; + } snprintf(exp, size, "?"); break; }