From 6fd0d93647a9fb7b9179e6833d480b83e1797586 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 14 Jun 2023 14:24:41 +0200 Subject: [PATCH] fixed the trace list output when marking crcbytes in color mode. Some odd cases exists. --- CHANGELOG.md | 1 + client/src/cmdhflist.c | 2 +- client/src/cmdtrace.c | 133 +++++++++++++++++++++++++++++------------ 3 files changed, 98 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfa5e9510..700f906bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] + - Fixed `trace list` - now handles marking of crc bytes w color a bit better (@iceman1001) - Changed `hf mfu pwdgen -r` - now generates pwd/pack for Philips Sonicare, thanks @ckuenzi, @atc1441 (@iceman1001) - Changed `hf mfu info` - now detects Philips Sonicare devices (@iceman1001) - Fixed truncated FPGA upload due to incorrect integer size variable (@d18c7db) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index 7207e50f9..fe0ee46b0 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -70,7 +70,7 @@ static uint8_t *gs_mfuc_key = NULL; uint8_t iso14443A_CRC_check(bool isResponse, uint8_t *d, uint8_t n) { if (n < 3) return 2; - if (isResponse && (n < 6)) return 2; + if (isResponse && (n == 5)) return 2; if (d[1] == 0x50 && d[0] >= ISO14443A_CMD_ANTICOLL_OR_SELECT && d[0] <= ISO14443A_CMD_ANTICOLL_OR_SELECT_3) { diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index d3096307a..ad4847e35 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -570,8 +570,12 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr //1 CRC-command, CRC ok //2 Not crc-command - //--- Draw the data column - char line[18][160] = {{0}}; + // Draw the data column + #define TRACE_MAX_LINES 36 + // number of hex bytes to be printed per row (16 data + 2 crc) + #define TRACE_MAX_HEX_BYTES 18 + + char line[TRACE_MAX_LINES][160] = {{0}}; if (data_len == 0) { if (protocol == ICLASS && duration == 2048) { @@ -582,9 +586,10 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr snprintf(line[0], sizeof(line[0]), ""); } } + uint8_t partialbytebuff = 0; uint8_t offset = 0; - for (int j = 0; j < data_len && j / 18 < 18; j++) { + for (int j = 0; j < data_len && (j / TRACE_MAX_HEX_BYTES) < TRACE_MAX_HEX_BYTES; j++) { uint8_t parityBits = parityBytes[j >> 3]; if (protocol != LEGIC && protocol != ISO_14443B @@ -602,11 +607,14 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr && (oddparity8(frame[j]) != ((parityBits >> (7 - (j & 0x0007))) & 0x01))) { snprintf(line[j / 18] + ((j % 18) * 4), 120, "%02x! ", frame[j]); + } else if (protocol == ICLASS && hdr->isResponse == false) { + uint8_t parity = 0; for (int i = 0; i < 6; i++) { parity ^= ((frame[0] >> i) & 1); } + if (parity == ((frame[0] >> 7) & 1)) { snprintf(line[j / 18] + ((j % 18) * 4), 120, "%02x ", frame[j]); } else { @@ -631,10 +639,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } - - uint8_t crc_format_string_offset = 0; if (markCRCBytes && data_len > 2) { - //CRC-command + // CRC-command if (((protocol == PROTO_HITAG1) || (protocol == PROTO_HITAGS)) && (data_len > 1)) { // Note that UID REQUEST response has no CRC, but we don't know // if the response we see is a UID @@ -647,8 +653,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (crcStatus == 0 || crcStatus == 1) { - char *pos1 = line[(data_len - 2) / 18]; - pos1 += (((data_len - 2) % 18) * 4) - 1; + char *pos1 = line[(data_len - 2) / TRACE_MAX_HEX_BYTES]; + pos1 += (((data_len - 2) % TRACE_MAX_HEX_BYTES) * 4) - 1; (*(pos1 + 6 + 1)) = '\0'; @@ -657,26 +663,56 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (hdr->isResponse) { if (g_session.supports_colors) { if (crcStatus == 0) { - snprintf(pos1, 24, " " _RED_("%s") " ", cb_str); + snprintf(pos1, 24, AEND " " _RED_("%s"), cb_str); } else { - snprintf(pos1, 24, " " _GREEN_("%s") " ", cb_str); + snprintf(pos1, 24, AEND " " _GREEN_("%s"), cb_str); } - crc_format_string_offset = 9; } else { snprintf(pos1, 9, "[%s]", cb_str); } } else { if (g_session.supports_colors) { if (crcStatus == 0) { - snprintf(pos1, 24, AEND " " _RED_("%s") " ", cb_str); + snprintf(pos1, 24, AEND " " _RED_("%s"), cb_str); } else { - snprintf(pos1, 24, AEND " " _GREEN_("%s") " ", cb_str); + snprintf(pos1, 24, AEND " " _GREEN_("%s"), cb_str); } - crc_format_string_offset = 13; } else { snprintf(pos1, 9, "[%s]", cb_str); } } + + // odd case of second crc byte is alone in a new line + if (strlen(cb_str) < 5) { + + free(cb_str); + + pos1 = line[((data_len - 2) / TRACE_MAX_HEX_BYTES) + 1]; + cb_str = str_dup(pos1); + + if (hdr->isResponse) { + if (g_session.supports_colors) { + if (crcStatus == 0) { + snprintf(pos1, 24, _RED_("%s"), cb_str); + } else { + snprintf(pos1, 24, _GREEN_("%s"), cb_str); + } + } else { + snprintf(pos1, 9, "[%s]", cb_str); + } + } else { + if (g_session.supports_colors) { + if (crcStatus == 0) { + snprintf(pos1, 24, _RED_("%s"), cb_str); + } else { + snprintf(pos1, 24, _GREEN_("%s"), cb_str); + } + } else { + snprintf(pos1, 9, "[%s]", cb_str); + } + } + } + free(cb_str); } } @@ -688,8 +724,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr // mark short bytes (less than 8 Bit + Parity) if (protocol == ISO_14443A || - protocol == PROTO_MIFARE || - protocol == THINFILM) { + protocol == PROTO_MIFARE || + protocol == THINFILM) { // approximated with 128 * (9 * data_len); uint16_t bitime = 1056 + 32; @@ -791,8 +827,14 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } } - int num_lines = MIN((data_len - 1) / 18 + 1, 18); + int str_padder = 72; + int num_lines = MIN((data_len - 1) / TRACE_MAX_HEX_BYTES + 1, TRACE_MAX_HEX_BYTES); + for (int j = 0; j < num_lines ; j++) { + + bool last_line = (j == num_lines - 1); + str_padder = 72; + if (j == 0) { uint32_t time1 = hdr->timestamp - first_hdr->timestamp; @@ -802,25 +844,30 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr time2 = duration; } + // ansi codes addes extra chars that needs to be taken in consideration. + if (last_line && (memcmp(crc, "\x20\x20\x20\x20", 4) != 0) && g_session.supports_colors && markCRCBytes) { + str_padder = 85; + } + if (hdr->isResponse) { // tag row if (use_us) { PrintAndLogEx(NORMAL, " %10.1f | %10.1f | Tag |%-*s | %s| %s", (float)time1 / 13.56, (float)time2 / 13.56, - 72 + crc_format_string_offset, + str_padder, line[j], - (j == num_lines - 1) ? crc : " ", - (j == num_lines - 1) ? explanation : "" + (last_line) ? crc : " ", + (last_line) ? explanation : "" ); } else { PrintAndLogEx(NORMAL, " %10u | %10u | Tag |%-*s | %s| %s", time1, time2, - 72 + crc_format_string_offset, + str_padder, line[j], - (j == num_lines - 1) ? crc : " ", - (j == num_lines - 1) ? explanation : "" + (last_line) ? crc : " ", + (last_line) ? explanation : "" ); } } else { @@ -830,41 +877,51 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr _YELLOW_(" %10.1f") " | " _YELLOW_("%10.1f") " | " _YELLOW_("Rdr") " |" _YELLOW_("%-*s")" | " _YELLOW_("%s") "| " _YELLOW_("%s"), (float)time1 / 13.56, (float)time2 / 13.56, - 72 + crc_format_string_offset, + str_padder, line[j], - (j == num_lines - 1) ? crc : " ", - (j == num_lines - 1) ? explanation : "" + (last_line) ? crc : " ", + (last_line) ? explanation : "" ); } else { PrintAndLogEx(NORMAL, _YELLOW_(" %10u") " | " _YELLOW_("%10u") " | " _YELLOW_("Rdr") " |" _YELLOW_("%-*s")" | " _YELLOW_("%s") "| " _YELLOW_("%s"), time1, time2, - 72 + crc_format_string_offset, + str_padder, line[j], - (j == num_lines - 1) ? crc : " ", - (j == num_lines - 1) ? explanation : "" + (last_line) ? crc : " ", + (last_line) ? explanation : "" ); } - } } else { + + + if (last_line && (memcmp(crc, "\x20\x20\x20\x20", 4) != 0) && g_session.supports_colors && markCRCBytes) { + str_padder = 85; + // odd case of multiline, and last single byte on empty row has been colorised... + if (strlen(line[j]) < 14) { + str_padder = 81; + } + } + if (hdr->isResponse) { PrintAndLogEx(NORMAL, " | | |%-*s | %s| %s", - 72 + crc_format_string_offset, + str_padder, line[j], - (j == num_lines - 1) ? crc : " ", - (j == num_lines - 1) ? explanation : "" + last_line ? crc : " ", + last_line ? explanation : "" ); } else { PrintAndLogEx(NORMAL, " | | |" _YELLOW_("%-*s")" | " _YELLOW_("%s") "| " _YELLOW_("%s"), - 72 + crc_format_string_offset, + str_padder, line[j], - (j == num_lines - 1) ? crc : " ", - (j == num_lines - 1) ? explanation : "" + last_line ? crc : " ", + last_line ? explanation : "" ); } + } } @@ -875,8 +932,10 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr memset(explanation, 0x00, sizeof(explanation)); annotateIso14443a(explanation, sizeof(explanation), mfData, mfDataLen, hdr->isResponse); uint8_t crcc = iso14443A_CRC_check(hdr->isResponse, mfData, mfDataLen); + + //iceman: colorise crc bytes here will need a refactor of code from above. PrintAndLogEx(NORMAL, " | | * |%-*s | %-4s| %s", - 72 + crc_format_string_offset, + str_padder, sprint_hex_inrow_spaces(mfData, mfDataLen, 2), (crcc == 0 ? _RED_(" !! ") : (crcc == 1 ? _GREEN_(" ok ") : " ")), explanation);