added verbose flag to eview/view/info command where it will print the raw hex dump. This makes it a bit cleaner output

This commit is contained in:
iceman1001 2023-07-22 14:07:51 +02:00
commit 0180ca305e
2 changed files with 61 additions and 38 deletions

View file

@ -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... 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]
- Change `hf legic view/eview/info` - now in verbose mode will print raw hex dump (@iceman1001)
- Added new test for cotag demod using data commands in pm3_test.sh (@iceman1001) - Added new test for cotag demod using data commands in pm3_test.sh (@iceman1001)
- Added new sample trace file for cotag w fc/272. Thanks s1acky! (@iceman1001) - Added new sample trace file for cotag w fc/272. Thanks s1acky! (@iceman1001)
- Fixed `hf legic eload` - now it doesn't crash client (@doegox) - Fixed `hf legic eload` - now it doesn't crash client (@doegox)

View file

@ -58,32 +58,33 @@ static bool legic_xor(uint8_t *data, uint16_t cardsize) {
} }
static int decode_and_print_memory(uint16_t card_size, const uint8_t *input_buffer) { static int decode_and_print_memory(uint16_t card_size, const uint8_t *input_buffer) {
int i = 0, k = 0, segmentNum = 0, segment_len = 0, segment_flag = 0;
int crc = 0, wrp = 0, wrc = 0;
uint8_t stamp_len = 0;
char token_type[6] = {0, 0, 0, 0, 0, 0};
int dcf = 0;
int bIsSegmented = 0;
int return_value = PM3_SUCCESS;
if (!(card_size == LEGIC_PRIME_MIM22 || card_size == LEGIC_PRIME_MIM256 || card_size == LEGIC_PRIME_MIM1024)) { if (!(card_size == LEGIC_PRIME_MIM22 || card_size == LEGIC_PRIME_MIM256 || card_size == LEGIC_PRIME_MIM1024)) {
PrintAndLogEx(FAILED, "Bytebuffer is not any known legic card size! (MIM22, MIM256, MIM1024)"); PrintAndLogEx(FAILED, "Bytebuffer is not any known legic card size! (MIM22, MIM256, MIM1024)");
return_value = PM3_EFAILED;
return PM3_EFAILED; return PM3_EFAILED;
} }
// copy input buffer into newly allocated buffer, because the existing code mutates the data inside. // copy input buffer into newly allocated buffer, because the existing code mutates the data inside.
uint8_t *data = calloc(card_size, sizeof(uint8_t)); uint8_t *data = calloc(card_size, sizeof(uint8_t));
if (!data) { if (data == NULL) {
PrintAndLogEx(WARNING, "Cannot allocate memory"); PrintAndLogEx(WARNING, "Cannot allocate memory");
return PM3_EMALLOC; return PM3_EMALLOC;
} }
memcpy(data, input_buffer, card_size); memcpy(data, input_buffer, card_size);
int i = 0, k = 0, segmentNum = 0, segment_len = 0, segment_flag = 0;
int wrp = 0, wrc = 0, dcf = 0;
uint8_t stamp_len = 0;
char token_type[6] = {0, 0, 0, 0, 0, 0};
int bIsSegmented = 0;
int return_value = PM3_SUCCESS;
// Output CDF System area (9 bytes) plus remaining header area (12 bytes) // Output CDF System area (9 bytes) plus remaining header area (12 bytes)
crc = data[4]; int crc = data[4];
uint32_t calc_crc = CRC8Legic(data, 4); uint32_t calc_crc = CRC8Legic(data, 4);
PrintAndLogEx(INFO, "--------------------- " _CYAN_("Tag Information") " ----------------------");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, " " _CYAN_("CDF: System Area")); PrintAndLogEx(SUCCESS, " " _CYAN_("CDF: System Area"));
PrintAndLogEx(INFO, "------------------------------------------------------"); PrintAndLogEx(INFO, "------------------------------------------------------");
PrintAndLogEx(SUCCESS, "MCD: " _GREEN_("%02X") " MSN: " _GREEN_("%s") " MCC: " _GREEN_("%02X") " ( %s )", PrintAndLogEx(SUCCESS, "MCD: " _GREEN_("%02X") " MSN: " _GREEN_("%s") " MCC: " _GREEN_("%02X") " ( %s )",
@ -196,6 +197,7 @@ static int decode_and_print_memory(uint16_t card_size, const uint8_t *input_buff
goto out; goto out;
} }
PrintAndLogEx(INFO, "");
PrintAndLogEx(SUCCESS, _CYAN_("ADF: User Area")); PrintAndLogEx(SUCCESS, _CYAN_("ADF: User Area"));
PrintAndLogEx(INFO, "------------------------------------------------------"); PrintAndLogEx(INFO, "------------------------------------------------------");
@ -271,14 +273,14 @@ static int decode_and_print_memory(uint16_t card_size, const uint8_t *input_buff
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
PrintAndLogEx(SUCCESS, _CYAN_("WRC protected area:") " (I %d | K %d| WRC %d)", i, k, wrc); PrintAndLogEx(SUCCESS, _CYAN_("WRC protected area:") " (I %d | K %d| WRC %d)", i, k, wrc);
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
PrintAndLogEx(INFO, "## | data"); PrintAndLogEx(INFO, "## | data | ascii");
PrintAndLogEx(INFO, "---+------------------------------------------------"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
for (k = i; k < (i + wrc); ++k) for (k = i; k < (i + wrc); ++k)
data[k] ^= crc; data[k] ^= crc;
print_hex_break(data + i, wrc, 16); print_hex_break(data + i, wrc, 16);
PrintAndLogEx(INFO, "---+------------------------------------------------"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
i += wrc; i += wrc;
} }
@ -286,14 +288,14 @@ static int decode_and_print_memory(uint16_t card_size, const uint8_t *input_buff
if (hasWRP) { if (hasWRP) {
PrintAndLogEx(SUCCESS, _CYAN_("Remaining write protected area:") " (I %d | K %d | WRC %d | WRP %d WRP_LEN %d)", i, k, wrc, wrp, wrp_len); PrintAndLogEx(SUCCESS, _CYAN_("Remaining write protected area:") " (I %d | K %d | WRC %d | WRP %d WRP_LEN %d)", i, k, wrc, wrp, wrp_len);
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
PrintAndLogEx(INFO, "## | data"); PrintAndLogEx(INFO, "## | data | ascii");
PrintAndLogEx(INFO, "---+------------------------------------------------"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
for (k = i; k < (i + wrp_len); ++k) for (k = i; k < (i + wrp_len); ++k)
data[k] ^= crc; data[k] ^= crc;
print_hex_break(data + i, wrp_len, 16); print_hex_break(data + i, wrp_len, 16);
PrintAndLogEx(INFO, "---+------------------------------------------------"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
i += wrp_len; i += wrp_len;
@ -309,14 +311,14 @@ static int decode_and_print_memory(uint16_t card_size, const uint8_t *input_buff
if (remain_seg_payload_len > 0) { if (remain_seg_payload_len > 0) {
PrintAndLogEx(SUCCESS, _CYAN_("Remaining segment payload:") " (I %d | K %d | Remain LEN %d)", i, k, remain_seg_payload_len); PrintAndLogEx(SUCCESS, _CYAN_("Remaining segment payload:") " (I %d | K %d | Remain LEN %d)", i, k, remain_seg_payload_len);
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
PrintAndLogEx(INFO, "## | data"); PrintAndLogEx(INFO, "## | data | ascii");
PrintAndLogEx(INFO, "---+------------------------------------------------"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
for (k = i; k < (i + remain_seg_payload_len); ++k) for (k = i; k < (i + remain_seg_payload_len); ++k)
data[k] ^= crc; data[k] ^= crc;
print_hex_break(data + i, remain_seg_payload_len, 16); print_hex_break(data + i, remain_seg_payload_len, 16);
PrintAndLogEx(INFO, "---+------------------------------------------------\n"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------\n");
i += remain_seg_payload_len; i += remain_seg_payload_len;
} }
// end with last segment // end with last segment
@ -354,10 +356,10 @@ static int decode_and_print_memory(uint16_t card_size, const uint8_t *input_buff
if (hasWRC) { if (hasWRC) {
PrintAndLogEx(SUCCESS, _CYAN_("WRC protected area:") " (I %d | WRC %d)", i, wrc); PrintAndLogEx(SUCCESS, _CYAN_("WRC protected area:") " (I %d | WRC %d)", i, wrc);
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
PrintAndLogEx(INFO, "## | data"); PrintAndLogEx(INFO, "## | data | ascii");
PrintAndLogEx(INFO, "---+------------------------------------------------"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
print_hex_break(data + i, wrc, 16); print_hex_break(data + i, wrc, 16);
PrintAndLogEx(INFO, "----+------------------------------------------------"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
i += wrc; i += wrc;
} }
@ -365,10 +367,10 @@ static int decode_and_print_memory(uint16_t card_size, const uint8_t *input_buff
if (hasWRP) { if (hasWRP) {
PrintAndLogEx(SUCCESS, _CYAN_("Remaining write protected area:") " (I %d | WRC %d | WRP %d | WRP_LEN %d)", i, wrc, wrp, wrp_len); PrintAndLogEx(SUCCESS, _CYAN_("Remaining write protected area:") " (I %d | WRC %d | WRP %d | WRP_LEN %d)", i, wrc, wrp, wrp_len);
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
PrintAndLogEx(INFO, "## | data"); PrintAndLogEx(INFO, "## | data | ascii");
PrintAndLogEx(INFO, "---+------------------------------------------------"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
print_hex_break(data + i, wrp_len, 16); print_hex_break(data + i, wrp_len, 16);
PrintAndLogEx(INFO, "---+------------------------------------------------"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
i += wrp_len; i += wrp_len;
@ -386,10 +388,10 @@ static int decode_and_print_memory(uint16_t card_size, const uint8_t *input_buff
if (remain_seg_payload_len > 0) { if (remain_seg_payload_len > 0) {
PrintAndLogEx(SUCCESS, _CYAN_("Remaining segment payload:") " (I %d | Remain LEN %d)", i, remain_seg_payload_len); PrintAndLogEx(SUCCESS, _CYAN_("Remaining segment payload:") " (I %d | Remain LEN %d)", i, remain_seg_payload_len);
PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "");
PrintAndLogEx(INFO, "## | data"); PrintAndLogEx(INFO, "## | data | ascii");
PrintAndLogEx(INFO, "---+------------------------------------------------"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
print_hex_break(data + i, remain_seg_payload_len, 16); print_hex_break(data + i, remain_seg_payload_len, 16);
PrintAndLogEx(INFO, "---+------------------------------------------------\n"); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------\n");
} }
} }
@ -411,9 +413,11 @@ static int CmdLegicInfo(const char *Cmd) {
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
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);
CLIParserFree(ctx); CLIParserFree(ctx);
uint16_t datalen = 0; uint16_t datalen = 0;
@ -429,7 +433,7 @@ static int CmdLegicInfo(const char *Cmd) {
// allocate receiver buffer // allocate receiver buffer
uint8_t *data = calloc(card.cardsize, sizeof(uint8_t)); uint8_t *data = calloc(card.cardsize, sizeof(uint8_t));
if (!data) { if (data == NULL) {
PrintAndLogEx(WARNING, "Cannot allocate memory"); PrintAndLogEx(WARNING, "Cannot allocate memory");
return PM3_EMALLOC; return PM3_EMALLOC;
} }
@ -441,8 +445,15 @@ static int CmdLegicInfo(const char *Cmd) {
return status; return status;
} }
decode_and_print_memory(card.cardsize, data); if (verbose) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "## | 0 1 2 3 4 5 6 7 8 9 A B C D E F | ascii");
PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
print_hex_break(data, datalen, 16);
}
PrintAndLogEx(NORMAL, "");
decode_and_print_memory(card.cardsize, data);
free(data); free(data);
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -1186,6 +1197,7 @@ static int CmdLegicEView(const char *Cmd) {
arg_lit0(NULL, "22", "LEGIC Prime MIM22"), arg_lit0(NULL, "22", "LEGIC Prime MIM22"),
arg_lit0(NULL, "256", "LEGIC Prime MIM256 (def)"), arg_lit0(NULL, "256", "LEGIC Prime MIM256 (def)"),
arg_lit0(NULL, "1024", "LEGIC Prime MIM1024"), arg_lit0(NULL, "1024", "LEGIC Prime MIM1024"),
arg_lit0("v", "verbose", "verbose output"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -1193,6 +1205,7 @@ static int CmdLegicEView(const char *Cmd) {
bool m1 = arg_get_lit(ctx, 1); bool m1 = arg_get_lit(ctx, 1);
bool m2 = arg_get_lit(ctx, 2); bool m2 = arg_get_lit(ctx, 2);
bool m3 = arg_get_lit(ctx, 3); bool m3 = arg_get_lit(ctx, 3);
bool verbose = arg_get_lit(ctx, 4);
CLIParserFree(ctx); CLIParserFree(ctx);
// validations // validations
@ -1224,10 +1237,16 @@ static int CmdLegicEView(const char *Cmd) {
return PM3_ETIMEOUT; return PM3_ETIMEOUT;
} }
if (verbose) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "## | 0 1 2 3 4 5 6 7 8 9 A B C D E F | ascii");
PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
print_hex_break(dump, bytes, 16);
}
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "## | 0 1 2 3 4 5 6 7 8 9 A B C D E F | ascii"); decode_and_print_memory(bytes, dump);
PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
print_hex_break(dump, bytes, 16);
free(dump); free(dump);
return PM3_SUCCESS; return PM3_SUCCESS;
} }
@ -1380,12 +1399,14 @@ static int CmdLegicView(const char *Cmd) {
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
arg_str1("f", "file", "<fn>", "Filename of dump"), arg_str1("f", "file", "<fn>", "Filename of dump"),
arg_lit0("v", "verbose", "verbose output"),
arg_param_end arg_param_end
}; };
CLIExecWithReturn(ctx, Cmd, argtable, false); CLIExecWithReturn(ctx, Cmd, argtable, false);
int fnlen = 0; int fnlen = 0;
char filename[FILE_PATH_SIZE]; char filename[FILE_PATH_SIZE];
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
bool verbose = arg_get_lit(ctx, 2);
CLIParserFree(ctx); CLIParserFree(ctx);
// read dump file // read dump file
@ -1396,14 +1417,15 @@ static int CmdLegicView(const char *Cmd) {
return res; return res;
} }
PrintAndLogEx(NORMAL, ""); if (verbose) {
PrintAndLogEx(INFO, "## | 0 1 2 3 4 5 6 7 8 9 A B C D E F | ascii"); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------"); PrintAndLogEx(INFO, "## | 0 1 2 3 4 5 6 7 8 9 A B C D E F | ascii");
print_hex_break(dump, bytes_read, 16); PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
print_hex_break(dump, bytes_read, 16);
}
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
decode_and_print_memory(bytes_read, dump); decode_and_print_memory(bytes_read, dump);
free(dump); free(dump);
return PM3_SUCCESS; return PM3_SUCCESS;
} }