From 824d2129a047facb543a0c021c6f2bfe1f52c63a Mon Sep 17 00:00:00 2001 From: Doridian Date: Tue, 14 Jun 2022 15:56:04 -0700 Subject: [PATCH 001/759] Fix wrong length calcuation in *_to_buffer utilities --- client/src/util.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/client/src/util.c b/client/src/util.c index ed17d4120..bf506d3d6 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -164,7 +164,7 @@ void ascii_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len size_t i = 0; for (i = 0; i < max_len; ++i, tmp++) { char c = hex_data[i]; - snprintf(tmp, hex_max_len - (tmp - tmp_base), "%c", ((c < 32) || (c == 127)) ? '.' : c); + *tmp = ((c < 32) || (c == 127)) ? '.' : c; } size_t m = (min_str_len > i) ? min_str_len : 0; @@ -172,7 +172,7 @@ void ascii_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len m = hex_max_len; for (; i < m; i++, tmp++) - snprintf(tmp, hex_max_len - (tmp - tmp_base), " "); + *tmp = ' '; // remove last space *tmp = '\0'; @@ -187,13 +187,14 @@ void hex_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, char *tmp = tmp_base; size_t max_len = (hex_len > hex_max_len) ? hex_max_len : hex_len; + size_t str_max_len = hex_max_len * (2 + spaces_between); size_t i; for (i = 0; i < max_len; ++i, tmp += 2 + spaces_between) { - snprintf(tmp, hex_max_len - (tmp - tmp_base), (uppercase) ? "%02X" : "%02x", (unsigned int) hex_data[i]); + snprintf(tmp, str_max_len - (tmp - tmp_base), (uppercase) ? "%02X" : "%02x", (unsigned int) hex_data[i]); for (size_t j = 0; j < spaces_between; j++) - snprintf(tmp + 2 + j, hex_max_len - ((tmp + 2 + j) - tmp_base), " "); + *(tmp + 2 + j) = ' '; } i *= (2 + spaces_between); @@ -203,7 +204,7 @@ void hex_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, m = hex_max_len; for (; i < m; i++, tmp++) - snprintf(tmp, hex_max_len - (tmp - tmp_base), " "); + *tmp = ' '; // remove last space *tmp = '\0'; From d8c869560e59bda67e839eb0f66b62704e7c396d Mon Sep 17 00:00:00 2001 From: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> Date: Tue, 14 Jun 2022 18:56:27 -0700 Subject: [PATCH 002/759] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11934d16d..a57613df4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed - AID limitations when using Gallagher key diversification (@DarkMatterMatt) - Added new standalone mode `lf_em4100rsww` (@zabszk) - Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz) + - Added 122 new keys from Flipper Zero community to `mfc_default_keys.dic` (@UberGuidoZ) ## [Frostbit.4.14831][2022-01-11] - Changed Wiegand format lookup - now case-insensitive (@iceman1001) From cd6626829cd1623ba927a96d73872be5287dcb10 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 15 Jun 2022 07:18:58 +0200 Subject: [PATCH 003/759] fix: use correct target --- armsrc/mifarecmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 9ee2a5fc9..977e973ac 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1241,7 +1241,7 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, }; // pre-generate nonces - if (keyType == 1 && nt1 == 0x009080A2) { + if (targetKeyType == 1 && nt1 == 0x009080A2) { target_nt[0] = prng_successor(nt1, 161); target_nt[1] = prng_successor(nt1, 321); } else { From 049e73d45e6b635f06eec379cd51a1b873d2c6d8 Mon Sep 17 00:00:00 2001 From: Doridian Date: Tue, 14 Jun 2022 23:54:43 -0700 Subject: [PATCH 004/759] This actually is bytes --- client/src/util.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/src/util.c b/client/src/util.c index bf506d3d6..12e0140a7 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -187,11 +187,10 @@ void hex_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, char *tmp = tmp_base; size_t max_len = (hex_len > hex_max_len) ? hex_max_len : hex_len; - size_t str_max_len = hex_max_len * (2 + spaces_between); size_t i; for (i = 0; i < max_len; ++i, tmp += 2 + spaces_between) { - snprintf(tmp, str_max_len - (tmp - tmp_base), (uppercase) ? "%02X" : "%02x", (unsigned int) hex_data[i]); + snprintf(tmp, hex_max_len - (tmp - tmp_base), (uppercase) ? "%02X" : "%02x", (unsigned int) hex_data[i]); for (size_t j = 0; j < spaces_between; j++) *(tmp + 2 + j) = ' '; From e3b60869416ef185060c5ec3ad3e03191dd23903 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 15 Jun 2022 18:09:50 +0200 Subject: [PATCH 005/759] fix data diff, where wrong length was used --- client/src/cmddata.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index ad7879650..5653d78b8 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -3071,10 +3071,10 @@ static int CmdDiff(const char *Cmd) { // if ok, just print if (diff == 0) { - hex_to_buffer((uint8_t *)line, inA + i, width, width, 0, 1, true); + hex_to_buffer((uint8_t *)line, inA + i, width, sizeof(line), 0, 1, true); ascii_to_buffer((uint8_t *)(line + strlen(line)), inA + i, width, width, 0); - strcat(line + strlen(line), " | "); - hex_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, width, 0, 1, true); + strncat(line + strlen(line), " | ", 3); + hex_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, sizeof(line), 0, 1, true); ascii_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, width, 0); } else { @@ -3137,26 +3137,26 @@ static int CmdDiff(const char *Cmd) { memset(line, 0, sizeof(line)); if (tallestA) { - hex_to_buffer((uint8_t *)line, inA + i, width, width, 0, 1, true); - ascii_to_buffer((uint8_t *)(line + strlen(line)), inA + i, width, width, 0); + hex_to_buffer((uint8_t *)line, inA + i, width, sizeof(line), 0, 1, true); + ascii_to_buffer((uint8_t *)(line + strlen(line)), inA + i, width, sizeof(line), 0); strcat(line + strlen(line), " | "); for (int j = 0; j < width; j++) { - strcat(line + strlen(line), "-- "); + strncat(line + strlen(line), "-- ", 3); } for (int j = 0; j < width; j++) { - strcat(line + strlen(line), "."); + strncat(line + strlen(line), ".", 1); } } else { for (int j = 0; j < width; j++) { - strcat(line + strlen(line), "-- "); + strncat(line + strlen(line), "-- ", 3); } for (int j = 0; j < width; j++) { - strcat(line + strlen(line), "."); + strncat(line + strlen(line), ".", 1); } - strcat(line + strlen(line), " | "); - hex_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, width, 0, 1, true); - ascii_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, width, 0); + strncat(line + strlen(line), " | ", 3); + hex_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, sizeof(line), 0, 1, true); + ascii_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, sizeof(line), 0); } PrintAndLogEx(INFO, "%03X | %s", i, line); From 6118b11a3eda054ca614a895f1a566dc32ce76fd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 15 Jun 2022 18:48:36 +0200 Subject: [PATCH 006/759] fix proxspace breaking --- client/src/cmddata.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 5653d78b8..3b6aadc05 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -3073,7 +3073,7 @@ static int CmdDiff(const char *Cmd) { if (diff == 0) { hex_to_buffer((uint8_t *)line, inA + i, width, sizeof(line), 0, 1, true); ascii_to_buffer((uint8_t *)(line + strlen(line)), inA + i, width, width, 0); - strncat(line + strlen(line), " | ", 3); + strncat(line + strlen(line), " | ", sizeof(line) - strlen(line)); hex_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, sizeof(line), 0, 1, true); ascii_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, width, 0); } else { @@ -3137,26 +3137,26 @@ static int CmdDiff(const char *Cmd) { memset(line, 0, sizeof(line)); if (tallestA) { - hex_to_buffer((uint8_t *)line, inA + i, width, sizeof(line), 0, 1, true); - ascii_to_buffer((uint8_t *)(line + strlen(line)), inA + i, width, sizeof(line), 0); + hex_to_buffer((uint8_t *)line, inA + i, width, sizeof(line), 0, 1, true); + ascii_to_buffer((uint8_t *)(line + strlen(line)), inA + i, width, sizeof(line), 0); strcat(line + strlen(line), " | "); for (int j = 0; j < width; j++) { - strncat(line + strlen(line), "-- ", 3); + strncat(line + strlen(line), "-- ", sizeof(line) - strlen(line)); } for (int j = 0; j < width; j++) { - strncat(line + strlen(line), ".", 1); + strncat(line + strlen(line), ".", sizeof(line) - strlen(line)); } } else { for (int j = 0; j < width; j++) { - strncat(line + strlen(line), "-- ", 3); + strncat(line + strlen(line), "-- ", sizeof(line) - strlen(line)); } for (int j = 0; j < width; j++) { - strncat(line + strlen(line), ".", 1); + strncat(line + strlen(line), ".", sizeof(line) - strlen(line)); } - strncat(line + strlen(line), " | ", 3); - hex_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, sizeof(line), 0, 1, true); - ascii_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, sizeof(line), 0); + strncat(line + strlen(line), " | ", sizeof(line) - strlen(line)); + hex_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, sizeof(line), 0, 1, true); + ascii_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, sizeof(line), 0); } PrintAndLogEx(INFO, "%03X | %s", i, line); From 5ea305be288e39badbc0138c2e38968348c00e80 Mon Sep 17 00:00:00 2001 From: kormax Date: Wed, 15 Jun 2022 22:40:27 +0300 Subject: [PATCH 007/759] Fix `hf 14a reader --ecp` to work consistently --- CHANGELOG.md | 1 + armsrc/iso14443a.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a57613df4..05b1dd63b 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 `hf 14a reader --ecp` to work consistently (@kormax) - Change `trace list -t 14a` to annotate ECP frames of all valid V1 and V2 formats (@kormax) - Changed `hf mf staticnested` - significant speedups by using two encrypted nonces (@xianglin1998) - Change use of `sprintf` in code to `snprintf` to fix compilation on macOS (@Doridian) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 7cda6000d..2dbe043df 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2441,7 +2441,8 @@ static void iso14a_set_ATS_times(const uint8_t *ats) { static int GetATQA(uint8_t *resp, uint8_t *resp_par, bool use_ecp, bool use_magsafe) { -#define ECP_DELAY 15 +#define ECP_DELAY 10 +#define ECP_RETRY_TIMEOUT 100 #define WUPA_RETRY_TIMEOUT 10 // 10ms // 0x26 - REQA @@ -2457,12 +2458,14 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par, bool use_ecp, bool use_mags uint32_t save_iso14a_timeout = iso14a_get_timeout(); iso14a_set_timeout(1236 / 128 + 1); // response to WUPA is expected at exactly 1236/fc. No need to wait longer. + bool first_try = true; + uint32_t retry_timeout = use_ecp ? ECP_RETRY_TIMEOUT : WUPA_RETRY_TIMEOUT; uint32_t start_time = GetTickCount(); int len; // we may need several tries if we did send an unknown command or a wrong authentication before... do { - if (use_ecp) { + if (use_ecp && !first_try) { uint8_t ecp[] = { 0x6a, 0x02, 0xC8, 0x01, 0x00, 0x03, 0x00, 0x02, 0x79, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xD8}; ReaderTransmit(ecp, sizeof(ecp), NULL); SpinDelay(ECP_DELAY); @@ -2476,12 +2479,13 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par, bool use_ecp, bool use_mags } } - // Broadcast for a card, WUPA (0x52) will force response from all cards in the field ReaderTransmitBitsPar(wupa, 7, NULL, NULL); // Receive the ATQA len = ReaderReceive(resp, resp_par); - } while (len == 0 && GetTickCountDelta(start_time) <= WUPA_RETRY_TIMEOUT); + + first_try = false; + } while (len == 0 && GetTickCountDelta(start_time) <= retry_timeout); iso14a_set_timeout(save_iso14a_timeout); return len; From 13e13b70f48ecb7bcb958b4c41c23afd5dee65c3 Mon Sep 17 00:00:00 2001 From: kormax Date: Thu, 16 Jun 2022 09:04:21 +0300 Subject: [PATCH 008/759] Improve 'hf 14a reader --ecp' fix performance --- armsrc/iso14443a.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 2dbe043df..d6d365764 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2455,6 +2455,12 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par, bool use_ecp, bool use_mags wupa[0] = MAGSAFE_CMD_WUPA_4; } + if (use_ecp) { + // We drop the field to bring the phone back into an 'IDLE' state + switch_off(); + set_tracing(true); + } + uint32_t save_iso14a_timeout = iso14a_get_timeout(); iso14a_set_timeout(1236 / 128 + 1); // response to WUPA is expected at exactly 1236/fc. No need to wait longer. From e2574200c0a9b7665ab440ba1d240d9164edbdf5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 16 Jun 2022 21:16:25 +0200 Subject: [PATCH 009/759] commented out some dbg prints. They interfer with the simulation part --- armsrc/Standalone/hf_msdsal.c | 10 +++++----- armsrc/Standalone/hf_reblay.c | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/armsrc/Standalone/hf_msdsal.c b/armsrc/Standalone/hf_msdsal.c index f253b595b..55c545489 100644 --- a/armsrc/Standalone/hf_msdsal.c +++ b/armsrc/Standalone/hf_msdsal.c @@ -386,28 +386,28 @@ void RunMod(void) { // received a HALT } else if (receivedCmd[0] == ISO14443A_CMD_HALT && len == 4) { - DbpString(_YELLOW_("+") "Received a HALT"); +// DbpString(_YELLOW_("+") "Received a HALT"); p_response = NULL; // received a WAKEUP } else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) { - DbpString(_YELLOW_("+") "WAKEUP Received"); +// DbpString(_YELLOW_("+") "WAKEUP Received"); prevCmd = 0; p_response = &responses[RESP_INDEX_ATQA]; // received request for UID (cascade 1) } else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 2) { - DbpString(_YELLOW_("+") "Request for UID C1"); +// DbpString(_YELLOW_("+") "Request for UID C1"); p_response = &responses[RESP_INDEX_UIDC1]; // received a SELECT (cascade 1) } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 9) { - DbpString(_YELLOW_("+") "Request for SELECT S1"); +// DbpString(_YELLOW_("+") "Request for SELECT S1"); p_response = &responses[RESP_INDEX_SAKC1]; // received a RATS request } else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { - DbpString(_YELLOW_("+") "Request for RATS"); +// DbpString(_YELLOW_("+") "Request for RATS"); prevCmd = 0; p_response = &responses[RESP_INDEX_RATS]; diff --git a/armsrc/Standalone/hf_reblay.c b/armsrc/Standalone/hf_reblay.c index 6c7f16ede..cf290fa31 100644 --- a/armsrc/Standalone/hf_reblay.c +++ b/armsrc/Standalone/hf_reblay.c @@ -314,24 +314,24 @@ void RunMod() { } } if (receivedCmd[0] == ISO14443A_CMD_REQA && len == 1) { // Received a REQUEST - DbpString(_YELLOW_("+") "REQUEST Received"); +// DbpString(_YELLOW_("+") "REQUEST Received"); p_response = &responses[RESP_INDEX_ATQA]; } else if (receivedCmd[0] == ISO14443A_CMD_HALT && len == 4) { // Received a HALT - DbpString(_YELLOW_("+") "Received a HALT"); +// DbpString(_YELLOW_("+") "Received a HALT"); p_response = NULL; resp = 0; } else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) { // Received a WAKEUP - DbpString(_YELLOW_("+") "WAKEUP Received"); +// DbpString(_YELLOW_("+") "WAKEUP Received"); p_response = &responses[RESP_INDEX_ATQA]; resp = 0; } else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 2) { // Received request for UID (cascade 1) - DbpString(_YELLOW_("+") "Request for UID C1"); +// DbpString(_YELLOW_("+") "Request for UID C1"); p_response = &responses[RESP_INDEX_UIDC1]; } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 9) { // Received a SELECT (cascade 1) - DbpString(_YELLOW_("+") "Request for SELECT S1"); +// DbpString(_YELLOW_("+") "Request for SELECT S1"); p_response = &responses[RESP_INDEX_SAKC1]; } else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { // Received a RATS request - DbpString(_YELLOW_("+") "Request for RATS"); +// DbpString(_YELLOW_("+") "Request for RATS"); p_response = &responses[RESP_INDEX_RATS]; resp = 1; } else if (receivedCmd[0] == 0xf2 && len == 4) { // ACKed - Time extension From 8e8618c989297f173e06b64201bf909324078399 Mon Sep 17 00:00:00 2001 From: kormax Date: Thu, 16 Jun 2022 22:31:32 +0300 Subject: [PATCH 010/759] Replace rf reset with an s-block deselect when using 'hf 14a reader --ecp' --- armsrc/iso14443a.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index d6d365764..c897aa691 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2445,6 +2445,7 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par, bool use_ecp, bool use_mags #define ECP_RETRY_TIMEOUT 100 #define WUPA_RETRY_TIMEOUT 10 // 10ms + // 0x26 - REQA // 0x52 - WAKE-UP // 0x7A - MAGESAFE WAKE UP @@ -2456,9 +2457,11 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par, bool use_ecp, bool use_mags } if (use_ecp) { - // We drop the field to bring the phone back into an 'IDLE' state - switch_off(); - set_tracing(true); + // In case a device was already selected, we send a S-BLOCK deselect to bring it into an idle state so it can be selected again + uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4}; + ReaderTransmit(deselect_cmd, sizeof(deselect_cmd), NULL); + // Read response if present + ReaderReceive(resp, resp_par); } uint32_t save_iso14a_timeout = iso14a_get_timeout(); From 2e52b4ba30ad893e243832ea48d57b1997ac9d33 Mon Sep 17 00:00:00 2001 From: Mike <63983972+Teamwolf11@users.noreply.github.com> Date: Mon, 20 Jun 2022 11:08:18 +1200 Subject: [PATCH 011/759] Update Windows-Installation-Instructions.md --- .../Windows-Installation-Instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md index a16c3c4d4..6ac9e53b3 100644 --- a/doc/md/Installation_Instructions/Windows-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Windows-Installation-Instructions.md @@ -90,7 +90,7 @@ git clone https://github.com/RfidResearchGroup/proxmark3.git cd proxmark3 ``` -If you're a contributing developer, you probably want to be able to use `make style`. If so, you've to install astyle: +If you're a contributing developer, you probably want to be able to use `make style`. If so, you've got to install astyle: ```sh pacman -S mingw-w64-x86_64-astyle From b9b6f06bbb9850b3f2781c0a5c6d10d50a599802 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 23 Jun 2022 22:02:42 +0200 Subject: [PATCH 012/759] style --- client/src/cmdhfmfp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index dcd73fb35..c05adfe40 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -1372,7 +1372,7 @@ static int CmdHFMFPMAD(const char *Cmd) { if (mfpReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector0, verbose)) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(ERR, "error, read sector 0. card doesn't have MAD or doesn't have MAD on default keys"); - return 2; + return PM3_ESOFT; } PrintAndLogEx(NORMAL, ""); @@ -1392,7 +1392,7 @@ static int CmdHFMFPMAD(const char *Cmd) { if (mfpReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifarep_mad_key, sector10, verbose)) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(ERR, "error, read sector 0x10. card doesn't have MAD or doesn't have MAD on default keys"); - return 2; + return PM3_ESOFT; } MAD2DecodeAndPrint(sector10, swapmad, verbose); @@ -1403,7 +1403,7 @@ static int CmdHFMFPMAD(const char *Cmd) { size_t madlen = 0; if (MADDecode(sector0, sector10, mad, &madlen, swapmad)) { PrintAndLogEx(ERR, "can't decode MAD"); - return 10; + return PM3_EWRONGANSWER; } // copy default NDEF key From f3b5c7e8ba8e5f79eadab8164695985ace9dc38c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Jun 2022 15:17:02 +0300 Subject: [PATCH 013/759] decode password in case of the read/write comand --- client/src/cmdlft55xx.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 2af8f18b7..866702d08 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -4027,8 +4027,8 @@ static int CmdT55xxSniff(const char *Cmd) { // Headings PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, _CYAN_("T55xx command detection")); - PrintAndLogEx(SUCCESS, "Downlink mode | password | Data | blk | page | 0 | 1 | raw"); - PrintAndLogEx(SUCCESS, "----------------------+----------+----------+-----+------+-----+-----+-------------------------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, "Downlink mode | password | Data | blk | page | 0 | 1 | raw"); + PrintAndLogEx(SUCCESS, "------------------------+------------+----------+-----+------+-----+-----+-------------------------------------------------------------------------------"); idx = 0; // loop though sample buffer @@ -4164,11 +4164,15 @@ static int CmdT55xxSniff(const char *Cmd) { } have_data = true; modeText = "Default pwd write"; - snprintf(pwdText, sizeof(pwdText), "%08X", usedPassword); + snprintf(pwdText, sizeof(pwdText), " %08X", usedPassword); snprintf(dataText, sizeof(dataText), "%08X", blockData); } - // Default Write (or password read ??) + // Default Write or password read ??? + // the most confusing command. + // if the token is with a password - all is OK, + // if not - read command with a password will lead to write the shifted password to the memory and: + // IF the most bit of the data is `1` ----> IT LEADS TO LOCK this block of the memory if (dataLen == 38) { t55sniff_trim_samples(pulseBuffer, &pulseIdx, 38); @@ -4180,6 +4184,12 @@ static int CmdT55xxSniff(const char *Cmd) { if (data[i] == '1') blockData |= 1; } + for (uint8_t i = 2; i <= 33; i++) { + usedPassword <<= 1; + if (data[i] == '1') { + usedPassword |= 1; + } + } blockAddr = 0; for (uint8_t i = 35; i <= 37; i++) { blockAddr <<= 1; @@ -4187,7 +4197,8 @@ static int CmdT55xxSniff(const char *Cmd) { blockAddr |= 1; } have_data = true; - modeText = "Default write"; + modeText = "Default write/pwd read"; + snprintf(pwdText, sizeof(pwdText), "[%08X]", usedPassword); snprintf(dataText, sizeof(dataText), "%08X", blockData); } } @@ -4224,7 +4235,7 @@ static int CmdT55xxSniff(const char *Cmd) { } have_data = true; modeText = "Leading 0 pwd write"; - snprintf(pwdText, sizeof(pwdText), "%08X", usedPassword); + snprintf(pwdText, sizeof(pwdText), " %08X", usedPassword); snprintf(dataText, sizeof(dataText), "%08X", blockData); } } @@ -4234,9 +4245,9 @@ static int CmdT55xxSniff(const char *Cmd) { // Print results if (have_data) { if (blockAddr == 7) - PrintAndLogEx(SUCCESS, "%-20s | "_GREEN_("%8s")" | "_YELLOW_("%8s")" | "_YELLOW_("%d")" | "_GREEN_("%d")" | %3d | %3d | %s", modeText, pwdText, dataText, blockAddr, page, minWidth, maxWidth, data); + PrintAndLogEx(SUCCESS, "%-22s | "_GREEN_("%10s")" | "_YELLOW_("%8s")" | "_YELLOW_("%d")" | "_GREEN_("%d")" | %3d | %3d | %s", modeText, pwdText, dataText, blockAddr, page, minWidth, maxWidth, data); else - PrintAndLogEx(SUCCESS, "%-20s | "_GREEN_("%8s")" | "_GREEN_("%8s")" | "_GREEN_("%d")" | "_GREEN_("%d")" | %3d | %3d | %s", modeText, pwdText, dataText, blockAddr, page, minWidth, maxWidth, data); + PrintAndLogEx(SUCCESS, "%-22s | "_GREEN_("%10s")" | "_GREEN_("%8s")" | "_GREEN_("%d")" | "_GREEN_("%d")" | %3d | %3d | %s", modeText, pwdText, dataText, blockAddr, page, minWidth, maxWidth, data); } } From acdd39c15b32be5e8e383a9db1814f3ebe5840bb Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Jun 2022 15:51:59 +0300 Subject: [PATCH 014/759] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05b1dd63b..d8a13e0e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added new standalone mode `lf_em4100rsww` (@zabszk) - Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz) - Added 122 new keys from Flipper Zero community to `mfc_default_keys.dic` (@UberGuidoZ) + - Added showing password for the read command in the `lf t55xx sniff` command (@merlokk) ## [Frostbit.4.14831][2022-01-11] - Changed Wiegand format lookup - now case-insensitive (@iceman1001) From bf29c9d9d5ddf2267f7811e2c4e25d3bb085e828 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Jun 2022 21:55:19 +0300 Subject: [PATCH 015/759] add info to guide --- doc/T5577_Guide.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/doc/T5577_Guide.md b/doc/T5577_Guide.md index f1abe2bb9..c8b34e8e8 100644 --- a/doc/T5577_Guide.md +++ b/doc/T5577_Guide.md @@ -462,7 +462,9 @@ required, please do not proceed. ***Reading a T5577 block with a password when a password is not enabled can result in locking the card. Please only use read with a - password when it is known that a password is in use.*** + password when it is known that a password is in use. + + At least don't use block 0 for this and password with `1` in the most significant bit*** The proxmark3 has a safety check\! ``` @@ -718,6 +720,27 @@ it, we can follow the password section and update the config from _to be written_ +## sniffing commands + +Some readers work with cards via T55xx commands (read/write/etc) and think that they are safe) +The password in this case is sent in clear text. +So) There is a sniff command to get this command from the buffer or the field: + + ``` + [usb] pm3 --> lf t55xx sniff + ``` + result: + ``` + + [=] T55xx command detection + [+] Downlink mode | password | Data | blk | page | 0 | 1 | raw + [+] ------------------------+------------+----------+-----+------+-----+-+------------------------------------------------------------------------------- + [+] Default write/pwd read | [FFxxxxxx] | FFxxxxxx | 6 | 0 | 16 | 45 | 1011111111101xxxxxxxxxxxxxxxx100000110 + [+] Default write/pwd read | [FFxxxxxx] | FFxxxxxx | 6 | 0 | 17 | 46 | 1011111111101xxxxxxxxxxxxxxxx100000110 + [+] ----------------------------------------------------------------------------------------------------------------------------------------------------- + + ``` + ## T5577 and Keysy From 9168fe61643add9797f4831cf9de1cd6e0e0630f Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Jun 2022 22:01:00 +0300 Subject: [PATCH 016/759] Update T5577_Guide.md Signed-off-by: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> --- doc/T5577_Guide.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/doc/T5577_Guide.md b/doc/T5577_Guide.md index c8b34e8e8..3899bb075 100644 --- a/doc/T5577_Guide.md +++ b/doc/T5577_Guide.md @@ -726,20 +726,17 @@ Some readers work with cards via T55xx commands (read/write/etc) and think that The password in this case is sent in clear text. So) There is a sniff command to get this command from the buffer or the field: - ``` [usb] pm3 --> lf t55xx sniff - ``` + result: - ``` - + [=] T55xx command detection [+] Downlink mode | password | Data | blk | page | 0 | 1 | raw - [+] ------------------------+------------+----------+-----+------+-----+-+------------------------------------------------------------------------------- + [+] ------------------------+------------+----------+-----+------+-----+-+--------------------------------------------- [+] Default write/pwd read | [FFxxxxxx] | FFxxxxxx | 6 | 0 | 16 | 45 | 1011111111101xxxxxxxxxxxxxxxx100000110 [+] Default write/pwd read | [FFxxxxxx] | FFxxxxxx | 6 | 0 | 17 | 46 | 1011111111101xxxxxxxxxxxxxxxx100000110 - [+] ----------------------------------------------------------------------------------------------------------------------------------------------------- - - ``` + [+] ------------------------------------------------------------------------------------------------------------------- + ## T5577 and Keysy From deb12ab70068f84ad79277fdef3e6ebb4d0880cc Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Jun 2022 22:01:42 +0300 Subject: [PATCH 017/759] Update T5577_Guide.md Signed-off-by: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> --- doc/T5577_Guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/T5577_Guide.md b/doc/T5577_Guide.md index 3899bb075..ff0e0d3c0 100644 --- a/doc/T5577_Guide.md +++ b/doc/T5577_Guide.md @@ -720,7 +720,7 @@ it, we can follow the password section and update the config from _to be written_ -## sniffing commands +## Sniffing commands Some readers work with cards via T55xx commands (read/write/etc) and think that they are safe) The password in this case is sent in clear text. From 636a850171e539ebdbc69534b00410d2f1f19559 Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Jun 2022 22:03:53 +0300 Subject: [PATCH 018/759] Update T5577_Guide.md Signed-off-by: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> --- doc/T5577_Guide.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/T5577_Guide.md b/doc/T5577_Guide.md index ff0e0d3c0..deab49d53 100644 --- a/doc/T5577_Guide.md +++ b/doc/T5577_Guide.md @@ -22,6 +22,8 @@ | [The configuration Block – Block 0 Page 0](#the-configuration-block-block-0-page-0) | | [Exercise 2](#exercise-2) | | [The configuration Block – Block 3 Page 1](#the-configuration-block-block-3-page-1) | +| [Sniffing commands](#sniffing-commands) | +| [T5577 and Keysy](#t5577-and-keysy) | # Part 1 ^[Top](#top) @@ -721,6 +723,7 @@ _to be written_ ## Sniffing commands +^[Top](#top) Some readers work with cards via T55xx commands (read/write/etc) and think that they are safe) The password in this case is sent in clear text. @@ -740,6 +743,7 @@ So) There is a sniff command to get this command from the buffer or the field: ## T5577 and Keysy +^[Top](#top) The Keysy tag cloning tool (https://tinylabs.io/keysy/) uses T5577 tags that have a special "password" value (NOT the password described above) written in Block 6 that is tied to the traceability data. The Keysy checks and computes the proper value for Block 6 and will not write to a tag that does not contain the proper value. This DRM technology relies on the face that genuine T5577 chips cannot have their traceability data (Blocks 1 and 2 of Page 1) re-written and that the method to computer the proper value for Block 6 is proprietary, therefore compelling you to buy their branded tags. From ded87056d41b6e1a13be76436cf0a6f33888bbf8 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 24 Jun 2022 22:26:10 +0300 Subject: [PATCH 019/759] `hf texkom` command --- client/CMakeLists.txt | 1 + client/Makefile | 1 + client/src/cmdhf.c | 2 ++ client/src/cmdhftexkom.c | 69 ++++++++++++++++++++++++++++++++++++++++ client/src/cmdhftexkom.h | 27 ++++++++++++++++ 5 files changed, 100 insertions(+) create mode 100644 client/src/cmdhftexkom.c create mode 100644 client/src/cmdhftexkom.h diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index b86335c66..750c83c6b 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -294,6 +294,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdhfst25ta.c ${PM3_ROOT}/client/src/cmdhfthinfilm.c ${PM3_ROOT}/client/src/cmdhftopaz.c + ${PM3_ROOT}/client/src/cmdhftexkom.c ${PM3_ROOT}/client/src/cmdhfwaveshare.c ${PM3_ROOT}/client/src/cmdhw.c ${PM3_ROOT}/client/src/cmdlf.c diff --git a/client/Makefile b/client/Makefile index e2dd1a224..d4893b341 100644 --- a/client/Makefile +++ b/client/Makefile @@ -576,6 +576,7 @@ SRCS = mifare/aiddesfire.c \ cmdhfst25ta.c \ cmdhfthinfilm.c \ cmdhftopaz.c \ + cmdhftexkom.c \ cmdhfwaveshare.c \ cmdhw.c \ cmdlf.c \ diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index ccb697966..9ed214eac 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -47,6 +47,7 @@ #include "cmdhfseos.h" // SEOS #include "cmdhfst25ta.h" // ST25TA #include "cmdhfwaveshare.h" // Waveshare +#include "cmdhftexkom.h" // Texkom #include "cmdtrace.h" // trace list #include "ui.h" #include "proxgui.h" @@ -435,6 +436,7 @@ static command_t CommandTable[] = { {"st25ta", CmdHFST25TA, AlwaysAvailable, "{ ST25TA RFIDs... }"}, {"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"}, {"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"}, + {"texkom", CmdHFTexkom, AlwaysAvailable, "{ Texkom RFIDs... }"}, {"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"}, {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, {"help", CmdHelp, AlwaysAvailable, "This help"}, diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c new file mode 100644 index 000000000..54a1e47c7 --- /dev/null +++ b/client/src/cmdhftexkom.c @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// High frequency proximity cards from TEXCOM commands +//----------------------------------------------------------------------------- + +#include "cmdhftexkom.h" + +#include +#include +#include +#include "cliparser.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmdhf14a.h" + +static int CmdHFTexkomReader(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf texkom reader", + "Read a texkom tag", + "hf texkom reader"); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + +// uint8_t param = 0; +// SendCommandNG(CMD_HF_TEXKOM_READER, (uint8_t *)¶m, sizeof(uint8_t)); + + return PM3_SUCCESS; +} + + +static int CmdHelp(const char *Cmd); + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"reader", CmdHFTexkomReader, IfPm3Iso14443a, "Act like a Texkom reader"}, + //{"sim", CmdHFTexkomSim, IfPm3Iso14443a, "Simulate a Texkom tag"}, + //{"write", CmdHFTexkomWrite, IfPm3Iso14443a, "Write a Texkom tag"}, + {NULL, NULL, 0, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdHFTexkom(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/src/cmdhftexkom.h b/client/src/cmdhftexkom.h new file mode 100644 index 000000000..9f4a3b32f --- /dev/null +++ b/client/src/cmdhftexkom.h @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// High frequency proximity cards from TEXCOM commands +//----------------------------------------------------------------------------- + +#ifndef CMDHFTEXCOM_H__ +#define CMDHFTEXCOM_H__ + +#include "common.h" +#include "pm3_cmd.h" + +int CmdHFTexkom(const char *Cmd); + +#endif \ No newline at end of file From 541c060a5d5834af53b861545f685272f8be9d8b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 25 Jun 2022 00:36:42 +0300 Subject: [PATCH 020/759] hf read adc low level command --- armsrc/Makefile | 2 ++ armsrc/appmain.c | 10 ++++++++++ armsrc/hfops.c | 41 ++++++++++++++++++++++++++++++++++++++++ armsrc/hfops.h | 27 ++++++++++++++++++++++++++ client/src/cmdhftexkom.c | 4 ++-- common_arm/Makefile.hal | 3 +++ include/pm3_cmd.h | 1 + 7 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 armsrc/hfops.c create mode 100644 armsrc/hfops.h diff --git a/armsrc/Makefile b/armsrc/Makefile index 413570565..5505119b7 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -35,6 +35,7 @@ APP_CFLAGS = $(PLATFORM_DEFS) \ -ffunction-sections -fdata-sections SRC_LF = lfops.c lfsampling.c pcf7931.c lfdemod.c lfadc.c +SRC_HF = hfops.c SRC_ISO15693 = iso15693.c iso15693tools.c SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c #UNUSED: mifaresniff.c @@ -132,6 +133,7 @@ THUMBSRC = start.c \ $(SRC_EM4x50) \ $(SRC_EM4x70) \ $(SRC_SPIFFS) \ + $(SRC_HF) \ $(SRC_ISO14443a) \ $(SRC_ISO14443b) \ $(SRC_CRAPTO1) \ diff --git a/armsrc/appmain.c b/armsrc/appmain.c index afcdc04ac..c28357108 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -33,6 +33,7 @@ #include "legicrf.h" #include "BigBuf.h" #include "iclass_cmd.h" +#include "hfops.h" #include "iso14443a.h" #include "iso14443b.h" #include "iso15693.h" @@ -1384,6 +1385,15 @@ static void PacketReceived(PacketCommandNG *packet) { } #endif +#ifdef WITH_GENERAL_HF + case CMD_HF_ACQ_RAW_ADC: { + uint32_t samplesCount = 0; + memcpy(&samplesCount, packet->data.asBytes, 4); + HfReadADC(samplesCount); + break; + } +#endif + #ifdef WITH_ISO14443a case CMD_HF_ISO14443A_PRINT_CONFIG: { printHf14aConfig(); diff --git a/armsrc/hfops.c b/armsrc/hfops.c new file mode 100644 index 000000000..180cca409 --- /dev/null +++ b/armsrc/hfops.c @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// HF general operations +//----------------------------------------------------------------------------- + +#include "hfops.h" + +#include "proxmark3_arm.h" +#include "cmd.h" +#include "BigBuf.h" +#include "fpgaloader.h" +#include "ticks.h" +#include "dbprint.h" +#include "util.h" +#include "commonutil.h" + + +int HfReadADC(uint32_t samplesCount) { + + + + + DbpString("HfReadADC " _GREEN_("success")); + + return 0; +} + + diff --git a/armsrc/hfops.h b/armsrc/hfops.h new file mode 100644 index 000000000..76ed4b8bc --- /dev/null +++ b/armsrc/hfops.h @@ -0,0 +1,27 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// HF general operations +//----------------------------------------------------------------------------- + +#ifndef HFOPS_H +#define HFOPS_H + +#include "common.h" + +int HfReadADC(uint32_t samplesCount); + + +#endif \ No newline at end of file diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 54a1e47c7..51758af3e 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -40,8 +40,8 @@ static int CmdHFTexkomReader(const char *Cmd) { CLIExecWithReturn(ctx, Cmd, argtable, true); CLIParserFree(ctx); -// uint8_t param = 0; -// SendCommandNG(CMD_HF_TEXKOM_READER, (uint8_t *)¶m, sizeof(uint8_t)); + uint32_t samplesCount = 40000; + SendCommandNG(CMD_HF_ACQ_RAW_ADC, (uint8_t *)&samplesCount, sizeof(uint32_t)); return PM3_SUCCESS; } diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index 62b99020d..68417eb60 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -143,6 +143,9 @@ ifneq ($(SKIP_ZX8211),1) endif # common HF support +ifneq ($(SKIP_HF),1) + PLATFORM_DEFS += -DWITH_GENERAL_HF +endif ifneq ($(SKIP_ISO15693),1) PLATFORM_DEFS += -DWITH_ISO15693 endif diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index c900eb952..e53132309 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -511,6 +511,7 @@ typedef struct { // For the 13.56 MHz tags #define CMD_HF_ISO15693_ACQ_RAW_ADC 0x0300 +#define CMD_HF_ACQ_RAW_ADC 0x0301 #define CMD_HF_SRI_READ 0x0303 #define CMD_HF_ISO14443B_COMMAND 0x0305 #define CMD_HF_ISO15693_READER 0x0310 From e3a50e0e1ef7903edb5a10da044e12195b186323 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 25 Jun 2022 14:56:24 +0300 Subject: [PATCH 021/759] configuring fpga and dma --- armsrc/appmain.c | 2 +- armsrc/hfops.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++- armsrc/hfops.h | 2 +- 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index c28357108..5254368ae 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1389,7 +1389,7 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_HF_ACQ_RAW_ADC: { uint32_t samplesCount = 0; memcpy(&samplesCount, packet->data.asBytes, 4); - HfReadADC(samplesCount); + HfReadADC(samplesCount, true); break; } #endif diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 180cca409..a1bc7b80d 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -28,11 +28,87 @@ #include "commonutil.h" -int HfReadADC(uint32_t samplesCount) { +int HfReadADC(uint32_t samplesCount, bool ledcontrol) { + if (ledcontrol) LEDsoff(); + + BigBuf_Clear_ext(false); + + // And put the FPGA in the appropriate mode + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE); + + // Setup and start DMA. + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); + + // The DMA buffer, used to stream samples from the FPGA + dmabuf16_t *dma = get_dma16(); + + // Setup and start DMA. + if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { + if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscDma failed. Exiting"); + + FpgaDisableSscDma(); + FpgaSetupSsc(FPGA_MAJOR_MODE_OFF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + return PM3_EINIT; + } + + if (ledcontrol) LED_A_ON(); + + uint32_t samples = 0; + //uint32_t dma_start_time = 0; + uint16_t *upTo = dma->buf; + + for (;;) { + if (BUTTON_PRESS()) { + break; + } + + volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); + if (behindBy == 0) + continue; + + samples++; + if (samples == 1) { + // DMA has transferred the very first data + //dma_start_time = GetCountSspClk() & 0xfffffff0; + } + + if (upTo >= dma->buf + DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. + upTo = dma->buf; // start reading the circular buffer from the beginning + + // DMA Counter Register had reached 0, already rotated. + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { + + // primary buffer was stopped + if (AT91C_BASE_PDC_SSC->PDC_RCR == false) { + AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf; + AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; + } + // secondary buffer sets as primary, secondary buffer was stopped + if (AT91C_BASE_PDC_SSC->PDC_RNCR == false) { + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; + } + + WDT_HIT(); + } + } + } + + FpgaDisableSscDma(); + FpgaDisableTracing(); + + FpgaSetupSsc(FPGA_MAJOR_MODE_OFF); + // Turn the field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + + reply_ng(CMD_HF_ACQ_RAW_ADC, PM3_SUCCESS, NULL, 0); + if (ledcontrol) LEDsoff(); + DbpString("HfReadADC " _GREEN_("success")); return 0; diff --git a/armsrc/hfops.h b/armsrc/hfops.h index 76ed4b8bc..2a804ccf1 100644 --- a/armsrc/hfops.h +++ b/armsrc/hfops.h @@ -21,7 +21,7 @@ #include "common.h" -int HfReadADC(uint32_t samplesCount); +int HfReadADC(uint32_t samplesCount, bool ledcontrol); #endif \ No newline at end of file From 0392cfaa9b63cc6b2c8275138344217db9ebe3f1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 25 Jun 2022 15:23:04 +0300 Subject: [PATCH 022/759] read response --- client/src/cmdhftexkom.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 51758af3e..e20be5af3 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -41,8 +41,15 @@ static int CmdHFTexkomReader(const char *Cmd) { CLIParserFree(ctx); uint32_t samplesCount = 40000; + clearCommandBuffer(); SendCommandNG(CMD_HF_ACQ_RAW_ADC, (uint8_t *)&samplesCount, sizeof(uint32_t)); + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_ACQ_RAW_ADC, &resp, 2500)) { + PrintAndLogEx(WARNING, "(hf texkom reader) command execution time out"); + return PM3_ETIMEOUT; + } + return PM3_SUCCESS; } From f007db6661e99f8803d6c46e4068fde20cb08c3f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 25 Jun 2022 15:42:11 +0300 Subject: [PATCH 023/759] fill samples - get samples --- armsrc/hfops.c | 10 ++++++++-- client/src/cmdhftexkom.c | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index a1bc7b80d..8bf588369 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -26,6 +26,7 @@ #include "dbprint.h" #include "util.h" #include "commonutil.h" +#include "lfsampling.h" int HfReadADC(uint32_t samplesCount, bool ledcontrol) { @@ -58,6 +59,9 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { //uint32_t dma_start_time = 0; uint16_t *upTo = dma->buf; + uint32_t sbs = samplesCount; + initSampleBuffer(&sbs); + for (;;) { if (BUTTON_PRESS()) { break; @@ -95,8 +99,10 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { } + logSample(50, 1, 8, false); - + if (getSampleCounter() >= samplesCount) + break; } FpgaDisableSscDma(); @@ -109,7 +115,7 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { reply_ng(CMD_HF_ACQ_RAW_ADC, PM3_SUCCESS, NULL, 0); if (ledcontrol) LEDsoff(); - DbpString("HfReadADC " _GREEN_("success")); + Dbprintf("-- samples: %d", getSampleCounter()); return 0; } diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index e20be5af3..b015c7fb7 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -26,6 +26,7 @@ #include "comms.h" #include "ui.h" #include "cmdhf14a.h" +#include "cmddata.h" static int CmdHFTexkomReader(const char *Cmd) { CLIParserContext *ctx; @@ -50,6 +51,8 @@ static int CmdHFTexkomReader(const char *Cmd) { return PM3_ETIMEOUT; } + getSamples(samplesCount, true); + return PM3_SUCCESS; } From 5784999002eb79eeb9b7a612c01e50a96f81cea8 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 25 Jun 2022 16:11:59 +0300 Subject: [PATCH 024/759] first look at the data --- armsrc/hfops.c | 25 +++++++++---------------- client/src/cmdhftexkom.c | 4 +++- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 8bf588369..a43897764 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -55,8 +55,6 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { if (ledcontrol) LED_A_ON(); - uint32_t samples = 0; - //uint32_t dma_start_time = 0; uint16_t *upTo = dma->buf; uint32_t sbs = samplesCount; @@ -71,11 +69,13 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { if (behindBy == 0) continue; - samples++; - if (samples == 1) { - // DMA has transferred the very first data - //dma_start_time = GetCountSspClk() & 0xfffffff0; - } + uint16_t sample = *upTo; + logSample(sample & 0xff, 1, 8, false); + logSample((sample >> 8) & 0xff, 1, 8, false); + upTo++; + + if (getSampleCounter() >= samplesCount) + break; if (upTo >= dma->buf + DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. upTo = dma->buf; // start reading the circular buffer from the beginning @@ -97,12 +97,6 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { WDT_HIT(); } } - - - logSample(50, 1, 8, false); - - if (getSampleCounter() >= samplesCount) - break; } FpgaDisableSscDma(); @@ -112,11 +106,10 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { // Turn the field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - reply_ng(CMD_HF_ACQ_RAW_ADC, PM3_SUCCESS, NULL, 0); + uint32_t scnt = getSampleCounter(); + reply_ng(CMD_HF_ACQ_RAW_ADC, PM3_SUCCESS, (uint8_t*)&scnt, 4); if (ledcontrol) LEDsoff(); - Dbprintf("-- samples: %d", getSampleCounter()); - return 0; } diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index b015c7fb7..e03dfb910 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -51,7 +51,9 @@ static int CmdHFTexkomReader(const char *Cmd) { return PM3_ETIMEOUT; } - getSamples(samplesCount, true); + uint32_t size = (resp.data.asDwords[0]); + if (size > 0) + getSamples(samplesCount, true); return PM3_SUCCESS; } From eeb7ac981c4c090179d89d62f2a19da6766f4a7f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 26 Jun 2022 11:29:34 +0300 Subject: [PATCH 025/759] additional init --- armsrc/hfops.c | 51 +++++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index a43897764..d4d5c1e51 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -18,6 +18,7 @@ #include "hfops.h" +#include #include "proxmark3_arm.h" #include "cmd.h" #include "BigBuf.h" @@ -33,15 +34,19 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { if (ledcontrol) LEDsoff(); BigBuf_Clear_ext(false); + // connect Demodulated Signal to ADC: + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // And put the FPGA in the appropriate mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE); // Setup and start DMA. FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); // The DMA buffer, used to stream samples from the FPGA dmabuf16_t *dma = get_dma16(); + memset((uint8_t *) dma->buf, 0, DMA_BUFFER_SIZE); // Setup and start DMA. if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { @@ -69,33 +74,41 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { if (behindBy == 0) continue; - uint16_t sample = *upTo; - logSample(sample & 0xff, 1, 8, false); - logSample((sample >> 8) & 0xff, 1, 8, false); - upTo++; + // FPGA side: + // corr_i_out <= {2'b00, corr_amplitude[13:8]}; + // corr_q_out <= corr_amplitude[7:0]; + // ci = upTo >> 8, cq = upTo + volatile uint16_t sample = *upTo++; + //if (sample & 0xc000) { + // Dbprintf("sample!!!! %d \r\n", getSampleCounter()); + // break; + //} + + logSample((sample >> 6) & 0xff, 1, 8, false); if (getSampleCounter() >= samplesCount) break; if (upTo >= dma->buf + DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. upTo = dma->buf; // start reading the circular buffer from the beginning + } - // DMA Counter Register had reached 0, already rotated. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { + // DMA Counter Register had reached 0, already rotated. + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { - // primary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RCR == false) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - } - // secondary buffer sets as primary, secondary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RNCR == false) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } - - WDT_HIT(); + // primary buffer was stopped + if (AT91C_BASE_PDC_SSC->PDC_RCR == false) { + AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf; + AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; + Dbprintf("blew\r\n"); } + // secondary buffer sets as primary, secondary buffer was stopped + if (AT91C_BASE_PDC_SSC->PDC_RNCR == false) { + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; + } + + WDT_HIT(); } } From 9813f8556749abb32785ab7b15270885dd73c73d Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 27 Jun 2022 00:30:49 +0300 Subject: [PATCH 026/759] read directly without dma --- armsrc/hfops.c | 80 ++++++++++++++------------------------------------ armsrc/hfops.h | 1 - 2 files changed, 22 insertions(+), 59 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index d4d5c1e51..37759d616 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -29,7 +29,6 @@ #include "commonutil.h" #include "lfsampling.h" - int HfReadADC(uint32_t samplesCount, bool ledcontrol) { if (ledcontrol) LEDsoff(); @@ -39,80 +38,45 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // And put the FPGA in the appropriate mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_212_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE); - // Setup and start DMA. + // Setup FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); - // The DMA buffer, used to stream samples from the FPGA - dmabuf16_t *dma = get_dma16(); - memset((uint8_t *) dma->buf, 0, DMA_BUFFER_SIZE); - - // Setup and start DMA. - if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { - if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscDma failed. Exiting"); - - FpgaDisableSscDma(); - FpgaSetupSsc(FPGA_MAJOR_MODE_OFF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - return PM3_EINIT; - } - if (ledcontrol) LED_A_ON(); - uint16_t *upTo = dma->buf; - uint32_t sbs = samplesCount; initSampleBuffer(&sbs); + uint32_t wdtcntr = 0; for (;;) { if (BUTTON_PRESS()) { break; } - volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); - if (behindBy == 0) + if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + volatile uint16_t sample = AT91C_BASE_SSC->SSC_RHR; + + // FPGA side: + // corr_i_out <= {2'b00, corr_amplitude[13:8]}; + // corr_q_out <= corr_amplitude[7:0]; + if (sample > 0x1fff) + sample = 0xff; + else + sample = sample >> 5; + logSample(sample & 0xff, 1, 8, false); + if (getSampleCounter() >= samplesCount) + break; + + if (wdtcntr++ > 512) { + WDT_HIT(); + wdtcntr = 0; + } + } else { continue; - - // FPGA side: - // corr_i_out <= {2'b00, corr_amplitude[13:8]}; - // corr_q_out <= corr_amplitude[7:0]; - // ci = upTo >> 8, cq = upTo - volatile uint16_t sample = *upTo++; - //if (sample & 0xc000) { - // Dbprintf("sample!!!! %d \r\n", getSampleCounter()); - // break; - //} - - logSample((sample >> 6) & 0xff, 1, 8, false); - - if (getSampleCounter() >= samplesCount) - break; - - if (upTo >= dma->buf + DMA_BUFFER_SIZE) { // we have read all of the DMA buffer content. - upTo = dma->buf; // start reading the circular buffer from the beginning - } - - // DMA Counter Register had reached 0, already rotated. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { - - // primary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RCR == false) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - Dbprintf("blew\r\n"); - } - // secondary buffer sets as primary, secondary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RNCR == false) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } - - WDT_HIT(); } } - FpgaDisableSscDma(); FpgaDisableTracing(); FpgaSetupSsc(FPGA_MAJOR_MODE_OFF); diff --git a/armsrc/hfops.h b/armsrc/hfops.h index 2a804ccf1..489c99bc6 100644 --- a/armsrc/hfops.h +++ b/armsrc/hfops.h @@ -23,5 +23,4 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol); - #endif \ No newline at end of file From 2248eadc7f1f883a7c6cdb055a257f5a76d1288f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 27 Jun 2022 00:31:15 +0300 Subject: [PATCH 027/759] locate start of the sequence and level --- client/src/cmdhftexkom.c | 71 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index e03dfb910..a2d8e39a8 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -27,6 +27,48 @@ #include "ui.h" #include "cmdhf14a.h" #include "cmddata.h" +#include "graph.h" + +#define TEXKOM_NOISE_THRESHOLD (10) + +inline uint32_t GetGraphBuffer(uint32_t indx) { + if (g_GraphBuffer[indx] < -128) + return 0; + else + return g_GraphBuffer[indx] + 128; +} + +static uint32_t TexkomSearchStart(uint32_t indx, uint8_t threshold) { + // one bit length = 27, minimal noise = 60 + uint32_t lownoisectr = 0; + for (uint32_t i = indx; i < g_GraphTraceLen; i++) { + if (lownoisectr > 60) { + if (GetGraphBuffer(i) > threshold) + return i; + } else { + if (GetGraphBuffer(i) > threshold) + lownoisectr = 0; + else + lownoisectr++; + } + } + + return 0; +} + +static uint32_t TexkomSearchMax(uint32_t indx, uint32_t len) { + uint32_t res = 0; + + for (uint32_t i = 0; i < len; i++) { + if (i + indx > g_GraphTraceLen) + break; + + if (GetGraphBuffer(indx + i) > res) + res = GetGraphBuffer(indx + i); + } + + return res; +} static int CmdHFTexkomReader(const char *Cmd) { CLIParserContext *ctx; @@ -41,7 +83,7 @@ static int CmdHFTexkomReader(const char *Cmd) { CLIExecWithReturn(ctx, Cmd, argtable, true); CLIParserFree(ctx); - uint32_t samplesCount = 40000; + uint32_t samplesCount = 12000; clearCommandBuffer(); SendCommandNG(CMD_HF_ACQ_RAW_ADC, (uint8_t *)&samplesCount, sizeof(uint32_t)); @@ -52,8 +94,31 @@ static int CmdHFTexkomReader(const char *Cmd) { } uint32_t size = (resp.data.asDwords[0]); - if (size > 0) - getSamples(samplesCount, true); + if (size > 0) { + if (getSamples(samplesCount, true) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Get samples error"); + return PM3_EFAILED; + }; + } + + uint32_t sindx = 0; + while (sindx < samplesCount - 5) { + sindx = TexkomSearchStart(sindx, TEXKOM_NOISE_THRESHOLD); + if (sindx == 0 || sindx > samplesCount - 5) + break; + + uint32_t maxlvl = TexkomSearchMax(sindx, 1760); + if (maxlvl < TEXKOM_NOISE_THRESHOLD) { + sindx += 1700; + continue; + } + PrintAndLogEx(WARNING, "--- indx: %d, max: %d", sindx, maxlvl); + + + + } + + PrintAndLogEx(WARNING, "Texkom card is not found"); return PM3_SUCCESS; } From a58c5b57ba165001ef2731d5674c980c7cdde89c Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 27 Jun 2022 01:03:13 +0300 Subject: [PATCH 028/759] calculate signal periods --- client/src/cmdhftexkom.c | 66 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index a2d8e39a8..97f2894d2 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -38,7 +38,7 @@ inline uint32_t GetGraphBuffer(uint32_t indx) { return g_GraphBuffer[indx] + 128; } -static uint32_t TexkomSearchStart(uint32_t indx, uint8_t threshold) { +static uint32_t TexkomSearchStart(uint32_t indx, uint32_t threshold) { // one bit length = 27, minimal noise = 60 uint32_t lownoisectr = 0; for (uint32_t i = indx; i < g_GraphTraceLen; i++) { @@ -56,6 +56,26 @@ static uint32_t TexkomSearchStart(uint32_t indx, uint8_t threshold) { return 0; } +static uint32_t TexkomSearchLength(uint32_t indx, uint32_t threshold) { + // one bit length = 27, minimal noise = 60 + uint32_t lownoisectr = 0; + uint32_t datalen = 0; + for (uint32_t i = indx; i < g_GraphTraceLen; i++) { + if (lownoisectr > 60) { + break; + } else { + if (GetGraphBuffer(i) > threshold) { + lownoisectr = 0; + datalen = i - indx + 27; + } else { + lownoisectr++; + } + } + } + + return datalen; +} + static uint32_t TexkomSearchMax(uint32_t indx, uint32_t len) { uint32_t res = 0; @@ -70,6 +90,22 @@ static uint32_t TexkomSearchMax(uint32_t indx, uint32_t len) { return res; } +static bool TexkomCorrelate(uint32_t indx, uint32_t threshold) { + if (indx < 2 || indx + 2 > g_GraphTraceLen) + return false; + + uint32_t g1 = GetGraphBuffer(indx - 2); + uint32_t g2 = GetGraphBuffer(indx - 1); + uint32_t g3 = GetGraphBuffer(indx); + uint32_t g4 = GetGraphBuffer(indx + 1); + uint32_t g5 = GetGraphBuffer(indx + 2); + + return ( + (g3 > threshold) && + (g3 >= g2) && (g3 >= g1) && (g3 > g4) && (g3 > g5) + ); +} + static int CmdHFTexkomReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf texkom reader", @@ -107,14 +143,38 @@ static int CmdHFTexkomReader(const char *Cmd) { if (sindx == 0 || sindx > samplesCount - 5) break; + uint32_t slen = TexkomSearchLength(sindx, TEXKOM_NOISE_THRESHOLD); + if (slen == 0) + continue; + uint32_t maxlvl = TexkomSearchMax(sindx, 1760); if (maxlvl < TEXKOM_NOISE_THRESHOLD) { sindx += 1700; continue; } - PrintAndLogEx(WARNING, "--- indx: %d, max: %d", sindx, maxlvl); - + uint32_t noiselvl = maxlvl / 5; + if (noiselvl < TEXKOM_NOISE_THRESHOLD) + noiselvl = TEXKOM_NOISE_THRESHOLD; + + PrintAndLogEx(WARNING, "--- indx: %d, len: %d, max: %d, noise: %d", sindx, slen, maxlvl, noiselvl); + + uint32_t implengths[256] = {}; + uint32_t implengthslen = 0; + uint32_t impulseindx = 0; + uint32_t impulsecnt = 0; + for (uint32_t i = 0; i < slen; i++) { + if (TexkomCorrelate(sindx + i, noiselvl)) { + impulsecnt++; + + if (impulseindx != 0) { + if (implengthslen < 256) + implengths[implengthslen++] = sindx + i - impulseindx; + } + impulseindx = sindx + i; + } + } + PrintAndLogEx(WARNING, "--- impulses: %d, lenarray: %d, [%d,%d]", impulsecnt, implengthslen, implengths[0], implengths[1]); } From a0d37a84c6bac3355326e5e4afce4729783662dd Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 27 Jun 2022 18:39:15 +0300 Subject: [PATCH 029/759] read tk13 with crc ok --- client/src/cmdhftexkom.c | 252 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 250 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 97f2894d2..c17c47991 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -106,6 +106,138 @@ static bool TexkomCorrelate(uint32_t indx, uint32_t threshold) { ); } +static bool TexkomCalculateMaxMin(uint32_t* data, uint32_t len, uint32_t* dmax, uint32_t* dmin) { + *dmax = 0; + *dmin = 0xffffffff; + for (size_t i = 0; i < len; i++) { + if (data[i] > *dmax) + *dmax = data[i]; + if (data[i] < *dmin) + *dmin = data[i]; + } + + return (*dmax != 0) && (*dmin != 0xffffffff) && (*dmax > *dmin); +} + +static bool TexkomCalculateBitLengths(uint32_t* data, uint32_t len, uint32_t* hi, uint32_t* low) { + *hi = 0; + *low = 0; + + uint32_t dmax = 0; + uint32_t dmin = 0xffffffff; + if (!TexkomCalculateMaxMin(data, len, &dmax, &dmin)) + return false; + + uint32_t dmiddle = (dmax + dmin) / 2; + uint32_t sumhi = 0; + uint32_t lenhi = 0; + uint32_t sumlow = 0; + uint32_t lenlow = 0; + for (size_t i = 0; i < len; i++) { + if (data[i] > dmiddle) { + sumhi += data[i]; + lenhi++; + } else { + sumlow += data[i]; + lenlow++; + } + } +PrintAndLogEx(WARNING, "--- min: %d, middle: %d, max: %d", dmin, dmiddle, dmax); + + *hi = sumhi / lenhi; + *low = sumlow / lenlow; + + return (*hi != 0) && (*low != 0) && (*hi > *low); +} + +inline bool TexcomCalculateBit(uint32_t data, uint32_t bitlen, uint32_t threshold) { + return + (data < (bitlen + threshold)) && + (data > (bitlen - threshold)); +} + +// code from https://github.com/li0ard/crclib/blob/main/index.js +static uint8_t TexcomTK13CRC(uint8_t* data) { + uint8_t crc = 0; + uint8_t indx = 0; + while (indx < 4) { + crc = crc ^ data[indx++]; + + for (uint8_t i = 0; i < 8; i++) + if (crc & 0x80) { + crc = 0x31 ^ (crc << 1); + } else + crc <<= 1; + }; + + PrintAndLogEx(WARNING, "--- crc: %x", crc); + return crc; +} + +static unsigned char dallas_crc8(const unsigned char * data, const unsigned int size) +{ + unsigned char crc = 0; + for ( unsigned int i = 0; i < size; ++i ) + { + unsigned char inbyte = data[i]; + for ( unsigned char j = 0; j < 8; ++j ) + { + unsigned char mix = (crc ^ inbyte) & 0x01; + crc >>= 1; + if ( mix ) crc ^= 0x8C; + inbyte >>= 1; + } + } + return crc; +} + +// code from https://github.com/li0ard/crclib/blob/main/index.js +static uint8_t TexcomTK17CRC(uint8_t* data) { + uint8_t ddata[8] = {0x00, 0x00, 0x00, data[0], data[1], data[2], data[3], 0x00}; + +/* + dallas (arrby) { + var arrby2 = []; + if (arrby.length < 8) { + return "FF"; + } + var n = 0; + var n2 = 7; + while (n < 7){ + arrby2[n] = arrby[n2]; + ++n; + --n2; + } + var n3 = 0; + var n4 = 0; + do { + var n5 = 255 & arrby2[n3]; + var n6 = n4; + for (var n7 = 0; n7 < 8; n7 = Number(n7 + 1)) { + var n8 = 1 & (255 & (n6 ^ n5)); + n6 = 255 & n6 >> 1; + n5 = 255 & n5 >> 1; + if (n8 != 1) continue; + n6 ^= 140; + } + if ((n3 = Number(n3 + 1)) >= 7) { + return n6.toString(16).toUpperCase(); + } + n4 = n6; + } while (true); + } + tk17(arrby) { + if(arrby.length < 8) { + return "FF" + } + return this.dallas( [0x00, arrby[1], arrby[2], arrby[3], arrby[4], 0x00, 0x00, 0x00] ) + } +*/ + + return dallas_crc8(ddata, 8); +} + + static int CmdHFTexkomReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf texkom reader", @@ -117,9 +249,12 @@ static int CmdHFTexkomReader(const char *Cmd) { arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); + + bool verbose = true; + CLIParserFree(ctx); - uint32_t samplesCount = 12000; + uint32_t samplesCount = 30000; clearCommandBuffer(); SendCommandNG(CMD_HF_ACQ_RAW_ADC, (uint8_t *)&samplesCount, sizeof(uint32_t)); @@ -137,6 +272,9 @@ static int CmdHFTexkomReader(const char *Cmd) { }; } + char bitstring[256] = {0}; + char cbitstring[128] = {0}; + bool codefound = false; uint32_t sindx = 0; while (sindx < samplesCount - 5) { sindx = TexkomSearchStart(sindx, TEXKOM_NOISE_THRESHOLD); @@ -176,9 +314,119 @@ static int CmdHFTexkomReader(const char *Cmd) { } PrintAndLogEx(WARNING, "--- impulses: %d, lenarray: %d, [%d,%d]", impulsecnt, implengthslen, implengths[0], implengths[1]); + uint32_t hilength = 0; + uint32_t lowlength = 0; + if (!TexkomCalculateBitLengths(implengths, implengthslen, &hilength, &lowlength)) + continue; + + uint32_t threshold = (hilength - lowlength) / 3 + 1; + PrintAndLogEx(WARNING, "--- hi: %d, low: %d, threshold: %d", hilength, lowlength, threshold); + + bitstring[0] = 0; + bool biterror = false; + for (uint32_t i = 0; i < implengthslen; i++) { + if (TexcomCalculateBit(implengths[i], hilength, threshold)) + strcat(bitstring, "1"); + else if (TexcomCalculateBit(implengths[i], lowlength, threshold)) + strcat(bitstring, "0"); + else { + biterror = true; + break; + } + } + + if (biterror || strlen(bitstring) == 0) + continue; + + if (verbose) + PrintAndLogEx(INFO, "raw bit string [%d]: %s", strlen(bitstring), bitstring); + + // add trailing impulse (some tags just ignore it) + if (strlen(bitstring) % 2 != 0) { + if (bitstring[strlen(bitstring) - 1] == '1') + strcat(bitstring, "0"); + else + strcat(bitstring, "1"); + } + PrintAndLogEx(INFO, "bs [%d]: %s", strlen(bitstring), bitstring); + + cbitstring[0] = 0; + for (uint32_t i = 0; i < strlen(bitstring); i = i + 2) { + if (bitstring[i] == bitstring[i + 1]) { + cbitstring[0] = 0; + if (verbose) + PrintAndLogEx(WARNING, "Raw bit string have error at offset %d.", i); + break; + } + if (bitstring[i] == '1') + strcat(cbitstring, "1"); + else + strcat(cbitstring, "0"); + } + + if (strlen(cbitstring) == 0) + continue; + + if (verbose) + PrintAndLogEx(INFO, "bit string [%d]: %s", strlen(cbitstring), cbitstring); + + if (strlen(cbitstring) != 64) + continue; + + uint8_t tcode[8] = {0}; + for (uint32_t i = 0; i < strlen(cbitstring); i++) { + tcode[i / 8] = (tcode[i / 8] << 1) | ((cbitstring[i] == '1') ? 1 : 0); + } + + if (verbose) + PrintAndLogEx(INFO, "Hex code: %s", sprint_hex(tcode, 8)); + + if (tcode[0] != 0xff || tcode[1] != 0xff) + continue; + + // decoding code + + if (!verbose) + PrintAndLogEx(INFO, "Texkom: %s", sprint_hex(tcode, 8)); + + if (tcode[2] == 0x63) { + // TK13 + PrintAndLogEx(INFO, "type: TK13"); + PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); + + if (TexcomTK13CRC(&tcode[3]) == tcode[7]) + PrintAndLogEx(INFO, "crc : OK"); + else + PrintAndLogEx(WARNING, "crc : WRONG"); + + } else if (tcode[2] == 0xca) { + // TK17 + PrintAndLogEx(INFO, "type: TK17"); + PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); + + if (TexcomTK17CRC(&tcode[3]) == tcode[7]) + PrintAndLogEx(INFO, "crc : OK"); + else + PrintAndLogEx(WARNING, "crc : WRONG"); + + } else { + PrintAndLogEx(INFO, "type: unknown"); + PrintAndLogEx(INFO, "uid : %s (maybe)", sprint_hex(&tcode[3], 4)); + } + + + codefound = true; + break; } - PrintAndLogEx(WARNING, "Texkom card is not found"); + if (!codefound) { + if (strlen(bitstring) > 0) + PrintAndLogEx(INFO, "last raw bit string [%d]: %s", strlen(bitstring), bitstring); + if (strlen(cbitstring) > 0) + PrintAndLogEx(INFO, "last bit string [%d]: %s", strlen(cbitstring), cbitstring); + + PrintAndLogEx(ERR, "Texkom card is not found"); + } return PM3_SUCCESS; } From e341ce68e4f2b2a71664ba1f8ac2bac8c5669ae1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 27 Jun 2022 19:00:24 +0300 Subject: [PATCH 030/759] remove crc debug and add dynamic threshold --- client/src/cmdhftexkom.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index c17c47991..3a34efc58 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -119,7 +119,7 @@ static bool TexkomCalculateMaxMin(uint32_t* data, uint32_t len, uint32_t* dmax, return (*dmax != 0) && (*dmin != 0xffffffff) && (*dmax > *dmin); } -static bool TexkomCalculateBitLengths(uint32_t* data, uint32_t len, uint32_t* hi, uint32_t* low) { +static bool TexkomCalculateBitLengths(uint32_t* data, uint32_t len, uint32_t* hi, uint32_t* low, uint32_t* lmax, uint32_t* lmin) { *hi = 0; *low = 0; @@ -147,6 +147,11 @@ PrintAndLogEx(WARNING, "--- min: %d, middle: %d, max: %d", dmin, dmiddle, dmax); *hi = sumhi / lenhi; *low = sumlow / lenlow; + if (lmax != NULL) + *lmax = dmax; + if (lmin != NULL) + *lmin = dmin; + return (*hi != 0) && (*low != 0) && (*hi > *low); } @@ -170,7 +175,6 @@ static uint8_t TexcomTK13CRC(uint8_t* data) { crc <<= 1; }; - PrintAndLogEx(WARNING, "--- crc: %x", crc); return crc; } @@ -316,7 +320,9 @@ static int CmdHFTexkomReader(const char *Cmd) { uint32_t hilength = 0; uint32_t lowlength = 0; - if (!TexkomCalculateBitLengths(implengths, implengthslen, &hilength, &lowlength)) + uint32_t lenmax = 0; + uint32_t lenmin = 0; + if (!TexkomCalculateBitLengths(implengths, implengthslen, &hilength, &lowlength, &lenmax, &lenmin)) continue; uint32_t threshold = (hilength - lowlength) / 3 + 1; @@ -325,7 +331,7 @@ static int CmdHFTexkomReader(const char *Cmd) { bitstring[0] = 0; bool biterror = false; for (uint32_t i = 0; i < implengthslen; i++) { - if (TexcomCalculateBit(implengths[i], hilength, threshold)) + if (TexcomCalculateBit(implengths[i], hilength, MAX(threshold, lenmax - hilength))) strcat(bitstring, "1"); else if (TexcomCalculateBit(implengths[i], lowlength, threshold)) strcat(bitstring, "0"); From cea9806226221b3580a51afaf9604638193c79f7 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 27 Jun 2022 23:47:02 +0300 Subject: [PATCH 031/759] tk17 raw reading --- client/src/cmdhftexkom.c | 66 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 3a34efc58..18ce04830 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -241,6 +241,52 @@ static uint8_t TexcomTK17CRC(uint8_t* data) { return dallas_crc8(ddata, 8); } +inline int TexcomTK17Get2Bits(uint32_t len1, uint32_t len2) { + uint32_t xlen = (len2 * 100) / (len1 + len2); + if (xlen < 10 || xlen > 90) + return -1; + if (xlen < 30) + return 0; + if (xlen < 50) + return 1; + if (xlen < 70) + return 2; + return 3; +} + + +static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, bool verbose) { + char bitstring[256] = {0}; + + for (uint32_t i = 0; i < implengthslen; i = i + 2) { + int dbit = TexcomTK17Get2Bits(implengths[i], implengths[i + 1]); + if (dbit < 0) + return false; + + switch (dbit) { + case 0: + strcat(bitstring, "00"); + break; + case 1: + strcat(bitstring, "01"); + break; + case 2: + strcat(bitstring, "10"); + break; + case 3: + strcat(bitstring, "11"); + break; + default: + return false; + } + } + + if (verbose) + PrintAndLogEx(INFO, "TK17 raw bit string [%d]: %s", strlen(bitstring), bitstring); + + + return strlen(bitstring) == 64; +} static int CmdHFTexkomReader(const char *Cmd) { CLIParserContext *ctx; @@ -270,7 +316,7 @@ static int CmdHFTexkomReader(const char *Cmd) { uint32_t size = (resp.data.asDwords[0]); if (size > 0) { - if (getSamples(samplesCount, true) != PM3_SUCCESS) { + if (getSamples(samplesCount, false) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Get samples error"); return PM3_EFAILED; }; @@ -318,11 +364,16 @@ static int CmdHFTexkomReader(const char *Cmd) { } PrintAndLogEx(WARNING, "--- impulses: %d, lenarray: %d, [%d,%d]", impulsecnt, implengthslen, implengths[0], implengths[1]); + // check if it TK-17 modulation + // 65 impulses and 64 intervals + if (impulsecnt == 65) { + if (TexcomTK17Decode(implengths, implengthslen, verbose)) + break; + } + uint32_t hilength = 0; uint32_t lowlength = 0; - uint32_t lenmax = 0; - uint32_t lenmin = 0; - if (!TexkomCalculateBitLengths(implengths, implengthslen, &hilength, &lowlength, &lenmax, &lenmin)) + if (!TexkomCalculateBitLengths(implengths, implengthslen, &hilength, &lowlength, NULL, NULL)) continue; uint32_t threshold = (hilength - lowlength) / 3 + 1; @@ -331,11 +382,16 @@ static int CmdHFTexkomReader(const char *Cmd) { bitstring[0] = 0; bool biterror = false; for (uint32_t i = 0; i < implengthslen; i++) { - if (TexcomCalculateBit(implengths[i], hilength, MAX(threshold, lenmax - hilength))) + if (TexcomCalculateBit(implengths[i], hilength, threshold)) strcat(bitstring, "1"); else if (TexcomCalculateBit(implengths[i], lowlength, threshold)) strcat(bitstring, "0"); else { + PrintAndLogEx(INFO, "ERROR string [%d]: %s, bit: %d, blen: %d", strlen(bitstring), bitstring, i, implengths[i]); + //for (uint32_t j = 0; j < implengthslen; j++) + // printf("%d,", implengths[j]); + //printf("\r\n"); + biterror = true; break; } From f16386249680b76a551ab693bae4cbe7acd4f386 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 27 Jun 2022 23:50:23 +0300 Subject: [PATCH 032/759] fix codeql --- client/src/cmdhftexkom.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 18ce04830..8cb5c0554 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -282,7 +282,7 @@ static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, bool } if (verbose) - PrintAndLogEx(INFO, "TK17 raw bit string [%d]: %s", strlen(bitstring), bitstring); + PrintAndLogEx(INFO, "TK17 raw bit string [%zu]: %s", strlen(bitstring), bitstring); return strlen(bitstring) == 64; @@ -387,7 +387,7 @@ static int CmdHFTexkomReader(const char *Cmd) { else if (TexcomCalculateBit(implengths[i], lowlength, threshold)) strcat(bitstring, "0"); else { - PrintAndLogEx(INFO, "ERROR string [%d]: %s, bit: %d, blen: %d", strlen(bitstring), bitstring, i, implengths[i]); + PrintAndLogEx(INFO, "ERROR string [%zu]: %s, bit: %d, blen: %d", strlen(bitstring), bitstring, i, implengths[i]); //for (uint32_t j = 0; j < implengthslen; j++) // printf("%d,", implengths[j]); //printf("\r\n"); @@ -401,7 +401,7 @@ static int CmdHFTexkomReader(const char *Cmd) { continue; if (verbose) - PrintAndLogEx(INFO, "raw bit string [%d]: %s", strlen(bitstring), bitstring); + PrintAndLogEx(INFO, "raw bit string [%zu]: %s", strlen(bitstring), bitstring); // add trailing impulse (some tags just ignore it) if (strlen(bitstring) % 2 != 0) { @@ -410,7 +410,6 @@ static int CmdHFTexkomReader(const char *Cmd) { else strcat(bitstring, "1"); } - PrintAndLogEx(INFO, "bs [%d]: %s", strlen(bitstring), bitstring); cbitstring[0] = 0; for (uint32_t i = 0; i < strlen(bitstring); i = i + 2) { @@ -430,7 +429,7 @@ static int CmdHFTexkomReader(const char *Cmd) { continue; if (verbose) - PrintAndLogEx(INFO, "bit string [%d]: %s", strlen(cbitstring), cbitstring); + PrintAndLogEx(INFO, "bit string [%zu]: %s", strlen(cbitstring), cbitstring); if (strlen(cbitstring) != 64) continue; @@ -483,9 +482,9 @@ static int CmdHFTexkomReader(const char *Cmd) { if (!codefound) { if (strlen(bitstring) > 0) - PrintAndLogEx(INFO, "last raw bit string [%d]: %s", strlen(bitstring), bitstring); + PrintAndLogEx(INFO, "last raw bit string [%zu]: %s", strlen(bitstring), bitstring); if (strlen(cbitstring) > 0) - PrintAndLogEx(INFO, "last bit string [%d]: %s", strlen(cbitstring), cbitstring); + PrintAndLogEx(INFO, "last bit string [%zu]: %s", strlen(cbitstring), cbitstring); PrintAndLogEx(ERR, "Texkom card is not found"); } From 2fdf09606fcb19d4cd2f3f3c5320ace1c1647c5d Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 28 Jun 2022 00:05:18 +0300 Subject: [PATCH 033/759] calc tk17 raw bitstring --- client/src/cmdhftexkom.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 8cb5c0554..8ae4760aa 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -248,15 +248,16 @@ inline int TexcomTK17Get2Bits(uint32_t len1, uint32_t len2) { if (xlen < 30) return 0; if (xlen < 50) - return 1; - if (xlen < 70) return 2; + if (xlen < 70) + return 1; return 3; } static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, bool verbose) { char bitstring[256] = {0}; + char cbitstring[256] = {0}; for (uint32_t i = 0; i < implengthslen; i = i + 2) { int dbit = TexcomTK17Get2Bits(implengths[i], implengths[i + 1]); @@ -284,6 +285,16 @@ static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, bool if (verbose) PrintAndLogEx(INFO, "TK17 raw bit string [%zu]: %s", strlen(bitstring), bitstring); + for (uint32_t i = 0; i < 8; i++) { + memcpy(&cbitstring[i * 8 + 0], &bitstring[i * 8 + 6], 2); + memcpy(&cbitstring[i * 8 + 2], &bitstring[i * 8 + 4], 2); + memcpy(&cbitstring[i * 8 + 4], &bitstring[i * 8 + 2], 2); + memcpy(&cbitstring[i * 8 + 6], &bitstring[i * 8 + 0], 2); + } + + if (verbose) + PrintAndLogEx(INFO, "TK17 bit string [%zu]: %s", strlen(cbitstring), cbitstring); + return strlen(bitstring) == 64; } From a18e50b18a7a4c55053a6b65d7cb5ae7274cb7b1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 28 Jun 2022 00:14:50 +0300 Subject: [PATCH 034/759] move print code to one place and check preamble --- client/src/cmdhftexkom.c | 77 ++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 8ae4760aa..5d431ab1f 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -255,9 +255,9 @@ inline int TexcomTK17Get2Bits(uint32_t len1, uint32_t len2) { } -static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, bool verbose) { - char bitstring[256] = {0}; - char cbitstring[256] = {0}; +static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, char* bitstring, char* cbitstring, bool verbose) { + bitstring[0] = 0; + cbitstring[0] = 0; for (uint32_t i = 0; i < implengthslen; i = i + 2) { int dbit = TexcomTK17Get2Bits(implengths[i], implengths[i + 1]); @@ -295,8 +295,7 @@ static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, bool if (verbose) PrintAndLogEx(INFO, "TK17 bit string [%zu]: %s", strlen(cbitstring), cbitstring); - - return strlen(bitstring) == 64; + return (strlen(bitstring) == 64) && (strncmp(cbitstring, "1111111111111111", 16) == 0); } static int CmdHFTexkomReader(const char *Cmd) { @@ -378,8 +377,10 @@ static int CmdHFTexkomReader(const char *Cmd) { // check if it TK-17 modulation // 65 impulses and 64 intervals if (impulsecnt == 65) { - if (TexcomTK17Decode(implengths, implengthslen, verbose)) + if (TexcomTK17Decode(implengths, implengthslen, bitstring, cbitstring, verbose)) { + codefound = true; break; + } } uint32_t hilength = 0; @@ -442,9 +443,14 @@ static int CmdHFTexkomReader(const char *Cmd) { if (verbose) PrintAndLogEx(INFO, "bit string [%zu]: %s", strlen(cbitstring), cbitstring); - if (strlen(cbitstring) != 64) + if ((strlen(cbitstring) != 64) || (strncmp(cbitstring, "1111111111111111", 16) != 0)) continue; + codefound = true; + break; + } + + if (codefound) { uint8_t tcode[8] = {0}; for (uint32_t i = 0; i < strlen(cbitstring); i++) { tcode[i / 8] = (tcode[i / 8] << 1) | ((cbitstring[i] == '1') ? 1 : 0); @@ -453,45 +459,40 @@ static int CmdHFTexkomReader(const char *Cmd) { if (verbose) PrintAndLogEx(INFO, "Hex code: %s", sprint_hex(tcode, 8)); - if (tcode[0] != 0xff || tcode[1] != 0xff) - continue; + if (tcode[0] == 0xff && tcode[1] == 0xff) { + // decoding code - // decoding code + if (!verbose) + PrintAndLogEx(INFO, "Texkom: %s", sprint_hex(tcode, 8)); - if (!verbose) - PrintAndLogEx(INFO, "Texkom: %s", sprint_hex(tcode, 8)); + if (tcode[2] == 0x63) { + // TK13 + PrintAndLogEx(INFO, "type: TK13"); + PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); - if (tcode[2] == 0x63) { - // TK13 - PrintAndLogEx(INFO, "type: TK13"); - PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); + if (TexcomTK13CRC(&tcode[3]) == tcode[7]) + PrintAndLogEx(INFO, "crc : OK"); + else + PrintAndLogEx(WARNING, "crc : WRONG"); - if (TexcomTK13CRC(&tcode[3]) == tcode[7]) - PrintAndLogEx(INFO, "crc : OK"); - else - PrintAndLogEx(WARNING, "crc : WRONG"); + } else if (tcode[2] == 0xca) { + // TK17 + PrintAndLogEx(INFO, "type: TK17"); + PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); - } else if (tcode[2] == 0xca) { - // TK17 - PrintAndLogEx(INFO, "type: TK17"); - PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); - - if (TexcomTK17CRC(&tcode[3]) == tcode[7]) - PrintAndLogEx(INFO, "crc : OK"); - else - PrintAndLogEx(WARNING, "crc : WRONG"); + if (TexcomTK17CRC(&tcode[3]) == tcode[7]) + PrintAndLogEx(INFO, "crc : OK"); + else + PrintAndLogEx(WARNING, "crc : WRONG"); + } else { + PrintAndLogEx(INFO, "type: unknown"); + PrintAndLogEx(INFO, "uid : %s (maybe)", sprint_hex(&tcode[3], 4)); + } } else { - PrintAndLogEx(INFO, "type: unknown"); - PrintAndLogEx(INFO, "uid : %s (maybe)", sprint_hex(&tcode[3], 4)); + PrintAndLogEx(ERR, "Code have no preamble FFFF: %s", sprint_hex(tcode, 8)); } - - - codefound = true; - break; - } - - if (!codefound) { + } else { if (strlen(bitstring) > 0) PrintAndLogEx(INFO, "last raw bit string [%zu]: %s", strlen(bitstring), bitstring); if (strlen(cbitstring) > 0) From 6bb71fb8602a6e8c51b3ef370e7d009e05cd7ab7 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 28 Jun 2022 00:22:29 +0300 Subject: [PATCH 035/759] bit names refactoring --- client/src/cmdhftexkom.c | 21 ++++++++++----------- client/src/cmdhftexkom.h | 8 ++++++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 5d431ab1f..317a28a25 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -244,37 +244,36 @@ static uint8_t TexcomTK17CRC(uint8_t* data) { inline int TexcomTK17Get2Bits(uint32_t len1, uint32_t len2) { uint32_t xlen = (len2 * 100) / (len1 + len2); if (xlen < 10 || xlen > 90) - return -1; + return TK17WrongBit; if (xlen < 30) - return 0; + return TK17Bit00; if (xlen < 50) - return 2; + return TK17Bit10; if (xlen < 70) - return 1; - return 3; + return TK17Bit01; + return TK17Bit11; } - static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, char* bitstring, char* cbitstring, bool verbose) { bitstring[0] = 0; cbitstring[0] = 0; for (uint32_t i = 0; i < implengthslen; i = i + 2) { int dbit = TexcomTK17Get2Bits(implengths[i], implengths[i + 1]); - if (dbit < 0) + if (dbit == TK17WrongBit) return false; switch (dbit) { - case 0: + case TK17Bit00: strcat(bitstring, "00"); break; - case 1: + case TK17Bit01: strcat(bitstring, "01"); break; - case 2: + case TK17Bit10: strcat(bitstring, "10"); break; - case 3: + case TK17Bit11: strcat(bitstring, "11"); break; default: diff --git a/client/src/cmdhftexkom.h b/client/src/cmdhftexkom.h index 9f4a3b32f..0c46759c2 100644 --- a/client/src/cmdhftexkom.h +++ b/client/src/cmdhftexkom.h @@ -22,6 +22,14 @@ #include "common.h" #include "pm3_cmd.h" +enum TK17Bits { + TK17WrongBit, + TK17Bit00, + TK17Bit01, + TK17Bit10, + TK17Bit11 +}; + int CmdHFTexkom(const char *Cmd); #endif \ No newline at end of file From 383dc934d6d6ce0d3125b1bd96e0ff536fc367b3 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 28 Jun 2022 00:31:42 +0300 Subject: [PATCH 036/759] print modulation type --- client/src/cmdhftexkom.c | 39 +++++++++++++++++++++++++-------------- client/src/cmdhftexkom.h | 6 ++++++ 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 317a28a25..3765eca70 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -333,7 +333,7 @@ static int CmdHFTexkomReader(const char *Cmd) { char bitstring[256] = {0}; char cbitstring[128] = {0}; - bool codefound = false; + int codefound = TexkomModError; uint32_t sindx = 0; while (sindx < samplesCount - 5) { sindx = TexkomSearchStart(sindx, TEXKOM_NOISE_THRESHOLD); @@ -377,7 +377,7 @@ static int CmdHFTexkomReader(const char *Cmd) { // 65 impulses and 64 intervals if (impulsecnt == 65) { if (TexcomTK17Decode(implengths, implengthslen, bitstring, cbitstring, verbose)) { - codefound = true; + codefound = TexkomModTK17; break; } } @@ -445,11 +445,11 @@ static int CmdHFTexkomReader(const char *Cmd) { if ((strlen(cbitstring) != 64) || (strncmp(cbitstring, "1111111111111111", 16) != 0)) continue; - codefound = true; + codefound = TexkomModTK13; break; } - if (codefound) { + if (codefound != TexkomModError) { uint8_t tcode[8] = {0}; for (uint32_t i = 0; i < strlen(cbitstring); i++) { tcode[i / 8] = (tcode[i / 8] << 1) | ((cbitstring[i] == '1') ? 1 : 0); @@ -464,29 +464,40 @@ static int CmdHFTexkomReader(const char *Cmd) { if (!verbose) PrintAndLogEx(INFO, "Texkom: %s", sprint_hex(tcode, 8)); + if (codefound == TexkomModTK13) + PrintAndLogEx(INFO, "modulation: TK13"); + else if (codefound == TexkomModTK17) + PrintAndLogEx(INFO, "modulation: TK17"); + else + PrintAndLogEx(INFO, "modulation: unknown"); + if (tcode[2] == 0x63) { // TK13 - PrintAndLogEx(INFO, "type: TK13"); - PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); + if (codefound != TexkomModTK13) + PrintAndLogEx(WARNING, " mod type: WRONG"); + PrintAndLogEx(INFO, "type : TK13"); + PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); if (TexcomTK13CRC(&tcode[3]) == tcode[7]) - PrintAndLogEx(INFO, "crc : OK"); + PrintAndLogEx(INFO, "crc : OK"); else - PrintAndLogEx(WARNING, "crc : WRONG"); + PrintAndLogEx(WARNING, "crc : WRONG"); } else if (tcode[2] == 0xca) { // TK17 - PrintAndLogEx(INFO, "type: TK17"); - PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); + if (codefound != TexkomModTK17) + PrintAndLogEx(WARNING, " mod type: WRONG"); + PrintAndLogEx(INFO, "type : TK17"); + PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); if (TexcomTK17CRC(&tcode[3]) == tcode[7]) - PrintAndLogEx(INFO, "crc : OK"); + PrintAndLogEx(INFO, "crc : OK"); else - PrintAndLogEx(WARNING, "crc : WRONG"); + PrintAndLogEx(WARNING, "crc : WRONG"); } else { - PrintAndLogEx(INFO, "type: unknown"); - PrintAndLogEx(INFO, "uid : %s (maybe)", sprint_hex(&tcode[3], 4)); + PrintAndLogEx(INFO, "type : unknown"); + PrintAndLogEx(INFO, "uid : %s (maybe)", sprint_hex(&tcode[3], 4)); } } else { PrintAndLogEx(ERR, "Code have no preamble FFFF: %s", sprint_hex(tcode, 8)); diff --git a/client/src/cmdhftexkom.h b/client/src/cmdhftexkom.h index 0c46759c2..2e8a79658 100644 --- a/client/src/cmdhftexkom.h +++ b/client/src/cmdhftexkom.h @@ -30,6 +30,12 @@ enum TK17Bits { TK17Bit11 }; +enum TexkomModulation { + TexkomModError, + TexkomModTK13, + TexkomModTK17 +}; + int CmdHFTexkom(const char *Cmd); #endif \ No newline at end of file From 5fd951a799ebaecc20a9fd119efed0f560fc0693 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 28 Jun 2022 00:36:09 +0300 Subject: [PATCH 037/759] remove debug --- client/src/cmdhftexkom.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 3765eca70..9fc996ed0 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -142,7 +142,6 @@ static bool TexkomCalculateBitLengths(uint32_t* data, uint32_t len, uint32_t* hi lenlow++; } } -PrintAndLogEx(WARNING, "--- min: %d, middle: %d, max: %d", dmin, dmiddle, dmax); *hi = sumhi / lenhi; *low = sumlow / lenlow; @@ -354,7 +353,7 @@ static int CmdHFTexkomReader(const char *Cmd) { if (noiselvl < TEXKOM_NOISE_THRESHOLD) noiselvl = TEXKOM_NOISE_THRESHOLD; - PrintAndLogEx(WARNING, "--- indx: %d, len: %d, max: %d, noise: %d", sindx, slen, maxlvl, noiselvl); + //PrintAndLogEx(WARNING, "--- indx: %d, len: %d, max: %d, noise: %d", sindx, slen, maxlvl, noiselvl); uint32_t implengths[256] = {}; uint32_t implengthslen = 0; @@ -371,7 +370,7 @@ static int CmdHFTexkomReader(const char *Cmd) { impulseindx = sindx + i; } } - PrintAndLogEx(WARNING, "--- impulses: %d, lenarray: %d, [%d,%d]", impulsecnt, implengthslen, implengths[0], implengths[1]); + //PrintAndLogEx(WARNING, "--- impulses: %d, lenarray: %d, [%d,%d]", impulsecnt, implengthslen, implengths[0], implengths[1]); // check if it TK-17 modulation // 65 impulses and 64 intervals @@ -388,7 +387,7 @@ static int CmdHFTexkomReader(const char *Cmd) { continue; uint32_t threshold = (hilength - lowlength) / 3 + 1; - PrintAndLogEx(WARNING, "--- hi: %d, low: %d, threshold: %d", hilength, lowlength, threshold); + //PrintAndLogEx(WARNING, "--- hi: %d, low: %d, threshold: %d", hilength, lowlength, threshold); bitstring[0] = 0; bool biterror = false; @@ -398,7 +397,7 @@ static int CmdHFTexkomReader(const char *Cmd) { else if (TexcomCalculateBit(implengths[i], lowlength, threshold)) strcat(bitstring, "0"); else { - PrintAndLogEx(INFO, "ERROR string [%zu]: %s, bit: %d, blen: %d", strlen(bitstring), bitstring, i, implengths[i]); + //PrintAndLogEx(INFO, "ERROR string [%zu]: %s, bit: %d, blen: %d", strlen(bitstring), bitstring, i, implengths[i]); //for (uint32_t j = 0; j < implengthslen; j++) // printf("%d,", implengths[j]); //printf("\r\n"); From 7feca916875afe80b560975dcefd6623675c76de Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 28 Jun 2022 09:47:27 +0300 Subject: [PATCH 038/759] refactoring decoders and verbosity --- client/src/cmdhftexkom.c | 168 +++++++++++++++++++++++++-------------- 1 file changed, 107 insertions(+), 61 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 9fc996ed0..d863fba05 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -191,6 +191,7 @@ static unsigned char dallas_crc8(const unsigned char * data, const unsigned int inbyte >>= 1; } } +PrintAndLogEx(WARNING, "--crc %x", crc); return crc; } @@ -240,6 +241,68 @@ static uint8_t TexcomTK17CRC(uint8_t* data) { return dallas_crc8(ddata, 8); } +static bool TexcomTK13Decode(uint32_t* implengths, uint32_t implengthslen, char* bitstring, char* cbitstring, bool verbose) { + bitstring[0] = 0; + cbitstring[0] = 0; + + uint32_t hilength = 0; + uint32_t lowlength = 0; + if (!TexkomCalculateBitLengths(implengths, implengthslen, &hilength, &lowlength, NULL, NULL)) + return false; + + uint32_t threshold = (hilength - lowlength) / 3 + 1; + //PrintAndLogEx(WARNING, "--- hi: %d, low: %d, threshold: %d", hilength, lowlength, threshold); + + bool biterror = false; + for (uint32_t i = 0; i < implengthslen; i++) { + if (TexcomCalculateBit(implengths[i], hilength, threshold)) + strcat(bitstring, "1"); + else if (TexcomCalculateBit(implengths[i], lowlength, threshold)) + strcat(bitstring, "0"); + else { + //PrintAndLogEx(INFO, "ERROR string [%zu]: %s, bit: %d, blen: %d", strlen(bitstring), bitstring, i, implengths[i]); + + biterror = true; + break; + } + } + + if (biterror || strlen(bitstring) == 0) + return false; + + if (verbose) + PrintAndLogEx(INFO, "raw bit string [%zu]: %s", strlen(bitstring), bitstring); + + // add trailing impulse (some tags just ignore it) + if (strlen(bitstring) % 2 != 0) { + if (bitstring[strlen(bitstring) - 1] == '1') + strcat(bitstring, "0"); + else + strcat(bitstring, "1"); + } + + for (uint32_t i = 0; i < strlen(bitstring); i = i + 2) { + if (bitstring[i] == bitstring[i + 1]) { + cbitstring[0] = 0; + if (verbose) + PrintAndLogEx(WARNING, "Raw bit string have error at offset %d.", i); + break; + } + if (bitstring[i] == '1') + strcat(cbitstring, "1"); + else + strcat(cbitstring, "0"); + } + + if (strlen(cbitstring) == 0) + return false; + + if (verbose) + PrintAndLogEx(INFO, "bit string [%zu]: %s", strlen(cbitstring), cbitstring); + + return ((strlen(cbitstring) == 64) && (strncmp(cbitstring, "1111111111111111", 16) == 0)); +} + inline int TexcomTK17Get2Bits(uint32_t len1, uint32_t len2) { uint32_t xlen = (len2 * 100) / (len1 + len2); if (xlen < 10 || xlen > 90) @@ -296,6 +359,41 @@ static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, char* return (strlen(bitstring) == 64) && (strncmp(cbitstring, "1111111111111111", 16) == 0); } + +static bool TexcomGeneralDecode(uint32_t* implengths, uint32_t implengthslen, char* bitstring, bool verbose) { + uint32_t hilength = 0; + uint32_t lowlength = 0; + if (!TexkomCalculateBitLengths(implengths, implengthslen, &hilength, &lowlength, NULL, NULL)) + return false; + + uint32_t threshold = (hilength - lowlength) / 3 + 1; + + bitstring[0] = 0; + bool biterror = false; + for (uint32_t i = 0; i < implengthslen; i++) { + if (TexcomCalculateBit(implengths[i], hilength, threshold)) + strcat(bitstring, "1"); + else if (TexcomCalculateBit(implengths[i], lowlength, threshold)) + strcat(bitstring, "0"); + else { + if (verbose) { + PrintAndLogEx(INFO, "ERROR string [%zu]: %s, bit: %d, blen: %d", strlen(bitstring), bitstring, i, implengths[i]); + printf("Length array: \r\n"); + for (uint32_t j = 0; j < implengthslen; j++) + printf("%d,", implengths[j]); + printf("\r\n"); + } + + biterror = true; + break; + } + } + if (verbose) + PrintAndLogEx(INFO, "General raw bit string [%zu]: %s", strlen(bitstring), bitstring); + + return (!biterror && strlen(bitstring) > 0); +} + static int CmdHFTexkomReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf texkom reader", @@ -304,11 +402,12 @@ static int CmdHFTexkomReader(const char *Cmd) { void *argtable[] = { arg_param_begin, + arg_lit0("v", "verbose", "Verbose scan and output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - bool verbose = true; + bool verbose = arg_get_lit(ctx, 1); CLIParserFree(ctx); @@ -332,6 +431,7 @@ static int CmdHFTexkomReader(const char *Cmd) { char bitstring[256] = {0}; char cbitstring[128] = {0}; + char genbitstring[256] = {0}; int codefound = TexkomModError; uint32_t sindx = 0; while (sindx < samplesCount - 5) { @@ -381,71 +481,15 @@ static int CmdHFTexkomReader(const char *Cmd) { } } - uint32_t hilength = 0; - uint32_t lowlength = 0; - if (!TexkomCalculateBitLengths(implengths, implengthslen, &hilength, &lowlength, NULL, NULL)) - continue; - - uint32_t threshold = (hilength - lowlength) / 3 + 1; - //PrintAndLogEx(WARNING, "--- hi: %d, low: %d, threshold: %d", hilength, lowlength, threshold); - - bitstring[0] = 0; - bool biterror = false; - for (uint32_t i = 0; i < implengthslen; i++) { - if (TexcomCalculateBit(implengths[i], hilength, threshold)) - strcat(bitstring, "1"); - else if (TexcomCalculateBit(implengths[i], lowlength, threshold)) - strcat(bitstring, "0"); - else { - //PrintAndLogEx(INFO, "ERROR string [%zu]: %s, bit: %d, blen: %d", strlen(bitstring), bitstring, i, implengths[i]); - //for (uint32_t j = 0; j < implengthslen; j++) - // printf("%d,", implengths[j]); - //printf("\r\n"); - - biterror = true; + if (impulsecnt == 127 || impulsecnt == 128) { + if (TexcomTK13Decode(implengths, implengthslen, bitstring, cbitstring, verbose)) { + codefound = TexkomModTK13; break; } } - if (biterror || strlen(bitstring) == 0) - continue; - if (verbose) - PrintAndLogEx(INFO, "raw bit string [%zu]: %s", strlen(bitstring), bitstring); - - // add trailing impulse (some tags just ignore it) - if (strlen(bitstring) % 2 != 0) { - if (bitstring[strlen(bitstring) - 1] == '1') - strcat(bitstring, "0"); - else - strcat(bitstring, "1"); - } - - cbitstring[0] = 0; - for (uint32_t i = 0; i < strlen(bitstring); i = i + 2) { - if (bitstring[i] == bitstring[i + 1]) { - cbitstring[0] = 0; - if (verbose) - PrintAndLogEx(WARNING, "Raw bit string have error at offset %d.", i); - break; - } - if (bitstring[i] == '1') - strcat(cbitstring, "1"); - else - strcat(cbitstring, "0"); - } - - if (strlen(cbitstring) == 0) - continue; - - if (verbose) - PrintAndLogEx(INFO, "bit string [%zu]: %s", strlen(cbitstring), cbitstring); - - if ((strlen(cbitstring) != 64) || (strncmp(cbitstring, "1111111111111111", 16) != 0)) - continue; - - codefound = TexkomModTK13; - break; + TexcomGeneralDecode(implengths, implengthslen, genbitstring, verbose); } if (codefound != TexkomModError) { @@ -502,6 +546,8 @@ static int CmdHFTexkomReader(const char *Cmd) { PrintAndLogEx(ERR, "Code have no preamble FFFF: %s", sprint_hex(tcode, 8)); } } else { + if (strlen(genbitstring) > 0) + PrintAndLogEx(INFO, "General decoding bitstring: %s", genbitstring); if (strlen(bitstring) > 0) PrintAndLogEx(INFO, "last raw bit string [%zu]: %s", strlen(bitstring), bitstring); if (strlen(cbitstring) > 0) From 45804fb45c8cb8351b752b13c63b1637937b340b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 28 Jun 2022 11:41:03 +0300 Subject: [PATCH 039/759] show code as in the duplicator and some comments --- client/src/cmdhftexkom.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index d863fba05..b5bb018fa 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -394,6 +394,13 @@ static bool TexcomGeneralDecode(uint32_t* implengths, uint32_t implengthslen, ch return (!biterror && strlen(bitstring) > 0); } +static void TexcomReverseCode(const uint8_t *code, int length, uint8_t *reverse_code) { + for (int i = 0; i < length; i++) { + reverse_code[i] = code[(length - 1) - i]; + } +}; + + static int CmdHFTexkomReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf texkom reader", @@ -473,7 +480,7 @@ static int CmdHFTexkomReader(const char *Cmd) { //PrintAndLogEx(WARNING, "--- impulses: %d, lenarray: %d, [%d,%d]", impulsecnt, implengthslen, implengths[0], implengths[1]); // check if it TK-17 modulation - // 65 impulses and 64 intervals + // 65 impulses and 64 intervals (1 interval = 2 bits, interval length encoding) that represents 128 bit of card code if (impulsecnt == 65) { if (TexcomTK17Decode(implengths, implengthslen, bitstring, cbitstring, verbose)) { codefound = TexkomModTK17; @@ -481,6 +488,8 @@ static int CmdHFTexkomReader(const char *Cmd) { } } + // check if it TK-13 modulation + // it have 127 or 128 impulses and 128 double-intervals that represents 128 bit of card code if (impulsecnt == 127 || impulsecnt == 128) { if (TexcomTK13Decode(implengths, implengthslen, bitstring, cbitstring, verbose)) { codefound = TexkomModTK13; @@ -488,6 +497,8 @@ static int CmdHFTexkomReader(const char *Cmd) { } } + // general decoding. it thought that there is 2 types of intervals "long" (1) and "short" (0) + // and tries to decode sequence. shows only raw data if (verbose) TexcomGeneralDecode(implengths, implengthslen, genbitstring, verbose); } @@ -498,14 +509,21 @@ static int CmdHFTexkomReader(const char *Cmd) { tcode[i / 8] = (tcode[i / 8] << 1) | ((cbitstring[i] == '1') ? 1 : 0); } - if (verbose) + uint8_t rtcode[8] = {0}; + TexcomReverseCode(tcode, 8, rtcode); + + if (verbose) { PrintAndLogEx(INFO, "Hex code: %s", sprint_hex(tcode, 8)); + PrintAndLogEx(INFO, "Hex code reversed: %s", sprint_hex(rtcode, 8)); + } if (tcode[0] == 0xff && tcode[1] == 0xff) { // decoding code - if (!verbose) + if (!verbose) { PrintAndLogEx(INFO, "Texkom: %s", sprint_hex(tcode, 8)); + PrintAndLogEx(INFO, "Texkom duplicator: %s", sprint_hex(rtcode, 8)); + } if (codefound == TexkomModTK13) PrintAndLogEx(INFO, "modulation: TK13"); From 67fc919c72b3fbb96b283893a374f9db5914fb44 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 28 Jun 2022 11:45:48 +0300 Subject: [PATCH 040/759] make style --- armsrc/hfops.c | 2 +- client/src/cmdhftexkom.c | 129 +++++++++++++++++++-------------------- client/src/cmdhftexkom.h | 2 +- doc/commands.json | 31 ++++++++-- doc/commands.md | 10 +++ 5 files changed, 100 insertions(+), 74 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 37759d616..3bf060c56 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -84,7 +84,7 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); uint32_t scnt = getSampleCounter(); - reply_ng(CMD_HF_ACQ_RAW_ADC, PM3_SUCCESS, (uint8_t*)&scnt, 4); + reply_ng(CMD_HF_ACQ_RAW_ADC, PM3_SUCCESS, (uint8_t *)&scnt, 4); if (ledcontrol) LEDsoff(); return 0; diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index b5bb018fa..8d4f016f8 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -25,9 +25,9 @@ #include "cmdparser.h" // command_t #include "comms.h" #include "ui.h" -#include "cmdhf14a.h" -#include "cmddata.h" -#include "graph.h" +#include "cmdhf14a.h" +#include "cmddata.h" +#include "graph.h" #define TEXKOM_NOISE_THRESHOLD (10) @@ -101,12 +101,12 @@ static bool TexkomCorrelate(uint32_t indx, uint32_t threshold) { uint32_t g5 = GetGraphBuffer(indx + 2); return ( - (g3 > threshold) && - (g3 >= g2) && (g3 >= g1) && (g3 > g4) && (g3 > g5) - ); + (g3 > threshold) && + (g3 >= g2) && (g3 >= g1) && (g3 > g4) && (g3 > g5) + ); } -static bool TexkomCalculateMaxMin(uint32_t* data, uint32_t len, uint32_t* dmax, uint32_t* dmin) { +static bool TexkomCalculateMaxMin(uint32_t *data, uint32_t len, uint32_t *dmax, uint32_t *dmin) { *dmax = 0; *dmin = 0xffffffff; for (size_t i = 0; i < len; i++) { @@ -119,7 +119,7 @@ static bool TexkomCalculateMaxMin(uint32_t* data, uint32_t len, uint32_t* dmax, return (*dmax != 0) && (*dmin != 0xffffffff) && (*dmax > *dmin); } -static bool TexkomCalculateBitLengths(uint32_t* data, uint32_t len, uint32_t* hi, uint32_t* low, uint32_t* lmax, uint32_t* lmin) { +static bool TexkomCalculateBitLengths(uint32_t *data, uint32_t len, uint32_t *hi, uint32_t *low, uint32_t *lmax, uint32_t *lmin) { *hi = 0; *low = 0; @@ -155,19 +155,19 @@ static bool TexkomCalculateBitLengths(uint32_t* data, uint32_t len, uint32_t* hi } inline bool TexcomCalculateBit(uint32_t data, uint32_t bitlen, uint32_t threshold) { - return - (data < (bitlen + threshold)) && + return + (data < (bitlen + threshold)) && (data > (bitlen - threshold)); } // code from https://github.com/li0ard/crclib/blob/main/index.js -static uint8_t TexcomTK13CRC(uint8_t* data) { +static uint8_t TexcomTK13CRC(uint8_t *data) { uint8_t crc = 0; uint8_t indx = 0; while (indx < 4) { crc = crc ^ data[indx++]; - for (uint8_t i = 0; i < 8; i++) + for (uint8_t i = 0; i < 8; i++) if (crc & 0x80) { crc = 0x31 ^ (crc << 1); } else @@ -177,71 +177,68 @@ static uint8_t TexcomTK13CRC(uint8_t* data) { return crc; } -static unsigned char dallas_crc8(const unsigned char * data, const unsigned int size) -{ +static unsigned char dallas_crc8(const unsigned char *data, const unsigned int size) { unsigned char crc = 0; - for ( unsigned int i = 0; i < size; ++i ) - { + for (unsigned int i = 0; i < size; ++i) { unsigned char inbyte = data[i]; - for ( unsigned char j = 0; j < 8; ++j ) - { + for (unsigned char j = 0; j < 8; ++j) { unsigned char mix = (crc ^ inbyte) & 0x01; crc >>= 1; - if ( mix ) crc ^= 0x8C; + if (mix) crc ^= 0x8C; inbyte >>= 1; } } -PrintAndLogEx(WARNING, "--crc %x", crc); + PrintAndLogEx(WARNING, "--crc %x", crc); return crc; } // code from https://github.com/li0ard/crclib/blob/main/index.js -static uint8_t TexcomTK17CRC(uint8_t* data) { +static uint8_t TexcomTK17CRC(uint8_t *data) { uint8_t ddata[8] = {0x00, 0x00, 0x00, data[0], data[1], data[2], data[3], 0x00}; -/* - dallas (arrby) { - var arrby2 = []; - if (arrby.length < 8) { - return "FF"; - } - var n = 0; - var n2 = 7; - while (n < 7){ - arrby2[n] = arrby[n2]; - ++n; - --n2; - } - var n3 = 0; - var n4 = 0; - do { - var n5 = 255 & arrby2[n3]; - var n6 = n4; - for (var n7 = 0; n7 < 8; n7 = Number(n7 + 1)) { - var n8 = 1 & (255 & (n6 ^ n5)); - n6 = 255 & n6 >> 1; - n5 = 255 & n5 >> 1; - if (n8 != 1) continue; - n6 ^= 140; - } - if ((n3 = Number(n3 + 1)) >= 7) { - return n6.toString(16).toUpperCase(); - } - n4 = n6; - } while (true); - } - tk17(arrby) { - if(arrby.length < 8) { - return "FF" - } - return this.dallas( [0x00, arrby[1], arrby[2], arrby[3], arrby[4], 0x00, 0x00, 0x00] ) - } -*/ + /* + dallas (arrby) { + var arrby2 = []; + if (arrby.length < 8) { + return "FF"; + } + var n = 0; + var n2 = 7; + while (n < 7){ + arrby2[n] = arrby[n2]; + ++n; + --n2; + } + var n3 = 0; + var n4 = 0; + do { + var n5 = 255 & arrby2[n3]; + var n6 = n4; + for (var n7 = 0; n7 < 8; n7 = Number(n7 + 1)) { + var n8 = 1 & (255 & (n6 ^ n5)); + n6 = 255 & n6 >> 1; + n5 = 255 & n5 >> 1; + if (n8 != 1) continue; + n6 ^= 140; + } + if ((n3 = Number(n3 + 1)) >= 7) { + return n6.toString(16).toUpperCase(); + } + n4 = n6; + } while (true); + } + tk17(arrby) { + if(arrby.length < 8) { + return "FF" + } + return this.dallas( [0x00, arrby[1], arrby[2], arrby[3], arrby[4], 0x00, 0x00, 0x00] ) + } + */ return dallas_crc8(ddata, 8); } -static bool TexcomTK13Decode(uint32_t* implengths, uint32_t implengthslen, char* bitstring, char* cbitstring, bool verbose) { +static bool TexcomTK13Decode(uint32_t *implengths, uint32_t implengthslen, char *bitstring, char *cbitstring, bool verbose) { bitstring[0] = 0; cbitstring[0] = 0; @@ -275,7 +272,7 @@ static bool TexcomTK13Decode(uint32_t* implengths, uint32_t implengthslen, char* // add trailing impulse (some tags just ignore it) if (strlen(bitstring) % 2 != 0) { - if (bitstring[strlen(bitstring) - 1] == '1') + if (bitstring[strlen(bitstring) - 1] == '1') strcat(bitstring, "0"); else strcat(bitstring, "1"); @@ -316,7 +313,7 @@ inline int TexcomTK17Get2Bits(uint32_t len1, uint32_t len2) { return TK17Bit11; } -static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, char* bitstring, char* cbitstring, bool verbose) { +static bool TexcomTK17Decode(uint32_t *implengths, uint32_t implengthslen, char *bitstring, char *cbitstring, bool verbose) { bitstring[0] = 0; cbitstring[0] = 0; @@ -324,7 +321,7 @@ static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, char* int dbit = TexcomTK17Get2Bits(implengths[i], implengths[i + 1]); if (dbit == TK17WrongBit) return false; - + switch (dbit) { case TK17Bit00: strcat(bitstring, "00"); @@ -359,8 +356,7 @@ static bool TexcomTK17Decode(uint32_t* implengths, uint32_t implengthslen, char* return (strlen(bitstring) == 64) && (strncmp(cbitstring, "1111111111111111", 16) == 0); } - -static bool TexcomGeneralDecode(uint32_t* implengths, uint32_t implengthslen, char* bitstring, bool verbose) { +static bool TexcomGeneralDecode(uint32_t *implengths, uint32_t implengthslen, char *bitstring, bool verbose) { uint32_t hilength = 0; uint32_t lowlength = 0; if (!TexkomCalculateBitLengths(implengths, implengthslen, &hilength, &lowlength, NULL, NULL)) @@ -400,7 +396,6 @@ static void TexcomReverseCode(const uint8_t *code, int length, uint8_t *reverse_ } }; - static int CmdHFTexkomReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf texkom reader", @@ -461,7 +456,7 @@ static int CmdHFTexkomReader(const char *Cmd) { noiselvl = TEXKOM_NOISE_THRESHOLD; //PrintAndLogEx(WARNING, "--- indx: %d, len: %d, max: %d, noise: %d", sindx, slen, maxlvl, noiselvl); - + uint32_t implengths[256] = {}; uint32_t implengthslen = 0; uint32_t impulseindx = 0; diff --git a/client/src/cmdhftexkom.h b/client/src/cmdhftexkom.h index 2e8a79658..a90d36033 100644 --- a/client/src/cmdhftexkom.h +++ b/client/src/cmdhftexkom.h @@ -38,4 +38,4 @@ enum TexkomModulation { int CmdHFTexkom(const char *Cmd); -#endif \ No newline at end of file +#endif diff --git a/doc/commands.json b/doc/commands.json index 4f6703656..db5be2717 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -2661,7 +2661,7 @@ }, "hf help": { "command": "hf help", - "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags", + "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } texkom { Texkom RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags", "notes": [], "offline": true, "options": [], @@ -6302,6 +6302,27 @@ ], "usage": "hf st25ta sim [-h] -u " }, + "hf texkom help": { + "command": "hf texkom help", + "description": "help This help", + "notes": [], + "offline": true, + "options": [], + "usage": "" + }, + "hf texkom reader": { + "command": "hf texkom reader", + "description": "Read a texkom tag", + "notes": [ + "hf texkom reader" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-v, --verbose Verbose scan and output" + ], + "usage": "hf texkom reader [-hv]" + }, "hf thinfilm help": { "command": "hf thinfilm help", "description": "help This help list List NFC Barcode / Thinfilm history - not correct", @@ -6528,8 +6549,8 @@ "command": "hw connect", "description": "Connects to a Proxmark3 device via specified serial port. Baudrate here is only for physical UART or UART-BT, NOT for USB-CDC or blue shark add-on", "notes": [ - "hw connect -p /dev/ttyACM0", - "hw connect -p /dev/ttyACM0 -b 115200" + "hw connect -p /dev/ttyacm0", + "hw connect -p /dev/ttyacm0 -b 115200" ], "offline": true, "options": [ @@ -10998,8 +11019,8 @@ } }, "metadata": { - "commands_extracted": 693, + "commands_extracted": 695, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-06-12T09:54:12" + "extracted_on": "2022-06-28T08:43:20" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 6421ba761..b9689c5c2 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -646,6 +646,16 @@ Check column "offline" for their availability. |`hf topaz raw `|N |`Send raw hex data to tag` +### hf texkom + + { Texkom RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf texkom help `|Y |`This help` +|`hf texkom reader `|N |`Act like a Texkom reader` + + ### hf waveshare { Waveshare NFC ePaper... } From 4df92e2655a0e2899cac09393e0965b29fb887b1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 28 Jun 2022 12:26:20 +0300 Subject: [PATCH 041/759] crc for tk17 works --- client/src/cmdhftexkom.c | 42 +--------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 8d4f016f8..8cb73d6c0 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -188,7 +188,6 @@ static unsigned char dallas_crc8(const unsigned char *data, const unsigned int s inbyte >>= 1; } } - PrintAndLogEx(WARNING, "--crc %x", crc); return crc; } @@ -196,46 +195,7 @@ static unsigned char dallas_crc8(const unsigned char *data, const unsigned int s static uint8_t TexcomTK17CRC(uint8_t *data) { uint8_t ddata[8] = {0x00, 0x00, 0x00, data[0], data[1], data[2], data[3], 0x00}; - /* - dallas (arrby) { - var arrby2 = []; - if (arrby.length < 8) { - return "FF"; - } - var n = 0; - var n2 = 7; - while (n < 7){ - arrby2[n] = arrby[n2]; - ++n; - --n2; - } - var n3 = 0; - var n4 = 0; - do { - var n5 = 255 & arrby2[n3]; - var n6 = n4; - for (var n7 = 0; n7 < 8; n7 = Number(n7 + 1)) { - var n8 = 1 & (255 & (n6 ^ n5)); - n6 = 255 & n6 >> 1; - n5 = 255 & n5 >> 1; - if (n8 != 1) continue; - n6 ^= 140; - } - if ((n3 = Number(n3 + 1)) >= 7) { - return n6.toString(16).toUpperCase(); - } - n4 = n6; - } while (true); - } - tk17(arrby) { - if(arrby.length < 8) { - return "FF" - } - return this.dallas( [0x00, arrby[1], arrby[2], arrby[3], arrby[4], 0x00, 0x00, 0x00] ) - } - */ - - return dallas_crc8(ddata, 8); + return dallas_crc8(ddata, 7); } static bool TexcomTK13Decode(uint32_t *implengths, uint32_t implengthslen, char *bitstring, char *cbitstring, bool verbose) { From 22f1e8e209b9843a9e1c9a51d0aba48fbdc2db0d Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Tue, 28 Jun 2022 19:06:17 +0300 Subject: [PATCH 042/759] check noise at the antenna --- client/src/cmdhftexkom.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 8cb73d6c0..d810c2f16 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -38,6 +38,17 @@ inline uint32_t GetGraphBuffer(uint32_t indx) { return g_GraphBuffer[indx] + 128; } +static uint32_t TexkomAVGField(void) { + if (g_GraphTraceLen == 0) + return 0; + + uint64_t vsum = 0; + for (uint32_t i = 0; i < g_GraphTraceLen; i++) + vsum += GetGraphBuffer(i); + + return vsum / g_GraphTraceLen; +} + static uint32_t TexkomSearchStart(uint32_t indx, uint32_t threshold) { // one bit length = 27, minimal noise = 60 uint32_t lownoisectr = 0; @@ -398,8 +409,11 @@ static int CmdHFTexkomReader(const char *Cmd) { uint32_t sindx = 0; while (sindx < samplesCount - 5) { sindx = TexkomSearchStart(sindx, TEXKOM_NOISE_THRESHOLD); - if (sindx == 0 || sindx > samplesCount - 5) + if (sindx == 0 || sindx > samplesCount - 5) { + if (TexkomAVGField() > 30) + PrintAndLogEx(WARNING, "Too noisy environment. Try to move the tag from the antenna a bit."); break; + } uint32_t slen = TexkomSearchLength(sindx, TEXKOM_NOISE_THRESHOLD); if (slen == 0) From de29369b03acdc84d083acc3945bc9a876484303 Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> Date: Tue, 28 Jun 2022 23:45:50 +0300 Subject: [PATCH 043/759] Update CHANGELOG.md Signed-off-by: Oleg Moiseenko <807634+merlokk@users.noreply.github.com> --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8a13e0e1..5c6a799e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz) - Added 122 new keys from Flipper Zero community to `mfc_default_keys.dic` (@UberGuidoZ) - Added showing password for the read command in the `lf t55xx sniff` command (@merlokk) + - Added reading texcom tk13 and tk17 tags with `hf texkom read` command (@merlokk @iceman1001) ## [Frostbit.4.14831][2022-01-11] - Changed Wiegand format lookup - now case-insensitive (@iceman1001) From 6d699d66bc92e881714fb8cdf1b9cb44f0805f0c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Jun 2022 22:50:52 +0200 Subject: [PATCH 044/759] adding support to read fuji/xerox tags, thanks to user Horror --- CHANGELOG.md | 3 + armsrc/iso14443b.c | 282 ++++++++++-- armsrc/iso14443b.h | 1 + client/Makefile | 1 + client/src/cmdhf.c | 2 + client/src/cmdhf14b.c | 22 +- client/src/cmdhfxerox.c | 744 ++++++++++++++++++++++++++++++++ client/src/cmdhfxerox.h | 12 + client/src/pm3line_vocabulory.h | 5 + doc/commands.json | 48 ++- doc/commands.md | 11 + include/iso14b.h | 1 + 12 files changed, 1083 insertions(+), 49 deletions(-) create mode 100644 client/src/cmdhfxerox.c create mode 100644 client/src/cmdhfxerox.h diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c6a799e9..9aa7ff298 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ 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 14b raw` - now supports selecting Fuji/Xerox tag (@horror) + - Added `hf xerox dump` - dump a Fuji/Xerox tag (@horror) + - Added `hf xerox info` - read Fuji/Xerox tag (@horror) - Fixed `hf 14a reader --ecp` to work consistently (@kormax) - Change `trace list -t 14a` to annotate ECP frames of all valid V1 and V2 formats (@kormax) - Changed `hf mf staticnested` - significant speedups by using two encrypted nonces (@xianglin1998) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 655ed367e..0372189a5 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -1381,11 +1381,11 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t } if (Demod.len > 0) { - uint32_t sof_time = *eof_time - - (Demod.len * (8 + 2)) // time for byte transfers - - (10) // time for TR1 - - (10 + 2) // time for SOF transfer - - (10); // time for EOF transfer + uint32_t sof_time = *eof_time - ETU_TO_SSP( + (Demod.len * (8 + 2)) // time for byte transfers +// + (10) // time for TR1 + + (10 + 2) // time for SOF transfer + + (10)); // time for EOF transfer LogTrace(Demod.output, Demod.len, sof_time, *eof_time, NULL, false); } return Demod.len; @@ -1435,9 +1435,28 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) { } WDT_HIT(); } + + // transmit remaining bits. we need one-sample granularity now + + volatile uint8_t data = ts->buf[ts->max], last_bits = ts->bit; + + for (uint8_t i = 0; i < last_bits; i++) { + volatile uint16_t send_word = (data & 0x80) ? 0x0000 : 0xFFFF; + + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; + AT91C_BASE_SSC->SSC_THR = send_word; + + while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; + AT91C_BASE_SSC->SSC_THR = send_word; + + data <<= 1; + } + WDT_HIT(); + + LED_B_OFF(); - *start_time += DELAY_ARM_TO_TAG; +// *start_time += DELAY_ARM_TO_TAG; // wait for last transfer to complete while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) {}; @@ -1447,7 +1466,7 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) { // Code a layer 2 command (string of octets, including CRC) into ToSend[], // so that it is ready to transmit to the tag using TransmitFor14443b(). //----------------------------------------------------------------------------- -static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { +static void CodeIso14443bAsReader(const uint8_t *cmd, int len, bool framing) { /* * QUESTION: how long is a 1 or 0 in pulses in the xcorr_848 mode? * 1 "stuffbit" = 1ETU (9us) @@ -1460,14 +1479,18 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { int i; tosend_reset(); - // Send SOF - // 10-11 ETUs of ZERO - for (i = 0; i < 10; i++) { - tosend_stuffbit(0); + // add framing enable flag. xerox chips use unframed commands during anticollision + + if (framing) { + // Send SOF + // 10-11 ETUs of ZERO + for (i = 0; i < 10; i++) { + tosend_stuffbit(0); + } + // 2-3 ETUs of ONE + tosend_stuffbit(1); + tosend_stuffbit(1); } - // 2-3 ETUs of ONE - tosend_stuffbit(1); - tosend_stuffbit(1); // Sending cmd, LSB // from here we add BITS @@ -1493,28 +1516,36 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { // FOR PICC it ranges 0-19us == 0 - 2 ETU } - // Send EOF - // 10-11 ETUs of ZERO - for (i = 0; i < 10; i++) { - tosend_stuffbit(0); + if (framing) { + // Send EOF + // 10-11 ETUs of ZERO + for (i = 0; i < 10; i++) { + tosend_stuffbit(0); + } } - - int pad = (10 + 2 + (len * 10) + 10) & 0x7; - for (i = 0; i < 16 - pad; ++i) - tosend_stuffbit(1); - + // we can't use padding now + /* + int pad = (10 + 2 + (len * 10) + 10) & 0x7; + for (i = 0; i < 16 - pad; ++i) + tosend_stuffbit(1); + */ } /* * Convenience function to encode, transmit and trace iso 14443b comms */ -static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_time, uint32_t *eof_time) { +static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_time, uint32_t *eof_time, bool framing) { tosend_t *ts = get_tosend(); - CodeIso14443bAsReader(cmd, len); + CodeIso14443bAsReader(cmd, len, framing); TransmitFor14443b_AsReader(start_time); if (g_trigger) LED_A_ON(); - *eof_time = *start_time + (10 * ts->max) + 10 + 2 + 10; + +// eof_time in ssp clocks, but bits was added here! +// *eof_time = *start_time + (10 * ts->max) + 10 + 2 + 10; + + *eof_time = *start_time + ETU_TO_SSP(8 * ts->max); + LogTrace(cmd, len, *start_time, *eof_time, NULL, true); } @@ -1545,7 +1576,7 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void // send uint32_t start_time = 0; uint32_t eof_time = 0; - CodeAndTransmit14443bAsReader(real_cmd, msg_len + 3, &start_time, &eof_time); + CodeAndTransmit14443bAsReader(real_cmd, msg_len + 3, &start_time, &eof_time, true); eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; int len = Get14443bAnswerFromTag(rxdata, rxmaxlen, iso14b_timeout, &eof_time); @@ -1578,7 +1609,7 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void AddCrc14B(data_bytes, len - 2); // transmit S-Block - CodeAndTransmit14443bAsReader(data_bytes, len, &start_time, &eof_time); + CodeAndTransmit14443bAsReader(data_bytes, len, &start_time, &eof_time, true); // retrieve the result again (with increased timeout) eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; @@ -1637,7 +1668,7 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) { uint32_t start_time = 0; uint32_t eof_time = 0; - CodeAndTransmit14443bAsReader(cmdINIT, sizeof(cmdINIT), &start_time, &eof_time); + CodeAndTransmit14443bAsReader(cmdINIT, sizeof(cmdINIT), &start_time, &eof_time, true); eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; int retlen = Get14443bAnswerFromTag(r, sizeof(r), iso14b_timeout, &eof_time); @@ -1657,7 +1688,7 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) { } start_time = eof_time + ISO14B_TR2; - CodeAndTransmit14443bAsReader(cmdMSBUID, sizeof(cmdMSBUID), &start_time, &eof_time); + CodeAndTransmit14443bAsReader(cmdMSBUID, sizeof(cmdMSBUID), &start_time, &eof_time, true); eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; retlen = Get14443bAnswerFromTag(r, sizeof(r), iso14b_timeout, &eof_time); @@ -1675,7 +1706,7 @@ static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) { } start_time = eof_time + ISO14B_TR2; - CodeAndTransmit14443bAsReader(cmdLSBUID, sizeof(cmdLSBUID), &start_time, &eof_time); + CodeAndTransmit14443bAsReader(cmdLSBUID, sizeof(cmdLSBUID), &start_time, &eof_time, true); eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; retlen = Get14443bAnswerFromTag(r, sizeof(r), iso14b_timeout, &eof_time); @@ -1706,7 +1737,7 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) { uint32_t start_time = 0; uint32_t eof_time = 0; - CodeAndTransmit14443bAsReader(init_srx, sizeof(init_srx), &start_time, &eof_time); + CodeAndTransmit14443bAsReader(init_srx, sizeof(init_srx), &start_time, &eof_time, true); eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; int retlen = Get14443bAnswerFromTag(r_init, sizeof(r_init), iso14b_timeout, &eof_time); @@ -1728,7 +1759,7 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) { AddCrc14B(select_srx, 2); start_time = eof_time + ISO14B_TR2; - CodeAndTransmit14443bAsReader(select_srx, sizeof(select_srx), &start_time, &eof_time); + CodeAndTransmit14443bAsReader(select_srx, sizeof(select_srx), &start_time, &eof_time, true); eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; retlen = Get14443bAnswerFromTag(r_select, sizeof(r_select), iso14b_timeout, &eof_time); @@ -1752,7 +1783,7 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) { AddCrc14B(select_srx, 1); start_time = eof_time + ISO14B_TR2; - CodeAndTransmit14443bAsReader(select_srx, 3, &start_time, &eof_time); // Only first three bytes for this one + CodeAndTransmit14443bAsReader(select_srx, 3, &start_time, &eof_time, true); // Only first three bytes for this one eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; retlen = Get14443bAnswerFromTag(r_papid, sizeof(r_papid), iso14b_timeout, &eof_time); @@ -1772,6 +1803,174 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) { return 0; } + +// Xerox tag connect function: wup, anticoll, attrib, password +// the original chips require all commands in this sequence + +// 0: OK, 1: select fail, 2: attrib fail, 3: crc fail, 4: password fail +int iso14443b_select_xrx_card(iso14b_card_select_t *card) { +// AFI + static const uint8_t x_wup1[] = { 0x0D, 0x37, 0x21, 0x92, 0xf2 }; + static const uint8_t x_wup2[] = { 0x5D, 0x37, 0x21, 0x71, 0x71 }; + uint8_t slot_mark[1]; + + uint8_t x_atqb[24] = {0x0}; // ATQB len = 18 + + uint32_t start_time = 0; + uint32_t eof_time = 0; + + iso14b_set_timeout(24); // wait for carrier + + // wup1 + CodeAndTransmit14443bAsReader(x_wup1, sizeof(x_wup1), &start_time, &eof_time, true); + + start_time = eof_time + US_TO_SSP(9000); // 9ms before next cmd + + // wup2 + CodeAndTransmit14443bAsReader(x_wup2, sizeof(x_wup2), &start_time, &eof_time, true); + + uint64_t uid = 0; + int retlen; + + for (int uid_pos = 0; uid_pos < 64; uid_pos += 2) { + int slot; + + for (slot = 0; slot < 4; slot++) { + start_time = eof_time + ETU_TO_SSP(30); //(24); // next slot after 24 ETU + + retlen = Get14443bAnswerFromTag(x_atqb, sizeof(x_atqb), iso14b_timeout, &eof_time); + + if (retlen > 0) { + FpgaDisableTracing(); + + Dbprintf("unexpected data %d", retlen); + Dbprintf("crc %s", check_crc(CRC_14443_B, x_atqb, retlen) ? "OK" : "BAD"); + return 1; + } + + // tx unframed slot-marker + + if (Demod.posCount) { // no rx, but subcarrier burst detected + uid |= (uint64_t)slot << uid_pos; + + slot_mark[0] = 0xB1 + (slot << 1); // ack slot + CodeAndTransmit14443bAsReader(slot_mark, sizeof(slot_mark), &start_time, &eof_time, false); + break; + } else { // no subcarrier burst + slot_mark[0] = 0xA1 + (slot << 1); // nak slot + CodeAndTransmit14443bAsReader(slot_mark, sizeof(slot_mark), &start_time, &eof_time, false); + } + } + + if (4 == slot) { + FpgaDisableTracing(); + + DbpString("no answer to anticollision"); + return 1; + } + } + + retlen = Get14443bAnswerFromTag(x_atqb, sizeof(x_atqb), iso14b_timeout, &eof_time); + + Dbprintf("anticollision uid %llx", uid); + + // ATQB too short? + if (retlen < 18) { + return 1; + } + + // VALIDATE CRC + if (check_crc(CRC_14443_B, x_atqb, 18) == false) { // use fixed len because unstable EOF catch + return 3; + } + + if (x_atqb[0] != 0x50) { +// DbpString("aqtb bad"); + return 1; + } + + if (card) { + card->uidlen = 8; + memcpy(card->uid, x_atqb + 1, 8); + memcpy(card->atqb, x_atqb + 9, 7); + } + +// DbpString("aqtb ok"); + + // send ATTRIB command + + uint8_t txbuf[18]; + + txbuf[1] = 0x1d; + memcpy(txbuf + 2, &uid, 8); + txbuf[10] = 0; + txbuf[11] = 0xF; + txbuf[12] = 1; + txbuf[13] = 0xF; + + AddCrc14B(txbuf + 1, 13); + + start_time = eof_time + ISO14B_TR2; + CodeAndTransmit14443bAsReader(txbuf + 1, 15, &start_time, &eof_time, true); + + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + retlen = Get14443bAnswerFromTag(x_atqb, sizeof(x_atqb), iso14b_timeout, &eof_time); + FpgaDisableTracing(); + + if (retlen < 3) { +// DbpString("attrib failed"); + return 2; + } + + if (check_crc(CRC_14443_B, x_atqb, 3) == false) { + return 3; + } + + if (x_atqb[0] != 0) { +// DbpString("attrib failed"); + return 2; + } + +// DbpString("attrib ok"); + + // apply PASSWORD command + + txbuf[0] = 2; + txbuf[1] = 0x38; + // uid from previous command used + txbuf[10] = 3; + txbuf[11] = 0x4e; + txbuf[12] = 0x4b; + txbuf[13] = 0x53; + txbuf[14] = 0x4F; + + AddCrc14B(txbuf, 15); + + start_time = eof_time + ISO14B_TR2; + CodeAndTransmit14443bAsReader(txbuf, 17, &start_time, &eof_time, true); + + eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; + retlen = Get14443bAnswerFromTag(x_atqb, sizeof(x_atqb), iso14b_timeout, &eof_time); + + if (retlen < 4) { +// DbpString("passwd failed"); + return 4; + } + + if (check_crc(CRC_14443_B, x_atqb, 4) == false) { + return 3; + } + + if (x_atqb[0] != 2 || x_atqb[1] != 0) { +// DbpString("passwd failed"); + return 4; + } + +// DbpString("passwd ok"); + + return 0; +} + /* Perform the ISO 14443 B Card Selection procedure * Currently does NOT do any collision handling. * It expects 0-1 cards in the device's range. @@ -1794,7 +1993,7 @@ int iso14443b_select_card(iso14b_card_select_t *card) { // first, wake up the tag uint32_t start_time = 0; uint32_t eof_time = 0; - CodeAndTransmit14443bAsReader(wupb, sizeof(wupb), &start_time, &eof_time); + CodeAndTransmit14443bAsReader(wupb, sizeof(wupb), &start_time, &eof_time, true); eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; int retlen = Get14443bAnswerFromTag(r_pupid, sizeof(r_pupid), iso14b_timeout, &eof_time); @@ -1823,7 +2022,7 @@ int iso14443b_select_card(iso14b_card_select_t *card) { attrib[7] = r_pupid[10] & 0x0F; AddCrc14B(attrib, 9); start_time = eof_time + ISO14B_TR2; - CodeAndTransmit14443bAsReader(attrib, sizeof(attrib), &start_time, &eof_time); + CodeAndTransmit14443bAsReader(attrib, sizeof(attrib), &start_time, &eof_time, true); eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; retlen = Get14443bAnswerFromTag(r_attrib, sizeof(r_attrib), iso14b_timeout, &eof_time); @@ -1916,7 +2115,7 @@ static int read_srx_block(uint8_t blocknr, uint8_t *block) { uint32_t start_time = 0; uint32_t eof_time = 0; - CodeAndTransmit14443bAsReader(cmd, sizeof(cmd), &start_time, &eof_time); + CodeAndTransmit14443bAsReader(cmd, sizeof(cmd), &start_time, &eof_time, true); eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER; int retlen = Get14443bAnswerFromTag(r_block, sizeof(r_block), iso14b_timeout, &eof_time); @@ -2223,6 +2422,13 @@ void SendRawCommand14443B_Ex(iso14b_raw_cmd_t *p) { if (status > 0) goto out; } + if ((p->flags & ISO14B_SELECT_XRX) == ISO14B_SELECT_XRX) { + status = iso14443b_select_xrx_card(&card); + reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, (uint8_t *)&card, sendlen); + // 0: OK, 1: select fail, 2: attrib fail, 3: crc fail, 4: password fail + if (status != 0) goto out; + } + if ((p->flags & ISO14B_APDU) == ISO14B_APDU) { uint8_t res; status = iso14443b_apdu(p->raw, p->rawlen, (p->flags & ISO14B_SEND_CHAINING), buf, sizeof(buf), &res); @@ -2239,7 +2445,7 @@ void SendRawCommand14443B_Ex(iso14b_raw_cmd_t *p) { } uint32_t start_time = 0; uint32_t eof_time = 0; - CodeAndTransmit14443bAsReader(p->raw, p->rawlen, &start_time, &eof_time); + CodeAndTransmit14443bAsReader(p->raw, p->rawlen, &start_time, &eof_time, true); if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred FpgaDisableTracing(); diff --git a/armsrc/iso14443b.h b/armsrc/iso14443b.h index 3dcbceaae..2579e6f1c 100644 --- a/armsrc/iso14443b.h +++ b/armsrc/iso14443b.h @@ -39,6 +39,7 @@ int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void int iso14443b_select_card(iso14b_card_select_t *card); int iso14443b_select_card_srx(iso14b_card_select_t *card); +int iso14443b_select_xrx_card(iso14b_card_select_t *card); void SimulateIso14443bTag(uint8_t *pupi); void AcquireRawAdcSamplesIso14443b(uint32_t parameter); diff --git a/client/Makefile b/client/Makefile index d4893b341..3f57cd1bd 100644 --- a/client/Makefile +++ b/client/Makefile @@ -578,6 +578,7 @@ SRCS = mifare/aiddesfire.c \ cmdhftopaz.c \ cmdhftexkom.c \ cmdhfwaveshare.c \ + cmdhfxerox.c \ cmdhw.c \ cmdlf.c \ cmdlfawid.c \ diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 9ed214eac..31979a5cd 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -48,6 +48,7 @@ #include "cmdhfst25ta.h" // ST25TA #include "cmdhfwaveshare.h" // Waveshare #include "cmdhftexkom.h" // Texkom +#include "cmdhfxerox.h" // Xerox #include "cmdtrace.h" // trace list #include "ui.h" #include "proxgui.h" @@ -437,6 +438,7 @@ static command_t CommandTable[] = { {"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"}, {"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"}, {"texkom", CmdHFTexkom, AlwaysAvailable, "{ Texkom RFIDs... }"}, + {"xerox", CmdHFXerox, AlwaysAvailable, "{ Fuji/Xerox cartridge RFIDs... }"}, {"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"}, {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, {"help", CmdHelp, AlwaysAvailable, "This help"}, diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index d981727b4..5a1193cd0 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -283,6 +283,7 @@ static int CmdHF14BCmdRaw(const char *Cmd) { arg_lit0("s", "std", "activate field, use ISO14B select"), arg_lit0(NULL, "sr", "activate field, use SRx ST select"), arg_lit0(NULL, "cts", "activate field, use ASK C-ticket select"), + arg_lit0(NULL, "xrx", "activate field, use Fuji/Xerox select"), arg_lit0("c", "crc", "calculate and append CRC"), arg_lit0("r", NULL, "do not read response from card"), arg_int0("t", "timeout", "", "timeout in ms"), @@ -296,10 +297,11 @@ static int CmdHF14BCmdRaw(const char *Cmd) { bool select_std = arg_get_lit(ctx, 2); bool select_sr = arg_get_lit(ctx, 3); bool select_cts = arg_get_lit(ctx, 4); - bool add_crc = arg_get_lit(ctx, 5); - bool read_reply = (arg_get_lit(ctx, 6) == false); - int user_timeout = arg_get_int_def(ctx, 7, -1); - bool verbose = arg_get_lit(ctx, 8); + bool select_xrx = arg_get_lit(ctx, 5); + bool add_crc = arg_get_lit(ctx, 6); + bool read_reply = (arg_get_lit(ctx, 7) == false); + int user_timeout = arg_get_int_def(ctx, 8, -1); + bool verbose = arg_get_lit(ctx, 9); uint32_t flags = ISO14B_CONNECT; if (add_crc) { @@ -318,11 +320,15 @@ static int CmdHF14BCmdRaw(const char *Cmd) { flags |= (ISO14B_SELECT_CTS | ISO14B_CLEARTRACE); if (verbose) PrintAndLogEx(INFO, "using ASK/C-ticket select"); + } else if (select_xrx) { + flags |= (ISO14B_SELECT_XRX | ISO14B_CLEARTRACE); + if (verbose) + PrintAndLogEx(INFO, "using Fuji/Xerox select"); } uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; int datalen = 0; - int res = CLIParamHexToBuf(arg_get_str(ctx, 9), data, sizeof(data), &datalen); + int res = CLIParamHexToBuf(arg_get_str(ctx, 10), data, sizeof(data), &datalen); if (res && verbose) { PrintAndLogEx(INFO, "called with no raw bytes"); } @@ -395,6 +401,12 @@ static int CmdHF14BCmdRaw(const char *Cmd) { PrintAndLogEx(SUCCESS, "Got response for ASK/C-ticket select"); } + if (select_xrx) { + success = wait_cmd_14b(verbose, true, user_timeout); + if (verbose && success) + PrintAndLogEx(SUCCESS, "Got response for Fuji/Xerox select"); + } + // get back response from the raw bytes you sent. if (success && datalen > 0) { wait_cmd_14b(true, false, user_timeout); diff --git a/client/src/cmdhfxerox.c b/client/src/cmdhfxerox.c new file mode 100644 index 000000000..0041de368 --- /dev/null +++ b/client/src/cmdhfxerox.c @@ -0,0 +1,744 @@ +//----------------------------------------------------------------------------- +// High frequency Xerox commands (ISO14443B) +//----------------------------------------------------------------------------- + +#include "cmdhfxerox.h" + +#include "fileutils.h" + +#include "cmdparser.h" // command_t +#include "cliparser.h" +#include "comms.h" +#include "iso14b.h" +#include "crc16.h" + +#define TIMEOUT 2000 + + +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#define C_RC2(n) \ + t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \ + x0=(t<<1)|(t>>15); \ + t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \ + x1=(t<<2)|(t>>14); \ + t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \ + x2=(t<<3)|(t>>13); \ + t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \ + x3=(t<<5)|(t>>11); + +#define RC2_ENCRYPT 1 +#define RC2_DECRYPT 0 + +typedef unsigned int RC2_INT; + +typedef struct rc2_key_st { + RC2_INT data[64]; +} RC2_KEY; + +static const unsigned char key_table[256] = { + 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, + 0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, + 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5, + 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32, + 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, + 0x5c, 0x6b, 0x4e, 0x82, 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, + 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, 0x12, 0x75, 0xca, 0x1f, + 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26, + 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, + 0xbc, 0x94, 0x43, 0x03, 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, + 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, 0x08, 0xe8, 0xea, 0xde, + 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a, + 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, + 0x04, 0x18, 0xa4, 0xec, 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, + 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, 0x99, 0x7c, 0x3a, 0x85, + 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31, + 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, + 0x67, 0x6c, 0xba, 0xc9, 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, + 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, 0x0d, 0x38, 0x34, 0x1b, + 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e, + 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, + 0xfe, 0x7f, 0xc1, 0xad, +}; + +static const unsigned char var_list[] = {0x1c, 0x1e, 0x20, 0x26, 0x28, 0x2a, 0x2c, 0x2e}; + + +static int CmdHelp(const char *Cmd); +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits); +void RC2_encrypt(unsigned long *d, RC2_KEY *key); +void RC2_decrypt(unsigned long *d, RC2_KEY *key); +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, RC2_KEY *ks, unsigned char *iv, int encrypt); + + +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) { + int i, j; + unsigned char *k; + RC2_INT *ki; + unsigned int c, d; + + k = (unsigned char *) & (key->data[0]); + *k = 0; /* for if there is a zero length key */ + + if (len > 128) + len = 128; + if (bits <= 0) + bits = 1024; + if (bits > 1024) + bits = 1024; + + for (i = 0; i < len; i++) + k[i] = data[i]; + + /* expand table */ + d = k[len - 1]; + j = 0; + for (i = len; i < 128; i++, j++) { + d = key_table[(k[j] + d) & 0xff]; + k[i] = d; + } + + /* hmm.... key reduction to 'bits' bits */ + + j = (bits + 7) >> 3; + i = 128 - j; + c = (0xff >> (-bits & 0x07)); + + d = key_table[k[i] & c]; + k[i] = d; + while (i--) { + d = key_table[k[i + j] ^ d]; + k[i] = d; + } + + /* copy from bytes into RC2_INT's */ + ki = &(key->data[63]); + for (i = 127; i >= 0; i -= 2) + * (ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff; +} + +void RC2_encrypt(unsigned long *d, RC2_KEY *key) { + int i, n; + register RC2_INT *p0, *p1; + register RC2_INT x0, x1, x2, x3, t; + unsigned long l; + + l = d[0]; + x0 = (RC2_INT)l & 0xffff; + x1 = (RC2_INT)(l >> 16L); + l = d[1]; + x2 = (RC2_INT)l & 0xffff; + x3 = (RC2_INT)(l >> 16L); + + n = 3; + i = 5; + + p0 = p1 = &(key->data[0]); + for (;;) { + t = (x0 + (x1 & ~x3) + (x2 & x3) + * (p0++)) & 0xffff; + x0 = (t << 1) | (t >> 15); + t = (x1 + (x2 & ~x0) + (x3 & x0) + * (p0++)) & 0xffff; + x1 = (t << 2) | (t >> 14); + t = (x2 + (x3 & ~x1) + (x0 & x1) + * (p0++)) & 0xffff; + x2 = (t << 3) | (t >> 13); + t = (x3 + (x0 & ~x2) + (x1 & x2) + * (p0++)) & 0xffff; + x3 = (t << 5) | (t >> 11); + + if (--i == 0) { + if (--n == 0) break; + i = (n == 2) ? 6 : 5; + + x0 += p1[x3 & 0x3f]; + x1 += p1[x0 & 0x3f]; + x2 += p1[x1 & 0x3f]; + x3 += p1[x2 & 0x3f]; + } + } + + d[0] = (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L); + d[1] = (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L); +} + +void RC2_decrypt(unsigned long *d, RC2_KEY *key) { + int i, n; + register RC2_INT *p0, *p1; + register RC2_INT x0, x1, x2, x3, t; + unsigned long l; + + l = d[0]; + x0 = (RC2_INT)l & 0xffff; + x1 = (RC2_INT)(l >> 16L); + l = d[1]; + x2 = (RC2_INT)l & 0xffff; + x3 = (RC2_INT)(l >> 16L); + + n = 3; + i = 5; + + p0 = &(key->data[63]); + p1 = &(key->data[0]); + for (;;) { + t = ((x3 << 11) | (x3 >> 5)) & 0xffff; + x3 = (t - (x0 & ~x2) - (x1 & x2) - * (p0--)) & 0xffff; + t = ((x2 << 13) | (x2 >> 3)) & 0xffff; + x2 = (t - (x3 & ~x1) - (x0 & x1) - * (p0--)) & 0xffff; + t = ((x1 << 14) | (x1 >> 2)) & 0xffff; + x1 = (t - (x2 & ~x0) - (x3 & x0) - * (p0--)) & 0xffff; + t = ((x0 << 15) | (x0 >> 1)) & 0xffff; + x0 = (t - (x1 & ~x3) - (x2 & x3) - * (p0--)) & 0xffff; + + if (--i == 0) { + if (--n == 0) break; + i = (n == 2) ? 6 : 5; + + x3 = (x3 - p1[x2 & 0x3f]) & 0xffff; + x2 = (x2 - p1[x1 & 0x3f]) & 0xffff; + x1 = (x1 - p1[x0 & 0x3f]) & 0xffff; + x0 = (x0 - p1[x3 & 0x3f]) & 0xffff; + } + } + + d[0] = (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L); + d[1] = (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L); +} + +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int encrypt) { + register unsigned long tin0, tin1; + register unsigned long tout0, tout1, xor0, xor1; + register long l = length; + unsigned long tin[2]; + + if (encrypt) { + c2l(iv, tout0); + c2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC2_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC2_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC2_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC2_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2c(xor0, iv); + l2c(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +static int switch_off_field(void) { + SetISODEPState(ISODEP_INACTIVE); + iso14b_raw_cmd_t packet = { + .flags = ISO14B_DISCONNECT, + .timeout = 0, + .rawlen = 0, + }; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)&packet, sizeof(iso14b_raw_cmd_t)); + return PM3_SUCCESS; +} + +static int findXerox(iso14b_card_select_t *card, bool disconnect) { + + if (card == NULL) + return false; + + int8_t retry = 3; + while (retry--) { + + iso14b_raw_cmd_t packet = { + .flags = (ISO14B_CONNECT | ISO14B_SELECT_XRX | (disconnect ? ISO14B_DISCONNECT : 0)), + .timeout = 0, + .rawlen = 0, + }; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)&packet, sizeof(iso14b_raw_cmd_t)); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) { + /* + PrintAndLogEx(INFO, "%X %X %X %X %X %I64X %I64X %I64X %X %X %X %c", + resp.cmd, resp.length, resp.magic, resp.status, resp.crc, resp.oldarg[0], resp.oldarg[1], resp.oldarg[2], + resp.data.asBytes[0], resp.data.asBytes[1], resp.data.asBytes[2], resp.ng ? 't' : 'f'); + */ + if (resp.oldarg[0] == 0) { + memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t)); + } + return resp.oldarg[0]; + } + } // retry + +// switch_off_field(); + PrintAndLogEx(FAILED, "command execution timeout"); + return -1; +} + +static uint8_t info_blocks[] = {0x15, 0x16, 0x17, 0x18, 0x22}; +static const char *c_type[] = {"drum", "yellow", "magenta", "cyan", "black"}; + +static inline char dec_digit(uint8_t dig) { return (dig <= 9) ? dig + '0' : '?'; } + +static void gen_pn(uint8_t *data, char *pn) { + pn[0] = dec_digit(data[0] >> 4); + pn[1] = dec_digit(data[0] & 0xF); + pn[2] = dec_digit(data[1] >> 4); + + char sym = ((data[1] & 0xF) << 4) | (data[2] >> 4); + pn[3] = (sym >= 'A' && sym <= 'Z') ? sym : '?'; + + pn[4] = dec_digit(data[2] & 0xF); + pn[5] = dec_digit(data[3] >> 4); + pn[6] = dec_digit(data[3] & 0xF); + pn[7] = dec_digit(data[4] >> 4); + pn[8] = dec_digit(data[4] & 0xF); + pn[9] = '-'; + pn[10] = dec_digit(data[5] >> 4); + pn[11] = dec_digit(data[5] & 0xF); + pn[12] = 0; +} + +static int CmdHFXeroxInfo(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf xerox info", + "Act as a reader.", + "hf xerox info"); + + void *argtable[] = { + arg_param_begin, + arg_lit0("v", "verbose", "verbose output"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool verbose = arg_get_lit(ctx, 1); + CLIParserFree(ctx); + + iso14b_card_select_t card; + int status = findXerox(&card, false); + if (status != 0) { + switch_off_field(); + if (verbose) PrintAndLogEx(FAILED, "Fuji/Xerox tag select failed"); + return PM3_ERFTRANS; + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen)); + PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb))); + + iso14b_raw_cmd_t *packet = (iso14b_raw_cmd_t *)calloc(1, sizeof(iso14b_raw_cmd_t) + 11); + if (packet == NULL) { + PrintAndLogEx(FAILED, "failed to allocate memory"); + return PM3_EMALLOC; + } + + int blocknum = 0; + uint8_t data[sizeof(info_blocks) * 4] = {0}; + + // set up the read command + packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW); + packet->rawlen = 11; + packet->raw[0] = 0x02; + packet->raw[1] = 0x20; // set command: read mem + memcpy(packet->raw + 2, card.uid, 8); // store uid + + for (int retry = 0; (retry < 5 && blocknum < sizeof(info_blocks)); retry++) { + + packet->raw[10] = info_blocks[blocknum]; + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)packet, sizeof(iso14b_raw_cmd_t) + packet->rawlen); + if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) { + /* + PrintAndLogEx(INFO, "%X %X %X %X %X %I64X %I64X %I64X %X %X %X %c", + resp.cmd, resp.length, resp.magic, resp.status, resp.crc, resp.oldarg[0], resp.oldarg[1], resp.oldarg[2], + resp.data.asBytes[0], resp.data.asBytes[1], resp.data.asBytes[2], resp.ng ? 't' : 'f'); + */ + if (/*resp.status != 0 ||*/ resp.length < 7) { // 14b raw command send data_len instead of status + PrintAndLogEx(FAILED, "retrying one more time"); + continue; + } + + uint8_t *recv = resp.data.asBytes; + + if (check_crc(CRC_14443_B, recv, 7) == false) { + PrintAndLogEx(FAILED, "crc fail, retrying one more time"); + continue; + } + + if (recv[0] != 2) { + PrintAndLogEx(FAILED, "Tag returned Error %x %x", recv[0], recv[1]); + break; + } + + memcpy(data + (blocknum * 4), resp.data.asBytes + 1, 4); + + retry = 0; + blocknum++; + } + } + + switch_off_field(); + free(packet); + + if (blocknum != sizeof(info_blocks)) { + PrintAndLogEx(FAILED, "Fuji/Xerox tag read failed"); + return PM3_ERFTRANS; + } + + char pn[13]; + gen_pn(data, pn); + PrintAndLogEx(SUCCESS, " PartNo : %s", pn); + PrintAndLogEx(SUCCESS, " Date : %02d.%02d.%02d", data[8], data[9], data[10]); + PrintAndLogEx(SUCCESS, " Serial : %d", (data[14] << 16) | (data[13] << 8) | data[12]); + PrintAndLogEx(SUCCESS, " Type : %s", (data[18] <= 4) ? c_type[data[18]] : "Unknown"); + + return PM3_SUCCESS; +} + +static int CmdHFXeroxDump(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf xerox dump", + "Dump all memory from a Fuji/Xerox tag", + "hf xerox dump\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_str0("f", "file", "", "filename to save dump to"), + arg_lit0("d", "decrypt", "decrypt secret blocks"), + 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); + + bool decrypt = arg_get_lit(ctx, 2); + + CLIParserFree(ctx); + + iso14b_raw_cmd_t *packet = (iso14b_raw_cmd_t *)calloc(1, sizeof(iso14b_raw_cmd_t) + 11); + if (packet == NULL) { + PrintAndLogEx(FAILED, "failed to allocate memory"); + return PM3_EMALLOC; + } + + iso14b_card_select_t card; + int status = findXerox(&card, false); // remain RF on + if (status != 0) { + switch_off_field(); + return PM3_ERFTRANS; + } + + PrintAndLogEx(INFO, "Reading memory from tag UID " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen)); + + int blocknum = 1; // block 0 all zeros + uint8_t data[256 * 4] = {0}; + + // set up the read command + packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW); + packet->rawlen = 11; + packet->raw[0] = 0x02; + memcpy(packet->raw + 2, card.uid, 8); // store uid + + PrintAndLogEx(INFO, "." NOLF); + + for (int retry = 0; (retry < 5 && blocknum < 0x100); retry++) { + + packet->raw[1] = (blocknum < 12) ? 0x30 : 0x20; // set command: read ext mem or read mem + packet->raw[10] = blocknum & 0xFF; + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)packet, sizeof(iso14b_raw_cmd_t) + packet->rawlen); + if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) { + /* + PrintAndLogEx(INFO, "%X %X %X %X %X %I64X %I64X %I64X %X %X %X %c", + resp.cmd, resp.length, resp.magic, resp.status, resp.crc, resp.oldarg[0], resp.oldarg[1], resp.oldarg[2], + resp.data.asBytes[0], resp.data.asBytes[1], resp.data.asBytes[2], resp.ng ? 't' : 'f'); + */ + if (/*resp.status != 0 ||*/ resp.length < 7) { // 14b raw command send data_len instead of status + PrintAndLogEx(FAILED, "retrying one more time"); + continue; + } + + uint8_t *recv = resp.data.asBytes; + + if (check_crc(CRC_14443_B, recv, 7) == false) { + PrintAndLogEx(FAILED, "crc fail, retrying one more time"); + continue; + } + + if (recv[0] != 2) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(FAILED, "Tag returned Error %x %x", recv[0], recv[1]); + break; + } + + memcpy(data + (blocknum * 4), resp.data.asBytes + 1, 4); + + retry = 0; + blocknum++; + + PrintAndLogEx(NORMAL, "." NOLF); + fflush(stdout); +// PrintAndLogEx(INPLACE, "blk %3d", blocknum); + } + } + + switch_off_field(); + + free(packet); + + PrintAndLogEx(NORMAL, ""); + + if (blocknum != 0x100) + PrintAndLogEx(FAILED, "dump failed at block %d", blocknum); + + if (decrypt) { + PrintAndLogEx(INFO, "Decrypting secret blocks..."); + + RC2_KEY exp_key; + uint8_t k1[8], iv[8], k2[8], decr[8]; + + k1[0] = data[8]; + k1[1] = data[5]; + k1[2] = data[6]; + k1[3] = data[7]; + k1[4] = data[0x18 * 4 + 0]; + k1[5] = data[0x18 * 4 + 1]; + k1[6] = data[0x22 * 4 + 0]; + k1[7] = 0; + + RC2_set_key(&exp_key, 8, k1, 64); + + memset(iv, 0, sizeof(iv)); + iv[0] = k1[6]; + iv[1] = k1[7]; + iv[2] = 1; + + RC2_cbc_encrypt(k1, k2, 8, &exp_key, iv, RC2_ENCRYPT); + + memcpy(k1, k2, sizeof(k1)); + + k1[2] = k2[3] ^ data[0x22 * 4 + 0]; + k1[3] = k2[4] ^ data[0x22 * 4 + 1]; // first_key[7]; + k1[5] = k2[1] ^ 0x01; // 01 = crypto method? rfid[23][2] + + RC2_set_key(&exp_key, 8, k1, 64); + + for (int n = 0; n < sizeof(var_list); n++) { + + uint8_t dadr = var_list[n]; + + if (dadr + 1 >= blocknum) { + PrintAndLogEx(INFO, "secret block %02X skipped.", dadr); + continue; + } + + memset(iv, 0, sizeof(iv)); + iv[0] = dadr; + + RC2_cbc_encrypt(&data[dadr * 4], decr, 8, &exp_key, iv, RC2_DECRYPT); + + memcpy(&data[dadr * 4], decr, 8); + + int b; + uint16_t cs, csd; + + // calc checksum + for (b = 0, cs = 0; b < sizeof(decr) - 2; b += 2) cs += decr[b] | (decr[b + 1] << 8); + cs = ~cs; + csd = (decr[7] << 8) | decr[6]; + + if (cs != csd) { + PrintAndLogEx(FAILED, "secret block %02X checksum failed.", dadr); + } + } + } + + PrintAndLogEx(INFO, "block# | data | ascii"); + PrintAndLogEx(INFO, "---------+--------------+----------"); + + for (int i = 0; i < blocknum; i++) { + PrintAndLogEx(INFO, + "%3d/0x%02X | %s | %s", + i, + i, + sprint_hex(data + (i * 4), 4), + sprint_ascii(data + (i * 4), 4) + ); + } + PrintAndLogEx(INFO, "---------+--------------+----------"); + PrintAndLogEx(NORMAL, ""); + + if (0 == filename[0]) { // generate filename from uid + /* + PrintAndLogEx(INFO, "Using UID as filename"); + + sprintf(filename, "hf-xerox-%02X%02X%02X%02X%02X%02X%02X%02X-dump%s", + card.uid[7],card.uid[6],card.uid[5],card.uid[4],card.uid[3],card.uid[2],card.uid[1],card.uid[0], + decrypt ? "-dec" : ""); + */ + char *fptr = filename; + PrintAndLogEx(INFO, "Using UID as filename"); + fptr += snprintf(fptr, sizeof(filename), "hf-xerox-"); + FillFileNameByUID(fptr, SwapEndian64(card.uid, card.uidlen, 8), decrypt ? "-dump-dec" : "-dump", card.uidlen); + } + + size_t datalen = blocknum * 4; + saveFile(filename, ".bin", data, datalen); +// saveFileEML(filename, data, datalen, 4); +// saveFileJSON(filename, jsf15, data, datalen, NULL); + return PM3_SUCCESS; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"info", CmdHFXeroxInfo, IfPm3Iso14443b, "Short info on Fuji/Xerox tag"}, + {"dump", CmdHFXeroxDump, IfPm3Iso14443b, "Read all memory pages of an Fuji/Xerox tag, save to file"}, +// {"rdbl", CmdHFXeroxRdBl, IfPm3Iso14443b, "Read Fuji/Xerox block"}, +// {"wrbl", CmdHFXeroxWrBl, IfPm3Iso14443b, "Write Fuji/Xerox block"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdHFXerox(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/src/cmdhfxerox.h b/client/src/cmdhfxerox.h new file mode 100644 index 000000000..68b9906c8 --- /dev/null +++ b/client/src/cmdhfxerox.h @@ -0,0 +1,12 @@ +//----------------------------------------------------------------------------- +// High frequency Xerox commands (ISO14443B) +//----------------------------------------------------------------------------- + +#ifndef CMDHFXEROX_H__ +#define CMDHFXEROX_H__ + +#include "common.h" + +int CmdHFXerox(const char *Cmd); + +#endif diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 4e4c3948e..c8619f164 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -425,6 +425,11 @@ const static vocabulory_t vocabulory[] = { { 0, "hf topaz sim" }, { 0, "hf topaz sniff" }, { 0, "hf topaz raw" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox dump" }, { 1, "hf waveshare help" }, { 0, "hf waveshare loadbmp" }, { 1, "hw help" }, diff --git a/doc/commands.json b/doc/commands.json index db5be2717..5fb476e59 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -1365,13 +1365,14 @@ "-s, --std activate field, use ISO14B select", "--sr activate field, use SRx ST select", "--cts activate field, use ASK C-ticket select", + "--xrx activate field, use Fuji/Xerox select", "-c, --crc calculate and append CRC", "-r do not read response from card", "-t, --timeout timeout in ms", "-v, --verbose verbose", "-d, --data data, bytes to send" ], - "usage": "hf 14b raw [-hkscrv] [--sr] [--cts] [-t ] [-d ]" + "usage": "hf 14b raw [-hkscrv] [--sr] [--cts] [--xrx] [-t ] [-d ]" }, "hf 14b rdbl": { "command": "hf 14b rdbl", @@ -2661,7 +2662,7 @@ }, "hf help": { "command": "hf help", - "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } texkom { Texkom RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags", + "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } texkom { Texkom RFIDs... } xerox { Fuji/Xerox cartridge RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags", "notes": [], "offline": true, "options": [], @@ -6518,6 +6519,41 @@ ], "usage": "hf waveshare loadbmp [-hs] -m -f " }, + "hf xerox dump": { + "command": "hf xerox dump", + "description": "Dump all memory from a Fuji/Xerox tag", + "notes": [ + "hf xerox dump" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-f, --file filename to save dump to", + "-d, --decrypt decrypt secret blocks" + ], + "usage": "hf xerox dump [-hd] [-f ]" + }, + "hf xerox help": { + "command": "hf xerox help", + "description": "help This help", + "notes": [], + "offline": true, + "options": [], + "usage": "" + }, + "hf xerox info": { + "command": "hf xerox info", + "description": "Act as a reader.", + "notes": [ + "hf xerox info" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-v, --verbose verbose output" + ], + "usage": "hf xerox info [-hv]" + }, "hints": { "command": "hints", "description": "Turn on/off hints", @@ -6549,8 +6585,8 @@ "command": "hw connect", "description": "Connects to a Proxmark3 device via specified serial port. Baudrate here is only for physical UART or UART-BT, NOT for USB-CDC or blue shark add-on", "notes": [ - "hw connect -p /dev/ttyacm0", - "hw connect -p /dev/ttyacm0 -b 115200" + "hw connect -p /dev/ttyACM0", + "hw connect -p /dev/ttyACM0 -b 115200" ], "offline": true, "options": [ @@ -11019,8 +11055,8 @@ } }, "metadata": { - "commands_extracted": 695, + "commands_extracted": 698, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-06-28T08:43:20" + "extracted_on": "2022-06-30T19:19:33" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index b9689c5c2..fe57dfbdb 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -656,6 +656,17 @@ Check column "offline" for their availability. |`hf texkom reader `|N |`Act like a Texkom reader` +### hf xerox + + { Fuji/Xerox cartridge RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf xerox help `|Y |`This help` +|`hf xerox info `|N |`Short info on Fuji/Xerox tag` +|`hf xerox dump `|N |`Read all memory pages of an Fuji/Xerox tag, save to file` + + ### hf waveshare { Waveshare NFC ePaper... } diff --git a/include/iso14b.h b/include/iso14b.h index 432baac0c..38862950b 100644 --- a/include/iso14b.h +++ b/include/iso14b.h @@ -47,6 +47,7 @@ typedef enum ISO14B_COMMAND { ISO14B_SEND_CHAINING = (1 << 9), ISO14B_SELECT_CTS = (1 << 10), ISO14B_CLEARTRACE = (1 << 11), + ISO14B_SELECT_XRX = (1 << 12), } iso14b_command_t; typedef struct { From 56525cc453fca4ec040a692147e185783601fdf4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Jun 2022 22:54:13 +0200 Subject: [PATCH 045/759] style --- armsrc/iso14443a.c | 6 +- armsrc/legicrf.c | 1 + armsrc/mifarecmd.c | 8 +- client/src/cmdlft55xx.c | 4 +- client/src/mifare/mifarehost.c | 188 ++++++++++++++++----------------- 5 files changed, 104 insertions(+), 103 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index c897aa691..6d982a3b9 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2441,8 +2441,8 @@ static void iso14a_set_ATS_times(const uint8_t *ats) { static int GetATQA(uint8_t *resp, uint8_t *resp_par, bool use_ecp, bool use_magsafe) { -#define ECP_DELAY 10 -#define ECP_RETRY_TIMEOUT 100 +#define ECP_DELAY 10 +#define ECP_RETRY_TIMEOUT 100 #define WUPA_RETRY_TIMEOUT 10 // 10ms @@ -2492,7 +2492,7 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par, bool use_ecp, bool use_mags ReaderTransmitBitsPar(wupa, 7, NULL, NULL); // Receive the ATQA len = ReaderReceive(resp, resp_par); - + first_try = false; } while (len == 0 && GetTickCountDelta(start_time) <= retry_timeout); diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 637d22fee..c6af0dace 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -79,6 +79,7 @@ static uint16_t rx_frame_from_fpga(void) { return AT91C_BASE_SSC->SSC_RHR; } } + return 0; } //----------------------------------------------------------------------------- diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 977e973ac..c7afb3a75 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1225,8 +1225,8 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, LED_C_ON(); // Main loop - get crypted nonces for target sector - for (uint8_t rtr = 0; rtr < 2; rtr++) { - + for (uint8_t rtr = 0; rtr < 2; rtr++) { + if (mifare_classic_halt(pcs, cuid)) { continue; } @@ -1253,10 +1253,10 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, if (len != 4) { continue; }; - + nt2 = bytes_to_num(receivedAnswer, 4); target_ks[0] = nt2 ^ target_nt[0]; - + // second colleciton if (mifare_classic_halt(pcs, cuid)) { diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 866702d08..00fa2b2c9 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -4169,8 +4169,8 @@ static int CmdT55xxSniff(const char *Cmd) { } // Default Write or password read ??? - // the most confusing command. - // if the token is with a password - all is OK, + // the most confusing command. + // if the token is with a password - all is OK, // if not - read command with a password will lead to write the shifted password to the memory and: // IF the most bit of the data is `1` ----> IT LEADS TO LOCK this block of the memory if (dataLen == 38) { diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 3ac048958..cfb8bca4a 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -635,104 +635,104 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl memcpy(&statelists[1].nt_enc, package->nt_b, sizeof(package->nt_b)); memcpy(&statelists[1].ks1, package->ks_b, sizeof(package->ks_b)); - // calc keys - pthread_t thread_id[2]; - - // create and run worker threads - for (uint8_t i = 0; i < 2; i++) - pthread_create(thread_id + i, NULL, nested_worker_thread, &statelists[i]); - - // wait for threads to terminate: - for (uint8_t i = 0; i < 2; i++) - pthread_join(thread_id[i], (void *)&statelists[i].head.slhead); - - // the first 16 Bits of the cryptostate already contain part of our key. - // Create the intersection of the two lists based on these 16 Bits and - // roll back the cryptostate - p1 = p3 = statelists[0].head.slhead; - p2 = p4 = statelists[1].head.slhead; - - while (p1 <= statelists[0].tail.sltail && p2 <= statelists[1].tail.sltail) { - if (Compare16Bits(p1, p2) == 0) { - - struct Crypto1State savestate; - savestate = *p1; - while (Compare16Bits(p1, &savestate) == 0 && p1 <= statelists[0].tail.sltail) { - *p3 = *p1; - lfsr_rollback_word(p3, statelists[0].nt_enc ^ statelists[0].uid, 0); - p3++; - p1++; - } - savestate = *p2; - while (Compare16Bits(p2, &savestate) == 0 && p2 <= statelists[1].tail.sltail) { - *p4 = *p2; - lfsr_rollback_word(p4, statelists[1].nt_enc ^ statelists[1].uid, 0); - p4++; - p2++; - } - } else { - while (Compare16Bits(p1, p2) == -1) p1++; - while (Compare16Bits(p1, p2) == 1) p2++; - } - } - - p3->odd = -1; - p3->even = -1; - p4->odd = -1; - p4->even = -1; - statelists[0].len = p3 - statelists[0].head.slhead; - statelists[1].len = p4 - statelists[1].head.slhead; - statelists[0].tail.sltail = --p3; - statelists[1].tail.sltail = --p4; - - // the statelists now contain possible keys. The key we are searching for must be in the - // intersection of both lists - qsort(statelists[0].head.keyhead, statelists[0].len, sizeof(uint64_t), compare_uint64); - qsort(statelists[1].head.keyhead, statelists[1].len, sizeof(uint64_t), compare_uint64); - // Create the intersection - statelists[0].len = intersection(statelists[0].head.keyhead, statelists[1].head.keyhead); - - -/* - - memcpy(&uid, package->cuid, sizeof(package->cuid)); - - statelists[0].blockNo = package->block; - statelists[0].keyType = package->keytype; - statelists[0].uid = uid; - - memcpy(&statelists[0].nt_enc, package->nt, sizeof(package->nt)); - memcpy(&statelists[0].ks1, package->ks, sizeof(package->ks)); - // calc keys - pthread_t t; + pthread_t thread_id[2]; - // create and run worker thread - pthread_create(&t, NULL, nested_worker_thread, &statelists[0]); + // create and run worker threads + for (uint8_t i = 0; i < 2; i++) + pthread_create(thread_id + i, NULL, nested_worker_thread, &statelists[i]); - // wait for thread to terminate: - pthread_join(t, (void *)&statelists[0].head.slhead); + // wait for threads to terminate: + for (uint8_t i = 0; i < 2; i++) + pthread_join(thread_id[i], (void *)&statelists[i].head.slhead); // the first 16 Bits of the cryptostate already contain part of our key. + // Create the intersection of the two lists based on these 16 Bits and + // roll back the cryptostate p1 = p3 = statelists[0].head.slhead; + p2 = p4 = statelists[1].head.slhead; - // create key candidates. - while (p1 <= statelists[0].tail.sltail) { - struct Crypto1State savestate; - savestate = *p1; - while (Compare16Bits(p1, &savestate) == 0 && p1 <= statelists[0].tail.sltail) { - *p3 = *p1; - lfsr_rollback_word(p3, statelists[0].nt_enc ^ statelists[0].uid, 0); - p3++; - p1++; + while (p1 <= statelists[0].tail.sltail && p2 <= statelists[1].tail.sltail) { + if (Compare16Bits(p1, p2) == 0) { + + struct Crypto1State savestate; + savestate = *p1; + while (Compare16Bits(p1, &savestate) == 0 && p1 <= statelists[0].tail.sltail) { + *p3 = *p1; + lfsr_rollback_word(p3, statelists[0].nt_enc ^ statelists[0].uid, 0); + p3++; + p1++; + } + savestate = *p2; + while (Compare16Bits(p2, &savestate) == 0 && p2 <= statelists[1].tail.sltail) { + *p4 = *p2; + lfsr_rollback_word(p4, statelists[1].nt_enc ^ statelists[1].uid, 0); + p4++; + p2++; + } + } else { + while (Compare16Bits(p1, p2) == -1) p1++; + while (Compare16Bits(p1, p2) == 1) p2++; } } p3->odd = -1; p3->even = -1; + p4->odd = -1; + p4->even = -1; statelists[0].len = p3 - statelists[0].head.slhead; + statelists[1].len = p4 - statelists[1].head.slhead; statelists[0].tail.sltail = --p3; -*/ + statelists[1].tail.sltail = --p4; + + // the statelists now contain possible keys. The key we are searching for must be in the + // intersection of both lists + qsort(statelists[0].head.keyhead, statelists[0].len, sizeof(uint64_t), compare_uint64); + qsort(statelists[1].head.keyhead, statelists[1].len, sizeof(uint64_t), compare_uint64); + // Create the intersection + statelists[0].len = intersection(statelists[0].head.keyhead, statelists[1].head.keyhead); + + + /* + + memcpy(&uid, package->cuid, sizeof(package->cuid)); + + statelists[0].blockNo = package->block; + statelists[0].keyType = package->keytype; + statelists[0].uid = uid; + + memcpy(&statelists[0].nt_enc, package->nt, sizeof(package->nt)); + memcpy(&statelists[0].ks1, package->ks, sizeof(package->ks)); + + // calc keys + pthread_t t; + + // create and run worker thread + pthread_create(&t, NULL, nested_worker_thread, &statelists[0]); + + // wait for thread to terminate: + pthread_join(t, (void *)&statelists[0].head.slhead); + + // the first 16 Bits of the cryptostate already contain part of our key. + p1 = p3 = statelists[0].head.slhead; + + // create key candidates. + while (p1 <= statelists[0].tail.sltail) { + struct Crypto1State savestate; + savestate = *p1; + while (Compare16Bits(p1, &savestate) == 0 && p1 <= statelists[0].tail.sltail) { + *p3 = *p1; + lfsr_rollback_word(p3, statelists[0].nt_enc ^ statelists[0].uid, 0); + p3++; + p1++; + } + } + + p3->odd = -1; + p3->even = -1; + statelists[0].len = p3 - statelists[0].head.slhead; + statelists[0].tail.sltail = --p3; + */ uint32_t keycnt = statelists[0].len; if (keycnt == 0) goto out; @@ -753,16 +753,16 @@ int mfStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBl // used for mfCheckKeys_file, which needs a header mem = calloc((maxkeysinblock * 6) + 5, sizeof(uint8_t)); - if (mem == NULL) { - free(statelists[0].head.slhead); - return PM3_EMALLOC; - } + if (mem == NULL) { + free(statelists[0].head.slhead); + return PM3_EMALLOC; + } - mem[0] = statelists[0].keyType; - mem[1] = statelists[0].blockNo; - mem[2] = 1; - mem[3] = ((max_keys_chunk >> 8) & 0xFF); - mem[4] = (max_keys_chunk & 0xFF); + mem[0] = statelists[0].keyType; + mem[1] = statelists[0].blockNo; + mem[2] = 1; + mem[3] = ((max_keys_chunk >> 8) & 0xFF); + mem[4] = (max_keys_chunk & 0xFF); p_keyblock = mem + 5; } else { @@ -854,7 +854,7 @@ out: ); free(statelists[0].head.slhead); - free(statelists[1].head.slhead); + free(statelists[1].head.slhead); return PM3_ESOFT; } From cc933541486a36baac503d1aff587f56aa552a63 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Jun 2022 23:28:09 +0200 Subject: [PATCH 046/759] fix coverity and style --- client/src/cmdhfxerox.c | 176 ++++++++++++++++++++++------------------ 1 file changed, 95 insertions(+), 81 deletions(-) diff --git a/client/src/cmdhfxerox.c b/client/src/cmdhfxerox.c index 0041de368..1d3e91210 100644 --- a/client/src/cmdhfxerox.c +++ b/client/src/cmdhfxerox.c @@ -15,60 +15,60 @@ #define TIMEOUT 2000 -#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<<24L) +#define c2l(c,l) (l = ((unsigned long)(*((c)++))), \ + l |= ((unsigned long)(*((c)++))) << 8L, \ + l |= ((unsigned long)(*((c)++))) << 16L, \ + l |= ((unsigned long)(*((c)++))) << 24L) /* NOTE - c is not incremented as per c2l */ #define c2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ + c += n; \ + l1 = l2 = 0; \ switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ - case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ - case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ - case 5: l2|=((unsigned long)(*(--(c)))); \ - case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ - case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ - case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ - case 1: l1|=((unsigned long)(*(--(c)))); \ + case 8: l2 = ((unsigned long)(*(--(c)))) << 24L; \ + case 7: l2 |= ((unsigned long)(*(--(c)))) << 16L; \ + case 6: l2 |= ((unsigned long)(*(--(c)))) << 8L; \ + case 5: l2 |= ((unsigned long)(*(--(c)))); \ + case 4: l1 = ((unsigned long)(*(--(c)))) << 24L; \ + case 3: l1 |= ((unsigned long)(*(--(c)))) << 16L; \ + case 2: l1 |= ((unsigned long)(*(--(c)))) << 8L; \ + case 1: l1 |= ((unsigned long)(*(--(c)))); \ } \ } -#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24L)&0xff)) +#define l2c(l,c) (*((c)++) = (uint8_t)(((l)) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 8L) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 16L) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 24L) & 0xff)) /* NOTE - c is not incremented as per l2c */ #define l2cn(l1,l2,c,n) { \ - c+=n; \ + c += n; \ switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 8: *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \ + case 7: *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \ + case 6: *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \ + case 5: *(--(c)) = (uint8_t)(((l2)) & 0xff); \ + case 4: *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \ + case 3: *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \ + case 2: *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \ + case 1: *(--(c)) = (uint8_t)(((l1)) & 0xff); \ } \ } /* NOTE - c is not incremented as per n2l */ #define n2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ + c += n; \ + l1 = l2 = 0; \ switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c)))) ; \ - case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ - case 6: l2|=((unsigned long)(*(--(c))))<<16; \ - case 5: l2|=((unsigned long)(*(--(c))))<<24; \ - case 4: l1 =((unsigned long)(*(--(c)))) ; \ - case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ - case 2: l1|=((unsigned long)(*(--(c))))<<16; \ - case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + case 8: l2 = ((unsigned long)(*(--(c)))); \ + case 7: l2 |= ((unsigned long)(*(--(c)))) << 8; \ + case 6: l2 |= ((unsigned long)(*(--(c)))) << 16; \ + case 5: l2 |= ((unsigned long)(*(--(c)))) << 24; \ + case 4: l1 = ((unsigned long)(*(--(c)))); \ + case 3: l1 |= ((unsigned long)(*(--(c)))) << 8; \ + case 2: l1 |= ((unsigned long)(*(--(c)))) << 16; \ + case 1: l1 |= ((unsigned long)(*(--(c)))) << 24; \ } \ } @@ -76,36 +76,36 @@ #define l2nn(l1,l2,c,n) { \ c+=n; \ switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + case 8: *(--(c)) = (uint8_t)(((l2)) & 0xff); \ + case 7: *(--(c)) = (uint8_t)(((l2) >> 8) & 0xff); \ + case 6: *(--(c)) = (uint8_t)(((l2) >> 16) & 0xff); \ + case 5: *(--(c)) = (uint8_t)(((l2) >> 24) & 0xff); \ + case 4: *(--(c)) = (uint8_t)(((l1)) & 0xff); \ + case 3: *(--(c)) = (uint8_t)(((l1) >> 8) & 0xff); \ + case 2: *(--(c)) = (uint8_t)(((l1) >> 16) & 0xff); \ + case 1: *(--(c)) = (uint8_t)(((l1) >> 24) & 0xff); \ } \ } -#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))) +#define n2l(c,l) (l = ((unsigned long)(*((c)++))) << 24L, \ + l |= ((unsigned long)(*((c)++))) << 16L, \ + l |= ((unsigned long)(*((c)++))) << 8L, \ + l |= ((unsigned long)(*((c)++)))) -#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) +#define l2n(l,c) (*((c)++) = (uint8_t)(((l) >> 24L) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 16L) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 8L) & 0xff), \ + *((c)++) = (uint8_t)(((l)) & 0xff)) #define C_RC2(n) \ - t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \ - x0=(t<<1)|(t>>15); \ - t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \ - x1=(t<<2)|(t>>14); \ - t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \ - x2=(t<<3)|(t>>13); \ - t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \ - x3=(t<<5)|(t>>11); + t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; \ + x0 = (t << 1) | (t >> 15); \ + t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; \ + x1 = (t << 2) | (t >> 14); \ + t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; \ + x2 = (t << 3) | (t >> 13); \ + t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; \ + x3 = (t << 5) | (t >> 11); #define RC2_ENCRYPT 1 #define RC2_DECRYPT 0 @@ -116,7 +116,7 @@ typedef struct rc2_key_st { RC2_INT data[64]; } RC2_KEY; -static const unsigned char key_table[256] = { +static const uint8_t lut[256] = { 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5, @@ -141,7 +141,7 @@ static const unsigned char key_table[256] = { 0xfe, 0x7f, 0xc1, 0xad, }; -static const unsigned char var_list[] = {0x1c, 0x1e, 0x20, 0x26, 0x28, 0x2a, 0x2c, 0x2e}; +static const uint8_t var_list[] = {0x1c, 0x1e, 0x20, 0x26, 0x28, 0x2a, 0x2c, 0x2e}; static int CmdHelp(const char *Cmd); @@ -162,8 +162,10 @@ void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) { if (len > 128) len = 128; + if (bits <= 0) bits = 1024; + if (bits > 1024) bits = 1024; @@ -174,7 +176,7 @@ void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) { d = k[len - 1]; j = 0; for (i = len; i < 128; i++, j++) { - d = key_table[(k[j] + d) & 0xff]; + d = lut[(k[j] + d) & 0xff]; k[i] = d; } @@ -184,10 +186,10 @@ void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) { i = 128 - j; c = (0xff >> (-bits & 0x07)); - d = key_table[k[i] & c]; + d = lut[k[i] & c]; k[i] = d; while (i--) { - d = key_table[k[i + j] ^ d]; + d = lut[k[i + j] ^ d]; k[i] = d; } @@ -268,7 +270,9 @@ void RC2_decrypt(unsigned long *d, RC2_KEY *key) { x0 = (t - (x1 & ~x3) - (x2 & x3) - * (p0--)) & 0xffff; if (--i == 0) { - if (--n == 0) break; + if (--n == 0) + break; + i = (n == 2) ? 6 : 5; x3 = (x3 - p1[x2 & 0x3f]) & 0xffff; @@ -290,9 +294,11 @@ void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, unsigned long tin[2]; if (encrypt) { + c2l(iv, tout0); c2l(iv, tout1); iv -= 8; + for (l -= 8; l >= 0; l -= 8) { c2l(in, tin0); c2l(in, tin1); @@ -306,6 +312,7 @@ void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, tout1 = tin[1]; l2c(tout1, out); } + if (l != -8) { c2ln(in, tin0, tin1, l + 8); tin0 ^= tout0; @@ -318,12 +325,16 @@ void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, tout1 = tin[1]; l2c(tout1, out); } + l2c(tout0, iv); l2c(tout1, iv); + } else { + c2l(iv, xor0); c2l(iv, xor1); iv -= 8; + for (l -= 8; l >= 0; l -= 8) { c2l(in, tin0); tin[0] = tin0; @@ -337,6 +348,7 @@ void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, xor0 = tin0; xor1 = tin1; } + if (l != -8) { c2l(in, tin0); tin[0] = tin0; @@ -349,6 +361,7 @@ void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, xor0 = tin0; xor1 = tin1; } + l2c(xor0, iv); l2c(xor1, iv); } @@ -371,7 +384,7 @@ static int switch_off_field(void) { static int findXerox(iso14b_card_select_t *card, bool disconnect) { if (card == NULL) - return false; + return PM3_EINVARG; int8_t retry = 3; while (retry--) { @@ -385,11 +398,7 @@ static int findXerox(iso14b_card_select_t *card, bool disconnect) { SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)&packet, sizeof(iso14b_raw_cmd_t)); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) { - /* - PrintAndLogEx(INFO, "%X %X %X %X %X %I64X %I64X %I64X %X %X %X %c", - resp.cmd, resp.length, resp.magic, resp.status, resp.crc, resp.oldarg[0], resp.oldarg[1], resp.oldarg[2], - resp.data.asBytes[0], resp.data.asBytes[1], resp.data.asBytes[2], resp.ng ? 't' : 'f'); - */ + if (resp.oldarg[0] == 0) { memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t)); } @@ -399,13 +408,15 @@ static int findXerox(iso14b_card_select_t *card, bool disconnect) { // switch_off_field(); PrintAndLogEx(FAILED, "command execution timeout"); - return -1; + return PM3_ESOFT; } -static uint8_t info_blocks[] = {0x15, 0x16, 0x17, 0x18, 0x22}; -static const char *c_type[] = {"drum", "yellow", "magenta", "cyan", "black"}; +static uint8_t info_blocks[] = { 0x15, 0x16, 0x17, 0x18, 0x22 }; +static const char *c_type[] = { "drum", "yellow", "magenta", "cyan", "black" }; -static inline char dec_digit(uint8_t dig) { return (dig <= 9) ? dig + '0' : '?'; } +static inline char dec_digit(uint8_t dig) { + return (dig <= 9) ? dig + '0' : '?'; +} static void gen_pn(uint8_t *data, char *pn) { pn[0] = dec_digit(data[0] >> 4); @@ -443,9 +454,11 @@ static int CmdHFXeroxInfo(const char *Cmd) { iso14b_card_select_t card; int status = findXerox(&card, false); - if (status != 0) { + if (status != PM3_SUCCESS) { switch_off_field(); - if (verbose) PrintAndLogEx(FAILED, "Fuji/Xerox tag select failed"); + if (verbose) { + PrintAndLogEx(FAILED, "Fuji/Xerox tag select failed"); + } return PM3_ERFTRANS; } @@ -555,7 +568,8 @@ static int CmdHFXeroxDump(const char *Cmd) { iso14b_card_select_t card; int status = findXerox(&card, false); // remain RF on - if (status != 0) { + if (status != PM3_SUCCESS) { + free(packet); switch_off_field(); return PM3_ERFTRANS; } @@ -718,7 +732,7 @@ static int CmdHFXeroxDump(const char *Cmd) { size_t datalen = blocknum * 4; saveFile(filename, ".bin", data, datalen); -// saveFileEML(filename, data, datalen, 4); + saveFileEML(filename, data, datalen, 4); // saveFileJSON(filename, jsf15, data, datalen, NULL); return PM3_SUCCESS; } From 9ecbe2da41ca50b68d2e7fbb6ee5c47a5e489dfb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Jun 2022 23:28:29 +0200 Subject: [PATCH 047/759] fix coverity div by zero --- client/src/cmdhftexkom.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index d810c2f16..615f0c0df 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -31,7 +31,7 @@ #define TEXKOM_NOISE_THRESHOLD (10) -inline uint32_t GetGraphBuffer(uint32_t indx) { +static inline uint32_t GetGraphBuffer(uint32_t indx) { if (g_GraphBuffer[indx] < -128) return 0; else @@ -154,8 +154,11 @@ static bool TexkomCalculateBitLengths(uint32_t *data, uint32_t len, uint32_t *hi } } - *hi = sumhi / lenhi; - *low = sumlow / lenlow; + if (lenhi) + *hi = sumhi / lenhi; + + if (lenlow) + *low = sumlow / lenlow; if (lmax != NULL) *lmax = dmax; @@ -165,7 +168,7 @@ static bool TexkomCalculateBitLengths(uint32_t *data, uint32_t len, uint32_t *hi return (*hi != 0) && (*low != 0) && (*hi > *low); } -inline bool TexcomCalculateBit(uint32_t data, uint32_t bitlen, uint32_t threshold) { +static inline bool TexcomCalculateBit(uint32_t data, uint32_t bitlen, uint32_t threshold) { return (data < (bitlen + threshold)) && (data > (bitlen - threshold)); From 45ea60c92bf5fce038bb2440a17e2fffa2139e14 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Jun 2022 23:38:40 +0200 Subject: [PATCH 048/759] add to cmake --- client/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 750c83c6b..3d535f8ea 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -296,6 +296,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdhftopaz.c ${PM3_ROOT}/client/src/cmdhftexkom.c ${PM3_ROOT}/client/src/cmdhfwaveshare.c + ${PM3_ROOT}/client/src/cmdhfxerox.c ${PM3_ROOT}/client/src/cmdhw.c ${PM3_ROOT}/client/src/cmdlf.c ${PM3_ROOT}/client/src/cmdlfawid.c From 1e91895b901252f651003872852b8a830a5d82d4 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 2 Jul 2022 22:45:32 +0300 Subject: [PATCH 049/759] simulate sketch --- armsrc/appmain.c | 7 ++++++ armsrc/hfops.c | 52 ++++++++++++++++++++++++++++++++++++++++ armsrc/hfops.h | 1 + client/src/cmdhftexkom.c | 47 +++++++++++++++++++++++++++++++++++- include/pm3_cmd.h | 1 + 5 files changed, 107 insertions(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 5254368ae..5e84aec4e 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1392,6 +1392,13 @@ static void PacketReceived(PacketCommandNG *packet) { HfReadADC(samplesCount, true); break; } + case CMD_HF_TEXKOM_SIMULATE: { + uint32_t timeout = 0; + memcpy(&timeout, &packet->data.asBytes[9], 4); + HfWriteTkm(packet->data.asBytes, packet->data.asBytes[8], timeout); + break; + } + #endif #ifdef WITH_ISO14443a diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 3bf060c56..de7f5ba03 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -19,6 +19,7 @@ #include "hfops.h" #include +#include "appmain.h" #include "proxmark3_arm.h" #include "cmd.h" #include "BigBuf.h" @@ -90,4 +91,55 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { return 0; } +static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation) { + return 0; +} + +int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { + // free eventually allocated BigBuf memory + BigBuf_free_keep_EM(); + + LEDsoff(); + + uint32_t elen = HfEncodeTkm(uid, modulation); + if (elen == 0) { + DbpString("encode error"); + reply_ng(CMD_HF_TEXKOM_SIMULATE, PM3_EAPDU_ENCODEFAIL, NULL, 0); + return PM3_EAPDU_ENCODEFAIL; + } + + LED_C_ON(); + + int vHf = 0; // in mV + bool button_pressed = false; + bool exit_loop = false; + while (exit_loop == false) { + + button_pressed = BUTTON_PRESS(); + if (button_pressed || data_available()) + break; + + WDT_HIT(); + + vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; + if (vHf > MF_MINFIELDV) { + LED_A_ON(); + } else { + LED_A_OFF(); + continue; + } + + + // TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow); + } + + switch_off(); + + if (button_pressed) + DbpString("button pressed"); + + reply_ng(CMD_HF_TEXKOM_SIMULATE, PM3_SUCCESS, NULL, 0); + + return PM3_SUCCESS; +} diff --git a/armsrc/hfops.h b/armsrc/hfops.h index 489c99bc6..f1d705913 100644 --- a/armsrc/hfops.h +++ b/armsrc/hfops.h @@ -22,5 +22,6 @@ #include "common.h" int HfReadADC(uint32_t samplesCount, bool ledcontrol); +int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout); #endif \ No newline at end of file diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 615f0c0df..534177669 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -550,12 +550,57 @@ static int CmdHFTexkomReader(const char *Cmd) { } +static int CmdHFTexkomSim(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf texkom sim", + "Simulate a texkom tag", + "hf texkom sim"); + + void *argtable[] = { + arg_param_begin, + arg_lit0("v", "verbose", "Verbose work"), + arg_lit0("t", "tk17", "Use TK-17 modulation (TK-13 by default)"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + bool verbose = arg_get_lit(ctx, 1); + uint32_t cmdtimeout = 0; + uint8_t modulation = 0; // tk-13 + if (arg_get_lit(ctx, 2)) + modulation = 1; //tk-17 + + CLIParserFree(ctx); + + // + uint8_t data[13] = {0}; + data[8] = modulation; + memcpy(&data[9], &cmdtimeout, 4); + clearCommandBuffer(); + SendCommandNG(CMD_HF_TEXKOM_SIMULATE, data, sizeof(data)); + + if (cmdtimeout > 0 && cmdtimeout < 2800) { + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_TEXKOM_SIMULATE, &resp, 3000)) { + if (verbose) + PrintAndLogEx(WARNING, "(hf texkom simulate) command execution time out"); + return PM3_ETIMEOUT; + } + PrintAndLogEx(INFO, "simulate command execution done"); + } else { + PrintAndLogEx(INFO, "simulate command started"); + } + + return PM3_SUCCESS; +} + + static int CmdHelp(const char *Cmd); static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"reader", CmdHFTexkomReader, IfPm3Iso14443a, "Act like a Texkom reader"}, - //{"sim", CmdHFTexkomSim, IfPm3Iso14443a, "Simulate a Texkom tag"}, + {"sim", CmdHFTexkomSim, IfPm3Iso14443a, "Simulate a Texkom tag"}, //{"write", CmdHFTexkomWrite, IfPm3Iso14443a, "Write a Texkom tag"}, {NULL, NULL, 0, NULL} }; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index e53132309..69d9fed5b 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -522,6 +522,7 @@ typedef struct { #define CMD_HF_ISO15693_CSETUID 0x0316 #define CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY 0x0317 #define CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI 0x0318 +#define CMD_HF_TEXKOM_SIMULATE 0x0320 #define CMD_LF_SNIFF_RAW_ADC 0x0360 From 3aeb745f0aab199840a6374026b333b07f16cea7 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 3 Jul 2022 00:09:55 +0300 Subject: [PATCH 050/759] encode sketch --- armsrc/hfops.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index de7f5ba03..843686984 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -92,8 +92,29 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { } static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation) { + uint32_t len = 0; + if (modulation == 0) { + // TK-13 + // 74ns 1 field cycle, + // 100 field cycle = impulse (13 bytes) + // 1000 field cycle = `1` (125 bytes) + // 500 field cycle = `0` (63 bytes) + // `1` - 125, 63 + // `0` - 63, 125 - return 0; + len = 2; + } else { + // TK-17 + // 74ns 1 field cycle, + // `00` - + // `01` - + // `10` - + // `11` - + + + } + + return len; } int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { @@ -110,6 +131,9 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { } LED_C_ON(); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K); int vHf = 0; // in mV bool button_pressed = false; @@ -130,8 +154,27 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { continue; } + SpinDelay(10); + for (int j = 0; j < 13;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0xff; + j++; + } + } + for (int j = 0; j < 125;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x00; + j++; + } + } + for (int j = 0; j < 13;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0xff; + j++; + } + } - // TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow); + SpinDelay(100); } switch_off(); From 6a28ca39f6eeea03d85e3e9c146be3f1f0d48129 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 3 Jul 2022 00:20:56 +0300 Subject: [PATCH 051/759] tk13 transmit sketch --- armsrc/hfops.c | 46 +++++++++++++++++++++++++--------------- client/src/cmdhftexkom.c | 9 ++++++++ 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 843686984..91e426c8d 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -91,7 +91,7 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { return 0; } -static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation) { +static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation, uint8_t *data) { uint32_t len = 0; if (modulation == 0) { // TK-13 @@ -102,6 +102,21 @@ static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation) { // `1` - 125, 63 // `0` - 63, 125 + int indx = 0; + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j++) { + if (((uid[i] << j) & 0x80) != 0) { + // `1` + data[indx++] = 125; + data[indx++] = 63; + } else { + // `0` + data[indx++] = 63; + data[indx++] = 125; + } + } + } + len = 2; } else { // TK-17 @@ -123,7 +138,8 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { LEDsoff(); - uint32_t elen = HfEncodeTkm(uid, modulation); + uint8_t* data = BigBuf_calloc(256); + uint32_t elen = HfEncodeTkm(uid, modulation, data); if (elen == 0) { DbpString("encode error"); reply_ng(CMD_HF_TEXKOM_SIMULATE, PM3_EAPDU_ENCODEFAIL, NULL, 0); @@ -155,22 +171,18 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { } SpinDelay(10); - for (int j = 0; j < 13;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0xff; - j++; + for (int i = 0; i < elen; i++) { + for (int j = 0; j < 13;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0xff; + j++; + } } - } - for (int j = 0; j < 125;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x00; - j++; - } - } - for (int j = 0; j < 13;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0xff; - j++; + for (int j = 0; j < data[i];) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x00; + j++; + } } } diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 534177669..a54342980 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -574,6 +574,15 @@ static int CmdHFTexkomSim(const char *Cmd) { // uint8_t data[13] = {0}; + data[0] = 0xFF; + data[1] = 0xFF; + data[2] = 0x63; + data[3] = 0x8C; + data[4] = 0x7D; + data[5] = 0xC4; + data[6] = 0x55; + data[7] = 0x53; + data[8] = modulation; memcpy(&data[9], &cmdtimeout, 4); clearCommandBuffer(); From e4df73738f88b2e22b8a67f55339a6aba255661a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 3 Jul 2022 18:19:57 +0300 Subject: [PATCH 052/759] transmit ok, timing not ok --- armsrc/hfops.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 91e426c8d..976cd7d64 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -117,7 +117,7 @@ static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation, uint8_t *data) { } } - len = 2; + len = indx; } else { // TK-17 // 74ns 1 field cycle, @@ -150,6 +150,7 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { FpgaDownloadAndGo(FPGA_BITSTREAM_HF); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K); + FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR); int vHf = 0; // in mV bool button_pressed = false; @@ -172,6 +173,9 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { SpinDelay(10); for (int i = 0; i < elen; i++) { + if (data[i] == 0) + data[i] = 10; + for (int j = 0; j < 13;) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { AT91C_BASE_SSC->SSC_THR = 0xff; From 7b732e152e5214c333fb8c9576f8390d61bcdca3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 3 Jul 2022 20:06:11 +0200 Subject: [PATCH 053/759] added `hf 14b view` and modified dump command to be prepared to handle the different tags --- client/src/cmdhf14b.c | 435 +++++++++++++++++++++++++++--------------- include/iso14b.h | 7 + 2 files changed, 291 insertions(+), 151 deletions(-) diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 5a1193cd0..575bf21e5 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -42,6 +42,9 @@ // client side time out, waiting for device to ask tag a APDU to answer #define APDU_TIMEOUT 2000 +// for static arrays +#define ST25TB_SR_BLOCK_SIZE 4 + // iso14b apdu input frame length static uint16_t apdu_frame_length = 0; //static uint16_t ats_fsc[] = {16, 24, 32, 40, 48, 64, 96, 128, 256}; @@ -415,10 +418,14 @@ static int CmdHF14BCmdRaw(const char *Cmd) { return PM3_SUCCESS; } -static bool get_14b_UID(iso14b_card_select_t *card) { +static bool get_14b_UID(uint8_t *d, iso14b_type_t *found_type) { - if (card == NULL) + // sanity checks + if (d == NULL || found_type == NULL) { return false; + } + + *found_type = ISO14B_NONE; iso14b_raw_cmd_t packet = { .flags = (ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT), @@ -429,11 +436,11 @@ static bool get_14b_UID(iso14b_card_select_t *card) { PacketResponseNG resp; clearCommandBuffer(); SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)&packet, sizeof(iso14b_raw_cmd_t)); - if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) { if (resp.oldarg[0] == 0) { - memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t)); + memcpy(d, resp.data.asBytes, sizeof(iso14b_card_select_t)); + *found_type = ISO14B_SELECT_SR; return true; } } @@ -445,7 +452,21 @@ static bool get_14b_UID(iso14b_card_select_t *card) { if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) { if (resp.oldarg[0] == 0) { - memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t)); + memcpy(d, resp.data.asBytes, sizeof(iso14b_card_select_t)); + *found_type = ISO14B_STANDARD; + return true; + } + } + + // test CT + packet.flags = (ISO14B_CONNECT | ISO14B_SELECT_CTS | ISO14B_DISCONNECT); + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)&packet, sizeof(iso14b_raw_cmd_t)); + if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) { + + if (resp.oldarg[0] == 0) { + memcpy(d, resp.data.asBytes, sizeof(iso14b_cts_card_select_t)); + *found_type = ISO14B_CT; return true; } } @@ -726,7 +747,7 @@ static void print_ct_general_info(void *vcard) { iso14b_cts_card_select_t card; memcpy(&card, (iso14b_cts_card_select_t *)vcard, sizeof(iso14b_cts_card_select_t)); - uint32_t uid32 = (card.uid[0] | card.uid[1] << 8 | card.uid[2] << 16 | card.uid[3] << 24); + uint32_t uid32 = MemLeToUint4byte(card.uid); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "ASK C-Ticket"); PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s") " ( " _YELLOW_("%010u") " )", sprint_hex(card.uid, sizeof(card.uid)), uid32); @@ -735,6 +756,71 @@ static void print_ct_general_info(void *vcard) { PrintAndLogEx(NORMAL, ""); } +static void print_hdr(void) { + PrintAndLogEx(INFO, " block# | data |lck| ascii"); + PrintAndLogEx(INFO, "---------+--------------+---+----------"); +} + +static void print_footer(void) { + PrintAndLogEx(INFO, "---------+--------------+---+----------"); + PrintAndLogEx(NORMAL, ""); +} + +/* +static void print_ct_blocks(uint8_t *data, size_t len) { + + size_t blocks = len / ST25TB_SR_BLOCK_SIZE; + + print_hdr(); + + for (int i = 0; i <= blocks; i++) { + PrintAndLogEx(INFO, + "%3d/0x%02X | %s | %s | %s", + i, + i, + sprint_hex(data + (i * 4), 4), + " ", + sprint_ascii(data + (i * 4), 4) + ); + } + print_footer(); +} +*/ + +static void print_sr_blocks(uint8_t *data, size_t len) { + + size_t blocks = len / ST25TB_SR_BLOCK_SIZE; + uint8_t chipid = get_st_chipid(data); + PrintAndLogEx(SUCCESS, _GREEN_("%s") " tag", get_st_chip_model(chipid)); + + PrintAndLogEx(DEBUG, "systemblock : %s", sprint_hex(data + (blocks * 4), 4)); + PrintAndLogEx(DEBUG, " otp lock : %02x %02x", data[(blocks * 4)], data[(blocks * 4) + 1]); + + print_hdr(); + + for (int i = 0; i <= blocks; i++) { + PrintAndLogEx(INFO, + "%3d/0x%02X | %s | %s | %s", + i, + i, + sprint_hex(data + (i * 4), 4), + get_st_lock_info(chipid, data + (blocks * 4), i), + sprint_ascii(data + (i * 4), 4) + ); + } + + PrintAndLogEx(INFO, + "%3d/0x%02X | %s | %s | %s", + 0xFF, + 0xFF, + sprint_hex(data + (0xFF * 4), 4), + get_st_lock_info(chipid, data + (blocks * 4), 0xFF), + sprint_ascii(data + (0xFF * 4), 4) + ); + + print_footer(); +} + // iceman, calypso? // 05 00 00 = find one tag in field // 1d xx xx xx xx 00 08 01 00 = attrib xx=UID (resp 10 [f9 e0]) @@ -1280,166 +1366,164 @@ static int CmdHF14BDump(const char *Cmd) { CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParserFree(ctx); - iso14b_card_select_t card; - if (get_14b_UID(&card) == false) { + + uint8_t select[sizeof(iso14b_card_select_t)] = {0}; + iso14b_type_t select_cardtype = ISO14B_NONE; + if (get_14b_UID(select, &select_cardtype) == false) { PrintAndLogEx(WARNING, "no tag found"); return PM3_SUCCESS; } - if (card.uidlen != 8) { - PrintAndLogEx(FAILED, "current dump command only work with SRI4K / SRI512 tags"); - return PM3_SUCCESS; - } + if (select_cardtype == ISO14B_CT) { + iso14b_cts_card_select_t ct_card; + memcpy(&ct_card, (iso14b_cts_card_select_t *)&select, sizeof(iso14b_cts_card_select_t)); - // detect cardsize - // 1 = 4096 - // 2 = 512 - uint8_t cardtype = get_st_cardsize(card.uid); - uint8_t blocks = 0; - uint16_t cardsize = 0; + uint32_t uid32 = MemLeToUint4byte(ct_card.uid); + PrintAndLogEx(SUCCESS, "UID: " _GREEN_("%s") " ( " _YELLOW_("%010u") " )", sprint_hex(ct_card.uid, 4), uid32); - switch (cardtype) { - case 2: - cardsize = (512 / 8) + 4; - blocks = 0x0F; - break; - case 1: - default: - cardsize = (4096 / 8) + 4; - blocks = 0x7F; - break; - } + // Have to figure out how large one of these are.. + PrintAndLogEx(FAILED, "Dumping CT tags is not implemented yet."); - uint8_t chipid = get_st_chipid(card.uid); - PrintAndLogEx(SUCCESS, "found a " _GREEN_("%s") " tag", get_st_chip_model(chipid)); - - // detect blocksize from card :) - PrintAndLogEx(INFO, "reading tag memory from UID " _GREEN_("%s"), sprint_hex_inrow(SwapEndian64(card.uid, card.uidlen, 8), card.uidlen)); - - iso14b_raw_cmd_t *packet = (iso14b_raw_cmd_t *)calloc(1, sizeof(iso14b_raw_cmd_t) + 2); - if (packet == NULL) { - PrintAndLogEx(FAILED, "failed to allocate memory"); - return PM3_EMALLOC; - } - packet->flags = (ISO14B_CONNECT | ISO14B_SELECT_SR); - packet->timeout = 0; - packet->rawlen = 0; - - clearCommandBuffer(); - SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)packet, sizeof(iso14b_raw_cmd_t)); - PacketResponseNG resp; - - // select - int status; - if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) { - status = resp.oldarg[0]; - if (status < 0) { - PrintAndLogEx(FAILED, "failed to select arg0[%" PRId64 "]", resp.oldarg[0]); - free(packet); - return switch_off_field_14b(); - } - } - - PrintAndLogEx(INFO, "." NOLF); - - uint8_t data[cardsize]; - memset(data, 0, sizeof(data)); - uint16_t blocknum = 0; - - for (int retry = 0; retry < 5; retry++) { - - // set up the read command - packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW); - packet->rawlen = 2; - packet->raw[0] = ISO14443B_READ_BLK; - packet->raw[1] = blocknum & 0xFF; - - clearCommandBuffer(); - SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)packet, sizeof(iso14b_raw_cmd_t) + 2); - if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) { - - status = resp.oldarg[0]; - if (status < 0) { - PrintAndLogEx(FAILED, "retrying one more time"); - continue; - } - - uint16_t len = (resp.oldarg[1] & 0xFFFF); - uint8_t *recv = resp.data.asBytes; - - if (check_crc(CRC_14443_B, recv, len) == false) { - PrintAndLogEx(FAILED, "crc fail, retrying one more time"); - continue; - } - - - // last read - if (blocknum == 0xFF) { - // we reserved space for this block after 0x0F and 0x7F, ie 0x10, 0x80 - memcpy(data + (blocks * 4), recv, 4); - break; - } - memcpy(data + (blocknum * 4), recv, 4); - - - retry = 0; - blocknum++; - if (blocknum > blocks) { - // read config block - blocknum = 0xFF; - } - - PrintAndLogEx(NORMAL, "." NOLF); - fflush(stdout); - } - } - free(packet); - - PrintAndLogEx(NORMAL, ""); - - if (blocknum != 0xFF) { - PrintAndLogEx(FAILED, "dump failed"); + // print_ct_blocks(data, cardsize); return switch_off_field_14b(); } - PrintAndLogEx(DEBUG, "systemblock : %s", sprint_hex(data + (blocks * 4), 4)); - PrintAndLogEx(DEBUG, " otp lock : %02x %02x", data[(blocks * 4)], data[(blocks * 4) + 1]); - - - PrintAndLogEx(INFO, " block# | data |lck| ascii"); - PrintAndLogEx(INFO, "---------+--------------+---+----------"); - - for (int i = 0; i <= blocks; i++) { - PrintAndLogEx(INFO, - "%3d/0x%02X | %s | %s | %s", - i, - i, - sprint_hex(data + (i * 4), 4), - get_st_lock_info(chipid, data + (blocks * 4), i), - sprint_ascii(data + (i * 4), 4) - ); + if (select_cardtype == ISO14B_CT) { + // Have to figure out how large one of these are.. + PrintAndLogEx(FAILED, "Dumping Standard ISO14443-B tags is not implemented yet."); + // print_std_blocks(data, cardsize); + return switch_off_field_14b(); } - PrintAndLogEx(INFO, - "%3d/0x%02X | %s | %s | %s", - 0xFF, - 0xFF, - sprint_hex(data + (0xFF * 4), 4), - get_st_lock_info(chipid, data + (blocks * 4), 0xFF), - sprint_ascii(data + (0xFF * 4), 4) - ); - PrintAndLogEx(INFO, "---------+--------------+---+----------"); - PrintAndLogEx(NORMAL, ""); - // save to file - if (fnlen < 1) { - PrintAndLogEx(INFO, "using UID as filename"); - char *fptr = filename + snprintf(filename, sizeof(filename), "hf-14b-"); - FillFileNameByUID(fptr, SwapEndian64(card.uid, card.uidlen, 8), "-dump", card.uidlen); + if (select_cardtype == ISO14B_SR) { + iso14b_card_select_t card; + memcpy(&card, (iso14b_card_select_t *)&select, sizeof(iso14b_card_select_t)); + + // detect cardsize + // 1 = 4096 + // 2 = 512 + uint8_t cardtype = get_st_cardsize(card.uid); + uint8_t blocks = 0; + uint16_t cardsize = 0; + + switch (cardtype) { + case 2: + cardsize = (512 / 8) + 4; + blocks = 0x0F; + break; + case 1: + default: + cardsize = (4096 / 8) + 4; + blocks = 0x7F; + break; + } + + uint8_t chipid = get_st_chipid(card.uid); + PrintAndLogEx(SUCCESS, "found a " _GREEN_("%s") " tag", get_st_chip_model(chipid)); + + // detect blocksize from card :) + PrintAndLogEx(INFO, "reading tag memory from UID " _GREEN_("%s"), sprint_hex_inrow(SwapEndian64(card.uid, card.uidlen, 8), card.uidlen)); + + iso14b_raw_cmd_t *packet = (iso14b_raw_cmd_t *)calloc(1, sizeof(iso14b_raw_cmd_t) + 2); + if (packet == NULL) { + PrintAndLogEx(FAILED, "failed to allocate memory"); + return PM3_EMALLOC; + } + packet->flags = (ISO14B_CONNECT | ISO14B_SELECT_SR); + packet->timeout = 0; + packet->rawlen = 0; + + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)packet, sizeof(iso14b_raw_cmd_t)); + PacketResponseNG resp; + + // select SR tag + int status; + if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) { + status = resp.oldarg[0]; + if (status < 0) { + PrintAndLogEx(FAILED, "failed to select arg0[%" PRId64 "]", resp.oldarg[0]); + free(packet); + return switch_off_field_14b(); + } + } + + PrintAndLogEx(INFO, "." NOLF); + + uint8_t data[cardsize]; + memset(data, 0, sizeof(data)); + uint16_t blocknum = 0; + + for (int retry = 0; retry < 5; retry++) { + + // set up the read command + packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW); + packet->rawlen = 2; + packet->raw[0] = ISO14443B_READ_BLK; + packet->raw[1] = blocknum & 0xFF; + + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)packet, sizeof(iso14b_raw_cmd_t) + 2); + if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) { + + status = resp.oldarg[0]; + if (status < 0) { + PrintAndLogEx(FAILED, "retrying one more time"); + continue; + } + + uint16_t len = (resp.oldarg[1] & 0xFFFF); + uint8_t *recv = resp.data.asBytes; + + if (check_crc(CRC_14443_B, recv, len) == false) { + PrintAndLogEx(FAILED, "crc fail, retrying one more time"); + continue; + } + + + // last read + if (blocknum == 0xFF) { + // we reserved space for this block after 0x0F and 0x7F, ie 0x10, 0x80 + memcpy(data + (blocks * 4), recv, 4); + break; + } + memcpy(data + (blocknum * 4), recv, 4); + + + retry = 0; + blocknum++; + if (blocknum > blocks) { + // read config block + blocknum = 0xFF; + } + + PrintAndLogEx(NORMAL, "." NOLF); + fflush(stdout); + } + } + free(packet); + + PrintAndLogEx(NORMAL, ""); + + if (blocknum != 0xFF) { + PrintAndLogEx(FAILED, "dump failed"); + return switch_off_field_14b(); + } + + print_sr_blocks(data, cardsize); + + // save to file + if (fnlen < 1) { + PrintAndLogEx(INFO, "using UID as filename"); + char *fptr = filename + snprintf(filename, sizeof(filename), "hf-14b-"); + FillFileNameByUID(fptr, SwapEndian64(card.uid, card.uidlen, 8), "-dump", card.uidlen); + } + + size_t datalen = (blocks + 1) * 4; + pm3_save_dump(filename, data, datalen, jsf14b, 4); } - size_t datalen = (blocks + 1) * 4; - pm3_save_dump(filename, data, datalen, jsf14b, 4); return switch_off_field_14b(); } /* @@ -2018,6 +2102,54 @@ out: return res; } + +static int CmdHF14BView(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14b view", + "Print a ISO14443-B dump file (bin/eml/json)", + "hf 14b view -f hf-14b-01020304-dump.bin" + ); + void *argtable[] = { + arg_param_begin, + arg_str1("f", "file", "", "filename of dump"), + arg_lit0("v", "verbose", "verbose output"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + int fnlen = 0; + char filename[FILE_PATH_SIZE]; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + bool verbose = arg_get_lit(ctx, 2); + CLIParserFree(ctx); + + // read dump file + uint8_t *dump = NULL; + size_t bytes_read = 0; + int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (ST25TB_SR_BLOCK_SIZE * 0xFF)); + if (res != PM3_SUCCESS) { + return res; + } + + uint16_t block_cnt = bytes_read / ST25TB_SR_BLOCK_SIZE; + + if (verbose) { + PrintAndLogEx(INFO, "File: " _YELLOW_("%s"), filename); + PrintAndLogEx(INFO, "File size %zu bytes, file blocks %d (0x%x)", bytes_read, block_cnt, block_cnt); + } + + // figure out a way to identify the different dump files. + // STD/SR/CT is difference + + print_sr_blocks(dump, bytes_read); + //print_std_blocks(dump, bytes_read); + //print_ct_blocks(dump, bytes_read); + + free(dump); + return PM3_SUCCESS; +} + + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"apdu", CmdHF14BAPDU, IfPm3Iso14443b, "Send ISO 14443-4 APDU to tag"}, @@ -2032,6 +2164,7 @@ static command_t CommandTable[] = { {"sniff", CmdHF14BSniff, IfPm3Iso14443b, "Eavesdrop ISO-14443-B"}, {"rdbl", CmdHF14BSriRdBl, IfPm3Iso14443b, "Read SRI512/SRIX4x block"}, {"sriwrite", CmdHF14BWriteSri, IfPm3Iso14443b, "Write data to a SRI512 or SRIX4K tag"}, + {"view", CmdHF14BView, AlwaysAvailable, "Display content from tag dump file"}, // {"valid", srix4kValid, AlwaysAvailable, "srix4k checksum test"}, {NULL, NULL, NULL, NULL} }; diff --git a/include/iso14b.h b/include/iso14b.h index 38862950b..88ba0c2be 100644 --- a/include/iso14b.h +++ b/include/iso14b.h @@ -50,6 +50,13 @@ typedef enum ISO14B_COMMAND { ISO14B_SELECT_XRX = (1 << 12), } iso14b_command_t; +typedef enum ISO14B_TYPE { + ISO14B_NONE = 0, + ISO14B_STANDARD = 1, + ISO14B_SR = 2, + ISO14B_CT = 4, +} iso14b_type_t; + typedef struct { uint16_t flags; // the ISO14B_COMMAND enum uint32_t timeout; From 87db9e7ec903346ad281aa7489c438a007fda894 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 3 Jul 2022 21:32:29 +0300 Subject: [PATCH 054/759] pm3-pm3 works --- armsrc/hfops.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 976cd7d64..9dc803804 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -107,12 +107,12 @@ static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation, uint8_t *data) { for (int j = 0; j < 8; j++) { if (((uid[i] << j) & 0x80) != 0) { // `1` - data[indx++] = 125; - data[indx++] = 63; + data[indx++] = 1; + data[indx++] = 0; } else { // `0` - data[indx++] = 63; - data[indx++] = 125; + data[indx++] = 0; + data[indx++] = 1; } } } @@ -149,7 +149,7 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { LED_C_ON(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_212K); FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR); int vHf = 0; // in mV @@ -173,19 +173,18 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { SpinDelay(10); for (int i = 0; i < elen; i++) { - if (data[i] == 0) - data[i] = 10; - - for (int j = 0; j < 13;) { + for (int j = 0; j < 1;) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0xff; + AT91C_BASE_SSC->SSC_THR = 0x80; j++; } } - for (int j = 0; j < data[i];) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x00; - j++; + if (data[i] > 0) { + for (int j = 0; j < data[i];) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x00; + j++; + } } } } From 353ef6f739baca7589d6f576cf5b7bbb14554031 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 3 Jul 2022 21:59:55 +0300 Subject: [PATCH 055/759] duplicator works too (on the edge of the field) --- armsrc/hfops.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 9dc803804..1efb4b052 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -96,6 +96,7 @@ static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation, uint8_t *data) { if (modulation == 0) { // TK-13 // 74ns 1 field cycle, + // carrier frequency is fc/64 (212kHz), 4.7 mks // 100 field cycle = impulse (13 bytes) // 1000 field cycle = `1` (125 bytes) // 500 field cycle = `0` (63 bytes) @@ -171,7 +172,7 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { continue; } - SpinDelay(10); + SpinDelay(5); for (int i = 0; i < elen; i++) { for (int j = 0; j < 1;) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { @@ -188,8 +189,6 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { } } } - - SpinDelay(100); } switch_off(); From 8571cfddbf323e631eba918bc2dd97629dea0c26 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 3 Jul 2022 22:07:03 +0300 Subject: [PATCH 056/759] led on/off optimization and wait for field stabization --- armsrc/hfops.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 1efb4b052..60dc4005e 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -156,6 +156,7 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { int vHf = 0; // in mV bool button_pressed = false; bool exit_loop = false; + bool field_on = false; while (exit_loop == false) { button_pressed = BUTTON_PRESS(); @@ -166,13 +167,20 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; if (vHf > MF_MINFIELDV) { - LED_A_ON(); + if (!field_on) { + LED_A_ON(); + SpinDelay(50); + } + field_on = true; } else { - LED_A_OFF(); + if (field_on) { + LED_A_OFF(); + } + field_on = false; continue; } - SpinDelay(5); + SpinDelay(3); for (int i = 0; i < elen; i++) { for (int j = 0; j < 1;) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { From 640f6772a58b048ec4d1c153420a3b634a362d49 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 3 Jul 2022 22:54:58 +0300 Subject: [PATCH 057/759] bit encoder, works very good with real reader --- armsrc/hfops.c | 74 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 60dc4005e..8351f7682 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -91,34 +91,66 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { return 0; } +uint8_t encode_acc = 0; +uint8_t encode_acc_bit_count = 0; +uint32_t encode_indx = 0; + +static void EncodeInit(void) { + encode_acc = 0; + encode_acc_bit_count = 0; + encode_indx = 0; +} + +static void EncodeAddBit(uint8_t* data, uint8_t bit, uint8_t bit_count) { + for (int i = 0; i < bit_count; i++) { + encode_acc = (encode_acc << 1) | (bit & 0x01); + encode_acc_bit_count++; + if (encode_acc_bit_count > 7) { + data[encode_indx++] = encode_acc; + encode_acc = 0; + encode_acc_bit_count = 0; + } + } +} + +static uint32_t EncodeFinish(uint8_t* data) { + if (encode_acc_bit_count > 0) { + encode_acc = encode_acc << (8 - encode_acc_bit_count); + data[encode_indx++] = encode_acc; + } + + return encode_indx; +} + static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation, uint8_t *data) { uint32_t len = 0; if (modulation == 0) { // TK-13 // 74ns 1 field cycle, // carrier frequency is fc/64 (212kHz), 4.7 mks - // 100 field cycle = impulse (13 bytes) - // 1000 field cycle = `1` (125 bytes) - // 500 field cycle = `0` (63 bytes) - // `1` - 125, 63 - // `0` - 63, 125 + // 100 field cycle = impulse 1.6 ( 1 bit from real tag) + // 1000 field cycle = `1` 15.6 (17 bit from real tag) + // 500 field cycle = `0` 7.8 ( 7 bit from real tag) - int indx = 0; + EncodeInit(); for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { if (((uid[i] << j) & 0x80) != 0) { // `1` - data[indx++] = 1; - data[indx++] = 0; + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 17); + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 7); } else { // `0` - data[indx++] = 0; - data[indx++] = 1; + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 7); + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 17); } } } - - len = indx; + len = EncodeFinish(data); } else { // TK-17 // 74ns 1 field cycle, @@ -181,20 +213,10 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { } SpinDelay(3); - for (int i = 0; i < elen; i++) { - for (int j = 0; j < 1;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x80; - j++; - } - } - if (data[i] > 0) { - for (int j = 0; j < data[i];) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x00; - j++; - } - } + for (int i = 0; i < elen;) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = data[i]; + i++; } } } From d2e671b7d1fdc28284929f79b4d118fa882a1612 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 3 Jul 2022 23:21:20 +0300 Subject: [PATCH 058/759] send raw data and compose raw data from id --- client/src/cmdhftexkom.c | 49 ++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index a54342980..1c698b559 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -554,12 +554,16 @@ static int CmdHFTexkomSim(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf texkom sim", "Simulate a texkom tag", - "hf texkom sim"); + "hf texkom sim \r\n" + "hf texkom sim --raw FFFF638C7DC45553 -> simulate TK13 tag with id 8C7DC455\r\n" + "hf texkom sim --id 8C7DC455 -> simulate TK13 tag with id 8C7DC455"); void *argtable[] = { arg_param_begin, arg_lit0("v", "verbose", "Verbose work"), - arg_lit0("t", "tk17", "Use TK-17 modulation (TK-13 by default)"), + arg_lit0("t", "tk17", "Use TK-17 modulation (TK-13 by default)"), + arg_str0(NULL, "raw", "", "Raw data for texkom card, 8 bytes. Manual modulation select."), + arg_str0(NULL, "id", "", "Raw data for texkom card, 8 bytes. Manual modulation select."), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -570,18 +574,43 @@ static int CmdHFTexkomSim(const char *Cmd) { if (arg_get_lit(ctx, 2)) modulation = 1; //tk-17 + uint8_t rawdata[250] = {0}; + int rawdatalen = 0; + CLIGetHexWithReturn(ctx, 3, rawdata, &rawdatalen); + + uint8_t iddata[250] = {0}; + int iddatalen = 0; + CLIGetHexWithReturn(ctx, 4, iddata, &iddatalen); + CLIParserFree(ctx); + if (rawdatalen == 0 && iddatalen == 0) { + PrintAndLogEx(ERR, " or must be specified to simulate"); + return PM3_EINVARG; + } + + if (iddatalen > 0 && iddatalen != 4) { + PrintAndLogEx(ERR, " must be 4 bytes long instead of: %d", iddatalen); + return PM3_EINVARG; + } + + if (iddatalen == 4) { + rawdata[0] = 0xff; + rawdata[1] = 0xff; + rawdata[2] = (modulation == 0) ? 0x63 : 0xca; + memcpy(&rawdata[3], iddata, 4); + rawdata[7] = (modulation == 0) ? TexcomTK13CRC(iddata) : TexcomTK17CRC(iddata); + rawdatalen = 8; + } + + if (rawdatalen > 0 && rawdatalen != 8) { + PrintAndLogEx(ERR, " must be 8 bytes long instead of: %d", rawdatalen); + return PM3_EINVARG; + } + // uint8_t data[13] = {0}; - data[0] = 0xFF; - data[1] = 0xFF; - data[2] = 0x63; - data[3] = 0x8C; - data[4] = 0x7D; - data[5] = 0xC4; - data[6] = 0x55; - data[7] = 0x53; + memcpy(data, rawdata, 8); data[8] = modulation; memcpy(&data[9], &cmdtimeout, 4); From 4ada5a9952cf25c904d2b9dcdcb6a1cfccd95670 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Jul 2022 00:05:04 +0300 Subject: [PATCH 059/759] add help --- client/src/cmdhftexkom.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 1c698b559..7cd04b408 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -556,7 +556,9 @@ static int CmdHFTexkomSim(const char *Cmd) { "Simulate a texkom tag", "hf texkom sim \r\n" "hf texkom sim --raw FFFF638C7DC45553 -> simulate TK13 tag with id 8C7DC455\r\n" - "hf texkom sim --id 8C7DC455 -> simulate TK13 tag with id 8C7DC455"); + "hf texkom sim --tk17 --raw FFFFCA17F31EC512 -> simulate TK17 tag with id 17F31EC5\r\n" + "hf texkom sim --id 8C7DC455 -> simulate TK13 tag with id 8C7DC455\r\n" + "hf texkom sim --id 8C7DC455 --tk17 -> simulate TK17 tag with id 17F31EC5"); void *argtable[] = { arg_param_begin, From 4efb9f22753ab4fbe29ed767dc162391c2b34a85 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Jul 2022 00:18:57 +0300 Subject: [PATCH 060/759] tk-17 works --- armsrc/hfops.c | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 8351f7682..c71ed37ff 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -154,12 +154,46 @@ static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation, uint8_t *data) { } else { // TK-17 // 74ns 1 field cycle, - // `00` - - // `01` - - // `10` - - // `11` - - + // carrier frequency is fc/64 (212kHz), 4.7 mks + // 0 --- 8 --- 12-15 --- 18-19 --- 26-28 --- 32 + // `00` -- 1-25-1-5 + // `01` -- 1-12-1-18 + // `10` -- 1-17-1-13 + // `11` -- 1-7-1-23 + EncodeInit(); + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 8; j += 2) { + uint8_t twobit = ((uid[i] >> j) & 0x03); + if (twobit == 0x00) { + // `00` + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 25); + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 5); + } else if (twobit == 0x01) { + // `01` + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 12); + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 18); + } else if (twobit == 0x02) { + // `10` + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 17); + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 13); + } else { // twobit == 0x03 + // `11` + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 7); + EncodeAddBit(data, 1, 1); + EncodeAddBit(data, 0, 23); + } + } + } + EncodeAddBit(data, 1, 1); + len = EncodeFinish(data); } return len; From be25a00444e25d810ccb9766c96d9aa40cef823f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Jul 2022 00:27:22 +0300 Subject: [PATCH 061/759] add warning --- armsrc/hfops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index c71ed37ff..8785e0d85 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -156,6 +156,7 @@ static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation, uint8_t *data) { // 74ns 1 field cycle, // carrier frequency is fc/64 (212kHz), 4.7 mks // 0 --- 8 --- 12-15 --- 18-19 --- 26-28 --- 32 + // DO NOT NORMALIZE!!!! it must be with some error like this!!!! // `00` -- 1-25-1-5 // `01` -- 1-12-1-18 // `10` -- 1-17-1-13 From 385d754fc33479637c6b8813f0aac44afe4130e2 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Jul 2022 00:29:35 +0300 Subject: [PATCH 062/759] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aa7ff298..ff51fbd4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added 122 new keys from Flipper Zero community to `mfc_default_keys.dic` (@UberGuidoZ) - Added showing password for the read command in the `lf t55xx sniff` command (@merlokk) - Added reading texcom tk13 and tk17 tags with `hf texkom read` command (@merlokk @iceman1001) + - Added simulating texcom tk13 and tk17 tags with `hf texkom sim` command (@merlokk) ## [Frostbit.4.14831][2022-01-11] - Changed Wiegand format lookup - now case-insensitive (@iceman1001) From 7ed8f08e096e94a86e1e8022bd6d10d07485f7a1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 4 Jul 2022 00:35:44 +0300 Subject: [PATCH 063/759] make style --- armsrc/hfops.c | 8 ++++---- armsrc/hfops.h | 2 +- doc/commands.json | 29 +++++++++++++++++++++++++---- doc/commands.md | 1 + 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 8785e0d85..591e80fda 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -101,7 +101,7 @@ static void EncodeInit(void) { encode_indx = 0; } -static void EncodeAddBit(uint8_t* data, uint8_t bit, uint8_t bit_count) { +static void EncodeAddBit(uint8_t *data, uint8_t bit, uint8_t bit_count) { for (int i = 0; i < bit_count; i++) { encode_acc = (encode_acc << 1) | (bit & 0x01); encode_acc_bit_count++; @@ -113,7 +113,7 @@ static void EncodeAddBit(uint8_t* data, uint8_t bit, uint8_t bit_count) { } } -static uint32_t EncodeFinish(uint8_t* data) { +static uint32_t EncodeFinish(uint8_t *data) { if (encode_acc_bit_count > 0) { encode_acc = encode_acc << (8 - encode_acc_bit_count); data[encode_indx++] = encode_acc; @@ -158,7 +158,7 @@ static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation, uint8_t *data) { // 0 --- 8 --- 12-15 --- 18-19 --- 26-28 --- 32 // DO NOT NORMALIZE!!!! it must be with some error like this!!!! // `00` -- 1-25-1-5 - // `01` -- 1-12-1-18 + // `01` -- 1-12-1-18 // `10` -- 1-17-1-13 // `11` -- 1-7-1-23 @@ -206,7 +206,7 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { LEDsoff(); - uint8_t* data = BigBuf_calloc(256); + uint8_t *data = BigBuf_calloc(256); uint32_t elen = HfEncodeTkm(uid, modulation, data); if (elen == 0) { DbpString("encode error"); diff --git a/armsrc/hfops.h b/armsrc/hfops.h index f1d705913..91f1de539 100644 --- a/armsrc/hfops.h +++ b/armsrc/hfops.h @@ -24,4 +24,4 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol); int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout); -#endif \ No newline at end of file +#endif diff --git a/doc/commands.json b/doc/commands.json index 5fb476e59..dfc8a4647 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -6324,6 +6324,27 @@ ], "usage": "hf texkom reader [-hv]" }, + "hf texkom sim": { + "command": "hf texkom sim", + "description": "Simulate a texkom tag", + "notes": [ + "hf texkom sim", + "", + "hf texkom sim --raw FFFF638C7DC45553 -> simulate TK13 tag with id 8C7DC455", + "hf texkom sim --tk17 --raw FFFFCA17F31EC512 -> simulate TK17 tag with id 17F31EC5", + "hf texkom sim --id 8C7DC455 -> simulate TK13 tag with id 8C7DC455", + "hf texkom sim --id 8C7DC455 --tk17 -> simulate TK17 tag with id 17F31EC5" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-v, --verbose Verbose work", + "-t, --tk17 Use TK-17 modulation (TK-13 by default)", + "--raw Raw data for texkom card, 8 bytes. Manual modulation select.", + "--id Raw data for texkom card, 8 bytes. Manual modulation select." + ], + "usage": "hf texkom sim [-hvt] [--raw ] [--id ]" + }, "hf thinfilm help": { "command": "hf thinfilm help", "description": "help This help list List NFC Barcode / Thinfilm history - not correct", @@ -6585,8 +6606,8 @@ "command": "hw connect", "description": "Connects to a Proxmark3 device via specified serial port. Baudrate here is only for physical UART or UART-BT, NOT for USB-CDC or blue shark add-on", "notes": [ - "hw connect -p /dev/ttyACM0", - "hw connect -p /dev/ttyACM0 -b 115200" + "hw connect -p /dev/ttyacm0", + "hw connect -p /dev/ttyacm0 -b 115200" ], "offline": true, "options": [ @@ -11055,8 +11076,8 @@ } }, "metadata": { - "commands_extracted": 698, + "commands_extracted": 699, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-06-30T19:19:33" + "extracted_on": "2022-07-03T21:31:15" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index fe57dfbdb..4f03dee72 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -654,6 +654,7 @@ Check column "offline" for their availability. |------- |------- |----------- |`hf texkom help `|Y |`This help` |`hf texkom reader `|N |`Act like a Texkom reader` +|`hf texkom sim `|N |`Simulate a Texkom tag` ### hf xerox From e98675f8e599fdc4c80cb9b7444529cf326c9c1e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 4 Jul 2022 10:20:01 +0200 Subject: [PATCH 064/759] fix faulty enum --- client/src/cmdhf14b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 575bf21e5..2e63de332 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -440,7 +440,7 @@ static bool get_14b_UID(uint8_t *d, iso14b_type_t *found_type) { if (resp.oldarg[0] == 0) { memcpy(d, resp.data.asBytes, sizeof(iso14b_card_select_t)); - *found_type = ISO14B_SELECT_SR; + *found_type = ISO14B_SR; return true; } } From c97f003b2f7869ea4dd04691641bc6adb534e91e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 4 Jul 2022 17:21:36 +0200 Subject: [PATCH 065/759] added a pm3 simulating trace of MIFARE HID SIO 1K card --- traces/README.md | 1 + traces/hf_mf_hid_sio_sim.trace | Bin 0 -> 742 bytes 2 files changed, 1 insertion(+) create mode 100644 traces/hf_mf_hid_sio_sim.trace diff --git a/traces/README.md b/traces/README.md index b6cad9fe8..939905017 100644 --- a/traces/README.md +++ b/traces/README.md @@ -102,3 +102,4 @@ |hf_visa_apple_transit_bypass.trace |Sniff of VISA Apple transaction bypass| |hf_mfdes_sniff.trace |Sniff of HID reader reading a MIFARE DESFire SIO card| |hf_iclass_sniff.trace |Sniff of HID reader reading a Picopass 2k card| +|hf_mf_hid_sio_sim.trace |Simulation of a HID SIO MFC 1K card| diff --git a/traces/hf_mf_hid_sio_sim.trace b/traces/hf_mf_hid_sio_sim.trace new file mode 100644 index 0000000000000000000000000000000000000000..4477a9a4b6660e1d3d69a1176589a45b7fe15b48 GIT binary patch literal 742 zcmezRS)b_vGb2L~gXSN7CI?QY1{MZ~@0) zRGF$U-B~&HXGX!--mnw%<@3wl1Q|9+W)^}~=Ie(V2Athl2sX3f?CxfZZ(3WD9@nt# zcpJ_klp|ks;Jr`@SfzD|pjg4Ru=|&TeXvyS#ElEzFIO@p0R3ljE!tEH>JvfVZ=pC^2OTMgD1!hDy# zV6|Nh*wrVliA;)!b@TiF>Bp(iEIs3^tBamD?A=rcR(bJk+$VvL%=KWEakf|Vf3V3U zmY@2awR(@Go(kKI1q|Oa8krUV!`jh$TSbHR&PK4SwO&R%k)JXD2>*^pc_JMe3|*Js zwK;rMXaSoU{^=9{g_VUZV3h`^i^SL#)x>g2*ZglQKXP#!!^Rc|+uLnmm79M3EV@w0 z*^cnv%(hOj|CT?#^mk#(g$qt7r3yEQ$Z6 z>2Z*+%QZTxNb;J-tFsM~+g?JGoA17tu;jM##!Faoi+%PIDY*p;yh2ZI?Y6Jr$qfMg CFB-i7 literal 0 HcmV?d00001 From c08c2dcf3abbe861c084a634b1307569b1dc3265 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 4 Jul 2022 18:49:30 +0200 Subject: [PATCH 066/759] make sure size_t doesnt overflow an int --- client/src/cmdhfemrtd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index 44c116b16..ed2fb00d6 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -716,7 +716,8 @@ static const uint8_t jpeg_header[4] = { 0xFF, 0xD8, 0xFF, 0xE0 }; static const uint8_t jpeg2k_header[6] = { 0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50 }; static int emrtd_dump_ef_dg2(uint8_t *file_contents, size_t file_length, const char *path) { - int offset, datalen = 0; + size_t offset; + int datalen = 0; // This is a hacky impl that just looks for the image header. I'll improve it eventually. // based on mrpkey.py @@ -738,6 +739,7 @@ static int emrtd_dump_ef_dg2(uint8_t *file_contents, size_t file_length, const c char *filepath = calloc(strlen(path) + 100, sizeof(char)); if (filepath == NULL) return PM3_EMALLOC; + strcpy(filepath, path); strncat(filepath, PATHSEP, 2); strcat(filepath, dg_table[EF_DG2].filename); From 009b91e096ef53c1c5ced5572c5efa6a3fbcb13c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 4 Jul 2022 19:23:44 +0200 Subject: [PATCH 067/759] limit hex print outs --- client/src/util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/util.c b/client/src/util.c index 12e0140a7..b38a28f6d 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -318,7 +318,7 @@ char *sprint_hex(const uint8_t *data, const size_t len) { } char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const size_t min_str_len) { - static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; + static char buf[UTIL_BUFFER_SIZE_SPRINT - 3] = {0}; hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, min_str_len, 0, true); return buf; } @@ -327,7 +327,7 @@ char *sprint_hex_inrow(const uint8_t *data, const size_t len) { return sprint_hex_inrow_ex(data, len, 0); } char *sprint_hex_inrow_spaces(const uint8_t *data, const size_t len, size_t spaces_between) { - static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; + static char buf[UTIL_BUFFER_SIZE_SPRINT - 3] = {0}; hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, spaces_between, true); return buf; } From 9407be8ea8e1ac6c76a184ab59a0ce13f9d4d461 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 4 Jul 2022 22:10:23 +0200 Subject: [PATCH 068/759] fix overflow in print hex --- client/src/util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/util.c b/client/src/util.c index b38a28f6d..27a23c3e2 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -189,7 +189,8 @@ void hex_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, size_t max_len = (hex_len > hex_max_len) ? hex_max_len : hex_len; size_t i; - for (i = 0; i < max_len; ++i, tmp += 2 + spaces_between) { + for (i = 0; i < max_len && (tmp - tmp_base); ++i, tmp += 2 + spaces_between) { + snprintf(tmp, hex_max_len - (tmp - tmp_base), (uppercase) ? "%02X" : "%02x", (unsigned int) hex_data[i]); for (size_t j = 0; j < spaces_between; j++) From 0d41ed0bba1ca6788f01c799b5986f4509f6eb22 Mon Sep 17 00:00:00 2001 From: nemanjan00 Date: Tue, 5 Jul 2022 16:15:05 +0200 Subject: [PATCH 069/759] --reboot-to-bootloader --- client/src/flash.c | 9 +++++++++ client/src/flash.h | 1 + client/src/proxmark3.c | 46 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/client/src/flash.c b/client/src/flash.c index ad627ffb6..3ced486a6 100644 --- a/client/src/flash.c +++ b/client/src/flash.c @@ -595,6 +595,15 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t return PM3_SUCCESS; } +// Reboot into bootloader +int flash_reboot_bootloader(char *serial_port_name) { + int ret; + + ret = enter_bootloader(serial_port_name); + + return ret; +} + static int write_block(uint32_t address, uint8_t *data, uint32_t length) { uint8_t block_buf[BLOCK_SIZE]; memset(block_buf, 0xFF, BLOCK_SIZE); diff --git a/client/src/flash.h b/client/src/flash.h index 5c2535620..fa5694dbd 100644 --- a/client/src/flash.h +++ b/client/src/flash.h @@ -44,6 +44,7 @@ typedef struct { int flash_load(flash_file_t *ctx, bool force); int flash_prepare(flash_file_t *ctx, int can_write_bl, int flash_size); int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed); +int flash_reboot_bootloader(char *serial_port_name); int flash_write(flash_file_t *ctx); void flash_free(flash_file_t *ctx); int flash_stop_flashing(void); diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index e15c9ff9f..750d585f3 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -696,6 +696,38 @@ finish2: PrintAndLogEx(INFO, "\nHave a nice day!"); return ret; } + +static int reboot_bootloader_pm3(char *serial_port_name) { + + int ret = PM3_EUNDEF; + + if (serial_port_name == NULL) { + PrintAndLogEx(ERR, "You must specify a port.\n"); + return PM3_EINVARG; + } + + if (OpenProxmark(&g_session.current_device, serial_port_name, true, 60, true, FLASHMODE_SPEED)) { + PrintAndLogEx(NORMAL, _GREEN_(" found")); + } else { + PrintAndLogEx(ERR, "Could not find Proxmark3 on " _RED_("%s") ".\n", serial_port_name); + ret = PM3_ETIMEOUT; + goto finish2; + } + + ret = flash_reboot_bootloader(serial_port_name); + return ret; + +finish2: + if (ret == PM3_SUCCESS) + PrintAndLogEx(SUCCESS, _CYAN_("All done")); + else if (ret == PM3_EOPABORTED) + PrintAndLogEx(FAILED, "Aborted by user"); + else + PrintAndLogEx(ERR, "Aborted on error"); + PrintAndLogEx(INFO, "\nHave a nice day!"); + return ret; +} + #endif //LIBPM3 void pm3_init(void) { @@ -732,6 +764,7 @@ int main(int argc, char *argv[]) { strncpy(exec_name, basename(argv[0]), sizeof(exec_name) - 1); bool flash_mode = false; + bool reboot_bootloader_mode = false; bool flash_can_write_bl = false; bool flash_force = false; bool debug_mode_forced = false; @@ -944,6 +977,12 @@ int main(int argc, char *argv[]) { continue; } + // go to flash mode + if (strcmp(argv[i], "--reboot-to-bootloader") == 0) { + reboot_bootloader_mode = true; + continue; + } + // unlock bootloader area if (strcmp(argv[i], "--unlock-bootloader") == 0) { flash_can_write_bl = true; @@ -1001,6 +1040,11 @@ int main(int argc, char *argv[]) { exit(EXIT_SUCCESS); } + if (reboot_bootloader_mode) { + reboot_bootloader_pm3(port); + exit(EXIT_SUCCESS); + } + if (script_cmd) { while (script_cmd[strlen(script_cmd) - 1] == ' ') script_cmd[strlen(script_cmd) - 1] = 0x00; @@ -1043,7 +1087,7 @@ int main(int argc, char *argv[]) { PrintAndLogEx(INFO, "Running in " _YELLOW_("OFFLINE") " mode. Check " _YELLOW_("\"%s -h\"") " if it's not what you want.\n", exec_name); // ascii art only in interactive client - if (!script_cmds_file && !script_cmd && g_session.stdinOnTTY && g_session.stdoutOnTTY && !flash_mode) + if (!script_cmds_file && !script_cmd && g_session.stdinOnTTY && g_session.stdoutOnTTY && !flash_mode && !reboot_bootloader_mode) showBanner(); // Save settings if not loaded from settings json file. From 187d10060b58b83a25819f80997e7432b7a35a3b Mon Sep 17 00:00:00 2001 From: nemanjan00 Date: Tue, 5 Jul 2022 16:44:11 +0200 Subject: [PATCH 070/759] Bootloader mode --- client/src/proxmark3.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 750d585f3..2e176335f 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -576,6 +576,7 @@ static void show_help(bool showFullHelp, char *exec_name) { PrintAndLogEx(NORMAL, " --incognito do not use history, prefs file nor log files"); PrintAndLogEx(NORMAL, "\nOptions in flasher mode:"); PrintAndLogEx(NORMAL, " --flash flash Proxmark3, requires at least one --image"); + PrintAndLogEx(NORMAL, " --reboot-bootloader reboot Proxmark3 into bootloader mode"); PrintAndLogEx(NORMAL, " --unlock-bootloader Enable flashing of bootloader area *DANGEROUS* (need --flash)"); PrintAndLogEx(NORMAL, " --force Enable flashing even if firmware seems to not match client version"); PrintAndLogEx(NORMAL, " --image image to flash. Can be specified several times."); From 1216c32f3c21b190a2daa1541cd9b6d41323ac3b Mon Sep 17 00:00:00 2001 From: nemanjan00 Date: Tue, 5 Jul 2022 16:54:56 +0200 Subject: [PATCH 071/759] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff51fbd4d..10fc67e9f 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] + - Added `--reboot-to-bootloader` arg to pm3 - Changed `hf 14b raw` - now supports selecting Fuji/Xerox tag (@horror) - Added `hf xerox dump` - dump a Fuji/Xerox tag (@horror) - Added `hf xerox info` - read Fuji/Xerox tag (@horror) From 86f0f2cc75baead268f80d2868f5dd091a611a24 Mon Sep 17 00:00:00 2001 From: Nemanja Nedeljkovic Date: Tue, 5 Jul 2022 18:12:49 +0200 Subject: [PATCH 072/759] cleanup --- client/src/flash.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/client/src/flash.c b/client/src/flash.c index 3ced486a6..3b2f6b277 100644 --- a/client/src/flash.c +++ b/client/src/flash.c @@ -597,11 +597,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t // Reboot into bootloader int flash_reboot_bootloader(char *serial_port_name) { - int ret; - - ret = enter_bootloader(serial_port_name); - - return ret; + return enter_bootloader(serial_port_name); } static int write_block(uint32_t address, uint8_t *data, uint32_t length) { From 444eabd20771420992ffb9ade798db0698d2373e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 07:38:04 +0200 Subject: [PATCH 073/759] fixed hex_to_buffer fct. --- client/src/util.c | 93 +++++++++++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 32 deletions(-) diff --git a/client/src/util.c b/client/src/util.c index 27a23c3e2..0565dc129 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -33,7 +33,7 @@ #include "ui.h" // PrintAndLog -#define UTIL_BUFFER_SIZE_SPRINT 8193 +#define UTIL_BUFFER_SIZE_SPRINT 8196 // global client debug variable uint8_t g_debugMode = 0; // global client disable logging variable @@ -90,6 +90,22 @@ int kbd_enter_pressed(void) { } #endif +static char b2s(uint8_t v, bool uppercase) { + // clear higher bits + v &= 0xF; + + switch(v) { + case 0xA : return (uppercase ? 'A' : 'a') ; + case 0xB : return (uppercase ? 'B' : 'b') ; + case 0xC : return (uppercase ? 'C' : 'c') ; + case 0xD : return (uppercase ? 'D' : 'd') ; + case 0xE : return (uppercase ? 'E' : 'e') ; + case 0xF : return (uppercase ? 'F' : 'f') ; + default: + return (char)(v + 0x30); + } +} + // create filename on hex uid. // param *fn - pointer to filename char array // param *uid - pointer to uid byte array @@ -181,33 +197,41 @@ void ascii_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len void hex_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, const size_t hex_max_len, const size_t min_str_len, const size_t spaces_between, bool uppercase) { - if (buf == NULL) return; + // sanity check + if (buf == NULL || hex_len < 1) + return; + // 1. hex string length. + // 2. byte array to be converted to string + // + + size_t max_byte_len = (hex_len > hex_max_len) ? hex_max_len : hex_len; + size_t max_str_len = (max_byte_len * ( 2 + spaces_between )) + 1; char *tmp_base = (char *)buf; char *tmp = tmp_base; - size_t max_len = (hex_len > hex_max_len) ? hex_max_len : hex_len; - size_t i; - for (i = 0; i < max_len && (tmp - tmp_base); ++i, tmp += 2 + spaces_between) { + for (i = 0; (i < max_byte_len) && (max_str_len > strlen(tmp_base)) ; ++i) { - snprintf(tmp, hex_max_len - (tmp - tmp_base), (uppercase) ? "%02X" : "%02x", (unsigned int) hex_data[i]); + *(tmp++) = b2s((hex_data[i] >> 4), uppercase); + *(tmp++) = b2s(hex_data[i], uppercase); for (size_t j = 0; j < spaces_between; j++) - *(tmp + 2 + j) = ' '; + *(tmp++) = ' '; } i *= (2 + spaces_between); - size_t m = min_str_len > i ? min_str_len : 0; + size_t m = (min_str_len > i) ? min_str_len : 0; if (m > hex_max_len) m = hex_max_len; - for (; i < m; i++, tmp++) - *tmp = ' '; + while (m--) + *(tmp++) = ' '; // remove last space *tmp = '\0'; + } // printing and converting functions @@ -299,7 +323,6 @@ void print_buffer_with_offset(const uint8_t *data, const size_t len, int offset, } } - void print_blocks(uint32_t *data, size_t len) { PrintAndLogEx(SUCCESS, "Blk | Data "); PrintAndLogEx(SUCCESS, "----+------------"); @@ -313,13 +336,15 @@ void print_blocks(uint32_t *data, size_t len) { } char *sprint_hex(const uint8_t *data, const size_t len) { - static char buf[UTIL_BUFFER_SIZE_SPRINT - 3] = {0}; + static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; + memset(buf, 0x00, sizeof(buf)); hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, 1, true); return buf; } char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const size_t min_str_len) { - static char buf[UTIL_BUFFER_SIZE_SPRINT - 3] = {0}; + static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; + memset(buf, 0x00, sizeof(buf)); hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, min_str_len, 0, true); return buf; } @@ -327,8 +352,10 @@ char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const size_t mi char *sprint_hex_inrow(const uint8_t *data, const size_t len) { return sprint_hex_inrow_ex(data, len, 0); } + char *sprint_hex_inrow_spaces(const uint8_t *data, const size_t len, size_t spaces_between) { - static char buf[UTIL_BUFFER_SIZE_SPRINT - 3] = {0}; + static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; + memset(buf, 0x00, sizeof(buf)); hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, spaces_between, true); return buf; } @@ -339,8 +366,7 @@ char *sprint_bytebits_bin_break(const uint8_t *data, const size_t len, const uin size_t rowlen = (len > MAX_BIN_BREAK_LENGTH) ? MAX_BIN_BREAK_LENGTH : len; // 3072 + end of line characters if broken at 8 bits - static char buf[MAX_BIN_BREAK_LENGTH]; - memset(buf, 0x00, sizeof(buf)); + static char buf[MAX_BIN_BREAK_LENGTH] = {0}; char *tmp = buf; // loop through the out_index to make sure we don't go too far @@ -414,39 +440,40 @@ char *sprint_bytebits_bin(const uint8_t *data, const size_t len) { char *sprint_bin(const uint8_t *data, const size_t len) { size_t binlen = (len * 8 > MAX_BIN_BREAK_LENGTH) ? MAX_BIN_BREAK_LENGTH : len * 8; - static uint8_t buf[MAX_BIN_BREAK_LENGTH]; + static uint8_t buf[MAX_BIN_BREAK_LENGTH] = {0}; bytes_to_bytebits(data, binlen / 8, buf); return sprint_bytebits_bin_break(buf, binlen, 0); } char *sprint_hex_ascii(const uint8_t *data, const size_t len) { - static char buf[UTIL_BUFFER_SIZE_SPRINT]; - memset(buf, 0x00, UTIL_BUFFER_SIZE_SPRINT); + static char buf[UTIL_BUFFER_SIZE_SPRINT + 20] = {0}; + memset(buf, 0x00, sizeof(buf)); size_t max_len = (len > 1010) ? 1010 : len; - snprintf(buf, sizeof(buf), "%s| ", sprint_hex(data, max_len)); + int ret = snprintf(buf, sizeof(buf) - 1, "%s| ", sprint_hex(data, max_len)); + if ( ret < 0) { + goto out; + } size_t i = 0; size_t pos = (max_len * 3) + 2; while (i < max_len) { - char c = data[i]; - if ((c < 32) || (c == 127)) - c = '.'; - - snprintf(buf + pos + i, sizeof(buf) - (pos + 1), "%c", c); + buf[pos + i] = ((c < 32) || (c == 127)) ? '.' : 'c'; ++i; } + +out: return buf; } char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len) { - static char buf[UTIL_BUFFER_SIZE_SPRINT]; + static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; char *tmp = buf; - memset(buf, 0x00, UTIL_BUFFER_SIZE_SPRINT); size_t max_len = (len > 1010) ? 1010 : len; size_t i = 0; + while (i < max_len) { char c = data[i]; tmp[i] = ((c < 32) || (c == 127)) ? '.' : c; @@ -728,13 +755,14 @@ int param_gethex_ex(const char *line, int paramnum, uint8_t *data, int *hexcnt) } int param_gethex_to_eol(const char *line, int paramnum, uint8_t *data, int maxdatalen, int *datalen) { - int bg, en; - uint32_t temp; - char buf[5] = {0}; - if (param_getptr(line, &bg, &en, paramnum)) return 1; + int bg, en; + + if (param_getptr(line, &bg, &en, paramnum)) + return 1; *datalen = 0; + char buf[5] = {0}; int indx = bg; while (line[indx]) { @@ -757,8 +785,9 @@ int param_gethex_to_eol(const char *line, int paramnum, uint8_t *data, int maxda } if (strlen(buf) >= 2) { + uint32_t temp = 0; sscanf(buf, "%x", &temp); - data[*datalen] = (uint8_t)(temp & 0xff); + data[*datalen] = (uint8_t)(temp & 0xFF); *buf = 0; (*datalen)++; } From a49e2ff3421fec3a905e87792b2b82dae7be63d3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 11:59:49 +0200 Subject: [PATCH 074/759] fix cid 395634 --- client/src/cmdhf14b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 2e63de332..831f87f8c 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -1388,7 +1388,7 @@ static int CmdHF14BDump(const char *Cmd) { return switch_off_field_14b(); } - if (select_cardtype == ISO14B_CT) { + if (select_cardtype == ISO14B_STANDARD) { // Have to figure out how large one of these are.. PrintAndLogEx(FAILED, "Dumping Standard ISO14443-B tags is not implemented yet."); // print_std_blocks(data, cardsize); From d7165b3aa94248186baba9b3102a2a455d31bc10 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 12:08:02 +0200 Subject: [PATCH 075/759] comments to @merlokk --- client/src/cmdhftexkom.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 7cd04b408..4de58b7f7 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -599,7 +599,7 @@ static int CmdHFTexkomSim(const char *Cmd) { if (iddatalen == 4) { rawdata[0] = 0xff; rawdata[1] = 0xff; - rawdata[2] = (modulation == 0) ? 0x63 : 0xca; + rawdata[2] = (modulation == 0) ? 0x63 : 0xCA; memcpy(&rawdata[3], iddata, 4); rawdata[7] = (modulation == 0) ? TexcomTK13CRC(iddata) : TexcomTK17CRC(iddata); rawdatalen = 8; @@ -610,6 +610,23 @@ static int CmdHFTexkomSim(const char *Cmd) { return PM3_EINVARG; } + //iceman, use a struct + /* + struct p { + uint8_t modulation; + uint32_t timeout; + uint8_t data[8]; + } PACKED payload; + + payload.modulation = modulation; + payload.timeout = cmdtimeout; + memcpy(payload.data, rawdata, sizeof(payload.data)); + + SendCommandNG(CMD_HF_TEXKOM_SIMULATE, (uint8_t*)&payload, sizeof(payload)); + + // Iceman, cmdtimeout is always 0. You never set it + */ + // uint8_t data[13] = {0}; memcpy(data, rawdata, 8); @@ -621,9 +638,10 @@ static int CmdHFTexkomSim(const char *Cmd) { if (cmdtimeout > 0 && cmdtimeout < 2800) { PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_HF_TEXKOM_SIMULATE, &resp, 3000)) { - if (verbose) + if (WaitForResponseTimeout(CMD_HF_TEXKOM_SIMULATE, &resp, 3000) == false) { + if (verbose) { PrintAndLogEx(WARNING, "(hf texkom simulate) command execution time out"); + } return PM3_ETIMEOUT; } PrintAndLogEx(INFO, "simulate command execution done"); From 1d66525b8e3e4d7f39bd1121cb34b0a6526be361 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 12:14:54 +0200 Subject: [PATCH 076/759] fix cid 395631 - making a local copy instead of object --- client/src/cipurse/cipursecore.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/src/cipurse/cipursecore.c b/client/src/cipurse/cipursecore.c index 76b9d9b8d..abe8a6bc2 100644 --- a/client/src/cipurse/cipursecore.c +++ b/client/src/cipurse/cipursecore.c @@ -412,10 +412,14 @@ void CIPURSEPrintDGI(uint8_t *dgi, size_t dgilen) { } for (int i = 0; i < len / 20; i++) { - PrintAndLogEx(INFO, "Key[%d]............ %s", i + 1, sprint_hex_inrow(&dgi[3 + i * 20 + 0], 16)); - PrintAndLogEx(INFO, " Additional info.. 0x%02x", dgi[3 + i * 20 + 16]); + uint8_t kvv[CIPURSE_KVV_LENGTH] = {0}; - CipurseCGetKVV(&dgi[3 + i * 20 + 0], kvv); + uint8_t aeskey[16] = {0}; + memcpy(aeskey, &dgi[3 + i * 20 + 0], sizeof(aeskey)); + + PrintAndLogEx(INFO, "Key[%d]............ %s", i + 1, sprint_hex_inrow(aeskey, sizeof(aeskey))); + PrintAndLogEx(INFO, " Additional info.. 0x%02x", dgi[3 + i * 20 + 16]); + CipurseCGetKVV(aeskey, kvv); bool kvvvalid = (memcmp(kvv, &dgi[3 + i * 20 + 17], 3) == 0); PrintAndLogEx(INFO, " KVV.............. %s (%s)", sprint_hex_inrow(&dgi[3 + i * 20 + 17], 3), (kvvvalid) ? _GREEN_("valid") : _RED_("invalid")); } From 742194896d11ea2f49458e225bb82a2f432bb26c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 12:21:14 +0200 Subject: [PATCH 077/759] fix cid 395629 - simpler logic --- client/src/proxmark3.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 2e176335f..9ca38a2a1 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -699,34 +699,18 @@ finish2: } static int reboot_bootloader_pm3(char *serial_port_name) { - - int ret = PM3_EUNDEF; - if (serial_port_name == NULL) { PrintAndLogEx(ERR, "You must specify a port.\n"); return PM3_EINVARG; } - if (OpenProxmark(&g_session.current_device, serial_port_name, true, 60, true, FLASHMODE_SPEED)) { - PrintAndLogEx(NORMAL, _GREEN_(" found")); - } else { + if (OpenProxmark(&g_session.current_device, serial_port_name, true, 60, true, FLASHMODE_SPEED) == false) { PrintAndLogEx(ERR, "Could not find Proxmark3 on " _RED_("%s") ".\n", serial_port_name); - ret = PM3_ETIMEOUT; - goto finish2; + return PM3_ETIMEOUT; } - ret = flash_reboot_bootloader(serial_port_name); - return ret; - -finish2: - if (ret == PM3_SUCCESS) - PrintAndLogEx(SUCCESS, _CYAN_("All done")); - else if (ret == PM3_EOPABORTED) - PrintAndLogEx(FAILED, "Aborted by user"); - else - PrintAndLogEx(ERR, "Aborted on error"); - PrintAndLogEx(INFO, "\nHave a nice day!"); - return ret; + PrintAndLogEx(NORMAL, _GREEN_(" found")); + return flash_reboot_bootloader(serial_port_name); } #endif //LIBPM3 From 88b583417eb7a6ff02358b08e099665785d8b84d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 12:34:18 +0200 Subject: [PATCH 078/759] fix cid 395628 - make local copy. Odd that it frees it --- client/src/crypto/asn1utils.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/client/src/crypto/asn1utils.c b/client/src/crypto/asn1utils.c index f54a6b451..2928a3c40 100644 --- a/client/src/crypto/asn1utils.c +++ b/client/src/crypto/asn1utils.c @@ -20,19 +20,29 @@ #include #include #include -#include "ui.h" // Print... +#include // memcpy +#include "ui.h" // Print... #include "emv/tlv.h" #include "asn1dump.h" #include "util.h" + int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *rval, uint8_t *sval) { - if (!signature || !signaturelen || !rval || !sval) + + if (!signature || !signaturelen || !rval || !sval) { return PM3_EINVARG; + } + + uint8_t *p = calloc(sizeof(uint8_t), signaturelen); + if (p == NULL) { + return PM3_EMALLOC; + } + + memcpy(p, signature, signaturelen); + const unsigned char *end = p + signaturelen; int res = PM3_SUCCESS; - unsigned char *p = signature; - const unsigned char *end = p + signaturelen; - size_t len; + size_t len = 0; mbedtls_mpi xmpi; if ((res = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) == 0) { @@ -61,11 +71,14 @@ int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *r goto exit; // check size - if (end != p) + if (end != p) { + free(p); return PM3_ESOFT; + } } exit: +// free(p); return res; } From 805b8e1e448c15ce33b464859598879b1d5de4ad Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 12:42:25 +0200 Subject: [PATCH 079/759] cppchecker fixes --- client/src/cmdhftexkom.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 4de58b7f7..3dfba4c2c 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -117,7 +117,7 @@ static bool TexkomCorrelate(uint32_t indx, uint32_t threshold) { ); } -static bool TexkomCalculateMaxMin(uint32_t *data, uint32_t len, uint32_t *dmax, uint32_t *dmin) { +static bool TexkomCalculateMaxMin(const uint32_t *data, uint32_t len, uint32_t *dmax, uint32_t *dmin) { *dmax = 0; *dmin = 0xffffffff; for (size_t i = 0; i < len; i++) { @@ -175,7 +175,7 @@ static inline bool TexcomCalculateBit(uint32_t data, uint32_t bitlen, uint32_t t } // code from https://github.com/li0ard/crclib/blob/main/index.js -static uint8_t TexcomTK13CRC(uint8_t *data) { +static uint8_t TexcomTK13CRC(const uint8_t *data) { uint8_t crc = 0; uint8_t indx = 0; while (indx < 4) { @@ -348,10 +348,12 @@ static bool TexcomGeneralDecode(uint32_t *implengths, uint32_t implengthslen, ch else { if (verbose) { PrintAndLogEx(INFO, "ERROR string [%zu]: %s, bit: %d, blen: %d", strlen(bitstring), bitstring, i, implengths[i]); - printf("Length array: \r\n"); - for (uint32_t j = 0; j < implengthslen; j++) - printf("%d,", implengths[j]); - printf("\r\n"); + + PrintAndLogEx(INFO, "Length array:"); + for (uint32_t j = 0; j < implengthslen; j++) { + PrintAndLogEx(NORMAL, "%u, " NOLF, implengths[j]); + } + PrintAndLogEx(NORMAL, ""); } biterror = true; From 6155f7b505d2741a353de67ab9f346ec3a0e4d27 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 12:42:56 +0200 Subject: [PATCH 080/759] reorder, we always put new lines from the top --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10fc67e9f..70e716b95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `hf xerox info` - read Fuji/Xerox tag (@horror) - Fixed `hf 14a reader --ecp` to work consistently (@kormax) - Change `trace list -t 14a` to annotate ECP frames of all valid V1 and V2 formats (@kormax) + - Added 122 new keys from Flipper Zero community to `mfc_default_keys.dic` (@UberGuidoZ) + - Added showing password for the read command in the `lf t55xx sniff` command (@merlokk) + - Added reading texcom tk13 and tk17 tags with `hf texkom read` command (@merlokk @iceman1001) + - Added simulating texcom tk13 and tk17 tags with `hf texkom sim` command (@merlokk) - Changed `hf mf staticnested` - significant speedups by using two encrypted nonces (@xianglin1998) - Change use of `sprintf` in code to `snprintf` to fix compilation on macOS (@Doridian) - Change `hf mf mad` - it now takes a dump file for offline MAD decoding (@iceman1001) @@ -69,10 +73,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed - AID limitations when using Gallagher key diversification (@DarkMatterMatt) - Added new standalone mode `lf_em4100rsww` (@zabszk) - Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz) - - Added 122 new keys from Flipper Zero community to `mfc_default_keys.dic` (@UberGuidoZ) - - Added showing password for the read command in the `lf t55xx sniff` command (@merlokk) - - Added reading texcom tk13 and tk17 tags with `hf texkom read` command (@merlokk @iceman1001) - - Added simulating texcom tk13 and tk17 tags with `hf texkom sim` command (@merlokk) + ## [Frostbit.4.14831][2022-01-11] - Changed Wiegand format lookup - now case-insensitive (@iceman1001) From 50429c8476fefdf4e368bf256846663ec57e5960 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 12:43:21 +0200 Subject: [PATCH 081/759] cppcheck fixes --- client/src/cmdhfxerox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfxerox.c b/client/src/cmdhfxerox.c index 1d3e91210..505aace8e 100644 --- a/client/src/cmdhfxerox.c +++ b/client/src/cmdhfxerox.c @@ -418,7 +418,7 @@ static inline char dec_digit(uint8_t dig) { return (dig <= 9) ? dig + '0' : '?'; } -static void gen_pn(uint8_t *data, char *pn) { +static void gen_pn(const uint8_t *data, char *pn) { pn[0] = dec_digit(data[0] >> 4); pn[1] = dec_digit(data[0] & 0xF); pn[2] = dec_digit(data[1] >> 4); From 167cca5fc0d8145d476543ae598cfe02d90d9015 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 13:45:06 +0200 Subject: [PATCH 082/759] cppchecker fixes --- armsrc/fpgaloader.c | 2 ++ armsrc/hfops.c | 16 +++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index a8abf0a7a..802c77558 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -613,10 +613,12 @@ void switch_off(void) { if (g_dbglevel > 3) { Dbprintf("switch_off"); } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); if (downloaded_bitstream == FPGA_BITSTREAM_HF || downloaded_bitstream == FPGA_BITSTREAM_HF_15) { FpgaDisableSscDma(); } + set_tracing(false); LEDsoff(); } diff --git a/armsrc/hfops.c b/armsrc/hfops.c index 591e80fda..cdc9aab8e 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -122,7 +122,7 @@ static uint32_t EncodeFinish(uint8_t *data) { return encode_indx; } -static uint32_t HfEncodeTkm(uint8_t *uid, uint8_t modulation, uint8_t *data) { +static uint32_t HfEncodeTkm(const uint8_t *uid, uint8_t modulation, uint8_t *data) { uint32_t len = 0; if (modulation == 0) { // TK-13 @@ -220,21 +220,23 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_212K); FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR); - int vHf = 0; // in mV bool button_pressed = false; bool exit_loop = false; bool field_on = false; + while (exit_loop == false) { button_pressed = BUTTON_PRESS(); - if (button_pressed || data_available()) + if (button_pressed || data_available()) { break; + } WDT_HIT(); - vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; + // in mV + int vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; if (vHf > MF_MINFIELDV) { - if (!field_on) { + if (field_on == false) { LED_A_ON(); SpinDelay(50); } @@ -248,10 +250,10 @@ int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { } SpinDelay(3); + for (int i = 0; i < elen;) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = data[i]; - i++; + AT91C_BASE_SSC->SSC_THR = data[i++]; } } } From c5119e5bead2073bd9d7ff8b903ce85094121d85 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 13:50:15 +0200 Subject: [PATCH 083/759] fix cid 390242 - uninitialized var usage --- armsrc/iso15693.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index ac81b494c..91dc22488 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -1673,7 +1673,7 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla dma_start_time = GetCountSspClk() & 0xfffffff0; } - volatile uint16_t sniffdata; + volatile uint16_t sniffdata = 0; volatile uint16_t sniffdata_prev = sniffdata; sniffdata = *upTo++; From 2494fef7fd9c10bbb58df322b55d82b42ed59209 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 13:55:59 +0200 Subject: [PATCH 084/759] fix cid 357754 --- client/src/cmdnfc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdnfc.c b/client/src/cmdnfc.c index a3f6ffd05..ab5ad1ac5 100644 --- a/client/src/cmdnfc.c +++ b/client/src/cmdnfc.c @@ -107,7 +107,7 @@ static int CmdNfcDecode(const char *Cmd) { uint8_t *dump = NULL; size_t bytes_read = 4096; res = pm3_load_dump(filename, (void **)&dump, &bytes_read, 4096); - if (res != PM3_SUCCESS) { + if (res != PM3_SUCCESS || dump == NULL) { return res; } From edffa21598688214b1f7e4cec312e6b85beb3d90 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 14:00:19 +0200 Subject: [PATCH 085/759] fix cid 395490, and 14a simulation --- armsrc/iso14443a.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 6d982a3b9..4af72bfba 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -927,9 +927,13 @@ bool GetIso14443aCommandFromReader(uint8_t *received, uint8_t *par, int *len) { (void)b; uint8_t flip = 0; - uint16_t checker = 0; + uint16_t checker = 4000; for (;;) { + WDT_HIT(); + + // ever 3 * 4000, check if we got any data from client + // takes long time, usually messes with simualtion if (flip == 3) { if (data_available()) return false; @@ -937,14 +941,14 @@ bool GetIso14443aCommandFromReader(uint8_t *received, uint8_t *par, int *len) { flip = 0; } - if (checker >= 3000) { + // button press, takes a bit time, might mess with simualtion + if (checker-- == 0) { if (BUTTON_PRESS()) return false; flip++; - checker = 0; + checker = 4000; } - ++checker; if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; @@ -2461,7 +2465,7 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par, bool use_ecp, bool use_mags uint8_t deselect_cmd[] = {0xc2, 0xe0, 0xb4}; ReaderTransmit(deselect_cmd, sizeof(deselect_cmd), NULL); // Read response if present - ReaderReceive(resp, resp_par); + (void) ReaderReceive(resp, resp_par); } uint32_t save_iso14a_timeout = iso14a_get_timeout(); From 2d4db27539697020939b8ca4484f64bd99a7fe6d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 14:56:08 +0200 Subject: [PATCH 086/759] fix hex printing --- client/src/util.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/src/util.c b/client/src/util.c index 0565dc129..dab5fef58 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -278,14 +278,20 @@ static void print_buffer_ex(const uint8_t *data, const size_t len, int level, ui char buf[UTIL_BUFFER_SIZE_SPRINT + 3]; int i; for (i = 0; i < len; i += breaks) { + + memset(buf, 0x00, sizeof(buf)); + if (len - i < breaks) { // incomplete block, will be treated out of the loop break; } + // (16 * 3) + (16) + + 1 snprintf(buf, sizeof(buf), "%*s%02x: ", (level * 4), " ", i); hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, breaks, (sizeof(buf) - strlen(buf) - 1), 0, 1, true); + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, breaks)); + PrintAndLogEx(INFO, "%s", buf); } From 8065d7eda0ca0c5b969a59032a9cdad2075595e3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 14:56:42 +0200 Subject: [PATCH 087/759] trying to free a pointer --- client/src/crypto/asn1utils.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/client/src/crypto/asn1utils.c b/client/src/crypto/asn1utils.c index 2928a3c40..55aa0d0f9 100644 --- a/client/src/crypto/asn1utils.c +++ b/client/src/crypto/asn1utils.c @@ -37,9 +37,10 @@ int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *r if (p == NULL) { return PM3_EMALLOC; } - + memcpy(p, signature, signaturelen); - const unsigned char *end = p + signaturelen; + uint8_t *p_tmp = p; + const uint8_t *end = p + signaturelen; int res = PM3_SUCCESS; size_t len = 0; @@ -72,13 +73,15 @@ int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *r // check size if (end != p) { - free(p); + free(p_tmp); + end = NULL; return PM3_ESOFT; } } exit: -// free(p); + free(p_tmp); + end = NULL; return res; } From 346b929c4df682474906d882adbd3709b715b34c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 6 Jul 2022 14:57:12 +0200 Subject: [PATCH 088/759] see if this silences coverity --- client/src/cmdhfemrtd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index ed2fb00d6..3216f68ae 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -2083,6 +2083,11 @@ int infoHF_EMRTD_offline(const char *path) { return PM3_ESOFT; } + // coverity scan CID 395630, + if (data != NULL) { + return PM3_ESOFT; + } + res = emrtd_parse_ef_sod_hashes(data, datalen, *dg_hashes_sod, &hash_algo); if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Failed to read hash list from EF_SOD. Hash checks will fail."); From a88cc901d98b7a92b5a74619a637e57dd1953fdf Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 6 Jul 2022 18:55:35 +0300 Subject: [PATCH 089/759] update sending parameters --- client/src/cmdhftexkom.c | 46 +++++++++++++++------------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 3dfba4c2c..41bf1efe3 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -568,15 +568,22 @@ static int CmdHFTexkomSim(const char *Cmd) { arg_lit0("t", "tk17", "Use TK-17 modulation (TK-13 by default)"), arg_str0(NULL, "raw", "", "Raw data for texkom card, 8 bytes. Manual modulation select."), arg_str0(NULL, "id", "", "Raw data for texkom card, 8 bytes. Manual modulation select."), + arg_int0(NULL, "timeout", "", "Simulation timeout in the ms. If not specified or 0 - infinite. Command can be skipped by pressing the button"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); + // + struct p { + uint8_t data[8]; + uint8_t modulation; + uint32_t timeout; + } PACKED payload = {}; + bool verbose = arg_get_lit(ctx, 1); - uint32_t cmdtimeout = 0; - uint8_t modulation = 0; // tk-13 + payload.modulation = 0; // tk-13 if (arg_get_lit(ctx, 2)) - modulation = 1; //tk-17 + payload.modulation = 1; //tk-17 uint8_t rawdata[250] = {0}; int rawdatalen = 0; @@ -586,6 +593,8 @@ static int CmdHFTexkomSim(const char *Cmd) { int iddatalen = 0; CLIGetHexWithReturn(ctx, 4, iddata, &iddatalen); + payload.timeout = arg_get_int_def(ctx, 5, 0); + CLIParserFree(ctx); if (rawdatalen == 0 && iddatalen == 0) { @@ -601,9 +610,9 @@ static int CmdHFTexkomSim(const char *Cmd) { if (iddatalen == 4) { rawdata[0] = 0xff; rawdata[1] = 0xff; - rawdata[2] = (modulation == 0) ? 0x63 : 0xCA; + rawdata[2] = (payload.modulation == 0) ? 0x63 : 0xCA; memcpy(&rawdata[3], iddata, 4); - rawdata[7] = (modulation == 0) ? TexcomTK13CRC(iddata) : TexcomTK17CRC(iddata); + rawdata[7] = (payload.modulation == 0) ? TexcomTK13CRC(iddata) : TexcomTK17CRC(iddata); rawdatalen = 8; } @@ -612,33 +621,12 @@ static int CmdHFTexkomSim(const char *Cmd) { return PM3_EINVARG; } - //iceman, use a struct - /* - struct p { - uint8_t modulation; - uint32_t timeout; - uint8_t data[8]; - } PACKED payload; - - payload.modulation = modulation; - payload.timeout = cmdtimeout; - memcpy(payload.data, rawdata, sizeof(payload.data)); + memcpy(payload.data, rawdata, 8); + clearCommandBuffer(); SendCommandNG(CMD_HF_TEXKOM_SIMULATE, (uint8_t*)&payload, sizeof(payload)); - // Iceman, cmdtimeout is always 0. You never set it - */ - - // - uint8_t data[13] = {0}; - memcpy(data, rawdata, 8); - - data[8] = modulation; - memcpy(&data[9], &cmdtimeout, 4); - clearCommandBuffer(); - SendCommandNG(CMD_HF_TEXKOM_SIMULATE, data, sizeof(data)); - - if (cmdtimeout > 0 && cmdtimeout < 2800) { + if (payload.timeout > 0 && payload.timeout < 2800) { PacketResponseNG resp; if (WaitForResponseTimeout(CMD_HF_TEXKOM_SIMULATE, &resp, 3000) == false) { if (verbose) { From 7c2379ac9f441b8e95f73a8cee3b751149760580 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 6 Jul 2022 19:03:17 +0300 Subject: [PATCH 090/759] rename and read parameters via struct --- armsrc/appmain.c | 10 +++++++--- armsrc/hfops.c | 2 +- armsrc/hfops.h | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 5e84aec4e..106fe3903 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1393,9 +1393,13 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_TEXKOM_SIMULATE: { - uint32_t timeout = 0; - memcpy(&timeout, &packet->data.asBytes[9], 4); - HfWriteTkm(packet->data.asBytes, packet->data.asBytes[8], timeout); + struct p { + uint8_t data[8]; + uint8_t modulation; + uint32_t timeout; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + HfSimulateTkm(payload->data, payload->modulation, payload->timeout); break; } diff --git a/armsrc/hfops.c b/armsrc/hfops.c index cdc9aab8e..ab7e5c9c4 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -200,7 +200,7 @@ static uint32_t HfEncodeTkm(const uint8_t *uid, uint8_t modulation, uint8_t *dat return len; } -int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { +int HfSimulateTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { // free eventually allocated BigBuf memory BigBuf_free_keep_EM(); diff --git a/armsrc/hfops.h b/armsrc/hfops.h index 91f1de539..352f9d2bc 100644 --- a/armsrc/hfops.h +++ b/armsrc/hfops.h @@ -22,6 +22,6 @@ #include "common.h" int HfReadADC(uint32_t samplesCount, bool ledcontrol); -int HfWriteTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout); +int HfSimulateTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout); #endif From 1a620c5563d5c97327df0866869ada3dc68590ca Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 6 Jul 2022 19:41:08 +0300 Subject: [PATCH 091/759] add timeout and some debug messages --- armsrc/hfops.c | 6 +++++- client/src/cmdhftexkom.c | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index ab7e5c9c4..a48b8eebd 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -224,6 +224,7 @@ int HfSimulateTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { bool exit_loop = false; bool field_on = false; + uint32_t startTime = GetTickCount(); while (exit_loop == false) { button_pressed = BUTTON_PRESS(); @@ -233,6 +234,9 @@ int HfSimulateTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { WDT_HIT(); + if (startTime > 0 && startTime + timeout < GetTickCount()) + break; + // in mV int vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; if (vHf > MF_MINFIELDV) { @@ -261,7 +265,7 @@ int HfSimulateTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { switch_off(); if (button_pressed) - DbpString("button pressed"); + DbpString("Exit by press button"); reply_ng(CMD_HF_TEXKOM_SIMULATE, PM3_SUCCESS, NULL, 0); diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 41bf1efe3..21bc87886 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -627,6 +627,7 @@ static int CmdHFTexkomSim(const char *Cmd) { SendCommandNG(CMD_HF_TEXKOM_SIMULATE, (uint8_t*)&payload, sizeof(payload)); if (payload.timeout > 0 && payload.timeout < 2800) { + PrintAndLogEx(INFO, "simulate command started"); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_HF_TEXKOM_SIMULATE, &resp, 3000) == false) { if (verbose) { @@ -636,7 +637,7 @@ static int CmdHFTexkomSim(const char *Cmd) { } PrintAndLogEx(INFO, "simulate command execution done"); } else { - PrintAndLogEx(INFO, "simulate command started"); + PrintAndLogEx(INFO, "simulate command started..."); } return PM3_SUCCESS; From 6ff336759f87ed1e3369d816694aeba8378a217d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 7 Jul 2022 15:28:03 +0200 Subject: [PATCH 092/759] fix ascii to print only the char C --- client/src/util.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/src/util.c b/client/src/util.c index dab5fef58..9f564d58f 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -454,6 +454,8 @@ char *sprint_bin(const uint8_t *data, const size_t len) { char *sprint_hex_ascii(const uint8_t *data, const size_t len) { static char buf[UTIL_BUFFER_SIZE_SPRINT + 20] = {0}; memset(buf, 0x00, sizeof(buf)); + + char *tmp = buf; size_t max_len = (len > 1010) ? 1010 : len; int ret = snprintf(buf, sizeof(buf) - 1, "%s| ", sprint_hex(data, max_len)); @@ -466,16 +468,17 @@ char *sprint_hex_ascii(const uint8_t *data, const size_t len) { while (i < max_len) { char c = data[i]; - buf[pos + i] = ((c < 32) || (c == 127)) ? '.' : 'c'; + tmp[pos + i] = ((c < 32) || (c == 127)) ? '.' : c; ++i; } - out: return buf; } char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len) { static char buf[UTIL_BUFFER_SIZE_SPRINT] = {0}; + memset(buf, 0x00, sizeof(buf)); + char *tmp = buf; size_t max_len = (len > 1010) ? 1010 : len; size_t i = 0; From 098a1e834337803dc7335ba78f580d046f5fc97e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 7 Jul 2022 16:41:43 +0200 Subject: [PATCH 093/759] added mfd aes brute tool to coverity scan --- covbuild.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/covbuild.sh b/covbuild.sh index b96e7059f..f3fbee6ba 100755 --- a/covbuild.sh +++ b/covbuild.sh @@ -27,6 +27,7 @@ cov-build --dir "$COVDIR" --no-generate-build-id --force make recovery cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --no-generate-build-id --force make CC=$HOSTCC CXX=$HOSTCXX LD=$HOSTLD mfkey cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --no-generate-build-id --force make CC=$HOSTCC CXX=$HOSTCXX LD=$HOSTLD nonce2key cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --no-generate-build-id --force make CC=$HOSTCC CXX=$HOSTCXX LD=$HOSTLD mf_nonce_brute +cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --no-generate-build-id --force make CC=$HOSTCC CXX=$HOSTCXX LD=$HOSTLD mfd_aes_brute cov-build --dir "$COVDIR" --c-coverage=gcov --no-network-coverage --no-generate-build-id --force make CC=$HOSTCC CXX=$HOSTCXX LD=$HOSTLD client ######################################### From 9b2bf3e544f8e344e7546cacfd6c02e26413be10 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 7 Jul 2022 22:45:15 +0200 Subject: [PATCH 094/759] adapted to hf search etc.. --- client/src/cmdhf.c | 8 ++ client/src/cmdhftexkom.c | 196 +++++++++++++++++++++++++++++++++++++-- client/src/cmdhftexkom.h | 9 +- 3 files changed, 205 insertions(+), 8 deletions(-) diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 31979a5cd..bb60c3ebe 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -165,6 +165,14 @@ int CmdHFSearch(const char *Cmd) { } } + // texkom + PROMPT_CLEARLINE; + PrintAndLogEx(INPLACE, " Searching for TEXCOM tag..."); + if (read_texkom_uid(false, false) == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("TEXCOM tag") " found\n"); + res = PM3_SUCCESS; + } + /* PROMPT_CLEARLINE; diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 21bc87886..fbf8fc09b 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -372,23 +372,205 @@ static void TexcomReverseCode(const uint8_t *code, int length, uint8_t *reverse_ } }; +static int texkom_get_type(texkom_card_select_t* card, bool verbose) { + + if (card == NULL) { + return PM3_EINVARG; + } + + // get samples from tag. + + uint32_t samplesCount = 30000; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ACQ_RAW_ADC, (uint8_t *)&samplesCount, sizeof(uint32_t)); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_HF_ACQ_RAW_ADC, &resp, 2500) == false) { + if (verbose) { + PrintAndLogEx(WARNING, "command execution time out"); + } + return PM3_ETIMEOUT; + } + + uint32_t size = (resp.data.asDwords[0]); + if (size > 0) { + if (getSamples(samplesCount, false) != PM3_SUCCESS) { + if (verbose) + PrintAndLogEx(ERR, "Get samples error"); + + return PM3_EFAILED; + }; + } + + // decode samples to 8 bytes + char bitstring[256] = {0}; + char cbitstring[128] = {0}; + char genbitstring[256] = {0}; + int found = TexkomModError; + uint32_t sindx = 0; + + while (sindx < samplesCount - 5) { + + sindx = TexkomSearchStart(sindx, TEXKOM_NOISE_THRESHOLD); + if (sindx == 0 || sindx > samplesCount - 5) { + if (TexkomAVGField() > 30 && verbose) { + PrintAndLogEx(WARNING, "Too noisy environment. Try to move the tag from the antenna a bit."); + } + break; + } + + uint32_t slen = TexkomSearchLength(sindx, TEXKOM_NOISE_THRESHOLD); + if (slen == 0) { + continue; + } + + uint32_t maxlvl = TexkomSearchMax(sindx, 1760); + if (maxlvl < TEXKOM_NOISE_THRESHOLD) { + sindx += 1700; + continue; + } + + uint32_t noiselvl = maxlvl / 5; + if (noiselvl < TEXKOM_NOISE_THRESHOLD) { + noiselvl = TEXKOM_NOISE_THRESHOLD; + } + + uint32_t implengths[256] = {}; + uint32_t implengthslen = 0; + uint32_t impulseindx = 0; + uint32_t impulsecnt = 0; + for (uint32_t i = 0; i < slen; i++) { + if (TexkomCorrelate(sindx + i, noiselvl)) { + impulsecnt++; + + if (impulseindx != 0) { + if (implengthslen < 256) { + implengths[implengthslen++] = sindx + i - impulseindx; + } + } + impulseindx = sindx + i; + } + } + + // check if it TK-17 modulation + // 65 impulses and 64 intervals (1 interval = 2 bits, interval length encoding) that represents 128 bit of card code + if (impulsecnt == 65) { + if (TexcomTK17Decode(implengths, implengthslen, bitstring, cbitstring, verbose)) { + found = TexkomModTK17; + break; + } + } + + // check if it TK-13 modulation + // it have 127 or 128 impulses and 128 double-intervals that represents 128 bit of card code + if (impulsecnt == 127 || impulsecnt == 128) { + if (TexcomTK13Decode(implengths, implengthslen, bitstring, cbitstring, verbose)) { + found = TexkomModTK13; + break; + } + } + + // general decoding. it thought that there is 2 types of intervals "long" (1) and "short" (0) + // and tries to decode sequence. shows only raw data + if (verbose) + TexcomGeneralDecode(implengths, implengthslen, genbitstring, verbose); + } + + if (found != TexkomModError) { + + for (uint32_t i = 0; i < strlen(cbitstring); i++) { + card->tcode[i / 8] = (card->tcode[i / 8] << 1) | ((cbitstring[i] == '1') ? 1 : 0); + } + + TexcomReverseCode(card->tcode, sizeof(card->tcode), card->rtcode); + return PM3_SUCCESS; + } + return PM3_ESOFT; +} + +int read_texkom_uid(bool loop, bool verbose) { + + do { + texkom_card_select_t card; + + int res = texkom_get_type(&card, verbose); + + if (loop) { + if (res != PM3_SUCCESS) { + continue; + } + } else { + switch (res) { + case PM3_EFAILED: + case PM3_EINVARG: + return res; + case PM3_ETIMEOUT: + if (verbose) { + PrintAndLogEx(WARNING, "command execution time out"); + } + return res; + case PM3_ESOFT: + if (verbose) { + PrintAndLogEx(WARNING, "texkom card select failed"); + } + return PM3_ESOFT; + default: + break; + } + } + + // decoding code + if (card.tcode[0] == 0xff && card.tcode[1] == 0xff) { + + bool crc = (TexcomTK13CRC(&card.tcode[3]) == card.tcode[7]); + + if (card.tcode[2] == 0x63) { + PrintAndLogEx(INFO, "TYPE..... TK13"); + PrintAndLogEx(INFO, "UID...... " _GREEN_("%s"), sprint_hex(&card.tcode[3], 4)); + if (verbose) { + PrintAndLogEx(INFO, "CRC...... %s", (crc) ? _GREEN_("ok") : _RED_("fail")); + } + } else if (card.tcode[2] == 0xCA) { + PrintAndLogEx(INFO, "TYPE..... TK17"); + PrintAndLogEx(INFO, "UID...... " _GREEN_("%s"), sprint_hex(&card.tcode[3], 4)); + if (verbose) { + PrintAndLogEx(INFO, "CRC...... %s", (crc) ? _GREEN_("ok") : _RED_("fail")); + } + } + PrintAndLogEx(INFO, "Raw... %s", sprint_hex(card.tcode, 8)); + PrintAndLogEx(INFO, "Raw Reversed... %s", sprint_hex(card.rtcode, 8)); + } + + } while (loop && kbd_enter_pressed() == false); + + return PM3_SUCCESS; +} + static int CmdHFTexkomReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf texkom reader", "Read a texkom tag", - "hf texkom reader"); + "hf texkom reader" + "hf texkom reader -@ -> continuous reader mode" + ); void *argtable[] = { arg_param_begin, arg_lit0("v", "verbose", "Verbose scan and output"), + arg_lit0("@", NULL, "optional - continuous reader mode"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); bool verbose = arg_get_lit(ctx, 1); + bool cm = arg_get_lit(ctx, 2); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } CLIParserFree(ctx); +// return read_texkom_uid(cm, true); + uint32_t samplesCount = 30000; clearCommandBuffer(); SendCommandNG(CMD_HF_ACQ_RAW_ADC, (uint8_t *)&samplesCount, sizeof(uint32_t)); @@ -494,7 +676,7 @@ static int CmdHFTexkomReader(const char *Cmd) { if (tcode[0] == 0xff && tcode[1] == 0xff) { // decoding code - if (!verbose) { + if (verbose == false) { PrintAndLogEx(INFO, "Texkom: %s", sprint_hex(tcode, 8)); PrintAndLogEx(INFO, "Texkom duplicator: %s", sprint_hex(rtcode, 8)); } @@ -508,8 +690,9 @@ static int CmdHFTexkomReader(const char *Cmd) { if (tcode[2] == 0x63) { // TK13 - if (codefound != TexkomModTK13) + if (codefound != TexkomModTK13) { PrintAndLogEx(WARNING, " mod type: WRONG"); + } PrintAndLogEx(INFO, "type : TK13"); PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); @@ -518,10 +701,11 @@ static int CmdHFTexkomReader(const char *Cmd) { else PrintAndLogEx(WARNING, "crc : WRONG"); - } else if (tcode[2] == 0xca) { + } else if (tcode[2] == 0xCA) { // TK17 - if (codefound != TexkomModTK17) + if (codefound != TexkomModTK17) { PrintAndLogEx(WARNING, " mod type: WRONG"); + } PrintAndLogEx(INFO, "type : TK17"); PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); @@ -551,7 +735,6 @@ static int CmdHFTexkomReader(const char *Cmd) { return PM3_SUCCESS; } - static int CmdHFTexkomSim(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf texkom sim", @@ -643,7 +826,6 @@ static int CmdHFTexkomSim(const char *Cmd) { return PM3_SUCCESS; } - static int CmdHelp(const char *Cmd); static command_t CommandTable[] = { diff --git a/client/src/cmdhftexkom.h b/client/src/cmdhftexkom.h index a90d36033..b8e96f45d 100644 --- a/client/src/cmdhftexkom.h +++ b/client/src/cmdhftexkom.h @@ -36,6 +36,13 @@ enum TexkomModulation { TexkomModTK17 }; -int CmdHFTexkom(const char *Cmd); +typedef struct { + uint8_t tcode[8]; + uint8_t rtcode[8]; + uint8_t tagtype; +} PACKED texkom_card_select_t; + +int CmdHFTexkom(const char *Cmd); +int read_texkom_uid(bool loop, bool verbose); #endif From 367c84bce3a2510cd361f63c0eea87507f697d7f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 7 Jul 2022 22:57:36 +0200 Subject: [PATCH 095/759] newline --- client/src/cmdhftexkom.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index fbf8fc09b..316f236d2 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -521,6 +521,10 @@ int read_texkom_uid(bool loop, bool verbose) { // decoding code if (card.tcode[0] == 0xff && card.tcode[1] == 0xff) { + if (loop == false) { + PrintAndLogEx(NORMAL, ""); + } + bool crc = (TexcomTK13CRC(&card.tcode[3]) == card.tcode[7]); if (card.tcode[2] == 0x63) { @@ -536,8 +540,10 @@ int read_texkom_uid(bool loop, bool verbose) { PrintAndLogEx(INFO, "CRC...... %s", (crc) ? _GREEN_("ok") : _RED_("fail")); } } - PrintAndLogEx(INFO, "Raw... %s", sprint_hex(card.tcode, 8)); - PrintAndLogEx(INFO, "Raw Reversed... %s", sprint_hex(card.rtcode, 8)); + if (verbose) { + PrintAndLogEx(INFO, "Raw... %s", sprint_hex(card.tcode, 8)); + PrintAndLogEx(INFO, "Raw Reversed... %s", sprint_hex(card.rtcode, 8)); + } } } while (loop && kbd_enter_pressed() == false); @@ -549,7 +555,7 @@ static int CmdHFTexkomReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf texkom reader", "Read a texkom tag", - "hf texkom reader" + "hf texkom reader\n" "hf texkom reader -@ -> continuous reader mode" ); From dca7e81d71f227a9df4cfed769472f2043308931 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 7 Jul 2022 23:06:15 +0200 Subject: [PATCH 096/759] enable continious mode and spelling mistakes --- client/src/cmdhf.c | 4 ++-- client/src/cmdhftexkom.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index bb60c3ebe..318e3a2f8 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -167,9 +167,9 @@ int CmdHFSearch(const char *Cmd) { // texkom PROMPT_CLEARLINE; - PrintAndLogEx(INPLACE, " Searching for TEXCOM tag..."); + PrintAndLogEx(INPLACE, " Searching for TEXKOM tag..."); if (read_texkom_uid(false, false) == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("TEXCOM tag") " found\n"); + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("TEXKOM tag") " found\n"); res = PM3_SUCCESS; } diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 316f236d2..ddb9100bd 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -570,12 +570,12 @@ static int CmdHFTexkomReader(const char *Cmd) { bool verbose = arg_get_lit(ctx, 1); bool cm = arg_get_lit(ctx, 2); - if (cm) { - PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); - } CLIParserFree(ctx); -// return read_texkom_uid(cm, true); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + return read_texkom_uid(cm, true); + } uint32_t samplesCount = 30000; clearCommandBuffer(); @@ -583,7 +583,7 @@ static int CmdHFTexkomReader(const char *Cmd) { PacketResponseNG resp; if (!WaitForResponseTimeout(CMD_HF_ACQ_RAW_ADC, &resp, 2500)) { - PrintAndLogEx(WARNING, "(hf texkom reader) command execution time out"); + PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } From 5f1c41503b1d674f501b4101be5f005eab25ea1d Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 8 Jul 2022 00:15:10 +0300 Subject: [PATCH 097/759] texkom simulation timeout and verbose fixes --- armsrc/hfops.c | 2 +- client/src/cmdhftexkom.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/hfops.c b/armsrc/hfops.c index a48b8eebd..6a97be76a 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -234,7 +234,7 @@ int HfSimulateTkm(uint8_t *uid, uint8_t modulation, uint32_t timeout) { WDT_HIT(); - if (startTime > 0 && startTime + timeout < GetTickCount()) + if (timeout > 0 && startTime + timeout < GetTickCount()) break; // in mV diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index ddb9100bd..fee7fca97 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -574,7 +574,7 @@ static int CmdHFTexkomReader(const char *Cmd) { if (cm) { PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); - return read_texkom_uid(cm, true); + return read_texkom_uid(cm, verbose); } uint32_t samplesCount = 30000; From 9fa8d9175b84dea682eee9f135ade182075d66b1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 8 Jul 2022 00:19:26 +0300 Subject: [PATCH 098/759] make style --- client/src/cmdhf.c | 2 +- client/src/cmdhf14b.c | 6 +++--- client/src/cmdhfemrtd.c | 4 ++-- client/src/cmdhftexkom.c | 16 ++++++++-------- client/src/cmdhfxerox.c | 6 +++--- client/src/crypto/asn1utils.c | 2 +- client/src/pm3line_vocabulory.h | 2 ++ client/src/util.c | 32 +++++++++++++++++++------------- doc/commands.json | 33 +++++++++++++++++++++++++-------- doc/commands.md | 1 + 10 files changed, 65 insertions(+), 39 deletions(-) diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 318e3a2f8..72af553f1 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -165,7 +165,7 @@ int CmdHFSearch(const char *Cmd) { } } - // texkom + // texkom PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, " Searching for TEXKOM tag..."); if (read_texkom_uid(false, false) == PM3_SUCCESS) { diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 831f87f8c..ac1ec0b9e 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -43,7 +43,7 @@ #define APDU_TIMEOUT 2000 // for static arrays -#define ST25TB_SR_BLOCK_SIZE 4 +#define ST25TB_SR_BLOCK_SIZE 4 // iso14b apdu input frame length static uint16_t apdu_frame_length = 0; @@ -458,7 +458,7 @@ static bool get_14b_UID(uint8_t *d, iso14b_type_t *found_type) { } } - // test CT + // test CT packet.flags = (ISO14B_CONNECT | ISO14B_SELECT_CTS | ISO14B_DISCONNECT); clearCommandBuffer(); SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)&packet, sizeof(iso14b_raw_cmd_t)); @@ -2164,7 +2164,7 @@ static command_t CommandTable[] = { {"sniff", CmdHF14BSniff, IfPm3Iso14443b, "Eavesdrop ISO-14443-B"}, {"rdbl", CmdHF14BSriRdBl, IfPm3Iso14443b, "Read SRI512/SRIX4x block"}, {"sriwrite", CmdHF14BWriteSri, IfPm3Iso14443b, "Write data to a SRI512 or SRIX4K tag"}, - {"view", CmdHF14BView, AlwaysAvailable, "Display content from tag dump file"}, + {"view", CmdHF14BView, AlwaysAvailable, "Display content from tag dump file"}, // {"valid", srix4kValid, AlwaysAvailable, "srix4k checksum test"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index 3216f68ae..cb656b169 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -716,7 +716,7 @@ static const uint8_t jpeg_header[4] = { 0xFF, 0xD8, 0xFF, 0xE0 }; static const uint8_t jpeg2k_header[6] = { 0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50 }; static int emrtd_dump_ef_dg2(uint8_t *file_contents, size_t file_length, const char *path) { - size_t offset; + size_t offset; int datalen = 0; // This is a hacky impl that just looks for the image header. I'll improve it eventually. @@ -2083,7 +2083,7 @@ int infoHF_EMRTD_offline(const char *path) { return PM3_ESOFT; } - // coverity scan CID 395630, + // coverity scan CID 395630, if (data != NULL) { return PM3_ESOFT; } diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index fee7fca97..18a1f5c48 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -372,7 +372,7 @@ static void TexcomReverseCode(const uint8_t *code, int length, uint8_t *reverse_ } }; -static int texkom_get_type(texkom_card_select_t* card, bool verbose) { +static int texkom_get_type(texkom_card_select_t *card, bool verbose) { if (card == NULL) { return PM3_EINVARG; @@ -474,7 +474,7 @@ static int texkom_get_type(texkom_card_select_t* card, bool verbose) { if (verbose) TexcomGeneralDecode(implengths, implengthslen, genbitstring, verbose); } - + if (found != TexkomModError) { for (uint32_t i = 0; i < strlen(cbitstring); i++) { @@ -483,7 +483,7 @@ static int texkom_get_type(texkom_card_select_t* card, bool verbose) { TexcomReverseCode(card->tcode, sizeof(card->tcode), card->rtcode); return PM3_SUCCESS; - } + } return PM3_ESOFT; } @@ -524,20 +524,20 @@ int read_texkom_uid(bool loop, bool verbose) { if (loop == false) { PrintAndLogEx(NORMAL, ""); } - + bool crc = (TexcomTK13CRC(&card.tcode[3]) == card.tcode[7]); if (card.tcode[2] == 0x63) { PrintAndLogEx(INFO, "TYPE..... TK13"); PrintAndLogEx(INFO, "UID...... " _GREEN_("%s"), sprint_hex(&card.tcode[3], 4)); if (verbose) { - PrintAndLogEx(INFO, "CRC...... %s", (crc) ? _GREEN_("ok") : _RED_("fail")); + PrintAndLogEx(INFO, "CRC...... %s", (crc) ? _GREEN_("ok") : _RED_("fail")); } } else if (card.tcode[2] == 0xCA) { PrintAndLogEx(INFO, "TYPE..... TK17"); PrintAndLogEx(INFO, "UID...... " _GREEN_("%s"), sprint_hex(&card.tcode[3], 4)); if (verbose) { - PrintAndLogEx(INFO, "CRC...... %s", (crc) ? _GREEN_("ok") : _RED_("fail")); + PrintAndLogEx(INFO, "CRC...... %s", (crc) ? _GREEN_("ok") : _RED_("fail")); } } if (verbose) { @@ -557,7 +557,7 @@ static int CmdHFTexkomReader(const char *Cmd) { "Read a texkom tag", "hf texkom reader\n" "hf texkom reader -@ -> continuous reader mode" - ); + ); void *argtable[] = { arg_param_begin, @@ -813,7 +813,7 @@ static int CmdHFTexkomSim(const char *Cmd) { memcpy(payload.data, rawdata, 8); clearCommandBuffer(); - SendCommandNG(CMD_HF_TEXKOM_SIMULATE, (uint8_t*)&payload, sizeof(payload)); + SendCommandNG(CMD_HF_TEXKOM_SIMULATE, (uint8_t *)&payload, sizeof(payload)); if (payload.timeout > 0 && payload.timeout < 2800) { PrintAndLogEx(INFO, "simulate command started"); diff --git a/client/src/cmdhfxerox.c b/client/src/cmdhfxerox.c index 505aace8e..ac2c3b75f 100644 --- a/client/src/cmdhfxerox.c +++ b/client/src/cmdhfxerox.c @@ -298,7 +298,7 @@ void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, c2l(iv, tout0); c2l(iv, tout1); iv -= 8; - + for (l -= 8; l >= 0; l -= 8) { c2l(in, tin0); c2l(in, tin1); @@ -414,7 +414,7 @@ static int findXerox(iso14b_card_select_t *card, bool disconnect) { static uint8_t info_blocks[] = { 0x15, 0x16, 0x17, 0x18, 0x22 }; static const char *c_type[] = { "drum", "yellow", "magenta", "cyan", "black" }; -static inline char dec_digit(uint8_t dig) { +static inline char dec_digit(uint8_t dig) { return (dig <= 9) ? dig + '0' : '?'; } @@ -569,7 +569,7 @@ static int CmdHFXeroxDump(const char *Cmd) { iso14b_card_select_t card; int status = findXerox(&card, false); // remain RF on if (status != PM3_SUCCESS) { - free(packet); + free(packet); switch_off_field(); return PM3_ERFTRANS; } diff --git a/client/src/crypto/asn1utils.c b/client/src/crypto/asn1utils.c index 55aa0d0f9..4618c5028 100644 --- a/client/src/crypto/asn1utils.c +++ b/client/src/crypto/asn1utils.c @@ -37,7 +37,7 @@ int ecdsa_asn1_get_signature(uint8_t *signature, size_t signaturelen, uint8_t *r if (p == NULL) { return PM3_EMALLOC; } - + memcpy(p, signature, signaturelen); uint8_t *p_tmp = p; const uint8_t *end = p + signaturelen; diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index c8619f164..982cbd734 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -156,6 +156,7 @@ const static vocabulory_t vocabulory[] = { { 0, "hf 14b sniff" }, { 0, "hf 14b rdbl" }, { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, { 1, "hf 15 help" }, { 1, "hf 15 list" }, { 1, "hf 15 demod" }, @@ -427,6 +428,7 @@ const static vocabulory_t vocabulory[] = { { 0, "hf topaz raw" }, { 1, "hf texkom help" }, { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, { 1, "hf xerox help" }, { 0, "hf xerox info" }, { 0, "hf xerox dump" }, diff --git a/client/src/util.c b/client/src/util.c index 9f564d58f..421cc84a3 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -94,13 +94,19 @@ static char b2s(uint8_t v, bool uppercase) { // clear higher bits v &= 0xF; - switch(v) { - case 0xA : return (uppercase ? 'A' : 'a') ; - case 0xB : return (uppercase ? 'B' : 'b') ; - case 0xC : return (uppercase ? 'C' : 'c') ; - case 0xD : return (uppercase ? 'D' : 'd') ; - case 0xE : return (uppercase ? 'E' : 'e') ; - case 0xF : return (uppercase ? 'F' : 'f') ; + switch (v) { + case 0xA : + return (uppercase ? 'A' : 'a') ; + case 0xB : + return (uppercase ? 'B' : 'b') ; + case 0xC : + return (uppercase ? 'C' : 'c') ; + case 0xD : + return (uppercase ? 'D' : 'd') ; + case 0xE : + return (uppercase ? 'E' : 'e') ; + case 0xF : + return (uppercase ? 'F' : 'f') ; default: return (char)(v + 0x30); } @@ -201,12 +207,12 @@ void hex_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, if (buf == NULL || hex_len < 1) return; - // 1. hex string length. + // 1. hex string length. // 2. byte array to be converted to string // size_t max_byte_len = (hex_len > hex_max_len) ? hex_max_len : hex_len; - size_t max_str_len = (max_byte_len * ( 2 + spaces_between )) + 1; + size_t max_str_len = (max_byte_len * (2 + spaces_between)) + 1; char *tmp_base = (char *)buf; char *tmp = tmp_base; @@ -291,7 +297,7 @@ static void print_buffer_ex(const uint8_t *data, const size_t len, int level, ui hex_to_buffer((uint8_t *)(buf + strlen(buf)), data + i, breaks, (sizeof(buf) - strlen(buf) - 1), 0, 1, true); snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "| %s", sprint_ascii(data + i, breaks)); - + PrintAndLogEx(INFO, "%s", buf); } @@ -453,13 +459,13 @@ char *sprint_bin(const uint8_t *data, const size_t len) { char *sprint_hex_ascii(const uint8_t *data, const size_t len) { static char buf[UTIL_BUFFER_SIZE_SPRINT + 20] = {0}; - memset(buf, 0x00, sizeof(buf)); + memset(buf, 0x00, sizeof(buf)); char *tmp = buf; size_t max_len = (len > 1010) ? 1010 : len; int ret = snprintf(buf, sizeof(buf) - 1, "%s| ", sprint_hex(data, max_len)); - if ( ret < 0) { + if (ret < 0) { goto out; } @@ -767,7 +773,7 @@ int param_gethex_to_eol(const char *line, int paramnum, uint8_t *data, int maxda int bg, en; - if (param_getptr(line, &bg, &en, paramnum)) + if (param_getptr(line, &bg, &en, paramnum)) return 1; *datalen = 0; diff --git a/doc/commands.json b/doc/commands.json index dfc8a4647..7b0472464 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -1295,7 +1295,7 @@ }, "hf 14b help": { "command": "hf 14b help", - "description": "help This help list List ISO-14443-B history", + "description": "help This help list List ISO-14443-B history view Display content from tag dump file", "notes": [], "offline": true, "options": [], @@ -1446,6 +1446,20 @@ ], "usage": "hf 14b sriwrite [-h] [-b ] -d [--512] [--4k] [--sb]" }, + "hf 14b view": { + "command": "hf 14b view", + "description": "Print a ISO14443-B dump file (bin/eml/json)", + "notes": [ + "hf 14b view -f hf-14b-01020304-dump.bin" + ], + "offline": true, + "options": [ + "-h, --help This help", + "-f, --file filename of dump", + "-v, --verbose verbose output" + ], + "usage": "hf 14b view [-hv] -f " + }, "hf 15 csetuid": { "command": "hf 15 csetuid", "description": "Set UID for magic Chinese card (only works with such cards)", @@ -6315,14 +6329,16 @@ "command": "hf texkom reader", "description": "Read a texkom tag", "notes": [ - "hf texkom reader" + "hf texkom reader", + "hf texkom reader -@ -> continuous reader mode" ], "offline": false, "options": [ "-h, --help This help", - "-v, --verbose Verbose scan and output" + "-v, --verbose Verbose scan and output", + "-@ optional - continuous reader mode" ], - "usage": "hf texkom reader [-hv]" + "usage": "hf texkom reader [-hv@]" }, "hf texkom sim": { "command": "hf texkom sim", @@ -6341,9 +6357,10 @@ "-v, --verbose Verbose work", "-t, --tk17 Use TK-17 modulation (TK-13 by default)", "--raw Raw data for texkom card, 8 bytes. Manual modulation select.", - "--id Raw data for texkom card, 8 bytes. Manual modulation select." + "--id Raw data for texkom card, 8 bytes. Manual modulation select.", + "--timeout Simulation timeout in the ms. If not specified or 0 - infinite. Command can be skipped by pressing the button" ], - "usage": "hf texkom sim [-hvt] [--raw ] [--id ]" + "usage": "hf texkom sim [-hvt] [--raw ] [--id ] [--timeout ]" }, "hf thinfilm help": { "command": "hf thinfilm help", @@ -11076,8 +11093,8 @@ } }, "metadata": { - "commands_extracted": 699, + "commands_extracted": 700, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-07-03T21:31:15" + "extracted_on": "2022-07-07T21:17:54" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 4f03dee72..3ff0c57cf 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -207,6 +207,7 @@ Check column "offline" for their availability. |`hf 14b sniff `|N |`Eavesdrop ISO-14443-B` |`hf 14b rdbl `|N |`Read SRI512/SRIX4x block` |`hf 14b sriwrite `|N |`Write data to a SRI512 or SRIX4K tag` +|`hf 14b view `|Y |`Display content from tag dump file` ### hf 15 From 4697994ec794e62d039b59d594369d3cc741d44e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 7 Jul 2022 23:26:10 +0200 Subject: [PATCH 099/759] added hf xerox reader, and added it to hf search --- client/src/cmdhf.c | 9 ++++++ client/src/cmdhf14b.c | 1 + client/src/cmdhfxerox.c | 66 +++++++++++++++++++++++++++++++++++++---- client/src/cmdhfxerox.h | 1 + 4 files changed, 71 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 72af553f1..e10524f4a 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -173,6 +173,15 @@ int CmdHFSearch(const char *Cmd) { res = PM3_SUCCESS; } + // xerox + PROMPT_CLEARLINE; + PrintAndLogEx(INPLACE, " Searching for Fuji/Xerox tag..."); + if (IfPm3Iso14443b()) { + if (read_xerox_uid(false, false) == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Fuji/Xerox tag") " found\n"); + res = PM3_SUCCESS; + } + } /* PROMPT_CLEARLINE; diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index ac1ec0b9e..14237c0fe 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -1181,6 +1181,7 @@ static int CmdHF14BReader(const char *Cmd) { CLIParserInit(&ctx, "hf 14b reader", "Act as a 14443B reader to identify a tag", "hf 14b reader\n" + "hf 14b reader -@ -> continuous reader mode" ); void *argtable[] = { diff --git a/client/src/cmdhfxerox.c b/client/src/cmdhfxerox.c index ac2c3b75f..5f9fde1e8 100644 --- a/client/src/cmdhfxerox.c +++ b/client/src/cmdhfxerox.c @@ -437,11 +437,62 @@ static void gen_pn(const uint8_t *data, char *pn) { pn[12] = 0; } +int read_xerox_uid(bool loop, bool verbose) { + + do { + iso14b_card_select_t card; + int status = findXerox(&card, true); + + if (loop) { + if (status != PM3_SUCCESS) { + continue; + } + } + + if (loop == false) { + PrintAndLogEx(NORMAL, ""); + } + PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen)); + PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb))); + + } while (loop && kbd_enter_pressed() == false); + + return PM3_SUCCESS; +} + +static int CmdHFXeroxReader(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf xerox reader", + "Act as a 14443B reader to identify a tag", + "hf xerox reader\n" + "hf xerox reader -@ \n" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0("v", "verbose", "verbose output"), + arg_lit0("@", NULL, "optional - continuous reader mode"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool verbose = arg_get_lit(ctx, 1); + bool cm = arg_get_lit(ctx, 2); + CLIParserFree(ctx); + + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + + return read_xerox_uid(cm, verbose); +} + static int CmdHFXeroxInfo(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf xerox info", - "Act as a reader.", - "hf xerox info"); + "Tag information for ISO/IEC 14443 type B / XEROX based tags", + "hf xerox info" + ); void *argtable[] = { arg_param_begin, @@ -495,7 +546,9 @@ static int CmdHFXeroxInfo(const char *Cmd) { resp.cmd, resp.length, resp.magic, resp.status, resp.crc, resp.oldarg[0], resp.oldarg[1], resp.oldarg[2], resp.data.asBytes[0], resp.data.asBytes[1], resp.data.asBytes[2], resp.ng ? 't' : 'f'); */ - if (/*resp.status != 0 ||*/ resp.length < 7) { // 14b raw command send data_len instead of status + + // 14b raw command send data_len instead of status + if (/*resp.status != 0 ||*/ resp.length < 7) { PrintAndLogEx(FAILED, "retrying one more time"); continue; } @@ -738,9 +791,10 @@ static int CmdHFXeroxDump(const char *Cmd) { } static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"info", CmdHFXeroxInfo, IfPm3Iso14443b, "Short info on Fuji/Xerox tag"}, - {"dump", CmdHFXeroxDump, IfPm3Iso14443b, "Read all memory pages of an Fuji/Xerox tag, save to file"}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"info", CmdHFXeroxInfo, IfPm3Iso14443b, "Short info on Fuji/Xerox tag"}, + {"reader", CmdHFXeroxReader, IfPm3Iso14443b, "Act like a Fuji/Xerox reader"}, + {"dump", CmdHFXeroxDump, IfPm3Iso14443b, "Read all memory pages of an Fuji/Xerox tag, save to file"}, // {"rdbl", CmdHFXeroxRdBl, IfPm3Iso14443b, "Read Fuji/Xerox block"}, // {"wrbl", CmdHFXeroxWrBl, IfPm3Iso14443b, "Write Fuji/Xerox block"}, {NULL, NULL, NULL, NULL} diff --git a/client/src/cmdhfxerox.h b/client/src/cmdhfxerox.h index 68b9906c8..6e3d55635 100644 --- a/client/src/cmdhfxerox.h +++ b/client/src/cmdhfxerox.h @@ -8,5 +8,6 @@ #include "common.h" int CmdHFXerox(const char *Cmd); +int read_xerox_uid(bool loop, bool verbose); #endif From 11e097c1bb66e8322dfc042d9d96a63af66f821f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 7 Jul 2022 23:43:45 +0200 Subject: [PATCH 100/759] fixing hf search loop and lessing the debug statements --- armsrc/iso14443b.c | 8 ++++++-- client/src/cmdhfxerox.c | 13 ++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 0372189a5..760736a5a 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -1865,14 +1865,18 @@ int iso14443b_select_xrx_card(iso14b_card_select_t *card) { if (4 == slot) { FpgaDisableTracing(); - DbpString("no answer to anticollision"); + if (g_dbglevel >= DBG_DEBUG) { + DbpString("no answer to anticollision"); + } return 1; } } retlen = Get14443bAnswerFromTag(x_atqb, sizeof(x_atqb), iso14b_timeout, &eof_time); - Dbprintf("anticollision uid %llx", uid); + if (g_dbglevel >= DBG_DEBUG) { + Dbprintf("anticollision uid %llx", uid); + } // ATQB too short? if (retlen < 18) { diff --git a/client/src/cmdhfxerox.c b/client/src/cmdhfxerox.c index 5f9fde1e8..5b7f39abe 100644 --- a/client/src/cmdhfxerox.c +++ b/client/src/cmdhfxerox.c @@ -447,13 +447,16 @@ int read_xerox_uid(bool loop, bool verbose) { if (status != PM3_SUCCESS) { continue; } - } + } else { - if (loop == false) { - PrintAndLogEx(NORMAL, ""); + if (status == PM3_SUCCESS) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen)); + PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb))); + } else { + return PM3_ESOFT; + } } - PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen)); - PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb))); } while (loop && kbd_enter_pressed() == false); From e17fc29e41c50ff08eea518fcc4a28aca5c0d29d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 9 Jul 2022 12:25:03 +0200 Subject: [PATCH 101/759] added the skeleton for fudan card support --- client/CMakeLists.txt | 1 + client/Makefile | 3 +- client/src/cmdhf.c | 2 + client/src/cmdhf14a.c | 14 +- client/src/cmdhffudan.c | 420 ++++++++++++++++++++++++++++++++++++++++ client/src/cmdhffudan.h | 29 +++ client/src/fileutils.c | 35 ++++ client/src/fileutils.h | 1 + 8 files changed, 498 insertions(+), 7 deletions(-) create mode 100644 client/src/cmdhffudan.c create mode 100644 client/src/cmdhffudan.h diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 3d535f8ea..a34348413 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -275,6 +275,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdhfepa.c ${PM3_ROOT}/client/src/cmdhffelica.c ${PM3_ROOT}/client/src/cmdhffido.c + ${PM3_ROOT}/client/src/cmdhffudan.c ${PM3_ROOT}/client/src/cmdhfgallagher.c ${PM3_ROOT}/client/src/cmdhfcipurse.c ${PM3_ROOT}/client/src/cmdhficlass.c diff --git a/client/Makefile b/client/Makefile index 3f57cd1bd..b1d7bb671 100644 --- a/client/Makefile +++ b/client/Makefile @@ -365,7 +365,7 @@ endif CFLAGS ?= $(DEFCFLAGS) # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: PM3CFLAGS = $(CFLAGS) -PM3CFLAGS += -I./src -I./include -I../include -I../common -I../common_fpga $(PM3INCLUDES) $(INCLUDES) +PM3CFLAGS += -g -I./src -I./include -I../include -I../common -I../common_fpga $(PM3INCLUDES) $(INCLUDES) # WIP Testing #PM3CFLAGS += -std=c11 -pedantic @@ -557,6 +557,7 @@ SRCS = mifare/aiddesfire.c \ cmdhfemrtd.c \ cmdhffelica.c \ cmdhffido.c \ + cmdhffudan.c \ cmdhfgallagher.c \ cmdhfksx6924.c \ cmdhfcipurse.c \ diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index e10524f4a..37560f785 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -49,6 +49,7 @@ #include "cmdhfwaveshare.h" // Waveshare #include "cmdhftexkom.h" // Texkom #include "cmdhfxerox.h" // Xerox +#include "cmdhffudan.h" // Fudan cards #include "cmdtrace.h" // trace list #include "ui.h" #include "proxgui.h" @@ -439,6 +440,7 @@ static command_t CommandTable[] = { {"emrtd", CmdHFeMRTD, AlwaysAvailable, "{ Machine Readable Travel Document... }"}, {"felica", CmdHFFelica, AlwaysAvailable, "{ ISO18092 / FeliCa RFIDs... }"}, {"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"}, + {"fudan", CmdHFFudan, AlwaysAvailable, "{ Fudan RFIDs... }"}, {"gallagher", CmdHFGallagher, AlwaysAvailable, "{ Gallagher DESFire RFIDs... }"}, {"ksx6924", CmdHFKSX6924, AlwaysAvailable, "{ KS X 6924 (T-Money, Snapper+) RFIDs }"}, {"jooki", CmdHF_Jooki, AlwaysAvailable, "{ Jooki RFIDs... }"}, diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 42c19781a..3fe0840d6 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -18,9 +18,9 @@ #include "cmdhf14a.h" #include #include -#include "cmdparser.h" // command_t -#include "commonutil.h" // ARRAYLEN -#include "comms.h" // clearCommandBuffer +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "comms.h" // clearCommandBuffer #include "cmdtrace.h" #include "cliparser.h" #include "cmdhfmf.h" @@ -29,9 +29,9 @@ #include "emv/emvcore.h" #include "ui.h" #include "crc16.h" -#include "util_posix.h" // msclock +#include "util_posix.h" // msclock #include "aidsearch.h" -#include "cmdhf.h" // handle HF plot +#include "cmdhf.h" // handle HF plot #include "cliparser.h" #include "protocols.h" // definitions of ISO14A/7816 protocol, MAGIC_GEN_1A #include "iso7816/apduinfo.h" // GetAPDUCodeDescription @@ -2301,7 +2301,8 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`emv search -s`")); if (isFUDAN) { - PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf 14a raw`") " - since FUDAN is different"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf fudan dump`")); + /* PrintAndLogEx(HINT, " hf 14a raw -a -b 7 -k 26"); PrintAndLogEx(HINT, " hf 14a raw -k -c 3000"); PrintAndLogEx(HINT, " hf 14a raw -k -c 3001"); @@ -2311,6 +2312,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { PrintAndLogEx(HINT, " hf 14a raw -k -c 3005"); PrintAndLogEx(HINT, " hf 14a raw -k -c 3006"); PrintAndLogEx(HINT, " hf 14a raw -c 3007"); + */ } PrintAndLogEx(NORMAL, ""); diff --git a/client/src/cmdhffudan.c b/client/src/cmdhffudan.c new file mode 100644 index 000000000..e4847d16e --- /dev/null +++ b/client/src/cmdhffudan.c @@ -0,0 +1,420 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// High frequency proximity cards from ISO14443A / Fudan commands +//----------------------------------------------------------------------------- + +#include "cmdhffudan.h" + +#include +#include +#include +#include "cliparser.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "cmdhf14a.h" +#include "cmddata.h" +#include "mifare.h" // xiso +#include "cmdhf.h" // +#include "fileutils.h" // saveFile +#include "ui.h" +#include "commonutil.h" // MemLeToUint2byte +#include "protocols.h" // ISO14 defines +#include "crc16.h" // compute_crc +#include "util_posix.h" // msclock + +#define FUDAN_BLOCK_READ_RETRY 3 +#define MAX_FUDAN_BLOCK_SIZE 4 +#define MAX_FUDAN_05_BLOCKS 8 // 16 +#define MAX_FUDAN_08_BLOCKS 64 + +#ifndef AddCrc14A +# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1) +#endif + + +// iceman: these types are quite unsure. +typedef enum { + FM11RF005M, + FM11RF008M, + FM11RF005SH, + FM11RF08SH, + FUDAN_NONE, +} fudan_type_t; + +static void fudan_print_blocks(uint16_t n, uint8_t *d) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "----+-------------+-----------------"); + PrintAndLogEx(INFO, "blk | data | ascii"); + PrintAndLogEx(INFO, "----+-------------+-----------------"); + for (uint16_t b = 0; b < n; b++) { + PrintAndLogEx(INFO, "%3d | %s ", b, sprint_hex_ascii(d + (b * MAX_FUDAN_BLOCK_SIZE), MAX_FUDAN_BLOCK_SIZE)); + } + PrintAndLogEx(INFO, "----+-------------+-----------------"); + PrintAndLogEx(NORMAL, ""); +} + +static char* GenerateFilename(iso14a_card_select_t *card, const char *prefix, const char *suffix) { + if (card == NULL) { + return NULL; + } + char *fptr = calloc(sizeof(char) * (strlen(prefix) + strlen(suffix)) + sizeof(card->uid) * 2 + 1, sizeof(uint8_t)); + strcpy(fptr, prefix); + FillFileNameByUID(fptr, card->uid, suffix, card->uidlen); + return fptr; +} + +static fudan_type_t fudan_detected(iso14a_card_select_t *card) { + + if ((card->sak & 0x0A) == 0x0A) { + + uint8_t atqa = MemLeToUint2byte(card->atqa); + if ((atqa & 0x0003) == 0x0003) { + // Uses Shanghai algo + // printTag("FM11RF005SH (FUDAN Shanghai Metro)"); + return FM11RF005SH; + } else if ((atqa & 0x0005) == 0x0005) { + // printTag("FM11RF005M (FUDAN MIFARE Classic clone)"); + return FM11RF005M; + } else if ((atqa & 0x0008) == 0x0008) { + // printTag("FM11RF008M (FUDAN MIFARE Classic clone)"); + return FM11RF008M; + } + + } else if ((card->sak & 0x53) == 0x53) { + // printTag("FM11RF08SH (FUDAN)"); + return FM11RF08SH; + } + return FUDAN_NONE; +} + +static int fudan_get_type(iso14a_card_select_t *card, bool verbose) { + + if (card == NULL) { + return PM3_EINVARG; + } + + clearCommandBuffer(); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(DEBUG, "iso14443a card select failed"); + return PM3_ESOFT; + } + + memcpy(card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); + + /* + 0: couldn't read + 1: OK, with ATS + 2: OK, no ATS + 3: proprietary Anticollision + */ + uint64_t select_status = resp.oldarg[0]; + + if (select_status == 0) { + PrintAndLogEx(DEBUG, "iso14443a card select failed"); + DropField(); + return PM3_ESOFT; + } + + if (select_status == 3) { + if (verbose) { + PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision"); + PrintAndLogEx(SUCCESS, "ATQA: %02X %02X", card->atqa[1], card->atqa[0]); + } + DropField(); + return PM3_ESOFT; + } + + PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(card->uid, card->uidlen)); + if (verbose) { + PrintAndLogEx(SUCCESS, "ATQA: " _GREEN_("%02X %02X"), card->atqa[1], card->atqa[0]); + PrintAndLogEx(SUCCESS, " SAK: " _GREEN_("%02X [%" PRIu64 "]"), card->sak, select_status); + + if (card->ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes + if (card->ats_len == card->ats[0] + 2) + PrintAndLogEx(SUCCESS, " ATS: " _GREEN_("%s"), sprint_hex(card->ats, card->ats[0])); + else { + PrintAndLogEx(SUCCESS, " ATS: [%d] " _GREEN_("%s"), card->ats_len, sprint_hex(card->ats, card->ats_len)); + } + } + } + return PM3_SUCCESS; +} + +int read_fudan_uid(bool loop, bool verbose) { + + do { + iso14a_card_select_t card; + + int res = fudan_get_type(&card, verbose); + + if (loop) { + if (res != PM3_SUCCESS) { + continue; + } + } else { + switch (res) { + case PM3_EFAILED: + case PM3_EINVARG: + return res; + case PM3_ETIMEOUT: + PrintAndLogEx(DEBUG, "command execution time out"); + return res; + case PM3_ESOFT: + PrintAndLogEx(DEBUG, "fudan card select failed"); + return PM3_ESOFT; + default: + break; + } + } + + + if (loop) { + res = handle_hf_plot(); + if (res != PM3_SUCCESS) { + break; + } + } + + // decoding code + if (loop == false) { + PrintAndLogEx(NORMAL, ""); + } + + } while (loop && kbd_enter_pressed() == false); + + + return PM3_SUCCESS; +} + +static int CmdHFFudanReader(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fudan reader", + "Read a fudan tag", + "hf fudan reader\n" + "hf fudan reader -@ -> continuous reader mode" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0("v", "verbose", "Verbose scan and output"), + arg_lit0("@", NULL, "optional - continuous reader mode"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + bool verbose = arg_get_lit(ctx, 1); + bool cm = arg_get_lit(ctx, 2); + + CLIParserFree(ctx); + + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + return read_fudan_uid(cm, verbose); + } + + DropField(); + return PM3_SUCCESS; +} + +static int CmdHFFudanDump(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fudan dump", + "Dump FUDAN tag to binary file\n" + "If no given, UID will be used as filename", + "hf fudan dump -f mydump --> dump using filename\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_str0("f", "file", "", "filename of dump"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + int datafnlen = 0; + char dataFilename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)dataFilename, FILE_PATH_SIZE, &datafnlen); + CLIParserFree(ctx); + + // Select card to get UID/UIDLEN/ATQA/SAK information + // leaves the field on + iso14a_card_select_t card; + int res = fudan_get_type(&card, false); + if (res != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "failed to select a fudan card. Exiting..."); + DropField(); + return PM3_SUCCESS; + } + + // validations + fudan_type_t t = fudan_detected(&card); + if (t == FUDAN_NONE) { + PrintAndLogEx(FAILED, "failed to detect a fudan card. Exiting..."); + DropField(); + return PM3_SUCCESS; + } + + // detect card size + // 512b, 8kbits + uint8_t num_blocks = MAX_FUDAN_05_BLOCKS; + switch(t) { + case FM11RF008M: + num_blocks = MAX_FUDAN_08_BLOCKS; + break; + case FM11RF005SH: + case FM11RF005M: + case FM11RF08SH: + case FUDAN_NONE: + default: + break; + } + + uint8_t carddata[num_blocks * MAX_FUDAN_BLOCK_SIZE]; + +/* + PrintAndLogEx(HINT, " hf 14a raw -a -b 7 -k 26"); + PrintAndLogEx(HINT, " hf 14a raw -k -c 3000"); + PrintAndLogEx(HINT, " hf 14a raw -k -c 3001"); + PrintAndLogEx(HINT, " hf 14a raw -k -c 3002"); + PrintAndLogEx(HINT, " hf 14a raw -k -c 3003"); + PrintAndLogEx(HINT, " hf 14a raw -k -c 3004"); + PrintAndLogEx(HINT, " hf 14a raw -k -c 3005"); + PrintAndLogEx(HINT, " hf 14a raw -k -c 3006"); + PrintAndLogEx(HINT, " hf 14a raw -c 3007"); +*/ + + // + uint16_t flags = (ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS | ISO14A_RAW); + uint32_t argtimeout = 0; + uint32_t numbits = 0; + + PrintAndLogEx(SUCCESS, "." NOLF); + // dump memory + for (uint8_t b = 0; b < num_blocks; b++) { + + // read block + uint8_t cmd[4] = {ISO14443A_CMD_READBLOCK, b, 0x00, 0x00}; + AddCrc14A(cmd, 2); + + for (uint8_t tries = 0; tries < FUDAN_BLOCK_READ_RETRY; tries++) { + + clearCommandBuffer(); + PacketResponseNG resp; + SendCommandOLD(CMD_HF_ISO14443A_READER, flags, sizeof(cmd) | ((uint32_t)(numbits << 16)), argtimeout, cmd, sizeof(cmd)); + + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + if (resp.status == PM3_SUCCESS) { + uint8_t *data = resp.data.asBytes; + memcpy(carddata + (b * MAX_FUDAN_BLOCK_SIZE), data, MAX_FUDAN_BLOCK_SIZE); + PrintAndLogEx(NORMAL, "." NOLF); + break; + } else { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(FAILED, "could not read block %2d", b); + } + } else { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(WARNING, "command execute timeout when trying to read block %2d", b); + } + } + + } + DropField(); + + PrintAndLogEx(SUCCESS, "\nSucceeded in dumping all blocks"); + + fudan_print_blocks(num_blocks, carddata); + + // create filename if none was given + if (strlen(dataFilename) < 1) { + char *fptr = GenerateFilename(&card, "hf-fudan-", "-dump"); + if (fptr == NULL) + return PM3_ESOFT; + + strcpy(dataFilename, fptr); + free(fptr); + } + + saveFile(dataFilename, ".bin", (uint8_t *)carddata, sizeof(carddata)); + saveFileEML(dataFilename, (uint8_t *)carddata, sizeof(carddata), MAX_FUDAN_BLOCK_SIZE); + + iso14a_mf_extdump_t xdump; + xdump.card_info = card; + xdump.dump = (uint8_t *)carddata; + xdump.dumplen = sizeof(carddata); + saveFileJSON(dataFilename, jsfFudan, (uint8_t *)&xdump, sizeof(xdump), NULL); + return PM3_SUCCESS; +} + +static int CmdHFFudanView(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fudan view", + "Print a FUDAN dump file (bin/eml/json)", + "hf fudan view -f hf-fudan-01020304-dump.bin" + ); + void *argtable[] = { + arg_param_begin, + arg_str1("f", "file", "", "filename of dump"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + int fnlen = 0; + char filename[FILE_PATH_SIZE]; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + CLIParserFree(ctx); + + // read dump file + uint8_t *dump = NULL; + size_t bytes_read = 0; + int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (MAX_FUDAN_BLOCK_SIZE * MAX_FUDAN_08_BLOCKS)); + if (res != PM3_SUCCESS) { + return res; + } + + uint16_t block_cnt = MIN(MAX_FUDAN_05_BLOCKS, (bytes_read / MAX_FUDAN_BLOCK_SIZE)); + + fudan_print_blocks(block_cnt, dump); + + free(dump); + return PM3_SUCCESS; +} + +static int CmdHelp(const char *Cmd); + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"reader", CmdHFFudanReader, IfPm3Iso14443a, "Act like a fudan reader"}, + {"dump", CmdHFFudanDump, IfPm3Iso14443a, "Dump FUDAN tag to binary file"}, + //{"sim", CmdHFFudanSim, IfPm3Iso14443a, "Simulate a fudan tag"}, + //{"rdbl", CmdHFFudanRead, IfPm3Iso14443a, "Read a fudan tag"}, + {"view", CmdHFFudanView, AlwaysAvailable, "Display content from tag dump file"}, + //{"wrbl", CmdHFFudanWrite, IfPm3Iso14443a, "Write a fudan tag"}, + {NULL, NULL, 0, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdHFFudan(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/src/cmdhffudan.h b/client/src/cmdhffudan.h new file mode 100644 index 000000000..afdd618bd --- /dev/null +++ b/client/src/cmdhffudan.h @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// High frequency proximity cards from ISO14443A / FUDAN commands +//----------------------------------------------------------------------------- + +#ifndef CMDHFFUDAN_H__ +#define CMDHFFUDAN_H__ + +#include "common.h" +#include "pm3_cmd.h" + +int CmdHFFudan(const char *Cmd); +int read_fudan_uid(bool loop, bool verbose); + +#endif + diff --git a/client/src/fileutils.c b/client/src/fileutils.c index 026193702..8e68ed03f 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -396,6 +396,19 @@ int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, } break; } + case jsfFudan: { + iso14a_mf_extdump_t *xdump = (iso14a_mf_extdump_t *)(void *) data; + JsonSaveStr(root, "FileType", "fudan"); + JsonSaveBufAsHexCompact(root, "$.Card.UID", xdump->card_info.uid, xdump->card_info.uidlen); + JsonSaveBufAsHexCompact(root, "$.Card.ATQA", xdump->card_info.atqa, 2); + JsonSaveBufAsHexCompact(root, "$.Card.SAK", &(xdump->card_info.sak), 1); + for (size_t i = 0; i < (xdump->dumplen / 4); i++) { + char path[PATH_MAX_LENGTH] = {0}; + snprintf(path, sizeof(path), "$.blocks.%zu", i); + JsonSaveBufAsHexCompact(root, path, &xdump->dump[i * 4], 4); + } + break; + } case jsfMfuMemory: { JsonSaveStr(root, "FileType", "mfu"); @@ -1108,6 +1121,28 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz *datalen = sptr; } + if (!strcmp(ctype, "fudan")) { + size_t sptr = 0; + for (int i = 0; i < 256; i++) { + if (sptr + 4 > maxdatalen) { + retval = PM3_EMALLOC; + goto out; + } + + char blocks[30] = {0}; + snprintf(blocks, sizeof(blocks), "$.blocks.%d", i); + + size_t len = 0; + JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); + if (!len) + break; + + sptr += len; + } + + *datalen = sptr; + } + if (!strcmp(ctype, "mfu")) { mfu_dump_t *mem = (mfu_dump_t *)udata; diff --git a/client/src/fileutils.h b/client/src/fileutils.h index c440c7c26..758dab84f 100644 --- a/client/src/fileutils.h +++ b/client/src/fileutils.h @@ -47,6 +47,7 @@ typedef enum { jsfEM4x69, jsfEM4x50, jsfFido, + jsfFudan, } JSONFileType; typedef enum { From 9e36458ee24c5f7990fa56332f145236fc76a5dc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 9 Jul 2022 12:25:39 +0200 Subject: [PATCH 102/759] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70e716b95..baa9edc3d 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] + - Added `hf fudan` skeleton commands (@iceman1001) - Added `--reboot-to-bootloader` arg to pm3 - Changed `hf 14b raw` - now supports selecting Fuji/Xerox tag (@horror) - Added `hf xerox dump` - dump a Fuji/Xerox tag (@horror) From cf58ba72f22ba705287f6aafa71bf32e0ed33156 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 9 Jul 2022 12:25:55 +0200 Subject: [PATCH 103/759] use defines --- client/src/cmdhfmfu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 38c2b7d4a..20b443787 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -437,7 +437,7 @@ static int ul_fudan_check(void) { if (!ul_select(&card)) return UL_ERROR; - uint8_t cmd[4] = {0x30, 0x00, 0x02, 0xa7}; //wrong crc on purpose should be 0xa8 + uint8_t cmd[4] = {ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa7}; //wrong crc on purpose should be 0xa8 clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 4, 0, cmd, sizeof(cmd)); PacketResponseNG resp; From 08c797a638a2f18d2b2b06eb34dd4be59a23f8ee Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 9 Jul 2022 13:47:44 +0200 Subject: [PATCH 104/759] now colors SR types of iclass --- client/src/cmdhficlass.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index cf17a2505..c79be251a 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -2494,7 +2494,8 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e if (i != 1) PrintAndLogEx(INFO, " ......"); - uint8_t fb = (iclass_dump + (6 * 8))[0]; + uint8_t fb1 = (iclass_dump + (6 * 8))[0]; + uint8_t fb2 = (iclass_dump + (10 * 8))[0]; while (i <= endblock) { uint8_t *blk = iclass_dump + (i * 8); @@ -2555,7 +2556,7 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e } else { const char *info_ks[] = {"CSN", "Config", "E-purse", "Debit", "Credit", "AIA", "User"}; - if (i >= 6 && i <= 9 && fb != 0x30) { + if (i >= 6 && i <= 9 && fb1 != 0x30) { // legacy credential PrintAndLogEx(INFO, "%3d/0x%02X | " _YELLOW_("%s") "| " _YELLOW_("%s") " | %s | User / Cred " , i @@ -2564,7 +2565,16 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e , sprint_ascii(blk, 8) , lockstr ); - } else if (i >= 6 && i <= 11 && fb == 0x30) { + } else if (i >= 6 && i <= 11 && fb1 == 0x30) { + // SIO credential + PrintAndLogEx(INFO, "%3d/0x%02X | " _CYAN_("%s") "| " _CYAN_("%s") " | %s | User / SIO" + , i + , i + , sprint_hex(blk, 8) + , sprint_ascii(blk, 8) + , lockstr + ); + } else if (i >= 10 && i <= 16 && fb2 == 0x30) { // SIO credential PrintAndLogEx(INFO, "%3d/0x%02X | " _CYAN_("%s") "| " _CYAN_("%s") " | %s | User / SIO" , i From dcea185ca2c942e086d1e160c24b5a501447a957 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 9 Jul 2022 14:14:48 +0200 Subject: [PATCH 105/759] fix viegand decoder in `hf iclass rdbl` --- client/src/cmdhficlass.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index c79be251a..59232669d 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -2363,23 +2363,21 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { if (memcmp(dec_data, empty, 8) != 0) { //todo: remove preamble/sentinel - - uint32_t top = 0, mid, bot; - mid = bytes_to_num(dec_data, 4); - bot = bytes_to_num(dec_data + 4, 4); + uint32_t top = 0, mid = 0, bot = 0; char hexstr[16 + 1] = {0}; hex_to_buffer((uint8_t *)hexstr, dec_data, 8, sizeof(hexstr) - 1, 0, 0, true); - char binstr[64 + 1] = {0}; - hextobinstring(binstr, hexstr); - size_t i = 0; - while (i < strlen(binstr) && binstr[i++] == '0'); + hexstring_to_u96(&top, &mid, &bot, hexstr); - i &= 0x3C; - PrintAndLogEx(SUCCESS, " bin : %s", binstr + i); + char binstr[64 + 1]; + hextobinstring(binstr, hexstr); + char *pbin = binstr; + while (strlen(pbin) && *(++pbin) == '0'); + + PrintAndLogEx(SUCCESS, " bin : %s", pbin); PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "------------------------------ " _CYAN_("wiegand") " -------------------------------"); - wiegand_message_t packed = initialize_message_object(top, mid, bot, strlen(binstr + i)); + wiegand_message_t packed = initialize_message_object(top, mid, bot, 0); HIDTryUnpack(&packed); } else { PrintAndLogEx(INFO, "no credential found"); From 0b95c519ff4a034dba64a8340cb63a08dcc39f38 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 9 Jul 2022 16:45:08 +0300 Subject: [PATCH 106/759] sh sniff skip some bytes from data - arm side --- armsrc/appmain.c | 4 +++- armsrc/hfsnoop.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- armsrc/hfsnoop.h | 9 ++++++++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 106fe3903..330bf2c48 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1784,11 +1784,13 @@ static void PacketReceived(PacketCommandNG *packet) { struct p { uint32_t samplesToSkip; uint32_t triggersToSkip; + uint8_t skipMode; + uint8_t skipRatio; } PACKED; struct p *payload = (struct p *)packet->data.asBytes; uint16_t len = 0; - int res = HfSniff(payload->samplesToSkip, payload->triggersToSkip, &len); + int res = HfSniff(payload->samplesToSkip, payload->triggersToSkip, &len, payload->skipMode, payload->skipRatio); struct { uint16_t len; diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index ba9ef0740..f12b4863b 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -36,7 +36,46 @@ static void RAMFUNC optimizedSniff(uint16_t *dest, uint16_t dsize) { } } -int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len) { +static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, uint8_t skipRatio) { + uint32_t accum = (skipMode == HF_SNOOP_SKIP_MIN) ? 0xffffffff : 0; + uint8_t ratioindx = 0; + while (dsize > 0) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + volatile uint16_t val = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); + switch (skipMode) { + case HF_SNOOP_SKIP_MAX: + if (accum < (val & 0xff)) + accum = val & 0xff; + if (accum < (val << 8)) + accum = val << 8; + case HF_SNOOP_SKIP_MIN: + if (accum > (val & 0xff)) + accum = val & 0xff; + if (accum > (val << 8)) + accum = val << 8; + case HF_SNOOP_SKIP_AVG: + accum += (val & 0xff) + (val << 8); + default: { // HF_SNOOP_SKIP_DROP and the rest + if (ratioindx == 0) + accum = val & 0xff; + } + } + + ratioindx++; + if (ratioindx >= skipRatio) { + ratioindx = 0; + if (skipMode == HF_SNOOP_SKIP_AVG) + *dest = accum / (skipRatio * 2); + else + *dest = accum; + dest++; + dsize --; + } + } + } +} + +int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len, uint8_t skipMode, uint8_t skipRatio) { BigBuf_free(); BigBuf_Clear_ext(false); @@ -105,7 +144,10 @@ int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len) { } } - optimizedSniff((uint16_t *)mem, *len); + if (skipMode == 0) + optimizedSniff((uint16_t *)mem, *len); + else + skipSniff(mem, *len, skipMode, skipRatio); if (g_dbglevel >= DBG_INFO) { Dbprintf("Trigger kicked in (%d >= 180)", r); diff --git a/armsrc/hfsnoop.h b/armsrc/hfsnoop.h index 4b715753d..a68d28a79 100644 --- a/armsrc/hfsnoop.h +++ b/armsrc/hfsnoop.h @@ -18,6 +18,13 @@ #include "proxmark3_arm.h" -int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len); +// what to do with skipped data +#define HF_SNOOP_SKIP_NONE (0) +#define HF_SNOOP_SKIP_DROP (1) +#define HF_SNOOP_SKIP_MAX (2) +#define HF_SNOOP_SKIP_MIN (3) +#define HF_SNOOP_SKIP_AVG (4) + +int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len, uint8_t skipMode, uint8_t skipRatio); void HfPlotDownload(void); #endif From e8b742414e36e94c94faa84c0e1a8d4f1c780b05 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:27:04 +0300 Subject: [PATCH 107/759] client part --- client/src/cmdhf.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 37560f785..419e52a4d 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -301,6 +301,23 @@ int CmdHFTune(const char *Cmd) { return PM3_SUCCESS; } +typedef enum { + HF_SNOOP_SKIP_NONE = 0x00, + HF_SNOOP_SKIP_DROP = 0x01, + HF_SNOOP_SKIP_MAX = 0x02, + HF_SNOOP_SKIP_MIN = 0x03, + HF_SNOOP_SKIP_AVG = 0x04 +} HFSnoopSkipMode; + +const CLIParserOption HFSnoopSkipModeOpts[] = { + {HF_SNOOP_SKIP_NONE, "none"}, + {HF_SNOOP_SKIP_DROP, "drop"}, + {HF_SNOOP_SKIP_MAX, "min"}, + {HF_SNOOP_SKIP_MIN, "max"}, + {HF_SNOOP_SKIP_AVG, "avg"}, + {0, NULL}, +}; + // Collects pars of u8, // uses 16bit transfers from FPGA for speed // Takes all available bigbuff memory @@ -317,8 +334,10 @@ int CmdHFSniff(const char *Cmd) { ); void *argtable[] = { arg_param_begin, - arg_u64_0(NULL, "sp", "", "skip sample pairs"), - arg_u64_0(NULL, "st", "", "skip number of triggers"), + arg_u64_0(NULL, "sp", "", "skip sample pairs"), + arg_u64_0(NULL, "st", "", "skip number of triggers"), + arg_str0(NULL, "smode", "[none|drop|min|max|avg]", "Skip mode. It switches on the function that applies to several samples before they saved to memory"), + arg_int0(NULL, "sratio", "", "Skip ratio. It applied the function above to (ratio * 2) samples. For ratio = 1 it 2 samples."), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -326,10 +345,20 @@ int CmdHFSniff(const char *Cmd) { struct { uint32_t samplesToSkip; uint32_t triggersToSkip; + uint8_t skipMode; + uint8_t skipRatio; } PACKED params; params.samplesToSkip = arg_get_u32_def(ctx, 1, 0); params.triggersToSkip = arg_get_u32_def(ctx, 2, 0); + int smode = 0; + if (CLIGetOptionList(arg_get_str(ctx, 3), HFSnoopSkipModeOpts, &smode)) + return PM3_EINVARG; + + if (smode > 0) + params.skipMode = smode; + + params.skipRatio = arg_get_int_def(ctx, 4, 0); CLIParserFree(ctx); clearCommandBuffer(); From 660858a02c62b858f60d1df1554990954630135e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:34:26 +0300 Subject: [PATCH 108/759] add some verbosity --- client/src/cmdhf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 419e52a4d..cd58e1647 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -361,6 +361,10 @@ int CmdHFSniff(const char *Cmd) { params.skipRatio = arg_get_int_def(ctx, 4, 0); CLIParserFree(ctx); + if (params.skipMode != HF_SNOOP_SKIP_NONE) + PrintAndLogEx(INFO, "Skip mode. Function: %s, each: %d sample", + CLIGetOptionListStr(HFSnoopSkipModeOpts, params.skipMode), params.skipRatio * 2); + clearCommandBuffer(); SendCommandNG(CMD_HF_SNIFF, (uint8_t *)¶ms, sizeof(params)); From 903af4412a6a0f9aec25dbdcb545b20b0b7eb74b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:36:53 +0300 Subject: [PATCH 109/759] fix accum clear --- armsrc/hfsnoop.c | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index f12b4863b..9d155237c 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -70,6 +70,7 @@ static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, u *dest = accum; dest++; dsize --; + accum = 0; } } } From c6386c68e0e814c493340ae715a9642a01807a48 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 9 Jul 2022 17:02:44 +0200 Subject: [PATCH 110/759] hf iclass textual and saving to files unified --- client/src/cmdhficlass.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 59232669d..95c78d5be 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -38,6 +38,7 @@ #include "proxendian.h" #include "iclass_cmd.h" +#define PICOPASS_BLOCK_SIZE 8 #define NUM_CSNS 9 #define ICLASS_KEYS_MAX 8 #define ICLASS_AUTH_RETRY 10 @@ -1076,9 +1077,7 @@ static int CmdHFiClassESave(const char *Cmd) { FillFileNameByUID(fptr, dump, "-dump", 8); } - saveFile(filename, ".bin", dump, bytes); - saveFileEML(filename, dump, bytes, 8); - saveFileJSON(filename, jsfIclass, dump, bytes, NULL); + pm3_save_dump(filename, dump, bytes, jsfIclass, PICOPASS_BLOCK_SIZE); free(dump); PrintAndLogEx(HINT, "Try `" _YELLOW_("hf iclass view -f") "` to view dump file"); @@ -1325,9 +1324,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { strcat(fptr, "hf-iclass-"); FillFileNameByUID(fptr, hdr->csn, "-dump-decrypted", sizeof(hdr->csn)); - saveFile(fptr, ".bin", decrypted, decryptedlen); - saveFileEML(fptr, decrypted, decryptedlen, 8); - saveFileJSON(fptr, jsfIclass, decrypted, decryptedlen, NULL); + pm3_save_dump(fptr, decrypted, decryptedlen, jsfIclass, PICOPASS_BLOCK_SIZE); printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); @@ -1879,9 +1876,8 @@ write_dump: // save the dump to .bin file PrintAndLogEx(SUCCESS, "saving dump file - %u blocks read", bytes_got / 8); - saveFile(filename, ".bin", tag_data, bytes_got); - saveFileEML(filename, tag_data, bytes_got, 8); - saveFileJSON(filename, jsfIclass, tag_data, bytes_got, NULL); + + pm3_save_dump(filename, tag_data, bytes_got, jsfIclass, PICOPASS_BLOCK_SIZE); PrintAndLogEx(HINT, "Try `" _YELLOW_("hf iclass decrypt -f") "` to decrypt dump file"); PrintAndLogEx(HINT, "Try `" _YELLOW_("hf iclass view -f") "` to view dump file"); @@ -2480,10 +2476,10 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e int i = startblock; PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "-------------------------- " _CYAN_("Tag memory") " ---------------------------"); + PrintAndLogEx(INFO, "--------------------------- " _CYAN_("Tag memory") " ----------------------------"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, " block# | data | ascii |lck| info"); - PrintAndLogEx(INFO, "---------+-------------------------+----------+---+--------------"); + PrintAndLogEx(INFO, "---------+-------------------------+----------+---+----------------"); PrintAndLogEx(INFO, " 0/0x00 | " _GREEN_("%s") "| " _GREEN_("%s") " | | CSN " , sprint_hex(iclass_dump, 8) , sprint_ascii(iclass_dump, 8) @@ -2491,9 +2487,9 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e if (i != 1) PrintAndLogEx(INFO, " ......"); - - uint8_t fb1 = (iclass_dump + (6 * 8))[0]; - uint8_t fb2 = (iclass_dump + (10 * 8))[0]; + bool isLegacy = (memcmp(iclass_dump + (7 * 8), "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8)); + bool isSE = (memcmp(iclass_dump + (12 * 8) + 4, "\x05\x00\x05\x00", 4) == 0); + bool isSR = (memcmp(iclass_dump + (16 * 8) + 3, "\x05\x00\x05\x00\x00", 5) == 0); while (i <= endblock) { uint8_t *blk = iclass_dump + (i * 8); @@ -2554,7 +2550,7 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e } else { const char *info_ks[] = {"CSN", "Config", "E-purse", "Debit", "Credit", "AIA", "User"}; - if (i >= 6 && i <= 9 && fb1 != 0x30) { + if (i >= 6 && i <= 9 && isLegacy && isSE == false) { // legacy credential PrintAndLogEx(INFO, "%3d/0x%02X | " _YELLOW_("%s") "| " _YELLOW_("%s") " | %s | User / Cred " , i @@ -2563,7 +2559,7 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e , sprint_ascii(blk, 8) , lockstr ); - } else if (i >= 6 && i <= 11 && fb1 == 0x30) { + } else if (i >= 6 && i <= 13 && isSE) { // SIO credential PrintAndLogEx(INFO, "%3d/0x%02X | " _CYAN_("%s") "| " _CYAN_("%s") " | %s | User / SIO" , i @@ -2572,9 +2568,9 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e , sprint_ascii(blk, 8) , lockstr ); - } else if (i >= 10 && i <= 16 && fb2 == 0x30) { + } else if (i >= 10 && i <= 16 && isSR) { // SIO credential - PrintAndLogEx(INFO, "%3d/0x%02X | " _CYAN_("%s") "| " _CYAN_("%s") " | %s | User / SIO" + PrintAndLogEx(INFO, "%3d/0x%02X | " _CYAN_("%s") "| " _CYAN_("%s") " | %s | User / SIO / SR" , i , i , sprint_hex(blk, 8) @@ -2591,9 +2587,12 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e } i++; } - PrintAndLogEx(INFO, "---------+-------------------------+----------+---+--------------"); + PrintAndLogEx(INFO, "---------+-------------------------+----------+---+----------------"); + if (isLegacy) PrintAndLogEx(HINT, _YELLOW_("yellow") " = legacy credential"); - PrintAndLogEx(HINT, _CYAN_("cyan") " = SIO credential"); + if (isSE || isSR) + PrintAndLogEx(HINT, _CYAN_("cyan") " = SIO / SR credential"); + PrintAndLogEx(NORMAL, ""); } From 3bbcefacf953e5b2f73f18a2dde33e3a4cd3f507 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 9 Jul 2022 18:20:23 +0200 Subject: [PATCH 111/759] fix hf iclass decrypt wiegand --- client/src/cmdhficlass.c | 16 +++++++--------- client/src/cmdwiegand.c | 1 + 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 95c78d5be..1b2e5ac45 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1343,26 +1343,24 @@ static int CmdHFiClassDecrypt(const char *Cmd) { if (has_values) { //todo: remove preamble/sentinel - uint32_t top = 0, mid, bot; - mid = bytes_to_num(decrypted + (8 * 7), 4); - bot = bytes_to_num(decrypted + (8 * 7) + 4, 4); + uint32_t top = 0, mid = 0, bot = 0; PrintAndLogEx(INFO, "Block 7 decoder"); char hexstr[16 + 1] = {0}; hex_to_buffer((uint8_t *)hexstr, decrypted + (8 * 7), 8, sizeof(hexstr) - 1, 0, 0, true); + hexstring_to_u96(&top, &mid, &bot, hexstr); - char binstr[8 * 8 + 1] = {0}; + char binstr[64 + 1]; hextobinstring(binstr, hexstr); - size_t i = 0; - while (i < strlen(binstr) && binstr[i++] == '0'); + char *pbin = binstr; + while (strlen(pbin) && *(++pbin) == '0'); - PrintAndLogEx(SUCCESS, "Binary..................... " _GREEN_("%s"), binstr + i); + PrintAndLogEx(SUCCESS, "Binary..................... " _GREEN_("%s"), pbin); PrintAndLogEx(INFO, "Wiegand decode"); - wiegand_message_t packed = initialize_message_object(top, mid, bot, strlen(binstr + i)); + wiegand_message_t packed = initialize_message_object(top, mid, bot, 0); HIDTryUnpack(&packed); - } else { PrintAndLogEx(INFO, "No credential found"); } diff --git a/client/src/cmdwiegand.c b/client/src/cmdwiegand.c index fe6148f4e..0973a9beb 100644 --- a/client/src/cmdwiegand.c +++ b/client/src/cmdwiegand.c @@ -158,6 +158,7 @@ int CmdWiegandDecode(const char *Cmd) { PrintAndLogEx(ERR, "empty input"); return PM3_EINVARG; } + wiegand_message_t packed = initialize_message_object(top, mid, bot, blen); HIDTryUnpack(&packed); return PM3_SUCCESS; From 9d337dbc01cebcec66ffaee8286b3c86e4d4f95e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 9 Jul 2022 21:16:22 +0200 Subject: [PATCH 112/759] fix missing AIA block in dump --- client/src/cmdhficlass.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 1b2e5ac45..75f394c59 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1732,7 +1732,7 @@ static int CmdHFiClassDump(const char *Cmd) { payload.start_block = 3; payload.req.do_auth = false; } else { - payload.start_block = 6; + payload.start_block = 5; } clearCommandBuffer(); @@ -2587,7 +2587,8 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e } PrintAndLogEx(INFO, "---------+-------------------------+----------+---+----------------"); if (isLegacy) - PrintAndLogEx(HINT, _YELLOW_("yellow") " = legacy credential"); + PrintAndLogEx(HINT, _YELLOW_("yellow") " = legacy credential"); + if (isSE || isSR) PrintAndLogEx(HINT, _CYAN_("cyan") " = SIO / SR credential"); From e7edefe24e5106b15915b74b53b201d3140d2621 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 10 Jul 2022 00:29:25 +0300 Subject: [PATCH 113/759] fix avg --- armsrc/hfsnoop.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index 9d155237c..e06e89eeb 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -54,7 +54,7 @@ static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, u if (accum > (val << 8)) accum = val << 8; case HF_SNOOP_SKIP_AVG: - accum += (val & 0xff) + (val << 8); + accum += (val & 0xff) + (val >> 8); default: { // HF_SNOOP_SKIP_DROP and the rest if (ratioindx == 0) accum = val & 0xff; @@ -64,10 +64,15 @@ static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, u ratioindx++; if (ratioindx >= skipRatio) { ratioindx = 0; - if (skipMode == HF_SNOOP_SKIP_AVG) - *dest = accum / (skipRatio * 2); - else + if (skipMode == HF_SNOOP_SKIP_AVG && skipRatio > 0) { + accum = accum / (skipRatio * 2); + if (accum <= 0xff) + *dest = accum; + else + *dest = 0xff; + } else { *dest = accum; + } dest++; dsize --; accum = 0; From 374f1907bb70d80fa2f19f3222c9b5e80b51d317 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 10 Jul 2022 00:47:40 +0300 Subject: [PATCH 114/759] fix max|min --- armsrc/hfsnoop.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index e06e89eeb..9acbf2d25 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -46,13 +46,13 @@ static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, u case HF_SNOOP_SKIP_MAX: if (accum < (val & 0xff)) accum = val & 0xff; - if (accum < (val << 8)) - accum = val << 8; + if (accum < (val >> 8)) + accum = val >> 8; case HF_SNOOP_SKIP_MIN: if (accum > (val & 0xff)) accum = val & 0xff; - if (accum > (val << 8)) - accum = val << 8; + if (accum > (val >> 8)) + accum = val >> 8; case HF_SNOOP_SKIP_AVG: accum += (val & 0xff) + (val >> 8); default: { // HF_SNOOP_SKIP_DROP and the rest @@ -75,7 +75,7 @@ static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, u } dest++; dsize --; - accum = 0; + accum = (skipMode == HF_SNOOP_SKIP_MIN) ? 0xffffffff : 0; } } } From fb3990086eb4d9e2aa66e5672e69fe3fbd84a696 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 10 Jul 2022 00:54:29 +0300 Subject: [PATCH 115/759] fix --- armsrc/hfsnoop.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index 9acbf2d25..08860da9d 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -48,13 +48,16 @@ static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, u accum = val & 0xff; if (accum < (val >> 8)) accum = val >> 8; + break; case HF_SNOOP_SKIP_MIN: if (accum > (val & 0xff)) accum = val & 0xff; if (accum > (val >> 8)) accum = val >> 8; + break; case HF_SNOOP_SKIP_AVG: - accum += (val & 0xff) + (val >> 8); + accum += (val & 0xff) + (val & 0xff); + break; default: { // HF_SNOOP_SKIP_DROP and the rest if (ratioindx == 0) accum = val & 0xff; @@ -63,7 +66,6 @@ static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, u ratioindx++; if (ratioindx >= skipRatio) { - ratioindx = 0; if (skipMode == HF_SNOOP_SKIP_AVG && skipRatio > 0) { accum = accum / (skipRatio * 2); if (accum <= 0xff) @@ -73,9 +75,11 @@ static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, u } else { *dest = accum; } + dest++; dsize --; accum = (skipMode == HF_SNOOP_SKIP_MIN) ? 0xffffffff : 0; + ratioindx = 0; } } } From 321d7cf06984aec7d69ffddca900ffab684ecc3b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 10 Jul 2022 11:35:34 +0300 Subject: [PATCH 116/759] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index baa9edc3d..0bc8e9ece 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] + - Added `hf sniff --smode` skip/group adc data to consume less memory. Now it can sniff very long signals (@merlokk) - Added `hf fudan` skeleton commands (@iceman1001) - Added `--reboot-to-bootloader` arg to pm3 - Changed `hf 14b raw` - now supports selecting Fuji/Xerox tag (@horror) From 0d5d6d8addc4319f81d43d6d9c25b0fcc984f558 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 10 Jul 2022 13:01:48 +0200 Subject: [PATCH 117/759] fix credential coloring in iclass --- client/src/cmdhficlass.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 75f394c59..bc553178b 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -2430,6 +2430,16 @@ static int CmdHFiClass_loclass(const char *Cmd) { return bruteforceFileNoKeys(filename); } +static void detect_credential(uint8_t *data, bool *legacy, bool *se, bool *sr) { + char* r1 = strstr((char*)data + (5 * 8), "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); + char* r2 = strstr((char*)data + (11 * 8), "\x05\x00\x05\x00"); + + *legacy = (r1) && (data[6 * 8] != 0x30); + *se = (r2) && (data[6 * 8] == 0x30); + *sr = (r2) && (data[10 * 8] == 0x30); + r1 = NULL, r2 = NULL; +} + void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize) { picopass_hdr_t *hdr = (picopass_hdr_t *)iclass_dump; @@ -2471,8 +2481,11 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e ); */ uint8_t pagemap = get_pagemap(hdr); - int i = startblock; + bool isLegacy, isSE, isSR; + detect_credential(iclass_dump, &isLegacy, &isSE, &isSR); + + int i = startblock; PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--------------------------- " _CYAN_("Tag memory") " ----------------------------"); PrintAndLogEx(NORMAL, ""); @@ -2485,9 +2498,6 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e if (i != 1) PrintAndLogEx(INFO, " ......"); - bool isLegacy = (memcmp(iclass_dump + (7 * 8), "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8)); - bool isSE = (memcmp(iclass_dump + (12 * 8) + 4, "\x05\x00\x05\x00", 4) == 0); - bool isSR = (memcmp(iclass_dump + (16 * 8) + 3, "\x05\x00\x05\x00\x00", 5) == 0); while (i <= endblock) { uint8_t *blk = iclass_dump + (i * 8); @@ -2557,9 +2567,9 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e , sprint_ascii(blk, 8) , lockstr ); - } else if (i >= 6 && i <= 13 && isSE) { + } else if (i >= 6 && i <= 12 && isSE) { // SIO credential - PrintAndLogEx(INFO, "%3d/0x%02X | " _CYAN_("%s") "| " _CYAN_("%s") " | %s | User / SIO" + PrintAndLogEx(INFO, "%3d/0x%02X | " _CYAN_("%s") "| " _CYAN_("%s") " | %s | User / SIO / SE" , i , i , sprint_hex(blk, 8) From 1faca20f5ee25ce2aba29e2e956d77767e77c38e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 10 Jul 2022 14:41:09 +0200 Subject: [PATCH 118/759] textual when flashing --- client/src/flash.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/flash.c b/client/src/flash.c index 3b2f6b277..6275db0bf 100644 --- a/client/src/flash.c +++ b/client/src/flash.c @@ -631,6 +631,7 @@ static const char ice[] = _RED_(" . .. .. . . .. ... . . . . . .. . ") "\n...................................................................\n" "...................................................................\n" + "...................................................................\n" ; // Write a file's segments to Flash From e7f7925dec5e24bce9a5f0e0f83421e0ba3ad7fb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 11 Jul 2022 06:44:07 +0200 Subject: [PATCH 119/759] adding asn1 tvl decoding of SIO in decrypt, view, eview commands. Available when giving the `-v` verbose flag --- client/src/cmdhficlass.c | 64 +++++++++++++++++++++++++++++++++++++++- client/src/util.c | 49 ++++++++++++++++++++++++++++++ client/src/util.h | 3 ++ 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index bc553178b..ea16de75c 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -37,6 +37,8 @@ #include "cmdsmartcard.h" // smart select fct #include "proxendian.h" #include "iclass_cmd.h" +#include "crypto/asn1utils.h" // ASN1 decoder + #define PICOPASS_BLOCK_SIZE 8 #define NUM_CSNS 9 @@ -56,6 +58,7 @@ static uint8_t empty[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; static uint8_t zeros[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static int CmdHelp(const char *Cmd); +static void printIclassSIO(uint8_t *iclass_dump); static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = { { 0xAE, 0xA6, 0x84, 0xA6, 0xDA, 0xB2, 0x32, 0x78 }, @@ -1139,6 +1142,11 @@ static int CmdHFiClassEView(const char *Cmd) { PrintAndLogEx(NORMAL, ""); printIclassDumpContents(dump, 1, blocks, bytes); + + if (verbose) { + printIclassSIO(dump); + } + free(dump); return PM3_SUCCESS; } @@ -1328,6 +1336,10 @@ static int CmdHFiClassDecrypt(const char *Cmd) { printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); + if (verbose) { + printIclassSIO(decrypted); + } + PrintAndLogEx(NORMAL, ""); // decode block 6 @@ -2440,6 +2452,48 @@ static void detect_credential(uint8_t *data, bool *legacy, bool *se, bool *sr) { r1 = NULL, r2 = NULL; } +// print ASN1 decoded array in TLV view +static void printIclassSIO(uint8_t *iclass_dump) { + + bool isLegacy, isSE, isSR; + detect_credential(iclass_dump, &isLegacy, &isSE, &isSR); + + uint8_t pattern[] = {0x05, 0x00, 0x05, 0x00}; + if (isSE) { + + int dlen = byte_strstr(iclass_dump + (6 * 8), 8*8, pattern, sizeof(pattern)); + if (dlen) { + + dlen += sizeof(pattern); + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "---------------------------- " _CYAN_("SIO - RAW") " ----------------------------"); + print_hex_noascii_break(iclass_dump + (6*8), dlen, 32); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "------------------------- " _CYAN_("SIO - ASN1 TLV") " --------------------------"); + asn1_print(iclass_dump + (6 * 8), dlen, " "); + PrintAndLogEx(NORMAL, ""); + } + } + + if (isSR) { + + int dlen = byte_strstr(iclass_dump + (10 * 8), 8*8, pattern, sizeof(pattern)); + + if (dlen) { + dlen += sizeof(pattern); + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "---------------------------- " _CYAN_("SIO - RAW") " ----------------------------"); + print_hex_noascii_break(iclass_dump + (10*8), dlen, 32); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "------------------------- " _CYAN_("SIO - ASN1 TLV") " --------------------------"); + asn1_print(iclass_dump + (10 * 8), dlen, " "); + PrintAndLogEx(NORMAL, ""); + } + } +} + void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize) { picopass_hdr_t *hdr = (picopass_hdr_t *)iclass_dump; @@ -2599,7 +2653,10 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e if (isLegacy) PrintAndLogEx(HINT, _YELLOW_("yellow") " = legacy credential"); - if (isSE || isSR) + if (isSE) + PrintAndLogEx(HINT, _CYAN_("cyan") " = SIO / SE credential"); + + if (isSR) PrintAndLogEx(HINT, _CYAN_("cyan") " = SIO / SR credential"); PrintAndLogEx(NORMAL, ""); @@ -2650,6 +2707,11 @@ static int CmdHFiClassView(const char *Cmd) { print_picopass_header((picopass_hdr_t *) dump); print_picopass_info((picopass_hdr_t *) dump); printIclassDumpContents(dump, startblock, endblock, bytes_read); + + if (verbose) { + printIclassSIO(dump); + } + free(dump); return PM3_SUCCESS; } diff --git a/client/src/util.c b/client/src/util.c index 421cc84a3..226a813df 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -276,6 +276,31 @@ void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) { } } +void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t breaks) { + if (data == NULL || len == 0 || breaks == 0) return; + + int i; + for (i = 0; i < len; i += breaks) { + if (len - i < breaks) { // incomplete block, will be treated out of the loop + break; + } + PrintAndLogEx(INFO, "%s", sprint_hex_inrow_spaces(data + i, breaks, 0)); + } + + // the last odd bytes + uint8_t mod = len % breaks; + + if (mod) { + char buf[UTIL_BUFFER_SIZE_SPRINT + 3]; + hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 0, true); + + // add the spaces... + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%*s", ((breaks - mod) * 3), " "); + PrintAndLogEx(INFO, "%s", buf); + } +} + + static void print_buffer_ex(const uint8_t *data, const size_t len, int level, uint8_t breaks) { if (len < 1) @@ -1209,3 +1234,27 @@ inline uint64_t leadingzeros64(uint64_t a) { return 0; #endif } + + +int byte_strstr(uint8_t* src, size_t srclen, uint8_t* pattern, size_t plen) { + + size_t max = srclen - plen + 1; + + for (size_t i = 0; i < max; i++) { + + // compare only first byte + if (src[i] != pattern[0]) + continue; + + // try to match rest of the pattern + for (int j = plen - 1; j >= 1; j--) { + + if (src[i + j] != pattern[j]) + break; + + if (j == 1) + return i; + } + } + return -1; +} \ No newline at end of file diff --git a/client/src/util.h b/client/src/util.h index 2401a95aa..064c88803 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -67,6 +67,8 @@ void hex_to_buffer(uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, void print_hex(const uint8_t *data, const size_t len); void print_hex_break(const uint8_t *data, const size_t len, const uint8_t breaks); +void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t breaks); + char *sprint_hex(const uint8_t *data, const size_t len); char *sprint_hex_inrow(const uint8_t *data, const size_t len); char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const size_t min_str_len); @@ -143,4 +145,5 @@ uint64_t bitcount64(uint64_t a); uint32_t leadingzeros32(uint32_t a); uint64_t leadingzeros64(uint64_t a); +int byte_strstr(uint8_t* src, size_t srclen, uint8_t* pattern, size_t plen); #endif From 4fc72f8112002764f8d67d60180f74cab845613b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 11 Jul 2022 22:03:08 +0200 Subject: [PATCH 120/759] fix some colors --- client/src/cmdhflist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index 89acdb0e1..7e79b49ee 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -323,7 +323,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i // buffer too small to print the full key, // so we give just a hint that one of the default keys was used // snprintf(exp, size, "AUTH-2 KEY: " _YELLOW_("%s"), sprint_hex(gs_mfuc_key, 16)); - snprintf(exp, size, "AUTH-2 KEY: " _YELLOW_("%02x%02x%02x%02x..."), gs_mfuc_key[0], gs_mfuc_key[1], gs_mfuc_key[2], gs_mfuc_key[3]); + snprintf(exp, size, "AUTH-2 KEY: " _GREEN_("%02X%02X%02X%02X..."), gs_mfuc_key[0], gs_mfuc_key[1], gs_mfuc_key[2], gs_mfuc_key[3]); } else { snprintf(exp, size, "AUTH-2"); } @@ -334,7 +334,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i break; case MIFARE_ULEV1_AUTH: if (cmdsize == 7) - snprintf(exp, size, "PWD-AUTH KEY: " _YELLOW_("0x%02x%02x%02x%02x"), cmd[1], cmd[2], cmd[3], cmd[4]); + snprintf(exp, size, "PWD-AUTH KEY: " _GREEN_("0x%02X%02X%02X%02X"), cmd[1], cmd[2], cmd[3], cmd[4]); else snprintf(exp, size, "PWD-AUTH"); break; From 07e5f62cab918410b5f3c160e7e3d94d45db7208 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 12 Jul 2022 08:59:21 +0200 Subject: [PATCH 121/759] follow same pattern with assuming memory alignment --- client/deps/hardnested/hardnested_bf_core.c | 3 ++- client/deps/hardnested/hardnested_tables.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client/deps/hardnested/hardnested_bf_core.c b/client/deps/hardnested/hardnested_bf_core.c index 0d4e680fb..64b0696aa 100644 --- a/client/deps/hardnested/hardnested_bf_core.c +++ b/client/deps/hardnested/hardnested_bf_core.c @@ -163,7 +163,8 @@ static void *malloc_bitslice(size_t x) { } #define free_bitslice(x) free(x) #else -#define malloc_bitslice(x) memalign(MAX_BITSLICES / 8, (x)) +//#define malloc_bitslice(x) memalign(MAX_BITSLICES / 8, (x)) +#define malloc_bitslice(x) __builtin_assume_aligned(memalign(MAX_BITSLICES / 8, (x)), MAX_BITSLICES / 8); #define free_bitslice(x) free(x) #endif diff --git a/client/deps/hardnested/hardnested_tables.c b/client/deps/hardnested/hardnested_tables.c index ce2f42cff..aade0c0cd 100644 --- a/client/deps/hardnested/hardnested_tables.c +++ b/client/deps/hardnested/hardnested_tables.c @@ -85,7 +85,8 @@ static void *malloc_bitarray(size_t x) { } #define free_bitarray(x) free(x) #else -#define malloc_bitarray(x) memalign(__BIGGEST_ALIGNMENT__, (x)) +//#define malloc_bitarray(x) memalign(__BIGGEST_ALIGNMENT__, (x)) +#define malloc_bitarray(x) __builtin_assume_aligned(memalign(__BIGGEST_ALIGNMENT__, (x)), __BIGGEST_ALIGNMENT__); #define free_bitarray(x) free(x) #endif From 0554ec220f1cfbf1c91a0f2610590a4bde64352e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 17 Jul 2022 19:29:47 +0200 Subject: [PATCH 122/759] hf plot - now uses NG --- armsrc/hfsnoop.c | 2 +- client/src/cmdhf.c | 4 ++-- client/src/comms.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index 08860da9d..0c9334c99 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -209,6 +209,6 @@ void HfPlotDownload(void) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // Trigger a finish downloading signal with an ACK frame - reply_mix(CMD_ACK, 1, 0, FPGA_TRACE_SIZE, 0, 0); + reply_ng(CMD_FPGAMEM_DOWNLOAD, PM3_SUCCESS, NULL, 0); LED_B_OFF(); } diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index cd58e1647..2c073e262 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -416,10 +416,10 @@ int CmdHFSniff(const char *Cmd) { int handle_hf_plot(void) { - uint8_t buf[FPGA_TRACE_SIZE]; + uint8_t buf[FPGA_TRACE_SIZE] = {0}; PacketResponseNG response; - if (!GetFromDevice(FPGA_MEM, buf, FPGA_TRACE_SIZE, 0, NULL, 0, &response, 4000, true)) { + if (GetFromDevice(FPGA_MEM, buf, FPGA_TRACE_SIZE, 0, NULL, 0, &response, 4000, true) == false) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } diff --git a/client/src/comms.c b/client/src/comms.c index 535b95a61..2b521d2d7 100644 --- a/client/src/comms.c +++ b/client/src/comms.c @@ -834,7 +834,7 @@ bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint3 return false; } case FPGA_MEM: { - SendCommandMIX(CMD_FPGAMEM_DOWNLOAD, start_index, bytes, 0, NULL, 0); + SendCommandNG(CMD_FPGAMEM_DOWNLOAD, NULL, 0); return dl_it(dest, bytes, response, ms_timeout, show_warning, CMD_FPGAMEM_DOWNLOADED); } } @@ -856,8 +856,8 @@ static bool dl_it(uint8_t *dest, uint32_t bytes, PacketResponseNG *response, siz if (response->cmd == CMD_ACK) return true; - // Spiffs download is converted to NG, - if (response->cmd == CMD_SPIFFS_DOWNLOAD) + // Spiffs // fpgamem-plot download is converted to NG, + if (response->cmd == CMD_SPIFFS_DOWNLOAD || response->cmd == CMD_FPGAMEM_DOWNLOAD) return true; // sample_buf is a array pointer, located in data.c From 4b55047c5ba5a1645ecdaf824b22cc1acf8a68eb Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 18 Jul 2022 09:47:15 +0300 Subject: [PATCH 123/759] add mmbit --- client/src/cmdhftexkom.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 18a1f5c48..41a0ecf52 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -191,6 +191,13 @@ static uint8_t TexcomTK13CRC(const uint8_t *data) { return crc; } +static uint8_t MMBITCRC(const uint8_t *data) { + return + (data[0] & 0x0f) ^ ((data[0] >> 4) & 0x0f) ^ + (data[1] & 0x0f) ^ ((data[1] >> 4) & 0x0f) ^ + (data[2] & 0x0f) ^ ((data[2] >> 4) & 0x0f); +} + static unsigned char dallas_crc8(const unsigned char *data, const unsigned int size) { unsigned char crc = 0; for (unsigned int i = 0; i < size; ++i) { @@ -539,6 +546,13 @@ int read_texkom_uid(bool loop, bool verbose) { if (verbose) { PrintAndLogEx(INFO, "CRC...... %s", (crc) ? _GREEN_("ok") : _RED_("fail")); } + } else if (card.tcode[2] == 0xFF && card.tcode[3] == 0xFF) { + PrintAndLogEx(INFO, "TYPE..... MMBIT"); + PrintAndLogEx(INFO, "UID...... " _GREEN_("%s"), sprint_hex(&card.tcode[4], 3)); + crc = (MMBITCRC(&card.tcode[4]) == card.tcode[7] >> 4); + if (verbose) { + PrintAndLogEx(INFO, "CRC...... %s", (crc) ? _GREEN_("ok") : _RED_("fail")); + } } if (verbose) { PrintAndLogEx(INFO, "Raw... %s", sprint_hex(card.tcode, 8)); From 29086a42ab9f6b60b5cc3d92a5d3c5401b5e56c5 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 18 Jul 2022 09:59:13 +0300 Subject: [PATCH 124/759] add check in the read command --- client/src/cmdhftexkom.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 41a0ecf52..07ca40d29 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -721,6 +721,18 @@ static int CmdHFTexkomReader(const char *Cmd) { else PrintAndLogEx(WARNING, "crc : WRONG"); + } else if (tcode[2] == 0xFF && tcode[3] == 0xFF) { + // MMBIT + if (codefound != TexkomModTK13) { + PrintAndLogEx(WARNING, " mod type: WRONG"); + } + PrintAndLogEx(INFO, "type : MMBIT"); + PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[4], 3)); + + if (MMBITCRC(&tcode[4]) == tcode[7] >> 4) + PrintAndLogEx(INFO, "crc : OK"); + else + PrintAndLogEx(WARNING, "crc : WRONG"); } else if (tcode[2] == 0xCA) { // TK17 if (codefound != TexkomModTK17) { From 075c53096240e056df62c8f457930799e5ad242b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 18 Jul 2022 10:11:13 +0300 Subject: [PATCH 125/759] fix crc --- client/src/cmdhftexkom.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 07ca40d29..b62460e6c 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -193,9 +193,11 @@ static uint8_t TexcomTK13CRC(const uint8_t *data) { static uint8_t MMBITCRC(const uint8_t *data) { return - (data[0] & 0x0f) ^ ((data[0] >> 4) & 0x0f) ^ - (data[1] & 0x0f) ^ ((data[1] >> 4) & 0x0f) ^ - (data[2] & 0x0f) ^ ((data[2] >> 4) & 0x0f); + (( (data[0] & 0x0f) ^ ((data[0] >> 4) & 0x0f) ^ + (data[1] & 0x0f) ^ ((data[1] >> 4) & 0x0f) ^ + (data[2] & 0x0f) ^ ((data[2] >> 4) & 0x0f) + ) ^ 0x0f + ) & 0x0f; } static unsigned char dallas_crc8(const unsigned char *data, const unsigned int size) { From d153c6c9776633d6532253fc643b1d0b8d33f3bd Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 18 Jul 2022 10:17:44 +0300 Subject: [PATCH 126/759] add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bc8e9ece..bd3d91adf 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] + - Added mmbit-002 (kibi-002, kb5004xk1) russian tag to `hf texkom read` command (@merlokk) - Added `hf sniff --smode` skip/group adc data to consume less memory. Now it can sniff very long signals (@merlokk) - Added `hf fudan` skeleton commands (@iceman1001) - Added `--reboot-to-bootloader` arg to pm3 From 6f35f7c8780da092190844c3e66555606493d068 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 18 Jul 2022 12:46:11 +0300 Subject: [PATCH 127/759] add no-fix parameter to `data load` to not to change source pm3 files --- client/src/cmddata.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 3b6aadc05..b633a7916 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -2032,6 +2032,7 @@ static int CmdLoad(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_str1("f", "file", "", "file to load"), + arg_lit0("n", "no-fix", "Load data from wile without any transformations"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -2039,6 +2040,9 @@ static int CmdLoad(const char *Cmd) { int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + + bool nofix = arg_get_lit(ctx, 2); + CLIParserFree(ctx); char *path = NULL; @@ -2069,12 +2073,14 @@ static int CmdLoad(const char *Cmd) { PrintAndLogEx(SUCCESS, "loaded " _YELLOW_("%zu") " samples", g_GraphTraceLen); - uint8_t bits[g_GraphTraceLen]; - size_t size = getFromGraphBuf(bits); + if (nofix == false) { + uint8_t bits[g_GraphTraceLen]; + size_t size = getFromGraphBuf(bits); - removeSignalOffset(bits, size); - setGraphBuf(bits, size); - computeSignalProperties(bits, size); + removeSignalOffset(bits, size); + setGraphBuf(bits, size); + computeSignalProperties(bits, size); + } setClockGrid(0, 0); g_DemodBufferLen = 0; From 60d5cf19833a781a9ba396641983f9070ceb9140 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 18 Jul 2022 12:48:40 +0300 Subject: [PATCH 128/759] get samples from graph buffer instead of reading --- client/src/cmdhftexkom.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index b62460e6c..cab0749a3 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -577,14 +577,16 @@ static int CmdHFTexkomReader(const char *Cmd) { void *argtable[] = { arg_param_begin, + arg_lit0("g", "gbuffer", "Get data from graph buffer"), arg_lit0("v", "verbose", "Verbose scan and output"), arg_lit0("@", NULL, "optional - continuous reader mode"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - bool verbose = arg_get_lit(ctx, 1); - bool cm = arg_get_lit(ctx, 2); + bool gbuffer = arg_get_lit(ctx, 1); + bool verbose = arg_get_lit(ctx, 2); + bool cm = arg_get_lit(ctx, 3); CLIParserFree(ctx); @@ -594,21 +596,25 @@ static int CmdHFTexkomReader(const char *Cmd) { } uint32_t samplesCount = 30000; - clearCommandBuffer(); - SendCommandNG(CMD_HF_ACQ_RAW_ADC, (uint8_t *)&samplesCount, sizeof(uint32_t)); + if (gbuffer) { + samplesCount = g_GraphTraceLen; + } else { + clearCommandBuffer(); + SendCommandNG(CMD_HF_ACQ_RAW_ADC, (uint8_t *)&samplesCount, sizeof(uint32_t)); - PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_HF_ACQ_RAW_ADC, &resp, 2500)) { - PrintAndLogEx(WARNING, "command execution time out"); - return PM3_ETIMEOUT; - } + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_HF_ACQ_RAW_ADC, &resp, 2500)) { + PrintAndLogEx(WARNING, "command execution time out"); + return PM3_ETIMEOUT; + } - uint32_t size = (resp.data.asDwords[0]); - if (size > 0) { - if (getSamples(samplesCount, false) != PM3_SUCCESS) { - PrintAndLogEx(ERR, "Get samples error"); - return PM3_EFAILED; - }; + uint32_t size = (resp.data.asDwords[0]); + if (size > 0) { + if (getSamples(samplesCount, false) != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Get samples error"); + return PM3_EFAILED; + }; + } } char bitstring[256] = {0}; From 24806f70e0a51ec94deecc35f0550032fc9ecf24 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 18 Jul 2022 14:19:37 +0300 Subject: [PATCH 129/759] add tk15 decoding --- client/src/cmdhftexkom.c | 71 +++++++++++++++++++++++++++++++++++++--- client/src/cmdhftexkom.h | 1 + 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index cab0749a3..d0e64d86b 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -224,6 +224,8 @@ static uint8_t TexcomTK17CRC(uint8_t *data) { static bool TexcomTK13Decode(uint32_t *implengths, uint32_t implengthslen, char *bitstring, char *cbitstring, bool verbose) { bitstring[0] = 0; cbitstring[0] = 0; + if (implengthslen == 0) + return false; uint32_t hilength = 0; uint32_t lowlength = 0; @@ -283,6 +285,52 @@ static bool TexcomTK13Decode(uint32_t *implengths, uint32_t implengthslen, char return ((strlen(cbitstring) == 64) && (strncmp(cbitstring, "1111111111111111", 16) == 0)); } +// general decode of the very bad signal. maybe here will be some of tk-13 old badges +static bool TexcomTK15Decode(uint32_t *implengths, uint32_t implengthslen, char *bitstring, char *cbitstring, bool verbose) { + bitstring[0] = 0; + cbitstring[0] = 0; + if (implengthslen == 0) + return false; + + bool biterror = false; + for (uint32_t i = 0; i < implengthslen / 2; i++) { + if (implengths[i * 2] == implengths[i * 2 + 1]) { + biterror = true; + break; + } else if (implengths[i * 2] > implengths[i * 2 + 1]) { + strcat(bitstring, "10"); + strcat(cbitstring, "1"); + } else { + strcat(bitstring, "01"); + strcat(cbitstring, "0"); + } + } + + if (implengthslen > 2 && implengthslen % 2 != 0) { + int lastimplen = implengths[implengthslen - 1]; + bool prevbit = (implengths[implengthslen - 3] > implengths[implengthslen - 2]); + bool thesamebit = (abs(lastimplen - implengths[implengthslen - 3]) < abs(lastimplen - implengths[implengthslen - 2])); + + if (prevbit ^ !thesamebit) { + strcat(bitstring, "10"); + strcat(cbitstring, "1"); + } else { + strcat(bitstring, "01"); + strcat(cbitstring, "0"); + } + } + + if (biterror || strlen(bitstring) == 0 || strlen(cbitstring) == 0) + return false; + + if (verbose) { + PrintAndLogEx(INFO, "raw bit string [%zu]: %s", strlen(bitstring), bitstring); + PrintAndLogEx(INFO, "bit string [%zu]: %s", strlen(cbitstring), cbitstring); + } + + return ((strlen(cbitstring) == 64) && (strncmp(cbitstring, "1111111111111111", 16) == 0)); +} + inline int TexcomTK17Get2Bits(uint32_t len1, uint32_t len2) { uint32_t xlen = (len2 * 100) / (len1 + len2); if (xlen < 10 || xlen > 90) @@ -299,6 +347,8 @@ inline int TexcomTK17Get2Bits(uint32_t len1, uint32_t len2) { static bool TexcomTK17Decode(uint32_t *implengths, uint32_t implengthslen, char *bitstring, char *cbitstring, bool verbose) { bitstring[0] = 0; cbitstring[0] = 0; + if (implengthslen == 0) + return false; for (uint32_t i = 0; i < implengthslen; i = i + 2) { int dbit = TexcomTK17Get2Bits(implengths[i], implengths[i + 1]); @@ -469,12 +519,15 @@ static int texkom_get_type(texkom_card_select_t *card, bool verbose) { } } - // check if it TK-13 modulation + // check if it TK-13 or TK-15 modulation // it have 127 or 128 impulses and 128 double-intervals that represents 128 bit of card code if (impulsecnt == 127 || impulsecnt == 128) { if (TexcomTK13Decode(implengths, implengthslen, bitstring, cbitstring, verbose)) { found = TexkomModTK13; break; + } else if (TexcomTK15Decode(implengths, implengthslen, bitstring, cbitstring, verbose)) { + found = TexkomModTK15; + break; } } @@ -678,6 +731,9 @@ static int CmdHFTexkomReader(const char *Cmd) { if (TexcomTK13Decode(implengths, implengthslen, bitstring, cbitstring, verbose)) { codefound = TexkomModTK13; break; + } else if (TexcomTK15Decode(implengths, implengthslen, bitstring, cbitstring, verbose)) { + codefound = TexkomModTK15; + break; } } @@ -711,6 +767,8 @@ static int CmdHFTexkomReader(const char *Cmd) { if (codefound == TexkomModTK13) PrintAndLogEx(INFO, "modulation: TK13"); + if (codefound == TexkomModTK15) + PrintAndLogEx(INFO, "modulation: TK15"); else if (codefound == TexkomModTK17) PrintAndLogEx(INFO, "modulation: TK17"); else @@ -718,10 +776,13 @@ static int CmdHFTexkomReader(const char *Cmd) { if (tcode[2] == 0x63) { // TK13 - if (codefound != TexkomModTK13) { + if (codefound == TexkomModTK13) + PrintAndLogEx(INFO, "type : TK13"); + else if (codefound == TexkomModTK15) + PrintAndLogEx(INFO, "type : TK15"); + else PrintAndLogEx(WARNING, " mod type: WRONG"); - } - PrintAndLogEx(INFO, "type : TK13"); + PrintAndLogEx(INFO, "uid : %s", sprint_hex(&tcode[3], 4)); if (TexcomTK13CRC(&tcode[3]) == tcode[7]) @@ -731,7 +792,7 @@ static int CmdHFTexkomReader(const char *Cmd) { } else if (tcode[2] == 0xFF && tcode[3] == 0xFF) { // MMBIT - if (codefound != TexkomModTK13) { + if (codefound != TexkomModTK13 && codefound != TexkomModTK15) { PrintAndLogEx(WARNING, " mod type: WRONG"); } PrintAndLogEx(INFO, "type : MMBIT"); diff --git a/client/src/cmdhftexkom.h b/client/src/cmdhftexkom.h index b8e96f45d..079a2e4fb 100644 --- a/client/src/cmdhftexkom.h +++ b/client/src/cmdhftexkom.h @@ -33,6 +33,7 @@ enum TK17Bits { enum TexkomModulation { TexkomModError, TexkomModTK13, + TexkomModTK15, TexkomModTK17 }; From 8df134f11a2e92454426dbd7dc3f20fb6e3e3852 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 18 Jul 2022 14:22:16 +0300 Subject: [PATCH 130/759] display fix --- client/src/cmdhftexkom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index d0e64d86b..eda931574 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -767,7 +767,7 @@ static int CmdHFTexkomReader(const char *Cmd) { if (codefound == TexkomModTK13) PrintAndLogEx(INFO, "modulation: TK13"); - if (codefound == TexkomModTK15) + else if (codefound == TexkomModTK15) PrintAndLogEx(INFO, "modulation: TK15"); else if (codefound == TexkomModTK17) PrintAndLogEx(INFO, "modulation: TK17"); From 7818161e9515be0ecc053ac25d3b1928537fc0b5 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 18 Jul 2022 14:24:21 +0300 Subject: [PATCH 131/759] change option --- client/src/cmdhftexkom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index eda931574..5bcc15cf6 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -630,7 +630,7 @@ static int CmdHFTexkomReader(const char *Cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("g", "gbuffer", "Get data from graph buffer"), + arg_lit0("1", NULL, "Use data from Graphbuffer"), arg_lit0("v", "verbose", "Verbose scan and output"), arg_lit0("@", NULL, "optional - continuous reader mode"), arg_param_end From e33e99e2687ce18afdef3484c2d07cd42c8e53f6 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 18 Jul 2022 14:31:42 +0300 Subject: [PATCH 132/759] comment --- client/src/cmdhftexkom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 5bcc15cf6..dbd6812ce 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -775,7 +775,7 @@ static int CmdHFTexkomReader(const char *Cmd) { PrintAndLogEx(INFO, "modulation: unknown"); if (tcode[2] == 0x63) { - // TK13 + // TK13 and TK15. differs only by timings. TK15 has impulse 0 and 1 lengths very close to each other. if (codefound == TexkomModTK13) PrintAndLogEx(INFO, "type : TK13"); else if (codefound == TexkomModTK15) From c8b5ddc0fc1a9590c12c147c6dfd418fd08c30a1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 18 Jul 2022 16:22:52 +0300 Subject: [PATCH 133/759] fix int --- client/src/cmdhftexkom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index dbd6812ce..9cbf238ad 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -309,7 +309,7 @@ static bool TexcomTK15Decode(uint32_t *implengths, uint32_t implengthslen, char if (implengthslen > 2 && implengthslen % 2 != 0) { int lastimplen = implengths[implengthslen - 1]; bool prevbit = (implengths[implengthslen - 3] > implengths[implengthslen - 2]); - bool thesamebit = (abs(lastimplen - implengths[implengthslen - 3]) < abs(lastimplen - implengths[implengthslen - 2])); + bool thesamebit = (abs(lastimplen - (int)implengths[implengthslen - 3]) < abs(lastimplen - (int)implengths[implengthslen - 2])); if (prevbit ^ !thesamebit) { strcat(bitstring, "10"); From 6d950e1e48fa18a518b853209b410e5c0264001a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 18 Jul 2022 22:17:53 +0200 Subject: [PATCH 134/759] fix coverity scan --- client/src/cmdhf.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 2c073e262..2fe5cbd9e 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -351,19 +351,24 @@ int CmdHFSniff(const char *Cmd) { params.samplesToSkip = arg_get_u32_def(ctx, 1, 0); params.triggersToSkip = arg_get_u32_def(ctx, 2, 0); + int smode = 0; - if (CLIGetOptionList(arg_get_str(ctx, 3), HFSnoopSkipModeOpts, &smode)) + if (CLIGetOptionList(arg_get_str(ctx, 3), HFSnoopSkipModeOpts, &smode)) { + CLIParserFree(ctx); return PM3_EINVARG; + } - if (smode > 0) - params.skipMode = smode; - + params.skipMode = smode; params.skipRatio = arg_get_int_def(ctx, 4, 0); + CLIParserFree(ctx); - if (params.skipMode != HF_SNOOP_SKIP_NONE) + if (params.skipMode != HF_SNOOP_SKIP_NONE) { PrintAndLogEx(INFO, "Skip mode. Function: %s, each: %d sample", - CLIGetOptionListStr(HFSnoopSkipModeOpts, params.skipMode), params.skipRatio * 2); + CLIGetOptionListStr(HFSnoopSkipModeOpts, params.skipMode), + params.skipRatio * 2 + ); + } clearCommandBuffer(); SendCommandNG(CMD_HF_SNIFF, (uint8_t *)¶ms, sizeof(params)); @@ -383,6 +388,7 @@ int CmdHFSniff(const char *Cmd) { PrintAndLogEx(INFO, "Button pressed, user aborted"); break; } + if (resp.status == PM3_SUCCESS) { struct r { From e2fe92ee3df1c3be16bf3ffe45bd4f883d9e7e36 Mon Sep 17 00:00:00 2001 From: nvx Date: Fri, 13 May 2022 17:37:11 +1000 Subject: [PATCH 135/759] Fix gallagher desfire kdf for default application card master key --- common/generator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/generator.c b/common/generator.c index 4856327e2..4b23d30ce 100644 --- a/common/generator.c +++ b/common/generator.c @@ -482,8 +482,8 @@ int mfdes_kdf_input_gallagher(uint8_t *uid, uint8_t uidLen, uint8_t keyNo, uint3 } int len = 0; - // If the keyNo == 1, then omit the UID. - if (keyNo != 1) { + // If the keyNo == 1 or the aid is 000000, then omit the UID. + if (keyNo != 1 && aid != 0x000000) { if (*kdfInputLen < (4 + uidLen)) { return PM3_EINVARG; } From c36395f2ccee9ee56c0a5f644e59592607e26a02 Mon Sep 17 00:00:00 2001 From: nvx Date: Wed, 20 Jul 2022 17:47:39 +1000 Subject: [PATCH 136/759] Add hf gallagher decode command --- client/src/cmdhfgallagher.c | 67 +++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfgallagher.c b/client/src/cmdhfgallagher.c index 0872e8681..ee51464a8 100644 --- a/client/src/cmdhfgallagher.c +++ b/client/src/cmdhfgallagher.c @@ -840,9 +840,10 @@ static int hfgal_read_card(uint32_t aid, uint8_t *site_key, bool verbose, bool q uint32_t current_aid = cad_aid_byte_to_uint(&cad[i + 3]); if (verbose) { - if (region_code > 0 || facility_code > 0) { - PrintAndLogEx(INFO, "Reading AID: " _YELLOW_("%06X") ", region: " _YELLOW_("%u") ", facility: " _YELLOW_("%u"), + if (region_code > 0 || facility_code > 0 || current_aid > 0) { + PrintAndLogEx(INFO, "Reading AID: " _YELLOW_("%06X") ", region: " _YELLOW_("%c") " (" _YELLOW_("%u") "), facility: " _YELLOW_("%u"), current_aid, + 'A' + region_code, region_code, facility_code ); @@ -860,11 +861,12 @@ static int hfgal_read_card(uint32_t aid, uint8_t *site_key, bool verbose, bool q } PM3_RET_IF_ERR_MAYBE_MSG(res, !quiet, "Failed reading card application credentials"); - PrintAndLogEx(SUCCESS, "Gallagher (AID %06X) - region: " _GREEN_("%u") + PrintAndLogEx(SUCCESS, "Gallagher (AID %06X) - region: " _GREEN_("%c") " (" _GREEN_("%u") ")" ", facility: " _GREEN_("%u") ", card number: " _GREEN_("%u") ", issue level: " _GREEN_("%u"), current_aid, + 'A' + creds.region_code, creds.region_code, creds.facility_code, creds.card_number, @@ -1252,12 +1254,71 @@ static int CmdGallagherDiversify(const char *cmd) { return PM3_SUCCESS; } +static int CmdGallagherDecode(const char *cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf gallagher decode", + "Decode Gallagher credential block\n" + "Credential block can be specified with or without the bitwise inverse.", + "hf gallagher decode --data A3B4B0C151B0A31B" + ); + + void *argtable[] = { + arg_param_begin, + arg_str1(NULL, "data", "", "Credential block (8 or 16 bytes)"), + arg_param_end + }; + CLIExecWithReturn(ctx, cmd, argtable, false); + + int data_len = 0; + uint8_t data_buf[16] = {0}; + CLIGetHexWithReturn(ctx, 1, data_buf, &data_len); + if (data_len != 8 && data_len != 16) { + PM3_RET_ERR_FREE(PM3_EINVARG, "--data must be 8 or 16 bytes"); + } + CLIParserFree(ctx); + + if (data_len == 16) { + // Check second half of file is the bitwise inverse of the first half + for (uint8_t i = 8; i < 16; i++) { + data_buf[i] ^= 0xFF; + } + + if (memcmp(data_buf, &data_buf[8], 8) != 0) { + PM3_RET_ERR(PM3_EFAILED, "Invalid cardholder data, last 8 bytes should be bitwise inverse of first 16 bytes. Received %s", + sprint_hex_inrow(data_buf, 16) + ); + } + } else { + for (uint8_t i = 0; i < 8; i++) { + data_buf[i + 8] = data_buf[i] ^ 0xFF; + } + PrintAndLogEx(INFO, "Full credential block with bitwise inverse: " _YELLOW_("%s"), sprint_hex_inrow(data_buf, 16)); + } + + GallagherCredentials_t creds = {0}; + gallagher_decode_creds(data_buf, &creds); + + PrintAndLogEx(SUCCESS, "Gallagher - region: " _GREEN_("%c") " (" _GREEN_("%u") ")" + ", facility: " _GREEN_("%u") + ", card number: " _GREEN_("%u") + ", issue level: " _GREEN_("%u"), + 'A' + creds.region_code, + creds.region_code, + creds.facility_code, + creds.card_number, + creds.issue_level + ); + + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"reader", CmdGallagherReader, IfPm3Iso14443, "Read & decode all Gallagher credentials on a DESFire card"}, {"clone", CmdGallagherClone, IfPm3Iso14443, "Add Gallagher credentials to a DESFire card"}, {"delete", CmdGallagherDelete, IfPm3Iso14443, "Delete Gallagher credentials from a DESFire card"}, {"diversifykey", CmdGallagherDiversify, AlwaysAvailable, "Diversify Gallagher key"}, + {"decode", CmdGallagherDecode, AlwaysAvailable, "Decode Gallagher credential block"}, {NULL, NULL, NULL, NULL} }; From 503ca0641cf39525f70f67d161a7e0a6aeb7748d Mon Sep 17 00:00:00 2001 From: nvx Date: Wed, 20 Jul 2022 18:14:00 +1000 Subject: [PATCH 137/759] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd3d91adf..9757a2952 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] + - Added `hf gallagher decode` command and fix Gallagher diversification for card master key (@nvx) - Added mmbit-002 (kibi-002, kb5004xk1) russian tag to `hf texkom read` command (@merlokk) - Added `hf sniff --smode` skip/group adc data to consume less memory. Now it can sniff very long signals (@merlokk) - Added `hf fudan` skeleton commands (@iceman1001) From 5c5a53963a36fade8c6ad37d4ab207506ad312a1 Mon Sep 17 00:00:00 2001 From: nvx Date: Fri, 22 Jul 2022 13:52:09 +1000 Subject: [PATCH 138/759] Fixed incorrect card config bit being checked for iClass key access flag --- CHANGELOG.md | 1 + client/src/cmdhficlass.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9757a2952..4584826d2 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 `hf iclass info` and `hf iclass view` key access info looking at the wrong card config bit (@nvx) - Added `hf gallagher decode` command and fix Gallagher diversification for card master key (@nvx) - Added mmbit-002 (kibi-002, kb5004xk1) russian tag to `hf texkom read` command (@merlokk) - Added `hf sniff --smode` skip/group adc data to consume less memory. Now it can sniff very long signals (@merlokk) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index ea16de75c..03f9a4b3a 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -588,8 +588,8 @@ static void mem_app_config(const picopass_hdr_t *hdr) { PrintAndLogEx(INFO, "------------------------- " _CYAN_("KeyAccess") " ------------------------"); PrintAndLogEx(INFO, " * Kd, Debit key, AA1 Kc, Credit key, AA2 *"); - uint8_t book = isset(mem, 0x20); - if (book) { + uint8_t keyAccess = isset(mem, 0x01); + if (keyAccess) { PrintAndLogEx(INFO, " Read A....... debit"); PrintAndLogEx(INFO, " Read B....... credit"); PrintAndLogEx(INFO, " Write A...... debit"); From eb6b170e51b25e95400a58bb9b4b7a2607b8e0e6 Mon Sep 17 00:00:00 2001 From: nvx Date: Fri, 22 Jul 2022 13:48:34 +1000 Subject: [PATCH 139/759] Changed `hf iclass list` to display matched keys on the CHECK command rather than the card response, and made it check for elite keys too --- CHANGELOG.md | 1 + client/src/cmdhficlass.c | 11 ++++++----- client/src/cmdhflist.c | 15 +++++++++------ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9757a2952..ce9be2aa5 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] + - Changed `hf iclass list` to display matched keys on the CHECK command rather than the card response, and made it check for elite keys too (@nvx) - Added `hf gallagher decode` command and fix Gallagher diversification for card master key (@nvx) - Added mmbit-002 (kibi-002, kb5004xk1) russian tag to `hf texkom read` command (@merlokk) - Added `hf sniff --smode` skip/group adc data to consume less memory. Now it can sniff very long signals (@merlokk) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index ea16de75c..6836df754 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -87,7 +87,7 @@ static int cmp_uint32(const void *a, const void *b) { bool check_known_default(uint8_t *csn, uint8_t *epurse, uint8_t *rmac, uint8_t *tmac, uint8_t *key) { - iclass_prekey_t *prekey = calloc(ICLASS_KEYS_MAX, sizeof(iclass_prekey_t)); + iclass_prekey_t *prekey = calloc(ICLASS_KEYS_MAX * 2, sizeof(iclass_prekey_t)); if (prekey == NULL) { return false; } @@ -97,17 +97,20 @@ bool check_known_default(uint8_t *csn, uint8_t *epurse, uint8_t *rmac, uint8_t * memcpy(ccnr + 8, rmac, 4); GenerateMacKeyFrom(csn, ccnr, false, false, (uint8_t *)iClass_Key_Table, ICLASS_KEYS_MAX, prekey); - qsort(prekey, ICLASS_KEYS_MAX, sizeof(iclass_prekey_t), cmp_uint32); + GenerateMacKeyFrom(csn, ccnr, false, true, (uint8_t *)iClass_Key_Table, ICLASS_KEYS_MAX, prekey + ICLASS_KEYS_MAX); + qsort(prekey, ICLASS_KEYS_MAX * 2, sizeof(iclass_prekey_t), cmp_uint32); iclass_prekey_t lookup; memcpy(lookup.mac, tmac, 4); // binsearch - iclass_prekey_t *item = (iclass_prekey_t *) bsearch(&lookup, prekey, ICLASS_KEYS_MAX, sizeof(iclass_prekey_t), cmp_uint32); + iclass_prekey_t *item = (iclass_prekey_t *) bsearch(&lookup, prekey, ICLASS_KEYS_MAX * 2, sizeof(iclass_prekey_t), cmp_uint32); if (item != NULL) { memcpy(key, item->key, 8); + free(prekey); return true; } + free(prekey); return false; } @@ -3534,8 +3537,6 @@ void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elit for (int i = 0; i < iclass_tc; i++) pthread_join(threads[i], NULL); - - PrintAndLogEx(NORMAL, ""); } // print diversified keys diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index 7e79b49ee..f326a8abb 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -464,10 +464,17 @@ void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool curr_state = PICO_NONE; break; case ICLASS_CMD_CHECK: - snprintf(exp, size, "CHECK"); curr_state = PICO_AUTH_MACS; memcpy(rmac, cmd + 1, 4); memcpy(tmac, cmd + 5, 4); + + uint8_t key[8]; + if (check_known_default(csn, epurse, rmac, tmac, key)) { + snprintf(exp, size, "CHECK ( %s )", sprint_hex_inrow(key, 8)); + } else { + snprintf(exp, size, "CHECK"); + } + break; case ICLASS_CMD_READ4: snprintf(exp, size, "READ4(%d)", cmd[1]); @@ -516,11 +523,7 @@ void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool } else if (curr_state == PICO_AUTH_EPURSE) { memcpy(epurse, cmd, 8); } else if (curr_state == PICO_AUTH_MACS) { - - uint8_t key[8]; - if (check_known_default(csn, epurse, rmac, tmac, key)) { - snprintf(exp, size, "( " _GREEN_("%s") " )", sprint_hex_inrow(key, 8)); - } + snprintf(exp, size, _GREEN_("CHECK SUCCESS")); curr_state = PICO_NONE; } } From 1acecc29b1e2b1efccbd3e1648970a3aa93ca8cd Mon Sep 17 00:00:00 2001 From: nvx Date: Fri, 22 Jul 2022 14:01:13 +1000 Subject: [PATCH 140/759] Changed `hf iclass view` to suppress consecutive blocks with repeated contents --- CHANGELOG.md | 1 + client/src/cmdhficlass.c | 51 +++++++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9757a2952..b71ef48e0 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] + - Changed `hf iclass view` to suppress consecutive blocks with repeated contents (@nvx) - Added `hf gallagher decode` command and fix Gallagher diversification for card master key (@nvx) - Added mmbit-002 (kibi-002, kb5004xk1) russian tag to `hf texkom read` command (@merlokk) - Added `hf sniff --smode` skip/group adc data to consume less memory. Now it can sniff very long signals (@merlokk) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index ea16de75c..f687807c4 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -2553,6 +2553,7 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e if (i != 1) PrintAndLogEx(INFO, " ......"); + bool in_repeated_block = false; while (i <= endblock) { uint8_t *blk = iclass_dump + (i * 8); @@ -2594,21 +2595,17 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e const char *lockstr = (bl_lock) ? _RED_("x") : " "; + const char *block_info; + bool regular_print_block = false; if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { const char *info_nonks[] = {"CSN", "Config", "AIA", "User"}; - const char *s = info_nonks[3]; if (i < 3) { - s = info_nonks[i]; + block_info = info_nonks[i]; + } else { + block_info = info_nonks[3]; } - PrintAndLogEx(INFO, "%3d/0x%02X | %s | %s | %s " - , i - , i - , sprint_hex_ascii(blk, 8) - , lockstr - , s - ); - + regular_print_block = true; } else { const char *info_ks[] = {"CSN", "Config", "E-purse", "Debit", "Credit", "AIA", "User"}; @@ -2640,13 +2637,40 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e , lockstr ); } else { - const char *s = info_ks[6]; if (i < 6) { - s = info_ks[i]; + block_info = info_ks[i]; + } else { + block_info = info_ks[6]; } - PrintAndLogEx(INFO, "%3d/0x%02X | %s | %s | %s ", i, i, sprint_hex_ascii(blk, 8), lockstr, s); + + regular_print_block = true; } } + + if (regular_print_block) { + // suppress repeating blocks, truncate as such that the first and last block with the same data is shown + // but the blocks in between are replaced with a single line of "*" + if (i > 6 && i < (endblock - 1) && !in_repeated_block && !memcmp(blk, blk - 8, 8) && + !memcmp(blk, blk + 8, 8) && !memcmp(blk, blk + 16, 8)) { + // we're in a user block that isn't the first user block nor last two user blocks, + // and the current block data is the same as the previous and next two block + in_repeated_block = true; + PrintAndLogEx(INFO, "*"); + } else if (in_repeated_block && (memcmp(blk, blk + 8, 8) || i == endblock)) { + // in a repeating block, but the next block doesn't match anymore, or we're at the end block + in_repeated_block = false; + } + if (!in_repeated_block) { + PrintAndLogEx(INFO, + "%3d/0x%02X | %s | %s | %s ", + i, + i, + sprint_hex_ascii(blk, 8), + lockstr, + block_info); + } + } + i++; } PrintAndLogEx(INFO, "---------+-------------------------+----------+---+----------------"); @@ -4127,4 +4151,3 @@ int info_iclass(void) { return PM3_SUCCESS; } - From 30cc57d3aa33abae1dbe99a003854b3556159cb0 Mon Sep 17 00:00:00 2001 From: nvx Date: Fri, 22 Jul 2022 14:06:47 +1000 Subject: [PATCH 141/759] Fix some bugs in the iClass SIO detection and printing --- client/src/cmdhficlass.c | 63 ++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index ea16de75c..c562263f0 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -2443,8 +2443,9 @@ static int CmdHFiClass_loclass(const char *Cmd) { } static void detect_credential(uint8_t *data, bool *legacy, bool *se, bool *sr) { - char* r1 = strstr((char*)data + (5 * 8), "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); - char* r2 = strstr((char*)data + (11 * 8), "\x05\x00\x05\x00"); + bool r1 = !memcmp(data + (5 * 8), "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8); + uint8_t pattern[] = {0x05, 0x00, 0x05, 0x00}; + bool r2 = byte_strstr(data + (11 * 8), 6 * 8, pattern, sizeof(pattern)) != -1; *legacy = (r1) && (data[6 * 8] != 0x30); *se = (r2) && (data[6 * 8] == 0x30); @@ -2458,40 +2459,31 @@ static void printIclassSIO(uint8_t *iclass_dump) { bool isLegacy, isSE, isSR; detect_credential(iclass_dump, &isLegacy, &isSE, &isSR); - uint8_t pattern[] = {0x05, 0x00, 0x05, 0x00}; + uint8_t *sio_start; if (isSE) { - - int dlen = byte_strstr(iclass_dump + (6 * 8), 8*8, pattern, sizeof(pattern)); - if (dlen) { - - dlen += sizeof(pattern); - - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "---------------------------- " _CYAN_("SIO - RAW") " ----------------------------"); - print_hex_noascii_break(iclass_dump + (6*8), dlen, 32); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "------------------------- " _CYAN_("SIO - ASN1 TLV") " --------------------------"); - asn1_print(iclass_dump + (6 * 8), dlen, " "); - PrintAndLogEx(NORMAL, ""); - } + sio_start = iclass_dump + (6 * 8); + } else if (isSR) { + sio_start = iclass_dump + (10 * 8); + } else { + return; } - if (isSR) { - - int dlen = byte_strstr(iclass_dump + (10 * 8), 8*8, pattern, sizeof(pattern)); - - if (dlen) { - dlen += sizeof(pattern); - - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "---------------------------- " _CYAN_("SIO - RAW") " ----------------------------"); - print_hex_noascii_break(iclass_dump + (10*8), dlen, 32); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "------------------------- " _CYAN_("SIO - ASN1 TLV") " --------------------------"); - asn1_print(iclass_dump + (10 * 8), dlen, " "); - PrintAndLogEx(NORMAL, ""); - } + uint8_t pattern[] = {0x05, 0x00, 0x05, 0x00}; + int dlen = byte_strstr(sio_start, 8 * 8, pattern, sizeof(pattern)); + if (dlen == -1) { + return; } + + dlen += sizeof(pattern); + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "---------------------------- " _CYAN_("SIO - RAW") " ----------------------------"); + print_hex_noascii_break(sio_start, dlen, 32); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "------------------------- " _CYAN_("SIO - ASN1 TLV") " --------------------------"); + asn1_print(sio_start, dlen, " "); + PrintAndLogEx(NORMAL, ""); + } void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize) { @@ -2536,8 +2528,10 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e */ uint8_t pagemap = get_pagemap(hdr); - bool isLegacy, isSE, isSR; - detect_credential(iclass_dump, &isLegacy, &isSE, &isSR); + bool isLegacy = false, isSE = false, isSR = false; + if (filemaxblock >= 17) { + detect_credential(iclass_dump, &isLegacy, &isSE, &isSR); + } int i = startblock; PrintAndLogEx(NORMAL, ""); @@ -4127,4 +4121,3 @@ int info_iclass(void) { return PM3_SUCCESS; } - From 881c32e0be7503066edcd32f2aa5d2766e1fcefd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 22 Jul 2022 09:47:11 +0200 Subject: [PATCH 142/759] change - added desfire product type identification --- client/src/cmdhfmfdes.c | 53 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index af8726298..2993c8def 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -149,6 +149,15 @@ typedef enum { NTAG413DNA, } nxp_cardtype_t; +typedef enum { + DESFIRE_UNKNOWN_PROD = 0, + DESFIRE_PHYSICAL, + DESFIRE_LIGHT_PHYSICAL, + DESFIRE_MICROCONTROLLER, + DESFIRE_JAVACARD, + DESFIRE_HCE, +} nxp_producttype_t; + typedef struct dfname { uint8_t aid[3]; uint8_t fid[2]; @@ -298,6 +307,43 @@ static nxp_cardtype_t getCardType(uint8_t major, uint8_t minor) { return DESFIRE_UNKNOWN; } +// ref: https://www.nxp.com/docs/en/application-note/AN12343.pdf p7 +static nxp_producttype_t getProductType(uint8_t *versionhw) { + + uint8_t product = versionhw[2]; + + if (product == 0x01) + return DESFIRE_PHYSICAL; + if (product == 0x08) + return DESFIRE_LIGHT_PHYSICAL; + if (product == 0x81 || product == 0x83) + return DESFIRE_MICROCONTROLLER; + if (product == 0x91) + return DESFIRE_JAVACARD; + if (product == 0xA1) + return DESFIRE_HCE; + return DESFIRE_UNKNOWN_PROD; +} + +static const char* getProductTypeStr(uint8_t *versionhw) { + + uint8_t product = versionhw[2]; + + if (product == 0x01) + return "MIFARE DESFire native IC (physical card)"; + if (product == 0x08) + return "MIFARE DESFire Light native IC (physical card)"; + if (product == 0x81 || product == 0x83) + return "MIFARE DESFire implementation on microcontroller (physical card)"; + if (product == 0x91) + return "MIFARE DESFire applet on Java card / secure element"; + if (product == 0xA1) + return "MIFARE DESFire HCE (MIFARE 2GO)"; + return "UNKNOWN PROD"; +} + + + static int mfdes_get_info(mfdes_info_res_t *info) { SendCommandNG(CMD_HF_DESFIRE_INFO, NULL, 0); PacketResponseNG resp; @@ -627,6 +673,12 @@ static int CmdHF14ADesInfo(const char *Cmd) { PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%s"), sprint_hex(info.uid, info.uidlen)); PrintAndLogEx(SUCCESS, " Batch number: " _GREEN_("%s"), sprint_hex(info.details + 7, 5)); PrintAndLogEx(SUCCESS, " Production date: week " _GREEN_("%02x") " / " _GREEN_("20%02x"), info.details[12], info.details[13]); + + nxp_producttype_t prodtype = getProductType(info.versionHW); + if (prodtype != DESFIRE_UNKNOWN_PROD) { + PrintAndLogEx(SUCCESS, " Product type: %s", getProductTypeStr(info.versionHW)); + } + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Hardware Information")); PrintAndLogEx(INFO, " raw: %s", sprint_hex_inrow(info.versionHW, sizeof(info.versionHW))); @@ -646,7 +698,6 @@ static int CmdHF14ADesInfo(const char *Cmd) { PrintAndLogEx(INFO, " Version: " _YELLOW_("%d.%d"), info.versionSW[3], info.versionSW[4]); PrintAndLogEx(INFO, " Storage size: %s", getCardSizeStr(info.versionSW[5])); PrintAndLogEx(INFO, " Protocol: %s", getProtocolStr(info.versionSW[6], false)); - PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--------------------------------- " _CYAN_("Card capabilities") " ---------------------------------"); uint8_t major = info.versionSW[3]; From 8cfbe6657b5bd3dc8646baee5c1e42cc84bebf9b Mon Sep 17 00:00:00 2001 From: Nathaniel McHugh Date: Fri, 22 Jul 2022 21:18:51 +0100 Subject: [PATCH 143/759] Add Paxton hitag2 password --- client/dictionaries/ht2_default.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/client/dictionaries/ht2_default.dic b/client/dictionaries/ht2_default.dic index 2dc816512..f503fa543 100644 --- a/client/dictionaries/ht2_default.dic +++ b/client/dictionaries/ht2_default.dic @@ -10,3 +10,4 @@ 25293C2F # # Paxton HT2 +BDF5E846 From 728e6d27c79847b1903dfaff73a403c17512bb05 Mon Sep 17 00:00:00 2001 From: nvx Date: Sat, 23 Jul 2022 12:37:07 +1000 Subject: [PATCH 144/759] add preference for dense output option and -z cmd flag --- client/src/cmdhficlass.c | 23 ++++++++---- client/src/cmdhficlass.h | 2 +- client/src/preferences.c | 75 +++++++++++++++++++++++++++++++++++++++- client/src/ui.h | 1 + 4 files changed, 92 insertions(+), 9 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index f687807c4..f1bb638f4 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -38,6 +38,7 @@ #include "proxendian.h" #include "iclass_cmd.h" #include "crypto/asn1utils.h" // ASN1 decoder +#include "preferences.h" #define PICOPASS_BLOCK_SIZE 8 @@ -1100,6 +1101,7 @@ static int CmdHFiClassEView(const char *Cmd) { arg_param_begin, arg_int0("s", "size", "<256|2048>", "number of bytes to save (default 256)"), arg_lit0("v", "verbose", "verbose output"), + arg_lit0("z", "dense", "dense dump output style"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1107,6 +1109,7 @@ static int CmdHFiClassEView(const char *Cmd) { uint16_t blocks = 32; uint16_t bytes = arg_get_int_def(ctx, 1, 256); bool verbose = arg_get_lit(ctx, 2); + bool dense_output = g_session.dense_output || arg_get_lit(ctx, 3); blocks = bytes / 8; CLIParserFree(ctx); @@ -1141,7 +1144,7 @@ static int CmdHFiClassEView(const char *Cmd) { } PrintAndLogEx(NORMAL, ""); - printIclassDumpContents(dump, 1, blocks, bytes); + printIclassDumpContents(dump, 1, blocks, bytes, dense_output); if (verbose) { printIclassSIO(dump); @@ -1174,6 +1177,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { arg_str0("k", "key", "", "3DES transport key"), arg_lit0("v", "verbose", "verbose output"), arg_lit0(NULL, "d6", "decode as block 6"), + arg_lit0("z", "dense", "dense dump output style"), arg_param_end }; CLIExecWithReturn(clictx, Cmd, argtable, false); @@ -1197,6 +1201,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { bool verbose = arg_get_lit(clictx, 4); bool use_decode6 = arg_get_lit(clictx, 5); + bool dense_output = g_session.dense_output || arg_get_lit(clictx, 6); CLIParserFree(clictx); // sanity checks @@ -1334,7 +1339,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { pm3_save_dump(fptr, decrypted, decryptedlen, jsfIclass, PICOPASS_BLOCK_SIZE); - printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen); + printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen, dense_output); if (verbose) { printIclassSIO(decrypted); @@ -1561,6 +1566,7 @@ static int CmdHFiClassDump(const char *Cmd) { arg_lit0(NULL, "elite", "elite computations applied to key"), arg_lit0(NULL, "raw", "raw, the key is interpreted as raw block 3/4"), arg_lit0(NULL, "nr", "replay of NR/MAC"), + arg_lit0("z", "dense", "dense dump output style"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1644,6 +1650,7 @@ static int CmdHFiClassDump(const char *Cmd) { bool elite = arg_get_lit(ctx, 6); bool rawkey = arg_get_lit(ctx, 7); bool use_replay = arg_get_lit(ctx, 8); + bool dense_output = g_session.dense_output || arg_get_lit(ctx, 9); CLIParserFree(ctx); @@ -1876,7 +1883,7 @@ write_dump: PrintAndLogEx(INFO, "Reading AA2 failed. dumping AA1 data to file"); // print the dump - printIclassDumpContents(tag_data, 1, (bytes_got / 8), bytes_got); + printIclassDumpContents(tag_data, 1, (bytes_got / 8), bytes_got, dense_output); // use CSN as filename if (filename[0] == 0) { @@ -2494,7 +2501,7 @@ static void printIclassSIO(uint8_t *iclass_dump) { } } -void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize) { +void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize, bool dense_output) { picopass_hdr_t *hdr = (picopass_hdr_t *)iclass_dump; // picopass_ns_hdr_t *ns_hdr = (picopass_ns_hdr_t *)iclass_dump; @@ -2649,8 +2656,8 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e if (regular_print_block) { // suppress repeating blocks, truncate as such that the first and last block with the same data is shown - // but the blocks in between are replaced with a single line of "*" - if (i > 6 && i < (endblock - 1) && !in_repeated_block && !memcmp(blk, blk - 8, 8) && + // but the blocks in between are replaced with a single line of "*" if dense_output is enabled + if (dense_output && i > 6 && i < (endblock - 1) && !in_repeated_block && !memcmp(blk, blk - 8, 8) && !memcmp(blk, blk + 8, 8) && !memcmp(blk, blk + 16, 8)) { // we're in a user block that isn't the first user block nor last two user blocks, // and the current block data is the same as the previous and next two block @@ -2699,6 +2706,7 @@ static int CmdHFiClassView(const char *Cmd) { arg_int0(NULL, "first", "", "Begin printing from this block (default block 6)"), arg_int0(NULL, "last", "", "End printing at this block (default 0, ALL)"), arg_lit0("v", "verbose", "verbose output"), + arg_lit0("z", "dense", "dense dump output style"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -2710,6 +2718,7 @@ static int CmdHFiClassView(const char *Cmd) { int startblock = arg_get_int_def(ctx, 2, 0); int endblock = arg_get_int_def(ctx, 3, 0); bool verbose = arg_get_lit(ctx, 4); + bool dense_output = g_session.dense_output || arg_get_lit(ctx, 5); CLIParserFree(ctx); @@ -2730,7 +2739,7 @@ static int CmdHFiClassView(const char *Cmd) { PrintAndLogEx(NORMAL, ""); print_picopass_header((picopass_hdr_t *) dump); print_picopass_info((picopass_hdr_t *) dump); - printIclassDumpContents(dump, startblock, endblock, bytes_read); + printIclassDumpContents(dump, startblock, endblock, bytes_read, dense_output); if (verbose) { printIclassSIO(dump); diff --git a/client/src/cmdhficlass.h b/client/src/cmdhficlass.h index f66a09a5e..a4d545a05 100644 --- a/client/src/cmdhficlass.h +++ b/client/src/cmdhficlass.h @@ -26,7 +26,7 @@ int CmdHFiClass(const char *Cmd); int info_iclass(void); int read_iclass_csn(bool loop, bool verbose); -void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize); +void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize, bool dense_output); void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite); void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, uint32_t keycnt, iclass_premac_t *list); diff --git a/client/src/preferences.c b/client/src/preferences.c index 7195b2393..28ae4d44f 100644 --- a/client/src/preferences.c +++ b/client/src/preferences.c @@ -63,6 +63,7 @@ int preferences_load(void) { g_session.overlay.w = g_session.plot.w; g_session.overlay_sliders = true; g_session.show_hints = true; + g_session.dense_output = false; g_session.bar_mode = STYLE_VALUE; setDefaultPath(spDefault, ""); @@ -185,6 +186,8 @@ void preferences_save_callback(json_t *root) { JsonSaveBoolean(root, "show.hints", g_session.show_hints); + JsonSaveBoolean(root, "output.dense", g_session.dense_output); + JsonSaveBoolean(root, "os.supports.colors", g_session.supports_colors); JsonSaveStr(root, "file.default.savepath", g_session.defaultPaths[spDefault]); @@ -319,6 +322,9 @@ void preferences_load_callback(json_t *root) { if (json_unpack_ex(root, &up_error, 0, "{s:b}", "show.hints", &b1) == 0) g_session.show_hints = (bool)b1; + if (json_unpack_ex(root, &up_error, 0, "{s:b}", "output.dense", &b1) == 0) + g_session.dense_output = (bool)b1; + if (json_unpack_ex(root, &up_error, 0, "{s:b}", "os.supports.colors", &b1) == 0) g_session.supports_colors = (bool)b1; @@ -517,6 +523,11 @@ static void showBarModeState(prefShowOpt_t opt) { } } +static void showOutputState(prefShowOpt_t opt) { + PrintAndLogEx(INFO, " %s output................. %s", prefShowMsg(opt), + g_session.dense_output ? _GREEN_("dense") : _WHITE_("normal")); +} + static void showClientExeDelayState(void) { PrintAndLogEx(INFO, " Cmd execution delay.... "_GREEN_("%u"), g_session.client_exe_delay); } @@ -738,6 +749,49 @@ static int setCmdDeviceDebug (const char *Cmd) } */ +static int setCmdOutput(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "prefs set output", + "Set dump output style to condense consecutive repeated data", + "prefs set output --normal --> sets the output style to normal\n" + "prefs set output --dense --> sets the output style to dense" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0(NULL, "normal", "normal output"), + arg_lit0(NULL, "dense", "dense output"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool use_off = arg_get_lit(ctx, 1); + bool use_on = arg_get_lit(ctx, 2); + CLIParserFree(ctx); + + if ((use_off + use_on) > 1) { + PrintAndLogEx(FAILED, "Can only set one option"); + return PM3_EINVARG; + } + + bool new_value = g_session.dense_output; + if (use_off) { + new_value = false; + } + if (use_on) { + new_value = true; + } + + if (g_session.dense_output != new_value) { + showOutputState(prefShowOLD); + g_session.dense_output = new_value; + showOutputState(prefShowNEW); + preferences_save(); + } else { + showOutputState(prefShowNone); + } + + return PM3_SUCCESS; +} static int setCmdExeDelay(const char *Cmd) { CLIParserContext *ctx; @@ -1044,6 +1098,22 @@ static int getCmdDebug(const char *Cmd) { return PM3_SUCCESS; } +static int getCmdOutput(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "prefs get output", + "Get preference of dump output style", + "prefs get output" + ); + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + showOutputState(prefShowNone); + return PM3_SUCCESS; +} + static int getCmdPlotSlider(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "prefs get plotsliders", @@ -1119,6 +1189,7 @@ static command_t CommandTableGet[] = { // {"devicedebug", getCmdDeviceDebug, AlwaysAvailable, "Get device debug level"}, {"emoji", getCmdEmoji, AlwaysAvailable, "Get emoji display preference"}, {"hints", getCmdHint, AlwaysAvailable, "Get hint display preference"}, + {"output", getCmdOutput, AlwaysAvailable, "Get dump output style preference"}, {"plotsliders", getCmdPlotSlider, AlwaysAvailable, "Get plot slider display preference"}, {NULL, NULL, NULL, NULL} }; @@ -1133,7 +1204,8 @@ static command_t CommandTableSet[] = { {"hints", setCmdHint, AlwaysAvailable, "Set hint display"}, {"savepaths", setCmdSavePaths, AlwaysAvailable, "... to be adjusted next ... "}, // {"devicedebug", setCmdDeviceDebug, AlwaysAvailable, "Set device debug level"}, - {"plotsliders", setCmdPlotSliders, AlwaysAvailable, "Set plot slider display"}, + {"output", setCmdOutput, AlwaysAvailable, "Set dump output style"}, + {"plotsliders", setCmdPlotSliders, AlwaysAvailable, "Set plot slider display"}, {NULL, NULL, NULL, NULL} }; @@ -1189,6 +1261,7 @@ static int CmdPrefShow(const char *Cmd) { // showDeviceDebugState(prefShowNone); showBarModeState(prefShowNone); showClientExeDelayState(); + showOutputState(prefShowNone); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; diff --git a/client/src/ui.h b/client/src/ui.h index ec496fd80..6b1ac4a83 100644 --- a/client/src/ui.h +++ b/client/src/ui.h @@ -47,6 +47,7 @@ typedef struct { bool pm3_present; bool help_dump_mode; bool show_hints; + bool dense_output; bool window_changed; // track if plot/overlay pos/size changed to save on exit qtWindow_t plot; qtWindow_t overlay; From 0177d2185f9be0458752035b2d50423fcf76b821 Mon Sep 17 00:00:00 2001 From: nvx Date: Sat, 23 Jul 2022 22:26:25 +1000 Subject: [PATCH 145/759] Added more details to the annotations of `hf mfdes list` output --- CHANGELOG.md | 1 + client/src/cmdhflist.c | 172 ++++++++++++++++++++++++++++++++--------- 2 files changed, 135 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db793db9a..5f074cc6d 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] + - Added more details to the annotations of `hf mfdes list` output (@nvx) - Changed `hf iclass view` and related to suppress consecutive blocks with repeated contents with a `-z` flag, or `prefs set output --dense` (@nvx) - Changed `hf iclass list` to display matched keys on the CHECK command rather than the card response, and made it check for elite keys too (@nvx) - Fixed `hf iclass info` and `hf iclass view` key access info looking at the wrong card config bit (@nvx) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index f326a8abb..b33cd37bf 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -884,18 +884,40 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { for (uint8_t i = 0; i < 2; i++, pos++) { bool found_annotation = true; + uint8_t *data = cmd + pos + 1; + // if the byte prior to the command is 90 the command is wrapped, so data starts 3 bytes later + if (i > 0 && cmd[pos - 1] == 0x90) { + data += 3; + } + uint8_t data_size = 0; + if (cmdsize > (data - cmd)) { + data_size = cmdsize - (data - cmd); + } + switch (cmd[pos]) { case MFDES_CREATE_APPLICATION: - snprintf(exp, size, "CREATE APPLICATION"); + if (data_size >= 3) { + snprintf(exp, size, "CREATE APPLICATION (appId %06x)", MemLeToUint3byte(data)); + } else { + snprintf(exp, size, "CREATE APPLICATION"); + } break; case MFDES_DELETE_APPLICATION: - snprintf(exp, size, "DELETE APPLICATION"); + if (data_size >= 3) { + snprintf(exp, size, "DELETE APPLICATION (appId %06x)", MemLeToUint3byte(data)); + } else { + snprintf(exp, size, "DELETE APPLICATION"); + } break; case MFDES_GET_APPLICATION_IDS: snprintf(exp, size, "GET APPLICATION IDS"); break; case MFDES_SELECT_APPLICATION: - snprintf(exp, size, "SELECT APPLICATION"); + if (data_size >= 3) { + snprintf(exp, size, "SELECT APPLICATION (appId %06x)", MemLeToUint3byte(data)); + } else { + snprintf(exp, size, "SELECT APPLICATION"); + } break; case MFDES_FORMAT_PICC: snprintf(exp, size, "FORMAT PICC"); @@ -904,31 +926,67 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { snprintf(exp, size, "GET VERSION"); break; case MFDES_READ_DATA: - snprintf(exp, size, "READ DATA"); + if (data_size >= 7) { + snprintf(exp, size, "READ DATA (fileId %02x, offset %d, len %d)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); + } else { + snprintf(exp, size, "READ DATA"); + } break; case MFDES_WRITE_DATA: - snprintf(exp, size, "WRITE DATA"); + if (data_size >= 7) { + snprintf(exp, size, "WRITE DATA (fileId %02x, offset %d, len %d)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); + } else { + snprintf(exp, size, "WRITE DATA"); + } break; case MFDES_GET_VALUE: - snprintf(exp, size, "GET VALUE"); + if (data_size >= 1) { + snprintf(exp, size, "GET VALUE (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "GET VALUE"); + } break; case MFDES_CREDIT: - snprintf(exp, size, "CREDIT"); + if (data_size >= 1) { + snprintf(exp, size, "CREDIT (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "CREDIT"); + } break; case MFDES_DEBIT: - snprintf(exp, size, "DEBIT"); + if (data_size >= 1) { + snprintf(exp, size, "DEBIT (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "DEBIT"); + } break; case MFDES_LIMITED_CREDIT: - snprintf(exp, size, "LIMITED CREDIT"); + if (data_size >= 1) { + snprintf(exp, size, "LIMITED CREDIT (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "LIMITED CREDIT"); + } break; case MFDES_WRITE_RECORD: - snprintf(exp, size, "WRITE RECORD"); + if (data_size >= 7) { + snprintf(exp, size, "WRITE RECORD (fileId %02x, offset %d, len %d)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); + } else { + snprintf(exp, size, "WRITE RECORD"); + } break; case MFDES_READ_RECORDS: - snprintf(exp, size, "READ RECORDS"); + if (data_size >= 7) { + snprintf(exp, size, "READ RECORDS (fileId %02x, offset %d, len %d)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); + } else { + snprintf(exp, size, "READ RECORDS"); + } break; case MFDES_CLEAR_RECORD_FILE: - snprintf(exp, size, "CLEAR RECORD FILE"); + if (data_size >= 1) { + snprintf(exp, size, "CLEAR RECORD FILE (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "CLEAR RECORD FILE"); + } break; case MFDES_COMMIT_TRANSACTION: snprintf(exp, size, "COMMIT TRANSACTION"); @@ -949,57 +1007,87 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { snprintf(exp, size, "GET ISOFILE IDS"); break; case MFDES_GET_FILE_SETTINGS: - snprintf(exp, size, "GET FILE SETTINGS"); + if (data_size >= 1) { + snprintf(exp, size, "GET FILE SETTINGS (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "GET FILE SETTINGS"); + } break; case MFDES_CHANGE_FILE_SETTINGS: - snprintf(exp, size, "CHANGE FILE SETTINGS"); + if (data_size >= 1) { + snprintf(exp, size, "CHANGE FILE SETTINGS (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "CHANGE FILE SETTINGS"); + } break; case MFDES_CREATE_STD_DATA_FILE: - snprintf(exp, size, "CREATE STD DATA FILE"); + if (data_size >= 1) { + snprintf(exp, size, "CREATE STD DATA FILE (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "CREATE STD DATA FILE"); + } break; case MFDES_CREATE_BACKUP_DATA_FILE: - snprintf(exp, size, "CREATE BACKUP DATA FILE"); + if (data_size >= 1) { + snprintf(exp, size, "CREATE BACKUP DATA FILE (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "CREATE BACKUP DATA FILE"); + } break; case MFDES_CREATE_VALUE_FILE: - snprintf(exp, size, "CREATE VALUE FILE"); + if (data_size >= 1) { + snprintf(exp, size, "CREATE VALUE FILE (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "CREATE VALUE FILE"); + } break; case MFDES_CREATE_LINEAR_RECORD_FILE: - snprintf(exp, size, "CREATE LINEAR RECORD FILE"); + if (data_size >= 1) { + snprintf(exp, size, "CREATE LINEAR RECORD FILE (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "CREATE LINEAR RECORD FILE"); + } break; case MFDES_CREATE_CYCLIC_RECORD_FILE: - snprintf(exp, size, "CREATE CYCLIC RECORD FILE"); + if (data_size >= 1) { + snprintf(exp, size, "CREATE CYCLIC RECORD FILE (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "CREATE CYCLIC RECORD FILE"); + } break; case MFDES_CREATE_TRANS_MAC_FILE: - snprintf(exp, size, "CREATE TRANSACTION MAC FILE"); + if (data_size >= 1) { + snprintf(exp, size, "CREATE TRANSACTION MAC FILE (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "CREATE TRANSACTION MAC FILE"); + } break; case MFDES_DELETE_FILE: - snprintf(exp, size, "DELETE FILE"); + if (data_size >= 1) { + snprintf(exp, size, "DELETE FILE (fileId %02x)", data[0]); + } else { + snprintf(exp, size, "DELETE FILE"); + } break; case MFDES_AUTHENTICATE: - if (cmdsize > 6) { - //Assume wrapped - snprintf(exp, size, "AUTH NATIVE (keyNo %d)", cmd[pos + 4]); + if (data_size >= 1) { + snprintf(exp, size, "AUTH NATIVE (keyNo %d)", data[0]); } else { - //Assume unwrapped - snprintf(exp, size, "AUTH NATIVE (keyNo %d)", cmd[pos + 1]); + snprintf(exp, size, "AUTH NATIVE"); } break; // AUTHENTICATE_NATIVE case MFDES_AUTHENTICATE_ISO: - if (cmdsize > 6) { - //Assume wrapped - snprintf(exp, size, "AUTH ISO (keyNo %d)", cmd[pos + 4]); + if (data_size >= 1) { + snprintf(exp, size, "AUTH ISO (keyNo %d)", data[0]); } else { - //Assume unwrapped - snprintf(exp, size, "AUTH ISO (keyNo %d)", cmd[pos + 1]); + snprintf(exp, size, "AUTH ISO"); } break; // AUTHENTICATE_STANDARD case MFDES_AUTHENTICATE_AES: - if (cmdsize > 6) { - //Assume wrapped - snprintf(exp, size, "AUTH AES (keyNo %d)", cmd[pos + 4]); + if (data_size >= 1) { + snprintf(exp, size, "AUTH AES (keyNo %d)", data[0]); } else { - //Assume unwrapped - snprintf(exp, size, "AUTH AES (keyNo %d)", cmd[pos + 1]); + snprintf(exp, size, "AUTH AES"); } break; case MFDES_AUTHENTICATE_EV2F: @@ -1015,10 +1103,18 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { snprintf(exp, size, "GET KEY SETTINGS"); break; case MFDES_CHANGE_KEY: - snprintf(exp, size, "CHANGE KEY"); + if (data_size >= 1) { + snprintf(exp, size, "CHANGE KEY (keyNo %d)", data[0]); + } else { + snprintf(exp, size, "CHANGE KEY"); + } break; case MFDES_GET_KEY_VERSION: - snprintf(exp, size, "GET KEY VERSION"); + if (data_size >= 1) { + snprintf(exp, size, "GET KEY VERSION (keyNo %d)", data[0]); + } else { + snprintf(exp, size, "GET KEY VERSION"); + } break; case MFDES_ADDITIONAL_FRAME: snprintf(exp, size, "AUTH FRAME / NEXT FRAME"); From cb82e848cc95c9716ca29b302774cbe5b8b3d7c9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Jul 2022 17:37:04 +0200 Subject: [PATCH 146/759] dense format to follow previous .... style --- client/src/cmdhficlass.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index d009bb92d..cc53ff77e 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -660,6 +660,10 @@ static int CmdHFiClassSniff(const char *Cmd) { bool jam_epurse_update = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (jam_epurse_update) { + PrintAndLogEx(INFO, "Sniff with jam of iCLASS e-purse updates..."); + } + const uint8_t update_epurse_sequence[2] = {0x87, 0x02}; struct { @@ -2659,7 +2663,7 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e // we're in a user block that isn't the first user block nor last two user blocks, // and the current block data is the same as the previous and next two block in_repeated_block = true; - PrintAndLogEx(INFO, "*"); + PrintAndLogEx(INFO, " ......"); } else if (in_repeated_block && (memcmp(blk, blk + 8, 8) || i == endblock)) { // in a repeating block, but the next block doesn't match anymore, or we're at the end block in_repeated_block = false; @@ -3564,6 +3568,8 @@ void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elit for (int i = 0; i < iclass_tc; i++) pthread_join(threads[i], NULL); + + PrintAndLogEx(NORMAL, ""); } // print diversified keys From 5a8d9b7954ce2aa9b60e5f508395cfe65ee808bf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Jul 2022 17:39:40 +0200 Subject: [PATCH 147/759] prep mac --- armsrc/iclass.c | 5 +++++ client/src/cmdhficlass.c | 34 ++++++++++++++++++++++++++-------- include/iclass_cmd.h | 1 + 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 326d77298..c4dcb10b8 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1846,6 +1846,10 @@ void iClass_WriteBlock(uint8_t *msg) { AddCrc(write + 1, 9); write_len -= 2; } else { + + if (payload->req.use_replay) { + memcpy(write + 10, payload->mac, sizeof(payload->mac)); + } else { // Secure tags uses MAC uint8_t wb[9]; wb[0] = payload->req.blockno; @@ -1857,6 +1861,7 @@ void iClass_WriteBlock(uint8_t *msg) { doMAC_N(wb, sizeof(wb), hdr.key_d, mac); memcpy(write + 10, mac, sizeof(mac)); + } } start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index cc53ff77e..495e30ef4 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1909,7 +1909,7 @@ write_dump: return PM3_SUCCESS; } -static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool replay, bool verbose, bool use_secure_pagemode) { +static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *macdata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool replay, bool verbose, bool use_secure_pagemode) { iclass_writeblock_req_t payload = { .req.use_raw = rawkey, @@ -1923,6 +1923,10 @@ static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bo memcpy(payload.req.key, KEY, 8); memcpy(payload.data, bldata, sizeof(payload.data)); + if (replay) { + memcpy(payload.mac, macdata, sizeof(payload.mac)); + } + clearCommandBuffer(); SendCommandNG(CMD_HF_ICLASS_WRITEBL, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; @@ -1953,6 +1957,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { arg_int0(NULL, "ki", "", "Key index to select key from memory 'hf iclass managekeys'"), arg_int1("b", "block", "", "The block number to read"), arg_str1("d", "data", "", "data to write as 8 hex bytes"), + arg_str0("m", "mac", "", "replay mac data (4 hex bytes)"), arg_lit0(NULL, "credit", "key is assumed to be the credit key"), arg_lit0(NULL, "elite", "elite computations applied to key"), arg_lit0(NULL, "raw", "no computations applied to key"), @@ -2008,11 +2013,24 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { return PM3_EINVARG; } - bool use_credit_key = arg_get_lit(ctx, 5); - bool elite = arg_get_lit(ctx, 6); - bool rawkey = arg_get_lit(ctx, 7); - bool use_replay = arg_get_lit(ctx, 8); - bool verbose = arg_get_lit(ctx, 9); + int mac_len = 0; + uint8_t mac[4] = {0}; + CLIGetHexWithReturn(ctx, 5, mac, &mac_len); + + if (mac_len) { + if (mac_len != 4) { + PrintAndLogEx(ERR, "MAC must be 4 hex bytes (8 hex symbols)"); + CLIParserFree(ctx); + return PM3_EINVARG; + } + } + + + bool use_credit_key = arg_get_lit(ctx, 6); + bool elite = arg_get_lit(ctx, 7); + bool rawkey = arg_get_lit(ctx, 8); + bool use_replay = arg_get_lit(ctx, 9); + bool verbose = arg_get_lit(ctx, 10); CLIParserFree(ctx); @@ -2021,7 +2039,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { return PM3_EINVARG; } - int isok = iclass_write_block(blockno, data, key, use_credit_key, elite, rawkey, use_replay, verbose, auth); + int isok = iclass_write_block(blockno, data, mac, key, use_credit_key, elite, rawkey, use_replay, verbose, auth); switch (isok) { case PM3_SUCCESS: PrintAndLogEx(SUCCESS, "Wrote block %3d/0x%02X successful", blockno, blockno); @@ -3891,7 +3909,7 @@ static int CmdHFiClassEncode(const char *Cmd) { int isok = PM3_SUCCESS; // write for (uint8_t i = 0; i < 4; i++) { - isok = iclass_write_block(6 + i, credential + (i * 8), key, use_credit_key, elite, rawkey, false, false, auth); + isok = iclass_write_block(6 + i, credential + (i * 8), NULL, key, use_credit_key, elite, rawkey, false, false, auth); switch (isok) { case PM3_SUCCESS: PrintAndLogEx(SUCCESS, "Write block %d/0x0%x ( " _GREEN_("ok") " ) --> " _YELLOW_("%s"), 6 + i, 6 + i, sprint_hex_inrow(credential + (i * 8), 8)); diff --git a/include/iclass_cmd.h b/include/iclass_cmd.h index e78531868..5a2f90226 100644 --- a/include/iclass_cmd.h +++ b/include/iclass_cmd.h @@ -82,6 +82,7 @@ typedef struct { typedef struct { iclass_auth_req_t req; uint8_t data[8]; + uint8_t mac[4]; } PACKED iclass_writeblock_req_t; // iCLASS dump data structure From 3001e2edce2db476bca6a28fea445bf148535cad Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 23 Jul 2022 18:08:33 +0200 Subject: [PATCH 148/759] fix some SE / SIO ends with 0x05 , 0x00 only --- client/src/cmdhficlass.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 495e30ef4..ae2f18c07 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -2476,13 +2476,17 @@ static int CmdHFiClass_loclass(const char *Cmd) { static void detect_credential(uint8_t *data, bool *legacy, bool *se, bool *sr) { bool r1 = !memcmp(data + (5 * 8), "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8); - uint8_t pattern[] = {0x05, 0x00, 0x05, 0x00}; - bool r2 = byte_strstr(data + (11 * 8), 6 * 8, pattern, sizeof(pattern)) != -1; + + uint8_t pattern_se[] = {0x05, 0x00}; + bool r2 = byte_strstr(data + (6 * 8), 6 * 8, pattern_se, sizeof(pattern_se)) != -1; + + uint8_t pattern_sr[] = {0x05, 0x00, 0x05, 0x00}; + bool r3 = byte_strstr(data + (11 * 8), 6 * 8, pattern_sr, sizeof(pattern_sr)) != -1; *legacy = (r1) && (data[6 * 8] != 0x30); *se = (r2) && (data[6 * 8] == 0x30); - *sr = (r2) && (data[10 * 8] == 0x30); - r1 = NULL, r2 = NULL; + *sr = (r3) && (data[10 * 8] == 0x30); + r1 = NULL, r2 = NULL, r3 = NULL; } // print ASN1 decoded array in TLV view @@ -2491,23 +2495,30 @@ static void printIclassSIO(uint8_t *iclass_dump) { bool isLegacy, isSE, isSR; detect_credential(iclass_dump, &isLegacy, &isSE, &isSR); + int dlen = 0; uint8_t *sio_start; if (isSE) { + sio_start = iclass_dump + (6 * 8); + uint8_t pattern_se[] = {0x05, 0x00}; + dlen = byte_strstr(sio_start, 8 * 8, pattern_se, sizeof(pattern_se)); + if (dlen == -1) { + return; + } + dlen += sizeof(pattern_se); } else if (isSR) { + sio_start = iclass_dump + (10 * 8); + uint8_t pattern_sr[] = {0x05, 0x00, 0x05, 0x00}; + dlen = byte_strstr(sio_start, 8 * 8, pattern_sr, sizeof(pattern_sr)); + if (dlen == -1) { + return; + } + dlen += sizeof(pattern_sr); } else { return; } - uint8_t pattern[] = {0x05, 0x00, 0x05, 0x00}; - int dlen = byte_strstr(sio_start, 8 * 8, pattern, sizeof(pattern)); - if (dlen == -1) { - return; - } - - dlen += sizeof(pattern); - PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "---------------------------- " _CYAN_("SIO - RAW") " ----------------------------"); print_hex_noascii_break(sio_start, dlen, 32); @@ -2515,7 +2526,6 @@ static void printIclassSIO(uint8_t *iclass_dump) { PrintAndLogEx(INFO, "------------------------- " _CYAN_("SIO - ASN1 TLV") " --------------------------"); asn1_print(sio_start, dlen, " "); PrintAndLogEx(NORMAL, ""); - } void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize, bool dense_output) { @@ -2686,7 +2696,8 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e // in a repeating block, but the next block doesn't match anymore, or we're at the end block in_repeated_block = false; } - if (!in_repeated_block) { + + if (in_repeated_block == false) { PrintAndLogEx(INFO, "%3d/0x%02X | %s | %s | %s ", i, From 9040a1a7d701148cedb06020144bc4820a8ae044 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Jul 2022 08:21:49 +0200 Subject: [PATCH 149/759] causes extra lines in trace list. --- client/src/cmdhficlass.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index ae2f18c07..e920f9f5d 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -3598,7 +3598,6 @@ void GenerateMacKeyFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elit for (int i = 0; i < iclass_tc; i++) pthread_join(threads[i], NULL); - PrintAndLogEx(NORMAL, ""); } // print diversified keys From 51408c89f6431692ad544d5434369ec8c4a3dd24 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 24 Jul 2022 11:41:25 +0200 Subject: [PATCH 150/759] fix #1722, this should fix the breaking on OSX for apdufind. Seems u64 triggers something in memory. Passing ref to array and makeing array u32 instead --- client/src/cmdhf14a.c | 46 ++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 3fe0840d6..3975f3926 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -2371,16 +2371,23 @@ int infoHF14A4Applications(bool verbose) { return found; } -static uint64_t inc_sw_error_occurrence(uint16_t sw, uint64_t all_sw[256][256]) { +static uint32_t inc_sw_error_occurrence(uint16_t sw, uint32_t *all_sw) { uint8_t sw1 = (uint8_t)(sw >> 8); uint8_t sw2 = (uint8_t)(0xff & sw); + + // Don't count successes if (sw1 == 0x90 && sw2 == 0x00) { - return 0; // Don't count successes. + return 0; } - if (sw1 == 0x6d && sw2 == 0x00) { - return 0xffffffffffffffffULL; // Always max "Instruction not supported". + + // Always max "Instruction not supported" + if (sw1 == 0x6D && sw2 == 0x00) { + return 0xFFFFFFFFUL; } - return ++all_sw[sw1][sw2]; + + all_sw[(sw1 * 256) + sw2]++; + + return all_sw[(sw1 * 256) + sw2]; } static int CmdHf14AFindapdu(const char *Cmd) { @@ -2416,20 +2423,26 @@ static int CmdHf14AFindapdu(const char *Cmd) { int cla_len = 0; uint8_t cla_arg[1] = {0}; CLIGetHexWithReturn(ctx, 1, cla_arg, &cla_len); + int ins_len = 0; uint8_t ins_arg[1] = {0}; CLIGetHexWithReturn(ctx, 2, ins_arg, &ins_len); + int p1_len = 0; uint8_t p1_arg[1] = {0}; CLIGetHexWithReturn(ctx, 3, p1_arg, &p1_len); + int p2_len = 0; uint8_t p2_arg[1] = {0}; CLIGetHexWithReturn(ctx, 4, p2_arg, &p2_len); + uint64_t reset_time = arg_get_u64_def(ctx, 5, 5 * 60); - uint64_t error_limit = arg_get_u64_def(ctx, 6, 512); + uint32_t error_limit = arg_get_u64_def(ctx, 6, 512); + int ignore_ins_len = 0; uint8_t ignore_ins_arg[250] = {0}; CLIGetHexWithReturn(ctx, 7, ignore_ins_arg, &ignore_ins_len); + bool with_le = arg_get_lit(ctx, 8); bool verbose = arg_get_lit(ctx, 9); @@ -2441,7 +2454,8 @@ static int CmdHf14AFindapdu(const char *Cmd) { uint8_t ins = ins_arg[0]; uint8_t p1 = p1_arg[0]; uint8_t p2 = p2_arg[0]; - uint8_t response[PM3_CMD_DATA_SIZE]; + + uint8_t response[PM3_CMD_DATA_SIZE] = {0}; int response_n = 0; uint8_t aSELECT_AID[80]; int aSELECT_AID_n = 0; @@ -2461,8 +2475,9 @@ static int CmdHf14AFindapdu(const char *Cmd) { bool inc_p1 = false; bool skip_ins = false; - uint64_t all_sw[256][256] = { { 0 } }; - uint64_t sw_occurrences = 0; + uint32_t all_sw[256][256] = { { 0 } }; + uint32_t sw_occurrences = 0; + uint64_t t_start = msclock(); uint64_t t_last_reset = msclock(); @@ -2484,6 +2499,7 @@ retry_ins: break; } } + if (skip_ins) { skip_ins = false; continue; @@ -2504,8 +2520,9 @@ retry_ins: activate_field = true; goto retry_ins; } + uint16_t sw = get_sw(response, response_n); - sw_occurrences = inc_sw_error_occurrence(sw, all_sw); + sw_occurrences = inc_sw_error_occurrence(sw, all_sw[0]); // Show response. if (sw_occurrences < error_limit) { @@ -2530,15 +2547,19 @@ retry_ins: } } } - activate_field = false; // Do not reativate the filed until the next reset. + // Do not reativate the filed until the next reset. + activate_field = false; } while (++ins != ins_arg[0]); + // Increment P1/P2 in an alternating fashion. if (inc_p1) { p1++; } else { p2++; } + inc_p1 = !inc_p1; + // Check if re-selecting the card is needed. uint64_t t_since_last_reset = ((msclock() - t_last_reset) / 1000); if (t_since_last_reset > reset_time) { @@ -2548,9 +2569,12 @@ retry_ins: PrintAndLogEx(INFO, "Last reset was %" PRIu64 " seconds ago. Resetting the tag to prevent timeout issues", t_since_last_reset); } PrintAndLogEx(INFO, "Status: [ CLA " _GREEN_("%02X") " INS " _GREEN_("%02X") " P1 " _GREEN_("%02X") " P2 " _GREEN_("%02X") " ]", cla, ins, p1, p2); + } while (p1 != p1_arg[0] || p2 != p2_arg[0]); + cla++; PrintAndLogEx(INFO, "Status: [ CLA " _GREEN_("%02X") " INS " _GREEN_("%02X") " P1 " _GREEN_("%02X") " P2 " _GREEN_("%02X") " ]", cla, ins, p1, p2); + } while (cla != cla_arg[0]); out: From 2f7083a59af93ff7750967b74c9cba16f3b0eab6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Jul 2022 07:45:57 +0200 Subject: [PATCH 151/759] text --- client/src/cmdhfmf.c | 10 +++++++--- client/src/cmdhfmfu.c | 5 ++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index b98e7bc1f..b5d061215 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -3421,18 +3421,22 @@ void readerAttack(sector_t *k_sector, uint8_t k_sectorsCount, nonces_t data, boo static int CmdHF14AMfSim(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf sim", - "Simulate MIFARE Classic card", + "Simulate MIFARE Classic family type based upon\n" + "ISO/IEC 14443 type A tag with 4,7 or 10 byte UID\n" + "from emulator memory. See `hf mf eload` first.\n" + "The UID from emulator memory will be used if not specified.", "hf mf sim --mini --> MIFARE Mini\n" "hf mf sim --1k --> MIFARE Classic 1k (default)\n" "hf mf sim --1k -u 0a0a0a0a --> MIFARE Classic 1k with 4b UID\n" "hf mf sim --1k -u 11223344556677 --> MIFARE Classic 1k with 7b UID\n" "hf mf sim --1k -u 11223344 -i -x --> Perform reader attack in interactive mode\n" "hf mf sim --2k --> MIFARE 2k\n" - "hf mf sim --4k --> MIFARE 4k"); + "hf mf sim --4k --> MIFARE 4k" + ); void *argtable[] = { arg_param_begin, - arg_str0("u", "uid", "", "UID 4,7 or 10bytes. If not specified, the UID 4b/7b from emulator memory will be used"), + arg_str0("u", "uid", "", "<4|7|10> hex bytes UID"), arg_lit0(NULL, "mini", "MIFARE Classic Mini / S20"), arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50"), arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 20b443787..60196afbd 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -2716,6 +2716,7 @@ static int CmdHF14AMfUeLoad(const char *Cmd) { int res = CmdHF14AMfELoad(nc); free(nc); + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfu sim -t 7`") " to simulate an Amiibo."); return res; } // @@ -2727,9 +2728,11 @@ static int CmdHF14AMfUSim(const char *Cmd) { "Simulate MIFARE Ultralight family type based upon\n" "ISO/IEC 14443 type A tag with 4,7 or 10 byte UID\n" "from emulator memory. See `hf mfu eload` first. \n" + "The UID from emulator memory will be used if not specified.\n" "See `hf 14a sim -h` to see available types. You want 2 or 7 usually.", "hf mfu sim -t 2 --uid 11223344556677 -> MIFARE Ultralight\n" - "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> AMIIBO (NTAG 215), pack 0x8080" + "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> Amiibo (NTAG 215), pack 0x8080\n" + "hf mfu sim -t 7 -> Amiibo (NTAG 215), pack 0x8080" ); void *argtable[] = { From 6290d505648f8d6bde4be9e1d0e77e941a11c006 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Jul 2022 08:00:30 +0200 Subject: [PATCH 152/759] make style --- armsrc/hfsnoop.c | 2 +- armsrc/iclass.c | 18 +++++++++--------- client/src/cmdhf.c | 12 ++++++------ client/src/cmdhf14a.c | 6 +++--- client/src/cmdhftexkom.c | 8 ++++---- client/src/cmdhfxerox.c | 4 ++-- client/src/pm3line_vocabulory.h | 3 +++ client/src/util.c | 10 +++++----- client/src/util.h | 2 +- doc/commands.md | 4 ++++ 10 files changed, 38 insertions(+), 31 deletions(-) diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index 0c9334c99..59931ea66 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -58,7 +58,7 @@ static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, u case HF_SNOOP_SKIP_AVG: accum += (val & 0xff) + (val & 0xff); break; - default: { // HF_SNOOP_SKIP_DROP and the rest + default: { // HF_SNOOP_SKIP_DROP and the rest if (ratioindx == 0) accum = val & 0xff; } diff --git a/armsrc/iclass.c b/armsrc/iclass.c index c4dcb10b8..1ed774f16 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1850,17 +1850,17 @@ void iClass_WriteBlock(uint8_t *msg) { if (payload->req.use_replay) { memcpy(write + 10, payload->mac, sizeof(payload->mac)); } else { - // Secure tags uses MAC - uint8_t wb[9]; - wb[0] = payload->req.blockno; - memcpy(wb + 1, payload->data, 8); + // Secure tags uses MAC + uint8_t wb[9]; + wb[0] = payload->req.blockno; + memcpy(wb + 1, payload->data, 8); - if (payload->req.use_credit_key) - doMAC_N(wb, sizeof(wb), hdr.key_c, mac); - else - doMAC_N(wb, sizeof(wb), hdr.key_d, mac); + if (payload->req.use_credit_key) + doMAC_N(wb, sizeof(wb), hdr.key_c, mac); + else + doMAC_N(wb, sizeof(wb), hdr.key_d, mac); - memcpy(write + 10, mac, sizeof(mac)); + memcpy(write + 10, mac, sizeof(mac)); } } diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 2fe5cbd9e..44b9b078f 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -303,7 +303,7 @@ int CmdHFTune(const char *Cmd) { typedef enum { HF_SNOOP_SKIP_NONE = 0x00, - HF_SNOOP_SKIP_DROP = 0x01, + HF_SNOOP_SKIP_DROP = 0x01, HF_SNOOP_SKIP_MAX = 0x02, HF_SNOOP_SKIP_MIN = 0x03, HF_SNOOP_SKIP_AVG = 0x04 @@ -364,10 +364,10 @@ int CmdHFSniff(const char *Cmd) { CLIParserFree(ctx); if (params.skipMode != HF_SNOOP_SKIP_NONE) { - PrintAndLogEx(INFO, "Skip mode. Function: %s, each: %d sample", - CLIGetOptionListStr(HFSnoopSkipModeOpts, params.skipMode), - params.skipRatio * 2 - ); + PrintAndLogEx(INFO, "Skip mode. Function: %s, each: %d sample", + CLIGetOptionListStr(HFSnoopSkipModeOpts, params.skipMode), + params.skipRatio * 2 + ); } clearCommandBuffer(); @@ -479,7 +479,7 @@ static command_t CommandTable[] = { {"emrtd", CmdHFeMRTD, AlwaysAvailable, "{ Machine Readable Travel Document... }"}, {"felica", CmdHFFelica, AlwaysAvailable, "{ ISO18092 / FeliCa RFIDs... }"}, {"fido", CmdHFFido, AlwaysAvailable, "{ FIDO and FIDO2 authenticators... }"}, - {"fudan", CmdHFFudan, AlwaysAvailable, "{ Fudan RFIDs... }"}, + {"fudan", CmdHFFudan, AlwaysAvailable, "{ Fudan RFIDs... }"}, {"gallagher", CmdHFGallagher, AlwaysAvailable, "{ Gallagher DESFire RFIDs... }"}, {"ksx6924", CmdHFKSX6924, AlwaysAvailable, "{ KS X 6924 (T-Money, Snapper+) RFIDs }"}, {"jooki", CmdHF_Jooki, AlwaysAvailable, "{ Jooki RFIDs... }"}, diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 3975f3926..dbd289820 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -655,7 +655,7 @@ int CmdHF14ASim(const char *Cmd) { "hf 14a sim -t 4 -> ISO/IEC 14443-4\n" "hf 14a sim -t 5 -> MIFARE Tnp3xxx\n" "hf 14a sim -t 6 -> MIFARE Mini\n" - "hf 14a sim -t 7 -> AMIIBO (NTAG 215), pack 0x8080\n" + "hf 14a sim -t 7 -> Amiibo (NTAG 215), pack 0x8080\n" "hf 14a sim -t 8 -> MIFARE Classic 4k\n" "hf 14a sim -t 9 -> FM11RF005SH Shanghai Metro\n" "hf 14a sim -t 10 -> ST25TA IKEA Rothult\n"); @@ -663,7 +663,7 @@ int CmdHF14ASim(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_int1("t", "type", "<1-10> ", "Simulation type to use"), - arg_str0("u", "uid", "", "4, 7 or 10 byte UID"), + arg_str0("u", "uid", "", "<4|7|10> hex bytes UID"), arg_int0("n", "num", "", "Exit simulation after blocks have been read by reader. 0 = infinite"), arg_lit0("x", NULL, "Performs the 'reader attack', nr/ar attack against a reader"), arg_lit0(NULL, "sk", "Fill simulator keys from found keys"), @@ -2379,7 +2379,7 @@ static uint32_t inc_sw_error_occurrence(uint16_t sw, uint32_t *all_sw) { if (sw1 == 0x90 && sw2 == 0x00) { return 0; } - + // Always max "Instruction not supported" if (sw1 == 0x6D && sw2 == 0x00) { return 0xFFFFFFFFUL; diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 9cbf238ad..0ab454117 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -193,9 +193,9 @@ static uint8_t TexcomTK13CRC(const uint8_t *data) { static uint8_t MMBITCRC(const uint8_t *data) { return - (( (data[0] & 0x0f) ^ ((data[0] >> 4) & 0x0f) ^ - (data[1] & 0x0f) ^ ((data[1] >> 4) & 0x0f) ^ - (data[2] & 0x0f) ^ ((data[2] >> 4) & 0x0f) + (((data[0] & 0x0f) ^ ((data[0] >> 4) & 0x0f) ^ + (data[1] & 0x0f) ^ ((data[1] >> 4) & 0x0f) ^ + (data[2] & 0x0f) ^ ((data[2] >> 4) & 0x0f) ) ^ 0x0f ) & 0x0f; } @@ -310,7 +310,7 @@ static bool TexcomTK15Decode(uint32_t *implengths, uint32_t implengthslen, char int lastimplen = implengths[implengthslen - 1]; bool prevbit = (implengths[implengthslen - 3] > implengths[implengthslen - 2]); bool thesamebit = (abs(lastimplen - (int)implengths[implengthslen - 3]) < abs(lastimplen - (int)implengths[implengthslen - 2])); - + if (prevbit ^ !thesamebit) { strcat(bitstring, "10"); strcat(cbitstring, "1"); diff --git a/client/src/cmdhfxerox.c b/client/src/cmdhfxerox.c index 5b7f39abe..578f797e0 100644 --- a/client/src/cmdhfxerox.c +++ b/client/src/cmdhfxerox.c @@ -470,7 +470,7 @@ static int CmdHFXeroxReader(const char *Cmd) { "Act as a 14443B reader to identify a tag", "hf xerox reader\n" "hf xerox reader -@ \n" - ); + ); void *argtable[] = { arg_param_begin, @@ -495,7 +495,7 @@ static int CmdHFXeroxInfo(const char *Cmd) { CLIParserInit(&ctx, "hf xerox info", "Tag information for ISO/IEC 14443 type B / XEROX based tags", "hf xerox info" - ); + ); void *argtable[] = { arg_param_begin, diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 982cbd734..706ee38a4 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -48,6 +48,7 @@ const static vocabulory_t vocabulory[] = { { 1, "prefs get savepaths" }, { 1, "prefs get emoji" }, { 1, "prefs get hints" }, + { 1, "prefs get output" }, { 1, "prefs get plotsliders" }, { 1, "prefs set help" }, { 1, "prefs set barmode" }, @@ -57,6 +58,7 @@ const static vocabulory_t vocabulory[] = { { 1, "prefs set emoji" }, { 1, "prefs set hints" }, { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, { 1, "prefs set plotsliders" }, { 1, "analyse help" }, { 1, "analyse lcr" }, @@ -431,6 +433,7 @@ const static vocabulory_t vocabulory[] = { { 0, "hf texkom sim" }, { 1, "hf xerox help" }, { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, { 0, "hf xerox dump" }, { 1, "hf waveshare help" }, { 0, "hf waveshare loadbmp" }, diff --git a/client/src/util.c b/client/src/util.c index 226a813df..57e213feb 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -1236,20 +1236,20 @@ inline uint64_t leadingzeros64(uint64_t a) { } -int byte_strstr(uint8_t* src, size_t srclen, uint8_t* pattern, size_t plen) { +int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen) { size_t max = srclen - plen + 1; for (size_t i = 0; i < max; i++) { // compare only first byte - if (src[i] != pattern[0]) + if (src[i] != pattern[0]) continue; - + // try to match rest of the pattern for (int j = plen - 1; j >= 1; j--) { - if (src[i + j] != pattern[j]) + if (src[i + j] != pattern[j]) break; if (j == 1) @@ -1257,4 +1257,4 @@ int byte_strstr(uint8_t* src, size_t srclen, uint8_t* pattern, size_t plen) { } } return -1; -} \ No newline at end of file +} diff --git a/client/src/util.h b/client/src/util.h index 064c88803..939e0a55d 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -145,5 +145,5 @@ uint64_t bitcount64(uint64_t a); uint32_t leadingzeros32(uint32_t a); uint64_t leadingzeros64(uint64_t a); -int byte_strstr(uint8_t* src, size_t srclen, uint8_t* pattern, size_t plen); +int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen); #endif diff --git a/doc/commands.md b/doc/commands.md index 3ff0c57cf..1bb282715 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -43,6 +43,7 @@ Check column "offline" for their availability. |`prefs get savepaths `|Y |`Get file folder ` |`prefs get emoji `|Y |`Get emoji display preference` |`prefs get hints `|Y |`Get hint display preference` +|`prefs get output `|Y |`Get dump output style preference` |`prefs get plotsliders `|Y |`Get plot slider display preference` @@ -60,6 +61,7 @@ Check column "offline" for their availability. |`prefs set emoji `|Y |`Set emoji display` |`prefs set hints `|Y |`Set hint display` |`prefs set savepaths `|Y |`... to be adjusted next ... ` +|`prefs set output `|Y |`Set dump output style` |`prefs set plotsliders `|Y |`Set plot slider display` @@ -335,6 +337,7 @@ Check column "offline" for their availability. |`hf gallagher clone `|N |`Add Gallagher credentials to a DESFire card` |`hf gallagher delete `|N |`Delete Gallagher credentials from a DESFire card` |`hf gallagher diversifykey`|Y |`Diversify Gallagher key` +|`hf gallagher decode `|Y |`Decode Gallagher credential block` ### hf ksx6924 @@ -666,6 +669,7 @@ Check column "offline" for their availability. |------- |------- |----------- |`hf xerox help `|Y |`This help` |`hf xerox info `|N |`Short info on Fuji/Xerox tag` +|`hf xerox reader `|N |`Act like a Fuji/Xerox reader` |`hf xerox dump `|N |`Read all memory pages of an Fuji/Xerox tag, save to file` From 0ba072118e183214e98c714f29e2bd192574159f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 25 Jul 2022 08:01:38 +0200 Subject: [PATCH 153/759] calloc --- client/deps/cliparser/cliparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index 980e3134d..bcdb4b3d8 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -33,7 +33,7 @@ // Example width set to 50 to allow help descriptions to align. approx line 93 int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) { - *ctx = malloc(sizeof(CLIParserContext)); + *ctx = calloc(sizeof(CLIParserContext), sizeof(uint8_t)); if (!*ctx) { PrintAndLogEx(ERR, "ERROR: Insufficient memory\n"); return 2; From 17ee1ba3bba3fe7089f6f73a7d35bcb6b6c7dcaf Mon Sep 17 00:00:00 2001 From: George Talusan Date: Tue, 26 Jul 2022 13:05:43 -0400 Subject: [PATCH 154/759] add hf_mfu_amiibo_sim to simulate Amiibo binary dumps --- client/luascripts/hf_mfu_amiibo_sim.lua | 2796 +++++++++++++++++++++++ 1 file changed, 2796 insertions(+) create mode 100644 client/luascripts/hf_mfu_amiibo_sim.lua diff --git a/client/luascripts/hf_mfu_amiibo_sim.lua b/client/luascripts/hf_mfu_amiibo_sim.lua new file mode 100644 index 000000000..99d21ea7d --- /dev/null +++ b/client/luascripts/hf_mfu_amiibo_sim.lua @@ -0,0 +1,2796 @@ +local cmds = require('commands') +local getopt = require('getopt') +local bin = require('bin') +local utils = require('utils') +local ansicolors = require('ansicolors') + +-- curl https://raw.githubusercontent.com/N3evin/AmiiboAPI/master/database/amiibo.json | jq 'del(.amiibos[].release)' | jq 'del(.characters)' | pbcopy --> transform to table +local amiiboDb = +{ + amiibo_series = { + ["0x00"] = "Super Smash Bros.", + ["0x01"] = "Super Mario Bros.", + ["0x02"] = "Chibi-Robo!", + ["0x03"] = "Yoshi's Woolly World", + ["0x04"] = "Splatoon", + ["0x05"] = "Animal Crossing", + ["0x06"] = "8-bit Mario", + ["0x07"] = "Skylanders", + ["0x09"] = "Legend Of Zelda", + ["0x0a"] = "Shovel Knight", + ["0x0c"] = "Kirby", + ["0x0d"] = "Pokemon", + ["0x0e"] = "Mario Sports Superstars", + ["0x0f"] = "Monster Hunter", + ["0x10"] = "BoxBoy!", + ["0x11"] = "Pikmin", + ["0x12"] = "Fire Emblem", + ["0x13"] = "Metroid", + ["0x14"] = "Others", + ["0x15"] = "Mega Man", + ["0x16"] = "Diablo", + ["0x17"] = "Power Pros", + ["0x18"] = "Monster Hunter Rise", + ["0x19"] = "Yu-Gi-Oh!", + ["0xff"] = "Super Nintendo World" + }, + amiibos = { + ["0x0000000000000002"] = { + name = "Mario" + }, + ["0x0000000000340102"] = { + name = "Mario" + }, + ["0x00000000003c0102"] = { + name = "Mario - Gold Edition" + }, + ["0x00000000003d0102"] = { + name = "Mario - Silver Edition" + }, + ["0x0000000002380602"] = { + name = "8-Bit Mario Classic Color" + }, + ["0x0000000002390602"] = { + name = "8-Bit Mario Modern Color" + }, + ["0x0000000003710102"] = { + name = "Mario - Wedding" + }, + ["0x00000003039bff02"] = { + name = "Mario - Power Up Band" + }, + ["0x0000010000190002"] = { + name = "Dr. Mario" + }, + ["0x0000030003a60102"] = { + name = "Mario - Cat" + }, + ["0x00010000000c0002"] = { + name = "Luigi" + }, + ["0x0001000000350102"] = { + name = "Luigi" + }, + ["0x00010003039cff02"] = { + name = "Luigi - Power Up Band" + }, + ["0x0002000000010002"] = { + name = "Peach" + }, + ["0x0002000000360102"] = { + name = "Peach" + }, + ["0x0002000003720102"] = { + name = "Peach - Wedding" + }, + ["0x00020003039dff02"] = { + name = "Peach - Power Up Band" + }, + ["0x0002010003a70102"] = { + name = "Peach - Cat" + }, + ["0x0003000000020002"] = { + name = "Yoshi" + }, + ["0x0003000000370102"] = { + name = "Yoshi" + }, + ["0x00030003039fff02"] = { + name = "Yoshi - Power Up Band" + }, + ["0x0003010200410302"] = { + name = "Green Yarn Yoshi" + }, + ["0x0003010200420302"] = { + name = "Pink Yarn Yoshi" + }, + ["0x0003010200430302"] = { + name = "Light Blue Yarn Yoshi" + }, + ["0x00030102023e0302"] = { + name = "Mega Yarn Yoshi" + }, + ["0x0004000002620102"] = { + name = "Rosalina" + }, + ["0x0004010000130002"] = { + name = "Rosalina & Luma" + }, + ["0x0005000000140002"] = { + name = "Bowser" + }, + ["0x0005000000390102"] = { + name = "Bowser" + }, + ["0x0005000003730102"] = { + name = "Bowser - Wedding" + }, + ["0x0005ff00023a0702"] = { + name = "Hammer Slam Bowser" + }, + ["0x0006000000150002"] = { + name = "Bowser Jr." + }, + ["0x00070000001a0002"] = { + name = "Wario" + }, + ["0x0007000002630102"] = { + name = "Wario" + }, + ["0x0008000000030002"] = { + name = "Donkey Kong" + }, + ["0x0008000002640102"] = { + name = "Donkey Kong" + }, + ["0x0008ff00023b0702"] = { + name = "Turbo Charge Donkey Kong" + }, + ["0x00090000000d0002"] = { + name = "Diddy Kong" + }, + ["0x0009000002650102"] = { + name = "Diddy Kong" + }, + ["0x000a000000380102"] = { + name = "Toad" + }, + ["0x000a000303a0ff02"] = { + name = "Toad - Power Up Band" + }, + ["0x0013000002660102"] = { + name = "Daisy" + }, + ["0x00130000037a0002"] = { + name = "Daisy" + }, + ["0x00130003039eff02"] = { + name = "Daisy - Power Up Band" + }, + ["0x0014000002670102"] = { + name = "Waluigi" + }, + ["0x0015000003670102"] = { + name = "Goomba" + }, + ["0x0017000002680102"] = { + name = "Boo" + }, + ["0x0023000003680102"] = { + name = "Koopa Troopa" + }, + ["0x00240000038d0002"] = { + name = "Piranha Plant" + }, + ["0x00800102035d0302"] = { + name = "Poochy" + }, + ["0x00c00000037b0002"] = { + name = "King K. Rool" + }, + ["0x0100000000040002"] = { + name = "Link" + }, + ["0x01000000034b0902"] = { + name = "Link - Ocarina of Time" + }, + ["0x01000000034c0902"] = { + name = "Link - Majora's Mask" + }, + ["0x01000000034d0902"] = { + name = "Link - Twilight Princess" + }, + ["0x01000000034e0902"] = { + name = "Link - Skyward Sword" + }, + ["0x01000000034f0902"] = { + name = "8-Bit Link" + }, + ["0x0100000003530902"] = { + name = "Link - Archer" + }, + ["0x0100000003540902"] = { + name = "Link - Rider" + }, + ["0x01000000037c0002"] = { + name = "Young Link" + }, + ["0x0100000003990902"] = { + name = "Link - Link's Awakening" + }, + ["0x0100010000160002"] = { + name = "Toon Link" + }, + ["0x0100010003500902"] = { + name = "Toon Link - The Wind Waker" + }, + ["0x01010000000e0002"] = { + name = "Zelda" + }, + ["0x0101000003520902"] = { + name = "Toon Zelda - The Wind Waker" + }, + ["0x0101000003560902"] = { + name = "Zelda" + }, + ["0x0101010000170002"] = { + name = "Sheik" + }, + ["0x0101030004140902"] = { + name = "Zelda & Loftwing" + }, + ["0x01020100001b0002"] = { + name = "Ganondorf" + }, + ["0x01030000024f0902"] = { + name = "Midna & Wolf Link" + }, + ["0x0105000003580902"] = { + name = "Daruk" + }, + ["0x0106000003590902"] = { + name = "Urbosa" + }, + ["0x01070000035a0902"] = { + name = "Mipha" + }, + ["0x01080000035b0902"] = { + name = "Revali" + }, + ["0x0140000003550902"] = { + name = "Guardian" + }, + ["0x01410000035c0902"] = { + name = "Bokoblin" + }, + ["0x0180000000080002"] = { + name = "Villager" + }, + ["0x01810000024b0502"] = { + name = "Isabelle - Summer Outfit" + }, + ["0x01810000037d0002"] = { + name = "Isabelle" + }, + ["0x0181000100440502"] = { + name = "Isabelle" + }, + ["0x0181000101d40502"] = { + name = "Isabelle - Character Parfait" + }, + ["0x01810100023f0502"] = { + name = "Isabelle - Winter Outfit" + }, + ["0x0181010100b40502"] = { + name = "Isabelle - Winter" + }, + ["0x01810201011a0502"] = { + name = "Isabelle - Kimono" + }, + ["0x0181030101700502"] = { + name = "Isabelle - Dress" + }, + ["0x0181040103aa0502"] = { + name = "Isabelle" + }, + ["0x0181050103bf0502"] = { + name = "Isabelle - Sweater" + }, + ["0x0182000002400502"] = { + name = "K. K. Slider" + }, + ["0x0182000100a80502"] = { + name = "K.K. Slider" + }, + ["0x0182000101d80502"] = { + name = "K. K. Slider - Pikopuri" + }, + ["0x0182000103b20502"] = { + name = "K.K. Slider" + }, + ["0x0182010100460502"] = { + name = "DJ KK" + }, + ["0x0183000002420502"] = { + name = "Tom Nook" + }, + ["0x0183000100450502"] = { + name = "Tom Nook" + }, + ["0x01830101010e0502"] = { + name = "Tom Nook - Jacket" + }, + ["0x0183020103a80502"] = { + name = "Tom Nook" + }, + ["0x0183030103be0502"] = { + name = "Tom Nook - Coat" + }, + ["0x01840000024d0502"] = { + name = "Timmy & Tommy" + }, + ["0x0184050103a90502"] = { + name = "Timmy & Tommy" + }, + ["0x01850001004b0502"] = { + name = "Timmy" + }, + ["0x0185020101170502"] = { + name = "Timmy - Full Apron" + }, + ["0x0185040101790502"] = { + name = "Timmy - Suit" + }, + ["0x0186010100af0502"] = { + name = "Tommy - Uniform" + }, + ["0x0186030101750502"] = { + name = "Tommy - Suit" + }, + ["0x0187000100470502"] = { + name = "Sable" + }, + ["0x0187000103b00502"] = { + name = "Sable" + }, + ["0x0188000002410502"] = { + name = "Mabel" + }, + ["0x0188000101120502"] = { + name = "Mabel" + }, + ["0x0188000103af0502"] = { + name = "Mabel" + }, + ["0x0189000100ab0502"] = { + name = "Label" + }, + ["0x0189010103b10502"] = { + name = "Label" + }, + ["0x018a000002450502"] = { + name = "Reese" + }, + ["0x018a000100a90502"] = { + name = "Reese" + }, + ["0x018b000002460502"] = { + name = "Cyrus" + }, + ["0x018b000101150502"] = { + name = "Cyrus" + }, + ["0x018c000002430502"] = { + name = "Digby" + }, + ["0x018c0001004c0502"] = { + name = "Digby" + }, + ["0x018c010101180502"] = { + name = "Digby - Raincoat" + }, + ["0x018d0000024c0502"] = { + name = "Rover" + }, + ["0x018d0001010c0502"] = { + name = "Rover" + }, + ["0x018e000002490502"] = { + name = "Resetti" + }, + ["0x018e000100490502"] = { + name = "Resetti" + }, + ["0x018e010101780502"] = { + name = "Resetti - Without Hat" + }, + ["0x018f000100b30502"] = { + name = "Don Resetti" + }, + ["0x018f010101190502"] = { + name = "Don Resetti - Without Hat" + }, + ["0x0190000101710502"] = { + name = "Brewster" + }, + ["0x01910001004e0502"] = { + name = "Harriet" + }, + ["0x0192000002470502"] = { + name = "Blathers" + }, + ["0x01920001010d0502"] = { + name = "Blathers" + }, + ["0x0192000103ad0502"] = { + name = "Blathers" + }, + ["0x0193000002480502"] = { + name = "Celeste" + }, + ["0x0193000101740502"] = { + name = "Celeste" + }, + ["0x0193000103ae0502"] = { + name = "Celeste" + }, + ["0x01940000024a0502"] = { + name = "Kicks" + }, + ["0x0194000100aa0502"] = { + name = "Kicks" + }, + ["0x0194000103b60502"] = { + name = "Kicks" + }, + ["0x0195000100b00502"] = { + name = "Porter" + }, + ["0x01960000024e0502"] = { + name = "Kapp'n" + }, + ["0x0196000100480502"] = { + name = "Kapp'n" + }, + ["0x0197000101770502"] = { + name = "Leilani" + }, + ["0x0198000100b10502"] = { + name = "Leila" + }, + ["0x0199000101160502"] = { + name = "Grams" + }, + ["0x019a000100b70502"] = { + name = "Chip" + }, + ["0x019b000100b60502"] = { + name = "Nat" + }, + ["0x019c000101730502"] = { + name = "Phineas" + }, + ["0x019d000100ac0502"] = { + name = "Copper" + }, + ["0x019e000100ad0502"] = { + name = "Booker" + }, + ["0x019f000101110502"] = { + name = "Pete" + }, + ["0x01a00001010f0502"] = { + name = "Pelly" + }, + ["0x01a1000101100502"] = { + name = "Phyllis" + }, + ["0x01a20001017d0502"] = { + name = "Gulliver" + }, + ["0x01a2000103b90502"] = { + name = "Gulliver" + }, + ["0x01a30001004a0502"] = { + name = "Joan" + }, + ["0x01a40001004d0502"] = { + name = "Pascal" + }, + ["0x01a5000101720502"] = { + name = "Katrina" + }, + ["0x01a6000100500502"] = { + name = "Saharah" + }, + ["0x01a6000103b70502"] = { + name = "Saharah" + }, + ["0x01a7000101140502"] = { + name = "Wendell" + }, + ["0x01a80001004f0502"] = { + name = "Redd" + }, + ["0x01a80101017e0502"] = { + name = "Redd - Shirt" + }, + ["0x01a9000101760502"] = { + name = "Gracie" + }, + ["0x01aa000100530502"] = { + name = "Lyle" + }, + ["0x01ab0001017c0502"] = { + name = "Pave" + }, + ["0x01ac0001017f0502"] = { + name = "Zipper" + }, + ["0x01ad000100b80502"] = { + name = "Jack" + }, + ["0x01ae0001011b0502"] = { + name = "Franklin" + }, + ["0x01af0001011c0502"] = { + name = "Jingle" + }, + ["0x01b0000100520502"] = { + name = "Tortimer" + }, + ["0x01b1000100b20502"] = { + name = "Shrunk" + }, + ["0x01b10101017b0502"] = { + name = "Shrunk - Loud Jacket" + }, + ["0x01b3000100b50502"] = { + name = "Blanca" + }, + ["0x01b4000101130502"] = { + name = "Leif" + }, + ["0x01b5000100510502"] = { + name = "Luna" + }, + ["0x01b6000100ae0502"] = { + name = "Katie" + }, + ["0x01c1000002440502"] = { + name = "Lottie" + }, + ["0x01c1000100540502"] = { + name = "Lottie" + }, + ["0x01c10101017a0502"] = { + name = "Lottie - Black Skirt And Bow" + }, + ["0x01c1020103bb0502"] = { + name = "Lottie - Island" + }, + ["0x0200000100a10502"] = { + name = "Cyrano" + }, + ["0x02010001016a0502"] = { + name = "Antonio" + }, + ["0x0202000101030502"] = { + name = "Pango" + }, + ["0x02030001019a0502"] = { + name = "Anabelle" + }, + ["0x0206000103120502"] = { + name = "Snooty" + }, + ["0x0208000100960502"] = { + name = "Annalisa" + }, + ["0x02090001019f0502"] = { + name = "Olaf" + }, + ["0x0214000100e40502"] = { + name = "Teddy" + }, + ["0x0215000101820502"] = { + name = "Pinky" + }, + ["0x0216000100570502"] = { + name = "Curt" + }, + ["0x0217000101b30502"] = { + name = "Chow" + }, + ["0x02190001007e0502"] = { + name = "Nate" + }, + ["0x021a000100da0502"] = { + name = "Groucho" + }, + ["0x021b000100800502"] = { + name = "Tutu" + }, + ["0x021c000102f70502"] = { + name = "Ursala" + }, + ["0x021d000101cd0502"] = { + name = "Grizzly" + }, + ["0x021e000101230502"] = { + name = "Paula" + }, + ["0x021f000103170502"] = { + name = "Ike" + }, + ["0x0220000100fd0502"] = { + name = "Charlise" + }, + ["0x02210001013c0502"] = { + name = "Beardo" + }, + ["0x0222000101440502"] = { + name = "Klaus" + }, + ["0x022d000100f20502"] = { + name = "Jay" + }, + ["0x022e000101d30502"] = { + name = "Robin" + }, + ["0x022f0001011e0502"] = { + name = "Anchovy" + }, + ["0x0230000101d20502"] = { + name = "Twiggy" + }, + ["0x02310001006a0502"] = { + name = "Jitters" + }, + ["0x0232000102ea0502"] = { + name = "Piper" + }, + ["0x0233000103060502"] = { + name = "Admiral" + }, + ["0x0235000100840502"] = { + name = "Midge" + }, + ["0x0238000102f80502"] = { + name = "Jacob" + }, + ["0x023c000100bd0502"] = { + name = "Lucha" + }, + ["0x023d000101b50502"] = { + name = "Jacques" + }, + ["0x023e000100d10502"] = { + name = "Peck" + }, + ["0x023f000101660502"] = { + name = "Sparro" + }, + ["0x024a000101d10502"] = { + name = "Angus" + }, + ["0x024b000101260502"] = { + name = "Rodeo" + }, + ["0x024d000102f60502"] = { + name = "Stu" + }, + ["0x024f000100810502"] = { + name = "T-Bone" + }, + ["0x0251000100c10502"] = { + name = "Coach" + }, + ["0x0252000100fe0502"] = { + name = "Vic" + }, + ["0x025d000100550502"] = { + name = "Bob" + }, + ["0x025e000101250502"] = { + name = "Mitzi" + }, + ["0x025f000101c50502"] = { + name = "Rosie" + }, + ["0x025f000101d70502"] = { + name = "Rosie - Amiibo Festival" + }, + ["0x0260000100d20502"] = { + name = "Olivia" + }, + ["0x0261000100650502"] = { + name = "Kiki" + }, + ["0x0262000101370502"] = { + name = "Tangy" + }, + ["0x0263000100750502"] = { + name = "Punchy" + }, + ["0x0264000101ac0502"] = { + name = "Purrl" + }, + ["0x0265000101540502"] = { + name = "Moe" + }, + ["0x0266000100680502"] = { + name = "Kabuki" + }, + ["0x0267000101080502"] = { + name = "Kid Cat" + }, + ["0x02680001007d0502"] = { + name = "Monique" + }, + ["0x02690001011f0502"] = { + name = "Tabby" + }, + ["0x026a000101460502"] = { + name = "Stinky" + }, + ["0x026b000100e90502"] = { + name = "Kitty" + }, + ["0x026c000100c30502"] = { + name = "Tom" + }, + ["0x026d0001013f0502"] = { + name = "Merry" + }, + ["0x026e000100ba0502"] = { + name = "Felicity" + }, + ["0x026f000101900502"] = { + name = "Lolly" + }, + ["0x0270000100ff0502"] = { + name = "Ankha" + }, + ["0x02710001019b0502"] = { + name = "Rudy" + }, + ["0x0272000101860502"] = { + name = "Katt" + }, + ["0x027d000100630502"] = { + name = "Bluebear" + }, + ["0x027e000101690502"] = { + name = "Maple" + }, + ["0x027f000100b90502"] = { + name = "Poncho" + }, + ["0x0280000100830502"] = { + name = "Pudge" + }, + ["0x0281000101200502"] = { + name = "Kody" + }, + ["0x0282000101810502"] = { + name = "Stitches" + }, + ["0x0282000101d60502"] = { + name = "Stitches - Amiibo Festival" + }, + ["0x0283000100c70502"] = { + name = "Vladimir" + }, + ["0x0284000102fe0502"] = { + name = "Murphy" + }, + ["0x0286000103130502"] = { + name = "Olive" + }, + ["0x02870001005a0502"] = { + name = "Cheri" + }, + ["0x028a000102e90502"] = { + name = "June" + }, + ["0x028b000100e30502"] = { + name = "Pekoe" + }, + ["0x028c0001013e0502"] = { + name = "Chester" + }, + ["0x028d000101bd0502"] = { + name = "Barold" + }, + ["0x028e0001019e0502"] = { + name = "Tammy" + }, + ["0x028f0101031a0502"] = { + name = "Marty" + }, + ["0x0299000100950502"] = { + name = "Goose" + }, + ["0x029a000100ee0502"] = { + name = "Benedict" + }, + ["0x029b000100cb0502"] = { + name = "Egbert" + }, + ["0x029e0001013d0502"] = { + name = "Ava" + }, + ["0x02a2000101ba0502"] = { + name = "Becky" + }, + ["0x02a3000102ff0502"] = { + name = "Plucky" + }, + ["0x02a4000100720502"] = { + name = "Knox" + }, + ["0x02a50001018c0502"] = { + name = "Broffina" + }, + ["0x02a6000101240502"] = { + name = "Ken" + }, + ["0x02b1000100690502"] = { + name = "Patty" + }, + ["0x02b2000100c40502"] = { + name = "Tipper" + }, + ["0x02b70001030f0502"] = { + name = "Norma" + }, + ["0x02b80001019c0502"] = { + name = "Naomi" + }, + ["0x02c3000100dc0502"] = { + name = "Alfonso" + }, + ["0x02c4000100670502"] = { + name = "Alli" + }, + ["0x02c5000103080502"] = { + name = "Boots" + }, + ["0x02c7000101220502"] = { + name = "Del" + }, + ["0x02c9000100cd0502"] = { + name = "Sly" + }, + ["0x02ca000101ca0502"] = { + name = "Gayle" + }, + ["0x02cb000101360502"] = { + name = "Drago" + }, + ["0x02d6000100560502"] = { + name = "Fauna" + }, + ["0x02d7000101300502"] = { + name = "Bam" + }, + ["0x02d8000100e20502"] = { + name = "Zell" + }, + ["0x02d9000101c80502"] = { + name = "Bruce" + }, + ["0x02da000101330502"] = { + name = "Deirdre" + }, + ["0x02db0001005e0502"] = { + name = "Lopez" + }, + ["0x02dc000100be0502"] = { + name = "Fuchsia" + }, + ["0x02dd000100ea0502"] = { + name = "Beau" + }, + ["0x02de0001009c0502"] = { + name = "Diana" + }, + ["0x02df000101910502"] = { + name = "Erik" + }, + ["0x02e00101031d0502"] = { + name = "Chelsea" + }, + ["0x02ea000101800502"] = { + name = "Goldie" + }, + ["0x02ea000101d50502"] = { + name = "Goldie - Amiibo Festival" + }, + ["0x02eb000100de0502"] = { + name = "Butch" + }, + ["0x02ec000101c40502"] = { + name = "Lucky" + }, + ["0x02ed0001015a0502"] = { + name = "Biskit" + }, + ["0x02ee000101990502"] = { + name = "Bones" + }, + ["0x02ef000100580502"] = { + name = "Portia" + }, + ["0x02f0000100a70502"] = { + name = "Walker" + }, + ["0x02f1000101450502"] = { + name = "Daisy" + }, + ["0x02f2000100cc0502"] = { + name = "Cookie" + }, + ["0x02f3000102f90502"] = { + name = "Maddie" + }, + ["0x02f4000103050502"] = { + name = "Bea" + }, + ["0x02f8000101380502"] = { + name = "Mac" + }, + ["0x02f9000101020502"] = { + name = "Marcel" + }, + ["0x02fa000100970502"] = { + name = "Benjamin" + }, + ["0x02fb000100900502"] = { + name = "Cherry" + }, + ["0x02fc0001018f0502"] = { + name = "Shep" + }, + ["0x0307000100640502"] = { + name = "Bill" + }, + ["0x03080001014d0502"] = { + name = "Joey" + }, + ["0x0309000100c60502"] = { + name = "Pate" + }, + ["0x030a000101c70502"] = { + name = "Maelle" + }, + ["0x030b000100790502"] = { + name = "Deena" + }, + ["0x030c000101b80502"] = { + name = "Pompom" + }, + ["0x030d000101840502"] = { + name = "Mallary" + }, + ["0x030e0001012f0502"] = { + name = "Freckles" + }, + ["0x030f0001016d0502"] = { + name = "Derwin" + }, + ["0x0310000100f80502"] = { + name = "Drake" + }, + ["0x0311000100d60502"] = { + name = "Scoot" + }, + ["0x0312000103090502"] = { + name = "Weber" + }, + ["0x0313000101210502"] = { + name = "Miranda" + }, + ["0x0314000102f40502"] = { + name = "Ketchup" + }, + ["0x0316000101c00502"] = { + name = "Gloria" + }, + ["0x0317000100a60502"] = { + name = "Molly" + }, + ["0x03180001006c0502"] = { + name = "Quillson" + }, + ["0x0323000100760502"] = { + name = "Opal" + }, + ["0x0324000101890502"] = { + name = "Dizzy" + }, + ["0x03250001010a0502"] = { + name = "Big Top" + }, + ["0x0326000101390502"] = { + name = "Eloise" + }, + ["0x0327000101c30502"] = { + name = "Margie" + }, + ["0x0328000102eb0502"] = { + name = "Paolo" + }, + ["0x03290001009d0502"] = { + name = "Axel" + }, + ["0x032a000103070502"] = { + name = "Ellie" + }, + ["0x032c000101480502"] = { + name = "Tucker" + }, + ["0x032d000100bc0502"] = { + name = "Tia" + }, + ["0x032e0101031c0502"] = { + name = "Chai" + }, + ["0x03380001011d0502"] = { + name = "Lily" + }, + ["0x0339000101b10502"] = { + name = "Ribbot" + }, + ["0x033a000101cc0502"] = { + name = "Frobert" + }, + ["0x033b000100fa0502"] = { + name = "Camofrog" + }, + ["0x033c000101000502"] = { + name = "Drift" + }, + ["0x033d0001013a0502"] = { + name = "Wart Jr." + }, + ["0x033e000101a20502"] = { + name = "Puddles" + }, + ["0x033f0001008f0502"] = { + name = "Jeremiah" + }, + ["0x03410001030e0502"] = { + name = "Tad" + }, + ["0x0342000101280502"] = { + name = "Cousteau" + }, + ["0x0343000102ef0502"] = { + name = "Huck" + }, + ["0x0344000100c50502"] = { + name = "Prince" + }, + ["0x03450001005f0502"] = { + name = "Jambette" + }, + ["0x0347000103020502"] = { + name = "Raddle" + }, + ["0x03480001006b0502"] = { + name = "Gigi" + }, + ["0x03490001018d0502"] = { + name = "Croque" + }, + ["0x034a000101430502"] = { + name = "Diva" + }, + ["0x034b0001009f0502"] = { + name = "Henry" + }, + ["0x0356000101350502"] = { + name = "Chevre" + }, + ["0x0357000100eb0502"] = { + name = "Nan" + }, + ["0x0358000102fa0502"] = { + name = "Billy" + }, + ["0x035a000100850502"] = { + name = "Gruff" + }, + ["0x035c000101290502"] = { + name = "Velma" + }, + ["0x035d000100c90502"] = { + name = "Kidd" + }, + ["0x035e0001018e0502"] = { + name = "Pashmina" + }, + ["0x0369000100d30502"] = { + name = "Cesar" + }, + ["0x036a0001019d0502"] = { + name = "Peewee" + }, + ["0x036b0001018b0502"] = { + name = "Boone" + }, + ["0x036d000103040502"] = { + name = "Louie" + }, + ["0x036e000102fb0502"] = { + name = "Boyd" + }, + ["0x03700001015d0502"] = { + name = "Violet" + }, + ["0x03710001005c0502"] = { + name = "Al" + }, + ["0x03720001010b0502"] = { + name = "Rocket" + }, + ["0x0373000101340502"] = { + name = "Hans" + }, + ["0x0374010103190502"] = { + name = "Rilla" + }, + ["0x037e000101560502"] = { + name = "Hamlet" + }, + ["0x037f000101aa0502"] = { + name = "Apple" + }, + ["0x0380000101870502"] = { + name = "Graham" + }, + ["0x0381000100d50502"] = { + name = "Rodney" + }, + ["0x03820001016b0502"] = { + name = "Soleil" + }, + ["0x03830001009b0502"] = { + name = "Clay" + }, + ["0x0384000100860502"] = { + name = "Flurry" + }, + ["0x0385000101060502"] = { + name = "Hamphrey" + }, + ["0x0390000101850502"] = { + name = "Rocco" + }, + ["0x0392000101270502"] = { + name = "Bubbles" + }, + ["0x0393000100a00502"] = { + name = "Bertha" + }, + ["0x0394000100890502"] = { + name = "Biff" + }, + ["0x0395000102fc0502"] = { + name = "Bitty" + }, + ["0x0398000100bf0502"] = { + name = "Harry" + }, + ["0x0399000101c20502"] = { + name = "Hippeux" + }, + ["0x03a40001014f0502"] = { + name = "Buck" + }, + ["0x03a50001015b0502"] = { + name = "Victoria" + }, + ["0x03a6000100c80502"] = { + name = "Savannah" + }, + ["0x03a7000101a10502"] = { + name = "Elmer" + }, + ["0x03a8000100910502"] = { + name = "Rosco" + }, + ["0x03a9000100710502"] = { + name = "Winnie" + }, + ["0x03aa000100e60502"] = { + name = "Ed" + }, + ["0x03ab000103160502"] = { + name = "Cleo" + }, + ["0x03ac000101880502"] = { + name = "Peaches" + }, + ["0x03ad000101b20502"] = { + name = "Annalise" + }, + ["0x03ae000100870502"] = { + name = "Clyde" + }, + ["0x03af0001012c0502"] = { + name = "Colton" + }, + ["0x03b0000101a90502"] = { + name = "Papi" + }, + ["0x03b1000100f00502"] = { + name = "Julian" + }, + ["0x03bc0001008a0502"] = { + name = "Yuka" + }, + ["0x03bd000100f90502"] = { + name = "Alice" + }, + ["0x03be000101980502"] = { + name = "Melba" + }, + ["0x03bf000101bc0502"] = { + name = "Sydney" + }, + ["0x03c0000103100502"] = { + name = "Gonzo" + }, + ["0x03c1000100bb0502"] = { + name = "Ozzie" + }, + ["0x03c40001012b0502"] = { + name = "Canberra" + }, + ["0x03c50001015c0502"] = { + name = "Lyman" + }, + ["0x03c6000100930502"] = { + name = "Eugene" + }, + ["0x03d1000100c20502"] = { + name = "Kitt" + }, + ["0x03d2000100e50502"] = { + name = "Mathilda" + }, + ["0x03d3000102f30502"] = { + name = "Carrie" + }, + ["0x03d6000101570502"] = { + name = "Astrid" + }, + ["0x03d7000101b40502"] = { + name = "Sylvia" + }, + ["0x03d9000101a50502"] = { + name = "Walt" + }, + ["0x03da000101510502"] = { + name = "Rooney" + }, + ["0x03db0001006d0502"] = { + name = "Marcie" + }, + ["0x03e6000100ec0502"] = { + name = "Bud" + }, + ["0x03e70001012a0502"] = { + name = "Elvis" + }, + ["0x03e8000102f50502"] = { + name = "Rex" + }, + ["0x03ea0001030b0502"] = { + name = "Leopold" + }, + ["0x03ec000101830502"] = { + name = "Mott" + }, + ["0x03ed000101a30502"] = { + name = "Rory" + }, + ["0x03ee0001008b0502"] = { + name = "Lionel" + }, + ["0x03fa000100d00502"] = { + name = "Nana" + }, + ["0x03fb000101cf0502"] = { + name = "Simon" + }, + ["0x03fc000101470502"] = { + name = "Tammi" + }, + ["0x03fd000101580502"] = { + name = "Monty" + }, + ["0x03fe000101a40502"] = { + name = "Elise" + }, + ["0x03ff000100f40502"] = { + name = "Flip" + }, + ["0x04000001006f0502"] = { + name = "Shari" + }, + ["0x0401000100660502"] = { + name = "Deli" + }, + ["0x040c000101590502"] = { + name = "Dora" + }, + ["0x040d000100780502"] = { + name = "Limberg" + }, + ["0x040e000100880502"] = { + name = "Bella" + }, + ["0x040f000101500502"] = { + name = "Bree" + }, + ["0x04100001007f0502"] = { + name = "Samson" + }, + ["0x0411000101ab0502"] = { + name = "Rod" + }, + ["0x04140001030a0502"] = { + name = "Candi" + }, + ["0x0415000101bb0502"] = { + name = "Rizzo" + }, + ["0x0416000100fb0502"] = { + name = "Anicotti" + }, + ["0x0418000100d80502"] = { + name = "Broccolo" + }, + ["0x041a000100e00502"] = { + name = "Moose" + }, + ["0x041b000100f10502"] = { + name = "Bettina" + }, + ["0x041c000101410502"] = { + name = "Greta" + }, + ["0x041d0001018a0502"] = { + name = "Penelope" + }, + ["0x041e0001015f0502"] = { + name = "Chadder" + }, + ["0x0429000100700502"] = { + name = "Octavian" + }, + ["0x042a0001012d0502"] = { + name = "Marina" + }, + ["0x042b000101af0502"] = { + name = "Zucker" + }, + ["0x0436000101940502"] = { + name = "Queenie" + }, + ["0x0437000101050502"] = { + name = "Gladys" + }, + ["0x0438000103000502"] = { + name = "Sandy" + }, + ["0x0439000103110502"] = { + name = "Sprocket" + }, + ["0x043b000103030502"] = { + name = "Julia" + }, + ["0x043c000101cb0502"] = { + name = "Cranston" + }, + ["0x043d0001007c0502"] = { + name = "Phil" + }, + ["0x043e000101490502"] = { + name = "Blanche" + }, + ["0x043f000101550502"] = { + name = "Flora" + }, + ["0x0440000100ca0502"] = { + name = "Phoebe" + }, + ["0x044b0001016c0502"] = { + name = "Apollo" + }, + ["0x044c0001008e0502"] = { + name = "Amelia" + }, + ["0x044d000101930502"] = { + name = "Pierce" + }, + ["0x044e000103150502"] = { + name = "Buzz" + }, + ["0x0450000100cf0502"] = { + name = "Avery" + }, + ["0x04510001015e0502"] = { + name = "Frank" + }, + ["0x0452000100730502"] = { + name = "Sterling" + }, + ["0x0453000101040502"] = { + name = "Keaton" + }, + ["0x0454000101ae0502"] = { + name = "Celia" + }, + ["0x045f000101a80502"] = { + name = "Aurora" + }, + ["0x0460000100a50502"] = { + name = "Roald" + }, + ["0x0461000101610502"] = { + name = "Cube" + }, + ["0x0462000100f60502"] = { + name = "Hopper" + }, + ["0x0463000101310502"] = { + name = "Friga" + }, + ["0x0464000100c00502"] = { + name = "Gwen" + }, + ["0x04650001006e0502"] = { + name = "Puck" + }, + ["0x0468000102f20502"] = { + name = "Wade" + }, + ["0x0469000101640502"] = { + name = "Boomer" + }, + ["0x046a000101d00502"] = { + name = "Iggly" + }, + ["0x046b000101970502"] = { + name = "Tex" + }, + ["0x046c0001008c0502"] = { + name = "Flo" + }, + ["0x046d000100f30502"] = { + name = "Sprinkle" + }, + ["0x0478000101630502"] = { + name = "Curly" + }, + ["0x0479000100920502"] = { + name = "Truffles" + }, + ["0x047a000100600502"] = { + name = "Rasher" + }, + ["0x047b000100f50502"] = { + name = "Hugh" + }, + ["0x047c000101a00502"] = { + name = "Lucy" + }, + ["0x047d0001012e0502"] = { + name = "Spork/Crackle" + }, + ["0x04800001008d0502"] = { + name = "Cobb" + }, + ["0x0481000102f10502"] = { + name = "Boris" + }, + ["0x0482000102fd0502"] = { + name = "Maggie" + }, + ["0x0483000101b00502"] = { + name = "Peggy" + }, + ["0x04850001014c0502"] = { + name = "Gala" + }, + ["0x0486000100fc0502"] = { + name = "Chops" + }, + ["0x0487000101bf0502"] = { + name = "Kevin" + }, + ["0x0488000100980502"] = { + name = "Pancetti" + }, + ["0x0489000100ef0502"] = { + name = "Agnes" + }, + ["0x04940001009a0502"] = { + name = "Bunnie" + }, + ["0x0495000101920502"] = { + name = "Dotty" + }, + ["0x0496000100d90502"] = { + name = "Coco" + }, + ["0x04970001007a0502"] = { + name = "Snake" + }, + ["0x04980001014a0502"] = { + name = "Gaston" + }, + ["0x0499000100df0502"] = { + name = "Gabi" + }, + ["0x049a0001014e0502"] = { + name = "Pippy" + }, + ["0x049b000100610502"] = { + name = "Tiffany" + }, + ["0x049c000101400502"] = { + name = "Genji" + }, + ["0x049d000100ed0502"] = { + name = "Ruby" + }, + ["0x049e000101b70502"] = { + name = "Doc" + }, + ["0x049f000103010502"] = { + name = "Claude" + }, + ["0x04a00001016e0502"] = { + name = "Francine" + }, + ["0x04a10001016f0502"] = { + name = "Chrissy" + }, + ["0x04a2000102e80502"] = { + name = "Hopkins" + }, + ["0x04a3000101c90502"] = { + name = "OHare" + }, + ["0x04a4000100d40502"] = { + name = "Carmen" + }, + ["0x04a5000100740502"] = { + name = "Bonbon" + }, + ["0x04a6000100a30502"] = { + name = "Cole" + }, + ["0x04a7000101a60502"] = { + name = "Mira" + }, + ["0x04a80101031e0502"] = { + name = "Toby" + }, + ["0x04b2000101b90502"] = { + name = "Tank" + }, + ["0x04b3000100dd0502"] = { + name = "Rhonda" + }, + ["0x04b40001030c0502"] = { + name = "Spike" + }, + ["0x04b6000102ec0502"] = { + name = "Hornsby" + }, + ["0x04b9000101600502"] = { + name = "Merengue" + }, + ["0x04ba0001005d0502"] = { + name = "Renée" + }, + ["0x04c5000101010502"] = { + name = "Vesta" + }, + ["0x04c6000101670502"] = { + name = "Baabara" + }, + ["0x04c7000100940502"] = { + name = "Eunice" + }, + ["0x04c8000102ed0502"] = { + name = "Stella" + }, + ["0x04c90001030d0502"] = { + name = "Cashmere" + }, + ["0x04cc000100a40502"] = { + name = "Willow" + }, + ["0x04cd000101520502"] = { + name = "Curlos" + }, + ["0x04ce000100db0502"] = { + name = "Wendy" + }, + ["0x04cf000100e10502"] = { + name = "Timbra" + }, + ["0x04d0000101960502"] = { + name = "Frita" + }, + ["0x04d10001009e0502"] = { + name = "Muffy" + }, + ["0x04d2000101a70502"] = { + name = "Pietro" + }, + ["0x04d30101031b0502"] = { + name = "Étoile" + }, + ["0x04dd000100a20502"] = { + name = "Peanut" + }, + ["0x04de000100ce0502"] = { + name = "Blaire" + }, + ["0x04df000100e80502"] = { + name = "Filbert" + }, + ["0x04e0000100f70502"] = { + name = "Pecan" + }, + ["0x04e1000101be0502"] = { + name = "Nibbles" + }, + ["0x04e2000101090502"] = { + name = "Agent S" + }, + ["0x04e3000101650502"] = { + name = "Caroline" + }, + ["0x04e4000101b60502"] = { + name = "Sally" + }, + ["0x04e5000101ad0502"] = { + name = "Static" + }, + ["0x04e6000100820502"] = { + name = "Mint" + }, + ["0x04e7000101320502"] = { + name = "Ricky" + }, + ["0x04e8000101ce0502"] = { + name = "Cally" + }, + ["0x04ea000103180502"] = { + name = "Tasha" + }, + ["0x04eb000102f00502"] = { + name = "Sylvana" + }, + ["0x04ec000100770502"] = { + name = "Poppy" + }, + ["0x04ed000100620502"] = { + name = "Sheldon" + }, + ["0x04ee0001014b0502"] = { + name = "Marshal" + }, + ["0x04ef0001013b0502"] = { + name = "Hazel" + }, + ["0x04fa000101680502"] = { + name = "Rolf" + }, + ["0x04fb000101c60502"] = { + name = "Rowan" + }, + ["0x04fc000102ee0502"] = { + name = "Tybalt" + }, + ["0x04fd0001007b0502"] = { + name = "Bangle" + }, + ["0x04fe000100590502"] = { + name = "Leonardo" + }, + ["0x04ff000101620502"] = { + name = "Claudia" + }, + ["0x0500000100e70502"] = { + name = "Bianca" + }, + ["0x050b000100990502"] = { + name = "Chief" + }, + ["0x050c000101c10502"] = { + name = "Lobo" + }, + ["0x050d000101420502"] = { + name = "Wolfgang" + }, + ["0x050e000100d70502"] = { + name = "Whitney" + }, + ["0x050f000103140502"] = { + name = "Dobie" + }, + ["0x0510000101070502"] = { + name = "Freya" + }, + ["0x0511000101950502"] = { + name = "Fang" + }, + ["0x0513000102e70502"] = { + name = "Vivian" + }, + ["0x0514000101530502"] = { + name = "Skye" + }, + ["0x05150001005b0502"] = { + name = "Kyle" + }, + ["0x0580000000050002"] = { + name = "Fox" + }, + ["0x05810000001c0002"] = { + name = "Falco" + }, + ["0x05840000037e0002"] = { + name = "Wolf" + }, + ["0x05c0000000060002"] = { + name = "Samus" + }, + ["0x05c0000003651302"] = { + name = "Samus Aran" + }, + ["0x05c0000004121302"] = { + name = "Samus - Metroid Dread" + }, + ["0x05c00100001d0002"] = { + name = "Zero Suit Samus" + }, + ["0x05c1000003661302"] = { + name = "Metroid" + }, + ["0x05c20000037f0002"] = { + name = "Ridley" + }, + ["0x05c3000003800002"] = { + name = "Dark Samus" + }, + ["0x05c4000004131302"] = { + name = "E.M.M.I." + }, + ["0x0600000000120002"] = { + name = "Captain Falcon" + }, + ["0x06400100001e0002"] = { + name = "Olimar" + }, + ["0x06420000035f1102"] = { + name = "Pikmin" + }, + ["0x06c00000000f0002"] = { + name = "Little Mac" + }, + ["0x0700000000070002"] = { + name = "Wii Fit Trainer" + }, + ["0x0740000000100002"] = { + name = "Pit" + }, + ["0x0741000000200002"] = { + name = "Dark Pit" + }, + ["0x07420000001f0002"] = { + name = "Palutena" + }, + ["0x07800000002d0002"] = { + name = "Mr. Game & Watch" + }, + ["0x07810000002e0002"] = { + name = "R.O.B. - Famicom" + }, + ["0x0781000000330002"] = { + name = "R.O.B. - NES" + }, + ["0x07820000002f0002"] = { + name = "Duck Hunt" + }, + ["0x078f000003810002"] = { + name = "Ice Climbers" + }, + ["0x07c0000000210002"] = { + name = "Mii Brawler" + }, + ["0x07c0010000220002"] = { + name = "Mii Swordfighter" + }, + ["0x07c0020000230002"] = { + name = "Mii Gunner" + }, + ["0x08000100003e0402"] = { + name = "Inkling Girl" + }, + ["0x08000100025f0402"] = { + name = "Inkling Girl - Lime Green" + }, + ["0x0800010003690402"] = { + name = "Inkling Girl - Neon Pink" + }, + ["0x0800010003820002"] = { + name = "Inkling" + }, + ["0x08000200003f0402"] = { + name = "Inkling Boy" + }, + ["0x0800020002600402"] = { + name = "Inkling Boy - Purple" + }, + ["0x08000200036a0402"] = { + name = "Inkling Boy - Neon Green" + }, + ["0x0800030000400402"] = { + name = "Inkling Squid" + }, + ["0x0800030002610402"] = { + name = "Inkling Squid - Orange" + }, + ["0x08000300036b0402"] = { + name = "Inkling Squid - Neon Purple" + }, + ["0x08010000025d0402"] = { + name = "Callie" + }, + ["0x08020000025e0402"] = { + name = "Marie" + }, + ["0x0803000003760402"] = { + name = "Pearl" + }, + ["0x0804000003770402"] = { + name = "Marina" + }, + ["0x08050100038e0402"] = { + name = "Octoling Girl" + }, + ["0x08050200038f0402"] = { + name = "Octoling Boy" + }, + ["0x0805030003900402"] = { + name = "Octoling Octopus" + }, + ["0x09c0010102690e02"] = { + name = "Mario - Soccer" + }, + ["0x09c00201026a0e02"] = { + name = "Mario - Baseball" + }, + ["0x09c00301026b0e02"] = { + name = "Mario - Tennis" + }, + ["0x09c00401026c0e02"] = { + name = "Mario - Golf" + }, + ["0x09c00501026d0e02"] = { + name = "Mario - Horse Racing" + }, + ["0x09c10101026e0e02"] = { + name = "Luigi - Soccer" + }, + ["0x09c10201026f0e02"] = { + name = "Luigi - Baseball" + }, + ["0x09c1030102700e02"] = { + name = "Luigi - Tennis" + }, + ["0x09c1040102710e02"] = { + name = "Luigi - Golf" + }, + ["0x09c1050102720e02"] = { + name = "Luigi - Horse Racing" + }, + ["0x09c2010102730e02"] = { + name = "Peach - Soccer" + }, + ["0x09c2020102740e02"] = { + name = "Peach - Baseball" + }, + ["0x09c2030102750e02"] = { + name = "Peach - Tennis" + }, + ["0x09c2040102760e02"] = { + name = "Peach - Golf" + }, + ["0x09c2050102770e02"] = { + name = "Peach - Horse Racing" + }, + ["0x09c3010102780e02"] = { + name = "Daisy - Soccer" + }, + ["0x09c3020102790e02"] = { + name = "Daisy - Baseball" + }, + ["0x09c30301027a0e02"] = { + name = "Daisy - Tennis" + }, + ["0x09c30401027b0e02"] = { + name = "Daisy - Golf" + }, + ["0x09c30501027c0e02"] = { + name = "Daisy - Horse Racing" + }, + ["0x09c40101027d0e02"] = { + name = "Yoshi - Soccer" + }, + ["0x09c40201027e0e02"] = { + name = "Yoshi - Baseball" + }, + ["0x09c40301027f0e02"] = { + name = "Yoshi - Tennis" + }, + ["0x09c4040102800e02"] = { + name = "Yoshi - Golf" + }, + ["0x09c4050102810e02"] = { + name = "Yoshi - Horse Racing" + }, + ["0x09c5010102820e02"] = { + name = "Wario - Soccer" + }, + ["0x09c5020102830e02"] = { + name = "Wario - Baseball" + }, + ["0x09c5030102840e02"] = { + name = "Wario - Tennis" + }, + ["0x09c5040102850e02"] = { + name = "Wario - Golf" + }, + ["0x09c5050102860e02"] = { + name = "Wario - Horse Racing" + }, + ["0x09c6010102870e02"] = { + name = "Waluigi - Soccer" + }, + ["0x09c6020102880e02"] = { + name = "Waluigi - Baseball" + }, + ["0x09c6030102890e02"] = { + name = "Waluigi - Tennis" + }, + ["0x09c60401028a0e02"] = { + name = "Waluigi - Golf" + }, + ["0x09c60501028b0e02"] = { + name = "Waluigi - Horse Racing" + }, + ["0x09c70101028c0e02"] = { + name = "Donkey Kong - Soccer" + }, + ["0x09c70201028d0e02"] = { + name = "Donkey Kong - Baseball" + }, + ["0x09c70301028e0e02"] = { + name = "Donkey Kong - Tennis" + }, + ["0x09c70401028f0e02"] = { + name = "Donkey Kong - Golf" + }, + ["0x09c7050102900e02"] = { + name = "Donkey Kong - Horse Racing" + }, + ["0x09c8010102910e02"] = { + name = "Diddy Kong - Soccer" + }, + ["0x09c8020102920e02"] = { + name = "Diddy Kong - Baseball" + }, + ["0x09c8030102930e02"] = { + name = "Diddy Kong - Tennis" + }, + ["0x09c8040102940e02"] = { + name = "Diddy Kong - Golf" + }, + ["0x09c8050102950e02"] = { + name = "Diddy Kong - Horse Racing" + }, + ["0x09c9010102960e02"] = { + name = "Bowser - Soccer" + }, + ["0x09c9020102970e02"] = { + name = "Bowser - Baseball" + }, + ["0x09c9030102980e02"] = { + name = "Bowser - Tennis" + }, + ["0x09c9040102990e02"] = { + name = "Bowser - Golf" + }, + ["0x09c90501029a0e02"] = { + name = "Bowser - Horse Racing" + }, + ["0x09ca0101029b0e02"] = { + name = "Bowser Jr. - Soccer" + }, + ["0x09ca0201029c0e02"] = { + name = "Bowser Jr. - Baseball" + }, + ["0x09ca0301029d0e02"] = { + name = "Bowser Jr. - Tennis" + }, + ["0x09ca0401029e0e02"] = { + name = "Bowser Jr. - Golf" + }, + ["0x09ca0501029f0e02"] = { + name = "Bowser Jr. - Horse Racing" + }, + ["0x09cb010102a00e02"] = { + name = "Boo - Soccer" + }, + ["0x09cb020102a10e02"] = { + name = "Boo - Baseball" + }, + ["0x09cb030102a20e02"] = { + name = "Boo - Tennis" + }, + ["0x09cb040102a30e02"] = { + name = "Boo - Golf" + }, + ["0x09cb050102a40e02"] = { + name = "Boo - Horse Racing" + }, + ["0x09cc010102a50e02"] = { + name = "Baby Mario - Soccer" + }, + ["0x09cc020102a60e02"] = { + name = "Baby Mario - Baseball" + }, + ["0x09cc030102a70e02"] = { + name = "Baby Mario - Tennis" + }, + ["0x09cc040102a80e02"] = { + name = "Baby Mario - Golf" + }, + ["0x09cc050102a90e02"] = { + name = "Baby Mario - Horse Racing" + }, + ["0x09cd010102aa0e02"] = { + name = "Baby Luigi - Soccer" + }, + ["0x09cd020102ab0e02"] = { + name = "Baby Luigi - Baseball" + }, + ["0x09cd030102ac0e02"] = { + name = "Baby Luigi - Tennis" + }, + ["0x09cd040102ad0e02"] = { + name = "Baby Luigi - Golf" + }, + ["0x09cd050102ae0e02"] = { + name = "Baby Luigi - Horse Racing" + }, + ["0x09ce010102af0e02"] = { + name = "Birdo - Soccer" + }, + ["0x09ce020102b00e02"] = { + name = "Birdo - Baseball" + }, + ["0x09ce030102b10e02"] = { + name = "Birdo - Tennis" + }, + ["0x09ce040102b20e02"] = { + name = "Birdo - Golf" + }, + ["0x09ce050102b30e02"] = { + name = "Birdo - Horse Racing" + }, + ["0x09cf010102b40e02"] = { + name = "Rosalina - Soccer" + }, + ["0x09cf020102b50e02"] = { + name = "Rosalina - Baseball" + }, + ["0x09cf030102b60e02"] = { + name = "Rosalina - Tennis" + }, + ["0x09cf040102b70e02"] = { + name = "Rosalina - Golf" + }, + ["0x09cf050102b80e02"] = { + name = "Rosalina - Horse Racing" + }, + ["0x09d0010102b90e02"] = { + name = "Metal Mario - Soccer" + }, + ["0x09d0020102ba0e02"] = { + name = "Metal Mario - Baseball" + }, + ["0x09d0030102bb0e02"] = { + name = "Metal Mario - Tennis" + }, + ["0x09d0040102bc0e02"] = { + name = "Metal Mario - Golf" + }, + ["0x09d0050102bd0e02"] = { + name = "Metal Mario - Horse Racing" + }, + ["0x09d1010102be0e02"] = { + name = "Pink Gold Peach - Soccer" + }, + ["0x09d1020102bf0e02"] = { + name = "Pink Gold Peach - Baseball" + }, + ["0x09d1030102c00e02"] = { + name = "Pink Gold Peach - Tennis" + }, + ["0x09d1040102c10e02"] = { + name = "Pink Gold Peach - Golf" + }, + ["0x09d1050102c20e02"] = { + name = "Pink Gold Peach - Horse Racing" + }, + ["0x0a00000103ab0502"] = { + name = "Orville" + }, + ["0x0a01000103ac0502"] = { + name = "Wilbur" + }, + ["0x0a02000103b30502"] = { + name = "C.J." + }, + ["0x0a03000103b40502"] = { + name = "Flick" + }, + ["0x0a04000103b50502"] = { + name = "Daisy Mae" + }, + ["0x0a05000103b80502"] = { + name = "Harvey" + }, + ["0x0a06000103ba0502"] = { + name = "Wisp" + }, + ["0x0a07000103bc0502"] = { + name = "Niko" + }, + ["0x0a08000103bd0502"] = { + name = "Wardell" + }, + ["0x0a09000103c00502"] = { + name = "Sherb" + }, + ["0x0a0a000103c10502"] = { + name = "Megan" + }, + ["0x0a0b000103c20502"] = { + name = "Dom" + }, + ["0x0a0c000103c30502"] = { + name = "Audie" + }, + ["0x0a0d000103c40502"] = { + name = "Cyd" + }, + ["0x0a0e000103c50502"] = { + name = "Judy" + }, + ["0x0a0f000103c60502"] = { + name = "Raymond" + }, + ["0x0a10000103c70502"] = { + name = "Reneigh" + }, + ["0x0a11000103c80502"] = { + name = "Sasha" + }, + ["0x0a12000103c90502"] = { + name = "Ione" + }, + ["0x0a13000103ca0502"] = { + name = "Tiansheng" + }, + ["0x0a14000103cb0502"] = { + name = "Shino" + }, + ["0x0a15000103cc0502"] = { + name = "Marlo" + }, + ["0x0a16000103cd0502"] = { + name = "Petri" + }, + ["0x0a17000103ce0502"] = { + name = "Cephalobot" + }, + ["0x0a18000103cf0502"] = { + name = "Quinn" + }, + ["0x0a19000103d00502"] = { + name = "Chabwick" + }, + ["0x0a1a000103d10502"] = { + name = "Zoe" + }, + ["0x0a1b000103d20502"] = { + name = "Ace" + }, + ["0x0a1c000103d30502"] = { + name = "Rio" + }, + ["0x0a1d000103d40502"] = { + name = "Frett" + }, + ["0x0a1e000103d50502"] = { + name = "Azalea" + }, + ["0x0a1f000103d60502"] = { + name = "Roswell" + }, + ["0x0a20000103d70502"] = { + name = "Faith" + }, + ["0x0a400000041d0002"] = { + name = "Min Min" + }, + ["0x1902000003830002"] = { + name = "Ivysaur" + }, + ["0x1906000000240002"] = { + name = "Charizard" + }, + ["0x1907000003840002"] = { + name = "Squirtle" + }, + ["0x1919000000090002"] = { + name = "Pikachu" + }, + ["0x1927000000260002"] = { + name = "Jigglypuff" + }, + ["0x19960000023d0002"] = { + name = "Mewtwo" + }, + ["0x19ac000003850002"] = { + name = "Pichu" + }, + ["0x1ac0000000110002"] = { + name = "Lucario" + }, + ["0x1b92000000250002"] = { + name = "Greninja" + }, + ["0x1bd7000003860002"] = { + name = "Incineroar" + }, + ["0x1d000001025c0d02"] = { + name = "Shadow Mewtwo" + }, + ["0x1d01000003750d02"] = { + name = "Detective Pikachu" + }, + ["0x1d40000003870002"] = { + name = "Pokemon Trainer" + }, + ["0x1f000000000a0002"] = { + name = "Kirby" + }, + ["0x1f00000002540c02"] = { + name = "Kirby" + }, + ["0x1f01000000270002"] = { + name = "Meta Knight" + }, + ["0x1f01000002550c02"] = { + name = "Meta Knight" + }, + ["0x1f02000000280002"] = { + name = "King Dedede" + }, + ["0x1f02000002560c02"] = { + name = "King Dedede" + }, + ["0x1f03000002570c02"] = { + name = "Waddle Dee" + }, + ["0x1f400000035e1002"] = { + name = "Qbby" + }, + ["0x21000000000b0002"] = { + name = "Marth" + }, + ["0x2101000000180002"] = { + name = "Ike" + }, + ["0x2102000000290002"] = { + name = "Lucina" + }, + ["0x21030000002a0002"] = { + name = "Robin" + }, + ["0x2104000002520002"] = { + name = "Roy" + }, + ["0x21050000025a0002"] = { + name = "Corrin" + }, + ["0x2105010003630002"] = { + name = "Corrin - Player 2" + }, + ["0x2106000003601202"] = { + name = "Alm" + }, + ["0x2107000003611202"] = { + name = "Celica" + }, + ["0x21080000036f1202"] = { + name = "Chrom" + }, + ["0x2108000003880002"] = { + name = "Chrom" + }, + ["0x2109000003701202"] = { + name = "Tiki" + }, + ["0x210b000003a50002"] = { + name = "Byleth" + }, + ["0x22400000002b0002"] = { + name = "Shulk" + }, + ["0x22800000002c0002"] = { + name = "Ness" + }, + ["0x2281000002510002"] = { + name = "Lucas" + }, + ["0x22c00000003a0202"] = { + name = "Chibi Robo" + }, + ["0x3200000000300002"] = { + name = "Sonic" + }, + ["0x32400000025b0002"] = { + name = "Bayonetta" + }, + ["0x3240010003640002"] = { + name = "Bayonetta - Player 2" + }, + ["0x3340000000320002"] = { + name = "Pac-Man" + }, + ["0x3380000003781402"] = { + name = "Solaire of Astora" + }, + ["0x3480000000310002"] = { + name = "Mega Man" + }, + ["0x3480000002580002"] = { + name = "Mega Man - Gold Edition" + }, + ["0x3480000003791502"] = { + name = "Mega Man" + }, + ["0x34c0000002530002"] = { + name = "Ryu" + }, + ["0x34c1000003890002"] = { + name = "Ken" + }, + ["0x3500010002e10f02"] = { + name = "One-Eyed Rathalos and Rider - Male" + }, + ["0x3500020002e20f02"] = { + name = "One-Eyed Rathalos and Rider - Female" + }, + ["0x3501000002e30f02"] = { + name = "Nabiru" + }, + ["0x3502010002e40f02"] = { + name = "Rathian and Cheval" + }, + ["0x3503010002e50f02"] = { + name = "Barioth and Ayuria" + }, + ["0x3504010002e60f02"] = { + name = "Qurupeco and Dan" + }, + ["0x35050000040c0f02"] = { + name = "Razewing Ratha" + }, + ["0x35060000040d0f02"] = { + name = "Ena" + }, + ["0x35070000040e0f02"] = { + name = "Tsukino" + }, + ["0x35080000040f1802"] = { + name = "Magnamalo" + }, + ["0x3509000004101802"] = { + name = "Palico" + }, + ["0x35090100042b1802"] = { + name = "Palico" + }, + ["0x350a000004111802"] = { + name = "Palamute" + }, + ["0x350a0100042c1802"] = { + name = "Palamute" + }, + ["0x350b0000042d1802"] = { + name = "Malzeno" + }, + ["0x35c0000002500a02"] = { + name = "Shovel Knight" + }, + ["0x35c0000003920a02"] = { + name = "Shovel Knight - Gold Edition" + }, + ["0x35c10000036c0a02"] = { + name = "Plague Knight" + }, + ["0x35c20000036d0a02"] = { + name = "Specter Knight" + }, + ["0x35c30000036e0a02"] = { + name = "King Knight" + }, + ["0x3600000002590002"] = { + name = "Cloud" + }, + ["0x3600010003620002"] = { + name = "Cloud - Player 2" + }, + ["0x3640000003a20002"] = { + name = "Hero" + }, + ["0x3740000103741402"] = { + name = "Super Mario Cereal" + }, + ["0x37800000038a0002"] = { + name = "Snake" + }, + ["0x37c00000038b0002"] = { + name = "Simon" + }, + ["0x37c10000038c0002"] = { + name = "Richter" + }, + ["0x3800000103931702"] = { + name = "Pawapuro" + }, + ["0x3801000103941702"] = { + name = "Ikari" + }, + ["0x3802000103951702"] = { + name = "Daijobu" + }, + ["0x3803000103961702"] = { + name = "Hayakawa" + }, + ["0x3804000103971702"] = { + name = "Yabe" + }, + ["0x3805000103981702"] = { + name = "Ganda" + }, + ["0x3840000104241902"] = { + name = "Yuga Ohdo" + }, + ["0x3841000104251902"] = { + name = "Tatsuhisa “Luke” Kamijō" + }, + ["0x3842000104261902"] = { + name = "Gakuto Sōgetsu" + }, + ["0x3843000104271902"] = { + name = "Romin Kirishima" + }, + ["0x3844000104281902"] = { + name = "Roa Kirishima" + }, + ["0x3845000104291902"] = { + name = "Nail Saionji" + }, + ["0x38460001042a1902"] = { + name = "Asana Mutsuba" + }, + ["0x38c0000003911602"] = { + name = "Loot Goblin" + }, + ["0x3a00000003a10002"] = { + name = "Joker" + }, + ["0x3b40000003a30002"] = { + name = "Banjo & Kazooie" + }, + ["0x3c80000003a40002"] = { + name = "Terry" + } + }, + game_series = { + ["0x000"] = "Super Mario", + ["0x001"] = "Super Mario", + ["0x002"] = "Super Mario", + ["0x008"] = "Yoshi's Woolly World", + ["0x00c"] = "Donkey Kong", + ["0x010"] = "The Legend of Zelda", + ["0x014"] = "Breath of the Wild", + ["0x018"] = "Animal Crossing", + ["0x019"] = "Animal Crossing", + ["0x01a"] = "Animal Crossing", + ["0x01b"] = "Animal Crossing", + ["0x01c"] = "Animal Crossing", + ["0x020"] = "Animal Crossing", + ["0x021"] = "Animal Crossing", + ["0x022"] = "Animal Crossing", + ["0x023"] = "Animal Crossing", + ["0x024"] = "Animal Crossing", + ["0x025"] = "Animal Crossing", + ["0x026"] = "Animal Crossing", + ["0x027"] = "Animal Crossing", + ["0x028"] = "Animal Crossing", + ["0x029"] = "Animal Crossing", + ["0x02a"] = "Animal Crossing", + ["0x02b"] = "Animal Crossing", + ["0x02c"] = "Animal Crossing", + ["0x02d"] = "Animal Crossing", + ["0x02e"] = "Animal Crossing", + ["0x02f"] = "Animal Crossing", + ["0x030"] = "Animal Crossing", + ["0x031"] = "Animal Crossing", + ["0x032"] = "Animal Crossing", + ["0x033"] = "Animal Crossing", + ["0x034"] = "Animal Crossing", + ["0x035"] = "Animal Crossing", + ["0x036"] = "Animal Crossing", + ["0x037"] = "Animal Crossing", + ["0x038"] = "Animal Crossing", + ["0x039"] = "Animal Crossing", + ["0x03a"] = "Animal Crossing", + ["0x03b"] = "Animal Crossing", + ["0x03c"] = "Animal Crossing", + ["0x03d"] = "Animal Crossing", + ["0x03e"] = "Animal Crossing", + ["0x03f"] = "Animal Crossing", + ["0x040"] = "Animal Crossing", + ["0x041"] = "Animal Crossing", + ["0x042"] = "Animal Crossing", + ["0x043"] = "Animal Crossing", + ["0x044"] = "Animal Crossing", + ["0x045"] = "Animal Crossing", + ["0x046"] = "Animal Crossing", + ["0x047"] = "Animal Crossing", + ["0x048"] = "Animal Crossing", + ["0x049"] = "Animal Crossing", + ["0x04a"] = "Animal Crossing", + ["0x04b"] = "Animal Crossing", + ["0x04c"] = "Animal Crossing", + ["0x04d"] = "Animal Crossing", + ["0x04e"] = "Animal Crossing", + ["0x04f"] = "Animal Crossing", + ["0x050"] = "Animal Crossing", + ["0x051"] = "Animal Crossing", + ["0x0a0"] = "Animal Crossing", + ["0x0a1"] = "Animal Crossing", + ["0x0a2"] = "Animal Crossing", + ["0x058"] = "Star Fox", + ["0x05c"] = "Metroid", + ["0x060"] = "F-Zero", + ["0x064"] = "Pikmin", + ["0x06c"] = "Punch Out", + ["0x070"] = "Wii Fit", + ["0x074"] = "Kid Icarus", + ["0x078"] = "Classic Nintendo", + ["0x07c"] = "Mii", + ["0x080"] = "Splatoon", + ["0x09c"] = "Mario Sports Superstars", + ["0x09d"] = "Mario Sports Superstars", + ["0x0a4"] = "ARMS", + ["0x190"] = "Pokemon", + ["0x191"] = "Pokemon", + ["0x192"] = "Pokemon", + ["0x199"] = "Pokemon", + ["0x19a"] = "Pokemon", + ["0x1ac"] = "Pokemon", + ["0x1b9"] = "Pokemon", + ["0x1bd"] = "Pokemon", + ["0x1d0"] = "Pokemon", + ["0x1d4"] = "Pokemon", + ["0x1f0"] = "Kirby", + ["0x1f4"] = "BoxBoy!", + ["0x210"] = "Fire Emblem", + ["0x224"] = "Xenoblade", + ["0x228"] = "Earthbound", + ["0x22c"] = "Chibi Robo", + ["0x320"] = "Sonic", + ["0x324"] = "Bayonetta", + ["0x334"] = "Pac-man", + ["0x338"] = "Dark Souls", + ["0x348"] = "Megaman", + ["0x34c"] = "Street fighter", + ["0x350"] = "Monster Hunter", + ["0x35c"] = "Shovel Knight", + ["0x360"] = "Final Fantasy", + ["0x364"] = "Dragon Quest", + ["0x374"] = "Kellogs", + ["0x378"] = "Metal Gear Solid", + ["0x37c"] = "Castlevania", + ["0x380"] = "Power Pros", + ["0x384"] = "Yu-Gi-Oh!", + ["0x38c"] = "Diablo", + ["0x3a0"] = "Persona", + ["0x3b4"] = "Banjo Kazooie", + ["0x3c8"] = "Fatal Fury" + }, + types = { + ["0x00"] = "Figure", + ["0x01"] = "Card", + ["0x02"] = "Yarn", + ["0x03"] = "Band" + } +} +copyright = '' +author = 'George Talusan' +version = 'v0.0.1' +desc = [[ +This script will try to load a binary datadump of an Amiibo. +It will recalculate PWD and PACK if necessary. +]] +example = [[ + 1. script run hf_mf_amiibo_sim + 2. script run hf_mf_amiibo_sim -f myfile +]] +usage = [[ +script run hf_mf_amiibo_sim [-h] [-f ] +]] +arguments = [[ + -h : this help + -f : filename for the datadump to read (bin) +]] + +local DEBUG = false -- the debug flag + +local bxor = bit32.bxor +local sub = string.sub +local format = string.format + +--- +-- A debug printout-function +local function dbg(args) + if not DEBUG then return end + if type(args) == 'table' then + local i = 1 + while result[i] do + dbg(result[i]) + i = i+1 + end + else + print('###', args) + end +end +--- +-- This is only meant to be used when errors occur +local function oops(err) + print('ERROR:', err) + core.clearCommandBuffer() + return nil, err +end +--- +-- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print(ansicolors.cyan..'Usage'..ansicolors.reset) + print(usage) + print(ansicolors.cyan..'Arguments'..ansicolors.reset) + print(arguments) + print(ansicolors.cyan..'Example usage'..ansicolors.reset) + print(example) +end +-- +-- Exit message +local function ExitMsg(msg) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print(msg) + print() +end + +local function LoadEmulator(uid, blocks) + io.write('Sending Amiibo to emulator memory') + local cmd, blockdata + for i=0,148,1 do + blockdata = blocks[i] + io.write('.') + io.flush() + core.clearCommandBuffer() + cmd = Command:newNG{cmd = cmds.CMD_HF_MIFARE_EML_MEMSET, data = ('%02x%02x%02x%s'):format(i, 1, 4, blockdata)} + local err, msg = cmd:sendNG(true) + if err == nil then return err, msg end + end + io.write('\n') +end + +local function main(args) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + + local result, err, hex + local inputTemplate = 'dumpdata.bin' + + for o, a in getopt.getopt(args, 'hf:u:') do + if o == 'h' then return help() end + if o == 'f' then inputTemplate = a end + end + + print(('Loading data from %s'):format(inputTemplate)) + hex, err = utils.ReadDumpFile(inputTemplate) + if not hex then return oops(err) end + + -- only deal with missing PWD and PACK, or with 56 emu hdr + if #hex ~= 1064 and #hex ~= 1080 and #hex ~= 1192 then return oops('Expecting either a plain binary or emulator dump') end + + local amiibo_offset = (#hex == 1064 or #hex == 1080) and 0 or 112 + local amiibo_info = hex:sub(amiibo_offset + 169, amiibo_offset + 169 + 15):lower() + local amiibo_game = amiibo_info:sub(1, 3) + local amiibo_type = amiibo_info:sub(7, 8) + local amiibo_series = amiibo_info:sub(13, 14) + + dbg('raw: '..ansicolors.green..amiibo_info..ansicolors.reset) + print('game: '..ansicolors.green..amiiboDb.game_series[("0x%s"):format(amiibo_game)]..ansicolors.reset) + print('character: '..ansicolors.green..amiiboDb.amiibos[("0x%s"):format(amiibo_info)].name..ansicolors.reset) + print('type: '..ansicolors.green..amiiboDb.types[("0x%s"):format(amiibo_type)]..ansicolors.reset) + print('series: '..ansicolors.green..amiiboDb.amiibo_series[("0x%s"):format(amiibo_series)]..ansicolors.reset) + + local blocks = {} + local blockindex = 0 + + -- add empty header if necessary + if (#hex == 1064 or #hex == 1080) then + for i = 0, 13, 1 do + blocks[i] = '00000000' + end + blocks[2] = '00000086' + blockindex = 14 + end + for i = 1, #hex, 8 do + blocks[blockindex] = hex:sub(i, i+7) + blockindex = blockindex + 1 + end + + -- add PWD and PACK if necessary + local uid = blocks[14]:sub(1, 6)..blocks[15]:sub(1, 8) + if blocks[147] == nil or blocks[147] == '00000000' then + blocks[147] = ("%08x"):format(bxor(bxor(tonumber(sub(uid, 2, 10), 16), tonumber(sub(uid, 6, 14), 16)), 0xaa55aa55)) + end + if blocks[148] == nil or blocks[148] == '00000000' then + blocks[148] = "80800000" + end + + err = LoadEmulator(uid, blocks) + if err then return oops(err) end + core.clearCommandBuffer() + core.console(("hf mfu sim -t 7 -u %s"):format(uid)) +end +main(args) From d89ed735b04d47f53b115c15cd468631a9151f4a Mon Sep 17 00:00:00 2001 From: George Talusan Date: Thu, 28 Jul 2022 22:01:18 -0400 Subject: [PATCH 155/759] add hf_mfu_amiibo_restore to restore an Amiibo dump to a blank NTAG215 --- client/lualibs/amiibo_tools.lua | 2648 ++++++++++++++++++ client/luascripts/hf_mfu_amiibo_restore.lua | 164 ++ client/luascripts/hf_mfu_amiibo_sim.lua | 2664 +------------------ client/pyscripts/amiibo_change_uid.py | 41 + client/src/scripting.c | 49 +- 5 files changed, 2913 insertions(+), 2653 deletions(-) create mode 100644 client/lualibs/amiibo_tools.lua create mode 100644 client/luascripts/hf_mfu_amiibo_restore.lua create mode 100644 client/pyscripts/amiibo_change_uid.py diff --git a/client/lualibs/amiibo_tools.lua b/client/lualibs/amiibo_tools.lua new file mode 100644 index 000000000..b4c3f3bbf --- /dev/null +++ b/client/lualibs/amiibo_tools.lua @@ -0,0 +1,2648 @@ +local amiibo_tools = {} + +-- curl https://raw.githubusercontent.com/N3evin/AmiiboAPI/master/database/amiibo.json | jq 'del(.amiibos[].release)' | jq 'del(.characters)' | pbcopy --> transform to table +amiibo_tools.db = +{ + amiibo_series = { + ["0x00"] = "Super Smash Bros.", + ["0x01"] = "Super Mario Bros.", + ["0x02"] = "Chibi-Robo!", + ["0x03"] = "Yoshi's Woolly World", + ["0x04"] = "Splatoon", + ["0x05"] = "Animal Crossing", + ["0x06"] = "8-bit Mario", + ["0x07"] = "Skylanders", + ["0x09"] = "Legend Of Zelda", + ["0x0a"] = "Shovel Knight", + ["0x0c"] = "Kirby", + ["0x0d"] = "Pokemon", + ["0x0e"] = "Mario Sports Superstars", + ["0x0f"] = "Monster Hunter", + ["0x10"] = "BoxBoy!", + ["0x11"] = "Pikmin", + ["0x12"] = "Fire Emblem", + ["0x13"] = "Metroid", + ["0x14"] = "Others", + ["0x15"] = "Mega Man", + ["0x16"] = "Diablo", + ["0x17"] = "Power Pros", + ["0x18"] = "Monster Hunter Rise", + ["0x19"] = "Yu-Gi-Oh!", + ["0xff"] = "Super Nintendo World" + }, + amiibos = { + ["0x0000000000000002"] = { + name = "Mario" + }, + ["0x0000000000340102"] = { + name = "Mario" + }, + ["0x00000000003c0102"] = { + name = "Mario - Gold Edition" + }, + ["0x00000000003d0102"] = { + name = "Mario - Silver Edition" + }, + ["0x0000000002380602"] = { + name = "8-Bit Mario Classic Color" + }, + ["0x0000000002390602"] = { + name = "8-Bit Mario Modern Color" + }, + ["0x0000000003710102"] = { + name = "Mario - Wedding" + }, + ["0x00000003039bff02"] = { + name = "Mario - Power Up Band" + }, + ["0x0000010000190002"] = { + name = "Dr. Mario" + }, + ["0x0000030003a60102"] = { + name = "Mario - Cat" + }, + ["0x00010000000c0002"] = { + name = "Luigi" + }, + ["0x0001000000350102"] = { + name = "Luigi" + }, + ["0x00010003039cff02"] = { + name = "Luigi - Power Up Band" + }, + ["0x0002000000010002"] = { + name = "Peach" + }, + ["0x0002000000360102"] = { + name = "Peach" + }, + ["0x0002000003720102"] = { + name = "Peach - Wedding" + }, + ["0x00020003039dff02"] = { + name = "Peach - Power Up Band" + }, + ["0x0002010003a70102"] = { + name = "Peach - Cat" + }, + ["0x0003000000020002"] = { + name = "Yoshi" + }, + ["0x0003000000370102"] = { + name = "Yoshi" + }, + ["0x00030003039fff02"] = { + name = "Yoshi - Power Up Band" + }, + ["0x0003010200410302"] = { + name = "Green Yarn Yoshi" + }, + ["0x0003010200420302"] = { + name = "Pink Yarn Yoshi" + }, + ["0x0003010200430302"] = { + name = "Light Blue Yarn Yoshi" + }, + ["0x00030102023e0302"] = { + name = "Mega Yarn Yoshi" + }, + ["0x0004000002620102"] = { + name = "Rosalina" + }, + ["0x0004010000130002"] = { + name = "Rosalina & Luma" + }, + ["0x0005000000140002"] = { + name = "Bowser" + }, + ["0x0005000000390102"] = { + name = "Bowser" + }, + ["0x0005000003730102"] = { + name = "Bowser - Wedding" + }, + ["0x0005ff00023a0702"] = { + name = "Hammer Slam Bowser" + }, + ["0x0006000000150002"] = { + name = "Bowser Jr." + }, + ["0x00070000001a0002"] = { + name = "Wario" + }, + ["0x0007000002630102"] = { + name = "Wario" + }, + ["0x0008000000030002"] = { + name = "Donkey Kong" + }, + ["0x0008000002640102"] = { + name = "Donkey Kong" + }, + ["0x0008ff00023b0702"] = { + name = "Turbo Charge Donkey Kong" + }, + ["0x00090000000d0002"] = { + name = "Diddy Kong" + }, + ["0x0009000002650102"] = { + name = "Diddy Kong" + }, + ["0x000a000000380102"] = { + name = "Toad" + }, + ["0x000a000303a0ff02"] = { + name = "Toad - Power Up Band" + }, + ["0x0013000002660102"] = { + name = "Daisy" + }, + ["0x00130000037a0002"] = { + name = "Daisy" + }, + ["0x00130003039eff02"] = { + name = "Daisy - Power Up Band" + }, + ["0x0014000002670102"] = { + name = "Waluigi" + }, + ["0x0015000003670102"] = { + name = "Goomba" + }, + ["0x0017000002680102"] = { + name = "Boo" + }, + ["0x0023000003680102"] = { + name = "Koopa Troopa" + }, + ["0x00240000038d0002"] = { + name = "Piranha Plant" + }, + ["0x00800102035d0302"] = { + name = "Poochy" + }, + ["0x00c00000037b0002"] = { + name = "King K. Rool" + }, + ["0x0100000000040002"] = { + name = "Link" + }, + ["0x01000000034b0902"] = { + name = "Link - Ocarina of Time" + }, + ["0x01000000034c0902"] = { + name = "Link - Majora's Mask" + }, + ["0x01000000034d0902"] = { + name = "Link - Twilight Princess" + }, + ["0x01000000034e0902"] = { + name = "Link - Skyward Sword" + }, + ["0x01000000034f0902"] = { + name = "8-Bit Link" + }, + ["0x0100000003530902"] = { + name = "Link - Archer" + }, + ["0x0100000003540902"] = { + name = "Link - Rider" + }, + ["0x01000000037c0002"] = { + name = "Young Link" + }, + ["0x0100000003990902"] = { + name = "Link - Link's Awakening" + }, + ["0x0100010000160002"] = { + name = "Toon Link" + }, + ["0x0100010003500902"] = { + name = "Toon Link - The Wind Waker" + }, + ["0x01010000000e0002"] = { + name = "Zelda" + }, + ["0x0101000003520902"] = { + name = "Toon Zelda - The Wind Waker" + }, + ["0x0101000003560902"] = { + name = "Zelda" + }, + ["0x0101010000170002"] = { + name = "Sheik" + }, + ["0x0101030004140902"] = { + name = "Zelda & Loftwing" + }, + ["0x01020100001b0002"] = { + name = "Ganondorf" + }, + ["0x01030000024f0902"] = { + name = "Midna & Wolf Link" + }, + ["0x0105000003580902"] = { + name = "Daruk" + }, + ["0x0106000003590902"] = { + name = "Urbosa" + }, + ["0x01070000035a0902"] = { + name = "Mipha" + }, + ["0x01080000035b0902"] = { + name = "Revali" + }, + ["0x0140000003550902"] = { + name = "Guardian" + }, + ["0x01410000035c0902"] = { + name = "Bokoblin" + }, + ["0x0180000000080002"] = { + name = "Villager" + }, + ["0x01810000024b0502"] = { + name = "Isabelle - Summer Outfit" + }, + ["0x01810000037d0002"] = { + name = "Isabelle" + }, + ["0x0181000100440502"] = { + name = "Isabelle" + }, + ["0x0181000101d40502"] = { + name = "Isabelle - Character Parfait" + }, + ["0x01810100023f0502"] = { + name = "Isabelle - Winter Outfit" + }, + ["0x0181010100b40502"] = { + name = "Isabelle - Winter" + }, + ["0x01810201011a0502"] = { + name = "Isabelle - Kimono" + }, + ["0x0181030101700502"] = { + name = "Isabelle - Dress" + }, + ["0x0181040103aa0502"] = { + name = "Isabelle" + }, + ["0x0181050103bf0502"] = { + name = "Isabelle - Sweater" + }, + ["0x0182000002400502"] = { + name = "K. K. Slider" + }, + ["0x0182000100a80502"] = { + name = "K.K. Slider" + }, + ["0x0182000101d80502"] = { + name = "K. K. Slider - Pikopuri" + }, + ["0x0182000103b20502"] = { + name = "K.K. Slider" + }, + ["0x0182010100460502"] = { + name = "DJ KK" + }, + ["0x0183000002420502"] = { + name = "Tom Nook" + }, + ["0x0183000100450502"] = { + name = "Tom Nook" + }, + ["0x01830101010e0502"] = { + name = "Tom Nook - Jacket" + }, + ["0x0183020103a80502"] = { + name = "Tom Nook" + }, + ["0x0183030103be0502"] = { + name = "Tom Nook - Coat" + }, + ["0x01840000024d0502"] = { + name = "Timmy & Tommy" + }, + ["0x0184050103a90502"] = { + name = "Timmy & Tommy" + }, + ["0x01850001004b0502"] = { + name = "Timmy" + }, + ["0x0185020101170502"] = { + name = "Timmy - Full Apron" + }, + ["0x0185040101790502"] = { + name = "Timmy - Suit" + }, + ["0x0186010100af0502"] = { + name = "Tommy - Uniform" + }, + ["0x0186030101750502"] = { + name = "Tommy - Suit" + }, + ["0x0187000100470502"] = { + name = "Sable" + }, + ["0x0187000103b00502"] = { + name = "Sable" + }, + ["0x0188000002410502"] = { + name = "Mabel" + }, + ["0x0188000101120502"] = { + name = "Mabel" + }, + ["0x0188000103af0502"] = { + name = "Mabel" + }, + ["0x0189000100ab0502"] = { + name = "Label" + }, + ["0x0189010103b10502"] = { + name = "Label" + }, + ["0x018a000002450502"] = { + name = "Reese" + }, + ["0x018a000100a90502"] = { + name = "Reese" + }, + ["0x018b000002460502"] = { + name = "Cyrus" + }, + ["0x018b000101150502"] = { + name = "Cyrus" + }, + ["0x018c000002430502"] = { + name = "Digby" + }, + ["0x018c0001004c0502"] = { + name = "Digby" + }, + ["0x018c010101180502"] = { + name = "Digby - Raincoat" + }, + ["0x018d0000024c0502"] = { + name = "Rover" + }, + ["0x018d0001010c0502"] = { + name = "Rover" + }, + ["0x018e000002490502"] = { + name = "Resetti" + }, + ["0x018e000100490502"] = { + name = "Resetti" + }, + ["0x018e010101780502"] = { + name = "Resetti - Without Hat" + }, + ["0x018f000100b30502"] = { + name = "Don Resetti" + }, + ["0x018f010101190502"] = { + name = "Don Resetti - Without Hat" + }, + ["0x0190000101710502"] = { + name = "Brewster" + }, + ["0x01910001004e0502"] = { + name = "Harriet" + }, + ["0x0192000002470502"] = { + name = "Blathers" + }, + ["0x01920001010d0502"] = { + name = "Blathers" + }, + ["0x0192000103ad0502"] = { + name = "Blathers" + }, + ["0x0193000002480502"] = { + name = "Celeste" + }, + ["0x0193000101740502"] = { + name = "Celeste" + }, + ["0x0193000103ae0502"] = { + name = "Celeste" + }, + ["0x01940000024a0502"] = { + name = "Kicks" + }, + ["0x0194000100aa0502"] = { + name = "Kicks" + }, + ["0x0194000103b60502"] = { + name = "Kicks" + }, + ["0x0195000100b00502"] = { + name = "Porter" + }, + ["0x01960000024e0502"] = { + name = "Kapp'n" + }, + ["0x0196000100480502"] = { + name = "Kapp'n" + }, + ["0x0197000101770502"] = { + name = "Leilani" + }, + ["0x0198000100b10502"] = { + name = "Leila" + }, + ["0x0199000101160502"] = { + name = "Grams" + }, + ["0x019a000100b70502"] = { + name = "Chip" + }, + ["0x019b000100b60502"] = { + name = "Nat" + }, + ["0x019c000101730502"] = { + name = "Phineas" + }, + ["0x019d000100ac0502"] = { + name = "Copper" + }, + ["0x019e000100ad0502"] = { + name = "Booker" + }, + ["0x019f000101110502"] = { + name = "Pete" + }, + ["0x01a00001010f0502"] = { + name = "Pelly" + }, + ["0x01a1000101100502"] = { + name = "Phyllis" + }, + ["0x01a20001017d0502"] = { + name = "Gulliver" + }, + ["0x01a2000103b90502"] = { + name = "Gulliver" + }, + ["0x01a30001004a0502"] = { + name = "Joan" + }, + ["0x01a40001004d0502"] = { + name = "Pascal" + }, + ["0x01a5000101720502"] = { + name = "Katrina" + }, + ["0x01a6000100500502"] = { + name = "Saharah" + }, + ["0x01a6000103b70502"] = { + name = "Saharah" + }, + ["0x01a7000101140502"] = { + name = "Wendell" + }, + ["0x01a80001004f0502"] = { + name = "Redd" + }, + ["0x01a80101017e0502"] = { + name = "Redd - Shirt" + }, + ["0x01a9000101760502"] = { + name = "Gracie" + }, + ["0x01aa000100530502"] = { + name = "Lyle" + }, + ["0x01ab0001017c0502"] = { + name = "Pave" + }, + ["0x01ac0001017f0502"] = { + name = "Zipper" + }, + ["0x01ad000100b80502"] = { + name = "Jack" + }, + ["0x01ae0001011b0502"] = { + name = "Franklin" + }, + ["0x01af0001011c0502"] = { + name = "Jingle" + }, + ["0x01b0000100520502"] = { + name = "Tortimer" + }, + ["0x01b1000100b20502"] = { + name = "Shrunk" + }, + ["0x01b10101017b0502"] = { + name = "Shrunk - Loud Jacket" + }, + ["0x01b3000100b50502"] = { + name = "Blanca" + }, + ["0x01b4000101130502"] = { + name = "Leif" + }, + ["0x01b5000100510502"] = { + name = "Luna" + }, + ["0x01b6000100ae0502"] = { + name = "Katie" + }, + ["0x01c1000002440502"] = { + name = "Lottie" + }, + ["0x01c1000100540502"] = { + name = "Lottie" + }, + ["0x01c10101017a0502"] = { + name = "Lottie - Black Skirt And Bow" + }, + ["0x01c1020103bb0502"] = { + name = "Lottie - Island" + }, + ["0x0200000100a10502"] = { + name = "Cyrano" + }, + ["0x02010001016a0502"] = { + name = "Antonio" + }, + ["0x0202000101030502"] = { + name = "Pango" + }, + ["0x02030001019a0502"] = { + name = "Anabelle" + }, + ["0x0206000103120502"] = { + name = "Snooty" + }, + ["0x0208000100960502"] = { + name = "Annalisa" + }, + ["0x02090001019f0502"] = { + name = "Olaf" + }, + ["0x0214000100e40502"] = { + name = "Teddy" + }, + ["0x0215000101820502"] = { + name = "Pinky" + }, + ["0x0216000100570502"] = { + name = "Curt" + }, + ["0x0217000101b30502"] = { + name = "Chow" + }, + ["0x02190001007e0502"] = { + name = "Nate" + }, + ["0x021a000100da0502"] = { + name = "Groucho" + }, + ["0x021b000100800502"] = { + name = "Tutu" + }, + ["0x021c000102f70502"] = { + name = "Ursala" + }, + ["0x021d000101cd0502"] = { + name = "Grizzly" + }, + ["0x021e000101230502"] = { + name = "Paula" + }, + ["0x021f000103170502"] = { + name = "Ike" + }, + ["0x0220000100fd0502"] = { + name = "Charlise" + }, + ["0x02210001013c0502"] = { + name = "Beardo" + }, + ["0x0222000101440502"] = { + name = "Klaus" + }, + ["0x022d000100f20502"] = { + name = "Jay" + }, + ["0x022e000101d30502"] = { + name = "Robin" + }, + ["0x022f0001011e0502"] = { + name = "Anchovy" + }, + ["0x0230000101d20502"] = { + name = "Twiggy" + }, + ["0x02310001006a0502"] = { + name = "Jitters" + }, + ["0x0232000102ea0502"] = { + name = "Piper" + }, + ["0x0233000103060502"] = { + name = "Admiral" + }, + ["0x0235000100840502"] = { + name = "Midge" + }, + ["0x0238000102f80502"] = { + name = "Jacob" + }, + ["0x023c000100bd0502"] = { + name = "Lucha" + }, + ["0x023d000101b50502"] = { + name = "Jacques" + }, + ["0x023e000100d10502"] = { + name = "Peck" + }, + ["0x023f000101660502"] = { + name = "Sparro" + }, + ["0x024a000101d10502"] = { + name = "Angus" + }, + ["0x024b000101260502"] = { + name = "Rodeo" + }, + ["0x024d000102f60502"] = { + name = "Stu" + }, + ["0x024f000100810502"] = { + name = "T-Bone" + }, + ["0x0251000100c10502"] = { + name = "Coach" + }, + ["0x0252000100fe0502"] = { + name = "Vic" + }, + ["0x025d000100550502"] = { + name = "Bob" + }, + ["0x025e000101250502"] = { + name = "Mitzi" + }, + ["0x025f000101c50502"] = { + name = "Rosie" + }, + ["0x025f000101d70502"] = { + name = "Rosie - Amiibo Festival" + }, + ["0x0260000100d20502"] = { + name = "Olivia" + }, + ["0x0261000100650502"] = { + name = "Kiki" + }, + ["0x0262000101370502"] = { + name = "Tangy" + }, + ["0x0263000100750502"] = { + name = "Punchy" + }, + ["0x0264000101ac0502"] = { + name = "Purrl" + }, + ["0x0265000101540502"] = { + name = "Moe" + }, + ["0x0266000100680502"] = { + name = "Kabuki" + }, + ["0x0267000101080502"] = { + name = "Kid Cat" + }, + ["0x02680001007d0502"] = { + name = "Monique" + }, + ["0x02690001011f0502"] = { + name = "Tabby" + }, + ["0x026a000101460502"] = { + name = "Stinky" + }, + ["0x026b000100e90502"] = { + name = "Kitty" + }, + ["0x026c000100c30502"] = { + name = "Tom" + }, + ["0x026d0001013f0502"] = { + name = "Merry" + }, + ["0x026e000100ba0502"] = { + name = "Felicity" + }, + ["0x026f000101900502"] = { + name = "Lolly" + }, + ["0x0270000100ff0502"] = { + name = "Ankha" + }, + ["0x02710001019b0502"] = { + name = "Rudy" + }, + ["0x0272000101860502"] = { + name = "Katt" + }, + ["0x027d000100630502"] = { + name = "Bluebear" + }, + ["0x027e000101690502"] = { + name = "Maple" + }, + ["0x027f000100b90502"] = { + name = "Poncho" + }, + ["0x0280000100830502"] = { + name = "Pudge" + }, + ["0x0281000101200502"] = { + name = "Kody" + }, + ["0x0282000101810502"] = { + name = "Stitches" + }, + ["0x0282000101d60502"] = { + name = "Stitches - Amiibo Festival" + }, + ["0x0283000100c70502"] = { + name = "Vladimir" + }, + ["0x0284000102fe0502"] = { + name = "Murphy" + }, + ["0x0286000103130502"] = { + name = "Olive" + }, + ["0x02870001005a0502"] = { + name = "Cheri" + }, + ["0x028a000102e90502"] = { + name = "June" + }, + ["0x028b000100e30502"] = { + name = "Pekoe" + }, + ["0x028c0001013e0502"] = { + name = "Chester" + }, + ["0x028d000101bd0502"] = { + name = "Barold" + }, + ["0x028e0001019e0502"] = { + name = "Tammy" + }, + ["0x028f0101031a0502"] = { + name = "Marty" + }, + ["0x0299000100950502"] = { + name = "Goose" + }, + ["0x029a000100ee0502"] = { + name = "Benedict" + }, + ["0x029b000100cb0502"] = { + name = "Egbert" + }, + ["0x029e0001013d0502"] = { + name = "Ava" + }, + ["0x02a2000101ba0502"] = { + name = "Becky" + }, + ["0x02a3000102ff0502"] = { + name = "Plucky" + }, + ["0x02a4000100720502"] = { + name = "Knox" + }, + ["0x02a50001018c0502"] = { + name = "Broffina" + }, + ["0x02a6000101240502"] = { + name = "Ken" + }, + ["0x02b1000100690502"] = { + name = "Patty" + }, + ["0x02b2000100c40502"] = { + name = "Tipper" + }, + ["0x02b70001030f0502"] = { + name = "Norma" + }, + ["0x02b80001019c0502"] = { + name = "Naomi" + }, + ["0x02c3000100dc0502"] = { + name = "Alfonso" + }, + ["0x02c4000100670502"] = { + name = "Alli" + }, + ["0x02c5000103080502"] = { + name = "Boots" + }, + ["0x02c7000101220502"] = { + name = "Del" + }, + ["0x02c9000100cd0502"] = { + name = "Sly" + }, + ["0x02ca000101ca0502"] = { + name = "Gayle" + }, + ["0x02cb000101360502"] = { + name = "Drago" + }, + ["0x02d6000100560502"] = { + name = "Fauna" + }, + ["0x02d7000101300502"] = { + name = "Bam" + }, + ["0x02d8000100e20502"] = { + name = "Zell" + }, + ["0x02d9000101c80502"] = { + name = "Bruce" + }, + ["0x02da000101330502"] = { + name = "Deirdre" + }, + ["0x02db0001005e0502"] = { + name = "Lopez" + }, + ["0x02dc000100be0502"] = { + name = "Fuchsia" + }, + ["0x02dd000100ea0502"] = { + name = "Beau" + }, + ["0x02de0001009c0502"] = { + name = "Diana" + }, + ["0x02df000101910502"] = { + name = "Erik" + }, + ["0x02e00101031d0502"] = { + name = "Chelsea" + }, + ["0x02ea000101800502"] = { + name = "Goldie" + }, + ["0x02ea000101d50502"] = { + name = "Goldie - Amiibo Festival" + }, + ["0x02eb000100de0502"] = { + name = "Butch" + }, + ["0x02ec000101c40502"] = { + name = "Lucky" + }, + ["0x02ed0001015a0502"] = { + name = "Biskit" + }, + ["0x02ee000101990502"] = { + name = "Bones" + }, + ["0x02ef000100580502"] = { + name = "Portia" + }, + ["0x02f0000100a70502"] = { + name = "Walker" + }, + ["0x02f1000101450502"] = { + name = "Daisy" + }, + ["0x02f2000100cc0502"] = { + name = "Cookie" + }, + ["0x02f3000102f90502"] = { + name = "Maddie" + }, + ["0x02f4000103050502"] = { + name = "Bea" + }, + ["0x02f8000101380502"] = { + name = "Mac" + }, + ["0x02f9000101020502"] = { + name = "Marcel" + }, + ["0x02fa000100970502"] = { + name = "Benjamin" + }, + ["0x02fb000100900502"] = { + name = "Cherry" + }, + ["0x02fc0001018f0502"] = { + name = "Shep" + }, + ["0x0307000100640502"] = { + name = "Bill" + }, + ["0x03080001014d0502"] = { + name = "Joey" + }, + ["0x0309000100c60502"] = { + name = "Pate" + }, + ["0x030a000101c70502"] = { + name = "Maelle" + }, + ["0x030b000100790502"] = { + name = "Deena" + }, + ["0x030c000101b80502"] = { + name = "Pompom" + }, + ["0x030d000101840502"] = { + name = "Mallary" + }, + ["0x030e0001012f0502"] = { + name = "Freckles" + }, + ["0x030f0001016d0502"] = { + name = "Derwin" + }, + ["0x0310000100f80502"] = { + name = "Drake" + }, + ["0x0311000100d60502"] = { + name = "Scoot" + }, + ["0x0312000103090502"] = { + name = "Weber" + }, + ["0x0313000101210502"] = { + name = "Miranda" + }, + ["0x0314000102f40502"] = { + name = "Ketchup" + }, + ["0x0316000101c00502"] = { + name = "Gloria" + }, + ["0x0317000100a60502"] = { + name = "Molly" + }, + ["0x03180001006c0502"] = { + name = "Quillson" + }, + ["0x0323000100760502"] = { + name = "Opal" + }, + ["0x0324000101890502"] = { + name = "Dizzy" + }, + ["0x03250001010a0502"] = { + name = "Big Top" + }, + ["0x0326000101390502"] = { + name = "Eloise" + }, + ["0x0327000101c30502"] = { + name = "Margie" + }, + ["0x0328000102eb0502"] = { + name = "Paolo" + }, + ["0x03290001009d0502"] = { + name = "Axel" + }, + ["0x032a000103070502"] = { + name = "Ellie" + }, + ["0x032c000101480502"] = { + name = "Tucker" + }, + ["0x032d000100bc0502"] = { + name = "Tia" + }, + ["0x032e0101031c0502"] = { + name = "Chai" + }, + ["0x03380001011d0502"] = { + name = "Lily" + }, + ["0x0339000101b10502"] = { + name = "Ribbot" + }, + ["0x033a000101cc0502"] = { + name = "Frobert" + }, + ["0x033b000100fa0502"] = { + name = "Camofrog" + }, + ["0x033c000101000502"] = { + name = "Drift" + }, + ["0x033d0001013a0502"] = { + name = "Wart Jr." + }, + ["0x033e000101a20502"] = { + name = "Puddles" + }, + ["0x033f0001008f0502"] = { + name = "Jeremiah" + }, + ["0x03410001030e0502"] = { + name = "Tad" + }, + ["0x0342000101280502"] = { + name = "Cousteau" + }, + ["0x0343000102ef0502"] = { + name = "Huck" + }, + ["0x0344000100c50502"] = { + name = "Prince" + }, + ["0x03450001005f0502"] = { + name = "Jambette" + }, + ["0x0347000103020502"] = { + name = "Raddle" + }, + ["0x03480001006b0502"] = { + name = "Gigi" + }, + ["0x03490001018d0502"] = { + name = "Croque" + }, + ["0x034a000101430502"] = { + name = "Diva" + }, + ["0x034b0001009f0502"] = { + name = "Henry" + }, + ["0x0356000101350502"] = { + name = "Chevre" + }, + ["0x0357000100eb0502"] = { + name = "Nan" + }, + ["0x0358000102fa0502"] = { + name = "Billy" + }, + ["0x035a000100850502"] = { + name = "Gruff" + }, + ["0x035c000101290502"] = { + name = "Velma" + }, + ["0x035d000100c90502"] = { + name = "Kidd" + }, + ["0x035e0001018e0502"] = { + name = "Pashmina" + }, + ["0x0369000100d30502"] = { + name = "Cesar" + }, + ["0x036a0001019d0502"] = { + name = "Peewee" + }, + ["0x036b0001018b0502"] = { + name = "Boone" + }, + ["0x036d000103040502"] = { + name = "Louie" + }, + ["0x036e000102fb0502"] = { + name = "Boyd" + }, + ["0x03700001015d0502"] = { + name = "Violet" + }, + ["0x03710001005c0502"] = { + name = "Al" + }, + ["0x03720001010b0502"] = { + name = "Rocket" + }, + ["0x0373000101340502"] = { + name = "Hans" + }, + ["0x0374010103190502"] = { + name = "Rilla" + }, + ["0x037e000101560502"] = { + name = "Hamlet" + }, + ["0x037f000101aa0502"] = { + name = "Apple" + }, + ["0x0380000101870502"] = { + name = "Graham" + }, + ["0x0381000100d50502"] = { + name = "Rodney" + }, + ["0x03820001016b0502"] = { + name = "Soleil" + }, + ["0x03830001009b0502"] = { + name = "Clay" + }, + ["0x0384000100860502"] = { + name = "Flurry" + }, + ["0x0385000101060502"] = { + name = "Hamphrey" + }, + ["0x0390000101850502"] = { + name = "Rocco" + }, + ["0x0392000101270502"] = { + name = "Bubbles" + }, + ["0x0393000100a00502"] = { + name = "Bertha" + }, + ["0x0394000100890502"] = { + name = "Biff" + }, + ["0x0395000102fc0502"] = { + name = "Bitty" + }, + ["0x0398000100bf0502"] = { + name = "Harry" + }, + ["0x0399000101c20502"] = { + name = "Hippeux" + }, + ["0x03a40001014f0502"] = { + name = "Buck" + }, + ["0x03a50001015b0502"] = { + name = "Victoria" + }, + ["0x03a6000100c80502"] = { + name = "Savannah" + }, + ["0x03a7000101a10502"] = { + name = "Elmer" + }, + ["0x03a8000100910502"] = { + name = "Rosco" + }, + ["0x03a9000100710502"] = { + name = "Winnie" + }, + ["0x03aa000100e60502"] = { + name = "Ed" + }, + ["0x03ab000103160502"] = { + name = "Cleo" + }, + ["0x03ac000101880502"] = { + name = "Peaches" + }, + ["0x03ad000101b20502"] = { + name = "Annalise" + }, + ["0x03ae000100870502"] = { + name = "Clyde" + }, + ["0x03af0001012c0502"] = { + name = "Colton" + }, + ["0x03b0000101a90502"] = { + name = "Papi" + }, + ["0x03b1000100f00502"] = { + name = "Julian" + }, + ["0x03bc0001008a0502"] = { + name = "Yuka" + }, + ["0x03bd000100f90502"] = { + name = "Alice" + }, + ["0x03be000101980502"] = { + name = "Melba" + }, + ["0x03bf000101bc0502"] = { + name = "Sydney" + }, + ["0x03c0000103100502"] = { + name = "Gonzo" + }, + ["0x03c1000100bb0502"] = { + name = "Ozzie" + }, + ["0x03c40001012b0502"] = { + name = "Canberra" + }, + ["0x03c50001015c0502"] = { + name = "Lyman" + }, + ["0x03c6000100930502"] = { + name = "Eugene" + }, + ["0x03d1000100c20502"] = { + name = "Kitt" + }, + ["0x03d2000100e50502"] = { + name = "Mathilda" + }, + ["0x03d3000102f30502"] = { + name = "Carrie" + }, + ["0x03d6000101570502"] = { + name = "Astrid" + }, + ["0x03d7000101b40502"] = { + name = "Sylvia" + }, + ["0x03d9000101a50502"] = { + name = "Walt" + }, + ["0x03da000101510502"] = { + name = "Rooney" + }, + ["0x03db0001006d0502"] = { + name = "Marcie" + }, + ["0x03e6000100ec0502"] = { + name = "Bud" + }, + ["0x03e70001012a0502"] = { + name = "Elvis" + }, + ["0x03e8000102f50502"] = { + name = "Rex" + }, + ["0x03ea0001030b0502"] = { + name = "Leopold" + }, + ["0x03ec000101830502"] = { + name = "Mott" + }, + ["0x03ed000101a30502"] = { + name = "Rory" + }, + ["0x03ee0001008b0502"] = { + name = "Lionel" + }, + ["0x03fa000100d00502"] = { + name = "Nana" + }, + ["0x03fb000101cf0502"] = { + name = "Simon" + }, + ["0x03fc000101470502"] = { + name = "Tammi" + }, + ["0x03fd000101580502"] = { + name = "Monty" + }, + ["0x03fe000101a40502"] = { + name = "Elise" + }, + ["0x03ff000100f40502"] = { + name = "Flip" + }, + ["0x04000001006f0502"] = { + name = "Shari" + }, + ["0x0401000100660502"] = { + name = "Deli" + }, + ["0x040c000101590502"] = { + name = "Dora" + }, + ["0x040d000100780502"] = { + name = "Limberg" + }, + ["0x040e000100880502"] = { + name = "Bella" + }, + ["0x040f000101500502"] = { + name = "Bree" + }, + ["0x04100001007f0502"] = { + name = "Samson" + }, + ["0x0411000101ab0502"] = { + name = "Rod" + }, + ["0x04140001030a0502"] = { + name = "Candi" + }, + ["0x0415000101bb0502"] = { + name = "Rizzo" + }, + ["0x0416000100fb0502"] = { + name = "Anicotti" + }, + ["0x0418000100d80502"] = { + name = "Broccolo" + }, + ["0x041a000100e00502"] = { + name = "Moose" + }, + ["0x041b000100f10502"] = { + name = "Bettina" + }, + ["0x041c000101410502"] = { + name = "Greta" + }, + ["0x041d0001018a0502"] = { + name = "Penelope" + }, + ["0x041e0001015f0502"] = { + name = "Chadder" + }, + ["0x0429000100700502"] = { + name = "Octavian" + }, + ["0x042a0001012d0502"] = { + name = "Marina" + }, + ["0x042b000101af0502"] = { + name = "Zucker" + }, + ["0x0436000101940502"] = { + name = "Queenie" + }, + ["0x0437000101050502"] = { + name = "Gladys" + }, + ["0x0438000103000502"] = { + name = "Sandy" + }, + ["0x0439000103110502"] = { + name = "Sprocket" + }, + ["0x043b000103030502"] = { + name = "Julia" + }, + ["0x043c000101cb0502"] = { + name = "Cranston" + }, + ["0x043d0001007c0502"] = { + name = "Phil" + }, + ["0x043e000101490502"] = { + name = "Blanche" + }, + ["0x043f000101550502"] = { + name = "Flora" + }, + ["0x0440000100ca0502"] = { + name = "Phoebe" + }, + ["0x044b0001016c0502"] = { + name = "Apollo" + }, + ["0x044c0001008e0502"] = { + name = "Amelia" + }, + ["0x044d000101930502"] = { + name = "Pierce" + }, + ["0x044e000103150502"] = { + name = "Buzz" + }, + ["0x0450000100cf0502"] = { + name = "Avery" + }, + ["0x04510001015e0502"] = { + name = "Frank" + }, + ["0x0452000100730502"] = { + name = "Sterling" + }, + ["0x0453000101040502"] = { + name = "Keaton" + }, + ["0x0454000101ae0502"] = { + name = "Celia" + }, + ["0x045f000101a80502"] = { + name = "Aurora" + }, + ["0x0460000100a50502"] = { + name = "Roald" + }, + ["0x0461000101610502"] = { + name = "Cube" + }, + ["0x0462000100f60502"] = { + name = "Hopper" + }, + ["0x0463000101310502"] = { + name = "Friga" + }, + ["0x0464000100c00502"] = { + name = "Gwen" + }, + ["0x04650001006e0502"] = { + name = "Puck" + }, + ["0x0468000102f20502"] = { + name = "Wade" + }, + ["0x0469000101640502"] = { + name = "Boomer" + }, + ["0x046a000101d00502"] = { + name = "Iggly" + }, + ["0x046b000101970502"] = { + name = "Tex" + }, + ["0x046c0001008c0502"] = { + name = "Flo" + }, + ["0x046d000100f30502"] = { + name = "Sprinkle" + }, + ["0x0478000101630502"] = { + name = "Curly" + }, + ["0x0479000100920502"] = { + name = "Truffles" + }, + ["0x047a000100600502"] = { + name = "Rasher" + }, + ["0x047b000100f50502"] = { + name = "Hugh" + }, + ["0x047c000101a00502"] = { + name = "Lucy" + }, + ["0x047d0001012e0502"] = { + name = "Spork/Crackle" + }, + ["0x04800001008d0502"] = { + name = "Cobb" + }, + ["0x0481000102f10502"] = { + name = "Boris" + }, + ["0x0482000102fd0502"] = { + name = "Maggie" + }, + ["0x0483000101b00502"] = { + name = "Peggy" + }, + ["0x04850001014c0502"] = { + name = "Gala" + }, + ["0x0486000100fc0502"] = { + name = "Chops" + }, + ["0x0487000101bf0502"] = { + name = "Kevin" + }, + ["0x0488000100980502"] = { + name = "Pancetti" + }, + ["0x0489000100ef0502"] = { + name = "Agnes" + }, + ["0x04940001009a0502"] = { + name = "Bunnie" + }, + ["0x0495000101920502"] = { + name = "Dotty" + }, + ["0x0496000100d90502"] = { + name = "Coco" + }, + ["0x04970001007a0502"] = { + name = "Snake" + }, + ["0x04980001014a0502"] = { + name = "Gaston" + }, + ["0x0499000100df0502"] = { + name = "Gabi" + }, + ["0x049a0001014e0502"] = { + name = "Pippy" + }, + ["0x049b000100610502"] = { + name = "Tiffany" + }, + ["0x049c000101400502"] = { + name = "Genji" + }, + ["0x049d000100ed0502"] = { + name = "Ruby" + }, + ["0x049e000101b70502"] = { + name = "Doc" + }, + ["0x049f000103010502"] = { + name = "Claude" + }, + ["0x04a00001016e0502"] = { + name = "Francine" + }, + ["0x04a10001016f0502"] = { + name = "Chrissy" + }, + ["0x04a2000102e80502"] = { + name = "Hopkins" + }, + ["0x04a3000101c90502"] = { + name = "OHare" + }, + ["0x04a4000100d40502"] = { + name = "Carmen" + }, + ["0x04a5000100740502"] = { + name = "Bonbon" + }, + ["0x04a6000100a30502"] = { + name = "Cole" + }, + ["0x04a7000101a60502"] = { + name = "Mira" + }, + ["0x04a80101031e0502"] = { + name = "Toby" + }, + ["0x04b2000101b90502"] = { + name = "Tank" + }, + ["0x04b3000100dd0502"] = { + name = "Rhonda" + }, + ["0x04b40001030c0502"] = { + name = "Spike" + }, + ["0x04b6000102ec0502"] = { + name = "Hornsby" + }, + ["0x04b9000101600502"] = { + name = "Merengue" + }, + ["0x04ba0001005d0502"] = { + name = "Renée" + }, + ["0x04c5000101010502"] = { + name = "Vesta" + }, + ["0x04c6000101670502"] = { + name = "Baabara" + }, + ["0x04c7000100940502"] = { + name = "Eunice" + }, + ["0x04c8000102ed0502"] = { + name = "Stella" + }, + ["0x04c90001030d0502"] = { + name = "Cashmere" + }, + ["0x04cc000100a40502"] = { + name = "Willow" + }, + ["0x04cd000101520502"] = { + name = "Curlos" + }, + ["0x04ce000100db0502"] = { + name = "Wendy" + }, + ["0x04cf000100e10502"] = { + name = "Timbra" + }, + ["0x04d0000101960502"] = { + name = "Frita" + }, + ["0x04d10001009e0502"] = { + name = "Muffy" + }, + ["0x04d2000101a70502"] = { + name = "Pietro" + }, + ["0x04d30101031b0502"] = { + name = "Étoile" + }, + ["0x04dd000100a20502"] = { + name = "Peanut" + }, + ["0x04de000100ce0502"] = { + name = "Blaire" + }, + ["0x04df000100e80502"] = { + name = "Filbert" + }, + ["0x04e0000100f70502"] = { + name = "Pecan" + }, + ["0x04e1000101be0502"] = { + name = "Nibbles" + }, + ["0x04e2000101090502"] = { + name = "Agent S" + }, + ["0x04e3000101650502"] = { + name = "Caroline" + }, + ["0x04e4000101b60502"] = { + name = "Sally" + }, + ["0x04e5000101ad0502"] = { + name = "Static" + }, + ["0x04e6000100820502"] = { + name = "Mint" + }, + ["0x04e7000101320502"] = { + name = "Ricky" + }, + ["0x04e8000101ce0502"] = { + name = "Cally" + }, + ["0x04ea000103180502"] = { + name = "Tasha" + }, + ["0x04eb000102f00502"] = { + name = "Sylvana" + }, + ["0x04ec000100770502"] = { + name = "Poppy" + }, + ["0x04ed000100620502"] = { + name = "Sheldon" + }, + ["0x04ee0001014b0502"] = { + name = "Marshal" + }, + ["0x04ef0001013b0502"] = { + name = "Hazel" + }, + ["0x04fa000101680502"] = { + name = "Rolf" + }, + ["0x04fb000101c60502"] = { + name = "Rowan" + }, + ["0x04fc000102ee0502"] = { + name = "Tybalt" + }, + ["0x04fd0001007b0502"] = { + name = "Bangle" + }, + ["0x04fe000100590502"] = { + name = "Leonardo" + }, + ["0x04ff000101620502"] = { + name = "Claudia" + }, + ["0x0500000100e70502"] = { + name = "Bianca" + }, + ["0x050b000100990502"] = { + name = "Chief" + }, + ["0x050c000101c10502"] = { + name = "Lobo" + }, + ["0x050d000101420502"] = { + name = "Wolfgang" + }, + ["0x050e000100d70502"] = { + name = "Whitney" + }, + ["0x050f000103140502"] = { + name = "Dobie" + }, + ["0x0510000101070502"] = { + name = "Freya" + }, + ["0x0511000101950502"] = { + name = "Fang" + }, + ["0x0513000102e70502"] = { + name = "Vivian" + }, + ["0x0514000101530502"] = { + name = "Skye" + }, + ["0x05150001005b0502"] = { + name = "Kyle" + }, + ["0x0580000000050002"] = { + name = "Fox" + }, + ["0x05810000001c0002"] = { + name = "Falco" + }, + ["0x05840000037e0002"] = { + name = "Wolf" + }, + ["0x05c0000000060002"] = { + name = "Samus" + }, + ["0x05c0000003651302"] = { + name = "Samus Aran" + }, + ["0x05c0000004121302"] = { + name = "Samus - Metroid Dread" + }, + ["0x05c00100001d0002"] = { + name = "Zero Suit Samus" + }, + ["0x05c1000003661302"] = { + name = "Metroid" + }, + ["0x05c20000037f0002"] = { + name = "Ridley" + }, + ["0x05c3000003800002"] = { + name = "Dark Samus" + }, + ["0x05c4000004131302"] = { + name = "E.M.M.I." + }, + ["0x0600000000120002"] = { + name = "Captain Falcon" + }, + ["0x06400100001e0002"] = { + name = "Olimar" + }, + ["0x06420000035f1102"] = { + name = "Pikmin" + }, + ["0x06c00000000f0002"] = { + name = "Little Mac" + }, + ["0x0700000000070002"] = { + name = "Wii Fit Trainer" + }, + ["0x0740000000100002"] = { + name = "Pit" + }, + ["0x0741000000200002"] = { + name = "Dark Pit" + }, + ["0x07420000001f0002"] = { + name = "Palutena" + }, + ["0x07800000002d0002"] = { + name = "Mr. Game & Watch" + }, + ["0x07810000002e0002"] = { + name = "R.O.B. - Famicom" + }, + ["0x0781000000330002"] = { + name = "R.O.B. - NES" + }, + ["0x07820000002f0002"] = { + name = "Duck Hunt" + }, + ["0x078f000003810002"] = { + name = "Ice Climbers" + }, + ["0x07c0000000210002"] = { + name = "Mii Brawler" + }, + ["0x07c0010000220002"] = { + name = "Mii Swordfighter" + }, + ["0x07c0020000230002"] = { + name = "Mii Gunner" + }, + ["0x08000100003e0402"] = { + name = "Inkling Girl" + }, + ["0x08000100025f0402"] = { + name = "Inkling Girl - Lime Green" + }, + ["0x0800010003690402"] = { + name = "Inkling Girl - Neon Pink" + }, + ["0x0800010003820002"] = { + name = "Inkling" + }, + ["0x08000200003f0402"] = { + name = "Inkling Boy" + }, + ["0x0800020002600402"] = { + name = "Inkling Boy - Purple" + }, + ["0x08000200036a0402"] = { + name = "Inkling Boy - Neon Green" + }, + ["0x0800030000400402"] = { + name = "Inkling Squid" + }, + ["0x0800030002610402"] = { + name = "Inkling Squid - Orange" + }, + ["0x08000300036b0402"] = { + name = "Inkling Squid - Neon Purple" + }, + ["0x08010000025d0402"] = { + name = "Callie" + }, + ["0x08020000025e0402"] = { + name = "Marie" + }, + ["0x0803000003760402"] = { + name = "Pearl" + }, + ["0x0804000003770402"] = { + name = "Marina" + }, + ["0x08050100038e0402"] = { + name = "Octoling Girl" + }, + ["0x08050200038f0402"] = { + name = "Octoling Boy" + }, + ["0x0805030003900402"] = { + name = "Octoling Octopus" + }, + ["0x09c0010102690e02"] = { + name = "Mario - Soccer" + }, + ["0x09c00201026a0e02"] = { + name = "Mario - Baseball" + }, + ["0x09c00301026b0e02"] = { + name = "Mario - Tennis" + }, + ["0x09c00401026c0e02"] = { + name = "Mario - Golf" + }, + ["0x09c00501026d0e02"] = { + name = "Mario - Horse Racing" + }, + ["0x09c10101026e0e02"] = { + name = "Luigi - Soccer" + }, + ["0x09c10201026f0e02"] = { + name = "Luigi - Baseball" + }, + ["0x09c1030102700e02"] = { + name = "Luigi - Tennis" + }, + ["0x09c1040102710e02"] = { + name = "Luigi - Golf" + }, + ["0x09c1050102720e02"] = { + name = "Luigi - Horse Racing" + }, + ["0x09c2010102730e02"] = { + name = "Peach - Soccer" + }, + ["0x09c2020102740e02"] = { + name = "Peach - Baseball" + }, + ["0x09c2030102750e02"] = { + name = "Peach - Tennis" + }, + ["0x09c2040102760e02"] = { + name = "Peach - Golf" + }, + ["0x09c2050102770e02"] = { + name = "Peach - Horse Racing" + }, + ["0x09c3010102780e02"] = { + name = "Daisy - Soccer" + }, + ["0x09c3020102790e02"] = { + name = "Daisy - Baseball" + }, + ["0x09c30301027a0e02"] = { + name = "Daisy - Tennis" + }, + ["0x09c30401027b0e02"] = { + name = "Daisy - Golf" + }, + ["0x09c30501027c0e02"] = { + name = "Daisy - Horse Racing" + }, + ["0x09c40101027d0e02"] = { + name = "Yoshi - Soccer" + }, + ["0x09c40201027e0e02"] = { + name = "Yoshi - Baseball" + }, + ["0x09c40301027f0e02"] = { + name = "Yoshi - Tennis" + }, + ["0x09c4040102800e02"] = { + name = "Yoshi - Golf" + }, + ["0x09c4050102810e02"] = { + name = "Yoshi - Horse Racing" + }, + ["0x09c5010102820e02"] = { + name = "Wario - Soccer" + }, + ["0x09c5020102830e02"] = { + name = "Wario - Baseball" + }, + ["0x09c5030102840e02"] = { + name = "Wario - Tennis" + }, + ["0x09c5040102850e02"] = { + name = "Wario - Golf" + }, + ["0x09c5050102860e02"] = { + name = "Wario - Horse Racing" + }, + ["0x09c6010102870e02"] = { + name = "Waluigi - Soccer" + }, + ["0x09c6020102880e02"] = { + name = "Waluigi - Baseball" + }, + ["0x09c6030102890e02"] = { + name = "Waluigi - Tennis" + }, + ["0x09c60401028a0e02"] = { + name = "Waluigi - Golf" + }, + ["0x09c60501028b0e02"] = { + name = "Waluigi - Horse Racing" + }, + ["0x09c70101028c0e02"] = { + name = "Donkey Kong - Soccer" + }, + ["0x09c70201028d0e02"] = { + name = "Donkey Kong - Baseball" + }, + ["0x09c70301028e0e02"] = { + name = "Donkey Kong - Tennis" + }, + ["0x09c70401028f0e02"] = { + name = "Donkey Kong - Golf" + }, + ["0x09c7050102900e02"] = { + name = "Donkey Kong - Horse Racing" + }, + ["0x09c8010102910e02"] = { + name = "Diddy Kong - Soccer" + }, + ["0x09c8020102920e02"] = { + name = "Diddy Kong - Baseball" + }, + ["0x09c8030102930e02"] = { + name = "Diddy Kong - Tennis" + }, + ["0x09c8040102940e02"] = { + name = "Diddy Kong - Golf" + }, + ["0x09c8050102950e02"] = { + name = "Diddy Kong - Horse Racing" + }, + ["0x09c9010102960e02"] = { + name = "Bowser - Soccer" + }, + ["0x09c9020102970e02"] = { + name = "Bowser - Baseball" + }, + ["0x09c9030102980e02"] = { + name = "Bowser - Tennis" + }, + ["0x09c9040102990e02"] = { + name = "Bowser - Golf" + }, + ["0x09c90501029a0e02"] = { + name = "Bowser - Horse Racing" + }, + ["0x09ca0101029b0e02"] = { + name = "Bowser Jr. - Soccer" + }, + ["0x09ca0201029c0e02"] = { + name = "Bowser Jr. - Baseball" + }, + ["0x09ca0301029d0e02"] = { + name = "Bowser Jr. - Tennis" + }, + ["0x09ca0401029e0e02"] = { + name = "Bowser Jr. - Golf" + }, + ["0x09ca0501029f0e02"] = { + name = "Bowser Jr. - Horse Racing" + }, + ["0x09cb010102a00e02"] = { + name = "Boo - Soccer" + }, + ["0x09cb020102a10e02"] = { + name = "Boo - Baseball" + }, + ["0x09cb030102a20e02"] = { + name = "Boo - Tennis" + }, + ["0x09cb040102a30e02"] = { + name = "Boo - Golf" + }, + ["0x09cb050102a40e02"] = { + name = "Boo - Horse Racing" + }, + ["0x09cc010102a50e02"] = { + name = "Baby Mario - Soccer" + }, + ["0x09cc020102a60e02"] = { + name = "Baby Mario - Baseball" + }, + ["0x09cc030102a70e02"] = { + name = "Baby Mario - Tennis" + }, + ["0x09cc040102a80e02"] = { + name = "Baby Mario - Golf" + }, + ["0x09cc050102a90e02"] = { + name = "Baby Mario - Horse Racing" + }, + ["0x09cd010102aa0e02"] = { + name = "Baby Luigi - Soccer" + }, + ["0x09cd020102ab0e02"] = { + name = "Baby Luigi - Baseball" + }, + ["0x09cd030102ac0e02"] = { + name = "Baby Luigi - Tennis" + }, + ["0x09cd040102ad0e02"] = { + name = "Baby Luigi - Golf" + }, + ["0x09cd050102ae0e02"] = { + name = "Baby Luigi - Horse Racing" + }, + ["0x09ce010102af0e02"] = { + name = "Birdo - Soccer" + }, + ["0x09ce020102b00e02"] = { + name = "Birdo - Baseball" + }, + ["0x09ce030102b10e02"] = { + name = "Birdo - Tennis" + }, + ["0x09ce040102b20e02"] = { + name = "Birdo - Golf" + }, + ["0x09ce050102b30e02"] = { + name = "Birdo - Horse Racing" + }, + ["0x09cf010102b40e02"] = { + name = "Rosalina - Soccer" + }, + ["0x09cf020102b50e02"] = { + name = "Rosalina - Baseball" + }, + ["0x09cf030102b60e02"] = { + name = "Rosalina - Tennis" + }, + ["0x09cf040102b70e02"] = { + name = "Rosalina - Golf" + }, + ["0x09cf050102b80e02"] = { + name = "Rosalina - Horse Racing" + }, + ["0x09d0010102b90e02"] = { + name = "Metal Mario - Soccer" + }, + ["0x09d0020102ba0e02"] = { + name = "Metal Mario - Baseball" + }, + ["0x09d0030102bb0e02"] = { + name = "Metal Mario - Tennis" + }, + ["0x09d0040102bc0e02"] = { + name = "Metal Mario - Golf" + }, + ["0x09d0050102bd0e02"] = { + name = "Metal Mario - Horse Racing" + }, + ["0x09d1010102be0e02"] = { + name = "Pink Gold Peach - Soccer" + }, + ["0x09d1020102bf0e02"] = { + name = "Pink Gold Peach - Baseball" + }, + ["0x09d1030102c00e02"] = { + name = "Pink Gold Peach - Tennis" + }, + ["0x09d1040102c10e02"] = { + name = "Pink Gold Peach - Golf" + }, + ["0x09d1050102c20e02"] = { + name = "Pink Gold Peach - Horse Racing" + }, + ["0x0a00000103ab0502"] = { + name = "Orville" + }, + ["0x0a01000103ac0502"] = { + name = "Wilbur" + }, + ["0x0a02000103b30502"] = { + name = "C.J." + }, + ["0x0a03000103b40502"] = { + name = "Flick" + }, + ["0x0a04000103b50502"] = { + name = "Daisy Mae" + }, + ["0x0a05000103b80502"] = { + name = "Harvey" + }, + ["0x0a06000103ba0502"] = { + name = "Wisp" + }, + ["0x0a07000103bc0502"] = { + name = "Niko" + }, + ["0x0a08000103bd0502"] = { + name = "Wardell" + }, + ["0x0a09000103c00502"] = { + name = "Sherb" + }, + ["0x0a0a000103c10502"] = { + name = "Megan" + }, + ["0x0a0b000103c20502"] = { + name = "Dom" + }, + ["0x0a0c000103c30502"] = { + name = "Audie" + }, + ["0x0a0d000103c40502"] = { + name = "Cyd" + }, + ["0x0a0e000103c50502"] = { + name = "Judy" + }, + ["0x0a0f000103c60502"] = { + name = "Raymond" + }, + ["0x0a10000103c70502"] = { + name = "Reneigh" + }, + ["0x0a11000103c80502"] = { + name = "Sasha" + }, + ["0x0a12000103c90502"] = { + name = "Ione" + }, + ["0x0a13000103ca0502"] = { + name = "Tiansheng" + }, + ["0x0a14000103cb0502"] = { + name = "Shino" + }, + ["0x0a15000103cc0502"] = { + name = "Marlo" + }, + ["0x0a16000103cd0502"] = { + name = "Petri" + }, + ["0x0a17000103ce0502"] = { + name = "Cephalobot" + }, + ["0x0a18000103cf0502"] = { + name = "Quinn" + }, + ["0x0a19000103d00502"] = { + name = "Chabwick" + }, + ["0x0a1a000103d10502"] = { + name = "Zoe" + }, + ["0x0a1b000103d20502"] = { + name = "Ace" + }, + ["0x0a1c000103d30502"] = { + name = "Rio" + }, + ["0x0a1d000103d40502"] = { + name = "Frett" + }, + ["0x0a1e000103d50502"] = { + name = "Azalea" + }, + ["0x0a1f000103d60502"] = { + name = "Roswell" + }, + ["0x0a20000103d70502"] = { + name = "Faith" + }, + ["0x0a400000041d0002"] = { + name = "Min Min" + }, + ["0x1902000003830002"] = { + name = "Ivysaur" + }, + ["0x1906000000240002"] = { + name = "Charizard" + }, + ["0x1907000003840002"] = { + name = "Squirtle" + }, + ["0x1919000000090002"] = { + name = "Pikachu" + }, + ["0x1927000000260002"] = { + name = "Jigglypuff" + }, + ["0x19960000023d0002"] = { + name = "Mewtwo" + }, + ["0x19ac000003850002"] = { + name = "Pichu" + }, + ["0x1ac0000000110002"] = { + name = "Lucario" + }, + ["0x1b92000000250002"] = { + name = "Greninja" + }, + ["0x1bd7000003860002"] = { + name = "Incineroar" + }, + ["0x1d000001025c0d02"] = { + name = "Shadow Mewtwo" + }, + ["0x1d01000003750d02"] = { + name = "Detective Pikachu" + }, + ["0x1d40000003870002"] = { + name = "Pokemon Trainer" + }, + ["0x1f000000000a0002"] = { + name = "Kirby" + }, + ["0x1f00000002540c02"] = { + name = "Kirby" + }, + ["0x1f01000000270002"] = { + name = "Meta Knight" + }, + ["0x1f01000002550c02"] = { + name = "Meta Knight" + }, + ["0x1f02000000280002"] = { + name = "King Dedede" + }, + ["0x1f02000002560c02"] = { + name = "King Dedede" + }, + ["0x1f03000002570c02"] = { + name = "Waddle Dee" + }, + ["0x1f400000035e1002"] = { + name = "Qbby" + }, + ["0x21000000000b0002"] = { + name = "Marth" + }, + ["0x2101000000180002"] = { + name = "Ike" + }, + ["0x2102000000290002"] = { + name = "Lucina" + }, + ["0x21030000002a0002"] = { + name = "Robin" + }, + ["0x2104000002520002"] = { + name = "Roy" + }, + ["0x21050000025a0002"] = { + name = "Corrin" + }, + ["0x2105010003630002"] = { + name = "Corrin - Player 2" + }, + ["0x2106000003601202"] = { + name = "Alm" + }, + ["0x2107000003611202"] = { + name = "Celica" + }, + ["0x21080000036f1202"] = { + name = "Chrom" + }, + ["0x2108000003880002"] = { + name = "Chrom" + }, + ["0x2109000003701202"] = { + name = "Tiki" + }, + ["0x210b000003a50002"] = { + name = "Byleth" + }, + ["0x22400000002b0002"] = { + name = "Shulk" + }, + ["0x22800000002c0002"] = { + name = "Ness" + }, + ["0x2281000002510002"] = { + name = "Lucas" + }, + ["0x22c00000003a0202"] = { + name = "Chibi Robo" + }, + ["0x3200000000300002"] = { + name = "Sonic" + }, + ["0x32400000025b0002"] = { + name = "Bayonetta" + }, + ["0x3240010003640002"] = { + name = "Bayonetta - Player 2" + }, + ["0x3340000000320002"] = { + name = "Pac-Man" + }, + ["0x3380000003781402"] = { + name = "Solaire of Astora" + }, + ["0x3480000000310002"] = { + name = "Mega Man" + }, + ["0x3480000002580002"] = { + name = "Mega Man - Gold Edition" + }, + ["0x3480000003791502"] = { + name = "Mega Man" + }, + ["0x34c0000002530002"] = { + name = "Ryu" + }, + ["0x34c1000003890002"] = { + name = "Ken" + }, + ["0x3500010002e10f02"] = { + name = "One-Eyed Rathalos and Rider - Male" + }, + ["0x3500020002e20f02"] = { + name = "One-Eyed Rathalos and Rider - Female" + }, + ["0x3501000002e30f02"] = { + name = "Nabiru" + }, + ["0x3502010002e40f02"] = { + name = "Rathian and Cheval" + }, + ["0x3503010002e50f02"] = { + name = "Barioth and Ayuria" + }, + ["0x3504010002e60f02"] = { + name = "Qurupeco and Dan" + }, + ["0x35050000040c0f02"] = { + name = "Razewing Ratha" + }, + ["0x35060000040d0f02"] = { + name = "Ena" + }, + ["0x35070000040e0f02"] = { + name = "Tsukino" + }, + ["0x35080000040f1802"] = { + name = "Magnamalo" + }, + ["0x3509000004101802"] = { + name = "Palico" + }, + ["0x35090100042b1802"] = { + name = "Palico" + }, + ["0x350a000004111802"] = { + name = "Palamute" + }, + ["0x350a0100042c1802"] = { + name = "Palamute" + }, + ["0x350b0000042d1802"] = { + name = "Malzeno" + }, + ["0x35c0000002500a02"] = { + name = "Shovel Knight" + }, + ["0x35c0000003920a02"] = { + name = "Shovel Knight - Gold Edition" + }, + ["0x35c10000036c0a02"] = { + name = "Plague Knight" + }, + ["0x35c20000036d0a02"] = { + name = "Specter Knight" + }, + ["0x35c30000036e0a02"] = { + name = "King Knight" + }, + ["0x3600000002590002"] = { + name = "Cloud" + }, + ["0x3600010003620002"] = { + name = "Cloud - Player 2" + }, + ["0x3640000003a20002"] = { + name = "Hero" + }, + ["0x3740000103741402"] = { + name = "Super Mario Cereal" + }, + ["0x37800000038a0002"] = { + name = "Snake" + }, + ["0x37c00000038b0002"] = { + name = "Simon" + }, + ["0x37c10000038c0002"] = { + name = "Richter" + }, + ["0x3800000103931702"] = { + name = "Pawapuro" + }, + ["0x3801000103941702"] = { + name = "Ikari" + }, + ["0x3802000103951702"] = { + name = "Daijobu" + }, + ["0x3803000103961702"] = { + name = "Hayakawa" + }, + ["0x3804000103971702"] = { + name = "Yabe" + }, + ["0x3805000103981702"] = { + name = "Ganda" + }, + ["0x3840000104241902"] = { + name = "Yuga Ohdo" + }, + ["0x3841000104251902"] = { + name = "Tatsuhisa “Luke” Kamijō" + }, + ["0x3842000104261902"] = { + name = "Gakuto Sōgetsu" + }, + ["0x3843000104271902"] = { + name = "Romin Kirishima" + }, + ["0x3844000104281902"] = { + name = "Roa Kirishima" + }, + ["0x3845000104291902"] = { + name = "Nail Saionji" + }, + ["0x38460001042a1902"] = { + name = "Asana Mutsuba" + }, + ["0x38c0000003911602"] = { + name = "Loot Goblin" + }, + ["0x3a00000003a10002"] = { + name = "Joker" + }, + ["0x3b40000003a30002"] = { + name = "Banjo & Kazooie" + }, + ["0x3c80000003a40002"] = { + name = "Terry" + } + }, + game_series = { + ["0x000"] = "Super Mario", + ["0x001"] = "Super Mario", + ["0x002"] = "Super Mario", + ["0x008"] = "Yoshi's Woolly World", + ["0x00c"] = "Donkey Kong", + ["0x010"] = "The Legend of Zelda", + ["0x014"] = "Breath of the Wild", + ["0x018"] = "Animal Crossing", + ["0x019"] = "Animal Crossing", + ["0x01a"] = "Animal Crossing", + ["0x01b"] = "Animal Crossing", + ["0x01c"] = "Animal Crossing", + ["0x020"] = "Animal Crossing", + ["0x021"] = "Animal Crossing", + ["0x022"] = "Animal Crossing", + ["0x023"] = "Animal Crossing", + ["0x024"] = "Animal Crossing", + ["0x025"] = "Animal Crossing", + ["0x026"] = "Animal Crossing", + ["0x027"] = "Animal Crossing", + ["0x028"] = "Animal Crossing", + ["0x029"] = "Animal Crossing", + ["0x02a"] = "Animal Crossing", + ["0x02b"] = "Animal Crossing", + ["0x02c"] = "Animal Crossing", + ["0x02d"] = "Animal Crossing", + ["0x02e"] = "Animal Crossing", + ["0x02f"] = "Animal Crossing", + ["0x030"] = "Animal Crossing", + ["0x031"] = "Animal Crossing", + ["0x032"] = "Animal Crossing", + ["0x033"] = "Animal Crossing", + ["0x034"] = "Animal Crossing", + ["0x035"] = "Animal Crossing", + ["0x036"] = "Animal Crossing", + ["0x037"] = "Animal Crossing", + ["0x038"] = "Animal Crossing", + ["0x039"] = "Animal Crossing", + ["0x03a"] = "Animal Crossing", + ["0x03b"] = "Animal Crossing", + ["0x03c"] = "Animal Crossing", + ["0x03d"] = "Animal Crossing", + ["0x03e"] = "Animal Crossing", + ["0x03f"] = "Animal Crossing", + ["0x040"] = "Animal Crossing", + ["0x041"] = "Animal Crossing", + ["0x042"] = "Animal Crossing", + ["0x043"] = "Animal Crossing", + ["0x044"] = "Animal Crossing", + ["0x045"] = "Animal Crossing", + ["0x046"] = "Animal Crossing", + ["0x047"] = "Animal Crossing", + ["0x048"] = "Animal Crossing", + ["0x049"] = "Animal Crossing", + ["0x04a"] = "Animal Crossing", + ["0x04b"] = "Animal Crossing", + ["0x04c"] = "Animal Crossing", + ["0x04d"] = "Animal Crossing", + ["0x04e"] = "Animal Crossing", + ["0x04f"] = "Animal Crossing", + ["0x050"] = "Animal Crossing", + ["0x051"] = "Animal Crossing", + ["0x0a0"] = "Animal Crossing", + ["0x0a1"] = "Animal Crossing", + ["0x0a2"] = "Animal Crossing", + ["0x058"] = "Star Fox", + ["0x05c"] = "Metroid", + ["0x060"] = "F-Zero", + ["0x064"] = "Pikmin", + ["0x06c"] = "Punch Out", + ["0x070"] = "Wii Fit", + ["0x074"] = "Kid Icarus", + ["0x078"] = "Classic Nintendo", + ["0x07c"] = "Mii", + ["0x080"] = "Splatoon", + ["0x09c"] = "Mario Sports Superstars", + ["0x09d"] = "Mario Sports Superstars", + ["0x0a4"] = "ARMS", + ["0x190"] = "Pokemon", + ["0x191"] = "Pokemon", + ["0x192"] = "Pokemon", + ["0x199"] = "Pokemon", + ["0x19a"] = "Pokemon", + ["0x1ac"] = "Pokemon", + ["0x1b9"] = "Pokemon", + ["0x1bd"] = "Pokemon", + ["0x1d0"] = "Pokemon", + ["0x1d4"] = "Pokemon", + ["0x1f0"] = "Kirby", + ["0x1f4"] = "BoxBoy!", + ["0x210"] = "Fire Emblem", + ["0x224"] = "Xenoblade", + ["0x228"] = "Earthbound", + ["0x22c"] = "Chibi Robo", + ["0x320"] = "Sonic", + ["0x324"] = "Bayonetta", + ["0x334"] = "Pac-man", + ["0x338"] = "Dark Souls", + ["0x348"] = "Megaman", + ["0x34c"] = "Street fighter", + ["0x350"] = "Monster Hunter", + ["0x35c"] = "Shovel Knight", + ["0x360"] = "Final Fantasy", + ["0x364"] = "Dragon Quest", + ["0x374"] = "Kellogs", + ["0x378"] = "Metal Gear Solid", + ["0x37c"] = "Castlevania", + ["0x380"] = "Power Pros", + ["0x384"] = "Yu-Gi-Oh!", + ["0x38c"] = "Diablo", + ["0x3a0"] = "Persona", + ["0x3b4"] = "Banjo Kazooie", + ["0x3c8"] = "Fatal Fury" + }, + types = { + ["0x00"] = "Figure", + ["0x01"] = "Card", + ["0x02"] = "Yarn", + ["0x03"] = "Band" + } +} + +return amiibo_tools diff --git a/client/luascripts/hf_mfu_amiibo_restore.lua b/client/luascripts/hf_mfu_amiibo_restore.lua new file mode 100644 index 000000000..5996b9fa6 --- /dev/null +++ b/client/luascripts/hf_mfu_amiibo_restore.lua @@ -0,0 +1,164 @@ +local cmds = require('commands') +local getopt = require('getopt') +local os = require('os') +local io = require('io') +local bin = require('bin') +local utils = require('utils') +local ansicolors = require('ansicolors') +local amiibo_tools = require('amiibo_tools') + +copyright = '' +author = 'George Talusan' +version = 'v0.0.1' +desc = [[ +This script will try to restore a binary datadump of an Amiibo to a blank NTAG215. +It will recalculate PWD and PACK if necessary, set the appropriate password and sector lock bytes. + +NOTE: PyAmiibo must be installed. The helper script pyscripts/amiibo_change_uid.py depends on PyAmiibo. + +YMMV if a non-blank NTAG215 is provided! +]] +example = [[ + 1. script run hf_mfu_amiibo_restore + 2. script run hf_mfu_amiibo_restore -f myfile -k password +]] +usage = [[ +script run hf_mfu_amiibo_restore [-h] [-f -k ] +]] +arguments = [[ + -h : this help + -f : filename for the datadump to read (bin) + -k : password of blank NTAG 215 (use `hf mfu info` to find it) +]] + +local DEBUG = false -- the debug flag + +local bxor = bit32.bxor +local sub = string.sub +local format = string.format + +--- +-- A debug printout-function +local function dbg(args) + if not DEBUG then return end + if type(args) == 'table' then + local i = 1 + while result[i] do + dbg(result[i]) + i = i+1 + end + else + print('###', args) + end +end +--- +-- This is only meant to be used when errors occur +local function oops(err) + print('ERROR:', err) + core.clearCommandBuffer() + return nil, err +end +--- +-- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print(ansicolors.cyan..'Usage'..ansicolors.reset) + print(usage) + print(ansicolors.cyan..'Arguments'..ansicolors.reset) + print(arguments) + print(ansicolors.cyan..'Example usage'..ansicolors.reset) + print(example) +end +-- +-- Exit message +local function ExitMsg(msg) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print(msg) + print() +end + +local function main(args) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + + local result, err, hex + local inputTemplate = 'dumpdata.bin' + local password + + for o, a in getopt.getopt(args, 'hf:k:') do + if o == 'h' then return help() end + if o == 'f' then inputTemplate = a end + if o == 'k' then password = a end + end + + print(('Loading data from %s'):format(inputTemplate)) + hex, err = utils.ReadDumpFile(inputTemplate) + if not hex then return oops(err) end + + if not password or #password ~= 8 then + return oops('Expecting 4 byte password (hint: use `hf mfu info` to get it)') + end + + -- chomp emu header + if #hex == 1192 then + hex = hex:sub(112) + end + + local amiibo_offset = 0 + local amiibo_info = hex:sub(amiibo_offset + 169, amiibo_offset + 169 + 15):lower() + local amiibo_game = amiibo_info:sub(1, 3) + local amiibo_type = amiibo_info:sub(7, 8) + local amiibo_series = amiibo_info:sub(13, 14) + + dbg('raw: '..ansicolors.green..amiibo_info..ansicolors.reset) + print('game: '..ansicolors.green..amiibo_tools.db.game_series[("0x%s"):format(amiibo_game)]..ansicolors.reset) + print('character: '..ansicolors.green..amiibo_tools.db.amiibos[("0x%s"):format(amiibo_info)].name..ansicolors.reset) + print('type: '..ansicolors.green..amiibo_tools.db.types[("0x%s"):format(amiibo_type)]..ansicolors.reset) + print('series: '..ansicolors.green..amiibo_tools.db.amiibo_series[("0x%s"):format(amiibo_series)]..ansicolors.reset) + + local uid = core.ul_read_uid(); + if uid == nil then + return oops("Can't read UID of NTAG215 card. Reposition card and try again.") + end + + local tmp = ('%s.bin'):format(os.tmpname()) + local amiibo_file = io.open(tmp, 'w+b') + amiibo_file:write(bin.pack('H', hex)) + amiibo_file:close() + local tmp2 = ('%s.bin'):format(os.tmpname()) + + print('generating new Amiibo binary for NTAG215 '..ansicolors.green..uid) + core.clearCommandBuffer() + core.console(('script run amiibo_change_uid %s %s %s %sresources/key_retail.bin'):format(uid, tmp, tmp2, core.ewd())) + + -- let's sanity check the output + hex, err = utils.ReadDumpFile(tmp2) + if not hex or #hex ~= 1080 then + os.remove(tmp) + os.remove(tmp2) + return oops('There was a problem generating the output Amiibo') + end + + core.console(('hf mfu restore -f %s -k %s'):format(tmp2, password)) + + -- re-write some blocks because `hf mfu restore` won't write out blocks 0-3, and PyAmiibo won't give a PACK/PWD + local pwd, pack = core.keygen_algo_b(uid) + core.console(('hf mfu wrbl -b 3 -d F110FFEE -k %s'):format(password)) -- CC? + core.console(('hf mfu wrbl -b 134 -d %04X0000 -k %s'):format(pack, password)) -- PACK/RFUI + core.console(('hf mfu wrbl -b 133 -d %08X -k %s'):format(pwd, password)) -- PWD + core.console(('hf mfu wrbl -b 131 -d 00000004 -k %08X'):format(pwd)) -- CFG0 + core.console(('hf mfu wrbl -b 132 -d 5F000000 -k %08X'):format(pwd)) -- CFG1 + + local lock_bytes = hex:sub(17, 24) + dbg('lock_bytes: '..lock_bytes) + core.console(('hf mfu wrbl -b 2 -d %s -k %08X'):format(lock_bytes, pwd)) -- BCC1/static lock + core.console(('hf mfu wrbl -b 130 -d 01000FBD -k %08X'):format(pwd)) -- dynamic lock/RFUI + + os.remove(tmp) + os.remove(tmp2) +end +main(args) diff --git a/client/luascripts/hf_mfu_amiibo_sim.lua b/client/luascripts/hf_mfu_amiibo_sim.lua index 99d21ea7d..058440097 100644 --- a/client/luascripts/hf_mfu_amiibo_sim.lua +++ b/client/luascripts/hf_mfu_amiibo_sim.lua @@ -3,2664 +3,21 @@ local getopt = require('getopt') local bin = require('bin') local utils = require('utils') local ansicolors = require('ansicolors') +local amiibo_tools = require('amiibo_tools') --- curl https://raw.githubusercontent.com/N3evin/AmiiboAPI/master/database/amiibo.json | jq 'del(.amiibos[].release)' | jq 'del(.characters)' | pbcopy --> transform to table -local amiiboDb = -{ - amiibo_series = { - ["0x00"] = "Super Smash Bros.", - ["0x01"] = "Super Mario Bros.", - ["0x02"] = "Chibi-Robo!", - ["0x03"] = "Yoshi's Woolly World", - ["0x04"] = "Splatoon", - ["0x05"] = "Animal Crossing", - ["0x06"] = "8-bit Mario", - ["0x07"] = "Skylanders", - ["0x09"] = "Legend Of Zelda", - ["0x0a"] = "Shovel Knight", - ["0x0c"] = "Kirby", - ["0x0d"] = "Pokemon", - ["0x0e"] = "Mario Sports Superstars", - ["0x0f"] = "Monster Hunter", - ["0x10"] = "BoxBoy!", - ["0x11"] = "Pikmin", - ["0x12"] = "Fire Emblem", - ["0x13"] = "Metroid", - ["0x14"] = "Others", - ["0x15"] = "Mega Man", - ["0x16"] = "Diablo", - ["0x17"] = "Power Pros", - ["0x18"] = "Monster Hunter Rise", - ["0x19"] = "Yu-Gi-Oh!", - ["0xff"] = "Super Nintendo World" - }, - amiibos = { - ["0x0000000000000002"] = { - name = "Mario" - }, - ["0x0000000000340102"] = { - name = "Mario" - }, - ["0x00000000003c0102"] = { - name = "Mario - Gold Edition" - }, - ["0x00000000003d0102"] = { - name = "Mario - Silver Edition" - }, - ["0x0000000002380602"] = { - name = "8-Bit Mario Classic Color" - }, - ["0x0000000002390602"] = { - name = "8-Bit Mario Modern Color" - }, - ["0x0000000003710102"] = { - name = "Mario - Wedding" - }, - ["0x00000003039bff02"] = { - name = "Mario - Power Up Band" - }, - ["0x0000010000190002"] = { - name = "Dr. Mario" - }, - ["0x0000030003a60102"] = { - name = "Mario - Cat" - }, - ["0x00010000000c0002"] = { - name = "Luigi" - }, - ["0x0001000000350102"] = { - name = "Luigi" - }, - ["0x00010003039cff02"] = { - name = "Luigi - Power Up Band" - }, - ["0x0002000000010002"] = { - name = "Peach" - }, - ["0x0002000000360102"] = { - name = "Peach" - }, - ["0x0002000003720102"] = { - name = "Peach - Wedding" - }, - ["0x00020003039dff02"] = { - name = "Peach - Power Up Band" - }, - ["0x0002010003a70102"] = { - name = "Peach - Cat" - }, - ["0x0003000000020002"] = { - name = "Yoshi" - }, - ["0x0003000000370102"] = { - name = "Yoshi" - }, - ["0x00030003039fff02"] = { - name = "Yoshi - Power Up Band" - }, - ["0x0003010200410302"] = { - name = "Green Yarn Yoshi" - }, - ["0x0003010200420302"] = { - name = "Pink Yarn Yoshi" - }, - ["0x0003010200430302"] = { - name = "Light Blue Yarn Yoshi" - }, - ["0x00030102023e0302"] = { - name = "Mega Yarn Yoshi" - }, - ["0x0004000002620102"] = { - name = "Rosalina" - }, - ["0x0004010000130002"] = { - name = "Rosalina & Luma" - }, - ["0x0005000000140002"] = { - name = "Bowser" - }, - ["0x0005000000390102"] = { - name = "Bowser" - }, - ["0x0005000003730102"] = { - name = "Bowser - Wedding" - }, - ["0x0005ff00023a0702"] = { - name = "Hammer Slam Bowser" - }, - ["0x0006000000150002"] = { - name = "Bowser Jr." - }, - ["0x00070000001a0002"] = { - name = "Wario" - }, - ["0x0007000002630102"] = { - name = "Wario" - }, - ["0x0008000000030002"] = { - name = "Donkey Kong" - }, - ["0x0008000002640102"] = { - name = "Donkey Kong" - }, - ["0x0008ff00023b0702"] = { - name = "Turbo Charge Donkey Kong" - }, - ["0x00090000000d0002"] = { - name = "Diddy Kong" - }, - ["0x0009000002650102"] = { - name = "Diddy Kong" - }, - ["0x000a000000380102"] = { - name = "Toad" - }, - ["0x000a000303a0ff02"] = { - name = "Toad - Power Up Band" - }, - ["0x0013000002660102"] = { - name = "Daisy" - }, - ["0x00130000037a0002"] = { - name = "Daisy" - }, - ["0x00130003039eff02"] = { - name = "Daisy - Power Up Band" - }, - ["0x0014000002670102"] = { - name = "Waluigi" - }, - ["0x0015000003670102"] = { - name = "Goomba" - }, - ["0x0017000002680102"] = { - name = "Boo" - }, - ["0x0023000003680102"] = { - name = "Koopa Troopa" - }, - ["0x00240000038d0002"] = { - name = "Piranha Plant" - }, - ["0x00800102035d0302"] = { - name = "Poochy" - }, - ["0x00c00000037b0002"] = { - name = "King K. Rool" - }, - ["0x0100000000040002"] = { - name = "Link" - }, - ["0x01000000034b0902"] = { - name = "Link - Ocarina of Time" - }, - ["0x01000000034c0902"] = { - name = "Link - Majora's Mask" - }, - ["0x01000000034d0902"] = { - name = "Link - Twilight Princess" - }, - ["0x01000000034e0902"] = { - name = "Link - Skyward Sword" - }, - ["0x01000000034f0902"] = { - name = "8-Bit Link" - }, - ["0x0100000003530902"] = { - name = "Link - Archer" - }, - ["0x0100000003540902"] = { - name = "Link - Rider" - }, - ["0x01000000037c0002"] = { - name = "Young Link" - }, - ["0x0100000003990902"] = { - name = "Link - Link's Awakening" - }, - ["0x0100010000160002"] = { - name = "Toon Link" - }, - ["0x0100010003500902"] = { - name = "Toon Link - The Wind Waker" - }, - ["0x01010000000e0002"] = { - name = "Zelda" - }, - ["0x0101000003520902"] = { - name = "Toon Zelda - The Wind Waker" - }, - ["0x0101000003560902"] = { - name = "Zelda" - }, - ["0x0101010000170002"] = { - name = "Sheik" - }, - ["0x0101030004140902"] = { - name = "Zelda & Loftwing" - }, - ["0x01020100001b0002"] = { - name = "Ganondorf" - }, - ["0x01030000024f0902"] = { - name = "Midna & Wolf Link" - }, - ["0x0105000003580902"] = { - name = "Daruk" - }, - ["0x0106000003590902"] = { - name = "Urbosa" - }, - ["0x01070000035a0902"] = { - name = "Mipha" - }, - ["0x01080000035b0902"] = { - name = "Revali" - }, - ["0x0140000003550902"] = { - name = "Guardian" - }, - ["0x01410000035c0902"] = { - name = "Bokoblin" - }, - ["0x0180000000080002"] = { - name = "Villager" - }, - ["0x01810000024b0502"] = { - name = "Isabelle - Summer Outfit" - }, - ["0x01810000037d0002"] = { - name = "Isabelle" - }, - ["0x0181000100440502"] = { - name = "Isabelle" - }, - ["0x0181000101d40502"] = { - name = "Isabelle - Character Parfait" - }, - ["0x01810100023f0502"] = { - name = "Isabelle - Winter Outfit" - }, - ["0x0181010100b40502"] = { - name = "Isabelle - Winter" - }, - ["0x01810201011a0502"] = { - name = "Isabelle - Kimono" - }, - ["0x0181030101700502"] = { - name = "Isabelle - Dress" - }, - ["0x0181040103aa0502"] = { - name = "Isabelle" - }, - ["0x0181050103bf0502"] = { - name = "Isabelle - Sweater" - }, - ["0x0182000002400502"] = { - name = "K. K. Slider" - }, - ["0x0182000100a80502"] = { - name = "K.K. Slider" - }, - ["0x0182000101d80502"] = { - name = "K. K. Slider - Pikopuri" - }, - ["0x0182000103b20502"] = { - name = "K.K. Slider" - }, - ["0x0182010100460502"] = { - name = "DJ KK" - }, - ["0x0183000002420502"] = { - name = "Tom Nook" - }, - ["0x0183000100450502"] = { - name = "Tom Nook" - }, - ["0x01830101010e0502"] = { - name = "Tom Nook - Jacket" - }, - ["0x0183020103a80502"] = { - name = "Tom Nook" - }, - ["0x0183030103be0502"] = { - name = "Tom Nook - Coat" - }, - ["0x01840000024d0502"] = { - name = "Timmy & Tommy" - }, - ["0x0184050103a90502"] = { - name = "Timmy & Tommy" - }, - ["0x01850001004b0502"] = { - name = "Timmy" - }, - ["0x0185020101170502"] = { - name = "Timmy - Full Apron" - }, - ["0x0185040101790502"] = { - name = "Timmy - Suit" - }, - ["0x0186010100af0502"] = { - name = "Tommy - Uniform" - }, - ["0x0186030101750502"] = { - name = "Tommy - Suit" - }, - ["0x0187000100470502"] = { - name = "Sable" - }, - ["0x0187000103b00502"] = { - name = "Sable" - }, - ["0x0188000002410502"] = { - name = "Mabel" - }, - ["0x0188000101120502"] = { - name = "Mabel" - }, - ["0x0188000103af0502"] = { - name = "Mabel" - }, - ["0x0189000100ab0502"] = { - name = "Label" - }, - ["0x0189010103b10502"] = { - name = "Label" - }, - ["0x018a000002450502"] = { - name = "Reese" - }, - ["0x018a000100a90502"] = { - name = "Reese" - }, - ["0x018b000002460502"] = { - name = "Cyrus" - }, - ["0x018b000101150502"] = { - name = "Cyrus" - }, - ["0x018c000002430502"] = { - name = "Digby" - }, - ["0x018c0001004c0502"] = { - name = "Digby" - }, - ["0x018c010101180502"] = { - name = "Digby - Raincoat" - }, - ["0x018d0000024c0502"] = { - name = "Rover" - }, - ["0x018d0001010c0502"] = { - name = "Rover" - }, - ["0x018e000002490502"] = { - name = "Resetti" - }, - ["0x018e000100490502"] = { - name = "Resetti" - }, - ["0x018e010101780502"] = { - name = "Resetti - Without Hat" - }, - ["0x018f000100b30502"] = { - name = "Don Resetti" - }, - ["0x018f010101190502"] = { - name = "Don Resetti - Without Hat" - }, - ["0x0190000101710502"] = { - name = "Brewster" - }, - ["0x01910001004e0502"] = { - name = "Harriet" - }, - ["0x0192000002470502"] = { - name = "Blathers" - }, - ["0x01920001010d0502"] = { - name = "Blathers" - }, - ["0x0192000103ad0502"] = { - name = "Blathers" - }, - ["0x0193000002480502"] = { - name = "Celeste" - }, - ["0x0193000101740502"] = { - name = "Celeste" - }, - ["0x0193000103ae0502"] = { - name = "Celeste" - }, - ["0x01940000024a0502"] = { - name = "Kicks" - }, - ["0x0194000100aa0502"] = { - name = "Kicks" - }, - ["0x0194000103b60502"] = { - name = "Kicks" - }, - ["0x0195000100b00502"] = { - name = "Porter" - }, - ["0x01960000024e0502"] = { - name = "Kapp'n" - }, - ["0x0196000100480502"] = { - name = "Kapp'n" - }, - ["0x0197000101770502"] = { - name = "Leilani" - }, - ["0x0198000100b10502"] = { - name = "Leila" - }, - ["0x0199000101160502"] = { - name = "Grams" - }, - ["0x019a000100b70502"] = { - name = "Chip" - }, - ["0x019b000100b60502"] = { - name = "Nat" - }, - ["0x019c000101730502"] = { - name = "Phineas" - }, - ["0x019d000100ac0502"] = { - name = "Copper" - }, - ["0x019e000100ad0502"] = { - name = "Booker" - }, - ["0x019f000101110502"] = { - name = "Pete" - }, - ["0x01a00001010f0502"] = { - name = "Pelly" - }, - ["0x01a1000101100502"] = { - name = "Phyllis" - }, - ["0x01a20001017d0502"] = { - name = "Gulliver" - }, - ["0x01a2000103b90502"] = { - name = "Gulliver" - }, - ["0x01a30001004a0502"] = { - name = "Joan" - }, - ["0x01a40001004d0502"] = { - name = "Pascal" - }, - ["0x01a5000101720502"] = { - name = "Katrina" - }, - ["0x01a6000100500502"] = { - name = "Saharah" - }, - ["0x01a6000103b70502"] = { - name = "Saharah" - }, - ["0x01a7000101140502"] = { - name = "Wendell" - }, - ["0x01a80001004f0502"] = { - name = "Redd" - }, - ["0x01a80101017e0502"] = { - name = "Redd - Shirt" - }, - ["0x01a9000101760502"] = { - name = "Gracie" - }, - ["0x01aa000100530502"] = { - name = "Lyle" - }, - ["0x01ab0001017c0502"] = { - name = "Pave" - }, - ["0x01ac0001017f0502"] = { - name = "Zipper" - }, - ["0x01ad000100b80502"] = { - name = "Jack" - }, - ["0x01ae0001011b0502"] = { - name = "Franklin" - }, - ["0x01af0001011c0502"] = { - name = "Jingle" - }, - ["0x01b0000100520502"] = { - name = "Tortimer" - }, - ["0x01b1000100b20502"] = { - name = "Shrunk" - }, - ["0x01b10101017b0502"] = { - name = "Shrunk - Loud Jacket" - }, - ["0x01b3000100b50502"] = { - name = "Blanca" - }, - ["0x01b4000101130502"] = { - name = "Leif" - }, - ["0x01b5000100510502"] = { - name = "Luna" - }, - ["0x01b6000100ae0502"] = { - name = "Katie" - }, - ["0x01c1000002440502"] = { - name = "Lottie" - }, - ["0x01c1000100540502"] = { - name = "Lottie" - }, - ["0x01c10101017a0502"] = { - name = "Lottie - Black Skirt And Bow" - }, - ["0x01c1020103bb0502"] = { - name = "Lottie - Island" - }, - ["0x0200000100a10502"] = { - name = "Cyrano" - }, - ["0x02010001016a0502"] = { - name = "Antonio" - }, - ["0x0202000101030502"] = { - name = "Pango" - }, - ["0x02030001019a0502"] = { - name = "Anabelle" - }, - ["0x0206000103120502"] = { - name = "Snooty" - }, - ["0x0208000100960502"] = { - name = "Annalisa" - }, - ["0x02090001019f0502"] = { - name = "Olaf" - }, - ["0x0214000100e40502"] = { - name = "Teddy" - }, - ["0x0215000101820502"] = { - name = "Pinky" - }, - ["0x0216000100570502"] = { - name = "Curt" - }, - ["0x0217000101b30502"] = { - name = "Chow" - }, - ["0x02190001007e0502"] = { - name = "Nate" - }, - ["0x021a000100da0502"] = { - name = "Groucho" - }, - ["0x021b000100800502"] = { - name = "Tutu" - }, - ["0x021c000102f70502"] = { - name = "Ursala" - }, - ["0x021d000101cd0502"] = { - name = "Grizzly" - }, - ["0x021e000101230502"] = { - name = "Paula" - }, - ["0x021f000103170502"] = { - name = "Ike" - }, - ["0x0220000100fd0502"] = { - name = "Charlise" - }, - ["0x02210001013c0502"] = { - name = "Beardo" - }, - ["0x0222000101440502"] = { - name = "Klaus" - }, - ["0x022d000100f20502"] = { - name = "Jay" - }, - ["0x022e000101d30502"] = { - name = "Robin" - }, - ["0x022f0001011e0502"] = { - name = "Anchovy" - }, - ["0x0230000101d20502"] = { - name = "Twiggy" - }, - ["0x02310001006a0502"] = { - name = "Jitters" - }, - ["0x0232000102ea0502"] = { - name = "Piper" - }, - ["0x0233000103060502"] = { - name = "Admiral" - }, - ["0x0235000100840502"] = { - name = "Midge" - }, - ["0x0238000102f80502"] = { - name = "Jacob" - }, - ["0x023c000100bd0502"] = { - name = "Lucha" - }, - ["0x023d000101b50502"] = { - name = "Jacques" - }, - ["0x023e000100d10502"] = { - name = "Peck" - }, - ["0x023f000101660502"] = { - name = "Sparro" - }, - ["0x024a000101d10502"] = { - name = "Angus" - }, - ["0x024b000101260502"] = { - name = "Rodeo" - }, - ["0x024d000102f60502"] = { - name = "Stu" - }, - ["0x024f000100810502"] = { - name = "T-Bone" - }, - ["0x0251000100c10502"] = { - name = "Coach" - }, - ["0x0252000100fe0502"] = { - name = "Vic" - }, - ["0x025d000100550502"] = { - name = "Bob" - }, - ["0x025e000101250502"] = { - name = "Mitzi" - }, - ["0x025f000101c50502"] = { - name = "Rosie" - }, - ["0x025f000101d70502"] = { - name = "Rosie - Amiibo Festival" - }, - ["0x0260000100d20502"] = { - name = "Olivia" - }, - ["0x0261000100650502"] = { - name = "Kiki" - }, - ["0x0262000101370502"] = { - name = "Tangy" - }, - ["0x0263000100750502"] = { - name = "Punchy" - }, - ["0x0264000101ac0502"] = { - name = "Purrl" - }, - ["0x0265000101540502"] = { - name = "Moe" - }, - ["0x0266000100680502"] = { - name = "Kabuki" - }, - ["0x0267000101080502"] = { - name = "Kid Cat" - }, - ["0x02680001007d0502"] = { - name = "Monique" - }, - ["0x02690001011f0502"] = { - name = "Tabby" - }, - ["0x026a000101460502"] = { - name = "Stinky" - }, - ["0x026b000100e90502"] = { - name = "Kitty" - }, - ["0x026c000100c30502"] = { - name = "Tom" - }, - ["0x026d0001013f0502"] = { - name = "Merry" - }, - ["0x026e000100ba0502"] = { - name = "Felicity" - }, - ["0x026f000101900502"] = { - name = "Lolly" - }, - ["0x0270000100ff0502"] = { - name = "Ankha" - }, - ["0x02710001019b0502"] = { - name = "Rudy" - }, - ["0x0272000101860502"] = { - name = "Katt" - }, - ["0x027d000100630502"] = { - name = "Bluebear" - }, - ["0x027e000101690502"] = { - name = "Maple" - }, - ["0x027f000100b90502"] = { - name = "Poncho" - }, - ["0x0280000100830502"] = { - name = "Pudge" - }, - ["0x0281000101200502"] = { - name = "Kody" - }, - ["0x0282000101810502"] = { - name = "Stitches" - }, - ["0x0282000101d60502"] = { - name = "Stitches - Amiibo Festival" - }, - ["0x0283000100c70502"] = { - name = "Vladimir" - }, - ["0x0284000102fe0502"] = { - name = "Murphy" - }, - ["0x0286000103130502"] = { - name = "Olive" - }, - ["0x02870001005a0502"] = { - name = "Cheri" - }, - ["0x028a000102e90502"] = { - name = "June" - }, - ["0x028b000100e30502"] = { - name = "Pekoe" - }, - ["0x028c0001013e0502"] = { - name = "Chester" - }, - ["0x028d000101bd0502"] = { - name = "Barold" - }, - ["0x028e0001019e0502"] = { - name = "Tammy" - }, - ["0x028f0101031a0502"] = { - name = "Marty" - }, - ["0x0299000100950502"] = { - name = "Goose" - }, - ["0x029a000100ee0502"] = { - name = "Benedict" - }, - ["0x029b000100cb0502"] = { - name = "Egbert" - }, - ["0x029e0001013d0502"] = { - name = "Ava" - }, - ["0x02a2000101ba0502"] = { - name = "Becky" - }, - ["0x02a3000102ff0502"] = { - name = "Plucky" - }, - ["0x02a4000100720502"] = { - name = "Knox" - }, - ["0x02a50001018c0502"] = { - name = "Broffina" - }, - ["0x02a6000101240502"] = { - name = "Ken" - }, - ["0x02b1000100690502"] = { - name = "Patty" - }, - ["0x02b2000100c40502"] = { - name = "Tipper" - }, - ["0x02b70001030f0502"] = { - name = "Norma" - }, - ["0x02b80001019c0502"] = { - name = "Naomi" - }, - ["0x02c3000100dc0502"] = { - name = "Alfonso" - }, - ["0x02c4000100670502"] = { - name = "Alli" - }, - ["0x02c5000103080502"] = { - name = "Boots" - }, - ["0x02c7000101220502"] = { - name = "Del" - }, - ["0x02c9000100cd0502"] = { - name = "Sly" - }, - ["0x02ca000101ca0502"] = { - name = "Gayle" - }, - ["0x02cb000101360502"] = { - name = "Drago" - }, - ["0x02d6000100560502"] = { - name = "Fauna" - }, - ["0x02d7000101300502"] = { - name = "Bam" - }, - ["0x02d8000100e20502"] = { - name = "Zell" - }, - ["0x02d9000101c80502"] = { - name = "Bruce" - }, - ["0x02da000101330502"] = { - name = "Deirdre" - }, - ["0x02db0001005e0502"] = { - name = "Lopez" - }, - ["0x02dc000100be0502"] = { - name = "Fuchsia" - }, - ["0x02dd000100ea0502"] = { - name = "Beau" - }, - ["0x02de0001009c0502"] = { - name = "Diana" - }, - ["0x02df000101910502"] = { - name = "Erik" - }, - ["0x02e00101031d0502"] = { - name = "Chelsea" - }, - ["0x02ea000101800502"] = { - name = "Goldie" - }, - ["0x02ea000101d50502"] = { - name = "Goldie - Amiibo Festival" - }, - ["0x02eb000100de0502"] = { - name = "Butch" - }, - ["0x02ec000101c40502"] = { - name = "Lucky" - }, - ["0x02ed0001015a0502"] = { - name = "Biskit" - }, - ["0x02ee000101990502"] = { - name = "Bones" - }, - ["0x02ef000100580502"] = { - name = "Portia" - }, - ["0x02f0000100a70502"] = { - name = "Walker" - }, - ["0x02f1000101450502"] = { - name = "Daisy" - }, - ["0x02f2000100cc0502"] = { - name = "Cookie" - }, - ["0x02f3000102f90502"] = { - name = "Maddie" - }, - ["0x02f4000103050502"] = { - name = "Bea" - }, - ["0x02f8000101380502"] = { - name = "Mac" - }, - ["0x02f9000101020502"] = { - name = "Marcel" - }, - ["0x02fa000100970502"] = { - name = "Benjamin" - }, - ["0x02fb000100900502"] = { - name = "Cherry" - }, - ["0x02fc0001018f0502"] = { - name = "Shep" - }, - ["0x0307000100640502"] = { - name = "Bill" - }, - ["0x03080001014d0502"] = { - name = "Joey" - }, - ["0x0309000100c60502"] = { - name = "Pate" - }, - ["0x030a000101c70502"] = { - name = "Maelle" - }, - ["0x030b000100790502"] = { - name = "Deena" - }, - ["0x030c000101b80502"] = { - name = "Pompom" - }, - ["0x030d000101840502"] = { - name = "Mallary" - }, - ["0x030e0001012f0502"] = { - name = "Freckles" - }, - ["0x030f0001016d0502"] = { - name = "Derwin" - }, - ["0x0310000100f80502"] = { - name = "Drake" - }, - ["0x0311000100d60502"] = { - name = "Scoot" - }, - ["0x0312000103090502"] = { - name = "Weber" - }, - ["0x0313000101210502"] = { - name = "Miranda" - }, - ["0x0314000102f40502"] = { - name = "Ketchup" - }, - ["0x0316000101c00502"] = { - name = "Gloria" - }, - ["0x0317000100a60502"] = { - name = "Molly" - }, - ["0x03180001006c0502"] = { - name = "Quillson" - }, - ["0x0323000100760502"] = { - name = "Opal" - }, - ["0x0324000101890502"] = { - name = "Dizzy" - }, - ["0x03250001010a0502"] = { - name = "Big Top" - }, - ["0x0326000101390502"] = { - name = "Eloise" - }, - ["0x0327000101c30502"] = { - name = "Margie" - }, - ["0x0328000102eb0502"] = { - name = "Paolo" - }, - ["0x03290001009d0502"] = { - name = "Axel" - }, - ["0x032a000103070502"] = { - name = "Ellie" - }, - ["0x032c000101480502"] = { - name = "Tucker" - }, - ["0x032d000100bc0502"] = { - name = "Tia" - }, - ["0x032e0101031c0502"] = { - name = "Chai" - }, - ["0x03380001011d0502"] = { - name = "Lily" - }, - ["0x0339000101b10502"] = { - name = "Ribbot" - }, - ["0x033a000101cc0502"] = { - name = "Frobert" - }, - ["0x033b000100fa0502"] = { - name = "Camofrog" - }, - ["0x033c000101000502"] = { - name = "Drift" - }, - ["0x033d0001013a0502"] = { - name = "Wart Jr." - }, - ["0x033e000101a20502"] = { - name = "Puddles" - }, - ["0x033f0001008f0502"] = { - name = "Jeremiah" - }, - ["0x03410001030e0502"] = { - name = "Tad" - }, - ["0x0342000101280502"] = { - name = "Cousteau" - }, - ["0x0343000102ef0502"] = { - name = "Huck" - }, - ["0x0344000100c50502"] = { - name = "Prince" - }, - ["0x03450001005f0502"] = { - name = "Jambette" - }, - ["0x0347000103020502"] = { - name = "Raddle" - }, - ["0x03480001006b0502"] = { - name = "Gigi" - }, - ["0x03490001018d0502"] = { - name = "Croque" - }, - ["0x034a000101430502"] = { - name = "Diva" - }, - ["0x034b0001009f0502"] = { - name = "Henry" - }, - ["0x0356000101350502"] = { - name = "Chevre" - }, - ["0x0357000100eb0502"] = { - name = "Nan" - }, - ["0x0358000102fa0502"] = { - name = "Billy" - }, - ["0x035a000100850502"] = { - name = "Gruff" - }, - ["0x035c000101290502"] = { - name = "Velma" - }, - ["0x035d000100c90502"] = { - name = "Kidd" - }, - ["0x035e0001018e0502"] = { - name = "Pashmina" - }, - ["0x0369000100d30502"] = { - name = "Cesar" - }, - ["0x036a0001019d0502"] = { - name = "Peewee" - }, - ["0x036b0001018b0502"] = { - name = "Boone" - }, - ["0x036d000103040502"] = { - name = "Louie" - }, - ["0x036e000102fb0502"] = { - name = "Boyd" - }, - ["0x03700001015d0502"] = { - name = "Violet" - }, - ["0x03710001005c0502"] = { - name = "Al" - }, - ["0x03720001010b0502"] = { - name = "Rocket" - }, - ["0x0373000101340502"] = { - name = "Hans" - }, - ["0x0374010103190502"] = { - name = "Rilla" - }, - ["0x037e000101560502"] = { - name = "Hamlet" - }, - ["0x037f000101aa0502"] = { - name = "Apple" - }, - ["0x0380000101870502"] = { - name = "Graham" - }, - ["0x0381000100d50502"] = { - name = "Rodney" - }, - ["0x03820001016b0502"] = { - name = "Soleil" - }, - ["0x03830001009b0502"] = { - name = "Clay" - }, - ["0x0384000100860502"] = { - name = "Flurry" - }, - ["0x0385000101060502"] = { - name = "Hamphrey" - }, - ["0x0390000101850502"] = { - name = "Rocco" - }, - ["0x0392000101270502"] = { - name = "Bubbles" - }, - ["0x0393000100a00502"] = { - name = "Bertha" - }, - ["0x0394000100890502"] = { - name = "Biff" - }, - ["0x0395000102fc0502"] = { - name = "Bitty" - }, - ["0x0398000100bf0502"] = { - name = "Harry" - }, - ["0x0399000101c20502"] = { - name = "Hippeux" - }, - ["0x03a40001014f0502"] = { - name = "Buck" - }, - ["0x03a50001015b0502"] = { - name = "Victoria" - }, - ["0x03a6000100c80502"] = { - name = "Savannah" - }, - ["0x03a7000101a10502"] = { - name = "Elmer" - }, - ["0x03a8000100910502"] = { - name = "Rosco" - }, - ["0x03a9000100710502"] = { - name = "Winnie" - }, - ["0x03aa000100e60502"] = { - name = "Ed" - }, - ["0x03ab000103160502"] = { - name = "Cleo" - }, - ["0x03ac000101880502"] = { - name = "Peaches" - }, - ["0x03ad000101b20502"] = { - name = "Annalise" - }, - ["0x03ae000100870502"] = { - name = "Clyde" - }, - ["0x03af0001012c0502"] = { - name = "Colton" - }, - ["0x03b0000101a90502"] = { - name = "Papi" - }, - ["0x03b1000100f00502"] = { - name = "Julian" - }, - ["0x03bc0001008a0502"] = { - name = "Yuka" - }, - ["0x03bd000100f90502"] = { - name = "Alice" - }, - ["0x03be000101980502"] = { - name = "Melba" - }, - ["0x03bf000101bc0502"] = { - name = "Sydney" - }, - ["0x03c0000103100502"] = { - name = "Gonzo" - }, - ["0x03c1000100bb0502"] = { - name = "Ozzie" - }, - ["0x03c40001012b0502"] = { - name = "Canberra" - }, - ["0x03c50001015c0502"] = { - name = "Lyman" - }, - ["0x03c6000100930502"] = { - name = "Eugene" - }, - ["0x03d1000100c20502"] = { - name = "Kitt" - }, - ["0x03d2000100e50502"] = { - name = "Mathilda" - }, - ["0x03d3000102f30502"] = { - name = "Carrie" - }, - ["0x03d6000101570502"] = { - name = "Astrid" - }, - ["0x03d7000101b40502"] = { - name = "Sylvia" - }, - ["0x03d9000101a50502"] = { - name = "Walt" - }, - ["0x03da000101510502"] = { - name = "Rooney" - }, - ["0x03db0001006d0502"] = { - name = "Marcie" - }, - ["0x03e6000100ec0502"] = { - name = "Bud" - }, - ["0x03e70001012a0502"] = { - name = "Elvis" - }, - ["0x03e8000102f50502"] = { - name = "Rex" - }, - ["0x03ea0001030b0502"] = { - name = "Leopold" - }, - ["0x03ec000101830502"] = { - name = "Mott" - }, - ["0x03ed000101a30502"] = { - name = "Rory" - }, - ["0x03ee0001008b0502"] = { - name = "Lionel" - }, - ["0x03fa000100d00502"] = { - name = "Nana" - }, - ["0x03fb000101cf0502"] = { - name = "Simon" - }, - ["0x03fc000101470502"] = { - name = "Tammi" - }, - ["0x03fd000101580502"] = { - name = "Monty" - }, - ["0x03fe000101a40502"] = { - name = "Elise" - }, - ["0x03ff000100f40502"] = { - name = "Flip" - }, - ["0x04000001006f0502"] = { - name = "Shari" - }, - ["0x0401000100660502"] = { - name = "Deli" - }, - ["0x040c000101590502"] = { - name = "Dora" - }, - ["0x040d000100780502"] = { - name = "Limberg" - }, - ["0x040e000100880502"] = { - name = "Bella" - }, - ["0x040f000101500502"] = { - name = "Bree" - }, - ["0x04100001007f0502"] = { - name = "Samson" - }, - ["0x0411000101ab0502"] = { - name = "Rod" - }, - ["0x04140001030a0502"] = { - name = "Candi" - }, - ["0x0415000101bb0502"] = { - name = "Rizzo" - }, - ["0x0416000100fb0502"] = { - name = "Anicotti" - }, - ["0x0418000100d80502"] = { - name = "Broccolo" - }, - ["0x041a000100e00502"] = { - name = "Moose" - }, - ["0x041b000100f10502"] = { - name = "Bettina" - }, - ["0x041c000101410502"] = { - name = "Greta" - }, - ["0x041d0001018a0502"] = { - name = "Penelope" - }, - ["0x041e0001015f0502"] = { - name = "Chadder" - }, - ["0x0429000100700502"] = { - name = "Octavian" - }, - ["0x042a0001012d0502"] = { - name = "Marina" - }, - ["0x042b000101af0502"] = { - name = "Zucker" - }, - ["0x0436000101940502"] = { - name = "Queenie" - }, - ["0x0437000101050502"] = { - name = "Gladys" - }, - ["0x0438000103000502"] = { - name = "Sandy" - }, - ["0x0439000103110502"] = { - name = "Sprocket" - }, - ["0x043b000103030502"] = { - name = "Julia" - }, - ["0x043c000101cb0502"] = { - name = "Cranston" - }, - ["0x043d0001007c0502"] = { - name = "Phil" - }, - ["0x043e000101490502"] = { - name = "Blanche" - }, - ["0x043f000101550502"] = { - name = "Flora" - }, - ["0x0440000100ca0502"] = { - name = "Phoebe" - }, - ["0x044b0001016c0502"] = { - name = "Apollo" - }, - ["0x044c0001008e0502"] = { - name = "Amelia" - }, - ["0x044d000101930502"] = { - name = "Pierce" - }, - ["0x044e000103150502"] = { - name = "Buzz" - }, - ["0x0450000100cf0502"] = { - name = "Avery" - }, - ["0x04510001015e0502"] = { - name = "Frank" - }, - ["0x0452000100730502"] = { - name = "Sterling" - }, - ["0x0453000101040502"] = { - name = "Keaton" - }, - ["0x0454000101ae0502"] = { - name = "Celia" - }, - ["0x045f000101a80502"] = { - name = "Aurora" - }, - ["0x0460000100a50502"] = { - name = "Roald" - }, - ["0x0461000101610502"] = { - name = "Cube" - }, - ["0x0462000100f60502"] = { - name = "Hopper" - }, - ["0x0463000101310502"] = { - name = "Friga" - }, - ["0x0464000100c00502"] = { - name = "Gwen" - }, - ["0x04650001006e0502"] = { - name = "Puck" - }, - ["0x0468000102f20502"] = { - name = "Wade" - }, - ["0x0469000101640502"] = { - name = "Boomer" - }, - ["0x046a000101d00502"] = { - name = "Iggly" - }, - ["0x046b000101970502"] = { - name = "Tex" - }, - ["0x046c0001008c0502"] = { - name = "Flo" - }, - ["0x046d000100f30502"] = { - name = "Sprinkle" - }, - ["0x0478000101630502"] = { - name = "Curly" - }, - ["0x0479000100920502"] = { - name = "Truffles" - }, - ["0x047a000100600502"] = { - name = "Rasher" - }, - ["0x047b000100f50502"] = { - name = "Hugh" - }, - ["0x047c000101a00502"] = { - name = "Lucy" - }, - ["0x047d0001012e0502"] = { - name = "Spork/Crackle" - }, - ["0x04800001008d0502"] = { - name = "Cobb" - }, - ["0x0481000102f10502"] = { - name = "Boris" - }, - ["0x0482000102fd0502"] = { - name = "Maggie" - }, - ["0x0483000101b00502"] = { - name = "Peggy" - }, - ["0x04850001014c0502"] = { - name = "Gala" - }, - ["0x0486000100fc0502"] = { - name = "Chops" - }, - ["0x0487000101bf0502"] = { - name = "Kevin" - }, - ["0x0488000100980502"] = { - name = "Pancetti" - }, - ["0x0489000100ef0502"] = { - name = "Agnes" - }, - ["0x04940001009a0502"] = { - name = "Bunnie" - }, - ["0x0495000101920502"] = { - name = "Dotty" - }, - ["0x0496000100d90502"] = { - name = "Coco" - }, - ["0x04970001007a0502"] = { - name = "Snake" - }, - ["0x04980001014a0502"] = { - name = "Gaston" - }, - ["0x0499000100df0502"] = { - name = "Gabi" - }, - ["0x049a0001014e0502"] = { - name = "Pippy" - }, - ["0x049b000100610502"] = { - name = "Tiffany" - }, - ["0x049c000101400502"] = { - name = "Genji" - }, - ["0x049d000100ed0502"] = { - name = "Ruby" - }, - ["0x049e000101b70502"] = { - name = "Doc" - }, - ["0x049f000103010502"] = { - name = "Claude" - }, - ["0x04a00001016e0502"] = { - name = "Francine" - }, - ["0x04a10001016f0502"] = { - name = "Chrissy" - }, - ["0x04a2000102e80502"] = { - name = "Hopkins" - }, - ["0x04a3000101c90502"] = { - name = "OHare" - }, - ["0x04a4000100d40502"] = { - name = "Carmen" - }, - ["0x04a5000100740502"] = { - name = "Bonbon" - }, - ["0x04a6000100a30502"] = { - name = "Cole" - }, - ["0x04a7000101a60502"] = { - name = "Mira" - }, - ["0x04a80101031e0502"] = { - name = "Toby" - }, - ["0x04b2000101b90502"] = { - name = "Tank" - }, - ["0x04b3000100dd0502"] = { - name = "Rhonda" - }, - ["0x04b40001030c0502"] = { - name = "Spike" - }, - ["0x04b6000102ec0502"] = { - name = "Hornsby" - }, - ["0x04b9000101600502"] = { - name = "Merengue" - }, - ["0x04ba0001005d0502"] = { - name = "Renée" - }, - ["0x04c5000101010502"] = { - name = "Vesta" - }, - ["0x04c6000101670502"] = { - name = "Baabara" - }, - ["0x04c7000100940502"] = { - name = "Eunice" - }, - ["0x04c8000102ed0502"] = { - name = "Stella" - }, - ["0x04c90001030d0502"] = { - name = "Cashmere" - }, - ["0x04cc000100a40502"] = { - name = "Willow" - }, - ["0x04cd000101520502"] = { - name = "Curlos" - }, - ["0x04ce000100db0502"] = { - name = "Wendy" - }, - ["0x04cf000100e10502"] = { - name = "Timbra" - }, - ["0x04d0000101960502"] = { - name = "Frita" - }, - ["0x04d10001009e0502"] = { - name = "Muffy" - }, - ["0x04d2000101a70502"] = { - name = "Pietro" - }, - ["0x04d30101031b0502"] = { - name = "Étoile" - }, - ["0x04dd000100a20502"] = { - name = "Peanut" - }, - ["0x04de000100ce0502"] = { - name = "Blaire" - }, - ["0x04df000100e80502"] = { - name = "Filbert" - }, - ["0x04e0000100f70502"] = { - name = "Pecan" - }, - ["0x04e1000101be0502"] = { - name = "Nibbles" - }, - ["0x04e2000101090502"] = { - name = "Agent S" - }, - ["0x04e3000101650502"] = { - name = "Caroline" - }, - ["0x04e4000101b60502"] = { - name = "Sally" - }, - ["0x04e5000101ad0502"] = { - name = "Static" - }, - ["0x04e6000100820502"] = { - name = "Mint" - }, - ["0x04e7000101320502"] = { - name = "Ricky" - }, - ["0x04e8000101ce0502"] = { - name = "Cally" - }, - ["0x04ea000103180502"] = { - name = "Tasha" - }, - ["0x04eb000102f00502"] = { - name = "Sylvana" - }, - ["0x04ec000100770502"] = { - name = "Poppy" - }, - ["0x04ed000100620502"] = { - name = "Sheldon" - }, - ["0x04ee0001014b0502"] = { - name = "Marshal" - }, - ["0x04ef0001013b0502"] = { - name = "Hazel" - }, - ["0x04fa000101680502"] = { - name = "Rolf" - }, - ["0x04fb000101c60502"] = { - name = "Rowan" - }, - ["0x04fc000102ee0502"] = { - name = "Tybalt" - }, - ["0x04fd0001007b0502"] = { - name = "Bangle" - }, - ["0x04fe000100590502"] = { - name = "Leonardo" - }, - ["0x04ff000101620502"] = { - name = "Claudia" - }, - ["0x0500000100e70502"] = { - name = "Bianca" - }, - ["0x050b000100990502"] = { - name = "Chief" - }, - ["0x050c000101c10502"] = { - name = "Lobo" - }, - ["0x050d000101420502"] = { - name = "Wolfgang" - }, - ["0x050e000100d70502"] = { - name = "Whitney" - }, - ["0x050f000103140502"] = { - name = "Dobie" - }, - ["0x0510000101070502"] = { - name = "Freya" - }, - ["0x0511000101950502"] = { - name = "Fang" - }, - ["0x0513000102e70502"] = { - name = "Vivian" - }, - ["0x0514000101530502"] = { - name = "Skye" - }, - ["0x05150001005b0502"] = { - name = "Kyle" - }, - ["0x0580000000050002"] = { - name = "Fox" - }, - ["0x05810000001c0002"] = { - name = "Falco" - }, - ["0x05840000037e0002"] = { - name = "Wolf" - }, - ["0x05c0000000060002"] = { - name = "Samus" - }, - ["0x05c0000003651302"] = { - name = "Samus Aran" - }, - ["0x05c0000004121302"] = { - name = "Samus - Metroid Dread" - }, - ["0x05c00100001d0002"] = { - name = "Zero Suit Samus" - }, - ["0x05c1000003661302"] = { - name = "Metroid" - }, - ["0x05c20000037f0002"] = { - name = "Ridley" - }, - ["0x05c3000003800002"] = { - name = "Dark Samus" - }, - ["0x05c4000004131302"] = { - name = "E.M.M.I." - }, - ["0x0600000000120002"] = { - name = "Captain Falcon" - }, - ["0x06400100001e0002"] = { - name = "Olimar" - }, - ["0x06420000035f1102"] = { - name = "Pikmin" - }, - ["0x06c00000000f0002"] = { - name = "Little Mac" - }, - ["0x0700000000070002"] = { - name = "Wii Fit Trainer" - }, - ["0x0740000000100002"] = { - name = "Pit" - }, - ["0x0741000000200002"] = { - name = "Dark Pit" - }, - ["0x07420000001f0002"] = { - name = "Palutena" - }, - ["0x07800000002d0002"] = { - name = "Mr. Game & Watch" - }, - ["0x07810000002e0002"] = { - name = "R.O.B. - Famicom" - }, - ["0x0781000000330002"] = { - name = "R.O.B. - NES" - }, - ["0x07820000002f0002"] = { - name = "Duck Hunt" - }, - ["0x078f000003810002"] = { - name = "Ice Climbers" - }, - ["0x07c0000000210002"] = { - name = "Mii Brawler" - }, - ["0x07c0010000220002"] = { - name = "Mii Swordfighter" - }, - ["0x07c0020000230002"] = { - name = "Mii Gunner" - }, - ["0x08000100003e0402"] = { - name = "Inkling Girl" - }, - ["0x08000100025f0402"] = { - name = "Inkling Girl - Lime Green" - }, - ["0x0800010003690402"] = { - name = "Inkling Girl - Neon Pink" - }, - ["0x0800010003820002"] = { - name = "Inkling" - }, - ["0x08000200003f0402"] = { - name = "Inkling Boy" - }, - ["0x0800020002600402"] = { - name = "Inkling Boy - Purple" - }, - ["0x08000200036a0402"] = { - name = "Inkling Boy - Neon Green" - }, - ["0x0800030000400402"] = { - name = "Inkling Squid" - }, - ["0x0800030002610402"] = { - name = "Inkling Squid - Orange" - }, - ["0x08000300036b0402"] = { - name = "Inkling Squid - Neon Purple" - }, - ["0x08010000025d0402"] = { - name = "Callie" - }, - ["0x08020000025e0402"] = { - name = "Marie" - }, - ["0x0803000003760402"] = { - name = "Pearl" - }, - ["0x0804000003770402"] = { - name = "Marina" - }, - ["0x08050100038e0402"] = { - name = "Octoling Girl" - }, - ["0x08050200038f0402"] = { - name = "Octoling Boy" - }, - ["0x0805030003900402"] = { - name = "Octoling Octopus" - }, - ["0x09c0010102690e02"] = { - name = "Mario - Soccer" - }, - ["0x09c00201026a0e02"] = { - name = "Mario - Baseball" - }, - ["0x09c00301026b0e02"] = { - name = "Mario - Tennis" - }, - ["0x09c00401026c0e02"] = { - name = "Mario - Golf" - }, - ["0x09c00501026d0e02"] = { - name = "Mario - Horse Racing" - }, - ["0x09c10101026e0e02"] = { - name = "Luigi - Soccer" - }, - ["0x09c10201026f0e02"] = { - name = "Luigi - Baseball" - }, - ["0x09c1030102700e02"] = { - name = "Luigi - Tennis" - }, - ["0x09c1040102710e02"] = { - name = "Luigi - Golf" - }, - ["0x09c1050102720e02"] = { - name = "Luigi - Horse Racing" - }, - ["0x09c2010102730e02"] = { - name = "Peach - Soccer" - }, - ["0x09c2020102740e02"] = { - name = "Peach - Baseball" - }, - ["0x09c2030102750e02"] = { - name = "Peach - Tennis" - }, - ["0x09c2040102760e02"] = { - name = "Peach - Golf" - }, - ["0x09c2050102770e02"] = { - name = "Peach - Horse Racing" - }, - ["0x09c3010102780e02"] = { - name = "Daisy - Soccer" - }, - ["0x09c3020102790e02"] = { - name = "Daisy - Baseball" - }, - ["0x09c30301027a0e02"] = { - name = "Daisy - Tennis" - }, - ["0x09c30401027b0e02"] = { - name = "Daisy - Golf" - }, - ["0x09c30501027c0e02"] = { - name = "Daisy - Horse Racing" - }, - ["0x09c40101027d0e02"] = { - name = "Yoshi - Soccer" - }, - ["0x09c40201027e0e02"] = { - name = "Yoshi - Baseball" - }, - ["0x09c40301027f0e02"] = { - name = "Yoshi - Tennis" - }, - ["0x09c4040102800e02"] = { - name = "Yoshi - Golf" - }, - ["0x09c4050102810e02"] = { - name = "Yoshi - Horse Racing" - }, - ["0x09c5010102820e02"] = { - name = "Wario - Soccer" - }, - ["0x09c5020102830e02"] = { - name = "Wario - Baseball" - }, - ["0x09c5030102840e02"] = { - name = "Wario - Tennis" - }, - ["0x09c5040102850e02"] = { - name = "Wario - Golf" - }, - ["0x09c5050102860e02"] = { - name = "Wario - Horse Racing" - }, - ["0x09c6010102870e02"] = { - name = "Waluigi - Soccer" - }, - ["0x09c6020102880e02"] = { - name = "Waluigi - Baseball" - }, - ["0x09c6030102890e02"] = { - name = "Waluigi - Tennis" - }, - ["0x09c60401028a0e02"] = { - name = "Waluigi - Golf" - }, - ["0x09c60501028b0e02"] = { - name = "Waluigi - Horse Racing" - }, - ["0x09c70101028c0e02"] = { - name = "Donkey Kong - Soccer" - }, - ["0x09c70201028d0e02"] = { - name = "Donkey Kong - Baseball" - }, - ["0x09c70301028e0e02"] = { - name = "Donkey Kong - Tennis" - }, - ["0x09c70401028f0e02"] = { - name = "Donkey Kong - Golf" - }, - ["0x09c7050102900e02"] = { - name = "Donkey Kong - Horse Racing" - }, - ["0x09c8010102910e02"] = { - name = "Diddy Kong - Soccer" - }, - ["0x09c8020102920e02"] = { - name = "Diddy Kong - Baseball" - }, - ["0x09c8030102930e02"] = { - name = "Diddy Kong - Tennis" - }, - ["0x09c8040102940e02"] = { - name = "Diddy Kong - Golf" - }, - ["0x09c8050102950e02"] = { - name = "Diddy Kong - Horse Racing" - }, - ["0x09c9010102960e02"] = { - name = "Bowser - Soccer" - }, - ["0x09c9020102970e02"] = { - name = "Bowser - Baseball" - }, - ["0x09c9030102980e02"] = { - name = "Bowser - Tennis" - }, - ["0x09c9040102990e02"] = { - name = "Bowser - Golf" - }, - ["0x09c90501029a0e02"] = { - name = "Bowser - Horse Racing" - }, - ["0x09ca0101029b0e02"] = { - name = "Bowser Jr. - Soccer" - }, - ["0x09ca0201029c0e02"] = { - name = "Bowser Jr. - Baseball" - }, - ["0x09ca0301029d0e02"] = { - name = "Bowser Jr. - Tennis" - }, - ["0x09ca0401029e0e02"] = { - name = "Bowser Jr. - Golf" - }, - ["0x09ca0501029f0e02"] = { - name = "Bowser Jr. - Horse Racing" - }, - ["0x09cb010102a00e02"] = { - name = "Boo - Soccer" - }, - ["0x09cb020102a10e02"] = { - name = "Boo - Baseball" - }, - ["0x09cb030102a20e02"] = { - name = "Boo - Tennis" - }, - ["0x09cb040102a30e02"] = { - name = "Boo - Golf" - }, - ["0x09cb050102a40e02"] = { - name = "Boo - Horse Racing" - }, - ["0x09cc010102a50e02"] = { - name = "Baby Mario - Soccer" - }, - ["0x09cc020102a60e02"] = { - name = "Baby Mario - Baseball" - }, - ["0x09cc030102a70e02"] = { - name = "Baby Mario - Tennis" - }, - ["0x09cc040102a80e02"] = { - name = "Baby Mario - Golf" - }, - ["0x09cc050102a90e02"] = { - name = "Baby Mario - Horse Racing" - }, - ["0x09cd010102aa0e02"] = { - name = "Baby Luigi - Soccer" - }, - ["0x09cd020102ab0e02"] = { - name = "Baby Luigi - Baseball" - }, - ["0x09cd030102ac0e02"] = { - name = "Baby Luigi - Tennis" - }, - ["0x09cd040102ad0e02"] = { - name = "Baby Luigi - Golf" - }, - ["0x09cd050102ae0e02"] = { - name = "Baby Luigi - Horse Racing" - }, - ["0x09ce010102af0e02"] = { - name = "Birdo - Soccer" - }, - ["0x09ce020102b00e02"] = { - name = "Birdo - Baseball" - }, - ["0x09ce030102b10e02"] = { - name = "Birdo - Tennis" - }, - ["0x09ce040102b20e02"] = { - name = "Birdo - Golf" - }, - ["0x09ce050102b30e02"] = { - name = "Birdo - Horse Racing" - }, - ["0x09cf010102b40e02"] = { - name = "Rosalina - Soccer" - }, - ["0x09cf020102b50e02"] = { - name = "Rosalina - Baseball" - }, - ["0x09cf030102b60e02"] = { - name = "Rosalina - Tennis" - }, - ["0x09cf040102b70e02"] = { - name = "Rosalina - Golf" - }, - ["0x09cf050102b80e02"] = { - name = "Rosalina - Horse Racing" - }, - ["0x09d0010102b90e02"] = { - name = "Metal Mario - Soccer" - }, - ["0x09d0020102ba0e02"] = { - name = "Metal Mario - Baseball" - }, - ["0x09d0030102bb0e02"] = { - name = "Metal Mario - Tennis" - }, - ["0x09d0040102bc0e02"] = { - name = "Metal Mario - Golf" - }, - ["0x09d0050102bd0e02"] = { - name = "Metal Mario - Horse Racing" - }, - ["0x09d1010102be0e02"] = { - name = "Pink Gold Peach - Soccer" - }, - ["0x09d1020102bf0e02"] = { - name = "Pink Gold Peach - Baseball" - }, - ["0x09d1030102c00e02"] = { - name = "Pink Gold Peach - Tennis" - }, - ["0x09d1040102c10e02"] = { - name = "Pink Gold Peach - Golf" - }, - ["0x09d1050102c20e02"] = { - name = "Pink Gold Peach - Horse Racing" - }, - ["0x0a00000103ab0502"] = { - name = "Orville" - }, - ["0x0a01000103ac0502"] = { - name = "Wilbur" - }, - ["0x0a02000103b30502"] = { - name = "C.J." - }, - ["0x0a03000103b40502"] = { - name = "Flick" - }, - ["0x0a04000103b50502"] = { - name = "Daisy Mae" - }, - ["0x0a05000103b80502"] = { - name = "Harvey" - }, - ["0x0a06000103ba0502"] = { - name = "Wisp" - }, - ["0x0a07000103bc0502"] = { - name = "Niko" - }, - ["0x0a08000103bd0502"] = { - name = "Wardell" - }, - ["0x0a09000103c00502"] = { - name = "Sherb" - }, - ["0x0a0a000103c10502"] = { - name = "Megan" - }, - ["0x0a0b000103c20502"] = { - name = "Dom" - }, - ["0x0a0c000103c30502"] = { - name = "Audie" - }, - ["0x0a0d000103c40502"] = { - name = "Cyd" - }, - ["0x0a0e000103c50502"] = { - name = "Judy" - }, - ["0x0a0f000103c60502"] = { - name = "Raymond" - }, - ["0x0a10000103c70502"] = { - name = "Reneigh" - }, - ["0x0a11000103c80502"] = { - name = "Sasha" - }, - ["0x0a12000103c90502"] = { - name = "Ione" - }, - ["0x0a13000103ca0502"] = { - name = "Tiansheng" - }, - ["0x0a14000103cb0502"] = { - name = "Shino" - }, - ["0x0a15000103cc0502"] = { - name = "Marlo" - }, - ["0x0a16000103cd0502"] = { - name = "Petri" - }, - ["0x0a17000103ce0502"] = { - name = "Cephalobot" - }, - ["0x0a18000103cf0502"] = { - name = "Quinn" - }, - ["0x0a19000103d00502"] = { - name = "Chabwick" - }, - ["0x0a1a000103d10502"] = { - name = "Zoe" - }, - ["0x0a1b000103d20502"] = { - name = "Ace" - }, - ["0x0a1c000103d30502"] = { - name = "Rio" - }, - ["0x0a1d000103d40502"] = { - name = "Frett" - }, - ["0x0a1e000103d50502"] = { - name = "Azalea" - }, - ["0x0a1f000103d60502"] = { - name = "Roswell" - }, - ["0x0a20000103d70502"] = { - name = "Faith" - }, - ["0x0a400000041d0002"] = { - name = "Min Min" - }, - ["0x1902000003830002"] = { - name = "Ivysaur" - }, - ["0x1906000000240002"] = { - name = "Charizard" - }, - ["0x1907000003840002"] = { - name = "Squirtle" - }, - ["0x1919000000090002"] = { - name = "Pikachu" - }, - ["0x1927000000260002"] = { - name = "Jigglypuff" - }, - ["0x19960000023d0002"] = { - name = "Mewtwo" - }, - ["0x19ac000003850002"] = { - name = "Pichu" - }, - ["0x1ac0000000110002"] = { - name = "Lucario" - }, - ["0x1b92000000250002"] = { - name = "Greninja" - }, - ["0x1bd7000003860002"] = { - name = "Incineroar" - }, - ["0x1d000001025c0d02"] = { - name = "Shadow Mewtwo" - }, - ["0x1d01000003750d02"] = { - name = "Detective Pikachu" - }, - ["0x1d40000003870002"] = { - name = "Pokemon Trainer" - }, - ["0x1f000000000a0002"] = { - name = "Kirby" - }, - ["0x1f00000002540c02"] = { - name = "Kirby" - }, - ["0x1f01000000270002"] = { - name = "Meta Knight" - }, - ["0x1f01000002550c02"] = { - name = "Meta Knight" - }, - ["0x1f02000000280002"] = { - name = "King Dedede" - }, - ["0x1f02000002560c02"] = { - name = "King Dedede" - }, - ["0x1f03000002570c02"] = { - name = "Waddle Dee" - }, - ["0x1f400000035e1002"] = { - name = "Qbby" - }, - ["0x21000000000b0002"] = { - name = "Marth" - }, - ["0x2101000000180002"] = { - name = "Ike" - }, - ["0x2102000000290002"] = { - name = "Lucina" - }, - ["0x21030000002a0002"] = { - name = "Robin" - }, - ["0x2104000002520002"] = { - name = "Roy" - }, - ["0x21050000025a0002"] = { - name = "Corrin" - }, - ["0x2105010003630002"] = { - name = "Corrin - Player 2" - }, - ["0x2106000003601202"] = { - name = "Alm" - }, - ["0x2107000003611202"] = { - name = "Celica" - }, - ["0x21080000036f1202"] = { - name = "Chrom" - }, - ["0x2108000003880002"] = { - name = "Chrom" - }, - ["0x2109000003701202"] = { - name = "Tiki" - }, - ["0x210b000003a50002"] = { - name = "Byleth" - }, - ["0x22400000002b0002"] = { - name = "Shulk" - }, - ["0x22800000002c0002"] = { - name = "Ness" - }, - ["0x2281000002510002"] = { - name = "Lucas" - }, - ["0x22c00000003a0202"] = { - name = "Chibi Robo" - }, - ["0x3200000000300002"] = { - name = "Sonic" - }, - ["0x32400000025b0002"] = { - name = "Bayonetta" - }, - ["0x3240010003640002"] = { - name = "Bayonetta - Player 2" - }, - ["0x3340000000320002"] = { - name = "Pac-Man" - }, - ["0x3380000003781402"] = { - name = "Solaire of Astora" - }, - ["0x3480000000310002"] = { - name = "Mega Man" - }, - ["0x3480000002580002"] = { - name = "Mega Man - Gold Edition" - }, - ["0x3480000003791502"] = { - name = "Mega Man" - }, - ["0x34c0000002530002"] = { - name = "Ryu" - }, - ["0x34c1000003890002"] = { - name = "Ken" - }, - ["0x3500010002e10f02"] = { - name = "One-Eyed Rathalos and Rider - Male" - }, - ["0x3500020002e20f02"] = { - name = "One-Eyed Rathalos and Rider - Female" - }, - ["0x3501000002e30f02"] = { - name = "Nabiru" - }, - ["0x3502010002e40f02"] = { - name = "Rathian and Cheval" - }, - ["0x3503010002e50f02"] = { - name = "Barioth and Ayuria" - }, - ["0x3504010002e60f02"] = { - name = "Qurupeco and Dan" - }, - ["0x35050000040c0f02"] = { - name = "Razewing Ratha" - }, - ["0x35060000040d0f02"] = { - name = "Ena" - }, - ["0x35070000040e0f02"] = { - name = "Tsukino" - }, - ["0x35080000040f1802"] = { - name = "Magnamalo" - }, - ["0x3509000004101802"] = { - name = "Palico" - }, - ["0x35090100042b1802"] = { - name = "Palico" - }, - ["0x350a000004111802"] = { - name = "Palamute" - }, - ["0x350a0100042c1802"] = { - name = "Palamute" - }, - ["0x350b0000042d1802"] = { - name = "Malzeno" - }, - ["0x35c0000002500a02"] = { - name = "Shovel Knight" - }, - ["0x35c0000003920a02"] = { - name = "Shovel Knight - Gold Edition" - }, - ["0x35c10000036c0a02"] = { - name = "Plague Knight" - }, - ["0x35c20000036d0a02"] = { - name = "Specter Knight" - }, - ["0x35c30000036e0a02"] = { - name = "King Knight" - }, - ["0x3600000002590002"] = { - name = "Cloud" - }, - ["0x3600010003620002"] = { - name = "Cloud - Player 2" - }, - ["0x3640000003a20002"] = { - name = "Hero" - }, - ["0x3740000103741402"] = { - name = "Super Mario Cereal" - }, - ["0x37800000038a0002"] = { - name = "Snake" - }, - ["0x37c00000038b0002"] = { - name = "Simon" - }, - ["0x37c10000038c0002"] = { - name = "Richter" - }, - ["0x3800000103931702"] = { - name = "Pawapuro" - }, - ["0x3801000103941702"] = { - name = "Ikari" - }, - ["0x3802000103951702"] = { - name = "Daijobu" - }, - ["0x3803000103961702"] = { - name = "Hayakawa" - }, - ["0x3804000103971702"] = { - name = "Yabe" - }, - ["0x3805000103981702"] = { - name = "Ganda" - }, - ["0x3840000104241902"] = { - name = "Yuga Ohdo" - }, - ["0x3841000104251902"] = { - name = "Tatsuhisa “Luke” Kamijō" - }, - ["0x3842000104261902"] = { - name = "Gakuto Sōgetsu" - }, - ["0x3843000104271902"] = { - name = "Romin Kirishima" - }, - ["0x3844000104281902"] = { - name = "Roa Kirishima" - }, - ["0x3845000104291902"] = { - name = "Nail Saionji" - }, - ["0x38460001042a1902"] = { - name = "Asana Mutsuba" - }, - ["0x38c0000003911602"] = { - name = "Loot Goblin" - }, - ["0x3a00000003a10002"] = { - name = "Joker" - }, - ["0x3b40000003a30002"] = { - name = "Banjo & Kazooie" - }, - ["0x3c80000003a40002"] = { - name = "Terry" - } - }, - game_series = { - ["0x000"] = "Super Mario", - ["0x001"] = "Super Mario", - ["0x002"] = "Super Mario", - ["0x008"] = "Yoshi's Woolly World", - ["0x00c"] = "Donkey Kong", - ["0x010"] = "The Legend of Zelda", - ["0x014"] = "Breath of the Wild", - ["0x018"] = "Animal Crossing", - ["0x019"] = "Animal Crossing", - ["0x01a"] = "Animal Crossing", - ["0x01b"] = "Animal Crossing", - ["0x01c"] = "Animal Crossing", - ["0x020"] = "Animal Crossing", - ["0x021"] = "Animal Crossing", - ["0x022"] = "Animal Crossing", - ["0x023"] = "Animal Crossing", - ["0x024"] = "Animal Crossing", - ["0x025"] = "Animal Crossing", - ["0x026"] = "Animal Crossing", - ["0x027"] = "Animal Crossing", - ["0x028"] = "Animal Crossing", - ["0x029"] = "Animal Crossing", - ["0x02a"] = "Animal Crossing", - ["0x02b"] = "Animal Crossing", - ["0x02c"] = "Animal Crossing", - ["0x02d"] = "Animal Crossing", - ["0x02e"] = "Animal Crossing", - ["0x02f"] = "Animal Crossing", - ["0x030"] = "Animal Crossing", - ["0x031"] = "Animal Crossing", - ["0x032"] = "Animal Crossing", - ["0x033"] = "Animal Crossing", - ["0x034"] = "Animal Crossing", - ["0x035"] = "Animal Crossing", - ["0x036"] = "Animal Crossing", - ["0x037"] = "Animal Crossing", - ["0x038"] = "Animal Crossing", - ["0x039"] = "Animal Crossing", - ["0x03a"] = "Animal Crossing", - ["0x03b"] = "Animal Crossing", - ["0x03c"] = "Animal Crossing", - ["0x03d"] = "Animal Crossing", - ["0x03e"] = "Animal Crossing", - ["0x03f"] = "Animal Crossing", - ["0x040"] = "Animal Crossing", - ["0x041"] = "Animal Crossing", - ["0x042"] = "Animal Crossing", - ["0x043"] = "Animal Crossing", - ["0x044"] = "Animal Crossing", - ["0x045"] = "Animal Crossing", - ["0x046"] = "Animal Crossing", - ["0x047"] = "Animal Crossing", - ["0x048"] = "Animal Crossing", - ["0x049"] = "Animal Crossing", - ["0x04a"] = "Animal Crossing", - ["0x04b"] = "Animal Crossing", - ["0x04c"] = "Animal Crossing", - ["0x04d"] = "Animal Crossing", - ["0x04e"] = "Animal Crossing", - ["0x04f"] = "Animal Crossing", - ["0x050"] = "Animal Crossing", - ["0x051"] = "Animal Crossing", - ["0x0a0"] = "Animal Crossing", - ["0x0a1"] = "Animal Crossing", - ["0x0a2"] = "Animal Crossing", - ["0x058"] = "Star Fox", - ["0x05c"] = "Metroid", - ["0x060"] = "F-Zero", - ["0x064"] = "Pikmin", - ["0x06c"] = "Punch Out", - ["0x070"] = "Wii Fit", - ["0x074"] = "Kid Icarus", - ["0x078"] = "Classic Nintendo", - ["0x07c"] = "Mii", - ["0x080"] = "Splatoon", - ["0x09c"] = "Mario Sports Superstars", - ["0x09d"] = "Mario Sports Superstars", - ["0x0a4"] = "ARMS", - ["0x190"] = "Pokemon", - ["0x191"] = "Pokemon", - ["0x192"] = "Pokemon", - ["0x199"] = "Pokemon", - ["0x19a"] = "Pokemon", - ["0x1ac"] = "Pokemon", - ["0x1b9"] = "Pokemon", - ["0x1bd"] = "Pokemon", - ["0x1d0"] = "Pokemon", - ["0x1d4"] = "Pokemon", - ["0x1f0"] = "Kirby", - ["0x1f4"] = "BoxBoy!", - ["0x210"] = "Fire Emblem", - ["0x224"] = "Xenoblade", - ["0x228"] = "Earthbound", - ["0x22c"] = "Chibi Robo", - ["0x320"] = "Sonic", - ["0x324"] = "Bayonetta", - ["0x334"] = "Pac-man", - ["0x338"] = "Dark Souls", - ["0x348"] = "Megaman", - ["0x34c"] = "Street fighter", - ["0x350"] = "Monster Hunter", - ["0x35c"] = "Shovel Knight", - ["0x360"] = "Final Fantasy", - ["0x364"] = "Dragon Quest", - ["0x374"] = "Kellogs", - ["0x378"] = "Metal Gear Solid", - ["0x37c"] = "Castlevania", - ["0x380"] = "Power Pros", - ["0x384"] = "Yu-Gi-Oh!", - ["0x38c"] = "Diablo", - ["0x3a0"] = "Persona", - ["0x3b4"] = "Banjo Kazooie", - ["0x3c8"] = "Fatal Fury" - }, - types = { - ["0x00"] = "Figure", - ["0x01"] = "Card", - ["0x02"] = "Yarn", - ["0x03"] = "Band" - } -} copyright = '' author = 'George Talusan' -version = 'v0.0.1' +version = 'v0.0.2' desc = [[ This script will try to load a binary datadump of an Amiibo. It will recalculate PWD and PACK if necessary. ]] example = [[ - 1. script run hf_mf_amiibo_sim - 2. script run hf_mf_amiibo_sim -f myfile + 1. script run hf_mfu_amiibo_sim + 2. script run hf_mfu_amiibo_sim -f myfile ]] usage = [[ -script run hf_mf_amiibo_sim [-h] [-f ] +script run hf_mfu_amiibo_sim [-h] [-f ] ]] arguments = [[ -h : this help @@ -2758,10 +115,10 @@ local function main(args) local amiibo_series = amiibo_info:sub(13, 14) dbg('raw: '..ansicolors.green..amiibo_info..ansicolors.reset) - print('game: '..ansicolors.green..amiiboDb.game_series[("0x%s"):format(amiibo_game)]..ansicolors.reset) - print('character: '..ansicolors.green..amiiboDb.amiibos[("0x%s"):format(amiibo_info)].name..ansicolors.reset) - print('type: '..ansicolors.green..amiiboDb.types[("0x%s"):format(amiibo_type)]..ansicolors.reset) - print('series: '..ansicolors.green..amiiboDb.amiibo_series[("0x%s"):format(amiibo_series)]..ansicolors.reset) + print('game: '..ansicolors.green..amiibo_tools.db.game_series[("0x%s"):format(amiibo_game)]..ansicolors.reset) + print('character: '..ansicolors.green..amiibo_tools.db.amiibos[("0x%s"):format(amiibo_info)].name..ansicolors.reset) + print('type: '..ansicolors.green..amiibo_tools.db.types[("0x%s"):format(amiibo_type)]..ansicolors.reset) + print('series: '..ansicolors.green..amiibo_tools.db.amiibo_series[("0x%s"):format(amiibo_series)]..ansicolors.reset) local blocks = {} local blockindex = 0 @@ -2779,6 +136,9 @@ local function main(args) blockindex = blockindex + 1 end + -- force lock bytes, otherwise the Amiibo won't be recognized + blocks[16] = blocks[16]:sub(1, 4)..'0FE0' + -- add PWD and PACK if necessary local uid = blocks[14]:sub(1, 6)..blocks[15]:sub(1, 8) if blocks[147] == nil or blocks[147] == '00000000' then diff --git a/client/pyscripts/amiibo_change_uid.py b/client/pyscripts/amiibo_change_uid.py new file mode 100644 index 000000000..725a4f5e0 --- /dev/null +++ b/client/pyscripts/amiibo_change_uid.py @@ -0,0 +1,41 @@ +import sys +from amiibo import AmiiboDump, AmiiboMasterKey + +def main(): + if(len(sys.argv) != 5): + print(""" + \t{0} - helper script for integrating with PyAmiibo + + Usage: {0} + + Example: + + \t{0} 04123456789ABC my_amiibo_original.bin my_amiibo_with_new_uid.bin keyfile.bin + + \n""".format(sys.argv[0])) + return 1 + + uid = sys.argv[1] + infile = sys.argv[2] + outfile = sys.argv[3] + keyfile = sys.argv[4] + + if len(uid) != 14: + print('expecting 7 byte UID') + return 1 + + with open(keyfile, 'rb') as keybin: + master_key = AmiiboMasterKey.from_combined_bin(keybin.read()) + + with open(infile, 'rb') as fin, open(outfile, 'wb') as fout: + dump = AmiiboDump(master_key, fin.read(), is_locked=True) + dump.unlock() + dump.uid_hex = uid + dump.lock() + fout.write(dump.data) + + return 0 + +if __name__ == "__main__": + sys.exit(main()) + diff --git a/client/src/scripting.c b/client/src/scripting.c index a12a53fd3..c96d593df 100644 --- a/client/src/scripting.c +++ b/client/src/scripting.c @@ -886,6 +886,39 @@ static int l_detect_prng(lua_State *L) { lua_pushinteger(L, res); return 1; } +/* + * @brief l_keygen_algoB is a function to calculate pwd/pack using UID, by algo B + * @param L + * @return + */ +static int l_keygen_algoB(lua_State *L) { + //Check number of arguments + int n = lua_gettop(L); + if (n != 1) { + return returnToLuaWithError(L, "Only UID"); + } + + size_t size; + uint32_t tmp; + const char *p_uid = luaL_checklstring(L, 1, &size); + if (size != 14) + return returnToLuaWithError(L, "Wrong size of UID, got %d bytes, expected 14", (int) size); + + uint8_t uid[7] = {0, 0, 0, 0, 0, 0, 0}; + + for (int i = 0; i < 14; i += 2) { + sscanf(&p_uid[i], "%02x", &tmp); + uid[i / 2] = tmp & 0xFF; + } + + uint32_t pwd = ul_ev1_pwdgenB(uid); + uint16_t pack = ul_ev1_packgenB(uid); + + lua_pushunsigned(L, pwd); + lua_pushunsigned(L, pack); + return 2; +} + /* * @brief l_keygen_algoD is a function to calculate pwd/pack using UID, by algo D * @param L @@ -1196,6 +1229,19 @@ static int l_ndefparse(lua_State *L) { return 1; } +static int l_ul_read_uid(lua_State *L) { + uint8_t uid[7] = { 0, 0, 0, 0, 0, 0, 0 }; + int res = ul_read_uid(uid); + if (res != PM3_SUCCESS) { + return returnToLuaWithError(L, "Failed to read Ultralight/NTAG UID"); + } + char buf[15]; + memset(buf, 0, sizeof(buf)); + snprintf(buf, sizeof(buf), "%02X%02X%02X%02X%02X%02X%02X", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6]); + lua_pushstring(L, buf); + return 1; +} + static int l_remark(lua_State *L) { //Check number of arguments int n = lua_gettop(L); @@ -1340,7 +1386,7 @@ int set_pm3_libraries(lua_State *L) { {"hardnested", l_hardnested}, {"detect_prng", l_detect_prng}, // {"keygen.algoA", l_keygen_algoA}, -// {"keygen.algoB", l_keygen_algoB}, + {"keygen_algo_b", l_keygen_algoB}, // {"keygen.algoC", l_keygen_algoC}, {"keygen_algo_d", l_keygen_algoD}, {"t55xx_readblock", l_T55xx_readblock}, @@ -1354,6 +1400,7 @@ int set_pm3_libraries(lua_State *L) { {"rem", l_remark}, {"em4x05_read", l_em4x05_read}, {"em4x50_read", l_em4x50_read}, + {"ul_read_uid", l_ul_read_uid}, {NULL, NULL} }; From 834023b132599c23bb8752bd393a4f6720c8facf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Jul 2022 10:03:51 +0200 Subject: [PATCH 156/759] add a pwd to ntag215 sim if empty --- armsrc/Makefile | 3 ++- armsrc/iso14443a.c | 8 ++++++++ common/generator.c | 14 ++++++++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index 5505119b7..c0703ccf4 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -152,7 +152,8 @@ THUMBSRC = start.c \ BigBuf.c \ ticks.c \ clocks.c \ - hfsnoop.c + hfsnoop.c \ + generator.c # These are to be compiled in ARM mode diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 4af72bfba..bcf206cc8 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -34,6 +34,7 @@ #include "commonutil.h" #include "crc16.h" #include "protocols.h" +#include "generator.h" #define MAX_ISO14A_TIMEOUT 524288 @@ -1104,6 +1105,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r // READ_SIG memcpy(rSIGN, mfu_header->signature, 32); AddCrc14A(rSIGN, sizeof(rSIGN) - 2); + } break; case 8: { // MIFARE Classic 4k @@ -1642,7 +1644,13 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_ // PWD stored in dump now uint8_t pwd[4]; emlGetMemBt(pwd, (pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH, sizeof(pwd)); + if (memcmp(pwd, "\x00\x00\x00\x00", 4) == 0) { + Uint4byteToMemLe(pwd, ul_ev1_pwdgenB(data)); + Dbprintf("Calc pwd... %02X %02X %02X %02X", pwd[0], pwd[1], pwd[2] ,pwd[3]); + } + if (memcmp(receivedCmd + 1, pwd, 4) == 0) { + uint8_t pack[4]; emlGetMemBt(pack, pages * 4 + MFU_DUMP_PREFIX_LENGTH, 2); if (memcmp(pack, "\x00\x00\x00\x00", 4) == 0) { diff --git a/common/generator.c b/common/generator.c index 4b23d30ce..b06e9deaf 100644 --- a/common/generator.c +++ b/common/generator.c @@ -27,10 +27,20 @@ #include "common.h" //BSWAP_32/64 #include "util.h" #include "pm3_cmd.h" -#include "ui.h" +#include "crc16.h" // crc16 ccitt #include "mbedtls/sha1.h" #include "mbedtls/md5.h" -#include "crc16.h" // crc16 ccitt +#include "mbedtls/cmac.h" +#include "mbedtls/cipher.h" +#include "mbedtls/md.h" + +#ifndef ON_DEVICE +#include "ui.h" +# define prnt(args...) PrintAndLogEx(DEBUG, ## args ); +#else +# include "dbprint.h" +# define prnt Dbprintf +#endif // Implementation tips: // For each implementation of the algos, I recommend adding a self test for easy "simple unit" tests when Travis CI / Appveyor runs. From f78ec337efec631dc12e29f12db9b80158d4d2e4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Jul 2022 10:07:05 +0200 Subject: [PATCH 157/759] adapt device side non-printing --- common/generator.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/common/generator.c b/common/generator.c index b06e9deaf..c4ff419ca 100644 --- a/common/generator.c +++ b/common/generator.c @@ -486,7 +486,7 @@ uint32_t lf_t55xx_white_pwdgen(uint32_t id) { int mfdes_kdf_input_gallagher(uint8_t *uid, uint8_t uidLen, uint8_t keyNo, uint32_t aid, uint8_t *kdfInputOut, uint8_t *kdfInputLen) { if (uid == NULL || (uidLen != 4 && uidLen != 7) || keyNo > 2 || kdfInputOut == NULL || kdfInputLen == NULL) { if (g_debugMode) { - PrintAndLogEx(WARNING, "Invalid arguments"); + prnt("Invalid arguments"); } return PM3_EINVARG; } @@ -548,8 +548,9 @@ int mfc_algo_touch_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t * //------------------------------------ // Self tests //------------------------------------ -int generator_selftest(void) { +int generator_selftest(void) { +#ifndef ON_DEVICE #define NUM_OF_TEST 8 PrintAndLogEx(INFO, "PWD / KEY generator selftest"); @@ -621,6 +622,8 @@ int generator_selftest(void) { PrintAndLogEx(success ? SUCCESS : WARNING, "ID | 0x00000080 | %08"PRIx32 " - %s", lf_id, success ? "OK" : "->00018383<--"); PrintAndLogEx(SUCCESS, "------------------- Selftest %s", (testresult == NUM_OF_TEST) ? "OK" : "fail"); + +#endif return PM3_SUCCESS; } From 712e46ab5a841ffcfd69700ab740d34033c694de Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Jul 2022 11:18:11 +0200 Subject: [PATCH 158/759] fix #1736 --- common/generator.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/common/generator.c b/common/generator.c index c4ff419ca..da1b4bac9 100644 --- a/common/generator.c +++ b/common/generator.c @@ -485,9 +485,7 @@ uint32_t lf_t55xx_white_pwdgen(uint32_t id) { // Gallagher Desfire Key Diversification Input for Cardax Card Data Application int mfdes_kdf_input_gallagher(uint8_t *uid, uint8_t uidLen, uint8_t keyNo, uint32_t aid, uint8_t *kdfInputOut, uint8_t *kdfInputLen) { if (uid == NULL || (uidLen != 4 && uidLen != 7) || keyNo > 2 || kdfInputOut == NULL || kdfInputLen == NULL) { - if (g_debugMode) { - prnt("Invalid arguments"); - } + prnt("Invalid arguments"); return PM3_EINVARG; } From 8f8f9f97ad2ec518ee830a9a8c7b81ca9f354034 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Jul 2022 11:47:03 +0200 Subject: [PATCH 159/759] prepping for fudan pm3 commands --- client/src/cmdhffudan.c | 152 ++++++++++++++++++++++++++++++++-------- 1 file changed, 121 insertions(+), 31 deletions(-) diff --git a/client/src/cmdhffudan.c b/client/src/cmdhffudan.c index e4847d16e..8c588a01c 100644 --- a/client/src/cmdhffudan.c +++ b/client/src/cmdhffudan.c @@ -26,8 +26,8 @@ #include "comms.h" #include "cmdhf14a.h" #include "cmddata.h" -#include "mifare.h" // xiso -#include "cmdhf.h" // +#include "mifare.h" // xiso +#include "cmdhf.h" // #include "fileutils.h" // saveFile #include "ui.h" #include "commonutil.h" // MemLeToUint2byte @@ -66,7 +66,7 @@ static void fudan_print_blocks(uint16_t n, uint8_t *d) { PrintAndLogEx(NORMAL, ""); } -static char* GenerateFilename(iso14a_card_select_t *card, const char *prefix, const char *suffix) { +static char *GenerateFilename(iso14a_card_select_t *card, const char *prefix, const char *suffix) { if (card == NULL) { return NULL; } @@ -98,7 +98,7 @@ static fudan_type_t fudan_detected(iso14a_card_select_t *card) { return FM11RF08SH; } return FUDAN_NONE; -} +} static int fudan_get_type(iso14a_card_select_t *card, bool verbose) { @@ -211,7 +211,7 @@ static int CmdHFFudanReader(const char *Cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("v", "verbose", "Verbose scan and output"), + arg_lit0("v", "verbose", "verbose output"), arg_lit0("@", NULL, "optional - continuous reader mode"), arg_param_end }; @@ -223,10 +223,11 @@ static int CmdHFFudanReader(const char *Cmd) { CLIParserFree(ctx); if (cm) { - PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); - return read_fudan_uid(cm, verbose); + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); } + read_fudan_uid(cm, verbose); + DropField(); return PM3_SUCCESS; } @@ -237,7 +238,7 @@ static int CmdHFFudanDump(const char *Cmd) { "Dump FUDAN tag to binary file\n" "If no given, UID will be used as filename", "hf fudan dump -f mydump --> dump using filename\n" - ); + ); void *argtable[] = { arg_param_begin, @@ -257,7 +258,7 @@ static int CmdHFFudanDump(const char *Cmd) { int res = fudan_get_type(&card, false); if (res != PM3_SUCCESS) { PrintAndLogEx(FAILED, "failed to select a fudan card. Exiting..."); - DropField(); + DropField(); return PM3_SUCCESS; } @@ -265,14 +266,14 @@ static int CmdHFFudanDump(const char *Cmd) { fudan_type_t t = fudan_detected(&card); if (t == FUDAN_NONE) { PrintAndLogEx(FAILED, "failed to detect a fudan card. Exiting..."); - DropField(); + DropField(); return PM3_SUCCESS; } // detect card size // 512b, 8kbits uint8_t num_blocks = MAX_FUDAN_05_BLOCKS; - switch(t) { + switch (t) { case FM11RF008M: num_blocks = MAX_FUDAN_08_BLOCKS; break; @@ -286,19 +287,7 @@ static int CmdHFFudanDump(const char *Cmd) { uint8_t carddata[num_blocks * MAX_FUDAN_BLOCK_SIZE]; -/* - PrintAndLogEx(HINT, " hf 14a raw -a -b 7 -k 26"); - PrintAndLogEx(HINT, " hf 14a raw -k -c 3000"); - PrintAndLogEx(HINT, " hf 14a raw -k -c 3001"); - PrintAndLogEx(HINT, " hf 14a raw -k -c 3002"); - PrintAndLogEx(HINT, " hf 14a raw -k -c 3003"); - PrintAndLogEx(HINT, " hf 14a raw -k -c 3004"); - PrintAndLogEx(HINT, " hf 14a raw -k -c 3005"); - PrintAndLogEx(HINT, " hf 14a raw -k -c 3006"); - PrintAndLogEx(HINT, " hf 14a raw -c 3007"); -*/ - - // + // uint16_t flags = (ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS | ISO14A_RAW); uint32_t argtimeout = 0; uint32_t numbits = 0; @@ -306,7 +295,7 @@ static int CmdHFFudanDump(const char *Cmd) { PrintAndLogEx(SUCCESS, "." NOLF); // dump memory for (uint8_t b = 0; b < num_blocks; b++) { - + // read block uint8_t cmd[4] = {ISO14443A_CMD_READBLOCK, b, 0x00, 0x00}; AddCrc14A(cmd, 2); @@ -328,13 +317,13 @@ static int CmdHFFudanDump(const char *Cmd) { PrintAndLogEx(FAILED, "could not read block %2d", b); } } else { - PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(WARNING, "command execute timeout when trying to read block %2d", b); } } } - DropField(); + DropField(); PrintAndLogEx(SUCCESS, "\nSucceeded in dumping all blocks"); @@ -361,6 +350,107 @@ static int CmdHFFudanDump(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHFFudanWrBl(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fudan wrbl", + "Write fudan block with 4 hex bytes of data\n", + "hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 01020304" + ); + void *argtable[] = { + arg_param_begin, + arg_int1(NULL, "blk", "", "block number"), + arg_str0("k", "key", "", "key, 6 hex bytes"), + arg_str0("d", "data", "", "bytes to write, 4 hex bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int b = arg_get_int_def(ctx, 1, 1); + + int keylen = 0; + uint8_t key[6] = {0}; + CLIGetHexWithReturn(ctx, 2, key, &keylen); + + uint8_t block[MAX_FUDAN_BLOCK_SIZE] = {0x00}; + int blen = 0; + CLIGetHexWithReturn(ctx, 3, block, &blen); + CLIParserFree(ctx); + + if (blen != MAX_FUDAN_BLOCK_SIZE) { + PrintAndLogEx(WARNING, "block data must include 4 HEX bytes. Got %i", blen); + return PM3_EINVARG; + } + + if (b > 255) { + return PM3_EINVARG; + } + + PrintAndLogEx(SUCCESS, "Not implemented yet. Feel free to contribute!"); + + /* + + uint8_t blockno = (uint8_t)b; + + PrintAndLogEx(INFO, "Writing block no %d, key %s", blockno, sprint_hex_inrow(key, sizeof(key))); + PrintAndLogEx(INFO, "data: %s", sprint_hex(block, sizeof(block))); + + uint8_t data[26]; + memcpy(data, key, sizeof(key)); + memcpy(data + 10, block, sizeof(block)); + clearCommandBuffer(); + SendCommandMIX(CMD_HF_MIFARE_WRITEBL, blockno, 0, 0, data, sizeof(data)); + + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { + PrintAndLogEx(FAILED, "Command execute timeout"); + return PM3_ETIMEOUT; + } + + uint8_t isok = resp.oldarg[0] & 0xff; + if (isok) { + PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )"); + PrintAndLogEx(HINT, "try `" _YELLOW_("hf fudan rdbl") "` to verify"); + } else { + PrintAndLogEx(FAILED, "Write ( " _RED_("fail") " )"); + } + */ + return PM3_SUCCESS; +} + +static int CmdHFFudanRdBl(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fudan rdbl", + "Read fudan block", + "hf fudan rdbl --blk 0 -k FFFFFFFFFFFF\n" + "hf fudan rdbl --blk 3 -v\n" + ); + void *argtable[] = { + arg_param_begin, + arg_int1(NULL, "blk", "", "block number"), + arg_str0("k", "key", "", "key, 6 hex bytes"), + arg_lit0("v", "verbose", "verbose output"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + int b = arg_get_int_def(ctx, 1, 0); + + int keylen = 0; + uint8_t key[6] = {0}; + CLIGetHexWithReturn(ctx, 2, key, &keylen); +// bool verbose = arg_get_lit(ctx, 3); + CLIParserFree(ctx); + + if (b > 255) { + return PM3_EINVARG; + } + + PrintAndLogEx(SUCCESS, "Not implemented yet. Feel free to contribute!"); + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; +} + + static int CmdHFFudanView(const char *Cmd) { CLIParserContext *ctx; @@ -400,11 +490,11 @@ static int CmdHelp(const char *Cmd); static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"reader", CmdHFFudanReader, IfPm3Iso14443a, "Act like a fudan reader"}, - {"dump", CmdHFFudanDump, IfPm3Iso14443a, "Dump FUDAN tag to binary file"}, + {"dump", CmdHFFudanDump, IfPm3Iso14443a, "Dump FUDAN tag to binary file"}, //{"sim", CmdHFFudanSim, IfPm3Iso14443a, "Simulate a fudan tag"}, - //{"rdbl", CmdHFFudanRead, IfPm3Iso14443a, "Read a fudan tag"}, - {"view", CmdHFFudanView, AlwaysAvailable, "Display content from tag dump file"}, - //{"wrbl", CmdHFFudanWrite, IfPm3Iso14443a, "Write a fudan tag"}, + {"rdbl", CmdHFFudanRdBl, IfPm3Iso14443a, "Read a fudan tag"}, + {"view", CmdHFFudanView, AlwaysAvailable, "Display content from tag dump file"}, + {"wrbl", CmdHFFudanWrBl, IfPm3Iso14443a, "Write a fudan tag"}, {NULL, NULL, 0, NULL} }; From 02d07f16c9eb50efbb4028734d8e4acad306c27c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Jul 2022 11:48:37 +0200 Subject: [PATCH 160/759] prepair for extended reading for LTO --- client/src/cmdhflto.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/client/src/cmdhflto.c b/client/src/cmdhflto.c index feed30cf3..a0e6d00f8 100644 --- a/client/src/cmdhflto.c +++ b/client/src/cmdhflto.c @@ -201,6 +201,31 @@ static int lto_rdbl(uint8_t blk, uint8_t *block_response, uint8_t *block_cnt_res return PM3_SUCCESS; } +/* +static int lto_rdbl_ext(uint16_t blk, uint8_t *block_response, uint8_t *block_cnt_response, bool verbose) { + + if (blk && 0x) { + blk &= 0xFE; + } + + uint16_t resp_len = 18; + uint8_t rdbl_ext_cmd[] = {0x21 , blk & 0xFF, (blk >> 8) & 0xFF}; + uint8_t rdbl_cnt_cmd[] = {0x80}; + + int status = lto_send_cmd_raw(rdbl_ext_cmd, sizeof(rdbl_ext_cmd), block_response, &resp_len, true, false, verbose); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { + return PM3_EWRONGANSWER; // READ BLOCK failed + } + + status = lto_send_cmd_raw(rdbl_cnt_cmd, sizeof(rdbl_cnt_cmd), block_cnt_response, &resp_len, false, false, verbose); + if (status == PM3_ETIMEOUT || status == PM3_ESOFT) { + return PM3_EWRONGANSWER; // READ BLOCK CONTINUE failed + } + + return PM3_SUCCESS; +} +*/ + static int CmdHfLTOInfo(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf lto info", From ac0088791aaf1ae6b88359fd0dca2a55a4b82155 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Jul 2022 11:49:30 +0200 Subject: [PATCH 161/759] style --- client/src/cmdhfmf.c | 5 +++-- client/src/cmdhfmfdes.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index b5d061215..25c039f4e 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -3432,7 +3432,7 @@ static int CmdHF14AMfSim(const char *Cmd) { "hf mf sim --1k -u 11223344 -i -x --> Perform reader attack in interactive mode\n" "hf mf sim --2k --> MIFARE 2k\n" "hf mf sim --4k --> MIFARE 4k" - ); + ); void *argtable[] = { arg_param_begin, @@ -3651,6 +3651,7 @@ static int CmdHF14AMfKeyBrute(const char *Cmd) { void printKeyTable(uint8_t sectorscnt, sector_t *e_sector) { return printKeyTableEx(sectorscnt, e_sector, 0); } + void printKeyTableEx(uint8_t sectorscnt, sector_t *e_sector, uint8_t start_sector) { char strA[12 + 1] = {0}; char strB[12 + 1] = {0}; @@ -6529,7 +6530,7 @@ static command_t CommandTable[] = { {"personalize", CmdHFMFPersonalize, IfPm3Iso14443a, "Personalize UID (MIFARE Classic EV1 only)"}, {"rdbl", CmdHF14AMfRdBl, IfPm3Iso14443a, "Read MIFARE Classic block"}, {"rdsc", CmdHF14AMfRdSc, IfPm3Iso14443a, "Read MIFARE Classic sector"}, - {"restore", CmdHF14AMfRestore, IfPm3Iso14443a, "Restore MIFARE Classic binary file to BLANK tag"}, + {"restore", CmdHF14AMfRestore, IfPm3Iso14443a, "Restore MIFARE Classic binary file to tag"}, {"setmod", CmdHf14AMfSetMod, IfPm3Iso14443a, "Set MIFARE Classic EV1 load modulation strength"}, {"value", CmdHF14AMfValue, AlwaysAvailable, "Value blocks"}, {"view", CmdHF14AMfView, AlwaysAvailable, "Display content from tag dump file"}, diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 2993c8def..91592032e 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -325,7 +325,7 @@ static nxp_producttype_t getProductType(uint8_t *versionhw) { return DESFIRE_UNKNOWN_PROD; } -static const char* getProductTypeStr(uint8_t *versionhw) { +static const char *getProductTypeStr(uint8_t *versionhw) { uint8_t product = versionhw[2]; From 1df51f38753fe9c61a8ecc12daf7e4ceb5003e55 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Jul 2022 15:42:07 +0200 Subject: [PATCH 162/759] add hf lto reader command with continious mode --- client/src/cmdhf.c | 2 +- client/src/cmdhflto.c | 71 ++++++++++++++++++++++++++++++++++++++++--- client/src/cmdhflto.h | 1 + 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 44b9b078f..d1628a054 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -92,7 +92,7 @@ int CmdHFSearch(const char *Cmd) { PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, " Searching for LTO-CM tag..."); if (IfPm3Iso14443a()) { - if (infoLTO(false) == PM3_SUCCESS) { + if (reader_lto(false, false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("LTO-CM tag") " found\n"); res = PM3_SUCCESS; } diff --git a/client/src/cmdhflto.c b/client/src/cmdhflto.c index a0e6d00f8..1bdc7ac1a 100644 --- a/client/src/cmdhflto.c +++ b/client/src/cmdhflto.c @@ -385,6 +385,65 @@ static void lto_print_mmi(uint8_t *d) { // - Application Specific Data (1056b) // - Suspended Append Writes (128b) +static int CmdHFLTOReader(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf lto reader", + "Act as a LTO-CM reader. Look for LTO-CM tags until Enter or the pm3 button is pressed", + "hf lto reader -@ -> continuous reader mode" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0("@", NULL, "optional - continuous reader mode"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool cm = arg_get_lit(ctx, 1); + CLIParserFree(ctx); + + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + + return reader_lto(cm, true); +} + +int reader_lto(bool loop, bool verbose) { + + int ret = PM3_SUCCESS; + + do { + uint8_t serial[5]; + uint8_t serial_len = sizeof(serial); + uint8_t type_info[2]; + + lto_switch_off_field(); + lto_switch_on_field(); + clearCommandBuffer(); + + ret = lto_select(serial, serial_len, type_info, verbose); + if (loop) { + if (ret != PM3_SUCCESS) { + continue; + } + } + + if (ret == PM3_SUCCESS) { + + if (loop == false) { + PrintAndLogEx(NORMAL, ""); + } + + PrintAndLogEx(INFO, "UID......... " _GREEN_("%s"), sprint_hex_inrow(serial, sizeof(serial))); + } + + } while (loop && kbd_enter_pressed() == false); + + lto_switch_off_field(); + return ret; +} + int infoLTO(bool verbose) { clearCommandBuffer(); @@ -397,6 +456,7 @@ int infoLTO(bool verbose) { int ret_val = lto_select(serial_number, serial_len, type_info, verbose); if (verbose == false) { if (ret_val == PM3_SUCCESS) { + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "UID......... " _YELLOW_("%s"), sprint_hex_inrow(serial_number, sizeof(serial_number))); } lto_switch_off_field(); @@ -801,12 +861,13 @@ static int CmdHfLTRestore(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"dump", CmdHfLTODump, IfPm3Iso14443a, "Dump LTO-CM tag to file"}, - {"restore", CmdHfLTRestore, IfPm3Iso14443a, "Restore dump file to LTO-CM tag"}, - {"info", CmdHfLTOInfo, IfPm3Iso14443a, "Tag information"}, - {"rdbl", CmdHfLTOReadBlock, IfPm3Iso14443a, "Read block"}, - {"wrbl", CmdHfLTOWriteBlock, IfPm3Iso14443a, "Write block"}, + {"dump", CmdHfLTODump, IfPm3Iso14443a, "Dump LTO-CM tag to file"}, + {"info", CmdHfLTOInfo, IfPm3Iso14443a, "Tag information"}, {"list", CmdHfLTOList, AlwaysAvailable, "List LTO-CM history"}, + {"rdbl", CmdHfLTOReadBlock, IfPm3Iso14443a, "Read block"}, + {"reader", CmdHFLTOReader, IfPm3Iso14443a, "Act like a LTO-CM reader"}, + {"restore", CmdHfLTRestore, IfPm3Iso14443a, "Restore dump file to LTO-CM tag"}, + {"wrbl", CmdHfLTOWriteBlock, IfPm3Iso14443a, "Write block"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmdhflto.h b/client/src/cmdhflto.h index beade8fa9..3c9b310a4 100644 --- a/client/src/cmdhflto.h +++ b/client/src/cmdhflto.h @@ -21,6 +21,7 @@ #include "common.h" +int reader_lto(bool loop, bool verbose); int infoLTO(bool verbose); int dumpLTO(uint8_t *dump, bool verbose); int restoreLTO(uint8_t *dump, bool verbose); From 36ee2f082b59f245db912b747e38f83657a09b38 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Jul 2022 16:51:17 +0200 Subject: [PATCH 163/759] maur keys --- client/dictionaries/mfc_default_keys.dic | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index ad77c7a9e..ed2b1201d 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1740,3 +1740,7 @@ FFD46FF6C5EE 1C5179C4A8A1 16CA203B811B 11AC8C8F3AF2 +# +# Spackular +7CB033257498 # key A +1153AABAFF6C # key b From fd7216fa89940746cc89fe922131037e8372ec02 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Jul 2022 16:52:09 +0200 Subject: [PATCH 164/759] text --- client/dictionaries/mfc_default_keys.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index ed2b1201d..1b0d1aa4e 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1742,5 +1742,6 @@ FFD46FF6C5EE 11AC8C8F3AF2 # # Spackular +# data from http://www.proxmark.org/forum/viewtopic.php?pid=45100#p45100 7CB033257498 # key A 1153AABAFF6C # key b From 6fb4723cd6c3c757837cde805da1702e72d73616 Mon Sep 17 00:00:00 2001 From: George Talusan Date: Sat, 30 Jul 2022 12:18:43 -0400 Subject: [PATCH 165/759] fix homebrew dependency detection --- Makefile.defs | 10 +++++++--- client/Makefile | 5 ++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 9b6947094..5a131c971 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -78,9 +78,13 @@ else endif ifeq ($(USE_BREW),1) - BREW_PREFIX = $(shell brew --prefix 2>/dev/null) - ifeq ($(strip $(BREW_PREFIX)),) - USE_BREW = 0 + ifneq ($(strip $(HOMEBREW_PREFIX)),) + BREW_PREFIX = $(HOMEBREW_PREFIX) + else + BREW_PREFIX = $(shell brew --prefix 2>/dev/null) + ifeq ($(strip $(BREW_PREFIX)),) + USE_BREW = 0 + endif endif endif diff --git a/client/Makefile b/client/Makefile index b1d7bb671..64c35eff8 100644 --- a/client/Makefile +++ b/client/Makefile @@ -37,8 +37,7 @@ OBJDIR = obj ifeq ($(USE_BREW),1) INCLUDES += -I$(BREW_PREFIX)/include LDLIBS += -L$(BREW_PREFIX)/lib - PKG_CONFIG_ENV := PKG_CONFIG_PATH=$(BREW_PREFIX)/opt/qt/lib/pkgconfig - PKG_CONFIG_ENV := PKG_CONFIG_PATH=$(BREW_PREFIX)/opt/qt5/lib/pkgconfig + PKG_CONFIG_ENV := PKG_CONFIG_PATH=$(BREW_PREFIX)/lib/pkgconfig:$(BREW_PREFIX)/opt/qt/lib/pkgconfig:$(BREW_PREFIX)/opt/qt5/lib/pkgconfig endif ifdef ($(USE_MACPORTS),1) @@ -479,7 +478,7 @@ ifeq ($(SKIPPYTHON),1) $(info Python3 library: skipped) else ifeq ($(PYTHON_FOUND),1) - $(info Python3 library: Python3 v$(shell pkg-config --modversion python3) found, enabled) + $(info Python3 library: Python3 v$(shell $(PKG_CONFIG_ENV) pkg-config --modversion python3) found, enabled) else $(info Python3 library: Python3 not found, disabled) endif From a2366047168b9f92249f4546d0f5163a288cf402 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Jul 2022 20:11:15 +0200 Subject: [PATCH 166/759] style --- client/src/cmdlft55xx.c | 6 +++--- client/src/cmdsmartcard.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 00fa2b2c9..dccacc3b1 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -2235,7 +2235,7 @@ static int CmdT55xxDump(const char *Cmd) { int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; - CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, sizeof(filename), &fnlen); + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); uint8_t override = arg_get_lit(ctx, 2) ? 1 : 0; @@ -2341,7 +2341,7 @@ static int CmdT55xxRestore(const char *Cmd) { int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; - CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, sizeof(filename), &fnlen); + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); bool usepwd = false; uint32_t password = 0; @@ -3035,7 +3035,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; - CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, sizeof(filename), &fnlen); + CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); // White cloner password based on EM4100 ID bool use_calc_password = false; diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index 3e273fc07..c6bfe648d 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -513,7 +513,7 @@ static int CmdSmartUpgrade(const char *Cmd) { CLIExecWithReturn(ctx, Cmd, argtable, true); int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; - CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, sizeof(filename), &fnlen); + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParserFree(ctx); char *bin_extension = filename; From 2cfc4dc733871b5c72c00866feb6dbb09cd7a32b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 30 Jul 2022 20:11:39 +0200 Subject: [PATCH 167/759] minor hitag adaptations --- client/src/cmdlfhitag.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 4f891ffda..a728bb6ff 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -627,6 +627,9 @@ static int CmdLFHitagReader(const char *Cmd) { // block3, 1 byte printHitag2Configuration(data[4 * 3]); + + // print data + print_hex_break(data, 48, 4); } return PM3_SUCCESS; } @@ -820,17 +823,14 @@ static int CmdLFHitag2Dump(const char *Cmd) { arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); - uint8_t filename[FILE_PATH_SIZE] = {0}; + int fnlen = 0; - int res = CLIParamHexToBuf(arg_get_str(ctx, 1), filename, sizeof(filename), &fnlen); - if (res != 0) { - CLIParserFree(ctx); - return PM3_EINVARG; - } + char filename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); uint8_t key[6]; int keylen = 0; - res = CLIParamHexToBuf(arg_get_str(ctx, 2), key, sizeof(key), &keylen); + int res = CLIParamHexToBuf(arg_get_str(ctx, 2), key, sizeof(key), &keylen); if (res != 0) { CLIParserFree(ctx); return PM3_EINVARG; @@ -844,22 +844,22 @@ static int CmdLFHitag2Dump(const char *Cmd) { return PM3_EINVARG; } - PrintAndLogEx(WARNING, "to be implemented..."); + PrintAndLogEx(SUCCESS, "Dumping tag memory..."); - /* - PrintAndLogEx(SUCCESS, "Dumping tag memory..."); + clearCommandBuffer(); + //SendCommandNG(CMD_LF_HITAG_DUMP, &htd, sizeof(htd)); + PacketResponseNG resp; + uint8_t *data = resp.data.asBytes; - clearCommandBuffer(); - //SendCommandNG(CMD_LF_HITAG_DUMP, &htd, sizeof(htd)); - PacketResponseNG resp; - uint8_t *data = resp.data.asBytes; - if (fnlen < 1) { - char *fptr = filename + snprintf(filename, sizeof(filename), "lf-hitag-"); - FillFileNameByUID(fptr, data, "-dump", 4); - } + if (fnlen < 1) { + char *fptr = filename; + fptr += snprintf(filename, sizeof(filename), "lf-hitag-"); + FillFileNameByUID(fptr, data, "-dump", 4); + } - pm3_save_dump(filename, data, 48, jsfHitag, 4); - */ + print_hex_break(data, 48, 4); + + pm3_save_dump(filename, data, 48, jsfHitag, 4); return PM3_SUCCESS; } From 3e222397ac9d64f0df4b5cad8a32131c972c1dfa Mon Sep 17 00:00:00 2001 From: George Talusan Date: Sat, 30 Jul 2022 14:48:14 -0400 Subject: [PATCH 168/759] determine qmake path similar to uic/moc --- client/Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/Makefile b/client/Makefile index 64c35eff8..ba620c84c 100644 --- a/client/Makefile +++ b/client/Makefile @@ -289,6 +289,7 @@ ifneq ($(SKIPQT),1) QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null) MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/moc UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/uic + QMAKE = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=host_bins Qt5Core)/qmake ifneq ($(QTLDLIBS),) QT5_FOUND = 1 else @@ -297,6 +298,7 @@ ifneq ($(SKIPQT),1) QTLDLIBS = $(shell $(PKG_CONFIG_ENV) pkg-config --libs QtCore QtGui 2>/dev/null) MOC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=moc_location QtCore) UIC = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=uic_location QtCore) + QMAKE = $(shell $(PKG_CONFIG_ENV) pkg-config --variable=exec_prefix QtCore)/bin/qmake endif ifeq ($(QTLDLIBS),) # if both pkg-config commands failed, search in common places @@ -313,6 +315,7 @@ ifneq ($(SKIPQT),1) endif MOC = $(QTDIR)/bin/moc UIC = $(QTDIR)/bin/uic + QMAKE = $(QTDIR)/bin/qmake endif endif ifneq ($(QTLDLIBS),) @@ -437,9 +440,9 @@ ifeq ($(SKIPQT),1) else ifeq ($(QT_FOUND),1) ifeq ($(QT5_FOUND),1) - $(info GUI support: QT5 found, enabled ($(shell QT_SELECT=5 qmake -v 2>/dev/null|grep -o 'Qt version.*'))) + $(info GUI support: QT5 found, enabled ($(shell QT_SELECT=5 $(QMAKE) -v 2>/dev/null|grep -o 'Qt version.*'))) else - $(info GUI support: QT4 found, enabled ($(shell QT_SELECT=4 qmake -v 2>/dev/null|grep -o 'Qt version.*'))) + $(info GUI support: QT4 found, enabled ($(shell QT_SELECT=4 $(QMAKE) -v 2>/dev/null|grep -o 'Qt version.*'))) endif else $(info GUI support: QT not found, disabled) From 27e24482af1bc4a3a7c21e56266c9810ce04152c Mon Sep 17 00:00:00 2001 From: George Talusan Date: Sat, 30 Jul 2022 16:02:34 -0400 Subject: [PATCH 169/759] add comment indicating pyamiibo should be installed --- client/pyscripts/amiibo_change_uid.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/pyscripts/amiibo_change_uid.py b/client/pyscripts/amiibo_change_uid.py index 725a4f5e0..4c7b2354a 100644 --- a/client/pyscripts/amiibo_change_uid.py +++ b/client/pyscripts/amiibo_change_uid.py @@ -1,3 +1,6 @@ +# Requirements: +# python3 -m pip install pyamiibo + import sys from amiibo import AmiiboDump, AmiiboMasterKey From de9be10d28b9d8b76354e6ad81544a850a45c117 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 31 Jul 2022 13:06:55 +0200 Subject: [PATCH 170/759] 14a reader/info - now hints topaz tags better --- client/src/cmdhf14a.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index dbd289820..8eeb0f402 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -400,7 +400,12 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card) { if (select_status == 3) { PrintAndLogEx(INFO, "E->Card doesn't support standard iso14443-3 anticollision"); - PrintAndLogEx(SUCCESS, "\tATQA : %02X %02X", card->atqa[1], card->atqa[0]); + // identify TOPAZ + if (card->atqa[1] == 0x0C && card->atqa[0] == 0x00) { + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf topaz info`")); + } else { + PrintAndLogEx(SUCCESS, "\tATQA : %02X %02X", card->atqa[1], card->atqa[0]); + } return 1; } @@ -511,7 +516,14 @@ static int CmdHF14AReader(const char *Cmd) { if (select_status == 3) { if (!(silent && continuous)) { PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision"); - PrintAndLogEx(SUCCESS, "ATQA: %02X %02X", card.atqa[1], card.atqa[0]); + + // identify TOPAZ + if (card.atqa[1] == 0x0C && card.atqa[0] == 0x00) { + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf topaz info`")); + } else { + PrintAndLogEx(SUCCESS, "ATQA: %02X %02X", card.atqa[1], card.atqa[0]); + } + } DropField(); res = PM3_ESOFT; @@ -1763,7 +1775,16 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if (select_status == 3) { PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision"); - PrintAndLogEx(SUCCESS, "ATQA: %02X %02X", card.atqa[1], card.atqa[0]); + + if (verbose) { + PrintAndLogEx(SUCCESS, "ATQA: %02X %02X", card.atqa[1], card.atqa[0]); + } + + // identify TOPAZ + if (card.atqa[1] == 0x0C && card.atqa[0] == 0x00) { + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf topaz info`")); + } + DropField(); return select_status; } From bf81acb55b92b07829ef82c96e2746821a801bfc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 31 Jul 2022 13:08:37 +0200 Subject: [PATCH 171/759] hf topaz reader - output and continuous mode support. hf topaz info - output text changes --- client/src/cmdhf.c | 2 +- client/src/cmdhftopaz.c | 254 +++++++++++++++++++++++++--------------- client/src/cmdhftopaz.h | 2 +- 3 files changed, 162 insertions(+), 96 deletions(-) diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index d1628a054..81e64584a 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -141,7 +141,7 @@ int CmdHFSearch(const char *Cmd) { PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, " Searching for Topaz tag..."); if (IfPm3Iso14443a()) { - if (readTopazUid(false) == PM3_SUCCESS) { + if (readTopazUid(false, false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Topaz tag") " found\n"); res = PM3_SUCCESS; } diff --git a/client/src/cmdhftopaz.c b/client/src/cmdhftopaz.c index 778471b99..12a445408 100644 --- a/client/src/cmdhftopaz.c +++ b/client/src/cmdhftopaz.c @@ -33,7 +33,12 @@ #include "nfc/ndef.h" #include "fileutils.h" // saveFile -#define TOPAZ_STATIC_MEMORY (0x0f * 8) // 15 blocks with 8 Bytes each + +#ifndef AddCrc14B +# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) +#endif + +#define TOPAZ_STATIC_MEMORY (0x0F * 8) // 15 blocks with 8 Bytes each // a struct to describe a memory area which contains lock bits and the corresponding lockable memory area typedef struct dynamic_lock_area { @@ -88,10 +93,7 @@ static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response, uint // calculate CRC bytes and send topaz command, returns the length of the response (0 in case of error) static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response, uint16_t *response_len, bool verbose) { if (len > 1) { - uint8_t b1, b2; - compute_crc(CRC_14443_B, cmd, len - 2, &b1, &b2); - cmd[len - 2] = b1; - cmd[len - 1] = b2; + AddCrc14B(cmd, len - 2); } return topaz_send_cmd_raw(cmd, len, response, response_len, verbose); @@ -126,7 +128,8 @@ static int topaz_select(uint8_t *atqa, uint8_t atqa_len, uint8_t *rid_response, // read all of the static memory of a selected Topaz tag. static int topaz_rall(uint8_t *uid, uint8_t *response) { - uint16_t resp_len = 0; + + uint16_t resp_len = 124; uint8_t rall_cmd[] = {TOPAZ_RALL, 0, 0, 0, 0, 0, 0, 0, 0}; memcpy(&rall_cmd[3], uid, 4); @@ -230,13 +233,16 @@ static int topaz_print_CC(uint8_t *data) { PrintAndLogEx(SUCCESS, "Capability Container: %02x %02x %02x %02x", data[0], data[1], data[2], data[3]); PrintAndLogEx(SUCCESS, " %02x: NDEF Magic Number", data[0]); PrintAndLogEx(SUCCESS, " %02x: version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f); + uint16_t memsize = (data[2] + 1) * 8; topaz_tag.size = memsize; topaz_tag.dynamic_memory = calloc(memsize - TOPAZ_STATIC_MEMORY, sizeof(uint8_t)); + PrintAndLogEx(SUCCESS, " %02x: Physical Memory Size of this tag: %d bytes", data[2], memsize); PrintAndLogEx(SUCCESS, " %02x: %s / %s", data[3], (data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security", (data[3] & 0x0F) == 0 ? "Write access granted without any security" : (data[3] & 0x0F) == 0x0F ? "No write access granted at all" : "(RFU)"); + return PM3_SUCCESS; } @@ -295,8 +301,10 @@ static void topaz_print_control_TLVs(uint8_t *memory) { uint16_t next_lockable_byte = 0x0f * 8; // first byte after static memory area while (*TLV_ptr != 0x03 && *TLV_ptr != 0xFD && *TLV_ptr != 0xFE) { + // all Lock Control TLVs shall be present before the NDEF message TLV, the proprietary TLV (and the Terminator TLV) get_TLV(&TLV_ptr, &TLV_type, &TLV_length, &TLV_value); + if (TLV_type == 0x01) { // a Lock Control TLV uint8_t pages_addr = TLV_value[0] >> 4; uint8_t byte_offset = TLV_value[0] & 0x0f; @@ -305,13 +313,16 @@ static void topaz_print_control_TLVs(uint8_t *memory) { uint16_t bytes_per_page = 1 << (TLV_value[2] & 0x0f); uint16_t bytes_locked_per_bit = 1 << (TLV_value[2] >> 4); uint16_t area_start = pages_addr * bytes_per_page + byte_offset; + PrintAndLogEx(SUCCESS, "Lock Area of %d bits at byte offset 0x%04x. Each Lock Bit locks %d bytes.", size_in_bits, area_start, bytes_locked_per_bit); + lock_TLV_present = true; dynamic_lock_area_t *old = topaz_tag.dynamic_lock_areas; dynamic_lock_area_t *new; + if (old == NULL) { new = topaz_tag.dynamic_lock_areas = (dynamic_lock_area_t *) calloc(sizeof(dynamic_lock_area_t), sizeof(uint8_t)); } else { @@ -321,38 +332,45 @@ static void topaz_print_control_TLVs(uint8_t *memory) { new = old->next = (dynamic_lock_area_t *) calloc(sizeof(dynamic_lock_area_t), sizeof(uint8_t)); } new->next = NULL; + if (area_start <= next_lockable_byte) { // lock areas are not lockable next_lockable_byte += size_in_bytes; } + new->first_locked_byte = next_lockable_byte; new->byte_offset = area_start; new->size_in_bits = size_in_bits; new->bytes_locked_per_bit = bytes_locked_per_bit; next_lockable_byte += size_in_bits * bytes_locked_per_bit; } + if (TLV_type == 0x02) { // a Reserved Memory Control TLV uint8_t pages_addr = TLV_value[0] >> 4; uint8_t byte_offset = TLV_value[0] & 0x0f; uint16_t size_in_bytes = TLV_value[1] ? TLV_value[1] : 256; uint8_t bytes_per_page = 1 << (TLV_value[2] & 0x0f); uint16_t area_start = pages_addr * bytes_per_page + byte_offset; + PrintAndLogEx(SUCCESS, "Reserved Memory of %d bytes at byte offset 0x%02x.", size_in_bytes, area_start); + reserved_memory_control_TLV_present = true; - adjust_lock_areas(area_start, size_in_bytes); // reserved memory areas are not lockable + + // reserved memory areas are not lockable + adjust_lock_areas(area_start, size_in_bytes); if (area_start <= next_lockable_byte) { next_lockable_byte += size_in_bytes; } } } - if (!lock_TLV_present) { + if (lock_TLV_present == false) { PrintAndLogEx(SUCCESS, "(No Lock Control TLV present)"); } - if (!reserved_memory_control_TLV_present) { + if (reserved_memory_control_TLV_present == false) { PrintAndLogEx(SUCCESS, "(No Reserved Memory Control TLV present)"); } } @@ -378,23 +396,31 @@ static int topaz_read_dynamic_data(void) { // read and print the dynamic memory static void topaz_print_dynamic_data(void) { - if (topaz_tag.size > TOPAZ_STATIC_MEMORY) { - PrintAndLogEx(SUCCESS, "Dynamic Data blocks:"); - if (topaz_read_dynamic_data() == 0) { - PrintAndLogEx(NORMAL, "block# | offset | Data | Locked(y/n)"); - PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); - char line[80]; - for (uint16_t blockno = 0x0F; blockno < topaz_tag.size / 8; blockno++) { - uint8_t *block_data = &topaz_tag.dynamic_memory[(blockno - 0x0F) * 8]; - char lockbits[9]; - for (uint16_t j = 0; j < 8; j++) { - int offset = 3 * j; - snprintf(line + offset, sizeof(line) - offset, "%02x ", block_data[j]); - lockbits[j] = topaz_byte_is_locked(blockno * 8 + j) ? 'y' : 'n'; - } - lockbits[8] = '\0'; - PrintAndLogEx(NORMAL, " 0x%02x | 0x%04x | %s| %-3s", blockno, blockno * 8, line, lockbits); + + if (topaz_tag.size <= TOPAZ_STATIC_MEMORY) { + return; + } + + PrintAndLogEx(SUCCESS, "Dynamic Data blocks:"); + + if (topaz_read_dynamic_data() == 0) { + + PrintAndLogEx(NORMAL, "block# | offset | Data | Locked (y/n)"); + PrintAndLogEx(NORMAL, "-------+--------+-------------------------+-------------"); + + char line[80]; + for (uint16_t blockno = 0x0F; blockno < topaz_tag.size / 8; blockno++) { + + uint8_t *block_data = &topaz_tag.dynamic_memory[(blockno - 0x0F) * 8]; + char lockbits[9]; + for (uint16_t j = 0; j < 8; j++) { + int offset = 3 * j; + snprintf(line + offset, sizeof(line) - offset, "%02x ", block_data[j]); + lockbits[j] = topaz_byte_is_locked(blockno * 8 + j) ? 'y' : 'n'; } + lockbits[8] = '\0'; + + PrintAndLogEx(NORMAL, " 0x%02x | 0x%04x | %s| %-3s", blockno, blockno * 8, line, lockbits); } } } @@ -407,20 +433,30 @@ static int CmdHFTopazReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf topaz reader", "Read UID from Topaz tags", - "hf topaz reader"); + "hf topaz reader\n" + "hf topaz reader -@ -> Continuous mode\n" + ); void *argtable[] = { arg_param_begin, arg_lit0("v", "verbose", "verbose output"), + arg_lit0("@", NULL, "optional - continuous reader mode"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); bool verbose = arg_get_lit(ctx, 1); - + bool cm = arg_get_lit(ctx, 2); CLIParserFree(ctx); - return readTopazUid(verbose); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + + int res = readTopazUid(cm, verbose); + + topaz_switch_off_field(); + return res; } // read a Topaz tag and print some useful information @@ -447,47 +483,68 @@ int CmdHFTopazInfo(const char *Cmd) { CLIParserFree(ctx); - int status = readTopazUid(verbose); - if (status != PM3_SUCCESS) + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------"); + + int status = readTopazUid(false, verbose); + if (status != PM3_SUCCESS) { return status; + } + PrintAndLogEx(SUCCESS, "MANUFACTURER: " _YELLOW_("%s"), getTagInfo(topaz_tag.uid[6])); + + // ToDo: CRC check + PrintAndLogEx(SUCCESS, " HR: " _GREEN_("%02X %02X"), topaz_tag.HR01[0], topaz_tag.HR01[1]); + PrintAndLogEx(SUCCESS, " ^^"); + + PrintAndLogEx(SUCCESS, " %s", sprint_bin(topaz_tag.HR01, 1)); + PrintAndLogEx(SUCCESS, " x.......... TOPAZ tag ( %s ) - NDEF capable ( %s )", + (topaz_tag.HR01[0] & 0xF0) == 0x10 ? _GREEN_("yes") : _RED_("no"), + (topaz_tag.HR01[0] & 0xF0) == 0x10 ? _GREEN_("yes") : _RED_("no") + ); + PrintAndLogEx(SUCCESS, " x... %s memory map", ((topaz_tag.HR01[0] & 0x0F) == 0x01) ? "Static" : "Dynamic" ); PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Static Data blocks " _YELLOW_("0x00") " to " _YELLOW_("0x0C")":"); PrintAndLogEx(NORMAL, "block# | offset | Data | Locked"); PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); + char line[80]; - for (uint16_t i = 0; i <= 0x0c; i++) { + for (uint8_t i = 0; i <= 0x0C; i++) { + char lockbits[9]; - for (uint16_t j = 0; j < 8; j++) { + for (uint8_t j = 0; j < 8; j++) { int offset = 3 * j; snprintf(line + offset, sizeof(line) - offset, "%02x ", topaz_tag.data_blocks[i][j] /*rall_response[2 + 8*i + j]*/); lockbits[j] = topaz_byte_is_locked(i * 8 + j) ? 'y' : 'n'; } lockbits[8] = '\0'; - PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", i, i * 8, line, lockbits); + PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", i, i * 8, line, lockbits); } PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "Static Reserved block " _YELLOW_("0x0D")":"); - for (uint16_t j = 0; j < 8; j++) { + + for (uint8_t j = 0; j < 8; j++) { int offset = 3 * j; snprintf(line + offset, sizeof(line) - offset, "%02x ", topaz_tag.data_blocks[0x0d][j]); } + PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0d, 0x0d * 8, line, "n/a"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "Static Lockbits and OTP Bytes:"); - for (uint16_t j = 0; j < 8; j++) { + + for (uint8_t j = 0; j < 8; j++) { int offset = 3 * j; snprintf(line + offset, sizeof(line) - offset, "%02x ", topaz_tag.data_blocks[0x0e][j]); } + PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0e, 0x0e * 8, line, "n/a"); PrintAndLogEx(NORMAL, ""); status = topaz_print_CC(&topaz_tag.data_blocks[1][0]); - if (status == PM3_ESOFT) { PrintAndLogEx(SUCCESS, "No NDEF message data present"); topaz_switch_off_field(); @@ -532,7 +589,7 @@ static int CmdHFTopazCmdRaw(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf topaz raw", "Send raw hex data to Topaz tags", - "hf topaz raw -> Not yet implemented"); + "hf topaz raw"); void *argtable[] = { arg_param_begin, @@ -540,8 +597,7 @@ static int CmdHFTopazCmdRaw(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, true); CLIParserFree(ctx); - - PrintAndLogEx(INFO, "not yet implemented. Use hf 14 raw with option -T."); + PrintAndLogEx(INFO, "not yet implemented. Use `hf 14 raw --topaz` meanwhile"); return PM3_SUCCESS; } @@ -575,7 +631,7 @@ static command_t CommandTable[] = { {"list", CmdHFTopazList, AlwaysAvailable, "List Topaz history"}, {"info", CmdHFTopazInfo, IfPm3Iso14443a, "Tag information"}, {"reader", CmdHFTopazReader, IfPm3Iso14443a, "Act like a Topaz reader"}, - {"sim", CmdHFTopazSim, IfPm3Iso14443a, " -- Simulate Topaz tag"}, + {"sim", CmdHFTopazSim, IfPm3Iso14443a, "Simulate Topaz tag"}, {"sniff", CmdHFTopazSniff, IfPm3Iso14443a, "Sniff Topaz reader-tag communication"}, {"raw", CmdHFTopazCmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"}, {NULL, NULL, 0, NULL} @@ -592,72 +648,82 @@ int CmdHFTopaz(const char *Cmd) { return CmdsParse(CommandTable, Cmd); } -int readTopazUid(bool verbose) { +int readTopazUid(bool loop, bool verbose) { - uint8_t atqa[2] = {0}; - uint8_t rid_response[8] = {0}; - uint8_t *uid_echo = &rid_response[2]; - uint8_t rall_response[124] = {0}; + int res = PM3_SUCCESS; - int status = topaz_select(atqa, sizeof(atqa), rid_response, sizeof(rid_response), verbose); - if (status == PM3_ESOFT) { - if (verbose) PrintAndLogEx(ERR, "Error: couldn't receive ATQA"); - return PM3_ESOFT; - } + do { + uint8_t atqa[2] = {0}; + uint8_t rid_response[8] = {0}; + uint8_t *uid_echo = &rid_response[2]; + uint8_t rall_response[124] = {0}; - if (atqa[1] != 0x0c && atqa[0] != 0x00) { - if (verbose) PrintAndLogEx(ERR, "Tag doesn't support the Topaz protocol."); - topaz_switch_off_field(); - return PM3_ESOFT; - } + int status = topaz_select(atqa, sizeof(atqa), rid_response, sizeof(rid_response), verbose); + if (status == PM3_ESOFT) { + if (verbose) PrintAndLogEx(ERR, "Error: couldn't receive ATQA"); - if (status == PM3_EWRONGANSWER) { - if (verbose) PrintAndLogEx(ERR, "Error: tag didn't answer to RID"); - topaz_switch_off_field(); - return PM3_ESOFT; - } + if (loop) { + continue; + } - status = topaz_rall(uid_echo, rall_response); - if (status == PM3_ESOFT) { - PrintAndLogEx(ERR, "Error: tag didn't answer to RALL"); - topaz_switch_off_field(); - return PM3_ESOFT; - } + res = status; + break; + } - memcpy(topaz_tag.uid, rall_response + 2, 7); - memcpy(topaz_tag.data_blocks, rall_response + 2, 0x0f * 8); + if (atqa[1] != 0x0c && atqa[0] != 0x00) { + if (verbose) PrintAndLogEx(ERR, "Tag doesn't support the Topaz protocol."); - // printing - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------"); - PrintAndLogEx(SUCCESS, " UID: %02x %02x %02x %02x %02x %02x %02x", - topaz_tag.uid[6], - topaz_tag.uid[5], - topaz_tag.uid[4], - topaz_tag.uid[3], - topaz_tag.uid[2], - topaz_tag.uid[1], - topaz_tag.uid[0]); + if (loop) { + continue; + } - PrintAndLogEx(SUCCESS, " UID[6] (Manufacturer Byte) = " _YELLOW_("%02x")", Manufacturer: " _YELLOW_("%s"), - topaz_tag.uid[6], - getTagInfo(topaz_tag.uid[6]) - ); + res = PM3_ESOFT; + break; + } - PrintAndLogEx(SUCCESS, " ATQA: %02x %02x", atqa[1], atqa[0]); + if (status == PM3_EWRONGANSWER) { + if (verbose) PrintAndLogEx(ERR, "Error: tag didn't answer to RID"); - topaz_tag.HR01[0] = rid_response[0]; - topaz_tag.HR01[1] = rid_response[1]; + if (loop) { + continue; + } + res = status; + break; + } - // ToDo: CRC check - PrintAndLogEx(SUCCESS, " HR0: %02x (%sa Topaz tag (%scapable of carrying a NDEF message), %s memory map)", - rid_response[0], - (rid_response[0] & 0xF0) == 0x10 ? "" : "not ", - (rid_response[0] & 0xF0) == 0x10 ? "" : "not ", - (rid_response[0] & 0x0F) == 0x01 ? "static" : "dynamic"); + status = topaz_rall(uid_echo, rall_response); + if (status == PM3_ESOFT) { + PrintAndLogEx(ERR, "Error: tag didn't answer to RALL"); - PrintAndLogEx(SUCCESS, " HR1: %02x", rid_response[1]); + if (loop) { + continue; + } + + res = status; + break; + } + + memcpy(topaz_tag.uid, rall_response + 2, 7); + memcpy(topaz_tag.data_blocks, rall_response + 2, 0x0F * 8); + + // printing + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%02X %02X %02X %02X %02X %02X %02X"), + topaz_tag.uid[6], + topaz_tag.uid[5], + topaz_tag.uid[4], + topaz_tag.uid[3], + topaz_tag.uid[2], + topaz_tag.uid[1], + topaz_tag.uid[0]); + + PrintAndLogEx(SUCCESS, "ATQA: " _GREEN_("%02X %02X"), atqa[1], atqa[0]); + + topaz_tag.HR01[0] = rid_response[0]; + topaz_tag.HR01[1] = rid_response[1]; + + } while (loop && kbd_enter_pressed() == false); topaz_switch_off_field(); - return PM3_SUCCESS; + return res; } diff --git a/client/src/cmdhftopaz.h b/client/src/cmdhftopaz.h index 499436107..773508798 100644 --- a/client/src/cmdhftopaz.h +++ b/client/src/cmdhftopaz.h @@ -24,5 +24,5 @@ int CmdHFTopaz(const char *Cmd); int CmdHFTopazInfo(const char *Cmd); -int readTopazUid(bool verbose); +int readTopazUid(bool loop, bool verbose); #endif From 566b805357dbd2fbcb8fcabdf68d06bd5c7b2f00 Mon Sep 17 00:00:00 2001 From: George Talusan Date: Sat, 30 Jul 2022 23:30:17 -0400 Subject: [PATCH 172/759] add -i to hf emrtd info --- client/src/cmdhfemrtd.c | 82 ++++------------------------------------ client/src/cmdhfemrtd.h | 2 +- client/src/proxgui.cpp | 8 ++-- client/src/proxgui.h | 2 +- client/src/proxguiqt.cpp | 27 +++---------- client/src/proxguiqt.h | 6 +-- 6 files changed, 23 insertions(+), 104 deletions(-) diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index cb656b169..f68f01655 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -1433,42 +1433,7 @@ static int emrtd_print_ef_dg2_info(uint8_t *data, size_t datalen) { return PM3_ESOFT; } - bool is_jpg = (data[offset] == 0xFF); - - size_t fn_len = strlen(dg_table[EF_DG2].filename) + 4 + 1; - char *fn = calloc(fn_len, sizeof(uint8_t)); - if (fn == NULL) - return PM3_EMALLOC; - - snprintf(fn, fn_len * sizeof(uint8_t), "%s.%s", dg_table[EF_DG2].filename, (is_jpg) ? "jpg" : "jp2"); - - PrintAndLogEx(DEBUG, "image filename `" _YELLOW_("%s") "`", fn); - - char *path; - if (searchHomeFilePath(&path, NULL, fn, false) != PM3_SUCCESS) { - free(fn); - return PM3_EFILE; - } - free(fn); - - // remove old file - if (fileExists(path)) { - PrintAndLogEx(DEBUG, "Delete old temp file `" _YELLOW_("%s") "`", path); - remove(path); - } - - // temp file. - PrintAndLogEx(DEBUG, "Save temp file `" _YELLOW_("%s") "`", path); - saveFile(path, "", data + offset, datalen); - - PrintAndLogEx(DEBUG, "view temp file `" _YELLOW_("%s") "`", path); - ShowPictureWindow(path); - msleep(500); - - // delete temp file - PrintAndLogEx(DEBUG, "Deleting temp file `" _YELLOW_("%s") "`", path); - remove(path); - //free(path); + ShowPictureWindow(data + offset, datalen); return PM3_SUCCESS; } @@ -1493,42 +1458,7 @@ static int emrtd_print_ef_dg5_info(uint8_t *data, size_t datalen) { return PM3_ESOFT; } - bool is_jpg = (data[offset] == 0xFF); - - size_t fn_len = strlen(dg_table[EF_DG5].filename) + 4 + 1; - char *fn = calloc(fn_len, sizeof(uint8_t)); - if (fn == NULL) - return PM3_EMALLOC; - - snprintf(fn, fn_len * sizeof(uint8_t), "%s.%s", dg_table[EF_DG5].filename, (is_jpg) ? "jpg" : "jp2"); - - PrintAndLogEx(DEBUG, "image filename `" _YELLOW_("%s") "`", fn); - - char *path; - if (searchHomeFilePath(&path, NULL, fn, false) != PM3_SUCCESS) { - free(fn); - return PM3_EFILE; - } - free(fn); - - // remove old file - if (fileExists(path)) { - PrintAndLogEx(DEBUG, "Delete old temp file `" _YELLOW_("%s") "`", path); - remove(path); - } - - // temp file. - PrintAndLogEx(DEBUG, "Save temp file `" _YELLOW_("%s") "`", path); - saveFile(path, "", data + offset, datalen); - - PrintAndLogEx(DEBUG, "view temp file `" _YELLOW_("%s") "`", path); - ShowPictureWindow(path); - msleep(500); - - // delete temp file - PrintAndLogEx(DEBUG, "Deleting temp file `" _YELLOW_("%s") "`", path); - remove(path); - //free(path); + ShowPictureWindow(data + offset, datalen); return PM3_SUCCESS; } @@ -1915,7 +1845,7 @@ static int emrtd_print_ef_cardaccess_info(uint8_t *data, size_t datalen) { return PM3_SUCCESS; } -int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_available) { +int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_available, bool only_fast) { uint8_t response[EMRTD_MAX_FILE_SIZE] = { 0x00 }; size_t resplen = 0; uint8_t ssc[8] = { 0x00 }; @@ -2001,7 +1931,7 @@ int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_availab PrintAndLogEx(INFO, "File tag not found, skipping: %02X", filelist[i]); continue; } - if (dg->fastdump && !dg->pace && !dg->eac) { + if (((dg->fastdump && only_fast) || !only_fast) && !dg->pace && !dg->eac) { if (emrtd_select_and_read(response, &resplen, dg->fileid, ks_enc, ks_mac, ssc, BAC)) { if (dg->parser != NULL) dg->parser(response, resplen); @@ -2263,6 +2193,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { arg_str0("e", "expiry", "", "expiry in YYMMDD format"), arg_str0("m", "mrz", "<[0-9A-Z<]>", "2nd line of MRZ, 44 chars (passports only)"), arg_str0(NULL, "path", "", "display info from offline dump stored in dirpath"), + arg_lit0("i", "images", "show images"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -2329,6 +2260,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { } uint8_t path[FILENAME_MAX] = { 0x00 }; bool is_offline = CLIParamStrToBuf(arg_get_str(ctx, 5), path, sizeof(path), &slen) == 0 && slen > 0; + bool show_images = arg_get_lit(ctx, 6); CLIParserFree(ctx); if ((! IfPm3Iso14443()) && (! is_offline)) { PrintAndLogEx(WARNING, "Only offline mode is available"); @@ -2344,7 +2276,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { if (g_debugMode >= 2) { SetAPDULogging(true); } - int res = infoHF_EMRTD((char *)docnum, (char *)dob, (char *)expiry, BAC); + int res = infoHF_EMRTD((char *)docnum, (char *)dob, (char *)expiry, BAC, !show_images); SetAPDULogging(restore_apdu_logging); return res; } diff --git a/client/src/cmdhfemrtd.h b/client/src/cmdhfemrtd.h index 1b9588983..962501331 100644 --- a/client/src/cmdhfemrtd.h +++ b/client/src/cmdhfemrtd.h @@ -63,7 +63,7 @@ typedef struct emrtd_pacesdp_s { int CmdHFeMRTD(const char *Cmd); int dumpHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_available, const char *path); -int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_available); +int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_available, bool only_fast); int infoHF_EMRTD_offline(const char *path); #ifdef __cplusplus diff --git a/client/src/proxgui.cpp b/client/src/proxgui.cpp index 5019e1946..9d95a372d 100644 --- a/client/src/proxgui.cpp +++ b/client/src/proxgui.cpp @@ -67,11 +67,13 @@ extern "C" void RepaintGraphWindow(void) { // hook up picture viewer -extern "C" void ShowPictureWindow(char *fn) { +extern "C" void ShowPictureWindow(uint8_t *data, int len) { // No support for jpeg2000 in Qt Image since a while... // https://doc.qt.io/qt-5/qtimageformats-index.html - if (strlen(fn) > 4 && !strcmp(fn + strlen(fn) - 4, ".jp2")) + QImage img = QImage::fromData(data, len); + if (img.isNull()) { return; + } if (!gui) { // Show a notice if X11/XQuartz isn't available #if defined(__MACH__) && defined(__APPLE__) @@ -82,7 +84,7 @@ extern "C" void ShowPictureWindow(char *fn) { return; } - gui->ShowPictureWindow(fn); + gui->ShowPictureWindow(img); } extern "C" void ShowBase64PictureWindow(char *b64) { diff --git a/client/src/proxgui.h b/client/src/proxgui.h index d38d41f1d..56d0d9574 100644 --- a/client/src/proxgui.h +++ b/client/src/proxgui.h @@ -32,7 +32,7 @@ void HideGraphWindow(void); void RepaintGraphWindow(void); // hook up picture viewer -void ShowPictureWindow(char *fn); +void ShowPictureWindow(uint8_t *data, int len); void ShowBase64PictureWindow(char *b64); void HidePictureWindow(void); void RepaintPictureWindow(void); diff --git a/client/src/proxguiqt.cpp b/client/src/proxguiqt.cpp index 6e36af9ee..ff88bce1e 100644 --- a/client/src/proxguiqt.cpp +++ b/client/src/proxguiqt.cpp @@ -65,8 +65,8 @@ void ProxGuiQT::HideGraphWindow(void) { } // emit picture viewer signals -void ProxGuiQT::ShowPictureWindow(char *fn) { - emit ShowPictureWindowSignal(fn); +void ProxGuiQT::ShowPictureWindow(const QImage &img) { + emit ShowPictureWindowSignal(img); } void ProxGuiQT::ShowBase64PictureWindow(char *b64) { @@ -116,24 +116,14 @@ void ProxGuiQT::_HideGraphWindow(void) { } // picture viewer -void ProxGuiQT::_ShowPictureWindow(char *fn) { +void ProxGuiQT::_ShowPictureWindow(const QImage &img) { if (!plotapp) return; - if (fn == NULL) + if (img.isNull()) return; - size_t slen = strlen(fn); - if (slen == 0) - return; - - char *myfn = (char *)calloc(slen + 1, sizeof(uint8_t)); - if (myfn == NULL) - return; - - memcpy(myfn, fn, slen); - if (!pictureWidget) { #if defined(__MACH__) && defined(__APPLE__) @@ -143,12 +133,7 @@ void ProxGuiQT::_ShowPictureWindow(char *fn) { pictureWidget = new PictureWidget(); } - QPixmap pm; - if (pm.load(myfn) == false) { - qWarning("Failed to load %s", myfn); - } - free(myfn); - free(fn); + QPixmap pm = QPixmap::fromImage(img); //QPixmap newPixmap = pm.scaled(QSize(50,50), Qt::KeepAspectRatio); //pm = pm.scaled(pictureController->lbl_pm->size(), Qt::KeepAspectRatio); @@ -264,7 +249,7 @@ void ProxGuiQT::MainLoop() { connect(this, SIGNAL(ExitSignal()), this, SLOT(_Exit())); // hook up picture viewer signals - connect(this, SIGNAL(ShowPictureWindowSignal(char *)), this, SLOT(_ShowPictureWindow(char *))); + connect(this, SIGNAL(ShowPictureWindowSignal(const QImage &)), this, SLOT(_ShowPictureWindow(const QImage &))); connect(this, SIGNAL(ShowBase64PictureWindowSignal(char *)), this, SLOT(_ShowBase64PictureWindow(char *))); connect(this, SIGNAL(RepaintPictureWindowSignal()), this, SLOT(_RepaintPictureWindow())); connect(this, SIGNAL(HidePictureWindowSignal()), this, SLOT(_HidePictureWindow())); diff --git a/client/src/proxguiqt.h b/client/src/proxguiqt.h index 20277f2fd..ac19a99c9 100644 --- a/client/src/proxguiqt.h +++ b/client/src/proxguiqt.h @@ -156,7 +156,7 @@ class ProxGuiQT : public QObject { void HideGraphWindow(void); // hook up picture viewer - void ShowPictureWindow(char *fn); + void ShowPictureWindow(const QImage &img); void ShowBase64PictureWindow(char *b64); void HidePictureWindow(void); void RepaintPictureWindow(void); @@ -170,7 +170,7 @@ class ProxGuiQT : public QObject { void _HideGraphWindow(void); // hook up picture viewer - void _ShowPictureWindow(char *fn); + void _ShowPictureWindow(const QImage &img); void _ShowBase64PictureWindow(char *b64); void _HidePictureWindow(void); void _RepaintPictureWindow(void); @@ -185,7 +185,7 @@ class ProxGuiQT : public QObject { void ExitSignal(void); // hook up picture viewer signals - void ShowPictureWindowSignal(char *fn); + void ShowPictureWindowSignal(const QImage &img); void ShowBase64PictureWindowSignal(char *b64); void HidePictureWindowSignal(void); void RepaintPictureWindowSignal(void); From 76bc54a41446aa7b52a62c329322874820696a27 Mon Sep 17 00:00:00 2001 From: George Talusan Date: Mon, 1 Aug 2022 00:12:41 -0400 Subject: [PATCH 173/759] use core.search_file when searching for amiibo resources --- client/luascripts/hf_mfu_amiibo_restore.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/luascripts/hf_mfu_amiibo_restore.lua b/client/luascripts/hf_mfu_amiibo_restore.lua index 5996b9fa6..b83f3feb1 100644 --- a/client/luascripts/hf_mfu_amiibo_restore.lua +++ b/client/luascripts/hf_mfu_amiibo_restore.lua @@ -133,7 +133,7 @@ local function main(args) print('generating new Amiibo binary for NTAG215 '..ansicolors.green..uid) core.clearCommandBuffer() - core.console(('script run amiibo_change_uid %s %s %s %sresources/key_retail.bin'):format(uid, tmp, tmp2, core.ewd())) + core.console(('script run amiibo_change_uid %s %s %s %s'):format(uid, tmp, tmp2, core.search_file('resources/key_retail', '.bin'))) -- let's sanity check the output hex, err = utils.ReadDumpFile(tmp2) From 2459fd43ee7b24318044553e0c8ef6079adec2bd Mon Sep 17 00:00:00 2001 From: mywalk <66966897+mywalkb@users.noreply.github.com> Date: Tue, 2 Aug 2022 21:36:17 +0200 Subject: [PATCH 174/759] Fix undefined symbol when build with clang --- client/src/cmdhftexkom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 0ab454117..88add72d6 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -331,7 +331,7 @@ static bool TexcomTK15Decode(uint32_t *implengths, uint32_t implengthslen, char return ((strlen(cbitstring) == 64) && (strncmp(cbitstring, "1111111111111111", 16) == 0)); } -inline int TexcomTK17Get2Bits(uint32_t len1, uint32_t len2) { +static inline int TexcomTK17Get2Bits(uint32_t len1, uint32_t len2) { uint32_t xlen = (len2 * 100) / (len1 + len2); if (xlen < 10 || xlen > 90) return TK17WrongBit; From 88d45d641c859eb1714d5e7e917dab0ed354fc9f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 2 Aug 2022 22:49:25 +0200 Subject: [PATCH 175/759] Do not create empty dump files --- client/src/fileutils.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/src/fileutils.c b/client/src/fileutils.c index 8e68ed03f..41831c7cf 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -1952,6 +1952,11 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl } int pm3_save_dump(const char *fn, uint8_t *d, size_t n, JSONFileType jsft, size_t blocksize) { + if (n == 0) { + PrintAndLogEx(INFO, "No data to save. Skipping..."); + return PM3_EINVARG; + } + saveFile(fn, ".bin", d, n); saveFileEML(fn, d, n, blocksize); saveFileJSON(fn, jsft, d, n, NULL); From 06e54d4399965ec0583d8bd9919f9522204f3bd2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 2 Aug 2022 23:51:34 +0200 Subject: [PATCH 176/759] textual --- client/src/cmdhfmfdes.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 91592032e..45849035e 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -5046,7 +5046,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) { "Write data from file. Key needs to be provided or flag --no-auth set (depend on file settings).", "In the mode with CommitReaderID to decode previous reader id command needs to read transaction counter via dump/read command and specify --trkey\n" "\n" - "hf mfdes write --aid 123456 --fid 01 -d 01020304 -> write file: app=123456, file=01, offset=0, get file type from card. use default channel settings from `default` command\n" + "hf mfdes write --aid 123456 --fid 01 -d 01020304 -> AID 123456, file=01, offset=0, get file type from card. use default channel settings from `default` command\n" "hf mfdes write --aid 123456 --fid 01 --type data -d 01020304 --0ffset 000100 -> write data to std file with offset 0x100\n" "hf mfdes write --aid 123456 --fid 01 --type data -d 01020304 --commit -> write data to backup file with commit\n" "hf mfdes write --aid 123456 --fid 01 --type value -d 00000001 -> increment value file\n" @@ -5394,9 +5394,10 @@ static int CmdHF14ADesWriteData(const char *Cmd) { static int CmdHF14ADesLsFiles(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes lsfiles", - "Show file list. Master key needs to be provided or flag --no-auth set (depend on cards settings).", - "hf mfdes lsfiles --aid 123456 -> show file list for: app=123456 with defaults from `default` command" - "hf mfdes lsfiles --isoid df01 --no-auth -> show files from desfire light"); + "This commands List files inside application AID / ISOID.\n" + "Master key needs to be provided or flag --no-auth set (depend on cards settings).", + "hf mfdes lsfiles --aid 123456 -> AID 123456, list files using `default` command creds\n" + "hf mfdes lsfiles --isoid df01 --no-auth -> list files for DESFire light"); void *argtable[] = { arg_param_begin, From 5f67ba85c6d04b5bea827ec1eabb640028d97ae8 Mon Sep 17 00:00:00 2001 From: Alexandre Reol Date: Wed, 3 Aug 2022 14:17:08 +0200 Subject: [PATCH 177/759] Add installation guide for macOS Ventura Beta users --- .../Mac-OS-X-Homebrew-Installation-Instructions.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index f905084f0..4a2258519 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -7,6 +7,7 @@ # Table of Contents - [Mac OS X - Homebrew automatic installation](#mac-os-x---homebrew-automatic-installation) - [Table of Contents](#table-of-contents) + - [macOS Ventura Beta users](#macos-ventura-beta-users) - [Apple Silicon (M1) Notes](#apple-silicon-m1-notes) - [Install Proxmark3 tools](#install-proxmark3-tools) - [Upgrade HomeBrew tap formula](#upgrade-homebrew-tap-formula) @@ -21,6 +22,18 @@ +## macOS Ventura Beta users +^[Top](#top) + +Users of macOS Ventura Beta can no longer use Xcode versions lower than 14.0. (*Technically* they can by `Show Package Contents` and running `/Contents/MacOS/Xcode` but this is not recommended or recognized by Brew installations) + +Therefore you need to download Xcode 14.0 Beta and open it to install the correct Command Line Tools. (https://developer.apple.com/download/all/) + +Important: you need to rename `Xcode-beta.app` to `Xcode.app` (Note: If you still need Xcode 13.0 for signing and uploading apps to App Store rename `Xcode.app` to `Xcode-2.app`). + +Continue installation as detailed below. + + ## Apple Silicon (M1) Notes ^[Top](#top) From bf5f6750f4b85558b01fa3a6b77415256f47e99c Mon Sep 17 00:00:00 2001 From: nvx Date: Thu, 4 Aug 2022 17:05:59 +1000 Subject: [PATCH 178/759] Fix gallagher KDF generation for Admin Cards aka Reader Config Cards --- common/generator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/generator.c b/common/generator.c index da1b4bac9..41bd49d89 100644 --- a/common/generator.c +++ b/common/generator.c @@ -491,7 +491,8 @@ int mfdes_kdf_input_gallagher(uint8_t *uid, uint8_t uidLen, uint8_t keyNo, uint3 int len = 0; // If the keyNo == 1 or the aid is 000000, then omit the UID. - if (keyNo != 1 && aid != 0x000000) { + // On the other hand, if the aid is 1f81f4 (config card) always include the UID. + if ((keyNo != 1 && aid != 0x000000) || (aid == 0x1f81f4)) { if (*kdfInputLen < (4 + uidLen)) { return PM3_EINVARG; } From ecea6a53471dd694ba2ea328f47be430aa2c8a80 Mon Sep 17 00:00:00 2001 From: Alexandre Reol Date: Thu, 4 Aug 2022 16:31:59 +0200 Subject: [PATCH 179/759] Update instructions for macOS Ventura --- ...c-OS-X-Homebrew-Installation-Instructions.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 4a2258519..9b6e8f0e2 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -25,14 +25,17 @@ ## macOS Ventura Beta users ^[Top](#top) -Users of macOS Ventura Beta can no longer use Xcode versions lower than 14.0. (*Technically* they can by `Show Package Contents` and running `/Contents/MacOS/Xcode` but this is not recommended or recognized by Brew installations) +Early users of macOS Ventura and Xcode 14.0 might run into an error saying that Xcode 14.0 is out-of-date (even though you have the latest Xcode Beta installed). -Therefore you need to download Xcode 14.0 Beta and open it to install the correct Command Line Tools. (https://developer.apple.com/download/all/) - -Important: you need to rename `Xcode-beta.app` to `Xcode.app` (Note: If you still need Xcode 13.0 for signing and uploading apps to App Store rename `Xcode.app` to `Xcode-2.app`). - -Continue installation as detailed below. +If (and only if) you run into that error, here is the fix: +- RE-download the *latest* Command Line Tools of Xcode Beta 14 and install them (again). (https://developer.apple.com/download/all/) +- Proceed with Brew installation +That should normally fix the issue. +Alternatively, and only if the issue still persists after following the steps above, you can use this *temporary and ugly* fix: +- Try renaming `Xcode-beta.app` to `Xcode.app` (Note: If you still need Xcode 13.0 for signing and uploading apps to App Store rename `Xcode.app` to `Xcode-2.app`) +- Proceed with Brew installation +- IMPORTANT: Reverse renaming done in first step. ## Apple Silicon (M1) Notes ^[Top](#top) @@ -198,4 +201,4 @@ pm3 If you want to manually select serial port, remember that the Proxmark3 port is `/dev/tty.usbmodemiceman1`, so commands become: ```sh proxmark3 /dev/ttyACM0 => proxmark3 /dev/tty.usbmodemiceman1 -``` \ No newline at end of file +``` From 647440236d9b4efedd8e727872df902493cfb84c Mon Sep 17 00:00:00 2001 From: Alexandre Reol Date: Thu, 4 Aug 2022 16:35:30 +0200 Subject: [PATCH 180/759] Add xcode-select command --- .../Mac-OS-X-Homebrew-Installation-Instructions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 9b6e8f0e2..4de2ec373 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -29,6 +29,7 @@ Early users of macOS Ventura and Xcode 14.0 might run into an error saying that If (and only if) you run into that error, here is the fix: - RE-download the *latest* Command Line Tools of Xcode Beta 14 and install them (again). (https://developer.apple.com/download/all/) +- Run `sudo xcode-select -s /Applications/Xcode-beta.app` in Terminal. - Proceed with Brew installation That should normally fix the issue. From d11999a811d29294a65f0799e714d0c41d390469 Mon Sep 17 00:00:00 2001 From: nvx Date: Fri, 5 Aug 2022 18:38:51 +1000 Subject: [PATCH 181/759] Fix eload from json files failing (ie, hf mf eload -f file.json) when the dump is the full size. Also fixed an accidental client double free when loading dumps. --- client/src/fileutils.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/client/src/fileutils.c b/client/src/fileutils.c index 41831c7cf..99f5395d2 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -1102,19 +1102,21 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz if (!strcmp(ctype, "mfcard")) { size_t sptr = 0; for (int i = 0; i < 256; i++) { + char blocks[30] = {0}; + snprintf(blocks, sizeof(blocks), "$.blocks.%d", i); + + size_t len = 0; + uint8_t block[16]; + JsonLoadBufAsHex(root, blocks, block, 16, &len); + if (!len) + break; + if (sptr + 16 > maxdatalen) { retval = PM3_EMALLOC; goto out; } - char blocks[30] = {0}; - snprintf(blocks, sizeof(blocks), "$.blocks.%d", i); - - size_t len = 0; - JsonLoadBufAsHex(root, blocks, &udata[sptr], 16, &len); - if (!len) - break; - + memcpy(&udata[sptr], block, 16); sptr += len; } @@ -1934,6 +1936,9 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl return PM3_EMALLOC; } res = loadFileJSON(fn, *pdump, maxdumplen, dumplen, NULL); + if (res != PM3_SUCCESS) { + free(*pdump); + } break; } case DICTIONARY: { @@ -1944,7 +1949,6 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl if (res != PM3_SUCCESS) { PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", fn); - free(*pdump); return PM3_EFILE; } From 5a4b8c822494f2f6b90942cc0b48db7adfda9b5b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Aug 2022 15:34:16 +0200 Subject: [PATCH 182/759] fix #1748 - failed to take in consideration size of legic struct packet when uploading data to device --- client/src/cmdhflegic.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhflegic.c b/client/src/cmdhflegic.c index f501dcb91..35b1ac886 100644 --- a/client/src/cmdhflegic.c +++ b/client/src/cmdhflegic.c @@ -34,6 +34,7 @@ static int CmdHelp(const char *Cmd); #define LEGIC_PRIME_MIM256 256 #define LEGIC_PRIME_MIM1024 1024 #define LEGIC_BLOCK_SIZE 8 +#define LEGIC_PACKET_SIZE (PM3_CMD_DATA_SIZE - sizeof(legic_packet_t)) static bool legic_xor(uint8_t *data, uint16_t cardsize) { @@ -737,9 +738,9 @@ void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) { // fast push mode g_conn.block_after_ACK = true; - for (size_t i = offset; i < numofbytes; i += (PM3_CMD_DATA_SIZE - sizeof(legic_packet_t))) { + for (size_t i = offset; i < numofbytes; i += LEGIC_PACKET_SIZE) { - size_t len = MIN((numofbytes - i), (PM3_CMD_DATA_SIZE - sizeof(legic_packet_t))); + size_t len = MIN((numofbytes - i), LEGIC_PACKET_SIZE); if (len == numofbytes - i) { // Disable fast mode on last packet g_conn.block_after_ACK = false; @@ -943,9 +944,9 @@ static int CmdLegicRestore(const char *Cmd) { // transfer to device PacketResponseNG resp; // 7 = skip UID bytes and MCC - for (size_t i = 7; i < bytes_read; i += PM3_CMD_DATA_SIZE) { + for (size_t i = 7; i < bytes_read; i += LEGIC_PACKET_SIZE) { - size_t len = MIN((bytes_read - i), PM3_CMD_DATA_SIZE); + size_t len = MIN((bytes_read - i), LEGIC_PACKET_SIZE); if (len == bytes_read - i) { // Disable fast mode on last packet g_conn.block_after_ACK = false; @@ -1209,11 +1210,11 @@ static int CmdLegicWipe(const char *Cmd) { // transfer to device PacketResponseNG resp; - for (size_t i = 7; i < card.cardsize; i += PM3_CMD_DATA_SIZE) { + for (size_t i = 7; i < card.cardsize; i += LEGIC_PACKET_SIZE) { PrintAndLogEx(NORMAL, "." NOLF); - size_t len = MIN((card.cardsize - i), PM3_CMD_DATA_SIZE); + size_t len = MIN((card.cardsize - i), LEGIC_PACKET_SIZE); if (len == card.cardsize - i) { // Disable fast mode on last packet g_conn.block_after_ACK = false; From 62980b50388dbb0d91899822ac06162936710b07 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Aug 2022 22:46:59 +0200 Subject: [PATCH 183/759] refactored topaz commands. It still uses a global var with dynamic memory. Added rdbl, wrbl, view, dump commands to match rest of client --- CHANGELOG.md | 4 +- client/src/cmdhfmfu.c | 16 +- client/src/cmdhftopaz.c | 578 ++++++++++++++++++++++++++++++++-------- client/src/cmdhftopaz.h | 26 +- client/src/fileutils.c | 51 ++++ client/src/fileutils.h | 1 + client/src/nfc/ndef.c | 30 ++- 7 files changed, 567 insertions(+), 139 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f074cc6d..8f87454e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,14 @@ 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 json topaz file format (@iceman1001) + - Added `hf topaz rdbl, wrbl, view` commands (@iceman1001) - Added more details to the annotations of `hf mfdes list` output (@nvx) - Changed `hf iclass view` and related to suppress consecutive blocks with repeated contents with a `-z` flag, or `prefs set output --dense` (@nvx) - Changed `hf iclass list` to display matched keys on the CHECK command rather than the card response, and made it check for elite keys too (@nvx) - Fixed `hf iclass info` and `hf iclass view` key access info looking at the wrong card config bit (@nvx) - Added `hf gallagher decode` command and fix Gallagher diversification for card master key (@nvx) - - Added mmbit-002 (kibi-002, kb5004xk1) russian tag to `hf texkom read` command (@merlokk) + - Changed `hf texkom reader` - now supports mmbit-002 (kibi-002, kb5004xk1) russian tag (@merlokk) - Added `hf sniff --smode` skip/group adc data to consume less memory. Now it can sniff very long signals (@merlokk) - Added `hf fudan` skeleton commands (@iceman1001) - Added `--reboot-to-bootloader` arg to pm3 diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 60196afbd..7ff381d22 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -606,14 +606,13 @@ static int ndef_print_CC(uint8_t *data) { uint8_t mlrule = (data[3] & 0x06) >> 1; uint8_t mbread = (data[3] & 0x01); - PrintAndLogEx(SUCCESS, " Additional feature information"); - PrintAndLogEx(SUCCESS, " %02X", data[3]); + PrintAndLogEx(SUCCESS, " %02X: Additional feature information", data[3]); PrintAndLogEx(SUCCESS, " 00000000"); - PrintAndLogEx(SUCCESS, " xxx - %02X: RFU ( %s )", msb3, (msb3 == 0) ? _GREEN_("ok") : _RED_("fail")); - PrintAndLogEx(SUCCESS, " x - %02X: %s special frame", sf, (sf) ? "support" : "don\'t support"); - PrintAndLogEx(SUCCESS, " x - %02X: %s lock block", lb, (lb) ? "support" : "don\'t support"); - PrintAndLogEx(SUCCESS, " xx - %02X: RFU ( %s )", mlrule, (mlrule == 0) ? _GREEN_("ok") : _RED_("fail")); - PrintAndLogEx(SUCCESS, " x - %02X: IC %s multiple block reads", mbread, (mbread) ? "support" : "don\'t support"); + PrintAndLogEx(SUCCESS, " xxx..... - %02X: RFU ( %s )", msb3, (msb3 == 0) ? _GREEN_("ok") : _RED_("fail")); + PrintAndLogEx(SUCCESS, " ...x.... - %02X: %s special frame", sf, (sf) ? "support" : "don\'t support"); + PrintAndLogEx(SUCCESS, " ....x... - %02X: %s lock block", lb, (lb) ? "support" : "don\'t support"); + PrintAndLogEx(SUCCESS, " .....xx. - %02X: RFU ( %s )", mlrule, (mlrule == 0) ? _GREEN_("ok") : _RED_("fail")); + PrintAndLogEx(SUCCESS, " .......x - %02X: IC %s multiple block reads", mbread, (mbread) ? "support" : "don\'t support"); return PM3_SUCCESS; } @@ -3243,7 +3242,8 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { } PrintAndLogEx(INFO, "------------------.---------------"); - PrintAndLogEx(INFO, " Using UID : " _YELLOW_("%s"), sprint_hex(uid, 7)); + PrintAndLogEx(INFO, " Using UID 4b: " _YELLOW_("%s"), sprint_hex(uid, 4)); + PrintAndLogEx(INFO, " Using UID 7b: " _YELLOW_("%s"), sprint_hex(uid, 7)); PrintAndLogEx(INFO, "----------------------------------"); PrintAndLogEx(INFO, " algo | pwd | pack"); PrintAndLogEx(INFO, "-----------------+----------+-----"); diff --git a/client/src/cmdhftopaz.c b/client/src/cmdhftopaz.c index 12a445408..6d7a1975d 100644 --- a/client/src/cmdhftopaz.c +++ b/client/src/cmdhftopaz.c @@ -38,25 +38,7 @@ # define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1) #endif -#define TOPAZ_STATIC_MEMORY (0x0F * 8) // 15 blocks with 8 Bytes each - -// a struct to describe a memory area which contains lock bits and the corresponding lockable memory area -typedef struct dynamic_lock_area { - struct dynamic_lock_area *next; - uint16_t byte_offset; // the address of the lock bits - uint16_t size_in_bits; - uint16_t first_locked_byte; // the address of the lockable area - uint16_t bytes_locked_per_bit; -} dynamic_lock_area_t; - -static struct { - uint8_t HR01[2]; - uint8_t uid[7]; - uint16_t size; - uint8_t data_blocks[TOPAZ_STATIC_MEMORY / 8][8]; // this memory is always there - uint8_t *dynamic_memory; // this memory can be there - dynamic_lock_area_t *dynamic_lock_areas; // lock area descriptors -} topaz_tag; +static topaz_tag_t topaz_tag; static void topaz_switch_on_field(void) { SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, 0, 0, NULL, 0); @@ -142,30 +124,68 @@ static int topaz_rall(uint8_t *uid, uint8_t *response) { } // read a block (8 Bytes) of a selected Topaz tag. -static int topaz_read_block(uint8_t *uid, uint8_t blockno, uint8_t *block_data) { - uint16_t resp_len = 0; - uint8_t read8_cmd[] = {TOPAZ_READ8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - uint8_t read8_response[11] = {0}; +static int topaz_read_block(uint8_t blockno, uint8_t *block_data) { + uint8_t atqa[2] = {0}; + uint8_t rid_response[8] = {0}; + int res = topaz_select(atqa, sizeof(atqa), rid_response, sizeof(rid_response), true); + if (res != PM3_SUCCESS) { + return res; + } - read8_cmd[1] = blockno; - memcpy(&read8_cmd[10], uid, 4); + if (atqa[1] != 0x0c && atqa[0] != 0x00) { + return res; + } - if (topaz_send_cmd(read8_cmd, sizeof(read8_cmd), read8_response, &resp_len, true) == PM3_ETIMEOUT) { + uint8_t *uid_echo = &rid_response[2]; + uint8_t rall_response[124] = {0}; + + res = topaz_rall(uid_echo, rall_response); + if (res == PM3_ESOFT) { + return res; + } + + uint8_t read8_cmd[] = {TOPAZ_READ8, blockno, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + memcpy(&read8_cmd[10], uid_echo, 4); + + uint16_t resp_len = 11; + uint8_t response[11] = {0}; + + if (topaz_send_cmd(read8_cmd, sizeof(read8_cmd), response, &resp_len, true) == PM3_ETIMEOUT) { topaz_switch_off_field(); return PM3_ESOFT; // READ8 failed } - memcpy(block_data, &read8_response[1], 8); + memcpy(block_data, &response[1], 8); return PM3_SUCCESS; } // read a segment (16 blocks = 128 Bytes) of a selected Topaz tag. Works only for tags with dynamic memory. -static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data) { - uint16_t resp_len = 0; +static int topaz_read_segment(uint8_t segno, uint8_t *segment_data) { + + uint8_t atqa[2] = {0}; + uint8_t rid_response[8] = {0}; + int res = topaz_select(atqa, sizeof(atqa), rid_response, sizeof(rid_response), true); + if (res != PM3_SUCCESS) { + return res; + } + + if (atqa[1] != 0x0c && atqa[0] != 0x00) { + return res; + } + + uint8_t *uid_echo = &rid_response[2]; + uint8_t rall_response[124] = {0}; + + res = topaz_rall(uid_echo, rall_response); + if (res == PM3_ESOFT) { + return res; + } + + uint16_t resp_len = 131; uint8_t rseg_cmd[] = {TOPAZ_RSEG, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t rseg_response[131]; rseg_cmd[1] = segno << 4; - memcpy(&rseg_cmd[10], uid, 4); + memcpy(&rseg_cmd[10], uid_echo, 4); if (topaz_send_cmd(rseg_cmd, sizeof(rseg_cmd), rseg_response, &resp_len, true) == PM3_ETIMEOUT) { topaz_switch_off_field(); @@ -175,6 +195,55 @@ static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data return PM3_SUCCESS; } +// write a block (8 Bytes) of a selected Topaz tag. +static int topaz_write_erase8_block(uint8_t blockno, uint8_t *block_data) { + + uint8_t atqa[2] = {0}; + uint8_t rid_response[8] = {0}; + int res = topaz_select(atqa, sizeof(atqa), rid_response, sizeof(rid_response), true); + if (res != PM3_SUCCESS) { + return res; + } + + if (atqa[1] != 0x0c && atqa[0] != 0x00) { + return res; + } + + uint8_t *uid_echo = &rid_response[2]; + uint8_t rall_response[124] = {0}; + + res = topaz_rall(uid_echo, rall_response); + if (res == PM3_ESOFT) { + return res; + } + + uint8_t wr8_cmd[] = {TOPAZ_WRITE_E8, blockno, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + memcpy(wr8_cmd + 10, uid_echo, 4); + memcpy(wr8_cmd + 2, block_data, 8); + + uint16_t resp_len = 11; + uint8_t response[11] = {0}; + + if (topaz_send_cmd(wr8_cmd, sizeof(wr8_cmd), response, &resp_len, true) == PM3_ETIMEOUT) { + topaz_switch_off_field(); + return PM3_ESOFT; // WriteErase 8bytes failed + } + + if (resp_len != 11) { + return PM3_EFAILED; + } + + if (blockno != response[0]) { + return PM3_EFAILED; + } + + if (memcmp(block_data, response + 1, 8) == 0) { + return PM3_SUCCESS; + } + return PM3_ESOFT; +} + + // search for the lock area descriptor for the lockable area including byteno static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno) { dynamic_lock_area_t *lock_area; @@ -223,25 +292,112 @@ static bool topaz_byte_is_locked(uint16_t byteno) { } } -// read and print the Capability Container -static int topaz_print_CC(uint8_t *data) { - if (data[0] != 0xe1) { +static int topaz_set_cc_dynamic(uint8_t *data) { + + if (data[0] != 0xE1) { topaz_tag.size = TOPAZ_STATIC_MEMORY; + PrintAndLogEx(WARNING, "No Type 1 NDEF capability container found"); return PM3_ESOFT; // no NDEF message } - PrintAndLogEx(SUCCESS, "Capability Container: %02x %02x %02x %02x", data[0], data[1], data[2], data[3]); - PrintAndLogEx(SUCCESS, " %02x: NDEF Magic Number", data[0]); - PrintAndLogEx(SUCCESS, " %02x: version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f); - + // setting of dynamic memory and allocation of such memory. uint16_t memsize = (data[2] + 1) * 8; topaz_tag.size = memsize; topaz_tag.dynamic_memory = calloc(memsize - TOPAZ_STATIC_MEMORY, sizeof(uint8_t)); + if (topaz_tag.dynamic_memory == NULL) { + return PM3_EMALLOC; + } + return PM3_SUCCESS; +} - PrintAndLogEx(SUCCESS, " %02x: Physical Memory Size of this tag: %d bytes", data[2], memsize); - PrintAndLogEx(SUCCESS, " %02x: %s / %s", data[3], - (data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security", - (data[3] & 0x0F) == 0 ? "Write access granted without any security" : (data[3] & 0x0F) == 0x0F ? "No write access granted at all" : "(RFU)"); +// read and print the Capability Container +static int topaz_print_CC(uint8_t *data) { + + if (data[0] != 0xE1) { + topaz_tag.size = TOPAZ_STATIC_MEMORY; + PrintAndLogEx(WARNING, "No Type 1 NDEF capability container found"); + return PM3_ESOFT; // no NDEF message + } + + +//NFC Forum Type 1,2,3,4 +// +// 4 has 1.1 (11) + +// b7, b6 major version +// b5, b4 minor version +// b3, b2 read +// 00 always, 01 rfu, 10 proprietary, 11 rfu +// b1, b0 write +// 00 always, 01 rfo, 10 proprietary, 11 never + +// vs + +// NFC Forum Type 2 docs, where +// b7654 = major version +// b3219 = minor version + +// CC write / read access +// (data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security", +// (data[3] & 0x0F) == 0 ? "Write access granted without any security" : (data[3] & 0x0F) == 0x0F ? "No write access granted at all" : "(RFU)"); + uint8_t cc_major = (data[1] & 0xF0) >> 4; + uint8_t cc_minor = (data[1] & 0x00); + + uint8_t cc_write = data[3] & 0x0F; + uint8_t cc_read = (data[3] & 0xF0) >> 4; + + const char *wStr; + switch (cc_write) { + case 0: + wStr = "Write access granted without any security"; + break; + case 0xF: + wStr = "No write access"; + break; + default: + wStr = "RFU"; + break; + } + const char *rStr; + switch (cc_read) { + case 0: + rStr = "Read access granted without any security"; + break; + default: + rStr = "RFU"; + break; + } + + PrintAndLogEx(SUCCESS, "Capability Container: %s", sprint_hex(data, 4)); + PrintAndLogEx(SUCCESS, " %02X: NDEF Magic Number", data[0]); + +// PrintAndLogEx(SUCCESS, " %02X : version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0F); + PrintAndLogEx(SUCCESS, " %02X: version %d.%d supported by tag", data[1], cc_major, cc_minor); + PrintAndLogEx(SUCCESS, " : %s / %s", rStr, wStr); + + PrintAndLogEx(SUCCESS, " %02X: Physical Memory Size: %d bytes", data[2], (data[2] + 1) * 8); + if (data[2] == 0x0E) + PrintAndLogEx(SUCCESS, " %02X: NDEF Memory Size: %d bytes", data[2], 120); + else if (data[2] == 0x1F) + PrintAndLogEx(SUCCESS, " %02X: NDEF Memory Size: %d bytes", data[2], 256); + else if (data[2] == 0xFF) + PrintAndLogEx(SUCCESS, " %02X: NDEF Memory Size: %d bytes", data[2], 2048); + + uint8_t msb3 = (data[3] & 0xE0) >> 5; + uint8_t sf = (data[3] & 0x10) >> 4; + uint8_t lb = (data[3] & 0x08) >> 3; + uint8_t mlrule = (data[3] & 0x06) >> 1; + uint8_t mbread = (data[3] & 0x01); + + PrintAndLogEx(SUCCESS, " %02X: Additional feature information", data[3]); + PrintAndLogEx(SUCCESS, " ^^"); + PrintAndLogEx(SUCCESS, " 00000000"); + PrintAndLogEx(SUCCESS, " xxx..... - %02X: RFU ( %s )", msb3, (msb3 == 0) ? _GREEN_("ok") : _RED_("fail")); + PrintAndLogEx(SUCCESS, " ...x.... - %02X: %s special frame", sf, (sf) ? "support" : "don\'t support"); + PrintAndLogEx(SUCCESS, " ....x... - %02X: %s lock block", lb, (lb) ? "support" : "don\'t support"); + PrintAndLogEx(SUCCESS, " .....xx. - %02X: RFU ( %s )", mlrule, (mlrule == 0) ? _GREEN_("ok") : _RED_("fail")); + PrintAndLogEx(SUCCESS, " .......x - %02X: IC %s multiple block reads", mbread, (mbread) ? "support" : "don\'t support"); + PrintAndLogEx(SUCCESS,""); return PM3_SUCCESS; } @@ -314,10 +470,8 @@ static void topaz_print_control_TLVs(uint8_t *memory) { uint16_t bytes_locked_per_bit = 1 << (TLV_value[2] >> 4); uint16_t area_start = pages_addr * bytes_per_page + byte_offset; - PrintAndLogEx(SUCCESS, "Lock Area of %d bits at byte offset 0x%04x. Each Lock Bit locks %d bytes.", - size_in_bits, - area_start, - bytes_locked_per_bit); + PrintAndLogEx(SUCCESS, "Lock Area of " _YELLOW_("%d") " bits at byte offset " _YELLOW_("0x%04x"), size_in_bits, area_start); + PrintAndLogEx(SUCCESS, "Each lock bit locks " _YELLOW_("%d") " bytes", bytes_locked_per_bit); lock_TLV_present = true; dynamic_lock_area_t *old = topaz_tag.dynamic_lock_areas; @@ -352,7 +506,7 @@ static void topaz_print_control_TLVs(uint8_t *memory) { uint8_t bytes_per_page = 1 << (TLV_value[2] & 0x0f); uint16_t area_start = pages_addr * bytes_per_page + byte_offset; - PrintAndLogEx(SUCCESS, "Reserved Memory of %d bytes at byte offset 0x%02x.", + PrintAndLogEx(SUCCESS, "Reserved Memory... " _GREEN_("%d") " bytes at byte offset " _YELLOW_("0x%02x"), size_in_bytes, area_start); @@ -378,15 +532,15 @@ static void topaz_print_control_TLVs(uint8_t *memory) { // read all of the dynamic memory static int topaz_read_dynamic_data(void) { // first read the remaining block of segment 0 - if (topaz_read_block(topaz_tag.uid, 0x0F, &topaz_tag.dynamic_memory[0]) == PM3_ESOFT) { + if (topaz_read_block(0x0F, &topaz_tag.dynamic_memory[0]) == PM3_ESOFT) { PrintAndLogEx(ERR, "Error while reading dynamic memory block " _YELLOW_("%02x") ". Aborting...", 0x0F); return PM3_ESOFT; } // read the remaining segments - uint8_t max_segment = topaz_tag.size / 128 - 1; - for (uint8_t segment = 1; segment <= max_segment; segment++) { - if (topaz_read_segment(topaz_tag.uid, segment, &topaz_tag.dynamic_memory[(segment - 1) * 128 + 8]) == PM3_ESOFT) { + uint8_t max = topaz_tag.size / 128 - 1; + for (uint8_t segment = 1; segment <= max; segment++) { + if (topaz_read_segment(segment, &topaz_tag.dynamic_memory[(segment - 1) * 128 + 8]) == PM3_ESOFT) { PrintAndLogEx(ERR, "Error while reading dynamic memory block " _YELLOW_("%02x") ". Aborting...", segment); return PM3_ESOFT; } @@ -403,10 +557,10 @@ static void topaz_print_dynamic_data(void) { PrintAndLogEx(SUCCESS, "Dynamic Data blocks:"); - if (topaz_read_dynamic_data() == 0) { + if (topaz_read_dynamic_data() == PM3_SUCCESS) { - PrintAndLogEx(NORMAL, "block# | offset | Data | Locked (y/n)"); - PrintAndLogEx(NORMAL, "-------+--------+-------------------------+-------------"); + PrintAndLogEx(SUCCESS, "block# | Data |lck"); + PrintAndLogEx(SUCCESS, "-------+-------------------------+-------------"); char line[80]; for (uint16_t blockno = 0x0F; blockno < topaz_tag.size / 8; blockno++) { @@ -420,7 +574,7 @@ static void topaz_print_dynamic_data(void) { } lockbits[8] = '\0'; - PrintAndLogEx(NORMAL, " 0x%02x | 0x%04x | %s| %-3s", blockno, blockno * 8, line, lockbits); + PrintAndLogEx(SUCCESS, " 0x%02x | %s| %-3s", blockno, line, lockbits); } } } @@ -429,6 +583,43 @@ static void topaz_print_lifecycle_state(uint8_t *data) { // to be done } +static void printTopazDumpContents(uint8_t *dump, size_t size) { + + topaz_tag_t *t = (topaz_tag_t *)dump; + + // uses a global var for all + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Static data blocks :"); + PrintAndLogEx(SUCCESS, "block# | data |lck| info"); + PrintAndLogEx(SUCCESS, "------------+-------------------------+---+------------"); + + const char *block_info; + const char *topaz_ks[] = { "uid", "user", "rfu", "lock / otp" }; + + for (uint8_t i = 0; i <= 0x0C; i++) { + + if (i == 0) + block_info = topaz_ks[i]; + else + block_info = topaz_ks[1]; + + const char *lockstr = (topaz_byte_is_locked(i * 8)) ? _RED_("x") : " "; + + PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| %s | %s", + i, + i, + sprint_hex(&t->data_blocks[i][0], 8), + lockstr, + block_info + ); + } + + PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| | %s", 0x0D, 0x0D, sprint_hex(&t->data_blocks[0x0D][0], 8), topaz_ks[2]); + PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| | %s", 0x0E, 0x0E, sprint_hex(&t->data_blocks[0x0E][0], 8), topaz_ks[3]); + PrintAndLogEx(SUCCESS, "------------+-------------------------+---+------------"); + PrintAndLogEx(NORMAL, ""); +} + static int CmdHFTopazReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf topaz reader", @@ -497,53 +688,21 @@ int CmdHFTopazInfo(const char *Cmd) { PrintAndLogEx(SUCCESS, " ^^"); PrintAndLogEx(SUCCESS, " %s", sprint_bin(topaz_tag.HR01, 1)); - PrintAndLogEx(SUCCESS, " x.......... TOPAZ tag ( %s ) - NDEF capable ( %s )", - (topaz_tag.HR01[0] & 0xF0) == 0x10 ? _GREEN_("yes") : _RED_("no"), - (topaz_tag.HR01[0] & 0xF0) == 0x10 ? _GREEN_("yes") : _RED_("no") + PrintAndLogEx(SUCCESS, " ...x.... - %s / %s", + (topaz_tag.HR01[0] & 0xF0) == 0x10 ? _GREEN_("TOPAZ tag") : "", + (topaz_tag.HR01[0] & 0xF0) == 0x10 ? _GREEN_("Type 1 NDEF") : "" ); - PrintAndLogEx(SUCCESS, " x... %s memory map", ((topaz_tag.HR01[0] & 0x0F) == 0x01) ? "Static" : "Dynamic" ); - PrintAndLogEx(NORMAL, ""); - - PrintAndLogEx(SUCCESS, "Static Data blocks " _YELLOW_("0x00") " to " _YELLOW_("0x0C")":"); - PrintAndLogEx(NORMAL, "block# | offset | Data | Locked"); - PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); - - char line[80]; - for (uint8_t i = 0; i <= 0x0C; i++) { - - char lockbits[9]; - for (uint8_t j = 0; j < 8; j++) { - int offset = 3 * j; - snprintf(line + offset, sizeof(line) - offset, "%02x ", topaz_tag.data_blocks[i][j] /*rall_response[2 + 8*i + j]*/); - lockbits[j] = topaz_byte_is_locked(i * 8 + j) ? 'y' : 'n'; - } - lockbits[8] = '\0'; - PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", i, i * 8, line, lockbits); - } - - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "Static Reserved block " _YELLOW_("0x0D")":"); - - for (uint8_t j = 0; j < 8; j++) { - int offset = 3 * j; - snprintf(line + offset, sizeof(line) - offset, "%02x ", topaz_tag.data_blocks[0x0d][j]); - } - - PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); - PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0d, 0x0d * 8, line, "n/a"); - PrintAndLogEx(NORMAL, ""); - - PrintAndLogEx(SUCCESS, "Static Lockbits and OTP Bytes:"); - - for (uint8_t j = 0; j < 8; j++) { - int offset = 3 * j; - snprintf(line + offset, sizeof(line) - offset, "%02x ", topaz_tag.data_blocks[0x0e][j]); - } - - PrintAndLogEx(NORMAL, "-------+--------+-------------------------+------------"); - PrintAndLogEx(NORMAL, " 0x%02x | 0x%02x | %s| %-3s", 0x0e, 0x0e * 8, line, "n/a"); + PrintAndLogEx(SUCCESS, " .......x - %s memory map", ((topaz_tag.HR01[0] & 0x0F) == 0x01) ? "Static" : "Dynamic" ); + PrintAndLogEx(SUCCESS, ""); + PrintAndLogEx(SUCCESS, " Lock bytes... %02X%02X", + topaz_tag.data_blocks[0x0e][0], + topaz_tag.data_blocks[0x0e][1] + ); + + PrintAndLogEx(SUCCESS, " OTP.......... %s", sprint_hex(&topaz_tag.data_blocks[0x0e][2], 6)); PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("NDEF configuration") " ---------------------------"); status = topaz_print_CC(&topaz_tag.data_blocks[1][0]); if (status == PM3_ESOFT) { PrintAndLogEx(SUCCESS, "No NDEF message data present"); @@ -555,16 +714,6 @@ int CmdHFTopazInfo(const char *Cmd) { topaz_print_control_TLVs(&topaz_tag.data_blocks[1][4]); PrintAndLogEx(NORMAL, ""); - topaz_print_dynamic_data(); - - topaz_print_lifecycle_state(&topaz_tag.data_blocks[1][0]); - - 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(); return PM3_SUCCESS; } @@ -585,7 +734,7 @@ static int CmdHFTopazSim(const char *Cmd) { return PM3_SUCCESS; } -static int CmdHFTopazCmdRaw(const char *Cmd) { +static int CmdHFTopazRaw(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf topaz raw", "Send raw hex data to Topaz tags", @@ -624,16 +773,213 @@ static int CmdHFTopazSniff(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHFTopazDump(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf topaz dump", + "Dump TOPAZ tag to binary file\n" + "If no given, UID will be used as filename", + "hf topaz dump\n"); + + void *argtable[] = { + arg_param_begin, + arg_str0("f", "file", "", "filename of dump"), + 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); + + int status = readTopazUid(false, false); + if (status != PM3_SUCCESS) { + return status; + } + printTopazDumpContents((uint8_t*)&topaz_tag, sizeof(topaz_tag_t)); + + bool set_dynamic = false; + if (topaz_set_cc_dynamic(&topaz_tag.data_blocks[1][0]) == PM3_SUCCESS) { + set_dynamic = true; + + topaz_print_dynamic_data(); + + topaz_print_lifecycle_state(&topaz_tag.data_blocks[1][0]); + + NDEFDecodeAndPrint(&topaz_tag.data_blocks[1][4], + (topaz_tag.HR01[0] == 1) ? (12 * 8) : 476 + , true + ); + } + + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + topaz_switch_off_field(); + + // user supplied filename? + if (fnlen < 1) { + PrintAndLogEx(INFO, "Using UID as filename"); + strcat(filename, "hf-topaz-"); + FillFileNameByUID(filename, topaz_tag.uid, "-dump", sizeof(topaz_tag.uid)); + } + + if (topaz_tag.size) + pm3_save_dump(filename, (uint8_t *)&topaz_tag, sizeof(topaz_tag_t) + topaz_tag.size, jsfTopaz, TOPAZ_BLOCK_SIZE); + else + pm3_save_dump(filename, (uint8_t *)&topaz_tag, sizeof(topaz_tag_t), jsfTopaz, TOPAZ_BLOCK_SIZE); + + if (set_dynamic) { + free(topaz_tag.dynamic_memory); + } + + return PM3_SUCCESS; +} + +static int CmdHFTopazView(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf topaz view", + "Print a Topaz tag dump file (bin/eml/json)", + "hf topaz view -f hf-topaz-04010203-dump.bin"); + + void *argtable[] = { + arg_param_begin, + arg_str1("f", "file", "", "filename of dump (bin/eml/json)"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + int fnlen = 0; + char filename[FILE_PATH_SIZE]; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + CLIParserFree(ctx); + + // read dump file + uint8_t *dump = NULL; + size_t bytes_read = TOPAZ_MAX_SIZE; + int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, sizeof(topaz_tag_t) + TOPAZ_MAX_SIZE); + if (res != PM3_SUCCESS) { + return res; + } + + printTopazDumpContents(dump, bytes_read); + + if (topaz_set_cc_dynamic(&topaz_tag.data_blocks[1][0]) == PM3_SUCCESS) { + + topaz_print_dynamic_data(); + + topaz_print_lifecycle_state(&topaz_tag.data_blocks[1][0]); + + NDEFDecodeAndPrint(&topaz_tag.data_blocks[1][4], + (topaz_tag.HR01[0] == 1) ? (12 * 8) : 476 + , true + ); + + PrintAndLogEx(INFO, "%s", sprint_hex(&topaz_tag.data_blocks[1][4], (12*8))); + + free(topaz_tag.dynamic_memory); + } + + free(dump); + return PM3_SUCCESS; +} + +// Read single block +static int CmdHFTopazRdBl(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf topaz rdbl", + "Read a block", + "hf topaz rdbl -b 7\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_int1("b", "block", "", "Block number to write"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + int blockno = arg_get_int_def(ctx, 1, -1); + CLIParserFree(ctx); + + if (blockno < 0) { + PrintAndLogEx(WARNING, "Wrong block number"); + return PM3_EINVARG; + } + + // send read block + uint8_t data[8] = {0}; + int res = topaz_read_block(blockno, data); + if (res == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "Block: %0d (0x%02X) [ %s]", blockno, blockno, sprint_hex(data, sizeof(data))); + } + + topaz_switch_off_field(); + return res; +} + +// Write single block +static int CmdHFTopazWrBl(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf topaz wrbl", + "Write a block", + "hf topaz wrbl -b 7 -d 1122334455667788\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_int1("b", "block", "", "Block number to write"), + arg_str1("d", "data", "", "Block data (8 hex bytes)"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int blockno = arg_get_int_def(ctx, 1, -1); + + int dlen = 0; + uint8_t data[8] = {0x00}; + CLIGetHexWithReturn(ctx, 2, data, &dlen); + + CLIParserFree(ctx); + + if (blockno < 0) { + PrintAndLogEx(WARNING, "Wrong block number"); + return PM3_EINVARG; + } + + if (dlen != 8 ) { + PrintAndLogEx(WARNING, "Wrong data length. Expect 8, got %d", dlen); + return PM3_EINVARG; + } + + PrintAndLogEx(INFO, "Block: %0d (0x%02X) [ %s]", blockno, blockno, sprint_hex(data, dlen)); + + // send write Block + int res = topaz_write_erase8_block(blockno, data); + + if (res == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )" ); + } else { + PrintAndLogEx(WARNING, "Write ( " _RED_("fail") " )" ); + } + + topaz_switch_off_field(); + return res; +} + static int CmdHelp(const char *Cmd); static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"list", CmdHFTopazList, AlwaysAvailable, "List Topaz history"}, - {"info", CmdHFTopazInfo, IfPm3Iso14443a, "Tag information"}, - {"reader", CmdHFTopazReader, IfPm3Iso14443a, "Act like a Topaz reader"}, - {"sim", CmdHFTopazSim, IfPm3Iso14443a, "Simulate Topaz tag"}, - {"sniff", CmdHFTopazSniff, IfPm3Iso14443a, "Sniff Topaz reader-tag communication"}, - {"raw", CmdHFTopazCmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"dump", CmdHFTopazDump, IfPm3Iso14443a, "Dump TOPAZ family tag to file"}, + {"list", CmdHFTopazList, AlwaysAvailable, "List Topaz history"}, + {"info", CmdHFTopazInfo, IfPm3Iso14443a, "Tag information"}, + {"reader", CmdHFTopazReader, IfPm3Iso14443a, "Act like a Topaz reader"}, + {"sim", CmdHFTopazSim, IfPm3Iso14443a, "Simulate Topaz tag"}, + {"sniff", CmdHFTopazSniff, IfPm3Iso14443a, "Sniff Topaz reader-tag communication"}, + {"raw", CmdHFTopazRaw, IfPm3Iso14443a, "Send raw hex data to tag"}, + {"rdbl", CmdHFTopazRdBl, IfPm3Iso14443a, "Read block"}, + {"view", CmdHFTopazView, AlwaysAvailable, "Display content from tag dump file"}, + {"wrbl", CmdHFTopazWrBl, IfPm3Iso14443a, "Write block"}, {NULL, NULL, 0, NULL} }; diff --git a/client/src/cmdhftopaz.h b/client/src/cmdhftopaz.h index 773508798..19dfbb2f9 100644 --- a/client/src/cmdhftopaz.h +++ b/client/src/cmdhftopaz.h @@ -21,8 +21,32 @@ #include "common.h" + +#define TOPAZ_STATIC_MEMORY (0x0F * 8) // 15 blocks with 8 Bytes each +#define TOPAZ_BLOCK_SIZE 8 +#define TOPAZ_MAX_SIZE 512 + +// a struct to describe a memory area which contains lock bits and the corresponding lockable memory area +typedef struct dynamic_lock_area_s { + struct dynamic_lock_area_s *next; + uint16_t byte_offset; // the address of the lock bits + uint16_t size_in_bits; + uint16_t first_locked_byte; // the address of the lockable area + uint16_t bytes_locked_per_bit; +} dynamic_lock_area_t; + +typedef struct topaz_tag_s { + uint8_t HR01[2]; + uint8_t uid[7]; + uint16_t size; + uint8_t data_blocks[TOPAZ_STATIC_MEMORY / 8][8]; // this memory is always there + uint8_t *dynamic_memory; // this memory can be there + dynamic_lock_area_t *dynamic_lock_areas; // lock area descriptors +} topaz_tag_t; + + + int CmdHFTopaz(const char *Cmd); int CmdHFTopazInfo(const char *Cmd); - int readTopazUid(bool loop, bool verbose); #endif diff --git a/client/src/fileutils.c b/client/src/fileutils.c index 99f5395d2..dcfbdfc32 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -28,6 +28,7 @@ #include "util.h" #include "cmdhficlass.h" // pagemap #include "protocols.h" // iclass defines +#include "cmdhftopaz.h" // TOPAZ defines #ifdef _WIN32 #include "scandir.h" @@ -632,6 +633,24 @@ int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, (*callback)(root); break; } + case jsfTopaz: { + topaz_tag_t *tag = (topaz_tag_t *)(void *) data; + JsonSaveStr(root, "FileType", "topaz"); + JsonSaveBufAsHexCompact(root, "$.Card.UID", tag->uid, sizeof(tag->uid)); + JsonSaveBufAsHexCompact(root, "$.Card.H0R1", tag->HR01, sizeof(tag->HR01)); + JsonSaveBufAsHexCompact(root, "$.Card.Size", (uint8_t *)&(tag->size), 2); + for (size_t i = 0; i < TOPAZ_STATIC_MEMORY / 8; i++) { + char path[PATH_MAX_LENGTH] = {0}; + snprintf(path, sizeof(path), "$.blocks.%zu", i); + JsonSaveBufAsHexCompact(root, path, &tag->data_blocks[i][0], TOPAZ_BLOCK_SIZE); + } + + // ICEMAN todo: add dynamic memory. + // uint16_z Size + // uint8_t *dynamic_memory; + + break; + } default: break; } @@ -1277,7 +1296,39 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz if (!strcmp(ctype, "legic")) { JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen); } + + if (!strcmp(ctype, "topaz")) { + topaz_tag_t *mem = (topaz_tag_t *)udata; + JsonLoadBufAsHex(root, "$.Card.UID", mem->uid, sizeof(mem->uid), datalen); + JsonLoadBufAsHex(root, "$.Card.HR01", mem->HR01, sizeof(mem->HR01), datalen); + JsonLoadBufAsHex(root, "$.Card.Size", (uint8_t *)&(mem->size), 2, datalen); + + size_t sptr = 0; + for (int i = 0; i < (TOPAZ_STATIC_MEMORY / 8); i++) { + + if (sptr + TOPAZ_BLOCK_SIZE > maxdatalen) { + retval = PM3_EMALLOC; + goto out; + } + + char blocks[30] = {0}; + snprintf(blocks, sizeof(blocks), "$.blocks.%d", i); + + size_t len = 0; + JsonLoadBufAsHex(root, blocks, &mem->data_blocks[sptr][0], TOPAZ_BLOCK_SIZE, &len); + if (!len) + break; + + sptr += len; + + // ICEMAN todo: add dynamic memory. + // uint16_z Size + // uint8_t *dynamic_memory; + } + + *datalen += sptr; + } out: if (callback != NULL) { diff --git a/client/src/fileutils.h b/client/src/fileutils.h index 758dab84f..d237b0fe7 100644 --- a/client/src/fileutils.h +++ b/client/src/fileutils.h @@ -48,6 +48,7 @@ typedef enum { jsfEM4x50, jsfFido, jsfFudan, + jsfTopaz, } JSONFileType; typedef enum { diff --git a/client/src/nfc/ndef.c b/client/src/nfc/ndef.c index f4d07ba7d..bd4e69710 100644 --- a/client/src/nfc/ndef.c +++ b/client/src/nfc/ndef.c @@ -1036,21 +1036,22 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { case 0x01: { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "--- " _CYAN_("NDEF Lock Control") " ---"); if (len != 3) { - PrintAndLogEx(WARNING, "NDEF Lock Control block size must be 3 instead of %d.", len); + PrintAndLogEx(WARNING, "NDEF Lock Control block size must be 3 instead of %d", len); } else { uint8_t pages_addr = (ndef[indx] >> 4) & 0x0f; uint8_t byte_offset = ndef[indx] & 0x0f; uint8_t Size = ndef[indx + 1]; uint8_t BytesLockedPerLockBit = (ndef[indx + 2] >> 4) & 0x0f; uint8_t bytes_per_page = ndef[indx + 2] & 0x0f; - PrintAndLogEx(SUCCESS, " Pages addr (number of pages)... %d", pages_addr); - PrintAndLogEx(SUCCESS, "Byte offset (number of bytes)... %d", byte_offset); - PrintAndLogEx(SUCCESS, "Size in bits of the lock area %d. bytes approx %d", Size, Size / 8); - PrintAndLogEx(SUCCESS, " Number of bytes / page... %d", bytes_per_page); - PrintAndLogEx(SUCCESS, "Bytes Locked Per LockBit"); - PrintAndLogEx(SUCCESS, " number of bytes that each dynamic lock bit is able to lock: %d", BytesLockedPerLockBit); + PrintAndLogEx(SUCCESS, " Pages addr (number of pages).... %d", pages_addr); + PrintAndLogEx(SUCCESS, " Byte offset (number of bytes)... %d", byte_offset); + PrintAndLogEx(SUCCESS, " Lock Area size in bits.......... %d ( %d bytes )", Size, Size / 8); + PrintAndLogEx(SUCCESS, " Number of bytes / page... %d", bytes_per_page); + PrintAndLogEx(SUCCESS, " Bytes Locked Per LockBit"); + PrintAndLogEx(SUCCESS, " number of bytes that each dynamic lock bit locks... %d", BytesLockedPerLockBit); } indx += len; break; @@ -1058,18 +1059,19 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { case 0x02: { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); - PrintAndLogEx(SUCCESS, "--- " _CYAN_("NDEF Memory Control") " ---"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "--- " _CYAN_("NDEF Memory Control") " ---"); if (len != 3) { - PrintAndLogEx(WARNING, "NDEF Memory Control block size must be 3 instead of %d.", len); + PrintAndLogEx(WARNING, "NDEF Memory Control block size must be 3 instead of %d", len); } else { uint8_t pages_addr = (ndef[indx] >> 4) & 0x0f; uint8_t byte_offset = ndef[indx] & 0x0f; uint8_t Size = ndef[indx + 1]; uint8_t bytes_per_page = ndef[indx + 2] & 0x0f; - PrintAndLogEx(SUCCESS, " Pages addr (number of pages) : %d", pages_addr); - PrintAndLogEx(SUCCESS, "Byte offset (number of bytes) : %d", byte_offset); - PrintAndLogEx(SUCCESS, "Size in bits of the reserved area : %d. bytes approx: %d", Size, Size / 8); - PrintAndLogEx(SUCCESS, " Number of bytes / page : %d", bytes_per_page); + PrintAndLogEx(SUCCESS, "Pages addr (number of pages).... %d", pages_addr); + PrintAndLogEx(SUCCESS, "Byte offset (number of bytes)... %d", byte_offset); + PrintAndLogEx(SUCCESS, "Reserved area size in bits...... %d ( %d bytes )", Size, Size / 8); + PrintAndLogEx(SUCCESS, " Number of bytes / page... %d", bytes_per_page); } indx += len; break; @@ -1077,6 +1079,7 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { case 0x03: { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "--- " _CYAN_("NDEF Message") " ---"); if (len == 0) { PrintAndLogEx(SUCCESS, "Found NDEF message w zero length"); @@ -1094,6 +1097,7 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { case 0xfd: { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "--- " _CYAN_("Proprietary info") " ---"); PrintAndLogEx(SUCCESS, " Can't decode, skipping %d bytes", len); indx += len; From 003623e5a731a40eb477a2dee964bbebe6477dae Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 6 Aug 2022 13:31:46 +0200 Subject: [PATCH 184/759] fix binary string printing. Making sure no left over data is in static array --- client/src/cmdhfmfu.c | 2 +- client/src/cmdhftopaz.c | 2 +- client/src/util.c | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 7ff381d22..47ab3a997 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -607,7 +607,7 @@ static int ndef_print_CC(uint8_t *data) { uint8_t mbread = (data[3] & 0x01); PrintAndLogEx(SUCCESS, " %02X: Additional feature information", data[3]); - PrintAndLogEx(SUCCESS, " 00000000"); + PrintAndLogEx(SUCCESS, " %s", sprint_bin(&data[3], 1)); PrintAndLogEx(SUCCESS, " xxx..... - %02X: RFU ( %s )", msb3, (msb3 == 0) ? _GREEN_("ok") : _RED_("fail")); PrintAndLogEx(SUCCESS, " ...x.... - %02X: %s special frame", sf, (sf) ? "support" : "don\'t support"); PrintAndLogEx(SUCCESS, " ....x... - %02X: %s lock block", lb, (lb) ? "support" : "don\'t support"); diff --git a/client/src/cmdhftopaz.c b/client/src/cmdhftopaz.c index 6d7a1975d..805d891d8 100644 --- a/client/src/cmdhftopaz.c +++ b/client/src/cmdhftopaz.c @@ -391,7 +391,7 @@ static int topaz_print_CC(uint8_t *data) { PrintAndLogEx(SUCCESS, " %02X: Additional feature information", data[3]); PrintAndLogEx(SUCCESS, " ^^"); - PrintAndLogEx(SUCCESS, " 00000000"); + PrintAndLogEx(SUCCESS, " %s", sprint_bin(&data[3], 1)); PrintAndLogEx(SUCCESS, " xxx..... - %02X: RFU ( %s )", msb3, (msb3 == 0) ? _GREEN_("ok") : _RED_("fail")); PrintAndLogEx(SUCCESS, " ...x.... - %02X: %s special frame", sf, (sf) ? "support" : "don\'t support"); PrintAndLogEx(SUCCESS, " ....x... - %02X: %s lock block", lb, (lb) ? "support" : "don\'t support"); diff --git a/client/src/util.c b/client/src/util.c index 57e213feb..e849ebb62 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -404,6 +404,8 @@ char *sprint_bytebits_bin_break(const uint8_t *data, const size_t len, const uin // 3072 + end of line characters if broken at 8 bits static char buf[MAX_BIN_BREAK_LENGTH] = {0}; + memset(buf, 0, sizeof(buf)); + char *tmp = buf; // loop through the out_index to make sure we don't go too far From 3e15b8f2db6e3cfc0bad1f34d6df1dbb044fa813 Mon Sep 17 00:00:00 2001 From: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> Date: Sun, 7 Aug 2022 00:48:20 -0700 Subject: [PATCH 185/759] Added Vigik and Blackhat keys Signed-off-by: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 31 ++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 1b0d1aa4e..017f07adb 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1745,3 +1745,34 @@ FFD46FF6C5EE # data from http://www.proxmark.org/forum/viewtopic.php?pid=45100#p45100 7CB033257498 # key A 1153AABAFF6C # key b +# +# Vigik ScanBadge App (fr.badgevigik.scanbadge) +# Website https://badge-vigik.fr/ - By Alex` +0000A2B3C86F +021200c20307 +021209197507 +1E34B127AF9C +303041534956 +4143532D494E +41454E521985 +43412d627400 +455249524345 +456666456666 +45B722C63319 +484585414354 +4D414C414741 +536563644C65 +57D27B730760 +593DD8FE167A +6472616E7265 +65626F726369 +680E95F3C287 +709BA7D4F920 +8829DAD9AF76 +92D0A0999CBA +948EE7CFC9DB +9EB7C8A6D4E3 +A22AE12C9013 +AFC984A3576E +# Blackhat USA 2013 conference +012279BAD3E5 From 5e093962bcb5b31ce7135a69d3f0fee958a3a8c0 Mon Sep 17 00:00:00 2001 From: kormax Date: Thu, 11 Aug 2022 19:25:35 +0300 Subject: [PATCH 186/759] improve ecp2 annotations to support varying length, append terminal type to annotation --- client/src/cmdhflist.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index b33cd37bf..d667b981f 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -182,14 +182,29 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i } if (cmdsize >= 7 && cmd[0] == ECP_HEADER) { - // Second byte of ECP frame indicates its version - // Version 0x01 payload is 7 bytes long (including crc) - // Version 0x02 payload is 15 bytes long (including crc) + // 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 == 15) { - snprintf(exp, size, "ECP2"); + } 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; + default: + snprintf(exp, size, "ECP2"); + break; + } return PM3_SUCCESS; } } From 5fed5a8e629784eec1e91df3926258fd044f57f7 Mon Sep 17 00:00:00 2001 From: kormax Date: Thu, 11 Aug 2022 19:30:05 +0300 Subject: [PATCH 187/759] add mobile-first aids --- client/resources/aidlist.json | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index 0188397f3..bc939de14 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -2206,5 +2206,61 @@ "Name": "SL Resekort", "Description": "transport card", "Type": "transport" + }, + { + "AID": "4F53452E5641532E3031", + "Vendor": "Apple, Google", + "Country": "", + "Name": "Value-Added Services (OSE.VAS.01)", + "Description": "Used by Apple VAS and Google SmartTap", + "Type": "loyalty" + }, + { + "AID": "A000000476D0000101", + "Vendor": "Google", + "Country": "", + "Name": "Google SmartTap 1.3 (Deprecated)", + "Description": "", + "Type": "loyalty" + }, + { + "AID": "A000000476D0000111", + "Vendor": "Google", + "Country": "", + "Name": "Google SmartTap 2.0", + "Description": "", + "Type": "loyalty" + }, + { + "AID": "A0000002480400", + "Vendor": "ISO/IEC JTC1/SC17", + "Country": "", + "Name": "Personal identification (mDL)", + "Description": "ISO/IEC 18013-5:2021 compliant Mobile driving licence (mDL) application.", + "Type": "identity" + }, + { + "AID": "A000000676", + "Vendor": "Blackboard", + "Country": "United States", + "Name": "Student ID", + "Description": "Student ID cards", + "Type": "identity" + }, + { + "AID": "A000000809434343444B467631", + "Vendor": "Car Connectivity Consortium (CCC)", + "Country": "", + "Name": "Digital Car Key", + "Description": "", + "Type": "access" + }, + { + "AID": "A0000008580101", + "Vendor": "Apple", + "Country": "", + "Name": "Apple Home Key", + "Description": "NFC Home Key for select HomeKit-compatible locks", + "Type": "access" } ] From 11065e965a9d7fbdd4397947fa7ccea5465f02bf Mon Sep 17 00:00:00 2001 From: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> Date: Sat, 13 Aug 2022 01:15:55 -0700 Subject: [PATCH 188/759] Added Vigik verified by quantum-x & iGuard Simple Signed-off-by: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 017f07adb..ce3a1237d 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1774,5 +1774,27 @@ FFD46FF6C5EE 9EB7C8A6D4E3 A22AE12C9013 AFC984A3576E -# Blackhat USA 2013 conference +# Vigik verified by quantum-x +# https://github.com/RfidResearchGroup/proxmark3/pull/1742#issuecomment-1206113976 +A00027000099 +A00016000028 +A00003000028 +A0000F000345 +A00001000030 +A00002000086 +A00002000036 +A00002000088 +A00000000058 +A00000000096 +A00000000008 +A00000043D79 +A00000000064 +A00025000030 +A00003000057 +# +# BH USA 2013 conference 012279BAD3E5 +# +# iGuard Simple (and reverse) keys +AAAAAAFFFFFF +FFFFFFAAAAAA From 5dce2d3f5a6d214d60ffcc782169ccbf5456722a Mon Sep 17 00:00:00 2001 From: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> Date: Sat, 13 Aug 2022 13:25:43 -0700 Subject: [PATCH 189/759] Correcting some O to 0 Signed-off-by: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index ce3a1237d..7a94d746b 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1694,19 +1694,19 @@ A0A1A2A8A4A5 1A1B1C1D1E1F 1665FE2AE945 158B51947A8E -EL67EC67C7FF -D53732OFF9OE +El67EC67C7FF +D537320FF90E 5E56BFA9E2C9 F81CED821B63 C81584EF5EDF 9551F8F9259D -36EL765CE3E8 +36El765CE3E8 509052C8E42E 776C9B03BE71 -C608EL3ADD50 +C608El3ADD50 BEE8B345B949 -EDOEC56EEFDD -9716D524LE28 +ED0EC56EEFDD +9716D524lE28 05D1FC14DC31 3321FB75A356 F22A78E29880 @@ -1720,9 +1720,9 @@ DB32A6811327 8AA8544A2207 8C5819E780A4 7549E90353A2 -2E52ABEOCE95 +2E52ABE0CE95 E46210ED98AB -61DO30COD7A8 +61D030C0D7A8 18E20102821E DA59354DFB88 040047C12B75 From d2a7e9377829f31edfd360ca047f8e0f25b6efe6 Mon Sep 17 00:00:00 2001 From: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> Date: Sat, 13 Aug 2022 13:27:56 -0700 Subject: [PATCH 190/759] Correcting L to 1 Signed-off-by: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 7a94d746b..389f86683 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1694,19 +1694,19 @@ A0A1A2A8A4A5 1A1B1C1D1E1F 1665FE2AE945 158B51947A8E -El67EC67C7FF +E167EC67C7FF D537320FF90E 5E56BFA9E2C9 F81CED821B63 C81584EF5EDF 9551F8F9259D -36El765CE3E8 +36E1765CE3E8 509052C8E42E 776C9B03BE71 -C608El3ADD50 +C608E13ADD50 BEE8B345B949 ED0EC56EEFDD -9716D524lE28 +9716D5241E28 05D1FC14DC31 3321FB75A356 F22A78E29880 From 1103f69b9615a50fd75ee37b7dc45ece0003d952 Mon Sep 17 00:00:00 2001 From: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> Date: Sat, 13 Aug 2022 21:21:32 -0700 Subject: [PATCH 191/759] Removed dupes, added more keys, fixed some HEX o/L Signed-off-by: UberGuidoZ <57457139+UberGuidoZ@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 27 +++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 389f86683..63afe7c0b 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1603,7 +1603,8 @@ FA1FBB3F0F1F FF16014FEFC7 ################################## # Keys from Flipper Zero Community -# Includes captured keys from devs and community +# +# Last update: Aug 13, 2022 # # Strelka Extension 5C83859F2224 @@ -1741,10 +1742,26 @@ FFD46FF6C5EE 16CA203B811B 11AC8C8F3AF2 # -# Spackular -# data from http://www.proxmark.org/forum/viewtopic.php?pid=45100#p45100 -7CB033257498 # key A -1153AABAFF6C # key b +# The Westin Jakarta Indonesia from D4DB0D +# Peppers Hotel Unknown location from D4DB0D +6E0DD4136B0A +A0A1A2A3A4A5 +B578F38A5C61 +141940E9B71B +0000014B5C31 +3B1D3AAC866E +95E9EE4CCF8F +FEA6B332F04A +BE0EC5155806 +0500D6BFCC4F +FC5AC7678BE3 +F09BB8DD142D +B4B3FFEDBE0A +540E0D2D1D08 +# +# Schlage 9691T Keyfob from seasnaill +7579B671051A +4F4553746B41 # # Vigik ScanBadge App (fr.badgevigik.scanbadge) # Website https://badge-vigik.fr/ - By Alex` From 0968b39243928ec24659660b64bc614189d145cd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 16 Aug 2022 04:18:27 +0200 Subject: [PATCH 192/759] fix #1694 - take in consideration pointer could be called with NULL --- CHANGELOG.md | 1 + armsrc/Standalone/hf_mfcsim.c | 28 +++++++++++++++++++--------- armsrc/mifaresim.c | 7 +++++++ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f87454e0..7b87b94fe 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 bad memory handling in MifareSim device side (@iceman1001) - Added json topaz file format (@iceman1001) - Added `hf topaz rdbl, wrbl, view` commands (@iceman1001) - Added more details to the annotations of `hf mfdes list` output (@nvx) diff --git a/armsrc/Standalone/hf_mfcsim.c b/armsrc/Standalone/hf_mfcsim.c index 34541a390..f4a8e73b5 100644 --- a/armsrc/Standalone/hf_mfcsim.c +++ b/armsrc/Standalone/hf_mfcsim.c @@ -56,10 +56,11 @@ static char cur_dump_file[22] = {0}; static bool fill_eml_from_file(char *dumpfile) { // check file exist - if (!exists_in_spiffs(dumpfile)) { + if (exists_in_spiffs(dumpfile) == false) { Dbprintf(_RED_("Dump file %s not found!"), dumpfile); return false; } + //check dumpfile size uint32_t size = size_in_spiffs(dumpfile); if (size != DUMP_SIZE) { @@ -67,9 +68,12 @@ static bool fill_eml_from_file(char *dumpfile) { BigBuf_free(); return false; } + //read and load dump file - if (g_dbglevel >= DBG_INFO) + if (g_dbglevel >= DBG_INFO) { Dbprintf(_YELLOW_("Found dump file %s. Uploading to emulator memory..."), dumpfile); + } + emlClearMem(); uint8_t *emCARD = BigBuf_get_EM_addr(); rdv40_spiffs_read_as_filetype(dumpfile, emCARD, size, RDV40_SPIFFS_SAFETY_SAFE); @@ -77,7 +81,7 @@ static bool fill_eml_from_file(char *dumpfile) { } static bool write_file_from_eml(char *dumpfile) { - if (!exists_in_spiffs(dumpfile)) { + if (exists_in_spiffs(dumpfile) == false) { Dbprintf(_RED_("Dump file %s not found!"), dumpfile); return false; } @@ -99,14 +103,18 @@ void RunMod(void) { bool flag_has_dumpfile = false; for (int i = 1;; i++) { + //Exit! usbcommand break if (data_available()) break; - //Infinite loop + // infinite loop if (i > 15) { - if (!flag_has_dumpfile) - break; //still no dump file found - i = 1; //next loop + // still no dump file found + if (flag_has_dumpfile == false) { + break; + } + // next loop + i = 1; } //Indicate which card will be simulated @@ -115,7 +123,7 @@ void RunMod(void) { //Try to load dump form flash sprintf(cur_dump_file, HF_MFCSIM_DUMPFILE_SIM, i); Dbprintf(_YELLOW_("[Slot: %d] Try to load dump file: %s"), i, cur_dump_file); - if (!fill_eml_from_file(cur_dump_file)) { + if (fill_eml_from_file(cur_dump_file) == false) { Dbprintf(_YELLOW_("[Slot: %d] Dump load Failed, Next one!"), i); LEDsoff(); continue; @@ -145,8 +153,10 @@ void RunMod(void) { } Dbprintf(_YELLOW_("[Slot: %d] Write Success! Change to next one!"), i); } - if (!flag_has_dumpfile) + + if (flag_has_dumpfile == false) { Dbprintf("No dump file found!"); + } Dbprintf("Breaked! Exit standalone mode!"); SpinErr(15, 200, 3); return; diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 47cae98ed..c2f81df21 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -486,6 +486,13 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1 uint8_t *rats = NULL; uint8_t rats_len = 0; + + // if fct is called with NULL we need to assign some memory since this pointer is passaed around + uint8_t datain_tmp[10] = {0}; + if (datain == NULL) { + datain = datain_tmp; + } + //Here, we collect UID,sector,keytype,NT,AR,NR,NT2,AR2,NR2 // This will be used in the reader-only attack. From a80680d7a092d027afc5e56ac15275d516ef5207 Mon Sep 17 00:00:00 2001 From: Michael Micsen Johannessen Wehus Date: Wed, 17 Aug 2022 01:24:38 +0100 Subject: [PATCH 193/759] Added script to simulate HID mifare credentials Only supports H10301 --- client/luascripts/hf_mf_sim_hid.lua | 185 ++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 client/luascripts/hf_mf_sim_hid.lua diff --git a/client/luascripts/hf_mf_sim_hid.lua b/client/luascripts/hf_mf_sim_hid.lua new file mode 100644 index 000000000..90b597149 --- /dev/null +++ b/client/luascripts/hf_mf_sim_hid.lua @@ -0,0 +1,185 @@ +-- +-- hf_mf_sim_hid.lua - A tool to clone a large number of tags at once. +-- Adapted from lf_hid_bulkclone.lua +-- Created 16.08.2022 +local getopt = require('getopt') +local ansicolors = require('ansicolors') + +copyright = '' +author = "Michael Micsen" +version = 'v0.0.1' +desc = [[ +Perform simulation of Mifare credentials with HID encoding +This script only supports: H10301 +]] +example = [[ + -- + script run hf_mf_sim_hid.lua -f 1 -c 10000 +]] +usage = [[ +script run hf_mf_sim_hid.lua -f facility -c card_number +]] +arguments = [[ + -h : this help + -f : facility id + -c : starting card id +]] +local DEBUG = true +--local bxor = bit32.bxor +local bor = bit32.bor +local lshift = bit32.lshift +--- +-- A debug printout-function +local function dbg(args) + if not DEBUG then return end + if type(args) == 'table' then + local i = 1 + while args[i] do + dbg(args[i]) + i = i+1 + end + else + print('###', args) + end +end +--- +-- This is only meant to be used when errors occur +local function oops(err) + print('ERROR:', err) + core.clearCommandBuffer() + return nil, errr +end +--- +-- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print(ansicolors.cyan..'Usage'..ansicolors.reset) + print(usage) + print(ansicolors.cyan..'Arguments'..ansicolors.reset) + print(arguments) + print(ansicolors.cyan..'Example usage'..ansicolors.reset) + print(example) +end +--- +-- Exit message +local function exitMsg(msg) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print(msg) + print() +end +--[[Implement a function to simply visualize the bitstream in a text format +--This is especially helpful for troubleshooting bitwise math issues]]-- +local function toBits(num,bits) + -- returns a table of bits, most significant first. + bits = bits or math.max(1, select(2, math.frexp(num))) + local t = {} -- will contain the bits + for b = bits, 1, -1 do + t[b] = math.fmod(num, 2) + num = math.floor((num - t[b]) / 2) + end + return table.concat(t) +end + +--[[ + Likely, I'm an idiot, but I couldn't find any parity functions in Lua + This can also be done with a combination of bitwise operations (in fact, + is the canonically "correct" way to do it, but my brain doesn't just + default to this and so counting some ones is good enough for me +]]-- +local function evenparity(s) + local _, count = string.gsub(s, '1', '') + local p = count % 2 + if (p == 0) then + return false + else + return true + end +end + +local function isempty(s) + return s == nil or s == '' +end + +--[[ + The Proxmark3 "clone" functions expect the data to be in hex format so + take the card id number and facility ID as arguments and construct the + hex. This should be easy enough to extend to non 26bit formats +]]-- +local function cardHex(i, f) + + fac = lshift(f, 16) + id = bor(i, fac) + stream = toBits(id, 24) + + --As the function defaults to even parity and returns a boolean, + --perform a 'not' function to get odd parity + high = evenparity(string.sub(stream,1,12)) and 1 or 0 + low = not evenparity(string.sub(stream,13)) and 1 or 0 + bits = bor( lshift(id, 1), low) + bits = bor( bits, lshift(high, 25)) + + --Add sentinel bit + sentinel = lshift(1, 26) + bits = bor(bits, sentinel) + + + return ('%08x'):format(bits) +end +--- +-- main +local function main(args) + + print( string.rep('--',20) ) + print( string.rep('--',20) ) + print() + + if #args == 0 then return help() end + + --I really wish a better getopt function would be brought in supporting + --long arguments, but it seems this library was chosen for BSD style + --compatibility + for o, a in getopt.getopt(args, 'f:c:h') do + if o == 'h' then return help() end + if o == 'f' then + if isempty(a) then + print('You did not supply a facility code, using 0') + facility = 0 + else + facility = a + end + end + if o == 'c' then + print(a) + if isempty(a) then return oops('You must supply the flag -c (card number)1') end + cardnum = a + end + end + + --Due to my earlier complaints about how this specific getopt library + --works, specifying ':' does not enforce supplying a value, thus we + --need to do these checks all over again. + if isempty(cardnum) then return oops('You must supply the flag -c (card number)2') end + --If the facility ID is non specified, ensure we code it as zero + if isempty(facility) then + print('Using 0 for the facility code as -f was not supplied') + facility = 0 + end + + -- Write the MAD to read for a Mifare HID credential + core.console('hf mf esetblk -b 1 -d 1B014D48000000000000000000000000') + core.console('hf mf esetblk -b 3 -d A0A1A2A3A4A5787788C189ECA97F8C2A') + --Write the sector trailer for the credential sector + core.console('hf mf esetblk -b 7 -d 484944204953787788AA204752454154') + local cardh = cardHex(cardnum, facility) + print('Hex') + print(cardh) + core.console( ('hf mf esetblk -b 5 -d 020000000000000000000000%s'):format(cardh) ) + + core.console('hf mf sim --1k -i') +end + +main(args) From 1a65d6b157228fd5300934583d9fbbedd2dc41c5 Mon Sep 17 00:00:00 2001 From: Michael Micsen Johannessen Wehus Date: Wed, 17 Aug 2022 01:27:48 +0100 Subject: [PATCH 194/759] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b87b94fe..128638811 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed - AID limitations when using Gallagher key diversification (@DarkMatterMatt) - Added new standalone mode `lf_em4100rsww` (@zabszk) - Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz) + - Added `script run hf_mf_hid_sim.lua` ## [Frostbit.4.14831][2022-01-11] From 7338c502f0c45e4533da7c1ba027f7819114d94b Mon Sep 17 00:00:00 2001 From: Michael Micsen Johannessen Wehus Date: Wed, 17 Aug 2022 01:28:21 +0100 Subject: [PATCH 195/759] Attribution --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 128638811..8c8294d2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,7 +84,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed - AID limitations when using Gallagher key diversification (@DarkMatterMatt) - Added new standalone mode `lf_em4100rsww` (@zabszk) - Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz) - - Added `script run hf_mf_hid_sim.lua` + - Added `script run hf_mf_hid_sim.lua` (@micsen) ## [Frostbit.4.14831][2022-01-11] From 65239243935ae1360de1c541f7dbf91616572ce6 Mon Sep 17 00:00:00 2001 From: Anton Bolshakov Date: Thu, 18 Aug 2022 11:57:46 +0800 Subject: [PATCH 196/759] Update Makefile.defs Do not overwrite global CC values (if specified in env) Signed-off-by: Anton Bolshakov --- Makefile.defs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 5a131c971..8f8c36e3b 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -38,9 +38,9 @@ TAR = tar TARFLAGS ?= -v --ignore-failed-read -r TARFLAGS += -C .. -f CROSS ?= arm-none-eabi- -CC = gcc -CXX = g++ -LD = g++ +CC ?= gcc +CXX ?= g++ +LD ?= g++ SH = sh BASH = bash PERL = perl From de73a58a78c007a1f1cd0a93fa085104ded3666e Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 18 Aug 2022 08:42:29 +0200 Subject: [PATCH 197/759] Revert "Update Makefile.defs" --- Makefile.defs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 8f8c36e3b..5a131c971 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -38,9 +38,9 @@ TAR = tar TARFLAGS ?= -v --ignore-failed-read -r TARFLAGS += -C .. -f CROSS ?= arm-none-eabi- -CC ?= gcc -CXX ?= g++ -LD ?= g++ +CC = gcc +CXX = g++ +LD = g++ SH = sh BASH = bash PERL = perl From 5a6440f298d9560e9f71b150c5b3532a0e94baba Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 18 Aug 2022 23:16:08 +0200 Subject: [PATCH 198/759] fix double param name --- client/src/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 25c039f4e..670be80e9 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -2039,7 +2039,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { arg_lit0("a", NULL, "Input key A (def)"), arg_lit0("b", NULL, "Input key B"), arg_str0("f", "file", "", "filename of dictionary"), - arg_lit0("s", "slow", "Slower acquisition (required by some non standard cards)"), + arg_lit0(NULL, "slow", "Slower acquisition (required by some non standard cards)"), arg_lit0("l", "legacy", "legacy mode (use the slow `hf mf chk`)"), arg_lit0("v", "verbose", "verbose output (statistics)"), From 49f2f59398494e7c0cae45f37731c860ae43987d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 19 Aug 2022 23:14:31 +0200 Subject: [PATCH 199/759] textual --- doc/md/Use_of_Proxmark/0_Compilation-Instructions.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md index a53b209e7..bd8fc00f3 100644 --- a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md +++ b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md @@ -13,6 +13,7 @@ - [if you got an error](#if-you-got-an-error) - [Install](#install) - [Flash the BOOTROM & FULLIMAGE](#flash-the-bootrom--fullimage) + - [The button trick](#the-button-trick) - [flasher stops and warns you about firmware image](#flasher-stops-and-warns-you-about-firmware-image) - [Run the client](#run-the-client) - [Next steps](#next-steps) @@ -106,8 +107,15 @@ or proxmark3 /dev/ttyACM0 --flash --unlock-bootloader --image /tmp/my-bootrom.elf --image /tmp/my-fullimage.elf ``` -If the flasher can't detect your Proxmark3 (especially the very first time you flash a new device), force it to enter the bootloader mode as following: -With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. You can release the button, two of the four LEDs should stay on. You're in bootloader mode, ready for the next step. In case the two LEDs don't stay on when you're releasing the button, you've a very old bootloader, start over and keep the button pressed during the whole flashing procedure. +### The button trick +^[Top](#top) +If the flasher can't detect your Proxmark3 (especially the very first time you flash a new device), force it to enter the bootloader mode as following: + +With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. +You can release the button, two of the four LEDs should stay on. +You're in bootloader mode, ready for the next step. + +In case the two LEDs don't stay on when you're releasing the button, you've a very old bootloader, start over and keep the button pressed during the whole flashing procedure. ## flasher stops and warns you about firmware image From 58d764a49a324fb5d86607711995eea7617def0a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 19 Aug 2022 23:15:48 +0200 Subject: [PATCH 200/759] textual --- doc/md/Use_of_Proxmark/0_Compilation-Instructions.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md index bd8fc00f3..d8dd7d5e0 100644 --- a/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md +++ b/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md @@ -109,6 +109,7 @@ proxmark3 /dev/ttyACM0 --flash --unlock-bootloader --image /tmp/my-bootrom.elf - ### The button trick ^[Top](#top) + If the flasher can't detect your Proxmark3 (especially the very first time you flash a new device), force it to enter the bootloader mode as following: With your Proxmark3 unplugged from your machine, press and hold the button on your Proxmark3 as you plug it into a USB port. From 4a31ce16563e74f4eafce349be1d256f393f1102 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 20 Aug 2022 13:08:24 +0200 Subject: [PATCH 201/759] hf mfdes mad textual --- client/src/cmdhfmfdes.c | 48 +++++++++++---- client/src/mifare/desfirecore.c | 101 ++++++++++++++++++-------------- client/src/mifare/mad.c | 9 +-- client/src/mifare/mad.h | 2 +- 4 files changed, 101 insertions(+), 59 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 45849035e..2c350e975 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -51,7 +51,7 @@ #define MAX_KEY_LEN 24 #define MAX_KEYS_LIST_LEN 1024 -#define status(x) ( ((uint16_t)(0x91<<8)) + (uint16_t)x ) +#define status(x) ( ((uint16_t)(0x91 << 8)) + (uint16_t)x ) /* static uint8_t desdefaultkeys[3][8] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //Official {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47}, @@ -342,8 +342,6 @@ static const char *getProductTypeStr(uint8_t *versionhw) { return "UNKNOWN PROD"; } - - static int mfdes_get_info(mfdes_info_res_t *info) { SendCommandNG(CMD_HF_DESFIRE_INFO, NULL, 0); PacketResponseNG resp; @@ -1776,18 +1774,20 @@ static int CmdHF14aDesMAD(const char *Cmd) { } } + PrintAndLogEx(SUCCESS, _CYAN_("Issuer")); + if (foundFFFFFF) { res = DesfireSelectAIDHexNoFieldOn(&dctx, 0xffffff); if (res == PM3_SUCCESS) { uint32_t madver = 0; res = DesfireValueFileOperations(&dctx, 0x00, MFDES_GET_VALUE, &madver); if (res != PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "MAD version : " _RED_("n/a")); + PrintAndLogEx(SUCCESS, "MAD version... " _RED_("n/a")); } else { if (madver == 3) - PrintAndLogEx(SUCCESS, "MAD version : " _GREEN_("3")); + PrintAndLogEx(SUCCESS, "MAD version... " _GREEN_("3")); else - PrintAndLogEx(WARNING, "MAD version : " _YELLOW_("%d"), madver); + PrintAndLogEx(WARNING, "MAD version... " _YELLOW_("%d"), madver); } uint8_t data[250] = {0}; @@ -1795,10 +1795,10 @@ static int CmdHF14aDesMAD(const char *Cmd) { res = DesfireReadFile(&dctx, 01, 0x000000, 0, data, &datalen); if (res != PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "Card Holder : " _RED_("n/a")); + PrintAndLogEx(SUCCESS, "Card Holder... " _RED_("n/a")); } else { if (datalen > 0) { - PrintAndLogEx(SUCCESS, "Card Holder : "); + PrintAndLogEx(SUCCESS, "Card Holder... "); if (verbose) { print_buffer_with_offset(data, datalen, 0, true); PrintAndLogEx(NORMAL, ""); @@ -1806,7 +1806,7 @@ static int CmdHF14aDesMAD(const char *Cmd) { MADCardHolderInfoDecode(data, datalen, verbose); PrintAndLogEx(NORMAL, ""); } else { - PrintAndLogEx(SUCCESS, "Card Holder : " _YELLOW_("none")); + PrintAndLogEx(SUCCESS, "Card Holder... " _YELLOW_("none")); } } @@ -1830,16 +1830,41 @@ static int CmdHF14aDesMAD(const char *Cmd) { } size_t madappcount = 0; - PrintAndLogEx(SUCCESS, "Applications : "); + PrintAndLogEx(SUCCESS, ""); + PrintAndLogEx(SUCCESS, _CYAN_("Applications")); for (int i = 0; i < PICCInfo.appCount; i++) { if ((AppList[i].appNum & 0xf00000) == 0xf00000) { DesfirePrintMADAID(AppList[i].appNum, verbose); + + // read file 0, 1, 2 + res = DesfireSelectAIDHexNoFieldOn(&dctx, AppList[i].appNum); + if (res == PM3_SUCCESS) { + uint8_t buf[APDU_RES_LEN] = {0}; + size_t buflen = 0; + + res = DesfireGetFileIDList(&dctx, buf, &buflen); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire GetFileIDList command " _RED_("error") ". Result: %d", res); + DropField(); + return PM3_ESOFT; + } + + if (buflen > 0) { + for (int j = 0; j < buflen; j++) { + PrintAndLogEx(INFO, " File ID... %02x", buf[j]); + } + } + } + madappcount++; } } - if (madappcount == 0) + if (madappcount == 0) { PrintAndLogEx(SUCCESS, "There is no MAD applications on the card"); + DropField(); + return PM3_SUCCESS; + } DropField(); return PM3_SUCCESS; @@ -3492,6 +3517,7 @@ static int CmdHF14ADesGetFileSettings(const char *Cmd) { DesfirePrintFileSettings(buf, buflen); + PrintAndLogEx(NORMAL, ""); DropField(); return PM3_SUCCESS; } diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index a89ac2a7a..c8987a546 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -942,7 +942,7 @@ void DesfirePrintMADAID(uint32_t appid, bool verbose) { if (appid == 0xffffff) PrintAndLogEx(SUCCESS, " Card issuer information application"); else - MADDFDecodeAndPrint(short_aid); + MADDFDecodeAndPrint(short_aid, verbose); } } @@ -953,7 +953,7 @@ void DesfirePrintAIDFunctions(uint32_t appid) { uint16_t short_aid = ((aid[2] & 0xF) << 12) | (aid[1] << 4) | (aid[0] >> 4); PrintAndLogEx(SUCCESS, " AID mapped to MIFARE Classic AID (MAD): " _YELLOW_("%02X"), short_aid); PrintAndLogEx(SUCCESS, " MAD AID Cluster 0x%02X : " _YELLOW_("%s"), short_aid >> 8, nxp_cluster_to_text(short_aid >> 8)); - MADDFDecodeAndPrint(short_aid); + MADDFDecodeAndPrint(short_aid, false); } else { AIDDFDecodeAndPrint(aid); } @@ -1827,7 +1827,7 @@ void DesfirePrintAppList(DesfireContext_t *dctx, PICCInfo_t *PICCInfo, AppListS DesfirePrintAIDFunctions(appList[i].appNum); if (PICCInfo->authCmdCheck.checked) { - PrintAndLogEx(SUCCESS, "Auth commands: " NOLF); + PrintAndLogEx(SUCCESS, "Auth commands: "); DesfireCheckAuthCommandsPrint(&appList[i].authCmdCheck); PrintAndLogEx(SUCCESS, ""); } @@ -2360,10 +2360,10 @@ void DesfireDecodeFileAcessMode(const uint8_t *mode, uint8_t *r, uint8_t *w, uin void DesfirePrintAccessRight(uint8_t *data) { uint8_t r = 0, w = 0, rw = 0, ch = 0; DesfireDecodeFileAcessMode(data, &r, &w, &rw, &ch); - PrintAndLogEx(SUCCESS, "read : %s", GetDesfireAccessRightStr(r)); - PrintAndLogEx(SUCCESS, "write : %s", GetDesfireAccessRightStr(w)); - PrintAndLogEx(SUCCESS, "readwrite: %s", GetDesfireAccessRightStr(rw)); - PrintAndLogEx(SUCCESS, "change : %s", GetDesfireAccessRightStr(ch)); + PrintAndLogEx(SUCCESS, " read......... %s", GetDesfireAccessRightStr(r)); + PrintAndLogEx(SUCCESS, " write........ %s", GetDesfireAccessRightStr(w)); + PrintAndLogEx(SUCCESS, " read/write... %s", GetDesfireAccessRightStr(rw)); + PrintAndLogEx(SUCCESS, " change....... %s", GetDesfireAccessRightStr(ch)); } void DesfireFillFileSettings(uint8_t *data, size_t datalen, FileSettings_t *fsettings) { @@ -2430,22 +2430,31 @@ static void DesfirePrintShortFileTypeSettings(FileSettings_t *fsettings) { switch (fsettings->fileType) { case 0x00: case 0x01: { - PrintAndLogEx(NORMAL, "size: %d [0x%x] " NOLF, fsettings->fileSize, fsettings->fileSize); + PrintAndLogEx(NORMAL, "Size " _YELLOW_("%d") " / " _YELLOW_("0x%X") NOLF, fsettings->fileSize, fsettings->fileSize); break; } case 0x02: { - PrintAndLogEx(NORMAL, "value [%d .. %d] lim cred: 0x%02x (%d [0x%x]) " NOLF, - fsettings->lowerLimit, fsettings->upperLimit, fsettings->limitedCredit, fsettings->value, fsettings->value); + PrintAndLogEx(NORMAL, "Value [%d .. %d] lim cred: 0x%02x (%d [0x%x]) " NOLF, + fsettings->lowerLimit, + fsettings->upperLimit, + fsettings->limitedCredit, + fsettings->value, + fsettings->value + ); break; } case 0x03: case 0x04: { - PrintAndLogEx(NORMAL, "record count %d/%d size: %d [0x%x]b " NOLF, - fsettings->curRecordCount, fsettings->maxRecordCount, fsettings->recordSize, fsettings->recordSize); + PrintAndLogEx(NORMAL, "Rec cnt %d/%d size: %d [0x%x]b " NOLF, + fsettings->curRecordCount, + fsettings->maxRecordCount, + fsettings->recordSize, + fsettings->recordSize + ); break; } case 0x05: { - PrintAndLogEx(NORMAL, "key type: 0x%02x version: 0x%02x " NOLF, fsettings->keyType, fsettings->keyVersion); + PrintAndLogEx(NORMAL, "Key type: 0x%02x ver: 0x%02x " NOLF, fsettings->keyType, fsettings->keyVersion); break; } default: { @@ -2469,8 +2478,8 @@ void DesfirePrintFileSettingsOneLine(FileSettings_t *fsettings) { void DesfirePrintFileSettingsTable(bool printheader, uint8_t id, bool isoidavail, uint16_t isoid, FileSettings_t *fsettings) { if (printheader) { - PrintAndLogEx(SUCCESS, " ID |ISO ID| File type | Mode | Rights: raw, r w rw ch | File settings "); - PrintAndLogEx(SUCCESS, "------------------------------------------------------------------------------------------------------------"); + PrintAndLogEx(SUCCESS, " ID |ISO ID| File type | Mode | Rights: raw, r w rw ch | File settings"); + PrintAndLogEx(SUCCESS, "----------------------------------------------------------------------------------------------------------"); } PrintAndLogEx(SUCCESS, " " _GREEN_("%02x") " |" NOLF, id); if (isoidavail) { @@ -2482,10 +2491,10 @@ void DesfirePrintFileSettingsTable(bool printheader, uint8_t id, bool isoidavail PrintAndLogEx(NORMAL, " |" NOLF); } - PrintAndLogEx(NORMAL, "0x%02x " _CYAN_("%-15s") " |" NOLF, fsettings->fileType, GetDesfireFileType(fsettings->fileType)); + PrintAndLogEx(NORMAL, " 0x%02x " _CYAN_("%-15s") " |" NOLF, fsettings->fileType, GetDesfireFileType(fsettings->fileType)); PrintAndLogEx(NORMAL, " %-5s |" NOLF, GetDesfireCommunicationMode(fsettings->fileCommMode)); - PrintAndLogEx(NORMAL, "%04x, %-4s %-4s %-4s %-4s |" NOLF, + PrintAndLogEx(NORMAL, " %04x, %-4s %-4s %-4s %-4s |" NOLF, fsettings->rawAccessRights, GetDesfireAccessRightShortStr(fsettings->rAccess), GetDesfireAccessRightShortStr(fsettings->wAccess), @@ -2539,15 +2548,12 @@ void DesfirePrintFileSettingsExtended(FileSettings_t *fsettings) { PrintAndLogEx(NORMAL, "change: %s)", GetDesfireAccessRightStr(fsettings->chAccess)); } - static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t datalen, uint8_t *dynlen, bool create) { switch (filetype) { case 0x00: case 0x01: { int filesize = MemLeToUint3byte(&data[0]); - - PrintAndLogEx(INFO, "File size : %d (0x%X) bytes", filesize, filesize); - + PrintAndLogEx(INFO, "File size (bytes)... " _YELLOW_("%d") " / " _YELLOW_("0x%X"), filesize, filesize); *dynlen = 3; break; } @@ -2557,15 +2563,23 @@ static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t int value = MemLeToUint4byte(&data[8]); uint8_t limited_credit_enabled = data[12]; - PrintAndLogEx(INFO, "Lower limit : %d (0x%08X)", lowerlimit, lowerlimit); - PrintAndLogEx(INFO, "Upper limit : %d (0x%08X)", upperlimit, upperlimit); + PrintAndLogEx(INFO, "Lower limit... %d / 0x%08X", lowerlimit, lowerlimit); + PrintAndLogEx(INFO, "Upper limit... %d / 0x%08X", upperlimit, upperlimit); if (create) { - PrintAndLogEx(INFO, "Value : %d (0x%08X)", value, value); - PrintAndLogEx(INFO, "Limited credit : [%d - %s]", limited_credit_enabled, ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled"); + PrintAndLogEx(INFO, "Value............ %d / 0x%08X", value, value); + PrintAndLogEx(INFO, "Limited credit... %d - %s" + , limited_credit_enabled + , ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled" + ); } else { - PrintAndLogEx(INFO, "Limited credit : [%d - %s] %d (0x%08X)", limited_credit_enabled, ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled", value, value); + PrintAndLogEx(INFO, "Limited credit... %d - %s %d (0x%08X)" + , limited_credit_enabled + , ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled" + , value + , value + ); } - PrintAndLogEx(INFO, "GetValue access : %s", ((limited_credit_enabled & 0x02) != 0) ? "Free" : "Not Free"); + PrintAndLogEx(INFO, "GetValue access... %s", ((limited_credit_enabled & 0x02) != 0) ? "Free" : "Not Free"); *dynlen = 13; break; @@ -2575,28 +2589,28 @@ static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t uint32_t recordsize = MemLeToUint3byte(&data[0]); uint32_t maxrecords = MemLeToUint3byte(&data[3]); uint32_t currentrecord = 0; - if (!create) + if (create == false) currentrecord = MemLeToUint3byte(&data[6]); - PrintAndLogEx(INFO, "Record size : %d (0x%X) bytes", recordsize, recordsize); - PrintAndLogEx(INFO, "Max num records : %d (0x%X)", maxrecords, maxrecords); - PrintAndLogEx(INFO, "Total size : %d (0x%X) bytes", recordsize * maxrecords, recordsize * maxrecords); - if (!create) - PrintAndLogEx(INFO, "Curr num records : %d (0x%X)", currentrecord, currentrecord); + PrintAndLogEx(INFO, "Record size....... %d / 0x%X bytes", recordsize, recordsize); + PrintAndLogEx(INFO, "Max num records... %d / 0x%X", maxrecords, maxrecords); + PrintAndLogEx(INFO, "Total size........ %d / 0x%X bytes", recordsize * maxrecords, recordsize * maxrecords); + if (create == false) + PrintAndLogEx(INFO, "Curr num records... %d / 0x%X", currentrecord, currentrecord); *dynlen = (create) ? 6 : 9; break; } case 0x05: { - PrintAndLogEx(INFO, "Key type [0x%02x] : %s", data[0], GetDesfireKeyType(data[0])); + PrintAndLogEx(INFO, "Key type [0x%02x] ... %s", data[0], GetDesfireKeyType(data[0])); *dynlen = 1; if (create) { - PrintAndLogEx(INFO, "Key : %s", sprint_hex(&data[1], 16)); + PrintAndLogEx(INFO, "Key... %s", sprint_hex(&data[1], 16)); *dynlen += 16; } - PrintAndLogEx(INFO, "Key version : %d (0x%X)", data[*dynlen], data[*dynlen]); + PrintAndLogEx(INFO, "Key version... %d / 0x%X", data[*dynlen], data[*dynlen]); (*dynlen)++; break; } @@ -2608,28 +2622,29 @@ static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t void DesfirePrintFileSettings(uint8_t *data, size_t len) { if (len < 6) { - PrintAndLogEx(ERR, "Wrong file settings length: %zu", len); + PrintAndLogEx(ERR, "Wrong file settings length, expected 6> got %zu ", len); return; } uint8_t filetype = data[0]; PrintAndLogEx(INFO, "---- " _CYAN_("File settings") " ----"); - PrintAndLogEx(SUCCESS, "File type [0x%02x] : %s file", filetype, GetDesfireFileType(filetype)); - PrintAndLogEx(SUCCESS, "File comm mode : %s", GetDesfireCommunicationMode(data[1] & 0x03)); + PrintAndLogEx(SUCCESS, "File type " _YELLOW_("0x%02x") " ..... %s file", filetype, GetDesfireFileType(filetype)); + PrintAndLogEx(SUCCESS, "File comm mode...... %s", GetDesfireCommunicationMode(data[1] & 0x03)); bool addaccess = false; if (filetype != 0x05) { addaccess = ((data[1] & 0x80) != 0); - PrintAndLogEx(SUCCESS, "Additional access: %s", (addaccess) ? "Yes" : "No"); + PrintAndLogEx(SUCCESS, "Additional access... %s", (addaccess) ? "Yes" : "No"); } - PrintAndLogEx(SUCCESS, "Access rights : %04x", MemLeToUint2byte(&data[2])); - DesfirePrintAccessRight(&data[2]); //2 bytes + + PrintAndLogEx(SUCCESS, "Access rights....... %04x", MemLeToUint2byte(&data[2])); + DesfirePrintAccessRight(&data[2]); // 2 bytes uint8_t reclen = 0; DesfirePrintFileSettDynPart(filetype, &data[4], len - 4, &reclen, false); reclen += 4; // static part if (addaccess && filetype != 0x05 && reclen > 0 && len > reclen && len == reclen + data[reclen] * 2) { - PrintAndLogEx(SUCCESS, "Add access records: %d", data[reclen]); + PrintAndLogEx(SUCCESS, "Add access records... %d", data[reclen]); for (int i = 0; i < data[reclen] * 2; i += 2) { PrintAndLogEx(SUCCESS, "Add access rights : [%d] %04x", i / 2, MemLeToUint2byte(&data[reclen + 1 + i])); DesfirePrintAccessRight(&data[reclen + 1 + i]); diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index f1d5c0b55..807d0c287 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -125,6 +125,7 @@ static int print_aid_description(json_t *root, uint16_t aid, char *fmt, bool ver PrintAndLogEx(INFO, fmt, " (unknown)"); return PM3_ENODATA; } + const char *vmad = mad_json_get_str(elm, "mad"); const char *application = mad_json_get_str(elm, "application"); const char *company = mad_json_get_str(elm, "company"); @@ -132,7 +133,7 @@ static int print_aid_description(json_t *root, uint16_t aid, char *fmt, bool ver const char *integrator = mad_json_get_str(elm, "system_integrator"); if (application && company) { - size_t result_len = 4 + strlen(application) + strlen(company); + size_t result_len = 6 + strlen(application) + strlen(company); char result[result_len]; snprintf(result, result_len, " %s [%s]", application, company); PrintAndLogEx(INFO, fmt, result); @@ -389,12 +390,12 @@ int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose) { return PM3_SUCCESS; } -int MADDFDecodeAndPrint(uint32_t short_aid) { +int MADDFDecodeAndPrint(uint32_t short_aid, bool verbose) { open_mad_file(&mad_known_aids, false); - char fmt[50]; + char fmt[128]; snprintf(fmt, sizeof(fmt), " MAD AID Function 0x%04X :" _YELLOW_("%s"), short_aid, "%s"); - print_aid_description(mad_known_aids, short_aid, fmt, false); + print_aid_description(mad_known_aids, short_aid, fmt, verbose); close_mad_file(mad_known_aids); return PM3_SUCCESS; } diff --git a/client/src/mifare/mad.h b/client/src/mifare/mad.h index cf951a0b7..14eae9b54 100644 --- a/client/src/mifare/mad.h +++ b/client/src/mifare/mad.h @@ -25,7 +25,7 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2); int MADDecode(uint8_t *sector0, uint8_t *sector10, uint16_t *mad, size_t *madlen, bool swapmad); int MAD1DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose, bool *haveMAD2); int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose); -int MADDFDecodeAndPrint(uint32_t short_aid); +int MADDFDecodeAndPrint(uint32_t short_aid, bool verbose); int MADCardHolderInfoDecode(uint8_t *data, size_t datalen, bool verbose); void MADPrintHeader(void); bool HasMADKey(uint8_t *d); From ec403485b6c1037b3ba5247faaffe7dfaf8dac21 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 20 Aug 2022 13:09:43 +0200 Subject: [PATCH 202/759] init vars --- client/src/cmdhflto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhflto.c b/client/src/cmdhflto.c index 1bdc7ac1a..b5a8d1206 100644 --- a/client/src/cmdhflto.c +++ b/client/src/cmdhflto.c @@ -414,9 +414,9 @@ int reader_lto(bool loop, bool verbose) { int ret = PM3_SUCCESS; do { - uint8_t serial[5]; + uint8_t serial[5] = {0}; uint8_t serial_len = sizeof(serial); - uint8_t type_info[2]; + uint8_t type_info[2] = {0}; lto_switch_off_field(); lto_switch_on_field(); From ab3e98844188383b2ca2104339d872cfd98102b6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 20 Aug 2022 23:20:28 +0200 Subject: [PATCH 203/759] test of PR 1756 --- client/Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/Makefile b/client/Makefile index ba620c84c..6817380bb 100644 --- a/client/Makefile +++ b/client/Makefile @@ -365,6 +365,8 @@ endif ####################################################################################################### CFLAGS ?= $(DEFCFLAGS) +CFLAGS += $(MYDEFS) $(MYCFLAGS) $(MYINCLUDES) + # We cannot just use CFLAGS+=... because it has impact on sub-makes if CFLAGS is defined in env: PM3CFLAGS = $(CFLAGS) PM3CFLAGS += -g -I./src -I./include -I../include -I../common -I../common_fpga $(PM3INCLUDES) $(INCLUDES) @@ -407,6 +409,8 @@ endif PM3CFLAGS += -DHAVE_SNPRINTF CXXFLAGS ?= -Wall -Werror -O3 +CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES) + PM3CXXFLAGS = $(CXXFLAGS) PM3CXXFLAGS += -I../include -I./include @@ -422,6 +426,8 @@ endif PM3CXXFLAGS += -DHAVE_SNPRINTF LDFLAGS ?= $(DEFLDFLAGS) +LDFLAGS += $(MYLDFLAGS) + PM3LDFLAGS = $(LDFLAGS) ifeq ($(platform),Darwin) PM3LDFLAGS += -framework Foundation -framework AppKit @@ -753,7 +759,8 @@ all-static: $(BINS) proxmark3: $(OBJS) $(STATICLIBS) lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua $(info [=] LD $@) - $(Q)$(LD) $(PM3LDFLAGS) $(OBJS) $(STATICLIBS) $(LDLIBS) -o $@ +# $(Q)$(LD) $(PM3LDFLAGS) $(OBJS) $(STATICLIBS) $(LDLIBS) -o $@ + $(Q)$(LD) $(PM3CFLAGS) $(PM3LDFLAGS) $(OBJS) $(STATICLIBS) $(LDLIBS) -o $@ src/proxgui.cpp: src/ui/ui_overlays.h src/ui/ui_image.h From 3be998de713711b3d6b279c472113da0c21feaad Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 20 Aug 2022 23:44:32 +0200 Subject: [PATCH 204/759] test of PR 1757 --- Makefile.defs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 5a131c971..397e25561 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -38,8 +38,8 @@ TAR = tar TARFLAGS ?= -v --ignore-failed-read -r TARFLAGS += -C .. -f CROSS ?= arm-none-eabi- -CC = gcc -CXX = g++ +CC ?= gcc +CXX ?= g++ LD = g++ SH = sh BASH = bash From 2b80262d078b7bf81f721633a24fa8c90daed841 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 20 Aug 2022 23:50:18 +0200 Subject: [PATCH 205/759] textual --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c8294d2d..93c557838 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] + - Change Client Makefile to respect global flags (@blshkv) + - Change Makefile, honors global CC values (@blshkv) - Fixed bad memory handling in MifareSim device side (@iceman1001) - Added json topaz file format (@iceman1001) - Added `hf topaz rdbl, wrbl, view` commands (@iceman1001) From 643f77996a4a8b8d4125088a5bdcefaa32e18fee Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 21 Aug 2022 00:52:53 +0200 Subject: [PATCH 206/759] hf mf mad - should be available offline too. Added some checks to quit if no device present --- client/src/cmdhfmf.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 670be80e9..b79fc3b14 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -172,7 +172,7 @@ static void decode_print_st(uint16_t blockno, uint8_t *data) { PrintAndLogEx(INFO, " # | Access rights"); PrintAndLogEx(INFO, "----+-----------------------------------------------------------------"); - if (! mfValidateAccessConditions(&data[6])) { + if (mfValidateAccessConditions(&data[6]) == false) { PrintAndLogEx(WARNING, _RED_("Invalid Access Conditions")); } @@ -365,7 +365,7 @@ static int CmdHF14AMfAcl(const char *Cmd) { if (memcmp(acl, "\xFF\x07\x80", 3) == 0) { PrintAndLogEx(INFO, "ACL... " _GREEN_("%s") " (transport configuration)", sprint_hex(acl, sizeof(acl))); } - if (! mfValidateAccessConditions(acl)) { + if (mfValidateAccessConditions(acl) == false) { PrintAndLogEx(ERR, _RED_("Invalid Access Conditions, NEVER write these on a card!")); } PrintAndLogEx(NORMAL, ""); @@ -1153,7 +1153,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { } // ensure access right isn't messed up. - if (! mfValidateAccessConditions(&bldata[6])) { + if (mfValidateAccessConditions(&bldata[6]) == false) { PrintAndLogEx(WARNING, "Invalid Access Conditions on sector %i, replacing by default values", s); memcpy(bldata + 6, "\xFF\x07\x80\x69", 4); } @@ -5392,6 +5392,9 @@ static int CmdHF14AMfMAD(const char *Cmd) { return PM3_SUCCESS; } + if (g_session.pm3_present == false) + return PM3_ENOTTY; + uint8_t sector0[16 * 4] = {0}; uint8_t sector10[16 * 4] = {0}; @@ -6422,6 +6425,10 @@ static int CmdHF14AMfValue(const char *Cmd) { } if (action < 3) { + + if (g_session.pm3_present == false) + return PM3_ENOTTY; + if (action <= 1) { // increment/decrement value memcpy(block, (uint8_t *)&value, 4); uint8_t cmddata[26]; @@ -6488,7 +6495,7 @@ static int CmdHF14AMfValue(const char *Cmd) { if (action == 4) { res = PM3_SUCCESS; // alread have data from command line } else { - res = mfReadBlock(blockno, keytype, key, data); + res = mfReadBlock(blockno, keytype, key, data); } if (res == PM3_SUCCESS) { @@ -6525,7 +6532,7 @@ static command_t CommandTable[] = { {"auth4", CmdHF14AMfAuth4, IfPm3Iso14443a, "ISO14443-4 AES authentication"}, {"acl", CmdHF14AMfAcl, AlwaysAvailable, "Decode and print MIFARE Classic access rights bytes"}, {"dump", CmdHF14AMfDump, IfPm3Iso14443a, "Dump MIFARE Classic tag to binary file"}, - {"mad", CmdHF14AMfMAD, IfPm3Iso14443a, "Checks and prints MAD"}, + {"mad", CmdHF14AMfMAD, AlwaysAvailable, "Checks and prints MAD"}, {"ndefread", CmdHFMFNDEFRead, IfPm3Iso14443a, "Prints NDEF records from card"}, {"personalize", CmdHFMFPersonalize, IfPm3Iso14443a, "Personalize UID (MIFARE Classic EV1 only)"}, {"rdbl", CmdHF14AMfRdBl, IfPm3Iso14443a, "Read MIFARE Classic block"}, From 28449aa580eecf4154f5531fd721bb7995804b49 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 21 Aug 2022 09:40:06 +0200 Subject: [PATCH 207/759] hf mf mad - detect and decode of HID PACS --- client/src/cmdhfmf.c | 37 +++++++++++++++++++++++++++++++++++++ client/src/mifare/mad.c | 15 +++++++++++++++ client/src/mifare/mad.h | 1 + 3 files changed, 53 insertions(+) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index b79fc3b14..3cdd94bf2 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -35,6 +35,8 @@ #include "crapto1/crapto1.h" // prng_successor #include "cmdhf14a.h" // exchange APDU #include "crypto/libpcrypto.h" +#include "wiegand_formats.h" +#include "wiegand_formatutils.h" #define MIFARE_4K_MAXBLOCK 256 #define MIFARE_2K_MAXBLOCK 128 @@ -5388,6 +5390,41 @@ static int CmdHF14AMfMAD(const char *Cmd) { MADPrintHeader(); bool haveMAD2 = false; MAD1DecodeAndPrint(dump, swapmad, verbose, &haveMAD2); + + int sector = DetectHID(dump, 0x484d); + if (sector > -1) { + + // decode it + PrintAndLogEx(INFO, ""); + PrintAndLogEx(INFO, _CYAN_("HID PACS detected")); + + uint8_t pacs_sector[MFBLOCK_SIZE * 3] = {0}; + memcpy(pacs_sector, dump + (sector * 4 * 16), sizeof(pacs_sector)); + + if (pacs_sector[16] == 0x02) { + + PrintAndLogEx(SUCCESS, "Raw...... " _GREEN_("%s"), sprint_hex_inrow(pacs_sector + 24, 8)); + + //todo: remove preamble/sentinel + uint32_t top = 0, mid = 0, bot = 0; + char hexstr[16 + 1] = {0}; + hex_to_buffer((uint8_t *)hexstr, pacs_sector + 24, 8, sizeof(hexstr) - 1, 0, 0, true); + hexstring_to_u96(&top, &mid, &bot, hexstr); + + PrintAndLogEx(INFO, "top %x %x %x", top, mid, bot); + + char binstr[64 + 1]; + hextobinstring(binstr, hexstr); + char *pbin = binstr; + while (strlen(pbin) && *(++pbin) == '0'); + + PrintAndLogEx(SUCCESS, "Binary... " _GREEN_("%s"), pbin); + + PrintAndLogEx(INFO, "Wiegand decode"); + wiegand_message_t packed = initialize_message_object(top, mid, bot, 0); + HIDTryUnpack(&packed); + } + } free(dump); return PM3_SUCCESS; } diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index 807d0c287..62a77d988 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -406,3 +406,18 @@ bool HasMADKey(uint8_t *d) { return (memcmp(d + (3 * MFBLOCK_SIZE), g_mifare_mad_key, sizeof(g_mifare_mad_key)) == 0); } + +int DetectHID(uint8_t *d, uint16_t manufacture) { + if (d == NULL) + return -1; + + // find HID + for (int i = 1; i < 16; i++) { + uint16_t aid = madGetAID(d, false, 1, i); + if (aid == manufacture) { + return i; + } + } + + return -1; +} \ No newline at end of file diff --git a/client/src/mifare/mad.h b/client/src/mifare/mad.h index 14eae9b54..e1ebec62c 100644 --- a/client/src/mifare/mad.h +++ b/client/src/mifare/mad.h @@ -29,4 +29,5 @@ int MADDFDecodeAndPrint(uint32_t short_aid, bool verbose); int MADCardHolderInfoDecode(uint8_t *data, size_t datalen, bool verbose); void MADPrintHeader(void); bool HasMADKey(uint8_t *d); +int DetectHID(uint8_t *d, uint16_t manufacture); #endif // _MAD_H_ From 38a664f00cf32b3e8dcc1120884dbe2e13b329a3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 21 Aug 2022 09:40:36 +0200 Subject: [PATCH 208/759] lets see if this still detects sentinels --- client/src/wiegand_formatutils.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/client/src/wiegand_formatutils.c b/client/src/wiegand_formatutils.c index 5f7dae901..15b7130b9 100644 --- a/client/src/wiegand_formatutils.c +++ b/client/src/wiegand_formatutils.c @@ -131,24 +131,17 @@ bool set_nonlinear_field(wiegand_message_t *data, uint64_t value, uint8_t numBit static uint8_t get_length_from_header(wiegand_message_t *data) { /** * detect if message has "preamble" / "sentinel bit" - * + * Right now we just calculate the highest bit set + * 37 bit formats is hard to detect since it doesnt have a sentinel bit */ - - uint8_t len = 0; uint32_t hfmt = 0; // for calculating card length if ((data->Top & 0x000FFFFF) > 0) { // > 64 bits hfmt = data->Top & 0x000FFFFF; len = 64; - } else if ((data->Mid & 0xFFFFFFC0) > 0) { // < 63-38 bits - hfmt = data->Mid & 0xFFFFFFC0; - len = 32; - } else if (data->Mid && (data->Mid & 0x00000020) == 0) { // 37 bits; - hfmt = 0; - len = 37; - } else if ((data->Mid & 0x0000001F) > 0) { // 36-32 bits - hfmt = data->Mid & 0x0000001F; + } else if (data->Mid > 0) { // < 63-32 bits + hfmt = data->Mid; len = 32; } else { hfmt = data->Bot; @@ -159,8 +152,11 @@ static uint8_t get_length_from_header(wiegand_message_t *data) { hfmt >>= 1; len++; } + + // everything less than 26 bits found, assume 26 bits if (len < 26) len = 26; + return len; } From b6908ab9c7ce0fd2c5e639d46169d5deda089e72 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 21 Aug 2022 11:01:30 +0200 Subject: [PATCH 209/759] need an even better check if we got anything --- client/src/cmdlfhitag.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index a728bb6ff..89a030d62 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -850,6 +850,8 @@ static int CmdLFHitag2Dump(const char *Cmd) { //SendCommandNG(CMD_LF_HITAG_DUMP, &htd, sizeof(htd)); PacketResponseNG resp; uint8_t *data = resp.data.asBytes; + if (data == NULL) + return PM3_ESOFT; if (fnlen < 1) { char *fptr = filename; From 6eaff873ba6de362dd433bf1478a843834e784f4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 21 Aug 2022 11:12:11 +0200 Subject: [PATCH 210/759] remove debug statements --- client/src/cmdhfmf.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 3cdd94bf2..dfbfecfe8 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5411,8 +5411,6 @@ static int CmdHF14AMfMAD(const char *Cmd) { hex_to_buffer((uint8_t *)hexstr, pacs_sector + 24, 8, sizeof(hexstr) - 1, 0, 0, true); hexstring_to_u96(&top, &mid, &bot, hexstr); - PrintAndLogEx(INFO, "top %x %x %x", top, mid, bot); - char binstr[64 + 1]; hextobinstring(binstr, hexstr); char *pbin = binstr; From c27264e4c4794b630120a63672dc07be106c366b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 22 Aug 2022 05:49:47 +0200 Subject: [PATCH 211/759] text --- client/src/cmddata.c | 2 +- client/src/cmdhf15.c | 12 +++++------ client/src/cmdhffido.c | 2 +- client/src/cmdhfgallagher.c | 6 +++--- client/src/cmdhfmf.c | 2 +- client/src/cmdhfmfp.c | 36 +++++++++++++++---------------- client/src/cmdhfst25ta.c | 4 ++-- client/src/cmdlfem4x50.c | 2 +- client/src/cmdmain.c | 2 +- client/src/emv/test/crypto_test.c | 2 +- client/src/loclass/cipher.c | 4 ++-- client/src/loclass/cipherutils.c | 8 +++---- client/src/loclass/elite_crack.c | 12 +++++------ client/src/wiegand_formatutils.c | 21 ++++++++++++++++-- tools/pm3_tests.sh | 4 ++-- 15 files changed, 68 insertions(+), 51 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index b633a7916..448ddb4e2 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -894,7 +894,7 @@ static int CmdAutoCorr(const char *Cmd) { } if (window >= g_GraphTraceLen) { - PrintAndLogEx(WARNING, "window must be smaller than trace (" _YELLOW_("%zu") " samples)", g_GraphTraceLen); + PrintAndLogEx(WARNING, "window must be smaller than trace ( " _YELLOW_("%zu") " samples )", g_GraphTraceLen); return PM3_EINVARG; } diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index d780056a6..aeda14380 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1377,7 +1377,7 @@ static int CmdHF15Dump(const char *Cmd) { if (CheckCrc15(recv, resp.length) == false) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(FAILED, "crc (" _RED_("fail") ")"); + PrintAndLogEx(FAILED, "crc ( " _RED_("fail") " )"); continue; } @@ -1603,7 +1603,7 @@ static int CmdHF15Readmulti(const char *Cmd) { uint8_t *data = resp.data.asBytes; if (CheckCrc15(data, resp.length) == false) { - PrintAndLogEx(FAILED, "crc (" _RED_("fail") ")"); + PrintAndLogEx(FAILED, "crc ( " _RED_("fail") " )"); return PM3_ESOFT; } @@ -1734,7 +1734,7 @@ static int CmdHF15Readblock(const char *Cmd) { uint8_t *data = resp.data.asBytes; if (CheckCrc15(data, resp.length) == false) { - PrintAndLogEx(FAILED, "crc (" _RED_("fail") ")"); + PrintAndLogEx(FAILED, "crc ( " _RED_("fail") " )"); return PM3_ESOFT; } @@ -1785,7 +1785,7 @@ static int hf_15_write_blk(bool verbose, bool fast, uint8_t *req, uint8_t reqlen uint8_t *recv = resp.data.asBytes; if (CheckCrc15(recv, resp.length) == false) { if (verbose) { - PrintAndLogEx(FAILED, "crc (" _RED_("fail") ")"); + PrintAndLogEx(FAILED, "crc ( " _RED_("fail") " )"); } return PM3_ESOFT; } @@ -2103,10 +2103,10 @@ static int CmdHF15CSetUID(const char *Cmd) { } if (memcmp(revuid, payload.uid, 8) != 0) { - PrintAndLogEx(FAILED, "setting new UID (" _RED_("failed") ")"); + PrintAndLogEx(FAILED, "setting new UID ( " _RED_("fail") " )"); return PM3_ESOFT; } else { - PrintAndLogEx(SUCCESS, "setting new UID (" _GREEN_("ok") ")"); + PrintAndLogEx(SUCCESS, "setting new UID ( " _GREEN_("ok") " )"); return PM3_SUCCESS; } } diff --git a/client/src/cmdhffido.c b/client/src/cmdhffido.c index 4609b93cb..d95923159 100644 --- a/client/src/cmdhffido.c +++ b/client/src/cmdhffido.c @@ -639,7 +639,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { PrintAndLogEx(WARNING, "Other signature check error: %x %s", (res < 0) ? -res : res, ecdsa_get_error(res)); } } else { - PrintAndLogEx(SUCCESS, "Signature is (" _GREEN_("ok") " )"); + PrintAndLogEx(SUCCESS, "Signature is ( " _GREEN_("ok") " )"); } } else { PrintAndLogEx(WARNING, "No public key provided. can't check signature."); diff --git a/client/src/cmdhfgallagher.c b/client/src/cmdhfgallagher.c index ee51464a8..ff527a524 100644 --- a/client/src/cmdhfgallagher.c +++ b/client/src/cmdhfgallagher.c @@ -841,7 +841,7 @@ static int hfgal_read_card(uint32_t aid, uint8_t *site_key, bool verbose, bool q if (verbose) { if (region_code > 0 || facility_code > 0 || current_aid > 0) { - PrintAndLogEx(INFO, "Reading AID: " _YELLOW_("%06X") ", region: " _YELLOW_("%c") " (" _YELLOW_("%u") "), facility: " _YELLOW_("%u"), + PrintAndLogEx(INFO, "Reading AID: " _YELLOW_("%06X") ", region: " _YELLOW_("%c") " ( " _YELLOW_("%u") " ), facility: " _YELLOW_("%u"), current_aid, 'A' + region_code, region_code, @@ -861,7 +861,7 @@ static int hfgal_read_card(uint32_t aid, uint8_t *site_key, bool verbose, bool q } PM3_RET_IF_ERR_MAYBE_MSG(res, !quiet, "Failed reading card application credentials"); - PrintAndLogEx(SUCCESS, "Gallagher (AID %06X) - region: " _GREEN_("%c") " (" _GREEN_("%u") ")" + PrintAndLogEx(SUCCESS, "Gallagher (AID %06X) - region: " _GREEN_("%c") " ( " _GREEN_("%u") " )" ", facility: " _GREEN_("%u") ", card number: " _GREEN_("%u") ", issue level: " _GREEN_("%u"), @@ -1298,7 +1298,7 @@ static int CmdGallagherDecode(const char *cmd) { GallagherCredentials_t creds = {0}; gallagher_decode_creds(data_buf, &creds); - PrintAndLogEx(SUCCESS, "Gallagher - region: " _GREEN_("%c") " (" _GREEN_("%u") ")" + PrintAndLogEx(SUCCESS, "Gallagher - region: " _GREEN_("%c") " ( " _GREEN_("%u") " )" ", facility: " _GREEN_("%u") ", card number: " _GREEN_("%u") ", issue level: " _GREEN_("%u"), diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index dfbfecfe8..173cfa7a7 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5150,7 +5150,7 @@ static int CmdHf14AMfSetMod(const char *Cmd) { if (resp.status == PM3_SUCCESS) PrintAndLogEx(SUCCESS, "Change ( " _GREEN_("ok") " )"); else - PrintAndLogEx(FAILED, "Change (" _GREEN_("fail") " )"); + PrintAndLogEx(FAILED, "Change ( " _RED_("fail") " )"); return resp.status; } diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index c05adfe40..fac52f531 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -65,9 +65,9 @@ static char *getCardSizeStr(uint8_t fsize) { // is LSB set? if (fsize & 1) - snprintf(retStr, sizeof(buf), "0x%02X (" _GREEN_("%d - %d bytes") ")", fsize, usize, lsize); + snprintf(retStr, sizeof(buf), "0x%02X ( " _GREEN_("%d - %d bytes") " )", fsize, usize, lsize); else - snprintf(retStr, sizeof(buf), "0x%02X (" _GREEN_("%d bytes") ")", fsize, lsize); + snprintf(retStr, sizeof(buf), "0x%02X ( " _GREEN_("%d bytes") " )", fsize, lsize); return buf; } @@ -77,14 +77,14 @@ static char *getProtocolStr(uint8_t id, bool hw) { char *retStr = buf; if (id == 0x04) { - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("ISO 14443-3 MIFARE, 14443-4") ")", id); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("ISO 14443-3 MIFARE, 14443-4") " )", id); } else if (id == 0x05) { if (hw) - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("ISO 14443-2, 14443-3") ")", id); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("ISO 14443-2, 14443-3") " )", id); else - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("ISO 14443-3, 14443-4") ")", id); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("ISO 14443-3, 14443-4") " )", id); } else { - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("Unknown") ")", id); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Unknown") " )", id); } return buf; } @@ -95,19 +95,19 @@ static char *getVersionStr(uint8_t major, uint8_t minor) { char *retStr = buf; if (major == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire MF3ICD40") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire MF3ICD40") " )", major, minor); else if (major == 0x01 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV1") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV1") " )", major, minor); else if (major == 0x12 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV2") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV2") " )", major, minor); else if (major == 0x33 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire EV3") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire EV3") " )", major, minor); else if (major == 0x30 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("DESFire Light") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("DESFire Light") " )", major, minor); else if (major == 0x11 && minor == 0x00) - snprintf(retStr, sizeof(buf), "%x.%x (" _GREEN_("Plus EV1") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _GREEN_("Plus EV1") " )", major, minor); else - snprintf(retStr, sizeof(buf), "%x.%x (" _YELLOW_("Unknown") ")", major, minor); + snprintf(retStr, sizeof(buf), "%x.%x ( " _YELLOW_("Unknown") " )", major, minor); return buf; } @@ -118,16 +118,16 @@ static char *getTypeStr(uint8_t type) { switch (type) { case 1: - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("DESFire") ")", type); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("DESFire") " )", type); break; case 2: - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("Plus") ")", type); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Plus") " )", type); break; case 3: - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("Ultralight") ")", type); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("Ultralight") " )", type); break; case 4: - snprintf(retStr, sizeof(buf), "0x%02X (" _YELLOW_("NTAG") ")", type); + snprintf(retStr, sizeof(buf), "0x%02X ( " _YELLOW_("NTAG") " )", type); break; default: break; @@ -513,8 +513,8 @@ static int CmdHFMFPWritePerso(const char *Cmd) { PrintAndLogEx(ERR, "Command error: %02x %s", data[0], mfpGetErrorDescription(data[0])); return PM3_ESOFT; } - PrintAndLogEx(INFO, "Write (" _GREEN_("ok") " )"); + PrintAndLogEx(INFO, "Write ( " _GREEN_("ok") " )"); return PM3_SUCCESS; } diff --git a/client/src/cmdhfst25ta.c b/client/src/cmdhfst25ta.c index 54c432ab9..d60a98f32 100644 --- a/client/src/cmdhfst25ta.c +++ b/client/src/cmdhfst25ta.c @@ -46,7 +46,7 @@ static void print_st25ta_system_info(uint8_t *d, uint8_t n) { PrintAndLogEx(SUCCESS, "------------ " _CYAN_("ST System file") " ------------"); uint16_t len = (d[0] << 8 | d[1]); - PrintAndLogEx(SUCCESS, " len %u bytes (" _GREEN_("0x%04X") ")", len, len); + PrintAndLogEx(SUCCESS, " len %u bytes ( " _GREEN_("0x%04X") " )", len, len); if (d[2] == 0x80) { PrintAndLogEx(SUCCESS, " ST reserved ( 0x%02X )", d[2]); @@ -98,7 +98,7 @@ static void print_st25ta_system_info(uint8_t *d, uint8_t n) { PrintAndLogEx(SUCCESS, " Device# " _YELLOW_("%s"), sprint_hex_inrow(d + 10, 5)); uint16_t mem = (d[0xF] << 8 | d[0x10]); - PrintAndLogEx(SUCCESS, " Memory Size - 1 %u bytes (" _GREEN_("0x%04X") ")", mem, mem); + PrintAndLogEx(SUCCESS, " Memory Size - 1 %u bytes ( " _GREEN_("0x%04X") " )", mem, mem); PrintAndLogEx(SUCCESS, " IC Reference code %u ( 0x%02X )", d[0x12], d[0x12]); diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index 8f6db24a3..abc8810fd 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -939,7 +939,7 @@ int CmdEM4x50WritePwd(const char *Cmd) { return PM3_SUCCESS; if (resp.status != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Writing password (" _RED_("failed") ")"); + PrintAndLogEx(FAILED, "Writing password ( " _RED_("fail") " )"); return PM3_EFAILED; } diff --git a/client/src/cmdmain.c b/client/src/cmdmain.c index 8c11f7bc5..99fef33d4 100644 --- a/client/src/cmdmain.c +++ b/client/src/cmdmain.c @@ -111,7 +111,7 @@ static int lf_search_plus(const char *Cmd) { // Try to change config! uint32_t d; d = config.divisor = default_divisor[i]; - PrintAndLogEx(INFO, "--> trying (" _GREEN_("%d.%02d kHz")")", 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100)); + PrintAndLogEx(INFO, "--> trying ( " _GREEN_("%d.%02d kHz")" )", 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100)); retval = lf_config(&config); if (retval != PM3_SUCCESS) diff --git a/client/src/emv/test/crypto_test.c b/client/src/emv/test/crypto_test.c index 332203ad1..ab67a2081 100644 --- a/client/src/emv/test/crypto_test.c +++ b/client/src/emv/test/crypto_test.c @@ -72,7 +72,7 @@ static int test_genkey(unsigned int keylength, unsigned char *msg, size_t msg_le } free(tmp2); - PrintAndLogEx(SUCCESS, "passed (" _GREEN_("%" PRIu64) " ms)", msclock() - ms); + PrintAndLogEx(SUCCESS, "passed ( " _GREEN_("%" PRIu64) " ms )", msclock() - ms); free_tmp: free(tmp); diff --git a/client/src/loclass/cipher.c b/client/src/loclass/cipher.c index b69230667..974eb5060 100644 --- a/client/src/loclass/cipher.c +++ b/client/src/loclass/cipher.c @@ -290,9 +290,9 @@ int testMAC(void) { doMAC(cc_nr, div_key, calculated_mac); if (memcmp(calculated_mac, correct_MAC, 4) == 0) { - PrintAndLogEx(SUCCESS, " MAC calculation (%s)", _GREEN_("ok")); + PrintAndLogEx(SUCCESS, " MAC calculation ( %s )", _GREEN_("ok")); } else { - PrintAndLogEx(FAILED, " MAC calculation (%s)", _RED_("failed")); + PrintAndLogEx(FAILED, " MAC calculation ( %s )", _RED_("fail")); printarr(" Calculated_MAC", calculated_mac, 4); printarr(" Correct_MAC ", correct_MAC, 4); return PM3_ESOFT; diff --git a/client/src/loclass/cipherutils.c b/client/src/loclass/cipherutils.c index eaeee3019..f3572b823 100644 --- a/client/src/loclass/cipherutils.c +++ b/client/src/loclass/cipherutils.c @@ -198,9 +198,9 @@ static int testBitStream(void) { } if (memcmp(input, output, sizeof(input)) == 0) { - PrintAndLogEx(SUCCESS, " Bitstream test 1 (%s)", _GREEN_("ok")); + PrintAndLogEx(SUCCESS, " Bitstream test 1 ( %s )", _GREEN_("ok")); } else { - PrintAndLogEx(FAILED, " Bitstream test 1 (%s)", _RED_("failed")); + PrintAndLogEx(FAILED, " Bitstream test 1 ( %s )", _RED_("fail")); uint8_t i; for (i = 0 ; i < ARRAYLEN(input) ; i++) { PrintAndLogEx(NORMAL, " IN %02x, OUT %02x", input[i], output[i]); @@ -228,9 +228,9 @@ static int testReversedBitstream(void) { } if (memcmp(input, output, sizeof(input)) == 0) { - PrintAndLogEx(SUCCESS, " Bitstream test 2 (%s)", _GREEN_("ok")); + PrintAndLogEx(SUCCESS, " Bitstream test 2 ( %s )", _GREEN_("ok")); } else { - PrintAndLogEx(FAILED, " Bitstream test 2 (%s)", _RED_("failed")); + PrintAndLogEx(FAILED, " Bitstream test 2 ( %s )", _RED_("fail")); uint8_t i; for (i = 0 ; i < ARRAYLEN(input) ; i++) { PrintAndLogEx(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]); diff --git a/client/src/loclass/elite_crack.c b/client/src/loclass/elite_crack.c index ec13ca76e..5d2be50e6 100644 --- a/client/src/loclass/elite_crack.c +++ b/client/src/loclass/elite_crack.c @@ -707,7 +707,7 @@ int calculateMasterKey(uint8_t first16bytes[], uint8_t kcus[]) { PrintAndLogEx(SUCCESS, "----- " _CYAN_("High security custom key (Kcus)") " -----"); PrintAndLogEx(SUCCESS, "Standard format %s", sprint_hex(key64_stdformat, 8)); PrintAndLogEx(SUCCESS, "iCLASS format " _GREEN_("%s"), sprint_hex(key64, 8)); - PrintAndLogEx(SUCCESS, "Key verified (" _GREEN_("ok") ")"); + PrintAndLogEx(SUCCESS, "Key verified ( " _GREEN_("ok") " )"); PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } @@ -758,7 +758,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) { first16bytes[i] = keytable[i] & 0xFF; if ((keytable[i] & LOCLASS_CRACKED) != LOCLASS_CRACKED) { - PrintAndLogEx(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i); + PrintAndLogEx(WARNING, "Warning: we are missing byte " _RED_("%d") " , custom key calculation will fail...", i); return PM3_ESOFT; } } @@ -849,7 +849,7 @@ static int _test_iclass_key_permutation(void) { return PM3_ESOFT; } - PrintAndLogEx(SUCCESS, " Iclass key permutation (%s)", _GREEN_("ok")); + PrintAndLogEx(SUCCESS, " Iclass key permutation ( %s )", _GREEN_("ok")); return PM3_SUCCESS; } @@ -892,17 +892,17 @@ int testElite(bool slowtests) { hash2(k_cus, keytable); printarr_human_readable("---------------------- Hash2 ----------------------", keytable, sizeof(keytable)); if (keytable[3] == 0xA1 && keytable[0x30] == 0xA3 && keytable[0x6F] == 0x95) { - PrintAndLogEx(SUCCESS, " hash2 (%s)", _GREEN_("ok")); + PrintAndLogEx(SUCCESS, " hash2 ( %s )", _GREEN_("ok")); } int res = PM3_SUCCESS; PrintAndLogEx(INFO, "Testing hash1..."); res += _testHash1(); - PrintAndLogEx((res == PM3_SUCCESS) ? SUCCESS : WARNING, " hash1 (%s)", (res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail")); + PrintAndLogEx((res == PM3_SUCCESS) ? SUCCESS : WARNING, " hash1 ( %s )", (res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail")); PrintAndLogEx(INFO, "Testing key diversification..."); res += _test_iclass_key_permutation(); - PrintAndLogEx((res == PM3_SUCCESS) ? SUCCESS : WARNING, " key diversification (%s)", (res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail")); + PrintAndLogEx((res == PM3_SUCCESS) ? SUCCESS : WARNING, " key diversification ( %s )", (res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail")); if (slowtests) res += _testBruteforce(); diff --git a/client/src/wiegand_formatutils.c b/client/src/wiegand_formatutils.c index 15b7130b9..adc628c03 100644 --- a/client/src/wiegand_formatutils.c +++ b/client/src/wiegand_formatutils.c @@ -141,8 +141,25 @@ static uint8_t get_length_from_header(wiegand_message_t *data) { hfmt = data->Top & 0x000FFFFF; len = 64; } else if (data->Mid > 0) { // < 63-32 bits - hfmt = data->Mid; - len = 32; + + // detect HID format b38 set + if (data->Mid & 0xFFFFFFC0) { + hfmt = data->Mid; + len = 32; + } else { + + printf("hid preamble detected\n"); + len = 32; + + if ((data->Mid ^ 0x20) == 0) { hfmt = data->Bot; len = 0; } + else if ((data->Mid & 0x10) == 0) { hfmt = data->Mid & 0x1F; } + else if ((data->Mid & 0x08) == 0) { hfmt = data->Mid & 0x0F; } + else if ((data->Mid & 0x04) == 0) { hfmt = data->Mid & 0x07; } + else if ((data->Mid & 0x02) == 0) { hfmt = data->Mid & 0x03; } + else if ((data->Mid & 0x01) == 0) { hfmt = data->Mid & 0x01; } + else { hfmt = data->Mid & 0x3F;} + } + } else { hfmt = data->Bot; len = 0; diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index df0d4aa5d..42ecb5eb3 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -502,11 +502,11 @@ while true; do echo -e "\n${C_BLUE}Testing HF:${C_NC}" if ! CheckExecute "hf mf offline text" "$CLIENTBIN -c 'hf mf'" "at_enc"; then break; fi if ! CheckExecute slow retry ignore "hf mf hardnested long test" "$CLIENTBIN -c 'hf mf hardnested -t --tk 000000000000'" "found:"; then break; fi - if ! CheckExecute slow "hf iclass loclass long test" "$CLIENTBIN -c 'hf iclass loclass --long'" "verified \(ok\)"; then break; fi + if ! CheckExecute slow "hf iclass loclass long test" "$CLIENTBIN -c 'hf iclass loclass --long'" "verified \( ok \)"; then break; fi if ! CheckExecute slow "emv long test" "$CLIENTBIN -c 'emv test -l'" "Test\(s\) \[ ok"; then break; fi if ! CheckExecute "hf iclass lookup test" "$CLIENTBIN -c 'hf iclass lookup --csn 9655a400f8ff12e0 --epurse f0ffffffffffffff --macs 0000000089cb984b -f $DICPATH/iclass_default_keys.dic'" \ "valid key AE A6 84 A6 DA B2 32 78"; then break; fi - if ! CheckExecute "hf iclass loclass test" "$CLIENTBIN -c 'hf iclass loclass --test'" "key diversification \(ok\)"; then break; fi + if ! CheckExecute "hf iclass loclass test" "$CLIENTBIN -c 'hf iclass loclass --test'" "key diversification \( ok \)"; then break; fi if ! CheckExecute "emv test" "$CLIENTBIN -c 'emv test'" "Test\(s\) \[ ok"; then break; fi if ! CheckExecute "hf cipurse test" "$CLIENTBIN -c 'hf cipurse test'" "Tests \[ ok"; then break; fi if ! CheckExecute "hf mfdes test" "$CLIENTBIN -c 'hf mfdes test'" "Tests \[ ok"; then break; fi From 811f76785d2ce8aa83b7377ccb782175aca88580 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 22 Aug 2022 12:25:25 +0200 Subject: [PATCH 212/759] textual --- client/src/cmddata.c | 2 +- client/src/cmdhf14b.c | 21 +++++++++++++-------- client/src/cmdhffelica.c | 12 ++++++------ client/src/cmdhfmfp.c | 2 +- client/src/cmdlfawid.c | 2 +- client/src/cmdlfem4x50.c | 2 +- client/src/cmdsmartcard.c | 4 ++-- 7 files changed, 25 insertions(+), 20 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 448ddb4e2..5b5055dd9 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -1817,7 +1817,7 @@ static int CmdSamples(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_int0("n", NULL, "", "num of samples (512 - 40000)"), - arg_lit0("v", "verbose", "verbose"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 14237c0fe..3150da049 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -290,7 +290,7 @@ static int CmdHF14BCmdRaw(const char *Cmd) { arg_lit0("c", "crc", "calculate and append CRC"), arg_lit0("r", NULL, "do not read response from card"), arg_int0("t", "timeout", "", "timeout in ms"), - arg_lit0("v", "verbose", "verbose"), + arg_lit0("v", "verbose", "verbose output"), arg_str0("d", "data", "", "data, bytes to send"), arg_param_end }; @@ -931,7 +931,7 @@ static int CmdHF14Binfo(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("s", "aidsearch", "checks if AIDs from aidlist.json is present on the card and prints information about found AIDs"), - arg_lit0("v", "verbose", "verbose"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1186,12 +1186,12 @@ static int CmdHF14BReader(const char *Cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("s", "silent", "silent (no messages)"), + arg_lit0("v", "verbose", "verbose output"), arg_lit0("@", NULL, "optional - continuous reader mode"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - bool verbose = (arg_get_lit(ctx, 1) == false); + bool verbose = arg_get_lit(ctx, 1); bool cm = arg_get_lit(ctx, 2); CLIParserFree(ctx); @@ -2203,20 +2203,25 @@ int readHF14B(bool loop, bool verbose) { do { // try std 14b (atqb) if (HF14B_std_reader(verbose)) - return PM3_SUCCESS; + if (loop) + continue; // try ST Microelectronics 14b if (HF14B_st_reader(verbose)) - return PM3_SUCCESS; + if (loop) + continue; // try ASK CT 14b if (HF14B_ask_ct_reader(verbose)) - return PM3_SUCCESS; + if (loop) + continue; // try unknown 14b read commands (to be identified later) // could be read of calypso, CEPAS, moneo, or pico pass. if (HF14B_other_reader(verbose)) - return PM3_SUCCESS; + if (loop) + continue; + } while (loop && kbd_enter_pressed() == false); diff --git a/client/src/cmdhffelica.c b/client/src/cmdhffelica.c index c809633e1..773556543 100644 --- a/client/src/cmdhffelica.c +++ b/client/src/cmdhffelica.c @@ -591,7 +591,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { arg_str0(NULL, "sn", "", "number of service, 1 byte"), arg_str0(NULL, "scl", "", "service code list, 2 bytes"), arg_str0("k", "key", "", "3des key, 16 bytes"), - arg_lit0("v", "verbose", "verbose helptext"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -804,7 +804,7 @@ static int CmdHFFelicaAuthentication2(const char *Cmd) { arg_str0("i", NULL, "", "set custom IDm"), arg_str0("c", "cc", "", "M3c card challenge, 8 bytes"), arg_str0("k", "key", "", "3des M3c decryption key, 16 bytes"), - arg_lit0("v", "verbose", "verbose helptext"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -970,7 +970,7 @@ static int CmdHFFelicaWritePlain(const char *Cmd) { arg_str0(NULL, "scl", "", "service code list"), arg_str0(NULL, "bn", "", "number of block"), arg_str0(NULL, "ble", "", "block list element (def 2|3 bytes)"), - arg_lit0("v", "verbose", "verbose helptext"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1136,7 +1136,7 @@ static int CmdHFFelicaReadPlain(const char *Cmd) { arg_str0(NULL, "scl", "", "service code list"), arg_str0(NULL, "bn", "", "number of block"), arg_str0(NULL, "ble", "", "block list element (def 2|3 bytes)"), - arg_lit0("v", "verbose", "verbose helptext"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1364,7 +1364,7 @@ static int CmdHFFelicaRequestSpecificationVersion(const char *Cmd) { arg_param_begin, arg_str0("i", NULL, "", "set custom IDm"), arg_str0("r", NULL, "", "set custom reserve"), - arg_lit0("v", "verbose", "verbose helptext"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1471,7 +1471,7 @@ static int CmdHFFelicaResetMode(const char *Cmd) { arg_param_begin, arg_str0("i", NULL, "", "set custom IDm"), arg_str0("r", NULL, "", "set custom reserve"), - arg_lit0("v", "verbose", "verbose helptext"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index fac52f531..9de9d40c1 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -461,7 +461,7 @@ static int CmdHFMFPWritePerso(const char *Cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("v", "verbose", "Verbose mode"), + arg_lit0("v", "verbose", "Verbose output"), arg_str1(NULL, "ki", "", " Key number, 2 hex bytes"), arg_str0(NULL, "key", "", " Key, 16 hex bytes"), arg_param_end diff --git a/client/src/cmdlfawid.c b/client/src/cmdlfawid.c index 06b9c520c..11db5fc83 100644 --- a/client/src/cmdlfawid.c +++ b/client/src/cmdlfawid.c @@ -487,7 +487,7 @@ static int CmdAWIDBrute(const char *Cmd) { arg_u64_1(NULL, "fc", "", "8|16bit value facility code"), arg_u64_0(NULL, "cn", "", "optional - card number to start with, max 65535"), arg_u64_0(NULL, "delay", "", "optional - delay betweens attempts in ms. Default 1000ms"), - arg_lit0("v", "verbose", "verbose logging, show all tries"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index abc8810fd..3bed45d1d 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -628,7 +628,7 @@ int CmdEM4x50Info(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_str0("p", "pwd", "", "password, 4 hex bytes, lsb"), - arg_lit0("v", "verbose", "additional output of data section"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index c6bfe648d..495b20015 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -670,7 +670,7 @@ static int CmdSmartInfo(const char *Cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("v", "verbose", "verbose"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -748,7 +748,7 @@ static int CmdSmartReader(const char *Cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("v", "verbose", "verbose"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); From 2887e8b0fd363dd7ae865486b5ca0b4b391e358d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 23 Aug 2022 14:35:13 +0200 Subject: [PATCH 213/759] need to skip a lot of mode to fit 256kb versions --- tools/build_all_firmwares.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/build_all_firmwares.sh b/tools/build_all_firmwares.sh index 482033189..5e1076684 100755 --- a/tools/build_all_firmwares.sh +++ b/tools/build_all_firmwares.sh @@ -22,7 +22,7 @@ echo "Destination: ${DEST:=firmware}" echo "Produce stats?: ${STATS:=false}" # Which parts to skip for the 256kb version? -SKIPS256="SKIP_HITAG=1" +SKIPS256="SKIP_HITAG=1 SKIP_LEGICRF=1 SKIP_FELICA=1 SKIP_EM4x50=1 SKIP_ISO14443b=1" make $MKFLAGS bootrom || exit 1 chmod 644 bootrom/obj/bootrom.elf @@ -34,7 +34,7 @@ STANDALONE_MODES=(LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM410 STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI) STANDALONE_MODES_REQ_BT=(HF_REBLAY) STANDALONE_MODES_REQ_SMARTCARD=() -STANDALONE_MODES_REQ_FLASH=(LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_14ASNIFF HF_15SNIFF HF_BOG HF_COLIN HF_ICECLASS HF_MFCSIM) +STANDALONE_MODES_REQ_FLASH=(LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_14ASNIFF HF_15SNIFF HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM) # PM3GENERIC 256kb, no flash, need to skip some parts to reduce size From e18194028b7e32ccbf1d2b0c6fb75f767f21f18b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 24 Aug 2022 07:25:10 +0200 Subject: [PATCH 214/759] style --- armsrc/Standalone/hf_mfcsim.c | 4 +- armsrc/iso14443a.c | 2 +- client/luascripts/hf_mf_sim_hid.lua | 4 +- client/luascripts/hf_mfu_amiibo_sim.lua | 2 +- client/src/cmdhffudan.c | 2 +- client/src/cmdhflist.c | 2 +- client/src/cmdhfmf.c | 4 +- client/src/cmdhfmfu.c | 4 +- client/src/cmdhftopaz.c | 96 +- client/src/fileutils.c | 12 +- client/src/mifare/desfirecore.c | 20 +- client/src/mifare/mad.c | 2 +- client/src/nfc/ndef.c | 2 +- client/src/pm3line_vocabulory.h | 1412 +++++++++++------------ client/src/wiegand_formatutils.c | 16 +- 15 files changed, 792 insertions(+), 792 deletions(-) diff --git a/armsrc/Standalone/hf_mfcsim.c b/armsrc/Standalone/hf_mfcsim.c index f4a8e73b5..86ff62f6c 100644 --- a/armsrc/Standalone/hf_mfcsim.c +++ b/armsrc/Standalone/hf_mfcsim.c @@ -110,8 +110,8 @@ void RunMod(void) { // infinite loop if (i > 15) { // still no dump file found - if (flag_has_dumpfile == false) { - break; + if (flag_has_dumpfile == false) { + break; } // next loop i = 1; diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index bcf206cc8..5f60942e4 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1646,7 +1646,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_ emlGetMemBt(pwd, (pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH, sizeof(pwd)); if (memcmp(pwd, "\x00\x00\x00\x00", 4) == 0) { Uint4byteToMemLe(pwd, ul_ev1_pwdgenB(data)); - Dbprintf("Calc pwd... %02X %02X %02X %02X", pwd[0], pwd[1], pwd[2] ,pwd[3]); + Dbprintf("Calc pwd... %02X %02X %02X %02X", pwd[0], pwd[1], pwd[2], pwd[3]); } if (memcmp(receivedCmd + 1, pwd, 4) == 0) { diff --git a/client/luascripts/hf_mf_sim_hid.lua b/client/luascripts/hf_mf_sim_hid.lua index 90b597149..4091a10b5 100644 --- a/client/luascripts/hf_mf_sim_hid.lua +++ b/client/luascripts/hf_mf_sim_hid.lua @@ -1,4 +1,4 @@ --- +-- -- hf_mf_sim_hid.lua - A tool to clone a large number of tags at once. -- Adapted from lf_hid_bulkclone.lua -- Created 16.08.2022 @@ -110,7 +110,7 @@ end hex. This should be easy enough to extend to non 26bit formats ]]-- local function cardHex(i, f) - + fac = lshift(f, 16) id = bor(i, fac) stream = toBits(id, 24) diff --git a/client/luascripts/hf_mfu_amiibo_sim.lua b/client/luascripts/hf_mfu_amiibo_sim.lua index 058440097..289e0b465 100644 --- a/client/luascripts/hf_mfu_amiibo_sim.lua +++ b/client/luascripts/hf_mfu_amiibo_sim.lua @@ -108,7 +108,7 @@ local function main(args) -- only deal with missing PWD and PACK, or with 56 emu hdr if #hex ~= 1064 and #hex ~= 1080 and #hex ~= 1192 then return oops('Expecting either a plain binary or emulator dump') end - local amiibo_offset = (#hex == 1064 or #hex == 1080) and 0 or 112 + local amiibo_offset = (#hex == 1064 or #hex == 1080) and 0 or 112 local amiibo_info = hex:sub(amiibo_offset + 169, amiibo_offset + 169 + 15):lower() local amiibo_game = amiibo_info:sub(1, 3) local amiibo_type = amiibo_info:sub(7, 8) diff --git a/client/src/cmdhffudan.c b/client/src/cmdhffudan.c index 8c588a01c..502425f83 100644 --- a/client/src/cmdhffudan.c +++ b/client/src/cmdhffudan.c @@ -223,7 +223,7 @@ static int CmdHFFudanReader(const char *Cmd) { CLIParserFree(ctx); if (cm) { - PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); } read_fudan_uid(cm, verbose); diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index d667b981f..80a7e5730 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -191,7 +191,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i return PM3_SUCCESS; } else if (cmd[1] == 0x02 && cmdsize == (cmd[2] & 0x0f) + 7) { // Byte 3 is the reader type - switch(cmd[3]) { + switch (cmd[3]) { case 0x01: snprintf(exp, size, "ECP2 (Transit)"); break; diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 173cfa7a7..1ea9a3055 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5427,7 +5427,7 @@ static int CmdHF14AMfMAD(const char *Cmd) { return PM3_SUCCESS; } - if (g_session.pm3_present == false) + if (g_session.pm3_present == false) return PM3_ENOTTY; @@ -6461,7 +6461,7 @@ static int CmdHF14AMfValue(const char *Cmd) { if (action < 3) { - if (g_session.pm3_present == false) + if (g_session.pm3_present == false) return PM3_ENOTTY; if (action <= 1) { // increment/decrement value diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 47ab3a997..2f6e18a53 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -606,7 +606,7 @@ static int ndef_print_CC(uint8_t *data) { uint8_t mlrule = (data[3] & 0x06) >> 1; uint8_t mbread = (data[3] & 0x01); - PrintAndLogEx(SUCCESS, " %02X: Additional feature information", data[3]); + PrintAndLogEx(SUCCESS, " %02X: Additional feature information", data[3]); PrintAndLogEx(SUCCESS, " %s", sprint_bin(&data[3], 1)); PrintAndLogEx(SUCCESS, " xxx..... - %02X: RFU ( %s )", msb3, (msb3 == 0) ? _GREEN_("ok") : _RED_("fail")); PrintAndLogEx(SUCCESS, " ...x.... - %02X: %s special frame", sf, (sf) ? "support" : "don\'t support"); @@ -3243,7 +3243,7 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { PrintAndLogEx(INFO, "------------------.---------------"); PrintAndLogEx(INFO, " Using UID 4b: " _YELLOW_("%s"), sprint_hex(uid, 4)); - PrintAndLogEx(INFO, " Using UID 7b: " _YELLOW_("%s"), sprint_hex(uid, 7)); + PrintAndLogEx(INFO, " Using UID 7b: " _YELLOW_("%s"), sprint_hex(uid, 7)); PrintAndLogEx(INFO, "----------------------------------"); PrintAndLogEx(INFO, " algo | pwd | pack"); PrintAndLogEx(INFO, "-----------------+----------+-----"); diff --git a/client/src/cmdhftopaz.c b/client/src/cmdhftopaz.c index 805d891d8..8ad9c23ee 100644 --- a/client/src/cmdhftopaz.c +++ b/client/src/cmdhftopaz.c @@ -238,7 +238,7 @@ static int topaz_write_erase8_block(uint8_t blockno, uint8_t *block_data) { } if (memcmp(block_data, response + 1, 8) == 0) { - return PM3_SUCCESS; + return PM3_SUCCESS; } return PM3_ESOFT; } @@ -331,13 +331,13 @@ static int topaz_print_CC(uint8_t *data) { // b1, b0 write // 00 always, 01 rfo, 10 proprietary, 11 never -// vs +// vs // NFC Forum Type 2 docs, where // b7654 = major version // b3219 = minor version -// CC write / read access +// CC write / read access // (data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security", // (data[3] & 0x0F) == 0 ? "Write access granted without any security" : (data[3] & 0x0F) == 0x0F ? "No write access granted at all" : "(RFU)"); uint8_t cc_major = (data[1] & 0xF0) >> 4; @@ -397,7 +397,7 @@ static int topaz_print_CC(uint8_t *data) { PrintAndLogEx(SUCCESS, " ....x... - %02X: %s lock block", lb, (lb) ? "support" : "don\'t support"); PrintAndLogEx(SUCCESS, " .....xx. - %02X: RFU ( %s )", mlrule, (mlrule == 0) ? _GREEN_("ok") : _RED_("fail")); PrintAndLogEx(SUCCESS, " .......x - %02X: IC %s multiple block reads", mbread, (mbread) ? "support" : "don\'t support"); - PrintAndLogEx(SUCCESS,""); + PrintAndLogEx(SUCCESS, ""); return PM3_SUCCESS; } @@ -457,7 +457,7 @@ static void topaz_print_control_TLVs(uint8_t *memory) { uint16_t next_lockable_byte = 0x0f * 8; // first byte after static memory area while (*TLV_ptr != 0x03 && *TLV_ptr != 0xFD && *TLV_ptr != 0xFE) { - + // all Lock Control TLVs shall be present before the NDEF message TLV, the proprietary TLV (and the Terminator TLV) get_TLV(&TLV_ptr, &TLV_type, &TLV_length, &TLV_value); @@ -556,7 +556,7 @@ static void topaz_print_dynamic_data(void) { } PrintAndLogEx(SUCCESS, "Dynamic Data blocks:"); - + if (topaz_read_dynamic_data() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "block# | Data |lck"); @@ -587,7 +587,7 @@ static void printTopazDumpContents(uint8_t *dump, size_t size) { topaz_tag_t *t = (topaz_tag_t *)dump; - // uses a global var for all + // uses a global var for all PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "Static data blocks :"); PrintAndLogEx(SUCCESS, "block# | data |lck| info"); @@ -598,7 +598,7 @@ static void printTopazDumpContents(uint8_t *dump, size_t size) { for (uint8_t i = 0; i <= 0x0C; i++) { - if (i == 0) + if (i == 0) block_info = topaz_ks[i]; else block_info = topaz_ks[1]; @@ -606,12 +606,12 @@ static void printTopazDumpContents(uint8_t *dump, size_t size) { const char *lockstr = (topaz_byte_is_locked(i * 8)) ? _RED_("x") : " "; PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| %s | %s", - i, - i, - sprint_hex(&t->data_blocks[i][0], 8), - lockstr, - block_info - ); + i, + i, + sprint_hex(&t->data_blocks[i][0], 8), + lockstr, + block_info + ); } PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| | %s", 0x0D, 0x0D, sprint_hex(&t->data_blocks[0x0D][0], 8), topaz_ks[2]); @@ -626,7 +626,7 @@ static int CmdHFTopazReader(const char *Cmd) { "Read UID from Topaz tags", "hf topaz reader\n" "hf topaz reader -@ -> Continuous mode\n" - ); + ); void *argtable[] = { arg_param_begin, @@ -675,7 +675,7 @@ int CmdHFTopazInfo(const char *Cmd) { CLIParserFree(ctx); PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------"); - + int status = readTopazUid(false, verbose); if (status != PM3_SUCCESS) { return status; @@ -689,15 +689,15 @@ int CmdHFTopazInfo(const char *Cmd) { PrintAndLogEx(SUCCESS, " %s", sprint_bin(topaz_tag.HR01, 1)); PrintAndLogEx(SUCCESS, " ...x.... - %s / %s", - (topaz_tag.HR01[0] & 0xF0) == 0x10 ? _GREEN_("TOPAZ tag") : "", - (topaz_tag.HR01[0] & 0xF0) == 0x10 ? _GREEN_("Type 1 NDEF") : "" - ); - PrintAndLogEx(SUCCESS, " .......x - %s memory map", ((topaz_tag.HR01[0] & 0x0F) == 0x01) ? "Static" : "Dynamic" ); + (topaz_tag.HR01[0] & 0xF0) == 0x10 ? _GREEN_("TOPAZ tag") : "", + (topaz_tag.HR01[0] & 0xF0) == 0x10 ? _GREEN_("Type 1 NDEF") : "" + ); + PrintAndLogEx(SUCCESS, " .......x - %s memory map", ((topaz_tag.HR01[0] & 0x0F) == 0x01) ? "Static" : "Dynamic"); PrintAndLogEx(SUCCESS, ""); PrintAndLogEx(SUCCESS, " Lock bytes... %02X%02X", - topaz_tag.data_blocks[0x0e][0], - topaz_tag.data_blocks[0x0e][1] - ); + topaz_tag.data_blocks[0x0e][0], + topaz_tag.data_blocks[0x0e][1] + ); PrintAndLogEx(SUCCESS, " OTP.......... %s", sprint_hex(&topaz_tag.data_blocks[0x0e][2], 6)); PrintAndLogEx(NORMAL, ""); @@ -792,12 +792,12 @@ static int CmdHFTopazDump(const char *Cmd) { char filename[FILE_PATH_SIZE] = {0}; CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParserFree(ctx); - + int status = readTopazUid(false, false); if (status != PM3_SUCCESS) { return status; } - printTopazDumpContents((uint8_t*)&topaz_tag, sizeof(topaz_tag_t)); + printTopazDumpContents((uint8_t *)&topaz_tag, sizeof(topaz_tag_t)); bool set_dynamic = false; if (topaz_set_cc_dynamic(&topaz_tag.data_blocks[1][0]) == PM3_SUCCESS) { @@ -807,10 +807,10 @@ static int CmdHFTopazDump(const char *Cmd) { topaz_print_lifecycle_state(&topaz_tag.data_blocks[1][0]); - NDEFDecodeAndPrint(&topaz_tag.data_blocks[1][4], - (topaz_tag.HR01[0] == 1) ? (12 * 8) : 476 - , true - ); + NDEFDecodeAndPrint(&topaz_tag.data_blocks[1][4], + (topaz_tag.HR01[0] == 1) ? (12 * 8) : 476 + , true + ); } PrintAndLogEx(INFO, "-------------------------------------------------------------"); @@ -827,7 +827,7 @@ static int CmdHFTopazDump(const char *Cmd) { pm3_save_dump(filename, (uint8_t *)&topaz_tag, sizeof(topaz_tag_t) + topaz_tag.size, jsfTopaz, TOPAZ_BLOCK_SIZE); else pm3_save_dump(filename, (uint8_t *)&topaz_tag, sizeof(topaz_tag_t), jsfTopaz, TOPAZ_BLOCK_SIZE); - + if (set_dynamic) { free(topaz_tag.dynamic_memory); } @@ -868,12 +868,12 @@ static int CmdHFTopazView(const char *Cmd) { topaz_print_lifecycle_state(&topaz_tag.data_blocks[1][0]); - NDEFDecodeAndPrint(&topaz_tag.data_blocks[1][4], - (topaz_tag.HR01[0] == 1) ? (12 * 8) : 476 - , true - ); + NDEFDecodeAndPrint(&topaz_tag.data_blocks[1][4], + (topaz_tag.HR01[0] == 1) ? (12 * 8) : 476 + , true + ); - PrintAndLogEx(INFO, "%s", sprint_hex(&topaz_tag.data_blocks[1][4], (12*8))); + PrintAndLogEx(INFO, "%s", sprint_hex(&topaz_tag.data_blocks[1][4], (12 * 8))); free(topaz_tag.dynamic_memory); } @@ -946,7 +946,7 @@ static int CmdHFTopazWrBl(const char *Cmd) { return PM3_EINVARG; } - if (dlen != 8 ) { + if (dlen != 8) { PrintAndLogEx(WARNING, "Wrong data length. Expect 8, got %d", dlen); return PM3_EINVARG; } @@ -957,9 +957,9 @@ static int CmdHFTopazWrBl(const char *Cmd) { int res = topaz_write_erase8_block(blockno, data); if (res == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )" ); + PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )"); } else { - PrintAndLogEx(WARNING, "Write ( " _RED_("fail") " )" ); + PrintAndLogEx(WARNING, "Write ( " _RED_("fail") " )"); } topaz_switch_off_field(); @@ -977,9 +977,9 @@ static command_t CommandTable[] = { {"sim", CmdHFTopazSim, IfPm3Iso14443a, "Simulate Topaz tag"}, {"sniff", CmdHFTopazSniff, IfPm3Iso14443a, "Sniff Topaz reader-tag communication"}, {"raw", CmdHFTopazRaw, IfPm3Iso14443a, "Send raw hex data to tag"}, - {"rdbl", CmdHFTopazRdBl, IfPm3Iso14443a, "Read block"}, + {"rdbl", CmdHFTopazRdBl, IfPm3Iso14443a, "Read block"}, {"view", CmdHFTopazView, AlwaysAvailable, "Display content from tag dump file"}, - {"wrbl", CmdHFTopazWrBl, IfPm3Iso14443a, "Write block"}, + {"wrbl", CmdHFTopazWrBl, IfPm3Iso14443a, "Write block"}, {NULL, NULL, 0, NULL} }; @@ -1055,20 +1055,20 @@ int readTopazUid(bool loop, bool verbose) { // printing PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, " UID: " _GREEN_("%02X %02X %02X %02X %02X %02X %02X"), - topaz_tag.uid[6], - topaz_tag.uid[5], - topaz_tag.uid[4], - topaz_tag.uid[3], - topaz_tag.uid[2], - topaz_tag.uid[1], - topaz_tag.uid[0]); + topaz_tag.uid[6], + topaz_tag.uid[5], + topaz_tag.uid[4], + topaz_tag.uid[3], + topaz_tag.uid[2], + topaz_tag.uid[1], + topaz_tag.uid[0]); PrintAndLogEx(SUCCESS, "ATQA: " _GREEN_("%02X %02X"), atqa[1], atqa[0]); topaz_tag.HR01[0] = rid_response[0]; topaz_tag.HR01[1] = rid_response[1]; - } while (loop && kbd_enter_pressed() == false); + } while (loop && kbd_enter_pressed() == false); topaz_switch_off_field(); return res; diff --git a/client/src/fileutils.c b/client/src/fileutils.c index dcfbdfc32..a2f8e4abe 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -638,14 +638,14 @@ int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, JsonSaveStr(root, "FileType", "topaz"); JsonSaveBufAsHexCompact(root, "$.Card.UID", tag->uid, sizeof(tag->uid)); JsonSaveBufAsHexCompact(root, "$.Card.H0R1", tag->HR01, sizeof(tag->HR01)); - JsonSaveBufAsHexCompact(root, "$.Card.Size", (uint8_t *)&(tag->size), 2); + JsonSaveBufAsHexCompact(root, "$.Card.Size", (uint8_t *) & (tag->size), 2); for (size_t i = 0; i < TOPAZ_STATIC_MEMORY / 8; i++) { char path[PATH_MAX_LENGTH] = {0}; snprintf(path, sizeof(path), "$.blocks.%zu", i); JsonSaveBufAsHexCompact(root, path, &tag->data_blocks[i][0], TOPAZ_BLOCK_SIZE); } - - // ICEMAN todo: add dynamic memory. + + // ICEMAN todo: add dynamic memory. // uint16_z Size // uint8_t *dynamic_memory; @@ -1296,13 +1296,13 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz if (!strcmp(ctype, "legic")) { JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen); } - + if (!strcmp(ctype, "topaz")) { topaz_tag_t *mem = (topaz_tag_t *)udata; JsonLoadBufAsHex(root, "$.Card.UID", mem->uid, sizeof(mem->uid), datalen); JsonLoadBufAsHex(root, "$.Card.HR01", mem->HR01, sizeof(mem->HR01), datalen); - JsonLoadBufAsHex(root, "$.Card.Size", (uint8_t *)&(mem->size), 2, datalen); + JsonLoadBufAsHex(root, "$.Card.Size", (uint8_t *) & (mem->size), 2, datalen); size_t sptr = 0; for (int i = 0; i < (TOPAZ_STATIC_MEMORY / 8); i++) { @@ -1322,7 +1322,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz sptr += len; - // ICEMAN todo: add dynamic memory. + // ICEMAN todo: add dynamic memory. // uint16_z Size // uint8_t *dynamic_memory; } diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index c8987a546..ed217e8eb 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -2440,7 +2440,7 @@ static void DesfirePrintShortFileTypeSettings(FileSettings_t *fsettings) { fsettings->limitedCredit, fsettings->value, fsettings->value - ); + ); break; } case 0x03: @@ -2450,7 +2450,7 @@ static void DesfirePrintShortFileTypeSettings(FileSettings_t *fsettings) { fsettings->maxRecordCount, fsettings->recordSize, fsettings->recordSize - ); + ); break; } case 0x05: { @@ -2568,16 +2568,16 @@ static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t if (create) { PrintAndLogEx(INFO, "Value............ %d / 0x%08X", value, value); PrintAndLogEx(INFO, "Limited credit... %d - %s" - , limited_credit_enabled - , ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled" - ); + , limited_credit_enabled + , ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled" + ); } else { PrintAndLogEx(INFO, "Limited credit... %d - %s %d (0x%08X)" - , limited_credit_enabled - , ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled" - , value - , value - ); + , limited_credit_enabled + , ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled" + , value + , value + ); } PrintAndLogEx(INFO, "GetValue access... %s", ((limited_credit_enabled & 0x02) != 0) ? "Free" : "Not Free"); diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index 62a77d988..0cb9df47c 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -420,4 +420,4 @@ int DetectHID(uint8_t *d, uint16_t manufacture) { } return -1; -} \ No newline at end of file +} diff --git a/client/src/nfc/ndef.c b/client/src/nfc/ndef.c index bd4e69710..1d4a6231f 100644 --- a/client/src/nfc/ndef.c +++ b/client/src/nfc/ndef.c @@ -1060,7 +1060,7 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "--- " _CYAN_("NDEF Memory Control") " ---"); + PrintAndLogEx(SUCCESS, "--- " _CYAN_("NDEF Memory Control") " ---"); if (len != 3) { PrintAndLogEx(WARNING, "NDEF Memory Control block size must be 3 instead of %d", len); } else { diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 706ee38a4..88557d416 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -31,711 +31,711 @@ typedef struct vocabulory_s { } vocabulory_t; const static vocabulory_t vocabulory[] = { - { 1, "help" }, - { 0, "auto" }, - { 1, "clear" }, - { 1, "hints" }, - { 1, "msleep" }, - { 1, "rem" }, - { 1, "quit" }, - { 1, "exit" }, - { 1, "prefs help" }, - { 1, "prefs show" }, - { 1, "prefs get barmode" }, - { 1, "prefs get clientdebug" }, - { 1, "prefs get clientdelay" }, - { 1, "prefs get color" }, - { 1, "prefs get savepaths" }, - { 1, "prefs get emoji" }, - { 1, "prefs get hints" }, - { 1, "prefs get output" }, - { 1, "prefs get plotsliders" }, - { 1, "prefs set help" }, - { 1, "prefs set barmode" }, - { 1, "prefs set clientdebug" }, - { 1, "prefs set clientdelay" }, - { 1, "prefs set color" }, - { 1, "prefs set emoji" }, - { 1, "prefs set hints" }, - { 1, "prefs set savepaths" }, - { 1, "prefs set output" }, - { 1, "prefs set plotsliders" }, - { 1, "analyse help" }, - { 1, "analyse lcr" }, - { 1, "analyse crc" }, - { 1, "analyse chksum" }, - { 1, "analyse dates" }, - { 1, "analyse lfsr" }, - { 1, "analyse a" }, - { 1, "analyse nuid" }, - { 1, "analyse demodbuff" }, - { 1, "analyse freq" }, - { 1, "analyse foo" }, - { 1, "analyse units" }, - { 1, "data help" }, - { 1, "data biphaserawdecode" }, - { 1, "data detectclock" }, - { 1, "data fsktonrz" }, - { 1, "data manrawdecode" }, - { 1, "data modulation" }, - { 1, "data rawdemod" }, - { 1, "data askedgedetect" }, - { 1, "data autocorr" }, - { 1, "data dirthreshold" }, - { 1, "data decimate" }, - { 1, "data undecimate" }, - { 1, "data hide" }, - { 1, "data hpf" }, - { 1, "data iir" }, - { 1, "data grid" }, - { 1, "data ltrim" }, - { 1, "data mtrim" }, - { 1, "data norm" }, - { 1, "data plot" }, - { 1, "data rtrim" }, - { 1, "data setgraphmarkers" }, - { 1, "data shiftgraphzero" }, - { 1, "data timescale" }, - { 1, "data zerocrossings" }, - { 1, "data convertbitstream" }, - { 1, "data getbitstream" }, - { 1, "data asn1" }, - { 1, "data bin2hex" }, - { 0, "data bitsamples" }, - { 1, "data clear" }, - { 1, "data diff" }, - { 0, "data hexsamples" }, - { 1, "data hex2bin" }, - { 1, "data load" }, - { 1, "data print" }, - { 0, "data samples" }, - { 1, "data save" }, - { 1, "data setdebugmode" }, - { 0, "data tune" }, - { 1, "emv help" }, - { 0, "emv exec" }, - { 0, "emv pse" }, - { 0, "emv search" }, - { 0, "emv select" }, - { 0, "emv gpo" }, - { 0, "emv readrec" }, - { 0, "emv genac" }, - { 0, "emv challenge" }, - { 0, "emv intauth" }, - { 0, "emv scan" }, - { 1, "emv test" }, - { 1, "emv list" }, - { 0, "emv roca" }, - { 1, "hf help" }, - { 1, "hf list" }, - { 0, "hf plot" }, - { 0, "hf tune" }, - { 1, "hf search" }, - { 0, "hf sniff" }, - { 1, "hf 14a help" }, - { 1, "hf 14a list" }, - { 0, "hf 14a info" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a raw" }, - { 0, "hf 14a antifuzz" }, - { 0, "hf 14a config" }, - { 0, "hf 14a apdufind" }, - { 1, "hf 14b help" }, - { 0, "hf 14b apdu" }, - { 0, "hf 14b dump" }, - { 0, "hf 14b info" }, - { 1, "hf 14b list" }, - { 0, "hf 14b ndefread" }, - { 0, "hf 14b raw" }, - { 0, "hf 14b reader" }, - { 0, "hf 14b sim" }, - { 0, "hf 14b sniff" }, - { 0, "hf 14b rdbl" }, - { 0, "hf 14b sriwrite" }, - { 1, "hf 14b view" }, - { 1, "hf 15 help" }, - { 1, "hf 15 list" }, - { 1, "hf 15 demod" }, - { 0, "hf 15 dump" }, - { 0, "hf 15 info" }, - { 0, "hf 15 sniff" }, - { 0, "hf 15 raw" }, - { 0, "hf 15 rdbl" }, - { 0, "hf 15 rdmulti" }, - { 0, "hf 15 reader" }, - { 0, "hf 15 restore" }, - { 0, "hf 15 samples" }, - { 0, "hf 15 sim" }, - { 0, "hf 15 slixdisable" }, - { 0, "hf 15 wrbl" }, - { 0, "hf 15 findafi" }, - { 0, "hf 15 writeafi" }, - { 0, "hf 15 writedsfid" }, - { 0, "hf 15 csetuid" }, - { 1, "hf cipurse help" }, - { 0, "hf cipurse info" }, - { 0, "hf cipurse select" }, - { 0, "hf cipurse auth" }, - { 0, "hf cipurse read" }, - { 0, "hf cipurse write" }, - { 0, "hf cipurse aread" }, - { 0, "hf cipurse awrite" }, - { 0, "hf cipurse formatall" }, - { 0, "hf cipurse create" }, - { 0, "hf cipurse delete" }, - { 0, "hf cipurse updkey" }, - { 0, "hf cipurse updakey" }, - { 0, "hf cipurse default" }, - { 1, "hf cipurse test" }, - { 1, "hf epa help" }, - { 0, "hf epa cnonces" }, - { 0, "hf epa preplay" }, - { 1, "hf emrtd help" }, - { 0, "hf emrtd dump" }, - { 1, "hf emrtd info" }, - { 1, "hf emrtd list" }, - { 1, "hf felica help" }, - { 1, "hf felica list" }, - { 0, "hf felica reader" }, - { 0, "hf felica info" }, - { 0, "hf felica sniff" }, - { 0, "hf felica raw" }, - { 0, "hf felica rdbl" }, - { 0, "hf felica wrbl" }, - { 0, "hf felica rqservice" }, - { 0, "hf felica rqresponse" }, - { 0, "hf felica scsvcode" }, - { 0, "hf felica rqsyscode" }, - { 0, "hf felica auth1" }, - { 0, "hf felica auth2" }, - { 0, "hf felica rqspecver" }, - { 0, "hf felica resetmode" }, - { 0, "hf felica litesim" }, - { 0, "hf felica litedump" }, - { 1, "hf fido help" }, - { 1, "hf fido list" }, - { 0, "hf fido info" }, - { 0, "hf fido reg" }, - { 0, "hf fido auth" }, - { 0, "hf fido make" }, - { 0, "hf fido assert" }, - { 1, "hf gallagher help" }, - { 0, "hf gallagher reader" }, - { 0, "hf gallagher clone" }, - { 0, "hf gallagher delete" }, - { 1, "hf gallagher diversifykey" }, - { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 initialize" }, - { 0, "hf ksx6924 prec" }, - { 0, "hf ksx6924 select" }, - { 1, "hf jooki help" }, - { 0, "hf jooki clone" }, - { 1, "hf jooki decode" }, - { 1, "hf jooki encode" }, - { 0, "hf jooki sim" }, - { 1, "hf iclass help" }, - { 0, "hf iclass dump" }, - { 1, "hf iclass info" }, - { 1, "hf iclass list" }, - { 0, "hf iclass rdbl" }, - { 0, "hf iclass reader" }, - { 0, "hf iclass restore" }, - { 0, "hf iclass sniff" }, - { 0, "hf iclass wrbl" }, - { 0, "hf iclass chk" }, - { 1, "hf iclass loclass" }, - { 1, "hf iclass lookup" }, - { 0, "hf iclass sim" }, - { 0, "hf iclass eload" }, - { 0, "hf iclass esave" }, - { 0, "hf iclass eview" }, - { 1, "hf iclass configcard" }, - { 1, "hf iclass calcnewkey" }, - { 1, "hf iclass encode" }, - { 1, "hf iclass encrypt" }, - { 1, "hf iclass decrypt" }, - { 1, "hf iclass managekeys" }, - { 1, "hf iclass permutekey" }, - { 1, "hf iclass view" }, - { 1, "hf legic help" }, - { 0, "hf legic dump" }, - { 0, "hf legic info" }, - { 1, "hf legic list" }, - { 0, "hf legic rdbl" }, - { 0, "hf legic reader" }, - { 0, "hf legic restore" }, - { 0, "hf legic wipe" }, - { 0, "hf legic wrbl" }, - { 0, "hf legic sim" }, - { 0, "hf legic eload" }, - { 0, "hf legic esave" }, - { 0, "hf legic eview" }, - { 1, "hf legic crc" }, - { 1, "hf legic view" }, - { 1, "hf lto help" }, - { 0, "hf lto dump" }, - { 0, "hf lto restore" }, - { 0, "hf lto info" }, - { 0, "hf lto rdbl" }, - { 0, "hf lto wrbl" }, - { 1, "hf lto list" }, - { 1, "hf mf help" }, - { 1, "hf mf list" }, - { 0, "hf mf darkside" }, - { 0, "hf mf nested" }, - { 1, "hf mf hardnested" }, - { 0, "hf mf staticnested" }, - { 0, "hf mf autopwn" }, - { 0, "hf mf nack" }, - { 0, "hf mf chk" }, - { 0, "hf mf fchk" }, - { 1, "hf mf decrypt" }, - { 0, "hf mf supercard" }, - { 0, "hf mf auth4" }, - { 1, "hf mf acl" }, - { 0, "hf mf dump" }, - { 0, "hf mf mad" }, - { 0, "hf mf ndefread" }, - { 0, "hf mf personalize" }, - { 0, "hf mf rdbl" }, - { 0, "hf mf rdsc" }, - { 0, "hf mf restore" }, - { 0, "hf mf setmod" }, - { 1, "hf mf value" }, - { 1, "hf mf view" }, - { 0, "hf mf wipe" }, - { 0, "hf mf wrbl" }, - { 0, "hf mf sim" }, - { 0, "hf mf ecfill" }, - { 0, "hf mf eclr" }, - { 0, "hf mf egetblk" }, - { 0, "hf mf egetsc" }, - { 0, "hf mf ekeyprn" }, - { 0, "hf mf eload" }, - { 0, "hf mf esave" }, - { 0, "hf mf esetblk" }, - { 0, "hf mf eview" }, - { 0, "hf mf cgetblk" }, - { 0, "hf mf cgetsc" }, - { 0, "hf mf cload" }, - { 0, "hf mf csave" }, - { 0, "hf mf csetblk" }, - { 0, "hf mf csetuid" }, - { 0, "hf mf cview" }, - { 0, "hf mf cwipe" }, - { 0, "hf mf gen3uid" }, - { 0, "hf mf gen3blk" }, - { 0, "hf mf gen3freeze" }, - { 0, "hf mf gview" }, - { 1, "hf mfp help" }, - { 0, "hf mfp info" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp commitp" }, - { 0, "hf mfp auth" }, - { 0, "hf mfp rdbl" }, - { 0, "hf mfp rdsc" }, - { 0, "hf mfp wrbl" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp mad" }, - { 0, "hf mfp ndefread" }, - { 1, "hf mfu help" }, - { 1, "hf mfu keygen" }, - { 1, "hf mfu pwdgen" }, - { 0, "hf mfu otptear" }, - { 0, "hf mfu cauth" }, - { 0, "hf mfu dump" }, - { 0, "hf mfu info" }, - { 0, "hf mfu ndefread" }, - { 0, "hf mfu rdbl" }, - { 0, "hf mfu restore" }, - { 1, "hf mfu view" }, - { 0, "hf mfu wrbl" }, - { 0, "hf mfu eload" }, - { 0, "hf mfu eview" }, - { 0, "hf mfu sim" }, - { 0, "hf mfu setpwd" }, - { 0, "hf mfu setuid" }, - { 1, "hf mfdes help" }, - { 0, "hf mfdes info" }, - { 0, "hf mfdes getuid" }, - { 0, "hf mfdes default" }, - { 0, "hf mfdes auth" }, - { 0, "hf mfdes chk" }, - { 0, "hf mfdes detect" }, - { 0, "hf mfdes freemem" }, - { 0, "hf mfdes setconfig" }, - { 0, "hf mfdes formatpicc" }, - { 1, "hf mfdes list" }, - { 0, "hf mfdes mad" }, - { 0, "hf mfdes lsapp" }, - { 0, "hf mfdes getaids" }, - { 0, "hf mfdes getappnames" }, - { 0, "hf mfdes bruteaid" }, - { 0, "hf mfdes createapp" }, - { 0, "hf mfdes deleteapp" }, - { 0, "hf mfdes selectapp" }, - { 0, "hf mfdes changekey" }, - { 0, "hf mfdes chkeysettings" }, - { 0, "hf mfdes getkeysettings" }, - { 0, "hf mfdes getkeyversions" }, - { 0, "hf mfdes getfileids" }, - { 0, "hf mfdes getfileisoids" }, - { 0, "hf mfdes lsfiles" }, - { 0, "hf mfdes dump" }, - { 0, "hf mfdes createfile" }, - { 0, "hf mfdes createvaluefile" }, - { 0, "hf mfdes createrecordfile" }, - { 0, "hf mfdes createmacfile" }, - { 0, "hf mfdes deletefile" }, - { 0, "hf mfdes getfilesettings" }, - { 0, "hf mfdes chfilesettings" }, - { 0, "hf mfdes read" }, - { 0, "hf mfdes write" }, - { 0, "hf mfdes value" }, - { 0, "hf mfdes clearrecfile" }, - { 1, "hf mfdes test" }, - { 1, "hf ntag424 help" }, - { 0, "hf ntag424 info" }, - { 0, "hf ntag424 sdm" }, - { 1, "hf ntag424 view" }, - { 1, "hf seos help" }, - { 0, "hf seos info" }, - { 1, "hf seos list" }, - { 1, "hf st25ta help" }, - { 0, "hf st25ta info" }, - { 1, "hf st25ta list" }, - { 1, "hf st25ta ndefread" }, - { 0, "hf st25ta protect" }, - { 0, "hf st25ta pwd" }, - { 0, "hf st25ta sim" }, - { 1, "hf thinfilm help" }, - { 0, "hf thinfilm info" }, - { 1, "hf thinfilm list" }, - { 0, "hf thinfilm sim" }, - { 1, "hf topaz help" }, - { 1, "hf topaz list" }, - { 0, "hf topaz info" }, - { 0, "hf topaz reader" }, - { 0, "hf topaz sim" }, - { 0, "hf topaz sniff" }, - { 0, "hf topaz raw" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, - { 1, "hf xerox help" }, - { 0, "hf xerox info" }, - { 0, "hf xerox reader" }, - { 0, "hf xerox dump" }, - { 1, "hf waveshare help" }, - { 0, "hf waveshare loadbmp" }, - { 1, "hw help" }, - { 0, "hw break" }, - { 1, "hw connect" }, - { 0, "hw dbg" }, - { 0, "hw detectreader" }, - { 0, "hw fpgaoff" }, - { 0, "hw lcd" }, - { 0, "hw lcdreset" }, - { 0, "hw ping" }, - { 0, "hw readmem" }, - { 0, "hw reset" }, - { 0, "hw setlfdivisor" }, - { 0, "hw setmux" }, - { 0, "hw standalone" }, - { 0, "hw status" }, - { 0, "hw tearoff" }, - { 0, "hw tia" }, - { 0, "hw tune" }, - { 1, "hw version" }, - { 1, "lf help" }, - { 0, "lf config" }, - { 0, "lf cmdread" }, - { 0, "lf read" }, - { 1, "lf search" }, - { 0, "lf sim" }, - { 0, "lf simask" }, - { 0, "lf simfsk" }, - { 0, "lf simpsk" }, - { 0, "lf simbidir" }, - { 0, "lf sniff" }, - { 0, "lf tune" }, - { 1, "lf awid help" }, - { 1, "lf awid demod" }, - { 0, "lf awid reader" }, - { 0, "lf awid clone" }, - { 0, "lf awid sim" }, - { 0, "lf awid brute" }, - { 0, "lf awid watch" }, - { 1, "lf cotag help" }, - { 1, "lf cotag demod" }, - { 0, "lf cotag reader" }, - { 1, "lf destron help" }, - { 1, "lf destron demod" }, - { 0, "lf destron reader" }, - { 0, "lf destron clone" }, - { 0, "lf destron sim" }, - { 1, "lf em help" }, - { 1, "lf em 410x help" }, - { 1, "lf em 410x demod" }, - { 0, "lf em 410x reader" }, - { 0, "lf em 410x sim" }, - { 0, "lf em 410x brute" }, - { 0, "lf em 410x watch" }, - { 0, "lf em 410x spoof" }, - { 0, "lf em 410x clone" }, - { 1, "lf em 4x05 help" }, - { 0, "lf em 4x05 brute" }, - { 0, "lf em 4x05 chk" }, - { 1, "lf em 4x05 demod" }, - { 0, "lf em 4x05 dump" }, - { 0, "lf em 4x05 info" }, - { 0, "lf em 4x05 read" }, - { 1, "lf em 4x05 sniff" }, - { 0, "lf em 4x05 unlock" }, - { 0, "lf em 4x05 wipe" }, - { 0, "lf em 4x05 write" }, - { 1, "lf em 4x50 help" }, - { 0, "lf em 4x50 brute" }, - { 0, "lf em 4x50 chk" }, - { 0, "lf em 4x50 dump" }, - { 0, "lf em 4x50 info" }, - { 0, "lf em 4x50 login" }, - { 0, "lf em 4x50 rdbl" }, - { 0, "lf em 4x50 reader" }, - { 0, "lf em 4x50 restore" }, - { 0, "lf em 4x50 wrbl" }, - { 0, "lf em 4x50 wrpwd" }, - { 0, "lf em 4x50 wipe" }, - { 0, "lf em 4x50 eload" }, - { 0, "lf em 4x50 esave" }, - { 0, "lf em 4x50 eview" }, - { 0, "lf em 4x50 sim" }, - { 1, "lf em 4x70 help" }, - { 0, "lf em 4x70 info" }, - { 0, "lf em 4x70 write" }, - { 0, "lf em 4x70 unlock" }, - { 0, "lf em 4x70 auth" }, - { 0, "lf em 4x70 writepin" }, - { 0, "lf em 4x70 writekey" }, - { 1, "lf fdxb help" }, - { 1, "lf fdxb demod" }, - { 0, "lf fdxb reader" }, - { 0, "lf fdxb clone" }, - { 0, "lf fdxb sim" }, - { 1, "lf gallagher help" }, - { 1, "lf gallagher demod" }, - { 0, "lf gallagher reader" }, - { 0, "lf gallagher clone" }, - { 0, "lf gallagher sim" }, - { 1, "lf gproxii help" }, - { 1, "lf gproxii demod" }, - { 0, "lf gproxii reader" }, - { 0, "lf gproxii clone" }, - { 0, "lf gproxii sim" }, - { 1, "lf hid help" }, - { 1, "lf hid demod" }, - { 0, "lf hid reader" }, - { 0, "lf hid clone" }, - { 0, "lf hid sim" }, - { 0, "lf hid brute" }, - { 0, "lf hid watch" }, - { 1, "lf hitag help" }, - { 0, "lf hitag eload" }, - { 1, "lf hitag list" }, - { 0, "lf hitag info" }, - { 0, "lf hitag reader" }, - { 0, "lf hitag sim" }, - { 0, "lf hitag sniff" }, - { 0, "lf hitag writer" }, - { 0, "lf hitag dump" }, - { 0, "lf hitag cc" }, - { 1, "lf idteck help" }, - { 1, "lf idteck demod" }, - { 0, "lf idteck reader" }, - { 0, "lf idteck clone" }, - { 0, "lf idteck sim" }, - { 1, "lf indala help" }, - { 1, "lf indala demod" }, - { 1, "lf indala altdemod" }, - { 0, "lf indala reader" }, - { 0, "lf indala clone" }, - { 0, "lf indala sim" }, - { 1, "lf io help" }, - { 1, "lf io demod" }, - { 0, "lf io reader" }, - { 0, "lf io clone" }, - { 0, "lf io sim" }, - { 0, "lf io watch" }, - { 1, "lf jablotron help" }, - { 1, "lf jablotron demod" }, - { 0, "lf jablotron reader" }, - { 0, "lf jablotron clone" }, - { 0, "lf jablotron sim" }, - { 1, "lf keri help" }, - { 1, "lf keri demod" }, - { 0, "lf keri reader" }, - { 0, "lf keri clone" }, - { 0, "lf keri sim" }, - { 1, "lf motorola help" }, - { 1, "lf motorola demod" }, - { 0, "lf motorola reader" }, - { 0, "lf motorola clone" }, - { 0, "lf motorola sim" }, - { 1, "lf nedap help" }, - { 1, "lf nedap demod" }, - { 0, "lf nedap reader" }, - { 0, "lf nedap clone" }, - { 0, "lf nedap sim" }, - { 1, "lf nexwatch help" }, - { 1, "lf nexwatch demod" }, - { 0, "lf nexwatch reader" }, - { 0, "lf nexwatch clone" }, - { 0, "lf nexwatch sim" }, - { 1, "lf noralsy help" }, - { 1, "lf noralsy demod" }, - { 0, "lf noralsy reader" }, - { 0, "lf noralsy clone" }, - { 0, "lf noralsy sim" }, - { 1, "lf pac help" }, - { 1, "lf pac demod" }, - { 0, "lf pac reader" }, - { 0, "lf pac clone" }, - { 0, "lf pac sim" }, - { 1, "lf paradox help" }, - { 1, "lf paradox demod" }, - { 0, "lf paradox reader" }, - { 0, "lf paradox clone" }, - { 0, "lf paradox sim" }, - { 1, "lf pcf7931 help" }, - { 0, "lf pcf7931 reader" }, - { 0, "lf pcf7931 write" }, - { 1, "lf pcf7931 config" }, - { 1, "lf presco help" }, - { 1, "lf presco demod" }, - { 0, "lf presco reader" }, - { 0, "lf presco clone" }, - { 0, "lf presco sim" }, - { 1, "lf pyramid help" }, - { 1, "lf pyramid demod" }, - { 0, "lf pyramid reader" }, - { 0, "lf pyramid clone" }, - { 0, "lf pyramid sim" }, - { 1, "lf securakey help" }, - { 1, "lf securakey demod" }, - { 0, "lf securakey reader" }, - { 0, "lf securakey clone" }, - { 0, "lf securakey sim" }, - { 1, "lf ti help" }, - { 1, "lf ti demod" }, - { 0, "lf ti reader" }, - { 0, "lf ti write" }, - { 1, "lf t55xx help" }, - { 0, "lf t55xx clonehelp" }, - { 1, "lf t55xx config" }, - { 0, "lf t55xx dangerraw" }, - { 1, "lf t55xx detect" }, - { 0, "lf t55xx deviceconfig" }, - { 0, "lf t55xx dump" }, - { 1, "lf t55xx info" }, - { 0, "lf t55xx p1detect" }, - { 0, "lf t55xx read" }, - { 0, "lf t55xx resetread" }, - { 0, "lf t55xx restore" }, - { 1, "lf t55xx trace" }, - { 0, "lf t55xx wakeup" }, - { 0, "lf t55xx write" }, - { 0, "lf t55xx bruteforce" }, - { 0, "lf t55xx chk" }, - { 0, "lf t55xx protect" }, - { 0, "lf t55xx recoverpw" }, - { 1, "lf t55xx sniff" }, - { 0, "lf t55xx special" }, - { 0, "lf t55xx wipe" }, - { 1, "lf viking help" }, - { 1, "lf viking demod" }, - { 0, "lf viking reader" }, - { 0, "lf viking clone" }, - { 0, "lf viking sim" }, - { 1, "lf visa2000 help" }, - { 1, "lf visa2000 demod" }, - { 0, "lf visa2000 reader" }, - { 0, "lf visa2000 clone" }, - { 0, "lf visa2000 sim" }, - { 1, "mem help" }, - { 0, "mem baudrate" }, - { 0, "mem dump" }, - { 0, "mem info" }, - { 0, "mem load" }, - { 0, "mem wipe" }, - { 1, "mem spiffs help" }, - { 0, "mem spiffs copy" }, - { 0, "mem spiffs check" }, - { 0, "mem spiffs dump" }, - { 0, "mem spiffs info" }, - { 0, "mem spiffs mount" }, - { 0, "mem spiffs remove" }, - { 0, "mem spiffs rename" }, - { 0, "mem spiffs test" }, - { 0, "mem spiffs tree" }, - { 0, "mem spiffs unmount" }, - { 0, "mem spiffs upload" }, - { 0, "mem spiffs view" }, - { 0, "mem spiffs wipe" }, - { 1, "nfc help" }, - { 1, "nfc decode" }, - { 0, "nfc type1 read" }, - { 1, "nfc type1 help" }, - { 0, "nfc type2 read" }, - { 1, "nfc type2 help" }, - { 0, "nfc type4a read" }, - { 0, "nfc type4a st25taread" }, - { 1, "nfc type4a help" }, - { 0, "nfc type4b read" }, - { 1, "nfc type4b help" }, - { 0, "nfc mf cread" }, - { 0, "nfc mf pread" }, - { 1, "nfc mf help" }, - { 0, "nfc barcode read" }, - { 0, "nfc barcode sim" }, - { 1, "nfc barcode help" }, - { 1, "smart help" }, - { 1, "smart list" }, - { 0, "smart info" }, - { 0, "smart reader" }, - { 0, "smart raw" }, - { 1, "smart upgrade" }, - { 0, "smart setclock" }, - { 0, "smart brute" }, - { 1, "script help" }, - { 1, "script list" }, - { 1, "script run" }, - { 1, "trace help" }, - { 1, "trace extract" }, - { 1, "trace list" }, - { 1, "trace load" }, - { 1, "trace save" }, - { 1, "usart help" }, - { 0, "usart btpin" }, - { 0, "usart btfactory" }, - { 0, "usart tx" }, - { 0, "usart rx" }, - { 0, "usart txrx" }, - { 0, "usart txhex" }, - { 0, "usart rxhex" }, - { 0, "usart config" }, - { 1, "wiegand help" }, - { 1, "wiegand list" }, - { 1, "wiegand encode" }, - { 1, "wiegand decode" }, + { 1, "help" }, + { 0, "auto" }, + { 1, "clear" }, + { 1, "hints" }, + { 1, "msleep" }, + { 1, "rem" }, + { 1, "quit" }, + { 1, "exit" }, + { 1, "prefs help" }, + { 1, "prefs show" }, + { 1, "prefs get barmode" }, + { 1, "prefs get clientdebug" }, + { 1, "prefs get clientdelay" }, + { 1, "prefs get color" }, + { 1, "prefs get savepaths" }, + { 1, "prefs get emoji" }, + { 1, "prefs get hints" }, + { 1, "prefs get output" }, + { 1, "prefs get plotsliders" }, + { 1, "prefs set help" }, + { 1, "prefs set barmode" }, + { 1, "prefs set clientdebug" }, + { 1, "prefs set clientdelay" }, + { 1, "prefs set color" }, + { 1, "prefs set emoji" }, + { 1, "prefs set hints" }, + { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, + { 1, "prefs set plotsliders" }, + { 1, "analyse help" }, + { 1, "analyse lcr" }, + { 1, "analyse crc" }, + { 1, "analyse chksum" }, + { 1, "analyse dates" }, + { 1, "analyse lfsr" }, + { 1, "analyse a" }, + { 1, "analyse nuid" }, + { 1, "analyse demodbuff" }, + { 1, "analyse freq" }, + { 1, "analyse foo" }, + { 1, "analyse units" }, + { 1, "data help" }, + { 1, "data biphaserawdecode" }, + { 1, "data detectclock" }, + { 1, "data fsktonrz" }, + { 1, "data manrawdecode" }, + { 1, "data modulation" }, + { 1, "data rawdemod" }, + { 1, "data askedgedetect" }, + { 1, "data autocorr" }, + { 1, "data dirthreshold" }, + { 1, "data decimate" }, + { 1, "data undecimate" }, + { 1, "data hide" }, + { 1, "data hpf" }, + { 1, "data iir" }, + { 1, "data grid" }, + { 1, "data ltrim" }, + { 1, "data mtrim" }, + { 1, "data norm" }, + { 1, "data plot" }, + { 1, "data rtrim" }, + { 1, "data setgraphmarkers" }, + { 1, "data shiftgraphzero" }, + { 1, "data timescale" }, + { 1, "data zerocrossings" }, + { 1, "data convertbitstream" }, + { 1, "data getbitstream" }, + { 1, "data asn1" }, + { 1, "data bin2hex" }, + { 0, "data bitsamples" }, + { 1, "data clear" }, + { 1, "data diff" }, + { 0, "data hexsamples" }, + { 1, "data hex2bin" }, + { 1, "data load" }, + { 1, "data print" }, + { 0, "data samples" }, + { 1, "data save" }, + { 1, "data setdebugmode" }, + { 0, "data tune" }, + { 1, "emv help" }, + { 0, "emv exec" }, + { 0, "emv pse" }, + { 0, "emv search" }, + { 0, "emv select" }, + { 0, "emv gpo" }, + { 0, "emv readrec" }, + { 0, "emv genac" }, + { 0, "emv challenge" }, + { 0, "emv intauth" }, + { 0, "emv scan" }, + { 1, "emv test" }, + { 1, "emv list" }, + { 0, "emv roca" }, + { 1, "hf help" }, + { 1, "hf list" }, + { 0, "hf plot" }, + { 0, "hf tune" }, + { 1, "hf search" }, + { 0, "hf sniff" }, + { 1, "hf 14a help" }, + { 1, "hf 14a list" }, + { 0, "hf 14a info" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a apdu" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a antifuzz" }, + { 0, "hf 14a config" }, + { 0, "hf 14a apdufind" }, + { 1, "hf 14b help" }, + { 0, "hf 14b apdu" }, + { 0, "hf 14b dump" }, + { 0, "hf 14b info" }, + { 1, "hf 14b list" }, + { 0, "hf 14b ndefread" }, + { 0, "hf 14b raw" }, + { 0, "hf 14b reader" }, + { 0, "hf 14b sim" }, + { 0, "hf 14b sniff" }, + { 0, "hf 14b rdbl" }, + { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, + { 1, "hf 15 help" }, + { 1, "hf 15 list" }, + { 1, "hf 15 demod" }, + { 0, "hf 15 dump" }, + { 0, "hf 15 info" }, + { 0, "hf 15 sniff" }, + { 0, "hf 15 raw" }, + { 0, "hf 15 rdbl" }, + { 0, "hf 15 rdmulti" }, + { 0, "hf 15 reader" }, + { 0, "hf 15 restore" }, + { 0, "hf 15 samples" }, + { 0, "hf 15 sim" }, + { 0, "hf 15 slixdisable" }, + { 0, "hf 15 wrbl" }, + { 0, "hf 15 findafi" }, + { 0, "hf 15 writeafi" }, + { 0, "hf 15 writedsfid" }, + { 0, "hf 15 csetuid" }, + { 1, "hf cipurse help" }, + { 0, "hf cipurse info" }, + { 0, "hf cipurse select" }, + { 0, "hf cipurse auth" }, + { 0, "hf cipurse read" }, + { 0, "hf cipurse write" }, + { 0, "hf cipurse aread" }, + { 0, "hf cipurse awrite" }, + { 0, "hf cipurse formatall" }, + { 0, "hf cipurse create" }, + { 0, "hf cipurse delete" }, + { 0, "hf cipurse updkey" }, + { 0, "hf cipurse updakey" }, + { 0, "hf cipurse default" }, + { 1, "hf cipurse test" }, + { 1, "hf epa help" }, + { 0, "hf epa cnonces" }, + { 0, "hf epa preplay" }, + { 1, "hf emrtd help" }, + { 0, "hf emrtd dump" }, + { 1, "hf emrtd info" }, + { 1, "hf emrtd list" }, + { 1, "hf felica help" }, + { 1, "hf felica list" }, + { 0, "hf felica reader" }, + { 0, "hf felica info" }, + { 0, "hf felica sniff" }, + { 0, "hf felica raw" }, + { 0, "hf felica rdbl" }, + { 0, "hf felica wrbl" }, + { 0, "hf felica rqservice" }, + { 0, "hf felica rqresponse" }, + { 0, "hf felica scsvcode" }, + { 0, "hf felica rqsyscode" }, + { 0, "hf felica auth1" }, + { 0, "hf felica auth2" }, + { 0, "hf felica rqspecver" }, + { 0, "hf felica resetmode" }, + { 0, "hf felica litesim" }, + { 0, "hf felica litedump" }, + { 1, "hf fido help" }, + { 1, "hf fido list" }, + { 0, "hf fido info" }, + { 0, "hf fido reg" }, + { 0, "hf fido auth" }, + { 0, "hf fido make" }, + { 0, "hf fido assert" }, + { 1, "hf gallagher help" }, + { 0, "hf gallagher reader" }, + { 0, "hf gallagher clone" }, + { 0, "hf gallagher delete" }, + { 1, "hf gallagher diversifykey" }, + { 1, "hf ksx6924 help" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 initialize" }, + { 0, "hf ksx6924 prec" }, + { 0, "hf ksx6924 select" }, + { 1, "hf jooki help" }, + { 0, "hf jooki clone" }, + { 1, "hf jooki decode" }, + { 1, "hf jooki encode" }, + { 0, "hf jooki sim" }, + { 1, "hf iclass help" }, + { 0, "hf iclass dump" }, + { 1, "hf iclass info" }, + { 1, "hf iclass list" }, + { 0, "hf iclass rdbl" }, + { 0, "hf iclass reader" }, + { 0, "hf iclass restore" }, + { 0, "hf iclass sniff" }, + { 0, "hf iclass wrbl" }, + { 0, "hf iclass chk" }, + { 1, "hf iclass loclass" }, + { 1, "hf iclass lookup" }, + { 0, "hf iclass sim" }, + { 0, "hf iclass eload" }, + { 0, "hf iclass esave" }, + { 0, "hf iclass eview" }, + { 1, "hf iclass configcard" }, + { 1, "hf iclass calcnewkey" }, + { 1, "hf iclass encode" }, + { 1, "hf iclass encrypt" }, + { 1, "hf iclass decrypt" }, + { 1, "hf iclass managekeys" }, + { 1, "hf iclass permutekey" }, + { 1, "hf iclass view" }, + { 1, "hf legic help" }, + { 0, "hf legic dump" }, + { 0, "hf legic info" }, + { 1, "hf legic list" }, + { 0, "hf legic rdbl" }, + { 0, "hf legic reader" }, + { 0, "hf legic restore" }, + { 0, "hf legic wipe" }, + { 0, "hf legic wrbl" }, + { 0, "hf legic sim" }, + { 0, "hf legic eload" }, + { 0, "hf legic esave" }, + { 0, "hf legic eview" }, + { 1, "hf legic crc" }, + { 1, "hf legic view" }, + { 1, "hf lto help" }, + { 0, "hf lto dump" }, + { 0, "hf lto restore" }, + { 0, "hf lto info" }, + { 0, "hf lto rdbl" }, + { 0, "hf lto wrbl" }, + { 1, "hf lto list" }, + { 1, "hf mf help" }, + { 1, "hf mf list" }, + { 0, "hf mf darkside" }, + { 0, "hf mf nested" }, + { 1, "hf mf hardnested" }, + { 0, "hf mf staticnested" }, + { 0, "hf mf autopwn" }, + { 0, "hf mf nack" }, + { 0, "hf mf chk" }, + { 0, "hf mf fchk" }, + { 1, "hf mf decrypt" }, + { 0, "hf mf supercard" }, + { 0, "hf mf auth4" }, + { 1, "hf mf acl" }, + { 0, "hf mf dump" }, + { 0, "hf mf mad" }, + { 0, "hf mf ndefread" }, + { 0, "hf mf personalize" }, + { 0, "hf mf rdbl" }, + { 0, "hf mf rdsc" }, + { 0, "hf mf restore" }, + { 0, "hf mf setmod" }, + { 1, "hf mf value" }, + { 1, "hf mf view" }, + { 0, "hf mf wipe" }, + { 0, "hf mf wrbl" }, + { 0, "hf mf sim" }, + { 0, "hf mf ecfill" }, + { 0, "hf mf eclr" }, + { 0, "hf mf egetblk" }, + { 0, "hf mf egetsc" }, + { 0, "hf mf ekeyprn" }, + { 0, "hf mf eload" }, + { 0, "hf mf esave" }, + { 0, "hf mf esetblk" }, + { 0, "hf mf eview" }, + { 0, "hf mf cgetblk" }, + { 0, "hf mf cgetsc" }, + { 0, "hf mf cload" }, + { 0, "hf mf csave" }, + { 0, "hf mf csetblk" }, + { 0, "hf mf csetuid" }, + { 0, "hf mf cview" }, + { 0, "hf mf cwipe" }, + { 0, "hf mf gen3uid" }, + { 0, "hf mf gen3blk" }, + { 0, "hf mf gen3freeze" }, + { 0, "hf mf gview" }, + { 1, "hf mfp help" }, + { 0, "hf mfp info" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp auth" }, + { 0, "hf mfp rdbl" }, + { 0, "hf mfp rdsc" }, + { 0, "hf mfp wrbl" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp mad" }, + { 0, "hf mfp ndefread" }, + { 1, "hf mfu help" }, + { 1, "hf mfu keygen" }, + { 1, "hf mfu pwdgen" }, + { 0, "hf mfu otptear" }, + { 0, "hf mfu cauth" }, + { 0, "hf mfu dump" }, + { 0, "hf mfu info" }, + { 0, "hf mfu ndefread" }, + { 0, "hf mfu rdbl" }, + { 0, "hf mfu restore" }, + { 1, "hf mfu view" }, + { 0, "hf mfu wrbl" }, + { 0, "hf mfu eload" }, + { 0, "hf mfu eview" }, + { 0, "hf mfu sim" }, + { 0, "hf mfu setpwd" }, + { 0, "hf mfu setuid" }, + { 1, "hf mfdes help" }, + { 0, "hf mfdes info" }, + { 0, "hf mfdes getuid" }, + { 0, "hf mfdes default" }, + { 0, "hf mfdes auth" }, + { 0, "hf mfdes chk" }, + { 0, "hf mfdes detect" }, + { 0, "hf mfdes freemem" }, + { 0, "hf mfdes setconfig" }, + { 0, "hf mfdes formatpicc" }, + { 1, "hf mfdes list" }, + { 0, "hf mfdes mad" }, + { 0, "hf mfdes lsapp" }, + { 0, "hf mfdes getaids" }, + { 0, "hf mfdes getappnames" }, + { 0, "hf mfdes bruteaid" }, + { 0, "hf mfdes createapp" }, + { 0, "hf mfdes deleteapp" }, + { 0, "hf mfdes selectapp" }, + { 0, "hf mfdes changekey" }, + { 0, "hf mfdes chkeysettings" }, + { 0, "hf mfdes getkeysettings" }, + { 0, "hf mfdes getkeyversions" }, + { 0, "hf mfdes getfileids" }, + { 0, "hf mfdes getfileisoids" }, + { 0, "hf mfdes lsfiles" }, + { 0, "hf mfdes dump" }, + { 0, "hf mfdes createfile" }, + { 0, "hf mfdes createvaluefile" }, + { 0, "hf mfdes createrecordfile" }, + { 0, "hf mfdes createmacfile" }, + { 0, "hf mfdes deletefile" }, + { 0, "hf mfdes getfilesettings" }, + { 0, "hf mfdes chfilesettings" }, + { 0, "hf mfdes read" }, + { 0, "hf mfdes write" }, + { 0, "hf mfdes value" }, + { 0, "hf mfdes clearrecfile" }, + { 1, "hf mfdes test" }, + { 1, "hf ntag424 help" }, + { 0, "hf ntag424 info" }, + { 0, "hf ntag424 sdm" }, + { 1, "hf ntag424 view" }, + { 1, "hf seos help" }, + { 0, "hf seos info" }, + { 1, "hf seos list" }, + { 1, "hf st25ta help" }, + { 0, "hf st25ta info" }, + { 1, "hf st25ta list" }, + { 1, "hf st25ta ndefread" }, + { 0, "hf st25ta protect" }, + { 0, "hf st25ta pwd" }, + { 0, "hf st25ta sim" }, + { 1, "hf thinfilm help" }, + { 0, "hf thinfilm info" }, + { 1, "hf thinfilm list" }, + { 0, "hf thinfilm sim" }, + { 1, "hf topaz help" }, + { 1, "hf topaz list" }, + { 0, "hf topaz info" }, + { 0, "hf topaz reader" }, + { 0, "hf topaz sim" }, + { 0, "hf topaz sniff" }, + { 0, "hf topaz raw" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, + { 0, "hf xerox dump" }, + { 1, "hf waveshare help" }, + { 0, "hf waveshare loadbmp" }, + { 1, "hw help" }, + { 0, "hw break" }, + { 1, "hw connect" }, + { 0, "hw dbg" }, + { 0, "hw detectreader" }, + { 0, "hw fpgaoff" }, + { 0, "hw lcd" }, + { 0, "hw lcdreset" }, + { 0, "hw ping" }, + { 0, "hw readmem" }, + { 0, "hw reset" }, + { 0, "hw setlfdivisor" }, + { 0, "hw setmux" }, + { 0, "hw standalone" }, + { 0, "hw status" }, + { 0, "hw tearoff" }, + { 0, "hw tia" }, + { 0, "hw tune" }, + { 1, "hw version" }, + { 1, "lf help" }, + { 0, "lf config" }, + { 0, "lf cmdread" }, + { 0, "lf read" }, + { 1, "lf search" }, + { 0, "lf sim" }, + { 0, "lf simask" }, + { 0, "lf simfsk" }, + { 0, "lf simpsk" }, + { 0, "lf simbidir" }, + { 0, "lf sniff" }, + { 0, "lf tune" }, + { 1, "lf awid help" }, + { 1, "lf awid demod" }, + { 0, "lf awid reader" }, + { 0, "lf awid clone" }, + { 0, "lf awid sim" }, + { 0, "lf awid brute" }, + { 0, "lf awid watch" }, + { 1, "lf cotag help" }, + { 1, "lf cotag demod" }, + { 0, "lf cotag reader" }, + { 1, "lf destron help" }, + { 1, "lf destron demod" }, + { 0, "lf destron reader" }, + { 0, "lf destron clone" }, + { 0, "lf destron sim" }, + { 1, "lf em help" }, + { 1, "lf em 410x help" }, + { 1, "lf em 410x demod" }, + { 0, "lf em 410x reader" }, + { 0, "lf em 410x sim" }, + { 0, "lf em 410x brute" }, + { 0, "lf em 410x watch" }, + { 0, "lf em 410x spoof" }, + { 0, "lf em 410x clone" }, + { 1, "lf em 4x05 help" }, + { 0, "lf em 4x05 brute" }, + { 0, "lf em 4x05 chk" }, + { 1, "lf em 4x05 demod" }, + { 0, "lf em 4x05 dump" }, + { 0, "lf em 4x05 info" }, + { 0, "lf em 4x05 read" }, + { 1, "lf em 4x05 sniff" }, + { 0, "lf em 4x05 unlock" }, + { 0, "lf em 4x05 wipe" }, + { 0, "lf em 4x05 write" }, + { 1, "lf em 4x50 help" }, + { 0, "lf em 4x50 brute" }, + { 0, "lf em 4x50 chk" }, + { 0, "lf em 4x50 dump" }, + { 0, "lf em 4x50 info" }, + { 0, "lf em 4x50 login" }, + { 0, "lf em 4x50 rdbl" }, + { 0, "lf em 4x50 reader" }, + { 0, "lf em 4x50 restore" }, + { 0, "lf em 4x50 wrbl" }, + { 0, "lf em 4x50 wrpwd" }, + { 0, "lf em 4x50 wipe" }, + { 0, "lf em 4x50 eload" }, + { 0, "lf em 4x50 esave" }, + { 0, "lf em 4x50 eview" }, + { 0, "lf em 4x50 sim" }, + { 1, "lf em 4x70 help" }, + { 0, "lf em 4x70 info" }, + { 0, "lf em 4x70 write" }, + { 0, "lf em 4x70 unlock" }, + { 0, "lf em 4x70 auth" }, + { 0, "lf em 4x70 writepin" }, + { 0, "lf em 4x70 writekey" }, + { 1, "lf fdxb help" }, + { 1, "lf fdxb demod" }, + { 0, "lf fdxb reader" }, + { 0, "lf fdxb clone" }, + { 0, "lf fdxb sim" }, + { 1, "lf gallagher help" }, + { 1, "lf gallagher demod" }, + { 0, "lf gallagher reader" }, + { 0, "lf gallagher clone" }, + { 0, "lf gallagher sim" }, + { 1, "lf gproxii help" }, + { 1, "lf gproxii demod" }, + { 0, "lf gproxii reader" }, + { 0, "lf gproxii clone" }, + { 0, "lf gproxii sim" }, + { 1, "lf hid help" }, + { 1, "lf hid demod" }, + { 0, "lf hid reader" }, + { 0, "lf hid clone" }, + { 0, "lf hid sim" }, + { 0, "lf hid brute" }, + { 0, "lf hid watch" }, + { 1, "lf hitag help" }, + { 0, "lf hitag eload" }, + { 1, "lf hitag list" }, + { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, + { 0, "lf hitag sim" }, + { 0, "lf hitag sniff" }, + { 0, "lf hitag writer" }, + { 0, "lf hitag dump" }, + { 0, "lf hitag cc" }, + { 1, "lf idteck help" }, + { 1, "lf idteck demod" }, + { 0, "lf idteck reader" }, + { 0, "lf idteck clone" }, + { 0, "lf idteck sim" }, + { 1, "lf indala help" }, + { 1, "lf indala demod" }, + { 1, "lf indala altdemod" }, + { 0, "lf indala reader" }, + { 0, "lf indala clone" }, + { 0, "lf indala sim" }, + { 1, "lf io help" }, + { 1, "lf io demod" }, + { 0, "lf io reader" }, + { 0, "lf io clone" }, + { 0, "lf io sim" }, + { 0, "lf io watch" }, + { 1, "lf jablotron help" }, + { 1, "lf jablotron demod" }, + { 0, "lf jablotron reader" }, + { 0, "lf jablotron clone" }, + { 0, "lf jablotron sim" }, + { 1, "lf keri help" }, + { 1, "lf keri demod" }, + { 0, "lf keri reader" }, + { 0, "lf keri clone" }, + { 0, "lf keri sim" }, + { 1, "lf motorola help" }, + { 1, "lf motorola demod" }, + { 0, "lf motorola reader" }, + { 0, "lf motorola clone" }, + { 0, "lf motorola sim" }, + { 1, "lf nedap help" }, + { 1, "lf nedap demod" }, + { 0, "lf nedap reader" }, + { 0, "lf nedap clone" }, + { 0, "lf nedap sim" }, + { 1, "lf nexwatch help" }, + { 1, "lf nexwatch demod" }, + { 0, "lf nexwatch reader" }, + { 0, "lf nexwatch clone" }, + { 0, "lf nexwatch sim" }, + { 1, "lf noralsy help" }, + { 1, "lf noralsy demod" }, + { 0, "lf noralsy reader" }, + { 0, "lf noralsy clone" }, + { 0, "lf noralsy sim" }, + { 1, "lf pac help" }, + { 1, "lf pac demod" }, + { 0, "lf pac reader" }, + { 0, "lf pac clone" }, + { 0, "lf pac sim" }, + { 1, "lf paradox help" }, + { 1, "lf paradox demod" }, + { 0, "lf paradox reader" }, + { 0, "lf paradox clone" }, + { 0, "lf paradox sim" }, + { 1, "lf pcf7931 help" }, + { 0, "lf pcf7931 reader" }, + { 0, "lf pcf7931 write" }, + { 1, "lf pcf7931 config" }, + { 1, "lf presco help" }, + { 1, "lf presco demod" }, + { 0, "lf presco reader" }, + { 0, "lf presco clone" }, + { 0, "lf presco sim" }, + { 1, "lf pyramid help" }, + { 1, "lf pyramid demod" }, + { 0, "lf pyramid reader" }, + { 0, "lf pyramid clone" }, + { 0, "lf pyramid sim" }, + { 1, "lf securakey help" }, + { 1, "lf securakey demod" }, + { 0, "lf securakey reader" }, + { 0, "lf securakey clone" }, + { 0, "lf securakey sim" }, + { 1, "lf ti help" }, + { 1, "lf ti demod" }, + { 0, "lf ti reader" }, + { 0, "lf ti write" }, + { 1, "lf t55xx help" }, + { 0, "lf t55xx clonehelp" }, + { 1, "lf t55xx config" }, + { 0, "lf t55xx dangerraw" }, + { 1, "lf t55xx detect" }, + { 0, "lf t55xx deviceconfig" }, + { 0, "lf t55xx dump" }, + { 1, "lf t55xx info" }, + { 0, "lf t55xx p1detect" }, + { 0, "lf t55xx read" }, + { 0, "lf t55xx resetread" }, + { 0, "lf t55xx restore" }, + { 1, "lf t55xx trace" }, + { 0, "lf t55xx wakeup" }, + { 0, "lf t55xx write" }, + { 0, "lf t55xx bruteforce" }, + { 0, "lf t55xx chk" }, + { 0, "lf t55xx protect" }, + { 0, "lf t55xx recoverpw" }, + { 1, "lf t55xx sniff" }, + { 0, "lf t55xx special" }, + { 0, "lf t55xx wipe" }, + { 1, "lf viking help" }, + { 1, "lf viking demod" }, + { 0, "lf viking reader" }, + { 0, "lf viking clone" }, + { 0, "lf viking sim" }, + { 1, "lf visa2000 help" }, + { 1, "lf visa2000 demod" }, + { 0, "lf visa2000 reader" }, + { 0, "lf visa2000 clone" }, + { 0, "lf visa2000 sim" }, + { 1, "mem help" }, + { 0, "mem baudrate" }, + { 0, "mem dump" }, + { 0, "mem info" }, + { 0, "mem load" }, + { 0, "mem wipe" }, + { 1, "mem spiffs help" }, + { 0, "mem spiffs copy" }, + { 0, "mem spiffs check" }, + { 0, "mem spiffs dump" }, + { 0, "mem spiffs info" }, + { 0, "mem spiffs mount" }, + { 0, "mem spiffs remove" }, + { 0, "mem spiffs rename" }, + { 0, "mem spiffs test" }, + { 0, "mem spiffs tree" }, + { 0, "mem spiffs unmount" }, + { 0, "mem spiffs upload" }, + { 0, "mem spiffs view" }, + { 0, "mem spiffs wipe" }, + { 1, "nfc help" }, + { 1, "nfc decode" }, + { 0, "nfc type1 read" }, + { 1, "nfc type1 help" }, + { 0, "nfc type2 read" }, + { 1, "nfc type2 help" }, + { 0, "nfc type4a read" }, + { 0, "nfc type4a st25taread" }, + { 1, "nfc type4a help" }, + { 0, "nfc type4b read" }, + { 1, "nfc type4b help" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf pread" }, + { 1, "nfc mf help" }, + { 0, "nfc barcode read" }, + { 0, "nfc barcode sim" }, + { 1, "nfc barcode help" }, + { 1, "smart help" }, + { 1, "smart list" }, + { 0, "smart info" }, + { 0, "smart reader" }, + { 0, "smart raw" }, + { 1, "smart upgrade" }, + { 0, "smart setclock" }, + { 0, "smart brute" }, + { 1, "script help" }, + { 1, "script list" }, + { 1, "script run" }, + { 1, "trace help" }, + { 1, "trace extract" }, + { 1, "trace list" }, + { 1, "trace load" }, + { 1, "trace save" }, + { 1, "usart help" }, + { 0, "usart btpin" }, + { 0, "usart btfactory" }, + { 0, "usart tx" }, + { 0, "usart rx" }, + { 0, "usart txrx" }, + { 0, "usart txhex" }, + { 0, "usart rxhex" }, + { 0, "usart config" }, + { 1, "wiegand help" }, + { 1, "wiegand list" }, + { 1, "wiegand encode" }, + { 1, "wiegand decode" }, {0, NULL} }; @@ -743,4 +743,4 @@ const static vocabulory_t vocabulory[] = { } #endif -#endif \ No newline at end of file +#endif diff --git a/client/src/wiegand_formatutils.c b/client/src/wiegand_formatutils.c index adc628c03..e55f999bd 100644 --- a/client/src/wiegand_formatutils.c +++ b/client/src/wiegand_formatutils.c @@ -149,15 +149,15 @@ static uint8_t get_length_from_header(wiegand_message_t *data) { } else { printf("hid preamble detected\n"); - len = 32; + len = 32; - if ((data->Mid ^ 0x20) == 0) { hfmt = data->Bot; len = 0; } - else if ((data->Mid & 0x10) == 0) { hfmt = data->Mid & 0x1F; } - else if ((data->Mid & 0x08) == 0) { hfmt = data->Mid & 0x0F; } - else if ((data->Mid & 0x04) == 0) { hfmt = data->Mid & 0x07; } - else if ((data->Mid & 0x02) == 0) { hfmt = data->Mid & 0x03; } - else if ((data->Mid & 0x01) == 0) { hfmt = data->Mid & 0x01; } - else { hfmt = data->Mid & 0x3F;} + if ((data->Mid ^ 0x20) == 0) { hfmt = data->Bot; len = 0; } + else if ((data->Mid & 0x10) == 0) { hfmt = data->Mid & 0x1F; } + else if ((data->Mid & 0x08) == 0) { hfmt = data->Mid & 0x0F; } + else if ((data->Mid & 0x04) == 0) { hfmt = data->Mid & 0x07; } + else if ((data->Mid & 0x02) == 0) { hfmt = data->Mid & 0x03; } + else if ((data->Mid & 0x01) == 0) { hfmt = data->Mid & 0x01; } + else { hfmt = data->Mid & 0x3F;} } } else { From 745928e609a556f127ffe01c2fa7154d26d6ee48 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Fri, 26 Aug 2022 09:28:04 +0200 Subject: [PATCH 215/759] Fix comments. --- armsrc/iso15693.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 91dc22488..d4a7be85f 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -2188,7 +2188,7 @@ void SimTagIso15693(uint8_t *uid) { bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH); uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; - // Build GET_SYSTEM_INFO command + // Build GET_SYSTEM_INFO response uint8_t resp_sysinfo[CMD_SYSINFO_RESP] = {0}; resp_sysinfo[0] = 0; // Response flags. @@ -2226,7 +2226,7 @@ void SimTagIso15693(uint8_t *uid) { bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH); uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; - // Build GET_SYSTEM_INFO command + // Build READ_BLOCK response uint8_t resp_readblock[CMD_READBLOCK_RESP] = {0}; resp_readblock[0] = 0; // Response flags. From 79cfa1d8faa56c390a045d779b997633b357c515 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 28 Aug 2022 12:21:21 +0200 Subject: [PATCH 216/759] adapt SPIFFS from 128kb -> 192kb. Increased GC to fit sector size 4kb. (thanks @mwalker33) --- armsrc/spiffs.c | 93 +++++++++++++++++++++++++++--------------- armsrc/spiffs.h | 14 ++++--- armsrc/spiffs_config.h | 4 +- 3 files changed, 70 insertions(+), 41 deletions(-) diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index bf20f8a70..027563729 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -18,7 +18,7 @@ // SPIFFS api for RDV40 Integration //----------------------------------------------------------------------------- -#define SPIFFS_CFG_PHYS_SZ (1024 * 128) +#define SPIFFS_CFG_PHYS_SZ (1024 * 192) #define SPIFFS_CFG_PHYS_ERASE_SZ (4 * 1024) #define SPIFFS_CFG_PHYS_ADDR (0) #define SPIFFS_CFG_LOG_PAGE_SZ (256) @@ -69,7 +69,7 @@ static s32_t rdv40_spiffs_llread(u32_t addr, u32_t size, u8_t *dst) { static s32_t rdv40_spiffs_llwrite(u32_t addr, u32_t size, u8_t *src) { - if (!FlashInit()) { + if (FlashInit() == false) { return 129; } Flash_Write(addr, src, size); @@ -77,9 +77,7 @@ static s32_t rdv40_spiffs_llwrite(u32_t addr, u32_t size, u8_t *src) { } static s32_t rdv40_spiffs_llerase(u32_t addr, u32_t size) { - uint8_t erased = 0; - - if (!FlashInit()) { + if (FlashInit() == false) { return 130; } @@ -99,10 +97,12 @@ static s32_t rdv40_spiffs_llerase(u32_t addr, u32_t size) { if (g_dbglevel >= DBG_DEBUG) Dbprintf("LLERASEDBG : block : %d, sector : %d \n", block, sector); - erased = Flash_Erase4k(block, sector); + uint8_t erased = Flash_Erase4k(block, sector); Flash_CheckBusy(BUSY_TIMEOUT); FlashStop(); + // iceman: SPIFFS_OK expands to 0, erased is bool from Flash_Erase4k, which returns TRUE if ok. + // so this return logic looks wrong. return (SPIFFS_OK == erased); } @@ -151,8 +151,17 @@ int rdv40_spiffs_mount(void) { // uncached version // int ret = SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds, // sizeof(spiffs_fds), 0, 0, 0); cached version, experimental - int ret = SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds, sizeof(spiffs_fds), spiffs_cache_buf, - sizeof(spiffs_cache_buf), 0); + int ret = SPIFFS_mount( + &fs, + &cfg, + spiffs_work_buf, + spiffs_fds, + sizeof(spiffs_fds), + spiffs_cache_buf, + sizeof(spiffs_cache_buf), + 0 + ); + if (ret == SPIFFS_OK) { RDV40_SPIFFS_MOUNT_STATUS = RDV40_SPIFFS_MOUNTED; } @@ -189,33 +198,38 @@ int rdv40_spiffs_check(void) { void write_to_spiffs(const char *filename, uint8_t *src, uint32_t size) { spiffs_file fd = SPIFFS_open(&fs, filename, SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0); - if (SPIFFS_write(&fs, fd, src, size) < 0) - Dbprintf("errno %i\n", SPIFFS_errno(&fs)); + if (SPIFFS_write(&fs, fd, src, size) < 0) { + Dbprintf("wr errno %i\n", SPIFFS_errno(&fs)); + } SPIFFS_close(&fs, fd); } void append_to_spiffs(const char *filename, uint8_t *src, uint32_t size) { spiffs_file fd = SPIFFS_open(&fs, filename, SPIFFS_APPEND | SPIFFS_RDWR, 0); - if (SPIFFS_write(&fs, fd, src, size) < 0) + if (SPIFFS_write(&fs, fd, src, size) < 0) { Dbprintf("errno %i\n", SPIFFS_errno(&fs)); + } SPIFFS_close(&fs, fd); } void read_from_spiffs(const char *filename, uint8_t *dst, uint32_t size) { spiffs_file fd = SPIFFS_open(&fs, filename, SPIFFS_RDWR, 0); - if (SPIFFS_read(&fs, fd, dst, size) < 0) + if (SPIFFS_read(&fs, fd, dst, size) < 0) { Dbprintf("errno %i\n", SPIFFS_errno(&fs)); + } SPIFFS_close(&fs, fd); } static void rename_in_spiffs(const char *old_filename, const char *new_filename) { - if (SPIFFS_rename(&fs, old_filename, new_filename) < 0) + if (SPIFFS_rename(&fs, old_filename, new_filename) < 0) { Dbprintf("errno %i\n", SPIFFS_errno(&fs)); + } } static void remove_from_spiffs(const char *filename) { - if (SPIFFS_remove(&fs, filename) < 0) + if (SPIFFS_remove(&fs, filename) < 0) { Dbprintf("errno %i\n", SPIFFS_errno(&fs)); + } } uint32_t size_in_spiffs(const char *filename) { @@ -233,8 +247,11 @@ static rdv40_spiffs_fsinfo info_of_spiffs(void) { fsinfo.pageSize = LOG_PAGE_SIZE; fsinfo.maxOpenFiles = RDV40_SPIFFS_MAX_FD; fsinfo.maxPathLength = SPIFFS_OBJ_NAME_LEN; - if (SPIFFS_info(&fs, &fsinfo.totalBytes, &fsinfo.usedBytes) < 0) + + if (SPIFFS_info(&fs, &fsinfo.totalBytes, &fsinfo.usedBytes) < 0) { Dbprintf("errno %i\n", SPIFFS_errno(&fs)); + } + fsinfo.freeBytes = fsinfo.totalBytes - fsinfo.usedBytes; // Rounding without float may be improved fsinfo.usedPercent = ((100 * fsinfo.usedBytes) + (fsinfo.totalBytes / 2)) / fsinfo.totalBytes; @@ -245,16 +262,18 @@ static rdv40_spiffs_fsinfo info_of_spiffs(void) { int exists_in_spiffs(const char *filename) { spiffs_stat stat; int rc = SPIFFS_stat(&fs, filename, &stat); - return rc == SPIFFS_OK; + return (rc == SPIFFS_OK); } static RDV40SpiFFSFileType filetype_in_spiffs(const char *filename) { RDV40SpiFFSFileType filetype = RDV40_SPIFFS_FILETYPE_UNKNOWN; char symlinked[SPIFFS_OBJ_NAME_LEN]; sprintf(symlinked, "%s.lnk", filename); + if (exists_in_spiffs(filename)) { filetype = RDV40_SPIFFS_FILETYPE_REAL; } + if (exists_in_spiffs(symlinked)) { if (filetype != RDV40_SPIFFS_FILETYPE_UNKNOWN) { filetype = RDV40_SPIFFS_FILETYPE_BOTH; @@ -262,19 +281,20 @@ static RDV40SpiFFSFileType filetype_in_spiffs(const char *filename) { filetype = RDV40_SPIFFS_FILETYPE_SYMLINK; } } + if (g_dbglevel >= DBG_DEBUG) { switch (filetype) { case RDV40_SPIFFS_FILETYPE_REAL: - Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_REAL"); + Dbprintf("Filetype is " _YELLOW_("RDV40_SPIFFS_FILETYPE_REAL")); break; case RDV40_SPIFFS_FILETYPE_SYMLINK: - Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_SYMLINK"); + Dbprintf("Filetype is " _YELLOW_("RDV40_SPIFFS_FILETYPE_SYMLINK")); break; case RDV40_SPIFFS_FILETYPE_BOTH: - Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_BOTH"); + Dbprintf("Filetype is " _YELLOW_("RDV40_SPIFFS_FILETYPE_BOTH")); break; case RDV40_SPIFFS_FILETYPE_UNKNOWN: - Dbprintf("Filetype is : RDV40_SPIFFS_FILETYPE_UNKNOWN"); + Dbprintf("Filetype is " _YELLOW_("RDV40_SPIFFS_FILETYPE_UNKNOWN")); break; } } @@ -386,10 +406,13 @@ just get back to this state. If not, just don't. // went well, it will return SPIFFS_OK if everything went well, and a report // back the chain a SPI_ERRNO if not. int rdv40_spiffs_lazy_mount_rollback(int changed) { - if (!changed) + if (!changed) { return SPIFFS_OK; - if (rdv40_spiffs_mounted()) + } + + if (rdv40_spiffs_mounted()) { return rdv40_spiffs_unmount(); + } return rdv40_spiffs_mount(); } /////////////////////////////////////////////////////////////////////////////// @@ -433,24 +456,24 @@ int rdv40_spiffs_read(const char *filename, uint8_t *dst, uint32_t size, RDV40Sp // TODO : forbid writing to a filename.lnk which already exists without lnk ! int rdv40_spiffs_rename(char *old_filename, char *new_filename, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( // - rename_in_spiffs((char *)old_filename, (char *)new_filename); // + rename_in_spiffs(old_filename, new_filename); // ) } int rdv40_spiffs_remove(char *filename, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( // - remove_from_spiffs((char *)filename); // + remove_from_spiffs(filename); // ) } int rdv40_spiffs_copy(char *src, char *dst, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( // - copy_in_spiffs((char *)src, (char *)dst); // + copy_in_spiffs(src, dst); // ) } int rdv40_spiffs_stat(char *filename, uint32_t *buf, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( // - *buf = size_in_spiffs((char *)filename); // + *buf = size_in_spiffs(filename); // ) } @@ -489,16 +512,16 @@ int rdv40_spiffs_read_as_symlink(char *filename, uint8_t *dst, uint32_t size, RD sprintf(linkfilename, "%s.lnk", filename); if (g_dbglevel >= DBG_DEBUG) - Dbprintf("Linkk real filename is : " _YELLOW_("%s"), linkfilename); + Dbprintf("Linkk real filename is " _YELLOW_("%s"), linkfilename); read_from_spiffs((char *)linkfilename, (uint8_t *)linkdest, SPIFFS_OBJ_NAME_LEN); if (g_dbglevel >= DBG_DEBUG) - Dbprintf("Symlink destination is : " _YELLOW_("%s"), linkdest); + Dbprintf("Symlink destination is " _YELLOW_("%s"), linkdest); read_from_spiffs((char *)linkdest, (uint8_t *)dst, size); ) - } +} // BEWARE ! This function is DESTRUCTIVE as it will UPDATE an existing symlink // Since it creates a .lnk extension file it may be minor to mistake the order of arguments @@ -534,7 +557,7 @@ int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, R rdv40_spiffs_read((char *)filename, (uint8_t *)dst, size, level); break; case RDV40_SPIFFS_FILETYPE_SYMLINK: - rdv40_spiffs_read_as_symlink((char *)filename, (uint8_t *)dst, size, level); + rdv40_spiffs_read_as_symlink(filename, (uint8_t *)dst, size, level); break; case RDV40_SPIFFS_FILETYPE_BOTH: case RDV40_SPIFFS_FILETYPE_UNKNOWN: @@ -559,18 +582,20 @@ void rdv40_spiffs_safe_print_fsinfo(void) { rdv40_spiffs_fsinfo fsinfo; rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE); - Dbprintf(" Logical block size......... " _YELLOW_("%d")" bytes", fsinfo.blockSize); - Dbprintf(" Logical page size.......... " _YELLOW_("%d")" bytes", fsinfo.pageSize); - Dbprintf(" Max open files............. " _YELLOW_("%d")" file descriptors", fsinfo.maxOpenFiles); - Dbprintf(" Max path length............ " _YELLOW_("%d")" chars", fsinfo.maxPathLength); + Dbprintf(" Logical block size... " _YELLOW_("%d")" bytes", fsinfo.blockSize); + Dbprintf(" Logical page size.... " _YELLOW_("%d")" bytes", fsinfo.pageSize); + Dbprintf(" Max open files....... " _YELLOW_("%d")" file descriptors", fsinfo.maxOpenFiles); + Dbprintf(" Max path length...... " _YELLOW_("%d")" chars", fsinfo.maxPathLength); DbpString(""); Dbprintf(" Filesystem size used available use% mounted"); + DbpString("------------------------------------------------------------------"); Dbprintf(" spiffs %6d B %6d B %6d B " _YELLOW_("%2d%")" /" , fsinfo.totalBytes , fsinfo.usedBytes , fsinfo.freeBytes , fsinfo.usedPercent ); + DbpString(""); } // this function is safe and WILL rollback since it is only a PRINTING function, diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h index 01bf113e8..c540a023f 100644 --- a/armsrc/spiffs.h +++ b/armsrc/spiffs.h @@ -24,7 +24,11 @@ extern "C" { #include "spiffs_config.h" -typedef enum spiffs_safety_level { RDV40_SPIFFS_SAFETY_NORMAL, RDV40_SPIFFS_SAFETY_LAZY, RDV40_SPIFFS_SAFETY_SAFE } RDV40SpiFFSSafetyLevel; +typedef enum spiffs_safety_level { + RDV40_SPIFFS_SAFETY_NORMAL, + RDV40_SPIFFS_SAFETY_LAZY, + RDV40_SPIFFS_SAFETY_SAFE +} RDV40SpiFFSSafetyLevel; typedef enum spiffs_file_type { RDV40_SPIFFS_FILETYPE_REAL, @@ -198,16 +202,16 @@ typedef void (*spiffs_file_callback)(struct spiffs_t *fs, spiffs_fileop_type op, #ifndef SPIFFS_DBG #define SPIFFS_DBG(...) \ - printf(__VA_ARGS__) + Dbprintf(__VA_ARGS__) #endif #ifndef SPIFFS_GC_DBG -#define SPIFFS_GC_DBG(...) printf(__VA_ARGS__) +#define SPIFFS_GC_DBG(...) Dbprintf(__VA_ARGS__) #endif #ifndef SPIFFS_CACHE_DBG -#define SPIFFS_CACHE_DBG(...) printf(__VA_ARGS__) +#define SPIFFS_CACHE_DBG(...) Dbprintf(__VA_ARGS__) #endif #ifndef SPIFFS_CHECK_DBG -#define SPIFFS_CHECK_DBG(...) printf(__VA_ARGS__) +#define SPIFFS_CHECK_DBG(...) Dbprintf(__VA_ARGS__) #endif /* Any write to the filehandle is appended to end of the file */ diff --git a/armsrc/spiffs_config.h b/armsrc/spiffs_config.h index eb699d976..f1d54a471 100644 --- a/armsrc/spiffs_config.h +++ b/armsrc/spiffs_config.h @@ -136,7 +136,7 @@ typedef uint8_t u8_t; // Define maximum number of gc runs to perform to reach desired free pages. #ifndef SPIFFS_GC_MAX_RUNS -#define SPIFFS_GC_MAX_RUNS 5 +#define SPIFFS_GC_MAX_RUNS 10 #endif // Enable/disable statistics on gc. Debug/test purpose only. @@ -236,7 +236,7 @@ typedef uint8_t u8_t; // Instead of giving parameters in config struct, singleton build must // give parameters in defines below. #ifndef SPIFFS_CFG_PHYS_SZ -#define SPIFFS_CFG_PHYS_SZ(ignore) (1024*128) +#define SPIFFS_CFG_PHYS_SZ(ignore) (1024*192) #endif #ifndef SPIFFS_CFG_PHYS_ERASE_SZ #define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (4*1024) From bebfe0ad2f1b37fd90102811191df33049f09614 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 28 Aug 2022 12:23:26 +0200 Subject: [PATCH 217/759] allow data load to load binary files as raw signal from device (@mwalker33) --- client/src/cmddata.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 5b5055dd9..02138b9ca 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -2032,7 +2032,8 @@ static int CmdLoad(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_str1("f", "file", "", "file to load"), - arg_lit0("n", "no-fix", "Load data from wile without any transformations"), + arg_lit0("b", "bin", "binary file"), + arg_lit0("n", "no-fix", "Load data from file without any transformations"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -2040,9 +2041,8 @@ static int CmdLoad(const char *Cmd) { int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); - - bool nofix = arg_get_lit(ctx, 2); - + bool is_bin = arg_get_lit(ctx, 2); + bool nofix = arg_get_lit(ctx, 3); CLIParserFree(ctx); char *path = NULL; @@ -2052,8 +2052,13 @@ static int CmdLoad(const char *Cmd) { } } - FILE *f = fopen(path, "r"); - if (!f) { + FILE *f; + if (is_bin) + f = fopen(path, "rb"); + else + f = fopen(path, "r"); + + if (f == NULL) { PrintAndLogEx(WARNING, "couldn't open '%s'", path); free(path); return PM3_EFILE; @@ -2061,13 +2066,25 @@ static int CmdLoad(const char *Cmd) { free(path); g_GraphTraceLen = 0; - char line[80]; - while (fgets(line, sizeof(line), f)) { - g_GraphBuffer[g_GraphTraceLen] = atoi(line); - g_GraphTraceLen++; - if (g_GraphTraceLen >= MAX_GRAPH_TRACE_LEN) - break; + if (is_bin) { + uint8_t val[2]; + while (fread(val, 1, 1, f)) { + g_GraphBuffer[g_GraphTraceLen] = val[0] - 127; + g_GraphTraceLen++; + + if (g_GraphTraceLen >= MAX_GRAPH_TRACE_LEN) + break; + } + } else { + char line[80]; + while (fgets(line, sizeof(line), f)) { + g_GraphBuffer[g_GraphTraceLen] = atoi(line); + g_GraphTraceLen++; + + if (g_GraphTraceLen >= MAX_GRAPH_TRACE_LEN) + break; + } } fclose(f); From 07c687186184aebe444e3c768defd7d4a2f16f44 Mon Sep 17 00:00:00 2001 From: "Rick Farina (Zero_Chaos)" Date: Mon, 29 Aug 2022 21:04:03 -0400 Subject: [PATCH 218/759] do not use LD if you aren't using ld All the uses of LD actually wanted g++, so just use CXX and remove an unused LD define Closes: https://github.com/pentoo/pentoo-overlay/issues/1259 Fixes: https://github.com/RfidResearchGroup/proxmark3/pull/1758 --- Makefile.defs | 1 - Makefile.host | 4 ++-- client/Makefile | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 397e25561..bd5898477 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -40,7 +40,6 @@ TARFLAGS += -C .. -f CROSS ?= arm-none-eabi- CC ?= gcc CXX ?= g++ -LD = g++ SH = sh BASH = bash PERL = perl diff --git a/Makefile.host b/Makefile.host index a2a9e829a..8ca8bc50d 100644 --- a/Makefile.host +++ b/Makefile.host @@ -86,8 +86,8 @@ $(BINDIR)/$(LIB_A): $(MYOBJS) $(MYCXXOBJS) $(Q)$(RANLIB) $@ $(BINDIR)/% : $(OBJDIR)/%.o $(MYOBJS) $(MYCXXOBJS) $(MYLIBS) - $(info [=] LD $(notdir $@)) - $(Q)$(LD) $(LDFLAGS) $(MYOBJS) $(MYCXXOBJS) $< -o $@ $(MYLIBS) $(MYLDLIBS) + $(info [=] CXX $(notdir $@)) + $(Q)$(CXX) $(LDFLAGS) $(MYOBJS) $(MYCXXOBJS) $< -o $@ $(MYLIBS) $(MYLDLIBS) %.o: %.c $(OBJDIR)/%.o : %.c $(OBJDIR)/%.d | $(OBJDIR) diff --git a/client/Makefile b/client/Makefile index 6817380bb..500e820f0 100644 --- a/client/Makefile +++ b/client/Makefile @@ -758,9 +758,9 @@ all-static: LDLIBS:=-static $(LDLIBS) all-static: $(BINS) proxmark3: $(OBJS) $(STATICLIBS) lualibs/pm3_cmd.lua lualibs/mfc_default_keys.lua - $(info [=] LD $@) -# $(Q)$(LD) $(PM3LDFLAGS) $(OBJS) $(STATICLIBS) $(LDLIBS) -o $@ - $(Q)$(LD) $(PM3CFLAGS) $(PM3LDFLAGS) $(OBJS) $(STATICLIBS) $(LDLIBS) -o $@ + $(info [=] CXX $@) +# $(Q)$(CXX) $(PM3LDFLAGS) $(OBJS) $(STATICLIBS) $(LDLIBS) -o $@ + $(Q)$(CXX) $(PM3CFLAGS) $(PM3LDFLAGS) $(OBJS) $(STATICLIBS) $(LDLIBS) -o $@ src/proxgui.cpp: src/ui/ui_overlays.h src/ui/ui_image.h From d8c18e6db85c9bc46fffa02f8c5eee5fcb288589 Mon Sep 17 00:00:00 2001 From: mwalker33 <51802811+mwalker33@users.noreply.github.com> Date: Wed, 31 Aug 2022 18:51:39 +1000 Subject: [PATCH 219/759] Prep spiffs for bigger data files - added spiffs check after flase wipe to force it to update its status - added spiffs write and append to write in 8192 byte chunks to allow spiffs space to be freed in time. - fixed spiffs dump to correctly handle issues if it could not allocate bugbuff space. --- armsrc/appmain.c | 30 ++++++++++++++++++------------ armsrc/flashmem.c | 4 ++++ armsrc/spiffs.c | 30 ++++++++++++++++++++++++++++-- client/src/comms.c | 2 ++ 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 330bf2c48..0f474933e 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2166,20 +2166,26 @@ static void PacketReceived(PacketCommandNG *packet) { uint32_t size = packet->oldarg[1]; uint8_t *buff = BigBuf_malloc(size); - rdv40_spiffs_read_as_filetype((char *)filename, (uint8_t *)buff, size, RDV40_SPIFFS_SAFETY_SAFE); + if (buff == NULL) { + if (g_dbglevel >= DBG_DEBUG) Dbprintf ("Could not allocate buffer"); + // Trigger a finish downloading signal with an PM3_EMALLOC + reply_ng(CMD_SPIFFS_DOWNLOAD, PM3_EMALLOC, NULL, 0); + } else { + rdv40_spiffs_read_as_filetype((char *)filename, (uint8_t *)buff, size, RDV40_SPIFFS_SAFETY_SAFE); + // arg0 = filename + // arg1 = size + // arg2 = RFU - // arg0 = filename - // arg1 = size - // arg2 = RFU - - for (size_t i = 0; i < size; i += PM3_CMD_DATA_SIZE) { - size_t len = MIN((size - i), PM3_CMD_DATA_SIZE); - int result = reply_old(CMD_SPIFFS_DOWNLOADED, i, len, 0, buff + i, len); - if (result != PM3_SUCCESS) - Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", i, i + len, len, result); + for (size_t i = 0; i < size; i += PM3_CMD_DATA_SIZE) { + size_t len = MIN((size - i), PM3_CMD_DATA_SIZE); + int result = reply_old(CMD_SPIFFS_DOWNLOADED, i, len, 0, buff + i, len); + if (result != PM3_SUCCESS) + Dbprintf("transfer to client failed :: | bytes between %d - %d (%d) | result: %d", i, i + len, len, result); + } + // Trigger a finish downloading signal with an ACK frame + reply_ng(CMD_SPIFFS_DOWNLOAD, PM3_SUCCESS, NULL, 0); + BigBuf_free (); } - // Trigger a finish downloading signal with an ACK frame - reply_ng(CMD_SPIFFS_DOWNLOAD, PM3_SUCCESS, NULL, 0); LED_B_OFF(); break; } diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index fb1f74140..fd5a95c97 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -22,6 +22,7 @@ #include "ticks.h" #include "dbprint.h" #include "string.h" +#include "spiffs.h" /* here: use NCPS2 @ PA10: */ #define SPI_CSR_NUM 2 @@ -449,6 +450,9 @@ bool Flash_WipeMemoryPage(uint8_t page) { Flash_CheckBusy(BUSY_TIMEOUT); FlashStop(); + + // let spiffs check and update its info post flash erase + rdv40_spiffs_check (); return true; } // Wipes flash memory completely, fills with 0xFF diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 027563729..aa7275cce 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -433,15 +433,41 @@ int rdv40_spiffs_lazy_mount_rollback(int changed) { // statement or some function taking function parameters // TODO : forbid writing to a filename which already exists as lnk ! // TODO : forbid writing to a filename.lnk which already exists without lnk ! +// Note: Writing in 8192 byte chucks helps to ensure "free space" has been erased by GC (Garbage collection) int rdv40_spiffs_write(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( - write_to_spiffs(filename, src, size); + uint16_t idx; + if (size <= 8192) { + // write small file + write_to_spiffs(filename, src, size); + size = 0; + } else { // + // write first 8192 bytes + // need to write the first chuck of data, then append + write_to_spiffs(filename, src, 8192); + } + // append remaing 8192 byte chuncks + for (idx = 1; idx < (size / 8192); idx++) { + append_to_spiffs(filename, &src[8192 * idx], 8192); + } + // append remaing bytes + if (((int64_t)size - (8192 * idx)) > 0) { + append_to_spiffs(filename, &src[8192 * idx], size - (8192 * idx)); + } ) } int rdv40_spiffs_append(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( - append_to_spiffs(filename, src, size); + uint16_t idx; + // Append any 8192 byte chunks + for (idx = 0; idx < (size/8192); idx++) { + append_to_spiffs(filename, &src[8192 * idx], 8192); + } + // Append remain bytes + if (((int64_t)size - (8192 * idx)) > 0) { + append_to_spiffs(filename, &src[8192 * idx], size - (8192 * idx)); + } ) } diff --git a/client/src/comms.c b/client/src/comms.c index 2b521d2d7..a8ed8be4c 100644 --- a/client/src/comms.c +++ b/client/src/comms.c @@ -856,6 +856,8 @@ static bool dl_it(uint8_t *dest, uint32_t bytes, PacketResponseNG *response, siz if (response->cmd == CMD_ACK) return true; + if (response->cmd == CMD_SPIFFS_DOWNLOAD && response->status == PM3_EMALLOC) + return false; // Spiffs // fpgamem-plot download is converted to NG, if (response->cmd == CMD_SPIFFS_DOWNLOAD || response->cmd == CMD_FPGAMEM_DOWNLOAD) return true; From 96876c01113455bcfd014fb3af9c653ae1a713df Mon Sep 17 00:00:00 2001 From: mwalker33 <51802811+mwalker33@users.noreply.github.com> Date: Wed, 31 Aug 2022 19:10:15 +1000 Subject: [PATCH 220/759] Update spiffs.c patch type size comparison --- armsrc/spiffs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index aa7275cce..665fb2cf8 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -436,7 +436,7 @@ int rdv40_spiffs_lazy_mount_rollback(int changed) { // Note: Writing in 8192 byte chucks helps to ensure "free space" has been erased by GC (Garbage collection) int rdv40_spiffs_write(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( - uint16_t idx; + uint32_t idx; if (size <= 8192) { // write small file write_to_spiffs(filename, src, size); @@ -459,7 +459,7 @@ int rdv40_spiffs_write(const char *filename, uint8_t *src, uint32_t size, RDV40S int rdv40_spiffs_append(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( - uint16_t idx; + uint32_t idx; // Append any 8192 byte chunks for (idx = 0; idx < (size/8192); idx++) { append_to_spiffs(filename, &src[8192 * idx], 8192); From eef1ce9c332dcbcd9ff735dcfff78d58afa38665 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Fri, 26 Aug 2022 09:29:15 +0200 Subject: [PATCH 221/759] Enhance simulation of ISO15693 devices. This adds the following things: - support for reading multiple blocks, - configurable block size, - ability to provide a memory image. --- armsrc/appmain.c | 5 ++- armsrc/iso15693.c | 87 +++++++++++++++++++++++++++++++++++--------- armsrc/iso15693.h | 2 +- client/src/cmdhf15.c | 37 ++++++++++++++++++- include/pm3_cmd.h | 4 ++ 5 files changed, 113 insertions(+), 22 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 330bf2c48..0eccd418a 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1259,9 +1259,12 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_HF_ISO15693_SIMULATE: { struct p { uint8_t uid[8]; + uint8_t block_size; + int data_length; + uint8_t data[PM3_CMD_BLOB_SIZE]; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - SimTagIso15693(payload->uid); + SimTagIso15693(payload->uid, payload->block_size, payload->data_length, payload->data); break; } case CMD_HF_ISO15693_CSETUID: { diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index d4a7be85f..f754d3a3c 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -2100,7 +2100,7 @@ void Iso15693InitTag(void) { // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands // all demodulation performed in arm rather than host. - greg -void SimTagIso15693(uint8_t *uid) { +void SimTagIso15693(uint8_t *uid, uint8_t block_size, int image_length, uint8_t *image) { // free eventually allocated BigBuf memory BigBuf_free_keep_EM(); @@ -2109,12 +2109,14 @@ void SimTagIso15693(uint8_t *uid) { LED_A_ON(); - Dbprintf("ISO-15963 Simulating uid: %02X%02X%02X%02X%02X%02X%02X%02X", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7]); + if (image_length == -1) { + Dbprintf("ISO-15963 Simulating uid: %02X%02X%02X%02X%02X%02X%02X%02X block size %d with no image", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7], block_size); + } else { + Dbprintf("ISO-15963 Simulating uid: %02X%02X%02X%02X%02X%02X%02X%02X block size %d with 0x%X bytes image", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7], block_size, image_length); + } LED_C_ON(); - - enum { NO_FIELD, IDLE, ACTIVATED, SELECTED, HALTED } chip_state = NO_FIELD; bool button_pressed = false; @@ -2207,8 +2209,14 @@ void SimTagIso15693(uint8_t *uid) { resp_sysinfo[10] = 0; // DSFID resp_sysinfo[11] = 0; // AFI - resp_sysinfo[12] = 0x1B; // Memory size. - resp_sysinfo[13] = 0x03; // Memory size. + // Memory size. + if (image_length == -1) { + // use sensible default value if no image is provided + resp_sysinfo[12] = 0x1F; + } else { + resp_sysinfo[12] = image_length / block_size; + } + resp_sysinfo[13] = block_size - 1; // Memory size. resp_sysinfo[14] = 0x01; // IC reference. // CRC @@ -2221,28 +2229,71 @@ void SimTagIso15693(uint8_t *uid) { LogTrace_ISO15693(resp_sysinfo, CMD_SYSINFO_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false); } - // READ_BLOCK - if ((cmd[1] == ISO15693_READBLOCK)) { + // READ_BLOCK and READ_MULTI_BLOCK + if ((cmd[1] == ISO15693_READBLOCK) || (cmd[1] == ISO15693_READ_MULTI_BLOCK)) { bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH); + bool option = cmd[0] & ISO15_REQ_OPTION; uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; - // Build READ_BLOCK response - uint8_t resp_readblock[CMD_READBLOCK_RESP] = {0}; + uint8_t block_idx = 0; + uint8_t block_count = 1; + if (cmd[1] == ISO15693_READBLOCK) { + if (cmd_len == 13) { + // addressed mode + block_idx= cmd[10]; + } else if (cmd_len == 5) { + // non-addressed mode + block_idx = cmd[2]; + } + } else if (cmd[1] == ISO15693_READ_MULTI_BLOCK) { + if (cmd_len == 14) { + // addressed mode + block_idx= cmd[10]; + block_count= cmd[11] + 1; + } else if (cmd_len == 6) { + // non-addressed mode + block_idx = cmd[2]; + block_count = cmd[3] + 1; + } + } - resp_readblock[0] = 0; // Response flags. - resp_readblock[1] = 0; // Block data. - resp_readblock[2] = 0; // Block data. - resp_readblock[3] = 0; // Block data. - resp_readblock[4] = 0; // Block data. + // Build READ_(MULTI_)BLOCK response + int response_length = 3 + block_size * block_count; + int security_offset = 0; + if (option) { + response_length += block_count; + security_offset = 1; + } + uint8_t resp_readblock[response_length]; + for (int i = 0; i < response_length; i++) { + resp_readblock[i] = 0; + } + + resp_readblock[0] = 0; // Response flags + for (int j = 0; j < block_count; j++) { + // where to put the data of the current block + int work_offset = 1 + j * (block_size + security_offset); + if (option) { + resp_readblock[work_offset] = 0; // Security status + } + for (int i = 0; i < block_size; i++) { + // Block data + if (block_size * (block_idx + j + 1) <= image_length) { + resp_readblock[work_offset + security_offset + i] = image[block_size * (block_idx + j) + i]; + } else { + resp_readblock[work_offset + security_offset + i] = 0; + } + } + } // CRC - AddCrc15(resp_readblock, 5); - CodeIso15693AsTag(resp_readblock, CMD_READBLOCK_RESP); + AddCrc15(resp_readblock, response_length - 2); + CodeIso15693AsTag(resp_readblock, response_length); tosend_t *ts = get_tosend(); TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow); - LogTrace_ISO15693(resp_readblock, CMD_READBLOCK_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false); + LogTrace_ISO15693(resp_readblock, response_length, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false); } } diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index 277074189..3fd40e49a 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -46,7 +46,7 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo //void RecordRawAdcSamplesIso15693(void); void AcquireRawAdcSamplesIso15693(void); void ReaderIso15693(iso15_card_select_t *p_card); // ISO15693 reader -void SimTagIso15693(uint8_t *uid); // simulate an ISO15693 tag +void SimTagIso15693(uint8_t *uid, uint8_t block_size, int payload_length, uint8_t *payload); // simulate an ISO15693 tag void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index aeda14380..c5a5677f2 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1000,23 +1000,56 @@ static int CmdHF15Sim(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_str1("u", "uid", "<8b hex>", "UID eg E011223344556677"), + arg_int0("b", "blocksize", "", "block size, defaults to 4"), + arg_str0("i", "image", "", "Memory image to load, defaults to zeros"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); struct { uint8_t uid[8]; + uint8_t block_size; + int image_length; + uint8_t image[PM3_CMD_BLOB_SIZE]; } PACKED payload; int uidlen = 0; CLIGetHexWithReturn(ctx, 1, payload.uid, &uidlen); - CLIParserFree(ctx); - if (uidlen != 8) { PrintAndLogEx(WARNING, "UID must include 16 HEX symbols"); return PM3_EINVARG; } + payload.block_size = arg_get_int_def(ctx, 2, 4); + + int fnlen = 0; + char filename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + CLIParserFree(ctx); + + if (fnlen > 0) { + uint8_t *image = NULL; + size_t image_len = 0; + if (loadFile_safe(filename, "", (void **)&image, &image_len) != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Could not open file " _YELLOW_("%s"), filename); + return PM3_EIO; + } + + if (image_len > PM3_CMD_BLOB_SIZE) { + PrintAndLogEx(WARNING, "Memory image to large for us"); + return PM3_EINVARG; + } + if (image_len % payload.block_size != 0) { + PrintAndLogEx(WARNING, "Memory image size not a multiple of the block size"); + return PM3_EINVARG; + } + payload.image_length = image_len; + memcpy(payload.image, image, image_len); + free(image); + } else { + payload.image_length = -1; + } + PrintAndLogEx(SUCCESS, "Starting simulating UID " _YELLOW_("%s"), iso15693_sprintUID(NULL, payload.uid)); PrintAndLogEx(INFO, "press " _YELLOW_("`Pm3 button`") " to cancel"); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 69d9fed5b..f2a8bc56a 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -27,6 +27,10 @@ #define PM3_CMD_DATA_SIZE 512 #define PM3_CMD_DATA_SIZE_MIX ( PM3_CMD_DATA_SIZE - 3 * sizeof(uint64_t) ) +/* To be used for commands with a big blob of data along with some other data (for which 32 bytes + * is put aside, so if there is more of it this is unsuitable). + */ +#define PM3_CMD_BLOB_SIZE ( PM3_CMD_DATA_SIZE - 32 ) typedef struct { uint64_t cmd; From 62b577d170c59e43ba416742023697545332b77c Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Wed, 31 Aug 2022 12:23:05 +0200 Subject: [PATCH 222/759] Remove unused definition. --- armsrc/iso15693.c | 1 - 1 file changed, 1 deletion(-) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index f754d3a3c..d894e3c1f 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -116,7 +116,6 @@ #define CMD_READ_RESP 13 #define CMD_INV_RESP 12 #define CMD_SYSINFO_RESP 17 -#define CMD_READBLOCK_RESP 7 //#define Crc(data, len) Crc(CRC_15693, (data), (len)) #define CheckCrc15(data, len) check_crc(CRC_15693, (data), (len)) From f3a41fdc4e91013ba3b5f8811d4a2a49c2293295 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Wed, 31 Aug 2022 12:40:25 +0200 Subject: [PATCH 223/759] Added Changelog entries. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93c557838..7c09c300b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -87,6 +87,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added new standalone mode `lf_em4100rsww` (@zabszk) - Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz) - Added `script run hf_mf_hid_sim.lua` (@micsen) + - Added `hf 15 sim --blocksize` - configure block size for simulation (@markus-oehme-pg40) + - Added `hf 15 sim --image` - specify memory image for simulation (@markus-oehme-pg40) ## [Frostbit.4.14831][2022-01-11] From 9406ef9fd3d5997b3c038d3cd0451b626bd49594 Mon Sep 17 00:00:00 2001 From: mwalker33 <51802811+mwalker33@users.noreply.github.com> Date: Thu, 1 Sep 2022 08:15:30 +1000 Subject: [PATCH 224/759] spiffs prep added define for chuck size update changelog --- CHANGELOG.md | 2 ++ armsrc/spiffs.c | 28 ++++++++++++++-------------- armsrc/spiffs.h | 2 ++ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93c557838..bbb1b0049 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 spiffs write/apped to send in 8192 chucks to ensure its eraised (@mwalker) + - Fixed spiffs dump to ensure to fails correctly if no big_buff was allocated (@mwalker) - Change Client Makefile to respect global flags (@blshkv) - Change Makefile, honors global CC values (@blshkv) - Fixed bad memory handling in MifareSim device side (@iceman1001) diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 665fb2cf8..ef7ca3174 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -433,26 +433,26 @@ int rdv40_spiffs_lazy_mount_rollback(int changed) { // statement or some function taking function parameters // TODO : forbid writing to a filename which already exists as lnk ! // TODO : forbid writing to a filename.lnk which already exists without lnk ! -// Note: Writing in 8192 byte chucks helps to ensure "free space" has been erased by GC (Garbage collection) +// Note: Writing in SPIFFS_WRITE_CHUNK_SIZE (8192) byte chucks helps to ensure "free space" has been erased by GC (Garbage collection) int rdv40_spiffs_write(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( uint32_t idx; - if (size <= 8192) { + if (size <= SPIFFS_WRITE_CHUNK_SIZE) { // write small file write_to_spiffs(filename, src, size); size = 0; } else { // - // write first 8192 bytes + // write first SPIFFS_WRITE_CHUNK_SIZE bytes // need to write the first chuck of data, then append - write_to_spiffs(filename, src, 8192); + write_to_spiffs(filename, src, SPIFFS_WRITE_CHUNK_SIZE); } - // append remaing 8192 byte chuncks - for (idx = 1; idx < (size / 8192); idx++) { - append_to_spiffs(filename, &src[8192 * idx], 8192); + // append remaing SPIFFS_WRITE_CHUNK_SIZE byte chuncks + for (idx = 1; idx < (size / SPIFFS_WRITE_CHUNK_SIZE); idx++) { + append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], SPIFFS_WRITE_CHUNK_SIZE); } // append remaing bytes - if (((int64_t)size - (8192 * idx)) > 0) { - append_to_spiffs(filename, &src[8192 * idx], size - (8192 * idx)); + if (((int64_t)size - (SPIFFS_WRITE_CHUNK_SIZE * idx)) > 0) { + append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], size - (SPIFFS_WRITE_CHUNK_SIZE * idx)); } ) } @@ -460,13 +460,13 @@ int rdv40_spiffs_write(const char *filename, uint8_t *src, uint32_t size, RDV40S int rdv40_spiffs_append(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( uint32_t idx; - // Append any 8192 byte chunks - for (idx = 0; idx < (size/8192); idx++) { - append_to_spiffs(filename, &src[8192 * idx], 8192); + // Append any SPIFFS_WRITE_CHUNK_SIZE byte chunks + for (idx = 0; idx < (size/SPIFFS_WRITE_CHUNK_SIZE); idx++) { + append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], SPIFFS_WRITE_CHUNK_SIZE); } // Append remain bytes - if (((int64_t)size - (8192 * idx)) > 0) { - append_to_spiffs(filename, &src[8192 * idx], size - (8192 * idx)); + if (((int64_t)size - (SPIFFS_WRITE_CHUNK_SIZE * idx)) > 0) { + append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], size - (SPIFFS_WRITE_CHUNK_SIZE * idx)); } ) } diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h index c540a023f..6af4fbac8 100644 --- a/armsrc/spiffs.h +++ b/armsrc/spiffs.h @@ -129,6 +129,8 @@ void rdv40_spiffs_safe_wipe(void); #define SPIFFS_ERR_TEST -10100 +// Amount of data to write/append to a file in one go. +#define SPIFFS_WRITE_CHUNK_SIZE 8192 // spiffs file descriptor index type. must be signed typedef s16_t spiffs_file; From 03fa7573952e4177c425fe46ba772194365764d7 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Thu, 1 Sep 2022 16:12:22 +0200 Subject: [PATCH 225/759] Implement `hf 15 eload` command to move image dump to emulator. --- armsrc/appmain.c | 14 ++++++ armsrc/iso15693.c | 14 ++++++ armsrc/iso15693.h | 2 + client/src/cmdhf15.c | 111 +++++++++++++++++++++++++++++++++++++++++++ include/pm3_cmd.h | 2 + 5 files changed, 143 insertions(+) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 0eccd418a..69961cc7d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1256,6 +1256,20 @@ static void PacketReceived(PacketCommandNG *packet) { ReaderIso15693(NULL); break; } + case CMD_HF_ISO15693_EML_CLEAR: { + EmlClearIso15693(); + break; + } + case CMD_HF_ISO15693_EML_SETMEM: { + struct p { + uint32_t offset; + uint8_t count; + uint8_t data[]; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + EmlSetMemIso15693(payload->count, payload->data, payload->offset); + break; + } case CMD_HF_ISO15693_SIMULATE: { struct p { uint8_t uid[8]; diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index d894e3c1f..92c6f2e4e 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -2097,6 +2097,20 @@ void Iso15693InitTag(void) { StartCountSspClk(); } + +void EmlClearIso15693(void) { + // Resetting the bitstream also frees the BigBuf memory, so we do this here to prevent + // an inconvenient reset in the future by Iso15693InitTag + FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15); + BigBuf_Clear_EM(); + reply_ng(CMD_HF_ISO15693_EML_CLEAR, PM3_SUCCESS, NULL, 0); +} + +void EmlSetMemIso15693(uint8_t count, uint8_t *data, uint32_t offset) { + uint8_t *emCARD = BigBuf_get_EM_addr(); + memcpy(emCARD + offset, data, count); +} + // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands // all demodulation performed in arm rather than host. - greg void SimTagIso15693(uint8_t *uid, uint8_t block_size, int image_length, uint8_t *image) { diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index 3fd40e49a..4f1800dc7 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -46,6 +46,8 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo //void RecordRawAdcSamplesIso15693(void); void AcquireRawAdcSamplesIso15693(void); void ReaderIso15693(iso15_card_select_t *p_card); // ISO15693 reader +void EmlClearIso15693(void); +void EmlSetMemIso15693(uint8_t count, uint8_t *data, uint32_t offset); void SimTagIso15693(uint8_t *uid, uint8_t block_size, int payload_length, uint8_t *payload); // simulate an ISO15693 tag void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index c5a5677f2..417ad1fe5 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -47,6 +47,7 @@ #define Logic0 Iso15693Logic0 #define Logic1 Iso15693Logic1 #define FrameEOF Iso15693FrameEOF +#define CARD_MEMORY_SIZE 4096 #ifndef Crc15 # define Crc15(data, len) Crc16ex(CRC_15693, (data), (len)) @@ -988,6 +989,115 @@ static int CmdHF15Reader(const char *Cmd) { return PM3_SUCCESS; } +static int hf15EmlClear(void) { + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_EML_CLEAR, NULL, 0); + PacketResponseNG resp; + WaitForResponse(CMD_HF_ISO15693_EML_CLEAR, &resp); + return PM3_SUCCESS; +} + +static int hf15EmlSetMem(uint8_t *data, uint8_t count, size_t offset) { + struct p { + uint32_t offset; + uint8_t count; + uint8_t data[]; + } PACKED; + + size_t size = count; + if (size > (PM3_CMD_DATA_SIZE - sizeof(struct p))) { + return PM3_ESOFT; + } + + size_t paylen = sizeof(struct p) + size; + struct p *payload = calloc(1, paylen); + + payload->offset = offset; + payload->count = count; + memcpy(payload->data, data, size); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_EML_SETMEM, (uint8_t *)payload, paylen); + free(payload); + return PM3_SUCCESS; +} + +static int CmdHF15ELoad(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 eload", + "Load memory image from file to be used with 'hf 15 sim'", + "hf 15 eload -f hf-15-01020304.bin\n" + ); + void *argtable[] = { + arg_param_begin, + arg_str1("f", "file", "", "filename of image"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int fnlen = 0; + char filename[FILE_PATH_SIZE]; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + CLIParserFree(ctx); + + uint8_t *data = NULL; + size_t bytes_read = 0; + int res = loadFile_safe(filename, ".bin", (void **)&data, &bytes_read); + if (res != PM3_SUCCESS) { + return res; + } + + if (bytes_read > CARD_MEMORY_SIZE) { + PrintAndLogEx(FAILED, "Memory image too large."); + free(data); + return PM3_EINVARG; + } + if (bytes_read == 0) { + PrintAndLogEx(FAILED, "Memory image empty."); + free(data); + return PM3_EINVARG; + } + + PrintAndLogEx(INFO, "Clearing emulator memory"); + fflush(stdout); + hf15EmlClear(); + + PrintAndLogEx(INFO, "Uploading to emulator memory"); + PrintAndLogEx(INFO, "." NOLF); + + // fast push mode + g_conn.block_after_ACK = true; + + int chuncksize = 64; + size_t offset = 0; + + while (bytes_read > 0) { + if (bytes_read <= chuncksize) { + // Disable fast mode on last packet + g_conn.block_after_ACK = false; + } + + int tosend = MIN(chuncksize, bytes_read); + if (hf15EmlSetMem(data + offset, tosend, offset) != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Can't set emulator memory at offest: 0x%x", offset); + free(data); + return PM3_ESOFT; + } + PrintAndLogEx(NORMAL, "." NOLF); + fflush(stdout); + + offset += tosend; + bytes_read -= tosend; + } + free(data); + PrintAndLogEx(NORMAL, ""); + + PrintAndLogEx(HINT, "You are ready to simulate. See " _YELLOW_("`hf 15 sim -h`")); + PrintAndLogEx(INFO, "Done!"); + return PM3_SUCCESS; +} + // Simulation is still not working very good // helptext static int CmdHF15Sim(const char *Cmd) { @@ -2208,6 +2318,7 @@ static command_t CommandTable[] = { {"reader", CmdHF15Reader, IfPm3Iso15693, "Act like an ISO-15693 reader"}, {"restore", CmdHF15Restore, IfPm3Iso15693, "Restore from file to all memory pages of an ISO-15693 tag"}, {"samples", CmdHF15Samples, IfPm3Iso15693, "Acquire samples as reader (enables carrier, sends inquiry)"}, + {"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file to be used by 'sim' command"}, {"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"}, {"slixdisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"}, {"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"}, diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index f2a8bc56a..f2e9f0607 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -527,6 +527,8 @@ typedef struct { #define CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY 0x0317 #define CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI 0x0318 #define CMD_HF_TEXKOM_SIMULATE 0x0320 +#define CMD_HF_ISO15693_EML_CLEAR 0x0330 +#define CMD_HF_ISO15693_EML_SETMEM 0x0331 #define CMD_LF_SNIFF_RAW_ADC 0x0360 From d79bd5b6b869831365134b82d3de54b86ae901a7 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Thu, 1 Sep 2022 18:46:20 +0200 Subject: [PATCH 226/759] Switch `hf 15 sim` to use image in emulator memory. --- armsrc/appmain.c | 4 +--- armsrc/iso15693.c | 23 +++++++---------------- armsrc/iso15693.h | 2 +- client/src/cmdhf15.c | 29 ----------------------------- include/pm3_cmd.h | 4 ---- 5 files changed, 9 insertions(+), 53 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 69961cc7d..d2ead4fc3 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1274,11 +1274,9 @@ static void PacketReceived(PacketCommandNG *packet) { struct p { uint8_t uid[8]; uint8_t block_size; - int data_length; - uint8_t data[PM3_CMD_BLOB_SIZE]; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - SimTagIso15693(payload->uid, payload->block_size, payload->data_length, payload->data); + SimTagIso15693(payload->uid, payload->block_size); break; } case CMD_HF_ISO15693_CSETUID: { diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 92c6f2e4e..7e4c5c4f3 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -2113,7 +2113,7 @@ void EmlSetMemIso15693(uint8_t count, uint8_t *data, uint32_t offset) { // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands // all demodulation performed in arm rather than host. - greg -void SimTagIso15693(uint8_t *uid, uint8_t block_size, int image_length, uint8_t *image) { +void SimTagIso15693(uint8_t *uid, uint8_t block_size) { // free eventually allocated BigBuf memory BigBuf_free_keep_EM(); @@ -2122,11 +2122,7 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size, int image_length, uint8_t LED_A_ON(); - if (image_length == -1) { - Dbprintf("ISO-15963 Simulating uid: %02X%02X%02X%02X%02X%02X%02X%02X block size %d with no image", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7], block_size); - } else { - Dbprintf("ISO-15963 Simulating uid: %02X%02X%02X%02X%02X%02X%02X%02X block size %d with 0x%X bytes image", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7], block_size, image_length); - } + Dbprintf("ISO-15963 Simulating uid: %02X%02X%02X%02X%02X%02X%02X%02X block size %d", uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7], block_size); LED_C_ON(); @@ -2222,14 +2218,8 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size, int image_length, uint8_t resp_sysinfo[10] = 0; // DSFID resp_sysinfo[11] = 0; // AFI - // Memory size. - if (image_length == -1) { - // use sensible default value if no image is provided - resp_sysinfo[12] = 0x1F; - } else { - resp_sysinfo[12] = image_length / block_size; - } - resp_sysinfo[13] = block_size - 1; // Memory size. + resp_sysinfo[12] = 0x1F; // Block count + resp_sysinfo[13] = block_size - 1; // Block size. resp_sysinfo[14] = 0x01; // IC reference. // CRC @@ -2282,6 +2272,7 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size, int image_length, uint8_t resp_readblock[i] = 0; } + uint8_t *emCARD = BigBuf_get_EM_addr(); resp_readblock[0] = 0; // Response flags for (int j = 0; j < block_count; j++) { // where to put the data of the current block @@ -2291,8 +2282,8 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size, int image_length, uint8_t } for (int i = 0; i < block_size; i++) { // Block data - if (block_size * (block_idx + j + 1) <= image_length) { - resp_readblock[work_offset + security_offset + i] = image[block_size * (block_idx + j) + i]; + if (block_size * (block_idx + j + 1) <= CARD_MEMORY_SIZE) { + resp_readblock[work_offset + security_offset + i] = emCARD[block_size * (block_idx + j) + i]; } else { resp_readblock[work_offset + security_offset + i] = 0; } diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index 4f1800dc7..6bd3882bc 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -48,7 +48,7 @@ void AcquireRawAdcSamplesIso15693(void); void ReaderIso15693(iso15_card_select_t *p_card); // ISO15693 reader void EmlClearIso15693(void); void EmlSetMemIso15693(uint8_t count, uint8_t *data, uint32_t offset); -void SimTagIso15693(uint8_t *uid, uint8_t block_size, int payload_length, uint8_t *payload); // simulate an ISO15693 tag +void SimTagIso15693(uint8_t *uid, uint8_t block_size); // simulate an ISO15693 tag void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 417ad1fe5..066d6bfdf 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1111,7 +1111,6 @@ static int CmdHF15Sim(const char *Cmd) { arg_param_begin, arg_str1("u", "uid", "<8b hex>", "UID eg E011223344556677"), arg_int0("b", "blocksize", "", "block size, defaults to 4"), - arg_str0("i", "image", "", "Memory image to load, defaults to zeros"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -1119,8 +1118,6 @@ static int CmdHF15Sim(const char *Cmd) { struct { uint8_t uid[8]; uint8_t block_size; - int image_length; - uint8_t image[PM3_CMD_BLOB_SIZE]; } PACKED payload; int uidlen = 0; @@ -1131,34 +1128,8 @@ static int CmdHF15Sim(const char *Cmd) { } payload.block_size = arg_get_int_def(ctx, 2, 4); - - int fnlen = 0; - char filename[FILE_PATH_SIZE] = {0}; - CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); CLIParserFree(ctx); - if (fnlen > 0) { - uint8_t *image = NULL; - size_t image_len = 0; - if (loadFile_safe(filename, "", (void **)&image, &image_len) != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Could not open file " _YELLOW_("%s"), filename); - return PM3_EIO; - } - - if (image_len > PM3_CMD_BLOB_SIZE) { - PrintAndLogEx(WARNING, "Memory image to large for us"); - return PM3_EINVARG; - } - if (image_len % payload.block_size != 0) { - PrintAndLogEx(WARNING, "Memory image size not a multiple of the block size"); - return PM3_EINVARG; - } - payload.image_length = image_len; - memcpy(payload.image, image, image_len); - free(image); - } else { - payload.image_length = -1; - } PrintAndLogEx(SUCCESS, "Starting simulating UID " _YELLOW_("%s"), iso15693_sprintUID(NULL, payload.uid)); PrintAndLogEx(INFO, "press " _YELLOW_("`Pm3 button`") " to cancel"); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index f2e9f0607..7c7eb6ed6 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -27,10 +27,6 @@ #define PM3_CMD_DATA_SIZE 512 #define PM3_CMD_DATA_SIZE_MIX ( PM3_CMD_DATA_SIZE - 3 * sizeof(uint64_t) ) -/* To be used for commands with a big blob of data along with some other data (for which 32 bytes - * is put aside, so if there is more of it this is unsuitable). - */ -#define PM3_CMD_BLOB_SIZE ( PM3_CMD_DATA_SIZE - 32 ) typedef struct { uint64_t cmd; From 6fe7d997fffc20b2c88cd2e9fdb0408c8caf8597 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Thu, 1 Sep 2022 18:48:24 +0200 Subject: [PATCH 227/759] Adjusted changelog entry to new `hf 15 eload` command. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c09c300b..1fcbd808a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -88,7 +88,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz) - Added `script run hf_mf_hid_sim.lua` (@micsen) - Added `hf 15 sim --blocksize` - configure block size for simulation (@markus-oehme-pg40) - - Added `hf 15 sim --image` - specify memory image for simulation (@markus-oehme-pg40) + - Added `hf 15 eload` - specify memory image for ISO15693 simulation (@markus-oehme-pg40) ## [Frostbit.4.14831][2022-01-11] From 9ed391469bed7aa9099e636517c4dfc3c18c59b9 Mon Sep 17 00:00:00 2001 From: Andrew MacPherson Date: Thu, 1 Sep 2022 13:15:17 -0700 Subject: [PATCH 228/759] Updated discord invite link User (Genoff) spotted the discord link doesnt work anymore, added a new invite link: https://discord.gg/xEvexdKmpF Signed-off-by: Andrew MacPherson --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0738cd144..5747d3d9f 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ The official PM3-GUI from Gaucho will not work. Not to mention is quite old and ## Official channels Where do you find the community? - - [RFID Hacking community discord server](https://discord.gg/iceman) + - [RFID Hacking community discord server](https://discord.gg/xEvexdKmpF) - [Proxmark3 IRC channel](https://web.libera.chat/?channels=#proxmark3) - [Proxmark3 sub reddit](https://www.reddit.com/r/proxmark3/) - [Proxmark3 forum](http://www.proxmark.org/forum/index.php) From 41f36199aa6c856c410d0bd49ddd31de48828965 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 2 Sep 2022 05:34:47 +0200 Subject: [PATCH 229/759] format string --- client/src/cmdhf15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 066d6bfdf..0d25e38f9 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1080,7 +1080,7 @@ static int CmdHF15ELoad(const char *Cmd) { int tosend = MIN(chuncksize, bytes_read); if (hf15EmlSetMem(data + offset, tosend, offset) != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Can't set emulator memory at offest: 0x%x", offset); + PrintAndLogEx(FAILED, "Can't set emulator memory at offest: %zu / 0x%zx", offset); free(data); return PM3_ESOFT; } From e0eeafe27f91aff369739edf96ae9428a33aedb8 Mon Sep 17 00:00:00 2001 From: mwalker33 <51802811+mwalker33@users.noreply.github.com> Date: Fri, 2 Sep 2022 22:35:48 +1000 Subject: [PATCH 230/759] mdu ndef error Patch to stop buffer overflow on ndef read from card Typo fix in change log. --- CHANGELOG.md | 3 ++- client/src/cmdhfmfu.c | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c99a941f5..8e846aa05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +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 spiffs write/apped to send in 8192 chucks to ensure its eraised (@mwalker) + - Fixed buffer overflow in mfu ndef decode (@mwalker) + - Changed spiffs write/append to send in 8192 chunks to ensure its eraised (@mwalker) - Fixed spiffs dump to ensure to fails correctly if no big_buff was allocated (@mwalker) - Change Client Makefile to respect global flags (@blshkv) - Change Makefile, honors global CC values (@blshkv) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 2f6e18a53..a1ee42306 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -4027,6 +4027,9 @@ int CmdHF14MfuNDEFRead(const char *Cmd) { } } + // The following read will read in blocks of 16 bytes. + // ensure maxsize is rounded up to a multiple of 16 + maxsize = maxsize + (16 - (maxsize % 16)); // allocate mem uint8_t *records = calloc(maxsize, sizeof(uint8_t)); if (records == NULL) { From de40ae1f051f8dc00e55e1fd2bce1f608f8c478c Mon Sep 17 00:00:00 2001 From: Builderhummel Date: Fri, 2 Sep 2022 14:47:12 +0200 Subject: [PATCH 231/759] Fix Typo "form" to "from" Signed-off-by: Builderhummel --- armsrc/Standalone/hf_legicsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/Standalone/hf_legicsim.c b/armsrc/Standalone/hf_legicsim.c index 7bb27fe8a..7765672b0 100644 --- a/armsrc/Standalone/hf_legicsim.c +++ b/armsrc/Standalone/hf_legicsim.c @@ -111,7 +111,7 @@ void RunMod(void) { //Indicate which card will be simulated LED(i, 0); - //Try to load dump form flash + //Try to load dump from flash sprintf(cur_dump_file, HF_LEGICSIM_DUMPFILE_SIM, i); Dbprintf(_YELLOW_("[Slot: %d] Try to load dump file: %s"), i, cur_dump_file); if (!fill_eml_from_file(cur_dump_file)) { From 0f96bcff0570936c3a6c480214784240a9787cfe Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Sep 2022 10:31:08 +0200 Subject: [PATCH 232/759] CID 398740, init a struct --- client/src/cmdhficlass.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index e920f9f5d..b4c9d934b 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -664,14 +664,15 @@ static int CmdHFiClassSniff(const char *Cmd) { PrintAndLogEx(INFO, "Sniff with jam of iCLASS e-purse updates..."); } - const uint8_t update_epurse_sequence[2] = {0x87, 0x02}; - struct { uint8_t jam_search_len; uint8_t jam_search_string[2]; } PACKED payload; + memset(&payload, 0, sizeof(payload)); + if (jam_epurse_update) { + const uint8_t update_epurse_sequence[2] = {0x87, 0x02}; payload.jam_search_len = sizeof(update_epurse_sequence); memcpy(payload.jam_search_string, update_epurse_sequence, sizeof(payload.jam_search_string)); } From eaebf469613bf917aa253f66a7de9de9639b8c05 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Sep 2022 10:34:52 +0200 Subject: [PATCH 233/759] CID 398739 , init of array w structs --- client/src/cmddata.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 02138b9ca..8020b7220 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -2767,13 +2767,19 @@ static int print_modulation(lf_modulation_t b) { static int try_detect_modulation(void) { - lf_modulation_t tests[6]; +#define LF_NUM_OF_TESTS 6 + + lf_modulation_t tests[LF_NUM_OF_TESTS]; + for (int i=0; i< ARRAYLEN(tests); i++) { + memset(&tests[i], 0, sizeof(lf_modulation_t)); + } + int clk = 0, firstClockEdge = 0; - uint8_t hits = 0, ans = 0; - uint8_t fc1 = 0, fc2 = 0; + uint8_t hits = 0, fc1 = 0, fc2 = 0; bool st = false; - ans = fskClocks(&fc1, &fc2, (uint8_t *)&clk, &firstClockEdge); + + uint8_t ans = fskClocks(&fc1, &fc2, (uint8_t *)&clk, &firstClockEdge); if (ans && ((fc1 == 10 && fc2 == 8) || (fc1 == 8 && fc2 == 5))) { From 1525a0059aced44bcecc1e6ac6bea42ee823ac8c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Sep 2022 11:14:33 +0200 Subject: [PATCH 234/759] fix #1771 - no default block size in call --- armsrc/Standalone/hf_tmudford.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/Standalone/hf_tmudford.c b/armsrc/Standalone/hf_tmudford.c index 158250a0c..a945a49ec 100644 --- a/armsrc/Standalone/hf_tmudford.c +++ b/armsrc/Standalone/hf_tmudford.c @@ -75,7 +75,8 @@ void RunMod(void) { } else if (state == STATE_EMUL) { Iso15693InitTag(); Dbprintf("Starting simulation, press pm3-button to stop and go back to search state."); - SimTagIso15693(card.uid); + // default block size is 4 + SimTagIso15693(card.uid, 4); state = STATE_READ; } From fccb398aeaff1fcbca6e436e01b7ea8b98915559 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Sep 2022 11:22:33 +0200 Subject: [PATCH 235/759] vanity url should work again --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5747d3d9f..0738cd144 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ The official PM3-GUI from Gaucho will not work. Not to mention is quite old and ## Official channels Where do you find the community? - - [RFID Hacking community discord server](https://discord.gg/xEvexdKmpF) + - [RFID Hacking community discord server](https://discord.gg/iceman) - [Proxmark3 IRC channel](https://web.libera.chat/?channels=#proxmark3) - [Proxmark3 sub reddit](https://www.reddit.com/r/proxmark3/) - [Proxmark3 forum](http://www.proxmark.org/forum/index.php) From 1a3aa7eb025e53260380695107a4ee9efa8be9c5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Sep 2022 11:23:01 +0200 Subject: [PATCH 236/759] missing var --- client/src/cmdhf15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 0d25e38f9..f08d7f764 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1080,7 +1080,7 @@ static int CmdHF15ELoad(const char *Cmd) { int tosend = MIN(chuncksize, bytes_read); if (hf15EmlSetMem(data + offset, tosend, offset) != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Can't set emulator memory at offest: %zu / 0x%zx", offset); + PrintAndLogEx(FAILED, "Can't set emulator memory at offest: %zu / 0x%zx", offset, offset); free(data); return PM3_ESOFT; } From 7a831fc94e8d8ee44cdf02eb3c321b95f2129041 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Sep 2022 11:23:44 +0200 Subject: [PATCH 237/759] CID 398738, missing init --- client/src/cmdlfhid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index d25c06811..4b6c69698 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -81,6 +81,7 @@ static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, boo } lf_hidsim_t payload; + payload.Q5 = false; payload.hi2 = packed.Top; payload.hi = packed.Mid; payload.lo = packed.Bot; @@ -483,7 +484,7 @@ static int CmdHIDBrute(const char *Cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("v", "verbose", "verbose logging, show all tries"), + arg_lit0("v", "verbose", "verbose output"), arg_str1("w", "wiegand", "", "see " _YELLOW_("`wiegand list`") " for available formats"), arg_u64_0(NULL, "fc", "", "facility code"), arg_u64_0(NULL, "cn", "", "card number to start with"), From d76284aa8d2d49a9f30a5888c3e456ab039ed0b8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 4 Sep 2022 13:58:49 +0200 Subject: [PATCH 238/759] style --- armsrc/mifarecmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index c7afb3a75..ce4b14631 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -887,9 +887,9 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, break; } - if (!have_uid) { // need a full select cycle to get the uid first + if (have_uid == false) { // need a full select cycle to get the uid first iso14a_card_select_t card_info; - if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { + if (iso14443a_select_card(uid, &card_info, &cuid, true, 0, true) == 0) { if (g_dbglevel >= DBG_ERROR) Dbprintf("AcquireEncryptedNonces: Can't select card (ALL)"); continue; } @@ -908,7 +908,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, } have_uid = true; } else { // no need for anticollision. We can directly select the card - if (!iso14443a_fast_select_card(uid, cascade_levels)) { + if (iso14443a_fast_select_card(uid, cascade_levels) == 0) { if (g_dbglevel >= DBG_ERROR) Dbprintf("AcquireEncryptedNonces: Can't select card (UID)"); continue; } From c062c44230012d73f15b8f5df82c7deef7c9b21e Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Mon, 5 Sep 2022 09:52:08 +0200 Subject: [PATCH 239/759] Refactor emulator accessor helpers for ISO15693. --- armsrc/iso15693.c | 17 +++++++++++------ armsrc/iso15693.h | 1 + 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 7e4c5c4f3..d4ab6e14e 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -2111,6 +2111,11 @@ void EmlSetMemIso15693(uint8_t count, uint8_t *data, uint32_t offset) { memcpy(emCARD + offset, data, count); } +void EmlGetMemIso15693(uint8_t count, uint8_t *output, uint32_t offset) { + uint8_t *emCARD = BigBuf_get_EM_addr(); + memcpy(output, emCARD + offset, count); +} + // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands // all demodulation performed in arm rather than host. - greg void SimTagIso15693(uint8_t *uid, uint8_t block_size) { @@ -2272,7 +2277,6 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) { resp_readblock[i] = 0; } - uint8_t *emCARD = BigBuf_get_EM_addr(); resp_readblock[0] = 0; // Response flags for (int j = 0; j < block_count; j++) { // where to put the data of the current block @@ -2280,11 +2284,12 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) { if (option) { resp_readblock[work_offset] = 0; // Security status } - for (int i = 0; i < block_size; i++) { - // Block data - if (block_size * (block_idx + j + 1) <= CARD_MEMORY_SIZE) { - resp_readblock[work_offset + security_offset + i] = emCARD[block_size * (block_idx + j) + i]; - } else { + // Block data + if (block_size * (block_idx + j + 1) <= CARD_MEMORY_SIZE) { + EmlGetMemIso15693(block_size, resp_readblock + (work_offset + security_offset), + block_size * (block_idx + j)); + } else { + for (int i = 0; i < block_size; i++) { resp_readblock[work_offset + security_offset + i] = 0; } } diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index 6bd3882bc..f9ba6e9da 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -48,6 +48,7 @@ void AcquireRawAdcSamplesIso15693(void); void ReaderIso15693(iso15_card_select_t *p_card); // ISO15693 reader void EmlClearIso15693(void); void EmlSetMemIso15693(uint8_t count, uint8_t *data, uint32_t offset); +void EmlGetMemIso15693(uint8_t count, uint8_t *output, uint32_t offset); void SimTagIso15693(uint8_t *uid, uint8_t block_size); // simulate an ISO15693 tag void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI From 7cc47eebba30df6338ea3d58d3582f6ed37fad70 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Fri, 2 Sep 2022 10:36:34 +0200 Subject: [PATCH 240/759] Accept eml and json files for `hf 15 eload`. --- client/src/cmdhf15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 0d25e38f9..fb80c57ab 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1043,7 +1043,7 @@ static int CmdHF15ELoad(const char *Cmd) { uint8_t *data = NULL; size_t bytes_read = 0; - int res = loadFile_safe(filename, ".bin", (void **)&data, &bytes_read); + int res = pm3_load_dump(filename, (void **)&data, &bytes_read, CARD_MEMORY_SIZE); if (res != PM3_SUCCESS) { return res; } From 2d7e1d30b94981adee0583ed80a276a92e33e5f4 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Mon, 5 Sep 2022 10:12:25 +0200 Subject: [PATCH 241/759] Refactor ISO 15693 READ commands to handle addressed flag. --- armsrc/iso15693.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index d4ab6e14e..060ce0124 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -2240,29 +2240,19 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) { // READ_BLOCK and READ_MULTI_BLOCK if ((cmd[1] == ISO15693_READBLOCK) || (cmd[1] == ISO15693_READ_MULTI_BLOCK)) { bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH); + bool addressed = cmd[0] & ISO15_REQ_ADDRESS; bool option = cmd[0] & ISO15_REQ_OPTION; uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; - uint8_t block_idx = 0; + uint8_t address_offset = 0; + if (addressed) { + address_offset = 8; + } + + uint8_t block_idx = cmd[2 + address_offset]; uint8_t block_count = 1; - if (cmd[1] == ISO15693_READBLOCK) { - if (cmd_len == 13) { - // addressed mode - block_idx= cmd[10]; - } else if (cmd_len == 5) { - // non-addressed mode - block_idx = cmd[2]; - } - } else if (cmd[1] == ISO15693_READ_MULTI_BLOCK) { - if (cmd_len == 14) { - // addressed mode - block_idx= cmd[10]; - block_count= cmd[11] + 1; - } else if (cmd_len == 6) { - // non-addressed mode - block_idx = cmd[2]; - block_count = cmd[3] + 1; - } + if (cmd[1] == ISO15693_READ_MULTI_BLOCK) { + block_count = cmd[3 + address_offset] + 1; } // Build READ_(MULTI_)BLOCK response From f6096367b31af17aa4c5962728c7ed07882b8139 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Mon, 5 Sep 2022 10:24:22 +0200 Subject: [PATCH 242/759] Add ISO15693 write commands to simulation. --- armsrc/iso15693.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 060ce0124..d2035d70b 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -2294,6 +2294,47 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) { TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow); LogTrace_ISO15693(resp_readblock, response_length, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false); } + + // WRITE_BLOCK and WRITE_MULTI_BLOCK + if ((cmd[1] == ISO15693_WRITEBLOCK) || (cmd[1] == ISO15693_WRITE_MULTI_BLOCK)) { + bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH); + bool addressed = cmd[0] & ISO15_REQ_ADDRESS; + uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; + + uint8_t address_offset = 0; + if (addressed) { + address_offset = 8; + } + + uint8_t block_idx = cmd[2 + address_offset]; + uint8_t block_count = 1; + uint8_t multi_offset = 0; + if (cmd[1] == ISO15693_WRITE_MULTI_BLOCK) { + block_count = cmd[3 + address_offset] + 1; + multi_offset = 1; + } + uint8_t *data = cmd + 3 + address_offset + multi_offset; + + // write data + EmlSetMemIso15693(block_count * block_size, data, block_idx * block_size); + + // Build WRITE_(MULTI_)BLOCK response + int response_length = 3; + uint8_t resp_writeblock[response_length]; + for (int i = 0; i < response_length; i++) { + resp_writeblock[i] = 0; + } + resp_writeblock[0] = 0; // Response flags + + // CRC + AddCrc15(resp_writeblock, response_length - 2); + CodeIso15693AsTag(resp_writeblock, response_length); + + tosend_t *ts = get_tosend(); + + TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow); + LogTrace_ISO15693(resp_writeblock, response_length, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false); + } } switch_off(); From de99fee83c2ab18b26aa7de08097649ab8ec77d7 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Fri, 2 Sep 2022 11:17:28 +0200 Subject: [PATCH 243/759] Add commands `hf 15 eview` and `hf 15 esave`. --- client/src/cmdhf15.c | 131 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index fb80c57ab..708b1e73c 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1098,6 +1098,133 @@ static int CmdHF15ELoad(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHF15ESave(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 esave", + "Save emulator memory into three files (BIN/EML/JSON) ", + "hf 15 esave -f hf-15-01020304" + "hf 15 esave -b 8 -c 42 -f hf-15-01020304" + ); + void *argtable[] = { + arg_param_begin, + arg_str1("f", "file", "", "filename of dump"), + arg_int0("b", "blocksize", "", "block size, defaults to 4"), + arg_int0("c", "count", "", "number of blocks to export, defaults to all"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + int fnlen = 0; + char filename[FILE_PATH_SIZE]; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + int blocksize = arg_get_int_def(ctx, 2, 4); + int count = arg_get_int_def(ctx, 3, -1); + CLIParserFree(ctx); + + int bytes = CARD_MEMORY_SIZE; + if (count > 0 && count * blocksize <= bytes) { + bytes = count * blocksize; + } + + // reserve memory + uint8_t *dump = calloc(bytes, sizeof(uint8_t)); + if (dump == NULL) { + PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); + return PM3_EMALLOC; + } + + PrintAndLogEx(INFO, "Downloading %u bytes from emulator memory", bytes); + if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) { + PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); + free(dump); + return PM3_ETIMEOUT; + } + + saveFile(filename, ".bin", dump, bytes); + saveFileEML(filename, dump, bytes, blocksize); + saveFileJSON(filename, jsf15, dump, bytes, NULL); + free(dump); + return PM3_SUCCESS; +} + +static void print_hrule(int blocksize) { + PrintAndLogEx(INFO, "-----+" NOLF); + for (int i = 0; i < blocksize; i++) { + PrintAndLogEx(NORMAL, "---" NOLF); + } + PrintAndLogEx(NORMAL, "-+-" NOLF); + for (int i = 0; i < blocksize; i++) { + PrintAndLogEx(NORMAL, "-" NOLF); + } + PrintAndLogEx(NORMAL, ""); +} + +static void print_blocks_15693(uint8_t *data, uint16_t bytes, int blocksize) { + int blocks = bytes / blocksize; + PrintAndLogEx(NORMAL, ""); + print_hrule(blocksize); + PrintAndLogEx(INFO, " blk | data " NOLF); + for (int i = 2; i < blocksize; i++) { + PrintAndLogEx(NORMAL, " " NOLF); + } + PrintAndLogEx(NORMAL, "| ascii"); + print_hrule(blocksize); + for (uint16_t i = 0; i < blocks; i++) { + PrintAndLogEx(INFO, "%4d | %s ", i, sprint_hex_ascii(data + (i * blocksize), blocksize)); + + } + if (bytes % blocksize != 0) { + // If there is something left over print it too + // This will have a broken layout, but should not happen anyway + PrintAndLogEx(INFO, "%4d | %s ", blocks, sprint_hex_ascii(data + (blocks * blocksize), + bytes % blocksize)); + } + print_hrule(blocksize); + PrintAndLogEx(NORMAL, ""); +} + +static int CmdHF15EView(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 eview", + "It displays emulator memory", + "hf 15 eview\n" + "hf 15 eview -b 8 -c 60\n" + ); + void *argtable[] = { + arg_param_begin, + arg_int0("b", "blocksize", "", "block size, defaults to 4"), + arg_int0("c", "count", "", "number of blocks to display, defaults to all"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + int blocksize = arg_get_int_def(ctx, 1, 4); + int count = arg_get_int_def(ctx, 2, -1); + CLIParserFree(ctx); + + int bytes = CARD_MEMORY_SIZE; + if (count > 0 && count * blocksize <= bytes) { + bytes = count * blocksize; + } + + uint8_t *dump = calloc(bytes, sizeof(uint8_t)); + if (dump == NULL) { + PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); + return PM3_EMALLOC; + } + + PrintAndLogEx(INFO, "Downloading %u bytes from emulator memory", bytes); + if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) { + PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); + free(dump); + return PM3_ETIMEOUT; + } + + print_blocks_15693(dump, bytes, blocksize); + free(dump); + return PM3_SUCCESS; +} + // Simulation is still not working very good // helptext static int CmdHF15Sim(const char *Cmd) { @@ -2289,7 +2416,9 @@ static command_t CommandTable[] = { {"reader", CmdHF15Reader, IfPm3Iso15693, "Act like an ISO-15693 reader"}, {"restore", CmdHF15Restore, IfPm3Iso15693, "Restore from file to all memory pages of an ISO-15693 tag"}, {"samples", CmdHF15Samples, IfPm3Iso15693, "Acquire samples as reader (enables carrier, sends inquiry)"}, - {"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file to be used by 'sim' command"}, + {"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file into emulator to be used by 'sim' command"}, + {"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"}, + {"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"}, {"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"}, {"slixdisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"}, {"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"}, From 42d0c6d8c135c56d688f745efe266e1dc7bb4980 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Mon, 5 Sep 2022 10:27:54 +0200 Subject: [PATCH 244/759] Use memset to zero memory for better code style. --- armsrc/iso15693.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index d2035d70b..388aaddce 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -2263,9 +2263,7 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) { security_offset = 1; } uint8_t resp_readblock[response_length]; - for (int i = 0; i < response_length; i++) { - resp_readblock[i] = 0; - } + memset(resp_readblock, 0, response_length); resp_readblock[0] = 0; // Response flags for (int j = 0; j < block_count; j++) { @@ -2279,9 +2277,7 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) { EmlGetMemIso15693(block_size, resp_readblock + (work_offset + security_offset), block_size * (block_idx + j)); } else { - for (int i = 0; i < block_size; i++) { - resp_readblock[work_offset + security_offset + i] = 0; - } + memset(resp_readblock + work_offset + security_offset, 0, block_size); } } @@ -2321,9 +2317,7 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) { // Build WRITE_(MULTI_)BLOCK response int response_length = 3; uint8_t resp_writeblock[response_length]; - for (int i = 0; i < response_length; i++) { - resp_writeblock[i] = 0; - } + memset(resp_writeblock, 0, response_length); resp_writeblock[0] = 0; // Response flags // CRC From 8ac9ba9a3dd78031e4b9cf9f3a485baa7d3d412c Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Mon, 5 Sep 2022 10:44:06 +0200 Subject: [PATCH 245/759] Updated changelog. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c99a941f5..025c4adc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -91,6 +91,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `script run hf_mf_hid_sim.lua` (@micsen) - Added `hf 15 sim --blocksize` - configure block size for simulation (@markus-oehme-pg40) - Added `hf 15 eload` - specify memory image for ISO15693 simulation (@markus-oehme-pg40) + - Added write command support to `hf 15 sim` (@markus-oehme-pg40) + - Added `hf 15 eview` and `hf 15 esave` - Retrieve emulator image for ISO15693 simulation (@markus-oehme-pg40) ## [Frostbit.4.14831][2022-01-11] From 84b58129dd391eadea871cc62937211ab5cbedc7 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Mon, 5 Sep 2022 10:46:06 +0200 Subject: [PATCH 246/759] Fix API breakage. --- armsrc/Standalone/hf_tmudford.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/Standalone/hf_tmudford.c b/armsrc/Standalone/hf_tmudford.c index 158250a0c..394d37e2d 100644 --- a/armsrc/Standalone/hf_tmudford.c +++ b/armsrc/Standalone/hf_tmudford.c @@ -75,7 +75,7 @@ void RunMod(void) { } else if (state == STATE_EMUL) { Iso15693InitTag(); Dbprintf("Starting simulation, press pm3-button to stop and go back to search state."); - SimTagIso15693(card.uid); + SimTagIso15693(card.uid, 4); state = STATE_READ; } From f511333b4d0b768a7ef1fb2b09a48551f6047a79 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Mon, 5 Sep 2022 11:13:18 +0200 Subject: [PATCH 247/759] Fix linter complaint. --- client/src/cmdhf15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 57c065b94..58a1e9005 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1169,7 +1169,7 @@ static void print_blocks_15693(uint8_t *data, uint16_t bytes, int blocksize) { } PrintAndLogEx(NORMAL, "| ascii"); print_hrule(blocksize); - for (uint16_t i = 0; i < blocks; i++) { + for (int i = 0; i < blocks; i++) { PrintAndLogEx(INFO, "%4d | %s ", i, sprint_hex_ascii(data + (i * blocksize), blocksize)); } From b49201ea6e4aefe85a68bd93356f3a8df823e3eb Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Tue, 6 Sep 2022 10:00:43 +0200 Subject: [PATCH 248/759] Use pm3_save_dump() for storing to disk. --- client/src/cmdhf15.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 58a1e9005..c4a335104 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1140,9 +1140,7 @@ static int CmdHF15ESave(const char *Cmd) { return PM3_ETIMEOUT; } - saveFile(filename, ".bin", dump, bytes); - saveFileEML(filename, dump, bytes, blocksize); - saveFileJSON(filename, jsf15, dump, bytes, NULL); + pm3_save_dump(filename, dump, bytes, jsf15, blocksize); free(dump); return PM3_SUCCESS; } From 751260b9d701a0ca79a89a0b6a457321bb9af91f Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Tue, 6 Sep 2022 10:28:36 +0200 Subject: [PATCH 249/759] Adjust changelog to convention. --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad14fefdc..2023e24bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ 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 `hf 15 eview` and `hf 15 esave` - Retrieve emulator image for ISO15693 simulation (@markus-oehme-pg40) + - Changed `hf 15 sim` - now supports reader writes (@markus-oehme-pg40) + - Added `hf 15 eload` - specify memory image for ISO15693 simulation (@markus-oehme-pg40) + - Added `hf 15 sim --blocksize` - configure block size for simulation (@markus-oehme-pg40) - Fixed buffer overflow in mfu ndef decode (@mwalker) - Changed spiffs write/append to send in 8192 chunks to ensure its eraised (@mwalker) - Fixed spiffs dump to ensure to fails correctly if no big_buff was allocated (@mwalker) @@ -90,10 +94,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added new standalone mode `lf_em4100rsww` (@zabszk) - Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz) - Added `script run hf_mf_hid_sim.lua` (@micsen) - - Added `hf 15 sim --blocksize` - configure block size for simulation (@markus-oehme-pg40) - - Added `hf 15 eload` - specify memory image for ISO15693 simulation (@markus-oehme-pg40) - - Added write command support to `hf 15 sim` (@markus-oehme-pg40) - - Added `hf 15 eview` and `hf 15 esave` - Retrieve emulator image for ISO15693 simulation (@markus-oehme-pg40) ## [Frostbit.4.14831][2022-01-11] From 69100e0e04c16732afcbcce0d494b2b5668d6d8b Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Tue, 6 Sep 2022 10:59:43 +0200 Subject: [PATCH 250/759] Use printf options to output variable width segments. --- client/src/cmdhf15.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index c4a335104..285769f68 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1146,26 +1146,16 @@ static int CmdHF15ESave(const char *Cmd) { } static void print_hrule(int blocksize) { - PrintAndLogEx(INFO, "-----+" NOLF); - for (int i = 0; i < blocksize; i++) { - PrintAndLogEx(NORMAL, "---" NOLF); - } - PrintAndLogEx(NORMAL, "-+-" NOLF); - for (int i = 0; i < blocksize; i++) { - PrintAndLogEx(NORMAL, "-" NOLF); - } - PrintAndLogEx(NORMAL, ""); + char dashes[] = "------------------------------------------------------------"; + PrintAndLogEx(INFO, "-----+%.*s-+-%.*s-", 3*blocksize, dashes, blocksize, dashes); } static void print_blocks_15693(uint8_t *data, uint16_t bytes, int blocksize) { int blocks = bytes / blocksize; PrintAndLogEx(NORMAL, ""); print_hrule(blocksize); - PrintAndLogEx(INFO, " blk | data " NOLF); - for (int i = 2; i < blocksize; i++) { - PrintAndLogEx(NORMAL, " " NOLF); - } - PrintAndLogEx(NORMAL, "| ascii"); + char spaces[] = " "; + PrintAndLogEx(INFO, " blk | data %.*s| ascii", MAX(0, 3*blocksize - 5), spaces); print_hrule(blocksize); for (int i = 0; i < blocks; i++) { PrintAndLogEx(INFO, "%4d | %s ", i, sprint_hex_ascii(data + (i * blocksize), blocksize)); From fbc9e3f6313efc10502c09218da584fcb39c9f40 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Sep 2022 19:01:16 +0200 Subject: [PATCH 251/759] p2p identification --- client/src/cmdhf14a.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 8eeb0f402..83b37dda4 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1487,6 +1487,7 @@ typedef enum { MTOTHER = 64, MTEMV = 128, MTFUDAN = 256, + MTISO18092 = 512, } nxp_mifare_type_t; // Based on NXP AN10833 Rev 3.6 and NXP AN10834 Rev 4.1 @@ -1499,6 +1500,13 @@ static int detect_nxp_card(uint8_t sak, uint16_t atqa, uint64_t select_status) { if ((sak & 0x19) == 0x19) { printTag("MIFARE Classic 2K"); type |= MTCLASSIC; + } else if ((sak & 0x40) == 0x40) { + if ((atqa & 0x0110) == 0x0110) + printTag("P2P Support / Proprietary"); + else + printTag("P2P Support / Android"); + + type |= MTISO18092; } else if ((sak & 0x38) == 0x38) { printTag("SmartMX with MIFARE Classic 4K"); type |= MTCLASSIC; @@ -1804,6 +1812,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { bool isST = false; bool isEMV = false; bool isFUDAN = false; + bool isISO18092 = false; int nxptype = MTNONE; if (card.uidlen <= 4) { @@ -1823,6 +1832,9 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { if ((nxptype & MTEMV) == MTEMV) isEMV = true; + if ((nxptype & MTISO18092) == MTISO18092) + isISO18092 = true; + } else { // Double & triple sized UID, can be mapped to a manufacturer. @@ -2259,9 +2271,15 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } } } else { - PrintAndLogEx(INFO, "proprietary non iso14443-4 card found, RATS not supported"); - if ((card.sak & 0x20) == 0x20) { - PrintAndLogEx(INFO, "--> SAK incorrectly claims that card supports RATS <--"); + + if (isISO18092) { + PrintAndLogEx(INFO, "proprietary iso18092 card found"); + } else { + + PrintAndLogEx(INFO, "proprietary non iso14443-4 card found, RATS not supported"); + if ((card.sak & 0x20) == 0x20) { + PrintAndLogEx(INFO, "--> SAK incorrectly claims that card supports RATS <--"); + } } if (select_status == 1) select_status = 2; From fa5e69ceef1237fbdb831e530c814bc030bf7aac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Sep 2022 20:27:49 +0200 Subject: [PATCH 252/759] fix coveriy --- client/src/cmdhf15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 285769f68..bc8dc8928 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1239,13 +1239,13 @@ static int CmdHF15Sim(const char *Cmd) { CLIGetHexWithReturn(ctx, 1, payload.uid, &uidlen); if (uidlen != 8) { PrintAndLogEx(WARNING, "UID must include 16 HEX symbols"); + CLIParserFree(ctx); return PM3_EINVARG; } payload.block_size = arg_get_int_def(ctx, 2, 4); CLIParserFree(ctx); - PrintAndLogEx(SUCCESS, "Starting simulating UID " _YELLOW_("%s"), iso15693_sprintUID(NULL, payload.uid)); PrintAndLogEx(INFO, "press " _YELLOW_("`Pm3 button`") " to cancel"); From cb16edc845da62513fd8dd9e57d4f2213ee90883 Mon Sep 17 00:00:00 2001 From: David Bryan Date: Fri, 9 Sep 2022 13:11:53 -0700 Subject: [PATCH 253/759] adding keys recoved --- client/dictionaries/mfc_default_keys.dic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 63afe7c0b..a343e3510 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1815,3 +1815,6 @@ A00003000057 # iGuard Simple (and reverse) keys AAAAAAFFFFFF FFFFFFAAAAAA +# Added by VideoMan. +3111A3A303EB # Random Hotel A Key Sec 0 Blk 3 +2A2C13CC242A # Random Hotel A key Sec 1 Blk 7 From a92942423a451c9ca06fc79a3fc9b69df824f9f8 Mon Sep 17 00:00:00 2001 From: David Bryan Date: Fri, 9 Sep 2022 13:20:04 -0700 Subject: [PATCH 254/759] updated key with a new static key recovered --- client/dictionaries/mfc_default_keys.dic | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index a343e3510..793b625c3 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -632,7 +632,7 @@ B66AC040203A AD4FB33388BF 69FB7B7CD8EE 2A6D9205E7CA # Hotel -2a2c13cc242a +2a2c13cc242a # KABA Hotel Locks 27FBC86A00D0 01FA3FC68349 # @@ -1816,5 +1816,4 @@ A00003000057 AAAAAAFFFFFF FFFFFFAAAAAA # Added by VideoMan. -3111A3A303EB # Random Hotel A Key Sec 0 Blk 3 -2A2C13CC242A # Random Hotel A key Sec 1 Blk 7 +3111A3A303EB # Random Hotel A Key Sec 0 Blk 3 - KABA Lock From c145c4b78ba1c61db02229c4aa243925c21d63bb Mon Sep 17 00:00:00 2001 From: DidierA Date: Tue, 20 Sep 2022 01:52:53 +0200 Subject: [PATCH 255/759] Fix dump of SRT512 tag --- client/src/cmdhf14b.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 3150da049..7288c3251 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -789,23 +789,24 @@ static void print_ct_blocks(uint8_t *data, size_t len) { static void print_sr_blocks(uint8_t *data, size_t len) { - size_t blocks = len / ST25TB_SR_BLOCK_SIZE; + size_t blocks = (len / ST25TB_SR_BLOCK_SIZE) -1 ; + uint8_t * systemblock = data + blocks * ST25TB_SR_BLOCK_SIZE ; uint8_t chipid = get_st_chipid(data); PrintAndLogEx(SUCCESS, _GREEN_("%s") " tag", get_st_chip_model(chipid)); - PrintAndLogEx(DEBUG, "systemblock : %s", sprint_hex(data + (blocks * 4), 4)); - PrintAndLogEx(DEBUG, " otp lock : %02x %02x", data[(blocks * 4)], data[(blocks * 4) + 1]); + PrintAndLogEx(DEBUG, "systemblock : %s", sprint_hex(systemblock, ST25TB_SR_BLOCK_SIZE)); + PrintAndLogEx(DEBUG, " otp lock : %02x %02x", *systemblock, *(systemblock + 1)); print_hdr(); - for (int i = 0; i <= blocks; i++) { + for (int i = 0; i < blocks; i++) { PrintAndLogEx(INFO, "%3d/0x%02X | %s | %s | %s", i, i, - sprint_hex(data + (i * 4), 4), - get_st_lock_info(chipid, data + (blocks * 4), i), - sprint_ascii(data + (i * 4), 4) + sprint_hex(data + (i * ST25TB_SR_BLOCK_SIZE), ST25TB_SR_BLOCK_SIZE), + get_st_lock_info(chipid, systemblock, i), + sprint_ascii(data + (i * ST25TB_SR_BLOCK_SIZE), ST25TB_SR_BLOCK_SIZE) ); } @@ -813,9 +814,9 @@ static void print_sr_blocks(uint8_t *data, size_t len) { "%3d/0x%02X | %s | %s | %s", 0xFF, 0xFF, - sprint_hex(data + (0xFF * 4), 4), - get_st_lock_info(chipid, data + (blocks * 4), 0xFF), - sprint_ascii(data + (0xFF * 4), 4) + sprint_hex(systemblock, ST25TB_SR_BLOCK_SIZE), + get_st_lock_info(chipid, systemblock, 0xFF), + sprint_ascii(systemblock, ST25TB_SR_BLOCK_SIZE) ); print_footer(); @@ -1405,18 +1406,18 @@ static int CmdHF14BDump(const char *Cmd) { // 1 = 4096 // 2 = 512 uint8_t cardtype = get_st_cardsize(card.uid); - uint8_t blocks = 0; + uint8_t lastblock = 0; uint16_t cardsize = 0; switch (cardtype) { case 2: - cardsize = (512 / 8) + 4; - blocks = 0x0F; + cardsize = (512 / 8) + ST25TB_SR_BLOCK_SIZE; + lastblock = 0x0F; break; case 1: default: - cardsize = (4096 / 8) + 4; - blocks = 0x7F; + cardsize = (4096 / 8) + ST25TB_SR_BLOCK_SIZE; + lastblock = 0x7F; break; } @@ -1486,15 +1487,15 @@ static int CmdHF14BDump(const char *Cmd) { // last read if (blocknum == 0xFF) { // we reserved space for this block after 0x0F and 0x7F, ie 0x10, 0x80 - memcpy(data + (blocks * 4), recv, 4); + memcpy(data + ((lastblock+1) * ST25TB_SR_BLOCK_SIZE), recv, ST25TB_SR_BLOCK_SIZE); break; } - memcpy(data + (blocknum * 4), recv, 4); + memcpy(data + (blocknum * ST25TB_SR_BLOCK_SIZE), recv, ST25TB_SR_BLOCK_SIZE); retry = 0; blocknum++; - if (blocknum > blocks) { + if (blocknum > lastblock) { // read config block blocknum = 0xFF; } @@ -1521,8 +1522,8 @@ static int CmdHF14BDump(const char *Cmd) { FillFileNameByUID(fptr, SwapEndian64(card.uid, card.uidlen, 8), "-dump", card.uidlen); } - size_t datalen = (blocks + 1) * 4; - pm3_save_dump(filename, data, datalen, jsf14b, 4); + size_t datalen = (lastblock + 2) * ST25TB_SR_BLOCK_SIZE; + pm3_save_dump(filename, data, datalen, jsf14b, ST25TB_SR_BLOCK_SIZE); } return switch_off_field_14b(); From ec5afd00ad4ba507000589c4bd71c7471c0484dc Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 20 Sep 2022 09:07:25 +0200 Subject: [PATCH 256/759] Update cmdlfparadox.c printing an used variable Signed-off-by: Iceman --- client/src/cmdlfparadox.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/src/cmdlfparadox.c b/client/src/cmdlfparadox.c index 328bda02c..f64c51be8 100644 --- a/client/src/cmdlfparadox.c +++ b/client/src/cmdlfparadox.c @@ -99,7 +99,7 @@ int demodParadox(bool verbose) { } uint32_t hi2 = 0, hi = 0, lo = 0; - uint8_t error = 0; + uint8_t errors = 0; // Remove manchester encoding from FSK bits, skip pre for (uint32_t i = idx + PARADOX_PREAMBLE_LEN; i < (idx + 96); i += 2) { @@ -107,7 +107,7 @@ int demodParadox(bool verbose) { // not manchester data if (bits[i] == bits[i + 1]) { PrintAndLogEx(WARNING, "Error Manchester at %u", i); - error++; + errors++; } hi2 = (hi2 << 1) | (hi >> 31); @@ -119,6 +119,10 @@ int demodParadox(bool verbose) { } } + if (errors) { + PrintAndLogEx(WARNING, "Total Manchester Errors... %u", errors); + } + setDemodBuff(bits, size, idx); setClockGrid(50, wave_idx + (idx * 50)); From 3e582b246a4557b1fa939be9958c826d83e22e3a Mon Sep 17 00:00:00 2001 From: DidierA Date: Tue, 20 Sep 2022 23:01:25 +0200 Subject: [PATCH 257/759] print_sr_blocks(): don't assume uid is at begining of dump --- client/src/cmdhf14b.c | 32 ++++++++++++++++++++++++++------ client/src/cmdhf14b.h | 1 + 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 7288c3251..1f6d62523 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -787,11 +787,11 @@ static void print_ct_blocks(uint8_t *data, size_t len) { } */ -static void print_sr_blocks(uint8_t *data, size_t len) { +static void print_sr_blocks(uint8_t *data, size_t len, const uint8_t *uid) { size_t blocks = (len / ST25TB_SR_BLOCK_SIZE) -1 ; uint8_t * systemblock = data + blocks * ST25TB_SR_BLOCK_SIZE ; - uint8_t chipid = get_st_chipid(data); + uint8_t chipid = get_st_chipid(uid); PrintAndLogEx(SUCCESS, _GREEN_("%s") " tag", get_st_chip_model(chipid)); PrintAndLogEx(DEBUG, "systemblock : %s", sprint_hex(systemblock, ST25TB_SR_BLOCK_SIZE)); @@ -1426,7 +1426,6 @@ static int CmdHF14BDump(const char *Cmd) { // detect blocksize from card :) PrintAndLogEx(INFO, "reading tag memory from UID " _GREEN_("%s"), sprint_hex_inrow(SwapEndian64(card.uid, card.uidlen, 8), card.uidlen)); - iso14b_raw_cmd_t *packet = (iso14b_raw_cmd_t *)calloc(1, sizeof(iso14b_raw_cmd_t) + 2); if (packet == NULL) { PrintAndLogEx(FAILED, "failed to allocate memory"); @@ -1513,7 +1512,7 @@ static int CmdHF14BDump(const char *Cmd) { return switch_off_field_14b(); } - print_sr_blocks(data, cardsize); + print_sr_blocks(data, cardsize, card.uid); // save to file if (fnlen < 1) { @@ -2104,6 +2103,28 @@ out: return res; } +/* extract uid from filename + * filename must match '^hf-14b-[0-9A-F]{16}' + */ +uint8_t * get_uid_from_filename(const char *filename) { + static uint8_t uid[8] ; + memset(uid, 0, 8) ; + char uidinhex[17] ; + if (strlen(filename)<23 || strncmp(filename, "hf-14b-", 7)) { + PrintAndLogEx(ERR, "can't get uid from filename '%s'. Expected format is hf-14b-...", filename); + return uid ; + } + // extract uid part from filename + strncpy(uidinhex, filename+7, 16) ; uidinhex[16]='\0' ; + int len=hex_to_bytes(uidinhex, uid, 8); + if (len == 8) + return SwapEndian64(uid , 8, 8); + else { + PrintAndLogEx(ERR, "get_uid_from_filename failed: hex_to_bytes returned %d", len); + memset(uid, 0, 8); + } + return uid ; +} static int CmdHF14BView(const char *Cmd) { @@ -2142,8 +2163,7 @@ static int CmdHF14BView(const char *Cmd) { // figure out a way to identify the different dump files. // STD/SR/CT is difference - - print_sr_blocks(dump, bytes_read); + print_sr_blocks(dump, bytes_read, get_uid_from_filename(filename)); //print_std_blocks(dump, bytes_read); //print_ct_blocks(dump, bytes_read); diff --git a/client/src/cmdhf14b.h b/client/src/cmdhf14b.h index b81149722..06cd637b9 100644 --- a/client/src/cmdhf14b.h +++ b/client/src/cmdhf14b.h @@ -25,6 +25,7 @@ int CmdHF14B(const char *Cmd); int CmdHF14BNdefRead(const char *Cmd); +uint8_t * get_uid_from_filename(const char *filename); int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool leave_signal_on, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, int user_timeout); int select_card_14443b_4(bool disconnect, iso14b_card_select_t *card); From a3b530108adbe40eef85b05df36e0f21660b1626 Mon Sep 17 00:00:00 2001 From: DidierA Date: Tue, 20 Sep 2022 23:18:40 +0200 Subject: [PATCH 258/759] forgot to update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2023e24bc..824c19966 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] + - Changed `hf 14b dump, view` to get correct chip type in case of SRT512 and friends (@DidierA) - Added `hf 15 eview` and `hf 15 esave` - Retrieve emulator image for ISO15693 simulation (@markus-oehme-pg40) - Changed `hf 15 sim` - now supports reader writes (@markus-oehme-pg40) - Added `hf 15 eload` - specify memory image for ISO15693 simulation (@markus-oehme-pg40) From 161731971f562baf5cbdd27824724a4f9d44419b Mon Sep 17 00:00:00 2001 From: Equip <72751518+equipter@users.noreply.github.com> Date: Thu, 22 Sep 2022 21:24:09 +0100 Subject: [PATCH 259/759] Update mfc_default_keys.dic moved 199404281970 and 199404281998 to #66 after discovering they're universal keys for this brand of reader which are over 90% of the uk's student accommodation and housing resource access control so they're very common :) thanks --- client/dictionaries/mfc_default_keys.dic | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 793b625c3..94f3bbd78 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -64,6 +64,10 @@ f1d83f964314 # RKF RejskortDanmark KeyB # Access control system 605F5E5D5C5B # +#NSP Global keys A and B (uk housing access control) +199404281970 +199404281998 +# # more Keys from mfc_default_keys.lua 000000000001 000000000002 @@ -1498,10 +1502,6 @@ fed791829013 668091829013 00008627c10a # -# keys from NSP Manchester University UK Accomodation Staff and students -199404281970 -199404281998 -# # easycard 310D51E539CA 2CCDA1358323 From ba1def2409b41ba517c1c5b8d59626bc3a2877ca Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Sep 2022 04:12:51 +0200 Subject: [PATCH 260/759] added well used keys --- client/src/mifare/mifaredefault.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/mifare/mifaredefault.h b/client/src/mifare/mifaredefault.h index 752679f33..ee9846240 100644 --- a/client/src/mifare/mifaredefault.h +++ b/client/src/mifare/mifaredefault.h @@ -45,7 +45,7 @@ static const uint64_t g_mifare_default_keys[] = { 0x0000014b5c31, 0xb578f38a5c61, 0x96a301bce267, - 0xfc00018778f7, + 0xfc00018778f7, // Public Transport 0x6471a5ef2d1a, // SimonsVoss 0x4E3552426B32, // ID06 0x6A1987C40A21, // Salto @@ -66,6 +66,8 @@ static const uint64_t g_mifare_default_keys[] = { 0x857464D3AAD1, // HTC Eindhoven key 0x08B386463229, // troika 0xe00000000000, // icopy + 0x199404281970, // NSP A + 0x199404281998, // NSP B }; static const uint8_t g_mifare_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}; From b82a8c288f3d904b6ec88f0d467362bc87518282 Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Thu, 29 Sep 2022 15:06:24 +0100 Subject: [PATCH 261/759] Removed Duplicates from t55xx_default_pwds L73 is the same as L152 and L13 is the same as L42 Signed-off-by: amec0e <88857687+amec0e@users.noreply.github.com> --- client/dictionaries/t55xx_default_pwds.dic | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/dictionaries/t55xx_default_pwds.dic b/client/dictionaries/t55xx_default_pwds.dic index 2b7f89947..99a4e42e8 100644 --- a/client/dictionaries/t55xx_default_pwds.dic +++ b/client/dictionaries/t55xx_default_pwds.dic @@ -38,8 +38,6 @@ E9920427 50520901 # iCopy-X 20206666 -# ID/HID CARD COPER SK-663 -65857569 # password found on discord 5469616E # wCopy NSR102-IDIC @@ -149,4 +147,3 @@ F1EA5EED # burtle 57721566 # euler constant (dec) 93C467E3 # euler constant (hex) 27182818 # natural log -50415353 # PASS From 0bae139adfc874e5de2d28d519d77e6156b77ab9 Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Thu, 29 Sep 2022 15:32:41 +0100 Subject: [PATCH 262/759] Removed duplicate entries L550 same as L1544, L548 same as L1550, L632 same as L1749 Signed-off-by: amec0e <88857687+amec0e@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 94f3bbd78..4253b5226 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1541,13 +1541,11 @@ F5C1B3F62FDA # # SUBE cards keys (old) # -7B296F353C6B 4C5A766DFE3A 32C6768847F5 F68930789631 8B42B6D64B02 B627A3CB13F8 -3FA7217EC575 562A4FB8260B 88DDC24E1671 91CB7802A559 @@ -1746,7 +1744,6 @@ FFD46FF6C5EE # Peppers Hotel Unknown location from D4DB0D 6E0DD4136B0A A0A1A2A3A4A5 -B578F38A5C61 141940E9B71B 0000014B5C31 3B1D3AAC866E From 350e2a81ca1781dfa7987693213b086fd399cfb8 Mon Sep 17 00:00:00 2001 From: elcuervo Date: Thu, 29 Sep 2022 15:46:15 -0300 Subject: [PATCH 263/759] Adds Uruguay shared key --- client/dictionaries/mfc_default_keys.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 94f3bbd78..49ff1d2e0 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1817,3 +1817,5 @@ AAAAAAFFFFFF FFFFFFAAAAAA # Added by VideoMan. 3111A3A303EB # Random Hotel A Key Sec 0 Blk 3 - KABA Lock +# Transport system Uruguay +D144BD193063 # Shared key From 1e508d2f23cab0bd1da96cfb814cf7183131c24f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 29 Sep 2022 21:18:32 +0200 Subject: [PATCH 264/759] remove another duplicate and keep some comments --- client/dictionaries/mfc_default_keys.dic | 1 - client/dictionaries/t55xx_default_pwds.dic | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 2acc47f79..24ae7c330 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1743,7 +1743,6 @@ FFD46FF6C5EE # The Westin Jakarta Indonesia from D4DB0D # Peppers Hotel Unknown location from D4DB0D 6E0DD4136B0A -A0A1A2A3A4A5 141940E9B71B 0000014B5C31 3B1D3AAC866E diff --git a/client/dictionaries/t55xx_default_pwds.dic b/client/dictionaries/t55xx_default_pwds.dic index 99a4e42e8..7fb494658 100644 --- a/client/dictionaries/t55xx_default_pwds.dic +++ b/client/dictionaries/t55xx_default_pwds.dic @@ -10,6 +10,7 @@ # blue gun EM4305 F9DCEBA0 # chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com) +# ID/HID CARD COPER SK-663 65857569 # ref. http://kazus.ru/forums/showpost.php?p=1045937&postcount=77 05D73B9F @@ -25,6 +26,8 @@ A5B4C3D2 1C0B5848 # ref. http://www.proxmark.org/forum/viewtopic.php?pid=35075#p35075 00434343 +# default PASS +50415353 # DNGR - DT default pwd 444E4752 4E457854 @@ -68,7 +71,6 @@ EEEEEEEE FFFFFFFF a0a1a2a3 b0b1b2b3 -50415353 00000001 00000002 0000000a From 1e54a65f021088eb6b40db5cc81ab564014eebb1 Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Fri, 30 Sep 2022 14:40:28 +0100 Subject: [PATCH 265/759] Removed another duplicate L628 same as L1747 Signed-off-by: amec0e <88857687+amec0e@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 1 - 1 file changed, 1 deletion(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 24ae7c330..f3284a448 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1744,7 +1744,6 @@ FFD46FF6C5EE # Peppers Hotel Unknown location from D4DB0D 6E0DD4136B0A 141940E9B71B -0000014B5C31 3B1D3AAC866E 95E9EE4CCF8F FEA6B332F04A From 3e7c0f4c450521107c22eab1e629686615153212 Mon Sep 17 00:00:00 2001 From: Iceman Date: Sun, 2 Oct 2022 15:30:48 +0200 Subject: [PATCH 266/759] Update jtag_notes.md Signed-off-by: Iceman --- doc/jtag_notes.md | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/doc/jtag_notes.md b/doc/jtag_notes.md index eaea64b6e..e5fc2dd99 100644 --- a/doc/jtag_notes.md +++ b/doc/jtag_notes.md @@ -57,34 +57,43 @@ You can also make yours with some 1.27mm headers (look for `1.27mm header` on Al J-Link [pinout](https://www.segger.com/interface-description.html): ``` - --------- --------- - |1917151311 9 7 5 3 1| - |201816141210 8 6 4 2| - -------------------- +Pin cut-out on a JLink 20 pin connector + + ^^ + -------------- --------- + |19 17 15 13 11 9 7 5 3 1| + |20 18 16 14 12 10 8 6 4 2| + ------------------------- ``` +``` +Map of pins between PM3 / JLink + PM3 | JLink --- | ----- -TMS | 7 -TDI | 5 -TDO |13 -TCK | 9 -GND | 6 -3.3 | 2 +TMS | 7 +TDI | 5 +TDO | 13 +TCK | 9 +GND | 6 +3.3 | 2 +``` ## Raspberry Pi pinout ^[Top](#top) RPi [pinout](https://pinout.xyz/): +``` PM3 | RPi ---- | ----- +--- | --- TMS | 22 TDI | 19 TDO | 21 TCK | 23 -GND | 6 -3.3 | 1 +GND | 6 +3.3 | 1 +``` # Where to find more information? ^[Top](#top) @@ -125,4 +134,4 @@ https://stackoverflow.com/questions/48794076/error-halt-timed-out-wake-up-gdb/64 ^[Top](#top) Describes the SEGGER JLINK, JTAG process but be warned, this document is old. -https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/original_proxmark3/Compiling%20Proxmark%20source%20and%20firmware%20upgrading%20v1.pdf \ No newline at end of file +https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/original_proxmark3/Compiling%20Proxmark%20source%20and%20firmware%20upgrading%20v1.pdf From 4120e2fe9154edba0faffa6d3289d02894e65763 Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Tue, 4 Oct 2022 00:12:48 +0100 Subject: [PATCH 267/759] Updated mfc_default_keys Removed extra whitespaces, Uppercased all the keys, Grouped keys where grouping was possible, removed extra line comments (and some for example "data from..."), moved line comments to above the key. Hopefully this little spring clean will help in the future when checking for duplicates, please do check this thoroughly and make sure it is okay. Signed-off-by: amec0e <88857687+amec0e@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 1357 ++++++++++++---------- 1 file changed, 718 insertions(+), 639 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index f3284a448..492ef91b5 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -3,63 +3,87 @@ # -- iceman fork version -- # -- contribute to this list, sharing is caring -- # -ffffffffffff # Defaultkey(firstkeyusedbyprogramifnouserdefinedkey) -000000000000 # Blankkey -a0a1a2a3a4a5 # NFC Forum MADkey -A5A4A3A2A1A0 # MAD access key A (reversed) -89ECA97F8C2A # MAD access key B -b0b1b2b3b4b5 -c0c1c2c3c4c5 -d0d1d2d3d4d5 -aabbccddeeff -4d3a99c351dd -1a982c7e459a -d3f7d3f7d3f7 # key A Wien -5a1b85fce20a # key B Wien -714c5c886e97 -587ee5f9350f -a0478cc39091 -533cb6c723f6 -8fd0a4f256e9 -e00000000000 # iCopy-X -e7d6064c5860 -b27ccab30dbd +# Defaultkey(firstkeyusedbyprogramifnouserdefinedkey) +FFFFFFFFFFFF +# Blankkey +000000000000 +# NFC Forum MADkey +A0A1A2A3A4A5 +# MAD access key A (reversed) +A5A4A3A2A1A0 +# MAD access key B +89ECA97F8C2A # -d2ece8b9395e # lib / Nat Bieb +B0B1B2B3B4B5 +C0C1C2C3C4C5 +D0D1D2D3D4D5 +AABBCCDDEEFF +4D3A99C351DD +1A982C7E459A +# key A Wien +D3F7D3F7D3F7 +# key B Wien +5A1B85FCE20A +# +714C5C886E97 +587EE5F9350F +A0478CC39091 +533CB6C723F6 +8FD0A4F256E9 +# iCopy-X +E00000000000 +# +E7D6064C5860 +B27CCAB30DBD +# +# lib / Nat Bieb +D2ECE8B9395E # NSCP default key 1494E81663D7 # # Kiev keys -569369c5a0e5 # kiev -632193be1c3c # kiev -644672bd4afe # kiev -8fe644038790 # kiev -9de89e070277 # kiev -b5ff67cba951 # kiev / ov-chipkaart -eff603e1efe9 # kiev -f14ee7cae863 # kiev +569369C5A0E5 +632193BE1C3C +644672BD4AFE +8FE644038790 +9DE89E070277 +B5FF67CBA951 +EFF603E1EFE9 +F14EE7CAE863 # # RKF -fc00018778f7 # Västtrafiken KeyA, RKF ÖstgötaTrafiken KeyA -0297927c0f77 # Västtrafiken KeyA -54726176656c # Västtrafiken KeyA -00000ffe2488 # Västtrafiken KeyB -776974687573 # Västtrafiken KeyB -ee0042f88840 # Västtrafiken KeyB -26940b21ff5d # RKF SLKeyA -a64598a77478 # RKF SLKeyA -5c598c9c58b5 # RKF SLKeyB -e4d2770a89be # RKF SLKeyB -722bfcc5375f # RKF RejskortDanmark KeyA -f1d83f964314 # RKF RejskortDanmark KeyB -505249564141 # RKF JOJOPRIVAKeyA -505249564142 # RKF JOJOPRIVAKeyB -47524f555041 # RKF JOJOGROUPKeyA -47524f555042 # RKF JOJOGROUPKeyB -434f4d4d4f41 # RKF JOJOGROUPKeyA -434f4d4d4f42 # RKF JOJOGROUPKeyB -# -4b0b20107ccb # TNP3xxx +# Västtrafiken KeyA, RKF ÖstgötaTrafiken KeyA +FC00018778F7 +# Västtrafiken KeyA +0297927C0F77 +54726176656C +# Västtrafiken KeyB +00000FFE2488 +776974687573 +EE0042F88840 +# RKF SLKeyA +26940B21FF5D +A64598A77478 +# RKF SLKeyB +5C598C9C58B5 +E4D2770A89BE +# RKF RejskortDanmark KeyA +722BFCC5375F +# RKF RejskortDanmark KeyB +F1D83F964314 +# RKF JOJOPRIVAKeyA +505249564141 +# RKF JOJOPRIVAKeyB +505249564142 +# RKF JOJOGROUPKeyA +47524F555041 +434F4D4D4F41 +# RKF JOJOGROUPKeyB +47524F555042 +434F4D4D4F42 +# +# TNP3xxx +4B0B20107CCB # # Access control system 605F5E5D5C5B @@ -71,81 +95,95 @@ f1d83f964314 # RKF RejskortDanmark KeyB # more Keys from mfc_default_keys.lua 000000000001 000000000002 -00000000000a -00000000000b +00000000000A +00000000000B 010203040506 -0123456789ab +0123456789AB 100000000000 111111111111 -123456789abc -12f2ee3478c1 -14d446e33363 -1999a3554a55 +123456789ABC +12F2EE3478C1 +14D446E33363 +1999A3554A55 200000000000 222222222222 -27dd91f1fcf1 -2BA9621E0A36 # DirectoryandeventlogKeyB -4AF9D7ADEBE4 # DirectoryandeventlogKeyA +27DD91F1FCF1 +# DirectoryandeventlogKeyB +2BA9621E0A36 +# DirectoryandeventlogKeyA +4AF9D7ADEBE4 +# 333333333333 -33f974b42769 -34d1df9934c5 -43ab19ef5c31 +33F974B42769 +34D1DF9934C5 +43AB19EF5C31 444444444444 505249565441 505249565442 555555555555 -55f5a5dd38c9 +55F5A5DD38C9 666666666666 777777777777 888888888888 999999999999 -99c636334433 -a00000000000 -a053a292a4af -a94133013401 -aaaaaaaaaaaa -abcdef123456 # Keyfromladyada.net -b00000000000 -b127c6f41436 -bbbbbbbbbbbb -bd493a3962b6 -c934fe34d934 -cccccccccccc -dddddddddddd -eeeeeeeeeeee +99C636334433 +A00000000000 +A053A292A4AF +A94133013401 +AAAAAAAAAAAA +# Keyfromladyada.net +ABCDEF123456 +# +B00000000000 +B127C6F41436 +BBBBBBBBBBBB +BD493A3962B6 +C934FE34D934 +CCCCCCCCCCCC +DDDDDDDDDDDD +EEEEEEEEEEEE # # elevator -# data from forum +# data from forum FFFFFF545846 # -f1a97341a9fc -44ab09010845 # hotel system -85fed980ea5a # hotel system +F1A97341A9FC +# hotel system +44AB09010845 +85FED980EA5A # -43454952534E # ARD (fr) key A -4A2B29111213 # ARD (fr) key B +# ARD (fr) key A +43454952534E +# ARD (fr) key B +4A2B29111213 # 4143414F5250 -a9b43414F585 # Tehran Railway -1FB235AC1388 # Tehran Railway +# Tehran Railway +A9B43414F585 +1FB235AC1388 # # Data from http://irq5.io/2013/04/13/decoding-bcard-conference-badges/ -f4a9ef2afc6d # BCARD KeyB +# BCARD KeyB +F4A9EF2AFC6D # -# Data from ... -89eac97f8c2a # S0 B -43c7600dee6b # S4 A -0120bf672a64 # S6 A -fb0b20df1f34 # S6 B # -a9f953def0a3 +# S0 B +89EAC97F8C2A +# S4 A +43C7600DEE6B +# S6 A +0120BF672A64 +# S6 B +FB0B20DF1F34 +# +A9F953DEF0A3 # # Data from forum -74a386ad0a6d -3f7a5c2dbd81 -21edf95e7433 -c121ff19f681 -3d5d9996359a +74A386AD0A6D +3F7A5C2DBD81 +21EDF95E7433 +C121FF19F681 +3D5D9996359A # # Here be BIP keys... 3A42F33AF429 @@ -182,22 +220,29 @@ D49E2826664F 6A470D54127C # # Data from http://pastebin.com/AK9Bftpw -48ffe71294a0 # Länstrafiken i Västerbotten -e3429281efc1 # Länstrafiken i Västerbotten -16f21a82ec84 # Länstrafiken i Västerbotten -460722122510 # Länstrafiken i Västerbotten +# Länstrafiken i Västerbotten +48FFE71294A0 +E3429281EFC1 +16F21A82EC84 +460722122510 # # 3dprinter -AAFB06045877 # EPI Envisionte# 3dprinter +# EPI Envisionte# 3dprinter +AAFB06045877 # # gym -3e65e4fb65b3 # Fysiken A -25094df6f148 # Fysiken B -a05dbd98e0fc # CleverFit +# Fysiken A +3E65E4FB65B3 +# Fysiken B +25094DF6F148 +# CleverFit +A05DBD98E0FC # -d3b595e9dd63 # Hotel KeyCard -afbecd121004 # Hotel KeyCard -6471a5ef2d1a # SimonsVoss +# Hotel KeyCard +D3B595E9DD63 +AFBECD121004 +# SimonsVoss +6471A5EF2D1A # # ID06 4E3552426B32 @@ -210,7 +255,7 @@ D21762B2DE3B 0E83A374B513 1F1FFE000000 A10F303FC879 -1322285230b8 +1322285230B8 0C71BCFB7E72 C3C88C6340B8 F101622750B7 @@ -219,8 +264,8 @@ F101622750B7 7C335FB121B5 B39AE17435DC # -# -454841585443 # key A +# key A +454841585443 # # Data from http://pastebin.com/gQ6nk38G D39BB83F5297 @@ -253,45 +298,45 @@ A0B0C0D0E0F0 A1B1C1D1E1F1 # # Data from msk social -2735fc181807 -2aba9519f574 -84fd7f7a12b6 -186d8c4b93f9 -3a4bba8adaf0 -8765b17968a2 -40ead80721ce -0db5e6523f7c -51119dae5216 -83e3549ce42d -136bdb246cac -7de02a7f6025 -bf23a53c1f63 -cb9a1f2d7368 -c7c0adb3284f -9f131d8c2057 -67362d90f973 -6202a38f69e2 -100533b89331 -653a87594079 -d8a274b2e026 -b20b83cb145c -9afa6cb4fc3d -a229e68ad9e5 -49c2b5296ef4 +2735FC181807 +2ABA9519F574 +84FD7F7A12B6 +186D8C4B93F9 +3A4BBA8ADAF0 +8765B17968A2 +40EAD80721CE +0DB5E6523F7C +51119DAE5216 +83E3549CE42D +136BDB246CAC +7DE02A7F6025 +BF23A53C1F63 +CB9A1F2D7368 +C7C0ADB3284F +9F131D8C2057 +67362D90F973 +6202A38F69E2 +100533B89331 +653A87594079 +D8A274B2E026 +B20B83CB145C +9AFA6CB4FC3D +A229E68AD9E5 +49C2B5296EF4 # # Data from http://pastebin.com/RRJUEDCM -0d258fe90296 -e55a3ca71826 -a4f204203f56 -eeb420209d0c -911e52fd7ce4 -752fbb5b7b45 -66b03aca6ee9 -48734389edc3 -17193709adf4 -1acc3189578c -c2b7ec7d4eb1 -369a4663acd2 +0D258FE90296 +E55A3CA71826 +A4F204203F56 +EEB420209D0C +911E52FD7CE4 +752FBB5B7B45 +66B03ACA6EE9 +48734389EDC3 +17193709ADF4 +1ACC3189578C +C2B7EC7D4EB1 +369A4663ACD2 # # Data from https://github.com/zhangjingye03/zxcardumper # zxcard Key A/B @@ -299,144 +344,150 @@ c2b7ec7d4eb1 003003003003 # # Data from http://phreakerclub.com/forum/showthread.php?p=41266 -26973ea74321 -71f3a315ad26 -51044efb5aab -ac70ca327a04 -eb0a8ff88ade +26973EA74321 +71F3A315AD26 +51044EFB5AAB +AC70CA327A04 +EB0A8FF88ADE # # Transport system Metromoney -2803bcb0c7e1 -9c616585e26d -4fa9eb49f75e -2dade48942c5 -a160fcd5ec4c +2803BCB0C7E1 +9C616585E26D +4FA9EB49F75E +2DADE48942C5 +A160FCD5EC4C 112233445566 -361a62f35bc9 -# +361A62F35BC9 +# # Transport system Spain -83f3cb98c258 -070d486bc555 -a9b018868cc1 -9dcdb136110c -749934cc8ed3 -506db955f161 -f088a85e71d7 -72b458d60363 -70c714869dc7 -b32464412ee3 -f253c30568c4 -1c68315674ac -cfe63749080a -c1e6f8afc9ec -dd0de3ba08a6 -3d923eb73534 -ff94f86b09a6 -d61707ffdfb1 -8223205047b6 -9951a273dee7 -c9449301af93 -66695a45c9fa -89aa9d743812 -c41514defc07 -c52876869800 -5353b3aecb53 -2e4169a5c79d -4bb747e48c2a -6285a1c8eb5c -5145c34dba19 -25352912cd8d -81b20c274c3f +83F3CB98C258 +070D486BC555 +A9B018868CC1 +9DCDB136110C +749934CC8ED3 +506DB955F161 +F088A85E71D7 +72B458D60363 +70C714869DC7 +B32464412EE3 +F253C30568C4 +1C68315674AC +CFE63749080A +C1E6F8AFC9EC +DD0DE3BA08A6 +3D923EB73534 +FF94F86B09A6 +D61707FFDFB1 +8223205047B6 +9951A273DEE7 +C9449301AF93 +66695A45C9FA +89AA9D743812 +C41514DEFC07 +C52876869800 +5353B3AECB53 +2E4169A5C79D +4BB747E48C2A +6285A1C8EB5C +5145C34DBA19 +25352912CD8D +81B20C274C3F # # Data from mall -abba1234fcb0 # playland balikesir -314f495254ff # A trio bowling bahcelievler -4152414b4e41 # A trio bowling bahcelievler -4E474434FFFF # karinca park nigde +# playland balikesir +ABBA1234FCB0 +# A trio bowling bahcelievler +314F495254FF +4152414B4E41 +# karinca park nigde +4E474434FFFF # # Data from https://github.com/RadioWar/NFCGUI -44dd5a385aaf -21a600056cb0 -b1aca33180a5 -dd61eb6bce22 -1565a172770f -3e84d2612e2a -f23442436765 -79674f96c771 -87df99d496cb -c5132c8980bc -a21680c27773 -f26e21edcee2 -675557ecc92e -f4396e468114 -6db17c16b35b -4186562a5bb2 -2feae851c199 -db1a3338b2eb -157b10d84c6b -a643f952ea57 -df37dcb6afb3 -4c32baf326e0 -91ce16c07ac5 -3c5d1c2bcd18 -c3f19ec592a2 -f72a29005459 -185fa3438949 -321a695bd266 -d327083a60a7 -45635ef66ef3 -5481986d2d62 -cba6ae869ad5 -645a166b1eeb -a7abbc77cc9e -f792c4c76a5c -bfb6796a11db +44DD5A385AAF +21A600056CB0 +B1ACA33180A5 +DD61EB6BCE22 +1565A172770F +3E84D2612E2A +F23442436765 +79674F96C771 +87DF99D496CB +C5132C8980BC +A21680C27773 +F26E21EDCEE2 +675557ECC92E +F4396E468114 +6DB17C16B35B +4186562A5BB2 +2FEAE851C199 +DB1A3338B2EB +157B10D84C6B +A643F952EA57 +DF37DCB6AFB3 +4C32BAF326E0 +91CE16C07AC5 +3C5D1C2BCD18 +C3F19EC592A2 +F72A29005459 +185FA3438949 +321A695BD266 +D327083A60A7 +45635EF66EF3 +5481986D2D62 +CBA6AE869AD5 +645A166B1EEB +A7ABBC77CC9E +F792C4C76A5C +BFB6796A11DB # # Data from Salto A/B 6A1987C40A21 7F33625BC129 # # Data from forum -2338b4913111 +2338B4913111 # # Data from stoye -cb779c50e1bd -a27d3804c259 -003cc420001a -f9861526130f -381ece050fbd -a57186bdd2b9 -48c739e21a04 -36abf5874ed7 -649d2abbbd20 -bbe8fffcf363 -ab4e7045e97d -340e40f81cd8 -e4f65c0ef32c -d2a597d76936 -a920f32fe93a -86afd95200f7 -9b832a9881ff -26643965b16e -0c669993c776 -b468d1991af9 -d9a37831dce5 -2fc1f32f51b1 -0ffbf65b5a14 -c5cfe06d9ea3 -c0dece673829 +CB779C50E1BD +A27D3804C259 +003CC420001A +F9861526130F +381ECE050FBD +A57186BDD2B9 +48C739E21A04 +36ABF5874ED7 +649D2ABBBD20 +BBE8FFFCF363 +AB4E7045E97D +340E40F81CD8 +E4F65C0EF32C +D2A597D76936 +A920F32FE93A +86AFD95200F7 +9B832A9881FF +26643965B16E +0C669993C776 +B468D1991AF9 +D9A37831DCE5 +2FC1F32F51B1 +0FFBF65B5A14 +C5CFE06D9EA3 +C0DECE673829 # -a56c2df9a26d +A56C2DF9A26D # # Data from https://pastebin.com/vbwast74 # -68d3f7307c89 -568c9083f71c # Smart Rider. Western Australian Public Transport Cards +68D3F7307C89 +# Smart Rider. Western Australian Public Transport Cards +568C9083F71C # -# -97F5DA640B18 # Bangkok metro key -A8844B0BCA06 # Metro Valencia key -857464D3AAD1 # HTC Eindhoven key +# Bangkok metro key +97F5DA640B18 +# Metro Valencia key +A8844B0BCA06 +# HTC Eindhoven key +857464D3AAD1 # # Vigik Keys # Various sources : @@ -445,95 +496,103 @@ A8844B0BCA06 # Metro Valencia key # * Own dumps # # French VIGIK -314B49474956 # VIGIK1 A -564c505f4d41 # VIGIK1 B -ba5b895da162 # VIGIK1 B +# VIGIK1 A +314B49474956 +# VIGIK1 B +564C505F4D41 +BA5B895DA162 # # Vigik mystery Keys Mifare 1k EV1 (S50) -5c8ff9990da2 # 16 A -75ccb59c9bed # 17 A -d01afeeb890a # 16 B -4b791bea7bcc # 17 B +# 16 A +5C8FF9990DA2 +# 17 A +75CCB59C9BED +# 16 B +D01AFEEB890A +# 17 B +4B791BEA7BCC # -021209197591 # BTCINO UNDETERMINED SPREAKD 0x01->0x13 key -2ef720f2af76 -414c41524f4e -424c41524f4e -4a6352684677 -bf1f4424af76 -536653644c65 +# BTCINO UNDETERMINED SPREAKD 0x01->0x13 key +021209197591 +# +2EF720F2AF76 +414C41524F4E +424C41524F4E +4A6352684677 +BF1F4424AF76 +536653644C65 # # Intratone Cogelec # Data from http://bouzdeck.com/rfid/32-cloning-a-mifare-classic-1k-tag.html 484558414354 -a22ae129c013 -49fae4e3849f -38fcf33072e0 -8ad5517b4b18 -509359f131b1 -6c78928e1317 -aa0720018738 -a6cac2886412 -62d0c424ed8e -e64a986a5d94 -8fa1d601d0a2 -89347350bd36 -66d2b7dc39ef -6bc1e1ae547d -22729a9bd40f +A22AE129C013 +49FAE4E3849F +38FCF33072E0 +8AD5517B4B18 +509359F131B1 +6C78928E1317 +AA0720018738 +A6CAC2886412 +62D0C424ED8E +E64A986A5D94 +8FA1D601D0A2 +89347350BD36 +66D2B7DC39EF +6BC1E1AE547D +22729A9BD40F # # Data from https://dfir.lu/blog/cloning-a-mifare-classic-1k-tag.html -925b158f796f -fad63ecb5891 -bba840ba1c57 -cc6b3b3cd263 -6245e47352e6 -8ed41e8b8056 -2dd39a54e1f3 -6d4c5b3658d2 -1877ed29435a -52264716efde -961c0db4a7ed -703140fd6d86 -157c9a513fa5 -e2a5dc8e066f +925B158F796F +FAD63ECB5891 +BBA840BA1C57 +CC6B3B3CD263 +6245E47352E6 +8ED41E8B8056 +2DD39A54E1F3 +6D4C5B3658D2 +1877ED29435A +52264716EFDE +961C0DB4A7ED +703140FD6D86 +157C9A513FA5 +E2A5DC8E066F # # Data from forum, schlage 9691T fob -ef1232ab18a0 +EF1232AB18A0 # # Data from a oyster card -374bf468607f -bfc8e353af63 -15cafd6159f6 -62efd80ab715 -987a7f7f1a35 -c4104fa3c526 -4c961f23e6be -67546972bc69 -f4cd5d4c13ff -94414c1a07dc -16551d52fd20 -9cb290282f7d -77a84170b574 -ed646c83a4f3 -e703589db50b -513c85d06cde -95093f0b2e22 -543b01b27a95 -c6d375b99972 -ee4cc572b40e -5106ca7e4a69 -c96bd1ce607f -167a1be102e0 -a8d0d850a606 -a2abb693ce34 -7b296c40c486 -91f93a5564c9 -e10623e7a016 -b725f9cbf183 +374BF468607F +BFC8E353AF63 +15CAFD6159F6 +62EFD80AB715 +987A7F7F1A35 +C4104FA3C526 +4C961F23E6BE +67546972BC69 +F4CD5D4C13FF +94414C1A07DC +16551D52FD20 +9CB290282F7D +77A84170B574 +ED646C83A4F3 +E703589DB50B +513C85D06CDE +95093F0B2E22 +543B01B27A95 +C6D375B99972 +EE4CC572B40E +5106CA7E4A69 +C96BD1CE607F +167A1BE102E0 +A8D0D850A606 +A2ABB693CE34 +7B296C40C486 +91F93A5564C9 +E10623E7A016 +B725F9CBF183 # # Data from FDi tag -8829da9daf76 +8829DA9DAF76 # # Data from GitHub issue 0A7932DC7E65 @@ -565,11 +624,11 @@ E241E8AFCBAF 050908080008 # # Data from hoist -4f9f59c9c875 +4F9F59C9C875 # # Data from pastebin -66f3ed00fed7 -f7a39753d018 +66F3ED00FED7 +F7A39753D018 # # Data from https://pastebin.com/Z7pEeZif 386B4D634A65 @@ -604,28 +663,28 @@ f7a39753d018 77646B633657 # # Data from TransPert -2031d1e57a3b -53c11f90822a -9189449ea24e +2031D1E57A3B +53C11F90822A +9189449EA24E # # data from Github -410b9b40b872 -2cb1a90071c8 +410B9B40B872 +2CB1A90071C8 # -# data from 8697389ACA26 1AB23CD45EF6 013889343891 # # -0000000018de -16ddcb6b3f24 +0000000018DE +16DDCB6B3F24 # # Data from https://pastebin.com/vwDRZW7d -EC0A9B1A9E06 # Vingcard Mifare 4k Staff card -6C94E1CED026 # Vingcard Mifare 4k Staff card -0F230695923F # Vingcard Mifare 4k Staff card -0000014B5C31 # Vingcard Mifare 4k Staff card +# Vingcard Mifare 4k Staff card +EC0A9B1A9E06 +6C94E1CED026 +0F230695923F +0000014B5C31 # BEDB604CC9D1 B8A1F613CF3D @@ -635,91 +694,101 @@ B66AC040203A 2E641D99AD5B AD4FB33388BF 69FB7B7CD8EE -2A6D9205E7CA # Hotel -2a2c13cc242a # KABA Hotel Locks +# Hotel +2A6D9205E7CA +13B91C226E56 +# KABA Hotel Locks +2A2C13CC242A +# 27FBC86A00D0 01FA3FC68349 # -13B91C226E56 # Hotel +# Smart Rider. Western Australian Public Transport Cards +6D44B5AAF464 +1717E34A7A8A # -6D44B5AAF464 # Smart Rider. Western Australian Public Transport Cards -1717E34A7A8A # Smart Rider. Western Australian Public Transport Cards +# RFIDeas +6B6579737472 # -6B6579737472 # RFIDeas +# HID MIFARE Classic 1k Key +484944204953 +204752454154 +# HID MIFARE SO +3B7E4FD575AD +11496F97752A # -484944204953 # HID MIFARE Classic 1k Key -204752454154 # HID MIFARE Classic 1k Key -3B7E4FD575AD # HID MIFARE SO -11496F97752A # HID MIFARE SO +# Luxeo/Aztek cashless vending +415A54454B4D # -415A54454B4D # Luxeo/Aztek cashless vending +# BQT +321958042333 # -321958042333 # BQT +# Aperio KEY_A Sector 1, 12, 13, 14, 15 Data Start 0 Length 48 +160A91D29A9C # -160A91D29A9C # Aperio KEY_A Sector 1, 12, 13, 14, 15 Data Start 0 Length 48 -# -b7bf0c13066e # Gallagher +# Gallagher +B7BF0C13066E # # PIK Comfort Moscow keys (ISBC Mifare Plus SE 1K) 009FB42D98ED 002E626E2820 # # Boston, MA, USA Transit - MBTA Charlie Card -3060206f5b0a # charlie -5ec39b022f2b # charlie -3a09594c8587 # charlie -f1b9f5669cc8 # charlie -f662248e7e89 # charlie -62387b8d250d # charlie -f238d78ff48f # charlie -9dc282d46217 # charlie -afd0ba94d624 # charlie -92ee4dc87191 # charlie -b35a0e4acc09 # charlie -756ef55e2507 # charlie -447ab7fd5a6b # charlie -932b9cb730ef # charlie -1f1a0a111b5b # charlie -ad9e0a1ca2f7 # charlie -d58023ba2bdc # charlie -62ced42a6d87 # charlie -2548a443df28 # charlie -2ed3b15e7c0f # charlie -f66224ee1e89 # charlie +3060206F5B0A +5EC39B022F2B +3A09594C8587 +F1B9F5669CC8 +F662248E7E89 +62387B8D250D +F238D78FF48F +9DC282D46217 +AFD0BA94D624 +92EE4DC87191 +B35A0E4ACC09 +756EF55E2507 +447AB7FD5A6B +932B9CB730EF +1F1A0A111B5B +AD9E0A1CA2F7 +D58023BA2BDC +62CED42A6D87 +2548A443DF28 +2ED3B15E7C0F +F66224EE1E89 # -60012e9ba3fa +60012E9BA3FA # -de1fcbec764b -81bfbe8cacba -bff123126c9b -2f47741062a0 -b4166b0a27ea -a170d9b59f95 -400bc9be8976 -d80511fc2ab4 -1fcef3005bcf -bb467463acd6 -e67c8010502d -ff58ba1b4478 +DE1FCBEC764B +81BFBE8CACBA +BFF123126C9B +2F47741062A0 +B4166B0A27EA +A170D9B59F95 +400BC9BE8976 +D80511FC2AB4 +1FCEF3005BCF +BB467463ACD6 +E67C8010502D +FF58BA1B4478 # Data from https://pastebin.com/Kz8xp4ev -fbf225dc5d58 +FBF225DC5D58 # # Data https://pastebin.com/BEm6bdAE # vingcard.txt -4708111c8604 -3d50d902ea48 -96a301bce267 -6700f10fec09 -7a09cc1db70a -560f7cff2d81 -66b31e64ca4b -9e53491f685b -3a09911d860c -8a036920ac0c -361f69d2c462 -d9bcde7fc489 -0c03a720f208 -6018522fac02 +4708111C8604 +3D50D902EA48 +96A301BCE267 +6700F10FEC09 +7A09CC1DB70A +560F7CFF2D81 +66B31E64CA4B +9E53491F685B +3A09911D860C +8A036920AC0C +361F69D2C462 +D9BCDE7FC489 +0C03A720F208 +6018522FAC02 # # Data from https://pastebin.com/4t2yFMgt # Mifare technische Universität Graz TUG @@ -728,9 +797,10 @@ D58660D1ACDE C01FC822C6E5 0854BF31111E # More keys: -8a19d40cf2b5 -ae8587108640 -135b88a94b8b # SafLock standalone door locks. +8A19D40CF2B5 +AE8587108640 +# SafLock standalone door locks. +135B88A94B8B # # Russian Troika card 08B386463229 @@ -840,12 +910,12 @@ E56AC127DD45 EA0FD73CB149 FC0001877BF7 FD8705E721B0 -00ada2cd516d +00ADA2CD516D # # ## -237a4d0d9119 -0ed7846c2bc9 +237A4D0D9119 +0ED7846C2BC9 FFFFD06F83E3 FFFFAE82366C F89C86B2A961 @@ -896,9 +966,10 @@ A2B2C9D187FB A2F63A485632 98631ED2B229 19F1FFE02563 -563A22C01FC8 # Argentina -43CA22C13091 # Argentina -25094DF2C1BD # Argentina +# Argentina +563A22C01FC8 +43CA22C13091 +25094DF2C1BD # # OMNITEC.ES HOTEL TIMECARD / MAINTENANCECARD AFBECD120454 @@ -996,38 +1067,38 @@ A7FB4824ACBF # # Transportes Insular La Palma # -0172066b2f03 -0000085f0000 -1a80b93f7107 -70172066b2f0 -b1a80c94f710 -0b0172066b2f -0f1a81c95071 -f0f0172066b2 -1131a81d9507 -2f130172066b -71171a82d951 -b2f170172066 -1711b1a82e96 -6b2f1b017206 -62711f1a83e9 -66b2f1f01720 -97271231a83f -066b2f230172 -f97371271a84 -2066b2f27017 -50983712b1a8 -72066b2f2b01 -850984712f1a -172066b2f2f0 -a85198481331 -0172066b2f33 -1a8619858137 -70172066b2f3 -b1a862985913 -3b0172066b2f -3f1a87298691 -f3f0172066b2 +0172066B2F03 +0000085F0000 +1A80B93F7107 +70172066B2F0 +B1A80C94F710 +0B0172066B2F +0F1A81C95071 +F0F0172066B2 +1131A81D9507 +2F130172066B +71171A82D951 +B2F170172066 +1711B1A82E96 +6B2F1B017206 +62711F1A83E9 +66B2F1F01720 +97271231A83F +066B2F230172 +F97371271A84 +2066B2F27017 +50983712B1A8 +72066B2F2B01 +850984712F1A +172066B2F2F0 +A85198481331 +0172066B2F33 +1A8619858137 +70172066B2F3 +B1A862985913 +3B0172066B2F +3F1A87298691 +F3F0172066B2 # # Tehran ezpay # @@ -1043,15 +1114,15 @@ EEC0626B01A1 D3B1C7EA5C53 41C82D231497 0B8B21C692C2 -604Ac8D87C7E +604AC8D87C7E 8E7B29460F12 BB3D7B11D224 # # Chaco # -b210cfa436d2 -b8b1cfa646a8 -a9f95891f0a4 +B210CFA436D2 +B8B1CFA646A8 +A9F95891F0A4 # # Keys from APK application "Scan Badge" 4A4C474F524D @@ -1076,39 +1147,39 @@ B069D0D03D17 # # From the DFW Area, TX, USA # -a506370e7c0f -26396f2042e7 -70758fdd31e0 -9f9d8eeddcce -06ff5f03aa1a -4098653289d3 -904735f00f9e -b4c36c79da8d -68f9a1f0b424 -5a85536395b3 -7dd399d4e897 -ef4c5a7ac6fc -b47058139187 -8268046cd154 -67cc03b7d577 +A506370E7C0F +26396F2042E7 +70758FDD31E0 +9F9D8EEDDCCE +06FF5F03AA1A +4098653289D3 +904735F00F9E +B4C36C79DA8D +68F9A1F0B424 +5A85536395B3 +7DD399D4E897 +EF4C5A7AC6FC +B47058139187 +8268046CD154 +67CC03B7D577 # # From the HTL Mödling, NÖ, AT # -a5524645cd91 -d964406e67b4 -99858a49c119 -7b7e752b6a2d -c27d999912ea -66a163ba82b4 -4c60f4b15ba8 +A5524645CD91 +D964406E67B4 +99858A49C119 +7B7E752B6A2D +C27D999912EA +66A163BA82B4 +4C60F4B15BA8 # # CAFE + CO, AT # -35d850d10a24 -4b511f4d28dd -e45230e7a9e8 -535f47d35e39 -fb6c88b7e279 +35D850D10A24 +4B511F4D28DD +E45230E7A9E8 +535F47D35E39 +FB6C88B7E279 # # Metro Card, AT # @@ -1116,110 +1187,115 @@ fb6c88b7e279 # # Unknown, AT # -23d4cdff8da3 -e6849fcc324b -12fd3a94df0e +23D4CDFF8DA3 +E6849FCC324B +12FD3A94DF0E # # Unknown, AT # -0b83797a9c64 -39ad2963d3d1 -34b16cd59ff8 # Hotel Berlin Classic room A KEY -bb2c0007d022 # Hotel Berlin Classic room B KEY +0B83797A9C64 +39AD2963D3D1 +# Hotel Berlin Classic room A KEY +34B16CD59FF8 +# Hotel Berlin Classic room B KEY +BB2C0007D022 # # Coinmatic laundry Smart card # data from: https://pastebin.com/XZQiLtUf # -0734bfb93dab -85a438f72a8a +0734BFB93DAB +85A438F72A8A # # Data from forum, Chinese hotel -58ac17bf3629 -b62307b62307 +58AC17BF3629 +B62307B62307 # -a2a3cca2a3cc +A2A3CCA2A3CC # # Granada, ES Transport Card 000000270000 -0f385ffb6529 -29173860fc76 -2fca8492f386 -385efa542907 -3864fcba5937 -3f3865fccb69 -6291b3860fc8 -63fca9492f38 -863fcb959373 -87291f3861fc -913385ffb752 -b385efa64290 -c9739233861f -f3864fcca693 -fc9839273862 +0F385FFB6529 +29173860FC76 +2FCA8492F386 +385EFA542907 +3864FCBA5937 +3F3865FCCB69 +6291B3860FC8 +63FCA9492F38 +863FCB959373 +87291F3861FC +913385FFB752 +B385EFA64290 +C9739233861F +F3864FCCA693 +FC9839273862 # # various hotel keys 34D3C568B348 91FF18E63887 4D8B8B95FDEE 354A787087F1 -4a306e62e9b6 +4A306E62E9B6 B9C874AE63D0 # # Data from official repo -f00dfeedd0d0 -0bb31dc123e5 -7578bf2c66a9 -cd212889c3ed -6936c035ae1b -c6c866aa421e -590bd659cdd2 -aa734d2f40e0 -09800ff94aaf -5a12f83326e7 -c554ef6a6015 -0d8ca561bdf3 -b8937130b6ba -d7744a1a0c44 -82908b57ef4f -fe04ecfe5577 +F00DFEEDD0D0 +0BB31DC123E5 +7578BF2C66A9 +CD212889C3ED +6936C035AE1B +C6C866AA421E +590BD659CDD2 +AA734D2F40E0 +09800FF94AAF +5A12F83326E7 +C554EF6A6015 +0D8CA561BDF3 +B8937130B6BA +D7744A1A0C44 +82908B57EF4F +FE04ECFE5577 # comfort inn hotel -4d57414c5648 -4d48414c5648 -# -# unknown hotel key -6d9b485a4845 +4D57414C5648 +4D48414C5648 # -5a7a52d5e20d # Bosch Solution 6000 +# unknown hotel key +6D9B485A4845 +# +# Bosch Solution 6000 +5A7A52D5E20D # # Found in TagInfo app -C1E51C63B8F5 # RATB key +# RATB key +C1E51C63B8F5 1DB710648A65 -18F34C92A56E # E-GO card key +# E-GO card key +18F34C92A56E # # Library Card MFP - SL1 -4a832584637d -ca679d6291b0 -30d9690fc5bc -5296c26109d4 -e77952748484 -91c2376005a1 -30b7680b2bc9 -e2a9e88bfe16 -43b04995d234 -aade86b1f9c1 -5ea088c824c9 -c67beb41ffbf -b84d52971107 -52b0d3f6116e +4A832584637D +CA679D6291B0 +30D9690FC5BC +5296C26109D4 +E77952748484 +91C2376005A1 +30B7680B2BC9 +E2A9E88BFE16 +43B04995D234 +AADE86B1F9C1 +5EA088C824C9 +C67BEB41FFBF +B84D52971107 +52B0D3F6116E # # Data from https://pastebin.com/cLSQQ9xN -ca3a24669d45 -4087c6a75a96 -403f09848b87 -d73438698eea -5f31f6fcd3a0 -a0974382c4c5 -a82045a10949 +CA3A24669D45 +4087C6A75A96 +403F09848B87 +D73438698EEA +5F31F6FCD3A0 +A0974382C4C5 +A82045A10949 # # Data from https://pastebin.com/2iV8h93h # @@ -1352,16 +1428,16 @@ AABAFFCC7612 17D071403C20 # 534F4C415249 -534f4c303232 +534F4C303232 # # Nespresso, smart card # key-gen algo, these keys are for one card -ff9a84635bd2 -6f30126ee7e4 -6039abb101bb -f1a1239a4487 +FF9A84635BD2 +6F30126EE7E4 +6039ABB101BB +F1A1239A4487 # -b882fd4a9f78 +B882FD4A9F78 CD7FFFF81C4A AA0857C641A3 C8AACD7CF3D1 @@ -1373,25 +1449,25 @@ A7395CCB42A0 D14E615E0545 69D92108C8B5 703265497350 -D75971531042 -10510049D725 -35C649004000 +D75971531042 +10510049D725 +35C649004000 5B0C7EC83645 -05F5EC05133C -521B517352C7 -94B6A644DFF6 -2CA4A4D68B8E -A7765C952DDF -E2F14D0A0E28 -DC018FC1D126 -4927C97F1D57 -046154274C11 -155332417E00 -6B13935CD550 -C151D998C669 -D973D917A4C7 -130662240200 -9386E2A48280 +05F5EC05133C +521B517352C7 +94B6A644DFF6 +2CA4A4D68B8E +A7765C952DDF +E2F14D0A0E28 +DC018FC1D126 +4927C97F1D57 +046154274C11 +155332417E00 +6B13935CD550 +C151D998C669 +D973D917A4C7 +130662240200 +9386E2A48280 52750A0E592A 075D1A4DD323 32CA52054416 @@ -1401,54 +1477,56 @@ D973D917A4C7 1F0128447C00 411053C05273 42454C4C4147 -C428C4550A75 -730956C72BC2 -28D70900734C -4F75030AD12B -6307417353C1 +C428C4550A75 +730956C72BC2 +28D70900734C +4F75030AD12B +6307417353C1 D65561530174 D1F71E05AD9D -F7FA2F629BB1 -0E620691B9FE -43E69C28F08C -735175696421 -424C0FFBF657 +F7FA2F629BB1 +0E620691B9FE +43E69C28F08C +735175696421 +424C0FFBF657 51E97FFF51E9 -E7316853E731 -00460740D722 -35D152154017 -5D0762D13401 -0F35D5660653 -1170553E4304 -0C4233587119 -F678905568C3 -50240A68D1D8 -2E71D3BD262A -540D5E6355CC -D1417E431949 +E7316853E731 +00460740D722 +35D152154017 +5D0762D13401 +0F35D5660653 +1170553E4304 +0C4233587119 +F678905568C3 +50240A68D1D8 +2E71D3BD262A +540D5E6355CC +D1417E431949 4BF6DE347FB6 # # -3a471b2192bf -a297ceb7d34b -ae76242931f1 +3A471B2192BF +A297CEB7D34B +AE76242931F1 # # 124578ABFEDC ABFEDC124578 4578ABFEDC12 # -# Data from +# Data from # premier inn hotel chain -5e594208ef02 -af9e38d36582 +5E594208EF02 +AF9E38D36582 # #Norwegian building site identication card. (HMS KORT) -10DF4D1859C8 # Key a -B5244E79B0C8 # Key B +# Key a +10DF4D1859C8 +# Key B +B5244E79B0C8 # # Ukraine hotel -f5c1c4c5de34 +F5C1C4C5DE34 # # Data from Mifare Classic Tool repo # Rotterdam University of applied sciences campus card @@ -1476,7 +1554,7 @@ B290401B0CAD AD11006B0601 # # Data from Mifare Classic Tool repo -# Armenian Metro +# Armenian Metro E4410EF8ED2D 6A68A7D83E11 0D6057E8133B @@ -1487,20 +1565,20 @@ D3F3B958B8A3 CE99FBC8BD26 # # keys from Eurothermes group (Switzerland) -d66d91829013 -75b691829013 -83e391829013 -a23c91829013 -e46a91829013 -d9e091829013 -fed791829013 -155f91829013 -06cc91829013 -8ddc91829013 -54af91829013 -29a791829013 +D66D91829013 +75B691829013 +83E391829013 +A23C91829013 +E46A91829013 +D9E091829013 +FED791829013 +155F91829013 +06CC91829013 +8DDC91829013 +54AF91829013 +29A791829013 668091829013 -00008627c10a +00008627C10A # # easycard 310D51E539CA @@ -1568,7 +1646,6 @@ BFE25035B0C8 D5C172325DD3 992B152E834A CE75D7EADEAF - # Russian Podorozhnik card (Saint-Petersburg transport, may be combined with Troika) 038B5F9B5A2A 04DC35277635 @@ -1761,13 +1838,13 @@ B4B3FFEDBE0A # Vigik ScanBadge App (fr.badgevigik.scanbadge) # Website https://badge-vigik.fr/ - By Alex` 0000A2B3C86F -021200c20307 +021200C20307 021209197507 1E34B127AF9C 303041534956 4143532D494E 41454E521985 -43412d627400 +43412D627400 455249524345 456666456666 45B722C63319 @@ -1806,11 +1883,13 @@ A00003000057 # # BH USA 2013 conference 012279BAD3E5 -# +# # iGuard Simple (and reverse) keys AAAAAAFFFFFF FFFFFFAAAAAA # Added by VideoMan. -3111A3A303EB # Random Hotel A Key Sec 0 Blk 3 - KABA Lock +# Random Hotel A Key Sec 0 Blk 3 - KABA Lock +3111A3A303EB # Transport system Uruguay -D144BD193063 # Shared key +# Shared key +D144BD193063 From eba98a55773f89e7256b7aa0ee3e36ca21525028 Mon Sep 17 00:00:00 2001 From: amec0e <88857687+amec0e@users.noreply.github.com> Date: Wed, 5 Oct 2022 23:07:19 +0100 Subject: [PATCH 268/759] Clean up of t55xx_default_pwds Removed 1 whitespace, grouped some keys, uppercased keys and moved line comments to above the keys. Duplicate checked after and all is good, just another little spring clean (wasn't much I'll admit that) Signed-off-by: amec0e <88857687+amec0e@users.noreply.github.com> --- client/dictionaries/t55xx_default_pwds.dic | 63 +++++++++++++--------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/client/dictionaries/t55xx_default_pwds.dic b/client/dictionaries/t55xx_default_pwds.dic index 7fb494658..e56904ea4 100644 --- a/client/dictionaries/t55xx_default_pwds.dic +++ b/client/dictionaries/t55xx_default_pwds.dic @@ -7,7 +7,7 @@ # ref. http://www.proxmark.org/forum/viewtopic.php?pid=40662#p40662 # default PROX 50524F58 -# blue gun EM4305 +# blue gun EM4305 F9DCEBA0 # chinese "handheld RFID writer" blue cloner from circa 2013 (also sold by xfpga.com) # ID/HID CARD COPER SK-663 @@ -50,8 +50,8 @@ C0F5009A 07CEE75D # # prefered pwds of members in the community -feedbeef -deadc0de +FEEDBEEF +DEADC0DE # Default pwd, simple: 00000000 11111111 @@ -69,12 +69,12 @@ CCCCCCCC DDDDDDDD EEEEEEEE FFFFFFFF -a0a1a2a3 -b0b1b2b3 +A0A1A2A3 +B0B1B2B3 00000001 00000002 -0000000a -0000000b +0000000A +0000000B 01020304 02030405 03040506 @@ -118,8 +118,10 @@ F0000000 AABBCCDD BBCCDDEE CCDDEEFF -0CB7E7FC # rfidler? -FABADA11 # china? +# rfidler? +0CB7E7FC +# china? +FABADA11 # 20 most common len==8 87654321 12341234 @@ -130,22 +132,33 @@ FABADA11 # china? 11112222 13131313 10041004 +# pii +31415926 # -31415926 # pii -abcd1234 +ABCD1234 20002000 19721972 -aa55aa55 # amiboo -55aa55aa # rev amiboo -4f271149 # seeds ul-ev1 -07d7bb0b # seeds ul-ev1 -9636ef8f # seeds ul-ev1 -b5f44686 # seeds ul-ev1 -9E3779B9 # TEA -C6EF3720 # TEA -7854794A # xbox tea constant :) -F1EA5EED # burtle -69314718 # ln2 -57721566 # euler constant (dec) -93C467E3 # euler constant (hex) -27182818 # natural log +# rev amiboo +AA55AA55 +55AA55AA +# seeds ul-ev1 +4F271149 +07D7BB0B +9636EF8F +B5F44686 +# TEA +9E3779B9 +C6EF3720 +# +# xbox tea constant :) +7854794A +# burtle +F1EA5EED +# ln2 +69314718 +# euler constant (dec) +57721566 +# euler constant (hex) +93C467E3 +# natural log +27182818 From 250fdedeacd202315003d5f621db60140125f23d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 16 Oct 2022 09:19:13 +0200 Subject: [PATCH 269/759] adapt makefile to use sudo, echo, usermod, adduser, getent as variables --- Makefile | 20 ++++++++++---------- Makefile.defs | 10 +++++++++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index a846bd706..b072d7379 100644 --- a/Makefile +++ b/Makefile @@ -248,28 +248,28 @@ ifeq ($(PLATFORM_CHANGED),true) $(Q)$(MAKE) --no-print-directory -C recovery clean $(Q)$(MAKE) --no-print-directory -C client clean $(Q)$(MAKE) --no-print-directory -C tools/fpga_compress clean - $(Q)echo CACHED_PLATFORM=$(PLATFORM) > .Makefile.options.cache - $(Q)echo CACHED_PLATFORM_EXTRAS=$(PLATFORM_EXTRAS) >> .Makefile.options.cache - $(Q)echo CACHED_PLATFORM_DEFS=$(PLATFORM_DEFS) >> .Makefile.options.cache + $(Q)$(ECHO) CACHED_PLATFORM=$(PLATFORM) > .Makefile.options.cache + $(Q)$(ECHO) CACHED_PLATFORM_EXTRAS=$(PLATFORM_EXTRAS) >> .Makefile.options.cache + $(Q)$(ECHO) CACHED_PLATFORM_DEFS=$(PLATFORM_DEFS) >> .Makefile.options.cache endif # configure system to ignore PM3 device as a modem (ModemManager blacklist, effective *only* if ModemManager is not using _strict_ policy) # Read doc/md/ModemManager-Must-Be-Discarded.md for more info udev: - sudo cp -rf driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules - sudo udevadm control --reload-rules + $(SUDO) cp -rf driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules + $(SUDO) udevadm control --reload-rules -# configure system to add user to the dialout group +# configure system to add user to the dialout group and if bluetooth group exists, add user to it # you need to logout, relogin to get this access right correct. # Finally, you might need to run the proxmark3 client under SUDO on some systems accessrights: ifneq ($(wildcard /etc/arch-release),) #If user is running ArchLinux, use specific command and group - $(Q)sudo usermod -aG uucp $(USER) - $(Q)getent group bluetooth >/dev/null && sudo usermod -aG bluetooth $(USER) || true + $(Q)$(SUDO) $(USERMOD) uucp $(USER) + $(Q)$(GETENT_BL) >/dev/null && $(SUDO) $(USERMOD) bluetooth $(USER) || true else - $(Q)sudo adduser $(USER) dialout - $(Q)getent group bluetooth >/dev/null && sudo adduser $(USER) bluetooth || true + $(Q)$(SUDO) $(ADDUSER) $(USER) dialout + $(Q)$(GETENT_BL) >/dev/null && $(SUDO) $(ADDUSER) $(USER) bluetooth || true endif # easy printing of MAKE VARIABLES diff --git a/Makefile.defs b/Makefile.defs index bd5898477..8f9d5f271 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -37,7 +37,7 @@ FALSE = false TAR = tar TARFLAGS ?= -v --ignore-failed-read -r TARFLAGS += -C .. -f -CROSS ?= arm-none-eabi- +CROSS ?= arm-none-eabi- CC ?= gcc CXX ?= g++ SH = sh @@ -47,6 +47,14 @@ SWIG = swig CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null|sed 's/\..*//') CC_VERSION := $(or $(strip $(CC_VERSION)),0) +ECHO = echo +SUDO = sudo +USERMOD = usermod -aG +ADDUSER = adduser +GETENT_BL = getent group bluetooth + + + PATHSEP=/ PREFIX ?= /usr/local UDEV_PREFIX ?= /etc/udev/rules.d From be1c5305f86ae8e605fd6553bc48354790bc1dfb Mon Sep 17 00:00:00 2001 From: Alisander Date: Sun, 16 Oct 2022 14:26:51 +0200 Subject: [PATCH 270/759] Update cmdlfhitag.c correct issue where only 4 or 6 key are used. Signed-off-by: Alisander --- client/src/cmdlfhitag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 89a030d62..d439eb814 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -780,7 +780,7 @@ static int CmdLFHitagWriter(const char *Cmd) { } if (h24) { htf = WHT2F_CRYPTO; - memcpy(htd.pwd.password, key, 4); + memcpy(htd.pwd.password, key, 6); memcpy(htd.crypto.data, data, sizeof(data)); } if (h27) { From 885a43aadbe43132c8a659af7ba77b84cf023ffb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 16 Oct 2022 17:45:46 +0200 Subject: [PATCH 271/759] added a new command to format a MFC tag as NFC with NDEF empty message --- CHANGELOG.md | 1 + client/src/cmdhfmf.c | 240 +++++++++++++++++++++++++++--- client/src/cmdhfmf.h | 9 +- client/src/cmdnfc.c | 6 +- client/src/mifare/mifaredefault.h | 4 + 5 files changed, 238 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 824c19966..54f228540 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] + - Added `hf mf ndefformat` - format a MIFARE Classic tag as NFC tag with Data Exchange Format (NDEF) (@iceman1001) - Changed `hf 14b dump, view` to get correct chip type in case of SRT512 and friends (@DidierA) - Added `hf 15 eview` and `hf 15 esave` - Retrieve emulator image for ISO15693 simulation (@markus-oehme-pg40) - Changed `hf 15 sim` - now supports reader writes (@markus-oehme-pg40) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 1ea9a3055..53d3afb1b 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -19,21 +19,21 @@ #include "cmdhfmf.h" #include -#include "cmdparser.h" // command_t -#include "commonutil.h" // ARRAYLEN -#include "comms.h" // clearCommandBuffer +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "comms.h" // clearCommandBuffer #include "fileutils.h" #include "cmdtrace.h" -#include "mifare/mifaredefault.h" // mifare default key array -#include "cliparser.h" // argtable -#include "hardnested_bf_core.h" // SetSIMDInstr +#include "mifare/mifaredefault.h" // mifare default key array +#include "cliparser.h" // argtable +#include "hardnested_bf_core.h" // SetSIMDInstr #include "mifare/mad.h" #include "nfc/ndef.h" #include "protocols.h" -#include "util_posix.h" // msclock +#include "util_posix.h" // msclock #include "cmdhfmfhard.h" -#include "crapto1/crapto1.h" // prng_successor -#include "cmdhf14a.h" // exchange APDU +#include "crapto1/crapto1.h" // prng_successor +#include "cmdhf14a.h" // exchange APDU #include "crypto/libpcrypto.h" #include "wiegand_formats.h" #include "wiegand_formatutils.h" @@ -336,6 +336,23 @@ static void mf_print_sector_hdr(uint8_t sector) { PrintAndLogEx(INFO, "----+-------------------------------------------------+-----------------"); } +static bool mf_write_block(uint8_t *key, uint8_t keytype, uint8_t blockno, uint8_t *block) { + + uint8_t data[26]; + memcpy(data, key, MFKEY_SIZE); + memcpy(data + 10, block, MFBLOCK_SIZE); + + clearCommandBuffer(); + SendCommandMIX(CMD_HF_MIFARE_WRITEBL, blockno, keytype, 0, data, sizeof(data)); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { + PrintAndLogEx(FAILED, "Command execute timeout"); + return PM3_ETIMEOUT; + } + + return (resp.oldarg[0] & 0xff); +} + static int CmdHF14AMfAcl(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf acl", @@ -800,8 +817,8 @@ static int CmdHF14AMfDump(const char *Cmd) { // Read keys A from file size_t bytes_read; for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { - bytes_read = fread(keyA[sectorNo], 1, 6, f); - if (bytes_read != 6) { + bytes_read = fread(keyA[sectorNo], 1, MFKEY_SIZE, f); + if (bytes_read != MFKEY_SIZE) { PrintAndLogEx(ERR, "File reading error."); fclose(f); return PM3_EFILE; @@ -810,8 +827,8 @@ static int CmdHF14AMfDump(const char *Cmd) { // Read keys B from file for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { - bytes_read = fread(keyB[sectorNo], 1, 6, f); - if (bytes_read != 6) { + bytes_read = fread(keyB[sectorNo], 1, MFKEY_SIZE, f); + if (bytes_read != MFKEY_SIZE) { PrintAndLogEx(ERR, "File reading error."); fclose(f); return PM3_EFILE; @@ -5677,7 +5694,194 @@ int CmdHFMFNDEFRead(const char *Cmd) { return PM3_SUCCESS; } -static int CmdHFMFPersonalize(const char *cmd) { +// https://www.nxp.com/docs/en/application-note/AN1305.pdf +int CmdHFMFNDEFFormat(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf ndefformat", + "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF)\n" + "If no given, UID will be used as filename", + "hf mf ndefformat --mini --> MIFARE Mini\n" + "hf mf ndefformat --1k --> MIFARE Classic 1k\n" + "hf mf ndefformat --2k --> MIFARE 2k\n" + "hf mf ndefformat --4k --> MIFARE 4k\n" + "hf mf ndefformat --keys hf-mf-066C8B78-key.bin --> MIFARE 1k with keys from specified file\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_str0("k", "keys", "", "filename of keys"), + arg_lit0(NULL, "mini", "MIFARE Classic Mini / S20"), + arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50 (def)"), + arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), + arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + int keyfnlen = 0; + char keyFilename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)keyFilename, FILE_PATH_SIZE, &keyfnlen); + + bool m0 = arg_get_lit(ctx, 2); + bool m1 = arg_get_lit(ctx, 3); + bool m2 = arg_get_lit(ctx, 4); + bool m4 = arg_get_lit(ctx, 5); + + CLIParserFree(ctx); + + // validations + if ((m0 + m1 + m2 + m4) > 1) { + PrintAndLogEx(WARNING, "Only specify one MIFARE Type"); + return PM3_EINVARG; + } else if ((m0 + m1 + m2 + m4) == 0) { + m1 = true; + } + + uint8_t numSectors = MIFARE_1K_MAXSECTOR; + + if (m0) { + numSectors = MIFARE_MINI_MAXSECTOR; + } else if (m1) { + numSectors = MIFARE_1K_MAXSECTOR; + } else if (m2) { + numSectors = MIFARE_2K_MAXSECTOR; + } else if (m4) { + numSectors = MIFARE_4K_MAXSECTOR; + } else { + PrintAndLogEx(WARNING, "Please specify a MIFARE Type"); + return PM3_EINVARG; + } + + + // init keys to default key + uint8_t keyA[MIFARE_4K_MAXSECTOR][MFKEY_SIZE]; + uint8_t keyB[MIFARE_4K_MAXSECTOR][MFKEY_SIZE]; + + for (uint8_t i = 0; i < MIFARE_4K_MAXSECTOR; i++ ) { + memcpy(keyA[i], g_mifare_default_key, sizeof(g_mifare_default_key)); + memcpy(keyB[i], g_mifare_default_key, sizeof(g_mifare_default_key)); + } + + // test if MAD key is used + uint64_t key64 = 0; + + // check if we can authenticate to sector + if (mfCheckKeys(0, MF_KEY_A, true, 1, (uint8_t*)g_mifare_mad_key, &key64) == PM3_SUCCESS) { + + // if used, assume KEY A is MAD/NDEF set. + memcpy(keyA[0], g_mifare_mad_key, sizeof(g_mifare_mad_key)); + memcpy(keyB[0], g_mifare_mad_key_b, sizeof(g_mifare_mad_key_b)); + for (uint8_t i = 1; i < MIFARE_4K_MAXSECTOR; i++ ) { + memcpy(keyA[i], g_mifare_ndef_key, sizeof(g_mifare_ndef_key)); + } + } + + // Do we have a keyfile based from UID? + if (strlen(keyFilename) == 0) { + char *fptr = GenerateFilename("hf-mf-", "-key.bin"); + if (fptr) { + strcpy(keyFilename, fptr); + } + free(fptr); + DropField(); + } + + // load key file if exist + if (strlen(keyFilename)) { + + FILE *f; + if ((f = fopen(keyFilename, "rb")) == NULL) { + // PrintAndLogEx(WARNING, "Could not find file " _YELLOW_("%s"), keyFilename); + goto skipfile; + } + + PrintAndLogEx(INFO, "Using `" _YELLOW_("%s") "`", keyFilename); + + // Read keys A from file + size_t bytes_read; + for (uint8_t i = 0; i < numSectors; i++) { + bytes_read = fread(keyA[i], 1, MFKEY_SIZE, f); + if (bytes_read != MFKEY_SIZE) { + PrintAndLogEx(ERR, "File reading error."); + fclose(f); + return PM3_EFILE; + } + } + + // Read keys B from file + for (uint8_t i = 0; i < numSectors; i++) { + bytes_read = fread(keyB[i], 1, MFKEY_SIZE, f); + if (bytes_read != MFKEY_SIZE) { + PrintAndLogEx(ERR, "File reading error."); + fclose(f); + return PM3_EFILE; + } + } + + fclose(f); + } + +skipfile: + + uint8_t firstblocks[8][16] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1 }, + { 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1 }, + { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x78, 0x77, 0x88, 0xC1, 0x89, 0xEC, 0xA9, 0x7F, 0x8C, 0x2A }, + { 0x03, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + }; + + // main loop + for (int i = 0; i < numSectors; i++) { + for (int j = 0; j < mfNumBlocksPerSector(j); j++) { + + uint8_t b = (mfFirstBlockOfSector(i) + j); + uint8_t block[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + switch(b) { + case 0: + continue; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + memcpy(block, firstblocks[b], MFBLOCK_SIZE); + break; + default: { + if (mfIsSectorTrailer(j) ) { + // ST NDEF + memcpy(block, firstblocks[7], MFBLOCK_SIZE); + } + break; + } + + } + + // write to card, try B key first, then A + if (mf_write_block(keyB[i], MF_KEY_B, b, block) == 0) { + // write failed try B key, + if (mf_write_block(keyA[i], MF_KEY_A, b, block) == 0) { + return PM3_EFAILED; + } + } + PrintAndLogEx(INPLACE, "Formatting block %u", b); + } + } + + PrintAndLogEx(NORMAL, ""); + + return PM3_SUCCESS; +} + + +static int CmdHFMFPersonalize(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf personalize", "Personalize the UID of a MIFARE Classic EV1 card. This is only possible \n" @@ -5700,7 +5904,7 @@ static int CmdHFMFPersonalize(const char *cmd) { arg_lit0(NULL, "f3", "UIDF3, single size NUID"), arg_param_end }; - CLIExecWithReturn(ctx, cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool use_a = arg_get_lit(ctx, 1); bool use_b = arg_get_lit(ctx, 2); @@ -6568,7 +6772,6 @@ static command_t CommandTable[] = { {"acl", CmdHF14AMfAcl, AlwaysAvailable, "Decode and print MIFARE Classic access rights bytes"}, {"dump", CmdHF14AMfDump, IfPm3Iso14443a, "Dump MIFARE Classic tag to binary file"}, {"mad", CmdHF14AMfMAD, AlwaysAvailable, "Checks and prints MAD"}, - {"ndefread", CmdHFMFNDEFRead, IfPm3Iso14443a, "Prints NDEF records from card"}, {"personalize", CmdHFMFPersonalize, IfPm3Iso14443a, "Personalize UID (MIFARE Classic EV1 only)"}, {"rdbl", CmdHF14AMfRdBl, IfPm3Iso14443a, "Read MIFARE Classic block"}, {"rdsc", CmdHF14AMfRdSc, IfPm3Iso14443a, "Read MIFARE Classic sector"}, @@ -6604,9 +6807,12 @@ static command_t CommandTable[] = { {"gen3freeze", CmdHf14AGen3Freeze, IfPm3Iso14443a, "Perma lock UID changes. irreversible"}, {"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GTU") " --------------------------"}, {"gview", CmdHF14AGen4View, IfPm3Iso14443a, "View card"}, -// {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("i") " -----------------------"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"}, // {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, + {"ndefformat", CmdHFMFNDEFFormat, IfPm3Iso14443a, "Format MIFARE Classic Tag as NFC Tag"}, + {"ndefread", CmdHFMFNDEFRead, IfPm3Iso14443a, "Prints NDEF records from card"}, {NULL, NULL, NULL, NULL} + }; static int CmdHelp(const char *Cmd) { diff --git a/client/src/cmdhfmf.h b/client/src/cmdhfmf.h index 32b6a909a..ed8c4c82d 100644 --- a/client/src/cmdhfmf.h +++ b/client/src/cmdhfmf.h @@ -21,12 +21,13 @@ #include "common.h" #include "mifare/mfkey.h" -#include "mifare/mifarehost.h" // struct +#include "mifare/mifarehost.h" // structs int CmdHFMF(const char *Cmd); -int CmdHF14AMfELoad(const char *Cmd); // used by cmd hf mfu eload -int CmdHF14AMfDbg(const char *Cmd); // used by cmd hf mfu dbg -int CmdHFMFNDEFRead(const char *Cmd); +int CmdHF14AMfELoad(const char *Cmd); // used by "hf mfu eload" +int CmdHF14AMfDbg(const char *Cmd); // used by "hf mfu dbg" +int CmdHFMFNDEFRead(const char *Cmd); // used by "nfc mf cread" +int CmdHFMFNDEFFormat(const char *Cmd); // used by "nfc mf cformat" void showSectorTable(sector_t *k_sector, uint8_t k_sectorsCount); void readerAttack(sector_t *k_sector, uint8_t k_sectorsCount, nonces_t data, bool setEmulatorMem, bool verbose); diff --git a/client/src/cmdnfc.c b/client/src/cmdnfc.c index ab5ad1ac5..959c2d661 100644 --- a/client/src/cmdnfc.c +++ b/client/src/cmdnfc.c @@ -307,6 +307,10 @@ static int CmdNFCMFCRead(const char *Cmd) { return CmdHFMFNDEFRead(Cmd); } +static int CmdNFCMFCFormat(const char *Cmd) { + return CmdHFMFNDEFFormat(Cmd); +} + static int CmdNFCMFPRead(const char *Cmd) { return CmdHFMFPNDEFRead(Cmd); } @@ -318,7 +322,7 @@ static command_t CommandMFTable[] = { {"--------", CmdNFCMFHelp, AlwaysAvailable, "--------- " _CYAN_("NFC Type MIFARE Classic/Plus Tag") " --------"}, {"cread", CmdNFCMFCRead, IfPm3Iso14443a, "read NFC Type MIFARE Classic Tag"}, // {"cwrite", CmdNFCMFCWrite, IfPm3Iso14443a, "write NFC Type MIFARE Classic Tag"}, -// {"cformat", CmdNFCMFCFormat, IfPm3Iso14443a, "format MIFARE Classic Tag as NFC Tag"}, + {"cformat", CmdNFCMFCFormat, IfPm3Iso14443a, "format MIFARE Classic Tag as NFC Tag"}, {"pread", CmdNFCMFPRead, IfPm3Iso14443a, "read NFC Type MIFARE Plus Tag"}, {"--------", CmdNFCMFHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, {"help", CmdNFCMFHelp, AlwaysAvailable, "This help"}, diff --git a/client/src/mifare/mifaredefault.h b/client/src/mifare/mifaredefault.h index ee9846240..93c6b4a7f 100644 --- a/client/src/mifare/mifaredefault.h +++ b/client/src/mifare/mifaredefault.h @@ -21,6 +21,7 @@ #include "common.h" +#define MFKEY_SIZE 6 #define MFBLOCK_SIZE 16 static const uint64_t g_mifare_default_keys[] = { @@ -70,7 +71,10 @@ static const uint64_t g_mifare_default_keys[] = { 0x199404281998, // NSP B }; +static const uint8_t g_mifare_default_key[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; static const uint8_t g_mifare_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}; +static const uint8_t g_mifare_mad_key_b[] = {0x89, 0xEC, 0xA9, 0x7F, 0x8C, 0x2A}; + static const uint8_t g_mifare_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; static const uint8_t g_mifarep_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7}; static const uint8_t g_mifarep_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; From eff967923feb223aa09fa45517ae072a4d59b120 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 16 Oct 2022 17:48:13 +0200 Subject: [PATCH 272/759] changed hf mf cwipe with genuine data --- CHANGELOG.md | 1 + client/src/mifare/mifarehost.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54f228540..4c4125a89 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] + - Changed `hf mf cwipe` - swapped the block0 data to genuine manufacture ones (@iceman1001) - Added `hf mf ndefformat` - format a MIFARE Classic tag as NFC tag with Data Exchange Format (NDEF) (@iceman1001) - Changed `hf 14b dump, view` to get correct chip type in case of SRT512 and friends (@DidierA) - Added `hf 15 eview` and `hf 15 esave` - Retrieve emulator image for ISO15693 simulation (@markus-oehme-pg40) diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index cfb8bca4a..9d204c686 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1034,7 +1034,7 @@ int mfCSetUID(uint8_t *uid, uint8_t uidlen, const uint8_t *atqa, const uint8_t * } int mfCWipe(uint8_t *uid, const uint8_t *atqa, const uint8_t *sak) { - uint8_t block0[16] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xAF}; + uint8_t block0[16] = {0x04, 0x03, 0x02, 0x01, 0x04, 0x08, 0x04, 0x00, 0x64, 0xB9, 0x95, 0x11, 0x4D, 0x20, 0x42, 0x09}; uint8_t blockD[16] = {0x00}; uint8_t blockK[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x77, 0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t params = MAGIC_SINGLE; From 2d257167045dd68eae1cfc59cb3943470ef9cbe2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 16 Oct 2022 17:52:10 +0200 Subject: [PATCH 273/759] verify that there is a card on the proxmark before continuing --- client/src/cmdhfmf.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 53d3afb1b..620eff3ea 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5754,6 +5754,24 @@ int CmdHFMFNDEFFormat(const char *Cmd) { } + // Select card to get UID/UIDLEN/ATQA/SAK information + clearCommandBuffer(); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { + PrintAndLogEx(WARNING, "iso14443a card select timeout"); + return PM3_ETIMEOUT; + } + + uint64_t select_status = resp.oldarg[0]; + if (select_status == 0) { + PrintAndLogEx(WARNING, "iso14443a card select failed"); + return select_status; + } + + DropField(); + + // init keys to default key uint8_t keyA[MIFARE_4K_MAXSECTOR][MFKEY_SIZE]; uint8_t keyB[MIFARE_4K_MAXSECTOR][MFKEY_SIZE]; @@ -5876,7 +5894,7 @@ skipfile: } PrintAndLogEx(NORMAL, ""); - + return PM3_SUCCESS; } From 71f96ba1e7c9c672563646309fba34252d981b2c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 16 Oct 2022 17:56:12 +0200 Subject: [PATCH 274/759] make style --- armsrc/appmain.c | 4 +- armsrc/flashmem.c | 2 +- armsrc/spiffs.c | 70 +- armsrc/spiffs.h | 4 +- client/src/cmddata.c | 2 +- client/src/cmdhf14b.c | 23 +- client/src/cmdhf14b.h | 2 +- client/src/cmdhf15.c | 4 +- client/src/cmdhfmf.c | 22 +- client/src/pm3line_vocabulory.h | 1429 ++++++++++++++++--------------- doc/commands.json | 425 +++++++-- doc/commands.md | 38 +- 12 files changed, 1184 insertions(+), 841 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 1e1b844cf..96ba18729 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2182,7 +2182,7 @@ static void PacketReceived(PacketCommandNG *packet) { uint8_t *buff = BigBuf_malloc(size); if (buff == NULL) { - if (g_dbglevel >= DBG_DEBUG) Dbprintf ("Could not allocate buffer"); + if (g_dbglevel >= DBG_DEBUG) Dbprintf("Could not allocate buffer"); // Trigger a finish downloading signal with an PM3_EMALLOC reply_ng(CMD_SPIFFS_DOWNLOAD, PM3_EMALLOC, NULL, 0); } else { @@ -2199,7 +2199,7 @@ static void PacketReceived(PacketCommandNG *packet) { } // Trigger a finish downloading signal with an ACK frame reply_ng(CMD_SPIFFS_DOWNLOAD, PM3_SUCCESS, NULL, 0); - BigBuf_free (); + BigBuf_free(); } LED_B_OFF(); break; diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index fd5a95c97..426540143 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -452,7 +452,7 @@ bool Flash_WipeMemoryPage(uint8_t page) { FlashStop(); // let spiffs check and update its info post flash erase - rdv40_spiffs_check (); + rdv40_spiffs_check(); return true; } // Wipes flash memory completely, fills with 0xFF diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index ef7ca3174..cea6946d3 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -102,7 +102,7 @@ static s32_t rdv40_spiffs_llerase(u32_t addr, u32_t size) { FlashStop(); // iceman: SPIFFS_OK expands to 0, erased is bool from Flash_Erase4k, which returns TRUE if ok. - // so this return logic looks wrong. + // so this return logic looks wrong. return (SPIFFS_OK == erased); } @@ -152,15 +152,15 @@ int rdv40_spiffs_mount(void) { // int ret = SPIFFS_mount(&fs, &cfg, spiffs_work_buf, spiffs_fds, // sizeof(spiffs_fds), 0, 0, 0); cached version, experimental int ret = SPIFFS_mount( - &fs, - &cfg, - spiffs_work_buf, - spiffs_fds, - sizeof(spiffs_fds), - spiffs_cache_buf, - sizeof(spiffs_cache_buf), - 0 - ); + &fs, + &cfg, + spiffs_work_buf, + spiffs_fds, + sizeof(spiffs_fds), + spiffs_cache_buf, + sizeof(spiffs_cache_buf), + 0 + ); if (ret == SPIFFS_OK) { RDV40_SPIFFS_MOUNT_STATUS = RDV40_SPIFFS_MOUNTED; @@ -437,23 +437,23 @@ int rdv40_spiffs_lazy_mount_rollback(int changed) { int rdv40_spiffs_write(const char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( uint32_t idx; - if (size <= SPIFFS_WRITE_CHUNK_SIZE) { - // write small file - write_to_spiffs(filename, src, size); - size = 0; - } else { // - // write first SPIFFS_WRITE_CHUNK_SIZE bytes - // need to write the first chuck of data, then append - write_to_spiffs(filename, src, SPIFFS_WRITE_CHUNK_SIZE); - } - // append remaing SPIFFS_WRITE_CHUNK_SIZE byte chuncks - for (idx = 1; idx < (size / SPIFFS_WRITE_CHUNK_SIZE); idx++) { - append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], SPIFFS_WRITE_CHUNK_SIZE); - } - // append remaing bytes - if (((int64_t)size - (SPIFFS_WRITE_CHUNK_SIZE * idx)) > 0) { - append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], size - (SPIFFS_WRITE_CHUNK_SIZE * idx)); - } + if (size <= SPIFFS_WRITE_CHUNK_SIZE) { + // write small file + write_to_spiffs(filename, src, size); + size = 0; + } else { // + // write first SPIFFS_WRITE_CHUNK_SIZE bytes + // need to write the first chuck of data, then append + write_to_spiffs(filename, src, SPIFFS_WRITE_CHUNK_SIZE); + } + // append remaing SPIFFS_WRITE_CHUNK_SIZE byte chuncks + for (idx = 1; idx < (size / SPIFFS_WRITE_CHUNK_SIZE); idx++) { + append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], SPIFFS_WRITE_CHUNK_SIZE); + } + // append remaing bytes + if (((int64_t)size - (SPIFFS_WRITE_CHUNK_SIZE * idx)) > 0) { + append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], size - (SPIFFS_WRITE_CHUNK_SIZE * idx)); + } ) } @@ -461,13 +461,13 @@ int rdv40_spiffs_append(const char *filename, uint8_t *src, uint32_t size, RDV40 RDV40_SPIFFS_SAFE_FUNCTION( uint32_t idx; // Append any SPIFFS_WRITE_CHUNK_SIZE byte chunks - for (idx = 0; idx < (size/SPIFFS_WRITE_CHUNK_SIZE); idx++) { - append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], SPIFFS_WRITE_CHUNK_SIZE); - } - // Append remain bytes - if (((int64_t)size - (SPIFFS_WRITE_CHUNK_SIZE * idx)) > 0) { - append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], size - (SPIFFS_WRITE_CHUNK_SIZE * idx)); - } + for (idx = 0; idx < (size / SPIFFS_WRITE_CHUNK_SIZE); idx++) { + append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], SPIFFS_WRITE_CHUNK_SIZE); + } + // Append remain bytes + if (((int64_t)size - (SPIFFS_WRITE_CHUNK_SIZE * idx)) > 0) { + append_to_spiffs(filename, &src[SPIFFS_WRITE_CHUNK_SIZE * idx], size - (SPIFFS_WRITE_CHUNK_SIZE * idx)); + } ) } @@ -547,7 +547,7 @@ int rdv40_spiffs_read_as_symlink(char *filename, uint8_t *dst, uint32_t size, RD read_from_spiffs((char *)linkdest, (uint8_t *)dst, size); ) -} + } // BEWARE ! This function is DESTRUCTIVE as it will UPDATE an existing symlink // Since it creates a .lnk extension file it may be minor to mistake the order of arguments diff --git a/armsrc/spiffs.h b/armsrc/spiffs.h index 6af4fbac8..5958e559b 100644 --- a/armsrc/spiffs.h +++ b/armsrc/spiffs.h @@ -25,8 +25,8 @@ extern "C" { #include "spiffs_config.h" typedef enum spiffs_safety_level { - RDV40_SPIFFS_SAFETY_NORMAL, - RDV40_SPIFFS_SAFETY_LAZY, + RDV40_SPIFFS_SAFETY_NORMAL, + RDV40_SPIFFS_SAFETY_LAZY, RDV40_SPIFFS_SAFETY_SAFE } RDV40SpiFFSSafetyLevel; diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 8020b7220..6b2793df0 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -2770,7 +2770,7 @@ static int try_detect_modulation(void) { #define LF_NUM_OF_TESTS 6 lf_modulation_t tests[LF_NUM_OF_TESTS]; - for (int i=0; i< ARRAYLEN(tests); i++) { + for (int i = 0; i < ARRAYLEN(tests); i++) { memset(&tests[i], 0, sizeof(lf_modulation_t)); } diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 1f6d62523..8bac70d15 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -789,8 +789,8 @@ static void print_ct_blocks(uint8_t *data, size_t len) { static void print_sr_blocks(uint8_t *data, size_t len, const uint8_t *uid) { - size_t blocks = (len / ST25TB_SR_BLOCK_SIZE) -1 ; - uint8_t * systemblock = data + blocks * ST25TB_SR_BLOCK_SIZE ; + size_t blocks = (len / ST25TB_SR_BLOCK_SIZE) - 1 ; + uint8_t *systemblock = data + blocks * ST25TB_SR_BLOCK_SIZE ; uint8_t chipid = get_st_chipid(uid); PrintAndLogEx(SUCCESS, _GREEN_("%s") " tag", get_st_chip_model(chipid)); @@ -1486,7 +1486,7 @@ static int CmdHF14BDump(const char *Cmd) { // last read if (blocknum == 0xFF) { // we reserved space for this block after 0x0F and 0x7F, ie 0x10, 0x80 - memcpy(data + ((lastblock+1) * ST25TB_SR_BLOCK_SIZE), recv, ST25TB_SR_BLOCK_SIZE); + memcpy(data + ((lastblock + 1) * ST25TB_SR_BLOCK_SIZE), recv, ST25TB_SR_BLOCK_SIZE); break; } memcpy(data + (blocknum * ST25TB_SR_BLOCK_SIZE), recv, ST25TB_SR_BLOCK_SIZE); @@ -2105,25 +2105,26 @@ out: /* extract uid from filename * filename must match '^hf-14b-[0-9A-F]{16}' - */ -uint8_t * get_uid_from_filename(const char *filename) { + */ +uint8_t *get_uid_from_filename(const char *filename) { static uint8_t uid[8] ; memset(uid, 0, 8) ; char uidinhex[17] ; - if (strlen(filename)<23 || strncmp(filename, "hf-14b-", 7)) { + if (strlen(filename) < 23 || strncmp(filename, "hf-14b-", 7)) { PrintAndLogEx(ERR, "can't get uid from filename '%s'. Expected format is hf-14b-...", filename); return uid ; } - // extract uid part from filename - strncpy(uidinhex, filename+7, 16) ; uidinhex[16]='\0' ; - int len=hex_to_bytes(uidinhex, uid, 8); + // extract uid part from filename + strncpy(uidinhex, filename + 7, 16) ; + uidinhex[16] = '\0' ; + int len = hex_to_bytes(uidinhex, uid, 8); if (len == 8) - return SwapEndian64(uid , 8, 8); + return SwapEndian64(uid, 8, 8); else { PrintAndLogEx(ERR, "get_uid_from_filename failed: hex_to_bytes returned %d", len); memset(uid, 0, 8); } - return uid ; + return uid ; } static int CmdHF14BView(const char *Cmd) { diff --git a/client/src/cmdhf14b.h b/client/src/cmdhf14b.h index 06cd637b9..e66f5d19b 100644 --- a/client/src/cmdhf14b.h +++ b/client/src/cmdhf14b.h @@ -25,7 +25,7 @@ int CmdHF14B(const char *Cmd); int CmdHF14BNdefRead(const char *Cmd); -uint8_t * get_uid_from_filename(const char *filename); +uint8_t *get_uid_from_filename(const char *filename); int exchange_14b_apdu(uint8_t *datain, int datainlen, bool activate_field, bool leave_signal_on, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, int user_timeout); int select_card_14443b_4(bool disconnect, iso14b_card_select_t *card); diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index bc8dc8928..45040d7f2 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1147,7 +1147,7 @@ static int CmdHF15ESave(const char *Cmd) { static void print_hrule(int blocksize) { char dashes[] = "------------------------------------------------------------"; - PrintAndLogEx(INFO, "-----+%.*s-+-%.*s-", 3*blocksize, dashes, blocksize, dashes); + PrintAndLogEx(INFO, "-----+%.*s-+-%.*s-", 3 * blocksize, dashes, blocksize, dashes); } static void print_blocks_15693(uint8_t *data, uint16_t bytes, int blocksize) { @@ -1155,7 +1155,7 @@ static void print_blocks_15693(uint8_t *data, uint16_t bytes, int blocksize) { PrintAndLogEx(NORMAL, ""); print_hrule(blocksize); char spaces[] = " "; - PrintAndLogEx(INFO, " blk | data %.*s| ascii", MAX(0, 3*blocksize - 5), spaces); + PrintAndLogEx(INFO, " blk | data %.*s| ascii", MAX(0, 3 * blocksize - 5), spaces); print_hrule(blocksize); for (int i = 0; i < blocks; i++) { PrintAndLogEx(INFO, "%4d | %s ", i, sprint_hex_ascii(data + (i * blocksize), blocksize)); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 620eff3ea..3604c9686 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5706,7 +5706,7 @@ int CmdHFMFNDEFFormat(const char *Cmd) { "hf mf ndefformat --2k --> MIFARE 2k\n" "hf mf ndefformat --4k --> MIFARE 4k\n" "hf mf ndefformat --keys hf-mf-066C8B78-key.bin --> MIFARE 1k with keys from specified file\n" - ); + ); void *argtable[] = { arg_param_begin, @@ -5774,9 +5774,9 @@ int CmdHFMFNDEFFormat(const char *Cmd) { // init keys to default key uint8_t keyA[MIFARE_4K_MAXSECTOR][MFKEY_SIZE]; - uint8_t keyB[MIFARE_4K_MAXSECTOR][MFKEY_SIZE]; - - for (uint8_t i = 0; i < MIFARE_4K_MAXSECTOR; i++ ) { + uint8_t keyB[MIFARE_4K_MAXSECTOR][MFKEY_SIZE]; + + for (uint8_t i = 0; i < MIFARE_4K_MAXSECTOR; i++) { memcpy(keyA[i], g_mifare_default_key, sizeof(g_mifare_default_key)); memcpy(keyB[i], g_mifare_default_key, sizeof(g_mifare_default_key)); } @@ -5785,15 +5785,15 @@ int CmdHFMFNDEFFormat(const char *Cmd) { uint64_t key64 = 0; // check if we can authenticate to sector - if (mfCheckKeys(0, MF_KEY_A, true, 1, (uint8_t*)g_mifare_mad_key, &key64) == PM3_SUCCESS) { + if (mfCheckKeys(0, MF_KEY_A, true, 1, (uint8_t *)g_mifare_mad_key, &key64) == PM3_SUCCESS) { // if used, assume KEY A is MAD/NDEF set. memcpy(keyA[0], g_mifare_mad_key, sizeof(g_mifare_mad_key)); memcpy(keyB[0], g_mifare_mad_key_b, sizeof(g_mifare_mad_key_b)); - for (uint8_t i = 1; i < MIFARE_4K_MAXSECTOR; i++ ) { - memcpy(keyA[i], g_mifare_ndef_key, sizeof(g_mifare_ndef_key)); + for (uint8_t i = 1; i < MIFARE_4K_MAXSECTOR; i++) { + memcpy(keyA[i], g_mifare_ndef_key, sizeof(g_mifare_ndef_key)); } - } + } // Do we have a keyfile based from UID? if (strlen(keyFilename) == 0) { @@ -5850,7 +5850,7 @@ skipfile: { 0x03, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, }; // main loop @@ -5860,7 +5860,7 @@ skipfile: uint8_t b = (mfFirstBlockOfSector(i) + j); uint8_t block[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - switch(b) { + switch (b) { case 0: continue; case 1: @@ -5873,7 +5873,7 @@ skipfile: memcpy(block, firstblocks[b], MFBLOCK_SIZE); break; default: { - if (mfIsSectorTrailer(j) ) { + if (mfIsSectorTrailer(j)) { // ST NDEF memcpy(block, firstblocks[7], MFBLOCK_SIZE); } diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 88557d416..cbf89bde8 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -31,711 +31,728 @@ typedef struct vocabulory_s { } vocabulory_t; const static vocabulory_t vocabulory[] = { - { 1, "help" }, - { 0, "auto" }, - { 1, "clear" }, - { 1, "hints" }, - { 1, "msleep" }, - { 1, "rem" }, - { 1, "quit" }, - { 1, "exit" }, - { 1, "prefs help" }, - { 1, "prefs show" }, - { 1, "prefs get barmode" }, - { 1, "prefs get clientdebug" }, - { 1, "prefs get clientdelay" }, - { 1, "prefs get color" }, - { 1, "prefs get savepaths" }, - { 1, "prefs get emoji" }, - { 1, "prefs get hints" }, - { 1, "prefs get output" }, - { 1, "prefs get plotsliders" }, - { 1, "prefs set help" }, - { 1, "prefs set barmode" }, - { 1, "prefs set clientdebug" }, - { 1, "prefs set clientdelay" }, - { 1, "prefs set color" }, - { 1, "prefs set emoji" }, - { 1, "prefs set hints" }, - { 1, "prefs set savepaths" }, - { 1, "prefs set output" }, - { 1, "prefs set plotsliders" }, - { 1, "analyse help" }, - { 1, "analyse lcr" }, - { 1, "analyse crc" }, - { 1, "analyse chksum" }, - { 1, "analyse dates" }, - { 1, "analyse lfsr" }, - { 1, "analyse a" }, - { 1, "analyse nuid" }, - { 1, "analyse demodbuff" }, - { 1, "analyse freq" }, - { 1, "analyse foo" }, - { 1, "analyse units" }, - { 1, "data help" }, - { 1, "data biphaserawdecode" }, - { 1, "data detectclock" }, - { 1, "data fsktonrz" }, - { 1, "data manrawdecode" }, - { 1, "data modulation" }, - { 1, "data rawdemod" }, - { 1, "data askedgedetect" }, - { 1, "data autocorr" }, - { 1, "data dirthreshold" }, - { 1, "data decimate" }, - { 1, "data undecimate" }, - { 1, "data hide" }, - { 1, "data hpf" }, - { 1, "data iir" }, - { 1, "data grid" }, - { 1, "data ltrim" }, - { 1, "data mtrim" }, - { 1, "data norm" }, - { 1, "data plot" }, - { 1, "data rtrim" }, - { 1, "data setgraphmarkers" }, - { 1, "data shiftgraphzero" }, - { 1, "data timescale" }, - { 1, "data zerocrossings" }, - { 1, "data convertbitstream" }, - { 1, "data getbitstream" }, - { 1, "data asn1" }, - { 1, "data bin2hex" }, - { 0, "data bitsamples" }, - { 1, "data clear" }, - { 1, "data diff" }, - { 0, "data hexsamples" }, - { 1, "data hex2bin" }, - { 1, "data load" }, - { 1, "data print" }, - { 0, "data samples" }, - { 1, "data save" }, - { 1, "data setdebugmode" }, - { 0, "data tune" }, - { 1, "emv help" }, - { 0, "emv exec" }, - { 0, "emv pse" }, - { 0, "emv search" }, - { 0, "emv select" }, - { 0, "emv gpo" }, - { 0, "emv readrec" }, - { 0, "emv genac" }, - { 0, "emv challenge" }, - { 0, "emv intauth" }, - { 0, "emv scan" }, - { 1, "emv test" }, - { 1, "emv list" }, - { 0, "emv roca" }, - { 1, "hf help" }, - { 1, "hf list" }, - { 0, "hf plot" }, - { 0, "hf tune" }, - { 1, "hf search" }, - { 0, "hf sniff" }, - { 1, "hf 14a help" }, - { 1, "hf 14a list" }, - { 0, "hf 14a info" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a raw" }, - { 0, "hf 14a antifuzz" }, - { 0, "hf 14a config" }, - { 0, "hf 14a apdufind" }, - { 1, "hf 14b help" }, - { 0, "hf 14b apdu" }, - { 0, "hf 14b dump" }, - { 0, "hf 14b info" }, - { 1, "hf 14b list" }, - { 0, "hf 14b ndefread" }, - { 0, "hf 14b raw" }, - { 0, "hf 14b reader" }, - { 0, "hf 14b sim" }, - { 0, "hf 14b sniff" }, - { 0, "hf 14b rdbl" }, - { 0, "hf 14b sriwrite" }, - { 1, "hf 14b view" }, - { 1, "hf 15 help" }, - { 1, "hf 15 list" }, - { 1, "hf 15 demod" }, - { 0, "hf 15 dump" }, - { 0, "hf 15 info" }, - { 0, "hf 15 sniff" }, - { 0, "hf 15 raw" }, - { 0, "hf 15 rdbl" }, - { 0, "hf 15 rdmulti" }, - { 0, "hf 15 reader" }, - { 0, "hf 15 restore" }, - { 0, "hf 15 samples" }, - { 0, "hf 15 sim" }, - { 0, "hf 15 slixdisable" }, - { 0, "hf 15 wrbl" }, - { 0, "hf 15 findafi" }, - { 0, "hf 15 writeafi" }, - { 0, "hf 15 writedsfid" }, - { 0, "hf 15 csetuid" }, - { 1, "hf cipurse help" }, - { 0, "hf cipurse info" }, - { 0, "hf cipurse select" }, - { 0, "hf cipurse auth" }, - { 0, "hf cipurse read" }, - { 0, "hf cipurse write" }, - { 0, "hf cipurse aread" }, - { 0, "hf cipurse awrite" }, - { 0, "hf cipurse formatall" }, - { 0, "hf cipurse create" }, - { 0, "hf cipurse delete" }, - { 0, "hf cipurse updkey" }, - { 0, "hf cipurse updakey" }, - { 0, "hf cipurse default" }, - { 1, "hf cipurse test" }, - { 1, "hf epa help" }, - { 0, "hf epa cnonces" }, - { 0, "hf epa preplay" }, - { 1, "hf emrtd help" }, - { 0, "hf emrtd dump" }, - { 1, "hf emrtd info" }, - { 1, "hf emrtd list" }, - { 1, "hf felica help" }, - { 1, "hf felica list" }, - { 0, "hf felica reader" }, - { 0, "hf felica info" }, - { 0, "hf felica sniff" }, - { 0, "hf felica raw" }, - { 0, "hf felica rdbl" }, - { 0, "hf felica wrbl" }, - { 0, "hf felica rqservice" }, - { 0, "hf felica rqresponse" }, - { 0, "hf felica scsvcode" }, - { 0, "hf felica rqsyscode" }, - { 0, "hf felica auth1" }, - { 0, "hf felica auth2" }, - { 0, "hf felica rqspecver" }, - { 0, "hf felica resetmode" }, - { 0, "hf felica litesim" }, - { 0, "hf felica litedump" }, - { 1, "hf fido help" }, - { 1, "hf fido list" }, - { 0, "hf fido info" }, - { 0, "hf fido reg" }, - { 0, "hf fido auth" }, - { 0, "hf fido make" }, - { 0, "hf fido assert" }, - { 1, "hf gallagher help" }, - { 0, "hf gallagher reader" }, - { 0, "hf gallagher clone" }, - { 0, "hf gallagher delete" }, - { 1, "hf gallagher diversifykey" }, - { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 initialize" }, - { 0, "hf ksx6924 prec" }, - { 0, "hf ksx6924 select" }, - { 1, "hf jooki help" }, - { 0, "hf jooki clone" }, - { 1, "hf jooki decode" }, - { 1, "hf jooki encode" }, - { 0, "hf jooki sim" }, - { 1, "hf iclass help" }, - { 0, "hf iclass dump" }, - { 1, "hf iclass info" }, - { 1, "hf iclass list" }, - { 0, "hf iclass rdbl" }, - { 0, "hf iclass reader" }, - { 0, "hf iclass restore" }, - { 0, "hf iclass sniff" }, - { 0, "hf iclass wrbl" }, - { 0, "hf iclass chk" }, - { 1, "hf iclass loclass" }, - { 1, "hf iclass lookup" }, - { 0, "hf iclass sim" }, - { 0, "hf iclass eload" }, - { 0, "hf iclass esave" }, - { 0, "hf iclass eview" }, - { 1, "hf iclass configcard" }, - { 1, "hf iclass calcnewkey" }, - { 1, "hf iclass encode" }, - { 1, "hf iclass encrypt" }, - { 1, "hf iclass decrypt" }, - { 1, "hf iclass managekeys" }, - { 1, "hf iclass permutekey" }, - { 1, "hf iclass view" }, - { 1, "hf legic help" }, - { 0, "hf legic dump" }, - { 0, "hf legic info" }, - { 1, "hf legic list" }, - { 0, "hf legic rdbl" }, - { 0, "hf legic reader" }, - { 0, "hf legic restore" }, - { 0, "hf legic wipe" }, - { 0, "hf legic wrbl" }, - { 0, "hf legic sim" }, - { 0, "hf legic eload" }, - { 0, "hf legic esave" }, - { 0, "hf legic eview" }, - { 1, "hf legic crc" }, - { 1, "hf legic view" }, - { 1, "hf lto help" }, - { 0, "hf lto dump" }, - { 0, "hf lto restore" }, - { 0, "hf lto info" }, - { 0, "hf lto rdbl" }, - { 0, "hf lto wrbl" }, - { 1, "hf lto list" }, - { 1, "hf mf help" }, - { 1, "hf mf list" }, - { 0, "hf mf darkside" }, - { 0, "hf mf nested" }, - { 1, "hf mf hardnested" }, - { 0, "hf mf staticnested" }, - { 0, "hf mf autopwn" }, - { 0, "hf mf nack" }, - { 0, "hf mf chk" }, - { 0, "hf mf fchk" }, - { 1, "hf mf decrypt" }, - { 0, "hf mf supercard" }, - { 0, "hf mf auth4" }, - { 1, "hf mf acl" }, - { 0, "hf mf dump" }, - { 0, "hf mf mad" }, - { 0, "hf mf ndefread" }, - { 0, "hf mf personalize" }, - { 0, "hf mf rdbl" }, - { 0, "hf mf rdsc" }, - { 0, "hf mf restore" }, - { 0, "hf mf setmod" }, - { 1, "hf mf value" }, - { 1, "hf mf view" }, - { 0, "hf mf wipe" }, - { 0, "hf mf wrbl" }, - { 0, "hf mf sim" }, - { 0, "hf mf ecfill" }, - { 0, "hf mf eclr" }, - { 0, "hf mf egetblk" }, - { 0, "hf mf egetsc" }, - { 0, "hf mf ekeyprn" }, - { 0, "hf mf eload" }, - { 0, "hf mf esave" }, - { 0, "hf mf esetblk" }, - { 0, "hf mf eview" }, - { 0, "hf mf cgetblk" }, - { 0, "hf mf cgetsc" }, - { 0, "hf mf cload" }, - { 0, "hf mf csave" }, - { 0, "hf mf csetblk" }, - { 0, "hf mf csetuid" }, - { 0, "hf mf cview" }, - { 0, "hf mf cwipe" }, - { 0, "hf mf gen3uid" }, - { 0, "hf mf gen3blk" }, - { 0, "hf mf gen3freeze" }, - { 0, "hf mf gview" }, - { 1, "hf mfp help" }, - { 0, "hf mfp info" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp commitp" }, - { 0, "hf mfp auth" }, - { 0, "hf mfp rdbl" }, - { 0, "hf mfp rdsc" }, - { 0, "hf mfp wrbl" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp mad" }, - { 0, "hf mfp ndefread" }, - { 1, "hf mfu help" }, - { 1, "hf mfu keygen" }, - { 1, "hf mfu pwdgen" }, - { 0, "hf mfu otptear" }, - { 0, "hf mfu cauth" }, - { 0, "hf mfu dump" }, - { 0, "hf mfu info" }, - { 0, "hf mfu ndefread" }, - { 0, "hf mfu rdbl" }, - { 0, "hf mfu restore" }, - { 1, "hf mfu view" }, - { 0, "hf mfu wrbl" }, - { 0, "hf mfu eload" }, - { 0, "hf mfu eview" }, - { 0, "hf mfu sim" }, - { 0, "hf mfu setpwd" }, - { 0, "hf mfu setuid" }, - { 1, "hf mfdes help" }, - { 0, "hf mfdes info" }, - { 0, "hf mfdes getuid" }, - { 0, "hf mfdes default" }, - { 0, "hf mfdes auth" }, - { 0, "hf mfdes chk" }, - { 0, "hf mfdes detect" }, - { 0, "hf mfdes freemem" }, - { 0, "hf mfdes setconfig" }, - { 0, "hf mfdes formatpicc" }, - { 1, "hf mfdes list" }, - { 0, "hf mfdes mad" }, - { 0, "hf mfdes lsapp" }, - { 0, "hf mfdes getaids" }, - { 0, "hf mfdes getappnames" }, - { 0, "hf mfdes bruteaid" }, - { 0, "hf mfdes createapp" }, - { 0, "hf mfdes deleteapp" }, - { 0, "hf mfdes selectapp" }, - { 0, "hf mfdes changekey" }, - { 0, "hf mfdes chkeysettings" }, - { 0, "hf mfdes getkeysettings" }, - { 0, "hf mfdes getkeyversions" }, - { 0, "hf mfdes getfileids" }, - { 0, "hf mfdes getfileisoids" }, - { 0, "hf mfdes lsfiles" }, - { 0, "hf mfdes dump" }, - { 0, "hf mfdes createfile" }, - { 0, "hf mfdes createvaluefile" }, - { 0, "hf mfdes createrecordfile" }, - { 0, "hf mfdes createmacfile" }, - { 0, "hf mfdes deletefile" }, - { 0, "hf mfdes getfilesettings" }, - { 0, "hf mfdes chfilesettings" }, - { 0, "hf mfdes read" }, - { 0, "hf mfdes write" }, - { 0, "hf mfdes value" }, - { 0, "hf mfdes clearrecfile" }, - { 1, "hf mfdes test" }, - { 1, "hf ntag424 help" }, - { 0, "hf ntag424 info" }, - { 0, "hf ntag424 sdm" }, - { 1, "hf ntag424 view" }, - { 1, "hf seos help" }, - { 0, "hf seos info" }, - { 1, "hf seos list" }, - { 1, "hf st25ta help" }, - { 0, "hf st25ta info" }, - { 1, "hf st25ta list" }, - { 1, "hf st25ta ndefread" }, - { 0, "hf st25ta protect" }, - { 0, "hf st25ta pwd" }, - { 0, "hf st25ta sim" }, - { 1, "hf thinfilm help" }, - { 0, "hf thinfilm info" }, - { 1, "hf thinfilm list" }, - { 0, "hf thinfilm sim" }, - { 1, "hf topaz help" }, - { 1, "hf topaz list" }, - { 0, "hf topaz info" }, - { 0, "hf topaz reader" }, - { 0, "hf topaz sim" }, - { 0, "hf topaz sniff" }, - { 0, "hf topaz raw" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, - { 1, "hf xerox help" }, - { 0, "hf xerox info" }, - { 0, "hf xerox reader" }, - { 0, "hf xerox dump" }, - { 1, "hf waveshare help" }, - { 0, "hf waveshare loadbmp" }, - { 1, "hw help" }, - { 0, "hw break" }, - { 1, "hw connect" }, - { 0, "hw dbg" }, - { 0, "hw detectreader" }, - { 0, "hw fpgaoff" }, - { 0, "hw lcd" }, - { 0, "hw lcdreset" }, - { 0, "hw ping" }, - { 0, "hw readmem" }, - { 0, "hw reset" }, - { 0, "hw setlfdivisor" }, - { 0, "hw setmux" }, - { 0, "hw standalone" }, - { 0, "hw status" }, - { 0, "hw tearoff" }, - { 0, "hw tia" }, - { 0, "hw tune" }, - { 1, "hw version" }, - { 1, "lf help" }, - { 0, "lf config" }, - { 0, "lf cmdread" }, - { 0, "lf read" }, - { 1, "lf search" }, - { 0, "lf sim" }, - { 0, "lf simask" }, - { 0, "lf simfsk" }, - { 0, "lf simpsk" }, - { 0, "lf simbidir" }, - { 0, "lf sniff" }, - { 0, "lf tune" }, - { 1, "lf awid help" }, - { 1, "lf awid demod" }, - { 0, "lf awid reader" }, - { 0, "lf awid clone" }, - { 0, "lf awid sim" }, - { 0, "lf awid brute" }, - { 0, "lf awid watch" }, - { 1, "lf cotag help" }, - { 1, "lf cotag demod" }, - { 0, "lf cotag reader" }, - { 1, "lf destron help" }, - { 1, "lf destron demod" }, - { 0, "lf destron reader" }, - { 0, "lf destron clone" }, - { 0, "lf destron sim" }, - { 1, "lf em help" }, - { 1, "lf em 410x help" }, - { 1, "lf em 410x demod" }, - { 0, "lf em 410x reader" }, - { 0, "lf em 410x sim" }, - { 0, "lf em 410x brute" }, - { 0, "lf em 410x watch" }, - { 0, "lf em 410x spoof" }, - { 0, "lf em 410x clone" }, - { 1, "lf em 4x05 help" }, - { 0, "lf em 4x05 brute" }, - { 0, "lf em 4x05 chk" }, - { 1, "lf em 4x05 demod" }, - { 0, "lf em 4x05 dump" }, - { 0, "lf em 4x05 info" }, - { 0, "lf em 4x05 read" }, - { 1, "lf em 4x05 sniff" }, - { 0, "lf em 4x05 unlock" }, - { 0, "lf em 4x05 wipe" }, - { 0, "lf em 4x05 write" }, - { 1, "lf em 4x50 help" }, - { 0, "lf em 4x50 brute" }, - { 0, "lf em 4x50 chk" }, - { 0, "lf em 4x50 dump" }, - { 0, "lf em 4x50 info" }, - { 0, "lf em 4x50 login" }, - { 0, "lf em 4x50 rdbl" }, - { 0, "lf em 4x50 reader" }, - { 0, "lf em 4x50 restore" }, - { 0, "lf em 4x50 wrbl" }, - { 0, "lf em 4x50 wrpwd" }, - { 0, "lf em 4x50 wipe" }, - { 0, "lf em 4x50 eload" }, - { 0, "lf em 4x50 esave" }, - { 0, "lf em 4x50 eview" }, - { 0, "lf em 4x50 sim" }, - { 1, "lf em 4x70 help" }, - { 0, "lf em 4x70 info" }, - { 0, "lf em 4x70 write" }, - { 0, "lf em 4x70 unlock" }, - { 0, "lf em 4x70 auth" }, - { 0, "lf em 4x70 writepin" }, - { 0, "lf em 4x70 writekey" }, - { 1, "lf fdxb help" }, - { 1, "lf fdxb demod" }, - { 0, "lf fdxb reader" }, - { 0, "lf fdxb clone" }, - { 0, "lf fdxb sim" }, - { 1, "lf gallagher help" }, - { 1, "lf gallagher demod" }, - { 0, "lf gallagher reader" }, - { 0, "lf gallagher clone" }, - { 0, "lf gallagher sim" }, - { 1, "lf gproxii help" }, - { 1, "lf gproxii demod" }, - { 0, "lf gproxii reader" }, - { 0, "lf gproxii clone" }, - { 0, "lf gproxii sim" }, - { 1, "lf hid help" }, - { 1, "lf hid demod" }, - { 0, "lf hid reader" }, - { 0, "lf hid clone" }, - { 0, "lf hid sim" }, - { 0, "lf hid brute" }, - { 0, "lf hid watch" }, - { 1, "lf hitag help" }, - { 0, "lf hitag eload" }, - { 1, "lf hitag list" }, - { 0, "lf hitag info" }, - { 0, "lf hitag reader" }, - { 0, "lf hitag sim" }, - { 0, "lf hitag sniff" }, - { 0, "lf hitag writer" }, - { 0, "lf hitag dump" }, - { 0, "lf hitag cc" }, - { 1, "lf idteck help" }, - { 1, "lf idteck demod" }, - { 0, "lf idteck reader" }, - { 0, "lf idteck clone" }, - { 0, "lf idteck sim" }, - { 1, "lf indala help" }, - { 1, "lf indala demod" }, - { 1, "lf indala altdemod" }, - { 0, "lf indala reader" }, - { 0, "lf indala clone" }, - { 0, "lf indala sim" }, - { 1, "lf io help" }, - { 1, "lf io demod" }, - { 0, "lf io reader" }, - { 0, "lf io clone" }, - { 0, "lf io sim" }, - { 0, "lf io watch" }, - { 1, "lf jablotron help" }, - { 1, "lf jablotron demod" }, - { 0, "lf jablotron reader" }, - { 0, "lf jablotron clone" }, - { 0, "lf jablotron sim" }, - { 1, "lf keri help" }, - { 1, "lf keri demod" }, - { 0, "lf keri reader" }, - { 0, "lf keri clone" }, - { 0, "lf keri sim" }, - { 1, "lf motorola help" }, - { 1, "lf motorola demod" }, - { 0, "lf motorola reader" }, - { 0, "lf motorola clone" }, - { 0, "lf motorola sim" }, - { 1, "lf nedap help" }, - { 1, "lf nedap demod" }, - { 0, "lf nedap reader" }, - { 0, "lf nedap clone" }, - { 0, "lf nedap sim" }, - { 1, "lf nexwatch help" }, - { 1, "lf nexwatch demod" }, - { 0, "lf nexwatch reader" }, - { 0, "lf nexwatch clone" }, - { 0, "lf nexwatch sim" }, - { 1, "lf noralsy help" }, - { 1, "lf noralsy demod" }, - { 0, "lf noralsy reader" }, - { 0, "lf noralsy clone" }, - { 0, "lf noralsy sim" }, - { 1, "lf pac help" }, - { 1, "lf pac demod" }, - { 0, "lf pac reader" }, - { 0, "lf pac clone" }, - { 0, "lf pac sim" }, - { 1, "lf paradox help" }, - { 1, "lf paradox demod" }, - { 0, "lf paradox reader" }, - { 0, "lf paradox clone" }, - { 0, "lf paradox sim" }, - { 1, "lf pcf7931 help" }, - { 0, "lf pcf7931 reader" }, - { 0, "lf pcf7931 write" }, - { 1, "lf pcf7931 config" }, - { 1, "lf presco help" }, - { 1, "lf presco demod" }, - { 0, "lf presco reader" }, - { 0, "lf presco clone" }, - { 0, "lf presco sim" }, - { 1, "lf pyramid help" }, - { 1, "lf pyramid demod" }, - { 0, "lf pyramid reader" }, - { 0, "lf pyramid clone" }, - { 0, "lf pyramid sim" }, - { 1, "lf securakey help" }, - { 1, "lf securakey demod" }, - { 0, "lf securakey reader" }, - { 0, "lf securakey clone" }, - { 0, "lf securakey sim" }, - { 1, "lf ti help" }, - { 1, "lf ti demod" }, - { 0, "lf ti reader" }, - { 0, "lf ti write" }, - { 1, "lf t55xx help" }, - { 0, "lf t55xx clonehelp" }, - { 1, "lf t55xx config" }, - { 0, "lf t55xx dangerraw" }, - { 1, "lf t55xx detect" }, - { 0, "lf t55xx deviceconfig" }, - { 0, "lf t55xx dump" }, - { 1, "lf t55xx info" }, - { 0, "lf t55xx p1detect" }, - { 0, "lf t55xx read" }, - { 0, "lf t55xx resetread" }, - { 0, "lf t55xx restore" }, - { 1, "lf t55xx trace" }, - { 0, "lf t55xx wakeup" }, - { 0, "lf t55xx write" }, - { 0, "lf t55xx bruteforce" }, - { 0, "lf t55xx chk" }, - { 0, "lf t55xx protect" }, - { 0, "lf t55xx recoverpw" }, - { 1, "lf t55xx sniff" }, - { 0, "lf t55xx special" }, - { 0, "lf t55xx wipe" }, - { 1, "lf viking help" }, - { 1, "lf viking demod" }, - { 0, "lf viking reader" }, - { 0, "lf viking clone" }, - { 0, "lf viking sim" }, - { 1, "lf visa2000 help" }, - { 1, "lf visa2000 demod" }, - { 0, "lf visa2000 reader" }, - { 0, "lf visa2000 clone" }, - { 0, "lf visa2000 sim" }, - { 1, "mem help" }, - { 0, "mem baudrate" }, - { 0, "mem dump" }, - { 0, "mem info" }, - { 0, "mem load" }, - { 0, "mem wipe" }, - { 1, "mem spiffs help" }, - { 0, "mem spiffs copy" }, - { 0, "mem spiffs check" }, - { 0, "mem spiffs dump" }, - { 0, "mem spiffs info" }, - { 0, "mem spiffs mount" }, - { 0, "mem spiffs remove" }, - { 0, "mem spiffs rename" }, - { 0, "mem spiffs test" }, - { 0, "mem spiffs tree" }, - { 0, "mem spiffs unmount" }, - { 0, "mem spiffs upload" }, - { 0, "mem spiffs view" }, - { 0, "mem spiffs wipe" }, - { 1, "nfc help" }, - { 1, "nfc decode" }, - { 0, "nfc type1 read" }, - { 1, "nfc type1 help" }, - { 0, "nfc type2 read" }, - { 1, "nfc type2 help" }, - { 0, "nfc type4a read" }, - { 0, "nfc type4a st25taread" }, - { 1, "nfc type4a help" }, - { 0, "nfc type4b read" }, - { 1, "nfc type4b help" }, - { 0, "nfc mf cread" }, - { 0, "nfc mf pread" }, - { 1, "nfc mf help" }, - { 0, "nfc barcode read" }, - { 0, "nfc barcode sim" }, - { 1, "nfc barcode help" }, - { 1, "smart help" }, - { 1, "smart list" }, - { 0, "smart info" }, - { 0, "smart reader" }, - { 0, "smart raw" }, - { 1, "smart upgrade" }, - { 0, "smart setclock" }, - { 0, "smart brute" }, - { 1, "script help" }, - { 1, "script list" }, - { 1, "script run" }, - { 1, "trace help" }, - { 1, "trace extract" }, - { 1, "trace list" }, - { 1, "trace load" }, - { 1, "trace save" }, - { 1, "usart help" }, - { 0, "usart btpin" }, - { 0, "usart btfactory" }, - { 0, "usart tx" }, - { 0, "usart rx" }, - { 0, "usart txrx" }, - { 0, "usart txhex" }, - { 0, "usart rxhex" }, - { 0, "usart config" }, - { 1, "wiegand help" }, - { 1, "wiegand list" }, - { 1, "wiegand encode" }, - { 1, "wiegand decode" }, + { 1, "help" }, + { 0, "auto" }, + { 1, "clear" }, + { 1, "hints" }, + { 1, "msleep" }, + { 1, "rem" }, + { 1, "quit" }, + { 1, "exit" }, + { 1, "prefs help" }, + { 1, "prefs show" }, + { 1, "prefs get barmode" }, + { 1, "prefs get clientdebug" }, + { 1, "prefs get clientdelay" }, + { 1, "prefs get color" }, + { 1, "prefs get savepaths" }, + { 1, "prefs get emoji" }, + { 1, "prefs get hints" }, + { 1, "prefs get output" }, + { 1, "prefs get plotsliders" }, + { 1, "prefs set help" }, + { 1, "prefs set barmode" }, + { 1, "prefs set clientdebug" }, + { 1, "prefs set clientdelay" }, + { 1, "prefs set color" }, + { 1, "prefs set emoji" }, + { 1, "prefs set hints" }, + { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, + { 1, "prefs set plotsliders" }, + { 1, "analyse help" }, + { 1, "analyse lcr" }, + { 1, "analyse crc" }, + { 1, "analyse chksum" }, + { 1, "analyse dates" }, + { 1, "analyse lfsr" }, + { 1, "analyse a" }, + { 1, "analyse nuid" }, + { 1, "analyse demodbuff" }, + { 1, "analyse freq" }, + { 1, "analyse foo" }, + { 1, "analyse units" }, + { 1, "data help" }, + { 1, "data biphaserawdecode" }, + { 1, "data detectclock" }, + { 1, "data fsktonrz" }, + { 1, "data manrawdecode" }, + { 1, "data modulation" }, + { 1, "data rawdemod" }, + { 1, "data askedgedetect" }, + { 1, "data autocorr" }, + { 1, "data dirthreshold" }, + { 1, "data decimate" }, + { 1, "data undecimate" }, + { 1, "data hide" }, + { 1, "data hpf" }, + { 1, "data iir" }, + { 1, "data grid" }, + { 1, "data ltrim" }, + { 1, "data mtrim" }, + { 1, "data norm" }, + { 1, "data plot" }, + { 1, "data rtrim" }, + { 1, "data setgraphmarkers" }, + { 1, "data shiftgraphzero" }, + { 1, "data timescale" }, + { 1, "data zerocrossings" }, + { 1, "data convertbitstream" }, + { 1, "data getbitstream" }, + { 1, "data asn1" }, + { 1, "data bin2hex" }, + { 0, "data bitsamples" }, + { 1, "data clear" }, + { 1, "data diff" }, + { 0, "data hexsamples" }, + { 1, "data hex2bin" }, + { 1, "data load" }, + { 1, "data print" }, + { 0, "data samples" }, + { 1, "data save" }, + { 1, "data setdebugmode" }, + { 0, "data tune" }, + { 1, "emv help" }, + { 0, "emv exec" }, + { 0, "emv pse" }, + { 0, "emv search" }, + { 0, "emv select" }, + { 0, "emv gpo" }, + { 0, "emv readrec" }, + { 0, "emv genac" }, + { 0, "emv challenge" }, + { 0, "emv intauth" }, + { 0, "emv scan" }, + { 1, "emv test" }, + { 1, "emv list" }, + { 0, "emv roca" }, + { 1, "hf help" }, + { 1, "hf list" }, + { 0, "hf plot" }, + { 0, "hf tune" }, + { 1, "hf search" }, + { 0, "hf sniff" }, + { 1, "hf 14a help" }, + { 1, "hf 14a list" }, + { 0, "hf 14a info" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a apdu" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a antifuzz" }, + { 0, "hf 14a config" }, + { 0, "hf 14a apdufind" }, + { 1, "hf 14b help" }, + { 0, "hf 14b apdu" }, + { 0, "hf 14b dump" }, + { 0, "hf 14b info" }, + { 1, "hf 14b list" }, + { 0, "hf 14b ndefread" }, + { 0, "hf 14b raw" }, + { 0, "hf 14b reader" }, + { 0, "hf 14b sim" }, + { 0, "hf 14b sniff" }, + { 0, "hf 14b rdbl" }, + { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, + { 1, "hf 15 help" }, + { 1, "hf 15 list" }, + { 1, "hf 15 demod" }, + { 0, "hf 15 dump" }, + { 0, "hf 15 info" }, + { 0, "hf 15 sniff" }, + { 0, "hf 15 raw" }, + { 0, "hf 15 rdbl" }, + { 0, "hf 15 rdmulti" }, + { 0, "hf 15 reader" }, + { 0, "hf 15 restore" }, + { 0, "hf 15 samples" }, + { 0, "hf 15 eload" }, + { 0, "hf 15 esave" }, + { 0, "hf 15 eview" }, + { 0, "hf 15 sim" }, + { 0, "hf 15 slixdisable" }, + { 0, "hf 15 wrbl" }, + { 0, "hf 15 findafi" }, + { 0, "hf 15 writeafi" }, + { 0, "hf 15 writedsfid" }, + { 0, "hf 15 csetuid" }, + { 1, "hf cipurse help" }, + { 0, "hf cipurse info" }, + { 0, "hf cipurse select" }, + { 0, "hf cipurse auth" }, + { 0, "hf cipurse read" }, + { 0, "hf cipurse write" }, + { 0, "hf cipurse aread" }, + { 0, "hf cipurse awrite" }, + { 0, "hf cipurse formatall" }, + { 0, "hf cipurse create" }, + { 0, "hf cipurse delete" }, + { 0, "hf cipurse updkey" }, + { 0, "hf cipurse updakey" }, + { 0, "hf cipurse default" }, + { 1, "hf cipurse test" }, + { 1, "hf epa help" }, + { 0, "hf epa cnonces" }, + { 0, "hf epa preplay" }, + { 1, "hf emrtd help" }, + { 0, "hf emrtd dump" }, + { 1, "hf emrtd info" }, + { 1, "hf emrtd list" }, + { 1, "hf felica help" }, + { 1, "hf felica list" }, + { 0, "hf felica reader" }, + { 0, "hf felica info" }, + { 0, "hf felica sniff" }, + { 0, "hf felica raw" }, + { 0, "hf felica rdbl" }, + { 0, "hf felica wrbl" }, + { 0, "hf felica rqservice" }, + { 0, "hf felica rqresponse" }, + { 0, "hf felica scsvcode" }, + { 0, "hf felica rqsyscode" }, + { 0, "hf felica auth1" }, + { 0, "hf felica auth2" }, + { 0, "hf felica rqspecver" }, + { 0, "hf felica resetmode" }, + { 0, "hf felica litesim" }, + { 0, "hf felica litedump" }, + { 1, "hf fido help" }, + { 1, "hf fido list" }, + { 0, "hf fido info" }, + { 0, "hf fido reg" }, + { 0, "hf fido auth" }, + { 0, "hf fido make" }, + { 0, "hf fido assert" }, + { 1, "hf fudan help" }, + { 0, "hf fudan reader" }, + { 0, "hf fudan dump" }, + { 0, "hf fudan rdbl" }, + { 1, "hf fudan view" }, + { 0, "hf fudan wrbl" }, + { 1, "hf gallagher help" }, + { 0, "hf gallagher reader" }, + { 0, "hf gallagher clone" }, + { 0, "hf gallagher delete" }, + { 1, "hf gallagher diversifykey" }, + { 1, "hf gallagher decode" }, + { 1, "hf ksx6924 help" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 initialize" }, + { 0, "hf ksx6924 prec" }, + { 0, "hf ksx6924 select" }, + { 1, "hf jooki help" }, + { 0, "hf jooki clone" }, + { 1, "hf jooki decode" }, + { 1, "hf jooki encode" }, + { 0, "hf jooki sim" }, + { 1, "hf iclass help" }, + { 0, "hf iclass dump" }, + { 1, "hf iclass info" }, + { 1, "hf iclass list" }, + { 0, "hf iclass rdbl" }, + { 0, "hf iclass reader" }, + { 0, "hf iclass restore" }, + { 0, "hf iclass sniff" }, + { 0, "hf iclass wrbl" }, + { 0, "hf iclass chk" }, + { 1, "hf iclass loclass" }, + { 1, "hf iclass lookup" }, + { 0, "hf iclass sim" }, + { 0, "hf iclass eload" }, + { 0, "hf iclass esave" }, + { 0, "hf iclass eview" }, + { 1, "hf iclass configcard" }, + { 1, "hf iclass calcnewkey" }, + { 1, "hf iclass encode" }, + { 1, "hf iclass encrypt" }, + { 1, "hf iclass decrypt" }, + { 1, "hf iclass managekeys" }, + { 1, "hf iclass permutekey" }, + { 1, "hf iclass view" }, + { 1, "hf legic help" }, + { 0, "hf legic dump" }, + { 0, "hf legic info" }, + { 1, "hf legic list" }, + { 0, "hf legic rdbl" }, + { 0, "hf legic reader" }, + { 0, "hf legic restore" }, + { 0, "hf legic wipe" }, + { 0, "hf legic wrbl" }, + { 0, "hf legic sim" }, + { 0, "hf legic eload" }, + { 0, "hf legic esave" }, + { 0, "hf legic eview" }, + { 1, "hf legic crc" }, + { 1, "hf legic view" }, + { 1, "hf lto help" }, + { 0, "hf lto dump" }, + { 0, "hf lto info" }, + { 1, "hf lto list" }, + { 0, "hf lto rdbl" }, + { 0, "hf lto reader" }, + { 0, "hf lto restore" }, + { 0, "hf lto wrbl" }, + { 1, "hf mf help" }, + { 1, "hf mf list" }, + { 0, "hf mf darkside" }, + { 0, "hf mf nested" }, + { 1, "hf mf hardnested" }, + { 0, "hf mf staticnested" }, + { 0, "hf mf autopwn" }, + { 0, "hf mf nack" }, + { 0, "hf mf chk" }, + { 0, "hf mf fchk" }, + { 1, "hf mf decrypt" }, + { 0, "hf mf supercard" }, + { 0, "hf mf auth4" }, + { 1, "hf mf acl" }, + { 0, "hf mf dump" }, + { 1, "hf mf mad" }, + { 0, "hf mf personalize" }, + { 0, "hf mf rdbl" }, + { 0, "hf mf rdsc" }, + { 0, "hf mf restore" }, + { 0, "hf mf setmod" }, + { 1, "hf mf value" }, + { 1, "hf mf view" }, + { 0, "hf mf wipe" }, + { 0, "hf mf wrbl" }, + { 0, "hf mf sim" }, + { 0, "hf mf ecfill" }, + { 0, "hf mf eclr" }, + { 0, "hf mf egetblk" }, + { 0, "hf mf egetsc" }, + { 0, "hf mf ekeyprn" }, + { 0, "hf mf eload" }, + { 0, "hf mf esave" }, + { 0, "hf mf esetblk" }, + { 0, "hf mf eview" }, + { 0, "hf mf cgetblk" }, + { 0, "hf mf cgetsc" }, + { 0, "hf mf cload" }, + { 0, "hf mf csave" }, + { 0, "hf mf csetblk" }, + { 0, "hf mf csetuid" }, + { 0, "hf mf cview" }, + { 0, "hf mf cwipe" }, + { 0, "hf mf gen3uid" }, + { 0, "hf mf gen3blk" }, + { 0, "hf mf gen3freeze" }, + { 0, "hf mf gview" }, + { 0, "hf mf ndefformat" }, + { 0, "hf mf ndefread" }, + { 1, "hf mfp help" }, + { 0, "hf mfp info" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp auth" }, + { 0, "hf mfp rdbl" }, + { 0, "hf mfp rdsc" }, + { 0, "hf mfp wrbl" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp mad" }, + { 0, "hf mfp ndefread" }, + { 1, "hf mfu help" }, + { 1, "hf mfu keygen" }, + { 1, "hf mfu pwdgen" }, + { 0, "hf mfu otptear" }, + { 0, "hf mfu cauth" }, + { 0, "hf mfu dump" }, + { 0, "hf mfu info" }, + { 0, "hf mfu ndefread" }, + { 0, "hf mfu rdbl" }, + { 0, "hf mfu restore" }, + { 1, "hf mfu view" }, + { 0, "hf mfu wrbl" }, + { 0, "hf mfu eload" }, + { 0, "hf mfu eview" }, + { 0, "hf mfu sim" }, + { 0, "hf mfu setpwd" }, + { 0, "hf mfu setuid" }, + { 1, "hf mfdes help" }, + { 0, "hf mfdes info" }, + { 0, "hf mfdes getuid" }, + { 0, "hf mfdes default" }, + { 0, "hf mfdes auth" }, + { 0, "hf mfdes chk" }, + { 0, "hf mfdes detect" }, + { 0, "hf mfdes freemem" }, + { 0, "hf mfdes setconfig" }, + { 0, "hf mfdes formatpicc" }, + { 1, "hf mfdes list" }, + { 0, "hf mfdes mad" }, + { 0, "hf mfdes lsapp" }, + { 0, "hf mfdes getaids" }, + { 0, "hf mfdes getappnames" }, + { 0, "hf mfdes bruteaid" }, + { 0, "hf mfdes createapp" }, + { 0, "hf mfdes deleteapp" }, + { 0, "hf mfdes selectapp" }, + { 0, "hf mfdes changekey" }, + { 0, "hf mfdes chkeysettings" }, + { 0, "hf mfdes getkeysettings" }, + { 0, "hf mfdes getkeyversions" }, + { 0, "hf mfdes getfileids" }, + { 0, "hf mfdes getfileisoids" }, + { 0, "hf mfdes lsfiles" }, + { 0, "hf mfdes dump" }, + { 0, "hf mfdes createfile" }, + { 0, "hf mfdes createvaluefile" }, + { 0, "hf mfdes createrecordfile" }, + { 0, "hf mfdes createmacfile" }, + { 0, "hf mfdes deletefile" }, + { 0, "hf mfdes getfilesettings" }, + { 0, "hf mfdes chfilesettings" }, + { 0, "hf mfdes read" }, + { 0, "hf mfdes write" }, + { 0, "hf mfdes value" }, + { 0, "hf mfdes clearrecfile" }, + { 1, "hf mfdes test" }, + { 1, "hf ntag424 help" }, + { 0, "hf ntag424 info" }, + { 0, "hf ntag424 sdm" }, + { 1, "hf ntag424 view" }, + { 1, "hf seos help" }, + { 0, "hf seos info" }, + { 1, "hf seos list" }, + { 1, "hf st25ta help" }, + { 0, "hf st25ta info" }, + { 1, "hf st25ta list" }, + { 1, "hf st25ta ndefread" }, + { 0, "hf st25ta protect" }, + { 0, "hf st25ta pwd" }, + { 0, "hf st25ta sim" }, + { 1, "hf thinfilm help" }, + { 0, "hf thinfilm info" }, + { 1, "hf thinfilm list" }, + { 0, "hf thinfilm sim" }, + { 1, "hf topaz help" }, + { 0, "hf topaz dump" }, + { 1, "hf topaz list" }, + { 0, "hf topaz info" }, + { 0, "hf topaz reader" }, + { 0, "hf topaz sim" }, + { 0, "hf topaz sniff" }, + { 0, "hf topaz raw" }, + { 0, "hf topaz rdbl" }, + { 1, "hf topaz view" }, + { 0, "hf topaz wrbl" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, + { 0, "hf xerox dump" }, + { 1, "hf waveshare help" }, + { 0, "hf waveshare loadbmp" }, + { 1, "hw help" }, + { 0, "hw break" }, + { 1, "hw connect" }, + { 0, "hw dbg" }, + { 0, "hw detectreader" }, + { 0, "hw fpgaoff" }, + { 0, "hw lcd" }, + { 0, "hw lcdreset" }, + { 0, "hw ping" }, + { 0, "hw readmem" }, + { 0, "hw reset" }, + { 0, "hw setlfdivisor" }, + { 0, "hw setmux" }, + { 0, "hw standalone" }, + { 0, "hw status" }, + { 0, "hw tearoff" }, + { 0, "hw tia" }, + { 0, "hw tune" }, + { 1, "hw version" }, + { 1, "lf help" }, + { 0, "lf config" }, + { 0, "lf cmdread" }, + { 0, "lf read" }, + { 1, "lf search" }, + { 0, "lf sim" }, + { 0, "lf simask" }, + { 0, "lf simfsk" }, + { 0, "lf simpsk" }, + { 0, "lf simbidir" }, + { 0, "lf sniff" }, + { 0, "lf tune" }, + { 1, "lf awid help" }, + { 1, "lf awid demod" }, + { 0, "lf awid reader" }, + { 0, "lf awid clone" }, + { 0, "lf awid sim" }, + { 0, "lf awid brute" }, + { 0, "lf awid watch" }, + { 1, "lf cotag help" }, + { 1, "lf cotag demod" }, + { 0, "lf cotag reader" }, + { 1, "lf destron help" }, + { 1, "lf destron demod" }, + { 0, "lf destron reader" }, + { 0, "lf destron clone" }, + { 0, "lf destron sim" }, + { 1, "lf em help" }, + { 1, "lf em 410x help" }, + { 1, "lf em 410x demod" }, + { 0, "lf em 410x reader" }, + { 0, "lf em 410x sim" }, + { 0, "lf em 410x brute" }, + { 0, "lf em 410x watch" }, + { 0, "lf em 410x spoof" }, + { 0, "lf em 410x clone" }, + { 1, "lf em 4x05 help" }, + { 0, "lf em 4x05 brute" }, + { 0, "lf em 4x05 chk" }, + { 1, "lf em 4x05 demod" }, + { 0, "lf em 4x05 dump" }, + { 0, "lf em 4x05 info" }, + { 0, "lf em 4x05 read" }, + { 1, "lf em 4x05 sniff" }, + { 0, "lf em 4x05 unlock" }, + { 0, "lf em 4x05 wipe" }, + { 0, "lf em 4x05 write" }, + { 1, "lf em 4x50 help" }, + { 0, "lf em 4x50 brute" }, + { 0, "lf em 4x50 chk" }, + { 0, "lf em 4x50 dump" }, + { 0, "lf em 4x50 info" }, + { 0, "lf em 4x50 login" }, + { 0, "lf em 4x50 rdbl" }, + { 0, "lf em 4x50 reader" }, + { 0, "lf em 4x50 restore" }, + { 0, "lf em 4x50 wrbl" }, + { 0, "lf em 4x50 wrpwd" }, + { 0, "lf em 4x50 wipe" }, + { 0, "lf em 4x50 eload" }, + { 0, "lf em 4x50 esave" }, + { 0, "lf em 4x50 eview" }, + { 0, "lf em 4x50 sim" }, + { 1, "lf em 4x70 help" }, + { 0, "lf em 4x70 info" }, + { 0, "lf em 4x70 write" }, + { 0, "lf em 4x70 unlock" }, + { 0, "lf em 4x70 auth" }, + { 0, "lf em 4x70 writepin" }, + { 0, "lf em 4x70 writekey" }, + { 1, "lf fdxb help" }, + { 1, "lf fdxb demod" }, + { 0, "lf fdxb reader" }, + { 0, "lf fdxb clone" }, + { 0, "lf fdxb sim" }, + { 1, "lf gallagher help" }, + { 1, "lf gallagher demod" }, + { 0, "lf gallagher reader" }, + { 0, "lf gallagher clone" }, + { 0, "lf gallagher sim" }, + { 1, "lf gproxii help" }, + { 1, "lf gproxii demod" }, + { 0, "lf gproxii reader" }, + { 0, "lf gproxii clone" }, + { 0, "lf gproxii sim" }, + { 1, "lf hid help" }, + { 1, "lf hid demod" }, + { 0, "lf hid reader" }, + { 0, "lf hid clone" }, + { 0, "lf hid sim" }, + { 0, "lf hid brute" }, + { 0, "lf hid watch" }, + { 1, "lf hitag help" }, + { 0, "lf hitag eload" }, + { 1, "lf hitag list" }, + { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, + { 0, "lf hitag sim" }, + { 0, "lf hitag sniff" }, + { 0, "lf hitag writer" }, + { 0, "lf hitag dump" }, + { 0, "lf hitag cc" }, + { 1, "lf idteck help" }, + { 1, "lf idteck demod" }, + { 0, "lf idteck reader" }, + { 0, "lf idteck clone" }, + { 0, "lf idteck sim" }, + { 1, "lf indala help" }, + { 1, "lf indala demod" }, + { 1, "lf indala altdemod" }, + { 0, "lf indala reader" }, + { 0, "lf indala clone" }, + { 0, "lf indala sim" }, + { 1, "lf io help" }, + { 1, "lf io demod" }, + { 0, "lf io reader" }, + { 0, "lf io clone" }, + { 0, "lf io sim" }, + { 0, "lf io watch" }, + { 1, "lf jablotron help" }, + { 1, "lf jablotron demod" }, + { 0, "lf jablotron reader" }, + { 0, "lf jablotron clone" }, + { 0, "lf jablotron sim" }, + { 1, "lf keri help" }, + { 1, "lf keri demod" }, + { 0, "lf keri reader" }, + { 0, "lf keri clone" }, + { 0, "lf keri sim" }, + { 1, "lf motorola help" }, + { 1, "lf motorola demod" }, + { 0, "lf motorola reader" }, + { 0, "lf motorola clone" }, + { 0, "lf motorola sim" }, + { 1, "lf nedap help" }, + { 1, "lf nedap demod" }, + { 0, "lf nedap reader" }, + { 0, "lf nedap clone" }, + { 0, "lf nedap sim" }, + { 1, "lf nexwatch help" }, + { 1, "lf nexwatch demod" }, + { 0, "lf nexwatch reader" }, + { 0, "lf nexwatch clone" }, + { 0, "lf nexwatch sim" }, + { 1, "lf noralsy help" }, + { 1, "lf noralsy demod" }, + { 0, "lf noralsy reader" }, + { 0, "lf noralsy clone" }, + { 0, "lf noralsy sim" }, + { 1, "lf pac help" }, + { 1, "lf pac demod" }, + { 0, "lf pac reader" }, + { 0, "lf pac clone" }, + { 0, "lf pac sim" }, + { 1, "lf paradox help" }, + { 1, "lf paradox demod" }, + { 0, "lf paradox reader" }, + { 0, "lf paradox clone" }, + { 0, "lf paradox sim" }, + { 1, "lf pcf7931 help" }, + { 0, "lf pcf7931 reader" }, + { 0, "lf pcf7931 write" }, + { 1, "lf pcf7931 config" }, + { 1, "lf presco help" }, + { 1, "lf presco demod" }, + { 0, "lf presco reader" }, + { 0, "lf presco clone" }, + { 0, "lf presco sim" }, + { 1, "lf pyramid help" }, + { 1, "lf pyramid demod" }, + { 0, "lf pyramid reader" }, + { 0, "lf pyramid clone" }, + { 0, "lf pyramid sim" }, + { 1, "lf securakey help" }, + { 1, "lf securakey demod" }, + { 0, "lf securakey reader" }, + { 0, "lf securakey clone" }, + { 0, "lf securakey sim" }, + { 1, "lf ti help" }, + { 1, "lf ti demod" }, + { 0, "lf ti reader" }, + { 0, "lf ti write" }, + { 1, "lf t55xx help" }, + { 0, "lf t55xx clonehelp" }, + { 1, "lf t55xx config" }, + { 0, "lf t55xx dangerraw" }, + { 1, "lf t55xx detect" }, + { 0, "lf t55xx deviceconfig" }, + { 0, "lf t55xx dump" }, + { 1, "lf t55xx info" }, + { 0, "lf t55xx p1detect" }, + { 0, "lf t55xx read" }, + { 0, "lf t55xx resetread" }, + { 0, "lf t55xx restore" }, + { 1, "lf t55xx trace" }, + { 0, "lf t55xx wakeup" }, + { 0, "lf t55xx write" }, + { 0, "lf t55xx bruteforce" }, + { 0, "lf t55xx chk" }, + { 0, "lf t55xx protect" }, + { 0, "lf t55xx recoverpw" }, + { 1, "lf t55xx sniff" }, + { 0, "lf t55xx special" }, + { 0, "lf t55xx wipe" }, + { 1, "lf viking help" }, + { 1, "lf viking demod" }, + { 0, "lf viking reader" }, + { 0, "lf viking clone" }, + { 0, "lf viking sim" }, + { 1, "lf visa2000 help" }, + { 1, "lf visa2000 demod" }, + { 0, "lf visa2000 reader" }, + { 0, "lf visa2000 clone" }, + { 0, "lf visa2000 sim" }, + { 1, "mem help" }, + { 0, "mem baudrate" }, + { 0, "mem dump" }, + { 0, "mem info" }, + { 0, "mem load" }, + { 0, "mem wipe" }, + { 1, "mem spiffs help" }, + { 0, "mem spiffs copy" }, + { 0, "mem spiffs check" }, + { 0, "mem spiffs dump" }, + { 0, "mem spiffs info" }, + { 0, "mem spiffs mount" }, + { 0, "mem spiffs remove" }, + { 0, "mem spiffs rename" }, + { 0, "mem spiffs test" }, + { 0, "mem spiffs tree" }, + { 0, "mem spiffs unmount" }, + { 0, "mem spiffs upload" }, + { 0, "mem spiffs view" }, + { 0, "mem spiffs wipe" }, + { 1, "nfc help" }, + { 1, "nfc decode" }, + { 0, "nfc type1 read" }, + { 1, "nfc type1 help" }, + { 0, "nfc type2 read" }, + { 1, "nfc type2 help" }, + { 0, "nfc type4a read" }, + { 0, "nfc type4a st25taread" }, + { 1, "nfc type4a help" }, + { 0, "nfc type4b read" }, + { 1, "nfc type4b help" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf cformat" }, + { 0, "nfc mf pread" }, + { 1, "nfc mf help" }, + { 0, "nfc barcode read" }, + { 0, "nfc barcode sim" }, + { 1, "nfc barcode help" }, + { 1, "smart help" }, + { 1, "smart list" }, + { 0, "smart info" }, + { 0, "smart reader" }, + { 0, "smart raw" }, + { 1, "smart upgrade" }, + { 0, "smart setclock" }, + { 0, "smart brute" }, + { 1, "script help" }, + { 1, "script list" }, + { 1, "script run" }, + { 1, "trace help" }, + { 1, "trace extract" }, + { 1, "trace list" }, + { 1, "trace load" }, + { 1, "trace save" }, + { 1, "usart help" }, + { 0, "usart btpin" }, + { 0, "usart btfactory" }, + { 0, "usart tx" }, + { 0, "usart rx" }, + { 0, "usart txrx" }, + { 0, "usart txhex" }, + { 0, "usart rxhex" }, + { 0, "usart config" }, + { 1, "wiegand help" }, + { 1, "wiegand list" }, + { 1, "wiegand encode" }, + { 1, "wiegand decode" }, {0, NULL} }; @@ -743,4 +760,4 @@ const static vocabulory_t vocabulory[] = { } #endif -#endif +#endif \ No newline at end of file diff --git a/doc/commands.json b/doc/commands.json index 7b0472464..27eb64235 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -484,9 +484,11 @@ "offline": true, "options": [ "-h, --help This help", - "-f, --file file to load" + "-f, --file file to load", + "-b, --bin binary file", + "-n, --no-fix Load data from file without any transformations" ], - "usage": "data load [-h] -f " + "usage": "data load [-hbn] -f " }, "data ltrim": { "command": "data ltrim", @@ -631,7 +633,7 @@ "options": [ "-h, --help This help", "-n num of samples (512 - 40000)", - "-v, --verbose verbose" + "-v, --verbose verbose output" ], "usage": "data samples [-hv] [-n ]" }, @@ -1223,7 +1225,7 @@ "hf 14a sim -t 4 -> ISO/IEC 14443-4", "hf 14a sim -t 5 -> MIFARE Tnp3xxx", "hf 14a sim -t 6 -> MIFARE Mini", - "hf 14a sim -t 7 -> AMIIBO (NTAG 215), pack 0x8080", + "hf 14a sim -t 7 -> Amiibo (NTAG 215), pack 0x8080", "hf 14a sim -t 8 -> MIFARE Classic 4k", "hf 14a sim -t 9 -> FM11RF005SH Shanghai Metro", "hf 14a sim -t 10 -> ST25TA IKEA Rothult" @@ -1232,7 +1234,7 @@ "options": [ "-h, --help This help", "-t, --type <1-10> Simulation type to use", - "-u, --uid 4, 7 or 10 byte UID", + "-u, --uid <4|7|10> hex bytes UID", "-n, --num Exit simulation after blocks have been read by reader. 0 = infinite", "-x Performs the 'reader attack', nr/ar attack against a reader", "--sk Fill simulator keys from found keys", @@ -1311,7 +1313,7 @@ "options": [ "-h, --help This help", "-s, --aidsearch checks if AIDs from aidlist.json is present on the card and prints information about found AIDs", - "-v, --verbose verbose" + "-v, --verbose verbose output" ], "usage": "hf 14b info [-hsv]" }, @@ -1369,7 +1371,7 @@ "-c, --crc calculate and append CRC", "-r do not read response from card", "-t, --timeout timeout in ms", - "-v, --verbose verbose", + "-v, --verbose verbose output", "-d, --data data, bytes to send" ], "usage": "hf 14b raw [-hkscrv] [--sr] [--cts] [--xrx] [-t ] [-d ]" @@ -1391,15 +1393,16 @@ "command": "hf 14b reader", "description": "Act as a 14443B reader to identify a tag", "notes": [ - "hf 14b reader" + "hf 14b reader", + "hf 14b reader -@ -> continuous reader mode" ], "offline": false, "options": [ "-h, --help This help", - "-s, --silent silent (no messages)", + "-v, --verbose verbose output", "-@ optional - continuous reader mode" ], - "usage": "hf 14b reader [-hs@]" + "usage": "hf 14b reader [-hv@]" }, "hf 14b sim": { "command": "hf 14b sim", @@ -1505,6 +1508,49 @@ ], "usage": "hf 15 dump [-h*2o] [-u ] [--ua] [-f ]" }, + "hf 15 eload": { + "command": "hf 15 eload", + "description": "Load memory image from file to be used with 'hf 15 sim'", + "notes": [ + "hf 15 eload -f hf-15-01020304.bin" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-f, --file filename of image" + ], + "usage": "hf 15 eload [-h] -f " + }, + "hf 15 esave": { + "command": "hf 15 esave", + "description": "Save emulator memory into three files (BIN/EML/JSON)", + "notes": [ + "hf 15 esave -f hf-15-01020304hf 15 esave -b 8 -c 42 -f hf-15-01020304" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-f, --file filename of dump", + "-b, --blocksize block size, defaults to 4", + "-c, --count number of blocks to export, defaults to all" + ], + "usage": "hf 15 esave [-h] -f [-b ] [-c ]" + }, + "hf 15 eview": { + "command": "hf 15 eview", + "description": "It displays emulator memory", + "notes": [ + "hf 15 eview", + "hf 15 eview -b 8 -c 60" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-b, --blocksize block size, defaults to 4", + "-c, --count number of blocks to display, defaults to all" + ], + "usage": "hf 15 eview [-h] [-b ] [-c ]" + }, "hf 15 findafi": { "command": "hf 15 findafi", "description": "This command attempts to brute force AFI of an ISO-15693 tag Estimated execution time is around 2 minutes", @@ -1680,9 +1726,10 @@ "offline": false, "options": [ "-h, --help This help", - "-u, --uid <8b hex> UID eg E011223344556677" + "-u, --uid <8b hex> UID eg E011223344556677", + "-b, --blocksize block size, defaults to 4" ], - "usage": "hf 15 sim [-h] -u <8b hex>" + "usage": "hf 15 sim [-h] -u <8b hex> [-b ]" }, "hf 15 slixdisable": { "command": "hf 15 slixdisable", @@ -2133,9 +2180,10 @@ "-d, --dateofbirth date of birth in YYMMDD format", "-e, --expiry expiry in YYMMDD format", "-m, --mrz <[0-9A-Z<]> 2nd line of MRZ, 44 chars (passports only)", - "--path display info from offline dump stored in dirpath" + "--path display info from offline dump stored in dirpath", + "-i, --images show images" ], - "usage": "hf emrtd info [-h] [-n ] [-d ] [-e ] [-m <[0-9A-Z<]>] [--path ]" + "usage": "hf emrtd info [-hi] [-n ] [-d ] [-e ] [-m <[0-9A-Z<]>] [--path ]" }, "hf emrtd list": { "command": "hf emrtd list", @@ -2215,7 +2263,7 @@ "--sn number of service, 1 byte", "--scl service code list, 2 bytes", "-k, --key 3des key, 16 bytes", - "-v, --verbose verbose helptext" + "-v, --verbose verbose output" ], "usage": "hf felica auth1 [-hv] [--an ] [--acl ] [-i ] [--sn ] [--scl ] [-k ]" }, @@ -2232,7 +2280,7 @@ "-i set custom IDm", "-c, --cc M3c card challenge, 8 bytes", "-k, --key 3des M3c decryption key, 16 bytes", - "-v, --verbose verbose helptext" + "-v, --verbose verbose output" ], "usage": "hf felica auth2 [-hv] [-i ] [-c ] [-k ]" }, @@ -2357,7 +2405,7 @@ "-h, --help This help", "-i set custom IDm", "-r set custom reserve", - "-v, --verbose verbose helptext" + "-v, --verbose verbose output" ], "usage": "hf felica resetmode [-hv] [-i ] [-r ]" }, @@ -2405,7 +2453,7 @@ "-h, --help This help", "-i set custom IDm", "-r set custom reserve", - "-v, --verbose verbose helptext" + "-v, --verbose verbose output" ], "usage": "hf felica rqspecver [-hv] [-i ] [-r ]" }, @@ -2586,6 +2634,86 @@ ], "usage": "hf fido reg [-havt] [-f ] [--cp ] [--ap ] [--cpx ] [--apx ]" }, + "hf fudan dump": { + "command": "hf fudan dump", + "description": "Dump FUDAN tag to binary file If no given, UID will be used as filename", + "notes": [ + "hf fudan dump -f mydump -> dump using filename" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-f, --file filename of dump" + ], + "usage": "hf fudan dump [-h] [-f ]" + }, + "hf fudan help": { + "command": "hf fudan help", + "description": "help This help view Display content from tag dump file", + "notes": [], + "offline": true, + "options": [], + "usage": "" + }, + "hf fudan rdbl": { + "command": "hf fudan rdbl", + "description": "Read fudan block", + "notes": [ + "hf fudan rdbl --blk 0 -k FFFFFFFFFFFF", + "hf fudan rdbl --blk 3 -v" + ], + "offline": false, + "options": [ + "-h, --help This help", + "--blk block number", + "-k, --key key, 6 hex bytes", + "-v, --verbose verbose output" + ], + "usage": "hf fudan rdbl [-hv] --blk [-k ]" + }, + "hf fudan reader": { + "command": "hf fudan reader", + "description": "Read a fudan tag", + "notes": [ + "hf fudan reader", + "hf fudan reader -@ -> continuous reader mode" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-v, --verbose verbose output", + "-@ optional - continuous reader mode" + ], + "usage": "hf fudan reader [-hv@]" + }, + "hf fudan view": { + "command": "hf fudan view", + "description": "Print a FUDAN dump file (bin/eml/json)", + "notes": [ + "hf fudan view -f hf-fudan-01020304-dump.bin" + ], + "offline": true, + "options": [ + "-h, --help This help", + "-f, --file filename of dump" + ], + "usage": "hf fudan view [-h] -f " + }, + "hf fudan wrbl": { + "command": "hf fudan wrbl", + "description": "Write fudan block with 4 hex bytes of data", + "notes": [ + "hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 01020304" + ], + "offline": false, + "options": [ + "-h, --help This help", + "--blk block number", + "-k, --key key, 6 hex bytes", + "-d, --data bytes to write, 4 hex bytes" + ], + "usage": "hf fudan wrbl [-h] --blk [-k ] [-d ]" + }, "hf gallagher clone": { "command": "hf gallagher clone", "description": "Clone Gallagher credentials to a writable DESFire card Specify site key is required if using non-default key Key, lengths for the different crypto: DES 8 bytes 2TDEA or AES 16 bytes 3TDEA 24 bytes AID, default finds lowest available in range 0x??81F4, where ?? >= 0x20.", @@ -2612,6 +2740,19 @@ ], "usage": "hf gallagher clone [-hv] [-n ] [-t ] [-k ] --rc --fc --cn --il [--aid ] [--sitekey ] [--cadkey ] [--nocadupdate] [--noappcreate] [--apdu]" }, + "hf gallagher decode": { + "command": "hf gallagher decode", + "description": "Decode Gallagher credential block Credential block can be specified with or without the bitwise inverse.", + "notes": [ + "hf gallagher decode --data A3B4B0C151B0A31B" + ], + "offline": true, + "options": [ + "-h, --help This help", + "--data Credential block (8 or 16 bytes)" + ], + "usage": "hf gallagher decode [-h] --data " + }, "hf gallagher delete": { "command": "hf gallagher delete", "description": "Delete Gallagher application from a DESFire card Specify site key is required if using non-default key", @@ -2650,7 +2791,7 @@ }, "hf gallagher help": { "command": "hf gallagher help", - "description": "help This help diversifykey Diversify Gallagher key", + "description": "help This help diversifykey Diversify Gallagher key decode Decode Gallagher credential block", "notes": [], "offline": true, "options": [], @@ -2676,7 +2817,7 @@ }, "hf help": { "command": "hf help", - "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } texkom { Texkom RFIDs... } xerox { Fuji/Xerox cartridge RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags", + "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } texkom { Texkom RFIDs... } xerox { Fuji/Xerox cartridge RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags", "notes": [], "offline": true, "options": [], @@ -2768,9 +2909,10 @@ "--ci credit key index to select key from memory 'hf iclass managekeys'", "--elite elite computations applied to key", "--raw raw, the key is interpreted as raw block 3/4", - "--nr replay of NR/MAC" + "--nr replay of NR/MAC", + "-z, --dense dense dump output style" ], - "usage": "hf iclass dump [-h] [-f ] [-k ] [--ki ] [--credit ] [--ci ] [--elite] [--raw] [--nr]" + "usage": "hf iclass dump [-hz] [-f ] [-k ] [--ki ] [--credit ] [--ci ] [--elite] [--raw] [--nr]" }, "hf iclass eload": { "command": "hf iclass eload", @@ -2853,9 +2995,10 @@ "options": [ "-h, --help This help", "-s, --size <256|2048> number of bytes to save (default 256)", - "-v, --verbose verbose output" + "-v, --verbose verbose output", + "-z, --dense dense dump output style" ], - "usage": "hf iclass eview [-hv] [-s <256|2048>]" + "usage": "hf iclass eview [-hvz] [-s <256|2048>]" }, "hf iclass help": { "command": "hf iclass help", @@ -3072,9 +3215,10 @@ "-f, --file filename of dump (bin/eml/json)", "--first Begin printing from this block (default block 6)", "--last End printing at this block (default 0, ALL)", - "-v, --verbose verbose output" + "-v, --verbose verbose output", + "-z, --dense dense dump output style" ], - "usage": "hf iclass view [-hv] -f [--first ] [--last ]" + "usage": "hf iclass view [-hvz] -f [--first ] [--last ]" }, "hf iclass wrbl": { "command": "hf iclass wrbl", @@ -3091,13 +3235,14 @@ "--ki Key index to select key from memory 'hf iclass managekeys'", "-b, --block The block number to read", "-d, --data data to write as 8 hex bytes", + "-m, --mac replay mac data (4 hex bytes)", "--credit key is assumed to be the credit key", "--elite elite computations applied to key", "--raw no computations applied to key", "--nr replay of NR/MAC", "-v, --verbose verbose output" ], - "usage": "hf iclass wrbl [-hv] [-k ] [--ki ] -b -d [--credit] [--elite] [--raw] [--nr]" + "usage": "hf iclass wrbl [-hv] [-k ] [--ki ] -b -d [-m ] [--credit] [--elite] [--raw] [--nr]" }, "hf jooki clone": { "command": "hf jooki clone", @@ -3575,6 +3720,19 @@ ], "usage": "hf lto rdbl [-h] [--first ] [--last ]" }, + "hf lto reader": { + "command": "hf lto reader", + "description": "Act as a LTO-CM reader. Look for LTO-CM tags until Enter or the pm3 button is pressed", + "notes": [ + "hf lto reader -@ -> continuous reader mode" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-@ optional - continuous reader mode" + ], + "usage": "hf lto reader [-h@]" + }, "hf lto restore": { "command": "hf lto restore", "description": "Restore data from dumpfile to LTO tag", @@ -3646,7 +3804,7 @@ "-a Input key A (def)", "-b Input key B", "-f, --file filename of dictionary", - "-s, --slow Slower acquisition (required by some non standard cards)", + "--slow Slower acquisition (required by some non standard cards)", "-l, --legacy legacy mode (use the slow `hf mf chk`)", "-v, --verbose verbose output (statistics)", "--mini MIFARE Classic Mini / S20", @@ -3660,7 +3818,7 @@ "--i2 AVX2", "--i5 AVX512" ], - "usage": "hf mf autopwn [-habslv] [-k ] [-s ] [-f ] [--mini] [--1k] [--2k] [--4k] [--in] [--im] [--is] [--ia] [--i2] [--i5]" + "usage": "hf mf autopwn [-hablv] [-k ] [-s ] [-f ] [--slow] [--mini] [--1k] [--2k] [--4k] [--in] [--im] [--is] [--ia] [--i2] [--i5]" }, "hf mf cgetblk": { "command": "hf mf cgetblk", @@ -4143,7 +4301,7 @@ }, "hf mf help": { "command": "hf mf help", - "description": "help This help list List MIFARE history hardnested Nested attack for hardened MIFARE Classic cards decrypt [nt] [ar_enc] [at_enc] [data] - to decrypt sniff or trace acl Decode and print MIFARE Classic access rights bytes value Value blocks view Display content from tag dump file", + "description": "help This help list List MIFARE history hardnested Nested attack for hardened MIFARE Classic cards decrypt [nt] [ar_enc] [at_enc] [data] - to decrypt sniff or trace acl Decode and print MIFARE Classic access rights bytes mad Checks and prints MAD value Value blocks view Display content from tag dump file", "notes": [], "offline": true, "options": [], @@ -4178,7 +4336,7 @@ "hf mf mad --aid e103 -k ffffffffffff -b -> shows NDEF data if exists. read card with custom key and key B", "hf mf mad --dch -k ffffffffffff -> decode CardHolder information" ], - "offline": false, + "offline": true, "options": [ "-h, --help This help", "-v, --verbose show technical data", @@ -4204,6 +4362,27 @@ ], "usage": "hf mf nack [-hv]" }, + "hf mf ndefformat": { + "command": "hf mf ndefformat", + "description": "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename", + "notes": [ + "hf mf ndefformat --mini -> MIFARE Mini", + "hf mf ndefformat --1k -> MIFARE Classic 1k", + "hf mf ndefformat --2k -> MIFARE 2k", + "hf mf ndefformat --4k -> MIFARE 4k", + "hf mf ndefformat --keys hf-mf-066C8B78-key.bin -> MIFARE 1k with keys from specified file" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-k, --keys filename of keys", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70" + ], + "usage": "hf mf ndefformat [-h] [-k ] [--mini] [--1k] [--2k] [--4k]" + }, "hf mf ndefread": { "command": "hf mf ndefread", "description": "Prints NFC Data Exchange Format (NDEF)", @@ -4337,7 +4516,7 @@ }, "hf mf sim": { "command": "hf mf sim", - "description": "Simulate MIFARE Classic card", + "description": "Simulate MIFARE Classic family type based upon ISO/IEC 14443 type A tag with 4,7 or 10 byte UID from emulator memory. See `hf mf eload` first. The UID from emulator memory will be used if not specified.", "notes": [ "hf mf sim --mini -> MIFARE Mini", "hf mf sim --1k -> MIFARE Classic 1k (default)", @@ -4350,7 +4529,7 @@ "offline": false, "options": [ "-h, --help This help", - "-u, --uid UID 4,7 or 10bytes. If not specified, the UID 4b/7b from emulator memory will be used", + "-u, --uid <4|7|10> hex bytes UID", "--mini MIFARE Classic Mini / S20", "--1k MIFARE Classic 1k / S50", "--2k MIFARE Classic/Plus 2k", @@ -5347,9 +5526,10 @@ }, "hf mfdes lsfiles": { "command": "hf mfdes lsfiles", - "description": "Show file list. Master key needs to be provided or flag --no-auth set (depend on cards settings).", + "description": "This commands List files inside application AID / ISOID. Master key needs to be provided or flag --no-auth set (depend on cards settings).", "notes": [ - "hf mfdes lsfiles --aid 123456 -> show file list for: app=123456 with defaults from `default` commandhf mfdes lsfiles --isoid df01 --no-auth -> show files from desfire light" + "hf mfdes lsfiles --aid 123456 -> AID 123456, list files using `default` command creds", + "hf mfdes lsfiles --isoid df01 --no-auth -> list files for DESFire light" ], "offline": false, "options": [ @@ -5567,7 +5747,7 @@ "notes": [ "In the mode with CommitReaderID to decode previous reader id command needs to read transaction counter via dump/read command and specify --trkey", "", - "hf mfdes write --aid 123456 --fid 01 -d 01020304 -> write file: app=123456, file=01, offset=0, get file type from card. use default channel settings from `default` command", + "hf mfdes write --aid 123456 --fid 01 -d 01020304 -> AID 123456, file=01, offset=0, get file type from card. use default channel settings from `default` command", "hf mfdes write --aid 123456 --fid 01 --type data -d 01020304 --0ffset 000100 -> write data to std file with offset 0x100", "hf mfdes write --aid 123456 --fid 01 --type data -d 01020304 --commit -> write data to backup file with commit", "hf mfdes write --aid 123456 --fid 01 --type value -d 00000001 -> increment value file", @@ -5805,7 +5985,7 @@ "offline": false, "options": [ "-h, --help This help", - "-v, --verbose Verbose mode", + "-v, --verbose Verbose output", "--ki Key number, 2 hex bytes", "--key Key, 16 hex bytes" ], @@ -6037,10 +6217,11 @@ }, "hf mfu sim": { "command": "hf mfu sim", - "description": "Simulate MIFARE Ultralight family type based upon ISO/IEC 14443 type A tag with 4,7 or 10 byte UID from emulator memory. See `hf mfu eload` first. See `hf 14a sim -h` to see available types. You want 2 or 7 usually.", + "description": "Simulate MIFARE Ultralight family type based upon ISO/IEC 14443 type A tag with 4,7 or 10 byte UID from emulator memory. See `hf mfu eload` first. The UID from emulator memory will be used if not specified. See `hf 14a sim -h` to see available types. You want 2 or 7 usually.", "notes": [ "hf mfu sim -t 2 --uid 11223344556677 -> MIFARE Ultralight", - "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> AMIIBO (NTAG 215), pack 0x8080" + "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> Amiibo (NTAG 215), pack 0x8080", + "hf mfu sim -t 7 -> Amiibo (NTAG 215), pack 0x8080" ], "offline": false, "options": [ @@ -6209,9 +6390,11 @@ "options": [ "-h, --help This help", "--sp skip sample pairs", - "--st skip number of triggers" + "--st skip number of triggers", + "--smode [none|drop|min|max|avg] Skip mode. It switches on the function that applies to several samples before they saved to memory", + "--sratio Skip ratio. It applied the function above to (ratio * 2) samples. For ratio = 1 it 2 samples." ], - "usage": "hf sniff [-h] [--sp ] [--st ]" + "usage": "hf sniff [-h] [--sp ] [--st ] [--smode [none|drop|min|max|avg]] [--sratio ]" }, "hf st25ta help": { "command": "hf st25ta help", @@ -6335,17 +6518,17 @@ "offline": false, "options": [ "-h, --help This help", + "-1 Use data from Graphbuffer", "-v, --verbose Verbose scan and output", "-@ optional - continuous reader mode" ], - "usage": "hf texkom reader [-hv@]" + "usage": "hf texkom reader [-h1v@]" }, "hf texkom sim": { "command": "hf texkom sim", "description": "Simulate a texkom tag", "notes": [ "hf texkom sim", - "", "hf texkom sim --raw FFFF638C7DC45553 -> simulate TK13 tag with id 8C7DC455", "hf texkom sim --tk17 --raw FFFFCA17F31EC512 -> simulate TK17 tag with id 17F31EC5", "hf texkom sim --id 8C7DC455 -> simulate TK13 tag with id 8C7DC455", @@ -6417,9 +6600,22 @@ ], "usage": "hf thinfilm sim [-h] -d [--raw]" }, + "hf topaz dump": { + "command": "hf topaz dump", + "description": "Dump TOPAZ tag to binary file If no given, UID will be used as filename", + "notes": [ + "hf topaz dump" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-f, --file filename of dump" + ], + "usage": "hf topaz dump [-h] [-f ]" + }, "hf topaz help": { "command": "hf topaz help", - "description": "help This help list List Topaz history", + "description": "help This help list List Topaz history view Display content from tag dump file", "notes": [], "offline": true, "options": [], @@ -6465,7 +6661,7 @@ "command": "hf topaz raw", "description": "Send raw hex data to Topaz tags", "notes": [ - "hf topaz raw -> Not yet implemented" + "hf topaz raw" ], "offline": false, "options": [ @@ -6473,18 +6669,33 @@ ], "usage": "hf topaz raw [-h]" }, - "hf topaz reader": { - "command": "hf topaz reader", - "description": "Read UID from Topaz tags", + "hf topaz rdbl": { + "command": "hf topaz rdbl", + "description": "Read a block", "notes": [ - "hf topaz reader" + "hf topaz rdbl -b 7" ], "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose output" + "-b, --block Block number to write" ], - "usage": "hf topaz reader [-hv]" + "usage": "hf topaz rdbl [-h] -b " + }, + "hf topaz reader": { + "command": "hf topaz reader", + "description": "Read UID from Topaz tags", + "notes": [ + "hf topaz reader", + "hf topaz reader -@ -> Continuous mode" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-v, --verbose verbose output", + "-@ optional - continuous reader mode" + ], + "usage": "hf topaz reader [-hv@]" }, "hf topaz sim": { "command": "hf topaz sim", @@ -6510,6 +6721,33 @@ ], "usage": "hf topaz sniff [-h]" }, + "hf topaz view": { + "command": "hf topaz view", + "description": "Print a Topaz tag dump file (bin/eml/json)", + "notes": [ + "hf topaz view -f hf-topaz-04010203-dump.bin" + ], + "offline": true, + "options": [ + "-h, --help This help", + "-f, --file filename of dump (bin/eml/json)" + ], + "usage": "hf topaz view [-h] -f " + }, + "hf topaz wrbl": { + "command": "hf topaz wrbl", + "description": "Write a block", + "notes": [ + "hf topaz wrbl -b 7 -d 1122334455667788" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-b, --block Block number to write", + "-d, --data Block data (8 hex bytes)" + ], + "usage": "hf topaz wrbl [-h] -b -d " + }, "hf tune": { "command": "hf tune", "description": "Continuously measure HF antenna tuning. Press button or to interrupt.", @@ -6581,7 +6819,7 @@ }, "hf xerox info": { "command": "hf xerox info", - "description": "Act as a reader.", + "description": "Tag information for ISO/IEC 14443 type B / XEROX based tags", "notes": [ "hf xerox info" ], @@ -6592,6 +6830,21 @@ ], "usage": "hf xerox info [-hv]" }, + "hf xerox reader": { + "command": "hf xerox reader", + "description": "Act as a 14443B reader to identify a tag", + "notes": [ + "hf xerox reader", + "hf xerox reader -@" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-v, --verbose verbose output", + "-@ optional - continuous reader mode" + ], + "usage": "hf xerox reader [-hv@]" + }, "hints": { "command": "hints", "description": "Turn on/off hints", @@ -6623,8 +6876,8 @@ "command": "hw connect", "description": "Connects to a Proxmark3 device via specified serial port. Baudrate here is only for physical UART or UART-BT, NOT for USB-CDC or blue shark add-on", "notes": [ - "hw connect -p /dev/ttyacm0", - "hw connect -p /dev/ttyacm0 -b 115200" + "hw connect -p /dev/ttyACM0", + "hw connect -p /dev/ttyACM0 -b 115200" ], "offline": true, "options": [ @@ -6875,7 +7128,7 @@ "--fc 8|16bit value facility code", "--cn optional - card number to start with, max 65535", "--delay optional - delay betweens attempts in ms. Default 1000ms", - "-v, --verbose verbose logging, show all tries" + "-v, --verbose verbose output" ], "usage": "lf awid brute [-hv] --fmt --fc [--cn ] [--delay ]" }, @@ -7495,7 +7748,7 @@ "options": [ "-h, --help This help", "-p, --pwd password, 4 hex bytes, lsb", - "-v, --verbose additional output of data section" + "-v, --verbose verbose output" ], "usage": "lf em 4x50 info [-hv] [-p ]" }, @@ -7954,7 +8207,7 @@ "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose logging, show all tries", + "-v, --verbose verbose output", "-w, --wiegand see `wiegand list` for available formats", "--fc facility code", "--cn card number to start with", @@ -10274,6 +10527,27 @@ "options": [], "usage": "" }, + "nfc mf cformat": { + "command": "nfc mf cformat", + "description": "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename", + "notes": [ + "hf mf ndefformat --mini -> MIFARE Mini", + "hf mf ndefformat --1k -> MIFARE Classic 1k", + "hf mf ndefformat --2k -> MIFARE 2k", + "hf mf ndefformat --4k -> MIFARE 4k", + "hf mf ndefformat --keys hf-mf-066C8B78-key.bin -> MIFARE 1k with keys from specified file" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-k, --keys filename of keys", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70" + ], + "usage": "hf mf ndefformat [-h] [-k ] [--mini] [--1k] [--2k] [--4k]" + }, "nfc mf cread": { "command": "nfc mf cread", "description": "Prints NFC Data Exchange Format (NDEF)", @@ -10500,6 +10774,18 @@ ], "usage": "prefs get hints [-h]" }, + "prefs get output": { + "command": "prefs get output", + "description": "Get preference of dump output style", + "notes": [ + "prefs get output" + ], + "offline": true, + "options": [ + "-h, --help This help" + ], + "usage": "prefs get output [-h]" + }, "prefs get plotsliders": { "command": "prefs get plotsliders", "description": "Get preference of showing the plotslider control in the client", @@ -10608,7 +10894,7 @@ }, "prefs set help": { "command": "prefs set help", - "description": "help This help barmode Set bar mode clientdebug Set client debug level clientdelay Set client execution delay color Set color support emoji Set emoji display hints Set hint display savepaths ... to be adjusted next ... plotsliders Set plot slider display", + "description": "help This help barmode Set bar mode clientdebug Set client debug level clientdelay Set client execution delay color Set color support emoji Set emoji display hints Set hint display savepaths ... to be adjusted next ... output Set dump output style plotsliders Set plot slider display", "notes": [], "offline": true, "options": [], @@ -10628,6 +10914,21 @@ ], "usage": "prefs set hints [-h] [--off] [--on]" }, + "prefs set output": { + "command": "prefs set output", + "description": "Set dump output style to condense consecutive repeated data", + "notes": [ + "prefs set output --normal -> sets the output style to normal", + "prefs set output --dense -> sets the output style to dense" + ], + "offline": true, + "options": [ + "-h, --help This help", + "--normal normal output", + "--dense dense output" + ], + "usage": "prefs set output [-h] [--normal] [--dense]" + }, "prefs set plotsliders": { "command": "prefs set plotsliders", "description": "Set persistent preference of showing the plotslider control in the client", @@ -10748,7 +11049,7 @@ "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose" + "-v, --verbose verbose output" ], "usage": "smart info [-hv]" }, @@ -10803,7 +11104,7 @@ "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose" + "-v, --verbose verbose output" ], "usage": "smart reader [-hv]" }, @@ -11093,8 +11394,8 @@ } }, "metadata": { - "commands_extracted": 700, + "commands_extracted": 720, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-07-07T21:17:54" + "extracted_on": "2022-10-16T15:53:13" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 1bb282715..ab64b022f 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -230,6 +230,9 @@ Check column "offline" for their availability. |`hf 15 reader `|N |`Act like an ISO-15693 reader` |`hf 15 restore `|N |`Restore from file to all memory pages of an ISO-15693 tag` |`hf 15 samples `|N |`Acquire samples as reader (enables carrier, sends inquiry)` +|`hf 15 eload `|N |`Load image file into emulator to be used by 'sim' command` +|`hf 15 esave `|N |`Save emulator memory into image file` +|`hf 15 eview `|N |`View emulator memory` |`hf 15 sim `|N |`Fake an ISO-15693 tag` |`hf 15 slixdisable `|N |`Disable privacy mode on SLIX ISO-15693 tag` |`hf 15 wrbl `|N |`Write a block` @@ -326,6 +329,20 @@ Check column "offline" for their availability. |`hf fido assert `|N |`FIDO2 GetAssertion command.` +### hf fudan + + { Fudan RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf fudan help `|Y |`This help` +|`hf fudan reader `|N |`Act like a fudan reader` +|`hf fudan dump `|N |`Dump FUDAN tag to binary file` +|`hf fudan rdbl `|N |`Read a fudan tag` +|`hf fudan view `|Y |`Display content from tag dump file` +|`hf fudan wrbl `|N |`Write a fudan tag` + + ### hf gallagher { Gallagher DESFire RFIDs... } @@ -430,11 +447,12 @@ Check column "offline" for their availability. |------- |------- |----------- |`hf lto help `|Y |`This help` |`hf lto dump `|N |`Dump LTO-CM tag to file` -|`hf lto restore `|N |`Restore dump file to LTO-CM tag` |`hf lto info `|N |`Tag information` -|`hf lto rdbl `|N |`Read block` -|`hf lto wrbl `|N |`Write block` |`hf lto list `|Y |`List LTO-CM history` +|`hf lto rdbl `|N |`Read block` +|`hf lto reader `|N |`Act like a LTO-CM reader` +|`hf lto restore `|N |`Restore dump file to LTO-CM tag` +|`hf lto wrbl `|N |`Write block` ### hf mf @@ -458,12 +476,11 @@ Check column "offline" for their availability. |`hf mf auth4 `|N |`ISO14443-4 AES authentication` |`hf mf acl `|Y |`Decode and print MIFARE Classic access rights bytes` |`hf mf dump `|N |`Dump MIFARE Classic tag to binary file` -|`hf mf mad `|N |`Checks and prints MAD` -|`hf mf ndefread `|N |`Prints NDEF records from card` +|`hf mf mad `|Y |`Checks and prints MAD` |`hf mf personalize `|N |`Personalize UID (MIFARE Classic EV1 only)` |`hf mf rdbl `|N |`Read MIFARE Classic block` |`hf mf rdsc `|N |`Read MIFARE Classic sector` -|`hf mf restore `|N |`Restore MIFARE Classic binary file to BLANK tag` +|`hf mf restore `|N |`Restore MIFARE Classic binary file to tag` |`hf mf setmod `|N |`Set MIFARE Classic EV1 load modulation strength` |`hf mf value `|Y |`Value blocks` |`hf mf view `|Y |`Display content from tag dump file` @@ -491,6 +508,8 @@ Check column "offline" for their availability. |`hf mf gen3blk `|N |`Overwrite manufacturer block` |`hf mf gen3freeze `|N |`Perma lock UID changes. irreversible` |`hf mf gview `|N |`View card` +|`hf mf ndefformat `|N |`Format MIFARE Classic Tag as NFC Tag` +|`hf mf ndefread `|N |`Prints NDEF records from card` ### hf mfp @@ -642,12 +661,16 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`hf topaz help `|Y |`This help` +|`hf topaz dump `|N |`Dump TOPAZ family tag to file` |`hf topaz list `|Y |`List Topaz history` |`hf topaz info `|N |`Tag information` |`hf topaz reader `|N |`Act like a Topaz reader` -|`hf topaz sim `|N |` -- Simulate Topaz tag` +|`hf topaz sim `|N |`Simulate Topaz tag` |`hf topaz sniff `|N |`Sniff Topaz reader-tag communication` |`hf topaz raw `|N |`Send raw hex data to tag` +|`hf topaz rdbl `|N |`Read block` +|`hf topaz view `|Y |`Display content from tag dump file` +|`hf topaz wrbl `|N |`Write block` ### hf texkom @@ -1282,6 +1305,7 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`nfc mf cread `|N |`read NFC Type MIFARE Classic Tag` +|`nfc mf cformat `|N |`format MIFARE Classic Tag as NFC Tag` |`nfc mf pread `|N |`read NFC Type MIFARE Plus Tag` |`nfc mf help `|Y |`This help` From 04f4863dd464a96c68a2414444397df8ea8ef3fe Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 16 Oct 2022 18:10:14 +0200 Subject: [PATCH 275/759] fix label can only be part of a statement and a declaration is not a statement --- client/src/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 3604c9686..c55de1869 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5840,7 +5840,7 @@ int CmdHFMFNDEFFormat(const char *Cmd) { fclose(f); } -skipfile: +skipfile: ; uint8_t firstblocks[8][16] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, From f9d0649fe1e8f9320668152783d8e09b14db47fc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 16 Oct 2022 18:30:15 +0200 Subject: [PATCH 276/759] text --- client/src/cmdhfmf.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index c55de1869..6e368bc3f 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5700,12 +5700,16 @@ int CmdHFMFNDEFFormat(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf ndefformat", "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF)\n" - "If no given, UID will be used as filename", - "hf mf ndefformat --mini --> MIFARE Mini\n" + "If no given, UID will be used as filename. \n" + "It will try default keys and MAD keys to detect if tag is already formatted in order to write.\n" + "\n" + "If not, it will try finding a key file based on your UID. ie, if you ran autopwn before", + "hf mf ndefformat\n" + // "hf mf ndefformat --mini --> MIFARE Mini\n" "hf mf ndefformat --1k --> MIFARE Classic 1k\n" - "hf mf ndefformat --2k --> MIFARE 2k\n" - "hf mf ndefformat --4k --> MIFARE 4k\n" - "hf mf ndefformat --keys hf-mf-066C8B78-key.bin --> MIFARE 1k with keys from specified file\n" + // "hf mf ndefformat --2k --> MIFARE 2k\n" + // "hf mf ndefformat --4k --> MIFARE 4k\n" + "hf mf ndefformat --keys hf-mf-01020304-key.bin --> MIFARE 1k with keys from specified file\n" ); void *argtable[] = { From 98de0f434b5636cfd938c00e2248f8c13c4f9df0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 20 Oct 2022 17:30:03 +0200 Subject: [PATCH 277/759] style --- client/src/nfc/ndef.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/nfc/ndef.c b/client/src/nfc/ndef.c index 1d4a6231f..ff2584d50 100644 --- a/client/src/nfc/ndef.c +++ b/client/src/nfc/ndef.c @@ -1094,7 +1094,7 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { indx += len; break; } - case 0xfd: { + case 0xFD: { indx++; uint16_t len = ndefTLVGetLength(&ndef[indx], &indx); PrintAndLogEx(NORMAL, ""); @@ -1103,7 +1103,7 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { indx += len; break; } - case 0xfe: { + case 0xFE: { PrintAndLogEx(SUCCESS, "NDEF Terminator detected"); return PM3_SUCCESS; } From acb6fcb970c74a6c4f5160f1f6ac67d7f5e27f4f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 20 Oct 2022 17:31:01 +0200 Subject: [PATCH 278/759] changed "hf mf cwipe" - add a genuine block0 --- client/src/mifare/mifarehost.c | 7 ++++--- client/src/mifare/mifarehost.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 9d204c686..4f8440325 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -859,10 +859,10 @@ out: } // MIFARE -int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data) { +int mfReadSector(uint8_t sectorNo, uint8_t keyType, const uint8_t *key, uint8_t *data) { clearCommandBuffer(); - SendCommandMIX(CMD_HF_MIFARE_READSC, sectorNo, keyType, 0, key, 6); + SendCommandMIX(CMD_HF_MIFARE_READSC, sectorNo, keyType, 0, (uint8_t *)key, 6); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { uint8_t isOK = resp.oldarg[0] & 0xff; @@ -1034,7 +1034,8 @@ int mfCSetUID(uint8_t *uid, uint8_t uidlen, const uint8_t *atqa, const uint8_t * } int mfCWipe(uint8_t *uid, const uint8_t *atqa, const uint8_t *sak) { - uint8_t block0[16] = {0x04, 0x03, 0x02, 0x01, 0x04, 0x08, 0x04, 0x00, 0x64, 0xB9, 0x95, 0x11, 0x4D, 0x20, 0x42, 0x09}; + uint8_t block0[16] = {0x00, 0x56, 0x78, 0xBB, 0x95, 0x08, 0x04, 0x00, 0x02, 0xB2, 0x1E, 0x24, 0x23, 0x27, 0x1E, 0x1D}; + // uint8_t block0[16] = {0x04, 0x03, 0x02, 0x01, 0x04, 0x08, 0x04, 0x00, 0x64, 0xB9, 0x95, 0x11, 0x4D, 0x20, 0x42, 0x09}; uint8_t blockD[16] = {0x00}; uint8_t blockK[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x77, 0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t params = MAGIC_SINGLE; diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index 8db9f36bb..87b6dc802 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -79,7 +79,7 @@ int mfCheckKeys_file(uint8_t *destfn, uint64_t *key); int mfKeyBrute(uint8_t blockNo, uint8_t keyType, const uint8_t *key, uint64_t *resultkey); -int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data); +int mfReadSector(uint8_t sectorNo, uint8_t keyType, const uint8_t *key, uint8_t *data); int mfReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t *data); int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount); From 9e9d8ddbdea1d656041071b34b410bb2a4fae03a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 20 Oct 2022 17:31:23 +0200 Subject: [PATCH 279/759] style --- client/src/mifare/mad.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index 0cb9df47c..2d2ab8c8a 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -214,7 +214,7 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2) int res = madCRCCheck(sector0, true, 1); if (verbose && res == PM3_SUCCESS) - PrintAndLogEx(SUCCESS, "%14s " _GREEN_("0x%02x") " (%s)", "CRC8", sector0[16], _GREEN_("ok")); + PrintAndLogEx(SUCCESS, "%14s " _GREEN_("0x%02x") " ( %s )", "CRC8", sector0[16], _GREEN_("ok")); if (mad_ver == 2 && sector10) { int res2 = madCRCCheck(sector10, true, 2); @@ -222,7 +222,7 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2) res = res2; if (verbose && !res2) - PrintAndLogEx(SUCCESS, "%14s " _GREEN_("0x%02x") " (%s)", "CRC8", sector10[0], _GREEN_("ok")); + PrintAndLogEx(SUCCESS, "%14s " _GREEN_("0x%02x") " ( %s )", "CRC8", sector10[0], _GREEN_("ok")); } // MA (multi-application card) @@ -354,9 +354,9 @@ int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose) { int res = madCRCCheck(sector, true, 2); if (verbose) { if (res == PM3_SUCCESS) - PrintAndLogEx(SUCCESS, "CRC8 (%s)", _GREEN_("ok")); + PrintAndLogEx(SUCCESS, "CRC8 ( %s )", _GREEN_("ok")); else - PrintAndLogEx(WARNING, "CRC8 (%s)", _RED_("fail")); + PrintAndLogEx(WARNING, "CRC8 ( %s )", _RED_("fail")); } int ibs = MADInfoByteDecode(sector, swapmad, 2, verbose); From 76f793c9af0c9507109e72ac58e065db2b36cc69 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 20 Oct 2022 17:34:46 +0200 Subject: [PATCH 280/759] added hf mf ndefwrite command. to write a ndef record to mifare tag --- client/src/cmdhfmf.c | 174 +++++++++++++++++++++++++++++++++++++++---- client/src/cmdhfmf.h | 1 + 2 files changed, 162 insertions(+), 13 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 6e368bc3f..0b7cc7280 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -336,7 +336,7 @@ static void mf_print_sector_hdr(uint8_t sector) { PrintAndLogEx(INFO, "----+-------------------------------------------------+-----------------"); } -static bool mf_write_block(uint8_t *key, uint8_t keytype, uint8_t blockno, uint8_t *block) { +static bool mf_write_block(const uint8_t *key, uint8_t keytype, uint8_t blockno, uint8_t *block) { uint8_t data[26]; memcpy(data, key, MFKEY_SIZE); @@ -5607,7 +5607,7 @@ int CmdHFMFNDEFRead(const char *Cmd) { CLIParserFree(ctx); - uint16_t ndefAID = 0xe103; + uint16_t ndefAID = 0xE103; if (aidlen == 2) ndefAID = (aid[0] << 8) + aid[1]; @@ -5617,15 +5617,15 @@ int CmdHFMFNDEFRead(const char *Cmd) { memcpy(ndefkey, key, 6); } - uint8_t sector0[16 * 4] = {0}; - uint8_t sector10[16 * 4] = {0}; + uint8_t sector0[MFBLOCK_SIZE * 4] = {0}; + uint8_t sector10[MFBLOCK_SIZE * 4] = {0}; uint8_t data[4096] = {0}; int datalen = 0; if (verbose) PrintAndLogEx(INFO, "reading MAD v1 sector"); - if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector0)) { + if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, g_mifare_mad_key, sector0)) { PrintAndLogEx(ERR, "error, read sector 0. card doesn't have MAD or doesn't have MAD on default keys"); PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -k `") " with your custom key"); return PM3_ESOFT; @@ -5642,7 +5642,7 @@ int CmdHFMFNDEFRead(const char *Cmd) { if (verbose) PrintAndLogEx(INFO, "reading MAD v2 sector"); - if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, (uint8_t *)g_mifare_mad_key, sector10)) { + if (mfReadSector(MF_MAD2_SECTOR, MF_KEY_A, g_mifare_mad_key, sector10)) { PrintAndLogEx(ERR, "error, read sector 0x10. card doesn't have MAD or doesn't have MAD on default keys"); PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -k `") " with your custom key"); return PM3_ESOFT; @@ -5660,14 +5660,14 @@ int CmdHFMFNDEFRead(const char *Cmd) { PrintAndLogEx(INFO, "reading data from tag"); for (int i = 0; i < madlen; i++) { if (ndefAID == mad[i]) { - uint8_t vsector[16 * 4] = {0}; + uint8_t vsector[MFBLOCK_SIZE * 4] = {0}; if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, ndefkey, vsector)) { PrintAndLogEx(ERR, "error, reading sector %d ", i + 1); return PM3_ESOFT; } - memcpy(&data[datalen], vsector, 16 * 3); - datalen += 16 * 3; + memcpy(&data[datalen], vsector, MFBLOCK_SIZE * 3); + datalen += MFBLOCK_SIZE * 3; PrintAndLogEx(INPLACE, "%d", i); } @@ -5758,6 +5758,9 @@ int CmdHFMFNDEFFormat(const char *Cmd) { } + if (g_session.pm3_present == false) + return PM3_ENOTTY; + // Select card to get UID/UIDLEN/ATQA/SAK information clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); @@ -5800,7 +5803,7 @@ int CmdHFMFNDEFFormat(const char *Cmd) { } // Do we have a keyfile based from UID? - if (strlen(keyFilename) == 0) { + if (keyfnlen == 0) { char *fptr = GenerateFilename("hf-mf-", "-key.bin"); if (fptr) { strcpy(keyFilename, fptr); @@ -5886,9 +5889,9 @@ skipfile: ; } - // write to card, try B key first, then A + // write to card, try B key first if (mf_write_block(keyB[i], MF_KEY_B, b, block) == 0) { - // write failed try B key, + // try A key, if (mf_write_block(keyA[i], MF_KEY_A, b, block) == 0) { return PM3_EFAILED; } @@ -5902,6 +5905,150 @@ skipfile: ; return PM3_SUCCESS; } +int CmdHFMFNDEFWrite(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf ndefwrite", + "Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.\n", + "hf mf ndefread -d 0300FE -> write empty record to tag\n" + "hf mf ndefread -f myfilename" + ); + + void *argtable[] = { + arg_param_begin, + arg_str0("d", NULL, "", "raw NDEF hex bytes"), + arg_str0("f", "file", "", "write raw NDEF file to tag"), + arg_lit0(NULL, "mini", "MIFARE Classic Mini / S20"), + arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50 (def)"), + arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), + arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + uint8_t raw[4096] = {0}; + int rawlen; + CLIGetHexWithReturn(ctx, 1, raw, &rawlen); + + int fnlen = 0; + char filename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + + bool m0 = arg_get_lit(ctx, 3); + bool m1 = arg_get_lit(ctx, 4); + bool m2 = arg_get_lit(ctx, 5); + bool m4 = arg_get_lit(ctx, 6); + + CLIParserFree(ctx); + + // validations + if ((m0 + m1 + m2 + m4) > 1) { + PrintAndLogEx(WARNING, "Only specify one MIFARE Type"); + return PM3_EINVARG; + } else if ((m0 + m1 + m2 + m4) == 0) { + m1 = true; + } + + uint8_t numSectors = MIFARE_1K_MAXSECTOR; + + if (m0) { + numSectors = MIFARE_MINI_MAXSECTOR; + } else if (m1) { + numSectors = MIFARE_1K_MAXSECTOR; + } else if (m2) { + numSectors = MIFARE_2K_MAXSECTOR; + } else if (m4) { + numSectors = MIFARE_4K_MAXSECTOR; + } else { + PrintAndLogEx(WARNING, "Please specify a MIFARE Type"); + return PM3_EINVARG; + } + + PrintAndLogEx(INFO, "Number of sectors selected: %u", numSectors); + + if (g_session.pm3_present == false) { + PrintAndLogEx(FAILED, "No Proxmark3 device present"); + return PM3_ENOTTY; + } + + if ((rawlen && fnlen) || (rawlen == 0 && fnlen == 0) ) { + PrintAndLogEx(WARNING, "Please specify either raw hex or filename"); + return PM3_EINVARG; + } + + // test if MAD key is used + uint64_t key64 = 0; + + // check if we can authenticate to sector + int res = mfCheckKeys(0, MF_KEY_A, true, 1, (uint8_t *)g_mifare_mad_key, &key64); + if (res != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Sector 0 failed to authenticate with MAD default key"); + PrintAndLogEx(HINT, "Verify that the tag NDEF formatted"); + return res; + } + + // NDEF for MIFARE CLASSIC has different memory size available. + + int32_t bytes = rawlen; + + // read dump file + if (fnlen) { + uint8_t *dump = NULL; + size_t bytes_read = 0; + res = pm3_load_dump(filename, (void **)&dump, &bytes_read, sizeof(raw)); + if (res != PM3_SUCCESS) { + return res; + } + memcpy(raw, dump, bytes_read); + bytes = bytes_read; + free(dump); + } + + // read MAD Sector 0, block1,2 + uint8_t sector0[MFBLOCK_SIZE * 4] = {0}; + if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, g_mifare_mad_key, sector0)) { + PrintAndLogEx(ERR, "error, read sector 0. card doesn't have MAD or doesn't have MAD on default keys"); + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -k `") " with your custom key"); + return PM3_ESOFT; + } + + // how much memory do I have available ? + + // main loop - write blocks + uint8_t *ptr_raw = raw; + uint8_t b = 4; + while (bytes > 0) { + + uint8_t block[MFBLOCK_SIZE] = { 0x00 }; + + if (bytes < MFBLOCK_SIZE) { + memcpy(block, ptr_raw, bytes); + } else { + memcpy(block, ptr_raw, MFBLOCK_SIZE); + ptr_raw += MFBLOCK_SIZE; + } + + // write to card, try B key first + if (mf_write_block(g_mifare_default_key, MF_KEY_B, b, block) == 0) { + + // try A key, + if (mf_write_block(g_mifare_ndef_key, MF_KEY_A, b, block) == 0) { + return PM3_EFAILED; + } + } + + PrintAndLogEx(INPLACE, "%u", b); + + b++; + if (mfIsSectorTrailer(b)) { + b++; + } + bytes -= MFBLOCK_SIZE; + } + + PrintAndLogEx(NORMAL, ""); + return PM3_SUCCESS; +} static int CmdHFMFPersonalize(const char *Cmd) { CLIParserContext *ctx; @@ -6832,7 +6979,8 @@ static command_t CommandTable[] = { {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"}, // {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, {"ndefformat", CmdHFMFNDEFFormat, IfPm3Iso14443a, "Format MIFARE Classic Tag as NFC Tag"}, - {"ndefread", CmdHFMFNDEFRead, IfPm3Iso14443a, "Prints NDEF records from card"}, + {"ndefread", CmdHFMFNDEFRead, IfPm3Iso14443a, "Read and print NDEF records from card"}, + {"ndefwrite", CmdHFMFNDEFWrite, IfPm3Iso14443a, "Write NDEF records to card"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmdhfmf.h b/client/src/cmdhfmf.h index ed8c4c82d..94610421b 100644 --- a/client/src/cmdhfmf.h +++ b/client/src/cmdhfmf.h @@ -28,6 +28,7 @@ int CmdHF14AMfELoad(const char *Cmd); // used by "hf mfu eload" int CmdHF14AMfDbg(const char *Cmd); // used by "hf mfu dbg" int CmdHFMFNDEFRead(const char *Cmd); // used by "nfc mf cread" int CmdHFMFNDEFFormat(const char *Cmd); // used by "nfc mf cformat" +int CmdHFMFNDEFWrite(const char *Cmd); // used by "nfc mf cwrite" void showSectorTable(sector_t *k_sector, uint8_t k_sectorsCount); void readerAttack(sector_t *k_sector, uint8_t k_sectorsCount, nonces_t data, bool setEmulatorMem, bool verbose); From d3248a7059bbb313e6548c79b5420cb1059cad7f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 20 Oct 2022 17:35:24 +0200 Subject: [PATCH 281/759] make style --- client/src/pm3line_vocabulory.h | 1 + doc/commands.json | 65 +++++++++++++++------------------ doc/commands.md | 3 +- 3 files changed, 32 insertions(+), 37 deletions(-) diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index cbf89bde8..9dc5c84a7 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -347,6 +347,7 @@ const static vocabulory_t vocabulory[] = { { 0, "hf mf gview" }, { 0, "hf mf ndefformat" }, { 0, "hf mf ndefread" }, + { 0, "hf mf ndefwrite" }, { 1, "hf mfp help" }, { 0, "hf mfp info" }, { 0, "hf mfp wrp" }, diff --git a/doc/commands.json b/doc/commands.json index 27eb64235..0bc8ae626 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -4364,24 +4364,11 @@ }, "hf mf ndefformat": { "command": "hf mf ndefformat", - "description": "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename", - "notes": [ - "hf mf ndefformat --mini -> MIFARE Mini", - "hf mf ndefformat --1k -> MIFARE Classic 1k", - "hf mf ndefformat --2k -> MIFARE 2k", - "hf mf ndefformat --4k -> MIFARE 4k", - "hf mf ndefformat --keys hf-mf-066C8B78-key.bin -> MIFARE 1k with keys from specified file" - ], + "description": "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename. It will try default keys and MAD keys to detect if tag is already formatted in order to write.", + "notes": [], "offline": false, - "options": [ - "-h, --help This help", - "-k, --keys filename of keys", - "--mini MIFARE Classic Mini / S20", - "--1k MIFARE Classic 1k / S50 (def)", - "--2k MIFARE Classic/Plus 2k", - "--4k MIFARE Classic 4k / S70" - ], - "usage": "hf mf ndefformat [-h] [-k ] [--mini] [--1k] [--2k] [--4k]" + "options": [], + "usage": "" }, "hf mf ndefread": { "command": "hf mf ndefread", @@ -4403,6 +4390,25 @@ ], "usage": "hf mf ndefread [-hvb] [--aid ] [-k ] [-f ]" }, + "hf mf ndefwrite": { + "command": "hf mf ndefwrite", + "description": "Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.", + "notes": [ + "hf mf ndefread -d 0300FE -> write empty record to tag", + "hf mf ndefread -f myfilename" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-d raw NDEF hex bytes", + "-f, --file write raw NDEF file to tag", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70" + ], + "usage": "hf mf ndefwrite [-h] [-d ] [-f ] [--mini] [--1k] [--2k] [--4k]" + }, "hf mf nested": { "command": "hf mf nested", "description": "Execute Nested attack against MIFARE Classic card for key recovery", @@ -10529,24 +10535,11 @@ }, "nfc mf cformat": { "command": "nfc mf cformat", - "description": "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename", - "notes": [ - "hf mf ndefformat --mini -> MIFARE Mini", - "hf mf ndefformat --1k -> MIFARE Classic 1k", - "hf mf ndefformat --2k -> MIFARE 2k", - "hf mf ndefformat --4k -> MIFARE 4k", - "hf mf ndefformat --keys hf-mf-066C8B78-key.bin -> MIFARE 1k with keys from specified file" - ], + "description": "format MIFARE Classic Tag as a NFC tag with Data Exchange Format (NDEF) If no given, UID will be used as filename. It will try default keys and MAD keys to detect if tag is already formatted in order to write.", + "notes": [], "offline": false, - "options": [ - "-h, --help This help", - "-k, --keys filename of keys", - "--mini MIFARE Classic Mini / S20", - "--1k MIFARE Classic 1k / S50 (def)", - "--2k MIFARE Classic/Plus 2k", - "--4k MIFARE Classic 4k / S70" - ], - "usage": "hf mf ndefformat [-h] [-k ] [--mini] [--1k] [--2k] [--4k]" + "options": [], + "usage": "" }, "nfc mf cread": { "command": "nfc mf cread", @@ -11394,8 +11387,8 @@ } }, "metadata": { - "commands_extracted": 720, + "commands_extracted": 721, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-10-16T15:53:13" + "extracted_on": "2022-10-20T15:33:35" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index ab64b022f..bbf1aa317 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -509,7 +509,8 @@ Check column "offline" for their availability. |`hf mf gen3freeze `|N |`Perma lock UID changes. irreversible` |`hf mf gview `|N |`View card` |`hf mf ndefformat `|N |`Format MIFARE Classic Tag as NFC Tag` -|`hf mf ndefread `|N |`Prints NDEF records from card` +|`hf mf ndefread `|N |`Read and print NDEF records from card` +|`hf mf ndefwrite `|N |`Write NDEF records to card` ### hf mfp From 6a74c8fc9666be11b4d21e9a50d1302ced799608 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 20 Oct 2022 17:35:57 +0200 Subject: [PATCH 282/759] be more lenient with parsing ndef --- client/src/cmdhfmf.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 0b7cc7280..a71e7863b 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5688,7 +5688,12 @@ int CmdHFMFNDEFRead(const char *Cmd) { if (fnlen != 0) { saveFile(filename, ".bin", data, datalen); } - NDEFDecodeAndPrint(data, datalen, verbose); + + res = NDEFDecodeAndPrint(data, datalen, verbose); + if (res != PM3_SUCCESS) { + PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header"); + res = NDEFRecordsDecodeAndPrint(data, datalen); + } PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -vv`") " for more details"); return PM3_SUCCESS; @@ -5847,7 +5852,8 @@ int CmdHFMFNDEFFormat(const char *Cmd) { fclose(f); } -skipfile: ; +skipfile: + ; uint8_t firstblocks[8][16] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -5971,7 +5977,7 @@ int CmdHFMFNDEFWrite(const char *Cmd) { return PM3_ENOTTY; } - if ((rawlen && fnlen) || (rawlen == 0 && fnlen == 0) ) { + if ((rawlen && fnlen) || (rawlen == 0 && fnlen == 0)) { PrintAndLogEx(WARNING, "Please specify either raw hex or filename"); return PM3_EINVARG; } @@ -6020,9 +6026,9 @@ int CmdHFMFNDEFWrite(const char *Cmd) { while (bytes > 0) { uint8_t block[MFBLOCK_SIZE] = { 0x00 }; - + if (bytes < MFBLOCK_SIZE) { - memcpy(block, ptr_raw, bytes); + memcpy(block, ptr_raw, bytes); } else { memcpy(block, ptr_raw, MFBLOCK_SIZE); ptr_raw += MFBLOCK_SIZE; @@ -6980,7 +6986,7 @@ static command_t CommandTable[] = { // {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, {"ndefformat", CmdHFMFNDEFFormat, IfPm3Iso14443a, "Format MIFARE Classic Tag as NFC Tag"}, {"ndefread", CmdHFMFNDEFRead, IfPm3Iso14443a, "Read and print NDEF records from card"}, - {"ndefwrite", CmdHFMFNDEFWrite, IfPm3Iso14443a, "Write NDEF records to card"}, + {"ndefwrite", CmdHFMFNDEFWrite, IfPm3Iso14443a, "Write NDEF records to card"}, {NULL, NULL, NULL, NULL} }; From 17470a3720a46efc1d7817a82f8d82aa04a01916 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Oct 2022 19:02:18 +0200 Subject: [PATCH 283/759] keeping inside the arrays --- client/src/cmdlfhitag.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index d439eb814..44e06f68d 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -581,24 +581,24 @@ static int CmdLFHitagReader(const char *Cmd) { if (s01) { cmd = CMD_LF_HITAGS_READ; htf = RHTSF_CHALLENGE; - memcpy(htd.auth.NrAr, nrar, sizeof(nrar)); + memcpy(htd.auth.NrAr, nrar, sizeof(htd.auth.NrAr)); } if (s02) { cmd = CMD_LF_HITAGS_READ; htf = RHTSF_KEY; - memcpy(htd.crypto.key, key, sizeof(key)); + memcpy(htd.crypto.key, key, sizeof(htd.crypto.key)); } if (h21) { htf = RHT2F_PASSWORD; - memcpy(htd.pwd.password, key, 4); + memcpy(htd.pwd.password, key, sizeof(htd.pwd.password)); } if (h22) { htf = RHT2F_AUTHENTICATE; - memcpy(htd.auth.NrAr, nrar, sizeof(nrar)); + memcpy(htd.auth.NrAr, nrar, sizeof(htd.auth.NrAr)); } if (h23) { htf = RHT2F_CRYPTO; - memcpy(htd.crypto.key, key, sizeof(key)); + memcpy(htd.crypto.key, key, sizeof(htd.crypto.key)); } if (h25) { htf = RHT2F_TEST_AUTH_ATTEMPTS; @@ -770,22 +770,22 @@ static int CmdLFHitagWriter(const char *Cmd) { if (s03) { htf = WHTSF_CHALLENGE; - memcpy(htd.auth.NrAr, nrar, sizeof(nrar)); + memcpy(htd.auth.NrAr, nrar, sizeof(htd.auth.NrAr)); memcpy(htd.auth.data, data, sizeof(data)); } if (s04) { htf = WHTSF_KEY; - memcpy(htd.crypto.key, key, sizeof(key)); + memcpy(htd.crypto.key, key, sizeof(htd.crypto.key)); memcpy(htd.crypto.data, data, sizeof(data)); } if (h24) { htf = WHT2F_CRYPTO; - memcpy(htd.pwd.password, key, 6); + memcpy(htd.crypto.key, key, sizeof(htd.crypto.key)); memcpy(htd.crypto.data, data, sizeof(data)); } if (h27) { htf = WHT2F_PASSWORD; - memcpy(htd.pwd.password, key, 4); + memcpy(htd.pwd.password, key, sizeof(htd.pwd.password)); memcpy(htd.crypto.data, data, sizeof(data)); } @@ -920,7 +920,6 @@ void annotateHitag2(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, } - void annotateHitagS(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, bool is_response) { } From ab567001a8a363e3927ace992e37f6e083c4ff7a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Oct 2022 19:03:50 +0200 Subject: [PATCH 284/759] text --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c4125a89..c5015768c 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] + - Fixed `lf hitag` - keep inside the arrays for key/password/nrar (@iceman1001) + - Added `hf mf ndefwrite` - write raw NDEF records to MIFARE Classic tag (@iceman1001) - Changed `hf mf cwipe` - swapped the block0 data to genuine manufacture ones (@iceman1001) - Added `hf mf ndefformat` - format a MIFARE Classic tag as NFC tag with Data Exchange Format (NDEF) (@iceman1001) - Changed `hf 14b dump, view` to get correct chip type in case of SRT512 and friends (@DidierA) From a2c4682d1875ff5bcba03689dcd0088c28260f1a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 22 Oct 2022 19:51:33 +0200 Subject: [PATCH 285/759] Change "hf mf ndefwrite" added option to fix bad ndef records by adding a correct block and a terminator block --- client/src/cmdhfmf.c | 131 ++++++++++++++++++++++++++++++++++++------ client/src/nfc/ndef.c | 4 +- client/src/nfc/ndef.h | 2 + 3 files changed, 117 insertions(+), 20 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index a71e7863b..6d1dfa1b0 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5570,6 +5570,7 @@ static int CmdHF14AMfMAD(const char *Cmd) { return PM3_SUCCESS; } + int CmdHFMFNDEFRead(const char *Cmd) { CLIParserContext *ctx; @@ -5607,9 +5608,9 @@ int CmdHFMFNDEFRead(const char *Cmd) { CLIParserFree(ctx); - uint16_t ndefAID = 0xE103; + uint16_t ndef_aid = NDEF_MFC_AID; if (aidlen == 2) - ndefAID = (aid[0] << 8) + aid[1]; + ndef_aid = (aid[0] << 8) + aid[1]; uint8_t ndefkey[6] = {0}; memcpy(ndefkey, g_mifare_ndef_key, 6); @@ -5659,7 +5660,7 @@ int CmdHFMFNDEFRead(const char *Cmd) { PrintAndLogEx(INFO, "reading data from tag"); for (int i = 0; i < madlen; i++) { - if (ndefAID == mad[i]) { + if (ndef_aid == mad[i]) { uint8_t vsector[MFBLOCK_SIZE * 4] = {0}; if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, ndefkey, vsector)) { PrintAndLogEx(ERR, "error, reading sector %d ", i + 1); @@ -5916,18 +5917,21 @@ int CmdHFMFNDEFWrite(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf ndefwrite", "Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.\n", - "hf mf ndefread -d 0300FE -> write empty record to tag\n" - "hf mf ndefread -f myfilename" + "hf mf ndefwrite -d 0300FE -> write empty record to tag\n" + "hf mf ndefwrite -f myfilename\n" + "hf mf ndefwrite -d 033fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031\n" ); void *argtable[] = { - arg_param_begin, + arg_param_begin, arg_str0("d", NULL, "", "raw NDEF hex bytes"), arg_str0("f", "file", "", "write raw NDEF file to tag"), + arg_lit0("p", NULL, "fix NDEF record headers / terminator block if missing"), arg_lit0(NULL, "mini", "MIFARE Classic Mini / S20"), arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50 (def)"), arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -5940,10 +5944,13 @@ int CmdHFMFNDEFWrite(const char *Cmd) { char filename[FILE_PATH_SIZE] = {0}; CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); - bool m0 = arg_get_lit(ctx, 3); - bool m1 = arg_get_lit(ctx, 4); - bool m2 = arg_get_lit(ctx, 5); - bool m4 = arg_get_lit(ctx, 6); + bool fix_msg = arg_get_lit(ctx, 3); + + bool m0 = arg_get_lit(ctx, 4); + bool m1 = arg_get_lit(ctx, 5); + bool m2 = arg_get_lit(ctx, 6); + bool m4 = arg_get_lit(ctx, 7); + bool verbose = arg_get_lit(ctx, 8); CLIParserFree(ctx); @@ -5970,7 +5977,9 @@ int CmdHFMFNDEFWrite(const char *Cmd) { return PM3_EINVARG; } - PrintAndLogEx(INFO, "Number of sectors selected: %u", numSectors); + if (verbose) { + PrintAndLogEx(INFO, "Number of sectors selected: %u", numSectors); + } if (g_session.pm3_present == false) { PrintAndLogEx(FAILED, "No Proxmark3 device present"); @@ -6010,6 +6019,53 @@ int CmdHFMFNDEFWrite(const char *Cmd) { free(dump); } + // Has raw bytes ndef message header? + switch(raw[0]) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0xFD: + case 0xFE: + break; + default: { + if (fix_msg == false) { + PrintAndLogEx(WARNING, "raw NDEF message doesn't have a proper header, continuing..."); + } else { + if (bytes + 2 > sizeof(raw)) { + PrintAndLogEx(WARNING, "no room for header, exiting..."); + return PM3_EMALLOC; + } + uint8_t tmp_raw[4096]; + memcpy(tmp_raw, raw, sizeof(tmp_raw)); + raw[0] = 0x03; + raw[1] = bytes; + memcpy(raw + 2, tmp_raw, sizeof(raw) - 2 ); + bytes += 2; + PrintAndLogEx(SUCCESS, "Added generic message header (0x03)"); + } + } + } + + // Has raw bytes ndef a terminator block? + if (raw[bytes] != 0xFE) { + if (fix_msg == false) { + PrintAndLogEx(WARNING, "raw NDEF message doesn't have a terminator block, continuing..."); + } else { + + if (bytes + 1 > sizeof(raw)) { + PrintAndLogEx(WARNING, "no room for terminator block, exiting..."); + return PM3_EMALLOC; + } + raw[bytes++] = 0xFE; + PrintAndLogEx(SUCCESS, "Added terminator block (0xFE)"); + } + } + + if (verbose) { + PrintAndLogEx(INFO, "raw: %s", sprint_hex(raw, bytes)); + } + // read MAD Sector 0, block1,2 uint8_t sector0[MFBLOCK_SIZE * 4] = {0}; if (mfReadSector(MF_MAD1_SECTOR, MF_KEY_A, g_mifare_mad_key, sector0)) { @@ -6018,11 +6074,47 @@ int CmdHFMFNDEFWrite(const char *Cmd) { return PM3_ESOFT; } + // decode MAD + uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; + size_t madlen = 0; + res = MADDecode(sector0, NULL, mad, &madlen, false); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "can't decode MAD"); + return res; + } + // how much memory do I have available ? + // Skip sector 0 since its used for MAD + uint8_t freemem[MIFARE_4K_MAXSECTOR] = {0}; + uint16_t sum = 0; + uint8_t block_no = 0; + for (uint8_t i = 1; i < madlen; i++) { + + freemem[i] = (mad[i] == NDEF_MFC_AID); + + if (freemem[i]) { + + if (block_no == 0) { + block_no = mfFirstBlockOfSector(i); + } + + PrintAndLogEx(INFO, "Sector %u is NDEF formatted", i); + sum += (MFBLOCK_SIZE * 3 ); + } + } + + if (verbose) { + PrintAndLogEx(INFO, "Total avail ndef mem... %u", sum); + PrintAndLogEx(INFO, "First block............ %u", block_no); + } + + if (sum < bytes) { + PrintAndLogEx(WARNING, "Raw NDEF message is larger than available NDEF formatted memory"); + return PM3_EINVARG; + } // main loop - write blocks - uint8_t *ptr_raw = raw; - uint8_t b = 4; + uint8_t *ptr_raw = raw; while (bytes > 0) { uint8_t block[MFBLOCK_SIZE] = { 0x00 }; @@ -6035,20 +6127,21 @@ int CmdHFMFNDEFWrite(const char *Cmd) { } // write to card, try B key first - if (mf_write_block(g_mifare_default_key, MF_KEY_B, b, block) == 0) { + if (mf_write_block(g_mifare_default_key, MF_KEY_B, block_no, block) == 0) { // try A key, - if (mf_write_block(g_mifare_ndef_key, MF_KEY_A, b, block) == 0) { + if (mf_write_block(g_mifare_ndef_key, MF_KEY_A, block_no, block) == 0) { return PM3_EFAILED; } } - PrintAndLogEx(INPLACE, "%u", b); + PrintAndLogEx(INPLACE, "%u", block_no); - b++; - if (mfIsSectorTrailer(b)) { - b++; + block_no++; + if (mfIsSectorTrailer(block_no)) { + block_no++; } + bytes -= MFBLOCK_SIZE; } diff --git a/client/src/nfc/ndef.c b/client/src/nfc/ndef.c index ff2584d50..0b0fe8934 100644 --- a/client/src/nfc/ndef.c +++ b/client/src/nfc/ndef.c @@ -40,6 +40,7 @@ #define NDEF_XVCARDTEXT "text/x-vcard" + static const char *TypeNameFormat_s[] = { "Empty Record", "Well Known Record", @@ -117,7 +118,7 @@ static int ndefDecodePayload(NDEFHeader_t *ndef); static uint16_t ndefTLVGetLength(const uint8_t *data, size_t *indx) { uint16_t len = 0; - if (data[0] == 0xff) { + if (data[0] == 0xFF) { len = (data[1] << 8) + data[2]; *indx += 3; } else { @@ -1117,3 +1118,4 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { } return PM3_SUCCESS; } + \ No newline at end of file diff --git a/client/src/nfc/ndef.h b/client/src/nfc/ndef.h index b69384443..2e3374491 100644 --- a/client/src/nfc/ndef.h +++ b/client/src/nfc/ndef.h @@ -22,6 +22,8 @@ #include #include "common.h" +#define NDEF_MFC_AID 0xE103 + typedef enum { tnfEmptyRecord = 0x00, tnfWellKnownRecord = 0x01, From ac29a893cfe59b7bd72376dae3e9c6e040f97a6a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 23 Oct 2022 02:15:47 +0200 Subject: [PATCH 286/759] fix hf md ndefread, to correctly skip non ndef formatted sectors --- CHANGELOG.md | 1 + client/src/cmdhfmf.c | 10 ++++++---- client/src/mifare/mad.c | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5015768c..8bc9970cf 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 `hf mf ndefread` - now skips not ndef formatted sectors correctly (@iceman1001) - Fixed `lf hitag` - keep inside the arrays for key/password/nrar (@iceman1001) - Added `hf mf ndefwrite` - write raw NDEF records to MIFARE Classic tag (@iceman1001) - Changed `hf mf cwipe` - swapped the block0 data to genuine manufacture ones (@iceman1001) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 6d1dfa1b0..e8140a1c1 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5659,10 +5659,10 @@ int CmdHFMFNDEFRead(const char *Cmd) { } PrintAndLogEx(INFO, "reading data from tag"); - for (int i = 0; i < madlen; i++) { + for (int i = 1; i <= madlen; i++) { if (ndef_aid == mad[i]) { uint8_t vsector[MFBLOCK_SIZE * 4] = {0}; - if (mfReadSector(i + 1, keyB ? MF_KEY_B : MF_KEY_A, ndefkey, vsector)) { + if (mfReadSector(i, keyB ? MF_KEY_B : MF_KEY_A, ndefkey, vsector)) { PrintAndLogEx(ERR, "error, reading sector %d ", i + 1); return PM3_ESOFT; } @@ -5675,7 +5675,7 @@ int CmdHFMFNDEFRead(const char *Cmd) { } PrintAndLogEx(NORMAL, ""); - if (!datalen) { + if (datalen == 0) { PrintAndLogEx(WARNING, "no NDEF data"); return PM3_SUCCESS; } @@ -5696,7 +5696,9 @@ int CmdHFMFNDEFRead(const char *Cmd) { res = NDEFRecordsDecodeAndPrint(data, datalen); } - PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -vv`") " for more details"); + if (verbose2 == false) { + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -vv`") " for more details"); + } return PM3_SUCCESS; } diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index 2d2ab8c8a..57888c1ad 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -188,7 +188,7 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2) if (sector0 == NULL) return PM3_EINVARG; - uint8_t GPB = sector0[3 * 16 + 9]; + uint8_t GPB = sector0[(3 * 16) + 9]; if (verbose) PrintAndLogEx(SUCCESS, "%14s " _GREEN_("0x%02x"), "GPB", GPB); From 69fd1ac889627f1ee04d0f63bbdee1a96f83597f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 23 Oct 2022 02:17:49 +0200 Subject: [PATCH 287/759] now skips non ndef formmated sectors --- CHANGELOG.md | 1 + client/src/cmdhfmf.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bc9970cf..d6e416ae9 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 `hf mf ndefwrite` - now skips not ndef formatted sectors (@iceman1001) - Fixed `hf mf ndefread` - now skips not ndef formatted sectors correctly (@iceman1001) - Fixed `lf hitag` - keep inside the arrays for key/password/nrar (@iceman1001) - Added `hf mf ndefwrite` - write raw NDEF records to MIFARE Classic tag (@iceman1001) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index e8140a1c1..468922a53 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6139,9 +6139,15 @@ int CmdHFMFNDEFWrite(const char *Cmd) { PrintAndLogEx(INPLACE, "%u", block_no); + // find next available block block_no++; if (mfIsSectorTrailer(block_no)) { block_no++; + + // skip sectors which isn't ndef formatted + while ( freemem[mfSectorNum(block_no)] == 0 ) { + block_no++; + } } bytes -= MFBLOCK_SIZE; From 2627f3b3b9eefdb35f033449faff6acab111d891 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 23 Oct 2022 02:59:27 +0200 Subject: [PATCH 288/759] the ndef printing is now more dense and it honors verbose output --- CHANGELOG.md | 1 + client/src/cmdhf14a.c | 5 +- client/src/cmdhf14b.c | 5 +- client/src/cmdhfjooki.c | 4 +- client/src/cmdhfmf.c | 34 +++++++----- client/src/cmdhfmfu.c | 6 ++- client/src/cmdhfst25ta.c | 4 +- client/src/cmdnfc.c | 4 +- client/src/nfc/ndef.c | 109 ++++++++++++++++++++------------------- client/src/nfc/ndef.h | 2 +- doc/commands.json | 53 +++++++++++-------- 11 files changed, 130 insertions(+), 97 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6e416ae9..1ada99eba 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] + - Changed ndef output to be more dense. Honors verbose now (@iceman1001) - Fixed `hf mf ndefwrite` - now skips not ndef formatted sectors (@iceman1001) - Fixed `hf mf ndefread` - now skips not ndef formatted sectors correctly (@iceman1001) - Fixed `lf hitag` - keep inside the arrays for key/password/nrar (@iceman1001) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 83b37dda4..4dad816af 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -2633,12 +2633,15 @@ int CmdHF14ANdefRead(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_str0("f", "file", "", "save raw NDEF to file"), + arg_litn("v", "verbose", 0, 2, "show technical data"), 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); + + bool verbose = arg_get_lit(ctx, 2); CLIParserFree(ctx); bool activate_field = true; @@ -2828,7 +2831,7 @@ int CmdHF14ANdefRead(const char *Cmd) { saveFile(filename, ".bin", ndef_file, ndef_size); } - NDEFRecordsDecodeAndPrint(ndef_file, ndef_size); + NDEFRecordsDecodeAndPrint(ndef_file, ndef_size, verbose); free(ndef_file); return PM3_SUCCESS; } diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index 8bac70d15..cddf52365 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -2004,12 +2004,15 @@ int CmdHF14BNdefRead(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_str0("f", "file", "", "save raw NDEF to file"), + arg_litn("v", "verbose", 0, 2, "show technical data"), 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); + + bool verbose = arg_get_lit(ctx, 2); CLIParserFree(ctx); bool activate_field = true; @@ -2096,7 +2099,7 @@ int CmdHF14BNdefRead(const char *Cmd) { if (fnlen != 0) { saveFile(filename, ".bin", response + 2, resplen - 4); } - res = NDEFRecordsDecodeAndPrint(response + 2, resplen - 4); + res = NDEFRecordsDecodeAndPrint(response + 2, resplen - 4, verbose); out: switch_off_field_14b(); diff --git a/client/src/cmdhfjooki.c b/client/src/cmdhfjooki.c index bc0cdf89a..93ca6a00a 100644 --- a/client/src/cmdhfjooki.c +++ b/client/src/cmdhfjooki.c @@ -215,7 +215,7 @@ static void jooki_printEx(uint8_t *b64, uint8_t *iv, uint8_t tid, uint8_t fid, u PrintAndLogEx(INFO, "NDEF raw..... %s", sprint_hex_inrow(ndefmsg, sizeof(ndefmsg))); if (verbose) { - int res = NDEFRecordsDecodeAndPrint(ndefmsg, sizeof(ndefmsg)); + int res = NDEFRecordsDecodeAndPrint(ndefmsg, sizeof(ndefmsg), verbose); if (res != PM3_SUCCESS) { NDEFDecodeAndPrint(ndefmsg, sizeof(ndefmsg), verbose); } @@ -273,7 +273,7 @@ static int jooki_selftest(void) { jooki_create_ndef(b64, ndefmsg); PrintAndLogEx(INFO, "NDEF raw .... %s", sprint_hex(ndefmsg, sizeof(ndefmsg))); - int status = NDEFRecordsDecodeAndPrint(ndefmsg, sizeof(ndefmsg)); + int status = NDEFRecordsDecodeAndPrint(ndefmsg, sizeof(ndefmsg), true); if (status != PM3_SUCCESS) { status = NDEFDecodeAndPrint(ndefmsg, sizeof(ndefmsg), true); } diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 468922a53..6089b6514 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5693,11 +5693,15 @@ int CmdHFMFNDEFRead(const char *Cmd) { res = NDEFDecodeAndPrint(data, datalen, verbose); if (res != PM3_SUCCESS) { PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header"); - res = NDEFRecordsDecodeAndPrint(data, datalen); + res = NDEFRecordsDecodeAndPrint(data, datalen, verbose); } - if (verbose2 == false) { - PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -vv`") " for more details"); + if (verbose == false) { + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -v`") " for more details"); + } else { + if (verbose2 == false) { + PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndefread -vv`") " for more details"); + } } return PM3_SUCCESS; } @@ -5925,7 +5929,7 @@ int CmdHFMFNDEFWrite(const char *Cmd) { ); void *argtable[] = { - arg_param_begin, + arg_param_begin, arg_str0("d", NULL, "", "raw NDEF hex bytes"), arg_str0("f", "file", "", "write raw NDEF file to tag"), arg_lit0("p", NULL, "fix NDEF record headers / terminator block if missing"), @@ -5933,7 +5937,7 @@ int CmdHFMFNDEFWrite(const char *Cmd) { arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50 (def)"), arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), - arg_lit0("v", "verbose", "verbose output"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -6021,8 +6025,8 @@ int CmdHFMFNDEFWrite(const char *Cmd) { free(dump); } - // Has raw bytes ndef message header? - switch(raw[0]) { + // Has raw bytes ndef message header?bytes + switch (raw[0]) { case 0x00: case 0x01: case 0x02: @@ -6042,11 +6046,11 @@ int CmdHFMFNDEFWrite(const char *Cmd) { memcpy(tmp_raw, raw, sizeof(tmp_raw)); raw[0] = 0x03; raw[1] = bytes; - memcpy(raw + 2, tmp_raw, sizeof(raw) - 2 ); + memcpy(raw + 2, tmp_raw, sizeof(raw) - 2); bytes += 2; PrintAndLogEx(SUCCESS, "Added generic message header (0x03)"); } - } + } } // Has raw bytes ndef a terminator block? @@ -6092,7 +6096,7 @@ int CmdHFMFNDEFWrite(const char *Cmd) { uint8_t block_no = 0; for (uint8_t i = 1; i < madlen; i++) { - freemem[i] = (mad[i] == NDEF_MFC_AID); + freemem[i] = (mad[i] == NDEF_MFC_AID); if (freemem[i]) { @@ -6100,8 +6104,10 @@ int CmdHFMFNDEFWrite(const char *Cmd) { block_no = mfFirstBlockOfSector(i); } - PrintAndLogEx(INFO, "Sector %u is NDEF formatted", i); - sum += (MFBLOCK_SIZE * 3 ); + if (verbose) { + PrintAndLogEx(INFO, "Sector %u is NDEF formatted", i); + } + sum += (MFBLOCK_SIZE * 3); } } @@ -6116,7 +6122,7 @@ int CmdHFMFNDEFWrite(const char *Cmd) { } // main loop - write blocks - uint8_t *ptr_raw = raw; + uint8_t *ptr_raw = raw; while (bytes > 0) { uint8_t block[MFBLOCK_SIZE] = { 0x00 }; @@ -6145,7 +6151,7 @@ int CmdHFMFNDEFWrite(const char *Cmd) { block_no++; // skip sectors which isn't ndef formatted - while ( freemem[mfSectorNum(block_no)] == 0 ) { + while (freemem[mfSectorNum(block_no)] == 0) { block_no++; } } diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index a1ee42306..05436d77f 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -3958,6 +3958,7 @@ int CmdHF14MfuNDEFRead(const char *Cmd) { 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_litn("v", "verbose", 0, 2, "show technical data"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -3966,6 +3967,7 @@ int CmdHF14MfuNDEFRead(const char *Cmd) { int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + bool verbose = arg_get_lit(ctx, 4); CLIParserFree(ctx); switch (keylen) { @@ -4052,9 +4054,9 @@ int CmdHF14MfuNDEFRead(const char *Cmd) { if (fnlen != 0) { saveFile(filename, ".bin", records, (size_t)maxsize); } - status = NDEFRecordsDecodeAndPrint(records, (size_t)maxsize); + status = NDEFRecordsDecodeAndPrint(records, (size_t)maxsize, verbose); if (status != PM3_SUCCESS) { - status = NDEFDecodeAndPrint(records, (size_t)maxsize, true); + status = NDEFDecodeAndPrint(records, (size_t)maxsize, verbose); } char *jooki = strstr((char *)records, "s.jooki.rocks/s/?s="); diff --git a/client/src/cmdhfst25ta.c b/client/src/cmdhfst25ta.c index d60a98f32..0ccccd5d6 100644 --- a/client/src/cmdhfst25ta.c +++ b/client/src/cmdhfst25ta.c @@ -287,6 +287,7 @@ int CmdHFST25TANdefRead(const char *Cmd) { arg_param_begin, arg_str0("p", "pwd", "", "16 byte read password"), arg_str0("f", "file", "", "save raw NDEF to file"), + arg_litn("v", "verbose", 0, 2, "show technical data"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -294,6 +295,7 @@ int CmdHFST25TANdefRead(const char *Cmd) { 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 (pwdlen == 0) { @@ -404,7 +406,7 @@ int CmdHFST25TANdefRead(const char *Cmd) { if (fnlen != 0) { saveFile(filename, ".bin", response + 2, resplen - 4); } - NDEFRecordsDecodeAndPrint(response + 2, resplen - 4); + NDEFRecordsDecodeAndPrint(response + 2, resplen - 4, verbose); return PM3_SUCCESS; } diff --git a/client/src/cmdnfc.c b/client/src/cmdnfc.c index 959c2d661..aed87f069 100644 --- a/client/src/cmdnfc.c +++ b/client/src/cmdnfc.c @@ -114,7 +114,7 @@ static int CmdNfcDecode(const char *Cmd) { res = NDEFDecodeAndPrint(dump, bytes_read, verbose); if (res != PM3_SUCCESS) { PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header"); - res = NDEFRecordsDecodeAndPrint(dump, bytes_read); + res = NDEFRecordsDecodeAndPrint(dump, bytes_read, verbose); } free(dump); @@ -123,7 +123,7 @@ static int CmdNfcDecode(const char *Cmd) { res = NDEFDecodeAndPrint(data, datalen, verbose); if (res != PM3_SUCCESS) { PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header"); - res = NDEFRecordsDecodeAndPrint(data, datalen); + res = NDEFRecordsDecodeAndPrint(data, datalen, verbose); } } return res; diff --git a/client/src/nfc/ndef.c b/client/src/nfc/ndef.c index 0b0fe8934..2fa05d4ad 100644 --- a/client/src/nfc/ndef.c +++ b/client/src/nfc/ndef.c @@ -113,8 +113,8 @@ static const char *URI_s[] = { "urn:nfc:" // 0x23 }; -static int ndefRecordDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen); -static int ndefDecodePayload(NDEFHeader_t *ndef); +static int ndefRecordDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen, bool verbose); +static int ndefDecodePayload(NDEFHeader_t *ndef, bool verbose); static uint16_t ndefTLVGetLength(const uint8_t *data, size_t *indx) { uint16_t len = 0; @@ -166,23 +166,25 @@ static int ndefDecodeHeader(uint8_t *data, size_t datalen, NDEFHeader_t *header) return PM3_SUCCESS; } -static int ndefPrintHeader(NDEFHeader_t *header) { - PrintAndLogEx(INFO, _CYAN_("Header info")); +static int ndefPrintHeader(NDEFHeader_t *header, bool verbose) { - PrintAndLogEx(SUCCESS, " %s ....... Message begin", STRBOOL(header->MessageBegin)); - PrintAndLogEx(SUCCESS, " %s ...... Message end", STRBOOL(header->MessageEnd)); - PrintAndLogEx(SUCCESS, " %s ..... Chunk flag", STRBOOL(header->ChunkFlag)); - PrintAndLogEx(SUCCESS, " %s .... Short record bit", STRBOOL(header->ShortRecordBit)); - PrintAndLogEx(SUCCESS, " %s ... ID Len present", STRBOOL(header->IDLenPresent)); - PrintAndLogEx(SUCCESS, ""); + if (verbose) { + PrintAndLogEx(INFO, _CYAN_("Header info")); + PrintAndLogEx(SUCCESS, " %s ....... Message begin", STRBOOL(header->MessageBegin)); + PrintAndLogEx(SUCCESS, " %s ...... Message end", STRBOOL(header->MessageEnd)); + PrintAndLogEx(SUCCESS, " %s ..... Chunk flag", STRBOOL(header->ChunkFlag)); + PrintAndLogEx(SUCCESS, " %s .... Short record bit", STRBOOL(header->ShortRecordBit)); + PrintAndLogEx(SUCCESS, " %s ... ID Len present", STRBOOL(header->IDLenPresent)); + PrintAndLogEx(SUCCESS, ""); - PrintAndLogEx(SUCCESS, " Header length...... %zu", header->len); - PrintAndLogEx(SUCCESS, " Type length........ %zu", header->TypeLen); - PrintAndLogEx(SUCCESS, " Payload length..... %zu", header->PayloadLen); - PrintAndLogEx(SUCCESS, " ID length.......... %zu", header->IDLen); - PrintAndLogEx(SUCCESS, " Record length...... %zu", header->RecLen); + PrintAndLogEx(SUCCESS, " Header length...... %zu", header->len); + PrintAndLogEx(SUCCESS, " Type length........ %zu", header->TypeLen); + PrintAndLogEx(SUCCESS, " Payload length..... %zu", header->PayloadLen); + PrintAndLogEx(SUCCESS, " ID length.......... %zu", header->IDLen); - PrintAndLogEx(SUCCESS, " Type name format... [ 0x%02x ] " _YELLOW_("%s"), header->TypeNameFormat, TypeNameFormat_s[header->TypeNameFormat]); + PrintAndLogEx(SUCCESS, " Type name format... [ 0x%02x ] " _YELLOW_("%s"), header->TypeNameFormat, TypeNameFormat_s[header->TypeNameFormat]); + PrintAndLogEx(SUCCESS, " Record length...... %zu", header->RecLen); + } return PM3_SUCCESS; } @@ -483,26 +485,27 @@ static int ndefDecodePayloadSmartPoster(uint8_t *ndef, size_t ndeflen, bool prin return res; } - if (verbose) { - ndefPrintHeader(&NDEFHeader); - } + ndefPrintHeader(&NDEFHeader, verbose); if (NDEFHeader.TypeLen && NDEFHeader.PayloadLen) { - ndefDecodePayload(&NDEFHeader); + ndefDecodePayload(&NDEFHeader, verbose); } - if (NDEFHeader.TypeLen) { - PrintAndLogEx(INFO, "Type data"); - print_buffer(NDEFHeader.Type, NDEFHeader.TypeLen, 1); - } - if (NDEFHeader.IDLen) { - PrintAndLogEx(INFO, "ID data"); - print_buffer(NDEFHeader.ID, NDEFHeader.IDLen, 1); - } - if (NDEFHeader.PayloadLen) { - PrintAndLogEx(INFO, "Payload data"); - print_buffer(NDEFHeader.Payload, NDEFHeader.PayloadLen, 1); + if (verbose) { + if (NDEFHeader.TypeLen) { + PrintAndLogEx(INFO, "Type data"); + print_buffer(NDEFHeader.Type, NDEFHeader.TypeLen, 1); + } + if (NDEFHeader.IDLen) { + PrintAndLogEx(INFO, "ID data"); + print_buffer(NDEFHeader.ID, NDEFHeader.IDLen, 1); + } + if (NDEFHeader.PayloadLen) { + PrintAndLogEx(INFO, "Payload data"); + print_buffer(NDEFHeader.Payload, NDEFHeader.PayloadLen, 1); + } } + // recursive if (NDEFHeader.MessageEnd == false) { ndefDecodePayloadSmartPoster(ndef + NDEFHeader.RecLen, ndeflen - NDEFHeader.RecLen, false, false); @@ -825,7 +828,7 @@ static int ndefDecodeMime_bt(NDEFHeader_t *ndef) { return PM3_SUCCESS; } -static int ndefDecodePayload(NDEFHeader_t *ndef) { +static int ndefDecodePayload(NDEFHeader_t *ndef, bool verbose) { PrintAndLogEx(INFO, ""); switch (ndef->TypeNameFormat) { @@ -868,7 +871,7 @@ static int ndefDecodePayload(NDEFHeader_t *ndef) { } if (!strncmp((char *)ndef->Type, "Sp", ndef->TypeLen)) { - ndefDecodePayloadSmartPoster(ndef->Payload, ndef->PayloadLen, true, false); + ndefDecodePayloadSmartPoster(ndef->Payload, ndef->PayloadLen, true, verbose); } if (!strncmp((char *)ndef->Type, "Di", ndef->TypeLen)) { @@ -947,36 +950,39 @@ static int ndefDecodePayload(NDEFHeader_t *ndef) { return PM3_SUCCESS; } -static int ndefRecordDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { +static int ndefRecordDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen, bool verbose) { NDEFHeader_t NDEFHeader = {0}; int res = ndefDecodeHeader(ndefRecord, ndefRecordLen, &NDEFHeader); if (res != PM3_SUCCESS) return res; - ndefPrintHeader(&NDEFHeader); + ndefPrintHeader(&NDEFHeader, verbose); PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, _CYAN_("Payload info")); - if (NDEFHeader.TypeLen) { - PrintAndLogEx(INFO, "Type data"); - print_buffer(NDEFHeader.Type, NDEFHeader.TypeLen, 1); - } - if (NDEFHeader.IDLen) { - PrintAndLogEx(INFO, "ID data"); - print_buffer(NDEFHeader.ID, NDEFHeader.IDLen, 1); - } - if (NDEFHeader.PayloadLen) { - PrintAndLogEx(INFO, "Payload data"); - print_buffer(NDEFHeader.Payload, NDEFHeader.PayloadLen, 1); + if (verbose) { + if (NDEFHeader.TypeLen) { + PrintAndLogEx(INFO, "Type data"); + print_buffer(NDEFHeader.Type, NDEFHeader.TypeLen, 1); + } + if (NDEFHeader.IDLen) { + PrintAndLogEx(INFO, "ID data"); + print_buffer(NDEFHeader.ID, NDEFHeader.IDLen, 1); + } + if (NDEFHeader.PayloadLen) { + PrintAndLogEx(INFO, "Payload data"); + print_buffer(NDEFHeader.Payload, NDEFHeader.PayloadLen, 1); + } } + if (NDEFHeader.TypeLen && NDEFHeader.PayloadLen) { - ndefDecodePayload(&NDEFHeader); + ndefDecodePayload(&NDEFHeader, verbose); } return PM3_SUCCESS; } -int NDEFRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { +int NDEFRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen, bool verbose) { bool firstRec = true; size_t len = 0; size_t counter = 0; @@ -1005,7 +1011,7 @@ int NDEFRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, _CYAN_("Record") " " _YELLOW_("%zu"), counter); PrintAndLogEx(INFO, "-----------------------------------------------------"); - ndefRecordDecodeAndPrint(&ndefRecord[len], NDEFHeader.RecLen); + ndefRecordDecodeAndPrint(&ndefRecord[len], NDEFHeader.RecLen, verbose); len += NDEFHeader.RecLen; @@ -1085,9 +1091,9 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { if (len == 0) { PrintAndLogEx(SUCCESS, "Found NDEF message w zero length"); } else { - PrintAndLogEx(SUCCESS, "Found NDEF message (%d bytes)", len); + PrintAndLogEx(SUCCESS, "Found NDEF message ( " _YELLOW_("%d") " bytes )", len); - int res = NDEFRecordsDecodeAndPrint(&ndef[indx], len); + int res = NDEFRecordsDecodeAndPrint(&ndef[indx], len, verbose); if (res != PM3_SUCCESS) return res; } @@ -1118,4 +1124,3 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { } return PM3_SUCCESS; } - \ No newline at end of file diff --git a/client/src/nfc/ndef.h b/client/src/nfc/ndef.h index 2e3374491..478c28e0a 100644 --- a/client/src/nfc/ndef.h +++ b/client/src/nfc/ndef.h @@ -74,6 +74,6 @@ typedef struct { } NDEFHeader_t; int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose); -int NDEFRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen); +int NDEFRecordsDecodeAndPrint(uint8_t *ndefRecord, size_t ndefRecordLen, bool verbose); #endif // _NDEF_H_ diff --git a/doc/commands.json b/doc/commands.json index 0bc8ae626..39064b73d 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -1162,9 +1162,10 @@ "offline": false, "options": [ "-h, --help This help", - "-f, --file save raw NDEF to file" + "-f, --file save raw NDEF to file", + "-v, --verbose show technical data" ], - "usage": "hf 14a ndefread [-h] [-f ]" + "usage": "hf 14a ndefread [-hv] [-f ]" }, "hf 14a raw": { "command": "hf 14a raw", @@ -1348,9 +1349,10 @@ "offline": false, "options": [ "-h, --help This help", - "-f, --file save raw NDEF to file" + "-f, --file save raw NDEF to file", + "-v, --verbose show technical data" ], - "usage": "hf 14b ndefread [-h] [-f ]" + "usage": "hf 14b ndefread [-hv] [-f ]" }, "hf 14b raw": { "command": "hf 14b raw", @@ -4394,20 +4396,23 @@ "command": "hf mf ndefwrite", "description": "Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.", "notes": [ - "hf mf ndefread -d 0300FE -> write empty record to tag", - "hf mf ndefread -f myfilename" + "hf mf ndefwrite -d 0300FE -> write empty record to tag", + "hf mf ndefwrite -f myfilename", + "hf mf ndefwrite -d 033fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031" ], "offline": false, "options": [ "-h, --help This help", "-d raw NDEF hex bytes", "-f, --file write raw NDEF file to tag", + "-p fix NDEF record headers / terminator block if missing", "--mini MIFARE Classic Mini / S20", "--1k MIFARE Classic 1k / S50 (def)", "--2k MIFARE Classic/Plus 2k", - "--4k MIFARE Classic 4k / S70" + "--4k MIFARE Classic 4k / S70", + "-v, --verbose verbose output" ], - "usage": "hf mf ndefwrite [-h] [-d ] [-f ] [--mini] [--1k] [--2k] [--4k]" + "usage": "hf mf ndefwrite [-hpv] [-d ] [-f ] [--mini] [--1k] [--2k] [--4k]" }, "hf mf nested": { "command": "hf mf nested", @@ -6112,9 +6117,10 @@ "options": [ "-h, --help This help", "-l Swap entered key's endianness", - "-f, --file Save raw NDEF to file" + "-f, --file Save raw NDEF to file", + "-v, --verbose show technical data" ], - "usage": "hf mfu ndefread [-hl] [-k Replace default key for NDEF] [-f ]" + "usage": "hf mfu ndefread [-hlv] [-k Replace default key for NDEF] [-f ]" }, "hf mfu otptear": { "command": "hf mfu otptear", @@ -6454,9 +6460,10 @@ "options": [ "-h, --help This help", "-p, --pwd 16 byte read password", - "-f, --file save raw NDEF to file" + "-f, --file save raw NDEF to file", + "-v, --verbose show technical data" ], - "usage": "hf st25ta ndefread [-h] [-p ] [-f ]" + "usage": "hf st25ta ndefread [-hv] [-p ] [-f ]" }, "hf st25ta protect": { "command": "hf st25ta protect", @@ -10632,9 +10639,10 @@ "options": [ "-h, --help This help", "-l Swap entered key's endianness", - "-f, --file Save raw NDEF to file" + "-f, --file Save raw NDEF to file", + "-v, --verbose show technical data" ], - "usage": "hf mfu ndefread [-hl] [-k Replace default key for NDEF] [-f ]" + "usage": "hf mfu ndefread [-hlv] [-k Replace default key for NDEF] [-f ]" }, "nfc type4a help": { "command": "nfc type4a help", @@ -10654,9 +10662,10 @@ "offline": false, "options": [ "-h, --help This help", - "-f, --file save raw NDEF to file" + "-f, --file save raw NDEF to file", + "-v, --verbose show technical data" ], - "usage": "hf 14a ndefread [-h] [-f ]" + "usage": "hf 14a ndefread [-hv] [-f ]" }, "nfc type4a st25taread": { "command": "nfc type4a st25taread", @@ -10669,9 +10678,10 @@ "options": [ "-h, --help This help", "-p, --pwd 16 byte read password", - "-f, --file save raw NDEF to file" + "-f, --file save raw NDEF to file", + "-v, --verbose show technical data" ], - "usage": "hf st25ta ndefread [-h] [-p ] [-f ]" + "usage": "hf st25ta ndefread [-hv] [-p ] [-f ]" }, "nfc type4b help": { "command": "nfc type4b help", @@ -10691,9 +10701,10 @@ "offline": false, "options": [ "-h, --help This help", - "-f, --file save raw NDEF to file" + "-f, --file save raw NDEF to file", + "-v, --verbose show technical data" ], - "usage": "hf 14b ndefread [-h] [-f ]" + "usage": "hf 14b ndefread [-hv] [-f ]" }, "prefs get barmode": { "command": "prefs get barmode", @@ -11389,6 +11400,6 @@ "metadata": { "commands_extracted": 721, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-10-20T15:33:35" + "extracted_on": "2022-10-23T00:39:16" } } \ No newline at end of file From e1ae1cdd26bfb526f815457e3f036dfd0d17b1a0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 23 Oct 2022 03:20:24 +0200 Subject: [PATCH 289/759] style --- client/src/cmdnfc.c | 20 ++++++++++++++++---- client/src/pm3line_vocabulory.h | 3 ++- doc/commands.json | 26 ++++++++++++++++++++++++-- doc/commands.md | 3 ++- 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/client/src/cmdnfc.c b/client/src/cmdnfc.c index aed87f069..7afb8a718 100644 --- a/client/src/cmdnfc.c +++ b/client/src/cmdnfc.c @@ -138,6 +138,7 @@ static int CmdNFCType1Help(const char *Cmd); static command_t CommandNFCType1Table[] = { {"--------", CmdNFCType1Help, AlwaysAvailable, "-------------- " _CYAN_("NFC Forum Tag Type 1") " ---------------"}, +// {"format", CmdNFCType1Format, IfPm3Iso14443a, "format ISO-14443-a tag as NFC Tag"}, {"read", CmdNFCType1Read, IfPm3Iso14443a, "read NFC Forum Tag Type 1"}, // {"write", CmdNFCType1Write, IfPm3Iso14443a, "write NFC Forum Tag Type 1"}, {"--------", CmdNFCType1Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, @@ -165,6 +166,7 @@ static int CmdNFCType2Help(const char *Cmd); static command_t CommandNFCType2Table[] = { {"--------", CmdNFCType2Help, AlwaysAvailable, "-------------- " _CYAN_("NFC Forum Tag Type 2") " ---------------"}, +// {"format", CmdNFCType2Format, IfPm3Iso14443a, "format ISO-14443-a tag as NFC Tag"}, {"read", CmdNFCType2Read, IfPm3Iso14443a, "read NFC Forum Tag Type 2"}, // {"write", CmdNFCType2Write, IfPm3Iso14443a, "write NFC Forum Tag Type 2"}, {"--------", CmdNFCType2Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, @@ -193,8 +195,9 @@ static int CmdNFCType3Help(const char *Cmd); static command_t CommandNFCType3Table[] = { {"--------", CmdNFCType3Help, AlwaysAvailable, "-------------- " _CYAN_("NFC Forum Tag Type 3") " ---------------"}, +// {"format", CmdNFCType3Format, IfPm3Felica, "format FeliCa tag as NFC Tag"}, {"read", CmdNFCType3Read, IfPm3Felica, "read NFC Forum Tag Type 3"}, - {"write", CmdNFCType3Write, IfPm3Felica, "write NFC Forum Tag Type 3"}, +// {"write", CmdNFCType3Write, IfPm3Felica, "write NFC Forum Tag Type 3"}, {"--------", CmdNFCType3Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, {"help", CmdNFCType3Help, AlwaysAvailable, "This help"}, {NULL, NULL, NULL, NULL} @@ -225,6 +228,7 @@ static int CmdNFCType4AHelp(const char *Cmd); static command_t CommandNFCType4ATable[] = { {"--------", CmdNFCType4AHelp, AlwaysAvailable, "--------- " _CYAN_("NFC Forum Tag Type 4 ISO14443A") " ----------"}, +// {"format", CmdNFCType4AFormat, IfPm3Iso14443a, "format ISO-14443-a tag as NFC Tag"}, {"read", CmdNFCType4ARead, IfPm3Iso14443a, "read NFC Forum Tag Type 4 A"}, // {"write", CmdNFCType4AWrite, IfPm3Iso14443a, "write NFC Forum Tag Type 4 A"}, // {"mfdesread", CmdNFCMFDESRead, IfPm3Iso14443a, "read NDEF from MIFARE DESfire"}, // hf mfdes ndefread @@ -256,6 +260,7 @@ static int CmdNFCType4BHelp(const char *Cmd); static command_t CommandNFCType4BTable[] = { {"--------", CmdNFCType4BHelp, AlwaysAvailable, "--------- " _CYAN_("NFC Forum Tag Type 4 ISO14443B") " -------------"}, +// {"format", CmdNFCType4BFormat, IfPm3Iso14443b, "format ISO-14443-b tag as NFC Tag"}, {"read", CmdNFCType4BRead, IfPm3Iso14443b, "read NFC Forum Tag Type 4 B"}, // {"write", CmdNFCType4BWrite, IfPm3Iso14443b, "write NFC Forum Tag Type 4 B"}, {"--------", CmdNFCType4BHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, @@ -284,8 +289,9 @@ static int CmdNFCType5Help(const char *Cmd); static command_t CommandNFCType5Table[] = { {"--------", CmdNFCType5Help, AlwaysAvailable, "-------------- " _CYAN_("NFC Forum Tag Type 5") " ---------------"}, +// {"format", CmdNFCType5Format, IfPm3Iso15693, "format ISO-15693 tag as NFC Tag"}, {"read", CmdNFCType5Read, IfPm3Iso15693, "read NFC Forum Tag Type 5"}, - {"write", CmdNFCType5Write, IfPm3Iso15693, "write NFC Forum Tag Type 5"}, +// {"write", CmdNFCType5Write, IfPm3Iso15693, "write NFC Forum Tag Type 5"}, {"--------", CmdNFCType5Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, {"help", CmdNFCType5Help, AlwaysAvailable, "This help"}, {NULL, NULL, NULL, NULL} @@ -311,6 +317,11 @@ static int CmdNFCMFCFormat(const char *Cmd) { return CmdHFMFNDEFFormat(Cmd); } +static int CmdNFCMFCWrite(const char *Cmd) { + return CmdHFMFNDEFWrite(Cmd); +} + + static int CmdNFCMFPRead(const char *Cmd) { return CmdHFMFPNDEFRead(Cmd); } @@ -320,9 +331,9 @@ static int CmdNFCMFHelp(const char *Cmd); static command_t CommandMFTable[] = { {"--------", CmdNFCMFHelp, AlwaysAvailable, "--------- " _CYAN_("NFC Type MIFARE Classic/Plus Tag") " --------"}, - {"cread", CmdNFCMFCRead, IfPm3Iso14443a, "read NFC Type MIFARE Classic Tag"}, -// {"cwrite", CmdNFCMFCWrite, IfPm3Iso14443a, "write NFC Type MIFARE Classic Tag"}, {"cformat", CmdNFCMFCFormat, IfPm3Iso14443a, "format MIFARE Classic Tag as NFC Tag"}, + {"cread", CmdNFCMFCRead, IfPm3Iso14443a, "read NFC Type MIFARE Classic Tag"}, + {"cwrite", CmdNFCMFCWrite, IfPm3Iso14443a, "write NFC Type MIFARE Classic Tag"}, {"pread", CmdNFCMFPRead, IfPm3Iso14443a, "read NFC Type MIFARE Plus Tag"}, {"--------", CmdNFCMFHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, {"help", CmdNFCMFHelp, AlwaysAvailable, "This help"}, @@ -391,6 +402,7 @@ static command_t CommandTable[] = { {"--------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, {"help", CmdHelp, AlwaysAvailable, "This help"}, {"decode", CmdNfcDecode, AlwaysAvailable, "Decode NDEF records"}, +// {"encode", CmdNfcEncode, AlwaysAvailable, "Encode NDEF records"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 9dc5c84a7..da7ccffd1 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -718,8 +718,9 @@ const static vocabulory_t vocabulory[] = { { 1, "nfc type4a help" }, { 0, "nfc type4b read" }, { 1, "nfc type4b help" }, - { 0, "nfc mf cread" }, { 0, "nfc mf cformat" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf cwrite" }, { 0, "nfc mf pread" }, { 1, "nfc mf help" }, { 0, "nfc barcode read" }, diff --git a/doc/commands.json b/doc/commands.json index 39064b73d..d31d40d8c 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -10568,6 +10568,28 @@ ], "usage": "hf mf ndefread [-hvb] [--aid ] [-k ] [-f ]" }, + "nfc mf cwrite": { + "command": "nfc mf cwrite", + "description": "Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.", + "notes": [ + "hf mf ndefwrite -d 0300FE -> write empty record to tag", + "hf mf ndefwrite -f myfilename", + "hf mf ndefwrite -d 033fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-d raw NDEF hex bytes", + "-f, --file write raw NDEF file to tag", + "-p fix NDEF record headers / terminator block if missing", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70", + "-v, --verbose verbose output" + ], + "usage": "hf mf ndefwrite [-hpv] [-d ] [-f ] [--mini] [--1k] [--2k] [--4k]" + }, "nfc mf help": { "command": "nfc mf help", "description": "-------- --------- NFC Type MIFARE Classic/Plus Tag -------- -------- --------------------- General --------------------- help This help", @@ -11398,8 +11420,8 @@ } }, "metadata": { - "commands_extracted": 721, + "commands_extracted": 722, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-10-23T00:39:16" + "extracted_on": "2022-10-23T01:18:01" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index bbf1aa317..e8f272b7f 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -1305,8 +1305,9 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- -|`nfc mf cread `|N |`read NFC Type MIFARE Classic Tag` |`nfc mf cformat `|N |`format MIFARE Classic Tag as NFC Tag` +|`nfc mf cread `|N |`read NFC Type MIFARE Classic Tag` +|`nfc mf cwrite `|N |`write NFC Type MIFARE Classic Tag` |`nfc mf pread `|N |`read NFC Type MIFARE Plus Tag` |`nfc mf help `|Y |`This help` From 8940982c85ed3641ee84fd17b06818089eb0d3f5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 23 Oct 2022 18:45:20 +0200 Subject: [PATCH 290/759] changed "hf mfdes lsapp" to print dfname regardless if it is not a genuine strign --- client/src/cmdhfmfdes.c | 14 ++++++-------- client/src/mifare/aiddesfire.c | 2 +- client/src/mifare/desfirecore.c | 13 ++++++++++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 2c350e975..f3da73c2c 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -18,12 +18,10 @@ // Code heavily modified by B.Kerler :) #include "cmdhfmfdes.h" - #include #include - -#include "commonutil.h" // ARRAYLEN -#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "cmdparser.h" // command_t #include "comms.h" #include "ui.h" #include "cmdhf14a.h" @@ -32,16 +30,16 @@ #include "protocols.h" #include "cmdtrace.h" #include "cliparser.h" -#include "iso7816/apduinfo.h" // APDU manipulation / errorcodes +#include "iso7816/apduinfo.h" // APDU manipulation / errorcodes #include "iso7816/iso7816core.h" // APDU logging -#include "util_posix.h" // msleep +#include "util_posix.h" // msleep #include "mifare/desfirecore.h" #include "mifare/desfiretest.h" #include "mifare/desfiresecurechan.h" -#include "mifare/mifaredefault.h" // default keys +#include "mifare/mifaredefault.h" // default keys #include "crapto1/crapto1.h" #include "fileutils.h" -#include "nfc/ndef.h" // NDEF +//#include "nfc/ndef.h" // NDEF #include "mifare/mad.h" #include "mifare/mifaredefault.h" #include "generator.h" diff --git a/client/src/mifare/aiddesfire.c b/client/src/mifare/aiddesfire.c index 0e768daf9..7732a3649 100644 --- a/client/src/mifare/aiddesfire.c +++ b/client/src/mifare/aiddesfire.c @@ -333,7 +333,7 @@ int AIDDFDecodeAndPrint(uint8_t aid[3]) { open_aiddf_file(&df_known_aids, false); char fmt[80]; - snprintf(fmt, sizeof(fmt), " DF AID Function %02X%02X%02X :" _YELLOW_("%s"), aid[2], aid[1], aid[0], "%s"); + snprintf(fmt, sizeof(fmt), " DF AID Function... %02X%02X%02X :" _YELLOW_("%s"), aid[2], aid[1], aid[0], "%s"); print_aiddf_description(df_known_aids, aid, fmt, false); close_aiddf_file(df_known_aids); return PM3_SUCCESS; diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index ed217e8eb..f1a6412b5 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -997,7 +997,7 @@ int DesfireSelectAndAuthenticateEx(DesfireContext_t *dctx, DesfireSecureChannel if (isosw) dctx->cmdSet = DCCISO; - if (!noauth) { + if (noauth == false) { res = DesfireAuthenticate(dctx, secureChannel, verbose); if (res != PM3_SUCCESS) { PrintAndLogEx(ERR, "Desfire authenticate " _RED_("error") ". Result: [%d] %s", res, DesfireAuthErrorToStr(res)); @@ -1746,7 +1746,12 @@ int DesfireFillAppList(DesfireContext_t *dctx, PICCInfo_t *PICCInfo, AppListS ap int indx = AppListSearchAID(DesfireAIDByteToUint(&buf[i * 24 + 1]), appList, PICCInfo->appCount); if (indx >= 0) { appList[indx].appISONum = MemLeToUint2byte(&buf[i * 24 + 1 + 3]); - memcpy(appList[indx].appDFName, &buf[i * 24 + 1 + 5], strnlen((char *)&buf[i * 24 + 1 + 5], 16)); + memcpy( + appList[indx].appDFName, + &buf[i * 24 + 1 + 5], + // strnlen((char *)&buf[i * 24 + 1 + 5], 16) + 16 + ); } } } @@ -1822,7 +1827,9 @@ void DesfirePrintAppList(DesfireContext_t *dctx, PICCInfo_t *PICCInfo, AppListS PrintAndLogEx(SUCCESS, "--------------------------------- " _CYAN_("Applications list") " ---------------------------------"); for (int i = 0; i < PICCInfo->appCount; i++) { - PrintAndLogEx(SUCCESS, _CYAN_("Application number: 0x%02x") " iso id: " _GREEN_("0x%04x") " name: " _GREEN_("%s"), appList[i].appNum, appList[i].appISONum, appList[i].appDFName); + PrintAndLogEx(SUCCESS, _CYAN_("Application number: 0x%02X"), appList[i].appNum); + PrintAndLogEx(SUCCESS," ISO id.... " _GREEN_("0x%04X"), appList[i].appISONum); + PrintAndLogEx(SUCCESS," DF name... " _GREEN_("%s") " ( %s)", appList[i].appDFName, sprint_hex((uint8_t*)appList[i].appDFName, sizeof(appList[i].appDFName))); DesfirePrintAIDFunctions(appList[i].appNum); From 2025c8480abd5c7c04bc47e665f7e653678239ac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Oct 2022 18:48:56 +0200 Subject: [PATCH 291/759] added "hf 14a ndefwrite" - writes ndef to type4a tag --- client/src/cmdhf14a.c | 470 ++++++++++++++++++++++++++++++-- client/src/cmdhf14a.h | 8 +- client/src/cmdnfc.c | 22 +- client/src/pm3line_vocabulory.h | 21 +- doc/commands.json | 86 ++++-- doc/commands.md | 21 +- 6 files changed, 561 insertions(+), 67 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 4dad816af..2a1c3dfb2 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -18,9 +18,9 @@ #include "cmdhf14a.h" #include #include -#include "cmdparser.h" // command_t -#include "commonutil.h" // ARRAYLEN -#include "comms.h" // clearCommandBuffer +#include "cmdparser.h" // command_t +#include "commonutil.h" // ARRAYLEN +#include "comms.h" // clearCommandBuffer #include "cmdtrace.h" #include "cliparser.h" #include "cmdhfmf.h" @@ -29,16 +29,18 @@ #include "emv/emvcore.h" #include "ui.h" #include "crc16.h" -#include "util_posix.h" // msclock +#include "util_posix.h" // msclock #include "aidsearch.h" -#include "cmdhf.h" // handle HF plot +#include "cmdhf.h" // handle HF plot #include "cliparser.h" -#include "protocols.h" // definitions of ISO14A/7816 protocol, MAGIC_GEN_1A -#include "iso7816/apduinfo.h" // GetAPDUCodeDescription -#include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint -#include "cmdnfc.h" // print_type4_cc_info -#include "fileutils.h" // saveFile -#include "atrs.h" // getATRinfo +#include "protocols.h" // definitions of ISO14A/7816 protocol, MAGIC_GEN_1A +#include "iso7816/apduinfo.h" // GetAPDUCodeDescription +#include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint +#include "cmdnfc.h" // print_type4_cc_info +#include "fileutils.h" // saveFile +#include "atrs.h" // getATRinfo +#include "desfire.h" // desfire enums +#include "mifare/desfirecore.h" // desfire context static bool APDUInFramingEnable = true; @@ -2692,7 +2694,6 @@ int CmdHF14ANdefRead(const char *Cmd) { keep_field_on = true; // --------------- CC file reading ---------------- - uint8_t aSELECT_FILE_CC[30]; int aSELECT_FILE_CC_n = 0; if (backward_compatibility_v1) { @@ -2733,7 +2734,10 @@ int CmdHF14ANdefRead(const char *Cmd) { memcpy(cc_data, response, sizeof(cc_data)); uint8_t file_id[2] = {cc_data[9], cc_data[10]}; - print_type4_cc_info(cc_data, sizeof(cc_data)); + if (verbose) { + print_type4_cc_info(cc_data, sizeof(cc_data)); + } + uint16_t max_rapdu_size = (cc_data[3] << 8 | cc_data[4]) - 2; max_rapdu_size = max_rapdu_size < sizeof(response) - 2 ? max_rapdu_size : sizeof(response) - 2; @@ -2760,7 +2764,6 @@ int CmdHF14ANdefRead(const char *Cmd) { } // read first 2 bytes to get NDEF length - uint8_t aREAD_NDEF[30]; int aREAD_NDEF_n = 0; param_gethex_to_eol("00b0000002", 0, aREAD_NDEF, sizeof(aREAD_NDEF), &aREAD_NDEF_n); @@ -2836,21 +2839,442 @@ int CmdHF14ANdefRead(const char *Cmd) { return PM3_SUCCESS; } +int CmdHF14ANdefFormat(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a ndefformat", + "Format ISO14443-a Tag as a NFC tag with Data Exchange Format (NDEF)", + "hf 14a ndefformat\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_litn("v", "verbose", 0, 2, "show technical data"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool verbose = arg_get_lit(ctx, 1); + CLIParserFree(ctx); + + if (g_session.pm3_present == false) + return PM3_ENOTTY; + + bool activate_field = true; + bool keep_field_on = false; + uint8_t response[PM3_CMD_DATA_SIZE]; + int resplen = 0; + + SetAPDULogging(false); + + // step 1 - Select NDEF Tag application + uint8_t aSELECT_AID[80]; + int aSELECT_AID_n = 0; + param_gethex_to_eol("00a4040007d276000085010100", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n); + int res = ExchangeAPDU14a(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen); + + if (res != PM3_SUCCESS) { + return res; + } + + if (resplen < 2) { + return PM3_ESOFT; + } + + bool have_application = true; + uint16_t sw = get_sw(response, resplen); + if (sw != 0x9000) { + have_application = false; + PrintAndLogEx(INFO, "no NDEF application found"); + } else { + PrintAndLogEx(INFO, "found ndef application"); + } + + + // setup desfire authentication context + uint8_t empty_key[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + DesfireContext_t dctx; + dctx.secureChannel = DACNone; + DesfireSetKey(&dctx, 0, T_DES, empty_key); + DesfireSetKdf(&dctx, MFDES_KDF_ALGO_NONE, NULL, 0); + DesfireSetCommandSet(&dctx, DCCNativeISO); + DesfireSetCommMode(&dctx, DCMPlain); + + // step 1 - create application + if (have_application == false) { + // "hf mfdes createapp --aid 000001 --fid E110 --ks1 0B --ks2 A1 --dfhex D2760000850101 -t des -n 0 -k 0000000000000000" + PrintAndLogEx(INFO, "creating NDEF application..."); + + // authenticae first to AID 00 00 00 + res = DesfireSelectAndAuthenticateEx(&dctx, DACEV1, 0x000000, false, verbose); + if (res != PM3_SUCCESS) { + DropField(); + PrintAndLogEx(INFO, "failed empty auth.."); + return res; + } + + // create application + uint8_t dfname[] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01}; + uint8_t ks1 = 0x0B; + uint8_t ks2 = 0xA1; // bit FileID in ks2 + uint32_t appid = 0x0000001; + uint16_t fileid = 0xE110; + uint8_t data[250] = {0}; + size_t datalen = 0; + + DesfireAIDUintToByte(appid, &data[0]); + data[3] = ks1; + data[4] = ks2; + Uint2byteToMemLe(&data[5], fileid); + memcpy(&data[7], dfname, sizeof(dfname)); + datalen = 14; + + if (verbose) { + PrintAndLogEx(INFO, "---------------------------"); + PrintAndLogEx(INFO, _CYAN_("Creating Application using:")); + PrintAndLogEx(INFO, "AID........... 0x%02X%02X%02X", data[2], data[1], data[0]); + PrintAndLogEx(INFO, "Key Set 1..... 0x%02X", data[3]); + PrintAndLogEx(INFO, "Key Set 2..... 0x%02X", data[4]); + PrintAndLogEx(INFO, "ISO file ID... %s", (data[4] & 0x20) ? "enabled" : "disabled"); + if ((data[4] & 0x20)) { + PrintAndLogEx(INFO, "ISO file ID... 0x%04X", MemLeToUint2byte(&data[5])); + PrintAndLogEx(INFO, "DF Name[%02d] %s | %s\n", 7, sprint_ascii(dfname, sizeof(dfname)), sprint_hex(dfname, sizeof(dfname))); + } + PrintKeySettings(data[3], data[4], true, true); + PrintAndLogEx(INFO, "---------------------------"); + } + + res = DesfireCreateApplication(&dctx, data, datalen); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire CreateApplication command " _RED_("error") ". Result: %d", res); + DropField(); + return PM3_ESOFT; + } + + PrintAndLogEx(SUCCESS, "Desfire application %06x successfully " _GREEN_("created"), appid); + + + // step 2 - create capability container (CC File) + + // authenticae to the new AID 00 00 01 + uint8_t aes_key[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + dctx.secureChannel = DACNone; + DesfireSetKey(&dctx, 0, T_AES, aes_key); + DesfireSetKdf(&dctx, MFDES_KDF_ALGO_NONE, NULL, 0); + DesfireSetCommandSet(&dctx, DCCNativeISO); + DesfireSetCommMode(&dctx, DCMPlain); + res = DesfireSelectAndAuthenticateEx(&dctx, DACEV1, 0x000001, false, verbose); + if (res != PM3_SUCCESS) { + DropField(); + PrintAndLogEx(INFO, "failed aid auth.."); + return res; + } + + // hf mfdes createfile --aid 000001 --fid 01 --isofid E103 --amode plain --size 00000F + // --rrights free --wrights key0 --rwrights key0 --chrights key0 + // -n 0 -t aes -k 00000000000000000000000000000000 -m plain + uint8_t fid = 0x01; + uint16_t isofid = 0xE103; + uint32_t fsize = 0x0F; + uint8_t filetype = 0x00; // standard file + + // file access mode: plain 0x00 + // read access: free 0x0E + // write access: key0 0x00 + // r/w access: key0 0x00 + // change access: key0 0x00 + memset(data, 0x00, sizeof(data)); + datalen = 0; + + data[0] = fid; + data[1] = isofid & 0xff; + data[2] = (isofid >> 8) & 0xff; + datalen = 3; + + uint8_t *settings = &data[datalen]; + settings[0] = 0x00; + datalen++; + + DesfireEncodeFileAcessMode(&settings[1], 0x0E, 0x00, 0x00, 0x00) ; + datalen += 2; + + Uint3byteToMemLe(&data[datalen], fsize); + datalen += 3; + + if (verbose) { + PrintAndLogEx(INFO, "App: %06x. File num: 0x%02x type: 0x%02x data[%zu]: %s", appid, data[0], filetype, datalen, sprint_hex(data, datalen)); + } + + DesfirePrintCreateFileSettings(filetype, data, datalen); + + res = DesfireCreateFile(&dctx, filetype, data, datalen, true); // check length only if we dont use raw mode + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire CreateFile command " _RED_("error") ". Result: %d", res); + DropField(); + return PM3_ESOFT; + } + + PrintAndLogEx(SUCCESS, "%s file %02x in the app %06x created " _GREEN_("successfully"), GetDesfireFileType(filetype), data[0], appid); + + + + // hf mfdes write --aid 000001 --fid 01 -d 000F20003B00340406E10400FF00FF + // -n 0 -t aes -k 00000000000000000000000000000000 -m plain + res = DesfireSelectAndAuthenticateEx(&dctx, DACEV1, 0x000001, false, verbose); + if (res != PM3_SUCCESS) { + DropField(); + PrintAndLogEx(INFO, "failed aid auth.."); + return res; + } + + uint8_t fnum = 0x01; + uint32_t offset = 0; + uint8_t cc_data[] = {0x00, 0x0F, 0x20, 0x00, 0x3B, 0x00, 0x34, 0x04, 0x06, 0xE1, 0x04, 0x00, 0xFF, 0x00, 0x00}; + + res = DesfireWriteFile(&dctx, fnum, offset, sizeof(cc_data), cc_data); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire WriteFile command " _RED_("error") ". Result: %d", res); + DropField(); + return PM3_ESOFT; + } + + if (verbose) { + PrintAndLogEx(INFO, "Write data file %02x " _GREEN_("success"), fnum); + } + + + + // step 3 - create NDEF record file + // hf mfdes write --aid 000001 --fid 02 -d 000CD1010855016E78702E636F6DFE + // -n 0 -t aes -k 00000000000000000000000000000000 -m plain + + fid = 0x02; + isofid = 0xE104; + fsize = 0xFF; + filetype = 0x00; // standard file + + // file access mode: plain 0x00 + // read access: free 0x0E + // write access: key0 0x00 + // r/w access: key0 0x00 + // change access: key0 0x00 + memset(data, 0x00, sizeof(data)); + datalen = 0; + + data[0] = fid; + data[1] = isofid & 0xff; + data[2] = (isofid >> 8) & 0xff; + datalen = 3; + + settings = &data[datalen]; + settings[0] = 0x00; + datalen++; + + DesfireEncodeFileAcessMode(&settings[1], 0x0E, 0x00, 0x00, 0x00) ; + datalen += 2; + + Uint3byteToMemLe(&data[datalen], fsize); + datalen += 3; + + if (verbose) { + PrintAndLogEx(INFO, "App: %06x. File num: 0x%02x type: 0x%02x data[%zu]: %s", appid, data[0], filetype, datalen, sprint_hex(data, datalen)); + } + + DesfirePrintCreateFileSettings(filetype, data, datalen); + + res = DesfireCreateFile(&dctx, filetype, data, datalen, true); // check length only if we dont use raw mode + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire CreateFile command " _RED_("error") ". Result: %d", res); + DropField(); + return PM3_ESOFT; + } + + PrintAndLogEx(SUCCESS, "%s file %02x in the app %06x created " _GREEN_("successfully"), GetDesfireFileType(filetype), data[0], appid); + + DropField(); + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "finished"); + return PM3_SUCCESS; +} + + +int CmdHF14ANdefWrite(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a ndefwrite", + "Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.\n", + "hf 14a ndefwrite -d 0300FE -> write empty record to tag\n" + "hf 14a ndefwrite -f myfilename\n" + "hf 14a ndefwrite -d 003fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_str0("d", NULL, "", "raw NDEF hex bytes"), + arg_str0("f", "file", "", "write raw NDEF file to tag"), + arg_lit0("p", NULL, "fix NDEF record headers / terminator block if missing"), + arg_lit0("v", "verbose", "verbose output"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + uint8_t raw[256] = {0}; + int rawlen = 0; + CLIGetHexWithReturn(ctx, 1, raw, &rawlen); + + int fnlen = 0; + char filename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + + bool fix_msg = arg_get_lit(ctx, 3); + bool verbose = arg_get_lit(ctx, 4); + CLIParserFree(ctx); + + if (g_session.pm3_present == false) { + return PM3_ENOTTY; + } + + if ((rawlen && fnlen) || (rawlen == 0 && fnlen == 0)) { + PrintAndLogEx(WARNING, "Please specify either raw hex or filename"); + return PM3_EINVARG; + } + + int res = PM3_SUCCESS; + int32_t bytes = rawlen; + + // read dump file + if (fnlen) { + uint8_t *dump = NULL; + size_t bytes_read = 0; + res = pm3_load_dump(filename, (void **)&dump, &bytes_read, sizeof(raw)); + if (res != PM3_SUCCESS) { + return res; + } + memcpy(raw, dump, bytes_read); + bytes = bytes_read; + free(dump); + } + + if (verbose) { + PrintAndLogEx(INFO, "Num of bytes... %i (raw %i)", bytes, rawlen); + } + + // Has raw bytes ndef message header?bytes + switch (raw[0]) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0xFD: + case 0xFE: + break; + default: { + if (fix_msg == false) { + PrintAndLogEx(WARNING, "raw NDEF message doesn't have a proper header, continuing..."); + } else { + if (bytes + 2 > sizeof(raw)) { + PrintAndLogEx(WARNING, "no room for header, exiting..."); + return PM3_EMALLOC; + } + uint8_t tmp_raw[256]; + memcpy(tmp_raw, raw, sizeof(tmp_raw)); + raw[0] = 0x03; + raw[1] = bytes; + memcpy(raw + 2, tmp_raw, sizeof(raw) - 2); + bytes += 2; + PrintAndLogEx(SUCCESS, "Added generic message header (0x03)"); + } + } + } + + // Has raw bytes ndef a terminator block? + if (raw[bytes - 1] != 0xFE) { + if (fix_msg == false) { + PrintAndLogEx(WARNING, "raw NDEF message doesn't have a terminator block, continuing..."); + } else { + + if (bytes + 1 > sizeof(raw)) { + PrintAndLogEx(WARNING, "no room for terminator block, exiting..."); + return PM3_EMALLOC; + } + raw[bytes] = 0xFE; + bytes++; + PrintAndLogEx(SUCCESS, "Added terminator block (0xFE)"); + } + } + + if (verbose) { + PrintAndLogEx(INFO, "Num of Bytes... %u", bytes); + print_buffer(raw, bytes, 0); + } + + + // setup desfire authentication context + // authenticae to the new AID 00 00 01 + uint8_t aes_key[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + DesfireContext_t dctx; + dctx.secureChannel = DACNone; + DesfireSetKey(&dctx, 0, T_AES, aes_key); + DesfireSetKdf(&dctx, MFDES_KDF_ALGO_NONE, NULL, 0); + DesfireSetCommandSet(&dctx, DCCNativeISO); + DesfireSetCommMode(&dctx, DCMPlain); + res = DesfireSelectAndAuthenticateEx(&dctx, DACEV1, 0x000001, false, verbose); + if (res != PM3_SUCCESS) { + DropField(); + PrintAndLogEx(INFO, "failed aid auth.."); + return res; + } + + // write ndef file + + // hf mfdes write --aid 000002 --fid 02 - + // -n 0 -t aes -k 00000000000000000000000000000000 -m plain + uint8_t fnum = 0x02; + uint32_t offset = 0; + + res = DesfireWriteFile(&dctx, fnum, offset, bytes, raw); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Desfire WriteFile command " _RED_("error") ". Result: %d", res); + DropField(); + return PM3_ESOFT; + } + + if (verbose) { + PrintAndLogEx(INFO, "Write data file %02x " _GREEN_("success"), fnum); + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "finished"); + return PM3_SUCCESS; +} + static command_t CommandTable[] = { + {"-----------", CmdHelp, AlwaysAvailable, "----------------------- " _CYAN_("General") " -----------------------"}, {"help", CmdHelp, AlwaysAvailable, "This help"}, {"list", CmdHF14AList, AlwaysAvailable, "List ISO 14443-a history"}, - {"info", CmdHF14AInfo, IfPm3Iso14443a, "Tag information"}, - {"reader", CmdHF14AReader, IfPm3Iso14443a, "Act like an ISO14443-a reader"}, - {"ndefread", CmdHF14ANdefRead, IfPm3Iso14443a, "Read an NDEF file from ISO 14443-A Type 4 tag"}, - {"cuids", CmdHF14ACUIDs, IfPm3Iso14443a, "Collect n>0 ISO14443-a UIDs in one go"}, - {"sim", CmdHF14ASim, IfPm3Iso14443a, "Simulate ISO 14443-a tag"}, - {"sniff", CmdHF14ASniff, IfPm3Iso14443a, "sniff ISO 14443-a traffic"}, - {"apdu", CmdHF14AAPDU, IfPm3Iso14443a, "Send ISO 14443-4 APDU to tag"}, - {"chaining", CmdHF14AChaining, IfPm3Iso14443a, "Control ISO 14443-4 input chaining"}, - {"raw", CmdHF14ACmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "---------------------- " _CYAN_("operations") " ---------------------"}, {"antifuzz", CmdHF14AAntiFuzz, IfPm3Iso14443a, "Fuzzing the anticollision phase. Warning! Readers may react strange"}, {"config", CmdHf14AConfig, IfPm3Iso14443a, "Configure 14a settings (use with caution)"}, + {"cuids", CmdHF14ACUIDs, IfPm3Iso14443a, "Collect n>0 ISO14443-a UIDs in one go"}, + {"info", CmdHF14AInfo, IfPm3Iso14443a, "Tag information"}, + {"sim", CmdHF14ASim, IfPm3Iso14443a, "Simulate ISO 14443-a tag"}, + {"sniff", CmdHF14ASniff, IfPm3Iso14443a, "sniff ISO 14443-a traffic"}, + {"raw", CmdHF14ACmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"}, + {"reader", CmdHF14AReader, IfPm3Iso14443a, "Act like an ISO14443-a reader"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "------------------------- " _CYAN_("apdu") " -------------------------"}, + {"apdu", CmdHF14AAPDU, IfPm3Iso14443a, "Send ISO 14443-4 APDU to tag"}, {"apdufind", CmdHf14AFindapdu, IfPm3Iso14443a, "Enumerate APDUs - CLA/INS/P1P2"}, + {"chaining", CmdHF14AChaining, IfPm3Iso14443a, "Control ISO 14443-4 input chaining"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "------------------------- " _CYAN_("ndef") " -------------------------"}, + {"ndefformat", CmdHF14ANdefFormat, IfPm3Iso14443a, "Format ISO 14443-A as NFC Type 4 tag"}, + {"ndefread", CmdHF14ANdefRead, IfPm3Iso14443a, "Read an NDEF file from ISO 14443-A Type 4 tag"}, + {"ndefwrite", CmdHF14ANdefWrite, IfPm3Iso14443a, "Write NDEF records to ISO 14443-A tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmdhf14a.h b/client/src/cmdhf14a.h index 72d2e6e4f..2ac2672a1 100644 --- a/client/src/cmdhf14a.h +++ b/client/src/cmdhf14a.h @@ -37,9 +37,11 @@ typedef struct { } hintAIDList_t; int CmdHF14A(const char *Cmd); -int CmdHF14ASniff(const char *Cmd); // used by hf topaz sniff -int CmdHF14ASim(const char *Cmd); // used by hf mfu sim -int CmdHF14ANdefRead(const char *Cmd); +int CmdHF14ASniff(const char *Cmd); // used by hf topaz sniff +int CmdHF14ASim(const char *Cmd); // used by hf mfu sim +int CmdHF14ANdefRead(const char *Cmd); // used by cmdnfc.c +int CmdHF14ANdefFormat(const char *Cmd); // used by cmdnfc.c +int CmdHF14ANdefWrite(const char *Cmd); // used by cmdnfc.c int hf14a_getconfig(hf14a_config *config); int hf14a_setconfig(hf14a_config *config, bool verbose); diff --git a/client/src/cmdnfc.c b/client/src/cmdnfc.c index 7afb8a718..df87ee6f8 100644 --- a/client/src/cmdnfc.c +++ b/client/src/cmdnfc.c @@ -223,20 +223,28 @@ static int CmdNFCST25TARead(const char *Cmd) { return CmdHFST25TANdefRead(Cmd); } +static int CmdNFCType4AFormat(const char *Cmd) { + return CmdHF14ANdefFormat(Cmd); +} + +static int CmdNFCType4AWrite(const char *Cmd) { + return CmdHF14ANdefWrite(Cmd); +} + static int CmdNFCType4AHelp(const char *Cmd); static command_t CommandNFCType4ATable[] = { - {"--------", CmdNFCType4AHelp, AlwaysAvailable, "--------- " _CYAN_("NFC Forum Tag Type 4 ISO14443A") " ----------"}, -// {"format", CmdNFCType4AFormat, IfPm3Iso14443a, "format ISO-14443-a tag as NFC Tag"}, - {"read", CmdNFCType4ARead, IfPm3Iso14443a, "read NFC Forum Tag Type 4 A"}, -// {"write", CmdNFCType4AWrite, IfPm3Iso14443a, "write NFC Forum Tag Type 4 A"}, + {"--------", CmdNFCType4AHelp, AlwaysAvailable, "--------- " _CYAN_("NFC Forum Tag Type 4 ISO14443A") " ----------"}, + {"format", CmdNFCType4AFormat, IfPm3Iso14443a, "format ISO-14443-a tag as NFC Tag"}, + {"read", CmdNFCType4ARead, IfPm3Iso14443a, "read NFC Forum Tag Type 4 A"}, + {"write", CmdNFCType4AWrite, IfPm3Iso14443a, "write NFC Forum Tag Type 4 A"}, // {"mfdesread", CmdNFCMFDESRead, IfPm3Iso14443a, "read NDEF from MIFARE DESfire"}, // hf mfdes ndefread // {"mfdesformat", CmdNFCMFDESFormat, IfPm3Iso14443a, "format MIFARE DESfire as NFC Forum Tag Type 4"}, - {"st25taread", CmdNFCST25TARead, IfPm3Iso14443a, "read ST25TA as NFC Forum Tag Type 4"}, + {"st25taread", CmdNFCST25TARead, IfPm3Iso14443a, "read ST25TA as NFC Forum Tag Type 4"}, - {"--------", CmdNFCType4AHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, - {"help", CmdNFCType4AHelp, AlwaysAvailable, "This help"}, + {"--------", CmdNFCType4AHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, + {"help", CmdNFCType4AHelp, AlwaysAvailable, "This help"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index da7ccffd1..22abed93f 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -134,18 +134,20 @@ const static vocabulory_t vocabulory[] = { { 0, "hf sniff" }, { 1, "hf 14a help" }, { 1, "hf 14a list" }, - { 0, "hf 14a info" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a raw" }, { 0, "hf 14a antifuzz" }, { 0, "hf 14a config" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a info" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a apdu" }, { 0, "hf 14a apdufind" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a ndefformat" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a ndefwrite" }, { 1, "hf 14b help" }, { 0, "hf 14b apdu" }, { 0, "hf 14b dump" }, @@ -713,6 +715,7 @@ const static vocabulory_t vocabulory[] = { { 1, "nfc type1 help" }, { 0, "nfc type2 read" }, { 1, "nfc type2 help" }, + { 0, "nfc type4a format" }, { 0, "nfc type4a read" }, { 0, "nfc type4a st25taread" }, { 1, "nfc type4a help" }, diff --git a/doc/commands.json b/doc/commands.json index d31d40d8c..94d01e31b 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -1074,6 +1074,29 @@ ], "usage": "hf 14a apdu [-hsktde] [-m ] [-l ] []..." }, + "hf 14a apdufind": { + "command": "hf 14a apdufind", + "description": "Enumerate APDU's of ISO7816 protocol to find valid CLS/INS/P1/P2 commands. It loops all 256 possible values for each byte. The loop oder is INS -> P1/P2 (alternating) -> CLA. Tag must be on antenna before running.", + "notes": [ + "hf 14a apdufind", + "hf 14a apdufind --cla 80", + "hf 14a apdufind --cla 80 --error-limit 20 --skip-ins a4 --skip-ins b0 --with-le" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-c, --cla Start value of CLASS (1 hex byte)", + "-i, --ins Start value of INSTRUCTION (1 hex byte)", + "--p1 Start value of P1 (1 hex byte)", + "--p2 Start value of P2 (1 hex byte)", + "-r, --reset Minimum secondes before resetting the tag (to prevent timeout issues). Default is 5 minutes", + "-e, --error-limit Maximum times an status word other than 0x9000 or 0x6D00 is shown. Default is 512.", + "-s, --skip-ins Do not test an instruction (can be specified multiple times)", + "-l, --with-le Search for APDUs with Le=0 (case 2S) as well", + "-v, --verbose Verbose output" + ], + "usage": "hf 14a apdufind [-hlv] [-c ] [-i ] [--p1 ] [--p2 ] [-r ] [-e ] [-s ]..." + }, "hf 14a chaining": { "command": "hf 14a chaining", "description": "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", @@ -1089,25 +1112,12 @@ }, "hf 14a config": { "command": "hf 14a config", - "description": "--------------------------------------------------------------------------------------- hf 14a apdufind available offline: no", + "description": "--------------------------------------------------------------------------------------- hf 14a cuids available offline: no", "notes": [], "offline": false, "options": [], "usage": "" }, - "hf 14a cuids": { - "command": "hf 14a cuids", - "description": "Collect n>0 ISO14443-a UIDs in one go", - "notes": [ - "hf 14a cuids -n 5 -> Collect 5 UIDs" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-n, --num Number of UIDs to collect" - ], - "usage": "hf 14a cuids [-h] [-n ]" - }, "hf 14a help": { "command": "hf 14a help", "description": "help This help list List ISO 14443-a history", @@ -1152,6 +1162,19 @@ ], "usage": "hf 14a list [-h1fcrux] [--dict ]" }, + "hf 14a ndefformat": { + "command": "hf 14a ndefformat", + "description": "Format ISO14443-a Tag as a NFC tag with Data Exchange Format (NDEF)", + "notes": [ + "hf 14a ndefformat" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-v, --verbose show technical data" + ], + "usage": "hf 14a ndefformat [-hv]" + }, "hf 14a ndefread": { "command": "hf 14a ndefread", "description": "Read NFC Data Exchange Format (NDEF) file on Type 4 NDEF tag", @@ -1167,6 +1190,24 @@ ], "usage": "hf 14a ndefread [-hv] [-f ]" }, + "hf 14a ndefwrite": { + "command": "hf 14a ndefwrite", + "description": "Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.", + "notes": [ + "hf 14a ndefwrite -d 0300FE -> write empty record to tag", + "hf 14a ndefwrite -f myfilename", + "hf 14a ndefwrite -d 033fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-d raw NDEF hex bytes", + "-f, --file write raw NDEF file to tag", + "-p fix NDEF record headers / terminator block if missing", + "-v, --verbose verbose output" + ], + "usage": "hf 14a ndefwrite [-hpv] [-d ] [-f ]" + }, "hf 14a raw": { "command": "hf 14a raw", "description": "Sends raw bytes over ISO14443a. With option to use TOPAZ 14a mode.", @@ -10666,6 +10707,19 @@ ], "usage": "hf mfu ndefread [-hlv] [-k Replace default key for NDEF] [-f ]" }, + "nfc type4a format": { + "command": "nfc type4a format", + "description": "Format ISO14443-a Tag as a NFC tag with Data Exchange Format (NDEF)", + "notes": [ + "hf 14a ndefformat" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-v, --verbose show technical data" + ], + "usage": "hf 14a ndefformat [-hv]" + }, "nfc type4a help": { "command": "nfc type4a help", "description": "-------- --------- NFC Forum Tag Type 4 ISO14443A ---------- -------- --------------------- General --------------------- help This help", @@ -11420,8 +11474,8 @@ } }, "metadata": { - "commands_extracted": 722, + "commands_extracted": 725, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-10-23T01:18:01" + "extracted_on": "2022-10-24T16:21:33" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index e8f272b7f..a8a864d33 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -177,18 +177,20 @@ Check column "offline" for their availability. |------- |------- |----------- |`hf 14a help `|Y |`This help` |`hf 14a list `|Y |`List ISO 14443-a history` -|`hf 14a info `|N |`Tag information` -|`hf 14a reader `|N |`Act like an ISO14443-a reader` -|`hf 14a ndefread `|N |`Read an NDEF file from ISO 14443-A Type 4 tag` -|`hf 14a cuids `|N |`Collect n>0 ISO14443-a UIDs in one go` -|`hf 14a sim `|N |`Simulate ISO 14443-a tag` -|`hf 14a sniff `|N |`sniff ISO 14443-a traffic` -|`hf 14a apdu `|N |`Send ISO 14443-4 APDU to tag` -|`hf 14a chaining `|N |`Control ISO 14443-4 input chaining` -|`hf 14a raw `|N |`Send raw hex data to tag` |`hf 14a antifuzz `|N |`Fuzzing the anticollision phase. Warning! Readers may react strange` |`hf 14a config `|N |`Configure 14a settings (use with caution)` +|`hf 14a cuids `|N |`Collect n>0 ISO14443-a UIDs in one go` +|`hf 14a info `|N |`Tag information` +|`hf 14a sim `|N |`Simulate ISO 14443-a tag` +|`hf 14a sniff `|N |`sniff ISO 14443-a traffic` +|`hf 14a raw `|N |`Send raw hex data to tag` +|`hf 14a reader `|N |`Act like an ISO14443-a reader` +|`hf 14a apdu `|N |`Send ISO 14443-4 APDU to tag` |`hf 14a apdufind `|N |`Enumerate APDUs - CLA/INS/P1P2` +|`hf 14a chaining `|N |`Control ISO 14443-4 input chaining` +|`hf 14a ndefformat `|N |`Format ISO 14443-A as NFC Type 4 tag` +|`hf 14a ndefread `|N |`Read an NDEF file from ISO 14443-A Type 4 tag` +|`hf 14a ndefwrite `|N |`Write NDEF records to ISO 14443-A tag` ### hf 14b @@ -1284,6 +1286,7 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- +|`nfc type4a format `|N |`format ISO-14443-a tag as NFC Tag` |`nfc type4a read `|N |`read NFC Forum Tag Type 4 A` |`nfc type4a st25taread `|N |`read ST25TA as NFC Forum Tag Type 4` |`nfc type4a help `|Y |`This help` From 8d24e105ea842202d3a6307954451e11f11318d2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Oct 2022 18:49:08 +0200 Subject: [PATCH 292/759] text --- client/src/mifare/desfirecore.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index f1a6412b5..ab572b4d0 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -1828,8 +1828,8 @@ void DesfirePrintAppList(DesfireContext_t *dctx, PICCInfo_t *PICCInfo, AppListS for (int i = 0; i < PICCInfo->appCount; i++) { PrintAndLogEx(SUCCESS, _CYAN_("Application number: 0x%02X"), appList[i].appNum); - PrintAndLogEx(SUCCESS," ISO id.... " _GREEN_("0x%04X"), appList[i].appISONum); - PrintAndLogEx(SUCCESS," DF name... " _GREEN_("%s") " ( %s)", appList[i].appDFName, sprint_hex((uint8_t*)appList[i].appDFName, sizeof(appList[i].appDFName))); + PrintAndLogEx(SUCCESS, " ISO id.... " _GREEN_("0x%04X"), appList[i].appISONum); + PrintAndLogEx(SUCCESS, " DF name... " _GREEN_("%s") " ( %s)", appList[i].appDFName, sprint_hex((uint8_t *)appList[i].appDFName, sizeof(appList[i].appDFName))); DesfirePrintAIDFunctions(appList[i].appNum); @@ -2689,11 +2689,11 @@ void DesfirePrintCreateFileSettings(uint8_t filetype, uint8_t *data, size_t len) PrintAndLogEx(INFO, "---- " _CYAN_("Create file settings") " ----"); PrintAndLogEx(SUCCESS, "File type : %s", ftyperec->text); - PrintAndLogEx(SUCCESS, "File number : 0x%02x (%d)", data[0], data[0]); + PrintAndLogEx(SUCCESS, "File number : 0x%02X (%d)", data[0], data[0]); size_t xlen = 1; if (ftyperec->mayHaveISOfid) { if (isoidpresent) { - PrintAndLogEx(SUCCESS, "File ISO number : 0x%04x", MemLeToUint2byte(&data[xlen])); + PrintAndLogEx(SUCCESS, "File ISO number : 0x%04X", MemLeToUint2byte(&data[xlen])); xlen += 2; } else { PrintAndLogEx(SUCCESS, "File ISO number : n/a"); @@ -2705,7 +2705,7 @@ void DesfirePrintCreateFileSettings(uint8_t filetype, uint8_t *data, size_t len) PrintAndLogEx(SUCCESS, "Additional access: %s", (addaccess) ? "Yes" : "No"); xlen++; - PrintAndLogEx(SUCCESS, "Access rights : %04x", MemLeToUint2byte(&data[xlen])); + PrintAndLogEx(SUCCESS, "Access rights : %04X", MemLeToUint2byte(&data[xlen])); DesfirePrintAccessRight(&data[xlen]); xlen += 2; From 5280ada0549b593f095904bc82b077ea15cb2be2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Oct 2022 18:49:40 +0200 Subject: [PATCH 293/759] bug fix, added 0xFE in the wrong place --- client/src/cmdhfmf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 6089b6514..4fdeedbe0 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6054,7 +6054,7 @@ int CmdHFMFNDEFWrite(const char *Cmd) { } // Has raw bytes ndef a terminator block? - if (raw[bytes] != 0xFE) { + if (raw[bytes - 1] != 0xFE) { if (fix_msg == false) { PrintAndLogEx(WARNING, "raw NDEF message doesn't have a terminator block, continuing..."); } else { @@ -6063,13 +6063,15 @@ int CmdHFMFNDEFWrite(const char *Cmd) { PrintAndLogEx(WARNING, "no room for terminator block, exiting..."); return PM3_EMALLOC; } - raw[bytes++] = 0xFE; + raw[bytes] = 0xFE; + bytes++; PrintAndLogEx(SUCCESS, "Added terminator block (0xFE)"); } } if (verbose) { - PrintAndLogEx(INFO, "raw: %s", sprint_hex(raw, bytes)); + PrintAndLogEx(INFO, "Num of Bytes... %u", bytes); + print_buffer(raw, bytes, 0); } // read MAD Sector 0, block1,2 From 88c17fcd41a17c6ef4b8360a085ac697ce36f452 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Oct 2022 18:50:47 +0200 Subject: [PATCH 294/759] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ada99eba..78ac5dde8 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] + - Added `hf 14a ndefwrite` - write raw NDEF records to TYPE4A tags (@iceman1001) - Changed ndef output to be more dense. Honors verbose now (@iceman1001) - Fixed `hf mf ndefwrite` - now skips not ndef formatted sectors (@iceman1001) - Fixed `hf mf ndefread` - now skips not ndef formatted sectors correctly (@iceman1001) From 417f1b515d67d8fcbbb54d1018ac11a0afafe63c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Oct 2022 18:52:24 +0200 Subject: [PATCH 295/759] style --- client/src/pm3line_vocabulory.h | 1 + doc/commands.json | 26 ++++++++++++++++++++++---- doc/commands.md | 1 + 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 22abed93f..1044e2906 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -717,6 +717,7 @@ const static vocabulory_t vocabulory[] = { { 1, "nfc type2 help" }, { 0, "nfc type4a format" }, { 0, "nfc type4a read" }, + { 0, "nfc type4a write" }, { 0, "nfc type4a st25taread" }, { 1, "nfc type4a help" }, { 0, "nfc type4b read" }, diff --git a/doc/commands.json b/doc/commands.json index 94d01e31b..118f6332b 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -1120,7 +1120,7 @@ }, "hf 14a help": { "command": "hf 14a help", - "description": "help This help list List ISO 14443-a history", + "description": "----------- ----------------------- General ----------------------- help This help list List ISO 14443-a history", "notes": [], "offline": true, "options": [], @@ -1196,7 +1196,7 @@ "notes": [ "hf 14a ndefwrite -d 0300FE -> write empty record to tag", "hf 14a ndefwrite -f myfilename", - "hf 14a ndefwrite -d 033fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031" + "hf 14a ndefwrite -d 003fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031" ], "offline": false, "options": [ @@ -10759,6 +10759,24 @@ ], "usage": "hf st25ta ndefread [-hv] [-p ] [-f ]" }, + "nfc type4a write": { + "command": "nfc type4a write", + "description": "Write raw NDEF hex bytes to tag. This commands assumes tag already been NFC/NDEF formatted.", + "notes": [ + "hf 14a ndefwrite -d 0300FE -> write empty record to tag", + "hf 14a ndefwrite -f myfilename", + "hf 14a ndefwrite -d 003fd1023a53709101195405656e2d55534963656d616e2054776974746572206c696e6b5101195502747769747465722e636f6d2f686572726d616e6e31303031" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-d raw NDEF hex bytes", + "-f, --file write raw NDEF file to tag", + "-p fix NDEF record headers / terminator block if missing", + "-v, --verbose verbose output" + ], + "usage": "hf 14a ndefwrite [-hpv] [-d ] [-f ]" + }, "nfc type4b help": { "command": "nfc type4b help", "description": "-------- --------- NFC Forum Tag Type 4 ISO14443B ------------- -------- --------------------- General --------------------- help This help", @@ -11474,8 +11492,8 @@ } }, "metadata": { - "commands_extracted": 725, + "commands_extracted": 726, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-10-24T16:21:33" + "extracted_on": "2022-10-24T16:51:32" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index a8a864d33..a87a201df 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -1288,6 +1288,7 @@ Check column "offline" for their availability. |------- |------- |----------- |`nfc type4a format `|N |`format ISO-14443-a tag as NFC Tag` |`nfc type4a read `|N |`read NFC Forum Tag Type 4 A` +|`nfc type4a write `|N |`write NFC Forum Tag Type 4 A` |`nfc type4a st25taread `|N |`read ST25TA as NFC Forum Tag Type 4` |`nfc type4a help `|Y |`This help` From a1633f9323a40f47b7a6d55ea64fb7167c6b004e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 24 Oct 2022 19:11:53 +0200 Subject: [PATCH 296/759] length? --- client/src/cmdhf14a.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 2a1c3dfb2..0c70715dd 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -3100,7 +3100,6 @@ int CmdHF14ANdefFormat(const char *Cmd) { return PM3_SUCCESS; } - int CmdHF14ANdefWrite(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 14a ndefwrite", @@ -3180,7 +3179,7 @@ int CmdHF14ANdefWrite(const char *Cmd) { } uint8_t tmp_raw[256]; memcpy(tmp_raw, raw, sizeof(tmp_raw)); - raw[0] = 0x03; + raw[0] = 0x00; raw[1] = bytes; memcpy(raw + 2, tmp_raw, sizeof(raw) - 2); bytes += 2; From 5b90ea8117f1125ae9367ec16a0dfb4a8979c90b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 25 Oct 2022 07:56:57 +0200 Subject: [PATCH 297/759] skeleton code found at https://github.com/ZRD-Saar/proxmark3 --- armsrc/appmain.c | 6 ++++ armsrc/epa.c | 41 +++++++++++++++++++++++++ armsrc/epa.h | 5 ++-- client/src/cmdhfepa.c | 69 +++++++++++++++++++++++++++++++++++++++++-- include/pm3_cmd.h | 1 + 5 files changed, 116 insertions(+), 6 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 96ba18729..73ef066af 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1464,6 +1464,7 @@ static void PacketReceived(PacketCommandNG *packet) { iso14443a_antifuzz(payload->flag); break; } + // EPA related case CMD_HF_EPA_COLLECT_NONCE: { EPA_PACE_Collect_Nonce(packet); break; @@ -1472,6 +1473,11 @@ static void PacketReceived(PacketCommandNG *packet) { EPA_PACE_Replay(packet); break; } + case CMD_HF_EPA_PACE_SIMULATE: { + EPA_PACE_Simulate(packet); + break; + } + case CMD_HF_MIFARE_READER: { struct p { uint8_t first_run; diff --git a/armsrc/epa.c b/armsrc/epa.c index 7206e5fd2..9ec396031 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -592,3 +592,44 @@ int EPA_Setup(void) { Dbprintf("No card found"); return 1; } + +void EPA_PACE_Simulate(PacketCommandNG *c) { + + //---------Initializing--------- + + // Get password from arguments + unsigned char pwd[6]; + memcpy(pwd, c->data.asBytes, 6); + + // Set up communication with the card + int res = EPA_Setup(); + if (res != 0){ + EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 1, res); + return; + } + + // Read EF.CardAccess + uint8_t card_access[210] = {0}; + int card_access_length = EPA_Read_CardAccess(card_access, 210); + + // The response has to be at least this big to hold the OID + if (card_access_length < 18) { + EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 2, card_access_length); + return; + } + + // PACEInfo of the card + pace_version_info_t pace_version_info; + + // Search for the PACE OID + res = EPA_Parse_CardAccess(card_access, card_access_length, &pace_version_info); + + if (res != 0 || pace_version_info.version == 0) { + EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 3, res); + return; + } + + Dbprintf("Standardized Domain Parameter: %i", pace_version_info.parameter_id); + DbpString(""); + DbpString("finished"); +} \ No newline at end of file diff --git a/armsrc/epa.h b/armsrc/epa.h index d3ed7b75e..72524f836 100644 --- a/armsrc/epa.h +++ b/armsrc/epa.h @@ -32,9 +32,7 @@ typedef struct { // general functions void EPA_Finish(void); -size_t EPA_Parse_CardAccess(uint8_t *data, - size_t length, - pace_version_info_t *pace_info); +size_t EPA_Parse_CardAccess(uint8_t *data, size_t length, pace_version_info_t *pace_info); int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length); int EPA_Setup(void); @@ -44,5 +42,6 @@ int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce); void EPA_PACE_Collect_Nonce(PacketCommandNG *c); void EPA_PACE_Replay(PacketCommandNG *c); +void EPA_PACE_Simulate(PacketCommandNG *c); #endif /* __EPA_H */ diff --git a/client/src/cmdhfepa.c b/client/src/cmdhfepa.c index c676cc2f5..c79bc5ae1 100644 --- a/client/src/cmdhfepa.c +++ b/client/src/cmdhfepa.c @@ -103,9 +103,10 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) { // perform the PACE protocol by replaying APDUs static int CmdHFEPAPACEReplay(const char *Cmd) { CLIParserContext *ctx; - CLIParserInit(&ctx, "hf epa preplay", + CLIParserInit(&ctx, "hf epa replay", "Perform PACE protocol by replaying given APDUs", - "hf epa preplay --mse 0022C1A4 --get 1068000000 --map 1086000002 --pka 1234ABCDEF --ma 1A2B3C4D"); + "hf epa replay --mse 0022C1A4 --get 1068000000 --map 1086000002 --pka 1234ABCDEF --ma 1A2B3C4D" + ); void *argtable[] = { arg_param_begin, @@ -207,10 +208,72 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { return PM3_SUCCESS; } +// perform the PACE protocol by replaying APDUs +static int CmdHFEPAPACESimulate(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf epa sim", + "Simulate PACE protocol with given password pwd of type pty.\n" + "The crypto is performed on pc or proxmark", + "hf epa sim --pwd 112233445566\n" + "hf epa sim --pc --pty 1 --pwd 112233445566" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit1(NULL, "pc", "perform crypto on PC"), + arg_str1(NULL, "pty", "", "type of password"), + arg_str1("p", "pwd", "", "password"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + +// bool use_pc = arg_get_lit(ctx, 1); +// uint8_t pwd_type = 0; + + int plen = 0; + uint8_t pwd[6] = {0}; + CLIGetHexWithReturn(ctx, 3, pwd, &plen); + + CLIParserFree(ctx); + + PrintAndLogEx(INFO, "Starting PACE simulation..."); + + + clearCommandBuffer(); + SendCommandMIX(CMD_HF_EPA_PACE_SIMULATE, 0, 0, 0, pwd, plen); + + PacketResponseNG resp; + WaitForResponse(CMD_ACK, &resp); + + uint32_t *data = resp.data.asDwords; + + if (resp.oldarg[0] != 0) { + PrintAndLogEx(INFO, "\nPACE failed in step %u!", (uint32_t)resp.oldarg[0]); + PrintAndLogEx(INFO, "MSE Set AT: %u us", data[0]); + PrintAndLogEx(INFO, "GA Get Nonce: %u us", data[1]); + PrintAndLogEx(INFO, "GA Map Nonce: %u us", data[2]); + PrintAndLogEx(INFO, "GA Perform Key Agreement: %u us", data[3]); + PrintAndLogEx(INFO, "GA Mutual Authenticate: %u us", data[4]); + PrintAndLogEx(INFO, "----------------"); + } else { + PrintAndLogEx(INFO, "PACE successful!"); + PrintAndLogEx(INFO, "MSE Set AT: %u us", data[0]); + PrintAndLogEx(INFO, "GA Get Nonce: %u us", data[1]); + PrintAndLogEx(INFO, "GA Map Nonce: %u us", data[2]); + PrintAndLogEx(INFO, "GA Perform Key Agreement: %u us", data[3]); + PrintAndLogEx(INFO, "GA Mutual Authenticate: %u us", data[4]); + PrintAndLogEx(INFO, "----------------"); + } + + return PM3_SUCCESS; +} + + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"cnonces", CmdHFEPACollectPACENonces, IfPm3Iso14443, "Acquire encrypted PACE nonces of specific size"}, - {"preplay", CmdHFEPAPACEReplay, IfPm3Iso14443, "Perform PACE protocol by replaying given APDUs"}, + {"replay", CmdHFEPAPACEReplay, IfPm3Iso14443, "Perform PACE protocol by replaying given APDUs"}, + {"sim", CmdHFEPAPACESimulate, IfPm3Iso14443, "Simulate PACE protocol"}, {NULL, NULL, NULL, NULL} }; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 7c7eb6ed6..5a49871e1 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -556,6 +556,7 @@ typedef struct { #define CMD_HF_EPA_COLLECT_NONCE 0x038A #define CMD_HF_EPA_REPLAY 0x038B +#define CMD_HF_EPA_PACE_SIMULATE 0x039C #define CMD_HF_LEGIC_INFO 0x03BC #define CMD_HF_LEGIC_ESET 0x03BD From aff29b9d3b051af3388b93fa859b177d3659783a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 26 Oct 2022 06:55:47 +0200 Subject: [PATCH 298/759] silence warning (@natesales) --- common/mbedtls/bignum.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/mbedtls/bignum.c b/common/mbedtls/bignum.c index 7c0daebd3..9b7bcdd1c 100644 --- a/common/mbedtls/bignum.c +++ b/common/mbedtls/bignum.c @@ -33,6 +33,8 @@ * */ +#pragma GCC diagnostic ignored "-Wunused-variable" + #include "common.h" #if defined(MBEDTLS_BIGNUM_C) From ba225905d31e9d78fd3f0487af69d2e471559613 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 26 Oct 2022 06:57:21 +0200 Subject: [PATCH 299/759] changed "mf eload" / "iclass eload" to be able to transfer a file from SPIFFS to EMULATOR memory. Original idea from @natesales --- armsrc/appmain.c | 24 ++++++++++++++++++++++++ armsrc/spiffs.c | 24 ++++++++++++------------ client/src/cmdhficlass.c | 34 +++++++++++++++++++++++++++++++++- client/src/cmdhfmf.c | 36 ++++++++++++++++++++++++++++++++++-- include/pm3_cmd.h | 5 ++--- 5 files changed, 105 insertions(+), 18 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 73ef066af..07c3375f0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2313,6 +2313,30 @@ static void PacketReceived(PacketCommandNG *packet) { LED_B_OFF(); break; } + case CMD_SPIFFS_ELOAD: { + LED_B_ON(); + + uint8_t *em = BigBuf_get_EM_addr(); + if (em == NULL) { + reply_ng(CMD_SPIFFS_ELOAD, PM3_EMALLOC, NULL, 0); + LED_B_OFF(); + break; + } + + char *fn = (char *)packet->data.asBytes; + + uint32_t size = size_in_spiffs(fn); + if (size == 0) { + reply_ng(CMD_SPIFFS_ELOAD, PM3_SUCCESS, NULL, 0); + LED_B_OFF(); + break; + } + + rdv40_spiffs_read_as_filetype(fn, em, size, RDV40_SPIFFS_SAFETY_SAFE); + reply_ng(CMD_SPIFFS_ELOAD, PM3_SUCCESS, NULL, 0); + LED_B_OFF(); + break; + } case CMD_FLASHMEM_SET_SPIBAUDRATE: { if (packet->length != sizeof(uint32_t)) break; diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index cea6946d3..54d1360d6 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -578,18 +578,18 @@ int rdv40_spiffs_make_symlink(char *linkdest, char *filename, RDV40SpiFFSSafetyL int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( RDV40SpiFFSFileType filetype = filetype_in_spiffs((char *)filename); - switch (filetype) { - case RDV40_SPIFFS_FILETYPE_REAL: - rdv40_spiffs_read((char *)filename, (uint8_t *)dst, size, level); - break; - case RDV40_SPIFFS_FILETYPE_SYMLINK: - rdv40_spiffs_read_as_symlink(filename, (uint8_t *)dst, size, level); - break; - case RDV40_SPIFFS_FILETYPE_BOTH: - case RDV40_SPIFFS_FILETYPE_UNKNOWN: - default: - ; - } + switch (filetype) { + case RDV40_SPIFFS_FILETYPE_REAL: + rdv40_spiffs_read((char *)filename, (uint8_t *)dst, size, level); + break; + case RDV40_SPIFFS_FILETYPE_SYMLINK: + rdv40_spiffs_read_as_symlink(filename, (uint8_t *)dst, size, level); + break; + case RDV40_SPIFFS_FILETYPE_BOTH: + case RDV40_SPIFFS_FILETYPE_UNKNOWN: + default: + break; + } ) } diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index b4c9d934b..7d8138e7b 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -990,13 +990,14 @@ static int CmdHFiClassELoad(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf iclass eload", "Load emulator memory with data from (bin/eml/json) iCLASS dump file", - "hf iclass eload -f hf-iclass-AA162D30F8FF12F1-dump.bin\n" "hf iclass eload -f hf-iclass-AA162D30F8FF12F1-dump.eml\n" + "hf iclass eload -f hf-iclass-AA162D30F8FF12F1-dump.bin -m\n" ); void *argtable[] = { arg_param_begin, arg_str1("f", "file", "", "filename of dump (bin/eml/json)"), + arg_lit0("m", "mem", "use RDV4 spiffs"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -1011,8 +1012,39 @@ static int CmdHFiClassELoad(const char *Cmd) { return PM3_EINVARG; } + bool use_spiffs = arg_get_lit(ctx, 2); CLIParserFree(ctx); + // use RDV4 spiffs + if (use_spiffs && IfPm3Flash() == false) { + PrintAndLogEx(WARNING, "Device not compiled to support spiffs"); + return PM3_EINVARG; + } + + if (use_spiffs) { + + if (fnlen > 32) { + PrintAndLogEx(WARNING, "filename too long for spiffs, expected 32, got %u", fnlen); + return PM3_EINVARG; + } + + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_ELOAD, (uint8_t *)filename, fnlen); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_SPIFFS_ELOAD, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + + if (resp.status != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Loading file from spiffs to emulatore memory failed"); + return PM3_EFLASH; + } + + PrintAndLogEx(SUCCESS, "File transfered from spiffs to device emulator memory"); + return PM3_SUCCESS; + } + // read dump file uint8_t *dump = NULL; size_t bytes_read = 2048; diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 4fdeedbe0..e0bd6cc69 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -3890,6 +3890,7 @@ int CmdHF14AMfELoad(const char *Cmd) { arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), arg_lit0(NULL, "ul", "MIFARE Ultralight family"), + arg_lit0("m", "mem", "use RDV4 spiffs"), arg_int0("q", "qty", "", "manually set number of blocks (overrides)"), arg_param_end }; @@ -3905,7 +3906,8 @@ int CmdHF14AMfELoad(const char *Cmd) { bool m4 = arg_get_lit(ctx, 5); bool mu = arg_get_lit(ctx, 6); - int numblks = arg_get_int_def(ctx, 7, -1); + bool use_spiffs = arg_get_lit(ctx, 7); + int numblks = arg_get_int_def(ctx, 8, -1); CLIParserFree(ctx); @@ -3945,6 +3947,36 @@ int CmdHF14AMfELoad(const char *Cmd) { PrintAndLogEx(INFO, "overriding number of blocks, will use %d blocks ( %u bytes )", block_cnt, block_cnt * block_width); } + // use RDV4 spiffs + if (use_spiffs && IfPm3Flash() == false) { + PrintAndLogEx(WARNING, "Device not compiled to support spiffs"); + return PM3_EINVARG; + } + + if (use_spiffs) { + + if (fnlen > 32) { + PrintAndLogEx(WARNING, "filename too long for spiffs, expected 32, got %u", fnlen); + return PM3_EINVARG; + } + + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_ELOAD, (uint8_t *)filename, fnlen); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_SPIFFS_ELOAD, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + + if (resp.status != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Loading file from spiffs to emulatore memory failed"); + return PM3_EFLASH; + } + + PrintAndLogEx(SUCCESS, "File transfered from spiffs to device emulator memory"); + return PM3_SUCCESS; + } + uint8_t *data = NULL; size_t bytes_read = 0; int res = pm3_load_dump(filename, (void **)&data, &bytes_read, (block_width * block_cnt + hdr_len)); @@ -4204,7 +4236,7 @@ static int CmdHF14AMfECFill(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf ecfill", "Dump card and transfer the data to emulator memory.\n" - "Keys must be laid in the emulator memory", + "Keys must be in the emulator memory", "hf mf ecfill --> use key type A\n" "hf mf ecfill --4k -b --> target 4K card with key type B" ); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 5a49871e1..412ca2ba6 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -416,16 +416,15 @@ typedef struct { #define CMD_SPIFFS_WIPE 0x013A // This take a +0x2000 as they are high level helper and special functions -// As the others, they may have safety level argument if it makkes sense +// As the others, they may have safety level argument if it makes sense #define CMD_SPIFFS_PRINT_TREE 0x2130 #define CMD_SPIFFS_GET_TREE 0x2131 #define CMD_SPIFFS_TEST 0x2132 #define CMD_SPIFFS_PRINT_FSINFO 0x2133 #define CMD_SPIFFS_DOWNLOAD 0x2134 #define CMD_SPIFFS_DOWNLOADED 0x2135 +#define CMD_SPIFFS_ELOAD 0x2136 #define CMD_SPIFFS_CHECK 0x3000 -// more ? - // RDV40, Smart card operations #define CMD_SMART_RAW 0x0140 From 7c44f36c0c4eafc640d621ee90ff94bf0755ccac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 26 Oct 2022 22:32:04 +0200 Subject: [PATCH 300/759] added new test shell script to setup / install / build and test the proxmark source code for docker env archlinux --- docker/archlinux/README.md | 14 +++++++++ docker/archlinux/run_tests.sh | 59 +++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100755 docker/archlinux/run_tests.sh diff --git a/docker/archlinux/README.md b/docker/archlinux/README.md index 72756a91e..6e80a4abe 100644 --- a/docker/archlinux/README.md +++ b/docker/archlinux/README.md @@ -1,3 +1,17 @@ +# Notes on run_tests.sh script +This script does both setup the mirrors and pip install and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish. + +The script is to be run in proxmark root folder inside the docker env. + +``` +cd proxmark; +docker/archlinux/run_tests.sh; +``` + # Notes to install latest gcc and arm-none-eabi-gcc ``` diff --git a/docker/archlinux/run_tests.sh b/docker/archlinux/run_tests.sh new file mode 100755 index 000000000..8d4a56776 --- /dev/null +++ b/docker/archlinux/run_tests.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# Iceman 2022 +# +# This script is to be run from proxmark root folder inside the docker env +# cd proxmark; +# docker/archlinux/run_tests.sh; +# +# Script contains two phases. +# +# -- Init / setup phase +# Script to be run inside docker env. First install some dependencies for docker image. +# +# -- Build phase begins +# make builds +# cmake client builds +# of the different possible PLATFORM (PM3RDV4 / PM3GENERIC) and BTADDON combos + +cat << EOF |sudo tee -a /etc/pacman.conf + +[testing] +Include = /etc/pacman.d/mirrorlist + +[community-testing] +Include = /etc/pacman.d/mirrorlist + +[staging] +Include = /etc/pacman.d/mirrorlist +EOF + +sudo pacman -Syu + +# search available versions +pacman -Ss '^arm-none-eabi-gcc$' +pacman -Ss '^gcc$' + +# depending on where the latest bleeding edge is: +# sudo pacman -S community-testing/arm-none-eabi-gcc +# sudo pacman -S arm-none-eabi-gcc +# sudo pacman -S staging/gcc +# sudo pacman -S testing/gcc +# sudo pacman -S gcc + +sudo pacman --noconfirm -S python-pip +python3 -m pip install ansicolors sslcrypto + +# replace egrep to silence warning +sed -i 's/egrep/grep -E/g' tools/pm3_tests.sh + +# Makefile build tests +make clean; make -j PLATFORM=PM3GENERIC; tools/pm3_tests.sh --long || exit 1 +make clean; make -j PLATFORM=PM3RDV4; tools/pm3_tests.sh --long || exit 1 +make clean; make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON; tools/pm3_tests.sh --long || exit 1 + +# cmake client build test +( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 +( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3GENERIC ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 +( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3RDV4 ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 +( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client || exit 1 + From af8e84d71194810f8093da603d755c9f305f31fc Mon Sep 17 00:00:00 2001 From: Noah Clements Date: Thu, 27 Oct 2022 16:56:51 -0300 Subject: [PATCH 301/759] Fixed "Residency Permit" Output Bug discovered while scanning Swedish Residency Permit, resulted in document type of "German Residency Permit". Fixed for better accuracy. Signed-off-by: Noah Clements --- client/src/cmdhfemrtd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index f68f01655..d22df2459 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -1345,7 +1345,7 @@ static int emrtd_print_ef_dg1_info(uint8_t *data, size_t datalen) { } else if (mrz[0] == 'P') { PrintAndLogEx(SUCCESS, "Document Type.........: " _YELLOW_("Passport")); } else if (mrz[0] == 'A') { - PrintAndLogEx(SUCCESS, "Document Type.........: " _YELLOW_("German Residency Permit")); + PrintAndLogEx(SUCCESS, "Document Type.........: " _YELLOW_("Residency Permit")); } else { PrintAndLogEx(SUCCESS, "Document Type.........: " _YELLOW_("Unknown")); } From 038407a6abdd4db0b9017f33945cfcc7231a5979 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 28 Oct 2022 21:59:17 +0200 Subject: [PATCH 302/759] add pip when building the docker image instead --- docker/archlinux/Dockerfile | 3 +++ docker/archlinux/docker_run.sh | 2 +- docker/kali/run_tests.sh | 37 ++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100755 docker/kali/run_tests.sh diff --git a/docker/archlinux/Dockerfile b/docker/archlinux/Dockerfile index f822b33cc..709b7b5d4 100644 --- a/docker/archlinux/Dockerfile +++ b/docker/archlinux/Dockerfile @@ -7,6 +7,9 @@ RUN pacman-db-upgrade # bluez skipped, can't be installed in docker RUN pacman -S --noconfirm sudo git base-devel cmake libusb readline bzip2 arm-none-eabi-gcc arm-none-eabi-newlib python --needed +RUN pacman -S --noconfirm python-pip +RUN python3 -m pip install ansicolors sslcrypto + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/archlinux/docker_run.sh b/docker/archlinux/docker_run.sh index eac7e1378..f379c5307 100755 --- a/docker/archlinux/docker_run.sh +++ b/docker/archlinux/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-arch:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-arch:1.0 diff --git a/docker/kali/run_tests.sh b/docker/kali/run_tests.sh new file mode 100755 index 000000000..ccb111082 --- /dev/null +++ b/docker/kali/run_tests.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +# Iceman 2022 +# +# This script is to be run from proxmark root folder inside the docker env +# cd proxmark; +# docker/archlinux/run_tests.sh; +# +# Script contains two phases. +# +# -- Init / setup phase +# Script to be run inside docker env. First install some dependencies for docker image. +# +# -- Build phase begins +# make builds +# cmake client builds +# of the different possible PLATFORM (PM3RDV4 / PM3GENERIC) and BTADDON combos + +sudo apt update +sudo apt install -y python3-minimal +sudo apt install -y python3-pip +python3 -m pip install ansicolors sslcrypto + +# replace egrep to silence warning +#sed -i 's/egrep/grep -E/g' tools/pm3_tests.sh + +# Makefile build tests +make clean; make -j PLATFORM=PM3GENERIC; tools/pm3_tests.sh --long || exit 1 +make clean; make -j PLATFORM=PM3RDV4; tools/pm3_tests.sh --long || exit 1 +make clean; make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON; tools/pm3_tests.sh --long || exit 1 +# sudo make install; pushd /tmp; proxmark3 -c 'data load -f lf_EM4x05.pm3;lf search -1'; popd; sudo make uninstall + +# cmake client build test +#( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 +( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3GENERIC ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 +( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3RDV4 ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 +( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client || exit 1 + From 06d653e330f21ac9de908f4d2b52a712b20ee2c1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 28 Oct 2022 22:00:03 +0200 Subject: [PATCH 303/759] skip install testing --- docker/archlinux/run_tests.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docker/archlinux/run_tests.sh b/docker/archlinux/run_tests.sh index 8d4a56776..9c2b4daeb 100755 --- a/docker/archlinux/run_tests.sh +++ b/docker/archlinux/run_tests.sh @@ -40,9 +40,6 @@ pacman -Ss '^gcc$' # sudo pacman -S testing/gcc # sudo pacman -S gcc -sudo pacman --noconfirm -S python-pip -python3 -m pip install ansicolors sslcrypto - # replace egrep to silence warning sed -i 's/egrep/grep -E/g' tools/pm3_tests.sh @@ -50,9 +47,10 @@ sed -i 's/egrep/grep -E/g' tools/pm3_tests.sh make clean; make -j PLATFORM=PM3GENERIC; tools/pm3_tests.sh --long || exit 1 make clean; make -j PLATFORM=PM3RDV4; tools/pm3_tests.sh --long || exit 1 make clean; make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON; tools/pm3_tests.sh --long || exit 1 +# sudo make install; pushd /tmp; proxmark3 -c 'data load -f lf_EM4x05.pm3;lf search -1'; popd; sudo make uninstall # cmake client build test -( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 +#( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 ( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3GENERIC ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 ( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3RDV4 ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 ( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client || exit 1 From 3f0b77fa933f2f43b05d8ec9258153a9a4e0e0b5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 28 Oct 2022 22:17:01 +0200 Subject: [PATCH 304/759] add pip , cd directory when building and adding large release test script --- docker/kali/Dockerfile | 4 ++++ docker/kali/README.md | 18 +++++++++++++++--- docker/kali/docker_run.sh | 2 +- docker/kali/run_tests.sh | 7 ++----- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/docker/kali/Dockerfile b/docker/kali/Dockerfile index 72916c7b5..63dc3c841 100644 --- a/docker/kali/Dockerfile +++ b/docker/kali/Dockerfile @@ -8,6 +8,10 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean +RUN apt install -y python3-minimal +RUN apt install -y python3-pip +RUN python3 -m pip install ansicolors sslcrypto + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/kali/README.md b/docker/kali/README.md index f586fe064..e76d73ae2 100644 --- a/docker/kali/README.md +++ b/docker/kali/README.md @@ -1,9 +1,21 @@ +# Notes on run_tests.sh script +This script does both setup the mirrors and pip install and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish. + + # Notes to run tests +The script is to be run in proxmark root folder inside the docker env. +``` +docker/kali/run_tests.sh; +``` + +Or if you want to run single test, ``` sudo apt update -sudo apt install -y python3-minimal -sudo apt install -y python3-pip -python3 -m pip install ansicolors sslcrypto +make clean; make -j tools/pm3_tests.sh --long ``` diff --git a/docker/kali/docker_run.sh b/docker/kali/docker_run.sh index 5d9dcf13d..7124fe5b5 100755 --- a/docker/kali/docker_run.sh +++ b/docker/kali/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-kali:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-kali:1.0 diff --git a/docker/kali/run_tests.sh b/docker/kali/run_tests.sh index ccb111082..27b1c608f 100755 --- a/docker/kali/run_tests.sh +++ b/docker/kali/run_tests.sh @@ -15,13 +15,10 @@ # cmake client builds # of the different possible PLATFORM (PM3RDV4 / PM3GENERIC) and BTADDON combos -sudo apt update -sudo apt install -y python3-minimal -sudo apt install -y python3-pip -python3 -m pip install ansicolors sslcrypto +sudo apt update && sudo apt upgrade -y # replace egrep to silence warning -#sed -i 's/egrep/grep -E/g' tools/pm3_tests.sh +sed -i 's/egrep/grep -E/g' tools/pm3_tests.sh # Makefile build tests make clean; make -j PLATFORM=PM3GENERIC; tools/pm3_tests.sh --long || exit 1 From a557b53ae7899d67b8aa24b2af51c96288a85147 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 28 Oct 2022 22:17:22 +0200 Subject: [PATCH 305/759] text --- docker/archlinux/README.md | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/docker/archlinux/README.md b/docker/archlinux/README.md index 6e80a4abe..35fdf0c78 100644 --- a/docker/archlinux/README.md +++ b/docker/archlinux/README.md @@ -1,17 +1,3 @@ -# Notes on run_tests.sh script -This script does both setup the mirrors and pip install and then run a -bunch of different builds with make and cmake together with the different combos -of RDV4, GENERIC, BTADDON combos. - -If all tests OK, the script will finish. - -The script is to be run in proxmark root folder inside the docker env. - -``` -cd proxmark; -docker/archlinux/run_tests.sh; -``` - # Notes to install latest gcc and arm-none-eabi-gcc ``` @@ -41,12 +27,25 @@ sudo pacman -S testing/gcc sudo pacman -S gcc ``` -# Notes to run tests +# Notes on run_tests.sh script +This script does both setup the mirrors and pip install and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. -Add first the mirrors, see above +If all tests OK, the script will finish. + + +# Notes to run tests +Add first the mirrors, see above, if needed. + +The release test build script is to be run in proxmark root folder inside the docker env. +``` +docker/archlinux/run_tests.sh; +``` + +Or if you want to run single test, ``` -sudo pacman -S python-pip -python3 -m pip install ansicolors sslcrypto +make clean; make -j tools/pm3_tests.sh --long ``` From cf5b500a6ba92ac553119183db8a7accdfe0deba Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 28 Oct 2022 23:38:22 +0200 Subject: [PATCH 306/759] adapt debian docker --- docker/debian-bullseye/Dockerfile | 4 ++++ docker/debian-bullseye/README.md | 19 ++++++++++++++++--- docker/debian-bullseye/docker_run.sh | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docker/debian-bullseye/Dockerfile b/docker/debian-bullseye/Dockerfile index a23d32728..d443aee8c 100644 --- a/docker/debian-bullseye/Dockerfile +++ b/docker/debian-bullseye/Dockerfile @@ -8,6 +8,10 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean +RUN apt-get install -y python3-minimal && \ + apt-get install -y python3-pip && \ + python3 -m pip install ansicolors sslcrypto + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/debian-bullseye/README.md b/docker/debian-bullseye/README.md index c6fce658c..1170c19fe 100644 --- a/docker/debian-bullseye/README.md +++ b/docker/debian-bullseye/README.md @@ -1,9 +1,22 @@ +# Notes on run_tests.sh script +This script does both setup the mirrors and pip install and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish. + + # Notes to run tests +The script is to be run in proxmark root folder inside the docker env. + +``` +docker/debian-bullseye/run_tests.sh; +``` + +Or if you want to run single test, ``` sudo apt update -sudo apt install python3-minimal -sudo apt install python3-pip -python3 -m pip install ansicolors sslcrypto +make clean; make -j tools/pm3_tests.sh --long ``` diff --git a/docker/debian-bullseye/docker_run.sh b/docker/debian-bullseye/docker_run.sh index abe9dce77..1216f54cd 100755 --- a/docker/debian-bullseye/docker_run.sh +++ b/docker/debian-bullseye/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-debian-bullseye:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-debian-bullseye:1.0 From 7c7f1e94faa4ab15f29400c727b1f5f7d2bf915f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 28 Oct 2022 23:50:41 +0200 Subject: [PATCH 307/759] adapt parrot docker --- docker/parrot-core-latest/Dockerfile | 4 ++++ docker/parrot-core-latest/README.md | 19 ++++++++++++++++--- docker/parrot-core-latest/docker_run.sh | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docker/parrot-core-latest/Dockerfile b/docker/parrot-core-latest/Dockerfile index aef00ff54..2739b9821 100644 --- a/docker/parrot-core-latest/Dockerfile +++ b/docker/parrot-core-latest/Dockerfile @@ -8,6 +8,10 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean +RUN apt install -y python3-minimal && \ + apt install -y python3-pip && \ + python3 -m pip install ansicolors sslcrypto + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/parrot-core-latest/README.md b/docker/parrot-core-latest/README.md index f586fe064..45ad548df 100644 --- a/docker/parrot-core-latest/README.md +++ b/docker/parrot-core-latest/README.md @@ -1,9 +1,22 @@ +# Notes on run_tests.sh script +This script does both setup the mirrors and pip install and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish. + + # Notes to run tests +The script is to be run in proxmark root folder inside the docker env. + +``` +docker/parrot-core-latest/run_tests.sh; +``` + +Or if you want to run single test, ``` sudo apt update -sudo apt install -y python3-minimal -sudo apt install -y python3-pip -python3 -m pip install ansicolors sslcrypto +make clean; make -j tools/pm3_tests.sh --long ``` diff --git a/docker/parrot-core-latest/docker_run.sh b/docker/parrot-core-latest/docker_run.sh index 4f33acfe9..509df4461 100755 --- a/docker/parrot-core-latest/docker_run.sh +++ b/docker/parrot-core-latest/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-parrotsec-core-latest:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-parrotsec-core-latest:1.0 From 5245c6801debafb36f717458c32560f51919c1d0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 00:04:53 +0200 Subject: [PATCH 308/759] adapt ubuntu 18 docker --- docker/ubuntu-18.04/Dockerfile | 5 +++++ docker/ubuntu-18.04/README.md | 19 ++++++++++++++++--- docker/ubuntu-18.04/docker_run.sh | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/docker/ubuntu-18.04/Dockerfile b/docker/ubuntu-18.04/Dockerfile index 107a851a7..11c5afcd8 100644 --- a/docker/ubuntu-18.04/Dockerfile +++ b/docker/ubuntu-18.04/Dockerfile @@ -5,10 +5,15 @@ ENV DEBIAN_FRONTEND noninteractive # qtbase5-dev skipped # python3 skipped, not yet searchable with pkg-config python3 RUN apt-get update && \ + apt-get upgrade -y && \ apt-get dist-upgrade -y && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libssl-dev sudo && \ apt-get clean +RUN apt install -y python3-minimal && \ + apt install -y python3-pip && \ + python3 -m pip install ansicolors sslcrypto + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/ubuntu-18.04/README.md b/docker/ubuntu-18.04/README.md index f586fe064..0b7d2f748 100644 --- a/docker/ubuntu-18.04/README.md +++ b/docker/ubuntu-18.04/README.md @@ -1,9 +1,22 @@ +# Notes on run_tests.sh script +This script does both setup the mirrors and pip install and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish. + + # Notes to run tests +The script is to be run in proxmark root folder inside the docker env. + +``` +docker/ubuntu-18.04/run_tests.sh; +``` + +Or if you want to run single test, ``` sudo apt update -sudo apt install -y python3-minimal -sudo apt install -y python3-pip -python3 -m pip install ansicolors sslcrypto +make clean; make -j tools/pm3_tests.sh --long ``` diff --git a/docker/ubuntu-18.04/docker_run.sh b/docker/ubuntu-18.04/docker_run.sh index 6827b69ac..01d133712 100755 --- a/docker/ubuntu-18.04/docker_run.sh +++ b/docker/ubuntu-18.04/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-ubuntu-18.04:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-ubuntu-18.04:1.0 From 04ed4eb1d63a19fbf80235239d0f9e3bb38a922c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 00:14:31 +0200 Subject: [PATCH 309/759] adapted docker ubuntu-20 --- docker/ubuntu-20.04/Dockerfile | 5 +++++ docker/ubuntu-20.04/README.md | 19 ++++++++++++++++--- docker/ubuntu-20.04/docker_run.sh | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/docker/ubuntu-20.04/Dockerfile b/docker/ubuntu-20.04/Dockerfile index 5c3fab542..d9138aa0d 100644 --- a/docker/ubuntu-20.04/Dockerfile +++ b/docker/ubuntu-20.04/Dockerfile @@ -4,10 +4,15 @@ ENV LANG C ENV DEBIAN_FRONTEND noninteractive # qtbase5-dev skipped RUN apt-get update && \ + apt-get upgrade -y && \ apt-get dist-upgrade -y && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean +RUN apt install -y python3-minimal && \ + apt install -y python3-pip && \ + python3 -m pip install ansicolors sslcrypto + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/ubuntu-20.04/README.md b/docker/ubuntu-20.04/README.md index f586fe064..d8c7b3f53 100644 --- a/docker/ubuntu-20.04/README.md +++ b/docker/ubuntu-20.04/README.md @@ -1,9 +1,22 @@ +# Notes on run_tests.sh script +This script does both setup the mirrors and pip install and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish. + + # Notes to run tests +The script is to be run in proxmark root folder inside the docker env. + +``` +docker/ubuntu-20.04/run_tests.sh; +``` + +Or if you want to run single test, ``` sudo apt update -sudo apt install -y python3-minimal -sudo apt install -y python3-pip -python3 -m pip install ansicolors sslcrypto +make clean; make -j tools/pm3_tests.sh --long ``` diff --git a/docker/ubuntu-20.04/docker_run.sh b/docker/ubuntu-20.04/docker_run.sh index bb68ba6f8..dd05c9f79 100755 --- a/docker/ubuntu-20.04/docker_run.sh +++ b/docker/ubuntu-20.04/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-ubuntu-20.04:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-ubuntu-20.04:1.0 From c3f35bdde0b11440a85110410b6860bf7a087ca9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 00:21:06 +0200 Subject: [PATCH 310/759] adapt docker ubuntu-21, still no release since its EOL --- docker/ubuntu-21.04/Dockerfile | 5 +++++ docker/ubuntu-21.04/README.md | 18 +++++++++++++++--- docker/ubuntu-21.04/docker_run.sh | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/docker/ubuntu-21.04/Dockerfile b/docker/ubuntu-21.04/Dockerfile index 102f0c556..4350e8aa3 100644 --- a/docker/ubuntu-21.04/Dockerfile +++ b/docker/ubuntu-21.04/Dockerfile @@ -4,10 +4,15 @@ ENV LANG C ENV DEBIAN_FRONTEND noninteractive # qtbase5-dev skipped RUN apt-get update && \ + apt-get upgrade -y && \ apt-get dist-upgrade -y && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean +RUN apt install -y python3-minimal && \ + apt install -y python3-pip && \ + python3 -m pip install ansicolors sslcrypto + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/ubuntu-21.04/README.md b/docker/ubuntu-21.04/README.md index f586fe064..bb90abab8 100644 --- a/docker/ubuntu-21.04/README.md +++ b/docker/ubuntu-21.04/README.md @@ -1,9 +1,21 @@ +# Notes on run_tests.sh script +This script does both setup the mirrors and pip install and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish. + + # Notes to run tests +The script is to be run in proxmark root folder inside the docker env. +``` +docker/ubuntu-21.04/run_tests.sh; +``` + +Or if you want to run single test, ``` sudo apt update -sudo apt install -y python3-minimal -sudo apt install -y python3-pip -python3 -m pip install ansicolors sslcrypto +make clean; make -j tools/pm3_tests.sh --long ``` diff --git a/docker/ubuntu-21.04/docker_run.sh b/docker/ubuntu-21.04/docker_run.sh index ddd958144..d8fd6722f 100755 --- a/docker/ubuntu-21.04/docker_run.sh +++ b/docker/ubuntu-21.04/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-ubuntu-21.04:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-ubuntu-21.04:1.0 From 587167da839d3b23d968388593471fbdf6df5928 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 00:30:08 +0200 Subject: [PATCH 311/759] adapt docker opensuse-lead --- docker/opensuse-leap/Dockerfile | 3 +++ docker/opensuse-leap/README.md | 5 +---- docker/opensuse-leap/docker_run.sh | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docker/opensuse-leap/Dockerfile b/docker/opensuse-leap/Dockerfile index 97eff3030..c8a5c7cf1 100644 --- a/docker/opensuse-leap/Dockerfile +++ b/docker/opensuse-leap/Dockerfile @@ -4,6 +4,9 @@ ENV LANG C # libqt5-qtbase-devel skipped RUN zypper --non-interactive install --no-recommends shadow sudo git patterns-devel-base-devel_basis gcc-c++ readline-devel libbz2-devel bluez-devel python3-devel libopenssl-devel +RUN zypper --non-interactive install cmake python3 python3-pip +RUN python3 -m pip install ansicolors sslcrypto + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/opensuse-leap/README.md b/docker/opensuse-leap/README.md index 87ca26f4d..5ffab9127 100644 --- a/docker/opensuse-leap/README.md +++ b/docker/opensuse-leap/README.md @@ -3,9 +3,6 @@ No ARM compiler available ? ``` -sudo zypper --non-interactive install cmake -sudo zypper --non-interactive install python3 -sudo zypper --non-interactive install python3-pip -python3 -m pip install ansicolors sslcrypto +make clean; make -j tools/pm3_tests.sh --long mfkey nonce2key mf_nonce_brute fpga_compress common client ``` diff --git a/docker/opensuse-leap/docker_run.sh b/docker/opensuse-leap/docker_run.sh index 66e7b7ce2..f3c830626 100755 --- a/docker/opensuse-leap/docker_run.sh +++ b/docker/opensuse-leap/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-suse-leap:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-suse-leap:1.0 From ecc425683bb7f1f1ab6cad0c7d8a5e1be93adfdc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 00:38:48 +0200 Subject: [PATCH 312/759] adapt docker opensuse-tumbleweed --- docker/opensuse-tumbleweed/Dockerfile | 3 +++ docker/opensuse-tumbleweed/README.md | 5 +---- docker/opensuse-tumbleweed/docker_run.sh | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docker/opensuse-tumbleweed/Dockerfile b/docker/opensuse-tumbleweed/Dockerfile index 007f98455..5d4adbb8b 100644 --- a/docker/opensuse-tumbleweed/Dockerfile +++ b/docker/opensuse-tumbleweed/Dockerfile @@ -4,6 +4,9 @@ ENV LANG C # libqt5-qtbase-devel skipped RUN zypper --non-interactive install --no-recommends shadow sudo git patterns-devel-base-devel_basis gcc-c++ readline-devel libbz2-devel bluez-devel python3-devel libopenssl-devel cross-arm-none-gcc11 cross-arm-none-newlib-devel +RUN zypper --non-interactive install cmake python3 python3-pip +RUN python3 -m pip install ansicolors sslcrypto + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/opensuse-tumbleweed/README.md b/docker/opensuse-tumbleweed/README.md index b1456b1bb..00af06436 100644 --- a/docker/opensuse-tumbleweed/README.md +++ b/docker/opensuse-tumbleweed/README.md @@ -1,9 +1,6 @@ # Notes to run tests ``` -sudo zypper --non-interactive install cmake -sudo zypper --non-interactive install python3 -sudo zypper --non-interactive install python3-pip -python3 -m pip install ansicolors sslcrypto +make clean; make -j tools/pm3_tests.sh --long ``` diff --git a/docker/opensuse-tumbleweed/docker_run.sh b/docker/opensuse-tumbleweed/docker_run.sh index 047afd9b7..79ef74d5c 100755 --- a/docker/opensuse-tumbleweed/docker_run.sh +++ b/docker/opensuse-tumbleweed/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-suse-tumbleweed:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-suse-tumbleweed:1.0 From 489f91b38818b0933f31023621aae871912d1a4f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 00:39:35 +0200 Subject: [PATCH 313/759] better to upgrade too --- docker/kali/Dockerfile | 1 + docker/parrot-core-latest/Dockerfile | 1 + 2 files changed, 2 insertions(+) diff --git a/docker/kali/Dockerfile b/docker/kali/Dockerfile index 63dc3c841..e8a506dc5 100644 --- a/docker/kali/Dockerfile +++ b/docker/kali/Dockerfile @@ -4,6 +4,7 @@ ENV LANG C ENV DEBIAN_FRONTEND noninteractive # qtbase5-dev skipped RUN apt-get update && \ + apt-get upgrade -y && \ apt-get dist-upgrade -y && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean diff --git a/docker/parrot-core-latest/Dockerfile b/docker/parrot-core-latest/Dockerfile index 2739b9821..8ca8f9856 100644 --- a/docker/parrot-core-latest/Dockerfile +++ b/docker/parrot-core-latest/Dockerfile @@ -4,6 +4,7 @@ ENV LANG C ENV DEBIAN_FRONTEND noninteractive # qtbase5-dev skipped RUN apt-get update && \ + apt-get upgrade -y && \ apt-get dist-upgrade -y && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean From 01c469115b7404b062bb8ff42adb6a0bd111f7ef Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 00:40:03 +0200 Subject: [PATCH 314/759] better to upgrade too --- docker/debian-bullseye/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/debian-bullseye/Dockerfile b/docker/debian-bullseye/Dockerfile index d443aee8c..53114b795 100644 --- a/docker/debian-bullseye/Dockerfile +++ b/docker/debian-bullseye/Dockerfile @@ -4,6 +4,7 @@ ENV LANG C ENV DEBIAN_FRONTEND noninteractive # qtbase5-dev skipped RUN apt-get update && \ + apt-get upgrade -y && \ apt-get dist-upgrade -y && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean From 99659db10a940881b1cc49b45bee40f2f8ba31d8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 01:01:06 +0200 Subject: [PATCH 315/759] text --- docker/fedora-34/Dockerfile | 6 +++++- docker/fedora-34/README.md | 20 +++++++++++++++++--- docker/fedora-34/docker_run.sh | 2 +- docker/opensuse-leap/README.md | 20 ++++++++++++++++++-- docker/opensuse-tumbleweed/README.md | 20 +++++++++++++++++++- 5 files changed, 60 insertions(+), 8 deletions(-) diff --git a/docker/fedora-34/Dockerfile b/docker/fedora-34/Dockerfile index 444b5b195..90765a515 100644 --- a/docker/fedora-34/Dockerfile +++ b/docker/fedora-34/Dockerfile @@ -2,7 +2,11 @@ FROM fedora:34 ENV LANG C # qt5-qtbase-devel skipped -RUN dnf install -y passwd sudo git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel bzip2-devel bluez-libs-devel python3-devel openssl-devel libatomic +RUN dnf install -y passwd sudo git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel bzip2-devel bluez-libs-devel python3-devel openssl-devel libatomic findutils + +RUN yum -y update +RUN yum -y install cmake python-pip +RUN python3 -m pip install ansicolors sslcrypto # Create rrg user RUN useradd -ms /bin/bash rrg diff --git a/docker/fedora-34/README.md b/docker/fedora-34/README.md index 5fccbba41..7930f99d0 100644 --- a/docker/fedora-34/README.md +++ b/docker/fedora-34/README.md @@ -1,12 +1,26 @@ +# Notes on run_tests.sh script +This script does both strip the "recover_pk test" in pm3_tests.sh and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish. + + # Notes to run tests +The script is to be run in proxmark root folder inside the docker env. + +``` +docker/fedora-34/run_tests.sh; +``` + +Or if you want to run single test, ``` sudo yum -y update -sudo yum -y install cmake python-pip -python3 -m pip install ansicolors sslcrypto +make clean; make -j tools/pm3_tests.sh --long ``` Warning, `recover_pk selftests` will fail on Fedora because they stripped down the available ECC curves in their OpenSSL. -So just comment the "recover_pk test" +So just comment the "recover_pk test" \ No newline at end of file diff --git a/docker/fedora-34/docker_run.sh b/docker/fedora-34/docker_run.sh index 6fbb2e6a9..4be59d2c5 100755 --- a/docker/fedora-34/docker_run.sh +++ b/docker/fedora-34/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-fedora-34:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-fedora-34:1.0 diff --git a/docker/opensuse-leap/README.md b/docker/opensuse-leap/README.md index 5ffab9127..47a3b5c32 100644 --- a/docker/opensuse-leap/README.md +++ b/docker/opensuse-leap/README.md @@ -1,8 +1,24 @@ -# Notes to run tests +# Notes on run_tests.sh script +This script does both setup and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. -No ARM compiler available ? +If all tests OK, the script will finish. + + +# Notes to run tests +The script is to be run in proxmark root folder inside the docker env. + +``` +docker/opensuse-leap/run_tests.sh; +``` + +Or if you want to run single test, ``` make clean; make -j tools/pm3_tests.sh --long mfkey nonce2key mf_nonce_brute fpga_compress common client ``` + + +No ARM compiler available ? diff --git a/docker/opensuse-tumbleweed/README.md b/docker/opensuse-tumbleweed/README.md index 00af06436..126042512 100644 --- a/docker/opensuse-tumbleweed/README.md +++ b/docker/opensuse-tumbleweed/README.md @@ -1,6 +1,24 @@ +# Notes on run_tests.sh script +This script does both setup and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish. + + # Notes to run tests +The script is to be run in proxmark root folder inside the docker env. + +``` +docker/opensuse-tumbleweed/run_tests.sh; +``` + +Or if you want to run single test, ``` make clean; make -j -tools/pm3_tests.sh --long +tools/pm3_tests.sh --long mfkey nonce2key mf_nonce_brute fpga_compress common client ``` + + +No ARM compiler available ? From 216858eebadffcb7ce5825d9c69be8859595f81c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 01:13:01 +0200 Subject: [PATCH 316/759] adapt docker images --- docker/fedora-35/Dockerfile | 6 +++++- docker/fedora-35/README.md | 18 ++++++++++++++++-- docker/fedora-35/docker_run.sh | 2 +- docker/homebrew/docker_run.sh | 2 +- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/docker/fedora-35/Dockerfile b/docker/fedora-35/Dockerfile index 6397d60c4..40788b62a 100644 --- a/docker/fedora-35/Dockerfile +++ b/docker/fedora-35/Dockerfile @@ -2,7 +2,11 @@ FROM fedora:35 ENV LANG C # qt5-qtbase-devel skipped -RUN dnf install -y passwd sudo git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel bzip2-devel bluez-libs-devel python3-devel openssl-devel libatomic +RUN dnf install -y passwd sudo git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib readline-devel bzip2-devel bluez-libs-devel python3-devel openssl-devel libatomic findutils + +RUN yum -y update +RUN yum -y install cmake python-pip +RUN python3 -m pip install ansicolors sslcrypto # Create rrg user RUN useradd -ms /bin/bash rrg diff --git a/docker/fedora-35/README.md b/docker/fedora-35/README.md index 5fccbba41..966e86e7e 100644 --- a/docker/fedora-35/README.md +++ b/docker/fedora-35/README.md @@ -1,9 +1,23 @@ +# Notes on run_tests.sh script +This script does both strip the "recover_pk test" in pm3_tests.sh and then run a +bunch of different builds with make and cmake together with the different combos +of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish. + + # Notes to run tests +The script is to be run in proxmark root folder inside the docker env. + +``` +docker/fedora-35/run_tests.sh; +``` + +Or if you want to run single test, ``` sudo yum -y update -sudo yum -y install cmake python-pip -python3 -m pip install ansicolors sslcrypto +make clean; make -j tools/pm3_tests.sh --long ``` diff --git a/docker/fedora-35/docker_run.sh b/docker/fedora-35/docker_run.sh index aabf0b67a..d2e027507 100755 --- a/docker/fedora-35/docker_run.sh +++ b/docker/fedora-35/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -it pm3-fedora-35:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-fedora-35:1.0 diff --git a/docker/homebrew/docker_run.sh b/docker/homebrew/docker_run.sh index 349df8a26..16c744594 100755 --- a/docker/homebrew/docker_run.sh +++ b/docker/homebrew/docker_run.sh @@ -1,4 +1,4 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/linuxbrew/proxmark3 -it pm3-brew:1.0 +docker run --volume=$(pwd)/../..:/home/linuxbrew/proxmark3 -w /home/rrg/proxmark3 -it pm3-brew:1.0 # if needed, run brew as user linuxbrew From d11fe800387a603b76e1c8b7d2fa983b2a4f3d2e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 01:22:49 +0200 Subject: [PATCH 317/759] use grep -E instead of egrep --- tools/pm3_tests.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index 42ecb5eb3..f682d3491 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -193,7 +193,7 @@ function CheckExecute() { for I in $RETRY do RES=$(eval "$2") - if echo "$RES" | egrep -q "$3"; then + if echo "$RES" | grep -E -q "$3"; then echo -e "[ ${C_GREEN}OK${C_NC} ] ${C_OK}" return $RESULT fi @@ -315,7 +315,7 @@ while true; do HT2CRACK3NRAR=hitag2_${HT2CRACK3UID}_nrar_${HT2CRACK3N}emul.txt if ! CheckExecute "ht2crack3 gen testfile" "cd $HT2CRACK3PATH; python3 ../hitag2_gen_nRaR.py $HT2CRACK3KEY $HT2CRACK3UID $HT2CRACK3N > $HT2CRACK3NRAR && echo SUCCESS" "SUCCESS"; then break; fi if ! CheckExecute "ht2crack3test test" "cd $HT2CRACK3PATH; ./ht2crack3test $HT2CRACK3NRAR $HT2CRACK3KEY $HT2CRACK3UID|grep -v SUCCESS||echo SUCCESS" "SUCCESS"; then break; fi - if ! CheckExecute "ht2crack3 test" "cd $HT2CRACK3PATH; ./ht2crack3 $HT2CRACK3UID $HT2CRACK3NRAR |egrep -v '(trying|partial)'" "key = $HT2CRACK3KEY"; then break; fi + if ! CheckExecute "ht2crack3 test" "cd $HT2CRACK3PATH; ./ht2crack3 $HT2CRACK3UID $HT2CRACK3NRAR |grep -E -v '(trying|partial)'" "key = $HT2CRACK3KEY"; then break; fi if ! CheckExecute "ht2crack3 rm testfile" "cd $HT2CRACK3PATH; rm $HT2CRACK3NRAR && echo SUCCESS" "SUCCESS"; then break; fi echo -e "\n${C_BLUE}Testing ht2crack4:${C_NC} ${HT2CRACK4PATH:=./tools/hitag2crack/crack4/}" From 3f92d5ee676d803e1ef96ee151367458ff1093b2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 01:26:12 +0200 Subject: [PATCH 318/759] style --- armsrc/appmain.c | 10 +- armsrc/epa.c | 60 +- armsrc/spiffs.c | 24 +- client/src/cmdhfepa.c | 50 +- client/src/cmdhficlass.c | 2 +- client/src/cmdhfmf.c | 2 +- client/src/pm3line_vocabulory.h | 1458 +++++++++++++++---------------- 7 files changed, 803 insertions(+), 803 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 07c3375f0..932b4cf1e 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1477,7 +1477,7 @@ static void PacketReceived(PacketCommandNG *packet) { EPA_PACE_Simulate(packet); break; } - + case CMD_HF_MIFARE_READER: { struct p { uint8_t first_run; @@ -2319,22 +2319,22 @@ static void PacketReceived(PacketCommandNG *packet) { uint8_t *em = BigBuf_get_EM_addr(); if (em == NULL) { reply_ng(CMD_SPIFFS_ELOAD, PM3_EMALLOC, NULL, 0); - LED_B_OFF(); + LED_B_OFF(); break; - } + } char *fn = (char *)packet->data.asBytes; uint32_t size = size_in_spiffs(fn); if (size == 0) { reply_ng(CMD_SPIFFS_ELOAD, PM3_SUCCESS, NULL, 0); - LED_B_OFF(); + LED_B_OFF(); break; } rdv40_spiffs_read_as_filetype(fn, em, size, RDV40_SPIFFS_SAFETY_SAFE); reply_ng(CMD_SPIFFS_ELOAD, PM3_SUCCESS, NULL, 0); - LED_B_OFF(); + LED_B_OFF(); break; } case CMD_FLASHMEM_SET_SPIBAUDRATE: { diff --git a/armsrc/epa.c b/armsrc/epa.c index 9ec396031..7bd563676 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -594,42 +594,42 @@ int EPA_Setup(void) { } void EPA_PACE_Simulate(PacketCommandNG *c) { - - //---------Initializing--------- - // Get password from arguments - unsigned char pwd[6]; - memcpy(pwd, c->data.asBytes, 6); + //---------Initializing--------- - // Set up communication with the card - int res = EPA_Setup(); - if (res != 0){ - EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 1, res); - return; - } + // Get password from arguments + unsigned char pwd[6]; + memcpy(pwd, c->data.asBytes, 6); - // Read EF.CardAccess - uint8_t card_access[210] = {0}; - int card_access_length = EPA_Read_CardAccess(card_access, 210); + // Set up communication with the card + int res = EPA_Setup(); + if (res != 0) { + EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 1, res); + return; + } - // The response has to be at least this big to hold the OID - if (card_access_length < 18) { - EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 2, card_access_length); - return; - } + // Read EF.CardAccess + uint8_t card_access[210] = {0}; + int card_access_length = EPA_Read_CardAccess(card_access, 210); - // PACEInfo of the card - pace_version_info_t pace_version_info; + // The response has to be at least this big to hold the OID + if (card_access_length < 18) { + EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 2, card_access_length); + return; + } - // Search for the PACE OID - res = EPA_Parse_CardAccess(card_access, card_access_length, &pace_version_info); + // PACEInfo of the card + pace_version_info_t pace_version_info; - if (res != 0 || pace_version_info.version == 0) { - EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 3, res); - return; - } - - Dbprintf("Standardized Domain Parameter: %i", pace_version_info.parameter_id); + // Search for the PACE OID + res = EPA_Parse_CardAccess(card_access, card_access_length, &pace_version_info); + + if (res != 0 || pace_version_info.version == 0) { + EPA_PACE_Collect_Nonce_Abort(CMD_HF_EPA_PACE_SIMULATE, 3, res); + return; + } + + Dbprintf("Standardized Domain Parameter: %i", pace_version_info.parameter_id); DbpString(""); DbpString("finished"); -} \ No newline at end of file +} diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index 54d1360d6..e243b8ed1 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -578,18 +578,18 @@ int rdv40_spiffs_make_symlink(char *linkdest, char *filename, RDV40SpiFFSSafetyL int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( RDV40SpiFFSFileType filetype = filetype_in_spiffs((char *)filename); - switch (filetype) { - case RDV40_SPIFFS_FILETYPE_REAL: - rdv40_spiffs_read((char *)filename, (uint8_t *)dst, size, level); - break; - case RDV40_SPIFFS_FILETYPE_SYMLINK: - rdv40_spiffs_read_as_symlink(filename, (uint8_t *)dst, size, level); - break; - case RDV40_SPIFFS_FILETYPE_BOTH: - case RDV40_SPIFFS_FILETYPE_UNKNOWN: - default: - break; - } + switch (filetype) { + case RDV40_SPIFFS_FILETYPE_REAL: + rdv40_spiffs_read((char *)filename, (uint8_t *)dst, size, level); + break; + case RDV40_SPIFFS_FILETYPE_SYMLINK: + rdv40_spiffs_read_as_symlink(filename, (uint8_t *)dst, size, level); + break; + case RDV40_SPIFFS_FILETYPE_BOTH: + case RDV40_SPIFFS_FILETYPE_UNKNOWN: + default: + break; + } ) } diff --git a/client/src/cmdhfepa.c b/client/src/cmdhfepa.c index c79bc5ae1..7ce9a3e97 100644 --- a/client/src/cmdhfepa.c +++ b/client/src/cmdhfepa.c @@ -106,7 +106,7 @@ static int CmdHFEPAPACEReplay(const char *Cmd) { CLIParserInit(&ctx, "hf epa replay", "Perform PACE protocol by replaying given APDUs", "hf epa replay --mse 0022C1A4 --get 1068000000 --map 1086000002 --pka 1234ABCDEF --ma 1A2B3C4D" - ); + ); void *argtable[] = { arg_param_begin, @@ -216,7 +216,7 @@ static int CmdHFEPAPACESimulate(const char *Cmd) { "The crypto is performed on pc or proxmark", "hf epa sim --pwd 112233445566\n" "hf epa sim --pc --pty 1 --pwd 112233445566" - ); + ); void *argtable[] = { arg_param_begin, @@ -232,40 +232,40 @@ static int CmdHFEPAPACESimulate(const char *Cmd) { int plen = 0; uint8_t pwd[6] = {0}; - CLIGetHexWithReturn(ctx, 3, pwd, &plen); + CLIGetHexWithReturn(ctx, 3, pwd, &plen); CLIParserFree(ctx); - PrintAndLogEx(INFO, "Starting PACE simulation..."); + PrintAndLogEx(INFO, "Starting PACE simulation..."); clearCommandBuffer(); SendCommandMIX(CMD_HF_EPA_PACE_SIMULATE, 0, 0, 0, pwd, plen); - PacketResponseNG resp; - WaitForResponse(CMD_ACK, &resp); + PacketResponseNG resp; + WaitForResponse(CMD_ACK, &resp); uint32_t *data = resp.data.asDwords; - if (resp.oldarg[0] != 0) { - PrintAndLogEx(INFO, "\nPACE failed in step %u!", (uint32_t)resp.oldarg[0]); - PrintAndLogEx(INFO, "MSE Set AT: %u us", data[0]); - PrintAndLogEx(INFO, "GA Get Nonce: %u us", data[1]); - PrintAndLogEx(INFO, "GA Map Nonce: %u us", data[2]); - PrintAndLogEx(INFO, "GA Perform Key Agreement: %u us", data[3]); - PrintAndLogEx(INFO, "GA Mutual Authenticate: %u us", data[4]); - PrintAndLogEx(INFO, "----------------"); - } else { - PrintAndLogEx(INFO, "PACE successful!"); - PrintAndLogEx(INFO, "MSE Set AT: %u us", data[0]); - PrintAndLogEx(INFO, "GA Get Nonce: %u us", data[1]); - PrintAndLogEx(INFO, "GA Map Nonce: %u us", data[2]); - PrintAndLogEx(INFO, "GA Perform Key Agreement: %u us", data[3]); - PrintAndLogEx(INFO, "GA Mutual Authenticate: %u us", data[4]); - PrintAndLogEx(INFO, "----------------"); - } + if (resp.oldarg[0] != 0) { + PrintAndLogEx(INFO, "\nPACE failed in step %u!", (uint32_t)resp.oldarg[0]); + PrintAndLogEx(INFO, "MSE Set AT: %u us", data[0]); + PrintAndLogEx(INFO, "GA Get Nonce: %u us", data[1]); + PrintAndLogEx(INFO, "GA Map Nonce: %u us", data[2]); + PrintAndLogEx(INFO, "GA Perform Key Agreement: %u us", data[3]); + PrintAndLogEx(INFO, "GA Mutual Authenticate: %u us", data[4]); + PrintAndLogEx(INFO, "----------------"); + } else { + PrintAndLogEx(INFO, "PACE successful!"); + PrintAndLogEx(INFO, "MSE Set AT: %u us", data[0]); + PrintAndLogEx(INFO, "GA Get Nonce: %u us", data[1]); + PrintAndLogEx(INFO, "GA Map Nonce: %u us", data[2]); + PrintAndLogEx(INFO, "GA Perform Key Agreement: %u us", data[3]); + PrintAndLogEx(INFO, "GA Mutual Authenticate: %u us", data[4]); + PrintAndLogEx(INFO, "----------------"); + } - return PM3_SUCCESS; + return PM3_SUCCESS; } @@ -273,7 +273,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"cnonces", CmdHFEPACollectPACENonces, IfPm3Iso14443, "Acquire encrypted PACE nonces of specific size"}, {"replay", CmdHFEPAPACEReplay, IfPm3Iso14443, "Perform PACE protocol by replaying given APDUs"}, - {"sim", CmdHFEPAPACESimulate, IfPm3Iso14443, "Simulate PACE protocol"}, + {"sim", CmdHFEPAPACESimulate, IfPm3Iso14443, "Simulate PACE protocol"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 7d8138e7b..5757fcadd 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1015,7 +1015,7 @@ static int CmdHFiClassELoad(const char *Cmd) { bool use_spiffs = arg_get_lit(ctx, 2); CLIParserFree(ctx); - // use RDV4 spiffs + // use RDV4 spiffs if (use_spiffs && IfPm3Flash() == false) { PrintAndLogEx(WARNING, "Device not compiled to support spiffs"); return PM3_EINVARG; diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index e0bd6cc69..467c9b2ca 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -3947,7 +3947,7 @@ int CmdHF14AMfELoad(const char *Cmd) { PrintAndLogEx(INFO, "overriding number of blocks, will use %d blocks ( %u bytes )", block_cnt, block_cnt * block_width); } - // use RDV4 spiffs + // use RDV4 spiffs if (use_spiffs && IfPm3Flash() == false) { PrintAndLogEx(WARNING, "Device not compiled to support spiffs"); return PM3_EINVARG; diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 1044e2906..e715f9cab 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -31,734 +31,734 @@ typedef struct vocabulory_s { } vocabulory_t; const static vocabulory_t vocabulory[] = { - { 1, "help" }, - { 0, "auto" }, - { 1, "clear" }, - { 1, "hints" }, - { 1, "msleep" }, - { 1, "rem" }, - { 1, "quit" }, - { 1, "exit" }, - { 1, "prefs help" }, - { 1, "prefs show" }, - { 1, "prefs get barmode" }, - { 1, "prefs get clientdebug" }, - { 1, "prefs get clientdelay" }, - { 1, "prefs get color" }, - { 1, "prefs get savepaths" }, - { 1, "prefs get emoji" }, - { 1, "prefs get hints" }, - { 1, "prefs get output" }, - { 1, "prefs get plotsliders" }, - { 1, "prefs set help" }, - { 1, "prefs set barmode" }, - { 1, "prefs set clientdebug" }, - { 1, "prefs set clientdelay" }, - { 1, "prefs set color" }, - { 1, "prefs set emoji" }, - { 1, "prefs set hints" }, - { 1, "prefs set savepaths" }, - { 1, "prefs set output" }, - { 1, "prefs set plotsliders" }, - { 1, "analyse help" }, - { 1, "analyse lcr" }, - { 1, "analyse crc" }, - { 1, "analyse chksum" }, - { 1, "analyse dates" }, - { 1, "analyse lfsr" }, - { 1, "analyse a" }, - { 1, "analyse nuid" }, - { 1, "analyse demodbuff" }, - { 1, "analyse freq" }, - { 1, "analyse foo" }, - { 1, "analyse units" }, - { 1, "data help" }, - { 1, "data biphaserawdecode" }, - { 1, "data detectclock" }, - { 1, "data fsktonrz" }, - { 1, "data manrawdecode" }, - { 1, "data modulation" }, - { 1, "data rawdemod" }, - { 1, "data askedgedetect" }, - { 1, "data autocorr" }, - { 1, "data dirthreshold" }, - { 1, "data decimate" }, - { 1, "data undecimate" }, - { 1, "data hide" }, - { 1, "data hpf" }, - { 1, "data iir" }, - { 1, "data grid" }, - { 1, "data ltrim" }, - { 1, "data mtrim" }, - { 1, "data norm" }, - { 1, "data plot" }, - { 1, "data rtrim" }, - { 1, "data setgraphmarkers" }, - { 1, "data shiftgraphzero" }, - { 1, "data timescale" }, - { 1, "data zerocrossings" }, - { 1, "data convertbitstream" }, - { 1, "data getbitstream" }, - { 1, "data asn1" }, - { 1, "data bin2hex" }, - { 0, "data bitsamples" }, - { 1, "data clear" }, - { 1, "data diff" }, - { 0, "data hexsamples" }, - { 1, "data hex2bin" }, - { 1, "data load" }, - { 1, "data print" }, - { 0, "data samples" }, - { 1, "data save" }, - { 1, "data setdebugmode" }, - { 0, "data tune" }, - { 1, "emv help" }, - { 0, "emv exec" }, - { 0, "emv pse" }, - { 0, "emv search" }, - { 0, "emv select" }, - { 0, "emv gpo" }, - { 0, "emv readrec" }, - { 0, "emv genac" }, - { 0, "emv challenge" }, - { 0, "emv intauth" }, - { 0, "emv scan" }, - { 1, "emv test" }, - { 1, "emv list" }, - { 0, "emv roca" }, - { 1, "hf help" }, - { 1, "hf list" }, - { 0, "hf plot" }, - { 0, "hf tune" }, - { 1, "hf search" }, - { 0, "hf sniff" }, - { 1, "hf 14a help" }, - { 1, "hf 14a list" }, - { 0, "hf 14a antifuzz" }, - { 0, "hf 14a config" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a info" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a raw" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a apdufind" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a ndefformat" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a ndefwrite" }, - { 1, "hf 14b help" }, - { 0, "hf 14b apdu" }, - { 0, "hf 14b dump" }, - { 0, "hf 14b info" }, - { 1, "hf 14b list" }, - { 0, "hf 14b ndefread" }, - { 0, "hf 14b raw" }, - { 0, "hf 14b reader" }, - { 0, "hf 14b sim" }, - { 0, "hf 14b sniff" }, - { 0, "hf 14b rdbl" }, - { 0, "hf 14b sriwrite" }, - { 1, "hf 14b view" }, - { 1, "hf 15 help" }, - { 1, "hf 15 list" }, - { 1, "hf 15 demod" }, - { 0, "hf 15 dump" }, - { 0, "hf 15 info" }, - { 0, "hf 15 sniff" }, - { 0, "hf 15 raw" }, - { 0, "hf 15 rdbl" }, - { 0, "hf 15 rdmulti" }, - { 0, "hf 15 reader" }, - { 0, "hf 15 restore" }, - { 0, "hf 15 samples" }, - { 0, "hf 15 eload" }, - { 0, "hf 15 esave" }, - { 0, "hf 15 eview" }, - { 0, "hf 15 sim" }, - { 0, "hf 15 slixdisable" }, - { 0, "hf 15 wrbl" }, - { 0, "hf 15 findafi" }, - { 0, "hf 15 writeafi" }, - { 0, "hf 15 writedsfid" }, - { 0, "hf 15 csetuid" }, - { 1, "hf cipurse help" }, - { 0, "hf cipurse info" }, - { 0, "hf cipurse select" }, - { 0, "hf cipurse auth" }, - { 0, "hf cipurse read" }, - { 0, "hf cipurse write" }, - { 0, "hf cipurse aread" }, - { 0, "hf cipurse awrite" }, - { 0, "hf cipurse formatall" }, - { 0, "hf cipurse create" }, - { 0, "hf cipurse delete" }, - { 0, "hf cipurse updkey" }, - { 0, "hf cipurse updakey" }, - { 0, "hf cipurse default" }, - { 1, "hf cipurse test" }, - { 1, "hf epa help" }, - { 0, "hf epa cnonces" }, - { 0, "hf epa preplay" }, - { 1, "hf emrtd help" }, - { 0, "hf emrtd dump" }, - { 1, "hf emrtd info" }, - { 1, "hf emrtd list" }, - { 1, "hf felica help" }, - { 1, "hf felica list" }, - { 0, "hf felica reader" }, - { 0, "hf felica info" }, - { 0, "hf felica sniff" }, - { 0, "hf felica raw" }, - { 0, "hf felica rdbl" }, - { 0, "hf felica wrbl" }, - { 0, "hf felica rqservice" }, - { 0, "hf felica rqresponse" }, - { 0, "hf felica scsvcode" }, - { 0, "hf felica rqsyscode" }, - { 0, "hf felica auth1" }, - { 0, "hf felica auth2" }, - { 0, "hf felica rqspecver" }, - { 0, "hf felica resetmode" }, - { 0, "hf felica litesim" }, - { 0, "hf felica litedump" }, - { 1, "hf fido help" }, - { 1, "hf fido list" }, - { 0, "hf fido info" }, - { 0, "hf fido reg" }, - { 0, "hf fido auth" }, - { 0, "hf fido make" }, - { 0, "hf fido assert" }, - { 1, "hf fudan help" }, - { 0, "hf fudan reader" }, - { 0, "hf fudan dump" }, - { 0, "hf fudan rdbl" }, - { 1, "hf fudan view" }, - { 0, "hf fudan wrbl" }, - { 1, "hf gallagher help" }, - { 0, "hf gallagher reader" }, - { 0, "hf gallagher clone" }, - { 0, "hf gallagher delete" }, - { 1, "hf gallagher diversifykey" }, - { 1, "hf gallagher decode" }, - { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 initialize" }, - { 0, "hf ksx6924 prec" }, - { 0, "hf ksx6924 select" }, - { 1, "hf jooki help" }, - { 0, "hf jooki clone" }, - { 1, "hf jooki decode" }, - { 1, "hf jooki encode" }, - { 0, "hf jooki sim" }, - { 1, "hf iclass help" }, - { 0, "hf iclass dump" }, - { 1, "hf iclass info" }, - { 1, "hf iclass list" }, - { 0, "hf iclass rdbl" }, - { 0, "hf iclass reader" }, - { 0, "hf iclass restore" }, - { 0, "hf iclass sniff" }, - { 0, "hf iclass wrbl" }, - { 0, "hf iclass chk" }, - { 1, "hf iclass loclass" }, - { 1, "hf iclass lookup" }, - { 0, "hf iclass sim" }, - { 0, "hf iclass eload" }, - { 0, "hf iclass esave" }, - { 0, "hf iclass eview" }, - { 1, "hf iclass configcard" }, - { 1, "hf iclass calcnewkey" }, - { 1, "hf iclass encode" }, - { 1, "hf iclass encrypt" }, - { 1, "hf iclass decrypt" }, - { 1, "hf iclass managekeys" }, - { 1, "hf iclass permutekey" }, - { 1, "hf iclass view" }, - { 1, "hf legic help" }, - { 0, "hf legic dump" }, - { 0, "hf legic info" }, - { 1, "hf legic list" }, - { 0, "hf legic rdbl" }, - { 0, "hf legic reader" }, - { 0, "hf legic restore" }, - { 0, "hf legic wipe" }, - { 0, "hf legic wrbl" }, - { 0, "hf legic sim" }, - { 0, "hf legic eload" }, - { 0, "hf legic esave" }, - { 0, "hf legic eview" }, - { 1, "hf legic crc" }, - { 1, "hf legic view" }, - { 1, "hf lto help" }, - { 0, "hf lto dump" }, - { 0, "hf lto info" }, - { 1, "hf lto list" }, - { 0, "hf lto rdbl" }, - { 0, "hf lto reader" }, - { 0, "hf lto restore" }, - { 0, "hf lto wrbl" }, - { 1, "hf mf help" }, - { 1, "hf mf list" }, - { 0, "hf mf darkside" }, - { 0, "hf mf nested" }, - { 1, "hf mf hardnested" }, - { 0, "hf mf staticnested" }, - { 0, "hf mf autopwn" }, - { 0, "hf mf nack" }, - { 0, "hf mf chk" }, - { 0, "hf mf fchk" }, - { 1, "hf mf decrypt" }, - { 0, "hf mf supercard" }, - { 0, "hf mf auth4" }, - { 1, "hf mf acl" }, - { 0, "hf mf dump" }, - { 1, "hf mf mad" }, - { 0, "hf mf personalize" }, - { 0, "hf mf rdbl" }, - { 0, "hf mf rdsc" }, - { 0, "hf mf restore" }, - { 0, "hf mf setmod" }, - { 1, "hf mf value" }, - { 1, "hf mf view" }, - { 0, "hf mf wipe" }, - { 0, "hf mf wrbl" }, - { 0, "hf mf sim" }, - { 0, "hf mf ecfill" }, - { 0, "hf mf eclr" }, - { 0, "hf mf egetblk" }, - { 0, "hf mf egetsc" }, - { 0, "hf mf ekeyprn" }, - { 0, "hf mf eload" }, - { 0, "hf mf esave" }, - { 0, "hf mf esetblk" }, - { 0, "hf mf eview" }, - { 0, "hf mf cgetblk" }, - { 0, "hf mf cgetsc" }, - { 0, "hf mf cload" }, - { 0, "hf mf csave" }, - { 0, "hf mf csetblk" }, - { 0, "hf mf csetuid" }, - { 0, "hf mf cview" }, - { 0, "hf mf cwipe" }, - { 0, "hf mf gen3uid" }, - { 0, "hf mf gen3blk" }, - { 0, "hf mf gen3freeze" }, - { 0, "hf mf gview" }, - { 0, "hf mf ndefformat" }, - { 0, "hf mf ndefread" }, - { 0, "hf mf ndefwrite" }, - { 1, "hf mfp help" }, - { 0, "hf mfp info" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp commitp" }, - { 0, "hf mfp auth" }, - { 0, "hf mfp rdbl" }, - { 0, "hf mfp rdsc" }, - { 0, "hf mfp wrbl" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp mad" }, - { 0, "hf mfp ndefread" }, - { 1, "hf mfu help" }, - { 1, "hf mfu keygen" }, - { 1, "hf mfu pwdgen" }, - { 0, "hf mfu otptear" }, - { 0, "hf mfu cauth" }, - { 0, "hf mfu dump" }, - { 0, "hf mfu info" }, - { 0, "hf mfu ndefread" }, - { 0, "hf mfu rdbl" }, - { 0, "hf mfu restore" }, - { 1, "hf mfu view" }, - { 0, "hf mfu wrbl" }, - { 0, "hf mfu eload" }, - { 0, "hf mfu eview" }, - { 0, "hf mfu sim" }, - { 0, "hf mfu setpwd" }, - { 0, "hf mfu setuid" }, - { 1, "hf mfdes help" }, - { 0, "hf mfdes info" }, - { 0, "hf mfdes getuid" }, - { 0, "hf mfdes default" }, - { 0, "hf mfdes auth" }, - { 0, "hf mfdes chk" }, - { 0, "hf mfdes detect" }, - { 0, "hf mfdes freemem" }, - { 0, "hf mfdes setconfig" }, - { 0, "hf mfdes formatpicc" }, - { 1, "hf mfdes list" }, - { 0, "hf mfdes mad" }, - { 0, "hf mfdes lsapp" }, - { 0, "hf mfdes getaids" }, - { 0, "hf mfdes getappnames" }, - { 0, "hf mfdes bruteaid" }, - { 0, "hf mfdes createapp" }, - { 0, "hf mfdes deleteapp" }, - { 0, "hf mfdes selectapp" }, - { 0, "hf mfdes changekey" }, - { 0, "hf mfdes chkeysettings" }, - { 0, "hf mfdes getkeysettings" }, - { 0, "hf mfdes getkeyversions" }, - { 0, "hf mfdes getfileids" }, - { 0, "hf mfdes getfileisoids" }, - { 0, "hf mfdes lsfiles" }, - { 0, "hf mfdes dump" }, - { 0, "hf mfdes createfile" }, - { 0, "hf mfdes createvaluefile" }, - { 0, "hf mfdes createrecordfile" }, - { 0, "hf mfdes createmacfile" }, - { 0, "hf mfdes deletefile" }, - { 0, "hf mfdes getfilesettings" }, - { 0, "hf mfdes chfilesettings" }, - { 0, "hf mfdes read" }, - { 0, "hf mfdes write" }, - { 0, "hf mfdes value" }, - { 0, "hf mfdes clearrecfile" }, - { 1, "hf mfdes test" }, - { 1, "hf ntag424 help" }, - { 0, "hf ntag424 info" }, - { 0, "hf ntag424 sdm" }, - { 1, "hf ntag424 view" }, - { 1, "hf seos help" }, - { 0, "hf seos info" }, - { 1, "hf seos list" }, - { 1, "hf st25ta help" }, - { 0, "hf st25ta info" }, - { 1, "hf st25ta list" }, - { 1, "hf st25ta ndefread" }, - { 0, "hf st25ta protect" }, - { 0, "hf st25ta pwd" }, - { 0, "hf st25ta sim" }, - { 1, "hf thinfilm help" }, - { 0, "hf thinfilm info" }, - { 1, "hf thinfilm list" }, - { 0, "hf thinfilm sim" }, - { 1, "hf topaz help" }, - { 0, "hf topaz dump" }, - { 1, "hf topaz list" }, - { 0, "hf topaz info" }, - { 0, "hf topaz reader" }, - { 0, "hf topaz sim" }, - { 0, "hf topaz sniff" }, - { 0, "hf topaz raw" }, - { 0, "hf topaz rdbl" }, - { 1, "hf topaz view" }, - { 0, "hf topaz wrbl" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, - { 1, "hf xerox help" }, - { 0, "hf xerox info" }, - { 0, "hf xerox reader" }, - { 0, "hf xerox dump" }, - { 1, "hf waveshare help" }, - { 0, "hf waveshare loadbmp" }, - { 1, "hw help" }, - { 0, "hw break" }, - { 1, "hw connect" }, - { 0, "hw dbg" }, - { 0, "hw detectreader" }, - { 0, "hw fpgaoff" }, - { 0, "hw lcd" }, - { 0, "hw lcdreset" }, - { 0, "hw ping" }, - { 0, "hw readmem" }, - { 0, "hw reset" }, - { 0, "hw setlfdivisor" }, - { 0, "hw setmux" }, - { 0, "hw standalone" }, - { 0, "hw status" }, - { 0, "hw tearoff" }, - { 0, "hw tia" }, - { 0, "hw tune" }, - { 1, "hw version" }, - { 1, "lf help" }, - { 0, "lf config" }, - { 0, "lf cmdread" }, - { 0, "lf read" }, - { 1, "lf search" }, - { 0, "lf sim" }, - { 0, "lf simask" }, - { 0, "lf simfsk" }, - { 0, "lf simpsk" }, - { 0, "lf simbidir" }, - { 0, "lf sniff" }, - { 0, "lf tune" }, - { 1, "lf awid help" }, - { 1, "lf awid demod" }, - { 0, "lf awid reader" }, - { 0, "lf awid clone" }, - { 0, "lf awid sim" }, - { 0, "lf awid brute" }, - { 0, "lf awid watch" }, - { 1, "lf cotag help" }, - { 1, "lf cotag demod" }, - { 0, "lf cotag reader" }, - { 1, "lf destron help" }, - { 1, "lf destron demod" }, - { 0, "lf destron reader" }, - { 0, "lf destron clone" }, - { 0, "lf destron sim" }, - { 1, "lf em help" }, - { 1, "lf em 410x help" }, - { 1, "lf em 410x demod" }, - { 0, "lf em 410x reader" }, - { 0, "lf em 410x sim" }, - { 0, "lf em 410x brute" }, - { 0, "lf em 410x watch" }, - { 0, "lf em 410x spoof" }, - { 0, "lf em 410x clone" }, - { 1, "lf em 4x05 help" }, - { 0, "lf em 4x05 brute" }, - { 0, "lf em 4x05 chk" }, - { 1, "lf em 4x05 demod" }, - { 0, "lf em 4x05 dump" }, - { 0, "lf em 4x05 info" }, - { 0, "lf em 4x05 read" }, - { 1, "lf em 4x05 sniff" }, - { 0, "lf em 4x05 unlock" }, - { 0, "lf em 4x05 wipe" }, - { 0, "lf em 4x05 write" }, - { 1, "lf em 4x50 help" }, - { 0, "lf em 4x50 brute" }, - { 0, "lf em 4x50 chk" }, - { 0, "lf em 4x50 dump" }, - { 0, "lf em 4x50 info" }, - { 0, "lf em 4x50 login" }, - { 0, "lf em 4x50 rdbl" }, - { 0, "lf em 4x50 reader" }, - { 0, "lf em 4x50 restore" }, - { 0, "lf em 4x50 wrbl" }, - { 0, "lf em 4x50 wrpwd" }, - { 0, "lf em 4x50 wipe" }, - { 0, "lf em 4x50 eload" }, - { 0, "lf em 4x50 esave" }, - { 0, "lf em 4x50 eview" }, - { 0, "lf em 4x50 sim" }, - { 1, "lf em 4x70 help" }, - { 0, "lf em 4x70 info" }, - { 0, "lf em 4x70 write" }, - { 0, "lf em 4x70 unlock" }, - { 0, "lf em 4x70 auth" }, - { 0, "lf em 4x70 writepin" }, - { 0, "lf em 4x70 writekey" }, - { 1, "lf fdxb help" }, - { 1, "lf fdxb demod" }, - { 0, "lf fdxb reader" }, - { 0, "lf fdxb clone" }, - { 0, "lf fdxb sim" }, - { 1, "lf gallagher help" }, - { 1, "lf gallagher demod" }, - { 0, "lf gallagher reader" }, - { 0, "lf gallagher clone" }, - { 0, "lf gallagher sim" }, - { 1, "lf gproxii help" }, - { 1, "lf gproxii demod" }, - { 0, "lf gproxii reader" }, - { 0, "lf gproxii clone" }, - { 0, "lf gproxii sim" }, - { 1, "lf hid help" }, - { 1, "lf hid demod" }, - { 0, "lf hid reader" }, - { 0, "lf hid clone" }, - { 0, "lf hid sim" }, - { 0, "lf hid brute" }, - { 0, "lf hid watch" }, - { 1, "lf hitag help" }, - { 0, "lf hitag eload" }, - { 1, "lf hitag list" }, - { 0, "lf hitag info" }, - { 0, "lf hitag reader" }, - { 0, "lf hitag sim" }, - { 0, "lf hitag sniff" }, - { 0, "lf hitag writer" }, - { 0, "lf hitag dump" }, - { 0, "lf hitag cc" }, - { 1, "lf idteck help" }, - { 1, "lf idteck demod" }, - { 0, "lf idteck reader" }, - { 0, "lf idteck clone" }, - { 0, "lf idteck sim" }, - { 1, "lf indala help" }, - { 1, "lf indala demod" }, - { 1, "lf indala altdemod" }, - { 0, "lf indala reader" }, - { 0, "lf indala clone" }, - { 0, "lf indala sim" }, - { 1, "lf io help" }, - { 1, "lf io demod" }, - { 0, "lf io reader" }, - { 0, "lf io clone" }, - { 0, "lf io sim" }, - { 0, "lf io watch" }, - { 1, "lf jablotron help" }, - { 1, "lf jablotron demod" }, - { 0, "lf jablotron reader" }, - { 0, "lf jablotron clone" }, - { 0, "lf jablotron sim" }, - { 1, "lf keri help" }, - { 1, "lf keri demod" }, - { 0, "lf keri reader" }, - { 0, "lf keri clone" }, - { 0, "lf keri sim" }, - { 1, "lf motorola help" }, - { 1, "lf motorola demod" }, - { 0, "lf motorola reader" }, - { 0, "lf motorola clone" }, - { 0, "lf motorola sim" }, - { 1, "lf nedap help" }, - { 1, "lf nedap demod" }, - { 0, "lf nedap reader" }, - { 0, "lf nedap clone" }, - { 0, "lf nedap sim" }, - { 1, "lf nexwatch help" }, - { 1, "lf nexwatch demod" }, - { 0, "lf nexwatch reader" }, - { 0, "lf nexwatch clone" }, - { 0, "lf nexwatch sim" }, - { 1, "lf noralsy help" }, - { 1, "lf noralsy demod" }, - { 0, "lf noralsy reader" }, - { 0, "lf noralsy clone" }, - { 0, "lf noralsy sim" }, - { 1, "lf pac help" }, - { 1, "lf pac demod" }, - { 0, "lf pac reader" }, - { 0, "lf pac clone" }, - { 0, "lf pac sim" }, - { 1, "lf paradox help" }, - { 1, "lf paradox demod" }, - { 0, "lf paradox reader" }, - { 0, "lf paradox clone" }, - { 0, "lf paradox sim" }, - { 1, "lf pcf7931 help" }, - { 0, "lf pcf7931 reader" }, - { 0, "lf pcf7931 write" }, - { 1, "lf pcf7931 config" }, - { 1, "lf presco help" }, - { 1, "lf presco demod" }, - { 0, "lf presco reader" }, - { 0, "lf presco clone" }, - { 0, "lf presco sim" }, - { 1, "lf pyramid help" }, - { 1, "lf pyramid demod" }, - { 0, "lf pyramid reader" }, - { 0, "lf pyramid clone" }, - { 0, "lf pyramid sim" }, - { 1, "lf securakey help" }, - { 1, "lf securakey demod" }, - { 0, "lf securakey reader" }, - { 0, "lf securakey clone" }, - { 0, "lf securakey sim" }, - { 1, "lf ti help" }, - { 1, "lf ti demod" }, - { 0, "lf ti reader" }, - { 0, "lf ti write" }, - { 1, "lf t55xx help" }, - { 0, "lf t55xx clonehelp" }, - { 1, "lf t55xx config" }, - { 0, "lf t55xx dangerraw" }, - { 1, "lf t55xx detect" }, - { 0, "lf t55xx deviceconfig" }, - { 0, "lf t55xx dump" }, - { 1, "lf t55xx info" }, - { 0, "lf t55xx p1detect" }, - { 0, "lf t55xx read" }, - { 0, "lf t55xx resetread" }, - { 0, "lf t55xx restore" }, - { 1, "lf t55xx trace" }, - { 0, "lf t55xx wakeup" }, - { 0, "lf t55xx write" }, - { 0, "lf t55xx bruteforce" }, - { 0, "lf t55xx chk" }, - { 0, "lf t55xx protect" }, - { 0, "lf t55xx recoverpw" }, - { 1, "lf t55xx sniff" }, - { 0, "lf t55xx special" }, - { 0, "lf t55xx wipe" }, - { 1, "lf viking help" }, - { 1, "lf viking demod" }, - { 0, "lf viking reader" }, - { 0, "lf viking clone" }, - { 0, "lf viking sim" }, - { 1, "lf visa2000 help" }, - { 1, "lf visa2000 demod" }, - { 0, "lf visa2000 reader" }, - { 0, "lf visa2000 clone" }, - { 0, "lf visa2000 sim" }, - { 1, "mem help" }, - { 0, "mem baudrate" }, - { 0, "mem dump" }, - { 0, "mem info" }, - { 0, "mem load" }, - { 0, "mem wipe" }, - { 1, "mem spiffs help" }, - { 0, "mem spiffs copy" }, - { 0, "mem spiffs check" }, - { 0, "mem spiffs dump" }, - { 0, "mem spiffs info" }, - { 0, "mem spiffs mount" }, - { 0, "mem spiffs remove" }, - { 0, "mem spiffs rename" }, - { 0, "mem spiffs test" }, - { 0, "mem spiffs tree" }, - { 0, "mem spiffs unmount" }, - { 0, "mem spiffs upload" }, - { 0, "mem spiffs view" }, - { 0, "mem spiffs wipe" }, - { 1, "nfc help" }, - { 1, "nfc decode" }, - { 0, "nfc type1 read" }, - { 1, "nfc type1 help" }, - { 0, "nfc type2 read" }, - { 1, "nfc type2 help" }, - { 0, "nfc type4a format" }, - { 0, "nfc type4a read" }, - { 0, "nfc type4a write" }, - { 0, "nfc type4a st25taread" }, - { 1, "nfc type4a help" }, - { 0, "nfc type4b read" }, - { 1, "nfc type4b help" }, - { 0, "nfc mf cformat" }, - { 0, "nfc mf cread" }, - { 0, "nfc mf cwrite" }, - { 0, "nfc mf pread" }, - { 1, "nfc mf help" }, - { 0, "nfc barcode read" }, - { 0, "nfc barcode sim" }, - { 1, "nfc barcode help" }, - { 1, "smart help" }, - { 1, "smart list" }, - { 0, "smart info" }, - { 0, "smart reader" }, - { 0, "smart raw" }, - { 1, "smart upgrade" }, - { 0, "smart setclock" }, - { 0, "smart brute" }, - { 1, "script help" }, - { 1, "script list" }, - { 1, "script run" }, - { 1, "trace help" }, - { 1, "trace extract" }, - { 1, "trace list" }, - { 1, "trace load" }, - { 1, "trace save" }, - { 1, "usart help" }, - { 0, "usart btpin" }, - { 0, "usart btfactory" }, - { 0, "usart tx" }, - { 0, "usart rx" }, - { 0, "usart txrx" }, - { 0, "usart txhex" }, - { 0, "usart rxhex" }, - { 0, "usart config" }, - { 1, "wiegand help" }, - { 1, "wiegand list" }, - { 1, "wiegand encode" }, - { 1, "wiegand decode" }, + { 1, "help" }, + { 0, "auto" }, + { 1, "clear" }, + { 1, "hints" }, + { 1, "msleep" }, + { 1, "rem" }, + { 1, "quit" }, + { 1, "exit" }, + { 1, "prefs help" }, + { 1, "prefs show" }, + { 1, "prefs get barmode" }, + { 1, "prefs get clientdebug" }, + { 1, "prefs get clientdelay" }, + { 1, "prefs get color" }, + { 1, "prefs get savepaths" }, + { 1, "prefs get emoji" }, + { 1, "prefs get hints" }, + { 1, "prefs get output" }, + { 1, "prefs get plotsliders" }, + { 1, "prefs set help" }, + { 1, "prefs set barmode" }, + { 1, "prefs set clientdebug" }, + { 1, "prefs set clientdelay" }, + { 1, "prefs set color" }, + { 1, "prefs set emoji" }, + { 1, "prefs set hints" }, + { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, + { 1, "prefs set plotsliders" }, + { 1, "analyse help" }, + { 1, "analyse lcr" }, + { 1, "analyse crc" }, + { 1, "analyse chksum" }, + { 1, "analyse dates" }, + { 1, "analyse lfsr" }, + { 1, "analyse a" }, + { 1, "analyse nuid" }, + { 1, "analyse demodbuff" }, + { 1, "analyse freq" }, + { 1, "analyse foo" }, + { 1, "analyse units" }, + { 1, "data help" }, + { 1, "data biphaserawdecode" }, + { 1, "data detectclock" }, + { 1, "data fsktonrz" }, + { 1, "data manrawdecode" }, + { 1, "data modulation" }, + { 1, "data rawdemod" }, + { 1, "data askedgedetect" }, + { 1, "data autocorr" }, + { 1, "data dirthreshold" }, + { 1, "data decimate" }, + { 1, "data undecimate" }, + { 1, "data hide" }, + { 1, "data hpf" }, + { 1, "data iir" }, + { 1, "data grid" }, + { 1, "data ltrim" }, + { 1, "data mtrim" }, + { 1, "data norm" }, + { 1, "data plot" }, + { 1, "data rtrim" }, + { 1, "data setgraphmarkers" }, + { 1, "data shiftgraphzero" }, + { 1, "data timescale" }, + { 1, "data zerocrossings" }, + { 1, "data convertbitstream" }, + { 1, "data getbitstream" }, + { 1, "data asn1" }, + { 1, "data bin2hex" }, + { 0, "data bitsamples" }, + { 1, "data clear" }, + { 1, "data diff" }, + { 0, "data hexsamples" }, + { 1, "data hex2bin" }, + { 1, "data load" }, + { 1, "data print" }, + { 0, "data samples" }, + { 1, "data save" }, + { 1, "data setdebugmode" }, + { 0, "data tune" }, + { 1, "emv help" }, + { 0, "emv exec" }, + { 0, "emv pse" }, + { 0, "emv search" }, + { 0, "emv select" }, + { 0, "emv gpo" }, + { 0, "emv readrec" }, + { 0, "emv genac" }, + { 0, "emv challenge" }, + { 0, "emv intauth" }, + { 0, "emv scan" }, + { 1, "emv test" }, + { 1, "emv list" }, + { 0, "emv roca" }, + { 1, "hf help" }, + { 1, "hf list" }, + { 0, "hf plot" }, + { 0, "hf tune" }, + { 1, "hf search" }, + { 0, "hf sniff" }, + { 1, "hf 14a help" }, + { 1, "hf 14a list" }, + { 0, "hf 14a antifuzz" }, + { 0, "hf 14a config" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a info" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a apdu" }, + { 0, "hf 14a apdufind" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a ndefformat" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a ndefwrite" }, + { 1, "hf 14b help" }, + { 0, "hf 14b apdu" }, + { 0, "hf 14b dump" }, + { 0, "hf 14b info" }, + { 1, "hf 14b list" }, + { 0, "hf 14b ndefread" }, + { 0, "hf 14b raw" }, + { 0, "hf 14b reader" }, + { 0, "hf 14b sim" }, + { 0, "hf 14b sniff" }, + { 0, "hf 14b rdbl" }, + { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, + { 1, "hf 15 help" }, + { 1, "hf 15 list" }, + { 1, "hf 15 demod" }, + { 0, "hf 15 dump" }, + { 0, "hf 15 info" }, + { 0, "hf 15 sniff" }, + { 0, "hf 15 raw" }, + { 0, "hf 15 rdbl" }, + { 0, "hf 15 rdmulti" }, + { 0, "hf 15 reader" }, + { 0, "hf 15 restore" }, + { 0, "hf 15 samples" }, + { 0, "hf 15 eload" }, + { 0, "hf 15 esave" }, + { 0, "hf 15 eview" }, + { 0, "hf 15 sim" }, + { 0, "hf 15 slixdisable" }, + { 0, "hf 15 wrbl" }, + { 0, "hf 15 findafi" }, + { 0, "hf 15 writeafi" }, + { 0, "hf 15 writedsfid" }, + { 0, "hf 15 csetuid" }, + { 1, "hf cipurse help" }, + { 0, "hf cipurse info" }, + { 0, "hf cipurse select" }, + { 0, "hf cipurse auth" }, + { 0, "hf cipurse read" }, + { 0, "hf cipurse write" }, + { 0, "hf cipurse aread" }, + { 0, "hf cipurse awrite" }, + { 0, "hf cipurse formatall" }, + { 0, "hf cipurse create" }, + { 0, "hf cipurse delete" }, + { 0, "hf cipurse updkey" }, + { 0, "hf cipurse updakey" }, + { 0, "hf cipurse default" }, + { 1, "hf cipurse test" }, + { 1, "hf epa help" }, + { 0, "hf epa cnonces" }, + { 0, "hf epa preplay" }, + { 1, "hf emrtd help" }, + { 0, "hf emrtd dump" }, + { 1, "hf emrtd info" }, + { 1, "hf emrtd list" }, + { 1, "hf felica help" }, + { 1, "hf felica list" }, + { 0, "hf felica reader" }, + { 0, "hf felica info" }, + { 0, "hf felica sniff" }, + { 0, "hf felica raw" }, + { 0, "hf felica rdbl" }, + { 0, "hf felica wrbl" }, + { 0, "hf felica rqservice" }, + { 0, "hf felica rqresponse" }, + { 0, "hf felica scsvcode" }, + { 0, "hf felica rqsyscode" }, + { 0, "hf felica auth1" }, + { 0, "hf felica auth2" }, + { 0, "hf felica rqspecver" }, + { 0, "hf felica resetmode" }, + { 0, "hf felica litesim" }, + { 0, "hf felica litedump" }, + { 1, "hf fido help" }, + { 1, "hf fido list" }, + { 0, "hf fido info" }, + { 0, "hf fido reg" }, + { 0, "hf fido auth" }, + { 0, "hf fido make" }, + { 0, "hf fido assert" }, + { 1, "hf fudan help" }, + { 0, "hf fudan reader" }, + { 0, "hf fudan dump" }, + { 0, "hf fudan rdbl" }, + { 1, "hf fudan view" }, + { 0, "hf fudan wrbl" }, + { 1, "hf gallagher help" }, + { 0, "hf gallagher reader" }, + { 0, "hf gallagher clone" }, + { 0, "hf gallagher delete" }, + { 1, "hf gallagher diversifykey" }, + { 1, "hf gallagher decode" }, + { 1, "hf ksx6924 help" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 initialize" }, + { 0, "hf ksx6924 prec" }, + { 0, "hf ksx6924 select" }, + { 1, "hf jooki help" }, + { 0, "hf jooki clone" }, + { 1, "hf jooki decode" }, + { 1, "hf jooki encode" }, + { 0, "hf jooki sim" }, + { 1, "hf iclass help" }, + { 0, "hf iclass dump" }, + { 1, "hf iclass info" }, + { 1, "hf iclass list" }, + { 0, "hf iclass rdbl" }, + { 0, "hf iclass reader" }, + { 0, "hf iclass restore" }, + { 0, "hf iclass sniff" }, + { 0, "hf iclass wrbl" }, + { 0, "hf iclass chk" }, + { 1, "hf iclass loclass" }, + { 1, "hf iclass lookup" }, + { 0, "hf iclass sim" }, + { 0, "hf iclass eload" }, + { 0, "hf iclass esave" }, + { 0, "hf iclass eview" }, + { 1, "hf iclass configcard" }, + { 1, "hf iclass calcnewkey" }, + { 1, "hf iclass encode" }, + { 1, "hf iclass encrypt" }, + { 1, "hf iclass decrypt" }, + { 1, "hf iclass managekeys" }, + { 1, "hf iclass permutekey" }, + { 1, "hf iclass view" }, + { 1, "hf legic help" }, + { 0, "hf legic dump" }, + { 0, "hf legic info" }, + { 1, "hf legic list" }, + { 0, "hf legic rdbl" }, + { 0, "hf legic reader" }, + { 0, "hf legic restore" }, + { 0, "hf legic wipe" }, + { 0, "hf legic wrbl" }, + { 0, "hf legic sim" }, + { 0, "hf legic eload" }, + { 0, "hf legic esave" }, + { 0, "hf legic eview" }, + { 1, "hf legic crc" }, + { 1, "hf legic view" }, + { 1, "hf lto help" }, + { 0, "hf lto dump" }, + { 0, "hf lto info" }, + { 1, "hf lto list" }, + { 0, "hf lto rdbl" }, + { 0, "hf lto reader" }, + { 0, "hf lto restore" }, + { 0, "hf lto wrbl" }, + { 1, "hf mf help" }, + { 1, "hf mf list" }, + { 0, "hf mf darkside" }, + { 0, "hf mf nested" }, + { 1, "hf mf hardnested" }, + { 0, "hf mf staticnested" }, + { 0, "hf mf autopwn" }, + { 0, "hf mf nack" }, + { 0, "hf mf chk" }, + { 0, "hf mf fchk" }, + { 1, "hf mf decrypt" }, + { 0, "hf mf supercard" }, + { 0, "hf mf auth4" }, + { 1, "hf mf acl" }, + { 0, "hf mf dump" }, + { 1, "hf mf mad" }, + { 0, "hf mf personalize" }, + { 0, "hf mf rdbl" }, + { 0, "hf mf rdsc" }, + { 0, "hf mf restore" }, + { 0, "hf mf setmod" }, + { 1, "hf mf value" }, + { 1, "hf mf view" }, + { 0, "hf mf wipe" }, + { 0, "hf mf wrbl" }, + { 0, "hf mf sim" }, + { 0, "hf mf ecfill" }, + { 0, "hf mf eclr" }, + { 0, "hf mf egetblk" }, + { 0, "hf mf egetsc" }, + { 0, "hf mf ekeyprn" }, + { 0, "hf mf eload" }, + { 0, "hf mf esave" }, + { 0, "hf mf esetblk" }, + { 0, "hf mf eview" }, + { 0, "hf mf cgetblk" }, + { 0, "hf mf cgetsc" }, + { 0, "hf mf cload" }, + { 0, "hf mf csave" }, + { 0, "hf mf csetblk" }, + { 0, "hf mf csetuid" }, + { 0, "hf mf cview" }, + { 0, "hf mf cwipe" }, + { 0, "hf mf gen3uid" }, + { 0, "hf mf gen3blk" }, + { 0, "hf mf gen3freeze" }, + { 0, "hf mf gview" }, + { 0, "hf mf ndefformat" }, + { 0, "hf mf ndefread" }, + { 0, "hf mf ndefwrite" }, + { 1, "hf mfp help" }, + { 0, "hf mfp info" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp auth" }, + { 0, "hf mfp rdbl" }, + { 0, "hf mfp rdsc" }, + { 0, "hf mfp wrbl" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp mad" }, + { 0, "hf mfp ndefread" }, + { 1, "hf mfu help" }, + { 1, "hf mfu keygen" }, + { 1, "hf mfu pwdgen" }, + { 0, "hf mfu otptear" }, + { 0, "hf mfu cauth" }, + { 0, "hf mfu dump" }, + { 0, "hf mfu info" }, + { 0, "hf mfu ndefread" }, + { 0, "hf mfu rdbl" }, + { 0, "hf mfu restore" }, + { 1, "hf mfu view" }, + { 0, "hf mfu wrbl" }, + { 0, "hf mfu eload" }, + { 0, "hf mfu eview" }, + { 0, "hf mfu sim" }, + { 0, "hf mfu setpwd" }, + { 0, "hf mfu setuid" }, + { 1, "hf mfdes help" }, + { 0, "hf mfdes info" }, + { 0, "hf mfdes getuid" }, + { 0, "hf mfdes default" }, + { 0, "hf mfdes auth" }, + { 0, "hf mfdes chk" }, + { 0, "hf mfdes detect" }, + { 0, "hf mfdes freemem" }, + { 0, "hf mfdes setconfig" }, + { 0, "hf mfdes formatpicc" }, + { 1, "hf mfdes list" }, + { 0, "hf mfdes mad" }, + { 0, "hf mfdes lsapp" }, + { 0, "hf mfdes getaids" }, + { 0, "hf mfdes getappnames" }, + { 0, "hf mfdes bruteaid" }, + { 0, "hf mfdes createapp" }, + { 0, "hf mfdes deleteapp" }, + { 0, "hf mfdes selectapp" }, + { 0, "hf mfdes changekey" }, + { 0, "hf mfdes chkeysettings" }, + { 0, "hf mfdes getkeysettings" }, + { 0, "hf mfdes getkeyversions" }, + { 0, "hf mfdes getfileids" }, + { 0, "hf mfdes getfileisoids" }, + { 0, "hf mfdes lsfiles" }, + { 0, "hf mfdes dump" }, + { 0, "hf mfdes createfile" }, + { 0, "hf mfdes createvaluefile" }, + { 0, "hf mfdes createrecordfile" }, + { 0, "hf mfdes createmacfile" }, + { 0, "hf mfdes deletefile" }, + { 0, "hf mfdes getfilesettings" }, + { 0, "hf mfdes chfilesettings" }, + { 0, "hf mfdes read" }, + { 0, "hf mfdes write" }, + { 0, "hf mfdes value" }, + { 0, "hf mfdes clearrecfile" }, + { 1, "hf mfdes test" }, + { 1, "hf ntag424 help" }, + { 0, "hf ntag424 info" }, + { 0, "hf ntag424 sdm" }, + { 1, "hf ntag424 view" }, + { 1, "hf seos help" }, + { 0, "hf seos info" }, + { 1, "hf seos list" }, + { 1, "hf st25ta help" }, + { 0, "hf st25ta info" }, + { 1, "hf st25ta list" }, + { 1, "hf st25ta ndefread" }, + { 0, "hf st25ta protect" }, + { 0, "hf st25ta pwd" }, + { 0, "hf st25ta sim" }, + { 1, "hf thinfilm help" }, + { 0, "hf thinfilm info" }, + { 1, "hf thinfilm list" }, + { 0, "hf thinfilm sim" }, + { 1, "hf topaz help" }, + { 0, "hf topaz dump" }, + { 1, "hf topaz list" }, + { 0, "hf topaz info" }, + { 0, "hf topaz reader" }, + { 0, "hf topaz sim" }, + { 0, "hf topaz sniff" }, + { 0, "hf topaz raw" }, + { 0, "hf topaz rdbl" }, + { 1, "hf topaz view" }, + { 0, "hf topaz wrbl" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, + { 0, "hf xerox dump" }, + { 1, "hf waveshare help" }, + { 0, "hf waveshare loadbmp" }, + { 1, "hw help" }, + { 0, "hw break" }, + { 1, "hw connect" }, + { 0, "hw dbg" }, + { 0, "hw detectreader" }, + { 0, "hw fpgaoff" }, + { 0, "hw lcd" }, + { 0, "hw lcdreset" }, + { 0, "hw ping" }, + { 0, "hw readmem" }, + { 0, "hw reset" }, + { 0, "hw setlfdivisor" }, + { 0, "hw setmux" }, + { 0, "hw standalone" }, + { 0, "hw status" }, + { 0, "hw tearoff" }, + { 0, "hw tia" }, + { 0, "hw tune" }, + { 1, "hw version" }, + { 1, "lf help" }, + { 0, "lf config" }, + { 0, "lf cmdread" }, + { 0, "lf read" }, + { 1, "lf search" }, + { 0, "lf sim" }, + { 0, "lf simask" }, + { 0, "lf simfsk" }, + { 0, "lf simpsk" }, + { 0, "lf simbidir" }, + { 0, "lf sniff" }, + { 0, "lf tune" }, + { 1, "lf awid help" }, + { 1, "lf awid demod" }, + { 0, "lf awid reader" }, + { 0, "lf awid clone" }, + { 0, "lf awid sim" }, + { 0, "lf awid brute" }, + { 0, "lf awid watch" }, + { 1, "lf cotag help" }, + { 1, "lf cotag demod" }, + { 0, "lf cotag reader" }, + { 1, "lf destron help" }, + { 1, "lf destron demod" }, + { 0, "lf destron reader" }, + { 0, "lf destron clone" }, + { 0, "lf destron sim" }, + { 1, "lf em help" }, + { 1, "lf em 410x help" }, + { 1, "lf em 410x demod" }, + { 0, "lf em 410x reader" }, + { 0, "lf em 410x sim" }, + { 0, "lf em 410x brute" }, + { 0, "lf em 410x watch" }, + { 0, "lf em 410x spoof" }, + { 0, "lf em 410x clone" }, + { 1, "lf em 4x05 help" }, + { 0, "lf em 4x05 brute" }, + { 0, "lf em 4x05 chk" }, + { 1, "lf em 4x05 demod" }, + { 0, "lf em 4x05 dump" }, + { 0, "lf em 4x05 info" }, + { 0, "lf em 4x05 read" }, + { 1, "lf em 4x05 sniff" }, + { 0, "lf em 4x05 unlock" }, + { 0, "lf em 4x05 wipe" }, + { 0, "lf em 4x05 write" }, + { 1, "lf em 4x50 help" }, + { 0, "lf em 4x50 brute" }, + { 0, "lf em 4x50 chk" }, + { 0, "lf em 4x50 dump" }, + { 0, "lf em 4x50 info" }, + { 0, "lf em 4x50 login" }, + { 0, "lf em 4x50 rdbl" }, + { 0, "lf em 4x50 reader" }, + { 0, "lf em 4x50 restore" }, + { 0, "lf em 4x50 wrbl" }, + { 0, "lf em 4x50 wrpwd" }, + { 0, "lf em 4x50 wipe" }, + { 0, "lf em 4x50 eload" }, + { 0, "lf em 4x50 esave" }, + { 0, "lf em 4x50 eview" }, + { 0, "lf em 4x50 sim" }, + { 1, "lf em 4x70 help" }, + { 0, "lf em 4x70 info" }, + { 0, "lf em 4x70 write" }, + { 0, "lf em 4x70 unlock" }, + { 0, "lf em 4x70 auth" }, + { 0, "lf em 4x70 writepin" }, + { 0, "lf em 4x70 writekey" }, + { 1, "lf fdxb help" }, + { 1, "lf fdxb demod" }, + { 0, "lf fdxb reader" }, + { 0, "lf fdxb clone" }, + { 0, "lf fdxb sim" }, + { 1, "lf gallagher help" }, + { 1, "lf gallagher demod" }, + { 0, "lf gallagher reader" }, + { 0, "lf gallagher clone" }, + { 0, "lf gallagher sim" }, + { 1, "lf gproxii help" }, + { 1, "lf gproxii demod" }, + { 0, "lf gproxii reader" }, + { 0, "lf gproxii clone" }, + { 0, "lf gproxii sim" }, + { 1, "lf hid help" }, + { 1, "lf hid demod" }, + { 0, "lf hid reader" }, + { 0, "lf hid clone" }, + { 0, "lf hid sim" }, + { 0, "lf hid brute" }, + { 0, "lf hid watch" }, + { 1, "lf hitag help" }, + { 0, "lf hitag eload" }, + { 1, "lf hitag list" }, + { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, + { 0, "lf hitag sim" }, + { 0, "lf hitag sniff" }, + { 0, "lf hitag writer" }, + { 0, "lf hitag dump" }, + { 0, "lf hitag cc" }, + { 1, "lf idteck help" }, + { 1, "lf idteck demod" }, + { 0, "lf idteck reader" }, + { 0, "lf idteck clone" }, + { 0, "lf idteck sim" }, + { 1, "lf indala help" }, + { 1, "lf indala demod" }, + { 1, "lf indala altdemod" }, + { 0, "lf indala reader" }, + { 0, "lf indala clone" }, + { 0, "lf indala sim" }, + { 1, "lf io help" }, + { 1, "lf io demod" }, + { 0, "lf io reader" }, + { 0, "lf io clone" }, + { 0, "lf io sim" }, + { 0, "lf io watch" }, + { 1, "lf jablotron help" }, + { 1, "lf jablotron demod" }, + { 0, "lf jablotron reader" }, + { 0, "lf jablotron clone" }, + { 0, "lf jablotron sim" }, + { 1, "lf keri help" }, + { 1, "lf keri demod" }, + { 0, "lf keri reader" }, + { 0, "lf keri clone" }, + { 0, "lf keri sim" }, + { 1, "lf motorola help" }, + { 1, "lf motorola demod" }, + { 0, "lf motorola reader" }, + { 0, "lf motorola clone" }, + { 0, "lf motorola sim" }, + { 1, "lf nedap help" }, + { 1, "lf nedap demod" }, + { 0, "lf nedap reader" }, + { 0, "lf nedap clone" }, + { 0, "lf nedap sim" }, + { 1, "lf nexwatch help" }, + { 1, "lf nexwatch demod" }, + { 0, "lf nexwatch reader" }, + { 0, "lf nexwatch clone" }, + { 0, "lf nexwatch sim" }, + { 1, "lf noralsy help" }, + { 1, "lf noralsy demod" }, + { 0, "lf noralsy reader" }, + { 0, "lf noralsy clone" }, + { 0, "lf noralsy sim" }, + { 1, "lf pac help" }, + { 1, "lf pac demod" }, + { 0, "lf pac reader" }, + { 0, "lf pac clone" }, + { 0, "lf pac sim" }, + { 1, "lf paradox help" }, + { 1, "lf paradox demod" }, + { 0, "lf paradox reader" }, + { 0, "lf paradox clone" }, + { 0, "lf paradox sim" }, + { 1, "lf pcf7931 help" }, + { 0, "lf pcf7931 reader" }, + { 0, "lf pcf7931 write" }, + { 1, "lf pcf7931 config" }, + { 1, "lf presco help" }, + { 1, "lf presco demod" }, + { 0, "lf presco reader" }, + { 0, "lf presco clone" }, + { 0, "lf presco sim" }, + { 1, "lf pyramid help" }, + { 1, "lf pyramid demod" }, + { 0, "lf pyramid reader" }, + { 0, "lf pyramid clone" }, + { 0, "lf pyramid sim" }, + { 1, "lf securakey help" }, + { 1, "lf securakey demod" }, + { 0, "lf securakey reader" }, + { 0, "lf securakey clone" }, + { 0, "lf securakey sim" }, + { 1, "lf ti help" }, + { 1, "lf ti demod" }, + { 0, "lf ti reader" }, + { 0, "lf ti write" }, + { 1, "lf t55xx help" }, + { 0, "lf t55xx clonehelp" }, + { 1, "lf t55xx config" }, + { 0, "lf t55xx dangerraw" }, + { 1, "lf t55xx detect" }, + { 0, "lf t55xx deviceconfig" }, + { 0, "lf t55xx dump" }, + { 1, "lf t55xx info" }, + { 0, "lf t55xx p1detect" }, + { 0, "lf t55xx read" }, + { 0, "lf t55xx resetread" }, + { 0, "lf t55xx restore" }, + { 1, "lf t55xx trace" }, + { 0, "lf t55xx wakeup" }, + { 0, "lf t55xx write" }, + { 0, "lf t55xx bruteforce" }, + { 0, "lf t55xx chk" }, + { 0, "lf t55xx protect" }, + { 0, "lf t55xx recoverpw" }, + { 1, "lf t55xx sniff" }, + { 0, "lf t55xx special" }, + { 0, "lf t55xx wipe" }, + { 1, "lf viking help" }, + { 1, "lf viking demod" }, + { 0, "lf viking reader" }, + { 0, "lf viking clone" }, + { 0, "lf viking sim" }, + { 1, "lf visa2000 help" }, + { 1, "lf visa2000 demod" }, + { 0, "lf visa2000 reader" }, + { 0, "lf visa2000 clone" }, + { 0, "lf visa2000 sim" }, + { 1, "mem help" }, + { 0, "mem baudrate" }, + { 0, "mem dump" }, + { 0, "mem info" }, + { 0, "mem load" }, + { 0, "mem wipe" }, + { 1, "mem spiffs help" }, + { 0, "mem spiffs copy" }, + { 0, "mem spiffs check" }, + { 0, "mem spiffs dump" }, + { 0, "mem spiffs info" }, + { 0, "mem spiffs mount" }, + { 0, "mem spiffs remove" }, + { 0, "mem spiffs rename" }, + { 0, "mem spiffs test" }, + { 0, "mem spiffs tree" }, + { 0, "mem spiffs unmount" }, + { 0, "mem spiffs upload" }, + { 0, "mem spiffs view" }, + { 0, "mem spiffs wipe" }, + { 1, "nfc help" }, + { 1, "nfc decode" }, + { 0, "nfc type1 read" }, + { 1, "nfc type1 help" }, + { 0, "nfc type2 read" }, + { 1, "nfc type2 help" }, + { 0, "nfc type4a format" }, + { 0, "nfc type4a read" }, + { 0, "nfc type4a write" }, + { 0, "nfc type4a st25taread" }, + { 1, "nfc type4a help" }, + { 0, "nfc type4b read" }, + { 1, "nfc type4b help" }, + { 0, "nfc mf cformat" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf cwrite" }, + { 0, "nfc mf pread" }, + { 1, "nfc mf help" }, + { 0, "nfc barcode read" }, + { 0, "nfc barcode sim" }, + { 1, "nfc barcode help" }, + { 1, "smart help" }, + { 1, "smart list" }, + { 0, "smart info" }, + { 0, "smart reader" }, + { 0, "smart raw" }, + { 1, "smart upgrade" }, + { 0, "smart setclock" }, + { 0, "smart brute" }, + { 1, "script help" }, + { 1, "script list" }, + { 1, "script run" }, + { 1, "trace help" }, + { 1, "trace extract" }, + { 1, "trace list" }, + { 1, "trace load" }, + { 1, "trace save" }, + { 1, "usart help" }, + { 0, "usart btpin" }, + { 0, "usart btfactory" }, + { 0, "usart tx" }, + { 0, "usart rx" }, + { 0, "usart txrx" }, + { 0, "usart txhex" }, + { 0, "usart rxhex" }, + { 0, "usart config" }, + { 1, "wiegand help" }, + { 1, "wiegand list" }, + { 1, "wiegand encode" }, + { 1, "wiegand decode" }, {0, NULL} }; @@ -766,4 +766,4 @@ const static vocabulory_t vocabulory[] = { } #endif -#endif \ No newline at end of file +#endif From 93ca7b4f6e418f37b52c10cb0fbc80249e643003 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 01:34:05 +0200 Subject: [PATCH 319/759] Release v4.15864 - Radium --- Makefile.defs | 4 ++-- armsrc/Makefile | 2 +- bootrom/Makefile | 2 +- client/CMakeLists.txt | 4 ++-- client/Makefile | 4 ++-- client/deps/amiibo.cmake | 2 +- client/deps/cliparser.cmake | 2 +- client/deps/hardnested.cmake | 18 +++++++++--------- client/deps/jansson.cmake | 2 +- client/deps/lua.cmake | 2 +- client/deps/mbedtls.cmake | 2 +- client/deps/reveng.cmake | 2 +- client/deps/tinycbor.cmake | 2 +- client/deps/whereami.cmake | 2 +- client/src/proxmark3.c | 2 +- common/default_version_pm3.c | 27 +++++++-------------------- common_arm/Makefile.common | 2 +- 17 files changed, 34 insertions(+), 47 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 8f9d5f271..57132d8d0 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -104,8 +104,8 @@ ifeq ($(DEBUG),1) DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe DEFLDFLAGS = else - DEFCXXFLAGS = -Wall -Werror -O3 -pipe - DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe + DEFCXXFLAGS = -Wall -O3 -pipe + DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe DEFLDFLAGS = endif diff --git a/armsrc/Makefile b/armsrc/Makefile index c0703ccf4..0d4803788 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -187,7 +187,7 @@ showinfo: # version_pm3.c should be remade on every time fullimage.stage1.elf should be remade version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(info [-] GEN $@) - $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(info [-] GEN $@) diff --git a/bootrom/Makefile b/bootrom/Makefile index ec531f1af..fbff3fedf 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -50,7 +50,7 @@ OBJS = $(OBJDIR)/bootrom.s19 # version_pm3.c should be remade on every compilation version_pm3.c: default_version_pm3.c $(info [=] GEN $@) - $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ all: showinfo $(OBJS) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index a34348413..50c53aa54 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -362,7 +362,7 @@ set (TARGET_SOURCES add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c - COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c + COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c ) @@ -563,7 +563,7 @@ add_executable(proxmark3 ${ADDITIONAL_SRC} ) -target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) +target_compile_options(proxmark3 PUBLIC -Wall -O3) if (EMBED_READLINE) if (NOT SKIPREADLINE EQUAL 1) add_dependencies(proxmark3 ncurses readline) diff --git a/client/Makefile b/client/Makefile index 500e820f0..bd35b9fe5 100644 --- a/client/Makefile +++ b/client/Makefile @@ -408,7 +408,7 @@ endif PM3CFLAGS += -DHAVE_SNPRINTF -CXXFLAGS ?= -Wall -Werror -O3 +CXXFLAGS ?= -Wall -O3 CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES) PM3CXXFLAGS = $(CXXFLAGS) @@ -900,7 +900,7 @@ src/pm3_pywrap.c: pm3.i # version_pm3.c should be remade on every compilation src/version_pm3.c: default_version_pm3.c .FORCE $(info [=] GEN $@) - $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) diff --git a/client/deps/amiibo.cmake b/client/deps/amiibo.cmake index c946c0682..8c524c170 100644 --- a/client/deps/amiibo.cmake +++ b/client/deps/amiibo.cmake @@ -19,7 +19,7 @@ target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE m pm3rrg_rdv4_mbedtls) -target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool diff --git a/client/deps/cliparser.cmake b/client/deps/cliparser.cmake index fccae33b7..a85cc2374 100644 --- a/client/deps/cliparser.cmake +++ b/client/deps/cliparser.cmake @@ -9,5 +9,5 @@ target_include_directories(pm3rrg_rdv4_cliparser PRIVATE ../../include ../src) target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser) -target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index 524d4c939..290415173 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -2,7 +2,7 @@ add_library(pm3rrg_rdv4_hardnested_nosimd OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) -target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE @@ -32,7 +32,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE -mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -47,7 +47,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE -mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -62,7 +62,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE -mmmx -msse2 -mavx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -77,7 +77,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -92,7 +92,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mavx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -116,7 +116,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM64_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE @@ -134,7 +134,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM32_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE -mfpu=neon) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -155,7 +155,7 @@ add_library(pm3rrg_rdv4_hardnested STATIC hardnested/hardnested_bruteforce.c $ ${SIMD_TARGETS}) -target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested PRIVATE ../../common diff --git a/client/deps/jansson.cmake b/client/deps/jansson.cmake index c91a47047..42c701d5e 100644 --- a/client/deps/jansson.cmake +++ b/client/deps/jansson.cmake @@ -14,5 +14,5 @@ add_library(pm3rrg_rdv4_jansson STATIC target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H) target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson) -target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Werror -Wno-unused-function -O3) +target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Wno-unused-function -O3) set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/lua.cmake b/client/deps/lua.cmake index 12870342e..5cf33d724 100644 --- a/client/deps/lua.cmake +++ b/client/deps/lua.cmake @@ -52,5 +52,5 @@ if (NOT MINGW) endif (NOT MINGW) target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua) -target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/mbedtls.cmake b/client/deps/mbedtls.cmake index 40929e1ea..c726ddeba 100644 --- a/client/deps/mbedtls.cmake +++ b/client/deps/mbedtls.cmake @@ -44,5 +44,5 @@ add_library(pm3rrg_rdv4_mbedtls STATIC target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common) target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls) -target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/reveng.cmake b/client/deps/reveng.cmake index d7e3cfd8a..1040730f1 100644 --- a/client/deps/reveng.cmake +++ b/client/deps/reveng.cmake @@ -13,5 +13,5 @@ target_include_directories(pm3rrg_rdv4_reveng PRIVATE ../src ../../include) target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng) -target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/tinycbor.cmake b/client/deps/tinycbor.cmake index 5a6abda25..c74618149 100644 --- a/client/deps/tinycbor.cmake +++ b/client/deps/tinycbor.cmake @@ -11,5 +11,5 @@ add_library(pm3rrg_rdv4_tinycbor STATIC target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor) # Strange errors on Mingw when compiling with -O3 -target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -Werror -O2) +target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -O2) set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/whereami.cmake b/client/deps/whereami.cmake index d2d6a5b2a..721873066 100644 --- a/client/deps/whereami.cmake +++ b/client/deps/whereami.cmake @@ -2,5 +2,5 @@ add_library(pm3rrg_rdv4_whereami STATIC whereami/whereami.c) target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED) target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami) -target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 9ca38a2a1..a523e07f6 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -42,7 +42,7 @@ static int mainret = PM3_ESOFT; #ifndef LIBPM3 #define BANNERMSG1 "" #define BANNERMSG2 " [ :snowflake: ]" -#define BANNERMSG3 "" +#define BANNERMSG3 "Release v4.15864 - Radium" typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode; diff --git a/common/default_version_pm3.c b/common/default_version_pm3.c index 46eac57c9..4487813e9 100644 --- a/common/default_version_pm3.c +++ b/common/default_version_pm3.c @@ -1,20 +1,5 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- #include "common.h" -/* This is the default version_pm3.c file that Makefile.common falls back to if sh is not available */ +/* Generated file, do not edit */ #ifndef ON_DEVICE #define SECTVERSINFO #else @@ -23,8 +8,10 @@ const struct version_information_t SECTVERSINFO g_version_information = { VERSION_INFORMATION_MAGIC, - 1, /* version 1 */ - 0, /* version information not present */ - 2, /* cleanliness couldn't be determined */ - /* Remaining fields: zero */ + 1, + 1, + 1, + "Iceman/master/v4.15864", + "2022-10-29 01:34:05", + "844ca091a" }; diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index 99f4d9ecd..e40d998a6 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -49,7 +49,7 @@ VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/ INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h ARMCFLAGS = -mthumb-interwork -fno-builtin -DEFCFLAGS = -Wall -Werror -Os -pedantic -fstrict-aliasing -pipe +DEFCFLAGS = -Wall -Os -pedantic -fstrict-aliasing -pipe # Some more warnings we want as errors: DEFCFLAGS += -Wbad-function-cast -Wchar-subscripts -Wundef -Wunused -Wuninitialized -Wpointer-arith -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits From 063e2da49da348ca18aeb7d8cf51a5dfe069274a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 01:34:05 +0200 Subject: [PATCH 320/759] Revert "Release v4.15864 - Radium" This reverts commit 93ca7b4f6e418f37b52c10cb0fbc80249e643003. --- Makefile.defs | 4 ++-- armsrc/Makefile | 2 +- bootrom/Makefile | 2 +- client/CMakeLists.txt | 4 ++-- client/Makefile | 4 ++-- client/deps/amiibo.cmake | 2 +- client/deps/cliparser.cmake | 2 +- client/deps/hardnested.cmake | 18 +++++++++--------- client/deps/jansson.cmake | 2 +- client/deps/lua.cmake | 2 +- client/deps/mbedtls.cmake | 2 +- client/deps/reveng.cmake | 2 +- client/deps/tinycbor.cmake | 2 +- client/deps/whereami.cmake | 2 +- client/src/proxmark3.c | 2 +- common/default_version_pm3.c | 27 ++++++++++++++++++++------- common_arm/Makefile.common | 2 +- 17 files changed, 47 insertions(+), 34 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index 57132d8d0..8f9d5f271 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -104,8 +104,8 @@ ifeq ($(DEBUG),1) DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe DEFLDFLAGS = else - DEFCXXFLAGS = -Wall -O3 -pipe - DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe + DEFCXXFLAGS = -Wall -Werror -O3 -pipe + DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe DEFLDFLAGS = endif diff --git a/armsrc/Makefile b/armsrc/Makefile index 0d4803788..c0703ccf4 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -187,7 +187,7 @@ showinfo: # version_pm3.c should be remade on every time fullimage.stage1.elf should be remade version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) $(info [-] GEN $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(info [-] GEN $@) diff --git a/bootrom/Makefile b/bootrom/Makefile index fbff3fedf..ec531f1af 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -50,7 +50,7 @@ OBJS = $(OBJDIR)/bootrom.s19 # version_pm3.c should be remade on every compilation version_pm3.c: default_version_pm3.c $(info [=] GEN $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@ all: showinfo $(OBJS) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 50c53aa54..a34348413 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -362,7 +362,7 @@ set (TARGET_SOURCES add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c - COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c + COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c ) @@ -563,7 +563,7 @@ add_executable(proxmark3 ${ADDITIONAL_SRC} ) -target_compile_options(proxmark3 PUBLIC -Wall -O3) +target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) if (EMBED_READLINE) if (NOT SKIPREADLINE EQUAL 1) add_dependencies(proxmark3 ncurses readline) diff --git a/client/Makefile b/client/Makefile index bd35b9fe5..500e820f0 100644 --- a/client/Makefile +++ b/client/Makefile @@ -408,7 +408,7 @@ endif PM3CFLAGS += -DHAVE_SNPRINTF -CXXFLAGS ?= -Wall -O3 +CXXFLAGS ?= -Wall -Werror -O3 CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES) PM3CXXFLAGS = $(CXXFLAGS) @@ -900,7 +900,7 @@ src/pm3_pywrap.c: pm3.i # version_pm3.c should be remade on every compilation src/version_pm3.c: default_version_pm3.c .FORCE $(info [=] GEN $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) diff --git a/client/deps/amiibo.cmake b/client/deps/amiibo.cmake index 8c524c170..c946c0682 100644 --- a/client/deps/amiibo.cmake +++ b/client/deps/amiibo.cmake @@ -19,7 +19,7 @@ target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE m pm3rrg_rdv4_mbedtls) -target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool diff --git a/client/deps/cliparser.cmake b/client/deps/cliparser.cmake index a85cc2374..fccae33b7 100644 --- a/client/deps/cliparser.cmake +++ b/client/deps/cliparser.cmake @@ -9,5 +9,5 @@ target_include_directories(pm3rrg_rdv4_cliparser PRIVATE ../../include ../src) target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser) -target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index 290415173..524d4c939 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -2,7 +2,7 @@ add_library(pm3rrg_rdv4_hardnested_nosimd OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) -target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE @@ -32,7 +32,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE -mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -47,7 +47,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE -mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -62,7 +62,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE -mmmx -msse2 -mavx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -77,7 +77,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -92,7 +92,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mavx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -116,7 +116,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM64_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE @@ -134,7 +134,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM32_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE -mfpu=neon) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -155,7 +155,7 @@ add_library(pm3rrg_rdv4_hardnested STATIC hardnested/hardnested_bruteforce.c $ ${SIMD_TARGETS}) -target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested PRIVATE ../../common diff --git a/client/deps/jansson.cmake b/client/deps/jansson.cmake index 42c701d5e..c91a47047 100644 --- a/client/deps/jansson.cmake +++ b/client/deps/jansson.cmake @@ -14,5 +14,5 @@ add_library(pm3rrg_rdv4_jansson STATIC target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H) target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson) -target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Wno-unused-function -O3) +target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Werror -Wno-unused-function -O3) set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/lua.cmake b/client/deps/lua.cmake index 5cf33d724..12870342e 100644 --- a/client/deps/lua.cmake +++ b/client/deps/lua.cmake @@ -52,5 +52,5 @@ if (NOT MINGW) endif (NOT MINGW) target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua) -target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/mbedtls.cmake b/client/deps/mbedtls.cmake index c726ddeba..40929e1ea 100644 --- a/client/deps/mbedtls.cmake +++ b/client/deps/mbedtls.cmake @@ -44,5 +44,5 @@ add_library(pm3rrg_rdv4_mbedtls STATIC target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common) target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls) -target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/reveng.cmake b/client/deps/reveng.cmake index 1040730f1..d7e3cfd8a 100644 --- a/client/deps/reveng.cmake +++ b/client/deps/reveng.cmake @@ -13,5 +13,5 @@ target_include_directories(pm3rrg_rdv4_reveng PRIVATE ../src ../../include) target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng) -target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/tinycbor.cmake b/client/deps/tinycbor.cmake index c74618149..5a6abda25 100644 --- a/client/deps/tinycbor.cmake +++ b/client/deps/tinycbor.cmake @@ -11,5 +11,5 @@ add_library(pm3rrg_rdv4_tinycbor STATIC target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor) # Strange errors on Mingw when compiling with -O3 -target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -O2) +target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -Werror -O2) set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/whereami.cmake b/client/deps/whereami.cmake index 721873066..d2d6a5b2a 100644 --- a/client/deps/whereami.cmake +++ b/client/deps/whereami.cmake @@ -2,5 +2,5 @@ add_library(pm3rrg_rdv4_whereami STATIC whereami/whereami.c) target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED) target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami) -target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index a523e07f6..9ca38a2a1 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -42,7 +42,7 @@ static int mainret = PM3_ESOFT; #ifndef LIBPM3 #define BANNERMSG1 "" #define BANNERMSG2 " [ :snowflake: ]" -#define BANNERMSG3 "Release v4.15864 - Radium" +#define BANNERMSG3 "" typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode; diff --git a/common/default_version_pm3.c b/common/default_version_pm3.c index 4487813e9..46eac57c9 100644 --- a/common/default_version_pm3.c +++ b/common/default_version_pm3.c @@ -1,5 +1,20 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- #include "common.h" -/* Generated file, do not edit */ +/* This is the default version_pm3.c file that Makefile.common falls back to if sh is not available */ #ifndef ON_DEVICE #define SECTVERSINFO #else @@ -8,10 +23,8 @@ const struct version_information_t SECTVERSINFO g_version_information = { VERSION_INFORMATION_MAGIC, - 1, - 1, - 1, - "Iceman/master/v4.15864", - "2022-10-29 01:34:05", - "844ca091a" + 1, /* version 1 */ + 0, /* version information not present */ + 2, /* cleanliness couldn't be determined */ + /* Remaining fields: zero */ }; diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index e40d998a6..99f4d9ecd 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -49,7 +49,7 @@ VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/ INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h ARMCFLAGS = -mthumb-interwork -fno-builtin -DEFCFLAGS = -Wall -Os -pedantic -fstrict-aliasing -pipe +DEFCFLAGS = -Wall -Werror -Os -pedantic -fstrict-aliasing -pipe # Some more warnings we want as errors: DEFCFLAGS += -Wbad-function-cast -Wchar-subscripts -Wundef -Wunused -Wuninitialized -Wpointer-arith -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits From 1f75adcf6d94e52e644d0e903b93072ff527e63c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 29 Oct 2022 01:36:19 +0200 Subject: [PATCH 321/759] release --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78ac5dde8..6914e60a9 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] + +## [Radium.4.15864][2022-10-29] - Added `hf 14a ndefwrite` - write raw NDEF records to TYPE4A tags (@iceman1001) - Changed ndef output to be more dense. Honors verbose now (@iceman1001) - Fixed `hf mf ndefwrite` - now skips not ndef formatted sectors (@iceman1001) From 043fed010334e5e757d6947f0b234133efe6201a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 30 Oct 2022 08:54:13 +0100 Subject: [PATCH 322/759] added lf indala brute command. Based on lf hid brute, can go up and down in cardnumbers --- CHANGELOG.md | 1 + client/src/cmdlfindala.c | 205 +++++++++++++++++++++++++++++++++++++++ doc/commands.json | 64 +++++++++--- doc/commands.md | 4 +- 4 files changed, 261 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6914e60a9..8a82f766f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] ## [Radium.4.15864][2022-10-29] + - Added `lf indala brute`- brute forcing of 64b Indala ID (@iceman1001) - Added `hf 14a ndefwrite` - write raw NDEF records to TYPE4A tags (@iceman1001) - Changed ndef output to be more dense. Honors verbose now (@iceman1001) - Fixed `hf mf ndefwrite` - now skips not ndef formatted sectors (@iceman1001) diff --git a/client/src/cmdlfindala.c b/client/src/cmdlfindala.c index 9b174c74a..bd20f15db 100644 --- a/client/src/cmdlfindala.c +++ b/client/src/cmdlfindala.c @@ -37,6 +37,8 @@ #include "cliparser.h" #include "cmdlfem4x05.h" // EM defines #include "parity.h" // parity +#include "util_posix.h" + #define INDALA_ARR_LEN 64 static int CmdHelp(const char *Cmd); @@ -121,6 +123,72 @@ static void decodeHeden2L(uint8_t *bits) { PrintAndLogEx(SUCCESS, " Heden-2L | %u", cardnumber); } +// sending three times. Didn't seem to break the previous sim? +static int sendPing(void) { + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + SendCommandNG(CMD_PING, NULL, 0); + clearCommandBuffer(); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_PING, &resp, 1000) == false) { + return PM3_ETIMEOUT; + } + return PM3_SUCCESS; +} + +static int sendTry(uint8_t fc, uint16_t cn, uint32_t delay, bool fmt4041x, bool verbose) { + + // convert to fc / cn to binarray + uint8_t bs[64]; + memset(bs, 0x00, sizeof(bs)); + + // Bitstream generation, format select + int res; + if (fmt4041x) { + res = getIndalaBits4041x(fc, cn, bs); + } else { + res = getIndalaBits(fc, cn, bs); + } + + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Error with tag bitstream generation."); + return res; + } + + if (verbose) { + + uint8_t raw[8]; + raw[0] = bytebits_to_byte(bs, 8); + raw[1] = bytebits_to_byte(bs + 8, 8); + raw[2] = bytebits_to_byte(bs + 16, 8); + raw[3] = bytebits_to_byte(bs + 24, 8); + raw[4] = bytebits_to_byte(bs + 32, 8); + raw[5] = bytebits_to_byte(bs + 40, 8); + raw[6] = bytebits_to_byte(bs + 48, 8); + raw[7] = bytebits_to_byte(bs + 56, 8); + + PrintAndLogEx(INFO, "Trying FC: " _YELLOW_("%u") " CN: " _YELLOW_("%u") " Raw: " _YELLOW_("%s") + , fc + , cn + , sprint_hex_inrow(raw, sizeof(raw)) + ); + } + + // indala PSK, clock 32, carrier 0 + lf_psksim_t *payload = calloc(1, sizeof(lf_psksim_t) + sizeof(bs)); + payload->carrier = 2; + payload->invert = 0; + payload->clock = 32; + memcpy(payload->data, bs, sizeof(bs)); + + clearCommandBuffer(); + SendCommandNG(CMD_LF_PSK_SIMULATE, (uint8_t *)payload, sizeof(lf_psksim_t) + sizeof(bs)); + free(payload); + + msleep(delay); + return sendPing(); +} + + // Indala 26 bit decode // by marshmellow, martinbeier // optional arguments - same as PSKDemod (clock & invert & maxerr) @@ -823,8 +891,145 @@ static int CmdIndalaClone(const char *Cmd) { return res; } +static int CmdIndalaBrute(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf indala brute", + "Enables bruteforce of INDALA readers with specified facility code.\n" + "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step\n" + "if cardnumber is not given, it starts with 1 and goes up to 65535", + "lf indala brute --fc 224\n" + "lf indala brute --fc 21 -d 2000\n" + "lf indala brute -v --fc 21 --cn 200 -d 2000\n" + "lf indala brute -v --fc 21 --cn 200 -d 2000 --up\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0("v", "verbose", "verbose output"), + arg_u64_0(NULL, "fc", "", "facility code"), + arg_u64_0(NULL, "cn", "", "card number to start with"), + arg_u64_0("d", "delay", "", "delay betweens attempts in ms. Default 1000ms"), + arg_lit0(NULL, "up", "direction to increment card number. (default is both directions)"), + arg_lit0(NULL, "down", "direction to decrement card number. (default is both directions)"), + arg_lit0(NULL, "4041x", "specify Indala 4041X format"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + bool verbose = arg_get_lit(ctx, 1); + + uint32_t fc = arg_get_u32_def(ctx, 2, 0); + uint32_t cn = arg_get_u32_def(ctx, 3, 0); + + uint32_t delay = arg_get_u32_def(ctx, 4, 1000); + + int direction = 0; + if (arg_get_lit(ctx, 5) && arg_get_lit(ctx, 6)) { + direction = 0; + } else if (arg_get_lit(ctx, 5)) { + direction = 1; + } else if (arg_get_lit(ctx, 6)) { + direction = 2; + } + + bool fmt4041x = arg_get_lit(ctx, 7); + CLIParserFree(ctx); + + if (verbose) { + PrintAndLogEx(INFO, "Wiegand format... " _YELLOW_("%s"), (fmt4041x) ? "4041x" : "Standard"); + PrintAndLogEx(INFO, "Facility code.... " _YELLOW_("%u"), fc); + PrintAndLogEx(INFO, "Card number...... " _YELLOW_("%u"), cn); + PrintAndLogEx(INFO, "Delay............ " _YELLOW_("%d"), delay); + switch (direction) { + case 0: + PrintAndLogEx(INFO, "Direction........ " _YELLOW_("BOTH")); + break; + case 1: + PrintAndLogEx(INFO, "Direction........ " _YELLOW_("UP")); + break; + case 2: + PrintAndLogEx(INFO, "Direction........ " _YELLOW_("DOWN")); + break; + default: + break; + } + } + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "Started brute-forcing INDALA Prox reader"); + PrintAndLogEx(INFO, "Press " _GREEN_("") " or pm3-button to abort simulation"); + PrintAndLogEx(NORMAL, ""); + + // main loop + // iceman: could add options for bruteforcing FC as well.. + uint8_t fc_hi = fc; + uint8_t fc_low = fc; + uint16_t cn_hi = cn; + uint16_t cn_low = cn; + + bool exitloop = false; + bool fin_hi, fin_low; + fin_hi = fin_low = false; + do { + + if (g_session.pm3_present == false) { + PrintAndLogEx(WARNING, "Device offline\n"); + return PM3_ENODATA; + } + + if (kbd_enter_pressed()) { + PrintAndLogEx(WARNING, "aborted via keyboard!"); + return sendPing(); + } + + // do one up + if (direction != 2) { + if (cn_hi < 0xFFFF) { + if (sendTry(fc_hi, cn_hi, delay, fmt4041x, verbose) != PM3_SUCCESS) { + return PM3_ESOFT; + } + cn_hi++; + } else { + fin_hi = true; + } + } + + // do one down + if (direction != 1) { + if (cn_low > 0) { + cn_low--; + if (sendTry(fc_low, cn_low, delay, fmt4041x, verbose) != PM3_SUCCESS) { + return PM3_ESOFT; + } + } else { + fin_low = true; + } + } + + switch (direction) { + case 0: + if (fin_hi && fin_low) { + exitloop = true; + } + break; + case 1: + exitloop = fin_hi; + break; + case 2: + exitloop = fin_low; + break; + default: + break; + } + + } while (exitloop == false); + + PrintAndLogEx(INFO, "Brute forcing finished"); + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"brute", CmdIndalaBrute, IfPm3Lf, "Demodulate an Indala tag (PSK1) from the GraphBuffer"}, {"demod", CmdIndalaDemod, AlwaysAvailable, "Demodulate an Indala tag (PSK1) from the GraphBuffer"}, {"altdemod", CmdIndalaDemodAlt, AlwaysAvailable, "Alternative method to demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, {"reader", CmdIndalaReader, IfPm3Lf, "Read an Indala tag from the antenna"}, diff --git a/doc/commands.json b/doc/commands.json index 118f6332b..76c8aa781 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -2272,11 +2272,11 @@ "options": [], "usage": "" }, - "hf epa preplay": { - "command": "hf epa preplay", + "hf epa replay": { + "command": "hf epa replay", "description": "Perform PACE protocol by replaying given APDUs", "notes": [ - "hf epa preplay --mse 0022C1A4 --get 1068000000 --map 1086000002 --pka 1234ABCDEF --ma 1A2B3C4D" + "hf epa replay --mse 0022C1A4 --get 1068000000 --map 1086000002 --pka 1234ABCDEF --ma 1A2B3C4D" ], "offline": false, "options": [ @@ -2287,7 +2287,23 @@ "--pka pka APDU", "--ma ma APDU" ], - "usage": "hf epa preplay [-h] --mse --get --map --pka --ma " + "usage": "hf epa replay [-h] --mse --get --map --pka --ma " + }, + "hf epa sim": { + "command": "hf epa sim", + "description": "Simulate PACE protocol with given password pwd of type pty. The crypto is performed on pc or proxmark", + "notes": [ + "hf epa sim --pwd 112233445566", + "hf epa sim --pc --pty 1 --pwd 112233445566" + ], + "offline": false, + "options": [ + "-h, --help This help", + "--pc perform crypto on PC", + "--pty type of password", + "-p, --pwd password" + ], + "usage": "hf epa sim [-h] --pc --pty -p " }, "hf felica auth1": { "command": "hf felica auth1", @@ -2961,15 +2977,16 @@ "command": "hf iclass eload", "description": "Load emulator memory with data from (bin/eml/json) iCLASS dump file", "notes": [ - "hf iclass eload -f hf-iclass-AA162D30F8FF12F1-dump.bin", - "hf iclass eload -f hf-iclass-AA162D30F8FF12F1-dump.eml" + "hf iclass eload -f hf-iclass-AA162D30F8FF12F1-dump.eml", + "hf iclass eload -f hf-iclass-AA162D30F8FF12F1-dump.bin -m" ], "offline": false, "options": [ "-h, --help This help", - "-f, --file filename of dump (bin/eml/json)" + "-f, --file filename of dump (bin/eml/json)", + "-m, --mem use RDV4 spiffs" ], - "usage": "hf iclass eload [-h] -f " + "usage": "hf iclass eload [-hm] -f " }, "hf iclass encode": { "command": "hf iclass encode", @@ -4080,7 +4097,7 @@ }, "hf mf ecfill": { "command": "hf mf ecfill", - "description": "Dump card and transfer the data to emulator memory. Keys must be laid in the emulator memory", + "description": "Dump card and transfer the data to emulator memory. Keys must be in the emulator memory", "notes": [ "hf mf ecfill -> use key type A", "hf mf ecfill --4k -b -> target 4K card with key type B" @@ -4172,9 +4189,10 @@ "--2k MIFARE Classic/Plus 2k", "--4k MIFARE Classic 4k / S70", "--ul MIFARE Ultralight family", + "-m, --mem use RDV4 spiffs", "-q, --qty manually set number of blocks (overrides)" ], - "usage": "hf mf eload [-h] -f [--mini] [--1k] [--2k] [--4k] [--ul] [-q ]" + "usage": "hf mf eload [-hm] -f [--mini] [--1k] [--2k] [--4k] [--ul] [-q ]" }, "hf mf esave": { "command": "hf mf esave", @@ -8609,6 +8627,28 @@ ], "usage": "lf indala altdemod [-hl]" }, + "lf indala brute": { + "command": "lf indala brute", + "description": "Enables bruteforce of INDALA readers with specified facility code. This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step if cardnumber is not given, it starts with 1 and goes up to 65535", + "notes": [ + "lf indala brute --fc 224", + "lf indala brute --fc 21 -d 2000", + "lf indala brute -v --fc 21 --cn 200 -d 2000", + "lf indala brute -v --fc 21 --cn 200 -d 2000 --up" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-v, --verbose verbose output", + "--fc facility code", + "--cn card number to start with", + "-d, --delay delay betweens attempts in ms. Default 1000ms", + "--up direction to increment card number. (default is both directions)", + "--down direction to decrement card number. (default is both directions)", + "--4041x specify Indala 4041X format" + ], + "usage": "lf indala brute [-hv] [--fc ] [--cn ] [-d ] [--up] [--down] [--4041x]" + }, "lf indala clone": { "command": "lf indala clone", "description": "clone Indala UID to T55x7 or Q5/T5555 tag using different known formats", @@ -11492,8 +11532,8 @@ } }, "metadata": { - "commands_extracted": 726, + "commands_extracted": 728, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-10-24T16:51:32" + "extracted_on": "2022-10-29T22:52:55" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index a87a201df..a19a97a13 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -275,7 +275,8 @@ Check column "offline" for their availability. |------- |------- |----------- |`hf epa help `|Y |`This help` |`hf epa cnonces `|N |`Acquire encrypted PACE nonces of specific size` -|`hf epa preplay `|N |`Perform PACE protocol by replaying given APDUs` +|`hf epa replay `|N |`Perform PACE protocol by replaying given APDUs` +|`hf epa sim `|N |`Simulate PACE protocol` ### hf emrtd @@ -970,6 +971,7 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`lf indala help `|Y |`This help` +|`lf indala brute `|N |`Demodulate an Indala tag (PSK1) from the GraphBuffer` |`lf indala demod `|Y |`Demodulate an Indala tag (PSK1) from the GraphBuffer` |`lf indala altdemod `|Y |`Alternative method to demodulate samples for Indala 64 bit UID (option '224' for 224 bit)` |`lf indala reader `|N |`Read an Indala tag from the antenna` From a89983d1b350198857cd2f10451811aade2f01e2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 30 Oct 2022 08:54:33 +0100 Subject: [PATCH 323/759] text --- client/src/cmdlfhid.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index 4b6c69698..1ce02f4ed 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -532,27 +532,30 @@ static int CmdHIDBrute(const char *Cmd) { CLIParserFree(ctx); if (verbose) { - PrintAndLogEx(INFO, "Wiegand format#.. %i", format_idx); - PrintAndLogEx(INFO, "OEM#............. %u", cn_hi.OEM); - PrintAndLogEx(INFO, "ISSUE#........... %u", cn_hi.IssueLevel); - PrintAndLogEx(INFO, "Facility#........ %u", cn_hi.FacilityCode); - PrintAndLogEx(INFO, "Card#............ %" PRIu64, cn_hi.CardNumber); + PrintAndLogEx(INFO, "Wiegand format... %i", format_idx); + PrintAndLogEx(INFO, "OEM.............. %u", cn_hi.OEM); + PrintAndLogEx(INFO, "ISSUE............ %u", cn_hi.IssueLevel); + PrintAndLogEx(INFO, "Facility code.... %u", cn_hi.FacilityCode); + PrintAndLogEx(INFO, "Card number...... %" PRIu64, cn_hi.CardNumber); + PrintAndLogEx(INFO, "Delay............ " _YELLOW_("%d"), delay); switch (direction) { case 0: - PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("BOTH") " delay " _YELLOW_("%d"), delay); + PrintAndLogEx(INFO, "Direction........ " _YELLOW_("BOTH")); break; case 1: - PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("UP") " delay " _YELLOW_("%d"), delay); + PrintAndLogEx(INFO, "Direction........ " _YELLOW_("UP")); break; case 2: - PrintAndLogEx(INFO, "Brute-forcing direction: " _YELLOW_("DOWN") " delay " _YELLOW_("%d"), delay); + PrintAndLogEx(INFO, "Direction........ " _YELLOW_("DOWN")); break; default: break; } } + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Started brute-forcing HID Prox reader"); PrintAndLogEx(INFO, "Press " _GREEN_("") " or pm3-button to abort simulation"); + PrintAndLogEx(NORMAL, ""); // copy values to low. cn_low = cn_hi; @@ -563,7 +566,7 @@ static int CmdHIDBrute(const char *Cmd) { fin_hi = fin_low = false; do { - if (!g_session.pm3_present) { + if (g_session.pm3_present == false) { PrintAndLogEx(WARNING, "Device offline\n"); return PM3_ENODATA; } @@ -576,10 +579,10 @@ static int CmdHIDBrute(const char *Cmd) { // do one up if (direction != 2) { if (cn_hi.CardNumber < 0xFFFF) { - cn_hi.CardNumber++; if (sendTry(format_idx, &cn_hi, delay, verbose) != PM3_SUCCESS) { return PM3_ESOFT; } + cn_hi.CardNumber++; } else { fin_hi = true; } From d4b71a17749ae9abce30ae28abd3ab6ddb2f93e0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 30 Oct 2022 16:29:50 +0100 Subject: [PATCH 324/759] modified lf indala sim to also accept facility code and card number --- CHANGELOG.md | 1 + client/src/cmdlfindala.c | 102 +++++++++++++++++++++++++++++---------- doc/commands.json | 11 +++-- 3 files changed, 86 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a82f766f..831ee0ea8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] ## [Radium.4.15864][2022-10-29] + - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) - Added `lf indala brute`- brute forcing of 64b Indala ID (@iceman1001) - Added `hf 14a ndefwrite` - write raw NDEF records to TYPE4A tags (@iceman1001) - Changed ndef output to be more dense. Honors verbose now (@iceman1001) diff --git a/client/src/cmdlfindala.c b/client/src/cmdlfindala.c index bd20f15db..781db217b 100644 --- a/client/src/cmdlfindala.c +++ b/client/src/cmdlfindala.c @@ -632,6 +632,8 @@ static int CmdIndalaSim(const char *Cmd) { "Enables simulation of Indala card with specified facility code and card number.\n" "Simulation runs until the button is pressed or another USB command is issued.", "lf indala sim --heden 888\n" + "lf indala sim --fc 123 --cn 1337 \n" + "lf indala sim --fc 123 --cn 1337 --4041x\n" "lf indala sim --raw a0000000a0002021\n" "lf indala sim --raw 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5" ); @@ -640,8 +642,12 @@ static int CmdIndalaSim(const char *Cmd) { arg_param_begin, arg_str0("r", "raw", "", "raw bytes"), arg_int0(NULL, "heden", "", "Cardnumber for Heden 2L format"), + arg_int0(NULL, "fc", "", "Facility code (26 bit H10301 format)"), + arg_int0(NULL, "cn", "", "Card number (26 bit H10301 format)"), + arg_lit0(NULL, "4041x", "Optional - specify Indala 4041X format, must use with fc and cn"), arg_param_end }; + CLIExecWithReturn(ctx, Cmd, argtable, false); // raw param @@ -652,17 +658,34 @@ static int CmdIndalaSim(const char *Cmd) { bool is_long_uid = (raw_len == 28); + bool fmt4041x = arg_get_lit(ctx, 5); + + int32_t cardnumber; - bool got_cn = false; + uint8_t fc = 0; + uint16_t cn = 0; + bool got_cn = false, got_26 = false; + if (is_long_uid == false) { // Heden param cardnumber = arg_get_int_def(ctx, 2, -1); got_cn = (cardnumber != -1); + + // 26b FC/CN param + fc = arg_get_int_def(ctx, 3, 0); + cn = arg_get_int_def(ctx, 4, 0); + got_26 = (fc != 0 && cn != 0); } CLIParserFree(ctx); + if ((got_26 == false) && fmt4041x) { + PrintAndLogEx(FAILED, "You must specify a facility code and card number when using 4041X format"); + return PM3_EINVARG; + } + + // if HEDEN fmt? if (got_cn) { encodeHeden2L(raw, cardnumber); raw_len = 8; @@ -672,17 +695,47 @@ static int CmdIndalaSim(const char *Cmd) { uint8_t bs[224]; memset(bs, 0x00, sizeof(bs)); + // if RAW, copy to bitstream uint8_t counter = 0; for (int32_t i = 0; i < raw_len; i++) { - uint8_t tmp = raw[i]; - bs[counter++] = (tmp >> 7) & 1; - bs[counter++] = (tmp >> 6) & 1; - bs[counter++] = (tmp >> 5) & 1; - bs[counter++] = (tmp >> 4) & 1; - bs[counter++] = (tmp >> 3) & 1; - bs[counter++] = (tmp >> 2) & 1; - bs[counter++] = (tmp >> 1) & 1; - bs[counter++] = tmp & 1; + uint8_t b = raw[i]; + bs[counter++] = (b >> 7) & 1; + bs[counter++] = (b >> 6) & 1; + bs[counter++] = (b >> 5) & 1; + bs[counter++] = (b >> 4) & 1; + bs[counter++] = (b >> 3) & 1; + bs[counter++] = (b >> 2) & 1; + bs[counter++] = (b >> 1) & 1; + bs[counter++] = b & 1; + } + + counter = (raw_len * 8); + + // HEDEN + + // FC / CN not HEDEN. + if (raw_len == 0 && got_26) { + // Bitstream generation, format select + int res = PM3_ESOFT; + if (fmt4041x) { + res = getIndalaBits4041x(fc, cn, bs); + } else { + res = getIndalaBits(fc, cn, bs); + } + + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "Error with tag bitstream generation."); + return res; + } + + counter = INDALA_ARR_LEN; + + PrintAndLogEx(SUCCESS, "Simulating " _YELLOW_("64 bit") " Indala FC " _YELLOW_("%u") " CN " _YELLOW_("%u"), fc, cn); + } else { + PrintAndLogEx(SUCCESS, "Simulating " _YELLOW_("%s") " Indala raw " _YELLOW_("%s") + , (is_long_uid) ? "224 bit" : "64 bit" + , sprint_hex_inrow(raw, counter) + ); } // a0 00 00 00 bd 98 9a 11 @@ -691,10 +744,7 @@ static int CmdIndalaSim(const char *Cmd) { // It has to send either 64bits (8bytes) or 224bits (28bytes). Zero padding needed if not. // lf simpsk -1 -c 32 --fc 2 -d 0102030405060708 - PrintAndLogEx(SUCCESS, "Simulating " _YELLOW_("%s") " Indala raw " _YELLOW_("%s") - , (is_long_uid) ? "224 bit" : "64 bit" - , sprint_hex_inrow(raw, raw_len) - ); + PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command"); // indala PSK, clock 32, carrier 0 @@ -702,34 +752,31 @@ static int CmdIndalaSim(const char *Cmd) { payload->carrier = 2; payload->invert = 0; payload->clock = 32; - memcpy(payload->data, bs, raw_len * 8); + memcpy(payload->data, bs, counter); clearCommandBuffer(); - SendCommandNG(CMD_LF_PSK_SIMULATE, (uint8_t *)payload, sizeof(lf_psksim_t) + (raw_len * 8)); + SendCommandNG(CMD_LF_PSK_SIMULATE, (uint8_t *)payload, sizeof(lf_psksim_t) + counter); free(payload); PacketResponseNG resp; WaitForResponse(CMD_LF_PSK_SIMULATE, &resp); PrintAndLogEx(INFO, "Done"); - if (resp.status != PM3_EOPABORTED) + if (resp.status != PM3_EOPABORTED) { return resp.status; + } return PM3_SUCCESS; } static int CmdIndalaClone(const char *Cmd) { - int32_t cardnumber; - uint8_t fc = 0; - uint16_t cn = 0; - CLIParserContext *ctx; CLIParserInit(&ctx, "lf indala clone", "clone Indala UID to T55x7 or Q5/T5555 tag using different known formats\n" _RED_("\nWarning, encoding with FC/CN doesn't always work"), - "lf indala clone --heden 888 --> use Heden 2L format\n" - "lf indala clone --fc 123 --cn 1337 --> use standard 26b format\n" - "lf indala clone --fc 123 --cn 1337 --4041x --> use 4041x format\n" + "lf indala clone --heden 888\n" + "lf indala clone --fc 123 --cn 1337\n" + "lf indala clone --fc 123 --cn 1337 --4041x\n" "lf indala clone -r a0000000a0002021\n" "lf indala clone -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"); @@ -751,11 +798,16 @@ static int CmdIndalaClone(const char *Cmd) { CLIGetHexWithReturn(ctx, 1, raw, &raw_len); bool is_long_uid = (raw_len == 28); + bool q5 = arg_get_lit(ctx, 5); bool em = arg_get_lit(ctx, 6); bool fmt4041x = arg_get_lit(ctx, 7); + int32_t cardnumber; + uint8_t fc = 0; + uint16_t cn = 0; bool got_cn = false, got_26 = false; + if (is_long_uid == false) { // Heden param @@ -774,7 +826,7 @@ static int CmdIndalaClone(const char *Cmd) { return PM3_EINVARG; } - if ((!got_26) && fmt4041x) { + if ((got_26 == false) && fmt4041x) { PrintAndLogEx(FAILED, "You must specify a facility code and card number when using 4041X format"); return PM3_EINVARG; } diff --git a/doc/commands.json b/doc/commands.json index 76c8aa781..fd08851b8 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -8704,6 +8704,8 @@ "description": "Enables simulation of Indala card with specified facility code and card number. Simulation runs until the button is pressed or another USB command is issued.", "notes": [ "lf indala sim --heden 888", + "lf indala sim --fc 123 --cn 1337", + "lf indala sim --fc 123 --cn 1337 --4041x", "lf indala sim --raw a0000000a0002021", "lf indala sim --raw 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5" ], @@ -8711,9 +8713,12 @@ "options": [ "-h, --help This help", "-r, --raw raw bytes", - "--heden Cardnumber for Heden 2L format" + "--heden Cardnumber for Heden 2L format", + "--fc Facility code (26 bit H10301 format)", + "--cn Card number (26 bit H10301 format)", + "--4041x Optional - specify Indala 4041X format, must use with fc and cn" ], - "usage": "lf indala sim [-h] [-r ] [--heden ]" + "usage": "lf indala sim [-h] [-r ] [--heden ] [--fc ] [--cn ] [--4041x]" }, "lf io clone": { "command": "lf io clone", @@ -11534,6 +11539,6 @@ "metadata": { "commands_extracted": 728, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-10-29T22:52:55" + "extracted_on": "2022-10-30T15:28:49" } } \ No newline at end of file From cee55d43eeb66c1110c22ec8d3ecdc8527f9d20f Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Mon, 31 Oct 2022 20:13:09 +0100 Subject: [PATCH 325/759] Modified logic to also try key B on MF cards. In configurations where keyA is unknown but ACLs are configured to allow all blocks to be read by keyB the command `hf mf dump` was failing. This commit attempts to fix this behavior by trying keyA first and swapping for keyB if half of the allowed tries failed. --- client/src/cmdhfmf.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 467c9b2ca..9b0fbefc4 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -842,14 +842,17 @@ static int CmdHF14AMfDump(const char *Cmd) { uint8_t tries; mf_readblock_t payload; + uint8_t current_key; for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { + current_key = MF_KEY_A; for (tries = 0; tries < MIFARE_SECTOR_RETRY; tries++) { PrintAndLogEx(NORMAL, "." NOLF); fflush(stdout); payload.blockno = mfFirstBlockOfSector(sectorNo) + mfNumBlocksPerSector(sectorNo) - 1; - payload.keytype = MF_KEY_A; - memcpy(payload.key, keyA[sectorNo], sizeof(payload.key)); + payload.keytype = current_key; + + memcpy(payload.key, current_key == MF_KEY_A ? keyA[sectorNo] : keyB[sectorNo], sizeof(payload.key)); clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); @@ -863,7 +866,10 @@ static int CmdHF14AMfDump(const char *Cmd) { rights[sectorNo][2] = ((data[7] & 0x40) >> 4) | ((data[8] & 0x4) >> 1) | ((data[8] & 0x40) >> 6); // C1C2C3 for data area 2 rights[sectorNo][3] = ((data[7] & 0x80) >> 5) | ((data[8] & 0x8) >> 2) | ((data[8] & 0x80) >> 7); // C1C2C3 for sector trailer break; - } else if (tries == 2) { // on last try set defaults + } else if (tries == (MIFARE_SECTOR_RETRY / 2)) { // after 2 unsuccessful tries, give key B a go + PrintAndLogEx(FAILED, "\ntrying with key B instead...", sectorNo); + current_key = MF_KEY_B; + } else if (tries == MIFARE_SECTOR_RETRY) { // on last try set defaults PrintAndLogEx(FAILED, "\ncould not get access rights for sector %2d. Trying with defaults...", sectorNo); rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = 0x00; rights[sectorNo][3] = 0x01; @@ -882,13 +888,13 @@ static int CmdHF14AMfDump(const char *Cmd) { for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { for (blockNo = 0; blockNo < mfNumBlocksPerSector(sectorNo); blockNo++) { bool received = false; - + current_key = MF_KEY_A; for (tries = 0; tries < MIFARE_SECTOR_RETRY; tries++) { if (blockNo == mfNumBlocksPerSector(sectorNo) - 1) { // sector trailer. At least the Access Conditions can always be read with key A. payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; - payload.keytype = MF_KEY_A; - memcpy(payload.key, keyA[sectorNo], sizeof(payload.key)); + payload.keytype = current_key; + memcpy(payload.key, current_key == MF_KEY_A ? keyA[sectorNo] : keyB[sectorNo], sizeof(payload.key)); clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); @@ -898,7 +904,7 @@ static int CmdHF14AMfDump(const char *Cmd) { if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; - payload.keytype = 1; + payload.keytype = MF_KEY_B; memcpy(payload.key, keyB[sectorNo], sizeof(payload.key)); clearCommandBuffer(); @@ -911,8 +917,8 @@ static int CmdHF14AMfDump(const char *Cmd) { } else { // key A would work payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; - payload.keytype = MF_KEY_A; - memcpy(payload.key, keyA[sectorNo], sizeof(payload.key)); + payload.keytype = current_key; + memcpy(payload.key, current_key == MF_KEY_A ? keyA[sectorNo] : keyB[sectorNo], sizeof(payload.key)); clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); @@ -924,6 +930,10 @@ static int CmdHF14AMfDump(const char *Cmd) { // break the re-try loop break; } + if ((current_key == MF_KEY_A) && (tries == (MIFARE_SECTOR_RETRY / 2))) { + // Half the tries failed with key A. Swap for key B + current_key = MF_KEY_B; + } } } From b768f8e1a3977d0b74828859aa62c404b9c7c4d6 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Mon, 31 Oct 2022 20:28:35 +0100 Subject: [PATCH 326/759] Fix comment and unreachable boundary. --- client/src/cmdhfmf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 9b0fbefc4..a4b6243b4 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -866,10 +866,10 @@ static int CmdHF14AMfDump(const char *Cmd) { rights[sectorNo][2] = ((data[7] & 0x40) >> 4) | ((data[8] & 0x4) >> 1) | ((data[8] & 0x40) >> 6); // C1C2C3 for data area 2 rights[sectorNo][3] = ((data[7] & 0x80) >> 5) | ((data[8] & 0x8) >> 2) | ((data[8] & 0x80) >> 7); // C1C2C3 for sector trailer break; - } else if (tries == (MIFARE_SECTOR_RETRY / 2)) { // after 2 unsuccessful tries, give key B a go + } else if (tries == (MIFARE_SECTOR_RETRY / 2)) { // after half unsuccessful tries, give key B a go PrintAndLogEx(FAILED, "\ntrying with key B instead...", sectorNo); current_key = MF_KEY_B; - } else if (tries == MIFARE_SECTOR_RETRY) { // on last try set defaults + } else if (tries == (MIFARE_SECTOR_RETRY - 1)) { // on last try set defaults PrintAndLogEx(FAILED, "\ncould not get access rights for sector %2d. Trying with defaults...", sectorNo); rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = 0x00; rights[sectorNo][3] = 0x01; From fede61296b4d7494a52b69e3565c4b43e8948928 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Nov 2022 14:34:07 +0100 Subject: [PATCH 327/759] fix return types to follow our style better. 14a/mf needs more love --- armsrc/mifarecmd.c | 10 +++--- client/src/cmdhfmf.c | 63 ++++++++++++++++------------------ client/src/cmdhfmfhard.c | 41 ++++++++++++---------- client/src/mifare/mifarehost.c | 4 ++- 4 files changed, 61 insertions(+), 57 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index ce4b14631..b0dd2c116 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -852,7 +852,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint64_t ui64Key = bytes_to_num(datain, 6); uint32_t cuid = 0; - int16_t isOK = 0; + int16_t isOK = PM3_SUCCESS; uint16_t num_nonces = 0; uint8_t nt_par_enc = 0; uint8_t cascade_levels = 0; @@ -882,7 +882,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, // Test if the action was cancelled if (BUTTON_PRESS()) { - isOK = 2; + isOK = PM3_EOPABORTED; field_off = true; break; } @@ -917,7 +917,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, if (slow) SpinDelayUs(HARDNESTED_PRE_AUTHENTICATION_LEADTIME); - uint32_t nt1; + uint32_t nt1 = 0; if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) { if (g_dbglevel >= DBG_ERROR) Dbprintf("AcquireEncryptedNonces: Auth1 error"); continue; @@ -939,7 +939,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, memcpy(buf + i, receivedAnswer, 4); nt_par_enc = par_enc[0] & 0xf0; } else { - nt_par_enc |= par_enc[0] >> 4; + nt_par_enc |= par_enc[0] >> 4; memcpy(buf + i + 4, receivedAnswer, 4); memcpy(buf + i + 8, &nt_par_enc, 1); i += 9; @@ -2465,6 +2465,8 @@ OUT: void MifareHasStaticNonce(void) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // variables int retval = PM3_SUCCESS; uint32_t nt = 0; diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index a4b6243b4..c561c8091 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -430,9 +430,9 @@ static int CmdHF14AMfDarkside(const char *Cmd) { t1 = msclock() - t1; switch (isOK) { - case -1 : - PrintAndLogEx(WARNING, "button pressed, aborted"); - return PM3_ESOFT; + case PM3_EOPABORTED: + PrintAndLogEx(WARNING, "button pressed or aborted via keyboard. aborted"); + return PM3_EOPABORTED; case -2 : PrintAndLogEx(FAILED, "card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)"); return PM3_ESOFT; @@ -443,9 +443,6 @@ static int CmdHF14AMfDarkside(const char *Cmd) { PrintAndLogEx(FAILED, "card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown"); PrintAndLogEx(FAILED, "generating polynomial with 16 effective bits only, but shows unexpected behaviour"); return PM3_ESOFT; - case PM3_EOPABORTED : - PrintAndLogEx(WARNING, "aborted via keyboard"); - return PM3_EOPABORTED; default : PrintAndLogEx(SUCCESS, "found valid key: "_GREEN_("%012" PRIx64), key); break; @@ -1432,6 +1429,7 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't PrintAndLogEx(ERR, "Unknown error.\n"); } return PM3_SUCCESS; + } else { // ------------------------------------ multiple sectors working uint64_t t1 = msclock(); @@ -1576,7 +1574,7 @@ jumptoend: PrintAndLogEx(ERR, "Failed to save keys to file"); free(e_sector); free(fptr); - return PM3_ESOFT; + return PM3_EFILE; } free(fptr); } @@ -1606,7 +1604,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { arg_lit0("a", NULL, "Input key specified is keyA (def)"), arg_lit0("b", NULL, "Input key specified is keyB"), arg_lit0("e", "emukeys", "Fill simulator keys from found keys"), - arg_lit0(NULL, "dumpkeys", "Dump found keys to file"), + arg_lit0(NULL, "dumpkeys", "Dump found keys to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -1634,7 +1632,6 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { bool transferToEml = arg_get_lit(ctx, 9); bool createDumpFile = arg_get_lit(ctx, 10); - CLIParserFree(ctx); //validations @@ -1689,7 +1686,8 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { uint64_t t1 = msclock(); e_sector = calloc(SectorsCnt, sizeof(sector_t)); - if (e_sector == NULL) return PM3_EMALLOC; + if (e_sector == NULL) + return PM3_EMALLOC; // add our known key e_sector[mfSectorNum(blockNo)].foundKey[keyType] = 1; @@ -1825,7 +1823,7 @@ jumptoend: PrintAndLogEx(ERR, "Failed to save keys to file"); free(e_sector); free(fptr); - return PM3_ESOFT; + return PM3_EFILE; } free(fptr); } @@ -1987,8 +1985,9 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { if (nonce_file_write) { char *fptr = GenerateFilename("hf-mf-", "-nonces.bin"); - if (fptr == NULL) - return 1; + if (fptr == NULL) { + return PM3_EFILE; + } strncpy(filename, fptr, FILE_PATH_SIZE - 1); free(fptr); } @@ -2034,18 +2033,17 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { if (isOK) { switch (isOK) { - case 1 : + case PM3_ETIMEOUT : PrintAndLogEx(ERR, "Error: No response from Proxmark3.\n"); break; - case 2 : - PrintAndLogEx(NORMAL, "Button pressed. Aborted.\n"); + case PM3_EOPABORTED: + PrintAndLogEx(WARNING, "Button pressed. Aborted.\n"); break; default : break; } - return 2; } - return 0; + return isOK; } static int CmdHF14AMfAutoPWN(const char *Cmd) { @@ -2238,7 +2236,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { uint64_t select_status = resp.oldarg[0]; if (select_status == 0) { PrintAndLogEx(WARNING, "iso14443a card select failed"); - return select_status; + return PM3_ECARDEXCHANGE; } // store card info @@ -2263,10 +2261,10 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (has_staticnonce == NONCE_NORMAL) { prng_type = detect_classic_prng(); if (prng_type < 0) { - PrintAndLogEx(FAILED, "\nNo tag detected or other tag communication error"); + PrintAndLogEx(FAILED, "\nNo tag detected or other tag communication error (%u)", prng_type); free(e_sector); free(fptr); - return prng_type; + return PM3_ESOFT; } } @@ -2490,8 +2488,8 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { isOK = mfDarkside(mfFirstBlockOfSector(sectorno), keytype + 0x60, &key64); switch (isOK) { - case -1 : - PrintAndLogEx(WARNING, "\nButton pressed. Aborted."); + case PM3_EOPABORTED : + PrintAndLogEx(WARNING, "\nButton pressed or aborted via keyboard"); goto noValidKeyFound; case -2 : PrintAndLogEx(FAILED, "\nCard is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)."); @@ -2503,9 +2501,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { PrintAndLogEx(FAILED, "\nCard is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown"); PrintAndLogEx(FAILED, "generating polynomial with 16 effective bits only, but shows unexpected behaviour."); goto noValidKeyFound; - case -5 : - PrintAndLogEx(WARNING, "\naborted via keyboard."); - goto noValidKeyFound; default : PrintAndLogEx(SUCCESS, "\nFound valid key [ " _GREEN_("%012" PRIx64) " ]\n", key64); break; @@ -2590,7 +2585,7 @@ noValidKeyFound: clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); - if (!WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) goto skipReadBKey; + if (WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500) == false) goto skipReadBKey; if (resp.status != PM3_SUCCESS) goto skipReadBKey; @@ -2642,13 +2637,13 @@ tryNested: PrintAndLogEx(ERR, "\nError: No response from Proxmark3."); free(e_sector); free(fptr); - return PM3_ESOFT; + return isOK; } case PM3_EOPABORTED: { PrintAndLogEx(WARNING, "\nButton pressed. Aborted."); free(e_sector); free(fptr); - return PM3_EOPABORTED; + return isOK; } case PM3_EFAILED: { PrintAndLogEx(FAILED, "Tag isn't vulnerable to Nested Attack (PRNG is probably not predictable)."); @@ -2679,7 +2674,7 @@ tryNested: PrintAndLogEx(ERR, "unknown Error.\n"); free(e_sector); free(fptr); - return PM3_ESOFT; + return isOK; } } @@ -2697,11 +2692,11 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack DropField(); if (isOK) { switch (isOK) { - case 1: { + case PM3_ETIMEOUT: { PrintAndLogEx(ERR, "\nError: No response from Proxmark3"); break; } - case 2: { + case PM3_EOPABORTED: { PrintAndLogEx(NORMAL, "\nButton pressed, user aborted"); break; } @@ -2736,13 +2731,13 @@ tryStaticnested: PrintAndLogEx(ERR, "\nError: No response from Proxmark3"); free(e_sector); free(fptr); - return PM3_ESOFT; + return isOK; } case PM3_EOPABORTED: { PrintAndLogEx(WARNING, "\nButton pressed, user aborted"); free(e_sector); free(fptr); - return PM3_EOPABORTED; + return isOK; } case PM3_SUCCESS: { e_sector[current_sector_i].Key[current_key_type_i] = bytes_to_num(tmp_key, 6); diff --git a/client/src/cmdhfmfhard.c b/client/src/cmdhfmfhard.c index a8455deab..2d373e451 100644 --- a/client/src/cmdhfmfhard.c +++ b/client/src/cmdhfmfhard.c @@ -1043,7 +1043,7 @@ static int read_nonce_file(char *filename) { if (filename == NULL) { PrintAndLogEx(WARNING, "Filename is NULL"); - return 1; + return PM3_EINVARG; } FILE *fnonces = NULL; char progress_text[80] = ""; @@ -1052,7 +1052,7 @@ static int read_nonce_file(char *filename) { num_acquired_nonces = 0; if ((fnonces = fopen(filename, "rb")) == NULL) { PrintAndLogEx(WARNING, "Could not open file " _YELLOW_("%s"), filename); - return 1; + return PM3_EFILE; } snprintf(progress_text, 80, "Reading nonces from file " _YELLOW_("%s"), filename); @@ -1061,7 +1061,7 @@ static int read_nonce_file(char *filename) { if (bytes_read != 6) { PrintAndLogEx(ERR, "File reading error."); fclose(fnonces); - return 1; + return PM3_EFILE; } cuid = bytes_to_num(read_buf, 4); uint8_t trgBlockNo = bytes_to_num(read_buf + 4, 1); @@ -1095,7 +1095,7 @@ static int read_nonce_file(char *filename) { } if (got_match == false) { PrintAndLogEx(FAILED, "No match for the First_Byte_Sum (%u), is the card a genuine MFC Ev1? ", first_byte_Sum); - return 1; + return PM3_ESOFT; } return PM3_SUCCESS; } @@ -1417,7 +1417,7 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ if (WaitForResponseTimeout(CMD_ACK, &resp, 3000) == false) { DropField(); - return 1; + return PM3_ETIMEOUT; } // error during nested_hard @@ -1432,7 +1432,7 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ if ((fnonces = fopen(filename, "wb")) == NULL) { PrintAndLogEx(WARNING, "Could not create file " _YELLOW_("%s"), filename); DropField(); - return 3; + return PM3_EFILE; } snprintf(progress_text, 80, "Writing acquired nonces to binary file " _YELLOW_("%s"), filename); @@ -1481,7 +1481,7 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ if (got_match == false) { PrintAndLogEx(FAILED, "No match for the First_Byte_Sum (%u), is the card a genuine MFC Ev1? ", first_byte_Sum); - return 4; + return PM3_EWRONGANSWER; } hardnested_stage |= CHECK_2ND_BYTES; @@ -1515,7 +1515,7 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ fclose(fnonces); } DropField(); - return 1; + return PM3_ETIMEOUT; } // error during nested_hard @@ -2250,8 +2250,9 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc init_nonce_memory(); update_reduction_rate(0.0, true); - if (simulate_acquire_nonces() != PM3_SUCCESS) { - return 3; + int res = simulate_acquire_nonces(); + if ( res != PM3_SUCCESS) { + return res; } set_test_state(best_first_bytes[0]); @@ -2310,7 +2311,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc free_statelist_cache(); free_candidates_memory(candidates); candidates = NULL; - if (!key_found) { + if (key_found == false) { // update the statistics nonces[best_first_bytes[0]].sum_a8_guess[j].prob = 0; nonces[best_first_bytes[0]].sum_a8_guess[j].num_states = 0; @@ -2341,7 +2342,9 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc free_part_sum_bitarrays(); } fclose(fstats); + } else { + start_time = msclock(); print_progress_header(); snprintf(progress_text, sizeof(progress_text), "Brute force benchmark: %1.0f million (2^%1.1f) keys/s", brute_force_per_second / 1000000, log(brute_force_per_second) / log(2.0)); @@ -2353,30 +2356,32 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc init_nonce_memory(); update_reduction_rate(0.0, true); + int res; if (nonce_file_read) { // use pre-acquired data from file nonces.bin - if (read_nonce_file(filename) != 0) { + res = read_nonce_file(filename); + if (res != PM3_SUCCESS) { free_bitflip_bitarrays(); free_nonces_memory(); free_bitarray(all_bitflips_bitarray[ODD_STATE]); free_bitarray(all_bitflips_bitarray[EVEN_STATE]); free_sum_bitarrays(); free_part_sum_bitarrays(); - return 3; + return res; } hardnested_stage = CHECK_1ST_BYTES | CHECK_2ND_BYTES; update_nonce_data(false); float brute_force_depth; shrink_key_space(&brute_force_depth); } else { // acquire nonces. - uint16_t is_OK = acquire_nonces(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_write, slow, filename); - if (is_OK != 0) { + res = acquire_nonces(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_write, slow, filename); + if (res != PM3_SUCCESS) { free_bitflip_bitarrays(); free_nonces_memory(); free_bitarray(all_bitflips_bitarray[ODD_STATE]); free_bitarray(all_bitflips_bitarray[EVEN_STATE]); free_sum_bitarrays(); free_part_sum_bitarrays(); - return is_OK; + return res; } } @@ -2437,7 +2442,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc free_statelist_cache(); free_candidates_memory(candidates); candidates = NULL; - if (!key_found) { + if (key_found == false) { // update the statistics nonces[best_first_bytes[0]].sum_a8_guess[j].prob = 0; nonces[best_first_bytes[0]].sum_a8_guess[j].num_states = 0; @@ -2453,5 +2458,5 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc free_sum_bitarrays(); free_part_sum_bitarrays(); } - return 0; + return PM3_SUCCESS; } diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 4f8440325..3aa2d7702 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -80,7 +80,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { PacketResponseNG resp; if (WaitForResponseTimeout(CMD_HF_MIFARE_READER, &resp, 2000)) { if (resp.status == PM3_EOPABORTED) { - return -1; + return resp.status; } struct p { @@ -1271,6 +1271,8 @@ int detect_classic_nackbug(bool verbose) { if (verbose) PrintAndLogEx(SUCCESS, "press pm3-button on the Proxmark3 device to abort both Proxmark3 and client.\n"); + PrintAndLogEx(INFO, "." NOLF); + while (true) { PrintAndLogEx(NORMAL, "." NOLF); From fe11c1876f504160ce1219c9bd15b3eaadd80112 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Nov 2022 15:01:46 +0100 Subject: [PATCH 328/759] hf mf dump - if keyA failed to read, zero out its key to indicate in dumped file that the key is unknown. --- client/src/cmdhfmf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index c561c8091..d2862bdd6 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -864,8 +864,9 @@ static int CmdHF14AMfDump(const char *Cmd) { rights[sectorNo][3] = ((data[7] & 0x80) >> 5) | ((data[8] & 0x8) >> 2) | ((data[8] & 0x80) >> 7); // C1C2C3 for sector trailer break; } else if (tries == (MIFARE_SECTOR_RETRY / 2)) { // after half unsuccessful tries, give key B a go - PrintAndLogEx(FAILED, "\ntrying with key B instead...", sectorNo); + PrintAndLogEx(WARNING, "\ntrying with key B instead...", sectorNo); current_key = MF_KEY_B; + PrintAndLogEx(INFO, "." NOLF); } else if (tries == (MIFARE_SECTOR_RETRY - 1)) { // on last try set defaults PrintAndLogEx(FAILED, "\ncould not get access rights for sector %2d. Trying with defaults...", sectorNo); rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = 0x00; @@ -930,6 +931,9 @@ static int CmdHF14AMfDump(const char *Cmd) { if ((current_key == MF_KEY_A) && (tries == (MIFARE_SECTOR_RETRY / 2))) { // Half the tries failed with key A. Swap for key B current_key = MF_KEY_B; + + // clear out keyA since it failed. + memset(keyA[sectorNo], 0x00, sizeof(keyA[sectorNo])); } } } From 97263ab3b1a28cbe0c513c8a58698ada7537c019 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Nov 2022 19:27:03 +0100 Subject: [PATCH 329/759] fixed to get UID from even partial trace lists if 9320 exists --- CHANGELOG.md | 1 + client/src/cmdhflist.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 831ee0ea8..2b5e04bc8 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 -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index 80a7e5730..fdfa34671 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -1570,6 +1570,10 @@ void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, // get UID if (MifareAuthState == masNone) { + if (isResponse && cmdsize == 5 ) { + ClearAuthData(); + AuthData.uid = bytes_to_num(&cmd[0], 4); + } if (cmdsize == 9 && cmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && cmd[1] == 0x70) { ClearAuthData(); AuthData.uid = bytes_to_num(&cmd[2], 4); From 3f6859d3abad1258354759d2793041bc5a7ee360 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Nov 2022 20:44:44 +0100 Subject: [PATCH 330/759] maur key --- client/dictionaries/mfc_default_keys.dic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 492ef91b5..752fa06b3 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -402,6 +402,9 @@ ABBA1234FCB0 # karinca park nigde 4E474434FFFF # +# hotel system +537930363139 +# # Data from https://github.com/RadioWar/NFCGUI 44DD5A385AAF 21A600056CB0 From 32d47cb6a41792e764934b7e5a3354388f8d3955 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 4 Nov 2022 11:06:59 +0100 Subject: [PATCH 331/759] Fix prolematic return codes in mifare. Parts of the code returned positive values for error codes, which could result in the client exiting (return value 2). --- client/src/cmdhfmf.c | 20 ++++++++++---------- client/src/mifare/mad.c | 4 ++-- client/src/mifare/mifare4.c | 14 +++++++------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index d2862bdd6..11aae2f6e 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -115,14 +115,14 @@ static int GetHFMF14AUID(uint8_t *uid, int *uidlen) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { PrintAndLogEx(WARNING, "iso14443a card select failed"); DropField(); - return 0; + return PM3_ERFTRANS; } iso14a_card_select_t card; memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); memcpy(uid, card.uid, card.uidlen * sizeof(uint8_t)); *uidlen = card.uidlen; - return 1; + return PM3_SUCCESS; } static char *GenerateFilename(const char *prefix, const char *suffix) { @@ -133,8 +133,8 @@ static char *GenerateFilename(const char *prefix, const char *suffix) { int uidlen = 0; char *fptr = calloc(sizeof(char) * (strlen(prefix) + strlen(suffix)) + sizeof(uid) * 2 + 1, sizeof(uint8_t)); - GetHFMF14AUID(uid, &uidlen); - if (!uidlen) { + int res = GetHFMF14AUID(uid, &uidlen); + if (res != PM3_SUCCESS || !uidlen) { PrintAndLogEx(WARNING, "No tag found."); free(fptr); return NULL; @@ -234,7 +234,7 @@ static bool mfc_value(const uint8_t *d, int32_t *val) { if (val) { *val = a; } - return (val_checks); + return val_checks; } static void mf_print_block(uint8_t blockno, uint8_t *d, bool verbose) { if (blockno == 0) { @@ -788,7 +788,7 @@ static int CmdHF14AMfDump(const char *Cmd) { uint64_t select_status = resp.oldarg[0]; if (select_status == 0) { PrintAndLogEx(WARNING, "iso14443a card select failed"); - return select_status; + return PM3_SUCCESS; } // store card info @@ -4907,7 +4907,7 @@ static int CmdHF14AMfCSave(const char *Cmd) { uint64_t select_status = resp.oldarg[0]; if (select_status == 0) { PrintAndLogEx(WARNING, "iso14443a card select failed"); - return select_status; + return PM3_SUCCESS; } // store card info @@ -5058,7 +5058,7 @@ static int CmdHF14AMfCView(const char *Cmd) { if (select_status == 0) { PrintAndLogEx(WARNING, "iso14443a card select failed"); - return select_status; + return PM3_ERFTRANS; } iso14a_card_select_t card; @@ -5826,7 +5826,7 @@ int CmdHFMFNDEFFormat(const char *Cmd) { uint64_t select_status = resp.oldarg[0]; if (select_status == 0) { PrintAndLogEx(WARNING, "iso14443a card select failed"); - return select_status; + return PM3_SUCCESS; } DropField(); @@ -6834,7 +6834,7 @@ static int CmdHF14AGen4View(const char *Cmd) { if (select_status == 0) { PrintAndLogEx(WARNING, "iso14443a card select failed"); - return select_status; + return PM3_SUCCESS; } iso14a_card_select_t card; diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index 57888c1ad..023f3cbf6 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -317,7 +317,7 @@ int MAD1DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose, bool *haveMA int ibs = MADInfoByteDecode(sector, swapmad, 1, verbose); - if (ibs) { + if (ibs > 0) { PrintAndLogEx(SUCCESS, "Card publisher sector " _MAGENTA_("0x%02x"), ibs); } else { PrintAndLogEx(WARNING, "Card publisher " _RED_("not") " present " _YELLOW_("0x%02x"), ibs); @@ -360,7 +360,7 @@ int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose) { } int ibs = MADInfoByteDecode(sector, swapmad, 2, verbose); - if (ibs) { + if (ibs > 0) { PrintAndLogEx(SUCCESS, "Card publisher sector " _MAGENTA_("0x%02x"), ibs); } else { PrintAndLogEx(WARNING, "Card publisher " _RED_("not") " present " _YELLOW_("0x%02x"), ibs); diff --git a/client/src/mifare/mifare4.c b/client/src/mifare/mifare4.c index 166408223..a1427bc9f 100644 --- a/client/src/mifare/mifare4.c +++ b/client/src/mifare/mifare4.c @@ -198,7 +198,7 @@ int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool acti if (res) { if (!silentMode) PrintAndLogEx(ERR, "Exchange raw error: %d", res); if (dropFieldIfError) DropField(); - return 2; + return PM3_ERFTRANS; } if (verbose) @@ -207,19 +207,19 @@ int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool acti if (datalen < 1) { if (!silentMode) PrintAndLogEx(ERR, "Card response wrong length: %d", datalen); if (dropFieldIfError) DropField(); - return 3; + return PM3_EWRONGANSWER; } if (data[0] != 0x90) { if (!silentMode) PrintAndLogEx(ERR, "Card response error: %02x %s", data[0], mfpGetErrorDescription(data[0])); if (dropFieldIfError) DropField(); - return 3; + return PM3_EWRONGANSWER; } if (datalen != 19) { // code 1b + 16b + crc 2b if (!silentMode) PrintAndLogEx(ERR, "Card response must be 19 bytes long instead of: %d", datalen); if (dropFieldIfError) DropField(); - return 3; + return PM3_EWRONGANSWER; } aes_decode(NULL, key, &data[1], RndB, 16); @@ -242,7 +242,7 @@ int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool acti if (res) { if (!silentMode) PrintAndLogEx(ERR, "Exchange raw error: %d", res); if (dropFieldIfError) DropField(); - return 4; + return PM3_ERFTRANS; } if (verbose) @@ -262,7 +262,7 @@ int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool acti PrintAndLogEx(ERR, "RndA card: %s", sprint_hex(&raw[4], 16)); } if (dropFieldIfError) DropField(); - return 5; + return PM3_EWRONGANSWER; } if (verbose) { @@ -319,7 +319,7 @@ int MifareAuth4(mf4Session_t *mf4session, uint8_t *keyn, uint8_t *key, bool acti if (verbose) PrintAndLogEx(INFO, "Authentication OK"); - return 0; + return PM3_SUCCESS; } static int intExchangeRAW14aPlus(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { From 4b54c79104c5cf9372dc0bedf2ed49b69a59a17b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 4 Nov 2022 21:10:47 +0100 Subject: [PATCH 332/759] fix a square bracket missing in trace list -c when annotating crc bytes. Added color support for crc bytes and square brackets when no ansi colors is supported --- CHANGELOG.md | 1 + client/src/cmdtrace.c | 60 +++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b5e04bc8..6a56eb57b 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 -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) ## [Radium.4.15864][2022-10-29] diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index 1ef307cf6..c7ab9ec73 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -573,7 +573,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr //2 Not crc-command //--- Draw the data column - char line[18][120] = {{0}}; + char line[18][140] = {{0}}; if (data_len == 0) { if (protocol == ICLASS && duration == 2048) { @@ -633,6 +633,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } + uint8_t crc_format_string_offset = 0; if (markCRCBytes) { //CRC-command if (((protocol == PROTO_HITAG1) || (protocol == PROTO_HITAGS)) && (data_len > 1)) { @@ -644,12 +645,38 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr (*pos2) = ']'; (*(pos2 + 1)) = '\0'; } else { + if (crcStatus == 0 || crcStatus == 1) { - char *pos1 = line[(data_len - 2) / 18] + (((data_len - 2) % 18) * 4) - 1; - (*pos1) = '['; - char *pos2 = line[(data_len) / 18] + (((data_len) % 18) * 4) - 1; - (*pos2) = ']'; - (*(pos2 + 1)) = '\0'; + char *pos1 = line[(data_len - 2) / 18]; + pos1 += (((data_len - 2) % 18) * 4) - 1; + + (*(pos1 + 6 + 1)) = '\0'; + + char *cb_str = str_dup(pos1 + 1); + + 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); + } + 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); + } else { + snprintf(pos1, 24, AEND " " _GREEN_("%s") " ", cb_str); + } + crc_format_string_offset = 13; + } else { + snprintf(pos1, 9, "[%s]", cb_str); + } + } } } } @@ -777,17 +804,19 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (hdr->isResponse) { // tag row if (use_us) { - PrintAndLogEx(NORMAL, " %10.1f | %10.1f | Tag |%-72s | %s| %s", + PrintAndLogEx(NORMAL, " %10.1f | %10.1f | Tag |%-*s | %s| %s", (float)time1 / 13.56, (float)time2 / 13.56, + 72 + crc_format_string_offset, line[j], (j == num_lines - 1) ? crc : " ", (j == num_lines - 1) ? explanation : "" ); } else { - PrintAndLogEx(NORMAL, " %10u | %10u | Tag |%-72s | %s| %s", + PrintAndLogEx(NORMAL, " %10u | %10u | Tag |%-*s | %s| %s", (hdr->timestamp - first_hdr->timestamp), (end_of_transmission_timestamp - first_hdr->timestamp), + 72 + crc_format_string_offset, line[j], (j == num_lines - 1) ? crc : " ", (j == num_lines - 1) ? explanation : "" @@ -797,18 +826,20 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr // reader row if (use_us) { PrintAndLogEx(NORMAL, - _YELLOW_(" %10.1f") " | " _YELLOW_("%10.1f") " | " _YELLOW_("Rdr") " |" _YELLOW_("%-72s")" | " _YELLOW_("%s") "| " _YELLOW_("%s"), + _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, line[j], (j == num_lines - 1) ? crc : " ", (j == num_lines - 1) ? explanation : "" ); } else { PrintAndLogEx(NORMAL, - _YELLOW_(" %10u") " | " _YELLOW_("%10u") " | " _YELLOW_("Rdr") " |" _YELLOW_("%-72s")" | " _YELLOW_("%s") "| " _YELLOW_("%s"), + _YELLOW_(" %10u") " | " _YELLOW_("%10u") " | " _YELLOW_("Rdr") " |" _YELLOW_("%-*s")" | " _YELLOW_("%s") "| " _YELLOW_("%s"), (hdr->timestamp - first_hdr->timestamp), (end_of_transmission_timestamp - first_hdr->timestamp), + 72 + crc_format_string_offset, line[j], (j == num_lines - 1) ? crc : " ", (j == num_lines - 1) ? explanation : "" @@ -819,13 +850,15 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } else { if (hdr->isResponse) { - PrintAndLogEx(NORMAL, " | | |%-72s | %s| %s", + PrintAndLogEx(NORMAL, " | | |%-*s | %s| %s", + 72 + crc_format_string_offset, line[j], (j == num_lines - 1) ? crc : " ", (j == num_lines - 1) ? explanation : "" ); } else { - PrintAndLogEx(NORMAL, " | | |" _YELLOW_("%-72s")" | " _YELLOW_("%s") "| " _YELLOW_("%s"), + PrintAndLogEx(NORMAL, " | | |" _YELLOW_("%-*s")" | " _YELLOW_("%s") "| " _YELLOW_("%s"), + 72 + crc_format_string_offset, line[j], (j == num_lines - 1) ? crc : " ", (j == num_lines - 1) ? explanation : "" @@ -839,7 +872,8 @@ 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); - PrintAndLogEx(NORMAL, " | | * |%-72s | %-4s| %s", + PrintAndLogEx(NORMAL, " | | * |%-*s | %-4s| %s", + 72 + crc_format_string_offset, sprint_hex_inrow_spaces(mfData, mfDataLen, 2), (crcc == 0 ? "!crc" : (crcc == 1 ? " ok " : " ")), explanation); From 876abf2818fb91fc1120bcc58524487eca80f8f3 Mon Sep 17 00:00:00 2001 From: DidierA Date: Sat, 5 Nov 2022 03:30:43 +0100 Subject: [PATCH 333/759] Add hf mf gload, ggetblk, gsetblk --- CHANGELOG.md | 1 + armsrc/appmain.c | 11 + armsrc/mifarecmd.c | 45 + armsrc/mifarecmd.h | 1 + client/src/cmdhfmf.c | 325 ++++++- client/src/mifare/mifarehost.c | 23 + client/src/mifare/mifarehost.h | 1 + client/src/pm3line_vocabulory.h | 1463 ++++++++++++++++--------------- doc/commands.json | 62 +- doc/commands.md | 3 + include/pm3_cmd.h | 1 + 11 files changed, 1200 insertions(+), 736 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a56eb57b..7b44c517e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) + - Added `hf mf gload, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 932b4cf1e..d48483b53 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1656,6 +1656,17 @@ static void PacketReceived(PacketCommandNG *packet) { MifareG4ReadBlk(payload->blockno, payload->pwd); break; } + + case CMD_HF_MIFARE_G4_WRBL: { + struct p { + uint8_t blockno; + uint8_t pwd[4]; + uint8_t data[16]; // data to be written + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + MifareG4WriteBlk(payload->blockno, payload->pwd, payload->data); + break; + } case CMD_HF_MIFARE_PERSONALIZE_UID: { struct p { uint8_t keytype; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index b0dd2c116..476e7c96a 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2723,6 +2723,51 @@ OUT: BigBuf_free(); } +void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data) { + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + + int res = 0; + int retval = PM3_SUCCESS; + uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); + uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); + uint8_t *uid = BigBuf_malloc(10); + if (iso14443a_select_card(uid, NULL, NULL, true, 0, true) == false) { + retval = PM3_ESOFT; + goto OUT; + } + + LED_B_ON(); + uint32_t save_iso14a_timeout = iso14a_get_timeout(); + iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout + + uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, 0xCD, blockno, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 + }; + + memcpy(cmd + 1, pwd, 4); + memcpy(cmd + 7, data, 16); + + AddCrc14A(cmd, sizeof(cmd) - 2); + + ReaderTransmit(cmd, sizeof(cmd), NULL); + res = ReaderReceive(buf, par); + if ((res != 4) || (memcmp(buf, "\x90\x00\xfd\x07", 4) != 0)) { + retval = PM3_ESOFT; + } + iso14a_set_timeout(save_iso14a_timeout); + LED_B_OFF(); + +OUT: + reply_ng(CMD_HF_MIFARE_G4_WRBL, retval, buf, res); + // turns off + OnSuccessMagic(); + BigBuf_free(); +} + void MifareSetMod(uint8_t *datain) { uint8_t mod = datain[0]; diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 66bd2bacb..de3bd416c 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -58,6 +58,7 @@ void MifareGen3Freez(void); // Gen 3 magic card lock further UID changes // MFC GEN4 GTU void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd); +void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data); void MifareSetMod(uint8_t *datain); void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 11aae2f6e..a4269326d 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1608,7 +1608,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { arg_lit0("a", NULL, "Input key specified is keyA (def)"), arg_lit0("b", NULL, "Input key specified is keyB"), arg_lit0("e", "emukeys", "Fill simulator keys from found keys"), - arg_lit0(NULL, "dumpkeys", "Dump found keys to file"), + arg_lit0(NULL, "dumpkeys", "Dump found keys to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -1690,7 +1690,7 @@ static int CmdHF14AMfNestedStatic(const char *Cmd) { uint64_t t1 = msclock(); e_sector = calloc(SectorsCnt, sizeof(sector_t)); - if (e_sector == NULL) + if (e_sector == NULL) return PM3_EMALLOC; // add our known key @@ -6749,6 +6749,313 @@ static int CmdHF14AMfView(const char *Cmd) { return PM3_SUCCESS; } +// Read block from Gen4 GTU card +static int CmdHF14AGen4GetBlk(const char *cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf ggetblk", + "Get block data from magic gen4 GTU card.", + "hf mf ggetblk --blk 0 --> get block 0 (manufacturer)\n" + "hf mf ggetblk --blk 3 -v --> get block 3, decode sector trailer\n" + ); + void *argtable[] = { + arg_param_begin, + arg_int1("b", "blk", "", "block number"), + arg_lit0("v", "verbose", "verbose output"), + arg_str0("p", "pwd", "", "password 4bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, cmd, argtable, false); + int b = arg_get_int_def(ctx, 1, 0); + bool verbose = arg_get_lit(ctx, 2); + + int pwd_len = 0; + uint8_t pwd[4] = {0}; + CLIGetHexWithReturn(ctx, 3, pwd, &pwd_len); + CLIParserFree(ctx); + + //validate args + if (b > MIFARE_4K_MAXBLOCK) { + return PM3_EINVARG; + } + + if (pwd_len != 4 && pwd_len != 0) { + PrintAndLogEx(FAILED, "Must specify 4 bytes, got " _YELLOW_("%u"), pwd_len); + return PM3_EINVARG; + } + + uint8_t blockno = (uint8_t)b; + uint8_t data[16] = {0}; + + PrintAndLogEx(NORMAL, "Block: %x", blockno) ; + + int res = mfG4GetBlock(pwd, blockno, data); + if (res) { + PrintAndLogEx(ERR, "Can't read block. error=%d", res); + return PM3_ESOFT; + } + + uint8_t sector = mfSectorNum(blockno); + mf_print_sector_hdr(sector); + mf_print_block(blockno, data, verbose); + + if (verbose) { + decode_print_st(blockno, data); + } else { + PrintAndLogEx(NORMAL, ""); + } + + return PM3_SUCCESS; +} + +// Load dump to Gen4 GTU card +static int CmdHF14AGen4Load(const char *cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf gload", + "Load magic gen4 gtu card with data from (bin/eml/json) dump file\n" + "or from emulator memory.", + "hf mf gload --emu\n" + "hf mf gload -f hf-mf-01020304.eml\n" + "hf mf gload -p AABBCCDD --4k -v -f hf-mf-01020304-dump.bin\n" + "\n" + "Card must be configured beforehand with `script run hf_mf_ultimatecard`.\n" + "Blocks are 16 bytes long." + ); + void *argtable[] = { + arg_param_begin, + arg_lit0(NULL, "mini", "MIFARE Classic Mini / S20"), + arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50 (def)"), + arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), + arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), + arg_str0("p", "pwd", "", "password 4bytes"), + arg_lit0("v", "verbose", "verbose output"), + arg_str0("f", "file", "", "filename of dump"), + arg_lit0(NULL, "emu", "from emulator memory"), + arg_int0(NULL, "start", "", "index of block to start writing (default 0)"), + arg_int0(NULL, "end", "", "index of block to end writing (default last block)"), + arg_param_end + }; + + CLIExecWithReturn(ctx, cmd, argtable, false); + bool m0 = arg_get_lit(ctx, 1); + bool m1 = arg_get_lit(ctx, 2); + bool m2 = arg_get_lit(ctx, 3); + bool m4 = arg_get_lit(ctx, 4); + + int pwd_len = 0; + uint8_t pwd[4] = {0}; + CLIGetHexWithReturn(ctx, 5, pwd, &pwd_len); + + bool verbose = arg_get_lit(ctx, 6); + + int fnlen = 0; + char filename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 7), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + + bool fill_from_emulator = arg_get_lit(ctx, 8); + + int start = arg_get_int_def(ctx, 9, 0); + int end = arg_get_int_def(ctx, 10, -1); + + CLIParserFree(ctx); + + // validations + if (pwd_len != 4 && pwd_len != 0) { + PrintAndLogEx(FAILED, "Must specify 4 bytes, got " _YELLOW_("%u"), pwd_len); + return PM3_EINVARG; + } + + if ((m0 + m1 + m2 + m4) > 1) { + PrintAndLogEx(WARNING, "Only specify one MIFARE Type"); + return PM3_EINVARG; + } else if ((m0 + m1 + m2 + m4) == 0) { + m1 = true; + } + + char s[6]; + memset(s, 0, sizeof(s)); + uint16_t block_cnt = MIFARE_1K_MAXBLOCK; + if (m0) { + block_cnt = MIFARE_MINI_MAXBLOCK; + strncpy(s, "Mini", 5); + } else if (m1) { + block_cnt = MIFARE_1K_MAXBLOCK; + strncpy(s, "1K", 3); + } else if (m2) { + block_cnt = MIFARE_2K_MAXBLOCK; + strncpy(s, "2K", 3); + } else if (m4) { + block_cnt = MIFARE_4K_MAXBLOCK; + strncpy(s, "4K", 3); + } else { + PrintAndLogEx(WARNING, "Please specify a MIFARE Type"); + return PM3_EINVARG; + } + + if (fill_from_emulator && (fnlen != 0)) { + PrintAndLogEx(WARNING, "Please specify file or emulator memory, but not both"); + return PM3_EINVARG; + } + + if (!fill_from_emulator && (fnlen == 0)) { + PrintAndLogEx(WARNING, "Please specify file or emulator memory"); + return PM3_EINVARG; + } + + if (end == -1) { + end = block_cnt - 1; + } + + if (start < 0 || end < 0) { + PrintAndLogEx(WARNING, "start and end must be positive integers"); + return PM3_EINVARG ; + } + + if (start > end) { + PrintAndLogEx(WARNING, "start cannot be more than end"); + return PM3_EINVARG ; + } + + if (start >= block_cnt) { + PrintAndLogEx(WARNING, "Last block for Mifare %s is %d. Start is too high.", s, block_cnt - 1) ; + return PM3_EINVARG ; + } + + if (end >= block_cnt) { + PrintAndLogEx(WARNING, "Last block for Mifare %s is %d. End is too high.", s, block_cnt - 1) ; + return PM3_EINVARG ; + } + + uint8_t *data = NULL; + size_t bytes_read = 0; + + if (fill_from_emulator) { + data = calloc(block_cnt * MFBLOCK_SIZE, sizeof(uint8_t)); + if (data == NULL) { + PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); + return PM3_EMALLOC; + } + PrintAndLogEx(INFO, "downloading emulator memory"); + if (!GetFromDevice(BIG_BUF_EML, data, block_cnt * MFBLOCK_SIZE, 0, NULL, 0, NULL, 2500, false)) { + PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); + free(data); + return PM3_ETIMEOUT; + } + } else { + // read from file + int res = pm3_load_dump(filename, (void **)&data, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK)); + if (res != PM3_SUCCESS) { + return res; + } + + // check file size corresponds to card size. + if (bytes_read != (block_cnt * MFBLOCK_SIZE)) { + PrintAndLogEx(ERR, "File content error. Read %zu bytes, expected %zu", bytes_read, block_cnt * MFBLOCK_SIZE); + if (data != NULL) free(data); + return PM3_EFILE; + } + } + + if (verbose) { + if (fnlen != 0) { + PrintAndLogEx(INFO, "File: " _YELLOW_("%s"), filename); + PrintAndLogEx(INFO, "File size %zu bytes, file blocks %d (0x%x)", bytes_read, block_cnt, block_cnt); + } else { + PrintAndLogEx(INFO, "Read %zu blocks from emulator memory", block_cnt); + } + } + + PrintAndLogEx(INFO, "Copying to magic gen4 GTU MIFARE Classic " _GREEN_("%s"), s); + PrintAndLogEx(INFO, "Starting block: %d. Ending block: %d.", start, end); + + // copy to card + for (uint16_t blockno = start; blockno <= end; blockno++) { + + // 4k writes can be long, so we split status each 64 block boundary. + if (blockno % 64 == 0 || blockno == start) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "" NOLF) ; + } + PrintAndLogEx(NORMAL, "." NOLF); + fflush(stdout); + + // write block + if (mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE)) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Can't set magic card block: %d", blockno); + PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); + if (data != NULL) free(data); + return PM3_ESOFT; + } + } + PrintAndLogEx(NORMAL, "\n"); + + if (data != NULL) free(data); + + PrintAndLogEx(SUCCESS, "Card loaded " _YELLOW_("%d") " blocks from %s", end - start + 1, + (fill_from_emulator ? "emulator memory" : "file")); + PrintAndLogEx(INFO, "Done!"); + return PM3_SUCCESS; +} + +// Write block to Gen4 GTU card +static int CmdHF14AGen4SetBlk(const char *cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf gsetblk", + "Set block data on a magic gen4 GTU card", + "hf mf gsetblk --blk 1 -d 000102030405060708090a0b0c0d0e0f" + ); + void *argtable[] = { + arg_param_begin, + arg_int1("b", "blk", "", "block number"), + arg_str0("d", "data", "", "bytes to write, 16 hex bytes"), + arg_str0("p", "pwd", "", "password 4bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, cmd, argtable, false); + + int b = arg_get_int_def(ctx, 1, -1); + + uint8_t data[MFBLOCK_SIZE] = {0x00}; + int datalen = 0; + CLIGetHexWithReturn(ctx, 2, data, &datalen); + + int pwd_len = 0; + uint8_t pwd[4] = {0}; + CLIGetHexWithReturn(ctx, 3, pwd, &pwd_len); + + CLIParserFree(ctx); + + // validations + if (pwd_len != 4 && pwd_len != 0) { + PrintAndLogEx(FAILED, "Must specify 4 bytes, got " _YELLOW_("%u"), pwd_len); + return PM3_EINVARG; + } + + CLIParserFree(ctx); + + if (b < 0 || b >= MIFARE_4K_MAXBLOCK) { + PrintAndLogEx(FAILED, "target block number out-of-range, got %i", b); + return PM3_EINVARG; + } + + if (datalen != MFBLOCK_SIZE) { + PrintAndLogEx(FAILED, "expected 16 bytes data, got %i", datalen); + return PM3_EINVARG; + } + + // write block + PrintAndLogEx(INFO, "Writing block number:%2d data:%s", b, sprint_hex_inrow(data, sizeof(data))); + + uint8_t blockno = (uint8_t)b; + int res = mfG4SetBlock(pwd, blockno, data); + if (res) { + PrintAndLogEx(ERR, "Can't write block. error=%d", res); + return PM3_ESOFT; + } + + return PM3_SUCCESS; +} + static int CmdHF14AGen4View(const char *Cmd) { CLIParserContext *ctx; @@ -6813,7 +7120,6 @@ static int CmdHF14AGen4View(const char *Cmd) { return PM3_EINVARG; } PrintAndLogEx(SUCCESS, "View magic gen4 GTU MIFARE Classic " _GREEN_("%s"), s); - PrintAndLogEx(INFO, "." NOLF); // Select card to get UID/UIDLEN information clearCommandBuffer(); @@ -6850,14 +7156,20 @@ static int CmdHF14AGen4View(const char *Cmd) { for (uint16_t i = 0; i < block_cnt; i++) { + // 4k READs can be long, so we split status each 64 blocks. + if (i % 64 == 0) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "" NOLF) ; + } + PrintAndLogEx(NORMAL, "." NOLF); + fflush(stdout); + if (mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE)) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Can't get magic card block: %u", i); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); free(dump); return PM3_ESOFT; } - PrintAndLogEx(NORMAL, "." NOLF); - fflush(stdout); } PrintAndLogEx(NORMAL, ""); @@ -7131,6 +7443,9 @@ static command_t CommandTable[] = { {"gen3blk", CmdHf14AGen3Block, IfPm3Iso14443a, "Overwrite manufacturer block"}, {"gen3freeze", CmdHf14AGen3Freeze, IfPm3Iso14443a, "Perma lock UID changes. irreversible"}, {"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GTU") " --------------------------"}, + {"ggetblk", CmdHF14AGen4GetBlk, IfPm3Iso14443a, "Read block from card"}, + {"gload", CmdHF14AGen4Load, IfPm3Iso14443a, "Load dump to card"}, + {"gsetblk", CmdHF14AGen4SetBlk, IfPm3Iso14443a, "Write block to card"}, {"gview", CmdHF14AGen4View, IfPm3Iso14443a, "View card"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"}, // {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 3aa2d7702..2964289b2 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1181,6 +1181,29 @@ int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data) { return PM3_SUCCESS; } +int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data) { + struct p { + uint8_t blockno; + uint8_t pwd[4]; + uint8_t data[16]; + } PACKED payload; + payload.blockno = blockno; + memcpy(payload.pwd, pwd, sizeof(payload.pwd)); + memcpy(payload.data, data, sizeof(payload.data)); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_G4_WRBL, (uint8_t *)&payload, sizeof(payload)); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_HF_MIFARE_G4_WRBL, &resp, 1500)) { + if (resp.status != PM3_SUCCESS) { + return PM3_EUNDEF; + } + } else { + PrintAndLogEx(WARNING, "command execute timeout"); + return PM3_ETIMEOUT; + } + return PM3_SUCCESS; +} // variables uint32_t cuid = 0; // uid part used for crypto1. diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index 87b6dc802..cc0fa1f83 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -96,6 +96,7 @@ int mfGen3Block(uint8_t *block, int blockLen, uint8_t *newBlock); int mfGen3Freeze(void); int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data); +int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data); int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len); diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index e715f9cab..6d348e667 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -31,734 +31,739 @@ typedef struct vocabulory_s { } vocabulory_t; const static vocabulory_t vocabulory[] = { - { 1, "help" }, - { 0, "auto" }, - { 1, "clear" }, - { 1, "hints" }, - { 1, "msleep" }, - { 1, "rem" }, - { 1, "quit" }, - { 1, "exit" }, - { 1, "prefs help" }, - { 1, "prefs show" }, - { 1, "prefs get barmode" }, - { 1, "prefs get clientdebug" }, - { 1, "prefs get clientdelay" }, - { 1, "prefs get color" }, - { 1, "prefs get savepaths" }, - { 1, "prefs get emoji" }, - { 1, "prefs get hints" }, - { 1, "prefs get output" }, - { 1, "prefs get plotsliders" }, - { 1, "prefs set help" }, - { 1, "prefs set barmode" }, - { 1, "prefs set clientdebug" }, - { 1, "prefs set clientdelay" }, - { 1, "prefs set color" }, - { 1, "prefs set emoji" }, - { 1, "prefs set hints" }, - { 1, "prefs set savepaths" }, - { 1, "prefs set output" }, - { 1, "prefs set plotsliders" }, - { 1, "analyse help" }, - { 1, "analyse lcr" }, - { 1, "analyse crc" }, - { 1, "analyse chksum" }, - { 1, "analyse dates" }, - { 1, "analyse lfsr" }, - { 1, "analyse a" }, - { 1, "analyse nuid" }, - { 1, "analyse demodbuff" }, - { 1, "analyse freq" }, - { 1, "analyse foo" }, - { 1, "analyse units" }, - { 1, "data help" }, - { 1, "data biphaserawdecode" }, - { 1, "data detectclock" }, - { 1, "data fsktonrz" }, - { 1, "data manrawdecode" }, - { 1, "data modulation" }, - { 1, "data rawdemod" }, - { 1, "data askedgedetect" }, - { 1, "data autocorr" }, - { 1, "data dirthreshold" }, - { 1, "data decimate" }, - { 1, "data undecimate" }, - { 1, "data hide" }, - { 1, "data hpf" }, - { 1, "data iir" }, - { 1, "data grid" }, - { 1, "data ltrim" }, - { 1, "data mtrim" }, - { 1, "data norm" }, - { 1, "data plot" }, - { 1, "data rtrim" }, - { 1, "data setgraphmarkers" }, - { 1, "data shiftgraphzero" }, - { 1, "data timescale" }, - { 1, "data zerocrossings" }, - { 1, "data convertbitstream" }, - { 1, "data getbitstream" }, - { 1, "data asn1" }, - { 1, "data bin2hex" }, - { 0, "data bitsamples" }, - { 1, "data clear" }, - { 1, "data diff" }, - { 0, "data hexsamples" }, - { 1, "data hex2bin" }, - { 1, "data load" }, - { 1, "data print" }, - { 0, "data samples" }, - { 1, "data save" }, - { 1, "data setdebugmode" }, - { 0, "data tune" }, - { 1, "emv help" }, - { 0, "emv exec" }, - { 0, "emv pse" }, - { 0, "emv search" }, - { 0, "emv select" }, - { 0, "emv gpo" }, - { 0, "emv readrec" }, - { 0, "emv genac" }, - { 0, "emv challenge" }, - { 0, "emv intauth" }, - { 0, "emv scan" }, - { 1, "emv test" }, - { 1, "emv list" }, - { 0, "emv roca" }, - { 1, "hf help" }, - { 1, "hf list" }, - { 0, "hf plot" }, - { 0, "hf tune" }, - { 1, "hf search" }, - { 0, "hf sniff" }, - { 1, "hf 14a help" }, - { 1, "hf 14a list" }, - { 0, "hf 14a antifuzz" }, - { 0, "hf 14a config" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a info" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a raw" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a apdufind" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a ndefformat" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a ndefwrite" }, - { 1, "hf 14b help" }, - { 0, "hf 14b apdu" }, - { 0, "hf 14b dump" }, - { 0, "hf 14b info" }, - { 1, "hf 14b list" }, - { 0, "hf 14b ndefread" }, - { 0, "hf 14b raw" }, - { 0, "hf 14b reader" }, - { 0, "hf 14b sim" }, - { 0, "hf 14b sniff" }, - { 0, "hf 14b rdbl" }, - { 0, "hf 14b sriwrite" }, - { 1, "hf 14b view" }, - { 1, "hf 15 help" }, - { 1, "hf 15 list" }, - { 1, "hf 15 demod" }, - { 0, "hf 15 dump" }, - { 0, "hf 15 info" }, - { 0, "hf 15 sniff" }, - { 0, "hf 15 raw" }, - { 0, "hf 15 rdbl" }, - { 0, "hf 15 rdmulti" }, - { 0, "hf 15 reader" }, - { 0, "hf 15 restore" }, - { 0, "hf 15 samples" }, - { 0, "hf 15 eload" }, - { 0, "hf 15 esave" }, - { 0, "hf 15 eview" }, - { 0, "hf 15 sim" }, - { 0, "hf 15 slixdisable" }, - { 0, "hf 15 wrbl" }, - { 0, "hf 15 findafi" }, - { 0, "hf 15 writeafi" }, - { 0, "hf 15 writedsfid" }, - { 0, "hf 15 csetuid" }, - { 1, "hf cipurse help" }, - { 0, "hf cipurse info" }, - { 0, "hf cipurse select" }, - { 0, "hf cipurse auth" }, - { 0, "hf cipurse read" }, - { 0, "hf cipurse write" }, - { 0, "hf cipurse aread" }, - { 0, "hf cipurse awrite" }, - { 0, "hf cipurse formatall" }, - { 0, "hf cipurse create" }, - { 0, "hf cipurse delete" }, - { 0, "hf cipurse updkey" }, - { 0, "hf cipurse updakey" }, - { 0, "hf cipurse default" }, - { 1, "hf cipurse test" }, - { 1, "hf epa help" }, - { 0, "hf epa cnonces" }, - { 0, "hf epa preplay" }, - { 1, "hf emrtd help" }, - { 0, "hf emrtd dump" }, - { 1, "hf emrtd info" }, - { 1, "hf emrtd list" }, - { 1, "hf felica help" }, - { 1, "hf felica list" }, - { 0, "hf felica reader" }, - { 0, "hf felica info" }, - { 0, "hf felica sniff" }, - { 0, "hf felica raw" }, - { 0, "hf felica rdbl" }, - { 0, "hf felica wrbl" }, - { 0, "hf felica rqservice" }, - { 0, "hf felica rqresponse" }, - { 0, "hf felica scsvcode" }, - { 0, "hf felica rqsyscode" }, - { 0, "hf felica auth1" }, - { 0, "hf felica auth2" }, - { 0, "hf felica rqspecver" }, - { 0, "hf felica resetmode" }, - { 0, "hf felica litesim" }, - { 0, "hf felica litedump" }, - { 1, "hf fido help" }, - { 1, "hf fido list" }, - { 0, "hf fido info" }, - { 0, "hf fido reg" }, - { 0, "hf fido auth" }, - { 0, "hf fido make" }, - { 0, "hf fido assert" }, - { 1, "hf fudan help" }, - { 0, "hf fudan reader" }, - { 0, "hf fudan dump" }, - { 0, "hf fudan rdbl" }, - { 1, "hf fudan view" }, - { 0, "hf fudan wrbl" }, - { 1, "hf gallagher help" }, - { 0, "hf gallagher reader" }, - { 0, "hf gallagher clone" }, - { 0, "hf gallagher delete" }, - { 1, "hf gallagher diversifykey" }, - { 1, "hf gallagher decode" }, - { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 initialize" }, - { 0, "hf ksx6924 prec" }, - { 0, "hf ksx6924 select" }, - { 1, "hf jooki help" }, - { 0, "hf jooki clone" }, - { 1, "hf jooki decode" }, - { 1, "hf jooki encode" }, - { 0, "hf jooki sim" }, - { 1, "hf iclass help" }, - { 0, "hf iclass dump" }, - { 1, "hf iclass info" }, - { 1, "hf iclass list" }, - { 0, "hf iclass rdbl" }, - { 0, "hf iclass reader" }, - { 0, "hf iclass restore" }, - { 0, "hf iclass sniff" }, - { 0, "hf iclass wrbl" }, - { 0, "hf iclass chk" }, - { 1, "hf iclass loclass" }, - { 1, "hf iclass lookup" }, - { 0, "hf iclass sim" }, - { 0, "hf iclass eload" }, - { 0, "hf iclass esave" }, - { 0, "hf iclass eview" }, - { 1, "hf iclass configcard" }, - { 1, "hf iclass calcnewkey" }, - { 1, "hf iclass encode" }, - { 1, "hf iclass encrypt" }, - { 1, "hf iclass decrypt" }, - { 1, "hf iclass managekeys" }, - { 1, "hf iclass permutekey" }, - { 1, "hf iclass view" }, - { 1, "hf legic help" }, - { 0, "hf legic dump" }, - { 0, "hf legic info" }, - { 1, "hf legic list" }, - { 0, "hf legic rdbl" }, - { 0, "hf legic reader" }, - { 0, "hf legic restore" }, - { 0, "hf legic wipe" }, - { 0, "hf legic wrbl" }, - { 0, "hf legic sim" }, - { 0, "hf legic eload" }, - { 0, "hf legic esave" }, - { 0, "hf legic eview" }, - { 1, "hf legic crc" }, - { 1, "hf legic view" }, - { 1, "hf lto help" }, - { 0, "hf lto dump" }, - { 0, "hf lto info" }, - { 1, "hf lto list" }, - { 0, "hf lto rdbl" }, - { 0, "hf lto reader" }, - { 0, "hf lto restore" }, - { 0, "hf lto wrbl" }, - { 1, "hf mf help" }, - { 1, "hf mf list" }, - { 0, "hf mf darkside" }, - { 0, "hf mf nested" }, - { 1, "hf mf hardnested" }, - { 0, "hf mf staticnested" }, - { 0, "hf mf autopwn" }, - { 0, "hf mf nack" }, - { 0, "hf mf chk" }, - { 0, "hf mf fchk" }, - { 1, "hf mf decrypt" }, - { 0, "hf mf supercard" }, - { 0, "hf mf auth4" }, - { 1, "hf mf acl" }, - { 0, "hf mf dump" }, - { 1, "hf mf mad" }, - { 0, "hf mf personalize" }, - { 0, "hf mf rdbl" }, - { 0, "hf mf rdsc" }, - { 0, "hf mf restore" }, - { 0, "hf mf setmod" }, - { 1, "hf mf value" }, - { 1, "hf mf view" }, - { 0, "hf mf wipe" }, - { 0, "hf mf wrbl" }, - { 0, "hf mf sim" }, - { 0, "hf mf ecfill" }, - { 0, "hf mf eclr" }, - { 0, "hf mf egetblk" }, - { 0, "hf mf egetsc" }, - { 0, "hf mf ekeyprn" }, - { 0, "hf mf eload" }, - { 0, "hf mf esave" }, - { 0, "hf mf esetblk" }, - { 0, "hf mf eview" }, - { 0, "hf mf cgetblk" }, - { 0, "hf mf cgetsc" }, - { 0, "hf mf cload" }, - { 0, "hf mf csave" }, - { 0, "hf mf csetblk" }, - { 0, "hf mf csetuid" }, - { 0, "hf mf cview" }, - { 0, "hf mf cwipe" }, - { 0, "hf mf gen3uid" }, - { 0, "hf mf gen3blk" }, - { 0, "hf mf gen3freeze" }, - { 0, "hf mf gview" }, - { 0, "hf mf ndefformat" }, - { 0, "hf mf ndefread" }, - { 0, "hf mf ndefwrite" }, - { 1, "hf mfp help" }, - { 0, "hf mfp info" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp commitp" }, - { 0, "hf mfp auth" }, - { 0, "hf mfp rdbl" }, - { 0, "hf mfp rdsc" }, - { 0, "hf mfp wrbl" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp mad" }, - { 0, "hf mfp ndefread" }, - { 1, "hf mfu help" }, - { 1, "hf mfu keygen" }, - { 1, "hf mfu pwdgen" }, - { 0, "hf mfu otptear" }, - { 0, "hf mfu cauth" }, - { 0, "hf mfu dump" }, - { 0, "hf mfu info" }, - { 0, "hf mfu ndefread" }, - { 0, "hf mfu rdbl" }, - { 0, "hf mfu restore" }, - { 1, "hf mfu view" }, - { 0, "hf mfu wrbl" }, - { 0, "hf mfu eload" }, - { 0, "hf mfu eview" }, - { 0, "hf mfu sim" }, - { 0, "hf mfu setpwd" }, - { 0, "hf mfu setuid" }, - { 1, "hf mfdes help" }, - { 0, "hf mfdes info" }, - { 0, "hf mfdes getuid" }, - { 0, "hf mfdes default" }, - { 0, "hf mfdes auth" }, - { 0, "hf mfdes chk" }, - { 0, "hf mfdes detect" }, - { 0, "hf mfdes freemem" }, - { 0, "hf mfdes setconfig" }, - { 0, "hf mfdes formatpicc" }, - { 1, "hf mfdes list" }, - { 0, "hf mfdes mad" }, - { 0, "hf mfdes lsapp" }, - { 0, "hf mfdes getaids" }, - { 0, "hf mfdes getappnames" }, - { 0, "hf mfdes bruteaid" }, - { 0, "hf mfdes createapp" }, - { 0, "hf mfdes deleteapp" }, - { 0, "hf mfdes selectapp" }, - { 0, "hf mfdes changekey" }, - { 0, "hf mfdes chkeysettings" }, - { 0, "hf mfdes getkeysettings" }, - { 0, "hf mfdes getkeyversions" }, - { 0, "hf mfdes getfileids" }, - { 0, "hf mfdes getfileisoids" }, - { 0, "hf mfdes lsfiles" }, - { 0, "hf mfdes dump" }, - { 0, "hf mfdes createfile" }, - { 0, "hf mfdes createvaluefile" }, - { 0, "hf mfdes createrecordfile" }, - { 0, "hf mfdes createmacfile" }, - { 0, "hf mfdes deletefile" }, - { 0, "hf mfdes getfilesettings" }, - { 0, "hf mfdes chfilesettings" }, - { 0, "hf mfdes read" }, - { 0, "hf mfdes write" }, - { 0, "hf mfdes value" }, - { 0, "hf mfdes clearrecfile" }, - { 1, "hf mfdes test" }, - { 1, "hf ntag424 help" }, - { 0, "hf ntag424 info" }, - { 0, "hf ntag424 sdm" }, - { 1, "hf ntag424 view" }, - { 1, "hf seos help" }, - { 0, "hf seos info" }, - { 1, "hf seos list" }, - { 1, "hf st25ta help" }, - { 0, "hf st25ta info" }, - { 1, "hf st25ta list" }, - { 1, "hf st25ta ndefread" }, - { 0, "hf st25ta protect" }, - { 0, "hf st25ta pwd" }, - { 0, "hf st25ta sim" }, - { 1, "hf thinfilm help" }, - { 0, "hf thinfilm info" }, - { 1, "hf thinfilm list" }, - { 0, "hf thinfilm sim" }, - { 1, "hf topaz help" }, - { 0, "hf topaz dump" }, - { 1, "hf topaz list" }, - { 0, "hf topaz info" }, - { 0, "hf topaz reader" }, - { 0, "hf topaz sim" }, - { 0, "hf topaz sniff" }, - { 0, "hf topaz raw" }, - { 0, "hf topaz rdbl" }, - { 1, "hf topaz view" }, - { 0, "hf topaz wrbl" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, - { 1, "hf xerox help" }, - { 0, "hf xerox info" }, - { 0, "hf xerox reader" }, - { 0, "hf xerox dump" }, - { 1, "hf waveshare help" }, - { 0, "hf waveshare loadbmp" }, - { 1, "hw help" }, - { 0, "hw break" }, - { 1, "hw connect" }, - { 0, "hw dbg" }, - { 0, "hw detectreader" }, - { 0, "hw fpgaoff" }, - { 0, "hw lcd" }, - { 0, "hw lcdreset" }, - { 0, "hw ping" }, - { 0, "hw readmem" }, - { 0, "hw reset" }, - { 0, "hw setlfdivisor" }, - { 0, "hw setmux" }, - { 0, "hw standalone" }, - { 0, "hw status" }, - { 0, "hw tearoff" }, - { 0, "hw tia" }, - { 0, "hw tune" }, - { 1, "hw version" }, - { 1, "lf help" }, - { 0, "lf config" }, - { 0, "lf cmdread" }, - { 0, "lf read" }, - { 1, "lf search" }, - { 0, "lf sim" }, - { 0, "lf simask" }, - { 0, "lf simfsk" }, - { 0, "lf simpsk" }, - { 0, "lf simbidir" }, - { 0, "lf sniff" }, - { 0, "lf tune" }, - { 1, "lf awid help" }, - { 1, "lf awid demod" }, - { 0, "lf awid reader" }, - { 0, "lf awid clone" }, - { 0, "lf awid sim" }, - { 0, "lf awid brute" }, - { 0, "lf awid watch" }, - { 1, "lf cotag help" }, - { 1, "lf cotag demod" }, - { 0, "lf cotag reader" }, - { 1, "lf destron help" }, - { 1, "lf destron demod" }, - { 0, "lf destron reader" }, - { 0, "lf destron clone" }, - { 0, "lf destron sim" }, - { 1, "lf em help" }, - { 1, "lf em 410x help" }, - { 1, "lf em 410x demod" }, - { 0, "lf em 410x reader" }, - { 0, "lf em 410x sim" }, - { 0, "lf em 410x brute" }, - { 0, "lf em 410x watch" }, - { 0, "lf em 410x spoof" }, - { 0, "lf em 410x clone" }, - { 1, "lf em 4x05 help" }, - { 0, "lf em 4x05 brute" }, - { 0, "lf em 4x05 chk" }, - { 1, "lf em 4x05 demod" }, - { 0, "lf em 4x05 dump" }, - { 0, "lf em 4x05 info" }, - { 0, "lf em 4x05 read" }, - { 1, "lf em 4x05 sniff" }, - { 0, "lf em 4x05 unlock" }, - { 0, "lf em 4x05 wipe" }, - { 0, "lf em 4x05 write" }, - { 1, "lf em 4x50 help" }, - { 0, "lf em 4x50 brute" }, - { 0, "lf em 4x50 chk" }, - { 0, "lf em 4x50 dump" }, - { 0, "lf em 4x50 info" }, - { 0, "lf em 4x50 login" }, - { 0, "lf em 4x50 rdbl" }, - { 0, "lf em 4x50 reader" }, - { 0, "lf em 4x50 restore" }, - { 0, "lf em 4x50 wrbl" }, - { 0, "lf em 4x50 wrpwd" }, - { 0, "lf em 4x50 wipe" }, - { 0, "lf em 4x50 eload" }, - { 0, "lf em 4x50 esave" }, - { 0, "lf em 4x50 eview" }, - { 0, "lf em 4x50 sim" }, - { 1, "lf em 4x70 help" }, - { 0, "lf em 4x70 info" }, - { 0, "lf em 4x70 write" }, - { 0, "lf em 4x70 unlock" }, - { 0, "lf em 4x70 auth" }, - { 0, "lf em 4x70 writepin" }, - { 0, "lf em 4x70 writekey" }, - { 1, "lf fdxb help" }, - { 1, "lf fdxb demod" }, - { 0, "lf fdxb reader" }, - { 0, "lf fdxb clone" }, - { 0, "lf fdxb sim" }, - { 1, "lf gallagher help" }, - { 1, "lf gallagher demod" }, - { 0, "lf gallagher reader" }, - { 0, "lf gallagher clone" }, - { 0, "lf gallagher sim" }, - { 1, "lf gproxii help" }, - { 1, "lf gproxii demod" }, - { 0, "lf gproxii reader" }, - { 0, "lf gproxii clone" }, - { 0, "lf gproxii sim" }, - { 1, "lf hid help" }, - { 1, "lf hid demod" }, - { 0, "lf hid reader" }, - { 0, "lf hid clone" }, - { 0, "lf hid sim" }, - { 0, "lf hid brute" }, - { 0, "lf hid watch" }, - { 1, "lf hitag help" }, - { 0, "lf hitag eload" }, - { 1, "lf hitag list" }, - { 0, "lf hitag info" }, - { 0, "lf hitag reader" }, - { 0, "lf hitag sim" }, - { 0, "lf hitag sniff" }, - { 0, "lf hitag writer" }, - { 0, "lf hitag dump" }, - { 0, "lf hitag cc" }, - { 1, "lf idteck help" }, - { 1, "lf idteck demod" }, - { 0, "lf idteck reader" }, - { 0, "lf idteck clone" }, - { 0, "lf idteck sim" }, - { 1, "lf indala help" }, - { 1, "lf indala demod" }, - { 1, "lf indala altdemod" }, - { 0, "lf indala reader" }, - { 0, "lf indala clone" }, - { 0, "lf indala sim" }, - { 1, "lf io help" }, - { 1, "lf io demod" }, - { 0, "lf io reader" }, - { 0, "lf io clone" }, - { 0, "lf io sim" }, - { 0, "lf io watch" }, - { 1, "lf jablotron help" }, - { 1, "lf jablotron demod" }, - { 0, "lf jablotron reader" }, - { 0, "lf jablotron clone" }, - { 0, "lf jablotron sim" }, - { 1, "lf keri help" }, - { 1, "lf keri demod" }, - { 0, "lf keri reader" }, - { 0, "lf keri clone" }, - { 0, "lf keri sim" }, - { 1, "lf motorola help" }, - { 1, "lf motorola demod" }, - { 0, "lf motorola reader" }, - { 0, "lf motorola clone" }, - { 0, "lf motorola sim" }, - { 1, "lf nedap help" }, - { 1, "lf nedap demod" }, - { 0, "lf nedap reader" }, - { 0, "lf nedap clone" }, - { 0, "lf nedap sim" }, - { 1, "lf nexwatch help" }, - { 1, "lf nexwatch demod" }, - { 0, "lf nexwatch reader" }, - { 0, "lf nexwatch clone" }, - { 0, "lf nexwatch sim" }, - { 1, "lf noralsy help" }, - { 1, "lf noralsy demod" }, - { 0, "lf noralsy reader" }, - { 0, "lf noralsy clone" }, - { 0, "lf noralsy sim" }, - { 1, "lf pac help" }, - { 1, "lf pac demod" }, - { 0, "lf pac reader" }, - { 0, "lf pac clone" }, - { 0, "lf pac sim" }, - { 1, "lf paradox help" }, - { 1, "lf paradox demod" }, - { 0, "lf paradox reader" }, - { 0, "lf paradox clone" }, - { 0, "lf paradox sim" }, - { 1, "lf pcf7931 help" }, - { 0, "lf pcf7931 reader" }, - { 0, "lf pcf7931 write" }, - { 1, "lf pcf7931 config" }, - { 1, "lf presco help" }, - { 1, "lf presco demod" }, - { 0, "lf presco reader" }, - { 0, "lf presco clone" }, - { 0, "lf presco sim" }, - { 1, "lf pyramid help" }, - { 1, "lf pyramid demod" }, - { 0, "lf pyramid reader" }, - { 0, "lf pyramid clone" }, - { 0, "lf pyramid sim" }, - { 1, "lf securakey help" }, - { 1, "lf securakey demod" }, - { 0, "lf securakey reader" }, - { 0, "lf securakey clone" }, - { 0, "lf securakey sim" }, - { 1, "lf ti help" }, - { 1, "lf ti demod" }, - { 0, "lf ti reader" }, - { 0, "lf ti write" }, - { 1, "lf t55xx help" }, - { 0, "lf t55xx clonehelp" }, - { 1, "lf t55xx config" }, - { 0, "lf t55xx dangerraw" }, - { 1, "lf t55xx detect" }, - { 0, "lf t55xx deviceconfig" }, - { 0, "lf t55xx dump" }, - { 1, "lf t55xx info" }, - { 0, "lf t55xx p1detect" }, - { 0, "lf t55xx read" }, - { 0, "lf t55xx resetread" }, - { 0, "lf t55xx restore" }, - { 1, "lf t55xx trace" }, - { 0, "lf t55xx wakeup" }, - { 0, "lf t55xx write" }, - { 0, "lf t55xx bruteforce" }, - { 0, "lf t55xx chk" }, - { 0, "lf t55xx protect" }, - { 0, "lf t55xx recoverpw" }, - { 1, "lf t55xx sniff" }, - { 0, "lf t55xx special" }, - { 0, "lf t55xx wipe" }, - { 1, "lf viking help" }, - { 1, "lf viking demod" }, - { 0, "lf viking reader" }, - { 0, "lf viking clone" }, - { 0, "lf viking sim" }, - { 1, "lf visa2000 help" }, - { 1, "lf visa2000 demod" }, - { 0, "lf visa2000 reader" }, - { 0, "lf visa2000 clone" }, - { 0, "lf visa2000 sim" }, - { 1, "mem help" }, - { 0, "mem baudrate" }, - { 0, "mem dump" }, - { 0, "mem info" }, - { 0, "mem load" }, - { 0, "mem wipe" }, - { 1, "mem spiffs help" }, - { 0, "mem spiffs copy" }, - { 0, "mem spiffs check" }, - { 0, "mem spiffs dump" }, - { 0, "mem spiffs info" }, - { 0, "mem spiffs mount" }, - { 0, "mem spiffs remove" }, - { 0, "mem spiffs rename" }, - { 0, "mem spiffs test" }, - { 0, "mem spiffs tree" }, - { 0, "mem spiffs unmount" }, - { 0, "mem spiffs upload" }, - { 0, "mem spiffs view" }, - { 0, "mem spiffs wipe" }, - { 1, "nfc help" }, - { 1, "nfc decode" }, - { 0, "nfc type1 read" }, - { 1, "nfc type1 help" }, - { 0, "nfc type2 read" }, - { 1, "nfc type2 help" }, - { 0, "nfc type4a format" }, - { 0, "nfc type4a read" }, - { 0, "nfc type4a write" }, - { 0, "nfc type4a st25taread" }, - { 1, "nfc type4a help" }, - { 0, "nfc type4b read" }, - { 1, "nfc type4b help" }, - { 0, "nfc mf cformat" }, - { 0, "nfc mf cread" }, - { 0, "nfc mf cwrite" }, - { 0, "nfc mf pread" }, - { 1, "nfc mf help" }, - { 0, "nfc barcode read" }, - { 0, "nfc barcode sim" }, - { 1, "nfc barcode help" }, - { 1, "smart help" }, - { 1, "smart list" }, - { 0, "smart info" }, - { 0, "smart reader" }, - { 0, "smart raw" }, - { 1, "smart upgrade" }, - { 0, "smart setclock" }, - { 0, "smart brute" }, - { 1, "script help" }, - { 1, "script list" }, - { 1, "script run" }, - { 1, "trace help" }, - { 1, "trace extract" }, - { 1, "trace list" }, - { 1, "trace load" }, - { 1, "trace save" }, - { 1, "usart help" }, - { 0, "usart btpin" }, - { 0, "usart btfactory" }, - { 0, "usart tx" }, - { 0, "usart rx" }, - { 0, "usart txrx" }, - { 0, "usart txhex" }, - { 0, "usart rxhex" }, - { 0, "usart config" }, - { 1, "wiegand help" }, - { 1, "wiegand list" }, - { 1, "wiegand encode" }, - { 1, "wiegand decode" }, + { 1, "help" }, + { 0, "auto" }, + { 1, "clear" }, + { 1, "hints" }, + { 1, "msleep" }, + { 1, "rem" }, + { 1, "quit" }, + { 1, "exit" }, + { 1, "prefs help" }, + { 1, "prefs show" }, + { 1, "prefs get barmode" }, + { 1, "prefs get clientdebug" }, + { 1, "prefs get clientdelay" }, + { 1, "prefs get color" }, + { 1, "prefs get savepaths" }, + { 1, "prefs get emoji" }, + { 1, "prefs get hints" }, + { 1, "prefs get output" }, + { 1, "prefs get plotsliders" }, + { 1, "prefs set help" }, + { 1, "prefs set barmode" }, + { 1, "prefs set clientdebug" }, + { 1, "prefs set clientdelay" }, + { 1, "prefs set color" }, + { 1, "prefs set emoji" }, + { 1, "prefs set hints" }, + { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, + { 1, "prefs set plotsliders" }, + { 1, "analyse help" }, + { 1, "analyse lcr" }, + { 1, "analyse crc" }, + { 1, "analyse chksum" }, + { 1, "analyse dates" }, + { 1, "analyse lfsr" }, + { 1, "analyse a" }, + { 1, "analyse nuid" }, + { 1, "analyse demodbuff" }, + { 1, "analyse freq" }, + { 1, "analyse foo" }, + { 1, "analyse units" }, + { 1, "data help" }, + { 1, "data biphaserawdecode" }, + { 1, "data detectclock" }, + { 1, "data fsktonrz" }, + { 1, "data manrawdecode" }, + { 1, "data modulation" }, + { 1, "data rawdemod" }, + { 1, "data askedgedetect" }, + { 1, "data autocorr" }, + { 1, "data dirthreshold" }, + { 1, "data decimate" }, + { 1, "data undecimate" }, + { 1, "data hide" }, + { 1, "data hpf" }, + { 1, "data iir" }, + { 1, "data grid" }, + { 1, "data ltrim" }, + { 1, "data mtrim" }, + { 1, "data norm" }, + { 1, "data plot" }, + { 1, "data rtrim" }, + { 1, "data setgraphmarkers" }, + { 1, "data shiftgraphzero" }, + { 1, "data timescale" }, + { 1, "data zerocrossings" }, + { 1, "data convertbitstream" }, + { 1, "data getbitstream" }, + { 1, "data asn1" }, + { 1, "data bin2hex" }, + { 0, "data bitsamples" }, + { 1, "data clear" }, + { 1, "data diff" }, + { 0, "data hexsamples" }, + { 1, "data hex2bin" }, + { 1, "data load" }, + { 1, "data print" }, + { 0, "data samples" }, + { 1, "data save" }, + { 1, "data setdebugmode" }, + { 0, "data tune" }, + { 1, "emv help" }, + { 0, "emv exec" }, + { 0, "emv pse" }, + { 0, "emv search" }, + { 0, "emv select" }, + { 0, "emv gpo" }, + { 0, "emv readrec" }, + { 0, "emv genac" }, + { 0, "emv challenge" }, + { 0, "emv intauth" }, + { 0, "emv scan" }, + { 1, "emv test" }, + { 1, "emv list" }, + { 0, "emv roca" }, + { 1, "hf help" }, + { 1, "hf list" }, + { 0, "hf plot" }, + { 0, "hf tune" }, + { 1, "hf search" }, + { 0, "hf sniff" }, + { 1, "hf 14a help" }, + { 1, "hf 14a list" }, + { 0, "hf 14a antifuzz" }, + { 0, "hf 14a config" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a info" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a apdu" }, + { 0, "hf 14a apdufind" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a ndefformat" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a ndefwrite" }, + { 1, "hf 14b help" }, + { 0, "hf 14b apdu" }, + { 0, "hf 14b dump" }, + { 0, "hf 14b info" }, + { 1, "hf 14b list" }, + { 0, "hf 14b ndefread" }, + { 0, "hf 14b raw" }, + { 0, "hf 14b reader" }, + { 0, "hf 14b sim" }, + { 0, "hf 14b sniff" }, + { 0, "hf 14b rdbl" }, + { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, + { 1, "hf 15 help" }, + { 1, "hf 15 list" }, + { 1, "hf 15 demod" }, + { 0, "hf 15 dump" }, + { 0, "hf 15 info" }, + { 0, "hf 15 sniff" }, + { 0, "hf 15 raw" }, + { 0, "hf 15 rdbl" }, + { 0, "hf 15 rdmulti" }, + { 0, "hf 15 reader" }, + { 0, "hf 15 restore" }, + { 0, "hf 15 samples" }, + { 0, "hf 15 eload" }, + { 0, "hf 15 esave" }, + { 0, "hf 15 eview" }, + { 0, "hf 15 sim" }, + { 0, "hf 15 slixdisable" }, + { 0, "hf 15 wrbl" }, + { 0, "hf 15 findafi" }, + { 0, "hf 15 writeafi" }, + { 0, "hf 15 writedsfid" }, + { 0, "hf 15 csetuid" }, + { 1, "hf cipurse help" }, + { 0, "hf cipurse info" }, + { 0, "hf cipurse select" }, + { 0, "hf cipurse auth" }, + { 0, "hf cipurse read" }, + { 0, "hf cipurse write" }, + { 0, "hf cipurse aread" }, + { 0, "hf cipurse awrite" }, + { 0, "hf cipurse formatall" }, + { 0, "hf cipurse create" }, + { 0, "hf cipurse delete" }, + { 0, "hf cipurse updkey" }, + { 0, "hf cipurse updakey" }, + { 0, "hf cipurse default" }, + { 1, "hf cipurse test" }, + { 1, "hf epa help" }, + { 0, "hf epa cnonces" }, + { 0, "hf epa replay" }, + { 0, "hf epa sim" }, + { 1, "hf emrtd help" }, + { 0, "hf emrtd dump" }, + { 1, "hf emrtd info" }, + { 1, "hf emrtd list" }, + { 1, "hf felica help" }, + { 1, "hf felica list" }, + { 0, "hf felica reader" }, + { 0, "hf felica info" }, + { 0, "hf felica sniff" }, + { 0, "hf felica raw" }, + { 0, "hf felica rdbl" }, + { 0, "hf felica wrbl" }, + { 0, "hf felica rqservice" }, + { 0, "hf felica rqresponse" }, + { 0, "hf felica scsvcode" }, + { 0, "hf felica rqsyscode" }, + { 0, "hf felica auth1" }, + { 0, "hf felica auth2" }, + { 0, "hf felica rqspecver" }, + { 0, "hf felica resetmode" }, + { 0, "hf felica litesim" }, + { 0, "hf felica litedump" }, + { 1, "hf fido help" }, + { 1, "hf fido list" }, + { 0, "hf fido info" }, + { 0, "hf fido reg" }, + { 0, "hf fido auth" }, + { 0, "hf fido make" }, + { 0, "hf fido assert" }, + { 1, "hf fudan help" }, + { 0, "hf fudan reader" }, + { 0, "hf fudan dump" }, + { 0, "hf fudan rdbl" }, + { 1, "hf fudan view" }, + { 0, "hf fudan wrbl" }, + { 1, "hf gallagher help" }, + { 0, "hf gallagher reader" }, + { 0, "hf gallagher clone" }, + { 0, "hf gallagher delete" }, + { 1, "hf gallagher diversifykey" }, + { 1, "hf gallagher decode" }, + { 1, "hf ksx6924 help" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 initialize" }, + { 0, "hf ksx6924 prec" }, + { 0, "hf ksx6924 select" }, + { 1, "hf jooki help" }, + { 0, "hf jooki clone" }, + { 1, "hf jooki decode" }, + { 1, "hf jooki encode" }, + { 0, "hf jooki sim" }, + { 1, "hf iclass help" }, + { 0, "hf iclass dump" }, + { 1, "hf iclass info" }, + { 1, "hf iclass list" }, + { 0, "hf iclass rdbl" }, + { 0, "hf iclass reader" }, + { 0, "hf iclass restore" }, + { 0, "hf iclass sniff" }, + { 0, "hf iclass wrbl" }, + { 0, "hf iclass chk" }, + { 1, "hf iclass loclass" }, + { 1, "hf iclass lookup" }, + { 0, "hf iclass sim" }, + { 0, "hf iclass eload" }, + { 0, "hf iclass esave" }, + { 0, "hf iclass eview" }, + { 1, "hf iclass configcard" }, + { 1, "hf iclass calcnewkey" }, + { 1, "hf iclass encode" }, + { 1, "hf iclass encrypt" }, + { 1, "hf iclass decrypt" }, + { 1, "hf iclass managekeys" }, + { 1, "hf iclass permutekey" }, + { 1, "hf iclass view" }, + { 1, "hf legic help" }, + { 0, "hf legic dump" }, + { 0, "hf legic info" }, + { 1, "hf legic list" }, + { 0, "hf legic rdbl" }, + { 0, "hf legic reader" }, + { 0, "hf legic restore" }, + { 0, "hf legic wipe" }, + { 0, "hf legic wrbl" }, + { 0, "hf legic sim" }, + { 0, "hf legic eload" }, + { 0, "hf legic esave" }, + { 0, "hf legic eview" }, + { 1, "hf legic crc" }, + { 1, "hf legic view" }, + { 1, "hf lto help" }, + { 0, "hf lto dump" }, + { 0, "hf lto info" }, + { 1, "hf lto list" }, + { 0, "hf lto rdbl" }, + { 0, "hf lto reader" }, + { 0, "hf lto restore" }, + { 0, "hf lto wrbl" }, + { 1, "hf mf help" }, + { 1, "hf mf list" }, + { 0, "hf mf darkside" }, + { 0, "hf mf nested" }, + { 1, "hf mf hardnested" }, + { 0, "hf mf staticnested" }, + { 0, "hf mf autopwn" }, + { 0, "hf mf nack" }, + { 0, "hf mf chk" }, + { 0, "hf mf fchk" }, + { 1, "hf mf decrypt" }, + { 0, "hf mf supercard" }, + { 0, "hf mf auth4" }, + { 1, "hf mf acl" }, + { 0, "hf mf dump" }, + { 1, "hf mf mad" }, + { 0, "hf mf personalize" }, + { 0, "hf mf rdbl" }, + { 0, "hf mf rdsc" }, + { 0, "hf mf restore" }, + { 0, "hf mf setmod" }, + { 1, "hf mf value" }, + { 1, "hf mf view" }, + { 0, "hf mf wipe" }, + { 0, "hf mf wrbl" }, + { 0, "hf mf sim" }, + { 0, "hf mf ecfill" }, + { 0, "hf mf eclr" }, + { 0, "hf mf egetblk" }, + { 0, "hf mf egetsc" }, + { 0, "hf mf ekeyprn" }, + { 0, "hf mf eload" }, + { 0, "hf mf esave" }, + { 0, "hf mf esetblk" }, + { 0, "hf mf eview" }, + { 0, "hf mf cgetblk" }, + { 0, "hf mf cgetsc" }, + { 0, "hf mf cload" }, + { 0, "hf mf csave" }, + { 0, "hf mf csetblk" }, + { 0, "hf mf csetuid" }, + { 0, "hf mf cview" }, + { 0, "hf mf cwipe" }, + { 0, "hf mf gen3uid" }, + { 0, "hf mf gen3blk" }, + { 0, "hf mf gen3freeze" }, + { 0, "hf mf ggetblk" }, + { 0, "hf mf gload" }, + { 0, "hf mf gsetblk" }, + { 0, "hf mf gview" }, + { 0, "hf mf ndefformat" }, + { 0, "hf mf ndefread" }, + { 0, "hf mf ndefwrite" }, + { 1, "hf mfp help" }, + { 0, "hf mfp info" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp auth" }, + { 0, "hf mfp rdbl" }, + { 0, "hf mfp rdsc" }, + { 0, "hf mfp wrbl" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp mad" }, + { 0, "hf mfp ndefread" }, + { 1, "hf mfu help" }, + { 1, "hf mfu keygen" }, + { 1, "hf mfu pwdgen" }, + { 0, "hf mfu otptear" }, + { 0, "hf mfu cauth" }, + { 0, "hf mfu dump" }, + { 0, "hf mfu info" }, + { 0, "hf mfu ndefread" }, + { 0, "hf mfu rdbl" }, + { 0, "hf mfu restore" }, + { 1, "hf mfu view" }, + { 0, "hf mfu wrbl" }, + { 0, "hf mfu eload" }, + { 0, "hf mfu eview" }, + { 0, "hf mfu sim" }, + { 0, "hf mfu setpwd" }, + { 0, "hf mfu setuid" }, + { 1, "hf mfdes help" }, + { 0, "hf mfdes info" }, + { 0, "hf mfdes getuid" }, + { 0, "hf mfdes default" }, + { 0, "hf mfdes auth" }, + { 0, "hf mfdes chk" }, + { 0, "hf mfdes detect" }, + { 0, "hf mfdes freemem" }, + { 0, "hf mfdes setconfig" }, + { 0, "hf mfdes formatpicc" }, + { 1, "hf mfdes list" }, + { 0, "hf mfdes mad" }, + { 0, "hf mfdes lsapp" }, + { 0, "hf mfdes getaids" }, + { 0, "hf mfdes getappnames" }, + { 0, "hf mfdes bruteaid" }, + { 0, "hf mfdes createapp" }, + { 0, "hf mfdes deleteapp" }, + { 0, "hf mfdes selectapp" }, + { 0, "hf mfdes changekey" }, + { 0, "hf mfdes chkeysettings" }, + { 0, "hf mfdes getkeysettings" }, + { 0, "hf mfdes getkeyversions" }, + { 0, "hf mfdes getfileids" }, + { 0, "hf mfdes getfileisoids" }, + { 0, "hf mfdes lsfiles" }, + { 0, "hf mfdes dump" }, + { 0, "hf mfdes createfile" }, + { 0, "hf mfdes createvaluefile" }, + { 0, "hf mfdes createrecordfile" }, + { 0, "hf mfdes createmacfile" }, + { 0, "hf mfdes deletefile" }, + { 0, "hf mfdes getfilesettings" }, + { 0, "hf mfdes chfilesettings" }, + { 0, "hf mfdes read" }, + { 0, "hf mfdes write" }, + { 0, "hf mfdes value" }, + { 0, "hf mfdes clearrecfile" }, + { 1, "hf mfdes test" }, + { 1, "hf ntag424 help" }, + { 0, "hf ntag424 info" }, + { 0, "hf ntag424 sdm" }, + { 1, "hf ntag424 view" }, + { 1, "hf seos help" }, + { 0, "hf seos info" }, + { 1, "hf seos list" }, + { 1, "hf st25ta help" }, + { 0, "hf st25ta info" }, + { 1, "hf st25ta list" }, + { 1, "hf st25ta ndefread" }, + { 0, "hf st25ta protect" }, + { 0, "hf st25ta pwd" }, + { 0, "hf st25ta sim" }, + { 1, "hf thinfilm help" }, + { 0, "hf thinfilm info" }, + { 1, "hf thinfilm list" }, + { 0, "hf thinfilm sim" }, + { 1, "hf topaz help" }, + { 0, "hf topaz dump" }, + { 1, "hf topaz list" }, + { 0, "hf topaz info" }, + { 0, "hf topaz reader" }, + { 0, "hf topaz sim" }, + { 0, "hf topaz sniff" }, + { 0, "hf topaz raw" }, + { 0, "hf topaz rdbl" }, + { 1, "hf topaz view" }, + { 0, "hf topaz wrbl" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, + { 0, "hf xerox dump" }, + { 1, "hf waveshare help" }, + { 0, "hf waveshare loadbmp" }, + { 1, "hw help" }, + { 0, "hw break" }, + { 1, "hw connect" }, + { 0, "hw dbg" }, + { 0, "hw detectreader" }, + { 0, "hw fpgaoff" }, + { 0, "hw lcd" }, + { 0, "hw lcdreset" }, + { 0, "hw ping" }, + { 0, "hw readmem" }, + { 0, "hw reset" }, + { 0, "hw setlfdivisor" }, + { 0, "hw setmux" }, + { 0, "hw standalone" }, + { 0, "hw status" }, + { 0, "hw tearoff" }, + { 0, "hw tia" }, + { 0, "hw tune" }, + { 1, "hw version" }, + { 1, "lf help" }, + { 0, "lf config" }, + { 0, "lf cmdread" }, + { 0, "lf read" }, + { 1, "lf search" }, + { 0, "lf sim" }, + { 0, "lf simask" }, + { 0, "lf simfsk" }, + { 0, "lf simpsk" }, + { 0, "lf simbidir" }, + { 0, "lf sniff" }, + { 0, "lf tune" }, + { 1, "lf awid help" }, + { 1, "lf awid demod" }, + { 0, "lf awid reader" }, + { 0, "lf awid clone" }, + { 0, "lf awid sim" }, + { 0, "lf awid brute" }, + { 0, "lf awid watch" }, + { 1, "lf cotag help" }, + { 1, "lf cotag demod" }, + { 0, "lf cotag reader" }, + { 1, "lf destron help" }, + { 1, "lf destron demod" }, + { 0, "lf destron reader" }, + { 0, "lf destron clone" }, + { 0, "lf destron sim" }, + { 1, "lf em help" }, + { 1, "lf em 410x help" }, + { 1, "lf em 410x demod" }, + { 0, "lf em 410x reader" }, + { 0, "lf em 410x sim" }, + { 0, "lf em 410x brute" }, + { 0, "lf em 410x watch" }, + { 0, "lf em 410x spoof" }, + { 0, "lf em 410x clone" }, + { 1, "lf em 4x05 help" }, + { 0, "lf em 4x05 brute" }, + { 0, "lf em 4x05 chk" }, + { 1, "lf em 4x05 demod" }, + { 0, "lf em 4x05 dump" }, + { 0, "lf em 4x05 info" }, + { 0, "lf em 4x05 read" }, + { 1, "lf em 4x05 sniff" }, + { 0, "lf em 4x05 unlock" }, + { 0, "lf em 4x05 wipe" }, + { 0, "lf em 4x05 write" }, + { 1, "lf em 4x50 help" }, + { 0, "lf em 4x50 brute" }, + { 0, "lf em 4x50 chk" }, + { 0, "lf em 4x50 dump" }, + { 0, "lf em 4x50 info" }, + { 0, "lf em 4x50 login" }, + { 0, "lf em 4x50 rdbl" }, + { 0, "lf em 4x50 reader" }, + { 0, "lf em 4x50 restore" }, + { 0, "lf em 4x50 wrbl" }, + { 0, "lf em 4x50 wrpwd" }, + { 0, "lf em 4x50 wipe" }, + { 0, "lf em 4x50 eload" }, + { 0, "lf em 4x50 esave" }, + { 0, "lf em 4x50 eview" }, + { 0, "lf em 4x50 sim" }, + { 1, "lf em 4x70 help" }, + { 0, "lf em 4x70 info" }, + { 0, "lf em 4x70 write" }, + { 0, "lf em 4x70 unlock" }, + { 0, "lf em 4x70 auth" }, + { 0, "lf em 4x70 writepin" }, + { 0, "lf em 4x70 writekey" }, + { 1, "lf fdxb help" }, + { 1, "lf fdxb demod" }, + { 0, "lf fdxb reader" }, + { 0, "lf fdxb clone" }, + { 0, "lf fdxb sim" }, + { 1, "lf gallagher help" }, + { 1, "lf gallagher demod" }, + { 0, "lf gallagher reader" }, + { 0, "lf gallagher clone" }, + { 0, "lf gallagher sim" }, + { 1, "lf gproxii help" }, + { 1, "lf gproxii demod" }, + { 0, "lf gproxii reader" }, + { 0, "lf gproxii clone" }, + { 0, "lf gproxii sim" }, + { 1, "lf hid help" }, + { 1, "lf hid demod" }, + { 0, "lf hid reader" }, + { 0, "lf hid clone" }, + { 0, "lf hid sim" }, + { 0, "lf hid brute" }, + { 0, "lf hid watch" }, + { 1, "lf hitag help" }, + { 0, "lf hitag eload" }, + { 1, "lf hitag list" }, + { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, + { 0, "lf hitag sim" }, + { 0, "lf hitag sniff" }, + { 0, "lf hitag writer" }, + { 0, "lf hitag dump" }, + { 0, "lf hitag cc" }, + { 1, "lf idteck help" }, + { 1, "lf idteck demod" }, + { 0, "lf idteck reader" }, + { 0, "lf idteck clone" }, + { 0, "lf idteck sim" }, + { 1, "lf indala help" }, + { 0, "lf indala brute" }, + { 1, "lf indala demod" }, + { 1, "lf indala altdemod" }, + { 0, "lf indala reader" }, + { 0, "lf indala clone" }, + { 0, "lf indala sim" }, + { 1, "lf io help" }, + { 1, "lf io demod" }, + { 0, "lf io reader" }, + { 0, "lf io clone" }, + { 0, "lf io sim" }, + { 0, "lf io watch" }, + { 1, "lf jablotron help" }, + { 1, "lf jablotron demod" }, + { 0, "lf jablotron reader" }, + { 0, "lf jablotron clone" }, + { 0, "lf jablotron sim" }, + { 1, "lf keri help" }, + { 1, "lf keri demod" }, + { 0, "lf keri reader" }, + { 0, "lf keri clone" }, + { 0, "lf keri sim" }, + { 1, "lf motorola help" }, + { 1, "lf motorola demod" }, + { 0, "lf motorola reader" }, + { 0, "lf motorola clone" }, + { 0, "lf motorola sim" }, + { 1, "lf nedap help" }, + { 1, "lf nedap demod" }, + { 0, "lf nedap reader" }, + { 0, "lf nedap clone" }, + { 0, "lf nedap sim" }, + { 1, "lf nexwatch help" }, + { 1, "lf nexwatch demod" }, + { 0, "lf nexwatch reader" }, + { 0, "lf nexwatch clone" }, + { 0, "lf nexwatch sim" }, + { 1, "lf noralsy help" }, + { 1, "lf noralsy demod" }, + { 0, "lf noralsy reader" }, + { 0, "lf noralsy clone" }, + { 0, "lf noralsy sim" }, + { 1, "lf pac help" }, + { 1, "lf pac demod" }, + { 0, "lf pac reader" }, + { 0, "lf pac clone" }, + { 0, "lf pac sim" }, + { 1, "lf paradox help" }, + { 1, "lf paradox demod" }, + { 0, "lf paradox reader" }, + { 0, "lf paradox clone" }, + { 0, "lf paradox sim" }, + { 1, "lf pcf7931 help" }, + { 0, "lf pcf7931 reader" }, + { 0, "lf pcf7931 write" }, + { 1, "lf pcf7931 config" }, + { 1, "lf presco help" }, + { 1, "lf presco demod" }, + { 0, "lf presco reader" }, + { 0, "lf presco clone" }, + { 0, "lf presco sim" }, + { 1, "lf pyramid help" }, + { 1, "lf pyramid demod" }, + { 0, "lf pyramid reader" }, + { 0, "lf pyramid clone" }, + { 0, "lf pyramid sim" }, + { 1, "lf securakey help" }, + { 1, "lf securakey demod" }, + { 0, "lf securakey reader" }, + { 0, "lf securakey clone" }, + { 0, "lf securakey sim" }, + { 1, "lf ti help" }, + { 1, "lf ti demod" }, + { 0, "lf ti reader" }, + { 0, "lf ti write" }, + { 1, "lf t55xx help" }, + { 0, "lf t55xx clonehelp" }, + { 1, "lf t55xx config" }, + { 0, "lf t55xx dangerraw" }, + { 1, "lf t55xx detect" }, + { 0, "lf t55xx deviceconfig" }, + { 0, "lf t55xx dump" }, + { 1, "lf t55xx info" }, + { 0, "lf t55xx p1detect" }, + { 0, "lf t55xx read" }, + { 0, "lf t55xx resetread" }, + { 0, "lf t55xx restore" }, + { 1, "lf t55xx trace" }, + { 0, "lf t55xx wakeup" }, + { 0, "lf t55xx write" }, + { 0, "lf t55xx bruteforce" }, + { 0, "lf t55xx chk" }, + { 0, "lf t55xx protect" }, + { 0, "lf t55xx recoverpw" }, + { 1, "lf t55xx sniff" }, + { 0, "lf t55xx special" }, + { 0, "lf t55xx wipe" }, + { 1, "lf viking help" }, + { 1, "lf viking demod" }, + { 0, "lf viking reader" }, + { 0, "lf viking clone" }, + { 0, "lf viking sim" }, + { 1, "lf visa2000 help" }, + { 1, "lf visa2000 demod" }, + { 0, "lf visa2000 reader" }, + { 0, "lf visa2000 clone" }, + { 0, "lf visa2000 sim" }, + { 1, "mem help" }, + { 0, "mem baudrate" }, + { 0, "mem dump" }, + { 0, "mem info" }, + { 0, "mem load" }, + { 0, "mem wipe" }, + { 1, "mem spiffs help" }, + { 0, "mem spiffs copy" }, + { 0, "mem spiffs check" }, + { 0, "mem spiffs dump" }, + { 0, "mem spiffs info" }, + { 0, "mem spiffs mount" }, + { 0, "mem spiffs remove" }, + { 0, "mem spiffs rename" }, + { 0, "mem spiffs test" }, + { 0, "mem spiffs tree" }, + { 0, "mem spiffs unmount" }, + { 0, "mem spiffs upload" }, + { 0, "mem spiffs view" }, + { 0, "mem spiffs wipe" }, + { 1, "nfc help" }, + { 1, "nfc decode" }, + { 0, "nfc type1 read" }, + { 1, "nfc type1 help" }, + { 0, "nfc type2 read" }, + { 1, "nfc type2 help" }, + { 0, "nfc type4a format" }, + { 0, "nfc type4a read" }, + { 0, "nfc type4a write" }, + { 0, "nfc type4a st25taread" }, + { 1, "nfc type4a help" }, + { 0, "nfc type4b read" }, + { 1, "nfc type4b help" }, + { 0, "nfc mf cformat" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf cwrite" }, + { 0, "nfc mf pread" }, + { 1, "nfc mf help" }, + { 0, "nfc barcode read" }, + { 0, "nfc barcode sim" }, + { 1, "nfc barcode help" }, + { 1, "smart help" }, + { 1, "smart list" }, + { 0, "smart info" }, + { 0, "smart reader" }, + { 0, "smart raw" }, + { 1, "smart upgrade" }, + { 0, "smart setclock" }, + { 0, "smart brute" }, + { 1, "script help" }, + { 1, "script list" }, + { 1, "script run" }, + { 1, "trace help" }, + { 1, "trace extract" }, + { 1, "trace list" }, + { 1, "trace load" }, + { 1, "trace save" }, + { 1, "usart help" }, + { 0, "usart btpin" }, + { 0, "usart btfactory" }, + { 0, "usart tx" }, + { 0, "usart rx" }, + { 0, "usart txrx" }, + { 0, "usart txhex" }, + { 0, "usart rxhex" }, + { 0, "usart config" }, + { 1, "wiegand help" }, + { 1, "wiegand list" }, + { 1, "wiegand encode" }, + { 1, "wiegand decode" }, {0, NULL} }; @@ -766,4 +771,4 @@ const static vocabulory_t vocabulory[] = { } #endif -#endif +#endif \ No newline at end of file diff --git a/doc/commands.json b/doc/commands.json index fd08851b8..c9ce72f8c 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -4303,6 +4303,64 @@ ], "usage": "hf mf gen3uid [-h] [-u ]" }, + "hf mf ggetblk": { + "command": "hf mf ggetblk", + "description": "Get block data from magic gen4 GTU card.", + "notes": [ + "hf mf ggetblk --blk 0 -> get block 0 (manufacturer)", + "hf mf ggetblk --blk 3 -v -> get block 3, decode sector trailer" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-b, --blk block number", + "-v, --verbose verbose output", + "-p, --pwd password 4bytes" + ], + "usage": "hf mf ggetblk [-hv] -b [-p ]" + }, + "hf mf gload": { + "command": "hf mf gload", + "description": "Load magic gen4 gtu card with data from (bin/eml/json) dump file or from emulator memory.", + "notes": [ + "hf mf gload --emu", + "hf mf gload -f hf-mf-01020304.eml", + "hf mf gload -p AABBCCDD --4k -v -f hf-mf-01020304-dump.bin", + "", + "Card must be configured beforehand with `script run hf_mf_ultimatecard`.", + "Blocks are 16 bytes long." + ], + "offline": false, + "options": [ + "-h, --help This help", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70", + "-p, --pwd password 4bytes", + "-v, --verbose verbose output", + "-f, --file filename of dump", + "--emu from emulator memory", + "--start index of block to start writing (default 0)", + "--end index of block to end writing (default last block)" + ], + "usage": "hf mf gload [-hv] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu] --start --end " + }, + "hf mf gsetblk": { + "command": "hf mf gsetblk", + "description": "Set block data on a magic gen4 GTU card", + "notes": [ + "hf mf gsetblk --blk 1 -d 000102030405060708090a0b0c0d0e0f" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-b, --blk block number", + "-d, --data bytes to write, 16 hex bytes", + "-p, --pwd password 4bytes" + ], + "usage": "hf mf gsetblk [-h] -b [-d ] [-p ]" + }, "hf mf gview": { "command": "hf mf gview", "description": "View `magic gen4 gtu` card memory", @@ -11537,8 +11595,8 @@ } }, "metadata": { - "commands_extracted": 728, + "commands_extracted": 731, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-10-30T15:28:49" + "extracted_on": "2022-11-05T18:17:23" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index a19a97a13..498d62b62 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -510,6 +510,9 @@ Check column "offline" for their availability. |`hf mf gen3uid `|N |`Set UID without changing manufacturer block` |`hf mf gen3blk `|N |`Overwrite manufacturer block` |`hf mf gen3freeze `|N |`Perma lock UID changes. irreversible` +|`hf mf ggetblk `|N |`Read block from card` +|`hf mf gload `|N |`Load dump to card` +|`hf mf gsetblk `|N |`Write block to card` |`hf mf gview `|N |`View card` |`hf mf ndefformat `|N |`Format MIFARE Classic Tag as NFC Tag` |`hf mf ndefread `|N |`Read and print NDEF records from card` diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 412ca2ba6..eebf0bfd3 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -676,6 +676,7 @@ typedef struct { // Gen 4 GTU magic cards #define CMD_HF_MIFARE_G4_RDBL 0x0860 +#define CMD_HF_MIFARE_G4_WRBL 0x0861 #define CMD_UNKNOWN 0xFFFF From 4f2d86558e361770f3f7167d20d332ded6e97d1a Mon Sep 17 00:00:00 2001 From: DidierA Date: Sat, 5 Nov 2022 20:20:01 +0100 Subject: [PATCH 334/759] correct wrong type in formatting function --- client/src/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index a4269326d..222d0f961 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6961,7 +6961,7 @@ static int CmdHF14AGen4Load(const char *cmd) { PrintAndLogEx(INFO, "File: " _YELLOW_("%s"), filename); PrintAndLogEx(INFO, "File size %zu bytes, file blocks %d (0x%x)", bytes_read, block_cnt, block_cnt); } else { - PrintAndLogEx(INFO, "Read %zu blocks from emulator memory", block_cnt); + PrintAndLogEx(INFO, "Read %d blocks from emulator memory", block_cnt); } } From 3ac9c61cbf2becc81289b8de743f4138f8117f01 Mon Sep 17 00:00:00 2001 From: DidierA Date: Tue, 8 Nov 2022 01:53:31 +0100 Subject: [PATCH 335/759] Fix read oob in data diff --- client/src/cmddata.c | 152 +++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 93 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 6b2793df0..647c062a4 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -3063,8 +3063,8 @@ static int CmdDiff(const char *Cmd) { } */ - size_t n = (datalenA > datalenB) ? datalenB : datalenA; - PrintAndLogEx(DEBUG, "data len: %zu A %zu B %zu", n, datalenA, datalenB); + size_t biggest = (datalenA > datalenB) ? datalenA : datalenB; + PrintAndLogEx(DEBUG, "data len: %zu A %zu B %zu", biggest, datalenA, datalenB); if (inA == NULL) PrintAndLogEx(INFO, "inA null"); @@ -3091,102 +3091,68 @@ static int CmdDiff(const char *Cmd) { char line[880] = {0}; // print data diff loop - int i; - for (i = 0; i < n; i += width) { + for (int i = 0 ; i < biggest ; i += width) { + char dlnA[240] = {0}; + char dlnB[240] = {0}; + char dlnAii[180] = {0}; + char dlnBii[180] = {0}; - memset(line, 0, sizeof(line)); + memset(dlnA, 0, sizeof(dlnA)); + memset(dlnB, 0, sizeof(dlnB)); + memset(dlnAii, 0, sizeof(dlnAii)); + memset(dlnBii, 0, sizeof(dlnBii)); - int diff = memcmp(inA + i, inB + i, width); + for (int j = i; j < i + width; j++) { + int dlnALen = strlen(dlnA); + int dlnBLen = strlen(dlnB); + int dlnAiiLen = strlen(dlnAii); + int dlnBiiLen = strlen(dlnBii); - // if ok, just print - if (diff == 0) { - hex_to_buffer((uint8_t *)line, inA + i, width, sizeof(line), 0, 1, true); - ascii_to_buffer((uint8_t *)(line + strlen(line)), inA + i, width, width, 0); - strncat(line + strlen(line), " | ", sizeof(line) - strlen(line)); - hex_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, sizeof(line), 0, 1, true); - ascii_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, width, 0); - } else { - - char dlnA[240] = {0}; - char dlnB[240] = {0}; - char dlnAii[180] = {0}; - char dlnBii[180] = {0}; - - memset(dlnA, 0, sizeof(dlnA)); - memset(dlnB, 0, sizeof(dlnB)); - memset(dlnAii, 0, sizeof(dlnAii)); - memset(dlnBii, 0, sizeof(dlnBii)); - - // if diff, time to find it - for (int j = i; j < (i + width); j++) { - - char ca = inA[j]; - char cb = inB[j]; - - int dlnALen = strlen(dlnA); - int dlnBLen = strlen(dlnB); - int dlnAiiLen = strlen(dlnAii); - int dlnBiiLen = strlen(dlnBii); - - if (inA[j] != inB[j]) { - - // diff / add colors - snprintf(dlnA + dlnALen, sizeof(dlnA) - dlnALen, _GREEN_("%02X "), inA[j]); - snprintf(dlnB + dlnBLen, sizeof(dlnB) - dlnBLen, _RED_("%02X "), inB[j]); - snprintf(dlnAii + dlnAiiLen, sizeof(dlnAii) - dlnAiiLen, _GREEN_("%c"), ((ca < 32) || (ca == 127)) ? '.' : ca); - snprintf(dlnBii + dlnBiiLen, sizeof(dlnBii) - dlnBiiLen, _RED_("%c"), ((cb < 32) || (cb == 127)) ? '.' : cb); - - } else { - // normal - snprintf(dlnA + dlnALen, sizeof(dlnA) - dlnALen, "%02X ", inA[j]); - snprintf(dlnB + dlnBLen, sizeof(dlnB) - dlnBLen, "%02X ", inB[j]); - snprintf(dlnAii + dlnAiiLen, sizeof(dlnAii) - dlnAiiLen, "%c", ((ca < 32) || (ca == 127)) ? '.' : ca); - snprintf(dlnBii + dlnBiiLen, sizeof(dlnBii) - dlnBiiLen, "%c", ((cb < 32) || (cb == 127)) ? '.' : cb); - } + //both files ended + if (j >= datalenA && j >= datalenB) { + snprintf(dlnA + dlnALen, sizeof(dlnA) - dlnALen, "-- "); + snprintf(dlnAii + dlnAiiLen, sizeof(dlnAii) - dlnAiiLen, ".") ; + snprintf(dlnB + dlnBLen, sizeof(dlnB) - dlnBLen, "-- "); + snprintf(dlnBii + dlnBiiLen, sizeof(dlnBii) - dlnBiiLen, ".") ; + continue ; + } + + char ca, cb; + + if (j >= datalenA) { + // file A ended. print B without colors + cb = inB[j]; + snprintf(dlnA + dlnALen, sizeof(dlnA) - dlnALen, "-- "); + snprintf(dlnAii + dlnAiiLen, sizeof(dlnAii) - dlnAiiLen, ".") ; + snprintf(dlnB + dlnBLen, sizeof(dlnB) - dlnBLen, "%02X ", inB[j]); + snprintf(dlnBii + dlnBiiLen, sizeof(dlnBii) - dlnBiiLen, "%c", ((cb < 32) || (cb == 127)) ? '.' : cb); + continue ; + } + ca = inA[j]; + if (j >= datalenB) { + // file B ended. print A without colors + snprintf(dlnA + dlnALen, sizeof(dlnA) - dlnALen, "%02X ", inA[j]); + snprintf(dlnAii + dlnAiiLen, sizeof(dlnAii) - dlnAiiLen, "%c", ((ca < 32) || (ca == 127)) ? '.' : ca); + snprintf(dlnB + dlnBLen, sizeof(dlnB) - dlnBLen, "-- "); + snprintf(dlnBii + dlnBiiLen, sizeof(dlnBii) - dlnBiiLen, ".") ; + continue ; + } + cb = inB[j]; + if (inA[j] != inB[j]) { + // diff / add colors + snprintf(dlnA + dlnALen, sizeof(dlnA) - dlnALen, _GREEN_("%02X "), inA[j]); + snprintf(dlnB + dlnBLen, sizeof(dlnB) - dlnBLen, _RED_("%02X "), inB[j]); + snprintf(dlnAii + dlnAiiLen, sizeof(dlnAii) - dlnAiiLen, _GREEN_("%c"), ((ca < 32) || (ca == 127)) ? '.' : ca); + snprintf(dlnBii + dlnBiiLen, sizeof(dlnBii) - dlnBiiLen, _RED_("%c"), ((cb < 32) || (cb == 127)) ? '.' : cb); + } else { + // normal + snprintf(dlnA + dlnALen, sizeof(dlnA) - dlnALen, "%02X ", inA[j]); + snprintf(dlnB + dlnBLen, sizeof(dlnB) - dlnBLen, "%02X ", inB[j]); + snprintf(dlnAii + dlnAiiLen, sizeof(dlnAii) - dlnAiiLen, "%c", ((ca < 32) || (ca == 127)) ? '.' : ca); + snprintf(dlnBii + dlnBiiLen, sizeof(dlnBii) - dlnBiiLen, "%c", ((cb < 32) || (cb == 127)) ? '.' : cb); } - snprintf(line, sizeof(line), "%s%s | %s%s", dlnA, dlnAii, dlnB, dlnBii); - } - PrintAndLogEx(INFO, "%03X | %s", i, line); - } - - // mod - - - // print different length - bool tallestA = (datalenA > datalenB); - if (tallestA) { - n = datalenA; - } else { - n = datalenB; - } - - // print data diff loop - for (; i < n; i += width) { - - memset(line, 0, sizeof(line)); - - if (tallestA) { - hex_to_buffer((uint8_t *)line, inA + i, width, sizeof(line), 0, 1, true); - ascii_to_buffer((uint8_t *)(line + strlen(line)), inA + i, width, sizeof(line), 0); - strcat(line + strlen(line), " | "); - for (int j = 0; j < width; j++) { - strncat(line + strlen(line), "-- ", sizeof(line) - strlen(line)); - } - for (int j = 0; j < width; j++) { - strncat(line + strlen(line), ".", sizeof(line) - strlen(line)); - } - } else { - - for (int j = 0; j < width; j++) { - strncat(line + strlen(line), "-- ", sizeof(line) - strlen(line)); - } - for (int j = 0; j < width; j++) { - strncat(line + strlen(line), ".", sizeof(line) - strlen(line)); - } - strncat(line + strlen(line), " | ", sizeof(line) - strlen(line)); - hex_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, sizeof(line), 0, 1, true); - ascii_to_buffer((uint8_t *)(line + strlen(line)), inB + i, width, sizeof(line), 0); } + snprintf(line, sizeof(line), "%s%s | %s%s", dlnA, dlnAii, dlnB, dlnBii); PrintAndLogEx(INFO, "%03X | %s", i, line); } From c8f8685819332c4c878f844bb9690f2f4bc970df Mon Sep 17 00:00:00 2001 From: elcuervo Date: Tue, 8 Nov 2022 10:07:07 -0300 Subject: [PATCH 336/759] Adds some context for both Argentina and Uruguay keys --- client/dictionaries/mfc_default_keys.dic | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 752fa06b3..3a11457f2 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -607,7 +607,6 @@ B725F9CBF183 11428B5BCE0F 18971D893494 25D60050BF6E -3FA7217EC575 44F0B5FBE344 7B296F353C6B 8553263F4FF0 @@ -621,6 +620,9 @@ D4FE03CE5B09 D4FE03CE5B0A D4FE03CE5B0F E241E8AFCBAF +# Transport system Argentina - SUBE +# Shared key - sec 3 blk 15 +3FA7217EC575 # # Data from forum post 123F8888F322 @@ -1893,6 +1895,6 @@ FFFFFFAAAAAA # Added by VideoMan. # Random Hotel A Key Sec 0 Blk 3 - KABA Lock 3111A3A303EB -# Transport system Uruguay -# Shared key +# Transport system Uruguay - STM +# Shared key - sec 0 blk 3 D144BD193063 From 885911c469a8ef6d46cbb72c25947801704eb89d Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Wed, 9 Nov 2022 15:49:07 +0100 Subject: [PATCH 337/759] Rewrite of magic Gen4 GTU commands : refactor and speed --- armsrc/appmain.c | 8 +- armsrc/mifarecmd.c | 131 +++++++++++++++++++-------------- armsrc/mifarecmd.h | 5 +- client/src/cmdhfmf.c | 8 +- client/src/mifare/mifarehost.c | 8 +- client/src/mifare/mifarehost.h | 4 +- 6 files changed, 94 insertions(+), 70 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index d48483b53..f59cc13a3 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1651,20 +1651,22 @@ static void PacketReceived(PacketCommandNG *packet) { struct p { uint8_t blockno; uint8_t pwd[4]; + uint8_t workFlags; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - MifareG4ReadBlk(payload->blockno, payload->pwd); + MifareG4ReadBlk(payload->blockno, payload->pwd, payload->workFlags); break; } - + // Gen 4 GTU magic cards case CMD_HF_MIFARE_G4_WRBL: { struct p { uint8_t blockno; uint8_t pwd[4]; uint8_t data[16]; // data to be written + uint8_t workFlags; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - MifareG4WriteBlk(payload->blockno, payload->pwd, payload->data); + MifareG4WriteBlk(payload->blockno, payload->pwd, payload->data, payload->workFlags); break; } case CMD_HF_MIFARE_PERSONALIZE_UID: { diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 476e7c96a..e1e8dc2a9 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2684,90 +2684,107 @@ OUT: BigBuf_free(); } -void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd) { - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); +// read or write block to GEN4 GTU tag +void MifareG4ReadWriteBlk(uint8_t rw, uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags) { + bool read = rw & 0x1 & 0xFF ; + bool write = rw & 0x2 & 0xFF ; - int retval = PM3_SUCCESS; - uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); - uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); - uint8_t *uid = BigBuf_malloc(10); - if (iso14443a_select_card(uid, NULL, NULL, true, 0, true) == false) { - retval = PM3_ESOFT; - goto OUT; - } - - LED_B_ON(); - uint32_t save_iso14a_timeout = iso14a_get_timeout(); - iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout - - uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, 0xCE, blockno, 0x00, 0x00}; - - memcpy(cmd + 1, pwd, 4); - - AddCrc14A(cmd, sizeof(cmd) - 2); - - ReaderTransmit(cmd, sizeof(cmd), NULL); - int res = ReaderReceive(buf, par); - if (res != 18) { - retval = PM3_ESOFT; - } - iso14a_set_timeout(save_iso14a_timeout); - LED_B_OFF(); - -OUT: - reply_ng(CMD_HF_MIFARE_G4_RDBL, retval, buf, 18); - // turns off - OnSuccessMagic(); - BigBuf_free(); -} - -void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data) { - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - set_tracing(true); + bool setup = workFlags & MAGIC_INIT & 0xFF ; + bool done = workFlags & MAGIC_OFF & 0xFF ; int res = 0; int retval = PM3_SUCCESS; - uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); + uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); - uint8_t *uid = BigBuf_malloc(10); - if (iso14443a_select_card(uid, NULL, NULL, true, 0, true) == false) { - retval = PM3_ESOFT; + if (buf == NULL) { + retval = PM3_EMALLOC; goto OUT; } - LED_B_ON(); - uint32_t save_iso14a_timeout = iso14a_get_timeout(); - iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout + // check args + if (write && (data == NULL)) { + retval = PM3_EINVARG; + goto OUT; + } - uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, 0xCD, blockno, + if (!(read || write)) { + retval = PM3_EINVARG; + goto OUT; + } + + uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); + if (par == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + + if (setup) { + uint8_t *uid = BigBuf_malloc(10); + if (uid == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + + if (iso14443a_select_card(uid, NULL, NULL, true, 0, true) == false) { + retval = PM3_ESOFT; + goto OUT; + } + } + + LED_B_ON(); + + static uint32_t save_iso14a_timeout; + if (setup) { + save_iso14a_timeout = iso14a_get_timeout(); + iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout + } + + uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, (write ? 0xCD : 0xCE), blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(cmd + 1, pwd, 4); - memcpy(cmd + 7, data, 16); + if (write) memcpy(cmd + 7, data, 16); - AddCrc14A(cmd, sizeof(cmd) - 2); + size_t crc_pos = read ? 7 : (sizeof(cmd) - 2) ; + AddCrc14A(cmd, crc_pos); - ReaderTransmit(cmd, sizeof(cmd), NULL); + ReaderTransmit(cmd, crc_pos + 2, NULL); res = ReaderReceive(buf, par); - if ((res != 4) || (memcmp(buf, "\x90\x00\xfd\x07", 4) != 0)) { + + if (write) { + if ((res != 4) || (memcmp(buf, "\x90\x00\xfd\x07", 4) != 0)) { + retval = PM3_ESOFT; + } + } else if (res != 18) { retval = PM3_ESOFT; } - iso14a_set_timeout(save_iso14a_timeout); + + if (done || retval != 0) iso14a_set_timeout(save_iso14a_timeout); LED_B_OFF(); OUT: - reply_ng(CMD_HF_MIFARE_G4_WRBL, retval, buf, res); + reply_ng(write ? CMD_HF_MIFARE_G4_WRBL : CMD_HF_MIFARE_G4_RDBL, retval, buf, res); // turns off - OnSuccessMagic(); + if (done || retval != 0) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + if (done || retval != 0) set_tracing(false); BigBuf_free(); } +void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags) { + MifareG4ReadWriteBlk(0x1, blockno, pwd, NULL, workFlags) ; +} + +void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags) { + MifareG4ReadWriteBlk(0x2, blockno, pwd, data, workFlags) ; +} + void MifareSetMod(uint8_t *datain) { uint8_t mod = datain[0]; diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index de3bd416c..a68fed8db 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -57,8 +57,9 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block); // Gen 3 magic card overw void MifareGen3Freez(void); // Gen 3 magic card lock further UID changes // MFC GEN4 GTU -void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd); -void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data); +void MifareG4ReadWriteBlk(uint8_t rw, uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags); +void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags); +void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags); void MifareSetMod(uint8_t *datain); void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 222d0f961..b0c80f54a 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6788,7 +6788,7 @@ static int CmdHF14AGen4GetBlk(const char *cmd) { PrintAndLogEx(NORMAL, "Block: %x", blockno) ; - int res = mfG4GetBlock(pwd, blockno, data); + int res = mfG4GetBlock(pwd, blockno, data, MAGIC_INIT | MAGIC_OFF); if (res) { PrintAndLogEx(ERR, "Can't read block. error=%d", res); return PM3_ESOFT; @@ -6980,7 +6980,7 @@ static int CmdHF14AGen4Load(const char *cmd) { fflush(stdout); // write block - if (mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE)) != PM3_SUCCESS) { + if (mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE), MAGIC_INIT | MAGIC_OFF) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Can't set magic card block: %d", blockno); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); if (data != NULL) free(data); @@ -7047,7 +7047,7 @@ static int CmdHF14AGen4SetBlk(const char *cmd) { PrintAndLogEx(INFO, "Writing block number:%2d data:%s", b, sprint_hex_inrow(data, sizeof(data))); uint8_t blockno = (uint8_t)b; - int res = mfG4SetBlock(pwd, blockno, data); + int res = mfG4SetBlock(pwd, blockno, data, MAGIC_INIT | MAGIC_OFF); if (res) { PrintAndLogEx(ERR, "Can't write block. error=%d", res); return PM3_ESOFT; @@ -7164,7 +7164,7 @@ static int CmdHF14AGen4View(const char *Cmd) { PrintAndLogEx(NORMAL, "." NOLF); fflush(stdout); - if (mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE)) != PM3_SUCCESS) { + if (mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE), MAGIC_INIT | MAGIC_OFF) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Can't get magic card block: %u", i); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); free(dump); diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 2964289b2..1d57ec533 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1158,13 +1158,15 @@ int mfGen3Freeze(void) { } } -int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data) { +int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data, uint8_t workFlags) { struct p { uint8_t blockno; uint8_t pwd[4]; + uint8_t workFlags; } PACKED payload; payload.blockno = blockno; memcpy(payload.pwd, pwd, sizeof(payload.pwd)); + payload.workFlags = workFlags; clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_G4_RDBL, (uint8_t *)&payload, sizeof(payload)); @@ -1181,15 +1183,17 @@ int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data) { return PM3_SUCCESS; } -int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data) { +int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data, uint8_t workFlags) { struct p { uint8_t blockno; uint8_t pwd[4]; uint8_t data[16]; + uint8_t workFlags; } PACKED payload; payload.blockno = blockno; memcpy(payload.pwd, pwd, sizeof(payload.pwd)); memcpy(payload.data, data, sizeof(payload.data)); + payload.workFlags = workFlags; clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_G4_WRBL, (uint8_t *)&payload, sizeof(payload)); diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index cc0fa1f83..8f50ccbd7 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -95,8 +95,8 @@ int mfGen3UID(uint8_t *uid, uint8_t uidlen, uint8_t *oldUid); int mfGen3Block(uint8_t *block, int blockLen, uint8_t *newBlock); int mfGen3Freeze(void); -int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data); -int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data); +int mfG4GetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data, uint8_t workFlags); +int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data, uint8_t workFlags); int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len); From d126d5d9f6a9d68739232e49657aa8978824e8c8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 9 Nov 2022 23:25:41 +0100 Subject: [PATCH 338/759] remove vanity url since its hard to maintain to booster levels --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0738cd144..8b98ad79b 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ The official PM3-GUI from Gaucho will not work. Not to mention is quite old and ## Official channels Where do you find the community? - - [RFID Hacking community discord server](https://discord.gg/iceman) + - [RFID Hacking community discord server](https://t.ly/d4_C) - [Proxmark3 IRC channel](https://web.libera.chat/?channels=#proxmark3) - [Proxmark3 sub reddit](https://www.reddit.com/r/proxmark3/) - [Proxmark3 forum](http://www.proxmark.org/forum/index.php) From 64b13679d7d0388c45d32eed17247b28f26dc2f2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 11 Nov 2022 03:39:31 +0100 Subject: [PATCH 339/759] some default ones --- client/dictionaries/iclass_default_keys.dic | 33 ++++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/client/dictionaries/iclass_default_keys.dic b/client/dictionaries/iclass_default_keys.dic index ee39c1e4c..d2d6489b2 100644 --- a/client/dictionaries/iclass_default_keys.dic +++ b/client/dictionaries/iclass_default_keys.dic @@ -10,7 +10,32 @@ AEA684A6DAB23278 # AA1 F0E1D2C3B4A59687 # Kd from PicoPass 2k documentation 5CBCF1DA45D5FB4F # PicoPass Default Exchange Key 31ad7ebd2f282168 # From HID multiclassSE reader -6EFD46EFCBB3C875 # From pastebin: https://pastebin.com/uHqpjiuU -E033CA419AEE43F9 # From pastebin: https://pastebin.com/uHqpjiuU -2020666666668888 # iCopy-X iCL tags -6666202066668888 # iCopy-X iCS tags reversed from the SOs +# +# From pastebin: https://pastebin.com/uHqpjiuU +6EFD46EFCBB3C875 +E033CA419AEE43F9 +# +# iCopy-x DRM keys +2020666666668888 # iCL tags +6666202066668888 # iCS tags reversed from the SOs +# +# default picopass KD / Page 0 / Book 1 +FDCB5A52EA8F3090 +237FF9079863DF44 +5ADC25FB27181D32 +83B881F2936B2E49 +43644E61EE866BA5 +897034143D016080 +82D17B44C0122963 +4895CA7DE65E2025 +DADAD4C57BE271B7 +E41E9EDEF5719ABF +293D275EC3AF9C7F +C3C169251B8A70FB +F41DAF58B20C8B91 +28877A609EC0DD2B +66584C91EE80D5E5 +C1B74D7478053AE2 +# +# default iCLASS RFIDeas +6B65797374726B72 From dbb5e6d4c15fb8a696eafefb449c64fb8ca9c31a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 11 Nov 2022 23:49:49 +0100 Subject: [PATCH 340/759] fix coverity CID #402836, #402837, #402838 --- client/src/cmdhfmf.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 222d0f961..f540c0e80 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -864,7 +864,7 @@ static int CmdHF14AMfDump(const char *Cmd) { rights[sectorNo][3] = ((data[7] & 0x80) >> 5) | ((data[8] & 0x8) >> 2) | ((data[8] & 0x80) >> 7); // C1C2C3 for sector trailer break; } else if (tries == (MIFARE_SECTOR_RETRY / 2)) { // after half unsuccessful tries, give key B a go - PrintAndLogEx(WARNING, "\ntrying with key B instead...", sectorNo); + PrintAndLogEx(WARNING, "\ntrying with key B instead..."); current_key = MF_KEY_B; PrintAndLogEx(INFO, "." NOLF); } else if (tries == (MIFARE_SECTOR_RETRY - 1)) { // on last try set defaults @@ -6935,12 +6935,14 @@ static int CmdHF14AGen4Load(const char *cmd) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return PM3_EMALLOC; } + PrintAndLogEx(INFO, "downloading emulator memory"); - if (!GetFromDevice(BIG_BUF_EML, data, block_cnt * MFBLOCK_SIZE, 0, NULL, 0, NULL, 2500, false)) { + if (GetFromDevice(BIG_BUF_EML, data, block_cnt * MFBLOCK_SIZE, 0, NULL, 0, NULL, 2500, false) == false) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(data); return PM3_ETIMEOUT; } + } else { // read from file int res = pm3_load_dump(filename, (void **)&data, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK)); @@ -6950,7 +6952,7 @@ static int CmdHF14AGen4Load(const char *cmd) { // check file size corresponds to card size. if (bytes_read != (block_cnt * MFBLOCK_SIZE)) { - PrintAndLogEx(ERR, "File content error. Read %zu bytes, expected %zu", bytes_read, block_cnt * MFBLOCK_SIZE); + PrintAndLogEx(ERR, "File content error. Read %zu bytes, expected %i", bytes_read, block_cnt * MFBLOCK_SIZE); if (data != NULL) free(data); return PM3_EFILE; } @@ -6983,7 +6985,7 @@ static int CmdHF14AGen4Load(const char *cmd) { if (mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE)) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Can't set magic card block: %d", blockno); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); - if (data != NULL) free(data); + free(data); return PM3_ESOFT; } } From 9353f8ce9a21f58a97ef5ab1bdcb7956ee9180ed Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 11 Nov 2022 23:51:30 +0100 Subject: [PATCH 341/759] fix coverity CID #402839, resource leak --- client/src/cmdtrace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index c7ab9ec73..812a97b2e 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -677,6 +677,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr snprintf(pos1, 9, "[%s]", cb_str); } } + free(cb_str); } } } From 4ab5d9febc45637aec15584a32746ad3a4197de7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 12 Nov 2022 01:52:44 +0100 Subject: [PATCH 342/759] fixing serial port detection with WSL2 + usbipd , thanks to jrozner for verifying --- CHANGELOG.md | 1 + pm3 | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b44c517e..5ebafa820 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 `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001) - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - Added `hf mf gload, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) diff --git a/pm3 b/pm3 index e4469cd29..c0b0869b0 100755 --- a/pm3 +++ b/pm3 @@ -59,18 +59,20 @@ function get_pm3_list_Linux { fi for DEV in $(find /dev/ttyACM* 2>/dev/null); do if command -v udevadm >/dev/null; then + # WSL1 detection if udevadm info -q property -n "$DEV" | grep -q "ID_VENDOR=proxmark.org"; then PM3LIST+=("$DEV") if [ ${#PM3LIST[*]} -ge "$N" ]; then return fi fi - else - if grep -q "proxmark.org" "/sys/class/tty/${DEV#/dev/}/../../../manufacturer" 2>/dev/null; then - PM3LIST+=("$DEV") - if [ ${#PM3LIST[*]} -ge "$N" ]; then - return - fi + fi + # WSL2 with usbipd detection - doesn't report same things as WSL1 + + if grep -q "proxmark.org" "/sys/class/tty/${DEV#/dev/}/../../../manufacturer" 2>/dev/null; then + PM3LIST+=("$DEV") + if [ ${#PM3LIST[*]} -ge "$N" ]; then + return fi fi done From d465c5a9217711d8a8c6c1bf269ea3f59aa500f8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 12 Nov 2022 06:32:08 +0100 Subject: [PATCH 343/759] a test thingy --- client/src/cmdhficlass.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 5757fcadd..fa118ff52 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1607,6 +1607,7 @@ static int CmdHFiClassDump(const char *Cmd) { arg_lit0(NULL, "raw", "raw, the key is interpreted as raw block 3/4"), arg_lit0(NULL, "nr", "replay of NR/MAC"), arg_lit0("z", "dense", "dense dump output style"), + arg_lit0(NULL, "force", "force unsecure card read"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1691,6 +1692,7 @@ static int CmdHFiClassDump(const char *Cmd) { bool rawkey = arg_get_lit(ctx, 7); bool use_replay = arg_get_lit(ctx, 8); bool dense_output = g_session.dense_output || arg_get_lit(ctx, 9); + bool force = arg_get_lit(ctx, 10); CLIParserFree(ctx); @@ -1757,6 +1759,12 @@ static int CmdHFiClassDump(const char *Cmd) { } } + // + if (force) { + pagemap |= PICOPASS_NON_SECURE_PAGEMODE; + PrintAndLogEx(INFO, "Forcing NON SECURE PAGE dumping"); + } + if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { PrintAndLogEx(INFO, "Dumping all available memory, block 3 - %u (0x%02x)", app_limit1, app_limit1); if (auth) { @@ -3773,7 +3781,7 @@ static int CmdHFiClassEncode(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf iclass encode", - "Encode binary wiegand to block 7\n" + "Encode binary wiegand to block 7,8,9\n" "Use either --bin or --wiegand/--fc/--cn", "hf iclass encode --bin 10001111100000001010100011 --ki 0 -> FC 31 CN 337\n" "hf iclass encode --fc 31 --cn 337 --ki 0 -> FC 31 CN 337\n" @@ -3925,8 +3933,12 @@ static int CmdHFiClassEncode(const char *Cmd) { return PM3_ESOFT; } + // iceman: only for formats w length smaller than 37. + // Needs a check. + + // increase length to allow setting bit just above real data + packed.Length++; // Set sentinel bit - packed.Length++;// increase length to allow setting bit just above real data set_bit_by_position(&packed, true, 0); #ifdef HOST_LITTLE_ENDIAN @@ -3958,7 +3970,7 @@ static int CmdHFiClassEncode(const char *Cmd) { PrintAndLogEx(SUCCESS, "Write block %d/0x0%x ( " _GREEN_("ok") " ) --> " _YELLOW_("%s"), 6 + i, 6 + i, sprint_hex_inrow(credential + (i * 8), 8)); break; default: - PrintAndLogEx(SUCCESS, "Write block %d/0x0%x ( " _RED_("fail") " )", 6 + i, 6 + i); + PrintAndLogEx(INFO, "Write block %d/0x0%x ( " _RED_("fail") " )", 6 + i, 6 + i); break; } } From c74e095dc9d1c29788404aa5381800e9f7d13edd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 12 Nov 2022 07:12:41 +0100 Subject: [PATCH 344/759] test.. --- client/src/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index fa118ff52..1396f39f6 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1761,7 +1761,7 @@ static int CmdHFiClassDump(const char *Cmd) { // if (force) { - pagemap |= PICOPASS_NON_SECURE_PAGEMODE; + pagemap == PICOPASS_NON_SECURE_PAGEMODE; PrintAndLogEx(INFO, "Forcing NON SECURE PAGE dumping"); } From bde4e8d754394beb565f76f9a81160862df3e9f2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 12 Nov 2022 07:16:02 +0100 Subject: [PATCH 345/759] test.2 --- client/src/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 1396f39f6..755d71aeb 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1761,7 +1761,7 @@ static int CmdHFiClassDump(const char *Cmd) { // if (force) { - pagemap == PICOPASS_NON_SECURE_PAGEMODE; + pagemap = PICOPASS_NON_SECURE_PAGEMODE; PrintAndLogEx(INFO, "Forcing NON SECURE PAGE dumping"); } From c393b0caca8095286362eff3d7496fb30c8c277d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 12 Nov 2022 09:39:28 +0100 Subject: [PATCH 346/759] adapted hardnested and autopwn to detect MFC Ev1 cards and use the known sector key in the key recovery vectors --- CHANGELOG.md | 2 + client/src/cmdhf14a.c | 2 +- client/src/cmdhfmf.c | 76 +++++++++++++++++++++++-------- client/src/mifare/mifaredefault.h | 5 ++ client/src/mifare/mifarehost.c | 17 +++++-- client/src/mifare/mifarehost.h | 6 ++- 6 files changed, 82 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ebafa820..de2615206 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 mf hardnested` - now can detect and use MFC EV1 signature sector key (@iceman1001) + - Changed `hf mf autopwn` - now can detect and use MFC EV1 signature sector key (@iceman1001) - Fixed `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001) - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 0c70715dd..df13e0862 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -2318,7 +2318,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } uint8_t signature[32] = {0}; - res = detect_mfc_ev1_signature(signature); + res = read_mfc_ev1_signature(signature); if (res == PM3_SUCCESS) { mfc_ev1_print_signature(card.uid, card.uidlen, signature, sizeof(signature)); } diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index f540c0e80..6290415bf 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1841,19 +1841,22 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf hardnested", "Nested attack for hardened MIFARE Classic cards.\n" + "if card is EV1, command can detect and use known key see example below\n" + "\n" "`--i` set type of SIMD instructions. Without this flag programs autodetect it.\n" " or \n" " hf mf hardnested -r --tk [known target key]\n" "Add the known target key to check if it is present in the remaining key space\n" " hf mf hardnested --blk 0 -a -k A0A1A2A3A4A5 --tblk 4 --ta --tk FFFFFFFFFFFF\n" , + "hf mf hardnested --tblk 4 --ta --> works for MFC EV1\n" "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta\n" "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -w\n" "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -f nonces.bin -w -s\n" "hf mf hardnested -r\n" "hf mf hardnested -r --tk a0a1a2a3a4a5\n" "hf mf hardnested -t --tk a0a1a2a3a4a5\n" - "hf mf hardnested --blk 0 -a -k a0a1a2a3a4a5 --tblk 4 --ta --tk FFFFFFFFFFFF" + "hf mf hardnested --blk 0 -a -k a0a1a2a3a4a5 --tblk 4 --ta --tk FFFFFFFFFFFF\n" ); void *argtable[] = { @@ -1976,7 +1979,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { SetSIMDInstr(SIMD_NONE); - bool know_target_key = (trg_keylen); + bool known_target_key = (trg_keylen); if (nonce_file_read) { char *fptr = GenerateFilename("hf-mf-", "-nonces.bin"); @@ -2000,7 +2003,15 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { snprintf(filename, FILE_PATH_SIZE, "hf-mf-%s-nonces.bin", uid); } - if (know_target_key == false && nonce_file_read == false) { + // detect MFC EV1 Signature + if (detect_mfc_ev1_signature() && keylen == 0) { + PrintAndLogEx(INFO, "MIFARE Classic EV1 card detected"); + blockno = 69; + keytype = MF_KEY_B; + memcpy(key, g_mifare_signature_key_b, sizeof(g_mifare_signature_key_b)); + } + + if (known_target_key == false && nonce_file_read == false) { // check if tag doesn't have static nonce if (detect_classic_static_nonce() == NONCE_STATIC) { @@ -2021,7 +2032,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { trg_blockno, (trg_keytype == MF_KEY_B) ? 'B' : 'A', trg_key[0], trg_key[1], trg_key[2], trg_key[3], trg_key[4], trg_key[5], - know_target_key ? "" : " (not set)" + known_target_key ? "" : " (not set)" ); PrintAndLogEx(INFO, "File action: " _YELLOW_("%s") ", Slow: " _YELLOW_("%s") ", Tests: " _YELLOW_("%d"), nonce_file_write ? "write" : nonce_file_read ? "read" : "none", @@ -2029,7 +2040,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { tests); uint64_t foundkey = 0; - int16_t isOK = mfnestedhard(blockno, keytype, key, trg_blockno, trg_keytype, know_target_key ? trg_key : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, filename); + int16_t isOK = mfnestedhard(blockno, keytype, key, trg_blockno, trg_keytype, known_target_key ? trg_key : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, filename); if ((tests == 0) && IfPm3Iso14443a()) { DropField(); @@ -2105,7 +2116,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { return PM3_EINVARG; } - bool know_target_key = (keylen == 6); + bool known_key = (keylen == 6); uint8_t sectorno = arg_get_u32_def(ctx, 2, 0); @@ -2223,10 +2234,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { int bytes; // Settings int prng_type = PM3_EUNDEF; - int has_staticnonce; uint8_t num_found_keys = 0; -// ------------------------------ + // ------------------------------ // Select card to get UID/UIDLEN/ATQA/SAK information clearCommandBuffer(); @@ -2247,6 +2257,14 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { iso14a_card_select_t card; memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); + + // detect MFC EV1 Signature + bool is_ev1 = detect_mfc_ev1_signature(); + if (is_ev1) { + // hidden sectors on MFC EV1 + sector_cnt += 2; + } + // create/initialize key storage structure uint32_t e_sector_size = sector_cnt > sectorno ? sector_cnt : sectorno + 1; res = initSectorTable(&e_sector, e_sector_size); @@ -2255,11 +2273,31 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { return PM3_EMALLOC; } + if (is_ev1) { + PrintAndLogEx(INFO, "MIFARE Classic EV1 card detected"); + // Store the keys + e_sector[16].Key[MF_KEY_A] = bytes_to_num((uint8_t *)g_mifare_signature_key_a, sizeof(g_mifare_signature_key_a)); + e_sector[16].foundKey[MF_KEY_A] = 'D'; + + e_sector[17].Key[MF_KEY_A] = bytes_to_num((uint8_t *)g_mifare_signature_key_a, sizeof(g_mifare_signature_key_a)); + e_sector[17].foundKey[MF_KEY_A] = 'D'; + e_sector[17].Key[MF_KEY_B] = bytes_to_num((uint8_t *)g_mifare_signature_key_b, sizeof(g_mifare_signature_key_b)); + e_sector[17].foundKey[MF_KEY_B] = 'D'; + + // use found key if not supplied + if (known_key == false) { + known_key = true; + sectorno = 17; + keytype = MF_KEY_B; + memcpy(key, g_mifare_signature_key_b, sizeof(g_mifare_signature_key_b)); + } + } + // read uid to generate a filename for the key file char *fptr = GenerateFilename("hf-mf-", "-key.bin"); // check if tag doesn't have static nonce - has_staticnonce = detect_classic_static_nonce(); + int has_staticnonce = detect_classic_static_nonce(); // card prng type (weak=1 / hard=0 / select/card comm error = negative value) if (has_staticnonce == NONCE_NORMAL) { @@ -2276,7 +2314,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { if (verbose) { PrintAndLogEx(INFO, "======================= " _YELLOW_("SETTINGS") " ======================="); PrintAndLogEx(INFO, " card sectors .. " _YELLOW_("%d"), sector_cnt); - PrintAndLogEx(INFO, " key supplied .. " _YELLOW_("%s"), know_target_key ? "True" : "False"); + PrintAndLogEx(INFO, " key supplied .. " _YELLOW_("%s"), known_key ? "True" : "False"); PrintAndLogEx(INFO, " known sector .. " _YELLOW_("%d"), sectorno); PrintAndLogEx(INFO, " keytype ....... " _YELLOW_("%c"), (keytype == MF_KEY_B) ? 'B' : 'A'); PrintAndLogEx(INFO, " known key ..... " _YELLOW_("%s"), sprint_hex(key, sizeof(key))); @@ -2298,7 +2336,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { uint64_t t1 = msclock(); // check the user supplied key - if (know_target_key == false) { + if (known_key == false) { PrintAndLogEx(WARNING, "no known key was supplied, key recovery might fail"); } else { if (verbose) { @@ -2318,7 +2356,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { ++num_found_keys; } else { - know_target_key = false; + known_key = false; PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector"_RED_("%3d") " key type "_RED_("%c") " key " _RED_("%s"), sectorno, (keytype == MF_KEY_B) ? 'B' : 'A', @@ -2336,9 +2374,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { e_sector[i].foundKey[j] = 'U'; // If the user supplied secctor / keytype was wrong --> just be nice and correct it ;) - if (know_target_key == false) { + if (known_key == false) { num_to_bytes(e_sector[i].Key[j], 6, key); - know_target_key = true; + known_key = true; sectorno = i; keytype = j; PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)", @@ -2364,7 +2402,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } } - bool load_success = true; + bool load_success = true; // Load the dictionary if (has_filename) { res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 6, &key_cnt); @@ -2461,9 +2499,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { num_to_bytes(e_sector[i].Key[j], 6, tmp_key); // Store valid credentials for the nested / hardnested attack if none exist - if (know_target_key == false) { + if (known_key == false) { num_to_bytes(e_sector[i].Key[j], 6, key); - know_target_key = true; + known_key = true; sectorno = i; keytype = j; PrintAndLogEx(SUCCESS, "target sector %3u key type %c -- found valid key [ " _GREEN_("%s") " ] (used for nested / hardnested attack)", @@ -2483,7 +2521,8 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } // Check if at least one sector key was found - if (know_target_key == false) { + if (known_key == false) { + // Check if the darkside attack can be used if (prng_type && has_staticnonce != NONCE_STATIC) { if (verbose) { @@ -2520,6 +2559,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { key64 ); } else { + noValidKeyFound: PrintAndLogEx(FAILED, "No usable key was found!"); free(keyBlock); diff --git a/client/src/mifare/mifaredefault.h b/client/src/mifare/mifaredefault.h index 93c6b4a7f..e28bb7f09 100644 --- a/client/src/mifare/mifaredefault.h +++ b/client/src/mifare/mifaredefault.h @@ -29,6 +29,7 @@ static const uint64_t g_mifare_default_keys[] = { 0x000000000000, // Blank key 0xa0a1a2a3a4a5, // NFCForum MAD key 0xd3f7d3f7d3f7, // NDEF public key + 0x4b791bea7bcc, // MFC EV1 Signature B 0xb0b1b2b3b4b5, 0xaabbccddeeff, 0x1a2b3c4d5e6f, @@ -75,6 +76,10 @@ static const uint8_t g_mifare_default_key[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0x static const uint8_t g_mifare_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}; static const uint8_t g_mifare_mad_key_b[] = {0x89, 0xEC, 0xA9, 0x7F, 0x8C, 0x2A}; + // 16 key B D01AFEEB890A +static const uint8_t g_mifare_signature_key_a[] = {0x5C, 0x8F, 0xF9, 0x99, 0x0D, 0xA2}; +static const uint8_t g_mifare_signature_key_b[] = {0x4b, 0x79, 0x1b, 0xea, 0x7b, 0xcc}; + static const uint8_t g_mifare_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; static const uint8_t g_mifarep_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7}; static const uint8_t g_mifarep_ndef_key[] = {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}; diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 2964289b2..665f88edf 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -35,6 +35,8 @@ #include "util_posix.h" // msclock #include "cmdparser.h" // detection of flash capabilities #include "cmdflashmemspiffs.h" // upload to flash mem +#include "mifaredefault.h" // default keys + int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { uint32_t uid = 0; @@ -880,7 +882,7 @@ int mfReadSector(uint8_t sectorNo, uint8_t keyType, const uint8_t *key, uint8_t return PM3_SUCCESS; } -int mfReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t *data) { +int mfReadBlock(uint8_t blockNo, uint8_t keyType, const uint8_t *key, uint8_t *data) { mf_readblock_t payload = { .blockno = blockNo, .keytype = keyType @@ -1417,15 +1419,20 @@ int detect_mf_magic(bool is_mfc) { return isGeneration; } -int detect_mfc_ev1_signature(uint8_t *signature) { +bool detect_mfc_ev1_signature(void) { + uint64_t key = 0; + int res = mfCheckKeys(69, MF_KEY_B, false, 1, (uint8_t*)g_mifare_signature_key_b, &key); + return (res == PM3_SUCCESS); +} + +int read_mfc_ev1_signature(uint8_t *signature) { if (signature == NULL) { return PM3_EINVARG; } uint8_t sign[32] = {0}; - uint8_t key[] = {0x4b, 0x79, 0x1b, 0xea, 0x7b, 0xcc}; - int res = mfReadBlock(69, 1, key, sign); + int res = mfReadBlock(69, MF_KEY_B, g_mifare_signature_key_b, sign); if (res == PM3_SUCCESS) { - res = mfReadBlock(70, 1, key, sign + 16); + res = mfReadBlock(70, MF_KEY_B, g_mifare_signature_key_b, sign + 16); if (res == PM3_SUCCESS) { memcpy(signature, sign, sizeof(sign)); } diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index cc0fa1f83..9fb359f13 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -80,7 +80,7 @@ int mfCheckKeys_file(uint8_t *destfn, uint64_t *key); int mfKeyBrute(uint8_t blockNo, uint8_t keyType, const uint8_t *key, uint64_t *resultkey); int mfReadSector(uint8_t sectorNo, uint8_t keyType, const uint8_t *key, uint8_t *data); -int mfReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t *data); +int mfReadBlock(uint8_t blockNo, uint8_t keyType, const uint8_t *key, uint8_t *data); int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount); int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount); @@ -104,7 +104,9 @@ int detect_classic_prng(void); int detect_classic_nackbug(bool verbose); int detect_mf_magic(bool is_mfc); int detect_classic_static_nonce(void); -int detect_mfc_ev1_signature(uint8_t *signature); +bool detect_mfc_ev1_signature(void); +int read_mfc_ev1_signature(uint8_t *signature); + void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted); #endif From da1ce305337e265a6e97d62a352dd2f94ef5b7ba Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Sun, 13 Nov 2022 01:37:52 +0100 Subject: [PATCH 347/759] hf mf gview, gload : 2x speed on Gen4 GTU cards, a select was made before each read or write command. This commit adds a flag parameter to the read and write commands, and gload and gview commands use this flag to tell when to select and end. The trace buffer also contains the complete operation instead of the last blokc read/write. Speed gain: `time ./proxmark3 -p /dev/ttyACM0 -c 'hf mf gview --4k'` before: about 20s, now: about 7s `time ./proxmark3 -p /dev/ttyACM0 -c 'hf mf gload --4k -f ../../../dumps/4k.bin'` before: about 23s, now: about 10s --- client/src/cmdhfmf.c | 45 +++++++++++++++----------------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index eabef0423..5609d0363 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -2402,7 +2402,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) { } } - bool load_success = true; + bool load_success = true; // Load the dictionary if (has_filename) { res = loadFileDICTIONARY_safe(filename, (void **) &keyBlock, 6, &key_cnt); @@ -7022,8 +7022,13 @@ static int CmdHF14AGen4Load(const char *cmd) { fflush(stdout); // write block - if (mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE), MAGIC_INIT | MAGIC_OFF) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Can't set magic card block: %d", blockno); + uint8_t flags = 0 ; + if (blockno == start) flags |= MAGIC_INIT ; + if (blockno == end) flags |= MAGIC_OFF ; + + int res=mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE), flags); + if ( res != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Can't set magic card block: %d. error=%d", blockno, res); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); free(data); return PM3_ESOFT; @@ -7163,31 +7168,6 @@ static int CmdHF14AGen4View(const char *Cmd) { } PrintAndLogEx(SUCCESS, "View magic gen4 GTU MIFARE Classic " _GREEN_("%s"), s); - // Select card to get UID/UIDLEN information - clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); - PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { - PrintAndLogEx(WARNING, "iso14443a card select timeout"); - return PM3_ETIMEOUT; - } - - /* - 0: couldn't read - 1: OK, with ATS - 2: OK, no ATS - 3: proprietary Anticollision - */ - uint64_t select_status = resp.oldarg[0]; - - if (select_status == 0) { - PrintAndLogEx(WARNING, "iso14443a card select failed"); - return PM3_SUCCESS; - } - - iso14a_card_select_t card; - memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); - // reserve memory uint16_t bytes = block_cnt * MFBLOCK_SIZE; uint8_t *dump = calloc(bytes, sizeof(uint8_t)); @@ -7206,8 +7186,13 @@ static int CmdHF14AGen4View(const char *Cmd) { PrintAndLogEx(NORMAL, "." NOLF); fflush(stdout); - if (mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE), MAGIC_INIT | MAGIC_OFF) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Can't get magic card block: %u", i); + uint8_t flags = 0 ; + if (i == 0) flags |= MAGIC_INIT ; + if (i+1 == block_cnt) flags |= MAGIC_OFF ; + + int res = mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE), flags); + if ( res != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Can't get magic card block: %u. error=%d", i, res); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); free(dump); return PM3_ESOFT; From ee3e4968d34ab6c9e2651f3201f42bdbb3964bb1 Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Sun, 13 Nov 2022 02:08:23 +0100 Subject: [PATCH 348/759] remove MifareG4ReadWrite() --- armsrc/mifarecmd.c | 105 +++++++++++++++++++++++++++++++++------------ armsrc/mifarecmd.h | 1 - 2 files changed, 77 insertions(+), 29 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index e1e8dc2a9..cf5e34d8d 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2684,10 +2684,7 @@ OUT: BigBuf_free(); } -// read or write block to GEN4 GTU tag -void MifareG4ReadWriteBlk(uint8_t rw, uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags) { - bool read = rw & 0x1 & 0xFF ; - bool write = rw & 0x2 & 0xFF ; +void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags) { bool setup = workFlags & MAGIC_INIT & 0xFF ; bool done = workFlags & MAGIC_OFF & 0xFF ; @@ -2701,13 +2698,78 @@ void MifareG4ReadWriteBlk(uint8_t rw, uint8_t blockno, uint8_t *pwd, uint8_t *da goto OUT; } - // check args - if (write && (data == NULL)) { - retval = PM3_EINVARG; + uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); + if (par == NULL) { + retval = PM3_EMALLOC; goto OUT; } - if (!(read || write)) { + if (setup) { + uint8_t *uid = BigBuf_malloc(10); + if (uid == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + + if (iso14443a_select_card(uid, NULL, NULL, true, 0, true) == false) { + retval = PM3_ESOFT; + goto OUT; + } + } + + LED_B_ON(); + + static uint32_t save_iso14a_timeout; + if (setup) { + save_iso14a_timeout = iso14a_get_timeout(); + iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout + } + + uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, 0xCE, blockno, + 0x00, 0x00 + }; + + memcpy(cmd + 1, pwd, 4); + + AddCrc14A(cmd, sizeof(cmd) - 2); + + ReaderTransmit(cmd, sizeof(cmd), NULL); + res = ReaderReceive(buf, par); + + if (res != 18) { + retval = PM3_ESOFT; + } + + if (done || retval != 0) iso14a_set_timeout(save_iso14a_timeout); + LED_B_OFF(); + +OUT: + reply_ng(CMD_HF_MIFARE_G4_RDBL, retval, buf, res); + // turns off + if (done || retval != 0) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + if (done || retval != 0) set_tracing(false); + BigBuf_free(); +} + +void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags) { + bool setup = workFlags & MAGIC_INIT & 0xFF ; + bool done = workFlags & MAGIC_OFF & 0xFF ; + + int res = 0; + int retval = PM3_SUCCESS; + + uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); + if (buf == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + + // check args + if (data == NULL) { retval = PM3_EINVARG; goto OUT; } @@ -2742,26 +2804,21 @@ void MifareG4ReadWriteBlk(uint8_t rw, uint8_t blockno, uint8_t *pwd, uint8_t *da iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout } - uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, (write ? 0xCD : 0xCE), blockno, + uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, 0xCD, blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(cmd + 1, pwd, 4); - if (write) memcpy(cmd + 7, data, 16); + memcpy(cmd + 7, data, 16); - size_t crc_pos = read ? 7 : (sizeof(cmd) - 2) ; - AddCrc14A(cmd, crc_pos); + AddCrc14A(cmd, sizeof(cmd) - 2); - ReaderTransmit(cmd, crc_pos + 2, NULL); + ReaderTransmit(cmd, sizeof(cmd), NULL); res = ReaderReceive(buf, par); - if (write) { - if ((res != 4) || (memcmp(buf, "\x90\x00\xfd\x07", 4) != 0)) { - retval = PM3_ESOFT; - } - } else if (res != 18) { + if ((res != 4) || (memcmp(buf, "\x90\x00\xfd\x07", 4) != 0)) { retval = PM3_ESOFT; } @@ -2769,20 +2826,12 @@ void MifareG4ReadWriteBlk(uint8_t rw, uint8_t blockno, uint8_t *pwd, uint8_t *da LED_B_OFF(); OUT: - reply_ng(write ? CMD_HF_MIFARE_G4_WRBL : CMD_HF_MIFARE_G4_RDBL, retval, buf, res); + reply_ng(CMD_HF_MIFARE_G4_WRBL, retval, buf, res); // turns off if (done || retval != 0) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); if (done || retval != 0) set_tracing(false); - BigBuf_free(); -} - -void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags) { - MifareG4ReadWriteBlk(0x1, blockno, pwd, NULL, workFlags) ; -} - -void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags) { - MifareG4ReadWriteBlk(0x2, blockno, pwd, data, workFlags) ; + BigBuf_free(); } void MifareSetMod(uint8_t *datain) { diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index a68fed8db..30179aa3b 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -57,7 +57,6 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block); // Gen 3 magic card overw void MifareGen3Freez(void); // Gen 3 magic card lock further UID changes // MFC GEN4 GTU -void MifareG4ReadWriteBlk(uint8_t rw, uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags); void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags); void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags); From 63a1b7fdeff5bd4a168ddba9b9cd39be533c6dbf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 14 Nov 2022 07:44:23 +0100 Subject: [PATCH 349/759] added requirements.txt file for minimum installation to run pm3_tests.sh, there are more python scripts with other requirements. --- CHANGELOG.md | 1 + tools/requirements.txt | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 tools/requirements.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index de2615206..30314d514 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] + - Added requirements.txt file to tools folder. Minimum to run pm3_tests.sh (@iceman1001) - Changed `hf mf hardnested` - now can detect and use MFC EV1 signature sector key (@iceman1001) - Changed `hf mf autopwn` - now can detect and use MFC EV1 signature sector key (@iceman1001) - Fixed `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001) diff --git a/tools/requirements.txt b/tools/requirements.txt new file mode 100644 index 000000000..8bff1fb56 --- /dev/null +++ b/tools/requirements.txt @@ -0,0 +1,2 @@ +ansicolors==1.1.8 +sslcrypto==5.3 From fa95119171cc0e383390fcae4b84140fadb01a58 Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Mon, 14 Nov 2022 09:44:02 +0100 Subject: [PATCH 350/759] style: extract flags --- armsrc/mifarecmd.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index cf5e34d8d..4fd74c9ef 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2685,9 +2685,8 @@ OUT: } void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags) { - - bool setup = workFlags & MAGIC_INIT & 0xFF ; - bool done = workFlags & MAGIC_OFF & 0xFF ; + bool setup = ((workFlags & MAGIC_INIT) == MAGIC_INIT) ; + bool done = ((workFlags & MAGIC_OFF) == MAGIC_OFF) ; int res = 0; int retval = PM3_SUCCESS; @@ -2756,8 +2755,8 @@ OUT: } void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags) { - bool setup = workFlags & MAGIC_INIT & 0xFF ; - bool done = workFlags & MAGIC_OFF & 0xFF ; + bool setup = ((workFlags & MAGIC_INIT) == MAGIC_INIT) ; + bool done = ((workFlags & MAGIC_OFF) == MAGIC_OFF) ; int res = 0; int retval = PM3_SUCCESS; From 6c163fa26218030a60b3ceae85911f4d46f2cc10 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 15 Nov 2022 07:07:26 +0100 Subject: [PATCH 351/759] added a check for static encrypted nonces when collecting encrypted nonces for hardnested to run. Will abort the collection if detected. --- CHANGELOG.md | 1 + armsrc/mifarecmd.c | 27 +++++++++++++++++++++++---- client/src/cmdhfmf.c | 7 +++++++ client/src/mifare/mifarehost.c | 2 +- include/pm3_cmd.h | 4 ++++ 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30314d514..8f75478e7 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] + - Changed `hf mf hardnested` - a detection for static encrypted nonces (@iceman1001) - Added requirements.txt file to tools folder. Minimum to run pm3_tests.sh (@iceman1001) - Changed `hf mf hardnested` - now can detect and use MFC EV1 signature sector key (@iceman1001) - Changed `hf mf autopwn` - now can detect and use MFC EV1 signature sector key (@iceman1001) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 4fd74c9ef..e9cc713bd 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -775,7 +775,7 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t flags) { if (!have_uid) { // need a full select cycle to get the uid first iso14a_card_select_t card_info; - if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { + if (iso14443a_select_card(uid, &card_info, &cuid, true, 0, true) == 0) { if (g_dbglevel >= DBG_ERROR) Dbprintf("AcquireNonces: Can't select card (ALL)"); continue; } @@ -794,7 +794,7 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t flags) { } have_uid = true; } else { // no need for anticollision. We can directly select the card - if (!iso14443a_fast_select_card(uid, cascade_levels)) { + if (iso14443a_fast_select_card(uid, cascade_levels) == 0) { if (g_dbglevel >= DBG_ERROR) Dbprintf("AcquireNonces: Can't select card (UID)"); continue; } @@ -878,6 +878,9 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, LED_C_ON(); + uint8_t prev_enc_nt[] = {0,0,0,0}; + uint8_t prev_counter = 0; + for (uint16_t i = 0; i <= PM3_CMD_DATA_SIZE - 9;) { // Test if the action was cancelled @@ -944,6 +947,22 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, memcpy(buf + i + 8, &nt_par_enc, 1); i += 9; } + + + if (prev_enc_nt[0] == receivedAnswer[0] && + prev_enc_nt[1] == receivedAnswer[1] && + prev_enc_nt[2] == receivedAnswer[2] && + prev_enc_nt[3] == receivedAnswer[3] + ) { + prev_counter++; + } + memcpy(prev_enc_nt, receivedAnswer, 4); + if (prev_counter == 5) { + if (g_dbglevel >= DBG_EXTENDED) DbpString("Static encrypted nonce detected, exiting..."); + isOK = PM3_ESTATIC_NONCE; + break; + } + } LED_C_OFF(); @@ -952,7 +971,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, reply_old(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf)); LED_B_OFF(); - if (g_dbglevel >= 3) DbpString("AcquireEncryptedNonces finished"); + if (g_dbglevel >= DBG_ERROR) DbpString("AcquireEncryptedNonces finished"); if (field_off) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -1030,7 +1049,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 continue; } - if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (iso14443a_select_card(uid, NULL, &cuid, true, 0, true) == 0) { if (g_dbglevel >= DBG_INFO) Dbprintf("Nested: Can't select card"); rtr--; continue; diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 5609d0363..1847bc1a6 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -2054,6 +2054,9 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { case PM3_EOPABORTED: PrintAndLogEx(WARNING, "Button pressed. Aborted.\n"); break; + case PM3_ESTATIC_NONCE: + PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted.\n"); + break; default : break; } @@ -2744,6 +2747,10 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack PrintAndLogEx(NORMAL, "\nButton pressed, user aborted"); break; } + case PM3_ESTATIC_NONCE: { + PrintAndLogEx(ERR, "\nError: Static encrypted nonce detected. Aborted.\n"); + break; + } default: { break; } diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 93727e45f..f12f78eab 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -437,7 +437,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_NESTED, (uint8_t *)&payload, sizeof(payload)); - if (!WaitForResponseTimeout(CMD_HF_MIFARE_NESTED, &resp, 2000)) { + if (WaitForResponseTimeout(CMD_HF_MIFARE_NESTED, &resp, 2000) == false) { SendCommandNG(CMD_BREAK_LOOP, NULL, 0); return PM3_ETIMEOUT; } diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index eebf0bfd3..95750b9b7 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -773,11 +773,15 @@ typedef struct { // Got bad CRC client/pm3: error in transfer of data, crc mismatch. #define PM3_ECRC -24 +// STATIC Nonce detect pm3: when collecting nonces for hardnested +#define PM3_ESTATIC_NONCE -25 + // No data pm3: no data available, no host frame available (not really an error) #define PM3_ENODATA -98 // Quit program client: reserved, order to quit the program #define PM3_EFATAL -99 + // LF #define LF_FREQ2DIV(f) ((int)(((12000.0 + (f)/2.0)/(f))-1)) #define LF_DIVISOR_125 LF_FREQ2DIV(125) From dd8110871dce0e63bc613b7ff61de4140033f608 Mon Sep 17 00:00:00 2001 From: flamebarke <39644720+flamebarke@users.noreply.github.com> Date: Wed, 16 Nov 2022 13:23:50 +0800 Subject: [PATCH 352/759] Create hf_mfu_next.lua Add to CHANGELOG.md Rename to hf_mfu_ntag.lua Signed-off-by: flamebarke <39644720+flamebarke@users.noreply.github.com> --- client/luascripts/hf_mfu_next.lua | 171 ++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 client/luascripts/hf_mfu_next.lua diff --git a/client/luascripts/hf_mfu_next.lua b/client/luascripts/hf_mfu_next.lua new file mode 100644 index 000000000..0709fc9f8 --- /dev/null +++ b/client/luascripts/hf_mfu_next.lua @@ -0,0 +1,171 @@ +local getopt = require('getopt') +local ansicolors = require('ansicolors') + +copyright = '' +author = 'Shain Lakin' +version = 'v1.0.0' +desc =[[ + +This script modifies the DT NeXT implant (NTAG216) configuration pages. + +- NeXT Defaults - + +Default hf mfu info: +---------------------------------------------------------------------- +[=] --- Tag Configuration +[=] cfg0 [227/0xE3]: 04 00 00 E3 +[=] - strong modulation mode disabled +[=] - page 227 and above need authentication +[=] cfg1 [228/0xE4]: 00 05 00 00 +[=] - Unlimited password attempts +[=] - NFC counter disabled +[=] - NFC counter not protected +[=] - user configuration writeable +[=] - write access is protected with password +[=] - 05, Virtual Card Type Identifier is default +[=] PWD [229/0xE5]: 00 00 00 00 - (cannot be read) +[=] PACK [230/0xE6]: 00 00 - (cannot be read) +[=] RFU [230/0xE6]: 00 00 - (cannot be read) +---------------------------------------------------------------------- + +Default blocks 0xE0 to 0xE6: +------------------------------------- +[=] 224/0xE0 | 00 00 00 00 | 0 | .... +[=] 225/0xE1 | 4E 45 78 54 | 0 | NExT +[=] 226/0xE2 | 00 00 7F BD | 0 | .... +[=] 227/0xE3 | 04 00 00 E3 | 0 | .... +[=] 228/0xE4 | 00 05 00 00 | 0 | .... +[=] 229/0xE5 | 44 4E 47 52 | 0 | DNGR +[=] 230/0xE6 | 00 00 00 00 | 0 | .... +------------------------------------- +]] + +example =[[ + +Set a new password of SUDO using the default password of DNGR: + + script run hf_mfu_next -x pass -p DNGR -n SUDO + +Enable password protection from hex block 04 onwards (User memory): + + script run hf_mfu_next -x protect -p DNGR -a 04 + +Enable password protection from hex block E3 onwards (Configuration Pages): + + script run hf_mfu_next -x protect -p DNGR -a E3 + +Disable password protection: + + script run hf_mfu_next -x protect -p DNGR -a FF + +Enable the counter and enable read + write password protection on password protected pages +(protected block start page specified using -x protect mode): + + script run hf_mfu_next -x conf -p DNGR -c enable -m rw + +Disable the counter and enable write only password protection on password protected pages +(protected block start specified using -x protect mode): + + script run hf_mfu_next -x conf -p DNGR -c disable -m w + +]] +usage = [[ + + script run hf_mfu_next -x pass -p -n + script run hf_mfu_next -x protect -p -a + script run hf_mfu_next -x conf -p -c -m + +]] +arguments = [[ + -h this help + -x mode (pass, protect, conf) + -p password (ascii) + -n new password (ascii) + -a auth0 block (hex) + -c counter (enable/disable) + -m protection mode (r/rw) +]] +--- +--- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print(ansicolors.cyan..'Usage'..ansicolors.reset) + print(usage) + print(ansicolors.cyan..'Arguments'..ansicolors.reset) + print(arguments) + print(ansicolors.cyan..'Example usage'..ansicolors.reset) + print(example) +end +--- +--- Print user message +local function msg(msg) + print( string.rep('--',20) ) + print('') + print(msg) + print('') + print( string.rep('--',20) ) +end +--- +--- String to hex function +local function strhex(str) + return (str:gsub(".", function(char) return string.format("%2x", char:byte()) end)) + end +--- +-- Main +local function main(args) + + for o, a in getopt.getopt(args, 'b:m:c:a:p:x:n:h') do + if o == 'm' then prot_mode = a end + if o == 'c' then counter = a end + if o == 'a' then auth0_block = a end + if o == 'p' then passwd = strhex(a) end + if o == 'x' then mode = a end + if o == 'n' then new_pass = strhex(a) end + if o == 'h' then return help() end + end + + if mode == 'pass' then + command = 'hf mfu wrbl -b 229 -d '..new_pass..' -k '..passwd + msg('Writing '..new_pass..' to PASSWD block (229/0xE5) : \n\n'..command) + core.console(command) + command = 'hf mfu rdbl -b 0 -k '..new_pass..'' + msg('Verifying password is correctly set : \n\n'..command) + core.console(command) + elseif mode == 'conf' then + if counter == 'enable' then + if prot_mode == 'r' then + command = 'hf mfu wrbl -b 228 -d 10050000 -k '..passwd + msg('Enabling counter and setting write access to protected pages as password protected : \n\n'..command) + core.console(command) + elseif prot_mode == 'rw' then + command = 'hf mfu wrbl -b 228 -d 90050000 -k '..passwd + msg('Enabling counter and setting read/write access to protected pages as password protected : \n\n'..command) + core.console(command) + end + elseif counter == 'disable' then + if prot_mode == 'w' then + command = 'hf mfu wrbl -b 228 -d 00050000 -k '..passwd + msg('Disabling counter and setting write password protection on protected pages : \n\n'..command) + core.console(command) + elseif prot_mode == 'rw' then + command = 'hf mfu wrbl -b 228 -d 80050000 -k '..passwd + msg('Disabling counter and setting read/write password protection on protected pages : \n\n'..command) + core.console(command) + end + end + elseif mode == 'protect' then + command = 'hf mfu wrbl -k '..passwd..' -b 227 -d 040000'..auth0_block + msg('Enabling password protection from block '..auth0_block..' onwards : \n\n'..command) + core.console(command) + else + return print(usage) + end + + if command == '' then return print(usage) end + + +end +main(args) From 6381a1924353e85559f1218e373dfaefe6df92c9 Mon Sep 17 00:00:00 2001 From: Shain Lakin Date: Wed, 16 Nov 2022 14:10:45 +0800 Subject: [PATCH 353/759] Rename to hf_mfu_next.lua Add entry to changelog.md --- client/luascripts/hf_mfu_next.lua | 171 ------------------------------ 1 file changed, 171 deletions(-) delete mode 100644 client/luascripts/hf_mfu_next.lua diff --git a/client/luascripts/hf_mfu_next.lua b/client/luascripts/hf_mfu_next.lua deleted file mode 100644 index 0709fc9f8..000000000 --- a/client/luascripts/hf_mfu_next.lua +++ /dev/null @@ -1,171 +0,0 @@ -local getopt = require('getopt') -local ansicolors = require('ansicolors') - -copyright = '' -author = 'Shain Lakin' -version = 'v1.0.0' -desc =[[ - -This script modifies the DT NeXT implant (NTAG216) configuration pages. - -- NeXT Defaults - - -Default hf mfu info: ----------------------------------------------------------------------- -[=] --- Tag Configuration -[=] cfg0 [227/0xE3]: 04 00 00 E3 -[=] - strong modulation mode disabled -[=] - page 227 and above need authentication -[=] cfg1 [228/0xE4]: 00 05 00 00 -[=] - Unlimited password attempts -[=] - NFC counter disabled -[=] - NFC counter not protected -[=] - user configuration writeable -[=] - write access is protected with password -[=] - 05, Virtual Card Type Identifier is default -[=] PWD [229/0xE5]: 00 00 00 00 - (cannot be read) -[=] PACK [230/0xE6]: 00 00 - (cannot be read) -[=] RFU [230/0xE6]: 00 00 - (cannot be read) ----------------------------------------------------------------------- - -Default blocks 0xE0 to 0xE6: -------------------------------------- -[=] 224/0xE0 | 00 00 00 00 | 0 | .... -[=] 225/0xE1 | 4E 45 78 54 | 0 | NExT -[=] 226/0xE2 | 00 00 7F BD | 0 | .... -[=] 227/0xE3 | 04 00 00 E3 | 0 | .... -[=] 228/0xE4 | 00 05 00 00 | 0 | .... -[=] 229/0xE5 | 44 4E 47 52 | 0 | DNGR -[=] 230/0xE6 | 00 00 00 00 | 0 | .... -------------------------------------- -]] - -example =[[ - -Set a new password of SUDO using the default password of DNGR: - - script run hf_mfu_next -x pass -p DNGR -n SUDO - -Enable password protection from hex block 04 onwards (User memory): - - script run hf_mfu_next -x protect -p DNGR -a 04 - -Enable password protection from hex block E3 onwards (Configuration Pages): - - script run hf_mfu_next -x protect -p DNGR -a E3 - -Disable password protection: - - script run hf_mfu_next -x protect -p DNGR -a FF - -Enable the counter and enable read + write password protection on password protected pages -(protected block start page specified using -x protect mode): - - script run hf_mfu_next -x conf -p DNGR -c enable -m rw - -Disable the counter and enable write only password protection on password protected pages -(protected block start specified using -x protect mode): - - script run hf_mfu_next -x conf -p DNGR -c disable -m w - -]] -usage = [[ - - script run hf_mfu_next -x pass -p -n - script run hf_mfu_next -x protect -p -a - script run hf_mfu_next -x conf -p -c -m - -]] -arguments = [[ - -h this help - -x mode (pass, protect, conf) - -p password (ascii) - -n new password (ascii) - -a auth0 block (hex) - -c counter (enable/disable) - -m protection mode (r/rw) -]] ---- ---- Usage help -local function help() - print(copyright) - print(author) - print(version) - print(desc) - print(ansicolors.cyan..'Usage'..ansicolors.reset) - print(usage) - print(ansicolors.cyan..'Arguments'..ansicolors.reset) - print(arguments) - print(ansicolors.cyan..'Example usage'..ansicolors.reset) - print(example) -end ---- ---- Print user message -local function msg(msg) - print( string.rep('--',20) ) - print('') - print(msg) - print('') - print( string.rep('--',20) ) -end ---- ---- String to hex function -local function strhex(str) - return (str:gsub(".", function(char) return string.format("%2x", char:byte()) end)) - end ---- --- Main -local function main(args) - - for o, a in getopt.getopt(args, 'b:m:c:a:p:x:n:h') do - if o == 'm' then prot_mode = a end - if o == 'c' then counter = a end - if o == 'a' then auth0_block = a end - if o == 'p' then passwd = strhex(a) end - if o == 'x' then mode = a end - if o == 'n' then new_pass = strhex(a) end - if o == 'h' then return help() end - end - - if mode == 'pass' then - command = 'hf mfu wrbl -b 229 -d '..new_pass..' -k '..passwd - msg('Writing '..new_pass..' to PASSWD block (229/0xE5) : \n\n'..command) - core.console(command) - command = 'hf mfu rdbl -b 0 -k '..new_pass..'' - msg('Verifying password is correctly set : \n\n'..command) - core.console(command) - elseif mode == 'conf' then - if counter == 'enable' then - if prot_mode == 'r' then - command = 'hf mfu wrbl -b 228 -d 10050000 -k '..passwd - msg('Enabling counter and setting write access to protected pages as password protected : \n\n'..command) - core.console(command) - elseif prot_mode == 'rw' then - command = 'hf mfu wrbl -b 228 -d 90050000 -k '..passwd - msg('Enabling counter and setting read/write access to protected pages as password protected : \n\n'..command) - core.console(command) - end - elseif counter == 'disable' then - if prot_mode == 'w' then - command = 'hf mfu wrbl -b 228 -d 00050000 -k '..passwd - msg('Disabling counter and setting write password protection on protected pages : \n\n'..command) - core.console(command) - elseif prot_mode == 'rw' then - command = 'hf mfu wrbl -b 228 -d 80050000 -k '..passwd - msg('Disabling counter and setting read/write password protection on protected pages : \n\n'..command) - core.console(command) - end - end - elseif mode == 'protect' then - command = 'hf mfu wrbl -k '..passwd..' -b 227 -d 040000'..auth0_block - msg('Enabling password protection from block '..auth0_block..' onwards : \n\n'..command) - core.console(command) - else - return print(usage) - end - - if command == '' then return print(usage) end - - -end -main(args) From 789e338c4fd939436900208bbcd0242482e9eaf5 Mon Sep 17 00:00:00 2001 From: Shain Lakin Date: Wed, 16 Nov 2022 14:14:50 +0800 Subject: [PATCH 354/759] Renamed to hf_mfu_ntag Modified CHANGELOG.md --- CHANGELOG.md | 1 + client/luascripts/hf_mfu_ntag.lua | 171 ++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 client/luascripts/hf_mfu_ntag.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f75478e7..afe7f7fe4 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] + - Added luascript `hf_mfu_ntag` - Script for configuring NTAG216 configuration pages (@flamebarke) - Changed `hf mf hardnested` - a detection for static encrypted nonces (@iceman1001) - Added requirements.txt file to tools folder. Minimum to run pm3_tests.sh (@iceman1001) - Changed `hf mf hardnested` - now can detect and use MFC EV1 signature sector key (@iceman1001) diff --git a/client/luascripts/hf_mfu_ntag.lua b/client/luascripts/hf_mfu_ntag.lua new file mode 100644 index 000000000..0709fc9f8 --- /dev/null +++ b/client/luascripts/hf_mfu_ntag.lua @@ -0,0 +1,171 @@ +local getopt = require('getopt') +local ansicolors = require('ansicolors') + +copyright = '' +author = 'Shain Lakin' +version = 'v1.0.0' +desc =[[ + +This script modifies the DT NeXT implant (NTAG216) configuration pages. + +- NeXT Defaults - + +Default hf mfu info: +---------------------------------------------------------------------- +[=] --- Tag Configuration +[=] cfg0 [227/0xE3]: 04 00 00 E3 +[=] - strong modulation mode disabled +[=] - page 227 and above need authentication +[=] cfg1 [228/0xE4]: 00 05 00 00 +[=] - Unlimited password attempts +[=] - NFC counter disabled +[=] - NFC counter not protected +[=] - user configuration writeable +[=] - write access is protected with password +[=] - 05, Virtual Card Type Identifier is default +[=] PWD [229/0xE5]: 00 00 00 00 - (cannot be read) +[=] PACK [230/0xE6]: 00 00 - (cannot be read) +[=] RFU [230/0xE6]: 00 00 - (cannot be read) +---------------------------------------------------------------------- + +Default blocks 0xE0 to 0xE6: +------------------------------------- +[=] 224/0xE0 | 00 00 00 00 | 0 | .... +[=] 225/0xE1 | 4E 45 78 54 | 0 | NExT +[=] 226/0xE2 | 00 00 7F BD | 0 | .... +[=] 227/0xE3 | 04 00 00 E3 | 0 | .... +[=] 228/0xE4 | 00 05 00 00 | 0 | .... +[=] 229/0xE5 | 44 4E 47 52 | 0 | DNGR +[=] 230/0xE6 | 00 00 00 00 | 0 | .... +------------------------------------- +]] + +example =[[ + +Set a new password of SUDO using the default password of DNGR: + + script run hf_mfu_next -x pass -p DNGR -n SUDO + +Enable password protection from hex block 04 onwards (User memory): + + script run hf_mfu_next -x protect -p DNGR -a 04 + +Enable password protection from hex block E3 onwards (Configuration Pages): + + script run hf_mfu_next -x protect -p DNGR -a E3 + +Disable password protection: + + script run hf_mfu_next -x protect -p DNGR -a FF + +Enable the counter and enable read + write password protection on password protected pages +(protected block start page specified using -x protect mode): + + script run hf_mfu_next -x conf -p DNGR -c enable -m rw + +Disable the counter and enable write only password protection on password protected pages +(protected block start specified using -x protect mode): + + script run hf_mfu_next -x conf -p DNGR -c disable -m w + +]] +usage = [[ + + script run hf_mfu_next -x pass -p -n + script run hf_mfu_next -x protect -p -a + script run hf_mfu_next -x conf -p -c -m + +]] +arguments = [[ + -h this help + -x mode (pass, protect, conf) + -p password (ascii) + -n new password (ascii) + -a auth0 block (hex) + -c counter (enable/disable) + -m protection mode (r/rw) +]] +--- +--- Usage help +local function help() + print(copyright) + print(author) + print(version) + print(desc) + print(ansicolors.cyan..'Usage'..ansicolors.reset) + print(usage) + print(ansicolors.cyan..'Arguments'..ansicolors.reset) + print(arguments) + print(ansicolors.cyan..'Example usage'..ansicolors.reset) + print(example) +end +--- +--- Print user message +local function msg(msg) + print( string.rep('--',20) ) + print('') + print(msg) + print('') + print( string.rep('--',20) ) +end +--- +--- String to hex function +local function strhex(str) + return (str:gsub(".", function(char) return string.format("%2x", char:byte()) end)) + end +--- +-- Main +local function main(args) + + for o, a in getopt.getopt(args, 'b:m:c:a:p:x:n:h') do + if o == 'm' then prot_mode = a end + if o == 'c' then counter = a end + if o == 'a' then auth0_block = a end + if o == 'p' then passwd = strhex(a) end + if o == 'x' then mode = a end + if o == 'n' then new_pass = strhex(a) end + if o == 'h' then return help() end + end + + if mode == 'pass' then + command = 'hf mfu wrbl -b 229 -d '..new_pass..' -k '..passwd + msg('Writing '..new_pass..' to PASSWD block (229/0xE5) : \n\n'..command) + core.console(command) + command = 'hf mfu rdbl -b 0 -k '..new_pass..'' + msg('Verifying password is correctly set : \n\n'..command) + core.console(command) + elseif mode == 'conf' then + if counter == 'enable' then + if prot_mode == 'r' then + command = 'hf mfu wrbl -b 228 -d 10050000 -k '..passwd + msg('Enabling counter and setting write access to protected pages as password protected : \n\n'..command) + core.console(command) + elseif prot_mode == 'rw' then + command = 'hf mfu wrbl -b 228 -d 90050000 -k '..passwd + msg('Enabling counter and setting read/write access to protected pages as password protected : \n\n'..command) + core.console(command) + end + elseif counter == 'disable' then + if prot_mode == 'w' then + command = 'hf mfu wrbl -b 228 -d 00050000 -k '..passwd + msg('Disabling counter and setting write password protection on protected pages : \n\n'..command) + core.console(command) + elseif prot_mode == 'rw' then + command = 'hf mfu wrbl -b 228 -d 80050000 -k '..passwd + msg('Disabling counter and setting read/write password protection on protected pages : \n\n'..command) + core.console(command) + end + end + elseif mode == 'protect' then + command = 'hf mfu wrbl -k '..passwd..' -b 227 -d 040000'..auth0_block + msg('Enabling password protection from block '..auth0_block..' onwards : \n\n'..command) + core.console(command) + else + return print(usage) + end + + if command == '' then return print(usage) end + + +end +main(args) From 971452f81715fd1cf93ceb2d05a7fd39533896fe Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 16 Nov 2022 18:16:39 +0100 Subject: [PATCH 355/759] renamed luascript --- .../{hf_mfu_ntag.lua => hf_ntag_dt.lua} | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) rename client/luascripts/{hf_mfu_ntag.lua => hf_ntag_dt.lua} (90%) diff --git a/client/luascripts/hf_mfu_ntag.lua b/client/luascripts/hf_ntag_dt.lua similarity index 90% rename from client/luascripts/hf_mfu_ntag.lua rename to client/luascripts/hf_ntag_dt.lua index 0709fc9f8..7af6753ef 100644 --- a/client/luascripts/hf_mfu_ntag.lua +++ b/client/luascripts/hf_ntag_dt.lua @@ -44,36 +44,36 @@ example =[[ Set a new password of SUDO using the default password of DNGR: - script run hf_mfu_next -x pass -p DNGR -n SUDO + script run hf_ntag_dt -x pass -p DNGR -n SUDO Enable password protection from hex block 04 onwards (User memory): - script run hf_mfu_next -x protect -p DNGR -a 04 + script run hf_ntag_dt -x protect -p DNGR -a 04 Enable password protection from hex block E3 onwards (Configuration Pages): - script run hf_mfu_next -x protect -p DNGR -a E3 + script run hf_ntag_dt -x protect -p DNGR -a E3 Disable password protection: - script run hf_mfu_next -x protect -p DNGR -a FF + script run hf_ntag_dt -x protect -p DNGR -a FF Enable the counter and enable read + write password protection on password protected pages (protected block start page specified using -x protect mode): - script run hf_mfu_next -x conf -p DNGR -c enable -m rw + script run hf_ntag_dt -x conf -p DNGR -c enable -m rw Disable the counter and enable write only password protection on password protected pages (protected block start specified using -x protect mode): - script run hf_mfu_next -x conf -p DNGR -c disable -m w + script run hf_ntag_dt -x conf -p DNGR -c disable -m w ]] usage = [[ - script run hf_mfu_next -x pass -p -n - script run hf_mfu_next -x protect -p -a - script run hf_mfu_next -x conf -p -c -m + script run hf_ntag_dt -x pass -p -n + script run hf_ntag_dt -x protect -p -a + script run hf_ntag_dt -x conf -p -c -m ]] arguments = [[ From f828a727c9d984eced189312475feac34d47993b Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Sun, 20 Nov 2022 01:01:11 +0100 Subject: [PATCH 356/759] Fix: hf 14a sim parsing args was taking tag type as number of reads if no -n option given --- client/src/cmdhf14a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index df13e0862..1b0bd1b1f 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -715,7 +715,7 @@ int CmdHF14ASim(const char *Cmd) { useUIDfromEML = false; } - uint8_t exitAfterNReads = arg_get_int(ctx, 3); + uint8_t exitAfterNReads = arg_get_int_def(ctx, 3, 0); if (arg_get_lit(ctx, 4)) { flags |= FLAG_NR_AR_ATTACK; From 1d00ef797c046f419f0e57dcc824b2ec1cb889c2 Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Sun, 20 Nov 2022 01:26:42 +0100 Subject: [PATCH 357/759] hf 14a sim, hf mfu sim: add hint for Ultralitgh EV1 --- client/src/cmdhf14a.c | 2 +- client/src/cmdhfmfu.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 1b0bd1b1f..e7cc42908 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -669,7 +669,7 @@ int CmdHF14ASim(const char *Cmd) { "hf 14a sim -t 4 -> ISO/IEC 14443-4\n" "hf 14a sim -t 5 -> MIFARE Tnp3xxx\n" "hf 14a sim -t 6 -> MIFARE Mini\n" - "hf 14a sim -t 7 -> Amiibo (NTAG 215), pack 0x8080\n" + "hf 14a sim -t 7 -> MIFARE Ultralight EV1, Amiibo (NTAG 215), pack 0x8080\n" "hf 14a sim -t 8 -> MIFARE Classic 4k\n" "hf 14a sim -t 9 -> FM11RF005SH Shanghai Metro\n" "hf 14a sim -t 10 -> ST25TA IKEA Rothult\n"); diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 05436d77f..ba028e958 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -2730,8 +2730,8 @@ static int CmdHF14AMfUSim(const char *Cmd) { "The UID from emulator memory will be used if not specified.\n" "See `hf 14a sim -h` to see available types. You want 2 or 7 usually.", "hf mfu sim -t 2 --uid 11223344556677 -> MIFARE Ultralight\n" - "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> Amiibo (NTAG 215), pack 0x8080\n" - "hf mfu sim -t 7 -> Amiibo (NTAG 215), pack 0x8080" + "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> MIFARE Ultralight EV1, Amiibo (NTAG 215), pack 0x8080\n" + "hf mfu sim -t 7 -> MIFARE Ultralight EV1, Amiibo (NTAG 215), pack 0x8080" ); void *argtable[] = { From 9dbd6e5f23c6424bc298606ffea65338a9a1ae58 Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Sun, 20 Nov 2022 15:31:20 +0100 Subject: [PATCH 358/759] change help text to fit screen --- client/src/cmdhf14a.c | 23 ++++++++++++----------- client/src/cmdhfmfu.c | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index e7cc42908..f8a96fedd 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -662,17 +662,18 @@ static int CmdHF14ACUIDs(const char *Cmd) { int CmdHF14ASim(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 14a sim", - "Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID", - "hf 14a sim -t 1 --uid 11223344 -> MIFARE Classic 1k\n" - "hf 14a sim -t 2 -> MIFARE Ultralight\n" - "hf 14a sim -t 3 -> MIFARE Desfire\n" - "hf 14a sim -t 4 -> ISO/IEC 14443-4\n" - "hf 14a sim -t 5 -> MIFARE Tnp3xxx\n" - "hf 14a sim -t 6 -> MIFARE Mini\n" - "hf 14a sim -t 7 -> MIFARE Ultralight EV1, Amiibo (NTAG 215), pack 0x8080\n" - "hf 14a sim -t 8 -> MIFARE Classic 4k\n" - "hf 14a sim -t 9 -> FM11RF005SH Shanghai Metro\n" - "hf 14a sim -t 10 -> ST25TA IKEA Rothult\n"); + "Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID\n" + "Use type 7 for Mifare Ultralight EV1, Amiibo (NTAG215 pack 0x8080)", + "hf 14a sim -t 1 --uid 11223344 -> MIFARE Classic 1k\n" + "hf 14a sim -t 2 -> MIFARE Ultralight\n" + "hf 14a sim -t 3 -> MIFARE Desfire\n" + "hf 14a sim -t 4 -> ISO/IEC 14443-4\n" + "hf 14a sim -t 5 -> MIFARE Tnp3xxx\n" + "hf 14a sim -t 6 -> MIFARE Mini\n" + "hf 14a sim -t 7 -> MFUEV1 / NTAG 215 Amiibo\n" + "hf 14a sim -t 8 -> MIFARE Classic 4k\n" + "hf 14a sim -t 9 -> FM11RF005SH Shanghai Metro\n" + "hf 14a sim -t 10 -> ST25TA IKEA Rothult\n"); void *argtable[] = { arg_param_begin, diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index ba028e958..aa93047e2 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -2730,8 +2730,8 @@ static int CmdHF14AMfUSim(const char *Cmd) { "The UID from emulator memory will be used if not specified.\n" "See `hf 14a sim -h` to see available types. You want 2 or 7 usually.", "hf mfu sim -t 2 --uid 11223344556677 -> MIFARE Ultralight\n" - "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> MIFARE Ultralight EV1, Amiibo (NTAG 215), pack 0x8080\n" - "hf mfu sim -t 7 -> MIFARE Ultralight EV1, Amiibo (NTAG 215), pack 0x8080" + "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> MFUEV1 / NTAG 215 Amiibo\n" + "hf mfu sim -t 7 -> MFUEV1 / NTAG 215 Amiibo" ); void *argtable[] = { From 4fb096966e3470315830d21551f37bf923214191 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 20 Nov 2022 16:34:45 +0100 Subject: [PATCH 359/759] extra checks for argument parsing of ints. And some text updates. There are other int parsing but they are checked with mandatory param int1 --- client/src/cmdhf14a.c | 11 ++++++++--- client/src/cmdhficlass.c | 2 +- client/src/cmdhfmfp.c | 16 ++++++++-------- client/src/cmdhfmfu.c | 4 ++-- client/src/cmdhw.c | 2 +- client/src/cmdlfem4x70.c | 8 ++++---- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index f8a96fedd..4c2498a85 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -670,7 +670,7 @@ int CmdHF14ASim(const char *Cmd) { "hf 14a sim -t 4 -> ISO/IEC 14443-4\n" "hf 14a sim -t 5 -> MIFARE Tnp3xxx\n" "hf 14a sim -t 6 -> MIFARE Mini\n" - "hf 14a sim -t 7 -> MFUEV1 / NTAG 215 Amiibo\n" + "hf 14a sim -t 7 -> MFU EV1 / NTAG 215 Amiibo\n" "hf 14a sim -t 8 -> MIFARE Classic 4k\n" "hf 14a sim -t 9 -> FM11RF005SH Shanghai Metro\n" "hf 14a sim -t 10 -> ST25TA IKEA Rothult\n"); @@ -687,7 +687,7 @@ int CmdHF14ASim(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, false); - int tagtype = arg_get_int(ctx, 1); + int tagtype = arg_get_int_def(ctx, 1, 1); int uid_len = 0; uint8_t uid[10] = {0}; @@ -727,6 +727,11 @@ int CmdHF14ASim(const char *Cmd) { CLIParserFree(ctx); + if (tagtype > 10) { + PrintAndLogEx(ERR, "Undefined tag %d", tagtype); + return PM3_EINVARG; + } + sector_t *k_sector = NULL; uint8_t k_sectorsCount = 40; @@ -752,7 +757,7 @@ int CmdHF14ASim(const char *Cmd) { PrintAndLogEx(INFO, "Press pm3-button to abort simulation"); bool keypress = kbd_enter_pressed(); - while (!keypress) { + while (keypress == false) { if (WaitForResponseTimeout(CMD_HF_MIFARE_SIMULATE, &resp, 1500) == 0) continue; if (resp.status != PM3_SUCCESS) break; diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 755d71aeb..95e5a7bef 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -706,7 +706,7 @@ static int CmdHFiClassSim(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, false); - int sim_type = arg_get_int(ctx, 1); + int sim_type = arg_get_int_def(ctx, 1, 3); int csn_len = 0; uint8_t csn[8] = {0}; diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 9de9d40c1..fe11836e1 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -713,18 +713,18 @@ static int CmdHFMFPRdbl(const char *Cmd) { } if (blockn > 255) { - PrintAndLogEx(ERR, " must be in range [0..255] instead of: %d", blockn); + PrintAndLogEx(ERR, " must be in range [0..255] got: %d", blockn); return PM3_EINVARG; } if (keylen != 16) { - PrintAndLogEx(ERR, " must be 16 bytes long instead of: %d", keylen); + PrintAndLogEx(ERR, " must be 16 bytes long. got: %d", keylen); return PM3_EINVARG; } // 3 blocks - wo iso14443-4 chaining if (blocksCount > 3) { - PrintAndLogEx(ERR, "blocks count must be less than 3 instead of: %d", blocksCount); + PrintAndLogEx(ERR, "blocks count must be less than 3. got: %d", blocksCount); return PM3_EINVARG; } @@ -823,12 +823,12 @@ static int CmdHFMFPRdsc(const char *Cmd) { } if (sectorNum > 39) { - PrintAndLogEx(ERR, " must be in range [0..39] instead of: %d", sectorNum); + PrintAndLogEx(ERR, " must be in range [0..39] got: %d", sectorNum); return PM3_EINVARG; } if (keylen != 16) { - PrintAndLogEx(ERR, " must be 16 bytes long instead of: %d", keylen); + PrintAndLogEx(ERR, " must be 16 bytes long. got: %d", keylen); return PM3_EINVARG; } @@ -925,17 +925,17 @@ static int CmdHFMFPWrbl(const char *Cmd) { } if (blockNum > 255) { - PrintAndLogEx(ERR, " must be in range [0..255] instead of: %d", blockNum); + PrintAndLogEx(ERR, " must be in range [0..255] got: %d", blockNum); return PM3_EINVARG; } if (keylen != 16) { - PrintAndLogEx(ERR, " must be 16 bytes long instead of: %d", keylen); + PrintAndLogEx(ERR, " must be 16 bytes long. got: %d", keylen); return PM3_EINVARG; } if (datainlen != 16) { - PrintAndLogEx(ERR, " must be 16 bytes long instead of: %d", datainlen); + PrintAndLogEx(ERR, " must be 16 bytes long. got: %d", datainlen); return PM3_EINVARG; } diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index aa93047e2..5b0004c09 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -2730,8 +2730,8 @@ static int CmdHF14AMfUSim(const char *Cmd) { "The UID from emulator memory will be used if not specified.\n" "See `hf 14a sim -h` to see available types. You want 2 or 7 usually.", "hf mfu sim -t 2 --uid 11223344556677 -> MIFARE Ultralight\n" - "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> MFUEV1 / NTAG 215 Amiibo\n" - "hf mfu sim -t 7 -> MFUEV1 / NTAG 215 Amiibo" + "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> MFU EV1 / NTAG 215 Amiibo\n" + "hf mfu sim -t 7 -> MFU EV1 / NTAG 215 Amiibo" ); void *argtable[] = { diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index 9831135f5..4962edfe2 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -597,7 +597,7 @@ static int CmdLCD(const char *Cmd) { int r_len = 0; uint8_t raw[1] = {0}; CLIGetHexWithReturn(ctx, 1, raw, &r_len); - int j = arg_get_int(ctx, 2); + int j = arg_get_int_def(ctx, 2, 1); if (j < 1) { PrintAndLogEx(WARNING, "Count must be larger than zero"); return PM3_EINVARG; diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index e0087e230..7021b2b95 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -165,7 +165,7 @@ int CmdEM4x70Write(const char *Cmd) { CLIParserInit(&ctx, "lf em 4x70 write", "Write EM4x70\n", - "lf em 4x70 write -b 15 -d c0de -> write 'c0de' to block 15\n" + "lf em 4x70 write -b 15 -d c0de -> write 'c0de' to block 15\n" "lf em 4x70 write -b 15 -d c0de --par -> adds parity bit to commands\n" ); @@ -181,7 +181,7 @@ int CmdEM4x70Write(const char *Cmd) { etd.parity = arg_get_lit(ctx, 1); - int addr = arg_get_int(ctx, 2); + int addr = arg_get_int_def(ctx, 2, 1); int word_len = 0; uint8_t word[2] = {0x0}; @@ -190,12 +190,12 @@ int CmdEM4x70Write(const char *Cmd) { CLIParserFree(ctx); if (addr < 0 || addr >= EM4X70_NUM_BLOCKS) { - PrintAndLogEx(FAILED, "block has to be within range [0, 15]"); + PrintAndLogEx(FAILED, "block has to be within range [0, 15] got: %d", addr); return PM3_EINVARG; } if (word_len != 2) { - PrintAndLogEx(FAILED, "word/data length must be 2 bytes instead of %d", word_len); + PrintAndLogEx(FAILED, "word/data length must be 2 bytes. got: %d", word_len); return PM3_EINVARG; } From 4dfcd44edd8782969d80971eb891585f82c00b2e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 20 Nov 2022 16:43:12 +0100 Subject: [PATCH 360/759] return default value when arg is not enforced with u32_1 --- client/src/cmdhw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index 4962edfe2..f10fa8330 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -763,7 +763,7 @@ static int CmdStandalone(const char *Cmd) { arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - uint8_t arg = arg_get_u32(ctx, 1); + uint8_t arg = arg_get_u32_def(ctx, 1, 1); CLIParserFree(ctx); clearCommandBuffer(); SendCommandNG(CMD_STANDALONE, (uint8_t *)&arg, sizeof(arg)); @@ -938,7 +938,7 @@ static int CmdPing(const char *Cmd) { arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - uint32_t len = arg_get_u32(ctx, 1); + uint32_t len = arg_get_u32_def(ctx, 1, 32); CLIParserFree(ctx); if (len > PM3_CMD_DATA_SIZE) From 317ddf42bc0748187c40ca76887da3d201351143 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 20 Nov 2022 16:47:49 +0100 Subject: [PATCH 361/759] style --- armsrc/mifarecmd.c | 12 ++++++------ client/luascripts/hf_ntag_dt.lua | 8 ++++---- client/src/cmdhflist.c | 4 ++-- client/src/cmdhfmf.c | 10 +++++----- client/src/cmdhfmfhard.c | 4 ++-- client/src/mifare/mifaredefault.h | 2 +- client/src/mifare/mifarehost.c | 2 +- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index e9cc713bd..922cd674d 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -878,7 +878,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, LED_C_ON(); - uint8_t prev_enc_nt[] = {0,0,0,0}; + uint8_t prev_enc_nt[] = {0, 0, 0, 0}; uint8_t prev_counter = 0; for (uint16_t i = 0; i <= PM3_CMD_DATA_SIZE - 9;) { @@ -950,10 +950,10 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, if (prev_enc_nt[0] == receivedAnswer[0] && - prev_enc_nt[1] == receivedAnswer[1] && - prev_enc_nt[2] == receivedAnswer[2] && - prev_enc_nt[3] == receivedAnswer[3] - ) { + prev_enc_nt[1] == receivedAnswer[1] && + prev_enc_nt[2] == receivedAnswer[2] && + prev_enc_nt[3] == receivedAnswer[3] + ) { prev_counter++; } memcpy(prev_enc_nt, receivedAnswer, 4); @@ -2849,7 +2849,7 @@ OUT: if (done || retval != 0) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); if (done || retval != 0) set_tracing(false); - BigBuf_free(); + BigBuf_free(); } void MifareSetMod(uint8_t *datain) { diff --git a/client/luascripts/hf_ntag_dt.lua b/client/luascripts/hf_ntag_dt.lua index 7af6753ef..5626a0b07 100644 --- a/client/luascripts/hf_ntag_dt.lua +++ b/client/luascripts/hf_ntag_dt.lua @@ -27,7 +27,7 @@ Default hf mfu info: [=] PACK [230/0xE6]: 00 00 - (cannot be read) [=] RFU [230/0xE6]: 00 00 - (cannot be read) ---------------------------------------------------------------------- - + Default blocks 0xE0 to 0xE6: ------------------------------------- [=] 224/0xE0 | 00 00 00 00 | 0 | .... @@ -48,7 +48,7 @@ Set a new password of SUDO using the default password of DNGR: Enable password protection from hex block 04 onwards (User memory): - script run hf_ntag_dt -x protect -p DNGR -a 04 + script run hf_ntag_dt -x protect -p DNGR -a 04 Enable password protection from hex block E3 onwards (Configuration Pages): @@ -58,7 +58,7 @@ Disable password protection: script run hf_ntag_dt -x protect -p DNGR -a FF -Enable the counter and enable read + write password protection on password protected pages +Enable the counter and enable read + write password protection on password protected pages (protected block start page specified using -x protect mode): script run hf_ntag_dt -x conf -p DNGR -c enable -m rw @@ -154,7 +154,7 @@ local function main(args) command = 'hf mfu wrbl -b 228 -d 80050000 -k '..passwd msg('Disabling counter and setting read/write password protection on protected pages : \n\n'..command) core.console(command) - end + end end elseif mode == 'protect' then command = 'hf mfu wrbl -k '..passwd..' -b 227 -d 040000'..auth0_block diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index fdfa34671..68a050158 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -1570,10 +1570,10 @@ void annotateMifare(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, // get UID if (MifareAuthState == masNone) { - if (isResponse && cmdsize == 5 ) { + if (isResponse && cmdsize == 5) { ClearAuthData(); AuthData.uid = bytes_to_num(&cmd[0], 4); - } + } if (cmdsize == 9 && cmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && cmd[1] == 0x70) { ClearAuthData(); AuthData.uid = bytes_to_num(&cmd[2], 4); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 1847bc1a6..69a360c69 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1842,7 +1842,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { CLIParserInit(&ctx, "hf mf hardnested", "Nested attack for hardened MIFARE Classic cards.\n" "if card is EV1, command can detect and use known key see example below\n" - "\n" + " \n" "`--i` set type of SIMD instructions. Without this flag programs autodetect it.\n" " or \n" " hf mf hardnested -r --tk [known target key]\n" @@ -7033,8 +7033,8 @@ static int CmdHF14AGen4Load(const char *cmd) { if (blockno == start) flags |= MAGIC_INIT ; if (blockno == end) flags |= MAGIC_OFF ; - int res=mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE), flags); - if ( res != PM3_SUCCESS) { + int res = mfG4SetBlock(pwd, blockno, data + (blockno * MFBLOCK_SIZE), flags); + if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Can't set magic card block: %d. error=%d", blockno, res); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); free(data); @@ -7195,10 +7195,10 @@ static int CmdHF14AGen4View(const char *Cmd) { uint8_t flags = 0 ; if (i == 0) flags |= MAGIC_INIT ; - if (i+1 == block_cnt) flags |= MAGIC_OFF ; + if (i + 1 == block_cnt) flags |= MAGIC_OFF ; int res = mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE), flags); - if ( res != PM3_SUCCESS) { + if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Can't get magic card block: %u. error=%d", i, res); PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); free(dump); diff --git a/client/src/cmdhfmfhard.c b/client/src/cmdhfmfhard.c index 2d373e451..7d930a8a3 100644 --- a/client/src/cmdhfmfhard.c +++ b/client/src/cmdhfmfhard.c @@ -2251,7 +2251,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc update_reduction_rate(0.0, true); int res = simulate_acquire_nonces(); - if ( res != PM3_SUCCESS) { + if (res != PM3_SUCCESS) { return res; } @@ -2356,7 +2356,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc init_nonce_memory(); update_reduction_rate(0.0, true); - int res; + int res; if (nonce_file_read) { // use pre-acquired data from file nonces.bin res = read_nonce_file(filename); if (res != PM3_SUCCESS) { diff --git a/client/src/mifare/mifaredefault.h b/client/src/mifare/mifaredefault.h index e28bb7f09..7ce83e29f 100644 --- a/client/src/mifare/mifaredefault.h +++ b/client/src/mifare/mifaredefault.h @@ -76,7 +76,7 @@ static const uint8_t g_mifare_default_key[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0x static const uint8_t g_mifare_mad_key[] = {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}; static const uint8_t g_mifare_mad_key_b[] = {0x89, 0xEC, 0xA9, 0x7F, 0x8C, 0x2A}; - // 16 key B D01AFEEB890A +// 16 key B D01AFEEB890A static const uint8_t g_mifare_signature_key_a[] = {0x5C, 0x8F, 0xF9, 0x99, 0x0D, 0xA2}; static const uint8_t g_mifare_signature_key_b[] = {0x4b, 0x79, 0x1b, 0xea, 0x7b, 0xcc}; diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index f12f78eab..7a927d5ed 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1425,7 +1425,7 @@ int detect_mf_magic(bool is_mfc) { bool detect_mfc_ev1_signature(void) { uint64_t key = 0; - int res = mfCheckKeys(69, MF_KEY_B, false, 1, (uint8_t*)g_mifare_signature_key_b, &key); + int res = mfCheckKeys(69, MF_KEY_B, false, 1, (uint8_t *)g_mifare_signature_key_b, &key); return (res == PM3_SUCCESS); } From 5b790afe433ba1d0e501ce0aa997bceaca5d651b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 20 Nov 2022 16:48:20 +0100 Subject: [PATCH 362/759] renamed param dict / f for more consistency overall --- client/src/cmdtrace.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index 812a97b2e..aea1880cb 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -1088,8 +1088,8 @@ int CmdTraceListAlias(const char *Cmd, const char *alias, const char *protocol) protocol); char example[200] = {0}; snprintf(example, sizeof(example) - 1, - "%s list -f -> show frame delay times\n" - "%s list -1 -> use trace buffer ", + "%s list --frame -> show frame delay times\n" + "%s list -1 -> use trace buffer ", alias, alias); char fullalias[100] = {0}; snprintf(fullalias, sizeof(fullalias) - 1, "%s list", alias); @@ -1098,20 +1098,20 @@ int CmdTraceListAlias(const char *Cmd, const char *alias, const char *protocol) void *argtable[] = { arg_param_begin, arg_lit0("1", "buffer", "use data from trace buffer"), - arg_lit0("f", NULL, "show frame delay times"), + arg_lit0(NULL, "frame", "show frame delay times"), arg_lit0("c", NULL, "mark CRC bytes"), arg_lit0("r", NULL, "show relative times (gap and duration)"), arg_lit0("u", NULL, "display times in microseconds instead of clock cycles"), arg_lit0("x", NULL, "show hexdump to convert to pcap(ng)\n" " or to import into Wireshark using encapsulation type \"ISO 14443\""), - arg_str0(NULL, "dict", "", "use dictionary keys file"), + arg_str0("f", "file", "", "filename of dictionary"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); CLIParserFree(ctx); char args[128] = {0}; - snprintf(args, sizeof(args), "-t %s ", protocol); + snprintf(args, sizeof(args), "-c -t %s ", protocol); strncat(args, Cmd, sizeof(args) - strlen(args) - 1); return CmdTraceList(args); } @@ -1141,22 +1141,22 @@ int CmdTraceList(const char *Cmd) { "trace list -t thinfilm -> interpret as " _YELLOW_("Thinfilm") "\n" "trace list -t topaz -> interpret as " _YELLOW_("Topaz") "\n" "\n" - "trace list -t mf --dict -> use dictionary keys file\n" - "trace list -t 14a -f -> show frame delay times\n" - "trace list -t 14a -1 -> use trace buffer " + "trace list -t mf -f mfc_default_keys.dic -> use default dictionary file\n" + "trace list -t 14a --frame -> show frame delay times\n" + "trace list -t 14a -1 -> use trace buffer " ); void *argtable[] = { arg_param_begin, arg_lit0("1", "buffer", "use data from trace buffer"), - arg_lit0("f", NULL, "show frame delay times"), + arg_lit0(NULL, "frame", "show frame delay times"), arg_lit0("c", NULL, "mark CRC bytes"), arg_lit0("r", NULL, "show relative times (gap and duration)"), arg_lit0("u", NULL, "display times in microseconds instead of clock cycles"), arg_lit0("x", NULL, "show hexdump to convert to pcap(ng)\n" " or to import into Wireshark using encapsulation type \"ISO 14443\""), arg_str0("t", "type", NULL, "protocol to annotate the trace"), - arg_str0(NULL, "dict", "", "use dictionary keys file"), + arg_str0("f", "file", "", "filename of dictionary"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); From 584e0ad8332f703b1294a85fb15b7ad0d0a255a6 Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Sun, 20 Nov 2022 21:28:42 +0100 Subject: [PATCH 363/759] Added hf mfu esave --- CHANGELOG.md | 1 + client/src/cmdhfmf.c | 2 +- client/src/cmdhfmfu.c | 136 +++++++++++++++++--- client/src/pm3line_vocabulory.h | 1 + doc/commands.json | 216 +++++++++++++++++--------------- doc/commands.md | 3 +- 6 files changed, 239 insertions(+), 120 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afe7f7fe4..48f531dff 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] + - Added `hf mfu esave` - saves emulator memory to mfu dump file (@DidierA) - Added luascript `hf_mfu_ntag` - Script for configuring NTAG216 configuration pages (@flamebarke) - Changed `hf mf hardnested` - a detection for static encrypted nonces (@iceman1001) - Added requirements.txt file to tools folder. Minimum to run pm3_tests.sh (@iceman1001) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 69a360c69..f15cccbf8 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -4025,7 +4025,7 @@ int CmdHF14AMfELoad(const char *Cmd) { } if (resp.status != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Loading file from spiffs to emulatore memory failed"); + PrintAndLogEx(FAILED, "Loading file from spiffs to emulator memory failed"); return PM3_EFLASH; } diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 5b0004c09..1b802b46b 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -2718,6 +2718,7 @@ static int CmdHF14AMfUeLoad(const char *Cmd) { PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfu sim -t 7`") " to simulate an Amiibo."); return res; } + // // Simulate tag // @@ -4098,41 +4099,135 @@ int CmdHF14MfuNDEFRead(const char *Cmd) { return status; } -static int CmdHF14AMfuEView(const char *Cmd) { - CLIParserContext *ctx; - CLIParserInit(&ctx, "hf mfu eview", - "It displays emulator memory", - "hf mfu eview" - ); +// utility function. Retrieves emulator memory +static int GetMfuDumpFromEMul(mfu_dump_t **buf) { - void *argtable[] = { - arg_param_begin, - arg_param_end - }; - CLIExecWithReturn(ctx, Cmd, argtable, true); - CLIParserFree(ctx); - - uint16_t blocks = MFU_MAX_BLOCKS; - uint16_t bytes = MFU_MAX_BYTES + MFU_DUMP_PREFIX_LENGTH; - - uint8_t *dump = calloc(bytes, sizeof(uint8_t)); + uint8_t *dump = malloc(sizeof(mfu_dump_t)); if (dump == NULL) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return PM3_EMALLOC; } PrintAndLogEx(INFO, "downloading from emulator memory"); - if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF_EML, dump, sizeof(mfu_dump_t), 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(dump); return PM3_ETIMEOUT; } - printMFUdumpEx((mfu_dump_t *)dump, blocks, 0); + *buf = (mfu_dump_t *)dump ; + return PM3_SUCCESS ; +} + +static int CmdHF14AMfuEView(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfu eview", + "Displays emulator memory\n" + "By default number of pages shown depends on defined tag type.\n" + "You can override this with option --end.", + "hf mfu eview\n" + "hf mfu eview --end 255 -> dumps whole memory" + ); + + void *argtable[] = { + arg_param_begin, + arg_int0("e", "end", "", "index of last block"), + arg_param_end + }; + + CLIExecWithReturn(ctx, Cmd, argtable, true); + int end = arg_get_int_def(ctx, 1, -1); + CLIParserFree(ctx); + + bool override_end = (end != -1) ; + + if (override_end && (end < 0 || end > MFU_MAX_BLOCKS)) { + PrintAndLogEx(WARNING, "Invalid value for end:%d. Must be be positive integer < %d.", end, MFU_MAX_BLOCKS); + return PM3_EINVARG ; + } + + mfu_dump_t *dump ; + int res = GetMfuDumpFromEMul(&dump) ; + if (res != PM3_SUCCESS) { + return res ; + } + + if (override_end) { + ++end ; + } else { + end = dump->pages ; + } + + printMFUdumpEx(dump, end, 0); free(dump); return PM3_SUCCESS; } +static int CmdHF14AMfuESave(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfu esave", + "Saves emulator memory to a MIFARE Ultralight/NTAG dump file (bin/eml/json)\n" + "By default number of pages saved depends on defined tag type.\n" + "You can override this with option --end.", + "hf mfu esave\n" + "hf mfu esave --end 255 -> saves whole memory\n" + "hf mfu esave -f hf-mfu-04010203040506-dump.json" + ); + + void *argtable[] = { + arg_param_begin, + arg_int0("e", "end", "", "index of last block"), + arg_str0("f", "file", "", "filename of dump"), + arg_param_end + }; + + CLIExecWithReturn(ctx, Cmd, argtable, true); + int end = arg_get_int_def(ctx, 1, -1); + + char filename[FILE_PATH_SIZE]; + int fnlen = 0 ; + CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + + CLIParserFree(ctx); + + bool override_end = (end != -1) ; + + if (override_end && (end < 0 || end > MFU_MAX_BLOCKS)) { + PrintAndLogEx(WARNING, "Invalid value for end:%d. Must be be positive integer <= %d.", end, MFU_MAX_BLOCKS); + return PM3_EINVARG ; + } + + // get dump from memory + mfu_dump_t *dump ; + int res = GetMfuDumpFromEMul(&dump) ; + if (res != PM3_SUCCESS) { + return res ; + } + + // initialize filename + if (fnlen < 1) { + PrintAndLogEx(INFO, "Using UID as filename"); + uint8_t uid[7] = {0}; + memcpy(uid, (uint8_t *) & (dump->data), 3); + memcpy(uid + 3, (uint8_t *) & (dump->data) + 4, 4); + strcat(filename, "hf-mfu-"); + FillFileNameByUID(filename, uid, "-dump", sizeof(uid)); + } + + if (override_end) { + end ++ ; + } else { + end = dump->pages ; + } + + // save dump. Last block contains PACK + RFU + uint16_t datalen = (end + 1) * MFU_BLOCK_SIZE + MFU_DUMP_PREFIX_LENGTH; + res = pm3_save_dump(filename, (uint8_t *)dump, datalen, jsfMfuMemory, MFU_BLOCK_SIZE); + + free(dump); + return res; +} + static int CmdHF14AMfuView(const char *Cmd) { CLIParserContext *ctx; @@ -4247,7 +4342,8 @@ static command_t CommandTable[] = { {"view", CmdHF14AMfuView, AlwaysAvailable, "Display content from tag dump file"}, {"wrbl", CmdHF14AMfUWrBl, IfPm3Iso14443a, "Write block"}, {"---------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"}, - {"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "Load Ultralight .eml dump file into emulator memory"}, + {"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "Load Ultralight dump file into emulator memory"}, + {"esave", CmdHF14AMfuESave, IfPm3Iso14443a, "Save Ultralight dump file from emulator memory"}, {"eview", CmdHF14AMfuEView, IfPm3Iso14443a, "View emulator memory"}, {"sim", CmdHF14AMfUSim, IfPm3Iso14443a, "Simulate MIFARE Ultralight from emulator memory"}, {"---------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("magic") " ----------------------------"}, diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 6d348e667..f37a2f859 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -379,6 +379,7 @@ const static vocabulory_t vocabulory[] = { { 1, "hf mfu view" }, { 0, "hf mfu wrbl" }, { 0, "hf mfu eload" }, + { 0, "hf mfu esave" }, { 0, "hf mfu eview" }, { 0, "hf mfu sim" }, { 0, "hf mfu setpwd" }, diff --git a/doc/commands.json b/doc/commands.json index c9ce72f8c..7e1a692f3 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -868,22 +868,22 @@ "command": "emv list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "emv list -f -> show frame delay times", + "emv list --frame -> show frame delay times", "emv list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "emv list [-h1fcrux] [--dict ]" + "usage": "emv list [-h1crux] [--frame] [-f ]" }, "emv pse": { "command": "emv pse", @@ -1145,22 +1145,22 @@ "command": "hf 14a list", "description": "Alias of `trace list -t 14a` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf 14a list -f -> show frame delay times", + "hf 14a list --frame -> show frame delay times", "hf 14a list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf 14a list [-h1fcrux] [--dict ]" + "usage": "hf 14a list [-h1crux] [--frame] [-f ]" }, "hf 14a ndefformat": { "command": "hf 14a ndefformat", @@ -1259,7 +1259,7 @@ }, "hf 14a sim": { "command": "hf 14a sim", - "description": "Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID", + "description": "Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID Use type 7 for Mifare Ultralight EV1, Amiibo (NTAG215 pack 0x8080)", "notes": [ "hf 14a sim -t 1 --uid 11223344 -> MIFARE Classic 1k", "hf 14a sim -t 2 -> MIFARE Ultralight", @@ -1267,7 +1267,7 @@ "hf 14a sim -t 4 -> ISO/IEC 14443-4", "hf 14a sim -t 5 -> MIFARE Tnp3xxx", "hf 14a sim -t 6 -> MIFARE Mini", - "hf 14a sim -t 7 -> Amiibo (NTAG 215), pack 0x8080", + "hf 14a sim -t 7 -> MFU EV1 / NTAG 215 Amiibo", "hf 14a sim -t 8 -> MIFARE Classic 4k", "hf 14a sim -t 9 -> FM11RF005SH Shanghai Metro", "hf 14a sim -t 10 -> ST25TA IKEA Rothult" @@ -1363,22 +1363,22 @@ "command": "hf 14b list", "description": "Alias of `trace list -t 14b` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf 14b list -f -> show frame delay times", + "hf 14b list --frame -> show frame delay times", "hf 14b list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf 14b list [-h1fcrux] [--dict ]" + "usage": "hf 14b list [-h1crux] [--frame] [-f ]" }, "hf 14b ndefread": { "command": "hf 14b ndefread", @@ -1637,22 +1637,22 @@ "command": "hf 15 list", "description": "Alias of `trace list -t 15` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf 15 list -f -> show frame delay times", + "hf 15 list --frame -> show frame delay times", "hf 15 list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf 15 list [-h1fcrux] [--dict ]" + "usage": "hf 15 list [-h1crux] [--frame] [-f ]" }, "hf 15 raw": { "command": "hf 15 raw", @@ -2232,22 +2232,22 @@ "command": "hf emrtd list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf emrtd list -f -> show frame delay times", + "hf emrtd list --frame -> show frame delay times", "hf emrtd list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf emrtd list [-h1fcrux] [--dict ]" + "usage": "hf emrtd list [-h1crux] [--frame] [-f ]" }, "hf epa cnonces": { "command": "hf epa cnonces", @@ -2367,22 +2367,22 @@ "command": "hf felica list", "description": "Alias of `trace list -t felica` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf felica list -f -> show frame delay times", + "hf felica list --frame -> show frame delay times", "hf felica list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf felica list [-h1fcrux] [--dict ]" + "usage": "hf felica list [-h1crux] [--frame] [-f ]" }, "hf felica litedump": { "command": "hf felica litedump", @@ -2635,22 +2635,22 @@ "command": "hf fido list", "description": "Alias of `trace list -t 14a` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf fido list -f -> show frame delay times", + "hf fido list --frame -> show frame delay times", "hf fido list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf fido list [-h1fcrux] [--dict ]" + "usage": "hf fido list [-h1crux] [--frame] [-f ]" }, "hf fido make": { "command": "hf fido make", @@ -2969,9 +2969,10 @@ "--elite elite computations applied to key", "--raw raw, the key is interpreted as raw block 3/4", "--nr replay of NR/MAC", - "-z, --dense dense dump output style" + "-z, --dense dense dump output style", + "--force force unsecure card read" ], - "usage": "hf iclass dump [-hz] [-f ] [-k ] [--ki ] [--credit ] [--ci ] [--elite] [--raw] [--nr]" + "usage": "hf iclass dump [-hz] [-f ] [-k ] [--ki ] [--credit ] [--ci ] [--elite] [--raw] [--nr] [--force]" }, "hf iclass eload": { "command": "hf iclass eload", @@ -2990,7 +2991,7 @@ }, "hf iclass encode": { "command": "hf iclass encode", - "description": "Encode binary wiegand to block 7 Use either --bin or --wiegand/--fc/--cn", + "description": "Encode binary wiegand to block 7,8,9 Use either --bin or --wiegand/--fc/--cn", "notes": [ "hf iclass encode --bin 10001111100000001010100011 --ki 0 -> FC 31 CN 337", "hf iclass encode --fc 31 --cn 337 --ki 0 -> FC 31 CN 337", @@ -3084,22 +3085,22 @@ "command": "hf iclass list", "description": "Alias of `trace list -t iclass` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf iclass list -f -> show frame delay times", + "hf iclass list --frame -> show frame delay times", "hf iclass list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf iclass list [-h1fcrux] [--dict ]" + "usage": "hf iclass list [-h1crux] [--frame] [-f ]" }, "hf iclass loclass": { "command": "hf iclass loclass", @@ -3573,22 +3574,22 @@ "command": "hf legic list", "description": "Alias of `trace list -t legic` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf legic list -f -> show frame delay times", + "hf legic list --frame -> show frame delay times", "hf legic list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf legic list [-h1fcrux] [--dict ]" + "usage": "hf legic list [-h1crux] [--frame] [-f ]" }, "hf legic rdbl": { "command": "hf legic rdbl", @@ -3695,22 +3696,22 @@ "command": "hf list", "description": "Alias of `trace list -t raw` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf list -f -> show frame delay times", + "hf list --frame -> show frame delay times", "hf list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf list [-h1fcrux] [--dict ]" + "usage": "hf list [-h1crux] [--frame] [-f ]" }, "hf lto dump": { "command": "hf lto dump", @@ -3749,22 +3750,22 @@ "command": "hf lto list", "description": "Alias of `trace list -t lto` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf lto list -f -> show frame delay times", + "hf lto list --frame -> show frame delay times", "hf lto list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf lto list [-h1fcrux] [--dict ]" + "usage": "hf lto list [-h1crux] [--frame] [-f ]" }, "hf lto rdbl": { "command": "hf lto rdbl", @@ -4344,7 +4345,7 @@ "--start index of block to start writing (default 0)", "--end index of block to end writing (default last block)" ], - "usage": "hf mf gload [-hv] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu] --start --end " + "usage": "hf mf gload [-hv] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu] [--start ] [--end ]" }, "hf mf gsetblk": { "command": "hf mf gsetblk", @@ -4382,8 +4383,9 @@ }, "hf mf hardnested": { "command": "hf mf hardnested", - "description": "Nested attack for hardened MIFARE Classic cards. `--i` set type of SIMD instructions. Without this flag programs autodetect it. or hf mf hardnested -r --tk [known target key] Add the known target key to check if it is present in the remaining key space hf mf hardnested --blk 0 -a -k A0A1A2A3A4A5 --tblk 4 --ta --tk FFFFFFFFFFFF", + "description": "Nested attack for hardened MIFARE Classic cards. if card is EV1, command can detect and use known key see example below `--i` set type of SIMD instructions. Without this flag programs autodetect it. or hf mf hardnested -r --tk [known target key] Add the known target key to check if it is present in the remaining key space hf mf hardnested --blk 0 -a -k A0A1A2A3A4A5 --tblk 4 --ta --tk FFFFFFFFFFFF", "notes": [ + "hf mf hardnested --tblk 4 --ta -> works for MFC EV1", "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta", "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -w", "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -f nonces.bin -w -s", @@ -4430,22 +4432,22 @@ "command": "hf mf list", "description": "Alias of `trace list -t mf` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf mf list -f -> show frame delay times", + "hf mf list --frame -> show frame delay times", "hf mf list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf mf list [-h1fcrux] [--dict ]" + "usage": "hf mf list [-h1crux] [--frame] [-f ]" }, "hf mf mad": { "command": "hf mf mad", @@ -5609,22 +5611,22 @@ "command": "hf mfdes list", "description": "Alias of `trace list -t des` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf mfdes list -f -> show frame delay times", + "hf mfdes list --frame -> show frame delay times", "hf mfdes list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf mfdes list [-h1fcrux] [--dict ]" + "usage": "hf mfdes list [-h1crux] [--frame] [-f ]" }, "hf mfdes lsapp": { "command": "hf mfdes lsapp", @@ -6171,17 +6173,35 @@ ], "usage": "hf mfu eload [-h] -f [-q ]" }, - "hf mfu eview": { - "command": "hf mfu eview", - "description": "It displays emulator memory", + "hf mfu esave": { + "command": "hf mfu esave", + "description": "Saves emulator memory to a MIFARE Ultralight/NTAG dump file (bin/eml/json) By default number of pages saved depends on defined tag type. You can overrife this with option --end.", "notes": [ - "hf mfu eview" + "hf mfu esave", + "hf mfu esave --end 255 -> saves whole memory", + "hf mfu esave -f hf-mfu-04010203040506-dump.json" ], "offline": false, "options": [ - "-h, --help This help" + "-h, --help This help", + "-e, --end index of last block", + "-f, --file filename of dump" ], - "usage": "hf mfu eview [-h]" + "usage": "hf mfu esave [-h] [-e ] [-f ]" + }, + "hf mfu eview": { + "command": "hf mfu eview", + "description": "Displays emulator memory By default number of pages shown depends on defined tag type. You can overrife this with option --end.", + "notes": [ + "hf mfu eview", + "hf mfu eview --end 255 -> dumps whole memory" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-e, --end index of last block" + ], + "usage": "hf mfu eview [-h] [-e ]" }, "hf mfu help": { "command": "hf mfu help", @@ -6349,8 +6369,8 @@ "description": "Simulate MIFARE Ultralight family type based upon ISO/IEC 14443 type A tag with 4,7 or 10 byte UID from emulator memory. See `hf mfu eload` first. The UID from emulator memory will be used if not specified. See `hf 14a sim -h` to see available types. You want 2 or 7 usually.", "notes": [ "hf mfu sim -t 2 --uid 11223344556677 -> MIFARE Ultralight", - "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> Amiibo (NTAG 215), pack 0x8080", - "hf mfu sim -t 7 -> Amiibo (NTAG 215), pack 0x8080" + "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> MFU EV1 / NTAG 215 Amiibo", + "hf mfu sim -t 7 -> MFU EV1 / NTAG 215 Amiibo" ], "offline": false, "options": [ @@ -6491,22 +6511,22 @@ "command": "hf seos list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf seos list -f -> show frame delay times", + "hf seos list --frame -> show frame delay times", "hf seos list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf seos list [-h1fcrux] [--dict ]" + "usage": "hf seos list [-h1crux] [--frame] [-f ]" }, "hf sniff": { "command": "hf sniff", @@ -6549,22 +6569,22 @@ "command": "hf st25ta list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf st25ta list -f -> show frame delay times", + "hf st25ta list --frame -> show frame delay times", "hf st25ta list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf st25ta list [-h1fcrux] [--dict ]" + "usage": "hf st25ta list [-h1crux] [--frame] [-f ]" }, "hf st25ta ndefread": { "command": "hf st25ta ndefread", @@ -6699,22 +6719,22 @@ "command": "hf thinfilm list", "description": "Alias of `trace list -t thinfilm` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf thinfilm list -f -> show frame delay times", + "hf thinfilm list --frame -> show frame delay times", "hf thinfilm list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf thinfilm list [-h1fcrux] [--dict ]" + "usage": "hf thinfilm list [-h1crux] [--frame] [-f ]" }, "hf thinfilm sim": { "command": "hf thinfilm sim", @@ -6770,22 +6790,22 @@ "command": "hf topaz list", "description": "Alias of `trace list -t topaz` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf topaz list -f -> show frame delay times", + "hf topaz list --frame -> show frame delay times", "hf topaz list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf topaz list [-h1fcrux] [--dict ]" + "usage": "hf topaz list [-h1crux] [--frame] [-f ]" }, "hf topaz raw": { "command": "hf topaz raw", @@ -8513,22 +8533,22 @@ "command": "lf hitag list", "description": "Alias of `trace list -t hitag2` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "lf hitag list -f -> show frame delay times", + "lf hitag list --frame -> show frame delay times", "lf hitag list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "lf hitag list [-h1fcrux] [--dict ]" + "usage": "lf hitag list [-h1crux] [--frame] [-f ]" }, "lf hitag reader": { "command": "lf hitag reader", @@ -11258,22 +11278,22 @@ "command": "smart list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "smart list -f -> show frame delay times", + "smart list --frame -> show frame delay times", "smart list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "smart list [-h1fcrux] [--dict ]" + "usage": "smart list [-h1crux] [--frame] [-f ]" }, "smart raw": { "command": "smart raw", @@ -11380,24 +11400,24 @@ "trace list -t thinfilm -> interpret as Thinfilm", "trace list -t topaz -> interpret as Topaz", "", - "trace list -t mf --dict -> use dictionary keys file", - "trace list -t 14a -f -> show frame delay times", + "trace list -t mf -f mfc_default_keys.dic -> use default dictionary file", + "trace list -t 14a --frame -> show frame delay times", "trace list -t 14a -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", "-t, --type protocol to annotate the trace", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "trace list [-h1fcrux] [-t ] [--dict ]" + "usage": "trace list [-h1crux] [--frame] [-t ] [-f ]" }, "trace load": { "command": "trace load", @@ -11595,8 +11615,8 @@ } }, "metadata": { - "commands_extracted": 731, + "commands_extracted": 732, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-11-05T18:17:23" + "extracted_on": "2022-11-20T20:19:15" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 498d62b62..32d42e0a2 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -557,7 +557,8 @@ Check column "offline" for their availability. |`hf mfu restore `|N |`Restore a dump onto a MFU MAGIC tag` |`hf mfu view `|Y |`Display content from tag dump file` |`hf mfu wrbl `|N |`Write block` -|`hf mfu eload `|N |`Load Ultralight .eml dump file into emulator memory` +|`hf mfu eload `|N |`Load Ultralight dump file into emulator memory` +|`hf mfu esave `|N |`Save Ultralight dump file from emulator memory` |`hf mfu eview `|N |`View emulator memory` |`hf mfu sim `|N |`Simulate MIFARE Ultralight from emulator memory` |`hf mfu setpwd `|N |`Set 3DES key - Ultralight-C` From b857205504fba65c8aec5618333576ef51b5ee1e Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Mon, 21 Nov 2022 19:18:14 +0100 Subject: [PATCH 364/759] Add hf mf gsave --- CHANGELOG.md | 2 +- client/src/cmdhfmf.c | 193 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 193 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afe7f7fe4..fd037b40b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001) - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - - Added `hf mf gload, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) + - Added `hf mf gload, gsave, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 69a360c69..522ac1d7f 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -4889,7 +4889,7 @@ static int CmdHF14AMfCSave(const char *Cmd) { arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50 (def)"), arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), - arg_lit0(NULL, "emu", "from emulator memory"), + arg_lit0(NULL, "emu", "to emulator memory"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -7217,6 +7217,196 @@ static int CmdHF14AGen4View(const char *Cmd) { return PM3_SUCCESS; } +// save contents of Gent4 GTU card to file / emulator +static int CmdHF14AGen4Save(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf gsave", + "Save `magic gen4 gtu` card memory into three files (BIN/EML/JSON)" + "or into emulator memory", + "hf mf gsave\n" + "hf mf gsave --4k\n" + "hf mf gsave -p DEADBEEF -f hf-mf-01020304.json" + ); + void *argtable[] = { + arg_param_begin, + arg_lit0(NULL, "mini", "MIFARE Classic Mini / S20"), + arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50 (def)"), + arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), + arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), + arg_str0("p", "pwd", "", "password 4bytes"), + arg_str0("f", "file", "", "filename of dump"), + arg_lit0(NULL, "emu", "to emulator memory"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool m0 = arg_get_lit(ctx, 1); + bool m1 = arg_get_lit(ctx, 2); + bool m2 = arg_get_lit(ctx, 3); + bool m4 = arg_get_lit(ctx, 4); + + int pwd_len = 0; + uint8_t pwd[4] = {0}; + CLIGetHexWithReturn(ctx, 5, pwd, &pwd_len); + + int fnlen = 0; + char filename[FILE_PATH_SIZE]; + CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + + bool fill_emulator = arg_get_lit(ctx,7); + CLIParserFree(ctx); + + // validations + if (pwd_len != 4 && pwd_len != 0) { + PrintAndLogEx(FAILED, "Must specify 4 bytes, got " _YELLOW_("%u"), pwd_len); + return PM3_EINVARG; + } + + if ((m0 + m1 + m2 + m4) > 1) { + PrintAndLogEx(WARNING, "Only specify one MIFARE Type"); + return PM3_EINVARG; + } else if ((m0 + m1 + m2 + m4) == 0) { + m1 = true; + } + + char s[6]; + memset(s, 0, sizeof(s)); + uint16_t block_cnt = MIFARE_1K_MAXBLOCK; + if (m0) { + block_cnt = MIFARE_MINI_MAXBLOCK; + strncpy(s, "Mini", 5); + } else if (m1) { + block_cnt = MIFARE_1K_MAXBLOCK; + strncpy(s, "1K", 3); + } else if (m2) { + block_cnt = MIFARE_2K_MAXBLOCK; + strncpy(s, "2K", 3); + } else if (m4) { + block_cnt = MIFARE_4K_MAXBLOCK; + strncpy(s, "4K", 3); + } else { + PrintAndLogEx(WARNING, "Please specify a MIFARE Type"); + return PM3_EINVARG; + } + PrintAndLogEx(SUCCESS, "Dumping magic gen4 GTU MIFARE Classic " _GREEN_("%s") " card memory", s); + PrintAndLogEx(INFO, "." NOLF); + + // Select card to get UID/UIDLEN information + clearCommandBuffer(); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { + PrintAndLogEx(WARNING, "iso14443a card select timeout"); + return PM3_ETIMEOUT; + } + + /* + 0: couldn't read + 1: OK, with ATS + 2: OK, no ATS + 3: proprietary Anticollision + */ + uint64_t select_status = resp.oldarg[0]; + if (select_status == 0) { + PrintAndLogEx(WARNING, "iso14443a card select failed"); + return PM3_SUCCESS; + } + + // store card info + iso14a_card_select_t card; + memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); + + // reserve memory + uint16_t bytes = block_cnt * MFBLOCK_SIZE; + uint8_t *dump = calloc(bytes, sizeof(uint8_t)); + if (dump == NULL) { + PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); + return PM3_EMALLOC; + } + + for (uint16_t i = 0; i < block_cnt; i++) { + + // 4k READs can be long, so we split status each 64 blocks. + if (i % 64 == 0) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "" NOLF) ; + } + PrintAndLogEx(NORMAL, "." NOLF); + fflush(stdout); + + uint8_t flags = 0 ; + if (i == 0) flags |= MAGIC_INIT ; + if (i + 1 == block_cnt) flags |= MAGIC_OFF ; + + int res = mfG4GetBlock(pwd, i, dump + (i * MFBLOCK_SIZE), flags); + if (res != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Can't get magic card block: %u. error=%d", i, res); + PrintAndLogEx(HINT, "Verify your card size, and try again or try another tag position"); + free(dump); + return PM3_ESOFT; + } + } + + PrintAndLogEx(NORMAL, ""); + + if (fill_emulator) { + PrintAndLogEx(INFO, "uploading to emulator memory" NOLF); + // fast push mode + g_conn.block_after_ACK = true; + + size_t offset = 0; + int cnt = 0; + uint16_t bytes_left = bytes ; + + while (bytes_left > 0 && cnt < block_cnt) { + // 4k writes can be long, so we split status each 64 blocks. + if (cnt % 64 == 0) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "" NOLF) ; + } + PrintAndLogEx(NORMAL, "." NOLF); + fflush(stdout); + + if (bytes_left == MFBLOCK_SIZE) { + // Disable fast mode on last packet + g_conn.block_after_ACK = false; + } + + if (mfEmlSetMem_xt(dump + offset, cnt, 1, MFBLOCK_SIZE) != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Can't set emulator mem at block: %3d", cnt); + free(dump); + return PM3_ESOFT; + } + + cnt++; + offset += MFBLOCK_SIZE; + bytes_left -= MFBLOCK_SIZE; + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "uploaded " _YELLOW_("%d") " bytes to emulator memory", bytes); + } + + // user supplied filename? + if (fnlen < 1) { + char *fptr = filename; + fptr += snprintf(fptr, sizeof(filename), "hf-mf-"); + FillFileNameByUID(fptr, card.uid, "-dump", card.uidlen); + } + + saveFile(filename, ".bin", dump, bytes); + saveFileEML(filename, dump, bytes, MFBLOCK_SIZE); + iso14a_mf_extdump_t xdump; + xdump.card_info = card; + xdump.dump = dump; + xdump.dumplen = bytes; + saveFileJSON(filename, jsfCardMemory, (uint8_t *)&xdump, sizeof(xdump), NULL); + + free(dump); + return PM3_SUCCESS; +} + + static int CmdHF14AMfValue(const char *Cmd) { CLIParserContext *ctx; @@ -7479,6 +7669,7 @@ static command_t CommandTable[] = { {"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GTU") " --------------------------"}, {"ggetblk", CmdHF14AGen4GetBlk, IfPm3Iso14443a, "Read block from card"}, {"gload", CmdHF14AGen4Load, IfPm3Iso14443a, "Load dump to card"}, + {"gsave", CmdHF14AGen4Save, IfPm3Iso14443a, "Save dump from card into file or emulator"}, {"gsetblk", CmdHF14AGen4SetBlk, IfPm3Iso14443a, "Write block to card"}, {"gview", CmdHF14AGen4View, IfPm3Iso14443a, "View card"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"}, From 182d167aad4951da271952da3de39fbf069f8865 Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Mon, 21 Nov 2022 22:05:24 +0100 Subject: [PATCH 365/759] use calloc() --- client/src/cmdhfmfu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 1b802b46b..138cae25a 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -4102,7 +4102,7 @@ int CmdHF14MfuNDEFRead(const char *Cmd) { // utility function. Retrieves emulator memory static int GetMfuDumpFromEMul(mfu_dump_t **buf) { - uint8_t *dump = malloc(sizeof(mfu_dump_t)); + uint8_t *dump = calloc(MFU_MAX_BYTES + MFU_DUMP_PREFIX_LENGTH, sizeof(uint8_t)); if (dump == NULL) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return PM3_EMALLOC; From 54586180537abbf17fe86ba87c51279d5d5da4f2 Mon Sep 17 00:00:00 2001 From: Shain Lakin Date: Wed, 23 Nov 2022 08:58:03 +0800 Subject: [PATCH 366/759] Added new script for modifying user memory in sector 0 and 1 on the NTAG I2C PLUS 2K tag. Can also be used to dump a sector to disk, and write a file to a sector. --- CHANGELOG.md | 1 + client/luascripts/hf_i2c_plus_2k_utils.lua | 310 +++++++++++++++++++++ 2 files changed, 311 insertions(+) create mode 100644 client/luascripts/hf_i2c_plus_2k_utils.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d57d2b09..d06091bab 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] + - Added luascript `hf_i2c_plus_2k_utils` - Script for dumping/modifying user memory of sectors 0 and 1 (@flamebarke) - Added `hf mfu esave` - saves emulator memory to mfu dump file (@DidierA) - Added luascript `hf_mfu_ntag` - Script for configuring NTAG216 configuration pages (@flamebarke) - Changed `hf mf hardnested` - a detection for static encrypted nonces (@iceman1001) diff --git a/client/luascripts/hf_i2c_plus_2k_utils.lua b/client/luascripts/hf_i2c_plus_2k_utils.lua new file mode 100644 index 000000000..1816feb46 --- /dev/null +++ b/client/luascripts/hf_i2c_plus_2k_utils.lua @@ -0,0 +1,310 @@ +local getopt = require('getopt') +local lib14a = require('read14a') +local cmds = require('commands') +local utils = require('utils') +local ansicolors = require('ansicolors') + +--- Commands +NTAG_I2C_PLUS_2K = '0004040502021503C859' +GET_VERSION = '60' +SELECT_SECTOR_PKT1 = 'C2FF' +SELECT_SECTOR0_PKT2 = '00000000' +SELECT_SECTOR1_PKT2 = '01000000' +READ_BLOCK = '30' +WRITE_BLOCK = 'A2' +ACK = '0A' +NAK = '00' +--- + + +--- Arguments +copyright = '' +author = 'Shain Lakin' +version = 'v1.0.0' +desc =[[ + +This script can be used to read blocks, write blocks, dump sectors, +or write a files hex bytes to sector 0 or 1 on the NTAG I2C PLUS 2K tag. + +]] + +example =[[ + + Read block 04 from sector 1: + script run hf_ntagi2c_plus2k -m r -s 1 -b 04 + + Write FFFFFFFF to block A0 sector 1: + script run hf_ntagi2c_plus2k -m w -s 1 -b A0 -d FFFFFFFF + + Dump sector 1 user memory to console and file: + script run hf_ntag12c_plus2k -m d -s 1 + + Write a files hex bytes to sector 1 starting at block 04: + script run hf_ntagi2c_plus2k -m f -s 1 -f data.txt + +]] +usage = [[ + + Read mode: + script run hf_ntagi2c_plus2k -m r -s -b + + Write mode: + script run hf_ntagi2c_plus2k -m w -s -b -d + + Dump mode: + script run hf_ntagi2c_plus2k -m d -s + + File mode: + script run hf_ntagi2c_plus2k -m f -s -f + +]] +arguments = [[ + -h this help + -m mode (r/w/f) + -b block (hex) + -f file + -s sector (0/1) + -d data (hex) +]] +--- + + +--- Help function +local function help() + + print(copyright) + print(author) + print(version) + print(desc) + print(ansicolors.cyan..'Usage'..ansicolors.reset) + print(usage) + print(ansicolors.cyan..'Arguments'..ansicolors.reset) + print(arguments) + print(ansicolors.cyan..'Example usage'..ansicolors.reset) + print(example) + +end +--- + + +--- Message function +local function msg(string) + print(ansicolors.magenta..string.rep('-',29)..ansicolors.reset) + print(ansicolors.cyan..string..ansicolors.reset) + print(ansicolors.magenta..string.rep('-',29)..ansicolors.reset) +end +--- + + +--- Error handling +local function warn(err) + + print(ansicolors.magenta.."ERROR:"..ansicolors.reset,err) + core.clearCommandBuffer() + return nil, err + +end +--- + + +--- Setup tx/rx +local function sendRaw(rawdata, options) + + local flags = lib14a.ISO14A_COMMAND.ISO14A_NO_DISCONNECT + + lib14a.ISO14A_COMMAND.ISO14A_RAW + + lib14a.ISO14A_COMMAND.ISO14A_APPEND_CRC + + local c = Command:newMIX{cmd = cmds.CMD_HF_ISO14443A_READER, + arg1 = flags, + arg2 = string.len(rawdata)/2, + data = rawdata} + + return c:sendMIX(options.ignore_response) +end +--- + + +--- Function to connect +local function connect() + core.clearCommandBuffer() + + info, err = lib14a.read(true, true) + if err then + lib14a.disconnect() + return error(err) + else + return info.uid + end + core.clearCommandBuffer() + +end +--- + + +--- Function to disconnect +local function disconnect() + core.clearCommandBuffer() + lib14a.disconnect() +end +--- + + +--- Function to get response data +local function getResponseData(usbpacket) + + local resp = Command.parse(usbpacket) + local len = tonumber(resp.arg1) * 2 + return string.sub(tostring(resp.data), 0, len); + +end +--- + + +--- Function to send raw bytes +local function send(payload) + + local usb, err = sendRaw(payload,{ignore_response = false}) + if err then return warn(err) end + return getResponseData(usb) + +end +--- + +--- Function to select sector +local function select_sector(sector) + send(SELECT_SECTOR_PKT1) + if sector == '0' then + send(SELECT_SECTOR0_PKT2) + elseif sector == '1' then + send(SELECT_SECTOR1_PKT2) + end +end +--- + +--- Function to write file to sector +local function filewriter(file,sector) + file_bytes = utils.ReadDumpFile(file) + len = string.len(file_bytes) / 8 + start_char = 1 + end_char = 8 + block_counter = 4 + -- NTAG_I2C_PLUS_2K:SECTOR_0:225,SECTOR_1:255 + end_block = 225 + connect() + select_sector(sector) + for count = 1, len do + block = file_bytes:sub(start_char, end_char) + data = send(WRITE_BLOCK..string.format("%02x",block_counter)..block) + print('[*] Writing bytes '..block..' to page '..string.format("%02x", block_counter)) + if data == ACK then + print(ansicolors.cyan..'[*] Received ACK, write successful'..ansicolors.reset) + else + print(ansicolors.magenta..'[!] Write failed'..ansicolors.reset) + end + start_char = start_char + 8 + end_char = end_char + 8 + block_counter = block_counter + 1 + if block_counter == end_block then + print(ansicolors.magenta..'[!] Not enough memory space!'..ansicolors.reset) + break + end + end + disconnect() +end +--- + +--- Function to dump user memory to console and disk +local function dump(sector,uid) + connect() + select_sector(sector) + counter = 0 + dest = uid..'.hex' + file = io.open(dest, 'a') + io.output(file) + print("\n[+] Dumping sector "..sector.."\n") + print(ansicolors.magenta..string.rep('--',16)..ansicolors.reset) + for count = 1, 64 do + result = send(READ_BLOCK..string.format("%02x", counter)) + print(ansicolors.cyan..result:sub(1,32)..ansicolors.reset) + io.write(result:sub(1,32)) + counter = counter + 4 + end + io.close(file) + print(ansicolors.magenta..string.rep('--',16)..ansicolors.reset) + print("\n[+] Memory dump saved to "..uid..".hex") + disconnect() +end +--- + + +--- Function to read and write blocks +local function exec(cmd, sector, block, bytes) + connect() + select_sector(sector) + if cmd == READ_BLOCK then + data = send(cmd..block) + msg(data:sub(1,8)) + elseif cmd == WRITE_BLOCK then + if bytes == 'NOP' then + err = '[!] You need to pass some data' + warn(err) + print(usage) + do return end + else + data = send(cmd..block..bytes) + if data == ACK then + print(ansicolors.cyan..'[+] Received ACK, write succesful'..ansicolors.reset) + elseif data ~= ACK then + print(ansicolors.magenta..'[!] Write failed'..ansicolors.reset) + end + end + end + disconnect() + return(data) +end +--- + + +--- Main +local function main(args) + + for o, a in getopt.getopt(args, 'm:b:s:d:f:h') do + if o == 'm' then mode = a end + if o == 'b' then block = a end + if o == 's' then sector = a end + if o == 'd' then bytes = a end + if o == 'f' then file = a end + if o == 'h' then return help() end + end + + uid = connect() + + connect() + version = send(GET_VERSION) + disconnect() + + if version == NTAG_I2C_PLUS_2K then + + if mode == 'r' then + print('\n[+] Reading sector '..sector..' block '..block) + exec(READ_BLOCK,sector,block,bytes) + elseif mode == 'w' then + print('\n[+] Writing '..bytes..' to sector '..sector..' block '..block) + exec(WRITE_BLOCK,sector,block,bytes) + elseif mode == 'f' then + filewriter(file,sector) + elseif mode == 'd' then + dump(sector,uid) + end + + else + return print(usage) + end + + if command == '' then return print(usage) end + +end +--- + + +main(args) \ No newline at end of file From 75ef73dd57861a4cabae15a68f134fc51688679b Mon Sep 17 00:00:00 2001 From: flamebarke <39644720+flamebarke@users.noreply.github.com> Date: Wed, 23 Nov 2022 09:09:37 +0800 Subject: [PATCH 367/759] Update hf_i2c_plus_2k_utils.lua Signed-off-by: flamebarke <39644720+flamebarke@users.noreply.github.com> --- client/luascripts/hf_i2c_plus_2k_utils.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/luascripts/hf_i2c_plus_2k_utils.lua b/client/luascripts/hf_i2c_plus_2k_utils.lua index 1816feb46..7e6b9b300 100644 --- a/client/luascripts/hf_i2c_plus_2k_utils.lua +++ b/client/luascripts/hf_i2c_plus_2k_utils.lua @@ -31,31 +31,31 @@ or write a files hex bytes to sector 0 or 1 on the NTAG I2C PLUS 2K tag. example =[[ Read block 04 from sector 1: - script run hf_ntagi2c_plus2k -m r -s 1 -b 04 + script run hf_i2c_plus_2k_utils -m r -s 1 -b 04 Write FFFFFFFF to block A0 sector 1: - script run hf_ntagi2c_plus2k -m w -s 1 -b A0 -d FFFFFFFF + script run hf_i2c_plus_2k_utils -m w -s 1 -b A0 -d FFFFFFFF Dump sector 1 user memory to console and file: - script run hf_ntag12c_plus2k -m d -s 1 + script run hf_i2c_plus_2k_utils -m d -s 1 Write a files hex bytes to sector 1 starting at block 04: - script run hf_ntagi2c_plus2k -m f -s 1 -f data.txt + script run hf_i2c_plus_2k_utils -m f -s 1 -f data.txt ]] usage = [[ Read mode: - script run hf_ntagi2c_plus2k -m r -s -b + script run hf_i2c_plus_2k_utils -m r -s -b Write mode: - script run hf_ntagi2c_plus2k -m w -s -b -d + script run hf_i2c_plus_2k_utils -m w -s -b -d Dump mode: - script run hf_ntagi2c_plus2k -m d -s + script run hf_i2c_plus_2k_utils -m d -s File mode: - script run hf_ntagi2c_plus2k -m f -s -f + script run hf_i2c_plus_2k_utils -m f -s -f ]] arguments = [[ @@ -307,4 +307,4 @@ end --- -main(args) \ No newline at end of file +main(args) From d4f08abec3780be115adbd81008ae0a759c41caa Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Wed, 23 Nov 2022 10:47:55 +0100 Subject: [PATCH 368/759] Change calloc() so it passes Widnows build test Code compiles under linux (not tested yet, I have no proxmark available right now) Previous commit fails windows build test with: src/cmdhfmfu.c: In function 'CmdHF14AMfuESave': src/cmdhfmfu.c:4220:19: error: array subscript 'mfu_dump_t[0]' is partly outside array bounds of 'mfu_dump_t[0]' [-Werror=array-bounds] 4220 | end = dump->pages ; | ^~ In function 'GetMfuDumpFromEMul', inlined from 'CmdHF14AMfuESave' at src/cmdhfmfu.c:4202:15: src/cmdhfmfu.c:4105:21: note: object of size 1076 allocated by 'calloc' 4105 | uint8_t *dump = calloc(MFU_MAX_BYTES + MFU_DUMP_PREFIX_LENGTH, sizeof(uint8_t)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- client/src/cmdhfmfu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 138cae25a..c3701a76d 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -4102,20 +4102,20 @@ int CmdHF14MfuNDEFRead(const char *Cmd) { // utility function. Retrieves emulator memory static int GetMfuDumpFromEMul(mfu_dump_t **buf) { - uint8_t *dump = calloc(MFU_MAX_BYTES + MFU_DUMP_PREFIX_LENGTH, sizeof(uint8_t)); + mfu_dump_t *dump = calloc(1, sizeof(mfu_dump_t)); if (dump == NULL) { PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); return PM3_EMALLOC; } PrintAndLogEx(INFO, "downloading from emulator memory"); - if (!GetFromDevice(BIG_BUF_EML, dump, sizeof(mfu_dump_t), 0, NULL, 0, NULL, 2500, false)) { + if (!GetFromDevice(BIG_BUF_EML, (uint8_t *)dump, MFU_MAX_BYTES + MFU_DUMP_PREFIX_LENGTH, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); free(dump); return PM3_ETIMEOUT; } - *buf = (mfu_dump_t *)dump ; + *buf = dump ; return PM3_SUCCESS ; } From 864b632a1992a56a6287907e926e412f8817abd2 Mon Sep 17 00:00:00 2001 From: Geonyeob Kim Date: Thu, 24 Nov 2022 00:54:47 +0900 Subject: [PATCH 369/759] typo --- client/src/cmdhffido.c | 6 +++--- client/src/cmdhfksx6924.c | 14 +++++++------- client/src/emv/cmdemv.c | 20 ++++++++++---------- doc/commands.json | 26 +++++++++++++------------- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/client/src/cmdhffido.c b/client/src/cmdhffido.c index d95923159..a00206c01 100644 --- a/client/src/cmdhffido.c +++ b/client/src/cmdhffido.c @@ -413,7 +413,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("a", "apdu", "Show APDU reqests and responses"), + arg_lit0("a", "apdu", "Show APDU requests and responses"), arg_lit0("v", "verbose", "Verbose mode"), arg_rem("default mode:", "dont-enforce-user-presence-and-sign"), arg_lit0("u", "user", "mode: enforce-user-presence-and-sign"), @@ -675,7 +675,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("a", "apdu", "Show APDU reqests and responses"), + arg_lit0("a", "apdu", "Show APDU requests and responses"), arg_litn("v", "verbose", 0, 2, "Verbose mode. vv - show full certificates data"), arg_lit0("t", "tlv", "Show DER certificate contents in TLV representation"), arg_lit0("c", "cbor", "Show CBOR decoded data"), @@ -794,7 +794,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("a", "apdu", "Show APDU reqests and responses"), + arg_lit0("a", "apdu", "Show APDU requests and responses"), arg_litn("v", "verbose", 0, 2, "Verbose mode. vv - show full certificates data"), arg_lit0("c", "cbor", "Show CBOR decoded data"), arg_lit0("l", "list", "Add CredentialId from json to allowList"), diff --git a/client/src/cmdhfksx6924.c b/client/src/cmdhfksx6924.c index d405459c9..1bbe45700 100644 --- a/client/src/cmdhfksx6924.c +++ b/client/src/cmdhfksx6924.c @@ -69,7 +69,7 @@ static int CmdHFKSX6924Balance(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("k", "keep", "keep field ON for next command"), - arg_lit0("a", "apdu", "show APDU reqests and responses"), + arg_lit0("a", "apdu", "Show APDU requests and responses"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -102,7 +102,7 @@ static int CmdHFKSX6924Info(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("k", "keep", "keep field ON for next command"), - arg_lit0("a", "apdu", "show APDU reqests and responses"), + arg_lit0("a", "apdu", "Show APDU requests and responses"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -224,7 +224,7 @@ static int CmdHFKSX6924Select(const char *Cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("a", "apdu", "show APDU reqests and responses"), + arg_lit0("a", "apdu", "Show APDU requests and responses"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -252,8 +252,8 @@ static int CmdHFKSX6924Initialize(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("k", "keep", "keep field ON for next command"), - arg_lit0("a", "apdu", "show APDU reqests and responses"), - arg_str1(NULL, NULL, "", NULL), + arg_lit0("a", "apdu", "Show APDU requests and responses"), + arg_str1(NULL, NULL, "", NULL), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -269,7 +269,7 @@ static int CmdHFKSX6924Initialize(const char *Cmd) { SetAPDULogging(APDULogging); if (datalen != 4) { - PrintAndLogEx(WARNING, "Mpda parameter must be 4 byte long (eg: 000003e8)"); + PrintAndLogEx(WARNING, "Mpda parameter must be 4 bytes long (eg: 000003e8)"); return PM3_EINVARG; } @@ -305,7 +305,7 @@ static int CmdHFKSX6924PRec(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("k", "keep", "keep field ON for next command"), - arg_lit0("a", "apdu", "show APDU reqests and responses"), + arg_lit0("a", "apdu", "Show APDU requests and responses"), arg_str1(NULL, NULL, "", NULL), arg_param_end }; diff --git a/client/src/emv/cmdemv.c b/client/src/emv/cmdemv.c index a855b672f..bf1cde60d 100644 --- a/client/src/emv/cmdemv.c +++ b/client/src/emv/cmdemv.c @@ -140,7 +140,7 @@ static int CmdEMVSearch(const char *Cmd) { arg_param_begin, arg_lit0("sS", "select", "Activate field and select card"), arg_lit0("kK", "keep", "Keep field ON for next command"), - arg_lit0("aA", "apdu", "Show APDU reqests and responses"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), arg_param_end @@ -196,7 +196,7 @@ static int CmdEMVPPSE(const char *Cmd) { arg_lit0("kK", "keep", "Keep field ON for next command"), arg_lit0("1", "pse", "PSE (1PAY.SYS.DDF01) mode"), arg_lit0("2", "ppse", "PPSE (2PAY.SYS.DDF01) mode (def)"), - arg_lit0("aA", "apdu", "Show APDU reqests and responses"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), arg_param_end @@ -255,7 +255,7 @@ static int CmdEMVGPO(const char *Cmd) { arg_lit0("kK", "keep", "Keep field ON for next command"), arg_lit0("pP", "params", "Load parameters from `emv_defparams.json` file for PDOLdata making from PDOL and parameters"), arg_lit0("mM", "make", "Make PDOLdata from PDOL (tag 9F38) and parameters (def: uses default parameters)"), - arg_lit0("aA", "apdu", "Show APDU reqests and responses"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), arg_strx0(NULL, NULL, "", "PDOLdata/PDOL"), @@ -362,7 +362,7 @@ static int CmdEMVReadRecord(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("kK", "keep", "Keep field ON for next command"), - arg_lit0("aA", "apdu", "Show APDU reqests and responses"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), arg_strx1(NULL, NULL, "", "", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"), arg_lit0("pP", "params", "Load parameters from `emv_defparams.json` file for CDOLdata making from CDOL and parameters"), arg_lit0("mM", "make", "Make CDOLdata from CDOL (tag 8C and 8D) and parameters (def: use default parameters)"), - arg_lit0("aA", "apdu", "Show APDU reqests and responses"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), arg_strx1(NULL, NULL, "", "CDOLdata/CDOL"), @@ -544,7 +544,7 @@ static int CmdEMVGenerateChallenge(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("kK", "keep", "Keep field ON for next command"), - arg_lit0("aA", "apdu", "Show APDU reqests and responses"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), arg_param_end }; @@ -598,7 +598,7 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) { arg_lit0("kK", "keep", "Keep field ON for next command"), arg_lit0("pP", "params", "Load parameters from `emv_defparams.json` file for DDOLdata making from DDOL and parameters"), arg_lit0("mM", "make", "Make DDOLdata from DDOL (tag 9F49) and parameters (def: use default parameters)"), - arg_lit0("aA", "apdu", "Show APDU reqests and responses"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), arg_lit0("tT", "tlv", "TLV decode results of selected applets"), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), arg_strx1(NULL, NULL, "", "DDOLdata/DDOL"), @@ -823,7 +823,7 @@ static int CmdEMVExec(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("sS", "select", "Activate field and select card"), - arg_lit0("aA", "apdu", "Show APDU reqests and responses"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), arg_lit0("tT", "tlv", "TLV decode results"), arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file"), arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE"), @@ -1448,7 +1448,7 @@ static int CmdEMVScan(const char *Cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("aA", "apdu", "Show APDU reqests and responses"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), arg_lit0("tT", "tlv", "TLV decode results"), arg_lit0("eE", "extract", "Extract TLV elements and fill Application Data"), arg_lit0("jJ", "jload", "Load transaction parameters from `emv_defparams.json` file"), @@ -1872,7 +1872,7 @@ static int CmdEMVRoca(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("tT", "selftest", "Self test"), - arg_lit0("aA", "apdu", "Show APDU reqests and responses"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), arg_param_end }; diff --git a/doc/commands.json b/doc/commands.json index c9ce72f8c..b2138ee11 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -761,7 +761,7 @@ "options": [ "-h, --help This help", "-k, -K, --keep Keep field ON for next command", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)" ], "usage": "emv challenge [-hkaw]" @@ -777,7 +777,7 @@ "options": [ "-h, --help This help", "-s, -S, --select Activate field and select card", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results", "-j, -J, --jload Load transaction parameters from `emv_defparams.json` file", "-f, -F, --forceaid Force search AID. Search AID instead of execute PPSE", @@ -807,7 +807,7 @@ "-d, -D, --decision Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested", "-p, -P, --params Load parameters from `emv_defparams.json` file for CDOLdata making from CDOL and parameters", "-m, -M, --make Make CDOLdata from CDOL (tag 8C and 8D) and parameters (def: use default parameters)", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " CDOLdata/CDOL" @@ -828,7 +828,7 @@ "-k, -K, --keep Keep field ON for next command", "-p, -P, --params Load parameters from `emv_defparams.json` file for PDOLdata making from PDOL and parameters", "-m, -M, --make Make PDOLdata from PDOL (tag 9F38) and parameters (def: uses default parameters)", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " PDOLdata/PDOL" @@ -857,7 +857,7 @@ "-k, -K, --keep Keep field ON for next command", "-p, -P, --params Load parameters from `emv_defparams.json` file for DDOLdata making from DDOL and parameters", "-m, -M, --make Make DDOLdata from DDOL (tag 9F49) and parameters (def: use default parameters)", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " DDOLdata/DDOL" @@ -899,7 +899,7 @@ "-k, -K, --keep Keep field ON for next command", "-1, --pse PSE (1PAY.SYS.DDF01) mode", "-2, --ppse PPSE (2PAY.SYS.DDF01) mode (def)", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)" ], @@ -916,7 +916,7 @@ "options": [ "-h, --help This help", "-k, -K, --keep Keep field ON for next command", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " Date: Thu, 24 Nov 2022 00:57:13 +0900 Subject: [PATCH 370/759] textual --- client/src/ksx6924/ksx6924core.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/src/ksx6924/ksx6924core.c b/client/src/ksx6924/ksx6924core.c index 2748ea044..12bff1664 100644 --- a/client/src/ksx6924/ksx6924core.c +++ b/client/src/ksx6924/ksx6924core.c @@ -114,17 +114,17 @@ MAKE_ENUM_CONST(Alg, uint8_t, // KSX6924LookupTMoneyIDCenter MAKE_ENUM_CONST(TMoneyIDCenter, uint8_t, -{ 0x00, "reserved" }, +{ 0x00, "Reserved" }, { 0x01, "Korea Financial Telecommunications and Clearings Institute" }, { 0x02, "A-Cash" }, { 0x03, "Mybi" }, - +{ 0x04, "Reserved" }, { 0x05, "V-Cash" }, { 0x06, "Mondex Korea" }, { 0x07, "Korea Expressway Corporation" }, -{ 0x08, "Korea Smart Card Corporation" }, +{ 0x08, "Tmoney Co., Ltd." }, { 0x09, "KORAIL Networks" }, - +{ 0x0a, "Reserved" }, { 0x0b, "EB Card Corporation" }, { 0x0c, "Seoul Bus Transport Association" }, { 0x0d, "Cardnet" }, @@ -165,17 +165,17 @@ MAKE_ENUM_CONST(TMoneyTCode, uint8_t, // KSX6924LookupTMoneyCCode MAKE_ENUM_CONST(TMoneyCCode, uint8_t, { 0x00, "None" }, -{ 0x01, "KB Kookmin Bank" }, -{ 0x02, "Nonghyup Bank" }, +{ 0x01, "KB Card" }, +{ 0x02, "NH Card" }, { 0x03, "Lotte Card" }, { 0x04, "BC Card" }, { 0x05, "Samsung Card" }, -{ 0x06, "Shinhan Bank" }, +{ 0x06, "Shinhan Card" }, { 0x07, "Citibank Korea" }, { 0x08, "Korea Exchange Bank" }, -{ 0x09, "Woori" }, +{ 0x09, "Woori Card" }, { 0x0a, "Hana SK Card" }, -{ 0x0b, "Hyundai Capital Services" }, +{ 0x0b, "Hyundai Card" }, ); static const char *KSX6924_UNKNOWN = "Unknown"; From 878d123a78c4f08df62c66824605da74487a0f24 Mon Sep 17 00:00:00 2001 From: Geonyeob Kim Date: Thu, 24 Nov 2022 00:59:42 +0900 Subject: [PATCH 371/759] parse the `hf ksx6924 init` response --- client/src/cmdhfksx6924.c | 36 +++++++++------- client/src/ksx6924/ksx6924core.c | 71 +++++++++++++++++++++++++++++++- client/src/ksx6924/ksx6924core.h | 20 ++++++++- client/src/pm3line_vocabulory.h | 8 ++-- doc/commands.json | 71 ++++++++++++++++---------------- doc/commands.md | 8 ++-- 6 files changed, 155 insertions(+), 59 deletions(-) diff --git a/client/src/cmdhfksx6924.c b/client/src/cmdhfksx6924.c index 1bbe45700..6064a7611 100644 --- a/client/src/cmdhfksx6924.c +++ b/client/src/cmdhfksx6924.c @@ -245,9 +245,9 @@ static int CmdHFKSX6924Select(const char *Cmd) { static int CmdHFKSX6924Initialize(const char *Cmd) { CLIParserContext *ctx; - CLIParserInit(&ctx, "hf ksx6924 initialize", - "Perform transaction initialization (mpda)", - "hf ksx6924 initialize 000003e8 -> mpda\n"); + CLIParserInit(&ctx, "hf ksx6924 init", + "Perform transaction initialization with Mpda (Money of Purchase Transaction)", + "hf ksx6924 init 000003e8 -> Mpda\n"); void *argtable[] = { arg_param_begin, @@ -278,15 +278,23 @@ static int CmdHFKSX6924Initialize(const char *Cmd) { goto end; } - PrintAndLogEx(SUCCESS, "Initialize Card : Mpda -> %02X %02X %02X %02X", data[0], data[1], data[2], data[3]); - - uint8_t response[25] = {0}; - if (KSX6924InitializeCard(data[0], data[1], data[2], data[3], response)) { - PrintAndLogEx(SUCCESS, "Response : %s", sprint_hex(response, sizeof(response))); - } else { - PrintAndLogEx(FAILED, "Initialize Card Error"); + uint8_t resp[APDU_RES_LEN] = {0}; + size_t resp_len = 0; + if (KSX6924InitializeCard(data[0], data[1], data[2], data[3], resp, &resp_len) == false) { + goto end; } + uint8_t *r = resp; + struct ksx6924_initialize_card_response initCardResponse; + bool ret = KSX6924ParseInitializeCardResponse(r, resp_len, &initCardResponse); + + if (!ret) { + PrintAndLogEx(FAILED, "Error parsing KS X 6924 initialize card response"); + goto end; + } + + KSX6924PrintInitializeCardResponse(&initCardResponse); + end: if (keep == false) { DropField(); @@ -348,11 +356,11 @@ end: static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"balance", CmdHFKSX6924Balance, IfPm3Iso14443a, "Get current purse balance"}, - {"info", CmdHFKSX6924Info, IfPm3Iso14443a, "Get info about a KS X 6924 (T-Money, Snapper+) transit card"}, - {"initialize", CmdHFKSX6924Initialize, IfPm3Iso14443a, "Perform transaction initialization (Mpda)"}, - {"prec", CmdHFKSX6924PRec, IfPm3Iso14443a, "Send proprietary get record command (CLA=90, INS=4C)"}, {"select", CmdHFKSX6924Select, IfPm3Iso14443a, "Select application, and leave field up"}, + {"info", CmdHFKSX6924Info, IfPm3Iso14443a, "Get info about a KS X 6924 (T-Money, Snapper+) transit card"}, + {"balance", CmdHFKSX6924Balance, IfPm3Iso14443a, "Get current purse balance"}, + {"init", CmdHFKSX6924Initialize, IfPm3Iso14443a, "Perform transaction initialization with Mpda"}, + {"prec", CmdHFKSX6924PRec, IfPm3Iso14443a, "Send proprietary get record command (CLA=90, INS=4C)"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/ksx6924/ksx6924core.c b/client/src/ksx6924/ksx6924core.c index 12bff1664..b04f87358 100644 --- a/client/src/ksx6924/ksx6924core.c +++ b/client/src/ksx6924/ksx6924core.c @@ -66,6 +66,16 @@ typedef struct { uint8_t rfu[8]; } PACKED _ksx6924_internal_purse_info_t; +typedef struct { + uint8_t ALGep; + uint8_t VKep; + uint8_t BALep[4]; // uint32_t big-endian + uint8_t IDcenter; + uint8_t IDep[8]; // bcd + uint8_t NTep[4]; + uint8_t Sign1[4]; +} PACKED _ksx6924_initialize_card_response_t; + // Declares a structure for simple enums. #define MAKE_ENUM_TYPE(KEY_TYPE) \ struct _ksx6924_enum_ ## KEY_TYPE { \ @@ -446,7 +456,7 @@ bool KSX6924GetBalance(uint32_t *result) { /** * Perform transaction initialization. */ -bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t mpda4, uint8_t *result) { +bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t mpda4, uint8_t *result, size_t *result_len) { if (result == NULL) { return false; @@ -472,9 +482,68 @@ bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t //*result = ntohl(*(uint32_t*)(arr)); memcpy(result, arr, rlen + 2); // skip 2 sw bytes + memcpy(result_len, &rlen, sizeof(size_t)); return true; } +/** + * Parses Initialize Card response + */ +bool KSX6924ParseInitializeCardResponse(const uint8_t *initCardResponse, size_t resp_len, struct ksx6924_initialize_card_response *ret) { + + memset(ret, 0, sizeof(struct ksx6924_initialize_card_response)); + + if (resp_len != sizeof(_ksx6924_initialize_card_response_t)) { + // Invalid size! + PrintAndLogEx(FAILED, "Expected %ld bytes, got %ld\n", sizeof(_ksx6924_initialize_card_response_t), resp_len); + return false; + } + + const _ksx6924_initialize_card_response_t *internalInitCardResponse = (const _ksx6924_initialize_card_response_t *)initCardResponse; + + // Simple copies + ret->ALGep = internalInitCardResponse->ALGep; + ret->VKep = internalInitCardResponse->VKep; + ret->IDcenter = internalInitCardResponse->IDcenter; + + // Fields that need rewriting + hex_to_buffer(ret->IDep, internalInitCardResponse->IDep, + sizeof(internalInitCardResponse->IDep), + sizeof(ret->IDep) - 1, + 0, // min_str_len + 0, // spaces_between + false // uppercase + ); + + ret->BALep = MemBeToUint4byte((uint8_t *)internalInitCardResponse->BALep); + ret->NTep = MemBeToUint4byte((uint8_t *)internalInitCardResponse->NTep); + + memcpy(&ret->Sign1, &internalInitCardResponse->Sign1, 4); + + // TODO + return true; +}; + +/** + * Prints out a Initialize Card response + */ +void KSX6924PrintInitializeCardResponse(const struct ksx6924_initialize_card_response *response) { + + if (response == NULL) { + return; + } + + PrintAndLogEx(INFO, "--- " _CYAN_("KS X 6924 Initialize Card Response") " ---------------------------"); + PrintAndLogEx(INFO, ""); + PrintAndLogEx(INFO, " ALGep (Algorithm Identifier)........ %02x ( %s )", response->ALGep, KSX6924LookupAlg(response->ALGep, KSX6924_UNKNOWN)); + PrintAndLogEx(INFO, " VKep (Version of Key) .............. %02x", response->VKep); + PrintAndLogEx(INFO, " BALep (Balance...................... %" PRIu32, response->BALep); + PrintAndLogEx(INFO, " IDcenter (Issuer ID) ............... %02x ( %s )", response->IDcenter, KSX6924LookupTMoneyIDCenter(response->IDcenter, KSX6924_UNKNOWN)); + PrintAndLogEx(INFO, " IDep (Card number) ................. %s", response->IDep); + PrintAndLogEx(INFO, " NTep (Number of Transaction + 1) ... %" PRIu32, response->NTep); + PrintAndLogEx(INFO, " Sign1 .............................. %s", sprint_hex(response->Sign1, sizeof(response->Sign1))); + PrintAndLogEx(INFO, ""); +} /** * Issues a proprietary "get record" command (CLA=90, INS=4C). diff --git a/client/src/ksx6924/ksx6924core.h b/client/src/ksx6924/ksx6924core.h index c207628c8..96f597ec1 100644 --- a/client/src/ksx6924/ksx6924core.h +++ b/client/src/ksx6924/ksx6924core.h @@ -53,6 +53,18 @@ struct ksx6924_purse_info { uint8_t rfu[8]; }; +// Convenience structure for representing purse information. Actual on-card +// format is in _ksx6924_initialize_card_response_t. +struct ksx6924_initialize_card_response { + uint8_t ALGep; + uint8_t VKep; + uint32_t BALep; + uint8_t IDcenter; + uint8_t IDep[17]; // hex digits + null terminator + uint32_t NTep; + uint8_t Sign1[4]; +}; + // Get card type description const char *KSX6924LookupCardType(uint8_t key, const char *defaultValue); @@ -94,7 +106,13 @@ bool KSX6924TrySelect(void); bool KSX6924GetBalance(uint32_t *result); // Perform transaction initialization. -bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t mpda4, uint8_t *result); +bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t mpda4, uint8_t *result, size_t *result_len); + +// Parses Initialize Card response +bool KSX6924ParseInitializeCardResponse(const uint8_t *initCardResponse, size_t resp_len, struct ksx6924_initialize_card_response *ret); + +// Prints out a Initialize Card response +void KSX6924PrintInitializeCardResponse(const struct ksx6924_initialize_card_response *response); // Proprietary get record command. Function unknown. // result must be 10 bytes long. diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 6d348e667..a76bedddb 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -244,11 +244,11 @@ const static vocabulory_t vocabulory[] = { { 1, "hf gallagher diversifykey" }, { 1, "hf gallagher decode" }, { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 initialize" }, - { 0, "hf ksx6924 prec" }, { 0, "hf ksx6924 select" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 init" }, + { 0, "hf ksx6924 prec" }, { 1, "hf jooki help" }, { 0, "hf jooki clone" }, { 1, "hf jooki decode" }, diff --git a/doc/commands.json b/doc/commands.json index b2138ee11..1bd9422a4 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -3390,20 +3390,6 @@ ], "usage": "hf jooki sim [-h] [-b ]" }, - "hf ksx6924 balance": { - "command": "hf ksx6924 balance", - "description": "Gets the current purse balance", - "notes": [ - "hf ksx6924 balance" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-k, --keep keep field ON for next command", - "-a, --apdu show APDU reqests and responses" - ], - "usage": "hf ksx6924 balance [-hka]" - }, "hf ksx6924 help": { "command": "hf ksx6924 help", "description": "help This help", @@ -3412,6 +3398,19 @@ "options": [], "usage": "" }, + "hf ksx6924 select": { + "command": "hf ksx6924 select", + "description": "Selects KS X 6924 application, and leaves field up", + "notes": [ + "hf ksx6924 select" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-a, --apdu Show APDU requests and responses" + ], + "usage": "hf ksx6924 select [-ha]" + }, "hf ksx6924 info": { "command": "hf ksx6924 info", "description": "Get info about a KS X 6924 transit card. This application is used by T-Money (South Korea) and Snapper+ (Wellington, New Zealand).", @@ -3422,23 +3421,37 @@ "options": [ "-h, --help This help", "-k, --keep keep field ON for next command", - "-a, --apdu show APDU reqests and responses" + "-a, --apdu Show APDU requests and responses" ], "usage": "hf ksx6924 info [-hka]" }, - "hf ksx6924 initialize": { - "command": "hf ksx6924 initialize", - "description": "Perform transaction initialization (mpda)", + "hf ksx6924 balance": { + "command": "hf ksx6924 balance", + "description": "Gets the current purse balance", "notes": [ - "hf ksx6924 initialize 000003e8 -> mpda" + "hf ksx6924 balance" ], "offline": false, "options": [ "-h, --help This help", "-k, --keep keep field ON for next command", - "-a, --apdu show APDU reqests and responses" + "-a, --apdu Show APDU requests and responses" ], - "usage": "hf ksx6924 initialize [-hka] " + "usage": "hf ksx6924 balance [-hka]" + }, + "hf ksx6924 init": { + "command": "hf ksx6924 init", + "description": "Perform transaction initialization (mpda)", + "notes": [ + "hf ksx6924 init 000003e8 -> Mpda" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-k, --keep keep field ON for next command", + "-a, --apdu Show APDU requests and responses" + ], + "usage": "hf ksx6924 init [-hka] " }, "hf ksx6924 prec": { "command": "hf ksx6924 prec", @@ -3450,23 +3463,11 @@ "options": [ "-h, --help This help", "-k, --keep keep field ON for next command", - "-a, --apdu show APDU reqests and responses" + "-a, --apdu Show APDU requests and responses" ], "usage": "hf ksx6924 prec [-hka] " }, - "hf ksx6924 select": { - "command": "hf ksx6924 select", - "description": "Selects KS X 6924 application, and leaves field up", - "notes": [ - "hf ksx6924 select" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-a, --apdu show APDU reqests and responses" - ], - "usage": "hf ksx6924 select [-ha]" - }, + "hf legic crc": { "command": "hf legic crc", "description": "Calculates the legic crc8/crc16 on the given data", diff --git a/doc/commands.md b/doc/commands.md index 498d62b62..e5bb95f47 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -367,11 +367,11 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`hf ksx6924 help `|Y |`This help` -|`hf ksx6924 balance `|N |`Get current purse balance` -|`hf ksx6924 info `|N |`Get info about a KS X 6924 (T-Money, Snapper+) transit card` -|`hf ksx6924 initialize `|N |`Perform transaction initialization (Mpda)` -|`hf ksx6924 prec `|N |`Send proprietary get record command (CLA=90, INS=4C)` |`hf ksx6924 select `|N |`Select application, and leave field up` +|`hf ksx6924 info `|N |`Get info about a KS X 6924 (T-Money, Snapper+) transit card` +|`hf ksx6924 balance `|N |`Get current purse balance` +|`hf ksx6924 init `|N |`Perform transaction initialization with Mpda (Money of Purchase Transaction)` +|`hf ksx6924 prec `|N |`Send proprietary get record command (CLA=90, INS=4C)` ### hf jooki From 1adec4dfb27961790f949acf0225aae11f7e84b2 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Thu, 24 Nov 2022 03:16:58 +0100 Subject: [PATCH 372/759] Fix overflow in SPI memory when writing default key dictionnaries. Boundaries were defined in the memory layout but weren't enforced by the client, causing an overflow when trying to load a dictionnary that was too big. It's too hard to enforce it on the ARM side as the command is a generic write. Now that limits are defined, also outputs them as part of the `hw status` command. --- armsrc/flashmem.c | 6 +++--- client/src/cmdflashmem.c | 27 ++++++++++++++++++--------- include/pmflash.h | 12 +++++++++--- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index 426540143..ba882eaa7 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -594,7 +594,7 @@ void Flashmem_print_info(void) { if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); if (num != 0xFFFF && num != 0x0) - Dbprintf(" Mifare.................. "_YELLOW_("%d")" keys", num); + Dbprintf(" Mifare.................. "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_MF_KEYS_MAX); } Flash_CheckBusy(BUSY_TIMEOUT); @@ -602,7 +602,7 @@ void Flashmem_print_info(void) { if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); if (num != 0xFFFF && num != 0x0) - Dbprintf(" T55x7................... "_YELLOW_("%d")" keys", num); + Dbprintf(" T55x7................... "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_T55XX_KEYS_MAX); } Flash_CheckBusy(BUSY_TIMEOUT); @@ -610,7 +610,7 @@ void Flashmem_print_info(void) { if (isok == 2) { num = ((keysum[1] << 8) | keysum[0]); if (num != 0xFFFF && num != 0x0) - Dbprintf(" iClass.................. "_YELLOW_("%d")" keys", num); + Dbprintf(" iClass.................. "_YELLOW_("%d")" / "_GREEN_("%d")" keys", num, DEFAULT_ICLASS_KEYS_MAX); } FlashStop(); diff --git a/client/src/cmdflashmem.c b/client/src/cmdflashmem.c index 97126ad9b..f01531d55 100644 --- a/client/src/cmdflashmem.c +++ b/client/src/cmdflashmem.c @@ -204,19 +204,23 @@ static int CmdFlashMemLoad(const char *Cmd) { size_t datalen = 0; uint32_t keycount = 0; int res = 0; + uint8_t keylen = 0; uint8_t *data = calloc(FLASH_MEM_MAX_SIZE, sizeof(uint8_t)); switch (d) { case DICTIONARY_MIFARE: offset = DEFAULT_MF_KEYS_OFFSET; - res = loadFileDICTIONARY(filename, data + 2, &datalen, 6, &keycount); + keylen = 6; + res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount); if (res || !keycount) { free(data); return PM3_EFILE; } // limited space on flash mem - if (keycount > 0xFFFF) - keycount &= 0xFFFF; + if (keycount > DEFAULT_MF_KEYS_MAX) { + keycount = DEFAULT_MF_KEYS_MAX; + datalen = keycount * keylen; + } data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; @@ -224,14 +228,17 @@ static int CmdFlashMemLoad(const char *Cmd) { break; case DICTIONARY_T55XX: offset = DEFAULT_T55XX_KEYS_OFFSET; - res = loadFileDICTIONARY(filename, data + 2, &datalen, 4, &keycount); + keylen = 4; + res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount); if (res || !keycount) { free(data); return PM3_EFILE; } // limited space on flash mem - if (keycount > 0xFFFF) - keycount &= 0xFFFF; + if (keycount > DEFAULT_T55XX_KEYS_MAX) { + keycount = DEFAULT_T55XX_KEYS_MAX; + datalen = keycount * keylen; + } data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; @@ -239,14 +246,16 @@ static int CmdFlashMemLoad(const char *Cmd) { break; case DICTIONARY_ICLASS: offset = DEFAULT_ICLASS_KEYS_OFFSET; - res = loadFileDICTIONARY(filename, data + 2, &datalen, 8, &keycount); + res = loadFileDICTIONARY(filename, data + 2, &datalen, keylen, &keycount); if (res || !keycount) { free(data); return PM3_EFILE; } // limited space on flash mem - if (keycount > 0xFFFF) - keycount &= 0xFFFF; + if (keycount > DEFAULT_ICLASS_KEYS_MAX) { + keycount = DEFAULT_ICLASS_KEYS_MAX; + datalen = keycount * keylen; + } data[0] = (keycount >> 0) & 0xFF; data[1] = (keycount >> 8) & 0xFF; diff --git a/include/pmflash.h b/include/pmflash.h index 58bf2eb46..78e402ade 100644 --- a/include/pmflash.h +++ b/include/pmflash.h @@ -65,17 +65,23 @@ // Reserved space for T55XX PWD = 4 kb #ifndef DEFAULT_T55XX_KEYS_OFFSET -# define DEFAULT_T55XX_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x3000) +# define DEFAULT_T55XX_KEYS_LEN (0x1000) +# define DEFAULT_T55XX_KEYS_OFFSET (T55XX_CONFIG_OFFSET - DEFAULT_T55XX_KEYS_LEN) +# define DEFAULT_T55XX_KEYS_MAX ((DEFAULT_T55XX_KEYS_LEN - 2) / 4) #endif // Reserved space for iClass keys = 4 kb #ifndef DEFAULT_ICLASS_KEYS_OFFSET -# define DEFAULT_ICLASS_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x4000) +# define DEFAULT_ICLASS_KEYS_LEN (0x1000) +# define DEFAULT_ICLASS_KEYS_OFFSET (DEFAULT_T55XX_KEYS_OFFSET - DEFAULT_ICLASS_KEYS_LEN) +# define DEFAULT_ICLASS_KEYS_MAX ((DEFAULT_ICLASS_KEYS_LEN - 2) / 8) #endif // Reserved space for MIFARE Keys = 8 kb #ifndef DEFAULT_MF_KEYS_OFFSET -# define DEFAULT_MF_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x6000) +# define DEFAULT_MF_KEYS_LEN (0x2000) +# define DEFAULT_MF_KEYS_OFFSET (DEFAULT_ICLASS_KEYS_OFFSET - DEFAULT_MF_KEYS_LEN) +# define DEFAULT_MF_KEYS_MAX ((DEFAULT_MF_KEYS_LEN - 2) / 6) #endif // RDV40, validation structure to help identifying that client/firmware is talking with RDV40 From ba83c26c1eab8ba311ef43ade88bb36e1f4e4af7 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Thu, 24 Nov 2022 09:35:22 +0100 Subject: [PATCH 373/759] Add one more sector for Mifare keys on SPI flash. This is a breaking change and after firmware upgrade, dictionnaries should be loaded into flash again to ensure they're valid. --- include/pmflash.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/pmflash.h b/include/pmflash.h index 78e402ade..c3d00594a 100644 --- a/include/pmflash.h +++ b/include/pmflash.h @@ -28,7 +28,7 @@ // 0x3E000 - 1 4kb sector = settings // 0x3D000 - 1 4kb sector = default T55XX keys dictionary // 0x3B000 - 1 4kb sector = default ICLASS keys dictionary -// 0x39000 - 2 4kb sectors = default MFC keys dictionary +// 0x38000 - 3 4kb sectors = default MFC keys dictionary // #ifndef FLASH_MEM_BLOCK_SIZE # define FLASH_MEM_BLOCK_SIZE 256 @@ -79,7 +79,7 @@ // Reserved space for MIFARE Keys = 8 kb #ifndef DEFAULT_MF_KEYS_OFFSET -# define DEFAULT_MF_KEYS_LEN (0x2000) +# define DEFAULT_MF_KEYS_LEN (0x3000) # define DEFAULT_MF_KEYS_OFFSET (DEFAULT_ICLASS_KEYS_OFFSET - DEFAULT_MF_KEYS_LEN) # define DEFAULT_MF_KEYS_MAX ((DEFAULT_MF_KEYS_LEN - 2) / 6) #endif From 5bf0200b0260501de3cb1bfccbc8487f03a72f07 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Thu, 24 Nov 2022 09:37:02 +0100 Subject: [PATCH 374/759] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d06091bab..bc52d4c85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - Added `hf mf gload, gsave, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) + - Fixed SPI flash overflow when loading dictionnaries into flash. Breaking change: added 1 more sector for Mifare - dictionnaries should be loaded again (@jmichelp) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) From 8da4da6aa53bf11a017d40e2774223549540512c Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Thu, 24 Nov 2022 09:40:34 +0100 Subject: [PATCH 375/759] Also update comment about total size for Mifare keys storage. --- include/pmflash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pmflash.h b/include/pmflash.h index c3d00594a..f0deac507 100644 --- a/include/pmflash.h +++ b/include/pmflash.h @@ -77,7 +77,7 @@ # define DEFAULT_ICLASS_KEYS_MAX ((DEFAULT_ICLASS_KEYS_LEN - 2) / 8) #endif -// Reserved space for MIFARE Keys = 8 kb +// Reserved space for MIFARE Keys = 12 kb #ifndef DEFAULT_MF_KEYS_OFFSET # define DEFAULT_MF_KEYS_LEN (0x3000) # define DEFAULT_MF_KEYS_OFFSET (DEFAULT_ICLASS_KEYS_OFFSET - DEFAULT_MF_KEYS_LEN) From 9a0427d4d285b1f902f4327d538212a0378a7a8e Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Fri, 25 Nov 2022 10:13:33 +0100 Subject: [PATCH 376/759] Add Magic Gen4 GTU detection and symbols for Gen4 GTU protocol. --- CHANGELOG.md | 1 + armsrc/mifarecmd.c | 25 +++++++++++++++++++++++-- client/src/mifare/mifarehost.c | 3 +++ doc/magic_cards_notes.md | 19 +++++++++++++++++-- include/protocols.h | 19 +++++++++++++++++++ 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d06091bab..3712290e5 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] + - Added detection of magic Gen4 GTU (@DidierA) - Added luascript `hf_i2c_plus_2k_utils` - Script for dumping/modifying user memory of sectors 0 and 1 (@flamebarke) - Added `hf mfu esave` - saves emulator memory to mfu dump file (@DidierA) - Added luascript `hf_mfu_ntag` - Script for configuring NTAG216 configuration pages (@flamebarke) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 922cd674d..f5e649a2a 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2356,6 +2356,7 @@ void MifareCIdent(bool is_mfc) { uint8_t rats[4] = { ISO14443A_CMD_RATS, 0x80, 0x31, 0x73 }; uint8_t rdblf0[4] = { ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f}; uint8_t rdbl00[4] = { ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8}; + uint8_t gen4GetConf[8] = { GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0}; uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); uint8_t *uid = BigBuf_malloc(10); @@ -2388,6 +2389,26 @@ void MifareCIdent(bool is_mfc) { int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { + + // Check for Magic Gen4 GTU with default password : + // Get config should return 30 bytes. + AddCrc14A(gen4GetConf, sizeof(gen4GetConf) - 2); + ReaderTransmit(gen4GetConf, sizeof(gen4GetConf), NULL); + res = ReaderReceive(buf, par); + if (res == 32) { + isGen = MAGIC_GEN_4GTU; + goto OUT; + } + } + + // reset card + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(40); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + + res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); + if (res == 2) { + if (cuid == 0xAA55C396) { isGen = MAGIC_GEN_UNFUSED; goto OUT; @@ -2746,7 +2767,7 @@ void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags) { iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout } - uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, 0xCE, blockno, + uint8_t cmd[] = { GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_READ, blockno, 0x00, 0x00 }; @@ -2822,7 +2843,7 @@ void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t work iso14a_set_timeout(13560000 / 1000 / (8 * 16) * 1000); // 2 seconds timeout } - uint8_t cmd[] = { 0xCF, 0x00, 0x00, 0x00, 0x00, 0xCD, blockno, + uint8_t cmd[] = { GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_WRITE, blockno, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 7a927d5ed..917d84244 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1408,6 +1408,9 @@ int detect_mf_magic(bool is_mfc) { case MAGIC_GEN_3: PrintAndLogEx(SUCCESS, "Magic capabilities : possibly " _GREEN_("Gen 3 / APDU")); break; + case MAGIC_GEN_4GTU: + PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Gen 4 GTU")); + break; case MAGIC_GEN_UNFUSED: PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Write Once / FUID")); break; diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 9291fdec5..7b494d65c 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -998,9 +998,14 @@ Can emulate MIFARE Classic, Ultralight/NTAG families, 14b UID & App Data ### Identify ^[Top](#top) ^^[Gen4](#g4top) -👉 **TODO** Tag doesn't get identified correctly by latest Proxmark3 client (it might get mislabeled as MFC Gen2/CUID, Gen3/APDU or NTAG21x Modifiable, depending on configured UID/ATQA/SAK/ATS) +👉 **TODO** If the password is not default, Tag doesn't get identified correctly by latest Proxmark3 client (it might get mislabeled as MFC Gen2/CUID, Gen3/APDU or NTAG21x Modifiable, depending on configured UID/ATQA/SAK/ATS) -One can identify manually such card if the password is still the default one, with the command to get the current configuration: +``` +hf 14a info +[+] Magic capabilities : Gen 4 GTU +``` + +The card will be identified only if the password is the default one. One can identify manually such card if the password is still the default one, with the command to get the current configuration: ``` hf 14a raw -s -c -t 1000 CF00000000C6 ``` @@ -1108,6 +1113,14 @@ Default ``: `00000000` ``` # view contents of tag memory: hf mf gview +# Read a specific block via backdoor command: +hf mf ggetblk +# Write a specific block via backdoor command: +hf mf gsetblk +# Load dump to tag: +hf mf gload +# Save dump from tag: +hf mf gsave ``` 👉 **TODO** `hf mf gview` is currently missing Ultralight memory maps @@ -1120,6 +1133,8 @@ hf 14a raw -s -c -t 1000 CF00000000CE02 ... ``` +👉 **TODO** In Mifare Ultralight / NTAG mode, the special writes (option -s, -e, -r) do not apply. Use `script run hf_mf_ultimatecard` for UID and signature, and `hf mfu wrbl` for PWD and PACK. + ### Change ATQA / SAK ^[Top](#top) ^^[Gen4](#g4top) diff --git a/include/protocols.h b/include/protocols.h index 41ba5e1c5..563938f52 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -252,6 +252,25 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MAGIC_SUPER 6 #define MAGIC_NTAG21X 7 #define MAGIC_GEN_3 8 +#define MAGIC_GEN_4GTU 9 + +// Commands for configuration of Gen4 GTU cards. +// see https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/magic_cards_notes.md +#define GEN_4GTU_CMD 0xCF // Prefix for all commands, followed by pasword (4b) +#define GEN_4GTU_SHADOW 0x32 // Configure GTU shadow mode +#define GEN_4GTU_ATS 0x34 // Configure ATS +#define GEN_4GTU_ATQA 0x35 // Configure ATQA/SAK (swap ATQA bytes) +#define GEN_4GTU_UIDLEN 0x68 // Configure UID length +#define GEN_4GTU_ULEN 0x69 // (De)Activate Ultralight mode +#define GEN_4GTU_ULMODE 0x6A // Select Ultralight mode +#define GEN_4GTU_GETCNF 0xC6 // Dump configuration +#define GEN_4GTU_TEST 0xCC // Factory test, returns 6666 +#define GEN_4GTU_WRITE 0xCD // Backdoor write 16b block +#define GEN_4GTU_READ 0xCE // Backdoor read 16b block +#define GEN_4GTU_SETCNF 0xF0 // Configure all params in one cmd +#define GEN_4GTU_FUSCNF 0xF1 // Configure all params in one cmd and fuse the configuration permanently +#define GEN_4GTU_CHPWD 0xFE // change password + /** 06 00 = INITIATE 0E xx = SELECT ID (xx = Chip-ID) From c54db094cd70d62f6b7cbcc395903fea87813495 Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Fri, 25 Nov 2022 10:16:24 +0100 Subject: [PATCH 377/759] hf_mf_ultimatecard: '-w 0' now formats whole Mifare classic 4k --- client/luascripts/hf_mf_ultimatecard.lua | 158 ++++++++++++----------- 1 file changed, 86 insertions(+), 72 deletions(-) diff --git a/client/luascripts/hf_mf_ultimatecard.lua b/client/luascripts/hf_mf_ultimatecard.lua index e28dbdd08..b9011c36f 100644 --- a/client/luascripts/hf_mf_ultimatecard.lua +++ b/client/luascripts/hf_mf_ultimatecard.lua @@ -228,7 +228,6 @@ local function read_config() if ulmode == '03' then versionstr = 'Ultralight' elseif ulmode == '02' then versionstr = 'Ultralight-C' elseif cversion == '0004030101000B03' then versionstr = 'UL EV1 48b' - elseif cversion == '0004030101000B03' then versionstr = 'UL EV1 48b' elseif cversion == '0004030101000E03' then versionstr = 'UL EV1 128b' elseif cversion == '0004040101000B03' then versionstr = 'NTAG 210' elseif cversion == '0004040101000E03' then versionstr = 'NTAG 212' @@ -845,86 +844,101 @@ local function set_type(tagtype) end end --- +-- returns true if b is the index of a sector trailer +local function mfIsSectorTrailer(b) + n=b+1 + if (n < 32*4 ) then + if (n % 4 == 0) then return true + else return false + end + end + + if (n % 16 == 0) then return true + end + + return false +end +--- -- wipe tag local function wipe(wtype) local info = connect() if not info then return false, "Can't select card" end if wtype == '0' then - print('Starting Mifare Wipe') + print('Starting Mifare Wipe') send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000800") send("CF".._key.."CD000102030404080400000000000000BEAF") - local err, msg, resp - local cmd_empty = 'CF'.._key..'CD%02X00000000000000000000000000000000' - local cmd_cfg1 = 'CF'.._key..'CD%02XFFFFFFFFFFFFFF078069FFFFFFFFFFFF' - for b = 1, 0xFB do - if b == 0x03 or b == 0x07 or b == 0x0B or b == 0x0F or b == 0x13 or b == 0x17 or b == 0x1B or b == 0x1F or b == 0x23 or b == 0x27 or b == 0x2B or b == 0x2F or b == 0x33 or b == 0x37 or b == 0x3B or b == 0x3F then - local cmd = (cmd_cfg1):format(b) - resp = send(cmd) - else - local cmd = (cmd_empty):format(b) - resp = send(cmd) - end - if resp == nil then - io.write('\nwrote block '..b, ' failed\n') - err = true - else - io.write('.') - end - io.flush() - end - print('\n') - err, msg = set_type(3) - if err == nil then return err, msg end - lib14a.disconnect() - return true, 'Ok' + local err, msg, resp + local cmd_empty = 'CF'.._key..'CD%02X00000000000000000000000000000000' + local cmd_trail = 'CF'.._key..'CD%02XFFFFFFFFFFFFFF078069FFFFFFFFFFFF' + for b = 1, 0xFF do + if mfIsSectorTrailer(b) then + local cmd = (cmd_trail):format(b) + resp = send(cmd) + else + local cmd = (cmd_empty):format(b) + resp = send(cmd) + end + if resp == nil then + io.write('\nwrote block '..b, ' failed\n') + err = true + else + io.write('.') + end + io.flush() + end + print('\n') + err, msg = set_type(3) + if err == nil then return err, msg end + lib14a.disconnect() + return true, 'Ok' elseif wtype == '1' then - print('Starting Ultralight Wipe') - local err, msg, resp - local cmd_empty = 'A2%02X00000000' - local cmd_cfg1 = 'A2%02X000000FF' - local cmd_cfg2 = 'A2%02X00050000' - print('Wiping tag') - local info = connect() - if not info then return false, "Can't select card" end + print('Starting Ultralight Wipe') + local err, msg, resp + local cmd_empty = 'A2%02X00000000' + local cmd_cfg1 = 'A2%02X000000FF' + local cmd_cfg2 = 'A2%02X00050000' + print('Wiping tag') + local info = connect() + if not info then return false, "Can't select card" end send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") - for b = 3, 0xFB do - --configuration block 0 - if b == 0x29 or b == 0x83 or b == 0xe3 then - local cmd = (cmd_cfg1):format(b) - resp = send(cmd) - --configuration block 1 - elseif b == 0x2a or b == 0x84 or b == 0xe4 then - local cmd = (cmd_cfg2):format(b) - resp = send(cmd) - else - resp = send(cmd_empty:format(b)) - end - if resp == '04' or #resp == 0 then - io.write('\nwrote block '..b, ' failed\n') - err = true - else - io.write('.') - end - io.flush() - end - io.write('\r\n') - lib14a.disconnect() - print('\n') - if err then return nil, "Tag locked down, "..err_lock end - -- set NTAG213 default values - err, msg = set_type(14) - if err == nil then return err, msg end - --set UID - err, msg = write_uid('04112233445566') - if err == nil then return err, msg end - --set NTAG pwd - err, msg = write_ntagpwd('FFFFFFFF') - if err == nil then return err, msg end - --set pack - err, msg = write_pack('0000') - if err == nil then return err, msg end - lib14a.disconnect() - return true, 'Ok' + for b = 3, 0xFB do + --configuration block 0 + if b == 0x29 or b == 0x83 or b == 0xe3 then + local cmd = (cmd_cfg1):format(b) + resp = send(cmd) + --configuration block 1 + elseif b == 0x2a or b == 0x84 or b == 0xe4 then + local cmd = (cmd_cfg2):format(b) + resp = send(cmd) + else + resp = send(cmd_empty:format(b)) + end + if resp == '04' or #resp == 0 then + io.write('\nwrote block '..b, ' failed\n') + err = true + else + io.write('.') + end + io.flush() + end + io.write('\r\n') + lib14a.disconnect() + print('\n') + if err then return nil, "Tag locked down, "..err_lock end + -- set NTAG213 default values + err, msg = set_type(14) + if err == nil then return err, msg end + --set UID + err, msg = write_uid('04112233445566') + if err == nil then return err, msg end + --set NTAG pwd + err, msg = write_ntagpwd('FFFFFFFF') + if err == nil then return err, msg end + --set pack + err, msg = write_pack('0000') + if err == nil then return err, msg end + lib14a.disconnect() + return true, 'Ok' else oops('Use 0 for Mifare wipe or 1 for Ultralight wipe') end end From c88c3bc4f2e7366c51e701e13560c544b473ccd7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 25 Nov 2022 17:30:05 +0100 Subject: [PATCH 378/759] maur keys --- client/dictionaries/mfc_default_keys.dic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 3a11457f2..770979629 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1898,3 +1898,6 @@ FFFFFFAAAAAA # Transport system Uruguay - STM # Shared key - sec 0 blk 3 D144BD193063 +# +# Data from http://www.proxmark.org/forum/viewtopic.php?pid=45659#p45659 +3515AE068CAD From 417a6076cbd2b56d729f46cacd560904cb1d3ed6 Mon Sep 17 00:00:00 2001 From: "E.Nigma" Date: Tue, 29 Nov 2022 09:34:32 +0100 Subject: [PATCH 379/759] Add keys --- client/dictionaries/mfc_default_keys.dic | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 770979629..a336a32b5 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1901,3 +1901,11 @@ D144BD193063 # # Data from http://www.proxmark.org/forum/viewtopic.php?pid=45659#p45659 3515AE068CAD +# +# Keys Catering +6A0D531DA1A7 +4BB29463DC29 +# +# Keys Swim +8627C10A7014 +453857395635 From 28c48fe823a66b03521942f814f701cf0b1c664b Mon Sep 17 00:00:00 2001 From: Trevor Sayre Date: Tue, 29 Nov 2022 15:33:04 -0500 Subject: [PATCH 380/759] Update Termux notes to recommend F-Droid Signed-off-by: Trevor Sayre --- doc/termux_notes.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/doc/termux_notes.md b/doc/termux_notes.md index 98cbdcb25..852c3cdc1 100644 --- a/doc/termux_notes.md +++ b/doc/termux_notes.md @@ -30,10 +30,11 @@ ^[Top](#top) - Android phone -- [Termux](https://play.google.com/store/apps/details?id=com.termux) -- Proxmark3 RDV4 (https://www.proxmark.com/proxmark-3-hardware/proxmark-3-rdv4) -- Blueshark Standalone Module (Bluetooth ONLY) (https://www.proxmark.com/proxmark-news/proxmark3-blueshark-bluetooth-released) -- Proxmark with BTADDON compiled Firmware (Bluetooth ONLY) (https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md#platform_extras) +- [F-Droid](https://f-droid.org/) +- [Termux](https://f-droid.org/en/packages/com.termux/) +- [Proxmark3 RDV4](https://www.proxmark.com/proxmark-3-hardware/proxmark-3-rdv4) +- [Blueshark Standalone Module](https://www.proxmark.com/proxmark-news/proxmark3-blueshark-bluetooth-released) **(ONLY if using Bluetooth)** +- [Proxmark with BTADDON compiled Firmware](https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md#platform_extras) **(ONLY if using Bluetooth)** ## Notes @@ -48,8 +49,9 @@ ref : https://github.com/Proxmark/proxmark3/wiki/android ### Setting up Termux ^[Top](#top) -Install [Termux](https://f-droid.org/en/packages/com.termux/) and start it +Use [F-Droid](https://f-droid.org/) to install [Termux](https://f-droid.org/en/packages/com.termux/) and start it. +It is recommended to use the F-Droid version of Termux as it will be the latest. The [Play Store version](https://play.google.com/store/apps/details?id=com.termux) is not maintained (as stated in the description: "Updates over Google Play [are] currently halted due to technical reasons"). ### Install Proxmark3 package which follows tagged releases ^[Top](#top) From cfc72fb5f113bd2f5e20dbe334a0685027b95e38 Mon Sep 17 00:00:00 2001 From: Nat McHugh Date: Sun, 27 Nov 2022 14:55:12 +0000 Subject: [PATCH 381/759] Fix the dump command hitag2 --- client/src/cmdlfhitag.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index 44e06f68d..ba7b72195 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -844,15 +844,40 @@ static int CmdLFHitag2Dump(const char *Cmd) { return PM3_EINVARG; } - PrintAndLogEx(SUCCESS, "Dumping tag memory..."); + hitag_function htf; + hitag_data htd; + memset(&htd, 0, sizeof(htd)); + if (keylen == 6) { + htf = RHT2F_CRYPTO; + memcpy(htd.crypto.key, key, sizeof(htd.crypto.key)); + PrintAndLogEx(INFO, "Authenticating in crypto mode"); + } else { + htf = RHT2F_PASSWORD; + memcpy(htd.pwd.password, key, sizeof(htd.pwd.password)); + PrintAndLogEx(INFO, "Authenticating in password mode"); + } + + uint16_t cmd = CMD_LF_HITAG_READER; clearCommandBuffer(); - //SendCommandNG(CMD_LF_HITAG_DUMP, &htd, sizeof(htd)); + SendCommandMIX(cmd, htf, 0, 0, &htd, sizeof(htd)); PacketResponseNG resp; + + if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + if (resp.oldarg[0] == false) { + PrintAndLogEx(DEBUG, "DEBUG: Error - hitag failed"); + return PM3_ESOFT; + } uint8_t *data = resp.data.asBytes; + if (data == NULL) return PM3_ESOFT; + PrintAndLogEx(SUCCESS, "Dumping tag memory..."); + if (fnlen < 1) { char *fptr = filename; fptr += snprintf(filename, sizeof(filename), "lf-hitag-"); From 3326a58c0d968cedd91bc626def19f6b4cd1b109 Mon Sep 17 00:00:00 2001 From: Nathaniel McHugh Date: Wed, 30 Nov 2022 16:42:00 +0000 Subject: [PATCH 382/759] Update CHANGELOG.md Signed-off-by: Nathaniel McHugh --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05bf94a2d..cab2e0dc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - Added `hf mf gload, gsave, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) - Fixed SPI flash overflow when loading dictionnaries into flash. Breaking change: added 1 more sector for Mifare - dictionnaries should be loaded again (@jmichelp) + - Fixed `lf hitag dump` - Should now work as described in the command help (@natmchugh) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) From 49627524721e998e9d42d3d4ce16144fcf6335a3 Mon Sep 17 00:00:00 2001 From: nvx Date: Fri, 2 Dec 2022 20:13:13 +1000 Subject: [PATCH 383/759] Fix `trace list -r` (relative times) not working unless the `-u` (microseconds) flag was also provided. Also makes the `--frame` option respect microseconds and relative times as well. --- CHANGELOG.md | 1 + client/src/cmdtrace.c | 33 ++++++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05bf94a2d..e352d1a92 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 -r` (relative times) not working unless `-u` (microseconds) was specified, and made `--frame` respect `-u` and `-r` options (@nvx) - Added detection of magic Gen4 GTU (@DidierA) - Added luascript `hf_i2c_plus_2k_utils` - Script for dumping/modifying user memory of sectors 0 and 1 (@flamebarke) - Added `hf mfu esave` - saves emulator memory to mfu dump file (@DidierA) diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index aea1880cb..fd0b9b960 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -815,8 +815,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr ); } else { PrintAndLogEx(NORMAL, " %10u | %10u | Tag |%-*s | %s| %s", - (hdr->timestamp - first_hdr->timestamp), - (end_of_transmission_timestamp - first_hdr->timestamp), + time1, + time2, 72 + crc_format_string_offset, line[j], (j == num_lines - 1) ? crc : " ", @@ -838,8 +838,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } else { PrintAndLogEx(NORMAL, _YELLOW_(" %10u") " | " _YELLOW_("%10u") " | " _YELLOW_("Rdr") " |" _YELLOW_("%-*s")" | " _YELLOW_("%s") "| " _YELLOW_("%s"), - (hdr->timestamp - first_hdr->timestamp), - (end_of_transmission_timestamp - first_hdr->timestamp), + time1, + time2, 72 + crc_format_string_offset, line[j], (j == num_lines - 1) ? crc : " ", @@ -889,11 +889,26 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr tracelog_hdr_t *next_hdr = (tracelog_hdr_t *)(trace + tracepos); - PrintAndLogEx(NORMAL, " %10u | %10u | %s |fdt (Frame Delay Time): " _YELLOW_("%d"), - (end_of_transmission_timestamp - first_hdr->timestamp), - (next_hdr->timestamp - first_hdr->timestamp), - " ", - (next_hdr->timestamp - end_of_transmission_timestamp)); + uint32_t time1 = end_of_transmission_timestamp - first_hdr->timestamp; + uint32_t time2 = next_hdr->timestamp - first_hdr->timestamp; + if (prev_eot) { + time1 = 0; + time2 = next_hdr->timestamp - end_of_transmission_timestamp; + } + + if (use_us) { + PrintAndLogEx(NORMAL, " %10.1f | %10.1f | %s |fdt (Frame Delay Time): " _YELLOW_("%.1f"), + (float)time1 / 13.56, + (float)time2 / 13.56, + " ", + (float)(next_hdr->timestamp - end_of_transmission_timestamp) / 13.56); + } else { + PrintAndLogEx(NORMAL, " %10u | %10u | %s |fdt (Frame Delay Time): " _YELLOW_("%d"), + time1, + time2, + " ", + (next_hdr->timestamp - end_of_transmission_timestamp)); + } } return tracepos; From 9627c9dc287b08c76b5db03932c18449972e96eb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Dec 2022 11:57:54 +0100 Subject: [PATCH 384/759] liblua5.2-0-dbg package doesnt seem to exist anymore --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/ubuntu.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 73ef661f7..3d794dba1 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -41,7 +41,7 @@ jobs: run: sudo apt-get update - name: Install dependencies - run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0-dbg liblua5.2-0 lua5.2 sed libssl-dev + run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev - name: Install Python dependencies run: | diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 3f558bfac..e08bd1412 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -26,7 +26,7 @@ jobs: run: sudo apt-get update - name: Install dependencies - run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0-dbg liblua5.2-0 lua5.2 sed libssl-dev + run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev - name: Install Python dependencies run: | From 93f8021049cf6389352b5450d6ad58468a899a56 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Dec 2022 12:21:29 +0100 Subject: [PATCH 385/759] remove old dependency --- .github/workflows/ubuntu.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index e08bd1412..1df7dcfa2 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -58,7 +58,7 @@ jobs: run: sudo apt-get update - name: Install dependencies - run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0-dbg liblua5.2-0 lua5.2 sed libssl-dev + run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev - name: Install Python dependencies run: | @@ -91,7 +91,7 @@ jobs: run: sudo apt-get update - name: Install dependencies - run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0-dbg liblua5.2-0 lua5.2 sed libssl-dev + run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.2-dev liblua5.2-0 lua5.2 sed libssl-dev - name: Install Python dependencies run: | From 951bfb580d0523a8d9fc586fcf4238082e8a327d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Dec 2022 12:28:07 +0100 Subject: [PATCH 386/759] V2 used Node12, which is deprecated for Node16 --- .github/workflows/ubuntu.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 1df7dcfa2..acce10e3a 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Update apt repos run: sudo apt-get update @@ -52,7 +52,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Update apt repos run: sudo apt-get update @@ -85,7 +85,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Update apt repos run: sudo apt-get update From 87f29d1fa930ba97f884a669896906d6c0887774 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Dec 2022 12:31:53 +0100 Subject: [PATCH 387/759] node12 is deprecated, v3 uses Node16 --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/macos.yml | 6 +++--- .github/workflows/windows.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 3d794dba1..0ec56e054 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -51,7 +51,7 @@ jobs: if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index d4969452d..2245ef05f 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -19,7 +19,7 @@ jobs: runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set Git http.postBuffer to something high run: git config --global http.postBuffer 524288000 @@ -60,7 +60,7 @@ jobs: runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set Git http.postBuffer to something high run: git config --global http.postBuffer 524288000 @@ -102,7 +102,7 @@ jobs: runs-on: macos-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set Git http.postBuffer to something high run: git config --global http.postBuffer 524288000 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 5da0035d5..d639eebc4 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -48,7 +48,7 @@ jobs: working-directory: C:\ProxSpace run: ./runme64.bat -c "exit" - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: make clean run: make clean @@ -134,7 +134,7 @@ jobs: git config --global core.autocrlf false git config --global core.eol lf - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: make clean run: make clean From a6c09505ce6aba934b82c6c13094044e937968b7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Dec 2022 12:35:22 +0100 Subject: [PATCH 388/759] change token for !crc -> !! and added colors to it --- client/src/cmdtrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index fd0b9b960..a714b7e32 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -683,7 +683,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } // Draw the CRC column - const char *crcstrings[] = { "!crc", " ok ", " ", "A ok", "B ok" }; + const char *crcstrings[] = { _RED_(" !! "), _GREEN_(" ok "), " ", _GREEN_("A ok"), _GREEN_("B ok") }; const char *crc = crcstrings[crcStatus]; // mark short bytes (less than 8 Bit + Parity) @@ -876,7 +876,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr PrintAndLogEx(NORMAL, " | | * |%-*s | %-4s| %s", 72 + crc_format_string_offset, sprint_hex_inrow_spaces(mfData, mfDataLen, 2), - (crcc == 0 ? "!crc" : (crcc == 1 ? " ok " : " ")), + (crcc == 0 ? _RED_(" !! ") : (crcc == 1 ? _GREEN_(" ok ") : " ")), explanation); } } From 80505ca268b8a41160d72ac8435b1f073313b190 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Dec 2022 20:12:58 +0100 Subject: [PATCH 389/759] vigik has some more 491x --- client/resources/mad.json | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/client/resources/mad.json b/client/resources/mad.json index 078db1831..cfa6294d3 100644 --- a/client/resources/mad.json +++ b/client/resources/mad.json @@ -6097,6 +6097,41 @@ "service_provider": "CDVI", "system_integrator": "CDVI" }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4914", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4915", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4916", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4917", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, + { + "application": "(access control and security) VIGIK", + "company": "CDV International", + "mad": "0x4918", + "service_provider": "CDVI", + "system_integrator": "CDVI" + }, { "application": "(access control and security) VIGIK", "company": "NORALSY", From e4339bd846ef58cf841cfd81dbd3bd530c00ff4b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Dec 2022 20:30:13 +0100 Subject: [PATCH 390/759] wip - testing of a vigik annotater --- client/src/cmdhfmf.c | 52 ++++++- client/src/mifare/mifarehost.c | 247 ++++++++++++++++++++++++++++++++- client/src/mifare/mifarehost.h | 5 + 3 files changed, 302 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 72d8c1986..a2572df99 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -5528,6 +5528,13 @@ static int CmdHF14AMfMAD(const char *Cmd) { HIDTryUnpack(&packed); } } + + sector = DetectHID(dump, 0x4910); + if (sector > -1) { + // decode it + PrintAndLogEx(INFO, ""); + PrintAndLogEx(INFO, _CYAN_("VIGIK PACS detected")); + } free(dump); return PM3_SUCCESS; } @@ -5658,7 +5665,6 @@ static int CmdHF14AMfMAD(const char *Cmd) { return PM3_SUCCESS; } - int CmdHFMFNDEFRead(const char *Cmd) { CLIParserContext *ctx; @@ -6792,6 +6798,50 @@ static int CmdHF14AMfView(const char *Cmd) { mf_print_keys(block_cnt, dump); } + int sector = DetectHID(dump, 0x4910); + if (sector > -1) { + // decode it + PrintAndLogEx(INFO, ""); + PrintAndLogEx(INFO, _CYAN_("VIGIK PACS detected")); + + // decode MAD + uint16_t mad[7 + 8 + 8 + 8 + 8] = {0}; + size_t madlen = 0; + res = MADDecode(dump, NULL, mad, &madlen, false); + if (res != PM3_SUCCESS) { + PrintAndLogEx(ERR, "can't decode MAD"); + return res; + } + + // allocate memory + uint8_t* d = calloc(bytes_read, sizeof(uint8_t)); + if (d == NULL) { + return PM3_EMALLOC; + } + uint16_t dlen = 0; + + // vigik struture sector 0 + uint8_t *pdump = dump; + + memcpy(d + dlen, pdump, MFBLOCK_SIZE * 3); + dlen += MFBLOCK_SIZE * 3; + pdump += (MFBLOCK_SIZE * 4); // skip sectortrailer + + // extract memory from MAD sectors + for (int i = 0; i <= madlen; i++) { + if (0x4910 == mad[i] || 0x4916 == mad[i]) { + memcpy(d + dlen, pdump, MFBLOCK_SIZE * 3); + dlen += MFBLOCK_SIZE * 3; + } + + pdump += (MFBLOCK_SIZE * 4); // skip sectortrailer + } + +// convert_mfc_2_arr(pdump, bytes_read, d, &dlen); + vigik_annotate(d); + free(d); + } + free(dump); return PM3_SUCCESS; } diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 917d84244..e158822e2 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -36,7 +36,9 @@ #include "cmdparser.h" // detection of flash capabilities #include "cmdflashmemspiffs.h" // upload to flash mem #include "mifaredefault.h" // default keys - +#include "protocol_vigik.h" // VIGIK struct +#include "crypto/libpcrypto.h" +#include "util.h" // xor int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { uint32_t uid = 0; @@ -1446,3 +1448,246 @@ int read_mfc_ev1_signature(uint8_t *signature) { } return res; } + +int convert_mfc_2_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen) { + if (in == NULL || out == NULL) + return PM3_EINVARG; + + uint8_t blockno = 0; + while (ilen) { + + if (mfIsSectorTrailer(blockno) == false) { + memcpy(out, in, MFBLOCK_SIZE); + } + blockno++; + out += MFBLOCK_SIZE; + in += MFBLOCK_SIZE; + ilen -= MFBLOCK_SIZE; + *olen += MFBLOCK_SIZE; + } + return PM3_SUCCESS; +} + +int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len) { + + // iso9796 + // Exponent V = 2 + // n = The public modulus n is the product of the secret prime factors p and q. Its length is 1024 bits. + + + // calc SHA1 +/* + uint8_t mask[128] = {0}; + uint8_t *pmask = mask; + int mask_cnt; + for (mask_cnt = 0; mask_cnt < sizeof(mask); mask_cnt += 4) { + uint8_t seed[13] = {0}; + sprintf((char*)seed, "seed%08u", mask_cnt); + sha1hash(seed, 12, pmask); + pmask += 4; + } +*/ + + PrintAndLogEx(INFO, "Raw..."); + print_hex_noascii_break(uid, uidlen, MFBLOCK_SIZE * 2); + + + // t = 0xBC = Implicitly known + // t = 0xCC = look at byte before to determine hash function + // uint8_t T[] = {0x33, 0xCC}; + + // Success decrypt would mean 0x4b BB ... BB BA padding + // padding, message, hash, 8 bits or 16 bits + + // signature = h( C || M1 || h(M2) ) + // 1024 - 786 - 160 - 16 -1 + // salt C + // message M = 96 bytes, 768 bits + // sha1 hash H = 20 bytes, 160 bits + // padding = 20 bytes, 96 bits + + +// ref: MIFARE Classic EV1 Originality Signature Validation +#define PUBLIC_VIGIK_KEYLEN 128 + + const vigik_pk_t vigik_rsa_pk[5] = { + {"La Poste Service Universel", "AB9953CBFCCD9375B6C028ADBAB7584BED15B9CA037FADED9765996F9EA1AB983F3041C90DA3A198804FF90D5D872A96A4988F91F2243B821E01C5021E3ED4E1BA83B7CFECAB0E766D8563164DE0B2412AE4E6EA63804DF5C19C7AA78DC14F608294D732D7C8C67A88C6F84C0F2E3FAFAE34084349E11AB5953AC68729D07715"}, + {"La Poste Autres Services", "A6D99B8D902893B04F3F8DE56CB6BF24338FEE897C1BCE6DFD4EBD05B7B1A07FD2EB564BB4F7D35DBFE0A42966C2C137AD156E3DAB62904592BCA20C0BC7B8B1E261EF82D53F52D203843566305A49A22062DECC38C2FE3864CAD08E79219487651E2F79F1C9392B48CAFE1BFFAFF4802AE451E7A283E55A4026AD1E82DF1A15"}, + {"France Telecom", "C44DBCD92F9DCF42F4902A87335DBB35D2FF530CDB09814CFA1F4B95A1BD018D099BC6AB69F667B4922AE1ED826E72951AA3E0EAAA7D49A695F04F8CDAAE2D18D10D25BD529CBB05ABF070DC7C041EC35C2BA7F58CC4C349983CC6E11A5CBE828FB8ECBC26F08E1094A6B44C8953C8E1BAFD214DF3E69F430A98CCC75C03669D"}, + {"EDF-GDF", "B35193DBD2F88A21CDCFFF4BF84F7FC036A991A363DCB3E802407A5E5879DC2127EECFC520779E79E911394882482C87D09A88B0711CBC2973B77FFDAE40EA0001F595072708C558B484AB89D02BCBCB971FF1B80371C0BE30CB13661078078BB68EBCCA524B9DD55EBF7D47D9355AFC95511350CC1103A5DEE847868848B235"}, + {"demo", "BCEB2EB02E1C8E9999BC9603F8F91DA6084EA6E7C75BD18DD0CDBEDB21DA29F19E7311259DB0D190B1920186A8126B582D13ABA69958763ADA8F79F162C7379D6109D2C94AA2E041B383A74BBF17FFCC145760AA8B58BE3C00C52BA3BD05A9D0BE5BA503E6721FC4066D37A89BF072C97BABB26CF6B29633043DB4746F9D2175"}, + }; + + uint8_t i; + bool is_valid = false; + + mbedtls_mpi RN, E; + mbedtls_mpi_init(&RN); + + // exponent 2 + mbedtls_mpi_init(&E); + mbedtls_mpi_add_int(&E, &E, 2); + + for (i = 0; i < ARRAYLEN(vigik_rsa_pk); i++) { + + PrintAndLogEx(INFO, "\n\n--- RSA PUBLIC KEY ---\n"); + int dl = 0; + uint8_t n[PUBLIC_VIGIK_KEYLEN]; + param_gethex_to_eol(vigik_rsa_pk[i].n, 0, n, PUBLIC_VIGIK_KEYLEN, &dl); + + // convert + mbedtls_mpi N, s, sqr, res; + mbedtls_mpi_init(&N); + mbedtls_mpi_init(&s); + mbedtls_mpi_init(&sqr); + mbedtls_mpi_init(&res); + + mbedtls_mpi_read_binary(&N, (const unsigned char*)n, PUBLIC_VIGIK_KEYLEN); + +/* + uint8_t demo_sig[128]; + param_gethex_to_eol("0C0C62D3523F2DA3972679D0348D9A5038E93AE3D19E97DF875DCC046B2637DBCE7D4CCC5967529AB96D27B6D9B41F5456E65EEA328FDB7DAE6F4E7DA0CFC1CFF8AB5A80CC7C9B9F487EC2B590CBC2F31AFDC5CF9C3478B93C46D575A0E08D21D965A9C4FCAFE3562D64B1C30706AF0D43288156DA3FF990CB040D5C0863F262", 0, demo_sig, 128, &dl); + mbedtls_mpi_read_binary(&s, (const unsigned char*)demo_sig, 128); +*/ + mbedtls_mpi_read_binary(&s, (const unsigned char*)signature, signature_len); + + // check is sign < (N/2) + mbedtls_mpi n_2; + mbedtls_mpi_init(&n_2); + mbedtls_mpi_copy(&n_2, &N); + mbedtls_mpi_shift_r(&n_2, 1); + + bool is_less = (mbedtls_mpi_cmp_mpi(&s, &n_2) > 0) ? false : true; + PrintAndLogEx(INFO, "z < (N/2) ..... %s", (is_less) ? _GREEN_("YES") : _RED_("NO")); + + mbedtls_mpi_free(&n_2); + if (is_less) { + mbedtls_mpi_exp_mod(&sqr, &s, &E, &N, &RN); + } + + /* + if v is even and + ⎯ if J* mod 8 = 1, then f* = n–J*. + ⎯ if J* mod 8 = 4, then f* = J*, + ⎯ if J* mod 8 = 6, then f* = 2J*, + ⎯ if J* mod 8 = 7, then f* = 2(n–J*), + */ + uint8_t b2 = mbedtls_mpi_get_bit(&sqr, 2); + uint8_t b1 = mbedtls_mpi_get_bit(&sqr, 1); + uint8_t b0 = mbedtls_mpi_get_bit(&sqr, 0); + uint8_t lsb = (b2 << 2) | (b1 << 1) | b0; + + switch (lsb) { + case 1: + mbedtls_mpi_sub_mpi(&res, &N, &sqr); + break; + case 4: + mbedtls_mpi_copy(&res, &sqr); + break; + case 6: + mbedtls_mpi_mul_int(&res, &sqr, 2); + break; + case 7: + mbedtls_mpi foo; + mbedtls_mpi_init(&foo); + mbedtls_mpi_sub_mpi(&foo, &N, &sqr); + mbedtls_mpi_mul_int(&res, &foo, 2); + mbedtls_mpi_free(&foo); + break; + } + + PrintAndLogEx(INFO, "LSB............ " _GREEN_("%u"), lsb); + mbedtls_mpi_write_file( "E = 0x", &E, 16, NULL ); + mbedtls_mpi_write_file( "N = 0x", &N, 16, NULL ); + mbedtls_mpi_write_file( "[=] signature...... ", &s, 16, NULL ); + mbedtls_mpi_write_file( "[=] square mod n... ", &sqr, 16, NULL ); + mbedtls_mpi_write_file( "[=] n-fs........... ", &res, 16, NULL ); + // mbedtls_mpi_write_file( "masked ", &, 16, NULL ); + + uint8_t nfs[128] = {0}; + int bar = mbedtls_mpi_write_binary(&res, nfs, sizeof(nfs)); + if (bar != 0) + PrintAndLogEx(INFO, "FOO... %i", bar); + + PrintAndLogEx(INFO, "converted to byte array"); + print_hex_noascii_break(nfs, sizeof(nfs), 32); + + /* + for (int x = 0; x < uidlen; x++) { + nfs[x] ^= uid[x]; + } + + PrintAndLogEx(INFO, "xored set"); + print_hex_noascii_break(nfs, uidlen, 32); + */ + + mbedtls_mpi_free(&N); + mbedtls_mpi_free(&s); + mbedtls_mpi_free(&res); + /* + int ret = 0; + is_valid = (ret == 0); + if (is_valid) + break; + */ + } + mbedtls_mpi_free(&RN); + mbedtls_mpi_free(&E); + + return PM3_ESOFT; + + PrintAndLogEx(INFO, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); + PrintAndLogEx(INFO, "RSA: 1024bit"); + + if (is_valid == false || i == ARRAYLEN(vigik_rsa_pk)) { + PrintAndLogEx(INFO, "Signature:"); + print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2); + PrintAndLogEx(SUCCESS, "Signature verification: " _RED_("failed")); + return PM3_ESOFT; + } + + PrintAndLogEx(INFO, "Signature public key name: " _YELLOW_("%s"), vigik_rsa_pk[i].desc); + PrintAndLogEx(INFO, "Signature public key value:"); + PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n); + PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 64); + PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 128); + PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 192); + + PrintAndLogEx(INFO, "Signature:"); + print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2); + + PrintAndLogEx(SUCCESS, "Signature verification: " _GREEN_("successful")); + + return PM3_SUCCESS; +} + +int vigik_annotate(uint8_t *d) { + if (d == NULL) + return PM3_EINVARG; + + mfc_vigik_t *foo = (mfc_vigik_t*)d; + + PrintAndLogEx(INFO, "Manufacture......... %s", sprint_hex(foo->b0, sizeof(foo->b0))); + PrintAndLogEx(INFO, "MAD................. %s", sprint_hex(foo->mad, sizeof(foo->mad))); + PrintAndLogEx(INFO, "Counters............ %u", foo->counters); + PrintAndLogEx(INFO, "rtf................. %s", sprint_hex(foo->rtf, sizeof(foo->rtf))); + PrintAndLogEx(INFO, "Service code........ 0x%08x / %u ", foo->service_code, foo->service_code); + PrintAndLogEx(INFO, "Info flag........... %u -", foo->info_flag); // , sprint_bin(foo->info_flag, 1)); + PrintAndLogEx(INFO, "Key version......... %u", foo->key_version); + PrintAndLogEx(INFO, "PTR Counter......... %u", foo->ptr_counter); + PrintAndLogEx(INFO, "Counter num......... %u", foo->counter_num); + PrintAndLogEx(INFO, "Slot access date.... %s", sprint_hex(foo->slot_access_date, sizeof(foo->slot_access_date))); + PrintAndLogEx(INFO, "Slot dst duration... %u", foo->slot_dst_duration); + PrintAndLogEx(INFO, "Other Slots......... %s", sprint_hex(foo->other_slots, sizeof(foo->other_slots))); + PrintAndLogEx(INFO, "Services counter.... %u", foo->services_counter); + PrintAndLogEx(INFO, "Loading date........ %s", sprint_hex(foo->loading_date, sizeof(foo->loading_date))); + PrintAndLogEx(INFO, "Reserverd null...... %u", foo->reserved_null); + PrintAndLogEx(INFO, "----------------------------------------------------------------"); + PrintAndLogEx(INFO, ""); + vigik_verify(d, 96, foo->rsa_signature, sizeof(foo->rsa_signature)); + PrintAndLogEx(INFO, "----------------------------------------------------------------"); + PrintAndLogEx(INFO, ""); + return PM3_SUCCESS; + +} \ No newline at end of file diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index 48ec3d38d..3fde339f5 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -109,4 +109,9 @@ int read_mfc_ev1_signature(uint8_t *signature); void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted); + +// remove all sector trailers in a MFC dump +int convert_mfc_2_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen); +int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len); +int vigik_annotate(uint8_t *d); #endif From 4f70f777def197934cb30c617aa0643f3daa822f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Dec 2022 20:37:53 +0100 Subject: [PATCH 391/759] typedef file for vigik annotater --- include/protocol_vigik.h | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 include/protocol_vigik.h diff --git a/include/protocol_vigik.h b/include/protocol_vigik.h new file mode 100644 index 000000000..95ce9d1e3 --- /dev/null +++ b/include/protocol_vigik.h @@ -0,0 +1,44 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +#ifndef PROTOCOL_VIGIK_H +#define PROTOCOL_VIGIK_H +#include "common.h" + +typedef struct mfc_vigik_s { + uint8_t b0[16]; + uint8_t mad[32]; + uint8_t counters; + uint8_t rtf[15]; + uint32_t service_code; + uint8_t info_flag; + uint8_t key_version; + uint16_t ptr_counter; + uint8_t counter_num; + uint8_t slot_access_date[5]; + uint16_t slot_dst_duration; + uint8_t other_slots[8]; + uint8_t services_counter; + uint8_t loading_date[5]; + uint16_t reserved_null; + uint8_t rsa_signature[128]; +} mfc_vigik_t; + +typedef struct vigik_pk_s { + const char *desc; + const char *n; +} vigik_pk_t; + +#endif \ No newline at end of file From e3a6f8fe277c3239434fc6a14f162f12872d29d6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 3 Dec 2022 21:11:29 +0100 Subject: [PATCH 392/759] look up vigik service code --- client/src/mifare/mifarehost.c | 42 +++++++++++++++++++++++----------- client/src/mifare/mifarehost.h | 1 + include/protocol_vigik.h | 3 ++- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index e158822e2..fcc77a4b0 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1468,6 +1468,24 @@ int convert_mfc_2_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen) return PM3_SUCCESS; } +static const vigik_pk_t vigik_rsa_pk[] = { + {"La Poste Service Universel", 0x07AA, "AB9953CBFCCD9375B6C028ADBAB7584BED15B9CA037FADED9765996F9EA1AB983F3041C90DA3A198804FF90D5D872A96A4988F91F2243B821E01C5021E3ED4E1BA83B7CFECAB0E766D8563164DE0B2412AE4E6EA63804DF5C19C7AA78DC14F608294D732D7C8C67A88C6F84C0F2E3FAFAE34084349E11AB5953AC68729D07715"}, + {"La Poste Autres Services", 0x07AB, "A6D99B8D902893B04F3F8DE56CB6BF24338FEE897C1BCE6DFD4EBD05B7B1A07FD2EB564BB4F7D35DBFE0A42966C2C137AD156E3DAB62904592BCA20C0BC7B8B1E261EF82D53F52D203843566305A49A22062DECC38C2FE3864CAD08E79219487651E2F79F1C9392B48CAFE1BFFAFF4802AE451E7A283E55A4026AD1E82DF1A15"}, + {"France Telecom", 0x07AC, "C44DBCD92F9DCF42F4902A87335DBB35D2FF530CDB09814CFA1F4B95A1BD018D099BC6AB69F667B4922AE1ED826E72951AA3E0EAAA7D49A695F04F8CDAAE2D18D10D25BD529CBB05ABF070DC7C041EC35C2BA7F58CC4C349983CC6E11A5CBE828FB8ECBC26F08E1094A6B44C8953C8E1BAFD214DF3E69F430A98CCC75C03669D"}, + {"EDF-GDF", 0x07AD, "B35193DBD2F88A21CDCFFF4BF84F7FC036A991A363DCB3E802407A5E5879DC2127EECFC520779E79E911394882482C87D09A88B0711CBC2973B77FFDAE40EA0001F595072708C558B484AB89D02BCBCB971FF1B80371C0BE30CB13661078078BB68EBCCA524B9DD55EBF7D47D9355AFC95511350CC1103A5DEE847868848B235"}, + {"demo", 0x0000, "BCEB2EB02E1C8E9999BC9603F8F91DA6084EA6E7C75BD18DD0CDBEDB21DA29F19E7311259DB0D190B1920186A8126B582D13ABA69958763ADA8F79F162C7379D6109D2C94AA2E041B383A74BBF17FFCC145760AA8B58BE3C00C52BA3BD05A9D0BE5BA503E6721FC4066D37A89BF072C97BABB26CF6B29633043DB4746F9D2175"}, + {NULL, 0, NULL} +}; + +const char *vigik_get_service(uint16_t service_code) { + for (int i = 0; i < ARRAYLEN(vigik_rsa_pk); ++i) + if (service_code == vigik_rsa_pk[i].code) + return vigik_rsa_pk[i].desc; + + //No match, return default + return vigik_rsa_pk[ARRAYLEN(vigik_rsa_pk) - 1].desc; +} + int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len) { // iso9796 @@ -1510,14 +1528,6 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature // ref: MIFARE Classic EV1 Originality Signature Validation #define PUBLIC_VIGIK_KEYLEN 128 - const vigik_pk_t vigik_rsa_pk[5] = { - {"La Poste Service Universel", "AB9953CBFCCD9375B6C028ADBAB7584BED15B9CA037FADED9765996F9EA1AB983F3041C90DA3A198804FF90D5D872A96A4988F91F2243B821E01C5021E3ED4E1BA83B7CFECAB0E766D8563164DE0B2412AE4E6EA63804DF5C19C7AA78DC14F608294D732D7C8C67A88C6F84C0F2E3FAFAE34084349E11AB5953AC68729D07715"}, - {"La Poste Autres Services", "A6D99B8D902893B04F3F8DE56CB6BF24338FEE897C1BCE6DFD4EBD05B7B1A07FD2EB564BB4F7D35DBFE0A42966C2C137AD156E3DAB62904592BCA20C0BC7B8B1E261EF82D53F52D203843566305A49A22062DECC38C2FE3864CAD08E79219487651E2F79F1C9392B48CAFE1BFFAFF4802AE451E7A283E55A4026AD1E82DF1A15"}, - {"France Telecom", "C44DBCD92F9DCF42F4902A87335DBB35D2FF530CDB09814CFA1F4B95A1BD018D099BC6AB69F667B4922AE1ED826E72951AA3E0EAAA7D49A695F04F8CDAAE2D18D10D25BD529CBB05ABF070DC7C041EC35C2BA7F58CC4C349983CC6E11A5CBE828FB8ECBC26F08E1094A6B44C8953C8E1BAFD214DF3E69F430A98CCC75C03669D"}, - {"EDF-GDF", "B35193DBD2F88A21CDCFFF4BF84F7FC036A991A363DCB3E802407A5E5879DC2127EECFC520779E79E911394882482C87D09A88B0711CBC2973B77FFDAE40EA0001F595072708C558B484AB89D02BCBCB971FF1B80371C0BE30CB13661078078BB68EBCCA524B9DD55EBF7D47D9355AFC95511350CC1103A5DEE847868848B235"}, - {"demo", "BCEB2EB02E1C8E9999BC9603F8F91DA6084EA6E7C75BD18DD0CDBEDB21DA29F19E7311259DB0D190B1920186A8126B582D13ABA69958763ADA8F79F162C7379D6109D2C94AA2E041B383A74BBF17FFCC145760AA8B58BE3C00C52BA3BD05A9D0BE5BA503E6721FC4066D37A89BF072C97BABB26CF6B29633043DB4746F9D2175"}, - }; - uint8_t i; bool is_valid = false; @@ -1529,6 +1539,9 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature mbedtls_mpi_add_int(&E, &E, 2); for (i = 0; i < ARRAYLEN(vigik_rsa_pk); i++) { + if (vigik_rsa_pk[i].desc == NULL) { + break; + } PrintAndLogEx(INFO, "\n\n--- RSA PUBLIC KEY ---\n"); int dl = 0; @@ -1552,6 +1565,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature mbedtls_mpi_read_binary(&s, (const unsigned char*)signature, signature_len); // check is sign < (N/2) +/* mbedtls_mpi n_2; mbedtls_mpi_init(&n_2); mbedtls_mpi_copy(&n_2, &N); @@ -1561,9 +1575,10 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature PrintAndLogEx(INFO, "z < (N/2) ..... %s", (is_less) ? _GREEN_("YES") : _RED_("NO")); mbedtls_mpi_free(&n_2); - if (is_less) { +*/ +// if (is_less) { mbedtls_mpi_exp_mod(&sqr, &s, &E, &N, &RN); - } +// } /* if v is even and @@ -1631,6 +1646,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature break; */ } + mbedtls_mpi_free(&RN); mbedtls_mpi_free(&E); @@ -1665,14 +1681,14 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature int vigik_annotate(uint8_t *d) { if (d == NULL) return PM3_EINVARG; - + mfc_vigik_t *foo = (mfc_vigik_t*)d; PrintAndLogEx(INFO, "Manufacture......... %s", sprint_hex(foo->b0, sizeof(foo->b0))); PrintAndLogEx(INFO, "MAD................. %s", sprint_hex(foo->mad, sizeof(foo->mad))); PrintAndLogEx(INFO, "Counters............ %u", foo->counters); PrintAndLogEx(INFO, "rtf................. %s", sprint_hex(foo->rtf, sizeof(foo->rtf))); - PrintAndLogEx(INFO, "Service code........ 0x%08x / %u ", foo->service_code, foo->service_code); + PrintAndLogEx(INFO, "Service code........ 0x%08x / %u - " _YELLOW_("%s"), foo->service_code, foo->service_code, vigik_get_service(foo->service_code)); PrintAndLogEx(INFO, "Info flag........... %u -", foo->info_flag); // , sprint_bin(foo->info_flag, 1)); PrintAndLogEx(INFO, "Key version......... %u", foo->key_version); PrintAndLogEx(INFO, "PTR Counter......... %u", foo->ptr_counter); @@ -1682,7 +1698,7 @@ int vigik_annotate(uint8_t *d) { PrintAndLogEx(INFO, "Other Slots......... %s", sprint_hex(foo->other_slots, sizeof(foo->other_slots))); PrintAndLogEx(INFO, "Services counter.... %u", foo->services_counter); PrintAndLogEx(INFO, "Loading date........ %s", sprint_hex(foo->loading_date, sizeof(foo->loading_date))); - PrintAndLogEx(INFO, "Reserverd null...... %u", foo->reserved_null); + PrintAndLogEx(INFO, "Reserved null....... %u", foo->reserved_null); PrintAndLogEx(INFO, "----------------------------------------------------------------"); PrintAndLogEx(INFO, ""); vigik_verify(d, 96, foo->rsa_signature, sizeof(foo->rsa_signature)); diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index 3fde339f5..0212dd4f0 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -112,6 +112,7 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool i // remove all sector trailers in a MFC dump int convert_mfc_2_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen); +const char *vigik_get_service(uint16_t service_code); int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len); int vigik_annotate(uint8_t *d); #endif diff --git a/include/protocol_vigik.h b/include/protocol_vigik.h index 95ce9d1e3..a61c4ce03 100644 --- a/include/protocol_vigik.h +++ b/include/protocol_vigik.h @@ -38,7 +38,8 @@ typedef struct mfc_vigik_s { typedef struct vigik_pk_s { const char *desc; - const char *n; + uint16_t code; + const char *n; } vigik_pk_t; #endif \ No newline at end of file From 9af951c22bda6b2f8ab12663343d6c51c9febe45 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 4 Dec 2022 09:27:13 +0100 Subject: [PATCH 393/759] fix compiling --- client/src/mifare/mifarehost.c | 173 ++++++++++++++++++++++----------- 1 file changed, 115 insertions(+), 58 deletions(-) diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index fcc77a4b0..da2782102 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -39,6 +39,7 @@ #include "protocol_vigik.h" // VIGIK struct #include "crypto/libpcrypto.h" #include "util.h" // xor +#include "mbedtls/sha1.h" // SHA1 int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) { uint32_t uid = 0; @@ -1470,10 +1471,16 @@ int convert_mfc_2_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen) static const vigik_pk_t vigik_rsa_pk[] = { {"La Poste Service Universel", 0x07AA, "AB9953CBFCCD9375B6C028ADBAB7584BED15B9CA037FADED9765996F9EA1AB983F3041C90DA3A198804FF90D5D872A96A4988F91F2243B821E01C5021E3ED4E1BA83B7CFECAB0E766D8563164DE0B2412AE4E6EA63804DF5C19C7AA78DC14F608294D732D7C8C67A88C6F84C0F2E3FAFAE34084349E11AB5953AC68729D07715"}, + {"La Poste Service Universel", 0x07AA, "1577D02987C63A95B51AE149430834AEAF3F2E0F4CF8C6887AC6C8D732D79482604FC18DA77A9CC1F54D8063EAE6E42A41B2E04D1663856D760EABECCFB783BAE1D43E1E02C5011E823B24F2918F98A4962A875D0DF94F8098A1A30DC941303F98ABA19E6F996597EDAD7F03CAB915ED4B58B7BAAD28C0B67593CDFCCB5399AB"}, + {"La Poste Autres Services", 0x07AB, "A6D99B8D902893B04F3F8DE56CB6BF24338FEE897C1BCE6DFD4EBD05B7B1A07FD2EB564BB4F7D35DBFE0A42966C2C137AD156E3DAB62904592BCA20C0BC7B8B1E261EF82D53F52D203843566305A49A22062DECC38C2FE3864CAD08E79219487651E2F79F1C9392B48CAFE1BFFAFF4802AE451E7A283E55A4026AD1E82DF1A15"}, + {"La Poste Autres Services", 0x07AB, "151adf821ead26405ae583a2e751e42a80f4afff1bfeca482b39c9f1792f1e65879421798ed0ca6438fec238ccde6220a2495a3066358403d2523fd582ef61e2b1b8c70b0ca2bc92459062ab3d6e15ad37c1c26629a4e0bf5dd3f7b44b56ebd27fa0b1b705bd4efd6dce1b7c89ee8f3324bfb66ce58d3f4fb09328908d9bd9a6"}, + {"France Telecom", 0x07AC, "C44DBCD92F9DCF42F4902A87335DBB35D2FF530CDB09814CFA1F4B95A1BD018D099BC6AB69F667B4922AE1ED826E72951AA3E0EAAA7D49A695F04F8CDAAE2D18D10D25BD529CBB05ABF070DC7C041EC35C2BA7F58CC4C349983CC6E11A5CBE828FB8ECBC26F08E1094A6B44C8953C8E1BAFD214DF3E69F430A98CCC75C03669D"}, + {"France Telecom", 0x07AC, "9d66035cc7cc980a439fe6f34d21fdbae1c853894cb4a694108ef026bcecb88f82be5c1ae1c63c9849c3c48cf5a72b5cc31e047cdc70f0ab05bb9c52bd250dd1182daeda8c4ff095a6497daaeae0a31a95726e82ede12a92b467f669abc69b098d01bda1954b1ffa4c8109db0c53ffd235bb5d33872a90f442cf9d2fd9bc4dc4"}, + {"EDF-GDF", 0x07AD, "B35193DBD2F88A21CDCFFF4BF84F7FC036A991A363DCB3E802407A5E5879DC2127EECFC520779E79E911394882482C87D09A88B0711CBC2973B77FFDAE40EA0001F595072708C558B484AB89D02BCBCB971FF1B80371C0BE30CB13661078078BB68EBCCA524B9DD55EBF7D47D9355AFC95511350CC1103A5DEE847868848B235"}, - {"demo", 0x0000, "BCEB2EB02E1C8E9999BC9603F8F91DA6084EA6E7C75BD18DD0CDBEDB21DA29F19E7311259DB0D190B1920186A8126B582D13ABA69958763ADA8F79F162C7379D6109D2C94AA2E041B383A74BBF17FFCC145760AA8B58BE3C00C52BA3BD05A9D0BE5BA503E6721FC4066D37A89BF072C97BABB26CF6B29633043DB4746F9D2175"}, + {"EDF-GDF", 0x07AD, "35b248888647e8dea50311cc50135195fc5a35d9477dbf5ed59d4b52cabc8eb68b0778106613cb30bec07103b8f11f97cbcb2bd089ab84b458c508270795f50100ea40aefd7fb77329bc1c71b0889ad0872c4882483911e9799e7720c5cfee2721dc79585e7a4002e8b3dc63a391a936c07f4ff84bffcfcd218af8d2db9351b3"}, {NULL, 0, NULL} }; @@ -1486,29 +1493,32 @@ const char *vigik_get_service(uint16_t service_code) { return vigik_rsa_pk[ARRAYLEN(vigik_rsa_pk) - 1].desc; } +static void reverse_array(const uint8_t *src, int src_len, uint8_t *dest) { + for (int i = 0; i < src_len; i++) { + dest[i] = src[(src_len - 1) - i]; + } +}; + int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len) { // iso9796 // Exponent V = 2 // n = The public modulus n is the product of the secret prime factors p and q. Its length is 1024 bits. - - // calc SHA1 -/* - uint8_t mask[128] = {0}; - uint8_t *pmask = mask; - int mask_cnt; - for (mask_cnt = 0; mask_cnt < sizeof(mask); mask_cnt += 4) { - uint8_t seed[13] = {0}; - sprintf((char*)seed, "seed%08u", mask_cnt); - sha1hash(seed, 12, pmask); - pmask += 4; - } -*/ - - PrintAndLogEx(INFO, "Raw..."); + PrintAndLogEx(INFO, "Raw"); print_hex_noascii_break(uid, uidlen, MFBLOCK_SIZE * 2); + PrintAndLogEx(INFO, "Raw signature"); + print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2); + + + uint8_t rev_sig[128]; + reverse_array(signature, signature_len, rev_sig); + +// param_gethex_to_eol("27f2850cd5e114b3c5f4cd12cd6e0d4f0b1fce9f75c991f482024c6b1f4a19b29063d722ef76a3710f02cdbd5196825162ac402e3641b5ce7374d9e358280283d4e30479f5285785ac61152d0e4611b28fbadbf6b4ba8aa7374b87fb5ea8c0ba51e41dcf50e96b65336a11e379342048ed66a61c8351051f9bad308249b3fb00", 0, rev_sig, 128, &rv); + + PrintAndLogEx(INFO, "Raw signature reverse"); + print_hex_noascii_break(rev_sig, signature_len, MFBLOCK_SIZE * 2); // t = 0xBC = Implicitly known // t = 0xCC = look at byte before to determine hash function @@ -1531,23 +1541,26 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature uint8_t i; bool is_valid = false; - mbedtls_mpi RN, E; - mbedtls_mpi_init(&RN); - - // exponent 2 - mbedtls_mpi_init(&E); - mbedtls_mpi_add_int(&E, &E, 2); - for (i = 0; i < ARRAYLEN(vigik_rsa_pk); i++) { if (vigik_rsa_pk[i].desc == NULL) { break; } + mbedtls_mpi RN, E; + mbedtls_mpi_init(&RN); + + // exponent 2 = even + mbedtls_mpi_init(&E); + mbedtls_mpi_add_int(&E, &E, 2); + + PrintAndLogEx(INFO, "\n\n--- RSA PUBLIC KEY ---\n"); int dl = 0; uint8_t n[PUBLIC_VIGIK_KEYLEN]; + memset(n, 0, sizeof(n)); param_gethex_to_eol(vigik_rsa_pk[i].n, 0, n, PUBLIC_VIGIK_KEYLEN, &dl); + // convert mbedtls_mpi N, s, sqr, res; mbedtls_mpi_init(&N); @@ -1557,29 +1570,24 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature mbedtls_mpi_read_binary(&N, (const unsigned char*)n, PUBLIC_VIGIK_KEYLEN); -/* - uint8_t demo_sig[128]; - param_gethex_to_eol("0C0C62D3523F2DA3972679D0348D9A5038E93AE3D19E97DF875DCC046B2637DBCE7D4CCC5967529AB96D27B6D9B41F5456E65EEA328FDB7DAE6F4E7DA0CFC1CFF8AB5A80CC7C9B9F487EC2B590CBC2F31AFDC5CF9C3478B93C46D575A0E08D21D965A9C4FCAFE3562D64B1C30706AF0D43288156DA3FF990CB040D5C0863F262", 0, demo_sig, 128, &dl); - mbedtls_mpi_read_binary(&s, (const unsigned char*)demo_sig, 128); -*/ - mbedtls_mpi_read_binary(&s, (const unsigned char*)signature, signature_len); + //mbedtls_mpi_read_binary(&s, (const unsigned char*)signature, signature_len); + mbedtls_mpi_read_binary(&s, (const unsigned char*)rev_sig, signature_len); // check is sign < (N/2) -/* + mbedtls_mpi n_2; mbedtls_mpi_init(&n_2); mbedtls_mpi_copy(&n_2, &N); mbedtls_mpi_shift_r(&n_2, 1); - bool is_less = (mbedtls_mpi_cmp_mpi(&s, &n_2) > 0) ? false : true; PrintAndLogEx(INFO, "z < (N/2) ..... %s", (is_less) ? _GREEN_("YES") : _RED_("NO")); - mbedtls_mpi_free(&n_2); -*/ -// if (is_less) { + + + if (is_less) { mbedtls_mpi_exp_mod(&sqr, &s, &E, &N, &RN); -// } - + } + /* if v is even and ⎯ if J* mod 8 = 1, then f* = n–J*. @@ -1592,6 +1600,25 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature uint8_t b0 = mbedtls_mpi_get_bit(&sqr, 0); uint8_t lsb = (b2 << 2) | (b1 << 1) | b0; + /* + //1 + mbedtls_mpi_sub_mpi(&res, &N, &sqr); + mbedtls_mpi_write_file( "[=] 1... ", &res, 16, NULL ); + // 4 + mbedtls_mpi_copy(&res, &sqr); + mbedtls_mpi_write_file( "[=] 4... ", &res, 16, NULL ); + // 6 + mbedtls_mpi_mul_int(&res, &sqr, 2); + mbedtls_mpi_write_file( "[=] 6... ", &res, 16, NULL ); + // 7 + mbedtls_mpi foo; + mbedtls_mpi_init(&foo); + mbedtls_mpi_sub_mpi(&foo, &N, &sqr); + mbedtls_mpi_mul_int(&res, &foo, 2); + mbedtls_mpi_free(&foo); + mbedtls_mpi_write_file( "[=] 7... ", &res, 16, NULL ); + */ + switch (lsb) { case 1: mbedtls_mpi_sub_mpi(&res, &N, &sqr); @@ -1603,42 +1630,75 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature mbedtls_mpi_mul_int(&res, &sqr, 2); break; case 7: - mbedtls_mpi foo; - mbedtls_mpi_init(&foo); - mbedtls_mpi_sub_mpi(&foo, &N, &sqr); - mbedtls_mpi_mul_int(&res, &foo, 2); - mbedtls_mpi_free(&foo); + mbedtls_mpi foo2; + mbedtls_mpi_init(&foo2); + mbedtls_mpi_sub_mpi(&foo2, &N, &sqr); + mbedtls_mpi_mul_int(&res, &foo2, 2); + mbedtls_mpi_free(&foo2); + break; + default: break; } PrintAndLogEx(INFO, "LSB............ " _GREEN_("%u"), lsb); - mbedtls_mpi_write_file( "E = 0x", &E, 16, NULL ); - mbedtls_mpi_write_file( "N = 0x", &N, 16, NULL ); + mbedtls_mpi_write_file( "[=] N.............. ", &N, 16, NULL ); mbedtls_mpi_write_file( "[=] signature...... ", &s, 16, NULL ); mbedtls_mpi_write_file( "[=] square mod n... ", &sqr, 16, NULL ); mbedtls_mpi_write_file( "[=] n-fs........... ", &res, 16, NULL ); - // mbedtls_mpi_write_file( "masked ", &, 16, NULL ); uint8_t nfs[128] = {0}; int bar = mbedtls_mpi_write_binary(&res, nfs, sizeof(nfs)); - if (bar != 0) - PrintAndLogEx(INFO, "FOO... %i", bar); - PrintAndLogEx(INFO, "converted to byte array"); - print_hex_noascii_break(nfs, sizeof(nfs), 32); - - /* - for (int x = 0; x < uidlen; x++) { - nfs[x] ^= uid[x]; + // xor + for (int x = 0; x < sizeof(nfs); x +=2) { + nfs[x] ^= 0xDC; + nfs[x+1] ^= 0x01; } - PrintAndLogEx(INFO, "xored set"); - print_hex_noascii_break(nfs, uidlen, 32); - */ + PrintAndLogEx(INFO, "Message XOR 0xDC01"); + print_hex_noascii_break(nfs, sizeof(nfs), 32); + PrintAndLogEx(INFO, "\n"); + if (bar == 12054235) { + typedef struct vigik_rsa_s { + uint8_t rsa[127]; + uint8_t hash; + } vigik_rsa_t; + + vigik_rsa_t *ts = (vigik_rsa_t*)nfs; + if ( ts->hash == 0xCC ) { + PrintAndLogEx(INFO, "Hash byte... 0x%02X", ts->hash); + switch(ts->rsa[126]) { + case 0x11: + PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - SHA1"); + break; + case 0x22: + PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - RIPEMD"); + break; + case 0x33: + PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - SHA1"); + break; + default: + PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - " _RED_("err")); + break; + } + } else if ( ts->hash == 0xBC) { + PrintAndLogEx(INFO, "Hash byte... 0x%02X - " _GREEN_("implict"), ts->hash); + } else { + PrintAndLogEx(INFO, "Hash byte... 0x%02x - " _RED_("err"), ts->hash); + } + + PrintAndLogEx(INFO, "Message w padding"); + print_hex_noascii_break(ts->rsa, sizeof(ts->rsa) - 20, 32); + + } + mbedtls_mpi_free(&N); mbedtls_mpi_free(&s); mbedtls_mpi_free(&res); + mbedtls_mpi_free(&RN); + mbedtls_mpi_free(&E); + /* int ret = 0; is_valid = (ret == 0); @@ -1647,9 +1707,6 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature */ } - mbedtls_mpi_free(&RN); - mbedtls_mpi_free(&E); - return PM3_ESOFT; PrintAndLogEx(INFO, ""); From 37100a8a1820f3d46dbea8f06328d76284203ce4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 4 Dec 2022 15:15:24 +0100 Subject: [PATCH 394/759] fix compilation error --- client/src/mifare/mifarehost.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index da2782102..0bd63831b 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1620,24 +1620,29 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature */ switch (lsb) { - case 1: + case 1: { mbedtls_mpi_sub_mpi(&res, &N, &sqr); break; - case 4: + } + case 4: { mbedtls_mpi_copy(&res, &sqr); break; - case 6: + } + case 6: { mbedtls_mpi_mul_int(&res, &sqr, 2); break; - case 7: + } + case 7: { mbedtls_mpi foo2; mbedtls_mpi_init(&foo2); mbedtls_mpi_sub_mpi(&foo2, &N, &sqr); mbedtls_mpi_mul_int(&res, &foo2, 2); mbedtls_mpi_free(&foo2); break; - default: + } + default: { break; + } } PrintAndLogEx(INFO, "LSB............ " _GREEN_("%u"), lsb); From d170f68a008d96d133373b3d0f3473faaf43a6eb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 4 Dec 2022 15:34:35 +0100 Subject: [PATCH 395/759] fix compilation error, and more debug statements --- client/src/mifare/mifarehost.c | 89 ++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 0bd63831b..5ce88123d 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1505,18 +1505,16 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature // Exponent V = 2 // n = The public modulus n is the product of the secret prime factors p and q. Its length is 1024 bits. - PrintAndLogEx(INFO, "Raw"); - print_hex_noascii_break(uid, uidlen, MFBLOCK_SIZE * 2); + if (g_debugMode == DEBUG) { + PrintAndLogEx(INFO, "Raw"); + print_hex_noascii_break(uid, uidlen, MFBLOCK_SIZE * 2); - PrintAndLogEx(INFO, "Raw signature"); - print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2); - - + PrintAndLogEx(INFO, "Raw signature"); + print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2); + } uint8_t rev_sig[128]; reverse_array(signature, signature_len, rev_sig); -// param_gethex_to_eol("27f2850cd5e114b3c5f4cd12cd6e0d4f0b1fce9f75c991f482024c6b1f4a19b29063d722ef76a3710f02cdbd5196825162ac402e3641b5ce7374d9e358280283d4e30479f5285785ac61152d0e4611b28fbadbf6b4ba8aa7374b87fb5ea8c0ba51e41dcf50e96b65336a11e379342048ed66a61c8351051f9bad308249b3fb00", 0, rev_sig, 128, &rv); - PrintAndLogEx(INFO, "Raw signature reverse"); print_hex_noascii_break(rev_sig, signature_len, MFBLOCK_SIZE * 2); @@ -1553,14 +1551,11 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature mbedtls_mpi_init(&E); mbedtls_mpi_add_int(&E, &E, 2); - - PrintAndLogEx(INFO, "\n\n--- RSA PUBLIC KEY ---\n"); int dl = 0; uint8_t n[PUBLIC_VIGIK_KEYLEN]; memset(n, 0, sizeof(n)); param_gethex_to_eol(vigik_rsa_pk[i].n, 0, n, PUBLIC_VIGIK_KEYLEN, &dl); - // convert mbedtls_mpi N, s, sqr, res; mbedtls_mpi_init(&N); @@ -1580,12 +1575,14 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature mbedtls_mpi_copy(&n_2, &N); mbedtls_mpi_shift_r(&n_2, 1); bool is_less = (mbedtls_mpi_cmp_mpi(&s, &n_2) > 0) ? false : true; - PrintAndLogEx(INFO, "z < (N/2) ..... %s", (is_less) ? _GREEN_("YES") : _RED_("NO")); + PrintAndLogEx(DEBUG, "z < (N/2) ..... %s", (is_less) ? _GREEN_("YES") : _RED_("NO")); mbedtls_mpi_free(&n_2); if (is_less) { mbedtls_mpi_exp_mod(&sqr, &s, &E, &N, &RN); + } else { + continue; } /* @@ -1641,39 +1638,56 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature break; } default: { - break; + continue; } } - PrintAndLogEx(INFO, "LSB............ " _GREEN_("%u"), lsb); - mbedtls_mpi_write_file( "[=] N.............. ", &N, 16, NULL ); - mbedtls_mpi_write_file( "[=] signature...... ", &s, 16, NULL ); - mbedtls_mpi_write_file( "[=] square mod n... ", &sqr, 16, NULL ); - mbedtls_mpi_write_file( "[=] n-fs........... ", &res, 16, NULL ); + PrintAndLogEx(DEBUG, "LSB............ " _GREEN_("%u"), lsb); + if (g_debugMode == DEBUG) { + mbedtls_mpi_write_file( "[=] N.............. ", &N, 16, NULL ); + mbedtls_mpi_write_file( "[=] signature...... ", &s, 16, NULL ); + mbedtls_mpi_write_file( "[=] square mod n... ", &sqr, 16, NULL ); + mbedtls_mpi_write_file( "[=] n-fs........... ", &res, 16, NULL ); + } + uint8_t nfs[128] = {0}; - int bar = mbedtls_mpi_write_binary(&res, nfs, sizeof(nfs)); + mbedtls_mpi_write_binary(&res, nfs, sizeof(nfs)); - // xor + // xor 0xDC01 + int count_zero = 0; for (int x = 0; x < sizeof(nfs); x +=2) { nfs[x] ^= 0xDC; nfs[x+1] ^= 0x01; + + if (nfs[x] == 0x00) + count_zero++; + if (nfs[x + 1] == 0x00) + count_zero++; } - PrintAndLogEx(INFO, "Message XOR 0xDC01"); - print_hex_noascii_break(nfs, sizeof(nfs), 32); - PrintAndLogEx(INFO, "\n"); + if (count_zero > 10) { + PrintAndLogEx(INFO, ""); + PrintAndLogEx(INFO, "Message XORED"); + print_hex_noascii_break(nfs, sizeof(nfs), 32); + PrintAndLogEx(INFO, "\n"); + is_valid = true; + break; + } - if (bar == 12054235) { + /* + if (bar == 0) { typedef struct vigik_rsa_s { uint8_t rsa[127]; uint8_t hash; } vigik_rsa_t; - vigik_rsa_t *ts = (vigik_rsa_t*)nfs; - if ( ts->hash == 0xCC ) { - PrintAndLogEx(INFO, "Hash byte... 0x%02X", ts->hash); - switch(ts->rsa[126]) { + vigik_rsa_t ts; + memcpy(&ts, nfs, sizeof(ts)); + + if ( ts.hash == 0xCC ) { + PrintAndLogEx(INFO, "Hash byte... 0x%02X", ts.hash); + switch(ts.rsa[126]) { case 0x11: PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - SHA1"); break; @@ -1687,33 +1701,24 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - " _RED_("err")); break; } - } else if ( ts->hash == 0xBC) { - PrintAndLogEx(INFO, "Hash byte... 0x%02X - " _GREEN_("implict"), ts->hash); + } else if ( ts.hash == 0xBC) { + PrintAndLogEx(INFO, "Hash byte... 0x%02X - " _GREEN_("implict"), ts.hash); } else { - PrintAndLogEx(INFO, "Hash byte... 0x%02x - " _RED_("err"), ts->hash); + PrintAndLogEx(INFO, "Hash byte... 0x%02x - " _RED_("err"), ts.hash); } PrintAndLogEx(INFO, "Message w padding"); - print_hex_noascii_break(ts->rsa, sizeof(ts->rsa) - 20, 32); - + print_hex_noascii_break(ts.rsa, sizeof(ts.rsa) - 20, 32); } + */ mbedtls_mpi_free(&N); mbedtls_mpi_free(&s); mbedtls_mpi_free(&res); mbedtls_mpi_free(&RN); mbedtls_mpi_free(&E); - - /* - int ret = 0; - is_valid = (ret == 0); - if (is_valid) - break; - */ } - return PM3_ESOFT; - PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); PrintAndLogEx(INFO, "RSA: 1024bit"); From b557291a00957dbb856736c3cea2bddc8bf904a3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 4 Dec 2022 19:28:22 +0100 Subject: [PATCH 396/759] print sectors for mifare --- client/src/cmdhfmf.c | 50 +++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index a2572df99..e5ab53d66 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -236,13 +236,13 @@ static bool mfc_value(const uint8_t *d, int32_t *val) { } return val_checks; } -static void mf_print_block(uint8_t blockno, uint8_t *d, bool verbose) { - if (blockno == 0) { + +static void mf_print_block_one(uint8_t blockno, uint8_t *d, bool verbose) { + if (blockno == 0) { PrintAndLogEx(INFO, "%3d | " _RED_("%s"), blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); } else if (mfIsSectorTrailer(blockno)) { PrintAndLogEx(INFO, "%3d | " _YELLOW_("%s"), blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); } else { - int32_t value = 0; if (verbose && mfc_value(d, &value)) { PrintAndLogEx(INFO, "%3d | " _CYAN_("%s") " %"PRIi32, blockno, sprint_hex_ascii(d, MFBLOCK_SIZE), value); @@ -252,15 +252,37 @@ static void mf_print_block(uint8_t blockno, uint8_t *d, bool verbose) { } } +static void mf_print_block(uint8_t blockno, uint8_t *d, bool verbose) { + uint8_t sectorno = mfSectorNum(blockno); + + char secstr[6] = " "; + if (mfFirstBlockOfSector(sectorno) == blockno) { + sprintf(secstr, " %3d ", sectorno); + } + + if (blockno == 0) { + PrintAndLogEx(INFO, "%s| %3d | " _RED_("%s"), secstr, blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); + } else if (mfIsSectorTrailer(blockno)) { + PrintAndLogEx(INFO, "%s| %3d | " _YELLOW_("%s"), secstr, blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); + } else { + int32_t value = 0; + if (verbose && mfc_value(d, &value)) { + PrintAndLogEx(INFO, "%s| %3d | " _CYAN_("%s") " %"PRIi32, secstr, blockno, sprint_hex_ascii(d, MFBLOCK_SIZE), value); + } else { + PrintAndLogEx(INFO, "%s| %3d | %s ", secstr, blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); + } + } +} + static void mf_print_blocks(uint16_t n, uint8_t *d, bool verbose) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "----+-------------------------------------------------+-----------------"); - PrintAndLogEx(INFO, "blk | data | ascii"); - PrintAndLogEx(INFO, "----+-------------------------------------------------+-----------------"); + PrintAndLogEx(INFO, "-----+-----+-------------------------------------------------+-----------------"); + PrintAndLogEx(INFO, " sec | blk | data | ascii"); + PrintAndLogEx(INFO, "-----+-----+-------------------------------------------------+-----------------"); for (uint16_t i = 0; i < n; i++) { mf_print_block(i, d + (i * MFBLOCK_SIZE), verbose); } - PrintAndLogEx(INFO, "----+-------------------------------------------------+-----------------"); + PrintAndLogEx(INFO, "-----+-----+-------------------------------------------------+-----------------"); PrintAndLogEx(HINT, _CYAN_("cyan") " = value block with decoded value"); // MAD detection @@ -589,7 +611,7 @@ static int CmdHF14AMfRdBl(const char *Cmd) { uint8_t sector = mfSectorNum(blockno); mf_print_sector_hdr(sector); - mf_print_block(blockno, data, verbose); + mf_print_block_one(blockno, data, verbose); if (verbose) { decode_print_st(blockno, data); } @@ -652,7 +674,7 @@ static int CmdHF14AMfRdSc(const char *Cmd) { mf_print_sector_hdr(sector); for (int i = 0; i < blocks; i++) { - mf_print_block(start + i, data + (i * MFBLOCK_SIZE), verbose); + mf_print_block_one(start + i, data + (i * MFBLOCK_SIZE), verbose); } if (verbose) { @@ -3821,7 +3843,7 @@ static int CmdHF14AMfEGetBlk(const char *Cmd) { uint8_t sector = mfSectorNum(blockno); mf_print_sector_hdr(sector); - mf_print_block(blockno, data, verbose); + mf_print_block_one(blockno, data, verbose); } if (verbose) { decode_print_st(blockno, data); @@ -3863,7 +3885,7 @@ static int CmdHF14AMfEGetSc(const char *Cmd) { for (int i = 0; i < blocks; i++) { int res = mfEmlGetMem(data, start + i, 1); if (res == PM3_SUCCESS) { - mf_print_block(start + i, data, verbose); + mf_print_block_one(start + i, data, verbose); } } if (verbose) { @@ -4811,7 +4833,7 @@ static int CmdHF14AMfCGetBlk(const char *Cmd) { uint8_t sector = mfSectorNum(blockno); mf_print_sector_hdr(sector); - mf_print_block(blockno, data, verbose); + mf_print_block_one(blockno, data, verbose); if (verbose) { decode_print_st(blockno, data); @@ -4864,7 +4886,7 @@ static int CmdHF14AMfCGetSc(const char *Cmd) { PrintAndLogEx(ERR, "Can't read block. %d error=%d", start + i, res); return PM3_ESOFT; } - mf_print_block(start + i, data, verbose); + mf_print_block_one(start + i, data, verbose); } if (verbose) { decode_print_st(start + blocks - 1, data); @@ -6893,7 +6915,7 @@ static int CmdHF14AGen4GetBlk(const char *cmd) { uint8_t sector = mfSectorNum(blockno); mf_print_sector_hdr(sector); - mf_print_block(blockno, data, verbose); + mf_print_block_one(blockno, data, verbose); if (verbose) { decode_print_st(blockno, data); From 2f4167ee7406f471560924ef53142f73851a46c9 Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Sun, 4 Dec 2022 22:25:54 +0100 Subject: [PATCH 397/759] Consider different behavior of some Gen4 cards. Should fix #1822 --- armsrc/mifarecmd.c | 4 ++-- client/luascripts/hf_mf_ultimatecard.lua | 2 +- doc/magic_cards_notes.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index f5e649a2a..3db9112af 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2391,11 +2391,11 @@ void MifareCIdent(bool is_mfc) { if (res == 2) { // Check for Magic Gen4 GTU with default password : - // Get config should return 30 bytes. + // Get config should return 30 or 32 bytes AddCrc14A(gen4GetConf, sizeof(gen4GetConf) - 2); ReaderTransmit(gen4GetConf, sizeof(gen4GetConf), NULL); res = ReaderReceive(buf, par); - if (res == 32) { + if (res == 32 || res == 34) { isGen = MAGIC_GEN_4GTU; goto OUT; } diff --git a/client/luascripts/hf_mf_ultimatecard.lua b/client/luascripts/hf_mf_ultimatecard.lua index b9011c36f..4a70935bb 100644 --- a/client/luascripts/hf_mf_ultimatecard.lua +++ b/client/luascripts/hf_mf_ultimatecard.lua @@ -186,7 +186,7 @@ local function read_config() atqaf = atqa1..' '..atqa2 cardtype, cardprotocol, gtustr, atsstr = 'unknown', 'unknown', 'unknown', 'unknown' if magicconfig == nil then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end - if #magicconfig ~= 64 then lib14a.disconnect(); return nil, "partial read of configuration, "..err_lock end + if #magicconfig ~= 64 and #magicconfig ~= 68 then lib14a.disconnect(); return nil, "partial read of configuration, "..err_lock end if gtumode == '00' then gtustr = 'Pre-write/Shadow Mode' elseif gtumode == '01' then gtustr = 'Restore Mode' elseif gtumode == '02' then gtustr = 'Disabled' diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 7b494d65c..c8decbfe2 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -1009,7 +1009,7 @@ The card will be identified only if the password is the default one. One can ide ``` hf 14a raw -s -c -t 1000 CF00000000C6 ``` -If the card is an Ultimate Magic Card, it returns 30 bytes. +If the card is an Ultimate Magic Card, it returns 30 or 32 bytes. ### Magic commands ^[Top](#top) ^^[Gen4](#g4top) @@ -1133,7 +1133,7 @@ hf 14a raw -s -c -t 1000 CF00000000CE02 ... ``` -👉 **TODO** In Mifare Ultralight / NTAG mode, the special writes (option -s, -e, -r) do not apply. Use `script run hf_mf_ultimatecard` for UID and signature, and `hf mfu wrbl` for PWD and PACK. +👉 **TODO** In Mifare Ultralight / NTAG mode, the special writes (`hf mfu restore` option `-s`, `-e`, `-r`) do not apply. Use `script run hf_mf_ultimatecard` for UID and signature, and `hf mfu wrbl` for PWD and PACK. ### Change ATQA / SAK ^[Top](#top) ^^[Gen4](#g4top) From b70320d47d9d1f05397747efc39f4efb88fe0d34 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Sun, 4 Dec 2022 21:30:12 +0100 Subject: [PATCH 398/759] Fixing some ISO7816-4 logic. - Fixing overflow in BigBuffer if requesting to much data - Fixing integer wrapping with the SIM module by capping APDU data length - Fixing chaining logic which was loosing previously received data --- client/src/cmdsmartcard.c | 25 ++++++++++++++++++++----- client/src/cmdsmartcard.h | 5 +++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index 495b20015..92495f9cf 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -317,6 +317,7 @@ static int smart_wait(uint8_t *out, int maxoutlen, bool verbose) { static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) { int datalen = smart_wait(out, maxoutlen, verbose); + int totallen = datalen; bool needGetData = false; if (datalen < 2) { @@ -327,8 +328,21 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) { needGetData = true; } - if (needGetData) { + if (needGetData == true) { + // Don't discard data we already received except the SW code + totallen -= 2; + int ofs = totallen; + maxoutlen -= totallen; + int len = out[datalen - 1]; + if (len == 0 || len > MAX_APDU_SIZE) { + // Cap the data length or the smartcard may send us a buffer we can't handle + len = MAX_APDU_SIZE; + } + if (maxoutlen < len) { + // We don't have enough buffer to hold the next part + goto out; + } if (verbose) PrintAndLogEx(INFO, "Requesting " _YELLOW_("0x%02X") " bytes response", len); @@ -342,7 +356,7 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) { SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + sizeof(cmd_getresp)); free(payload); - datalen = smart_wait(out, maxoutlen, verbose); + datalen = smart_wait(&out[ofs], maxoutlen, verbose); if (datalen < 2) { goto out; @@ -352,7 +366,7 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) { if (datalen != len + 2) { // data with ACK if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK - if (out[0] != ISO7816_GET_RESPONSE) { + if (out[ofs] != ISO7816_GET_RESPONSE) { if (verbose) { PrintAndLogEx(ERR, "GetResponse ACK error. len 0x%x | data[0] %02X", len, out[0]); } @@ -361,7 +375,8 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) { } datalen--; - memmove(out, &out[1], datalen); + memmove(&out[ofs], &out[ofs + 1], datalen); + totallen += datalen; } else { // wrong length if (verbose) { @@ -372,7 +387,7 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) { } out: - return datalen; + return totallen; } static int smart_response(uint8_t *out, int maxoutlen) { diff --git a/client/src/cmdsmartcard.h b/client/src/cmdsmartcard.h index 65e6ba1c1..72c40fa3b 100644 --- a/client/src/cmdsmartcard.h +++ b/client/src/cmdsmartcard.h @@ -22,6 +22,11 @@ #include "common.h" #include "pm3_cmd.h" // structs +// On ARM side, ISO7816_MAX_FRAME is set to 255 +// This means we can't receive more than 250 bytes of data to leave enough room for +// SW status code and surrounding metadata without creating a buffer overflow. +#define MAX_APDU_SIZE 250 + int CmdSmartcard(const char *Cmd); bool smart_select(bool verbose, smart_card_atr_t *atr); From c2aed7900c1a799dfe00ee8387940f0c26d9000d Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Sun, 4 Dec 2022 21:31:06 +0100 Subject: [PATCH 399/759] Temporary fix buffer overflow until new SIM firmware is released --- armsrc/i2c.c | 25 ++++++++++++++----------- armsrc/i2c.h | 6 +++--- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 12d7c9cd2..b79f8bb0e 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -53,7 +53,7 @@ static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { #define I2C_DELAY_2CLK I2CSpinDelayClk(2) #define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x)) -#define ISO7618_MAX_FRAME 255 +#define ISO7618_MAX_FRAME 260 // try i2c bus recovery at 100kHz = 5us high, 5us low void I2C_recovery(void) { @@ -395,8 +395,8 @@ bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address) { } //Sends array of data (Array, length, command to be written , SlaveDevice address ). -// len = uint8 (max buffer to write 256bytes) -bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) { +// len = uint16 because we need to write up to 256 bytes +bool I2C_BufferWrite(uint8_t *data, uint16_t len, uint8_t device_cmd, uint8_t device_address) { bool bBreak = true; do { if (!I2C_Start()) @@ -433,8 +433,8 @@ bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t dev } // read one array of data (Data array, Readout length, command to be written , SlaveDevice address ). -// len = uint8 (max buffer to read 256bytes) -int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) { +// len = uint16 because we need to read up to 256bytes +int16_t I2C_BufferRead(uint8_t *data, uint16_t len, uint8_t device_cmd, uint8_t device_address) { if (!data || len == 0) return 0; @@ -631,7 +631,7 @@ int I2C_get_version(uint8_t *maj, uint8_t *min) { } // Will read response from smart card module, retries 3 times to get the data. -bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen) { +bool sc_rx_bytes(uint8_t *dest, uint16_t *destlen) { uint8_t i = 5; int16_t len = 0; @@ -656,7 +656,7 @@ bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen) { if (len <= 1) return false; - *destlen = (uint8_t)len & 0xFF; + *destlen = len; return true; } @@ -678,7 +678,10 @@ bool GetATR(smart_card_atr_t *card_ptr, bool verbose) { return false; // read bytes from module - uint8_t len = sizeof(card_ptr->atr); + uint16_t len = sizeof(card_ptr->atr); + if (len > sizeof(card_ptr->atr)) { + len = sizeof(card_ptr->atr); + } if (sc_rx_bytes(card_ptr->atr, &len) == false) return false; @@ -697,7 +700,7 @@ bool GetATR(smart_card_atr_t *card_ptr, bool verbose) { uint8_t chksum = 0; // xor property. will be zero when xored with chksum. - for (uint8_t i = 1; i < len; ++i) + for (uint16_t i = 1; i < len; ++i) chksum ^= card_ptr->atr[i]; if (chksum) { @@ -706,7 +709,7 @@ bool GetATR(smart_card_atr_t *card_ptr, bool verbose) { } } - card_ptr->atr_len = len; + card_ptr->atr_len = (uint8_t) (len & 0xff); if (verbose) { LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false); } @@ -732,7 +735,7 @@ void SmartCardAtr(void) { void SmartCardRaw(smart_card_raw_t *p) { LED_D_ON(); - uint8_t len = 0; + uint16_t len = 0; uint8_t *resp = BigBuf_malloc(ISO7618_MAX_FRAME); // check if alloacted... smartcard_command_t flags = p->flags; diff --git a/armsrc/i2c.h b/armsrc/i2c.h index c1b6ada03..2ce051bd7 100644 --- a/armsrc/i2c.h +++ b/armsrc/i2c.h @@ -41,14 +41,14 @@ void I2C_Reset_EnterBootloader(void); bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address); bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address); -bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address); -int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address); +bool I2C_BufferWrite(uint8_t *data, uint16_t len, uint8_t device_cmd, uint8_t device_address); +int16_t I2C_BufferRead(uint8_t *data, uint16_t len, uint8_t device_cmd, uint8_t device_address); // for firmware int16_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address); bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address); -bool sc_rx_bytes(uint8_t *dest, uint8_t *destlen); +bool sc_rx_bytes(uint8_t *dest, uint16_t *destlen); // bool GetATR(smart_card_atr_t *card_ptr, bool verbose); From 38cb327991501325aab6b24310e5428dc0369ab0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 5 Dec 2022 19:28:42 +0100 Subject: [PATCH 400/759] fix #1829 Py_SetProgramName is deprecated, but was optional in our code. --- client/src/cmdscript.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index 96d1f3637..c63842ae3 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -407,7 +407,7 @@ static int CmdScriptRun(const char *Cmd) { } // optional but recommended - Py_SetProgramName(program); + //Py_SetProgramName(program); #ifdef HAVE_PYTHON_SWIG // hook Proxmark3 API PyImport_AppendInittab("_pm3", PyInit__pm3); From 89702a4e6e26ed30e2f211ce14add29c2c6adda9 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Mon, 5 Dec 2022 19:33:41 +0100 Subject: [PATCH 401/759] Add SIM module firmware 4.12 from Sentinel --- client/resources/sim012.sha512.txt | 1 + tools/simmodule/sim012.asm | 817 +++++++++++++++++++++++++++++ 2 files changed, 818 insertions(+) create mode 100644 client/resources/sim012.sha512.txt create mode 100644 tools/simmodule/sim012.asm diff --git a/client/resources/sim012.sha512.txt b/client/resources/sim012.sha512.txt new file mode 100644 index 000000000..fdd509b54 --- /dev/null +++ b/client/resources/sim012.sha512.txt @@ -0,0 +1 @@ +ac65f93b15dea4e6a27a644056c18266113af57f4d29de9eead4871007816efa7d1ec9f73308377e5fe388fc81b3d408221bd4eff7e1d129e0a349bd2c0f3f2b sim012.bin diff --git a/tools/simmodule/sim012.asm b/tools/simmodule/sim012.asm new file mode 100644 index 000000000..5cec3b2f2 --- /dev/null +++ b/tools/simmodule/sim012.asm @@ -0,0 +1,817 @@ +; --------------------------------------------------------------------------- +; Proxmark3 RDV4 SIM module firmware +; +; Copyright (C) 2022 Sentinel +; +; This program is free software: you can redistribute it and/or modify it +; under the terms of the GNU Lesser General Public License as published by the +; Free Software Foundation, either version 3 of the License, or (at your +; option) any later version. +; +; This program is distributed in the hope that it will be useful, but WITHOUT +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +; more details. +; +; You should have received a copy of the GNU Lesser General Public License +; along with this program. If not, see +; --------------------------------------------------------------------------- +; + VERS_HI equ 4 + VERS_LO equ 12 +; +; +; + SCON_0 equ 098h + FE_0 equ 098h.7 + + SCON_1 equ 0F8h + RI_1 equ 0F8h.0 + TI_1 equ 0F8h.1 + FE_1 equ 0F8h.7 + SBUF_1 equ 09Ah + T3CON equ 0C4h + RL3 equ 0C5h + RH3 equ 0C6h + + P0M1 equ 0B1h + P0M2 equ 0B2h + P1M1 equ 0B3h + P1M2 equ 0B4h + P3M1 equ 0ACh; + P3M2 equ 0ADh; + + EIE equ 09Bh + EIE1 equ 09Ch + + TA equ 0C7h + + RCTRIM0 equ 084h +; + CKCON equ 08Eh + CKDIV equ 095h +; + P1S equ 0B3h ;Page1 + SFRS equ 091h ;TA Protection +; + ;AUXR1 equ 0A2h +; + I2DAT equ 0BCh; + I2STAT equ 0BDh; + I2CLK equ 0BEh; + I2TOC equ 0BFh; + I2CON equ 0C0h; + ; equ I2CON.7;8 + I2CEN equ I2CON.6;4 + STA equ I2CON.5;2 + STO equ I2CON.4;1 + SI equ I2CON.3;8 + AA equ I2CON.2;4 + ; equ I2CON.1;2 + I2CPX equ I2CON.0;1 + + + I2ADDR equ 0C1h; + +; +; +; + pin_TX1 equ P1.6 + + pin_TX0 equ P0.6 + pin_RX0 equ P0.7 + + pin_SCL equ P1.3 + pin_SDA equ P1.4 + + pin_RST equ P1.0 + pin_CLC equ P1.1 + pin_led equ P1.2 + +; +; + + + CMD_GENERATE_ATR equ 01h + CMD_WRITE_DATA_SIM equ 02h + CMD_READ_DATA_SIM equ 03h + + CMD_SET_BAUD_RATE equ 04h + CMD_SET_SIM_CLC equ 05h + CMD_GET_VERS equ 06h + CMD_WRITE_CONFIRM equ 07h + + + +; +; + + bit_RX0 equ 32.0 + bit_command_receive equ 32.1 + bit_generate_ATR equ 32.2 + i2c_write_mode equ 32.3 + i2c_write_done equ 32.4 + bit_data_sim_wr equ 32.5 + ; equ 32.6 + bit_TX0 equ 32.7 + + bit_command_buff equ 33.0 + i2c_write_command equ 33.1 + i2c_command_done equ 33.2 + bit_wait_confirm equ 33.3 + bit_first_ATR equ 33.4 ;11/03/2019 + bit_length_answerH equ 33.5 + bit_length_answerL equ 33.6 +; +; +; + bit_32 equ 32 + bit_33 equ 33 + + time_data_read equ 34 + time_confirm equ 35 + + pointer_RX1H equ 36 ;save SBUF(SIM) to XRAM + pointer_RX1L equ 37 ;save SBUF(SIM) to XRAM + + pointer_RX2H equ 38 ;read XRAM to I2C + pointer_RX2L equ 39 ;read XRAM to I2C + + pointer_TXH equ 40 + pointer_TXL equ 41 + + length_send_to_simH equ 42 + length_send_to_simL equ 43 + + length_answer_simH equ 44 + length_answer_simL equ 45 + + length_command equ 46 + + buff_command equ 47 + cmd_command equ 48 + data_command equ 49 + + STACKKKKK equ 200 +; +; + XRAM_TX_BUFF equ 0 + XRAM_RX_BUFF equ 384 +; +; +; + +; +; +; +; 砫 ᭮ ணࠬ + cseg at 00 + Ljmp main_start + +; +; +; + cseg at 11 ;1302Hz = 4MHZ(Fsys)/12/256 +; + jb time_confirm.7, $+3+2 ;3 + dec time_confirm ;2 +; + jb time_data_read.7,reti_timer0 + djnz time_data_read, reti_timer0 + setb pin_scl +reti_timer0: + reti + + +; +; +; + cseg at 35 ;UART0 + ajmp jmp_UART0_interrupt + +; +; +; + cseg at 51 ;I2C + ajmp jmp_i2c_interrupt + +; +; +; + cseg at 123 ;UART1 + clr RI_1 + clr TI_1 + reti + +; +; +; +jmp_UART0_interrupt: + jbc RI,jmp_byte_RI + jbc TI,jmp_byte_TI + reti +; +jmp_byte_RI: + jnb bit_first_ATR, jmp_not_collect ;11/03/2019 + + setb bit_RX0 + jb i2c_write_done,jmp_not_collect + PUSH ACC + PUSH DPH + PUSH DPL + mov DPL,pointer_RX1L + mov DPH,pointer_RX1H + mov a,SBUF + movx @DPTR,a + inc DPTR + mov pointer_RX1L,DPL + mov pointer_RX1H,DPH + POP DPL + POP DPH + POP ACC + ;09/08/2018 + clr pin_scl + mov time_data_read,#52 ;52/1302Hz = 40mS + + inc length_answer_simL + mov a,length_answer_simL + jnz $+2+2 ;2 + inc length_answer_simH ;2 + +jmp_not_collect: + reti +; +jmp_byte_TI: + setb bit_TX0 + reti + + +; +; +jmp_i2c_interrupt: + PUSH ACC + PUSH PSW + mov PSW,#24 + mov R7,I2STAT +; +; +; + cjne R7,#000h,nextttt00000 + setb STO + clr SI + jb STO,$ + ajmp pop_i2c_psw +nextttt00000: +; +; +; + cjne R7,#060h,nextttt00001 ;START+MY ADRESS + clr pin_led ;LED ON + + clr bit_command_receive + clr i2c_write_mode + clr bit_data_sim_wr + clr bit_length_answerH + clr bit_length_answerL + clr bit_command_buff + clr i2c_write_command + + ajmp end_i2c_interrupt +nextttt00001: +; +; +; +; +; + cjne R7,#080h,nextttt00002 ;RAM ADRESS + + jb bit_command_receive,jmp_data_receive + setb bit_command_receive + + mov a,I2DAT +; +; +; + cjne a,#CMD_WRITE_CONFIRM,next_comm001a + setb bit_wait_confirm + ajmp WRITEDATASIM +next_comm001a: +; + cjne a,#CMD_WRITE_DATA_SIM,next_comm001b + clr bit_wait_confirm + ajmp WRITEDATASIM +next_comm001b: +; + cjne a,#CMD_GENERATE_ATR,next_comm002 + ajmp ATR_GENERATE +next_comm002: +; + cjne a,#CMD_GET_VERS,next_comm003 + ajmp ANSWER_VERS +next_comm003: +; + cjne a,#CMD_SET_BAUD_RATE,next_comm004 + ajmp BAUD_RATE_SET +next_comm004: +; + cjne a,#CMD_SET_SIM_CLC,next_comm005 + ajmp SIM_CLC_SET +next_comm005: +; + ajmp end_i2c_interrupt +; +; +; +; +jmp_data_receive: + ;What receive ? Data to SIM/Command to bridge + jb bit_data_sim_wr, jmp_data_sim_receive + jb i2c_write_command,jmp_comm_bridge_receive + ajmp end_i2c_interrupt +; +jmp_comm_bridge_receive: + mov @R0,I2DAT + inc R0 + inc length_command + ajmp end_i2c_interrupt +; +jmp_data_sim_receive: + + setb i2c_write_mode + + PUSH DPH + PUSH DPL + mov DPL,pointer_TXL + mov DPH,pointer_TXH + mov a,I2DAT + movx @DPTR,a + inc DPTR + mov pointer_TXL,DPL + mov pointer_TXH,DPH + POP DPL + POP DPH + + inc length_send_to_simL + mov a,length_send_to_simL + jnz $+2+2 ;2 + inc length_send_to_simH ;2 + + ajmp end_i2c_interrupt +nextttt00002: +; +; +; + cjne R7,#0A0h,nextttt00003 ;STOP + setb pin_led ;LED OFF + + ;Command finish ? + jnb i2c_write_command,jmp_not_command + clr i2c_write_command + setb i2c_command_done +jmp_not_command: + + ;data to SIM finish ? + jnb i2c_write_mode,end_i2c_interrupt + clr i2c_write_mode + + setb i2c_write_done + ;Prepare to answer + mov length_answer_simH,#0 + mov length_answer_simL,#0 + mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX1L,#LOW (XRAM_RX_BUFF) + mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX2L,#LOW (XRAM_RX_BUFF) + + ajmp end_i2c_interrupt +nextttt00003: +; +; +; + cjne R7,#0A8h,nextttt00004 + sjmp read_byte_I2C +nextttt00004: +; +; +; + cjne R7,#0B8h,nextttt00005 +read_byte_I2C: + jnb bit_command_buff,jmp_not_comm_buff2 + mov I2DAT,@R0 + inc R0 + ajmp end_i2c_interrupt + +jmp_not_comm_buff2: + jb bit_length_answerH,jmp_not_comm_buff3 + setb bit_length_answerH + mov I2DAT,length_answer_simH + ajmp end_i2c_interrupt + +jmp_not_comm_buff3: + jb bit_length_answerL,read_byte_APROM + setb bit_length_answerL + mov I2DAT,length_answer_simL + ajmp end_i2c_interrupt + +read_byte_APROM: + PUSH DPH + PUSH DPL + mov DPL,pointer_RX2L + mov DPH,pointer_RX2H + movx a,@DPTR + mov I2DAT,a + inc DPTR + mov pointer_RX2L,DPL + mov pointer_RX2H,DPH + POP DPL + POP DPH + +nextttt00005: +; +; +; +end_i2c_interrupt: + clr STA + clr STO + setb AA +; +; +; +pop_i2c_psw: + POP PSW + POP ACC + clr SI + reti + + +; +; +; +ANSWER_VERS: + mov R0,#data_command + mov cmd_command,#CMD_GET_VERS + mov (data_command+0),#2 + mov (data_command+1),#VERS_HI + mov (data_command+2),#VERS_LO + setb bit_command_buff + ajmp end_i2c_interrupt + +; +; +; +ATR_GENERATE: + setb bit_generate_ATR + ;Prepare to answer + mov length_answer_simH,#0 + mov length_answer_simL,#0 + mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX1L,#LOW (XRAM_RX_BUFF) + mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX2L,#LOW (XRAM_RX_BUFF) + ajmp end_i2c_interrupt + + +; +; +; +BAUD_RATE_SET: + mov R0,#data_command + mov length_command,#0 + mov cmd_command,#CMD_SET_BAUD_RATE + setb i2c_write_command + ajmp end_i2c_interrupt + + +; +; +; +SIM_CLC_SET: + mov R0,#data_command + mov length_command,#0 + mov cmd_command,#CMD_SET_SIM_CLC + setb i2c_write_command + ajmp end_i2c_interrupt + +; +; +; +WRITEDATASIM: + mov length_send_to_simH,#0 + mov length_send_to_simL,#0 + setb bit_data_sim_wr + mov pointer_TXH,#HIGH(XRAM_TX_BUFF) + mov pointer_TXL,#LOW (XRAM_TX_BUFF) + ajmp end_i2c_interrupt + +; +; +; +; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +main_start: + mov SP,#STACKKKKK +; + ;0-bidirect 1-push pull 0-input only 1-open drain + ;0 0 1 1 +; + mov P0M2,#01000000b ;0 + mov P0M1,#11111111b ;P1.6-Tx0 SIM; + ; + mov P1M2,#01011111b ;1 + mov P1M1,#10111000b ;P1.6-Tx1 DEBUG; P1.4,P1.3 - I2C; + + mov P3M2,#00000000b ;P3 + mov P3M1,#11111111b ; +; + mov TMOD, #22h + mov TH0, #0 ;14400hz + mov TH1, #0E9h ;UART0 10800 Bit/sec + mov TCON, #55h +; +; + mov TA,#0AAh + mov TA,#055h + orl SFRS,#00000001b + + mov P1S, #00010000b ;P1.4 trigger schmiddt + + mov TA,#0AAh + mov TA,#055h + anl SFRS,#11111110b +; +; +; + ;------- CONFIG I2C --------- + mov I2CON, #44h ;set AA, set I2C enable + setb pin_sda + setb pin_scl + mov I2ADDR,#0C0h +; +; +; +; +; + ;mov SCON, #050h ;UART0 8bit + mov SCON, #0D0h ;UART0 9bit + ;mov PCON, #11000000b;FE_0 enable + mov PCON, #10000000b;FE_0 disable +; + mov SCON_1,#050h ;UART1 + ;mov T3CON, #01101000b;FE_1 enable TIMER3 UART0 BAUD + ;mov T3CON, #00101000b;FE_1 disable TIMER3 UART0 BAUD + mov T3CON, #00001000b;FE_1 disable TIMER1 UART0 BAUD + ;mov RL3,#0E9h ;10800/21600 + ;mov RH3,#0FFh +; + ;UART1 + mov RL3,#0F7h ;27777/55556 + mov RH3,#0FFh +; +; +; + mov CKDIV,#2 ;Fsys=4.00MHZ + ;mov CKDIV,#1 ;Fsys=8.00MHZ +; + mov bit_32,#0 + mov bit_33,#0 + setb time_data_read.7 +; + ;orl CKCON,#00000010b ;ENABLE CLC TIMER1 Fsys/12 + orl CKCON,#00010010b ;ENABLE CLC TIMER1 Fsys +; + ;mov a,RCTRIM0 + ;add a,#31 + ;mov TA,#0AAh + ;mov TA,#055h + ;mov RCTRIM0,a +; +; + acall clr_buffer +; + mov EIE, #00000001b ;I2C Interrupt + ;mov IE, #10010000b ;EA, SERIAL0 + mov IE, #10010010b ;EA, SERIAL0, TIMER0 +; +; +; +; +; +main_loop: + acall control_ATR + acall control_send_to_sim + acall control_command + sjmp main_loop + +; +; +; +control_command: + jbc i2c_command_done,$+3+1 ;3 + ret ;1 +; +; + ;Control Length command=1 + mov a,length_command + cjne a,#1,next_commandEND ;error length_command != 1 +; +; + mov a,cmd_command + cjne a,#CMD_SET_BAUD_RATE,next_command001 + mov TH1,data_command ;Timer1 HIGH byte + ret +next_command001: +; + cjne a,#CMD_SET_SIM_CLC, next_command002 + mov CKDIV,data_command ;Fsys DIV + ret +next_command002: +; +next_commandEND: + ret + +; +; +; +control_send_to_sim: + jb i2c_write_done,$+3+1 ;3 + ret ;1 +; +; + jbc bit_wait_confirm,jmp_wait_confirm +; +; + mov DPTR,#XRAM_TX_BUFF +looop_send: + movx a,@DPTR + inc DPTR + acall for_coooooom0 + + clr c + mov a,length_send_to_simL + subb a,#1 + mov length_send_to_simL,a + mov a,length_send_to_simH + subb a,#0 + mov length_send_to_simH,a + orl a,length_send_to_simL + jnz looop_send +; +; + jnb bit_RX0,$ + clr i2c_write_done + ret + + +; +; +; +jmp_wait_confirm: + mov DPTR,#(XRAM_TX_BUFF+1) + movx a,@DPTR + mov R3,a + mov R4,#5 +; + mov DPTR,#XRAM_TX_BUFF +looop_seend: + movx a,@DPTR + inc DPTR + acall for_coooooom0 + djnz R4,jmp_not_5byte + + jnb bit_RX0,$ + clr bit_RX0 + ;18/12/2018 + mov time_confirm,#65 ;New timeout 50mS +looop_waitconf: + jb time_confirm.7,jmp_no_answer + jnb bit_RX0,looop_waitconf + + ;clr pin_scl ;TEST PULSE! + mov a,SBUF + xrl a,R3 + ;setb pin_scl ;TEST PULSE! + + jnz jmp_no_correct_answer ;18/12/2018 + + ;pause for next byte 17/12/2018 + mov R7,#0 + djnz R7,$ ;~260mkSec + djnz R7,$ ;~260mkSec + djnz R7,$ ;~260mkSec + +jmp_not_5byte: + + clr c + mov a,length_send_to_simL + subb a,#1 + mov length_send_to_simL,a + mov a,length_send_to_simH + subb a,#0 + mov length_send_to_simH,a + orl a,length_send_to_simL + jnz looop_seend +; +; + jnb bit_RX0,$ + clr bit_RX0 +jmp_no_answer: + clr i2c_write_done + ret + +; +; +;18/12/2018 +jmp_no_correct_answer: + clr EA + clr i2c_write_done + + mov DPL,pointer_RX1L + mov DPH,pointer_RX1H + mov a,SBUF + movx @DPTR,a + inc DPTR + mov pointer_RX1L,DPL + mov pointer_RX1H,DPH + + clr pin_scl + mov time_data_read,#52 ;52/1302Hz = 40mS + + inc length_answer_simL + mov a,length_answer_simL + jnz $+2+2 ;2 + inc length_answer_simH ;2 + + setb EA + ret + + + +; +; +; +control_ATR: + jbc bit_generate_ATR,$+3+1 ;3 + ret ;1 +; + clr pin_RST + ;acall clr_buffer + ; Add rezet pause 17/12/2018 + + mov R6,#200 +looop_pause50mS: + djnz R7,$ ;~260mkSec + djnz R6,looop_pause50mS + + ;Prepare to answer 11/03/2019 + acall clr_buffer + + mov length_answer_simH,#0 + mov length_answer_simL,#0 + mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX1L,#LOW (XRAM_RX_BUFF) + mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX2L,#LOW (XRAM_RX_BUFF) + setb bit_first_ATR + setb pin_RST + ret + +; +; +; +for_coooooom0: + clr bit_RX0 + mov c,P + mov TB8,c ;9bit parity + mov SBUF,a + jnb bit_TX0,$ + clr bit_TX0 + mov R7,#100 + djnz R7,$ + ret + +; +; +; +clr_buffer: + mov DPTR,#0256 ;Receive SIM buffer + mov R7,#255 + clr a +looop_clr_bufff: + movx @DPTR,a + inc DPTR + djnz R7,looop_clr_bufff + ret + +; +; +; +;for_coooooom1: +; mov SBUF_1,a +; jnb TI_1,$ +; clr TI_1 +; ret +; +; +; +; + +end. From 83e6b223c4dc1974149ece3eac743356b6d7a566 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Mon, 5 Dec 2022 19:35:11 +0100 Subject: [PATCH 402/759] Adapt ARM code to comply with SIM module firmware 4.12 --- armsrc/i2c.c | 51 ++++++++++++++++++++++++++++++--------- client/src/cmdsmartcard.c | 7 +++++- client/src/cmdsmartcard.h | 6 ++--- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/armsrc/i2c.c b/armsrc/i2c.c index b79f8bb0e..eba6fe200 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -53,7 +53,8 @@ static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { #define I2C_DELAY_2CLK I2CSpinDelayClk(2) #define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x)) -#define ISO7618_MAX_FRAME 260 +// The SIM module v4 supports up to 384 bytes for the length. +#define ISO7816_MAX_FRAME 260 // try i2c bus recovery at 100kHz = 5us high, 5us low void I2C_recovery(void) { @@ -445,6 +446,7 @@ int16_t I2C_BufferRead(uint8_t *data, uint16_t len, uint8_t device_cmd, uint8_t bool bBreak = true; uint16_t readcount = 0; + uint16_t recv_len = 0; do { if (!I2C_Start()) @@ -484,11 +486,34 @@ int16_t I2C_BufferRead(uint8_t *data, uint16_t len, uint8_t device_cmd, uint8_t len--; - // The first byte in response is the message length - if (!readcount && (len > *data)) { - len = *data; + // Starting firmware v4 the length is encoded on the first two bytes. + // This only applies if command is I2C_DEVICE_CMD_READ. + if (device_cmd == I2C_DEVICE_CMD_READ) { + switch (readcount) { + case 0: + // Length (MSB) + recv_len = (*data) << 8; + break; + case 1: + // Length (LSB) + recv_len += *data; + // Adjust len if needed + if (len > recv_len) { + len = recv_len; + } + break; + default: + // Data byte received + data++; + break; + } } else { - data++; + // Length is encoded on 1 byte + if ((readcount == 0) && (len > *data)) { + len = *data; + } else { + data++; + } } readcount++; @@ -501,8 +526,8 @@ int16_t I2C_BufferRead(uint8_t *data, uint16_t len, uint8_t device_cmd, uint8_t I2C_Stop(); - // return bytecount - first byte (which is length byte) - return --readcount; + // return bytecount - bytes encoding length + return readcount - (device_cmd == I2C_DEVICE_CMD_READ ? 2 : 1); } int16_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) { @@ -612,10 +637,14 @@ bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t d void I2C_print_status(void) { DbpString(_CYAN_("Smart card module (ISO 7816)")); uint8_t maj, min; - if (I2C_get_version(&maj, &min) == PM3_SUCCESS) + if (I2C_get_version(&maj, &min) == PM3_SUCCESS) { Dbprintf(" version................. " _YELLOW_("v%x.%02d"), maj, min); - else + if (maj < 4) { + DbpString(" " _RED_("Outdated firmware.") " Please upgrade to v4.x or above."); + } + } else { DbpString(" version................. " _RED_("FAILED")); + } } int I2C_get_version(uint8_t *maj, uint8_t *min) { @@ -736,7 +765,7 @@ void SmartCardRaw(smart_card_raw_t *p) { LED_D_ON(); uint16_t len = 0; - uint8_t *resp = BigBuf_malloc(ISO7618_MAX_FRAME); + uint8_t *resp = BigBuf_malloc(ISO7816_MAX_FRAME); // check if alloacted... smartcard_command_t flags = p->flags; @@ -780,7 +809,7 @@ void SmartCardRaw(smart_card_raw_t *p) { } // read bytes from module - len = ISO7618_MAX_FRAME; + len = ISO7816_MAX_FRAME; res = sc_rx_bytes(resp, &len); if (res) { LogTrace(resp, len, 0, 0, NULL, false); diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index 92495f9cf..80cf0f4c4 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -329,10 +329,15 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) { } if (needGetData == true) { - // Don't discard data we already received except the SW code + // Don't discard data we already received except the SW code. + // If we only received 1 byte, this is the echo of INS, we discard it. totallen -= 2; + if (totallen == 1) { + totallen = 0; + } int ofs = totallen; maxoutlen -= totallen; + PrintAndLogEx(INFO, "Keeping data (%d bytes): %s", ofs, sprint_hex(out, ofs)); int len = out[datalen - 1]; if (len == 0 || len > MAX_APDU_SIZE) { diff --git a/client/src/cmdsmartcard.h b/client/src/cmdsmartcard.h index 72c40fa3b..6ed0a2842 100644 --- a/client/src/cmdsmartcard.h +++ b/client/src/cmdsmartcard.h @@ -22,10 +22,10 @@ #include "common.h" #include "pm3_cmd.h" // structs -// On ARM side, ISO7816_MAX_FRAME is set to 255 -// This means we can't receive more than 250 bytes of data to leave enough room for +// On ARM side, ISO7816_MAX_FRAME is set to 260 +// This means we can receive a full short APDU (256 bytes) of data and have enough room for // SW status code and surrounding metadata without creating a buffer overflow. -#define MAX_APDU_SIZE 250 +#define MAX_APDU_SIZE 256 int CmdSmartcard(const char *Cmd); From ba27eb03e0b265d668cdcf6068f0470814be16f9 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Mon, 5 Dec 2022 19:42:23 +0100 Subject: [PATCH 403/759] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47d9f5ad3..ceafdc02e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `hf mf gload, gsave, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) - Fixed SPI flash overflow when loading dictionnaries into flash. Breaking change: added 1 more sector for Mifare - dictionnaries should be loaded again (@jmichelp) - Fixed `lf hitag dump` - Should now work as described in the command help (@natmchugh) + - Fixed wired smartcard APDU chaining logic and allow 256 bytes ADPU payload. Need SIM firmware 4.12 to work (jmichel@) + - SIM module firmware 4.12 to accomodate with the new APDU payload size (sentinel@) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) From c23c2b2aef3d56a4d87a4a6cdf9664525c5a713c Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Mon, 5 Dec 2022 20:05:28 +0100 Subject: [PATCH 404/759] Rollback the firmware part --- CHANGELOG.md | 1 - client/resources/sim012.sha512.txt | 1 - tools/simmodule/sim012.asm | 817 ----------------------------- 3 files changed, 819 deletions(-) delete mode 100644 client/resources/sim012.sha512.txt delete mode 100644 tools/simmodule/sim012.asm diff --git a/CHANGELOG.md b/CHANGELOG.md index ceafdc02e..5dacd8ea2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed SPI flash overflow when loading dictionnaries into flash. Breaking change: added 1 more sector for Mifare - dictionnaries should be loaded again (@jmichelp) - Fixed `lf hitag dump` - Should now work as described in the command help (@natmchugh) - Fixed wired smartcard APDU chaining logic and allow 256 bytes ADPU payload. Need SIM firmware 4.12 to work (jmichel@) - - SIM module firmware 4.12 to accomodate with the new APDU payload size (sentinel@) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) diff --git a/client/resources/sim012.sha512.txt b/client/resources/sim012.sha512.txt deleted file mode 100644 index fdd509b54..000000000 --- a/client/resources/sim012.sha512.txt +++ /dev/null @@ -1 +0,0 @@ -ac65f93b15dea4e6a27a644056c18266113af57f4d29de9eead4871007816efa7d1ec9f73308377e5fe388fc81b3d408221bd4eff7e1d129e0a349bd2c0f3f2b sim012.bin diff --git a/tools/simmodule/sim012.asm b/tools/simmodule/sim012.asm deleted file mode 100644 index 5cec3b2f2..000000000 --- a/tools/simmodule/sim012.asm +++ /dev/null @@ -1,817 +0,0 @@ -; --------------------------------------------------------------------------- -; Proxmark3 RDV4 SIM module firmware -; -; Copyright (C) 2022 Sentinel -; -; This program is free software: you can redistribute it and/or modify it -; under the terms of the GNU Lesser General Public License as published by the -; Free Software Foundation, either version 3 of the License, or (at your -; option) any later version. -; -; This program is distributed in the hope that it will be useful, but WITHOUT -; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -; more details. -; -; You should have received a copy of the GNU Lesser General Public License -; along with this program. If not, see -; --------------------------------------------------------------------------- -; - VERS_HI equ 4 - VERS_LO equ 12 -; -; -; - SCON_0 equ 098h - FE_0 equ 098h.7 - - SCON_1 equ 0F8h - RI_1 equ 0F8h.0 - TI_1 equ 0F8h.1 - FE_1 equ 0F8h.7 - SBUF_1 equ 09Ah - T3CON equ 0C4h - RL3 equ 0C5h - RH3 equ 0C6h - - P0M1 equ 0B1h - P0M2 equ 0B2h - P1M1 equ 0B3h - P1M2 equ 0B4h - P3M1 equ 0ACh; - P3M2 equ 0ADh; - - EIE equ 09Bh - EIE1 equ 09Ch - - TA equ 0C7h - - RCTRIM0 equ 084h -; - CKCON equ 08Eh - CKDIV equ 095h -; - P1S equ 0B3h ;Page1 - SFRS equ 091h ;TA Protection -; - ;AUXR1 equ 0A2h -; - I2DAT equ 0BCh; - I2STAT equ 0BDh; - I2CLK equ 0BEh; - I2TOC equ 0BFh; - I2CON equ 0C0h; - ; equ I2CON.7;8 - I2CEN equ I2CON.6;4 - STA equ I2CON.5;2 - STO equ I2CON.4;1 - SI equ I2CON.3;8 - AA equ I2CON.2;4 - ; equ I2CON.1;2 - I2CPX equ I2CON.0;1 - - - I2ADDR equ 0C1h; - -; -; -; - pin_TX1 equ P1.6 - - pin_TX0 equ P0.6 - pin_RX0 equ P0.7 - - pin_SCL equ P1.3 - pin_SDA equ P1.4 - - pin_RST equ P1.0 - pin_CLC equ P1.1 - pin_led equ P1.2 - -; -; - - - CMD_GENERATE_ATR equ 01h - CMD_WRITE_DATA_SIM equ 02h - CMD_READ_DATA_SIM equ 03h - - CMD_SET_BAUD_RATE equ 04h - CMD_SET_SIM_CLC equ 05h - CMD_GET_VERS equ 06h - CMD_WRITE_CONFIRM equ 07h - - - -; -; - - bit_RX0 equ 32.0 - bit_command_receive equ 32.1 - bit_generate_ATR equ 32.2 - i2c_write_mode equ 32.3 - i2c_write_done equ 32.4 - bit_data_sim_wr equ 32.5 - ; equ 32.6 - bit_TX0 equ 32.7 - - bit_command_buff equ 33.0 - i2c_write_command equ 33.1 - i2c_command_done equ 33.2 - bit_wait_confirm equ 33.3 - bit_first_ATR equ 33.4 ;11/03/2019 - bit_length_answerH equ 33.5 - bit_length_answerL equ 33.6 -; -; -; - bit_32 equ 32 - bit_33 equ 33 - - time_data_read equ 34 - time_confirm equ 35 - - pointer_RX1H equ 36 ;save SBUF(SIM) to XRAM - pointer_RX1L equ 37 ;save SBUF(SIM) to XRAM - - pointer_RX2H equ 38 ;read XRAM to I2C - pointer_RX2L equ 39 ;read XRAM to I2C - - pointer_TXH equ 40 - pointer_TXL equ 41 - - length_send_to_simH equ 42 - length_send_to_simL equ 43 - - length_answer_simH equ 44 - length_answer_simL equ 45 - - length_command equ 46 - - buff_command equ 47 - cmd_command equ 48 - data_command equ 49 - - STACKKKKK equ 200 -; -; - XRAM_TX_BUFF equ 0 - XRAM_RX_BUFF equ 384 -; -; -; - -; -; -; -; 砫 ᭮ ணࠬ - cseg at 00 - Ljmp main_start - -; -; -; - cseg at 11 ;1302Hz = 4MHZ(Fsys)/12/256 -; - jb time_confirm.7, $+3+2 ;3 - dec time_confirm ;2 -; - jb time_data_read.7,reti_timer0 - djnz time_data_read, reti_timer0 - setb pin_scl -reti_timer0: - reti - - -; -; -; - cseg at 35 ;UART0 - ajmp jmp_UART0_interrupt - -; -; -; - cseg at 51 ;I2C - ajmp jmp_i2c_interrupt - -; -; -; - cseg at 123 ;UART1 - clr RI_1 - clr TI_1 - reti - -; -; -; -jmp_UART0_interrupt: - jbc RI,jmp_byte_RI - jbc TI,jmp_byte_TI - reti -; -jmp_byte_RI: - jnb bit_first_ATR, jmp_not_collect ;11/03/2019 - - setb bit_RX0 - jb i2c_write_done,jmp_not_collect - PUSH ACC - PUSH DPH - PUSH DPL - mov DPL,pointer_RX1L - mov DPH,pointer_RX1H - mov a,SBUF - movx @DPTR,a - inc DPTR - mov pointer_RX1L,DPL - mov pointer_RX1H,DPH - POP DPL - POP DPH - POP ACC - ;09/08/2018 - clr pin_scl - mov time_data_read,#52 ;52/1302Hz = 40mS - - inc length_answer_simL - mov a,length_answer_simL - jnz $+2+2 ;2 - inc length_answer_simH ;2 - -jmp_not_collect: - reti -; -jmp_byte_TI: - setb bit_TX0 - reti - - -; -; -jmp_i2c_interrupt: - PUSH ACC - PUSH PSW - mov PSW,#24 - mov R7,I2STAT -; -; -; - cjne R7,#000h,nextttt00000 - setb STO - clr SI - jb STO,$ - ajmp pop_i2c_psw -nextttt00000: -; -; -; - cjne R7,#060h,nextttt00001 ;START+MY ADRESS - clr pin_led ;LED ON - - clr bit_command_receive - clr i2c_write_mode - clr bit_data_sim_wr - clr bit_length_answerH - clr bit_length_answerL - clr bit_command_buff - clr i2c_write_command - - ajmp end_i2c_interrupt -nextttt00001: -; -; -; -; -; - cjne R7,#080h,nextttt00002 ;RAM ADRESS - - jb bit_command_receive,jmp_data_receive - setb bit_command_receive - - mov a,I2DAT -; -; -; - cjne a,#CMD_WRITE_CONFIRM,next_comm001a - setb bit_wait_confirm - ajmp WRITEDATASIM -next_comm001a: -; - cjne a,#CMD_WRITE_DATA_SIM,next_comm001b - clr bit_wait_confirm - ajmp WRITEDATASIM -next_comm001b: -; - cjne a,#CMD_GENERATE_ATR,next_comm002 - ajmp ATR_GENERATE -next_comm002: -; - cjne a,#CMD_GET_VERS,next_comm003 - ajmp ANSWER_VERS -next_comm003: -; - cjne a,#CMD_SET_BAUD_RATE,next_comm004 - ajmp BAUD_RATE_SET -next_comm004: -; - cjne a,#CMD_SET_SIM_CLC,next_comm005 - ajmp SIM_CLC_SET -next_comm005: -; - ajmp end_i2c_interrupt -; -; -; -; -jmp_data_receive: - ;What receive ? Data to SIM/Command to bridge - jb bit_data_sim_wr, jmp_data_sim_receive - jb i2c_write_command,jmp_comm_bridge_receive - ajmp end_i2c_interrupt -; -jmp_comm_bridge_receive: - mov @R0,I2DAT - inc R0 - inc length_command - ajmp end_i2c_interrupt -; -jmp_data_sim_receive: - - setb i2c_write_mode - - PUSH DPH - PUSH DPL - mov DPL,pointer_TXL - mov DPH,pointer_TXH - mov a,I2DAT - movx @DPTR,a - inc DPTR - mov pointer_TXL,DPL - mov pointer_TXH,DPH - POP DPL - POP DPH - - inc length_send_to_simL - mov a,length_send_to_simL - jnz $+2+2 ;2 - inc length_send_to_simH ;2 - - ajmp end_i2c_interrupt -nextttt00002: -; -; -; - cjne R7,#0A0h,nextttt00003 ;STOP - setb pin_led ;LED OFF - - ;Command finish ? - jnb i2c_write_command,jmp_not_command - clr i2c_write_command - setb i2c_command_done -jmp_not_command: - - ;data to SIM finish ? - jnb i2c_write_mode,end_i2c_interrupt - clr i2c_write_mode - - setb i2c_write_done - ;Prepare to answer - mov length_answer_simH,#0 - mov length_answer_simL,#0 - mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX1L,#LOW (XRAM_RX_BUFF) - mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX2L,#LOW (XRAM_RX_BUFF) - - ajmp end_i2c_interrupt -nextttt00003: -; -; -; - cjne R7,#0A8h,nextttt00004 - sjmp read_byte_I2C -nextttt00004: -; -; -; - cjne R7,#0B8h,nextttt00005 -read_byte_I2C: - jnb bit_command_buff,jmp_not_comm_buff2 - mov I2DAT,@R0 - inc R0 - ajmp end_i2c_interrupt - -jmp_not_comm_buff2: - jb bit_length_answerH,jmp_not_comm_buff3 - setb bit_length_answerH - mov I2DAT,length_answer_simH - ajmp end_i2c_interrupt - -jmp_not_comm_buff3: - jb bit_length_answerL,read_byte_APROM - setb bit_length_answerL - mov I2DAT,length_answer_simL - ajmp end_i2c_interrupt - -read_byte_APROM: - PUSH DPH - PUSH DPL - mov DPL,pointer_RX2L - mov DPH,pointer_RX2H - movx a,@DPTR - mov I2DAT,a - inc DPTR - mov pointer_RX2L,DPL - mov pointer_RX2H,DPH - POP DPL - POP DPH - -nextttt00005: -; -; -; -end_i2c_interrupt: - clr STA - clr STO - setb AA -; -; -; -pop_i2c_psw: - POP PSW - POP ACC - clr SI - reti - - -; -; -; -ANSWER_VERS: - mov R0,#data_command - mov cmd_command,#CMD_GET_VERS - mov (data_command+0),#2 - mov (data_command+1),#VERS_HI - mov (data_command+2),#VERS_LO - setb bit_command_buff - ajmp end_i2c_interrupt - -; -; -; -ATR_GENERATE: - setb bit_generate_ATR - ;Prepare to answer - mov length_answer_simH,#0 - mov length_answer_simL,#0 - mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX1L,#LOW (XRAM_RX_BUFF) - mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX2L,#LOW (XRAM_RX_BUFF) - ajmp end_i2c_interrupt - - -; -; -; -BAUD_RATE_SET: - mov R0,#data_command - mov length_command,#0 - mov cmd_command,#CMD_SET_BAUD_RATE - setb i2c_write_command - ajmp end_i2c_interrupt - - -; -; -; -SIM_CLC_SET: - mov R0,#data_command - mov length_command,#0 - mov cmd_command,#CMD_SET_SIM_CLC - setb i2c_write_command - ajmp end_i2c_interrupt - -; -; -; -WRITEDATASIM: - mov length_send_to_simH,#0 - mov length_send_to_simL,#0 - setb bit_data_sim_wr - mov pointer_TXH,#HIGH(XRAM_TX_BUFF) - mov pointer_TXL,#LOW (XRAM_TX_BUFF) - ajmp end_i2c_interrupt - -; -; -; -; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -main_start: - mov SP,#STACKKKKK -; - ;0-bidirect 1-push pull 0-input only 1-open drain - ;0 0 1 1 -; - mov P0M2,#01000000b ;0 - mov P0M1,#11111111b ;P1.6-Tx0 SIM; - ; - mov P1M2,#01011111b ;1 - mov P1M1,#10111000b ;P1.6-Tx1 DEBUG; P1.4,P1.3 - I2C; - - mov P3M2,#00000000b ;P3 - mov P3M1,#11111111b ; -; - mov TMOD, #22h - mov TH0, #0 ;14400hz - mov TH1, #0E9h ;UART0 10800 Bit/sec - mov TCON, #55h -; -; - mov TA,#0AAh - mov TA,#055h - orl SFRS,#00000001b - - mov P1S, #00010000b ;P1.4 trigger schmiddt - - mov TA,#0AAh - mov TA,#055h - anl SFRS,#11111110b -; -; -; - ;------- CONFIG I2C --------- - mov I2CON, #44h ;set AA, set I2C enable - setb pin_sda - setb pin_scl - mov I2ADDR,#0C0h -; -; -; -; -; - ;mov SCON, #050h ;UART0 8bit - mov SCON, #0D0h ;UART0 9bit - ;mov PCON, #11000000b;FE_0 enable - mov PCON, #10000000b;FE_0 disable -; - mov SCON_1,#050h ;UART1 - ;mov T3CON, #01101000b;FE_1 enable TIMER3 UART0 BAUD - ;mov T3CON, #00101000b;FE_1 disable TIMER3 UART0 BAUD - mov T3CON, #00001000b;FE_1 disable TIMER1 UART0 BAUD - ;mov RL3,#0E9h ;10800/21600 - ;mov RH3,#0FFh -; - ;UART1 - mov RL3,#0F7h ;27777/55556 - mov RH3,#0FFh -; -; -; - mov CKDIV,#2 ;Fsys=4.00MHZ - ;mov CKDIV,#1 ;Fsys=8.00MHZ -; - mov bit_32,#0 - mov bit_33,#0 - setb time_data_read.7 -; - ;orl CKCON,#00000010b ;ENABLE CLC TIMER1 Fsys/12 - orl CKCON,#00010010b ;ENABLE CLC TIMER1 Fsys -; - ;mov a,RCTRIM0 - ;add a,#31 - ;mov TA,#0AAh - ;mov TA,#055h - ;mov RCTRIM0,a -; -; - acall clr_buffer -; - mov EIE, #00000001b ;I2C Interrupt - ;mov IE, #10010000b ;EA, SERIAL0 - mov IE, #10010010b ;EA, SERIAL0, TIMER0 -; -; -; -; -; -main_loop: - acall control_ATR - acall control_send_to_sim - acall control_command - sjmp main_loop - -; -; -; -control_command: - jbc i2c_command_done,$+3+1 ;3 - ret ;1 -; -; - ;Control Length command=1 - mov a,length_command - cjne a,#1,next_commandEND ;error length_command != 1 -; -; - mov a,cmd_command - cjne a,#CMD_SET_BAUD_RATE,next_command001 - mov TH1,data_command ;Timer1 HIGH byte - ret -next_command001: -; - cjne a,#CMD_SET_SIM_CLC, next_command002 - mov CKDIV,data_command ;Fsys DIV - ret -next_command002: -; -next_commandEND: - ret - -; -; -; -control_send_to_sim: - jb i2c_write_done,$+3+1 ;3 - ret ;1 -; -; - jbc bit_wait_confirm,jmp_wait_confirm -; -; - mov DPTR,#XRAM_TX_BUFF -looop_send: - movx a,@DPTR - inc DPTR - acall for_coooooom0 - - clr c - mov a,length_send_to_simL - subb a,#1 - mov length_send_to_simL,a - mov a,length_send_to_simH - subb a,#0 - mov length_send_to_simH,a - orl a,length_send_to_simL - jnz looop_send -; -; - jnb bit_RX0,$ - clr i2c_write_done - ret - - -; -; -; -jmp_wait_confirm: - mov DPTR,#(XRAM_TX_BUFF+1) - movx a,@DPTR - mov R3,a - mov R4,#5 -; - mov DPTR,#XRAM_TX_BUFF -looop_seend: - movx a,@DPTR - inc DPTR - acall for_coooooom0 - djnz R4,jmp_not_5byte - - jnb bit_RX0,$ - clr bit_RX0 - ;18/12/2018 - mov time_confirm,#65 ;New timeout 50mS -looop_waitconf: - jb time_confirm.7,jmp_no_answer - jnb bit_RX0,looop_waitconf - - ;clr pin_scl ;TEST PULSE! - mov a,SBUF - xrl a,R3 - ;setb pin_scl ;TEST PULSE! - - jnz jmp_no_correct_answer ;18/12/2018 - - ;pause for next byte 17/12/2018 - mov R7,#0 - djnz R7,$ ;~260mkSec - djnz R7,$ ;~260mkSec - djnz R7,$ ;~260mkSec - -jmp_not_5byte: - - clr c - mov a,length_send_to_simL - subb a,#1 - mov length_send_to_simL,a - mov a,length_send_to_simH - subb a,#0 - mov length_send_to_simH,a - orl a,length_send_to_simL - jnz looop_seend -; -; - jnb bit_RX0,$ - clr bit_RX0 -jmp_no_answer: - clr i2c_write_done - ret - -; -; -;18/12/2018 -jmp_no_correct_answer: - clr EA - clr i2c_write_done - - mov DPL,pointer_RX1L - mov DPH,pointer_RX1H - mov a,SBUF - movx @DPTR,a - inc DPTR - mov pointer_RX1L,DPL - mov pointer_RX1H,DPH - - clr pin_scl - mov time_data_read,#52 ;52/1302Hz = 40mS - - inc length_answer_simL - mov a,length_answer_simL - jnz $+2+2 ;2 - inc length_answer_simH ;2 - - setb EA - ret - - - -; -; -; -control_ATR: - jbc bit_generate_ATR,$+3+1 ;3 - ret ;1 -; - clr pin_RST - ;acall clr_buffer - ; Add rezet pause 17/12/2018 - - mov R6,#200 -looop_pause50mS: - djnz R7,$ ;~260mkSec - djnz R6,looop_pause50mS - - ;Prepare to answer 11/03/2019 - acall clr_buffer - - mov length_answer_simH,#0 - mov length_answer_simL,#0 - mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX1L,#LOW (XRAM_RX_BUFF) - mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX2L,#LOW (XRAM_RX_BUFF) - setb bit_first_ATR - setb pin_RST - ret - -; -; -; -for_coooooom0: - clr bit_RX0 - mov c,P - mov TB8,c ;9bit parity - mov SBUF,a - jnb bit_TX0,$ - clr bit_TX0 - mov R7,#100 - djnz R7,$ - ret - -; -; -; -clr_buffer: - mov DPTR,#0256 ;Receive SIM buffer - mov R7,#255 - clr a -looop_clr_bufff: - movx @DPTR,a - inc DPTR - djnz R7,looop_clr_bufff - ret - -; -; -; -;for_coooooom1: -; mov SBUF_1,a -; jnb TI_1,$ -; clr TI_1 -; ret -; -; -; -; - -end. From 07a8f7a6de334e9adde8ea63776560480f72a467 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Mon, 5 Dec 2022 21:15:49 +0100 Subject: [PATCH 405/759] Raise the buffer size even more. I was too conservative as it requires 261 bytes. Let's put 270 for the peace of mind. --- armsrc/i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/i2c.c b/armsrc/i2c.c index eba6fe200..d8495e59c 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -54,7 +54,7 @@ static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { #define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x)) // The SIM module v4 supports up to 384 bytes for the length. -#define ISO7816_MAX_FRAME 260 +#define ISO7816_MAX_FRAME 270 // try i2c bus recovery at 100kHz = 5us high, 5us low void I2C_recovery(void) { From 5bd6379b5bd761405473f4d95aba93f0a77c3b00 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Mon, 5 Dec 2022 21:55:38 +0100 Subject: [PATCH 406/759] Move message to debug --- client/src/cmdsmartcard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index 80cf0f4c4..4a0a6606a 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -337,7 +337,7 @@ static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) { } int ofs = totallen; maxoutlen -= totallen; - PrintAndLogEx(INFO, "Keeping data (%d bytes): %s", ofs, sprint_hex(out, ofs)); + PrintAndLogEx(DEBUG, "Keeping data (%d bytes): %s", ofs, sprint_hex(out, ofs)); int len = out[datalen - 1]; if (len == 0 || len > MAX_APDU_SIZE) { From 53b2909f04f28d1f453c4964f94f8c1010382620 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 5 Dec 2022 22:32:40 +0100 Subject: [PATCH 407/759] prepping for sim module firmware upgrade file --- CHANGELOG.md | 9 +- Makefile | 2 +- client/resources/sim012.sha512.txt | 1 + client/src/cmdsmartcard.c | 4 +- doc/cheatsheet.md | 2 +- .../Troubleshooting.md | 44 +- .../2_Configuration-and-Verification.md | 31 +- doc/path_notes.md | 4 +- tools/pm3_online_check.py | 6 +- tools/pm3_tests.sh | 2 +- tools/simmodule/sim012.asm | 816 ++++++++++++++++++ 11 files changed, 874 insertions(+), 47 deletions(-) create mode 100644 client/resources/sim012.sha512.txt create mode 100644 tools/simmodule/sim012.asm diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dacd8ea2..04916e479 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ 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 `sc upgrade` updated firmware v4.12 (RDV40) (@sentiprox) + - Fixed contact interface / smartcard APDU chaining logic and allow 256 bytes ADPU payload. Need SIM firmware 4.12 to work (@jmichel) + - Fixed `lf hitag dump` - Should now work as described in the command help (@natmchugh) + - Fixed SPI flash overflow when loading dictionnaries into flash. Breaking change: added 1 more sector for Mifare - dictionnaries should be loaded again (@jmichelp) + - Added `hf mf gload, gsave, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) - Fixed `trace list -r` (relative times) not working unless `-u` (microseconds) was specified, and made `--frame` respect `-u` and `-r` options (@nvx) - Added detection of magic Gen4 GTU (@DidierA) - Added luascript `hf_i2c_plus_2k_utils` - Script for dumping/modifying user memory of sectors 0 and 1 (@flamebarke) @@ -15,10 +20,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001) - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - - Added `hf mf gload, gsave, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) - - Fixed SPI flash overflow when loading dictionnaries into flash. Breaking change: added 1 more sector for Mifare - dictionnaries should be loaded again (@jmichelp) - - Fixed `lf hitag dump` - Should now work as described in the command help (@natmchugh) - - Fixed wired smartcard APDU chaining logic and allow 256 bytes ADPU payload. Need SIM firmware 4.12 to work (jmichel@) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) diff --git a/Makefile b/Makefile index b072d7379..97ae22000 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfk #all clean install uninstall check: %: hitag2crack/% INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py pm3_amii_bin2eml.pl pm3_reblay-emulating.py pm3_reblay-reading.py -INSTALLSIMFW=sim011.bin sim011.sha512.txt +INSTALLSIMFW=sim012.bin sim012.sha512.txt INSTALLSCRIPTS=pm3 pm3-flash pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage INSTALLSHARES=tools/jtag_openocd traces INSTALLDOCS=doc/*.md doc/md diff --git a/client/resources/sim012.sha512.txt b/client/resources/sim012.sha512.txt new file mode 100644 index 000000000..abb996fb2 --- /dev/null +++ b/client/resources/sim012.sha512.txt @@ -0,0 +1 @@ +ac65f93b15dea4e6a27a644056c18266113af57f4d29de9eead4871007816efa7d1ec9f73308377e5fe388fc81b3d408221bd4eff7e1d129e0a349bd2c0f3f2b *sim012.bin diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index 4a0a6606a..3d9888a50 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -521,8 +521,8 @@ static int CmdSmartUpgrade(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "smart upgrade", - "Upgrade RDV4.0 sim module firmware", - "smart upgrade -f sim011.bin" + "Upgrade RDV4 sim module firmware", + "smart upgrade -f sim012.bin" ); void *argtable[] = { diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index a1f04faf1..1f0d66c1b 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -713,7 +713,7 @@ pm3 --> mem load -f iclass_default_keys --iclass Upgrade Sim Module firmware ``` -pm3 --> smart upgrade -f sim011.bin +pm3 --> smart upgrade -f sim012.bin ``` ## Smart Card diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index a69b0b9f9..b946fd0d0 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -6,24 +6,26 @@ Always use the latest repository commits from *master* branch. There are always ## Table of Contents - * [pm3 or pm3-flash* doesn't see my Proxmark](#pm3-or-pm3-flash-doesnt-see-my-proxmark) - * [pm3-flash* stops and warns about up-to-date firmware images](#pm3-flash-stops-and-warns-about-up-to-date-firmware-images) - * [My Proxmark3 seems bricked](#my-proxmark3-seems-bricked) - * [Maybe just a false alarm?](#maybe-just-a-false-alarm) - * [Find out why it would be bricked](#find-out-why-it-would-be-bricked) - * [Determine if the bootloader was damaged or only the main OS image](#determine-if-the-bootloader-was-damaged-or-only-the-main-os-image) - * [Ok, my bootloader is definitively dead, now what?](#ok-my-bootloader-is-definitively-dead-now-what) - * [Slow to boot or difficulties to enumerate the device over USB](#slow-to-boot-or-difficulties-to-enumerate-the-device-over-usb) - * [Troubles with SIM card reader](#troubles-with-sim-card-reader) - * [Troubles with t5577 commands or MFC/iClass/T55x7 dictionaries](#troubles-with-t5577-commands-or-mfciclasst55x7-dictionaries) - * [File not found](#file-not-found) - * [Pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) - * [Usb cable](#usb-cable) - * [WSL explorer.exe . doesn't work](#WSL) - * [Troubles with running the Proxmark3 client](#troubles-with-running-the-proxmark3-client) - * [libQt5Core.so.5 not found](#libQt5Coreso5-not-found) - * [Target attribute is not supported on this machine](#target-attribute-is-not-supported-on-this-machine) - * [Qt: Session management error:](#qt-session-management-error) +- [Troubleshooting guide](#troubleshooting-guide) + - [Table of Contents](#table-of-contents) + - [`pm3` or `pm3-flash*` doesn't see my Proxmark](#pm3-or-pm3-flash-doesnt-see-my-proxmark) + - [`pm3-flash*` stops and warns about up-to-date firmware images](#pm3-flash-stops-and-warns-about-up-to-date-firmware-images) + - [My Proxmark3 seems bricked](#my-proxmark3-seems-bricked) + - [Maybe just a false alarm?](#maybe-just-a-false-alarm) + - [Find out why it would be bricked](#find-out-why-it-would-be-bricked) + - [Determine if the bootloader was damaged or only the main OS image](#determine-if-the-bootloader-was-damaged-or-only-the-main-os-image) + - [Ok, my bootloader is definitively dead, now what?](#ok-my-bootloader-is-definitively-dead-now-what) + - [Slow to boot or difficulties to enumerate the device over USB](#slow-to-boot-or-difficulties-to-enumerate-the-device-over-usb) + - [Troubles with SIM card reader](#troubles-with-sim-card-reader) + - [Troubles with t5577 commands or MFC/iClass/T55x7 dictionaries](#troubles-with-t5577-commands-or-mfciclasst55x7-dictionaries) + - [File not found](#file-not-found) + - [Pixmap / pixbuf warnings](#pixmap--pixbuf-warnings) + - [Usb cable](#usb-cable) + - [WSL](#wsl) + - [Troubles with running the Proxmark3 client](#troubles-with-running-the-proxmark3-client) + - [libQt5Core.so.5 not found](#libqt5coreso5-not-found) + - [target attribute is not supported on this machine](#target-attribute-is-not-supported-on-this-machine) + - [Qt Session management error](#qt-session-management-error) ## `pm3` or `pm3-flash*` doesn't see my Proxmark @@ -159,9 +161,9 @@ proxmark3 --flash --image /usr/local/share/proxmark3/firmware/f proxmark3 --flash --image /usr/share/proxmark3/firmware/fullimage.elf using the script: -pm3 --> smart upgrade -f /usr/local/share/proxmark3/firmware/sim011.bin +pm3 --> smart upgrade -f /usr/local/share/proxmark3/firmware/sim012.bin <> -pm3 --> smart upgrade -f /usr/share/proxmark3/firmware/sim011.bin +pm3 --> smart upgrade -f /usr/share/proxmark3/firmware/sim012.bin ``` If you didn't install the PRoxmark but you're working from the sources directory and depending how you launch the client, your working directory might be the root of the repository: @@ -184,7 +186,7 @@ client/proxmark3 --flash --image armsrc/obj/fullimage.elf <> ./proxmark3 --flash --image ../armsrc/obj/fullimage.elf -pm3 --> smart upgrade -f sim011.bin +pm3 --> smart upgrade -f sim012.bin ``` etc. diff --git a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md index 175561062..00841d118 100644 --- a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md +++ b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md @@ -40,7 +40,7 @@ Set all t55xx settings to defaults (will set all 4 at once) To make sure you got the latest sim module firmware. -_Latest version is v3.11_ +_Latest version is v4.12_ ``` [usb] pm3 --> hw status @@ -51,27 +51,33 @@ Find version in the long output, look for these two lines ``` #db# Smart card module (ISO 7816) #db# version.................v2.06 + +or + +#db# Smart card module (ISO 7816) +#db# version.................v3.11 + ``` -This version is obsolete. +These versions is obsolete. -If you didn't download sim011.bin from the RRG Repo be aware that it might be corrupted or faulty. +If you didn't download sim012.bin from the RRG Repo be aware that it might be corrupted or faulty. You find a hash text file in this folder. It was generated with the following linux command. ``` -sha512sum -b sim011.bin > sim011.sha512.txt +sha512sum -b sim012.bin > sim012.sha512.txt ``` -You should validate the sim011.bin file against this hash file in order to be sure the file is not corrupted or faulty. +You should validate the sim012.bin file against this hash file in order to be sure the file is not corrupted or faulty. The following command upgrades your device sim module firmware. Don't not turn off your device during the execution of this command!! Even its a quite fast command you should be warned. You may brick it if you interrupt it. ``` -[usb] pm3 --> smart upgrade -f /usr/local/share/proxmark3/firmware/sim011.bin +[usb] pm3 --> smart upgrade -f /usr/local/share/proxmark3/firmware/sim012.bin # or if from local repo -[usb] pm3 --> smart upgrade -f sim011.bin +[usb] pm3 --> smart upgrade -f sim012.bin ``` You get the following output if the execution was successful: @@ -82,13 +88,13 @@ You get the following output if the execution was successful: [!] ⚠️ A dangerous command, do wrong and you could brick the sim module [=] ------------------------------------------------------------------- -[=] firmware file sim011.bin -[=] Checking integrity sim011.sha512.txt -[+] loaded 733 bytes from binary file sim011.bin -[+] loaded 141 bytes from binary file sim011.sha512.txt +[=] firmware file sim012.bin +[=] Checking integrity sim012.sha512.txt +[+] loaded 864 bytes from binary file sim012.bin +[+] loaded 141 bytes from binary file sim012.sha512.txt [=] Don't turn off your PM3! [+] Sim module firmware uploading to PM3... - 🕑 733 bytes sent + 🕑 864 bytes sent [+] Sim module firmware updating... [#] FW 0000 [#] FW 0080 @@ -96,6 +102,7 @@ You get the following output if the execution was successful: [#] FW 0180 [#] FW 0200 [#] FW 0280 +[#] FW 0300 [+] Sim module firmware upgrade successful ``` diff --git a/doc/path_notes.md b/doc/path_notes.md index 8f0d20b88..72bde2aa6 100644 --- a/doc/path_notes.md +++ b/doc/path_notes.md @@ -22,7 +22,7 @@ - [Gory details](#gory-details) - [Scripts](#scripts) - [Proxmark command script (.cmd)](#proxmark-command-script-cmd) - - [Shebangs (on *nix)](#shebangs-on-nix) + - [Shebangs (on \*nix)](#shebangs-on-nix) With the recent (2019-09-01) changes and creation of `make install` command it is easy to get lost. @@ -64,7 +64,7 @@ The recovery / firmware files will be copied to ``` * Proxmark3 firmware: `bootrom.elf`, `fullimage.elf`, `proxmark3_recovery.bin` (used for JTAG) -* SIM firmware: `sim011.bin`, `sim011.sha512.txt` +* SIM firmware: `sim012.bin`, `sim012.sha512.txt` ## Traces diff --git a/tools/pm3_online_check.py b/tools/pm3_online_check.py index 3a5f9d4cd..2298a2ede 100755 --- a/tools/pm3_online_check.py +++ b/tools/pm3_online_check.py @@ -12,7 +12,7 @@ # # This code is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This code is distributed in the hope that it will be useful, @@ -122,7 +122,7 @@ def pm3_lf_t55xx(child): def pm3_flash_sm(child): try: print("[+] Updating smart card fw") - child.sendline('smart upgrade -f sim011.bin') + child.sendline('smart upgrade -f sim012.bin') i = child.expect('pm3 --> ') msg = escape_ansi(str(child.before)) print("================") @@ -204,7 +204,7 @@ def main(): flash_mem = "baudrate................24 mhz".lower() # check smartcard fw version - sm_version = "version.................v3.11".lower() + sm_version = "version.................v4.12".lower() # check LF lf_search = "valid hid prox id found!".lower() diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index f682d3491..2187ff13a 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -236,7 +236,7 @@ while true; do if $TESTALL || $TESTCOMMON; then echo -e "\n${C_BLUE}Testing common:${C_NC}" if ! CheckFileExist "hardnested tables exists" "$RESOURCEPATH/hardnested_tables/bitflip_0_001_states.bin.bz2"; then break; fi - if ! CheckFileExist "simmodule fw file exists" "$RESOURCEPATH/sim011.bin"; then break; fi + if ! CheckFileExist "simmodule fw file exists" "$RESOURCEPATH/sim012.bin"; then break; fi if ! CheckFileExist "iCLASS dictionary exists" "$DICPATH/iclass_default_keys.dic"; then break; fi if ! CheckFileExist "MFC dictionary exists" "$DICPATH/mfc_default_keys.dic"; then break; fi if ! CheckFileExist "MFDES dictionary exists" "$DICPATH/mfdes_default_keys.dic"; then break; fi diff --git a/tools/simmodule/sim012.asm b/tools/simmodule/sim012.asm new file mode 100644 index 000000000..02466a288 --- /dev/null +++ b/tools/simmodule/sim012.asm @@ -0,0 +1,816 @@ +; --------------------------------------------------------------------------- +; Proxmark3 RDV4 SIM module firmware +; +; Copyright (C) 2109, 2022 Sentinel +; +; This program is free software: you can redistribute it and/or modify it +; under the terms of the GNU Lesser General Public License as published by the +; Free Software Foundation, either version 3 of the License, or (at your +; option) any later version. +; +; This program is distributed in the hope that it will be useful, but WITHOUT +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +; more details. +; +; You should have received a copy of the GNU Lesser General Public License +; along with this program. If not, see +; --------------------------------------------------------------------------- + VERS_HI equ 4 + VERS_LO equ 12 +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + SCON_0 equ 098h + FE_0 equ 098h.7 + + SCON_1 equ 0F8h + RI_1 equ 0F8h.0 + TI_1 equ 0F8h.1 + FE_1 equ 0F8h.7 + SBUF_1 equ 09Ah + T3CON equ 0C4h + RL3 equ 0C5h + RH3 equ 0C6h + + P0M1 equ 0B1h + P0M2 equ 0B2h + P1M1 equ 0B3h + P1M2 equ 0B4h + P3M1 equ 0ACh; + P3M2 equ 0ADh; + + EIE equ 09Bh + EIE1 equ 09Ch + + TA equ 0C7h + + RCTRIM0 equ 084h +; --------------------------------------------------------------------------- + CKCON equ 08Eh + CKDIV equ 095h +; --------------------------------------------------------------------------- + P1S equ 0B3h ;Page1 + SFRS equ 091h ;TA Protection +; --------------------------------------------------------------------------- + ;AUXR1 equ 0A2h +; --------------------------------------------------------------------------- + I2DAT equ 0BCh; + I2STAT equ 0BDh; + I2CLK equ 0BEh; + I2TOC equ 0BFh; + I2CON equ 0C0h; + ; equ I2CON.7;8 + I2CEN equ I2CON.6;4 + STA equ I2CON.5;2 + STO equ I2CON.4;1 + SI equ I2CON.3;8 + AA equ I2CON.2;4 + ; equ I2CON.1;2 + I2CPX equ I2CON.0;1 + + + I2ADDR equ 0C1h; + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + pin_TX1 equ P1.6 + + pin_TX0 equ P0.6 + pin_RX0 equ P0.7 + + pin_SCL equ P1.3 + pin_SDA equ P1.4 + + pin_RST equ P1.0 + pin_CLC equ P1.1 + pin_led equ P1.2 + +; --------------------------------------------------------------------------- +; =========================================================================== + + + CMD_GENERATE_ATR equ 01h + CMD_WRITE_DATA_SIM equ 02h + CMD_READ_DATA_SIM equ 03h + + CMD_SET_BAUD_RATE equ 04h + CMD_SET_SIM_CLC equ 05h + CMD_GET_VERS equ 06h + CMD_WRITE_CONFIRM equ 07h + + + +; --------------------------------------------------------------------------- +; =========================================================================== + + bit_RX0 equ 32.0 + bit_command_receive equ 32.1 + bit_generate_ATR equ 32.2 + i2c_write_mode equ 32.3 + i2c_write_done equ 32.4 + bit_data_sim_wr equ 32.5 + ; equ 32.6 + bit_TX0 equ 32.7 + + bit_command_buff equ 33.0 + i2c_write_command equ 33.1 + i2c_command_done equ 33.2 + bit_wait_confirm equ 33.3 + bit_first_ATR equ 33.4 ;11/03/2019 + bit_length_answerH equ 33.5 + bit_length_answerL equ 33.6 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + bit_32 equ 32 + bit_33 equ 33 + + time_data_read equ 34 + time_confirm equ 35 + + pointer_RX1H equ 36 ;save SBUF(SIM) to XRAM + pointer_RX1L equ 37 ;save SBUF(SIM) to XRAM + + pointer_RX2H equ 38 ;read XRAM to I2C + pointer_RX2L equ 39 ;read XRAM to I2C + + pointer_TXH equ 40 + pointer_TXL equ 41 + + length_send_to_simH equ 42 + length_send_to_simL equ 43 + + length_answer_simH equ 44 + length_answer_simL equ 45 + + length_command equ 46 + + buff_command equ 47 + cmd_command equ 48 + data_command equ 49 + + STACKKKKK equ 200 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + XRAM_TX_BUFF equ 0 + XRAM_RX_BUFF equ 384 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +; Beginning of the main program + cseg at 00 + Ljmp main_start + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 11 ;1302Hz = 4MHZ(Fsys)/12/256 +; --------------------------------------------------------------------------- + jb time_confirm.7, $+3+2 ;3 + dec time_confirm ;2 +; --------------------------------------------------------------------------- + jb time_data_read.7,reti_timer0 + djnz time_data_read, reti_timer0 + setb pin_scl +reti_timer0: + reti + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 35 ;UART0 + ajmp jmp_UART0_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 51 ;I2C + ajmp jmp_i2c_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 123 ;UART1 + clr RI_1 + clr TI_1 + reti + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_UART0_interrupt: + jbc RI,jmp_byte_RI + jbc TI,jmp_byte_TI + reti +; --------------------------------------------------------------------------- +jmp_byte_RI: + jnb bit_first_ATR, jmp_not_collect ;11/03/2019 + + setb bit_RX0 + jb i2c_write_done,jmp_not_collect + PUSH ACC + PUSH DPH + PUSH DPL + mov DPL,pointer_RX1L + mov DPH,pointer_RX1H + mov a,SBUF + movx @DPTR,a + inc DPTR + mov pointer_RX1L,DPL + mov pointer_RX1H,DPH + POP DPL + POP DPH + POP ACC + ;09/08/2018 + clr pin_scl + mov time_data_read,#52 ;52/1302Hz = 40mS + + inc length_answer_simL + mov a,length_answer_simL + jnz $+2+2 ;2 + inc length_answer_simH ;2 + +jmp_not_collect: + reti +; --------------------------------------------------------------------------- +jmp_byte_TI: + setb bit_TX0 + reti + + +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_i2c_interrupt: + PUSH ACC + PUSH PSW + mov PSW,#24 + mov R7,I2STAT +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#000h,nextttt00000 + setb STO + clr SI + jb STO,$ + ajmp pop_i2c_psw +nextttt00000: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#060h,nextttt00001 ;START+MY ADRESS + clr pin_led ;LED ON + + clr bit_command_receive + clr i2c_write_mode + clr bit_data_sim_wr + clr bit_length_answerH + clr bit_length_answerL + clr bit_command_buff + clr i2c_write_command + + ajmp end_i2c_interrupt +nextttt00001: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#080h,nextttt00002 ;RAM ADRESS + + jb bit_command_receive,jmp_data_receive + setb bit_command_receive + + mov a,I2DAT +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne a,#CMD_WRITE_CONFIRM,next_comm001a + setb bit_wait_confirm + ajmp WRITEDATASIM +next_comm001a: +; --------------------------------------------------------------------------- + cjne a,#CMD_WRITE_DATA_SIM,next_comm001b + clr bit_wait_confirm + ajmp WRITEDATASIM +next_comm001b: +; --------------------------------------------------------------------------- + cjne a,#CMD_GENERATE_ATR,next_comm002 + ajmp ATR_GENERATE +next_comm002: +; --------------------------------------------------------------------------- + cjne a,#CMD_GET_VERS,next_comm003 + ajmp ANSWER_VERS +next_comm003: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_BAUD_RATE,next_comm004 + ajmp BAUD_RATE_SET +next_comm004: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_SIM_CLC,next_comm005 + ajmp SIM_CLC_SET +next_comm005: +; --------------------------------------------------------------------------- + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +jmp_data_receive: + ;What receive ? Data to SIM/Command to bridge + jb bit_data_sim_wr, jmp_data_sim_receive + jb i2c_write_command,jmp_comm_bridge_receive + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +jmp_comm_bridge_receive: + mov @R0,I2DAT + inc R0 + inc length_command + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +jmp_data_sim_receive: + + setb i2c_write_mode + + PUSH DPH + PUSH DPL + mov DPL,pointer_TXL + mov DPH,pointer_TXH + mov a,I2DAT + movx @DPTR,a + inc DPTR + mov pointer_TXL,DPL + mov pointer_TXH,DPH + POP DPL + POP DPH + + inc length_send_to_simL + mov a,length_send_to_simL + jnz $+2+2 ;2 + inc length_send_to_simH ;2 + + ajmp end_i2c_interrupt +nextttt00002: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0A0h,nextttt00003 ;STOP + setb pin_led ;LED OFF + + ;Command finish ? + jnb i2c_write_command,jmp_not_command + clr i2c_write_command + setb i2c_command_done +jmp_not_command: + + ;data to SIM finish ? + jnb i2c_write_mode,end_i2c_interrupt + clr i2c_write_mode + + setb i2c_write_done + ;Prepare to answer + mov length_answer_simH,#0 + mov length_answer_simL,#0 + mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX1L,#LOW (XRAM_RX_BUFF) + mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX2L,#LOW (XRAM_RX_BUFF) + + ajmp end_i2c_interrupt +nextttt00003: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0A8h,nextttt00004 + sjmp read_byte_I2C +nextttt00004: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0B8h,nextttt00005 +read_byte_I2C: + jnb bit_command_buff,jmp_not_comm_buff2 + mov I2DAT,@R0 + inc R0 + ajmp end_i2c_interrupt + +jmp_not_comm_buff2: + jb bit_length_answerH,jmp_not_comm_buff3 + setb bit_length_answerH + mov I2DAT,length_answer_simH + ajmp end_i2c_interrupt + +jmp_not_comm_buff3: + jb bit_length_answerL,read_byte_APROM + setb bit_length_answerL + mov I2DAT,length_answer_simL + ajmp end_i2c_interrupt + +read_byte_APROM: + PUSH DPH + PUSH DPL + mov DPL,pointer_RX2L + mov DPH,pointer_RX2H + movx a,@DPTR + mov I2DAT,a + inc DPTR + mov pointer_RX2L,DPL + mov pointer_RX2H,DPH + POP DPL + POP DPH + +nextttt00005: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +end_i2c_interrupt: + clr STA + clr STO + setb AA +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +pop_i2c_psw: + POP PSW + POP ACC + clr SI + reti + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +ANSWER_VERS: + mov R0,#data_command + mov cmd_command,#CMD_GET_VERS + mov (data_command+0),#2 + mov (data_command+1),#VERS_HI + mov (data_command+2),#VERS_LO + setb bit_command_buff + ajmp end_i2c_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +ATR_GENERATE: + setb bit_generate_ATR + ;Prepare to answer + mov length_answer_simH,#0 + mov length_answer_simL,#0 + mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX1L,#LOW (XRAM_RX_BUFF) + mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX2L,#LOW (XRAM_RX_BUFF) + ajmp end_i2c_interrupt + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +BAUD_RATE_SET: + mov R0,#data_command + mov length_command,#0 + mov cmd_command,#CMD_SET_BAUD_RATE + setb i2c_write_command + ajmp end_i2c_interrupt + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +SIM_CLC_SET: + mov R0,#data_command + mov length_command,#0 + mov cmd_command,#CMD_SET_SIM_CLC + setb i2c_write_command + ajmp end_i2c_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +WRITEDATASIM: + mov length_send_to_simH,#0 + mov length_send_to_simL,#0 + setb bit_data_sim_wr + mov pointer_TXH,#HIGH(XRAM_TX_BUFF) + mov pointer_TXL,#LOW (XRAM_TX_BUFF) + ajmp end_i2c_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +main_start: + mov SP,#STACKKKKK +; --------------------------------------------------------------------------- + ;0-bidirect 1-push pull 0-input only 1-open drain + ;0 0 1 1 +; --------------------------------------------------------------------------- + mov P0M2,#01000000b ;?0 + mov P0M1,#11111111b ;P1.6-Tx0 SIM; + ; + mov P1M2,#01011111b ;1 + mov P1M1,#10111000b ;P1.6-Tx1 DEBUG; P1.4,P1.3 - I2C; + + mov P3M2,#00000000b ;P3 + mov P3M1,#11111111b ; +; --------------------------------------------------------------------------- + mov TMOD, #22h + mov TH0, #0 ;14400hz + mov TH1, #0E9h ;UART0 10800 Bit/sec + mov TCON, #55h +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov TA,#0AAh + mov TA,#055h + orl SFRS,#00000001b + + mov P1S, #00010000b ;P1.4 trigger schmiddt + + mov TA,#0AAh + mov TA,#055h + anl SFRS,#11111110b +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;------- CONFIG I2C --------- + mov I2CON, #44h ;set AA, set I2C enable + setb pin_sda + setb pin_scl + mov I2ADDR,#0C0h +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;mov SCON, #050h ;UART0 8bit + mov SCON, #0D0h ;UART0 9bit + ;mov PCON, #11000000b;FE_0 enable + mov PCON, #10000000b;FE_0 disable +; --------------------------------------------------------------------------- + mov SCON_1,#050h ;UART1 + ;mov T3CON, #01101000b;FE_1 enable TIMER3 UART0 BAUD + ;mov T3CON, #00101000b;FE_1 disable TIMER3 UART0 BAUD + mov T3CON, #00001000b;FE_1 disable TIMER1 UART0 BAUD + ;mov RL3,#0E9h ;10800/21600 + ;mov RH3,#0FFh +; --------------------------------------------------------------------------- + ;UART1 + mov RL3,#0F7h ;27777/55556 + mov RH3,#0FFh +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov CKDIV,#2 ;Fsys=4.00MHZ + ;mov CKDIV,#1 ;Fsys=8.00MHZ +; --------------------------------------------------------------------------- + mov bit_32,#0 + mov bit_33,#0 + setb time_data_read.7 +; --------------------------------------------------------------------------- + ;orl CKCON,#00000010b ;ENABLE CLC TIMER1 Fsys/12 + orl CKCON,#00010010b ;ENABLE CLC TIMER1 Fsys +; --------------------------------------------------------------------------- + ;mov a,RCTRIM0 + ;add a,#31 + ;mov TA,#0AAh + ;mov TA,#055h + ;mov RCTRIM0,a +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + acall clr_buffer +; --------------------------------------------------------------------------- + mov EIE, #00000001b ;I2C Interrupt + ;mov IE, #10010000b ;EA, SERIAL0 + mov IE, #10010010b ;EA, SERIAL0, TIMER0 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +main_loop: + acall control_ATR + acall control_send_to_sim + acall control_command + sjmp main_loop + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_command: + jbc i2c_command_done,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;Control Length command=1 + mov a,length_command + cjne a,#1,next_commandEND ;error length_command != 1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov a,cmd_command + cjne a,#CMD_SET_BAUD_RATE,next_command001 + mov TH1,data_command ;Timer1 HIGH byte + ret +next_command001: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_SIM_CLC, next_command002 + mov CKDIV,data_command ;Fsys DIV + ret +next_command002: +; --------------------------------------------------------------------------- +next_commandEND: + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_send_to_sim: + jb i2c_write_done,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jbc bit_wait_confirm,jmp_wait_confirm +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov DPTR,#XRAM_TX_BUFF +looop_send: + movx a,@DPTR + inc DPTR + acall for_coooooom0 + + clr c + mov a,length_send_to_simL + subb a,#1 + mov length_send_to_simL,a + mov a,length_send_to_simH + subb a,#0 + mov length_send_to_simH,a + orl a,length_send_to_simL + jnz looop_send +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jnb bit_RX0,$ + clr i2c_write_done + ret + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_wait_confirm: + mov DPTR,#(XRAM_TX_BUFF+1) + movx a,@DPTR + mov R3,a + mov R4,#5 +; --------------------------------------------------------------------------- + mov DPTR,#XRAM_TX_BUFF +looop_seend: + movx a,@DPTR + inc DPTR + acall for_coooooom0 + djnz R4,jmp_not_5byte + + jnb bit_RX0,$ + clr bit_RX0 + ;18/12/2018 + mov time_confirm,#65 ;New timeout 50mS +looop_waitconf: + jb time_confirm.7,jmp_no_answer + jnb bit_RX0,looop_waitconf + + ;clr pin_scl ;TEST PULSE! + mov a,SBUF + xrl a,R3 + ;setb pin_scl ;TEST PULSE! + + jnz jmp_no_correct_answer ;18/12/2018 + + ;pause for next byte 17/12/2018 + mov R7,#0 + djnz R7,$ ;~260mkSec + djnz R7,$ ;~260mkSec + djnz R7,$ ;~260mkSec + +jmp_not_5byte: + + clr c + mov a,length_send_to_simL + subb a,#1 + mov length_send_to_simL,a + mov a,length_send_to_simH + subb a,#0 + mov length_send_to_simH,a + orl a,length_send_to_simL + jnz looop_seend +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jnb bit_RX0,$ + clr bit_RX0 +jmp_no_answer: + clr i2c_write_done + ret + +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +;18/12/2018 +jmp_no_correct_answer: + clr EA + clr i2c_write_done + + mov DPL,pointer_RX1L + mov DPH,pointer_RX1H + mov a,SBUF + movx @DPTR,a + inc DPTR + mov pointer_RX1L,DPL + mov pointer_RX1H,DPH + + clr pin_scl + mov time_data_read,#52 ;52/1302Hz = 40mS + + inc length_answer_simL + mov a,length_answer_simL + jnz $+2+2 ;2 + inc length_answer_simH ;2 + + setb EA + ret + + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_ATR: + jbc bit_generate_ATR,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- + clr pin_RST + ;acall clr_buffer + ; Add rezet pause 17/12/2018 + + mov R6,#200 +looop_pause50mS: + djnz R7,$ ;~260mkSec + djnz R6,looop_pause50mS + + ;Prepare to answer 11/03/2019 + acall clr_buffer + + mov length_answer_simH,#0 + mov length_answer_simL,#0 + mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX1L,#LOW (XRAM_RX_BUFF) + mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX2L,#LOW (XRAM_RX_BUFF) + setb bit_first_ATR + setb pin_RST + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +for_coooooom0: + clr bit_RX0 + mov c,P + mov TB8,c ;9bit parity + mov SBUF,a + jnb bit_TX0,$ + clr bit_TX0 + mov R7,#100 + djnz R7,$ + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +clr_buffer: + mov DPTR,#0256 ;Receive SIM buffer + mov R7,#255 + clr a +looop_clr_bufff: + movx @DPTR,a + inc DPTR + djnz R7,looop_clr_bufff + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +;for_coooooom1: +; mov SBUF_1,a +; jnb TI_1,$ +; clr TI_1 +; ret +; +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + +end. From b487961cbd5aa82994bf312a15b2ee5b6aa20446 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Tue, 6 Dec 2022 18:07:10 +0100 Subject: [PATCH 408/759] Moved to non-deprecated API to init Python intepreter --- CHANGELOG.md | 1 + client/src/cmdscript.c | 24 +++++++++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04916e479..01094bf38 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] + - Moved to non-deprecated API to initialize Python interpreter (jmichel@) - Changed `sc upgrade` updated firmware v4.12 (RDV40) (@sentiprox) - Fixed contact interface / smartcard APDU chaining logic and allow 256 bytes ADPU payload. Need SIM firmware 4.12 to work (@jmichel) - Fixed `lf hitag dump` - Should now work as described in the command help (@natmchugh) diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index c63842ae3..18a0586f8 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -412,22 +412,28 @@ static int CmdScriptRun(const char *Cmd) { // hook Proxmark3 API PyImport_AppendInittab("_pm3", PyInit__pm3); #endif - Py_Initialize(); + PyConfig py_conf; + PyConfig_InitIsolatedConfig(&py_conf); //int argc, char ** argv char *argv[128]; - int argc = split(arguments, argv); - wchar_t *py_args[argc + 1]; - py_args[0] = Py_DecodeLocale(filename, NULL); - for (int i = 0; i < argc; i++) { - py_args[i + 1] = Py_DecodeLocale(argv[i], NULL); - } + argv[0] = filename; + int argc = split(arguments, &argv[1]); + PyConfig_SetBytesArgv(&py_conf, argc + 1, argv); + // Despite being isolated we probably want to allow users to use + // the Python packages they installed on their user directory as well + // as obey env variables. + py_conf.use_environment = 1; + py_conf.user_site_directory = 1; + // Setting this pre-intializes Python implictly which will change the config + PyConfig_SetString(&py_conf, &py_conf.program_name, program); - PySys_SetArgv(argc + 1, py_args); + Py_InitializeFromConfig(&py_conf); // clean up + PyConfig_Clear(&py_conf); for (int i = 0; i < argc; ++i) { - free(argv[i]); + free(argv[i + 1]); } // setup search paths. From ec5de2bbdf09c70cd049ce33b6e356406792b7b4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 6 Dec 2022 22:17:06 +0100 Subject: [PATCH 409/759] revert check until bin file is available --- tools/pm3_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index 2187ff13a..f682d3491 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -236,7 +236,7 @@ while true; do if $TESTALL || $TESTCOMMON; then echo -e "\n${C_BLUE}Testing common:${C_NC}" if ! CheckFileExist "hardnested tables exists" "$RESOURCEPATH/hardnested_tables/bitflip_0_001_states.bin.bz2"; then break; fi - if ! CheckFileExist "simmodule fw file exists" "$RESOURCEPATH/sim012.bin"; then break; fi + if ! CheckFileExist "simmodule fw file exists" "$RESOURCEPATH/sim011.bin"; then break; fi if ! CheckFileExist "iCLASS dictionary exists" "$DICPATH/iclass_default_keys.dic"; then break; fi if ! CheckFileExist "MFC dictionary exists" "$DICPATH/mfc_default_keys.dic"; then break; fi if ! CheckFileExist "MFDES dictionary exists" "$DICPATH/mfdes_default_keys.dic"; then break; fi From 5209407e9dfd62da5aac755aa28c48697c67712a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 6 Dec 2022 22:19:18 +0100 Subject: [PATCH 410/759] revert installing 012.bin until its available --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 97ae22000..b072d7379 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfk #all clean install uninstall check: %: hitag2crack/% INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py pm3_amii_bin2eml.pl pm3_reblay-emulating.py pm3_reblay-reading.py -INSTALLSIMFW=sim012.bin sim012.sha512.txt +INSTALLSIMFW=sim011.bin sim011.sha512.txt INSTALLSCRIPTS=pm3 pm3-flash pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage INSTALLSHARES=tools/jtag_openocd traces INSTALLDOCS=doc/*.md doc/md From 76846ae1869c51aaeceaf1e22acac7f13e889198 Mon Sep 17 00:00:00 2001 From: cynix Date: Thu, 8 Dec 2022 00:09:43 +1100 Subject: [PATCH 411/759] Add estimated FW size saving for SKIP_ZX8211 Signed-off-by: cynix --- doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index ba53d3aaf..06040b59e 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -166,7 +166,7 @@ a series of `SKIP_*` allow to skip some of the functionalities and to get a smal |SKIP_NFCBARCODE=1 | 1.4kb |SKIP_HFSNIFF=1 | 0.5kb |SKIP_HFPLOT=1 | 0.3kb -|SKIP_ZX8211=1 | unknown yet +|SKIP_ZX8211=1 | 0.3kb So for example, at the time of writing, this is a valid `Makefile.platform` compiling an image for 256k: ``` From e364d7e03d3ee0236088387b82a8776233387da0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Dec 2022 07:36:02 +0100 Subject: [PATCH 412/759] add updated sim module firmware v4.13, this is breaking change for `smart` category commands --- client/resources/sim013.bin | Bin 0 -> 866 bytes client/resources/sim013.sha512.txt | 1 + client/src/cmdsmartcard.c | 2 +- doc/cheatsheet.md | 2 +- .../Troubleshooting.md | 6 +- .../2_Configuration-and-Verification.md | 18 +- doc/path_notes.md | 2 +- tools/pm3_online_check.py | 2 +- tools/pm3_tests.sh | 2 +- tools/simmodule/sim013.asm | 819 ++++++++++++++++++ 10 files changed, 837 insertions(+), 17 deletions(-) create mode 100644 client/resources/sim013.bin create mode 100644 client/resources/sim013.sha512.txt create mode 100644 tools/simmodule/sim013.asm diff --git a/client/resources/sim013.bin b/client/resources/sim013.bin new file mode 100644 index 0000000000000000000000000000000000000000..3fae92bd845dd48dfe87824f6e70f47bec585472 GIT binary patch literal 866 zcmbVK&rcIU6rP#x(iSM$kQhu%V0S5{KWMWo`~e#DE>SKX)PpxK^zfnwBWpM7k3>u< zkkD{3k{HrxP}xKdYg&gQcrlwvycyerdoWzMG@wFp7BL3&}CTp7Nr6wUZVorU5F_ z2<@OD8dgeWSfEb2; zgVPp?5h$+=Ya#Kj6XHsdAd6T74o4k9)?uYNIuPs6SuwNTaJX2%WyX9lx<;#vx-K8Y zs(y12v=$g7pbIb*VZ0S1{}SZ93<6DHd$um&epTjXI@Rb>IIQd@T( zq5490WYtT};6}H_hXXF}L6@j-e9?}q7+X>$f>oNoy-{m^-sMmD>ql8T%c~SUaSQW}q88kv!HH|N Srkck__R>V<%hp0|SN#c3S3NZV literal 0 HcmV?d00001 diff --git a/client/resources/sim013.sha512.txt b/client/resources/sim013.sha512.txt new file mode 100644 index 000000000..202eff3c4 --- /dev/null +++ b/client/resources/sim013.sha512.txt @@ -0,0 +1 @@ +3bb6cbd893ce07720d8514d00706b230b4026a54d6c4dc068ca294beea3f3735c75dae65bc153f573b7b891753c85860f6427fb0ad7edb804d58925c50d1fc76 *sim013.bin diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index 3d9888a50..5cceb8b48 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -522,7 +522,7 @@ static int CmdSmartUpgrade(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "smart upgrade", "Upgrade RDV4 sim module firmware", - "smart upgrade -f sim012.bin" + "smart upgrade -f sim013.bin" ); void *argtable[] = { diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 1f0d66c1b..22e47b3f1 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -713,7 +713,7 @@ pm3 --> mem load -f iclass_default_keys --iclass Upgrade Sim Module firmware ``` -pm3 --> smart upgrade -f sim012.bin +pm3 --> smart upgrade -f sim013.bin ``` ## Smart Card diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index b946fd0d0..68d3d5570 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -161,9 +161,9 @@ proxmark3 --flash --image /usr/local/share/proxmark3/firmware/f proxmark3 --flash --image /usr/share/proxmark3/firmware/fullimage.elf using the script: -pm3 --> smart upgrade -f /usr/local/share/proxmark3/firmware/sim012.bin +pm3 --> smart upgrade -f /usr/local/share/proxmark3/firmware/sim013.bin <> -pm3 --> smart upgrade -f /usr/share/proxmark3/firmware/sim012.bin +pm3 --> smart upgrade -f /usr/share/proxmark3/firmware/sim013.bin ``` If you didn't install the PRoxmark but you're working from the sources directory and depending how you launch the client, your working directory might be the root of the repository: @@ -186,7 +186,7 @@ client/proxmark3 --flash --image armsrc/obj/fullimage.elf <> ./proxmark3 --flash --image ../armsrc/obj/fullimage.elf -pm3 --> smart upgrade -f sim012.bin +pm3 --> smart upgrade -f sim013.bin ``` etc. diff --git a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md index 00841d118..791605f17 100644 --- a/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md +++ b/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md @@ -61,23 +61,23 @@ or These versions is obsolete. -If you didn't download sim012.bin from the RRG Repo be aware that it might be corrupted or faulty. +If you didn't download sim013.bin from the RRG Repo be aware that it might be corrupted or faulty. You find a hash text file in this folder. It was generated with the following linux command. ``` -sha512sum -b sim012.bin > sim012.sha512.txt +sha512sum -b sim013.bin > sim013.sha512.txt ``` -You should validate the sim012.bin file against this hash file in order to be sure the file is not corrupted or faulty. +You should validate the sim013.bin file against this hash file in order to be sure the file is not corrupted or faulty. The following command upgrades your device sim module firmware. Don't not turn off your device during the execution of this command!! Even its a quite fast command you should be warned. You may brick it if you interrupt it. ``` -[usb] pm3 --> smart upgrade -f /usr/local/share/proxmark3/firmware/sim012.bin +[usb] pm3 --> smart upgrade -f /usr/local/share/proxmark3/firmware/sim013.bin # or if from local repo -[usb] pm3 --> smart upgrade -f sim012.bin +[usb] pm3 --> smart upgrade -f sim013.bin ``` You get the following output if the execution was successful: @@ -88,10 +88,10 @@ You get the following output if the execution was successful: [!] ⚠️ A dangerous command, do wrong and you could brick the sim module [=] ------------------------------------------------------------------- -[=] firmware file sim012.bin -[=] Checking integrity sim012.sha512.txt -[+] loaded 864 bytes from binary file sim012.bin -[+] loaded 141 bytes from binary file sim012.sha512.txt +[=] firmware file sim013.bin +[=] Checking integrity sim013.sha512.txt +[+] loaded 866 bytes from binary file sim013.bin +[+] loaded 141 bytes from binary file sim013.sha512.txt [=] Don't turn off your PM3! [+] Sim module firmware uploading to PM3... 🕑 864 bytes sent diff --git a/doc/path_notes.md b/doc/path_notes.md index 72bde2aa6..a111e8cd1 100644 --- a/doc/path_notes.md +++ b/doc/path_notes.md @@ -64,7 +64,7 @@ The recovery / firmware files will be copied to ``` * Proxmark3 firmware: `bootrom.elf`, `fullimage.elf`, `proxmark3_recovery.bin` (used for JTAG) -* SIM firmware: `sim012.bin`, `sim012.sha512.txt` +* SIM firmware: `sim013.bin`, `sim013.sha512.txt` ## Traces diff --git a/tools/pm3_online_check.py b/tools/pm3_online_check.py index 2298a2ede..a7961d319 100755 --- a/tools/pm3_online_check.py +++ b/tools/pm3_online_check.py @@ -122,7 +122,7 @@ def pm3_lf_t55xx(child): def pm3_flash_sm(child): try: print("[+] Updating smart card fw") - child.sendline('smart upgrade -f sim012.bin') + child.sendline('smart upgrade -f sim013.bin') i = child.expect('pm3 --> ') msg = escape_ansi(str(child.before)) print("================") diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index f682d3491..a39615cb6 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -236,7 +236,7 @@ while true; do if $TESTALL || $TESTCOMMON; then echo -e "\n${C_BLUE}Testing common:${C_NC}" if ! CheckFileExist "hardnested tables exists" "$RESOURCEPATH/hardnested_tables/bitflip_0_001_states.bin.bz2"; then break; fi - if ! CheckFileExist "simmodule fw file exists" "$RESOURCEPATH/sim011.bin"; then break; fi + if ! CheckFileExist "simmodule fw file exists" "$RESOURCEPATH/sim013.bin"; then break; fi if ! CheckFileExist "iCLASS dictionary exists" "$DICPATH/iclass_default_keys.dic"; then break; fi if ! CheckFileExist "MFC dictionary exists" "$DICPATH/mfc_default_keys.dic"; then break; fi if ! CheckFileExist "MFDES dictionary exists" "$DICPATH/mfdes_default_keys.dic"; then break; fi diff --git a/tools/simmodule/sim013.asm b/tools/simmodule/sim013.asm new file mode 100644 index 000000000..b26aa1906 --- /dev/null +++ b/tools/simmodule/sim013.asm @@ -0,0 +1,819 @@ +; --------------------------------------------------------------------------- +; Proxmark3 RDV4 SIM module firmware +; +; Copyright (C) 2109, 2022 Sentinel +; +; This program is free software: you can redistribute it and/or modify it +; under the terms of the GNU Lesser General Public License as published by the +; Free Software Foundation, either version 3 of the License, or (at your +; option) any later version. +; +; This program is distributed in the hope that it will be useful, but WITHOUT +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +; more details. +; +; You should have received a copy of the GNU Lesser General Public License +; along with this program. If not, see +; --------------------------------------------------------------------------- + VERS_HI equ 4 + VERS_LO equ 13 +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + SCON_0 equ 098h + FE_0 equ 098h.7 + + SCON_1 equ 0F8h + RI_1 equ 0F8h.0 + TI_1 equ 0F8h.1 + FE_1 equ 0F8h.7 + SBUF_1 equ 09Ah + T3CON equ 0C4h + RL3 equ 0C5h + RH3 equ 0C6h + + P0M1 equ 0B1h + P0M2 equ 0B2h + P1M1 equ 0B3h + P1M2 equ 0B4h + P3M1 equ 0ACh; + P3M2 equ 0ADh; + + EIE equ 09Bh + EIE1 equ 09Ch + + TA equ 0C7h + + RCTRIM0 equ 084h +; --------------------------------------------------------------------------- + CKCON equ 08Eh + CKDIV equ 095h +; --------------------------------------------------------------------------- + P1S equ 0B3h ;Page1 + SFRS equ 091h ;TA Protection +; --------------------------------------------------------------------------- + ;AUXR1 equ 0A2h +; --------------------------------------------------------------------------- + I2DAT equ 0BCh; + I2STAT equ 0BDh; + I2CLK equ 0BEh; + I2TOC equ 0BFh; + I2CON equ 0C0h; + ; equ I2CON.7;8 + I2CEN equ I2CON.6;4 + STA equ I2CON.5;2 + STO equ I2CON.4;1 + SI equ I2CON.3;8 + AA equ I2CON.2;4 + ; equ I2CON.1;2 + I2CPX equ I2CON.0;1 + + + I2ADDR equ 0C1h; + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + pin_TX1 equ P1.6 + + pin_TX0 equ P0.6 + pin_RX0 equ P0.7 + + pin_SCL equ P1.3 + pin_SDA equ P1.4 + + pin_RST equ P1.0 + pin_CLC equ P1.1 + pin_led equ P1.2 + +; --------------------------------------------------------------------------- +; =========================================================================== + + + CMD_GENERATE_ATR equ 01h + CMD_WRITE_DATA_SIM equ 02h + CMD_READ_DATA_SIM equ 03h + + CMD_SET_BAUD_RATE equ 04h + CMD_SET_SIM_CLC equ 05h + CMD_GET_VERS equ 06h + CMD_WRITE_CONFIRM equ 07h + + + +; --------------------------------------------------------------------------- +; =========================================================================== + + bit_RX0 equ 32.0 + bit_command_receive equ 32.1 + bit_generate_ATR equ 32.2 + i2c_write_mode equ 32.3 + i2c_write_done equ 32.4 + bit_data_sim_wr equ 32.5 + ; equ 32.6 + bit_TX0 equ 32.7 + + bit_command_buff equ 33.0 + i2c_write_command equ 33.1 + i2c_command_done equ 33.2 + bit_wait_confirm equ 33.3 + bit_first_ATR equ 33.4 ;11/03/2019 + bit_length_answerH equ 33.5 + bit_length_answerL equ 33.6 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + bit_32 equ 32 + bit_33 equ 33 + + time_data_read equ 34 + time_confirm equ 35 + + pointer_RX1H equ 36 ;save SBUF(SIM) to XRAM + pointer_RX1L equ 37 ;save SBUF(SIM) to XRAM + + pointer_RX2H equ 38 ;read XRAM to I2C + pointer_RX2L equ 39 ;read XRAM to I2C + + pointer_TXH equ 40 + pointer_TXL equ 41 + + length_send_to_simH equ 42 + length_send_to_simL equ 43 + + length_answer_simH equ 44 + length_answer_simL equ 45 + + length_command equ 46 + + buff_command equ 47 + cmd_command equ 48 + data_command equ 49 + + STACKKKKK equ 200 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + XRAM_TX_BUFF equ 0 + XRAM_RX_BUFF equ 384 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +; Beginning of the main program + cseg at 00 + Ljmp main_start + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 11 ;1302Hz = 4MHZ(Fsys)/12/256 +; --------------------------------------------------------------------------- + jb time_confirm.7, $+3+2 ;3 + dec time_confirm ;2 +; --------------------------------------------------------------------------- + jb time_data_read.7,reti_timer0 + djnz time_data_read, reti_timer0 + setb pin_scl +reti_timer0: + reti + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 35 ;UART0 + ajmp jmp_UART0_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 51 ;I2C + ajmp jmp_i2c_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + cseg at 123 ;UART1 + clr RI_1 + clr TI_1 + reti + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_UART0_interrupt: + jbc RI,jmp_byte_RI + jbc TI,jmp_byte_TI + reti +; --------------------------------------------------------------------------- +jmp_byte_RI: + jnb bit_first_ATR, jmp_not_collect ;11/03/2019 + + setb bit_RX0 + jb i2c_write_done,jmp_not_collect + PUSH ACC + PUSH DPH + PUSH DPL + mov DPL,pointer_RX1L + mov DPH,pointer_RX1H + mov a,SBUF + movx @DPTR,a + inc DPTR + mov pointer_RX1L,DPL + mov pointer_RX1H,DPH + POP DPL + POP DPH + POP ACC + ;09/08/2018 + clr pin_scl + mov time_data_read,#52 ;52/1302Hz = 40mS + + inc length_answer_simL + mov a,length_answer_simL + jnz $+2+2 ;2 + inc length_answer_simH ;2 + +jmp_not_collect: + reti +; --------------------------------------------------------------------------- +jmp_byte_TI: + setb bit_TX0 + reti + + +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_i2c_interrupt: + PUSH ACC + PUSH PSW + mov PSW,#24 + mov R7,I2STAT +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#000h,nextttt00000 + setb STO + clr SI + jb STO,$ + ajmp pop_i2c_psw +nextttt00000: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#060h,nextttt00001 ;START+MY ADRESS + clr pin_led ;LED ON + + clr bit_command_receive + clr i2c_write_mode + clr bit_data_sim_wr + clr bit_length_answerH + clr bit_length_answerL + clr bit_command_buff + clr i2c_write_command + + ajmp end_i2c_interrupt +nextttt00001: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#080h,nextttt00002 ;RAM ADRESS + + jb bit_command_receive,jmp_data_receive + setb bit_command_receive + + mov a,I2DAT +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne a,#CMD_WRITE_CONFIRM,next_comm001a + setb bit_wait_confirm + ajmp WRITEDATASIM +next_comm001a: +; --------------------------------------------------------------------------- + cjne a,#CMD_WRITE_DATA_SIM,next_comm001b + clr bit_wait_confirm + ajmp WRITEDATASIM +next_comm001b: +; --------------------------------------------------------------------------- + cjne a,#CMD_GENERATE_ATR,next_comm002 + ajmp ATR_GENERATE +next_comm002: +; --------------------------------------------------------------------------- + cjne a,#CMD_GET_VERS,next_comm003 + ajmp ANSWER_VERS +next_comm003: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_BAUD_RATE,next_comm004 + ajmp BAUD_RATE_SET +next_comm004: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_SIM_CLC,next_comm005 + ajmp SIM_CLC_SET +next_comm005: +; --------------------------------------------------------------------------- + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +jmp_data_receive: + ;What receive ? Data to SIM/Command to bridge + jb bit_data_sim_wr, jmp_data_sim_receive + jb i2c_write_command,jmp_comm_bridge_receive + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +jmp_comm_bridge_receive: + mov @R0,I2DAT + inc R0 + inc length_command + ajmp end_i2c_interrupt +; --------------------------------------------------------------------------- +jmp_data_sim_receive: + + setb i2c_write_mode + + PUSH DPH + PUSH DPL + mov DPL,pointer_TXL + mov DPH,pointer_TXH + mov a,I2DAT + movx @DPTR,a + inc DPTR + mov pointer_TXL,DPL + mov pointer_TXH,DPH + POP DPL + POP DPH + + inc length_send_to_simL + mov a,length_send_to_simL + jnz $+2+2 ;2 + inc length_send_to_simH ;2 + + ajmp end_i2c_interrupt +nextttt00002: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0A0h,nextttt00003 ;STOP + setb pin_led ;LED OFF + + ;Command finish ? + jnb i2c_write_command,jmp_not_command + clr i2c_write_command + setb i2c_command_done +jmp_not_command: + + ;data to SIM finish ? + jnb i2c_write_mode,end_i2c_interrupt + clr i2c_write_mode + + setb i2c_write_done + ;Prepare to answer + mov length_answer_simH,#0 + mov length_answer_simL,#0 + mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX1L,#LOW (XRAM_RX_BUFF) + mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX2L,#LOW (XRAM_RX_BUFF) + + ajmp end_i2c_interrupt +nextttt00003: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0A8h,nextttt00004 + sjmp read_byte_I2C +nextttt00004: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + cjne R7,#0B8h,nextttt00005 +read_byte_I2C: + jnb bit_command_buff,jmp_not_comm_buff2 + mov I2DAT,@R0 + inc R0 + ajmp end_i2c_interrupt + +jmp_not_comm_buff2: + jb bit_length_answerH,jmp_not_comm_buff3 + setb bit_length_answerH + mov I2DAT,length_answer_simH + ajmp end_i2c_interrupt + +jmp_not_comm_buff3: + jb bit_length_answerL,read_byte_APROM + setb bit_length_answerL + mov I2DAT,length_answer_simL + ajmp end_i2c_interrupt + +read_byte_APROM: + PUSH DPH + PUSH DPL + mov DPL,pointer_RX2L + mov DPH,pointer_RX2H + movx a,@DPTR + mov I2DAT,a + inc DPTR + mov pointer_RX2L,DPL + mov pointer_RX2H,DPH + POP DPL + POP DPH + +nextttt00005: +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +end_i2c_interrupt: + clr STA + clr STO + setb AA +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +pop_i2c_psw: + POP PSW + POP ACC + clr SI + reti + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +ANSWER_VERS: + mov R0,#data_command + mov cmd_command,#CMD_GET_VERS + mov (data_command+0),#2 + mov (data_command+1),#VERS_HI + mov (data_command+2),#VERS_LO + setb bit_command_buff + ajmp end_i2c_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +ATR_GENERATE: + setb bit_generate_ATR + ;Prepare to answer + mov length_answer_simH,#0 + mov length_answer_simL,#0 + mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX1L,#LOW (XRAM_RX_BUFF) + mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX2L,#LOW (XRAM_RX_BUFF) + ajmp end_i2c_interrupt + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +BAUD_RATE_SET: + mov R0,#data_command + mov length_command,#0 + mov cmd_command,#CMD_SET_BAUD_RATE + setb i2c_write_command + ajmp end_i2c_interrupt + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +SIM_CLC_SET: + mov R0,#data_command + mov length_command,#0 + mov cmd_command,#CMD_SET_SIM_CLC + setb i2c_write_command + ajmp end_i2c_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +WRITEDATASIM: + mov length_send_to_simH,#0 + mov length_send_to_simL,#0 + setb bit_data_sim_wr + mov pointer_TXH,#HIGH(XRAM_TX_BUFF) + mov pointer_TXL,#LOW (XRAM_TX_BUFF) + ajmp end_i2c_interrupt + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +main_start: + mov SP,#STACKKKKK +; --------------------------------------------------------------------------- + ;0-bidirect 1-push pull 0-input only 1-open drain + ;0 0 1 1 +; --------------------------------------------------------------------------- + mov P0M2,#01000000b ;?0 + mov P0M1,#11111111b ;P1.6-Tx0 SIM; + ; + mov P1M2,#01011111b ;1 + mov P1M1,#10111000b ;P1.6-Tx1 DEBUG; P1.4,P1.3 - I2C; + + mov P3M2,#00000000b ;P3 + mov P3M1,#11111111b ; +; --------------------------------------------------------------------------- + mov TMOD, #22h + mov TH0, #0 ;14400hz + mov TH1, #0E9h ;UART0 10800 Bit/sec + mov TCON, #55h +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov TA,#0AAh + mov TA,#055h + orl SFRS,#00000001b + + mov P1S, #00010000b ;P1.4 trigger schmiddt + + mov TA,#0AAh + mov TA,#055h + anl SFRS,#11111110b +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;------- CONFIG I2C --------- + mov I2CON, #44h ;set AA, set I2C enable + setb pin_sda + setb pin_scl + mov I2ADDR,#0C0h +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;mov SCON, #050h ;UART0 8bit + mov SCON, #0D0h ;UART0 9bit + ;mov PCON, #11000000b;FE_0 enable + mov PCON, #10000000b;FE_0 disable +; --------------------------------------------------------------------------- + mov SCON_1,#050h ;UART1 + ;mov T3CON, #01101000b;FE_1 enable TIMER3 UART0 BAUD + ;mov T3CON, #00101000b;FE_1 disable TIMER3 UART0 BAUD + mov T3CON, #00001000b;FE_1 disable TIMER1 UART0 BAUD + ;mov RL3,#0E9h ;10800/21600 + ;mov RH3,#0FFh +; --------------------------------------------------------------------------- + ;UART1 + mov RL3,#0F7h ;27777/55556 + mov RH3,#0FFh +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov CKDIV,#2 ;Fsys=4.00MHZ + ;mov CKDIV,#1 ;Fsys=8.00MHZ +; --------------------------------------------------------------------------- + mov bit_32,#0 + mov bit_33,#0 + setb time_data_read.7 +; --------------------------------------------------------------------------- + ;orl CKCON,#00000010b ;ENABLE CLC TIMER1 Fsys/12 + orl CKCON,#00010010b ;ENABLE CLC TIMER1 Fsys +; --------------------------------------------------------------------------- + ;mov a,RCTRIM0 + ;add a,#31 + ;mov TA,#0AAh + ;mov TA,#055h + ;mov RCTRIM0,a +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + acall clr_buffer +; --------------------------------------------------------------------------- + mov EIE, #00000001b ;I2C Interrupt + ;mov IE, #10010000b ;EA, SERIAL0 + mov IE, #10010010b ;EA, SERIAL0, TIMER0 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +main_loop: + acall control_ATR + acall control_send_to_sim + acall control_command + sjmp main_loop + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_command: + jbc i2c_command_done,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + ;Control Length command=1 + mov a,length_command + cjne a,#1,next_commandEND ;error length_command != 1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov a,cmd_command + cjne a,#CMD_SET_BAUD_RATE,next_command001 + mov TH1,data_command ;Timer1 HIGH byte + ret +next_command001: +; --------------------------------------------------------------------------- + cjne a,#CMD_SET_SIM_CLC, next_command002 + mov CKDIV,data_command ;Fsys DIV + ret +next_command002: +; --------------------------------------------------------------------------- +next_commandEND: + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_send_to_sim: + jb i2c_write_done,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jbc bit_wait_confirm,jmp_wait_confirm +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + mov DPTR,#XRAM_TX_BUFF +looop_send: + movx a,@DPTR + inc DPTR + acall for_coooooom0 + + clr c + mov a,length_send_to_simL + subb a,#1 + mov length_send_to_simL,a + mov a,length_send_to_simH + subb a,#0 + mov length_send_to_simH,a + orl a,length_send_to_simL + jnz looop_send +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jnb bit_RX0,$ + clr i2c_write_done + ret + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +jmp_wait_confirm: + mov DPTR,#(XRAM_TX_BUFF+1) + movx a,@DPTR + mov R3,a + mov R4,#5 +; --------------------------------------------------------------------------- + mov DPTR,#XRAM_TX_BUFF +looop_seend: + movx a,@DPTR + inc DPTR + acall for_coooooom0 + djnz R4,jmp_not_5byte + + jnb bit_RX0,$ + clr bit_RX0 + ;18/12/2018 + mov time_confirm,#65 ;New timeout 50mS +looop_waitconf: + jb time_confirm.7,jmp_no_answer + jnb bit_RX0,looop_waitconf + + ;clr pin_scl ;TEST PULSE! + mov a,SBUF + xrl a,R3 + ;setb pin_scl ;TEST PULSE! + + jnz jmp_no_correct_answer ;18/12/2018 + + ;pause for next byte 17/12/2018 + mov R7,#0 + djnz R7,$ ;~260mkSec + djnz R7,$ ;~260mkSec + djnz R7,$ ;~260mkSec + +jmp_not_5byte: + + clr c + mov a,length_send_to_simL + subb a,#1 + mov length_send_to_simL,a + mov a,length_send_to_simH + subb a,#0 + mov length_send_to_simH,a + orl a,length_send_to_simL + jnz looop_seend +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- + jnb bit_RX0,$ + clr bit_RX0 +jmp_no_answer: + clr i2c_write_done + ret + +; --------------------------------------------------------------------------- +; --------------------------------------------------------------------------- +;18/12/2018 +jmp_no_correct_answer: + clr EA + clr i2c_write_done + + mov DPL,pointer_RX1L + mov DPH,pointer_RX1H + mov a,SBUF + movx @DPTR,a + inc DPTR + mov pointer_RX1L,DPL + mov pointer_RX1H,DPH + + clr pin_scl + mov time_data_read,#52 ;52/1302Hz = 40mS + + inc length_answer_simL + mov a,length_answer_simL + jnz $+2+2 ;2 + inc length_answer_simH ;2 + + setb EA + ret + + + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +control_ATR: + jbc bit_generate_ATR,$+3+1 ;3 + ret ;1 +; --------------------------------------------------------------------------- + clr pin_RST + ;acall clr_buffer + ; Add rezet pause 17/12/2018 + + mov R6,#200 +looop_pause50mS: + djnz R7,$ ;~260mkSec + djnz R6,looop_pause50mS + + ;Prepare to answer 11/03/2019 + acall clr_buffer + + mov length_answer_simH,#0 + mov length_answer_simL,#0 + mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX1L,#LOW (XRAM_RX_BUFF) + mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) + mov pointer_RX2L,#LOW (XRAM_RX_BUFF) + setb bit_first_ATR + setb pin_RST + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +for_coooooom0: + clr bit_RX0 + mov c,P + mov TB8,c ;9bit parity + mov SBUF,a + jnb bit_TX0,$ + clr bit_TX0 + mov R7,#100 + djnz R7,$ + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +clr_buffer: + mov DPTR,#XRAM_RX_BUFF ;Receive SIM buffer 192+192 = 384b + acall clr_192buffer ;06/12/2022 +; --------------------------------------------------------------------------- +clr_192buffer: + mov R7,#192 + clr a +looop_clr_bufff: + movx @DPTR,a + inc DPTR + djnz R7,looop_clr_bufff + ret + +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- +;for_coooooom1: +; mov SBUF_1,a +; jnb TI_1,$ +; clr TI_1 +; ret +; +; --------------------------------------------------------------------------- +; =========================================================================== +; --------------------------------------------------------------------------- + +end. From 4c9c0b5264e1df2376c6400b91fa59b42114ac4c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Dec 2022 07:37:37 +0100 Subject: [PATCH 413/759] minor adaptations to timings --- armsrc/i2c.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/armsrc/i2c.c b/armsrc/i2c.c index d8495e59c..d2c239fcc 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -167,7 +167,7 @@ static bool WaitSCL_H_delay(uint32_t delay) { // 5000 * 3.07us = 15350us. 15.35ms // 15000 * 3.07us = 46050us. 46.05ms static bool WaitSCL_H(void) { - return WaitSCL_H_delay(15000); + return WaitSCL_H_delay(5000); } static bool WaitSCL_L_delay(uint32_t delay) { @@ -179,19 +179,21 @@ static bool WaitSCL_L_delay(uint32_t delay) { } return false; } + // 5000 * 3.07us = 15350us. 15.35ms +// 15000 * 3.07us = 46050us. 46.05ms static bool WaitSCL_L(void) { - return WaitSCL_L_delay(15000); + return WaitSCL_L_delay(5000); } // Wait max 1800ms or until SCL goes LOW. // It timeout reading response from card // Which ever comes first static bool WaitSCL_L_timeout(void) { - volatile uint32_t delay = 1700; + volatile uint32_t delay = 200; while (delay--) { // exit on SCL LOW - if (!SCL_read) + if (SCL_read == false) return true; WaitMS(1); From c5582ab7c746224916edb5dfa82dfce2e5319daa Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Dec 2022 07:39:04 +0100 Subject: [PATCH 414/759] Changing timings, this now waits for max 276 bytes while 8051 speaks with card --- armsrc/i2c.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/armsrc/i2c.c b/armsrc/i2c.c index d2c239fcc..c3d10a765 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -208,12 +208,15 @@ static bool I2C_Start(void) { SDA_H; I2C_DELAY_1CLK; SCL_H; - if (!WaitSCL_H()) return false; + if (!WaitSCL_H()) + return false; I2C_DELAY_2CLK; - if (!SCL_read) return false; - if (!SDA_read) return false; + if (!SCL_read) + return false; + if (!SDA_read) + return false; SDA_L; I2C_DELAY_2CLK; @@ -228,8 +231,9 @@ static bool I2C_WaitForSim(void) { // 8051 speaks with smart card. // 1000*50*3.07 = 153.5ms - // 1byte transfer == 1ms with max frame being 256bytes - return WaitSCL_H_delay(1000 * 300); + // 1000*90*3.07 = 276.3ms + // 1byte transfer == 1ms with max frame being 256bytes + return WaitSCL_H_delay(1000 * 90); } // send i2c STOP From ac84e855a931a00ce802011718ef811efc999b02 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Dec 2022 07:39:36 +0100 Subject: [PATCH 415/759] Jumps len check fix --- armsrc/i2c.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/armsrc/i2c.c b/armsrc/i2c.c index c3d10a765..6ede36b13 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -714,11 +714,12 @@ bool GetATR(smart_card_atr_t *card_ptr, bool verbose) { // read bytes from module uint16_t len = sizeof(card_ptr->atr); + if (sc_rx_bytes(card_ptr->atr, &len) == false) + return false; + if (len > sizeof(card_ptr->atr)) { len = sizeof(card_ptr->atr); } - if (sc_rx_bytes(card_ptr->atr, &len) == false) - return false; uint8_t pos_td = 1; if ((card_ptr->atr[1] & 0x10) == 0x10) pos_td++; From 8eb6f60ba6d7aa54343ae76c35339704f37fb2f8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Dec 2022 07:40:41 +0100 Subject: [PATCH 416/759] added a wait when init I2C, seems to increase stability --- armsrc/appmain.c | 2 +- armsrc/i2c.c | 10 +++++++--- armsrc/i2c.h | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index f59cc13a3..756ca4f4f 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2608,7 +2608,7 @@ void __attribute__((noreturn)) AppMain(void) { #endif #ifdef WITH_SMARTCARD - I2C_init(); + I2C_init(false); #endif #ifdef WITH_FPC_USART diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 6ede36b13..b9b536c24 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -91,7 +91,7 @@ void I2C_recovery(void) { DbpString("I2C bus recovery complete"); } -void I2C_init(void) { +void I2C_init(bool has_ticks) { // Configure reset pin, close up pull up, push-pull output, default high AT91C_BASE_PIOA->PIO_PPUDR = GPIO_RST; AT91C_BASE_PIOA->PIO_MDDR = GPIO_RST; @@ -106,6 +106,10 @@ void I2C_init(void) { AT91C_BASE_PIOA->PIO_OER |= (GPIO_SCL | GPIO_SDA | GPIO_RST); AT91C_BASE_PIOA->PIO_PER |= (GPIO_SCL | GPIO_SDA | GPIO_RST); + if (has_ticks) { + WaitMS(2); + } + bool isok = (SCL_read && SDA_read); if (isok == false) I2C_recovery(); @@ -133,7 +137,7 @@ void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA) { // Note: the SIM_Adapter will not enter the main program after power up. Please run this function before use SIM_Adapter. void I2C_Reset_EnterMainProgram(void) { StartTicks(); - I2C_init(); + I2C_init(true); I2C_SetResetStatus(0, 0, 0); WaitMS(30); I2C_SetResetStatus(1, 0, 0); @@ -146,7 +150,7 @@ void I2C_Reset_EnterMainProgram(void) { // Reserve for firmware update. void I2C_Reset_EnterBootloader(void) { StartTicks(); - I2C_init(); + I2C_init(true); I2C_SetResetStatus(0, 1, 1); WaitMS(100); I2C_SetResetStatus(1, 1, 1); diff --git a/armsrc/i2c.h b/armsrc/i2c.h index 2ce051bd7..972704c1b 100644 --- a/armsrc/i2c.h +++ b/armsrc/i2c.h @@ -31,7 +31,7 @@ #define I2C_DEVICE_CMD_SEND_T0 0x07 void I2C_recovery(void); -void I2C_init(void); +void I2C_init(bool has_ticks); void I2C_Reset(void); void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA); From 15a848f9bb58da92dcfebe04bf2c3170bac05327 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Dec 2022 07:46:41 +0100 Subject: [PATCH 417/759] remove old file --- client/resources/sim012.sha512.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 client/resources/sim012.sha512.txt diff --git a/client/resources/sim012.sha512.txt b/client/resources/sim012.sha512.txt deleted file mode 100644 index abb996fb2..000000000 --- a/client/resources/sim012.sha512.txt +++ /dev/null @@ -1 +0,0 @@ -ac65f93b15dea4e6a27a644056c18266113af57f4d29de9eead4871007816efa7d1ec9f73308377e5fe388fc81b3d408221bd4eff7e1d129e0a349bd2c0f3f2b *sim012.bin From deeb672b08ba14c8f25e5d95b318ee6118a6bbb9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Dec 2022 07:48:07 +0100 Subject: [PATCH 418/759] also include new firmware binary in the install --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b072d7379..7439c0dcf 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfk #all clean install uninstall check: %: hitag2crack/% INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py pm3_amii_bin2eml.pl pm3_reblay-emulating.py pm3_reblay-reading.py -INSTALLSIMFW=sim011.bin sim011.sha512.txt +INSTALLSIMFW=sim011.bin sim011.sha512.txt sim013.bin sim013.sha512.txt INSTALLSCRIPTS=pm3 pm3-flash pm3-flash-all pm3-flash-bootrom pm3-flash-fullimage INSTALLSHARES=tools/jtag_openocd traces INSTALLDOCS=doc/*.md doc/md From 7970fdf3ba1fe71449245998d8b04f6b25973cc8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Dec 2022 07:51:03 +0100 Subject: [PATCH 419/759] text --- CHANGELOG.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01094bf38..19c7f7113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,11 @@ 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] - - Moved to non-deprecated API to initialize Python interpreter (jmichel@) - - Changed `sc upgrade` updated firmware v4.12 (RDV40) (@sentiprox) - - Fixed contact interface / smartcard APDU chaining logic and allow 256 bytes ADPU payload. Need SIM firmware 4.12 to work (@jmichel) + - Fixed length check in sim module communications (@jmichel) + - Changed timings in i2c.c when communicating with sim module (@iceman1001) + - Moved to non-deprecated API to initialize Python interpreter (@jmichel) + - Changed `sc upgrade` updated firmware v4.13 (RDV40) - frame buffer is now 384 bytes (@sentiprox) + - Fixed contact interface / smartcard APDU chaining logic and allow 256 bytes ADPU payload. Need SIM firmware 4.13 to work (@jmichel) - Fixed `lf hitag dump` - Should now work as described in the command help (@natmchugh) - Fixed SPI flash overflow when loading dictionnaries into flash. Breaking change: added 1 more sector for Mifare - dictionnaries should be loaded again (@jmichelp) - Added `hf mf gload, gsave, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) From 4c695c03b6f259bbf526c565850feec60ecb41c0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Dec 2022 07:51:33 +0100 Subject: [PATCH 420/759] added pexpect requirement --- tools/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/requirements.txt b/tools/requirements.txt index 8bff1fb56..b6be80271 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -1,2 +1,3 @@ ansicolors==1.1.8 sslcrypto==5.3 +pexpect==4.8.0 \ No newline at end of file From f32de52b4698b1bb40be97dd8a35c8ba7cfdbc96 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 9 Dec 2022 13:17:19 +0100 Subject: [PATCH 421/759] Wait a bit longer for the smartcard. For the max 256-byte frame, SIM wasn't ready early enough, corrupting the reception buffer with 5 spurious bytes. Empirically, 109 clock cycles is the minimum value that worked. Adding 1 clock cycle as a safety buffer. --- armsrc/i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/i2c.c b/armsrc/i2c.c index b9b536c24..491e12a04 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -235,9 +235,9 @@ static bool I2C_WaitForSim(void) { // 8051 speaks with smart card. // 1000*50*3.07 = 153.5ms - // 1000*90*3.07 = 276.3ms + // 1000*110*3.07 = 337.7ms // 1byte transfer == 1ms with max frame being 256bytes - return WaitSCL_H_delay(1000 * 90); + return WaitSCL_H_delay(1000 * 110); } // send i2c STOP From 0083e0ae1321555904c1a7c543c9c530b12ff293 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 9 Dec 2022 21:58:28 +0100 Subject: [PATCH 422/759] Fix embedded python not working with Proxspace. --- client/src/cmdscript.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index 18a0586f8..b19c5b9df 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -399,34 +399,26 @@ static int CmdScriptRun(const char *Cmd) { PrintAndLogEx(SUCCESS, "executing python " _YELLOW_("%s"), script_path); PrintAndLogEx(SUCCESS, "args " _YELLOW_("'%s'"), arguments); - wchar_t *program = Py_DecodeLocale(filename, NULL); - if (program == NULL) { - PrintAndLogEx(ERR, "could not decode " _YELLOW_("%s"), filename); - free(script_path); - return PM3_ESOFT; - } - - // optional but recommended - //Py_SetProgramName(program); #ifdef HAVE_PYTHON_SWIG // hook Proxmark3 API PyImport_AppendInittab("_pm3", PyInit__pm3); #endif PyConfig py_conf; PyConfig_InitIsolatedConfig(&py_conf); + // Despite being isolated we probably want to allow users to use + // the Python packages they installed on their user directory as well + // as system ones. But it seems isolated mode still enforces them off. + py_conf.use_environment = 1; + py_conf.user_site_directory = 1; //int argc, char ** argv char *argv[128]; argv[0] = filename; int argc = split(arguments, &argv[1]); + // The following line will implicitly pre-initialize Python PyConfig_SetBytesArgv(&py_conf, argc + 1, argv); - // Despite being isolated we probably want to allow users to use - // the Python packages they installed on their user directory as well - // as obey env variables. - py_conf.use_environment = 1; - py_conf.user_site_directory = 1; - // Setting this pre-intializes Python implictly which will change the config - PyConfig_SetString(&py_conf, &py_conf.program_name, program); + // This is required by Proxspace to work with an isolated Python configuration + PyConfig_SetBytesString(&py_conf, &py_conf.home, getenv("PYTHONHOME")); Py_InitializeFromConfig(&py_conf); @@ -447,7 +439,6 @@ static int CmdScriptRun(const char *Cmd) { } int ret = Pm3PyRun_SimpleFileNoExit(f, filename); Py_Finalize(); - PyMem_RawFree(program); free(script_path); if (ret) { PrintAndLogEx(WARNING, "\nfinished " _YELLOW_("%s") " with exception", filename); From b14730d57c3ce13d990e55068cd12754993d6360 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 10 Dec 2022 03:32:18 +0100 Subject: [PATCH 423/759] fix codeql #155 - narrow type with wide type comparison in loop --- client/src/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index e5ab53d66..51a9a13f0 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6212,7 +6212,7 @@ int CmdHFMFNDEFWrite(const char *Cmd) { uint8_t freemem[MIFARE_4K_MAXSECTOR] = {0}; uint16_t sum = 0; uint8_t block_no = 0; - for (uint8_t i = 1; i < madlen; i++) { + for (uint8_t i = 1; i < (madlen & 0xFF); i++) { freemem[i] = (mad[i] == NDEF_MFC_AID); From 6132646f10472c05289e950bd1ce81c922ecaa03 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 10 Dec 2022 03:33:36 +0100 Subject: [PATCH 424/759] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19c7f7113..c1dfcdd6d 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 failing compilation on Proxspace environment due to how python is initialized (@jmichel) - Fixed length check in sim module communications (@jmichel) - Changed timings in i2c.c when communicating with sim module (@iceman1001) - Moved to non-deprecated API to initialize Python interpreter (@jmichel) From 086d6b6f65096d9e46afaf034a304dc1bff1f28a Mon Sep 17 00:00:00 2001 From: Iceman Date: Sat, 10 Dec 2022 03:45:32 +0100 Subject: [PATCH 425/759] Create SECURITY.md Signed-off-by: Iceman --- SECURITY.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..93cabb3fb --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,15 @@ +# Security Policy + +This is an open source project driven by volunteering devs contributing their time for free. + +This is a bleeding edge repository. +The maintainers actively is working out of this repository and will be periodically re-structuring the code to make it easier to comprehend, navigate, build, test, and contribute to, so DO expect significant changes to code layout on a regular basis. + + +## Reporting a Vulnerability + +if you find a vulnerability feel free to make a pull request with your fix and we will deal with it. + + +👉 Remember! +If you intend to contribute to the code, please read the coding style notes first. We usually merge your contributions fast since we do like the idea of getting a functionality in the Proxmark3 and weed out the bugs afterwards. From 2c1fe700e2b9f5ca12611516386c5fdd2fbe780a Mon Sep 17 00:00:00 2001 From: Edward Li Date: Fri, 9 Dec 2022 23:44:47 -0500 Subject: [PATCH 426/759] Fix `make accessrights` for Fedora --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 7439c0dcf..5452842cc 100644 --- a/Makefile +++ b/Makefile @@ -267,6 +267,10 @@ ifneq ($(wildcard /etc/arch-release),) #If user is running ArchLinux, use specific command and group $(Q)$(SUDO) $(USERMOD) uucp $(USER) $(Q)$(GETENT_BL) >/dev/null && $(SUDO) $(USERMOD) bluetooth $(USER) || true +else ifneq ($(wildcard /etc/fedora-release),) +# If the user is running Fedora, use `usermod` with the dialout group + $(Q)$(SUDO) $(USERMOD) dialout $(USER) + $(Q)$(GETENT_BL) >/dev/null && $(SUDO) $(USERMOD) bluetooth $(USER) || true else $(Q)$(SUDO) $(ADDUSER) $(USER) dialout $(Q)$(GETENT_BL) >/dev/null && $(SUDO) $(ADDUSER) $(USER) bluetooth || true From 3927ae59210b9f7b8cfc0b0a1b155b8bae8e092d Mon Sep 17 00:00:00 2001 From: Edward Li Date: Fri, 9 Dec 2022 23:50:29 -0500 Subject: [PATCH 427/759] Update changelog for #1795 fix --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1dfcdd6d..72fcfa94e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001) - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) + - Fixed `make accessrights` on Fedora (@mooey5775) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) From a63257799a0092460f86cce8bb3ded3e13cd2de2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 13 Dec 2022 21:47:25 +0100 Subject: [PATCH 428/759] test of faster pack response for "hf mfu sim -t 7" --- armsrc/iso14443a.c | 23 +++++++++++++++++------ armsrc/iso14443a.h | 3 ++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 5f60942e4..23b46cf54 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1039,6 +1039,8 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r // PPS response static uint8_t rPPS[3] = { 0xD0 }; + static uint8_t rPACK[4] = { 0x00, 0x00, 0x00, 0x00 }; + switch (tagType) { case 1: { // MIFARE Classic 1k rATQA[0] = 0x04; @@ -1227,6 +1229,8 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r AddCrc14A(rPPS, sizeof(rPPS) - 2); + AddCrc14A(rPACK, sizeof(rPACK) - 2); + static tag_response_info_t responses_init[] = { { .response = rATQA, .response_n = sizeof(rATQA) }, // Answer to request - respond with card type { .response = rUIDc1, .response_n = sizeof(rUIDc1) }, // Anticollision cascade1 - respond with uid @@ -1238,14 +1242,16 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r { .response = rRATS, .response_n = sizeof(rRATS) }, // dummy ATS (pseudo-ATR), answer to RATS { .response = rVERSION, .response_n = sizeof(rVERSION) }, // EV1/NTAG GET_VERSION response { .response = rSIGN, .response_n = sizeof(rSIGN) }, // EV1/NTAG READ_SIG response - { .response = rPPS, .response_n = sizeof(rPPS) } // PPS response + { .response = rPPS, .response_n = sizeof(rPPS) }, // PPS response + { .response = rPACK, .response_n = sizeof(rPACK) } // PACK response }; - // "precompile" responses. There are 11 predefined responses with a total of 80 bytes data to transmit. + // "precompile" responses. There are 12 predefined responses with a total of 84 bytes data to transmit. + // Coded responses need one byte per bit to transfer (data, parity, start, stop, correction) - // 81 * 8 data bits, 81 * 1 parity bits, 11 start bits, 11 stop bits, 11 correction bits - // 81 * 8 + 81 + 11 + 11 + 11 == 762 -#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 762 + // 85 * 8 data bits, 85 * 1 parity bits, 12 start bits, 12 stop bits, 12 correction bits + // 85 * 8 + 85 + 12 + 12 + 12 == 801 +#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 801 uint8_t *free_buffer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE); // modulation buffer pointer and current buffer free space size @@ -1641,6 +1647,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_ LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); p_response = NULL; } else if (receivedCmd[0] == MIFARE_ULEV1_AUTH && len == 7 && tagType == 7) { // NTAG / EV-1 authentication + + /* // PWD stored in dump now uint8_t pwd[4]; emlGetMemBt(pwd, (pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH, sizeof(pwd)); @@ -1654,7 +1662,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_ uint8_t pack[4]; emlGetMemBt(pack, pages * 4 + MFU_DUMP_PREFIX_LENGTH, 2); if (memcmp(pack, "\x00\x00\x00\x00", 4) == 0) { - memcpy(pack, "\x80\x80\x00\x00", 4); + pack[0] = 0x80; + pack[1] = 0x80; } AddCrc14A(pack, sizeof(pack) - 2); EmSendCmd(pack, sizeof(pack)); @@ -1663,6 +1672,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_ if (g_dbglevel >= DBG_DEBUG) Dbprintf("Auth attempt: %08x", bytes_to_num(receivedCmd + 1, 4)); } p_response = NULL; + */ + p_response = &responses[RESP_INDEX_PACK]; } else if (receivedCmd[0] == MIFARE_ULEV1_VCSL && len == 23 && tagType == 7) { uint8_t cmd[3]; emlGetMemBt(cmd, (pages - 2) * 4 + 1 + MFU_DUMP_PREFIX_LENGTH, 1); diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index cf3ecf854..104d6b680 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -104,7 +104,8 @@ typedef enum { RESP_INDEX_RATS, RESP_INDEX_VERSION, RESP_INDEX_SIGNATURE, - RESP_INDEX_PPS + RESP_INDEX_PPS, + RESP_INDEX_PACK, } resp_index_t; #ifndef AddCrc14A From 1fe1f61400f8281ab4155652fc0e7c5967461413 Mon Sep 17 00:00:00 2001 From: Self Not Found Date: Fri, 16 Dec 2022 01:46:21 +0800 Subject: [PATCH 429/759] Fix typo in Troubleshooting.md Signed-off-by: Self Not Found --- doc/md/Installation_Instructions/Troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index 68d3d5570..710b2de26 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -166,7 +166,7 @@ pm3 --> smart upgrade -f /usr/local/share/proxmark3/firmware/sim013.bin pm3 --> smart upgrade -f /usr/share/proxmark3/firmware/sim013.bin ``` -If you didn't install the PRoxmark but you're working from the sources directory and depending how you launch the client, your working directory might be the root of the repository: +If you didn't install the Proxmark but you're working from the sources directory and depending how you launch the client, your working directory might be the root of the repository: ``` ./pm3 ... From 0d2e86f99c1d5598d2fd5ae7d9bdb627babf9bc4 Mon Sep 17 00:00:00 2001 From: Nitraiolo Date: Sat, 17 Dec 2022 15:26:36 +0100 Subject: [PATCH 430/759] Conditional build of cmdscript to allow compilation with old python versions (<3.10.x) --- client/src/cmdscript.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index b19c5b9df..d326af4d1 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -403,6 +403,7 @@ static int CmdScriptRun(const char *Cmd) { // hook Proxmark3 API PyImport_AppendInittab("_pm3", PyInit__pm3); #endif +#if PY_MINOR_VERSION >= 10 PyConfig py_conf; PyConfig_InitIsolatedConfig(&py_conf); // Despite being isolated we probably want to allow users to use @@ -410,11 +411,15 @@ static int CmdScriptRun(const char *Cmd) { // as system ones. But it seems isolated mode still enforces them off. py_conf.use_environment = 1; py_conf.user_site_directory = 1; +#else + Py_Initialize(); +#endif //int argc, char ** argv char *argv[128]; argv[0] = filename; int argc = split(arguments, &argv[1]); +#if PY_MINOR_VERSION >= 10 // The following line will implicitly pre-initialize Python PyConfig_SetBytesArgv(&py_conf, argc + 1, argv); // This is required by Proxspace to work with an isolated Python configuration @@ -424,6 +429,17 @@ static int CmdScriptRun(const char *Cmd) { // clean up PyConfig_Clear(&py_conf); +#else + wchar_t *py_args[argc + 1]; + py_args[0] = Py_DecodeLocale(filename, NULL); + for (int i = 0; i < argc; i++) { + py_args[i + 1] = Py_DecodeLocale(argv[i], NULL); + } + + PySys_SetArgv(argc + 1, py_args); + + // clean up +#endif for (int i = 0; i < argc; ++i) { free(argv[i + 1]); } From 912d9be2d14201e138cdf4963e0998a3f1bc53b1 Mon Sep 17 00:00:00 2001 From: Nitraiolo Date: Sat, 17 Dec 2022 20:12:12 +0100 Subject: [PATCH 431/759] Added major version into compile condition of cmdscript --- client/src/cmdscript.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index d326af4d1..16d933d76 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -403,7 +403,7 @@ static int CmdScriptRun(const char *Cmd) { // hook Proxmark3 API PyImport_AppendInittab("_pm3", PyInit__pm3); #endif -#if PY_MINOR_VERSION >= 10 +#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 10 PyConfig py_conf; PyConfig_InitIsolatedConfig(&py_conf); // Despite being isolated we probably want to allow users to use @@ -419,7 +419,7 @@ static int CmdScriptRun(const char *Cmd) { char *argv[128]; argv[0] = filename; int argc = split(arguments, &argv[1]); -#if PY_MINOR_VERSION >= 10 +#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 10 // The following line will implicitly pre-initialize Python PyConfig_SetBytesArgv(&py_conf, argc + 1, argv); // This is required by Proxspace to work with an isolated Python configuration From 997e5aac3eb40ad17784c10195ed9a951efc6ab5 Mon Sep 17 00:00:00 2001 From: Nitraiolo Date: Sat, 17 Dec 2022 21:49:04 +0100 Subject: [PATCH 432/759] Fix py_args[] population --- client/src/cmdscript.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index 16d933d76..b8065950e 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -431,9 +431,8 @@ static int CmdScriptRun(const char *Cmd) { PyConfig_Clear(&py_conf); #else wchar_t *py_args[argc + 1]; - py_args[0] = Py_DecodeLocale(filename, NULL); - for (int i = 0; i < argc; i++) { - py_args[i + 1] = Py_DecodeLocale(argv[i], NULL); + for (int i = 0; i <= argc; i++) { + py_args[i] = Py_DecodeLocale(argv[i], NULL); } PySys_SetArgv(argc + 1, py_args); From 96d8528a0af94f21734124c39481307f3993334f Mon Sep 17 00:00:00 2001 From: Nitraiolo Date: Sun, 18 Dec 2022 09:45:46 +0100 Subject: [PATCH 433/759] Inverted condition in python check so it defaults to new code now. --- client/src/cmdscript.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index b8065950e..9e19c0959 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -403,7 +403,9 @@ static int CmdScriptRun(const char *Cmd) { // hook Proxmark3 API PyImport_AppendInittab("_pm3", PyInit__pm3); #endif -#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 10 +#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 10 + Py_Initialize(); +#else PyConfig py_conf; PyConfig_InitIsolatedConfig(&py_conf); // Despite being isolated we probably want to allow users to use @@ -411,15 +413,22 @@ static int CmdScriptRun(const char *Cmd) { // as system ones. But it seems isolated mode still enforces them off. py_conf.use_environment = 1; py_conf.user_site_directory = 1; -#else - Py_Initialize(); #endif //int argc, char ** argv char *argv[128]; argv[0] = filename; int argc = split(arguments, &argv[1]); -#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 10 +#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 10 + wchar_t *py_args[argc + 1]; + for (int i = 0; i <= argc; i++) { + py_args[i] = Py_DecodeLocale(argv[i], NULL); + } + + PySys_SetArgv(argc + 1, py_args); + + // clean up +#else // The following line will implicitly pre-initialize Python PyConfig_SetBytesArgv(&py_conf, argc + 1, argv); // This is required by Proxspace to work with an isolated Python configuration @@ -429,15 +438,6 @@ static int CmdScriptRun(const char *Cmd) { // clean up PyConfig_Clear(&py_conf); -#else - wchar_t *py_args[argc + 1]; - for (int i = 0; i <= argc; i++) { - py_args[i] = Py_DecodeLocale(argv[i], NULL); - } - - PySys_SetArgv(argc + 1, py_args); - - // clean up #endif for (int i = 0; i < argc; ++i) { free(argv[i + 1]); From 4375f5b91e440e53c1d311fed36f61ec0b54d71f Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Tue, 20 Dec 2022 15:32:38 +0100 Subject: [PATCH 434/759] Avoid memory leaks with Python <3.10 --- client/src/cmdscript.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index 9e19c0959..7a5a59130 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -426,8 +426,6 @@ static int CmdScriptRun(const char *Cmd) { } PySys_SetArgv(argc + 1, py_args); - - // clean up #else // The following line will implicitly pre-initialize Python PyConfig_SetBytesArgv(&py_conf, argc + 1, argv); @@ -453,6 +451,12 @@ static int CmdScriptRun(const char *Cmd) { return PM3_ESOFT; } int ret = Pm3PyRun_SimpleFileNoExit(f, filename); +#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 10 + // Py_DecodeLocale() allocates memory that needs to be free'd + for (int i = 0; i < argc + 1; i++) { + PyMem_RawFree(py_args[i]); + } +#endif Py_Finalize(); free(script_path); if (ret) { From 1f7d3d85a746949f47ca1549ea492d24a712a860 Mon Sep 17 00:00:00 2001 From: Self Not Found Date: Thu, 22 Dec 2022 12:24:20 +0800 Subject: [PATCH 435/759] Fix the steps when updating from old version When updating from a old version on Windows, the `pm3-flash-all` always fails even after updating the bootloader. This is because it detects the hardware by the serial number "ICEMAN", which only appears after flashing the fullimage. --- client/src/flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/flash.c b/client/src/flash.c index 6275db0bf..20729b2da 100644 --- a/client/src/flash.c +++ b/client/src/flash.c @@ -489,7 +489,7 @@ static void flash_suggest_update_bootloader(void) { PrintAndLogEx(ERR, "------------- " _CYAN_("Follow these steps") " -------------------"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(ERR, " 1) ./pm3-flash-bootrom"); - PrintAndLogEx(ERR, " 2) ./pm3-flash-all"); + PrintAndLogEx(ERR, " 2) ./pm3-flash-fullimage"); PrintAndLogEx(ERR, " 3) ./pm3"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "---------------------------------------------------"); From d998fabe2f3574094e8f086666d6a97fd51c0551 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Dec 2022 20:01:04 +0100 Subject: [PATCH 436/759] add aid to resource file --- CHANGELOG.md | 1 + client/resources/aidlist.json | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72fcfa94e..47e2d30df 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] + - Added PIV aid to resource file (@jmichel) - Fixed failing compilation on Proxspace environment due to how python is initialized (@jmichel) - Fixed length check in sim module communications (@jmichel) - Changed timings in i2c.c when communicating with sim module (@iceman1001) diff --git a/client/resources/aidlist.json b/client/resources/aidlist.json index bc939de14..81a153bba 100644 --- a/client/resources/aidlist.json +++ b/client/resources/aidlist.json @@ -1247,6 +1247,14 @@ "Description": "PIV End Point Applet. Last 2 bytes designate version", "Type": "" }, + { + "AID": "A000000308000010000100", + "Vendor": "National Institute of Standards and Technology", + "Country": "United States", + "Name": "Personal Identity Verification (PIV) / ID-ONE PIV BIO", + "Description": "PIV End Point Applet. Last 2 bytes designate version", + "Type": "" + }, { "AID": "A00000031510100528", "Vendor": "Currence Holding/PIN BV", From 08930766cb8a7e76b96eed44572bc7f46979f0c6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 23 Dec 2022 20:05:45 +0100 Subject: [PATCH 437/759] fix potential NULL array printing --- CHANGELOG.md | 1 + client/src/util.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47e2d30df..679a27524 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 potential NULL array printing (@jmichel) - Added PIV aid to resource file (@jmichel) - Fixed failing compilation on Proxspace environment due to how python is initialized (@jmichel) - Fixed length check in sim module communications (@jmichel) diff --git a/client/src/util.c b/client/src/util.c index e849ebb62..d6d57414d 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -303,7 +303,8 @@ void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t brea static void print_buffer_ex(const uint8_t *data, const size_t len, int level, uint8_t breaks) { - if (len < 1) + // sanity checks + if ((data == NULL) || (len < 1)) return; char buf[UTIL_BUFFER_SIZE_SPRINT + 3]; From b43bb92961c8b3adcd5ef0778fe3e29ecf9d9c7b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 28 Dec 2022 21:53:14 +0100 Subject: [PATCH 438/759] textual --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b98ad79b..d931e1ad5 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,13 @@ We define generic Proxmark3 platforms as following devices. - ⚠ VX - **Note**: unknown device hw - ⚠ Proxmark3 X - - **Note**: unknown device hw. + - **Note**: unknown device hw +- ⚠ Proxmark3 Ultimate + - **Note**: unknown device hw +- ⚠ Proxmark3 SE + - **Note**: unknown device hw + +When it comes to these new unknown models we are depending on the community to report in if this repo works and what they did to make it work. **256kb flash memory size of generic Proxmark3 platforms** From e44f84747419a1931fb6b57abf049a226b7e5514 Mon Sep 17 00:00:00 2001 From: nvx Date: Thu, 29 Dec 2022 22:37:50 +1000 Subject: [PATCH 439/759] Improved NXP SLI/SLIX series tag identification --- CHANGELOG.md | 1 + client/src/cmdhf15.c | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 679a27524..befb67d0f 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] + - Improved NXP SLI/SLIX series tag identification (@nvx) - Fixed potential NULL array printing (@jmichel) - Added PIV aid to resource file (@jmichel) - Fixed failing compilation on Proxspace environment due to how python is initialized (@jmichel) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 45040d7f2..84629d56e 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -67,7 +67,7 @@ typedef struct { // structure and database for uid -> tagtype lookups typedef struct { uint64_t uid; - int mask; // how many MSB bits used + uint64_t mask; // how many MSB bits used, or mask itself if larger than 64 const char *desc; } productName_t; @@ -90,17 +90,22 @@ static const productName_t uidmapping[] = { // E0 04 xx // 04 = Manufacturer code (Philips/NXP) // XX = IC id (Chip ID Family) - //I-Code SLI SL2 ICS20 [IC id = 01] - //I-Code SLI-S [IC id = 02] - //I-Code SLI-L [IC id = 03] - //I-Code SLIX [IC id = 01 + bit36 set to 1 (starting from bit0 - different from normal SLI)] + //I-Code SLI SL2 ICS20 [IC id = 01 + bit35 set to 0 + bit36 set to 0] + //I-Code SLIX [IC id = 01 + bit35 set to 0 + bit36 set to 1] //I-Code SLIX2 [IC id = 01 + bit35 set to 1 + bit36 set to 0] + //I-Code SLI-S [IC id = 02 + bit36 set to 0] //I-Code SLIX-S [IC id = 02 + bit36 set to 1] + //I-Code SLI-L [IC id = 03 + bit36 set to 0] //I-Code SLIX-L [IC id = 03 + bit36 set to 1] { 0xE004000000000000LL, 16, "NXP Semiconductors Germany (Philips)" }, { 0xE004010000000000LL, 24, "NXP(Philips); IC SL2 ICS20/ICS21(SLI) ICS2002/ICS2102(SLIX) ICS2602(SLIX2)" }, - { 0xE004020000000000LL, 24, "NXP(Philips); IC SL2 ICS53/ICS54(SLI-S) ICS5302/ICS5402(SLIX-S)" }, - { 0xE004030000000000LL, 24, "NXP(Philips); IC SL2 ICS50/ICS51(SLI-L) ICS5002/ICS5102(SLIX-L)" }, + { 0xE004010000000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS20/ICS21(SLI)" }, + { 0xE004011000000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS2002/ICS2102(SLIX)" }, + { 0xE004010800000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS2602(SLIX2)" }, + { 0xE004020000000000LL, 0xFFFFFF1000000000LL, "NXP(Philips); IC SL2 ICS53/ICS54(SLI-S)" }, + { 0xE004021000000000LL, 0xFFFFFF1000000000LL, "NXP(Philips); ICS5302/ICS5402(SLIX-S)" }, + { 0xE004030000000000LL, 0xFFFFFF1000000000LL, "NXP(Philips); IC SL2 ICS50/ICS51(SLI-L)" }, + { 0xE004031000000000LL, 0xFFFFFF1000000000LL, "NXP(Philips); ICS5002/ICS5102(SLIX-L)" }, // E0 05 XX .. .. .. // 05 = Manufacturer code (Infineon) @@ -364,7 +369,11 @@ static const char *getTagInfo_15(uint8_t *uid) { int i = 0, best = -1; memcpy(&myuid, uid, sizeof(uint64_t)); while (uidmapping[i].mask > 0) { - mask = (~0ULL) << (64 - uidmapping[i].mask); + if (uidmapping[i].mask > 64) { + mask = uidmapping[i].mask; + } else { + mask = (~0ULL) << (64 - uidmapping[i].mask); + } if ((myuid & mask) == uidmapping[i].uid) { if (best == -1) { best = i; From 9e0fe3ca3697f65ec7d3a3538b6b32d7f2632a47 Mon Sep 17 00:00:00 2001 From: Hanno Heinrichs Date: Thu, 29 Dec 2022 12:52:19 +0100 Subject: [PATCH 440/759] Fix stack-based buffer overflow in "lf em 4x05 sniff" command --- CHANGELOG.md | 1 + client/src/cmdlfem4x05.c | 63 ++++++++++++++++++++++------------------ client/src/cmdlfem4x05.h | 2 ++ client/src/util.c | 9 ++++++ client/src/util.h | 7 +++++ 5 files changed, 54 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 679a27524..3aa8d4389 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 buffer overflow in "lf em 4x05 sniff" (@HeinrichsH) - Fixed potential NULL array printing (@jmichel) - Added PIV aid to resource file (@jmichel) - Fixed failing compilation on Proxspace environment due to how python is initialized (@jmichel) diff --git a/client/src/cmdlfem4x05.c b/client/src/cmdlfem4x05.c index 6eb2bb837..8e6110c62 100644 --- a/client/src/cmdlfem4x05.c +++ b/client/src/cmdlfem4x05.c @@ -41,6 +41,7 @@ #include "generator.h" #include "cliparser.h" #include "cmdhw.h" +#include "util.h" //////////////// 4205 / 4305 commands @@ -1996,8 +1997,7 @@ int CmdEM4x05Sniff(const char *Cmd) { const char *cmdText; char dataText[100]; char blkAddr[4]; - char bits[80]; - int i, bitidx; + int i; int ZeroWidth; // 32-42 "1" is 32 int CycleWidth; size_t pulseSamples; @@ -2018,6 +2018,10 @@ int CmdEM4x05Sniff(const char *Cmd) { PrintAndLogEx(SUCCESS, "offset | Command | Data | blk | raw"); PrintAndLogEx(SUCCESS, "-------+-------------+----------+-----+------------------------------------------------------------"); + smartbuf bits = { 0 }; + bits.ptr = malloc(EM4X05_BITS_BUFSIZE); + bits.size = EM4X05_BITS_BUFSIZE; + bits.idx = 0; size_t idx = 0; // loop though sample buffer while (idx < g_GraphTraceLen) { @@ -2037,8 +2041,8 @@ int CmdEM4x05Sniff(const char *Cmd) { if (ZeroWidth <= 50) { pktOffset -= ZeroWidth; - memset(bits, 0x00, sizeof(bits)); - bitidx = 0; + memset(bits.ptr, 0, bits.size); + bits.idx = 0; while ((idx < g_GraphTraceLen) && !eop) { CycleWidth = idx; @@ -2047,7 +2051,7 @@ int CmdEM4x05Sniff(const char *Cmd) { CycleWidth = idx - CycleWidth; if ((CycleWidth > 300) || (CycleWidth < (ZeroWidth - 5))) { // to long or too short eop = true; - bits[bitidx++] = '0'; // Append last zero from the last bit find + sb_append_char(&bits, '0'); // Append last zero from the last bit find cmdText = ""; // EM4305 command lengths @@ -2059,76 +2063,77 @@ int CmdEM4x05Sniff(const char *Cmd) { // -> disable 1010 11111111 0 11111111 0 11111111 0 11111111 0 00000000 0 // Check to see if we got the leading 0 - if (((strncmp(bits, "00011", 5) == 0) && (bitidx == 50)) || - ((strncmp(bits, "00101", 5) == 0) && (bitidx == 57)) || - ((strncmp(bits, "01001", 5) == 0) && (bitidx == 12)) || - ((strncmp(bits, "01100", 5) == 0) && (bitidx == 50)) || - ((strncmp(bits, "01010", 5) == 0) && (bitidx == 50))) { - memmove(bits, &bits[1], bitidx - 1); - bitidx--; + if (((strncmp(bits.ptr, "00011", 5) == 0) && (bits.idx == 50)) || + ((strncmp(bits.ptr, "00101", 5) == 0) && (bits.idx == 57)) || + ((strncmp(bits.ptr, "01001", 5) == 0) && (bits.idx == 12)) || + ((strncmp(bits.ptr, "01100", 5) == 0) && (bits.idx == 50)) || + ((strncmp(bits.ptr, "01010", 5) == 0) && (bits.idx == 50))) { + memmove(bits.ptr, &bits.ptr[1], bits.idx - 1); + bits.idx--; PrintAndLogEx(INFO, "Trim leading 0"); } - bits[bitidx] = 0; + sb_append_char(&bits, 0); + bits.idx--; // logon - if ((strncmp(bits, "0011", 4) == 0) && (bitidx == 49)) { + if ((strncmp(bits.ptr, "0011", 4) == 0) && (bits.idx == 49)) { haveData = true; pwd = true; cmdText = "Logon"; strncpy(blkAddr, " ", sizeof(blkAddr)); - tmpValue = em4x05_Sniff_GetBlock(&bits[4], fwd); + tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[4], fwd); snprintf(dataText, sizeof(dataText), "%08X", tmpValue); } // write - if ((strncmp(bits, "0101", 4) == 0) && (bitidx == 56)) { + if ((strncmp(bits.ptr, "0101", 4) == 0) && (bits.idx == 56)) { haveData = true; cmdText = "Write"; - tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3); + tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3); snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue); if (tmpValue == 2) { pwd = true; } - tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd); + tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd); snprintf(dataText, sizeof(dataText), "%08X", tmpValue); } // read - if ((strncmp(bits, "1001", 4) == 0) && (bitidx == 11)) { + if ((strncmp(bits.ptr, "1001", 4) == 0) && (bits.idx == 11)) { haveData = true; pwd = false; cmdText = "Read"; - tmpValue = (bits[4] - '0') + ((bits[5] - '0') << 1) + ((bits[6] - '0') << 2) + ((bits[7] - '0') << 3); + tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3); snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue); strncpy(dataText, " ", sizeof(dataText)); } // protect - if ((strncmp(bits, "1100", 4) == 0) && (bitidx == 49)) { + if ((strncmp(bits.ptr, "1100", 4) == 0) && (bits.idx == 49)) { haveData = true; pwd = false; cmdText = "Protect"; strncpy(blkAddr, " ", sizeof(blkAddr)); - tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd); + tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd); snprintf(dataText, sizeof(dataText), "%08X", tmpValue); } // disable - if ((strncmp(bits, "1010", 4) == 0) && (bitidx == 49)) { + if ((strncmp(bits.ptr, "1010", 4) == 0) && (bits.idx == 49)) { haveData = true; pwd = false; cmdText = "Disable"; strncpy(blkAddr, " ", sizeof(blkAddr)); - tmpValue = em4x05_Sniff_GetBlock(&bits[11], fwd); + tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd); snprintf(dataText, sizeof(dataText), "%08X", tmpValue); } // bits[bitidx] = 0; } else { i = (CycleWidth - ZeroWidth) / 28; - bits[bitidx++] = '0'; + sb_append_char(&bits, '0'); for (int ii = 0; ii < i; ii++) { - bits[bitidx++] = '1'; + sb_append_char(&bits, '1'); } } } @@ -2139,11 +2144,13 @@ int CmdEM4x05Sniff(const char *Cmd) { // Print results if (haveData) { //&& (minWidth > 1) && (maxWidth > minWidth)){ if (pwd) - PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _YELLOW_("%8s")" | " _YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); + PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _YELLOW_("%8s")" | " _YELLOW_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits.ptr); else - PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _GREEN_("%8s")" | " _GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits); + PrintAndLogEx(SUCCESS, "%6zu | %-10s | " _GREEN_("%8s")" | " _GREEN_("%3s")" | %s", pktOffset, cmdText, dataText, blkAddr, bits.ptr); } } + free(bits.ptr); + bits.ptr = NULL; // footer PrintAndLogEx(SUCCESS, "---------------------------------------------------------------------------------------------------"); diff --git a/client/src/cmdlfem4x05.h b/client/src/cmdlfem4x05.h index 19c3dd4f2..ed472a803 100644 --- a/client/src/cmdlfem4x05.h +++ b/client/src/cmdlfem4x05.h @@ -27,6 +27,8 @@ #define EM4305_PROT2_BLOCK 15 #define EM4469_PROT_BLOCK 3 +#define EM4X05_BITS_BUFSIZE 128 + // config blocks #define EM4305_DEFAULT_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(4) ) // ASK/MAN , data rate 32, 4 data blocks //#define EM4305_DEFAULT_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(4) ) // ASK/BIPHASE , data rate 32, 4 data blocks diff --git a/client/src/util.c b/client/src/util.c index d6d57414d..56eb3164a 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -1261,3 +1261,12 @@ int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen) { } return -1; } + +void sb_append_char(smartbuf *sb, unsigned char c) { + if (sb->idx >= sb->size) { + sb->size *= 2; + sb->ptr = realloc(sb->ptr, sb->size); + } + sb->ptr[sb->idx] = c; + sb->idx++; +} diff --git a/client/src/util.h b/client/src/util.h index 939e0a55d..616272c84 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -146,4 +146,11 @@ uint32_t leadingzeros32(uint32_t a); uint64_t leadingzeros64(uint64_t a); int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen); + +struct smartbuf { + char *ptr; + size_t size; + size_t idx; +} typedef smartbuf; +void sb_append_char(smartbuf *sb, unsigned char c); #endif From 6d208346f7cd6be7f84f17966b83ecc2345ff267 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 31 Dec 2022 10:03:17 +0100 Subject: [PATCH 441/759] remove file --- tools/simmodule/sim012.asm | 816 ------------------------------------- 1 file changed, 816 deletions(-) delete mode 100644 tools/simmodule/sim012.asm diff --git a/tools/simmodule/sim012.asm b/tools/simmodule/sim012.asm deleted file mode 100644 index 02466a288..000000000 --- a/tools/simmodule/sim012.asm +++ /dev/null @@ -1,816 +0,0 @@ -; --------------------------------------------------------------------------- -; Proxmark3 RDV4 SIM module firmware -; -; Copyright (C) 2109, 2022 Sentinel -; -; This program is free software: you can redistribute it and/or modify it -; under the terms of the GNU Lesser General Public License as published by the -; Free Software Foundation, either version 3 of the License, or (at your -; option) any later version. -; -; This program is distributed in the hope that it will be useful, but WITHOUT -; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -; more details. -; -; You should have received a copy of the GNU Lesser General Public License -; along with this program. If not, see -; --------------------------------------------------------------------------- - VERS_HI equ 4 - VERS_LO equ 12 -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- - SCON_0 equ 098h - FE_0 equ 098h.7 - - SCON_1 equ 0F8h - RI_1 equ 0F8h.0 - TI_1 equ 0F8h.1 - FE_1 equ 0F8h.7 - SBUF_1 equ 09Ah - T3CON equ 0C4h - RL3 equ 0C5h - RH3 equ 0C6h - - P0M1 equ 0B1h - P0M2 equ 0B2h - P1M1 equ 0B3h - P1M2 equ 0B4h - P3M1 equ 0ACh; - P3M2 equ 0ADh; - - EIE equ 09Bh - EIE1 equ 09Ch - - TA equ 0C7h - - RCTRIM0 equ 084h -; --------------------------------------------------------------------------- - CKCON equ 08Eh - CKDIV equ 095h -; --------------------------------------------------------------------------- - P1S equ 0B3h ;Page1 - SFRS equ 091h ;TA Protection -; --------------------------------------------------------------------------- - ;AUXR1 equ 0A2h -; --------------------------------------------------------------------------- - I2DAT equ 0BCh; - I2STAT equ 0BDh; - I2CLK equ 0BEh; - I2TOC equ 0BFh; - I2CON equ 0C0h; - ; equ I2CON.7;8 - I2CEN equ I2CON.6;4 - STA equ I2CON.5;2 - STO equ I2CON.4;1 - SI equ I2CON.3;8 - AA equ I2CON.2;4 - ; equ I2CON.1;2 - I2CPX equ I2CON.0;1 - - - I2ADDR equ 0C1h; - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- - pin_TX1 equ P1.6 - - pin_TX0 equ P0.6 - pin_RX0 equ P0.7 - - pin_SCL equ P1.3 - pin_SDA equ P1.4 - - pin_RST equ P1.0 - pin_CLC equ P1.1 - pin_led equ P1.2 - -; --------------------------------------------------------------------------- -; =========================================================================== - - - CMD_GENERATE_ATR equ 01h - CMD_WRITE_DATA_SIM equ 02h - CMD_READ_DATA_SIM equ 03h - - CMD_SET_BAUD_RATE equ 04h - CMD_SET_SIM_CLC equ 05h - CMD_GET_VERS equ 06h - CMD_WRITE_CONFIRM equ 07h - - - -; --------------------------------------------------------------------------- -; =========================================================================== - - bit_RX0 equ 32.0 - bit_command_receive equ 32.1 - bit_generate_ATR equ 32.2 - i2c_write_mode equ 32.3 - i2c_write_done equ 32.4 - bit_data_sim_wr equ 32.5 - ; equ 32.6 - bit_TX0 equ 32.7 - - bit_command_buff equ 33.0 - i2c_write_command equ 33.1 - i2c_command_done equ 33.2 - bit_wait_confirm equ 33.3 - bit_first_ATR equ 33.4 ;11/03/2019 - bit_length_answerH equ 33.5 - bit_length_answerL equ 33.6 -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - bit_32 equ 32 - bit_33 equ 33 - - time_data_read equ 34 - time_confirm equ 35 - - pointer_RX1H equ 36 ;save SBUF(SIM) to XRAM - pointer_RX1L equ 37 ;save SBUF(SIM) to XRAM - - pointer_RX2H equ 38 ;read XRAM to I2C - pointer_RX2L equ 39 ;read XRAM to I2C - - pointer_TXH equ 40 - pointer_TXL equ 41 - - length_send_to_simH equ 42 - length_send_to_simL equ 43 - - length_answer_simH equ 44 - length_answer_simL equ 45 - - length_command equ 46 - - buff_command equ 47 - cmd_command equ 48 - data_command equ 49 - - STACKKKKK equ 200 -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - XRAM_TX_BUFF equ 0 - XRAM_RX_BUFF equ 384 -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -; Beginning of the main program - cseg at 00 - Ljmp main_start - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- - cseg at 11 ;1302Hz = 4MHZ(Fsys)/12/256 -; --------------------------------------------------------------------------- - jb time_confirm.7, $+3+2 ;3 - dec time_confirm ;2 -; --------------------------------------------------------------------------- - jb time_data_read.7,reti_timer0 - djnz time_data_read, reti_timer0 - setb pin_scl -reti_timer0: - reti - - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- - cseg at 35 ;UART0 - ajmp jmp_UART0_interrupt - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- - cseg at 51 ;I2C - ajmp jmp_i2c_interrupt - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- - cseg at 123 ;UART1 - clr RI_1 - clr TI_1 - reti - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -jmp_UART0_interrupt: - jbc RI,jmp_byte_RI - jbc TI,jmp_byte_TI - reti -; --------------------------------------------------------------------------- -jmp_byte_RI: - jnb bit_first_ATR, jmp_not_collect ;11/03/2019 - - setb bit_RX0 - jb i2c_write_done,jmp_not_collect - PUSH ACC - PUSH DPH - PUSH DPL - mov DPL,pointer_RX1L - mov DPH,pointer_RX1H - mov a,SBUF - movx @DPTR,a - inc DPTR - mov pointer_RX1L,DPL - mov pointer_RX1H,DPH - POP DPL - POP DPH - POP ACC - ;09/08/2018 - clr pin_scl - mov time_data_read,#52 ;52/1302Hz = 40mS - - inc length_answer_simL - mov a,length_answer_simL - jnz $+2+2 ;2 - inc length_answer_simH ;2 - -jmp_not_collect: - reti -; --------------------------------------------------------------------------- -jmp_byte_TI: - setb bit_TX0 - reti - - -; =========================================================================== -; --------------------------------------------------------------------------- -jmp_i2c_interrupt: - PUSH ACC - PUSH PSW - mov PSW,#24 - mov R7,I2STAT -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - cjne R7,#000h,nextttt00000 - setb STO - clr SI - jb STO,$ - ajmp pop_i2c_psw -nextttt00000: -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - cjne R7,#060h,nextttt00001 ;START+MY ADRESS - clr pin_led ;LED ON - - clr bit_command_receive - clr i2c_write_mode - clr bit_data_sim_wr - clr bit_length_answerH - clr bit_length_answerL - clr bit_command_buff - clr i2c_write_command - - ajmp end_i2c_interrupt -nextttt00001: -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - cjne R7,#080h,nextttt00002 ;RAM ADRESS - - jb bit_command_receive,jmp_data_receive - setb bit_command_receive - - mov a,I2DAT -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - cjne a,#CMD_WRITE_CONFIRM,next_comm001a - setb bit_wait_confirm - ajmp WRITEDATASIM -next_comm001a: -; --------------------------------------------------------------------------- - cjne a,#CMD_WRITE_DATA_SIM,next_comm001b - clr bit_wait_confirm - ajmp WRITEDATASIM -next_comm001b: -; --------------------------------------------------------------------------- - cjne a,#CMD_GENERATE_ATR,next_comm002 - ajmp ATR_GENERATE -next_comm002: -; --------------------------------------------------------------------------- - cjne a,#CMD_GET_VERS,next_comm003 - ajmp ANSWER_VERS -next_comm003: -; --------------------------------------------------------------------------- - cjne a,#CMD_SET_BAUD_RATE,next_comm004 - ajmp BAUD_RATE_SET -next_comm004: -; --------------------------------------------------------------------------- - cjne a,#CMD_SET_SIM_CLC,next_comm005 - ajmp SIM_CLC_SET -next_comm005: -; --------------------------------------------------------------------------- - ajmp end_i2c_interrupt -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -jmp_data_receive: - ;What receive ? Data to SIM/Command to bridge - jb bit_data_sim_wr, jmp_data_sim_receive - jb i2c_write_command,jmp_comm_bridge_receive - ajmp end_i2c_interrupt -; --------------------------------------------------------------------------- -jmp_comm_bridge_receive: - mov @R0,I2DAT - inc R0 - inc length_command - ajmp end_i2c_interrupt -; --------------------------------------------------------------------------- -jmp_data_sim_receive: - - setb i2c_write_mode - - PUSH DPH - PUSH DPL - mov DPL,pointer_TXL - mov DPH,pointer_TXH - mov a,I2DAT - movx @DPTR,a - inc DPTR - mov pointer_TXL,DPL - mov pointer_TXH,DPH - POP DPL - POP DPH - - inc length_send_to_simL - mov a,length_send_to_simL - jnz $+2+2 ;2 - inc length_send_to_simH ;2 - - ajmp end_i2c_interrupt -nextttt00002: -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - cjne R7,#0A0h,nextttt00003 ;STOP - setb pin_led ;LED OFF - - ;Command finish ? - jnb i2c_write_command,jmp_not_command - clr i2c_write_command - setb i2c_command_done -jmp_not_command: - - ;data to SIM finish ? - jnb i2c_write_mode,end_i2c_interrupt - clr i2c_write_mode - - setb i2c_write_done - ;Prepare to answer - mov length_answer_simH,#0 - mov length_answer_simL,#0 - mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX1L,#LOW (XRAM_RX_BUFF) - mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX2L,#LOW (XRAM_RX_BUFF) - - ajmp end_i2c_interrupt -nextttt00003: -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - cjne R7,#0A8h,nextttt00004 - sjmp read_byte_I2C -nextttt00004: -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - cjne R7,#0B8h,nextttt00005 -read_byte_I2C: - jnb bit_command_buff,jmp_not_comm_buff2 - mov I2DAT,@R0 - inc R0 - ajmp end_i2c_interrupt - -jmp_not_comm_buff2: - jb bit_length_answerH,jmp_not_comm_buff3 - setb bit_length_answerH - mov I2DAT,length_answer_simH - ajmp end_i2c_interrupt - -jmp_not_comm_buff3: - jb bit_length_answerL,read_byte_APROM - setb bit_length_answerL - mov I2DAT,length_answer_simL - ajmp end_i2c_interrupt - -read_byte_APROM: - PUSH DPH - PUSH DPL - mov DPL,pointer_RX2L - mov DPH,pointer_RX2H - movx a,@DPTR - mov I2DAT,a - inc DPTR - mov pointer_RX2L,DPL - mov pointer_RX2H,DPH - POP DPL - POP DPH - -nextttt00005: -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -end_i2c_interrupt: - clr STA - clr STO - setb AA -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -pop_i2c_psw: - POP PSW - POP ACC - clr SI - reti - - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -ANSWER_VERS: - mov R0,#data_command - mov cmd_command,#CMD_GET_VERS - mov (data_command+0),#2 - mov (data_command+1),#VERS_HI - mov (data_command+2),#VERS_LO - setb bit_command_buff - ajmp end_i2c_interrupt - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -ATR_GENERATE: - setb bit_generate_ATR - ;Prepare to answer - mov length_answer_simH,#0 - mov length_answer_simL,#0 - mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX1L,#LOW (XRAM_RX_BUFF) - mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX2L,#LOW (XRAM_RX_BUFF) - ajmp end_i2c_interrupt - - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -BAUD_RATE_SET: - mov R0,#data_command - mov length_command,#0 - mov cmd_command,#CMD_SET_BAUD_RATE - setb i2c_write_command - ajmp end_i2c_interrupt - - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -SIM_CLC_SET: - mov R0,#data_command - mov length_command,#0 - mov cmd_command,#CMD_SET_SIM_CLC - setb i2c_write_command - ajmp end_i2c_interrupt - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -WRITEDATASIM: - mov length_send_to_simH,#0 - mov length_send_to_simL,#0 - setb bit_data_sim_wr - mov pointer_TXH,#HIGH(XRAM_TX_BUFF) - mov pointer_TXL,#LOW (XRAM_TX_BUFF) - ajmp end_i2c_interrupt - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -main_start: - mov SP,#STACKKKKK -; --------------------------------------------------------------------------- - ;0-bidirect 1-push pull 0-input only 1-open drain - ;0 0 1 1 -; --------------------------------------------------------------------------- - mov P0M2,#01000000b ;?0 - mov P0M1,#11111111b ;P1.6-Tx0 SIM; - ; - mov P1M2,#01011111b ;1 - mov P1M1,#10111000b ;P1.6-Tx1 DEBUG; P1.4,P1.3 - I2C; - - mov P3M2,#00000000b ;P3 - mov P3M1,#11111111b ; -; --------------------------------------------------------------------------- - mov TMOD, #22h - mov TH0, #0 ;14400hz - mov TH1, #0E9h ;UART0 10800 Bit/sec - mov TCON, #55h -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - mov TA,#0AAh - mov TA,#055h - orl SFRS,#00000001b - - mov P1S, #00010000b ;P1.4 trigger schmiddt - - mov TA,#0AAh - mov TA,#055h - anl SFRS,#11111110b -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - ;------- CONFIG I2C --------- - mov I2CON, #44h ;set AA, set I2C enable - setb pin_sda - setb pin_scl - mov I2ADDR,#0C0h -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - ;mov SCON, #050h ;UART0 8bit - mov SCON, #0D0h ;UART0 9bit - ;mov PCON, #11000000b;FE_0 enable - mov PCON, #10000000b;FE_0 disable -; --------------------------------------------------------------------------- - mov SCON_1,#050h ;UART1 - ;mov T3CON, #01101000b;FE_1 enable TIMER3 UART0 BAUD - ;mov T3CON, #00101000b;FE_1 disable TIMER3 UART0 BAUD - mov T3CON, #00001000b;FE_1 disable TIMER1 UART0 BAUD - ;mov RL3,#0E9h ;10800/21600 - ;mov RH3,#0FFh -; --------------------------------------------------------------------------- - ;UART1 - mov RL3,#0F7h ;27777/55556 - mov RH3,#0FFh -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - mov CKDIV,#2 ;Fsys=4.00MHZ - ;mov CKDIV,#1 ;Fsys=8.00MHZ -; --------------------------------------------------------------------------- - mov bit_32,#0 - mov bit_33,#0 - setb time_data_read.7 -; --------------------------------------------------------------------------- - ;orl CKCON,#00000010b ;ENABLE CLC TIMER1 Fsys/12 - orl CKCON,#00010010b ;ENABLE CLC TIMER1 Fsys -; --------------------------------------------------------------------------- - ;mov a,RCTRIM0 - ;add a,#31 - ;mov TA,#0AAh - ;mov TA,#055h - ;mov RCTRIM0,a -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - acall clr_buffer -; --------------------------------------------------------------------------- - mov EIE, #00000001b ;I2C Interrupt - ;mov IE, #10010000b ;EA, SERIAL0 - mov IE, #10010010b ;EA, SERIAL0, TIMER0 -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -main_loop: - acall control_ATR - acall control_send_to_sim - acall control_command - sjmp main_loop - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -control_command: - jbc i2c_command_done,$+3+1 ;3 - ret ;1 -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - ;Control Length command=1 - mov a,length_command - cjne a,#1,next_commandEND ;error length_command != 1 -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - mov a,cmd_command - cjne a,#CMD_SET_BAUD_RATE,next_command001 - mov TH1,data_command ;Timer1 HIGH byte - ret -next_command001: -; --------------------------------------------------------------------------- - cjne a,#CMD_SET_SIM_CLC, next_command002 - mov CKDIV,data_command ;Fsys DIV - ret -next_command002: -; --------------------------------------------------------------------------- -next_commandEND: - ret - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -control_send_to_sim: - jb i2c_write_done,$+3+1 ;3 - ret ;1 -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - jbc bit_wait_confirm,jmp_wait_confirm -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - mov DPTR,#XRAM_TX_BUFF -looop_send: - movx a,@DPTR - inc DPTR - acall for_coooooom0 - - clr c - mov a,length_send_to_simL - subb a,#1 - mov length_send_to_simL,a - mov a,length_send_to_simH - subb a,#0 - mov length_send_to_simH,a - orl a,length_send_to_simL - jnz looop_send -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - jnb bit_RX0,$ - clr i2c_write_done - ret - - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -jmp_wait_confirm: - mov DPTR,#(XRAM_TX_BUFF+1) - movx a,@DPTR - mov R3,a - mov R4,#5 -; --------------------------------------------------------------------------- - mov DPTR,#XRAM_TX_BUFF -looop_seend: - movx a,@DPTR - inc DPTR - acall for_coooooom0 - djnz R4,jmp_not_5byte - - jnb bit_RX0,$ - clr bit_RX0 - ;18/12/2018 - mov time_confirm,#65 ;New timeout 50mS -looop_waitconf: - jb time_confirm.7,jmp_no_answer - jnb bit_RX0,looop_waitconf - - ;clr pin_scl ;TEST PULSE! - mov a,SBUF - xrl a,R3 - ;setb pin_scl ;TEST PULSE! - - jnz jmp_no_correct_answer ;18/12/2018 - - ;pause for next byte 17/12/2018 - mov R7,#0 - djnz R7,$ ;~260mkSec - djnz R7,$ ;~260mkSec - djnz R7,$ ;~260mkSec - -jmp_not_5byte: - - clr c - mov a,length_send_to_simL - subb a,#1 - mov length_send_to_simL,a - mov a,length_send_to_simH - subb a,#0 - mov length_send_to_simH,a - orl a,length_send_to_simL - jnz looop_seend -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- - jnb bit_RX0,$ - clr bit_RX0 -jmp_no_answer: - clr i2c_write_done - ret - -; --------------------------------------------------------------------------- -; --------------------------------------------------------------------------- -;18/12/2018 -jmp_no_correct_answer: - clr EA - clr i2c_write_done - - mov DPL,pointer_RX1L - mov DPH,pointer_RX1H - mov a,SBUF - movx @DPTR,a - inc DPTR - mov pointer_RX1L,DPL - mov pointer_RX1H,DPH - - clr pin_scl - mov time_data_read,#52 ;52/1302Hz = 40mS - - inc length_answer_simL - mov a,length_answer_simL - jnz $+2+2 ;2 - inc length_answer_simH ;2 - - setb EA - ret - - - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -control_ATR: - jbc bit_generate_ATR,$+3+1 ;3 - ret ;1 -; --------------------------------------------------------------------------- - clr pin_RST - ;acall clr_buffer - ; Add rezet pause 17/12/2018 - - mov R6,#200 -looop_pause50mS: - djnz R7,$ ;~260mkSec - djnz R6,looop_pause50mS - - ;Prepare to answer 11/03/2019 - acall clr_buffer - - mov length_answer_simH,#0 - mov length_answer_simL,#0 - mov pointer_RX1H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX1L,#LOW (XRAM_RX_BUFF) - mov pointer_RX2H,#HIGH(XRAM_RX_BUFF) - mov pointer_RX2L,#LOW (XRAM_RX_BUFF) - setb bit_first_ATR - setb pin_RST - ret - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -for_coooooom0: - clr bit_RX0 - mov c,P - mov TB8,c ;9bit parity - mov SBUF,a - jnb bit_TX0,$ - clr bit_TX0 - mov R7,#100 - djnz R7,$ - ret - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -clr_buffer: - mov DPTR,#0256 ;Receive SIM buffer - mov R7,#255 - clr a -looop_clr_bufff: - movx @DPTR,a - inc DPTR - djnz R7,looop_clr_bufff - ret - -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- -;for_coooooom1: -; mov SBUF_1,a -; jnb TI_1,$ -; clr TI_1 -; ret -; -; --------------------------------------------------------------------------- -; =========================================================================== -; --------------------------------------------------------------------------- - -end. From e77781e6211bfbed9b83cc3cf81aa40543e29844 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 31 Dec 2022 10:04:30 +0100 Subject: [PATCH 442/759] only mark CRC bytes if we have 3 or more bytes, and increase the line buffer since ansi colors eats chars --- client/src/cmdtrace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index a714b7e32..5fbf90b0d 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -573,7 +573,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr //2 Not crc-command //--- Draw the data column - char line[18][140] = {{0}}; + char line[18][160] = {{0}}; if (data_len == 0) { if (protocol == ICLASS && duration == 2048) { @@ -633,8 +633,9 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } + uint8_t crc_format_string_offset = 0; - if (markCRCBytes) { + if (markCRCBytes && data_len > 2) { //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 @@ -647,6 +648,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } else { if (crcStatus == 0 || crcStatus == 1) { + char *pos1 = line[(data_len - 2) / 18]; pos1 += (((data_len - 2) % 18) * 4) - 1; From 2b27ce02863bfaf33c3c449288a9c6fc8c722fe7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 31 Dec 2022 13:21:22 +0100 Subject: [PATCH 443/759] mac os actions seem to report a different return code and it exits the action. lets see if it works if it continues --- .github/workflows/macos.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 2245ef05f..a632a5e37 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -36,6 +36,7 @@ jobs: - name: Install dependencies run: brew install readline coreutils qt5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl + continue-on-error: true - name: Install Python dependencies run: | @@ -77,6 +78,7 @@ jobs: - name: Install dependencies run: brew install readline coreutils qt5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl + continue-on-error: true - name: Install Python dependencies run: | @@ -119,6 +121,7 @@ jobs: - name: Install dependencies run: brew install readline coreutils qt5 RfidResearchGroup/proxmark3/arm-none-eabi-gcc openssl + continue-on-error: true - name: Install Python dependencies run: | From d6af860136e6174e04d06045703a30d4daffaef8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 31 Dec 2022 22:30:07 +0100 Subject: [PATCH 444/759] adapt path separator to handle WIN32 backslash. --- client/src/ui.h | 4 +++- include/common.h | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/client/src/ui.h b/client/src/ui.h index 6b1ac4a83..7aff98eba 100644 --- a/client/src/ui.h +++ b/client/src/ui.h @@ -35,7 +35,9 @@ typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLA typedef enum emojiMode {EMO_ALIAS, EMO_EMOJI, EMO_ALTTEXT, EMO_NONE} emojiMode_t; typedef enum clientdebugLevel {cdbOFF, cdbSIMPLE, cdbFULL} clientdebugLevel_t; // typedef enum devicedebugLevel {ddbOFF, ddbERROR, ddbINFO, ddbDEBUG, ddbEXTENDED} devicedebugLevel_t; -typedef enum savePaths {spDefault, spDump, spTrace, spItemCount} savePaths_t; // last item spItemCount used to auto map to number of files + + // last item spItemCount used to auto map to number of files +typedef enum savePaths {spDefault, spDump, spTrace, spItemCount} savePaths_t; typedef struct {int x; int y; int h; int w;} qtWindow_t; typedef struct { diff --git a/include/common.h b/include/common.h index 22c7a90e7..bb3781c4a 100644 --- a/include/common.h +++ b/include/common.h @@ -23,7 +23,14 @@ #include #include +#ifdef _WIN32 +#define ABOVE "..\\" +#define PATHSEP "\\" +#else +#define ABOVE "../" #define PATHSEP "/" +#endif + // PM3 share path relative to executable when installed #define PM3_SHARE_RELPATH ".." PATHSEP "share" PATHSEP "proxmark3" PATHSEP From 53808f2c7f134eb205819c432e3e42912c3a1f07 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 31 Dec 2022 23:07:54 +0100 Subject: [PATCH 445/759] sanity checks and style --- client/src/fileutils.c | 113 +++++++++++++++++++++++++++++++---------- client/src/fileutils.h | 4 +- 2 files changed, 88 insertions(+), 29 deletions(-) diff --git a/client/src/fileutils.c b/client/src/fileutils.c index a2f8e4abe..22cf3ad5e 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -214,18 +214,23 @@ bool create_path(const char *dirname) { } */ -bool setDefaultPath(savePaths_t pathIndex, const char *Path) { +bool setDefaultPath(savePaths_t pathIndex, const char *path) { if (pathIndex < spItemCount) { - if ((Path == NULL) && (g_session.defaultPaths[pathIndex] != NULL)) { + + if ((path == NULL) && (g_session.defaultPaths[pathIndex] != NULL)) { free(g_session.defaultPaths[pathIndex]); g_session.defaultPaths[pathIndex] = NULL; } - if (Path != NULL) { - g_session.defaultPaths[pathIndex] = (char *)realloc(g_session.defaultPaths[pathIndex], strlen(Path) + 1); - strcpy(g_session.defaultPaths[pathIndex], Path); + if (path == NULL) { + return false; } + + size_t len = strlen(path); + + g_session.defaultPaths[pathIndex] = (char *)realloc(g_session.defaultPaths[pathIndex], len + 1); + strcpy(g_session.defaultPaths[pathIndex], path); return true; } return false; @@ -234,47 +239,70 @@ bool setDefaultPath(savePaths_t pathIndex, const char *Path) { static char *filenamemcopy(const char *preferredName, const char *suffix) { if (preferredName == NULL) return NULL; if (suffix == NULL) return NULL; + char *fileName = (char *) calloc(strlen(preferredName) + strlen(suffix) + 1, sizeof(uint8_t)); - if (fileName == NULL) + if (fileName == NULL) { return NULL; + } + strcpy(fileName, preferredName); - if (str_endswith(fileName, suffix)) + if (str_endswith(fileName, suffix)) { return fileName; + } + strcat(fileName, suffix); return fileName; } +static size_t path_size(savePaths_t a) { + if (a == spItemCount) { + return 0; + } + return strlen( g_session.defaultPaths[a] ); +} + char *newfilenamemcopy(const char *preferredName, const char *suffix) { - if (preferredName == NULL) return NULL; - if (suffix == NULL) return NULL; + if (preferredName == NULL || suffix == NULL) { + return NULL; + } uint16_t p_namelen = strlen(preferredName); if (str_endswith(preferredName, suffix)) p_namelen -= strlen(suffix); - const size_t fileNameLen = p_namelen + strlen(suffix) + 1 + 10; - const size_t fileNameSize = fileNameLen * sizeof(uint8_t); + // 10: room for filenum to ensure new filename + const size_t len = p_namelen + strlen(suffix) + 1 + 10; - char *fileName = (char *) calloc(fileNameLen, sizeof(uint8_t)); // 10: room for filenum to ensure new filename + int foobar = path_size(spDefault); + (void) foobar; + + char *fileName = (char *) calloc(len, sizeof(uint8_t)); if (fileName == NULL) { return NULL; } - int num = 1; - snprintf(fileName, fileNameSize, "%.*s%s", p_namelen, preferredName, suffix); + + snprintf(fileName, len, "%.*s%s", p_namelen, preferredName, suffix); while (fileExists(fileName)) { - snprintf(fileName, fileNameSize, "%.*s-%d%s", p_namelen, preferredName, num, suffix); + snprintf(fileName, len, "%.*s-%d%s", p_namelen, preferredName, num, suffix); num++; } + + PrintAndLogEx(INFO, "FILE PATH: %s", fileName); return fileName; } int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) { - if (data == NULL) return PM3_EINVARG; + if (data == NULL || datalen == 0) { + return PM3_EINVARG; + } + char *fileName = newfilenamemcopy(preferredName, suffix); - if (fileName == NULL) return PM3_EMALLOC; + if (fileName == NULL) { + return PM3_EMALLOC; + } /* We should have a valid filename now, e.g. dumpdata-3.bin */ @@ -295,9 +323,14 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize) { - if (data == NULL) return PM3_EINVARG; + if (data == NULL || datalen == 0) { + return PM3_EINVARG; + } + char *fileName = newfilenamemcopy(preferredName, ".eml"); - if (fileName == NULL) return PM3_EMALLOC; + if (fileName == NULL) { + return PM3_EMALLOC; + } int retval = PM3_SUCCESS; int blocks = datalen / blocksize; @@ -343,10 +376,14 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s } int saveFileJSONex(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen, bool verbose, void (*callback)(json_t *)) { - if (data == NULL) return PM3_EINVARG; + if (data == NULL || datalen == 0) { + return PM3_EINVARG; + } char *fileName = newfilenamemcopy(preferredName, ".json"); - if (fileName == NULL) return PM3_EMALLOC; + if (fileName == NULL) { + return PM3_EMALLOC; + } int retval = PM3_SUCCESS; @@ -704,9 +741,15 @@ int saveFileJSONrootEx(const char *preferredName, void *root, size_t flags, bool int saveFileWAVE(const char *preferredName, const int *data, size_t datalen) { - if (data == NULL) return PM3_EINVARG; + if (data == NULL || datalen == 0) { + return PM3_EINVARG; + } + char *fileName = newfilenamemcopy(preferredName, ".wav"); - if (fileName == NULL) return PM3_EMALLOC; + if (fileName == NULL) { + return PM3_EMALLOC; + } + int retval = PM3_SUCCESS; struct wave_info_t wave_info = { @@ -731,11 +774,14 @@ int saveFileWAVE(const char *preferredName, const int *data, size_t datalen) { retval = PM3_EFILE; goto out; } + fwrite(&wave_info, sizeof(wave_info), 1, wave_file); + for (int i = 0; i < datalen; i++) { uint8_t sample = data[i] + 128; fwrite(&sample, 1, 1, wave_file); } + fclose(wave_file); PrintAndLogEx(SUCCESS, "saved " _YELLOW_("%zu") " bytes to wave file " _YELLOW_("'%s'"), 2 * datalen, fileName); @@ -747,9 +793,14 @@ out: int saveFilePM3(const char *preferredName, int *data, size_t datalen) { - if (data == NULL) return PM3_EINVARG; + if (data == NULL || datalen == 0) { + return PM3_EINVARG; + } + char *fileName = newfilenamemcopy(preferredName, ".pm3"); - if (fileName == NULL) return PM3_EMALLOC; + if (fileName == NULL) { + return PM3_EMALLOC; + } int retval = PM3_SUCCESS; @@ -760,8 +811,9 @@ int saveFilePM3(const char *preferredName, int *data, size_t datalen) { goto out; } - for (uint32_t i = 0; i < datalen; i++) + for (uint32_t i = 0; i < datalen; i++) { fprintf(f, "%d\n", data[i]); + } fflush(f); fclose(f); @@ -1862,14 +1914,18 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea (strcmp(PYTHON_SCRIPTS_SUBDIR, pm3dir) == 0) || (strcmp(RESOURCES_SUBDIR, pm3dir) == 0))) { char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char)); - if (path == NULL) + if (path == NULL) { goto out; + } + strcpy(path, exec_path); strcat(path, pm3dir); strcat(path, filename); + if ((g_debugMode == 2) && (!silent)) { PrintAndLogEx(INFO, "Searching %s", path); } + if (fileExists(path)) { free(filename); *foundpath = path; @@ -2007,7 +2063,8 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl } int pm3_save_dump(const char *fn, uint8_t *d, size_t n, JSONFileType jsft, size_t blocksize) { - if (n == 0) { + + if (d == NULL || n == 0) { PrintAndLogEx(INFO, "No data to save. Skipping..."); return PM3_EINVARG; } diff --git a/client/src/fileutils.h b/client/src/fileutils.h index d237b0fe7..fc5d274aa 100644 --- a/client/src/fileutils.h +++ b/client/src/fileutils.h @@ -60,7 +60,9 @@ typedef enum { int fileExists(const char *filename); //bool create_path(const char *dirname); -bool setDefaultPath(savePaths_t pathIndex, const char *Path); // set a path in the path list g_session.defaultPaths + +// set a path in the path list g_session.defaultPaths +bool setDefaultPath(savePaths_t pathIndex, const char *path); char *newfilenamemcopy(const char *preferredName, const char *suffix); From 41806352189a6d86b1d17f6e220eca11aa44394d Mon Sep 17 00:00:00 2001 From: nvx Date: Wed, 4 Jan 2023 23:27:00 +1000 Subject: [PATCH 446/759] Add `--shallow` option to `hf iclass` reader commands to do shallow (ASK) reader modulation instead of OOK. --- CHANGELOG.md | 1 + armsrc/Standalone/hf_iceclass.c | 18 +++++---- armsrc/iclass.c | 70 ++++++++++++++++++--------------- armsrc/iclass.h | 4 +- armsrc/iso15693.c | 10 ++--- armsrc/iso15693.h | 2 +- client/src/cmdhf.c | 2 +- client/src/cmdhficlass.c | 66 +++++++++++++++++++++++++------ client/src/cmdhficlass.h | 4 +- include/iclass_cmd.h | 3 ++ 10 files changed, 117 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e87e6bfae..e2875edde 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] + - Add `--shallow` option to `hf iclass` reader commands to do shallow (ASK) reader modulation instead of OOK (@nvx) - Improved NXP SLI/SLIX series tag identification (@nvx) - Fixed buffer overflow in "lf em 4x05 sniff" (@HeinrichsH) - Fixed potential NULL array printing (@jmichel) diff --git a/armsrc/Standalone/hf_iceclass.c b/armsrc/Standalone/hf_iceclass.c index 8f9bf4c63..7d69e867a 100644 --- a/armsrc/Standalone/hf_iceclass.c +++ b/armsrc/Standalone/hf_iceclass.c @@ -322,6 +322,7 @@ static int reader_dump_mode(void) { .use_credit_key = false, .do_auth = true, .send_reply = false, + .shallow_mod = false, }; memcpy(auth.key, legacy_aa1_key, sizeof(auth.key)); @@ -333,7 +334,7 @@ static int reader_dump_mode(void) { // select tag. uint32_t eof_time = 0; - bool res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time); + bool res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time, false); if (res == false) { switch_off(); continue; @@ -382,7 +383,7 @@ static int reader_dump_mode(void) { // main read loop for (uint16_t i = start_block; i <= app1_limit; i++) { - if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time)) { + if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time, false)) { dumped++; } } @@ -394,7 +395,7 @@ static int reader_dump_mode(void) { auth.use_credit_key = true; memcpy(auth.key, aa2_key, sizeof(auth.key)); - res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time); + res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time, false); if (res) { // sanity check of CSN. @@ -408,7 +409,7 @@ static int reader_dump_mode(void) { start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; for (uint16_t i = app1_limit + 1; i <= app2_limit; i++) { - if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time)) { + if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time, false)) { dumped++; } } @@ -458,6 +459,7 @@ static int dump_sim_mode(void) { .use_credit_key = false, .do_auth = true, .send_reply = false, + .shallow_mod = false, }; memcpy(auth.key, legacy_aa1_key, sizeof(auth.key)); @@ -469,7 +471,7 @@ static int dump_sim_mode(void) { // select tag. uint32_t eof_time = 0; - bool res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time); + bool res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time, false); if (res == false) { switch_off(); continue; @@ -518,7 +520,7 @@ static int dump_sim_mode(void) { // main read loop for (uint16_t i = start_block; i <= app1_limit; i++) { - if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time)) { + if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time, false)) { dumped++; } } @@ -530,7 +532,7 @@ static int dump_sim_mode(void) { auth.use_credit_key = true; memcpy(auth.key, aa2_key, sizeof(auth.key)); - res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time); + res = select_iclass_tag(hdr, auth.use_credit_key, &eof_time, false); if (res) { // sanity check of CSN. @@ -544,7 +546,7 @@ static int dump_sim_mode(void) { start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; for (uint16_t i = app1_limit + 1; i <= app2_limit; i++) { - if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time)) { + if (iclass_read_block(i, card_data + (8 * i), &start_time, &eof_time, false)) { dumped++; } } diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 1ed774f16..a25fbd52c 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1245,23 +1245,23 @@ send: } // THE READER CODE -static void iclass_send_as_reader(uint8_t *frame, int len, uint32_t *start_time, uint32_t *end_time) { +static void iclass_send_as_reader(uint8_t *frame, int len, uint32_t *start_time, uint32_t *end_time, bool shallow_mod) { CodeIso15693AsReader(frame, len); tosend_t *ts = get_tosend(); - TransmitTo15693Tag(ts->buf, ts->max, start_time); + TransmitTo15693Tag(ts->buf, ts->max, start_time, shallow_mod); *end_time = *start_time + (32 * ((8 * ts->max) - 4)); // subtract the 4 padding bits after EOF LogTrace_ISO15693(frame, len, (*start_time * 4), (*end_time * 4), NULL, true); } static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t *resp, size_t max_resp_size, uint8_t expected_size, uint8_t tries, uint32_t *start_time, - uint16_t timeout, uint32_t *eof_time) { + uint16_t timeout, uint32_t *eof_time, bool shallow_mod) { uint16_t resp_len = 0; int res; while (tries-- > 0) { - iclass_send_as_reader(cmd, cmdsize, start_time, eof_time); + iclass_send_as_reader(cmd, cmdsize, start_time, eof_time, shallow_mod); if (resp == NULL) { return true; @@ -1282,7 +1282,7 @@ static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t * * @return false = fail * true = Got all. */ -static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, uint8_t *status) { +static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, uint8_t *status, bool shallow_mod) { static uint8_t act_all[] = { ICLASS_CMD_ACTALL }; static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 }; @@ -1299,7 +1299,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 // wakeup uint32_t start_time = GetCountSspClk(); - iclass_send_as_reader(act_all, 1, &start_time, eof_time); + iclass_send_as_reader(act_all, 1, &start_time, eof_time, shallow_mod); int res; uint16_t resp_len = 0; res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_ACTALL, eof_time, false, true, &resp_len); @@ -1308,7 +1308,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 // send Identify start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; - iclass_send_as_reader(identify, 1, &start_time, eof_time); + iclass_send_as_reader(identify, 1, &start_time, eof_time, shallow_mod); // expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len); @@ -1320,7 +1320,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 // select the card start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; - iclass_send_as_reader(select, sizeof(select), &start_time, eof_time); + iclass_send_as_reader(select, sizeof(select), &start_time, eof_time, shallow_mod); // expect a 10-byte response here, 8 byte CSN and 2 byte CRC res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len); @@ -1332,7 +1332,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 // card selected, now read config (block1) (only 8 bytes no CRC) start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; - iclass_send_as_reader(read_conf, sizeof(read_conf), &start_time, eof_time); + iclass_send_as_reader(read_conf, sizeof(read_conf), &start_time, eof_time, shallow_mod); // expect a 8-byte response here res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len); @@ -1350,7 +1350,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 // read App Issuer Area block 5 start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; - iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time); + iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time, shallow_mod); // expect a 10-byte response here res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len); @@ -1364,7 +1364,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 // card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; - iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, eof_time); + iclass_send_as_reader(read_check_cc, sizeof(read_check_cc), &start_time, eof_time, shallow_mod); // expect a 8-byte response here res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len); @@ -1386,7 +1386,7 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 read_aia[3] = 0x10; start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; - iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time); + iclass_send_as_reader(read_aia, sizeof(read_aia), &start_time, eof_time, shallow_mod); // expect a 10-byte response here res = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time, false, true, &resp_len); @@ -1402,9 +1402,9 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3 return true; } -bool select_iclass_tag(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time) { +bool select_iclass_tag(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, bool shallow_mod) { uint8_t result = 0; - return select_iclass_tag_ex(hdr, use_credit_key, eof_time, &result); + return select_iclass_tag_ex(hdr, use_credit_key, eof_time, &result, shallow_mod); } // Reader iClass Anticollission @@ -1413,6 +1413,7 @@ void ReaderIClass(uint8_t flags) { // flag to use credit key bool use_credit_key = ((flags & FLAG_ICLASS_READER_CREDITKEY) == FLAG_ICLASS_READER_CREDITKEY); + bool shallow_mod = (flags & FLAG_ICLASS_READER_SHALLOW_MOD); if ((flags & FLAG_ICLASS_READER_INIT) == FLAG_ICLASS_READER_INIT) { Iso15693InitReader(); @@ -1427,7 +1428,7 @@ void ReaderIClass(uint8_t flags) { uint32_t eof_time = 0; picopass_hdr_t hdr = {0}; - if (select_iclass_tag_ex(&hdr, use_credit_key, &eof_time, &res) == false) { + if (select_iclass_tag_ex(&hdr, use_credit_key, &eof_time, &res, shallow_mod) == false) { reply_ng(CMD_HF_ICLASS_READER, PM3_ERFTRANS, NULL, 0); goto out; } @@ -1498,7 +1499,7 @@ bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr_t *hdr, ui cmd_check[7] = pmac[2]; cmd_check[8] = pmac[3]; } - return iclass_send_cmd_with_retries(cmd_check, sizeof(cmd_check), resp_auth, sizeof(resp_auth), 4, 2, start_time, ICLASS_READER_TIMEOUT_OTHERS, eof_time); + return iclass_send_cmd_with_retries(cmd_check, sizeof(cmd_check), resp_auth, sizeof(resp_auth), 4, 2, start_time, ICLASS_READER_TIMEOUT_OTHERS, eof_time, payload->shallow_mod); } @@ -1516,6 +1517,8 @@ void iClass_Authentication_fast(iclass_chk_t *p) { return; } + bool shallow_mod = p->shallow_mod; + uint8_t check[9] = { ICLASS_CMD_CHECK }; uint8_t resp[ICLASS_BUFFER_SIZE] = {0}; uint8_t readcheck_cc[] = { 0x80 | ICLASS_CMD_READCHECK, 0x02 }; @@ -1537,7 +1540,7 @@ void iClass_Authentication_fast(iclass_chk_t *p) { bool isOK = false; uint32_t start_time = 0, eof_time = 0; - if (select_iclass_tag(&hdr, p->use_credit_key, &eof_time) == false) + if (select_iclass_tag(&hdr, p->use_credit_key, &eof_time, shallow_mod) == false) goto out; start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; @@ -1566,14 +1569,14 @@ void iClass_Authentication_fast(iclass_chk_t *p) { check[8] = keys[i].mac[3]; // expect 4bytes, 3 retries times.. - isOK = iclass_send_cmd_with_retries(check, sizeof(check), resp, sizeof(resp), 4, 2, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time); + isOK = iclass_send_cmd_with_retries(check, sizeof(check), resp, sizeof(resp), 4, 2, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, shallow_mod); if (isOK) goto out; start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER; // Auth Sequence MUST begin with reading e-purse. (block2) // Card selected, now read e-purse (cc) (block2) (only 8 bytes no CRC) - iclass_send_as_reader(readcheck_cc, sizeof(readcheck_cc), &start_time, &eof_time); + iclass_send_as_reader(readcheck_cc, sizeof(readcheck_cc), &start_time, &eof_time, shallow_mod); LED_B_OFF(); } @@ -1586,11 +1589,11 @@ out: // Tries to read block. // retries 3times. // reply 8 bytes block -bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time) { +bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time, bool shallow_mod) { uint8_t resp[10]; uint8_t c[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockno, 0x00, 0x00}; AddCrc(c + 1, 1); - bool isOK = iclass_send_cmd_with_retries(c, sizeof(c), resp, sizeof(resp), 10, 2, start_time, ICLASS_READER_TIMEOUT_OTHERS, eof_time); + bool isOK = iclass_send_cmd_with_retries(c, sizeof(c), resp, sizeof(resp), 10, 2, start_time, ICLASS_READER_TIMEOUT_OTHERS, eof_time, shallow_mod); if (isOK) memcpy(data, resp, 8); return isOK; @@ -1602,6 +1605,7 @@ bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, ui void iClass_ReadBlock(uint8_t *msg) { iclass_auth_req_t *payload = (iclass_auth_req_t *)msg; + bool shallow_mod = payload->shallow_mod; iclass_readblock_resp_t response = { .isOK = true }; memset(response.data, 0, sizeof(response.data)); @@ -1614,7 +1618,7 @@ void iClass_ReadBlock(uint8_t *msg) { // select tag. uint32_t eof_time = 0; picopass_hdr_t hdr = {0}; - bool res = select_iclass_tag(&hdr, payload->use_credit_key, &eof_time); + bool res = select_iclass_tag(&hdr, payload->use_credit_key, &eof_time, shallow_mod); if (res == false) { if (payload->send_reply) { response.isOK = res; @@ -1642,7 +1646,7 @@ void iClass_ReadBlock(uint8_t *msg) { // read data uint8_t resp[10]; - res = iclass_send_cmd_with_retries(cmd_read, sizeof(cmd_read), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time); + res = iclass_send_cmd_with_retries(cmd_read, sizeof(cmd_read), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, shallow_mod); if (res) { memcpy(response.data, resp, sizeof(response.data)); if (payload->send_reply) { @@ -1670,6 +1674,7 @@ void iClass_Dump(uint8_t *msg) { iclass_dump_req_t *cmd = (iclass_dump_req_t *)msg; iclass_auth_req_t *req = &cmd->req; + bool shallow_mod = req->shallow_mod; uint8_t *dataout = BigBuf_malloc(ICLASS_16KS_SIZE); if (dataout == NULL) { @@ -1689,7 +1694,7 @@ void iClass_Dump(uint8_t *msg) { picopass_hdr_t hdr = {0}; memset(&hdr, 0xff, sizeof(picopass_hdr_t)); - bool res = select_iclass_tag(&hdr, req->use_credit_key, &eof_time); + bool res = select_iclass_tag(&hdr, req->use_credit_key, &eof_time, shallow_mod); if (res == false) { if (req->send_reply) { reply_ng(CMD_HF_ICLASS_DUMP, PM3_ETIMEOUT, NULL, 0); @@ -1724,7 +1729,7 @@ void iClass_Dump(uint8_t *msg) { uint8_t c[] = {ICLASS_CMD_READ_OR_IDENTIFY, i, 0x00, 0x00}; AddCrc(c + 1, 1); - res = iclass_send_cmd_with_retries(c, sizeof(c), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time); + res = iclass_send_cmd_with_retries(c, sizeof(c), resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time, shallow_mod); if (res) { memcpy(dataout + (8 * i), resp, 8); } else { @@ -1759,7 +1764,7 @@ void iClass_Dump(uint8_t *msg) { BigBuf_free(); } -static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac, bool use_mac) { +static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac, bool use_mac, bool shallow_mod) { // write command: cmd, 1 blockno, 8 data, 4 mac uint8_t write[14] = { 0x80 | ICLASS_CMD_UPDATE, blockno }; @@ -1775,7 +1780,7 @@ static bool iclass_writeblock_ext(uint8_t blockno, uint8_t *data, uint8_t *mac, uint8_t resp[10] = {0}; uint32_t eof_time = 0, start_time = 0; - bool isOK = iclass_send_cmd_with_retries(write, write_len, resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_UPDATE, &eof_time); + bool isOK = iclass_send_cmd_with_retries(write, write_len, resp, sizeof(resp), 10, 3, &start_time, ICLASS_READER_TIMEOUT_UPDATE, &eof_time, shallow_mod); if (isOK == false) { return false; } @@ -1807,6 +1812,7 @@ void iClass_WriteBlock(uint8_t *msg) { LED_A_ON(); iclass_writeblock_req_t *payload = (iclass_writeblock_req_t *)msg; + bool shallow_mod = payload->req.shallow_mod; uint8_t write[14] = { 0x80 | ICLASS_CMD_UPDATE, payload->req.blockno }; uint8_t write_len = 14; @@ -1816,7 +1822,7 @@ void iClass_WriteBlock(uint8_t *msg) { // select tag. uint32_t eof_time = 0; picopass_hdr_t hdr = {0}; - uint8_t res = select_iclass_tag(&hdr, payload->req.use_credit_key, &eof_time); + uint8_t res = select_iclass_tag(&hdr, payload->req.use_credit_key, &eof_time, shallow_mod); if (res == false) { goto out; } @@ -1871,7 +1877,7 @@ void iClass_WriteBlock(uint8_t *msg) { uint8_t tries = 3; while (tries-- > 0) { - iclass_send_as_reader(write, write_len, &start_time, &eof_time); + iclass_send_as_reader(write, write_len, &start_time, &eof_time, shallow_mod); if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred res = false; @@ -1939,6 +1945,8 @@ void iClass_Restore(iclass_restore_req_t *msg) { return; } + bool shallow_mod = msg->req.shallow_mod; + LED_A_ON(); Iso15693InitReader(); @@ -1947,7 +1955,7 @@ void iClass_Restore(iclass_restore_req_t *msg) { picopass_hdr_t hdr = {0}; // select - bool res = select_iclass_tag(&hdr, msg->req.use_credit_key, &eof_time); + bool res = select_iclass_tag(&hdr, msg->req.use_credit_key, &eof_time, shallow_mod); if (res == false) { goto out; } @@ -1988,7 +1996,7 @@ void iClass_Restore(iclass_restore_req_t *msg) { } // data + mac - if (iclass_writeblock_ext(item.blockno, item.data, mac, use_mac)) { + if (iclass_writeblock_ext(item.blockno, item.data, mac, use_mac, shallow_mod)) { Dbprintf("Write block [%3d/0x%02X] " _GREEN_("successful"), item.blockno, item.blockno); written++; } else { diff --git a/armsrc/iclass.h b/armsrc/iclass.h index 6801777f9..ebbda2e9f 100644 --- a/armsrc/iclass.h +++ b/armsrc/iclass.h @@ -38,8 +38,8 @@ void iClass_Authentication_fast(iclass_chk_t *p); bool iclass_auth(iclass_auth_req_t *payload, uint8_t *out); void iClass_ReadBlock(uint8_t *msg); -bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time); +bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time, bool shallow_mod); -bool select_iclass_tag(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time); +bool select_iclass_tag(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, bool shallow_mod); bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr_t *hdr, uint32_t *start_time, uint32_t *eof_time, uint8_t *mac_out); #endif diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 388aaddce..ab650da8f 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -262,9 +262,9 @@ void CodeIso15693AsTag(const uint8_t *cmd, size_t len) { } // Transmit the command (to the tag) that was placed in cmd[]. -void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time) { +void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time, bool shallow_mod) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_FULL_MOD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | (shallow_mod ? FPGA_HF_READER_MODE_SEND_SHALLOW_MOD : FPGA_HF_READER_MODE_SEND_FULL_MOD)); if (*start_time < DELAY_ARM_TO_TAG) { *start_time = DELAY_ARM_TO_TAG; @@ -1585,7 +1585,7 @@ void AcquireRawAdcSamplesIso15693(void) { tosend_t *ts = get_tosend(); uint32_t start_time = 0; - TransmitTo15693Tag(ts->buf, ts->max, &start_time); + TransmitTo15693Tag(ts->buf, ts->max, &start_time, false); // wait for last transfer to complete while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) ; @@ -1899,7 +1899,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t } tosend_t *ts = get_tosend(); - TransmitTo15693Tag(ts->buf, ts->max, &start_time); + TransmitTo15693Tag(ts->buf, ts->max, &start_time, false); if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred *resp_len = 0; @@ -1922,7 +1922,7 @@ int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, ui CodeIso15693AsReaderEOF(); tosend_t *ts = get_tosend(); - TransmitTo15693Tag(ts->buf, ts->max, &start_time); + TransmitTo15693Tag(ts->buf, ts->max, &start_time, false); uint32_t end_time = start_time + 32 * (8 * ts->max - 4); // subtract the 4 padding bits after EOF LogTrace_ISO15693(NULL, 0, (start_time * 4), (end_time * 4), NULL, true); diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index f9ba6e9da..2097b3769 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -40,7 +40,7 @@ void CodeIso15693AsTag(const uint8_t *cmd, size_t len); void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, uint32_t slot_time, bool slow); int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eof_time); -void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time); +void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time, bool shallow_mod); int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time, bool fsk, bool recv_speed, uint16_t *resp_len); //void RecordRawAdcSamplesIso15693(void); diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 81e64584a..7bba6d41a 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -123,7 +123,7 @@ int CmdHFSearch(const char *Cmd) { PROMPT_CLEARLINE; PrintAndLogEx(INPLACE, " Searching for iCLASS / PicoPass tag..."); if (IfPm3Iclass()) { - if (read_iclass_csn(false, false) == PM3_SUCCESS) { + if (read_iclass_csn(false, false, false) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("iCLASS tag / PicoPass tag") " found\n"); res = PM3_SUCCESS; } diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 95e5a7bef..4e555f909 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -285,7 +285,7 @@ static int generate_config_card(const iclass_config_card_item_t *o, uint8_t *ke // get header from card PrintAndLogEx(INFO, "trying to read a card.."); - int res = read_iclass_csn(false, false); + int res = read_iclass_csn(false, false, false); if (res == PM3_SUCCESS) { cc = &iclass_last_known_card; // calc diversified key for selected card @@ -905,19 +905,25 @@ static int CmdHFiClassInfo(const char *Cmd) { void *argtable[] = { arg_param_begin, + arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); + bool shallow_mod = arg_get_lit(ctx, 1); CLIParserFree(ctx); - return info_iclass(); + return info_iclass(shallow_mod); } -int read_iclass_csn(bool loop, bool verbose) { +int read_iclass_csn(bool loop, bool verbose, bool shallow_mod) { iclass_card_select_t payload = { .flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE) }; + if (shallow_mod) { + payload.flags |= FLAG_ICLASS_READER_SHALLOW_MOD; + } + int res = PM3_SUCCESS; do { @@ -973,17 +979,19 @@ static int CmdHFiClassReader(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_lit0("@", NULL, "optional - continuous reader mode"), + arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); bool cm = arg_get_lit(ctx, 1); + bool shallow_mod = arg_get_lit(ctx, 2); CLIParserFree(ctx); if (cm) { PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); } - return read_iclass_csn(cm, true); + return read_iclass_csn(cm, true, shallow_mod); } static int CmdHFiClassELoad(const char *Cmd) { @@ -1547,12 +1555,16 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) { return PM3_SUCCESS; } -static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool verbose) { +static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool verbose, bool shallow_mod) { iclass_card_select_t payload = { .flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE) }; + if (shallow_mod) { + payload.flags |= FLAG_ICLASS_READER_SHALLOW_MOD; + } + clearCommandBuffer(); PacketResponseNG resp; SendCommandNG(CMD_HF_ICLASS_READER, (uint8_t *)&payload, sizeof(iclass_card_select_t)); @@ -1608,6 +1620,7 @@ static int CmdHFiClassDump(const char *Cmd) { arg_lit0(NULL, "nr", "replay of NR/MAC"), arg_lit0("z", "dense", "dense dump output style"), arg_lit0(NULL, "force", "force unsecure card read"), + arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1693,6 +1706,7 @@ static int CmdHFiClassDump(const char *Cmd) { bool use_replay = arg_get_lit(ctx, 8); bool dense_output = g_session.dense_output || arg_get_lit(ctx, 9); bool force = arg_get_lit(ctx, 10); + bool shallow_mod = arg_get_lit(ctx, 11); CLIParserFree(ctx); @@ -1711,6 +1725,11 @@ static int CmdHFiClassDump(const char *Cmd) { iclass_card_select_t payload_rdr = { .flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE) }; + + if (shallow_mod) { + payload_rdr.flags |= FLAG_ICLASS_READER_SHALLOW_MOD; + } + clearCommandBuffer(); PacketResponseNG resp; SendCommandNG(CMD_HF_ICLASS_READER, (uint8_t *)&payload_rdr, sizeof(iclass_card_select_t)); @@ -1790,6 +1809,7 @@ static int CmdHFiClassDump(const char *Cmd) { .req.use_replay = use_replay, .req.send_reply = true, .req.do_auth = auth, + .req.shallow_mod = shallow_mod, .end_block = app_limit1, }; memcpy(payload.req.key, key, 8); @@ -1950,7 +1970,7 @@ write_dump: return PM3_SUCCESS; } -static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *macdata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool replay, bool verbose, bool use_secure_pagemode) { +static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *macdata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool replay, bool verbose, bool use_secure_pagemode, bool shallow_mod) { iclass_writeblock_req_t payload = { .req.use_raw = rawkey, @@ -1960,6 +1980,7 @@ static int iclass_write_block(uint8_t blockno, uint8_t *bldata, uint8_t *macdata .req.blockno = blockno, .req.send_reply = true, .req.do_auth = use_secure_pagemode, + .req.shallow_mod = shallow_mod, }; memcpy(payload.req.key, KEY, 8); memcpy(payload.data, bldata, sizeof(payload.data)); @@ -2004,6 +2025,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { arg_lit0(NULL, "raw", "no computations applied to key"), arg_lit0(NULL, "nr", "replay of NR/MAC"), arg_lit0("v", "verbose", "verbose output"), + arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -2072,6 +2094,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { bool rawkey = arg_get_lit(ctx, 8); bool use_replay = arg_get_lit(ctx, 9); bool verbose = arg_get_lit(ctx, 10); + bool shallow_mod = arg_get_lit(ctx, 11); CLIParserFree(ctx); @@ -2080,7 +2103,7 @@ static int CmdHFiClass_WriteBlock(const char *Cmd) { return PM3_EINVARG; } - int isok = iclass_write_block(blockno, data, mac, key, use_credit_key, elite, rawkey, use_replay, verbose, auth); + int isok = iclass_write_block(blockno, data, mac, key, use_credit_key, elite, rawkey, use_replay, verbose, auth, shallow_mod); switch (isok) { case PM3_SUCCESS: PrintAndLogEx(SUCCESS, "Wrote block %3d/0x%02X successful", blockno, blockno); @@ -2116,6 +2139,7 @@ static int CmdHFiClassRestore(const char *Cmd) { arg_lit0(NULL, "elite", "elite computations applied to key"), arg_lit0(NULL, "raw", "no computations applied to key"), arg_lit0("v", "verbose", "verbose output"), + arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -2165,6 +2189,7 @@ static int CmdHFiClassRestore(const char *Cmd) { bool elite = arg_get_lit(ctx, 7); bool rawkey = arg_get_lit(ctx, 8); bool verbose = arg_get_lit(ctx, 9); + bool shallow_mod = arg_get_lit(ctx, 10); CLIParserFree(ctx); @@ -2215,6 +2240,7 @@ static int CmdHFiClassRestore(const char *Cmd) { payload->req.blockno = startblock; payload->req.send_reply = true; payload->req.do_auth = true; + payload->req.shallow_mod = shallow_mod; memcpy(payload->req.key, key, 8); payload->item_cnt = (endblock - startblock + 1); @@ -2268,7 +2294,7 @@ static int CmdHFiClassRestore(const char *Cmd) { return resp.status; } -static int iclass_read_block(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool replay, bool verbose, bool auth, uint8_t *out) { +static int iclass_read_block(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool replay, bool verbose, bool auth, bool shallow_mod, uint8_t *out) { iclass_auth_req_t payload = { .use_raw = rawkey, @@ -2278,6 +2304,7 @@ static int iclass_read_block(uint8_t *KEY, uint8_t blockno, uint8_t keyType, boo .blockno = blockno, .send_reply = true, .do_auth = auth, + .shallow_mod = shallow_mod, }; memcpy(payload.key, KEY, 8); @@ -2331,6 +2358,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { arg_lit0(NULL, "raw", "no computations applied to key"), arg_lit0(NULL, "nr", "replay of NR/MAC"), arg_lit0("v", "verbose", "verbose output"), + arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -2381,6 +2409,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { bool rawkey = arg_get_lit(ctx, 6); bool use_replay = arg_get_lit(ctx, 7); bool verbose = arg_get_lit(ctx, 8); + bool shallow_mod = arg_get_lit(ctx, 9); CLIParserFree(ctx); @@ -2400,7 +2429,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { } uint8_t data[8] = {0}; - int res = iclass_read_block(key, blockno, keyType, elite, rawkey, use_replay, verbose, auth, data); + int res = iclass_read_block(key, blockno, keyType, elite, rawkey, use_replay, verbose, auth, shallow_mod, data); if (res != PM3_SUCCESS) return res; @@ -2975,7 +3004,7 @@ static int CmdHFiClassCalcNewKey(const char *Cmd) { if (givenCSN == false) { uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - if (select_only(csn, CCNR, true) == false) { + if (select_only(csn, CCNR, true, false) == false) { DropField(); return PM3_ESOFT; } @@ -3173,6 +3202,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { arg_lit0(NULL, "credit", "key is assumed to be the credit key"), arg_lit0(NULL, "elite", "elite computations applied to key"), arg_lit0(NULL, "raw", "no computations applied to key (raw)"), + arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -3184,6 +3214,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { bool use_credit_key = arg_get_lit(ctx, 2); bool use_elite = arg_get_lit(ctx, 3); bool use_raw = arg_get_lit(ctx, 4); + bool shallow_mod = arg_get_lit(ctx, 5); CLIParserFree(ctx); @@ -3213,7 +3244,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { bool got_csn = false; for (uint8_t i = 0; i < ICLASS_AUTH_RETRY; i++) { - got_csn = select_only(CSN, CCNR, false); + got_csn = select_only(CSN, CCNR, false, shallow_mod); if (got_csn == false) PrintAndLogEx(WARNING, "one more try"); else @@ -3295,6 +3326,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) { } packet->use_credit_key = use_credit_key; packet->count = curr_chunk_cnt; + packet->shallow_mod = shallow_mod; // copy chunk of pre calculated macs to packet memcpy(packet->items, (pre + chunk_offset), (4 * curr_chunk_cnt)); @@ -3799,6 +3831,7 @@ static int CmdHFiClassEncode(const char *Cmd) { arg_u64_0(NULL, "fc", "", "facility code"), arg_u64_0(NULL, "cn", "", "card number"), arg_str0("w", "wiegand", "", "see " _YELLOW_("`wiegand list`") " for available formats"), + arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -3843,6 +3876,8 @@ static int CmdHFiClassEncode(const char *Cmd) { int format_len = 0; CLIParamStrToBuf(arg_get_str(ctx, 9), (uint8_t *)format, sizeof(format), &format_len); + bool shallow_mod = arg_get_lit(ctx, 10); + CLIParserFree(ctx); if ((rawkey + elite) > 1) { @@ -3964,7 +3999,7 @@ static int CmdHFiClassEncode(const char *Cmd) { int isok = PM3_SUCCESS; // write for (uint8_t i = 0; i < 4; i++) { - isok = iclass_write_block(6 + i, credential + (i * 8), NULL, key, use_credit_key, elite, rawkey, false, false, auth); + isok = iclass_write_block(6 + i, credential + (i * 8), NULL, key, use_credit_key, elite, rawkey, false, false, auth, shallow_mod); switch (isok) { case PM3_SUCCESS: PrintAndLogEx(SUCCESS, "Write block %d/0x0%x ( " _GREEN_("ok") " ) --> " _YELLOW_("%s"), 6 + i, 6 + i, sprint_hex_inrow(credential + (i * 8), 8)); @@ -4135,11 +4170,16 @@ int CmdHFiClass(const char *Cmd) { // DESFIRE| | | //} -int info_iclass(void) { +int info_iclass(bool shallow_mod) { iclass_card_select_t payload = { .flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE) }; + + if (shallow_mod) { + payload.flags |= FLAG_ICLASS_READER_SHALLOW_MOD; + } + clearCommandBuffer(); PacketResponseNG resp; SendCommandNG(CMD_HF_ICLASS_READER, (uint8_t *)&payload, sizeof(iclass_card_select_t)); diff --git a/client/src/cmdhficlass.h b/client/src/cmdhficlass.h index a4d545a05..db242d496 100644 --- a/client/src/cmdhficlass.h +++ b/client/src/cmdhficlass.h @@ -24,8 +24,8 @@ int CmdHFiClass(const char *Cmd); -int info_iclass(void); -int read_iclass_csn(bool loop, bool verbose); +int info_iclass(bool shallow_mod); +int read_iclass_csn(bool loop, bool verbose, bool shallow_mod); void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize, bool dense_output); void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite); diff --git a/include/iclass_cmd.h b/include/iclass_cmd.h index 5a2f90226..bc7c1e6ca 100644 --- a/include/iclass_cmd.h +++ b/include/iclass_cmd.h @@ -32,6 +32,7 @@ //#define FLAG_ICLASS_READER_ONLY_ONCE 0x04 #define FLAG_ICLASS_READER_CREDITKEY 0x08 #define FLAG_ICLASS_READER_AIA 0x10 +#define FLAG_ICLASS_READER_SHALLOW_MOD 0x20 // iCLASS reader status flags #define FLAG_ICLASS_NULL 0x00 @@ -60,6 +61,7 @@ typedef struct { bool use_replay; bool send_reply; bool do_auth; + bool shallow_mod; uint8_t blockno; } PACKED iclass_auth_req_t; @@ -103,6 +105,7 @@ typedef struct iclass_premac { typedef struct { bool use_credit_key; + bool shallow_mod; uint8_t count; iclass_premac_t items[]; } PACKED iclass_chk_t; From 80a4698a7fe544806401a5efa253de1abd256c94 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 6 Jan 2023 13:03:10 +0100 Subject: [PATCH 447/759] Initial rework on TLV to avoid mem leaks --- client/src/emv/tlv.c | 73 ++++++++++++++++++++++++++++++++++++-------- client/src/emv/tlv.h | 19 +++++++++++- 2 files changed, 78 insertions(+), 14 deletions(-) diff --git a/client/src/emv/tlv.c b/client/src/emv/tlv.c index f22bfea4c..67fa51b58 100644 --- a/client/src/emv/tlv.c +++ b/client/src/emv/tlv.c @@ -44,19 +44,6 @@ // const typeof( ((type *)0)->member ) *__mptr = (ptr); // (type *)( (char *)__mptr - offsetof(type,member) );}) -struct tlvdb { - struct tlv tag; - struct tlvdb *next; - struct tlvdb *parent; - struct tlvdb *children; -}; - -struct tlvdb_root { - struct tlvdb db; - size_t len; - unsigned char buf[0]; -}; - static tlv_tag_t tlv_parse_tag(const unsigned char **buf, size_t *len) { tlv_tag_t tag; @@ -212,6 +199,7 @@ struct tlvdb *tlvdb_parse(const unsigned char *buf, size_t len) { err: tlvdb_free(&root->db); + free(root); return NULL; } @@ -248,9 +236,53 @@ struct tlvdb *tlvdb_parse_multi(const unsigned char *buf, size_t len) { err: tlvdb_free(&root->db); + free(root); return NULL; } +bool tlvdb_parse_root(struct tlvdb_root *root) { + if (root == NULL || root->len == 0) { + return false; + } + + const uint8_t *tmp; + size_t left; + + tmp = root->buf; + left = root->len; + if (tlvdb_parse_one(&root->db, NULL, &tmp, &left) == true) { + if (left == 0) { + return true; + } + } + return false; +} + +bool tlvdb_parse_root_multi(struct tlvdb_root *root) { + if (root == NULL || root->len == 0) { + return false; + } + + const uint8_t *tmp; + size_t left; + + tmp = root->buf; + left = root->len; + if (tlvdb_parse_one(&root->db, NULL, &tmp, &left) == true) { + while (left > 0) { + struct tlvdb *db = calloc(1, sizeof(*db)); + if (tlvdb_parse_one(db, NULL, &tmp, &left) == true) { + tlvdb_add(&root->db, db); + } else { + free(db); + return false; + } + } + return true; + } + return false; +} + struct tlvdb *tlvdb_fixed(tlv_tag_t tag, size_t len, const unsigned char *value) { struct tlvdb_root *root = calloc(1, sizeof(*root) + len); @@ -291,6 +323,21 @@ void tlvdb_free(struct tlvdb *tlvdb) { } } +void tlvdb_root_free(struct tlvdb_root *root) { + if (root == NULL) { + return; + } + if (root->db.children) { + tlvdb_free(root->db.children); + root->db.children = NULL; + } + if (root->db.next) { + tlvdb_free(root->db.next); + root->db.next = NULL; + } + free(root); +} + struct tlvdb *tlvdb_find_next(struct tlvdb *tlvdb, tlv_tag_t tag) { if (!tlvdb) return NULL; diff --git a/client/src/emv/tlv.h b/client/src/emv/tlv.h index 50d046659..39f1bcacd 100644 --- a/client/src/emv/tlv.h +++ b/client/src/emv/tlv.h @@ -31,14 +31,31 @@ struct tlv { const unsigned char *value; }; -struct tlvdb; +struct tlvdb { + struct tlv tag; + struct tlvdb *next; + struct tlvdb *parent; + struct tlvdb *children; +}; + +struct tlvdb_root { + struct tlvdb db; + size_t len; + unsigned char buf[0]; +}; + typedef void (*tlv_cb)(void *data, const struct tlv *tlv, int level, bool is_leaf); struct tlvdb *tlvdb_fixed(tlv_tag_t tag, size_t len, const unsigned char *value); struct tlvdb *tlvdb_external(tlv_tag_t tag, size_t len, const unsigned char *value); struct tlvdb *tlvdb_parse(const unsigned char *buf, size_t len); struct tlvdb *tlvdb_parse_multi(const unsigned char *buf, size_t len); + +bool tlvdb_parse_root(struct tlvdb_root *root); +bool tlvdb_parse_root_multi(struct tlvdb_root *root); + void tlvdb_free(struct tlvdb *tlvdb); +void tlvdb_root_free(struct tlvdb_root *root); struct tlvdb *tlvdb_elm_get_next(struct tlvdb *tlvdb); struct tlvdb *tlvdb_elm_get_children(struct tlvdb *tlvdb); From 309603f19b015db91fccb478ae301a47034139d0 Mon Sep 17 00:00:00 2001 From: Yann GASCUEL <34003959+lnv42@users.noreply.github.com> Date: Fri, 6 Jan 2023 15:57:39 +0100 Subject: [PATCH 448/759] Add new Standalone mode LF_PROX2BRUT: HID ProxII brueforce v2 Trivial card number brute forcer for when you know the facility code and want to find valid(s) card number(s). --- armsrc/Standalone/Makefile.hal | 5 +- armsrc/Standalone/Makefile.inc | 4 ++ armsrc/Standalone/lf_prox2brute.c | 108 ++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 armsrc/Standalone/lf_prox2brute.c diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 6b4510da8..3c18e681b 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -56,6 +56,9 @@ define KNOWN_STANDALONE_DEFINITIONS | LF_PROXBRUTE | HID ProxII bruteforce | | | - Brad Antoniewicz | +----------------------------------------------------------+ +| LF_PROX2BRUTE | HID ProxII bruteforce v2 | +| | | ++----------------------------------------------------------+ | LF_SAMYRUN | HID26 read/clone/sim | | (default) | - Samy Kamkar | +----------------------------------------------------------+ @@ -118,7 +121,7 @@ define KNOWN_STANDALONE_DEFINITIONS +----------------------------------------------------------+ endef -STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID +STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI STANDALONE_MODES_REQ_BT := HF_REBLAY STANDALONE_MODES_REQ_SMARTCARD := diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index 05a63f1dd..15218912c 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -29,6 +29,10 @@ endif ifneq (,$(findstring WITH_STANDALONE_LF_PROXBRUTE,$(APP_CFLAGS))) SRC_STANDALONE = lf_proxbrute.c endif +# WITH_STANDALONE_LF_PROX2BRUTE +ifneq (,$(findstring WITH_STANDALONE_LF_PROX2BRUTE,$(APP_CFLAGS))) + SRC_STANDALONE = lf_prox2brute.c +endif # WITH_STANDALONE_LF_HIDBRUTE ifneq (,$(findstring WITH_STANDALONE_LF_HIDBRUTE,$(APP_CFLAGS))) SRC_STANDALONE = lf_hidbrute.c diff --git a/armsrc/Standalone/lf_prox2brute.c b/armsrc/Standalone/lf_prox2brute.c new file mode 100644 index 000000000..0117e91e6 --- /dev/null +++ b/armsrc/Standalone/lf_prox2brute.c @@ -0,0 +1,108 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Brad Antoniewicz 2011 +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// LF HID ProxII Brutforce v2 by lnv42 - based on Proxbrute by Brad antoniewicz +// +// Following code is a trivial brute forcer for when you know the facility +// code and want to find valid(s) card number(s). It will try all card +// fnumbers rom CARDNUM_START to CARDNUM_END one by one (max. ~65k tries). +// This brute force will be a lot faster than Proxbrute that will try all +// possibles values for LF low, even those with bad checksum (~4g tries). +// LEDs will help you know which card number(s) worked. +// +//----------------------------------------------------------------------------- +#include "standalone.h" // standalone definitions +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "util.h" +#include "dbprint.h" +#include "lfops.h" +#include "parity.h" + +#define CARDNUM_START 0 +#define CARDNUM_END 0xFFFF +#define FACILITY_CODE 2 + +void ModInfo(void) { + DbpString(" LF HID ProxII bruteforce v2"); +} + +// samy's sniff and repeat routine for LF +void RunMod(void) { + StandAloneMode(); + Dbprintf(">> LF HID proxII bruteforce v2 a.k.a Prox2Brute Started <<"); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + + const uint32_t high = 0x20; // LF high value is always 0x20 here + uint32_t low = 0; + + uint32_t fac = FACILITY_CODE, cardnum = 0; + + LED_D_ON(); + while (BUTTON_HELD(200) != BUTTON_HOLD) { // Waiting for a 200ms button press + WDT_HIT(); + // exit from SamyRun, send a usbcommand. + if (data_available()) { // early exit + DbpString("[=] You can take the shell back :) ..."); + LEDsoff(); + return; + } + } + + LED_C_ON(); + WAIT_BUTTON_RELEASED(); // We are now ready to start brutforcing card numbers + LEDsoff(); + + Dbprintf("[=] Starting HID ProxII Bruteforce from card %08x to %08x", + CARDNUM_START, MIN(CARDNUM_END, 0xFFFF)); + + for (cardnum = CARDNUM_START ; cardnum <= MIN(CARDNUM_END, 0xFFFF) ; cardnum++) { + WDT_HIT(); + + // exit from SamyRun, send a usbcommand. + if (data_available()) break; + + // short button press may be used for fast-forward + if (BUTTON_HELD(1000) == BUTTON_HOLD) break; // long button press (>=1sec) exit + + // calculate the new LF low value including Card number, Facility code and checksum + low = (cardnum << 1) | (fac << 17); + low |= oddparity32((low >> 1) & 0xFFF); + low |= evenparity32((low >> 13) & 0xFFF) << 25; + + Dbprintf("[=] trying Facility = %08x, Card = %08x, raw = %08x%08x", + fac, cardnum, high, low); + + // Start simulating an HID TAG, with high/low values, no led control and 20000 cycles timeout + CmdHIDsimTAGEx(0, high, low, 0, false, 20000); + + // switch leds to be able to know (aproximatly) which card number worked (64 tries loop) + LED_A_INV(); // switch led A every try + if ((cardnum-CARDNUM_START) % 8 == 7) // switch led B every 8 tries + LED_B_INV(); + if ((cardnum-CARDNUM_START) % 16 == 15) // switch led C every 16 tries + LED_C_INV(); + if ((cardnum-CARDNUM_START) % 32 == 31) // switch led D every 32 tries + LED_D_INV(); + } + + SpinErr((LED_A | LED_B | LED_C | LED_D), 250, 5); // Xmax tree + Dbprintf("[=] Ending HID ProxII Bruteforce from card %08x to %08x", + CARDNUM_START, cardnum - 1); + DbpString("[=] You can take the shell back :) ..."); + LEDsoff(); // This is the end +} From 6e084d82d5c9bda9c1cd6a044dfb9e4bc3ed3800 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 6 Jan 2023 18:19:31 +0100 Subject: [PATCH 449/759] First two PIV commands --- client/CMakeLists.txt | 1 + client/Makefile | 1 + client/src/cmdmain.c | 2 + client/src/cmdpiv.c | 813 ++++++++++++++++++++++++++++++++++++++++++ client/src/cmdpiv.h | 26 ++ 5 files changed, 843 insertions(+) create mode 100644 client/src/cmdpiv.c create mode 100644 client/src/cmdpiv.h diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index a34348413..1622190f9 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -336,6 +336,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdmain.c ${PM3_ROOT}/client/src/cmdnfc.c ${PM3_ROOT}/client/src/cmdparser.c + ${PM3_ROOT}/client/src/cmdpiv.c ${PM3_ROOT}/client/src/cmdscript.c ${PM3_ROOT}/client/src/cmdsmartcard.c ${PM3_ROOT}/client/src/cmdtrace.c diff --git a/client/Makefile b/client/Makefile index 500e820f0..03f022297 100644 --- a/client/Makefile +++ b/client/Makefile @@ -626,6 +626,7 @@ SRCS = mifare/aiddesfire.c \ cmdmain.c \ cmdnfc.c \ cmdparser.c \ + cmdpiv.c \ cmdscript.c \ cmdsmartcard.c \ cmdtrace.c \ diff --git a/client/src/cmdmain.c b/client/src/cmdmain.c index 99fef33d4..14e198f5c 100644 --- a/client/src/cmdmain.c +++ b/client/src/cmdmain.c @@ -39,6 +39,7 @@ #include "cmdanalyse.h" #include "emv/cmdemv.h" // EMV #include "cmdflashmem.h" // rdv40 flashmem commands +#include "cmdpiv.h" #include "cmdsmartcard.h" // rdv40 smart card ISO7816 commands #include "cmdusart.h" // rdv40 FPC USART commands #include "cmdwiegand.h" // wiegand commands @@ -324,6 +325,7 @@ static command_t CommandTable[] = { {"lf", CmdLF, AlwaysAvailable, "{ Low frequency commands... }"}, {"mem", CmdFlashMem, IfPm3Flash, "{ Flash memory manipulation... }"}, {"nfc", CmdNFC, AlwaysAvailable, "{ NFC commands... }"}, + {"piv", CmdPIV, AlwaysAvailable, "{ PIV commands... }"}, {"reveng", CmdRev, AlwaysAvailable, "{ CRC calculations from RevEng software... }"}, {"smart", CmdSmartcard, AlwaysAvailable, "{ Smart card ISO-7816 commands... }"}, {"script", CmdScript, AlwaysAvailable, "{ Scripting commands... }"}, diff --git a/client/src/cmdpiv.c b/client/src/cmdpiv.c new file mode 100644 index 000000000..9e800055a --- /dev/null +++ b/client/src/cmdpiv.c @@ -0,0 +1,813 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// PIV commands +//----------------------------------------------------------------------------- + +#include "cmdpiv.h" + +#include "comms.h" // DropField +#include "cmdsmartcard.h" // smart_select +#include "cmdtrace.h" +#include "cliparser.h" +#include "cmdparser.h" +#include "commonutil.h" // Mem[LB]eToUintXByte +#include "emv/tlv.h" +#include "proxmark3.h" +#include "cmdhf14a.h" +#include "fileutils.h" +#include "crypto/asn1utils.h" + +static int CmdHelp(const char *Cmd); + +static const uint16_t APDU_RES_SUCCESS = 0x9000; +static const uint16_t APDU_RES_NOT_FOUND = 0x6A82; +static const uint16_t APDU_RES_SECURITY = 0x6982; +static const uint16_t APDU_RES_PIN_BLOCKED = 0x6983; + +static uint8_t PIV_APPLET[9] = "\xA0\x00\x00\x03\x08\x00\x00\x10\x00"; + +enum piv_condition_t { + PIV_MANDATORY, + PIV_CONDITIONAL, + PIV_OPTIONAL, + PIV_INVALID = 0xff, +}; + +struct piv_container { + uint32_t id; + const uint8_t *tlv_tag; // tag is between 1 and 3 bytes. + size_t len; // length of the hex-form if the tag (i.e. twice the byte size) for pretty printing + enum piv_condition_t cond; + const char *name; +}; + +#define PIV_TAG_ID(x) ((const uint8_t *)(x)) +#define PIV_CONTAINER_FINISH { (~0), NULL, 0, PIV_INVALID, NULL } + +// Source: SP800-73-4, Annex A +// https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-73-4.pdf +static const struct piv_container PIV_CONTAINERS[] = { + {0xDB00, PIV_TAG_ID("\x5F\xC1\x07"), 3, PIV_MANDATORY, "Card Capability Container"}, + {0x3000, PIV_TAG_ID("\x5F\xC1\x02"), 3, PIV_MANDATORY, "Card Holder Unique Identifier"}, + {0x0101, PIV_TAG_ID("\x5F\xC1\x05"), 3, PIV_MANDATORY, "X.509 Certificate for PIV Authentication (key ref 9A)"}, + {0x6010, PIV_TAG_ID("\x5F\xC1\x03"), 3, PIV_MANDATORY, "Cardholder Fingerprints"}, + {0x9000, PIV_TAG_ID("\x5F\xC1\x06"), 3, PIV_MANDATORY, "Security Object"}, + {0x6030, PIV_TAG_ID("\x5F\xC1\x08"), 3, PIV_MANDATORY, "Cardholder Facial Image"}, + {0x0500, PIV_TAG_ID("\x5F\xC1\x01"), 3, PIV_MANDATORY, "X.509 Certificate for Card Authentication (key ref 9E)"}, + {0x0100, PIV_TAG_ID("\x5F\xC1\x0A"), 3, PIV_CONDITIONAL, "X.509 Certificate for Digital Signature (key ref 9C)"}, + {0x0102, PIV_TAG_ID("\x5F\xC1\x0B"), 3, PIV_CONDITIONAL, "X.509 Certificate for Key Management (key ref 9D)"}, + {0x3001, PIV_TAG_ID("\x5F\xC1\x09"), 3, PIV_OPTIONAL, "Printed Information"}, + {0x6050, PIV_TAG_ID( "\x7E"), 1, PIV_OPTIONAL, "Discovery Object"}, + {0x6060, PIV_TAG_ID("\x5F\xC1\x0C"), 3, PIV_OPTIONAL, "Key History Object"}, + {0x1001, PIV_TAG_ID("\x5F\xC1\x0D"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 1 (key ref 82)"}, + {0x1002, PIV_TAG_ID("\x5F\xC1\x0E"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 2 (key ref 83)"}, + {0x1003, PIV_TAG_ID("\x5F\xC1\x0F"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 3 (key ref 84)"}, + {0x1004, PIV_TAG_ID("\x5F\xC1\x10"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 4 (key ref 85)"}, + {0x1005, PIV_TAG_ID("\x5F\xC1\x11"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 5 (key ref 86)"}, + {0x1006, PIV_TAG_ID("\x5F\xC1\x12"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 6 (key ref 87)"}, + {0x1007, PIV_TAG_ID("\x5F\xC1\x13"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 7 (key ref 88)"}, + {0x1008, PIV_TAG_ID("\x5F\xC1\x14"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 8 (key ref 89)"}, + {0x1009, PIV_TAG_ID("\x5F\xC1\x15"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 9 (key ref 8A)"}, + {0x100A, PIV_TAG_ID("\x5F\xC1\x16"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 10 (key ref 8B)"}, + {0x100B, PIV_TAG_ID("\x5F\xC1\x17"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 11 (key ref 8C)"}, + {0x100C, PIV_TAG_ID("\x5F\xC1\x18"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 12 (key ref 8D)"}, + {0x100D, PIV_TAG_ID("\x5F\xC1\x19"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 13 (key ref 8E)"}, + {0x100E, PIV_TAG_ID("\x5F\xC1\x1A"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 14 (key ref 8F)"}, + {0x100F, PIV_TAG_ID("\x5F\xC1\x1B"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 15 (key ref 90)"}, + {0x1010, PIV_TAG_ID("\x5F\xC1\x1C"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 16 (key ref 91)"}, + {0x1011, PIV_TAG_ID("\x5F\xC1\x1D"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 17 (key ref 92)"}, + {0x1012, PIV_TAG_ID("\x5F\xC1\x1E"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 18 (key ref 93)"}, + {0x1013, PIV_TAG_ID("\x5F\xC1\x1F"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 19 (key ref 94)"}, + {0x1014, PIV_TAG_ID("\x5F\xC1\x20"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 20 (key ref 95)"}, + {0x1015, PIV_TAG_ID("\x5F\xC1\x21"), 3, PIV_OPTIONAL, "Cardholder Iris Images"}, + {0x1016, PIV_TAG_ID( "\x7F\x61"), 2, PIV_OPTIONAL, "Biometric Information Templates Group Template"}, + {0x1017, PIV_TAG_ID("\x5F\xC1\x22"), 3, PIV_OPTIONAL, "Secure Messaging Certificate Signer"}, + {0x1018, PIV_TAG_ID("\x5F\xC1\x23"), 3, PIV_OPTIONAL, "Pairing Code Reference Data Container"}, + PIV_CONTAINER_FINISH, +}; + +enum piv_tag_t { + PIV_TAG_GENERIC, + PIV_TAG_HEXDUMP, + PIV_TAG_STRING, + PIV_TAG_PRINTSTR, + PIV_TAG_NUMERIC, + PIV_TAG_YYYYMMDD, + PIV_TAG_ENUM, + PIV_TAG_TLV, + PIV_TAG_GUID, + PIV_TAG_CERT, + PIV_TAG_FASCN, +}; + +struct piv_tag { + tlv_tag_t tag; + const char *name; + enum piv_tag_t type; + const void *data; +}; + +struct piv_tag_enum { + unsigned long value; + const char *name; +}; + +#define PIV_ENUM_FINISH { (~0), NULL } + +// From table 6-2 in SP800-78 specification +static const struct piv_tag_enum PIV_CRYPTO_ALG[] = { + {0x00, "3 Key 3DES - ECB"}, + {0x03, "3 Key 3DES - ECB"}, // Not a typo, 2 identifiers for the same algorithm + {0x06, "RSA 1024 bit"}, + {0x07, "RSA 2048 bit"}, + {0x08, "AES-128 ECB"}, + {0x0A, "AES-192 ECB"}, + {0x0C, "AES-256 ECB"}, + {0x11, "ECC P-256"}, + {0x14, "ECC P-384"}, + {0x27, "Cipher Suite 2"}, + {0x2E, "Cipher Suite 7"}, + PIV_ENUM_FINISH, +}; + +static const struct piv_tag_enum PIV_CERT_INFO[] = { + {0x00, "Uncompressed"}, + {0x01, "GZIP Compressed"}, + PIV_ENUM_FINISH, +}; + +static const struct piv_tag piv_tags[] = { + { 0x00, "Unknown ???", PIV_TAG_HEXDUMP, NULL }, + { 0x01, "Name", PIV_TAG_PRINTSTR, NULL }, + { 0x02, "Employee Affiliation", PIV_TAG_PRINTSTR, NULL }, + { 0x04, "Expiry Date", PIV_TAG_PRINTSTR, NULL }, + { 0x05, "Agency Card Serial Number", PIV_TAG_PRINTSTR, NULL }, + { 0x06, "Issuer identification", PIV_TAG_PRINTSTR, NULL }, + { 0x07, "Organization Affiliation (Line 1)", PIV_TAG_PRINTSTR, NULL }, + { 0x08, "Organization Affiliation (Line 2)", PIV_TAG_PRINTSTR, NULL }, + + { 0x30, "FASC-N", PIV_TAG_FASCN, NULL }, + { 0x32, "Organizational Identifier [deprecated]", PIV_TAG_HEXDUMP, NULL }, + { 0x33, "DUNS [deprecated]", PIV_TAG_HEXDUMP, NULL }, + { 0x34, "GUID", PIV_TAG_GUID, NULL }, + { 0x35, "Expiry Date", PIV_TAG_YYYYMMDD, NULL }, + { 0x36, "Cardholder UUID", PIV_TAG_GUID, NULL }, + { 0x3d, "Authentication Key Map", PIV_TAG_HEXDUMP, NULL }, + { 0x3e, "Issuer Asymmetric Signature", PIV_TAG_CERT, NULL }, + + { 0x4f, "Application Identifier (AID)", PIV_TAG_STRING, NULL }, + + { 0x50, "Application Label", PIV_TAG_PRINTSTR, NULL }, + { 0x53, "Discretionary data (or template)", PIV_TAG_TLV, NULL }, + { 0x5f2f, "PIN Usage Policy", PIV_TAG_HEXDUMP, NULL }, + { 0x5f50, "Issuer URL", PIV_TAG_PRINTSTR, NULL }, + + { 0x61, "Application Property Template", PIV_TAG_GENERIC, NULL }, + + { 0x70, "Certificate", PIV_TAG_CERT, NULL }, + { 0x71, "CertInfo", PIV_TAG_ENUM, PIV_CERT_INFO }, + { 0x72, "MSCUID [deprecated]", PIV_TAG_HEXDUMP, NULL }, + { 0x79, "Coexistent tag allocation authority", PIV_TAG_HEXDUMP, NULL }, + { 0x7f21, "Intermediate CVC", PIV_TAG_HEXDUMP, NULL }, + { 0x7f60, "Biometric Information Template", PIV_TAG_GENERIC, NULL }, + + { 0x80, "Cryptographic algorithm identifier", PIV_TAG_ENUM, PIV_CRYPTO_ALG }, + + { 0x99, "Pairing Code", PIV_TAG_PRINTSTR, NULL }, + + { 0xac, "Cryptographic algorithms supported", PIV_TAG_GENERIC, NULL }, + + { 0xb4, "Security Object Buffer (deprecated)", PIV_TAG_GENERIC, NULL }, + { 0xba, "Mapping of DG to Container ID", PIV_TAG_HEXDUMP, NULL }, + { 0xbb, "Security Object", PIV_TAG_CERT, NULL }, + { 0xbc, "Fingerprint I & II or Image for Visual Verification", PIV_TAG_GENERIC, NULL }, + + { 0xc1, "keysWithOnCardCerts", PIV_TAG_NUMERIC, NULL }, + { 0xc2, "keysWithOffCardCerts", PIV_TAG_NUMERIC, NULL }, + + { 0xe3, "Extended Application CardURL [deprecated]", PIV_TAG_GENERIC, NULL }, + { 0xee, "Buffer Length [deprecated]", PIV_TAG_NUMERIC, NULL }, + + { 0xf0, "Card Identifier", PIV_TAG_STRING, NULL }, + { 0xf1, "Capability Container version number", PIV_TAG_NUMERIC, NULL }, + { 0xf2, "Capability Grammar version number", PIV_TAG_NUMERIC, NULL }, + { 0xf3, "Application Card URL", PIV_TAG_PRINTSTR, NULL }, + { 0xf4, "PKCS#15", PIV_TAG_NUMERIC, NULL }, + { 0xf5, "Registered Data Model Number", PIV_TAG_NUMERIC, NULL }, + { 0xf6, "Access Control Rule Table", PIV_TAG_HEXDUMP, NULL }, + { 0xf7, "Card APDUs", PIV_TAG_GENERIC, NULL }, + { 0xfa, "Redirection Tag", PIV_TAG_GENERIC, NULL }, + { 0xfb, "Capability Tuples (CT)", PIV_TAG_GENERIC, NULL }, + { 0xfc, "Status Tuples (ST)", PIV_TAG_GENERIC, NULL }, + { 0xfd, "Next CCC", PIV_TAG_GENERIC, NULL }, + { 0xfe, "Error Detection Code", PIV_TAG_GENERIC, NULL }, +}; + +struct guid { + uint32_t part1; + uint16_t part2; + uint16_t part3; + uint8_t data[8]; +}; + +static void parse_guid(const uint8_t *data, struct guid *guid) { + if (guid == NULL) { + return; + } + size_t ofs = 0; + guid->part1 = MemBeToUint4byte(&data[ofs]); + ofs += sizeof(uint32_t); + guid->part2 = MemBeToUint2byte(&data[ofs]); + ofs += sizeof(uint16_t); + guid->part3 = MemBeToUint2byte(&data[ofs]); + ofs += sizeof(uint16_t); + for (size_t i = 0; i < sizeof(guid->data); i++) { + guid->data[i] = data[ofs + i]; + } +} + +static void piv_print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf); +static bool piv_tag_dump(const struct tlv *tlv, int level); + +static void PrintChannel(Iso7816CommandChannel channel) { + switch (channel) { + case CC_CONTACTLESS: + PrintAndLogEx(INFO, "Selected channel... " _GREEN_("CONTACTLESS (T=CL)")); + break; + case CC_CONTACT: + PrintAndLogEx(INFO, "Selected channel... " _GREEN_("CONTACT")); + break; + } +} + +static int piv_sort_tag(tlv_tag_t tag) { + return (int)(tag >= 0x100 ? tag : tag << 8); +} + +static int piv_tlv_compare(const void *a, const void *b) { + const struct tlv *tlv = a; + const struct piv_tag *tag = b; + + return piv_sort_tag(tlv->tag) - (piv_sort_tag(tag->tag)); +} + +static const struct piv_tag *piv_get_tag(const struct tlv *tlv) { + const struct piv_tag *tag = bsearch(tlv, piv_tags, ARRAYLEN(piv_tags), + sizeof(piv_tags[0]), piv_tlv_compare); + return tag != NULL ? tag : &piv_tags[0]; +} + +static unsigned long piv_value_numeric(const struct tlv *tlv, unsigned start, unsigned end) { + unsigned long ret = 0; + int i; + + if (end > tlv->len * 2) + return ret; + if (start >= end) + return ret; + + if (start & 1) { + ret += tlv->value[start / 2] & 0xf; + i = start + 1; + } else + i = start; + + for (; i < end - 1; i += 2) { + ret *= 10; + ret += tlv->value[i / 2] >> 4; + ret *= 10; + ret += tlv->value[i / 2] & 0xf; + } + + if (end & 1) { + ret *= 10; + ret += tlv->value[end / 2] >> 4; + } + + return ret; +} + +static void piv_tag_dump_yyyymmdd(const struct tlv *tlv, const struct piv_tag *tag, int level) { + bool is_printable = true; + for (size_t i = 0; i < tlv->len; i++) { + if ((tlv->value[i] < 0x30) || (tlv->value[i] > 0x39)) { + is_printable = false; + break; + } + } + if (is_printable) { + PrintAndLogEx(NORMAL, " " _YELLOW_("%c%c%c%c.%c%c.%c%c"), + tlv->value[0], tlv->value[1], tlv->value[2], tlv->value[3], + tlv->value[4], tlv->value[5], + tlv->value[6], tlv->value[7] + ); + } else { + PrintAndLogEx(NORMAL, " " _YELLOW_("%04lu.%02lu.%02lu"), + piv_value_numeric(tlv, 0, 4), + piv_value_numeric(tlv, 4, 6), + piv_value_numeric(tlv, 6, 8) + ); + } +} + +static void piv_tag_dump_enum(const struct tlv *tlv, const struct piv_tag *tag, int level) { + const struct piv_tag_enum *values = tag->data; + for (size_t i = 0; values[i].name != NULL; i++) { + if (values[i].value == tlv->value[0]) { + PrintAndLogEx(NORMAL, " %u - '" _YELLOW_("%s")"'", + tlv->value[0], values[i].name); + return; + } + } + PrintAndLogEx(NORMAL, " %u - " _RED_("Unknown??"), tlv->value[0]); +} + +static void piv_tag_dump_tlv(const struct tlv *tlv, const struct piv_tag *tag, int level) { + // We don't use parsing methods because we need to discard constructed tags + const unsigned char *buf = tlv->value; + size_t left = tlv->len; + + while (left) { + struct tlv sub_tlv; + //const struct piv_tag *sub_tag; + + if (!tlv_parse_tl(&buf, &left, &sub_tlv)) { + PrintAndLogEx(INFO, "%*sInvalid Tag-Len", (level * 4), " "); + continue; + } + sub_tlv.value = buf; + piv_tag_dump(&sub_tlv, level + 1); + buf += sub_tlv.len; + left -= sub_tlv.len; + } + +} + +static void piv_print_cert(const uint8_t *buf, const size_t len, int level) { + char prefix[256] = {0}; + PrintAndLogEx(NORMAL, ""); + snprintf(prefix, sizeof(prefix), "%*s", 4 * level, " "); + // TODO: when mbedTLS has a new release with the PCKS7 parser, we can replace the generic ASN.1 print + // The pull request has been merged end of Nov 2022. + asn1_print((uint8_t *) buf, len, prefix); +} + +static void piv_print_fascn(const uint8_t *buf, const size_t len, int level) { + const char *encoded[32] = { + _RED_("?"), // 0b00000 + "0", // 0b00001 + "8", // 0b00010 + _RED_("?"), // 0b00011 + "4", // 0b00100 + _RED_("?"), // 0b00101 + _RED_("?"), // 0b00110 + _RED_("?"), // 0b00111 + "2", // 0b01000 + _RED_("?"), // 0b01001 + _RED_("?"), // 0b01010 + _RED_("?"), // 0b01011 + _RED_("?"), // 0b01100 + "6", // 0b01101 + _RED_("?"), // 0b01110 + _RED_("?"), // 0b01111 + "1", // 0b10000 + _RED_("?"), // 0b10001 + _RED_("?"), // 0b10010 + "9", // 0b10011 + _RED_("?"), // 0b10100 + "5", // 0b10101 + _GREEN_(" FS "), // 0b10110 + _RED_("?"), // 0b10111 + _RED_("?"), // 0b11000 + "3", // 0b11001 + _YELLOW_("SS "), // 0b11010 + _RED_("?"), // 0b11011 + "7", // 0b11100 + _RED_("?"), // 0b11101 + _RED_("?"), // 0b11110 + _YELLOW_(" ES"), // 0b11111 + }; + const uint8_t cycle[8] = {5, 2, 7, 4, 1, 6, 3, 8}; + + PrintAndLogEx(INFO, "%*s" NOLF, 4 * level, " "); + // Buffer is 40 bytes but last byte is LRC that we process separately + for (int i = 0; i < 39; i++) { + uint8_t tmp = buf[(5 * i) >> 3]; + uint8_t rot = cycle[i & 7]; + // rotate left to get the bits in place + tmp = (tmp << rot) | (tmp >> (8 - rot)); + // append bits from next byte if needed + if (rot < 5) { + uint8_t tmp2 = buf[(5 * (i + 1)) >> 3]; + tmp2 = (tmp2 << rot) | (tmp2 >> (8 - rot)); + tmp &= 0x1f << rot; + tmp |= tmp2 & ((1 << rot) - 1); + } + PrintAndLogEx(NORMAL, "%s" NOLF, encoded[tmp & 0x1f]); + } + uint8_t lrc = buf[24] & 0x1f; + PrintAndLogEx(NORMAL, " LRC=[" _YELLOW_("%02x") "]", lrc); +} + +static bool piv_tag_dump(const struct tlv *tlv, int level) { + if (tlv == NULL) { + PrintAndLogEx(FAILED, "NULL"); + return false; + } + + const struct piv_tag *tag = piv_get_tag(tlv); + + PrintAndLogEx(INFO, "%*s--%2x[%02zx] '%s':" NOLF, (level * 4), " ", tlv->tag, tlv->len, tag->name); + + switch (tag->type) { + case PIV_TAG_GENERIC: + PrintAndLogEx(NORMAL, ""); + break; + case PIV_TAG_HEXDUMP: + PrintAndLogEx(NORMAL, ""); + print_buffer(tlv->value, tlv->len, level + 1); + break; + case PIV_TAG_STRING: + PrintAndLogEx(NORMAL, " '" _YELLOW_("%s")"'", sprint_hex_inrow(tlv->value, tlv->len)); + break; + case PIV_TAG_NUMERIC: + PrintAndLogEx(NORMAL, " " _YELLOW_("%lu"), piv_value_numeric(tlv, 0, tlv->len * 2)); + break; + case PIV_TAG_YYYYMMDD: + piv_tag_dump_yyyymmdd(tlv, tag, level); + break; + case PIV_TAG_ENUM: + piv_tag_dump_enum(tlv, tag, level + 1); + break; + case PIV_TAG_TLV: + PrintAndLogEx(NORMAL, ""); + piv_tag_dump_tlv(tlv, tag, level); + break; + case PIV_TAG_PRINTSTR: + PrintAndLogEx(NORMAL, " '" NOLF); + for (size_t i = 0; i < tlv->len; i++) { + PrintAndLogEx(NORMAL, _YELLOW_("%c") NOLF, tlv->value[i]); + } + PrintAndLogEx(NORMAL, "'"); + break; + case PIV_TAG_GUID: + if (tlv->len != 16) { + PrintAndLogEx(NORMAL, _RED_("")); + } else { + struct guid guid = {0}; + parse_guid(tlv->value, &guid); + PrintAndLogEx(NORMAL, " " _YELLOW_("{%08x-%04x-%04x-") NOLF, guid.part1, guid.part2, guid.part3); + for (size_t i = 0; i < 8; i++) { + PrintAndLogEx(NORMAL, _YELLOW_("%02x") NOLF, guid.data[i]); + } + PrintAndLogEx(NORMAL, _YELLOW_("}")); + } + break; + case PIV_TAG_CERT: + piv_print_cert(tlv->value, tlv->len, level + 2); + break; + case PIV_TAG_FASCN: + PrintAndLogEx(NORMAL, " '" _YELLOW_("%s")"'", sprint_hex_inrow(tlv->value, tlv->len)); + if (tlv->len == 25) { + piv_print_fascn(tlv->value, tlv->len, level + 2); + } + break; + }; + + return true; +} + +static void piv_print_cb(void *data, const struct tlv *tlv, int level, bool is_leaf) { + piv_tag_dump(tlv, level); + if (is_leaf) { + print_buffer(tlv->value, tlv->len, level); + } +} + +static void PrintTLV(const struct tlvdb* tlvdb) { + if (tlvdb) { + tlvdb_visit(tlvdb, piv_print_cb, NULL, 0); + } +} + +static void PrintTLVFromBuffer(const uint8_t* buf, size_t len) { + if (buf == NULL || len == 0) { + return; + } + struct tlvdb_root *root = calloc(1, sizeof(*root) + len); + if (root == NULL) { + return; + } + root->len = len; + memcpy(root->buf, buf, len); + if (tlvdb_parse_root_multi(root) == true) { + PrintTLV(&(root->db)); + } else { + PrintAndLogEx(WARNING, "TLV ERROR: Can't parse buffer as TLV tree."); + } + tlvdb_root_free(root); +} + +static int PivGetData(Iso7816CommandChannel channel, const uint8_t tag[], size_t tag_len, bool verbose, struct tlvdb_root **result, uint16_t *sw) { + uint8_t apdu_data[5] = {0x5c, 0x00}; + + *result = NULL; + *sw = 0; + + if (tag_len < 1 || tag_len > 3) { + return PM3_EINVARG; + } + + apdu_data[1] = tag_len; + memcpy(&apdu_data[2], tag, tag_len); + + sAPDU_t apdu = { + .CLA = 0x00, + .INS = 0xCB, + .P1 = 0x3F, + .P2 = 0xFF, + .Lc = tag_len + 2, + .data = apdu_data + }; + + // Answer can be chained. Let's use a dynamically allocated buffer. + size_t capacity = PM3_CMD_DATA_SIZE; + struct tlvdb_root *root = calloc(1, sizeof(*root) + capacity); + + if (root == NULL) { + return PM3_EMALLOC; + } + root->len = 0; + + size_t more_data = 0; + do { + size_t received = 0; + int res = Iso7816ExchangeEx(channel, false, true, apdu, (more_data != 0), more_data, &(root->buf[root->len]), capacity - root->len, &received, sw); + if (res != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Sending APDU failed with code %d", res); + free(root); + return res; + } + root->len += received; + if (((*sw) & 0xff00) == 0x6100) { + // More data + more_data = (*sw) & 0xff; + if (more_data == 0x00 || more_data > MAX_APDU_SIZE) { + more_data = MAX_APDU_SIZE; + } + apdu.CLA = 0x00; + apdu.INS = 0xC0; + apdu.P1 = 0x00; + apdu.P2 = 0x00; + apdu.Lc = 0; + apdu.data = NULL; + if ((capacity - root->len) < PM3_CMD_DATA_SIZE) { + PrintAndLogEx(DEBUG, "Adding more capacity to buffer..."); + capacity += PM3_CMD_DATA_SIZE; + struct tlvdb_root *new_root = realloc(root, sizeof(*root) + capacity); + if (new_root == NULL) { + PrintAndLogEx(FAILED, "Running out of memory while re-allocating buffer"); + free(root); + return PM3_EMALLOC; + } + root = new_root; + } + } + if ((*sw) == APDU_RES_SUCCESS) { + more_data = 0; + } + } while (more_data > 0); + + // Now we can try parse the TLV and return it + *result = root; + if (*sw == APDU_RES_SUCCESS && tlvdb_parse_root(root) == true) { + return PM3_SUCCESS; + } + if (verbose == true) { + PrintAndLogEx(WARNING, "Couldn't parse TLV answer."); + } + return PM3_SUCCESS; +} + +static int PivGetDataByCidAndPrint(Iso7816CommandChannel channel, const struct piv_container* cid, bool decodeTLV, bool verbose) { + struct tlvdb_root *root = NULL; + + if (cid == NULL) { + return PM3_SUCCESS; + } + + PrintAndLogEx(INFO, "Getting %s [" _GREEN_("%s") "]", cid->name, sprint_hex_inrow(cid->tlv_tag, cid->len)); + + uint16_t sw = 0; + + if (PivGetData(channel, cid->tlv_tag, cid->len, verbose, &root, &sw) == PM3_SUCCESS) { + switch (sw) { + case APDU_RES_SUCCESS: + if (decodeTLV == true) { + PrintTLV(&(root->db)); + } else { + print_buffer(root->buf, root->len, 0); + } + break; + case APDU_RES_NOT_FOUND: + PrintAndLogEx(FAILED, "Container not found."); + break; + case APDU_RES_SECURITY: + PrintAndLogEx(WARNING, "Security conditions not met."); + break; + default: + if (verbose == true) { + PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); + } + break; + } + tlvdb_root_free(root); + } + return PM3_SUCCESS; +} + +static int PivGetDataByTagAndPrint(Iso7816CommandChannel channel, const uint8_t tag[], size_t tag_len, bool decodeTLV, bool verbose) { + int idx = 0; + + for (; PIV_CONTAINERS[idx].len != 0; idx++) { + if ((tag_len == PIV_CONTAINERS[idx].len) && (memcmp(tag, PIV_CONTAINERS[idx].tlv_tag, tag_len) == 0)) { + break; + } + } + if (PIV_CONTAINERS[idx].len == 0) { + struct piv_container cid = {0x00, tag, tag_len, PIV_OPTIONAL, "Getting unknown contained ID"}; + return PivGetDataByCidAndPrint(channel, &cid, decodeTLV, verbose); + } + return PivGetDataByCidAndPrint(channel, &(PIV_CONTAINERS[idx]), decodeTLV, verbose); +} + +static int PivSelect(Iso7816CommandChannel channel, bool activateField, bool leaveFieldOn, bool decodeTLV, bool silent, uint8_t applet[], size_t appletLen) { + uint8_t buf[APDU_RES_LEN] = {0}; + size_t len = 0; + uint16_t sw = 0; + + int res = Iso7816Select(channel, activateField, leaveFieldOn, applet, appletLen, buf, sizeof(buf), &len, &sw); + if ((sw != 0) && (silent == false)) { + PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); + } + if (res != PM3_SUCCESS || sw != APDU_RES_SUCCESS) { + PrintAndLogEx(FAILED, "Applet selection failed. Card is not a PIV card."); + return res; + } + if (silent == false) { + if (decodeTLV == true) { + PrintTLVFromBuffer(buf, len); + } else { + print_buffer(buf, len, 0); + } + } + return PM3_SUCCESS; +} + +static int CmdPIVSelect(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "piv select", + "Executes select applet command", + "piv select -s -> select card, select applet\n" + "piv select -st --aid a00000030800001000 -> select card, select applet a00000030800001000, show result in TLV\n"); + + void *argtable[] = { + arg_param_begin, + arg_lit0("sS", "select", "Activate field and select applet"), + arg_lit0("kK", "keep", "Keep field for next command"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), + arg_lit0("tT", "tlv", "TLV decode results"), + arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), + arg_str0(NULL, "aid", "", "Applet ID to select. By default A0000003080000100 will be used"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + bool activateField = arg_get_lit(ctx, 1); + bool leaveSignalON = arg_get_lit(ctx, 2); + bool APDULogging = arg_get_lit(ctx, 3); + bool decodeTLV = arg_get_lit(ctx, 4); + Iso7816CommandChannel channel = CC_CONTACTLESS; + if (arg_get_lit(ctx, 5)) + channel = CC_CONTACT; + PrintChannel(channel); + + uint8_t applet_id[APDU_AID_LEN] = {0}; + int aid_len = 0; + CLIGetHexWithReturn(ctx, 6, applet_id, &aid_len); + if (aid_len == 0) { + memcpy(applet_id, PIV_APPLET, sizeof(PIV_APPLET)); + aid_len = sizeof(PIV_APPLET); + } + + CLIParserFree(ctx); + + SetAPDULogging(APDULogging); + + return PivSelect(channel, activateField, leaveSignalON, decodeTLV, false, applet_id, aid_len); +} + +static int CmdPIVGetData(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "piv getdata", + "Get a data container of a given tag", + "piv getdata -s 5fc102 -> select card, select applet, get card holder unique identifer\n" + "piv getdata -st 5fc102 -> select card, select applet, get card holder unique identifer, show result in TLV\n"); + + void *argtable[] = { + arg_param_begin, + arg_lit0("sS", "select", "Activate field and select applet"), + arg_lit0("kK", "keep", "Keep field for next command"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), + arg_lit0("tT", "tlv", "TLV decode results"), + arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), + arg_str0(NULL, "aid", "", "Applet ID to select. By default A0000003080000100 will be used"), + arg_str1(NULL, NULL, "", "Tag ID to read, between 1 and 3 bytes."), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + bool activateField = arg_get_lit(ctx, 1); + bool leaveSignalON = arg_get_lit(ctx, 2); + bool APDULogging = arg_get_lit(ctx, 3); + bool decodeTLV = arg_get_lit(ctx, 4); + Iso7816CommandChannel channel = CC_CONTACTLESS; + if (arg_get_lit(ctx, 5)) + channel = CC_CONTACT; + PrintChannel(channel); + + uint8_t applet_id[APDU_AID_LEN] = {0}; + int aid_len = 0; + CLIGetHexWithReturn(ctx, 6, applet_id, &aid_len); + if (aid_len == 0) { + memcpy(applet_id, PIV_APPLET, sizeof(PIV_APPLET)); + aid_len = sizeof(PIV_APPLET); + } + + uint8_t tag[4] = {0}; + int tag_len = 0; + CLIGetHexWithReturn(ctx, 7, tag, &tag_len); + + CLIParserFree(ctx); + + if ((tag_len < 1) || (tag_len > 3)) { + PrintAndLogEx(WARNING, "Tag should be between 1 and 3 bytes. Got %i", tag_len); + return PM3_EINVARG; + } + + SetAPDULogging(APDULogging); + + int res = 0; + if (activateField == true) { + res = PivSelect(channel, activateField, true, decodeTLV, true, applet_id, aid_len); + if (res != PM3_SUCCESS) { + if (leaveSignalON == false) { + DropFieldEx(channel); + } + return res; + } + } + res = PivGetDataByTagAndPrint(channel, tag, tag_len, decodeTLV, false); + if (leaveSignalON == false) { + DropFieldEx(channel); + } + return res; +} + +static int CmdPIVList(const char *Cmd) { + return CmdTraceListAlias(Cmd, "piv", "7816"); +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"select", CmdPIVSelect, IfPm3Iso14443, "Select the PIV applet"}, + {"getdata", CmdPIVGetData, IfPm3Iso14443, "Gets a container on a PIV card"}, + + {"list", CmdPIVList, AlwaysAvailable, "List ISO7816 history"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdPIV(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} + diff --git a/client/src/cmdpiv.h b/client/src/cmdpiv.h new file mode 100644 index 000000000..13b5fffe9 --- /dev/null +++ b/client/src/cmdpiv.h @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// PIV commands +//----------------------------------------------------------------------------- + +#ifndef CMDPIV_H__ +#define CMDPIV_H__ + +#include "common.h" + +int CmdPIV(const char *Cmd); + +#endif From 663fd4efc9696904b3ebe70d2b9dc7c5444a942b Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 6 Jan 2023 18:28:53 +0100 Subject: [PATCH 450/759] Remove unused error code. Will be added back for the PIN check command --- client/src/cmdpiv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/cmdpiv.c b/client/src/cmdpiv.c index 9e800055a..cd0af5ba9 100644 --- a/client/src/cmdpiv.c +++ b/client/src/cmdpiv.c @@ -35,7 +35,6 @@ static int CmdHelp(const char *Cmd); static const uint16_t APDU_RES_SUCCESS = 0x9000; static const uint16_t APDU_RES_NOT_FOUND = 0x6A82; static const uint16_t APDU_RES_SECURITY = 0x6982; -static const uint16_t APDU_RES_PIN_BLOCKED = 0x6983; static uint8_t PIV_APPLET[9] = "\xA0\x00\x00\x03\x08\x00\x00\x10\x00"; From e9d461947e876ce7716d71e971dfe0f72c8fca9b Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 6 Jan 2023 18:31:12 +0100 Subject: [PATCH 451/759] Add changelog and fix my github handle --- CHANGELOG.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2875edde..5192c890d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,17 +3,18 @@ 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] + - Add support for PIV commands, over wired and contactless interfaces (@jmichelp) - Add `--shallow` option to `hf iclass` reader commands to do shallow (ASK) reader modulation instead of OOK (@nvx) - Improved NXP SLI/SLIX series tag identification (@nvx) - Fixed buffer overflow in "lf em 4x05 sniff" (@HeinrichsH) - - Fixed potential NULL array printing (@jmichel) - - Added PIV aid to resource file (@jmichel) - - Fixed failing compilation on Proxspace environment due to how python is initialized (@jmichel) - - Fixed length check in sim module communications (@jmichel) + - Fixed potential NULL array printing (@jmichelp) + - Added PIV aid to resource file (@jmichelp) + - Fixed failing compilation on Proxspace environment due to how python is initialized (@jmichelp) + - Fixed length check in sim module communications (@jmichelp) - Changed timings in i2c.c when communicating with sim module (@iceman1001) - - Moved to non-deprecated API to initialize Python interpreter (@jmichel) + - Moved to non-deprecated API to initialize Python interpreter (@jmichelp) - Changed `sc upgrade` updated firmware v4.13 (RDV40) - frame buffer is now 384 bytes (@sentiprox) - - Fixed contact interface / smartcard APDU chaining logic and allow 256 bytes ADPU payload. Need SIM firmware 4.13 to work (@jmichel) + - Fixed contact interface / smartcard APDU chaining logic and allow 256 bytes ADPU payload. Need SIM firmware 4.13 to work (@jmichelp) - Fixed `lf hitag dump` - Should now work as described in the command help (@natmchugh) - Fixed SPI flash overflow when loading dictionnaries into flash. Breaking change: added 1 more sector for Mifare - dictionnaries should be loaded again (@jmichelp) - Added `hf mf gload, gsave, ggetblk, gsetblk` for Gen4 GTU in mifare classic mode (@DidierA) From efc685864ad2bfe59dff21b122ba3ede6ccef53f Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 6 Jan 2023 21:23:22 +0100 Subject: [PATCH 452/759] Add PIV command to scan all data containers on a PIV card. --- client/src/cmdpiv.c | 65 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/client/src/cmdpiv.c b/client/src/cmdpiv.c index cd0af5ba9..7295269d2 100644 --- a/client/src/cmdpiv.c +++ b/client/src/cmdpiv.c @@ -786,6 +786,70 @@ static int CmdPIVGetData(const char *Cmd) { return res; } +static int CmdPIVScan(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "piv scan", + "Scan a PIV card for known containers", + "piv scan -s -> select card, select applet and run scan\n" + "piv scan -st --aid a00000030800001000 -> select card, select applet a00000030800001000, show result of the scan in TLV\n"); + + void *argtable[] = { + arg_param_begin, + arg_lit0("sS", "select", "Activate field and select applet"), + arg_lit0("kK", "keep", "Keep field for next command"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), + arg_lit0("tT", "tlv", "TLV decode results"), + arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), + arg_str0(NULL, "aid", "", "Applet ID to select. By default A0000003080000100 will be used"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + bool activateField = arg_get_lit(ctx, 1); + bool leaveSignalON = arg_get_lit(ctx, 2); + bool APDULogging = arg_get_lit(ctx, 3); + bool decodeTLV = arg_get_lit(ctx, 4); + Iso7816CommandChannel channel = CC_CONTACTLESS; + if (arg_get_lit(ctx, 5)) + channel = CC_CONTACT; + PrintChannel(channel); + + uint8_t applet_id[APDU_AID_LEN] = {0}; + int aid_len = 0; + CLIGetHexWithReturn(ctx, 6, applet_id, &aid_len); + if (aid_len == 0) { + memcpy(applet_id, PIV_APPLET, sizeof(PIV_APPLET)); + aid_len = sizeof(PIV_APPLET); + } + + CLIParserFree(ctx); + + SetAPDULogging(APDULogging); + if (aid_len == 0) { + memcpy(applet_id, PIV_APPLET, sizeof(PIV_APPLET)); + aid_len = sizeof(PIV_APPLET); + } + int res = 0; + if (activateField == true) { + res = PivSelect(channel, activateField, true, decodeTLV, true, applet_id, aid_len); + if (res != PM3_SUCCESS) { + if (leaveSignalON == false) { + DropFieldEx(channel); + } + return res; + } + } + + for (int i = 0; PIV_CONTAINERS[i].len != 0; i++) { + PivGetDataByCidAndPrint(channel, &(PIV_CONTAINERS[i]), decodeTLV, false); + PrintAndLogEx(NORMAL, ""); + } + if (leaveSignalON == false) { + DropFieldEx(channel); + } + return PM3_SUCCESS; +} + static int CmdPIVList(const char *Cmd) { return CmdTraceListAlias(Cmd, "piv", "7816"); } @@ -794,6 +858,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"select", CmdPIVSelect, IfPm3Iso14443, "Select the PIV applet"}, {"getdata", CmdPIVGetData, IfPm3Iso14443, "Gets a container on a PIV card"}, + {"scan", CmdPIVScan, IfPm3Iso14443, "Scan PIV card for known containers"}, {"list", CmdPIVList, AlwaysAvailable, "List ISO7816 history"}, {NULL, NULL, NULL, NULL} From e5f6e34632cd70b90237e2bb2024592811f7fd29 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 6 Jan 2023 21:25:48 +0100 Subject: [PATCH 453/759] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5192c890d..5cda9db5c 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] + - Add command `piv scan` which tries to read all known containers on PIV (@jmichelp) - Add support for PIV commands, over wired and contactless interfaces (@jmichelp) - Add `--shallow` option to `hf iclass` reader commands to do shallow (ASK) reader modulation instead of OOK (@nvx) - Improved NXP SLI/SLIX series tag identification (@nvx) From 15b541c2ea19ce038d35a5268356fb9ed9e7c605 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 6 Jan 2023 21:36:08 +0100 Subject: [PATCH 454/759] Add command `piv authsign` --- CHANGELOG.md | 1 + client/src/cmdpiv.c | 114 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cda9db5c..bc54763f8 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] + - Add command `piv authsign` to get a buffer signed by the selected key (@jmichelp) - Add command `piv scan` which tries to read all known containers on PIV (@jmichelp) - Add support for PIV commands, over wired and contactless interfaces (@jmichelp) - Add `--shallow` option to `hf iclass` reader commands to do shallow (ASK) reader modulation instead of OOK (@nvx) diff --git a/client/src/cmdpiv.c b/client/src/cmdpiv.c index 7295269d2..937f6a369 100644 --- a/client/src/cmdpiv.c +++ b/client/src/cmdpiv.c @@ -653,6 +653,44 @@ static int PivGetDataByTagAndPrint(Iso7816CommandChannel channel, const uint8_t return PivGetDataByCidAndPrint(channel, &(PIV_CONTAINERS[idx]), decodeTLV, verbose); } +static int PivAuthenticateSign(Iso7816CommandChannel channel, uint8_t alg_id, uint8_t key_id, uint8_t nonce[], size_t nonce_len, void **result, bool decodeTLV, bool verbose) { + if (nonce_len > 0x7A) { + if (verbose == true) { + PrintAndLogEx(WARNING, "Nonce cannot exceed %d bytes. Got %d bytes.", 0x7a, nonce_len); + } + return PM3_EINVARG; + } + uint8_t apdu_buf[APDU_RES_LEN] = {0x7c, nonce_len + 4, 0x82, 0x00, 0x81, nonce_len}; + memcpy(&apdu_buf[6], nonce, nonce_len); + sAPDU_t apdu = { + 0x00, 0x87, alg_id, key_id, + 6 + nonce_len, apdu_buf + }; + + uint16_t sw = 0; + uint8_t buf[APDU_RES_LEN] = {0}; + size_t len = 0; + int res = Iso7816ExchangeEx(channel, false, true, apdu, false, 0, buf, APDU_RES_LEN, &len, &sw); + if (res != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Sending APDU failed with code %d", res); + return res; + } + if (sw != APDU_RES_SUCCESS) { + if (verbose == true) { + PrintAndLogEx(INFO, "Unexpected APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); + } + return PM3_EFAILED; + } + if (verbose == true) { + if (decodeTLV == true) { + PrintTLVFromBuffer(buf, len); + } else { + print_buffer(buf, len, 0); + } + } + return PM3_SUCCESS; +} + static int PivSelect(Iso7816CommandChannel channel, bool activateField, bool leaveFieldOn, bool decodeTLV, bool silent, uint8_t applet[], size_t appletLen) { uint8_t buf[APDU_RES_LEN] = {0}; size_t len = 0; @@ -786,6 +824,81 @@ static int CmdPIVGetData(const char *Cmd) { return res; } +static int CmdPIVAuthenticateSign(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "piv sign", + "Send a nonce and ask the PIV card to sign it", + "piv sign -sk -> select card, select applet, sign a NULL nonce\n"); + + void *argtable[] = { + arg_param_begin, + arg_lit0("sS", "select", "Activate field and select applet"), + arg_lit0("kK", "keep", "Keep field for next command"), + arg_lit0("aA", "apdu", "Show APDU requests and responses"), + arg_lit0("tT", "tlv", "TLV decode results"), + arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. (def: Contactless interface)"), + arg_str0(NULL, "aid", "", "Applet ID to select. By default A0000003080000100 will be used"), + arg_str1(NULL, "nonce", "", "Nonce to sign."), + arg_int0(NULL, "slot", "", "Slot number. Default will be 0x9E (card auth cert)."), + arg_int0(NULL, "alg", "", "Algorithm to use to sign. Example values: 06=RSA-1024, 07=RSA-2048, 11=ECC-P256 (default), 14=ECC-P384"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + bool activateField = arg_get_lit(ctx, 1); + bool leaveSignalON = arg_get_lit(ctx, 2); + bool APDULogging = arg_get_lit(ctx, 3); + bool decodeTLV = arg_get_lit(ctx, 4); + Iso7816CommandChannel channel = CC_CONTACTLESS; + if (arg_get_lit(ctx, 5)) + channel = CC_CONTACT; + PrintChannel(channel); + + uint8_t applet_id[APDU_AID_LEN] = {0}; + int aid_len = 0; + CLIGetHexWithReturn(ctx, 6, applet_id, &aid_len); + if (aid_len == 0) { + memcpy(applet_id, PIV_APPLET, sizeof(PIV_APPLET)); + aid_len = sizeof(PIV_APPLET); + } + + uint8_t nonce[APDU_RES_LEN] = {0}; + int nonce_len = 0; + CLIGetHexWithReturn(ctx, 7, nonce, &nonce_len); + + int key_slot = arg_get_int_def(ctx, 8, 0x9e); + int alg_id = arg_get_int_def(ctx, 9, 0x11); + + CLIParserFree(ctx); + + if (key_slot > 0xff) { + PrintAndLogEx(FAILED, "Key slot must fit on 1 byte."); + return PM3_EINVARG; + } + if (alg_id > 0xff) { + PrintAndLogEx(FAILED, "Algorithm ID must fit on 1 byte"); + return PM3_EINVARG; + } + + SetAPDULogging(APDULogging); + + int res = 0; + if (activateField == true) { + res = PivSelect(channel, activateField, true, decodeTLV, true, applet_id, aid_len); + if (res != PM3_SUCCESS) { + if (leaveSignalON == false) { + DropFieldEx(channel); + } + return res; + } + } + res = PivAuthenticateSign(channel, (uint8_t)(alg_id & 0xff), (uint8_t)(key_slot & 0xff), nonce, nonce_len, NULL, decodeTLV, true); + if (leaveSignalON == false) { + DropFieldEx(channel); + } + return res; +} + static int CmdPIVScan(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "piv scan", @@ -858,6 +971,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"select", CmdPIVSelect, IfPm3Iso14443, "Select the PIV applet"}, {"getdata", CmdPIVGetData, IfPm3Iso14443, "Gets a container on a PIV card"}, + {"authsign", CmdPIVAuthenticateSign, IfPm3Iso14443, "Authenticate with the card"}, {"scan", CmdPIVScan, IfPm3Iso14443, "Scan PIV card for known containers"}, {"list", CmdPIVList, AlwaysAvailable, "List ISO7816 history"}, From a7980d8e8a0693ca2424e8fe2a93470f8c7a852e Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 6 Jan 2023 21:52:26 +0100 Subject: [PATCH 455/759] Use a typed constant and see if that makes CodeQL happy :) --- client/src/cmdpiv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/src/cmdpiv.c b/client/src/cmdpiv.c index 937f6a369..1c9dc701a 100644 --- a/client/src/cmdpiv.c +++ b/client/src/cmdpiv.c @@ -654,9 +654,10 @@ static int PivGetDataByTagAndPrint(Iso7816CommandChannel channel, const uint8_t } static int PivAuthenticateSign(Iso7816CommandChannel channel, uint8_t alg_id, uint8_t key_id, uint8_t nonce[], size_t nonce_len, void **result, bool decodeTLV, bool verbose) { - if (nonce_len > 0x7A) { + const size_t MAX_NONCE_LEN = 0x7a; + if (nonce_len > MAX_NONCE_LEN) { if (verbose == true) { - PrintAndLogEx(WARNING, "Nonce cannot exceed %d bytes. Got %d bytes.", 0x7a, nonce_len); + PrintAndLogEx(WARNING, "Nonce cannot exceed %d bytes. Got %d bytes.", MAX_NONCE_LEN, nonce_len); } return PM3_EINVARG; } From 16410b064d7ad97ced4ccce5203781fe02bb2680 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Fri, 6 Jan 2023 22:06:07 +0100 Subject: [PATCH 456/759] Fix format string to please CodeQL --- client/src/cmdpiv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdpiv.c b/client/src/cmdpiv.c index 1c9dc701a..d73c52fee 100644 --- a/client/src/cmdpiv.c +++ b/client/src/cmdpiv.c @@ -657,7 +657,7 @@ static int PivAuthenticateSign(Iso7816CommandChannel channel, uint8_t alg_id, ui const size_t MAX_NONCE_LEN = 0x7a; if (nonce_len > MAX_NONCE_LEN) { if (verbose == true) { - PrintAndLogEx(WARNING, "Nonce cannot exceed %d bytes. Got %d bytes.", MAX_NONCE_LEN, nonce_len); + PrintAndLogEx(WARNING, "Nonce cannot exceed %zu bytes. Got %zu bytes.", MAX_NONCE_LEN, nonce_len); } return PM3_EINVARG; } From 9888eef8dc86f87c5fa9ec6038f311ff2c191bd6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 6 Jan 2023 23:53:25 +0100 Subject: [PATCH 457/759] changed hf mf wrbl and view command to look for strict readonly ACL in the data. --- CHANGELOG.md | 2 + armsrc/i2c.c | 2 +- armsrc/mifarecmd.c | 2 +- client/luascripts/hf_i2c_plus_2k_utils.lua | 20 +- client/luascripts/hf_mf_ultimatecard.lua | 6 +- client/src/cmdhficlass.c | 2 +- client/src/cmdhfmf.c | 76 +++++++- client/src/cmdhfmfu.c | 2 +- client/src/cmdlfhitag.c | 4 +- client/src/cmdscript.c | 2 +- client/src/cmdtrace.c | 16 +- client/src/mifare/mifare4.c | 39 ++-- client/src/mifare/mifare4.h | 1 + client/src/pm3line_vocabulory.h | 6 + client/src/ui.h | 2 +- doc/commands.json | 217 ++++++++++++++++----- doc/commands.md | 16 +- 17 files changed, 313 insertions(+), 102 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc54763f8..4278b6c12 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 mf wrbl` - now checks for strict readonly ACL's in the data to write (@iceman1001) + - Changed `hf mf view` - verbose printing if strict readonly ACL's exists in dump file (@iceman1001) - Add command `piv authsign` to get a buffer signed by the selected key (@jmichelp) - Add command `piv scan` which tries to read all known containers on PIV (@jmichelp) - Add support for PIV commands, over wired and contactless interfaces (@jmichelp) diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 491e12a04..ca3cb46fd 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -749,7 +749,7 @@ bool GetATR(smart_card_atr_t *card_ptr, bool verbose) { } } - card_ptr->atr_len = (uint8_t) (len & 0xff); + card_ptr->atr_len = (uint8_t)(len & 0xff); if (verbose) { LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false); } diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 3db9112af..74e75ddce 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2356,7 +2356,7 @@ void MifareCIdent(bool is_mfc) { uint8_t rats[4] = { ISO14443A_CMD_RATS, 0x80, 0x31, 0x73 }; uint8_t rdblf0[4] = { ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f}; uint8_t rdbl00[4] = { ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8}; - uint8_t gen4GetConf[8] = { GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0}; + uint8_t gen4GetConf[8] = { GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0}; uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); uint8_t *uid = BigBuf_malloc(10); diff --git a/client/luascripts/hf_i2c_plus_2k_utils.lua b/client/luascripts/hf_i2c_plus_2k_utils.lua index 7e6b9b300..5e7652316 100644 --- a/client/luascripts/hf_i2c_plus_2k_utils.lua +++ b/client/luascripts/hf_i2c_plus_2k_utils.lua @@ -23,7 +23,7 @@ author = 'Shain Lakin' version = 'v1.0.0' desc =[[ -This script can be used to read blocks, write blocks, dump sectors, +This script can be used to read blocks, write blocks, dump sectors, or write a files hex bytes to sector 0 or 1 on the NTAG I2C PLUS 2K tag. ]] @@ -32,7 +32,7 @@ example =[[ Read block 04 from sector 1: script run hf_i2c_plus_2k_utils -m r -s 1 -b 04 - + Write FFFFFFFF to block A0 sector 1: script run hf_i2c_plus_2k_utils -m w -s 1 -b A0 -d FFFFFFFF @@ -45,15 +45,15 @@ example =[[ ]] usage = [[ - Read mode: + Read mode: script run hf_i2c_plus_2k_utils -m r -s -b - - Write mode: + + Write mode: script run hf_i2c_plus_2k_utils -m w -s -b -d - + Dump mode: script run hf_i2c_plus_2k_utils -m d -s - + File mode: script run hf_i2c_plus_2k_utils -m f -s -f @@ -124,7 +124,7 @@ end --- ---- Function to connect +--- Function to connect local function connect() core.clearCommandBuffer() @@ -189,7 +189,7 @@ local function filewriter(file,sector) end_char = 8 block_counter = 4 -- NTAG_I2C_PLUS_2K:SECTOR_0:225,SECTOR_1:255 - end_block = 225 + end_block = 225 connect() select_sector(sector) for count = 1, len do @@ -296,7 +296,7 @@ local function main(args) elseif mode == 'd' then dump(sector,uid) end - + else return print(usage) end diff --git a/client/luascripts/hf_mf_ultimatecard.lua b/client/luascripts/hf_mf_ultimatecard.lua index 4a70935bb..aec47e9d0 100644 --- a/client/luascripts/hf_mf_ultimatecard.lua +++ b/client/luascripts/hf_mf_ultimatecard.lua @@ -847,13 +847,13 @@ end -- returns true if b is the index of a sector trailer local function mfIsSectorTrailer(b) n=b+1 - if (n < 32*4 ) then - if (n % 4 == 0) then return true + if (n < 32*4 ) then + if (n % 4 == 0) then return true else return false end end - if (n % 16 == 0) then return true + if (n % 16 == 0) then return true end return false diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 4e555f909..94d710f98 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -3968,7 +3968,7 @@ static int CmdHFiClassEncode(const char *Cmd) { return PM3_ESOFT; } - // iceman: only for formats w length smaller than 37. + // iceman: only for formats w length smaller than 37. // Needs a check. // increase length to allow setting bit just above real data diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 51a9a13f0..eba190b5e 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -238,7 +238,7 @@ static bool mfc_value(const uint8_t *d, int32_t *val) { } static void mf_print_block_one(uint8_t blockno, uint8_t *d, bool verbose) { - if (blockno == 0) { + if (blockno == 0) { PrintAndLogEx(INFO, "%3d | " _RED_("%s"), blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); } else if (mfIsSectorTrailer(blockno)) { PrintAndLogEx(INFO, "%3d | " _YELLOW_("%s"), blockno, sprint_hex_ascii(d, MFBLOCK_SIZE)); @@ -375,6 +375,31 @@ static bool mf_write_block(const uint8_t *key, uint8_t keytype, uint8_t blockno, return (resp.oldarg[0] & 0xff); } +static void mf_analyse_acl(uint16_t n, uint8_t *d) { + + for (uint16_t b = 3; b < n; b++) { + if (mfIsSectorTrailer(b) == false) { + continue; + } + + uint8_t block[MFBLOCK_SIZE] = {0x00}; + memcpy(block, d + (b * MFBLOCK_SIZE), MFBLOCK_SIZE); + + // ensure access right isn't messed up. + if (mfValidateAccessConditions(&block[6]) == false) { + PrintAndLogEx(WARNING, "Invalid Access Conditions on sector " _YELLOW_("%u"), mfSectorNum(b)); + } + + // Warn if ACL is strict read-only + uint8_t bar = mfNumBlocksPerSector(mfSectorNum(b)); + for (uint8_t foo = 0; foo < bar; foo++) { + if (mfReadOnlyAccessConditions(foo, &block[6])) { + PrintAndLogEx(WARNING, _YELLOW_("s%u / b%u") " - Strict ReadOnly Access Conditions detected", mfSectorNum(b), b - bar + 1 + foo); + } + } + } +} + static int CmdHF14AMfAcl(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf acl", @@ -539,6 +564,32 @@ static int CmdHF14AMfWrBl(const char *Cmd) { uint8_t blockno = (uint8_t)b; + // Warn if ACL is strict read-only + if (mfIsSectorTrailer(blockno)) { + PrintAndLogEx(INFO, "Sector trailer (ST) write detected"); + + // ensure access right isn't messed up. + if (mfValidateAccessConditions(&block[6]) == false) { + PrintAndLogEx(WARNING, "Invalid Access Conditions detected, replacing by default values"); + memcpy(block + 6, "\xFF\x07\x80\x69", 4); + } + + bool ro_detected = false; + uint8_t bar = mfNumBlocksPerSector(mfSectorNum(blockno)); + for (uint8_t foo = 0; foo < bar; foo++) { + if (mfReadOnlyAccessConditions(foo, &block[6])) { + PrintAndLogEx(WARNING, "Strict ReadOnly Access Conditions on block " _YELLOW_("%u") " detected", blockno - bar + 1 + foo); + ro_detected = true; + } + } + if (ro_detected) { + PrintAndLogEx(INFO, "Exiting, please run `" _YELLOW_("hf mf acl -d %s") "` to understand", sprint_hex_inrow(&block[6], 3)); + return PM3_EINVARG; + } else { + PrintAndLogEx(SUCCESS, "ST passed checks, continuing..."); + } + } + PrintAndLogEx(INFO, "Writing block no %d, key %c - %s", blockno, (keytype == MF_KEY_B) ? 'B' : 'A', sprint_hex_inrow(key, sizeof(key))); PrintAndLogEx(INFO, "data: %s", sprint_hex(block, sizeof(block))); @@ -1172,7 +1223,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { PrintAndLogEx(INFO, "Restoring " _YELLOW_("%s")" to card", datafilename); - // main loop for restoreing. + // main loop for restoring. // a bit more complicated than needed // this is because of two things. // 1. we are setting keys from a key file or using the existing ones in the dump @@ -1182,7 +1233,6 @@ static int CmdHF14AMfRestore(const char *Cmd) { for (uint8_t b = 0; b < mfNumBlocksPerSector(s); b++) { uint8_t bldata[MFBLOCK_SIZE] = {0x00}; - memcpy(bldata, dump, MFBLOCK_SIZE); // if sector trailer @@ -1209,6 +1259,13 @@ static int CmdHF14AMfRestore(const char *Cmd) { PrintAndLogEx(WARNING, "Invalid Access Conditions on sector %i, replacing by default values", s); memcpy(bldata + 6, "\xFF\x07\x80\x69", 4); } + + // Warn if ACL is strict read-only + for (uint8_t foo = 0; foo < mfNumBlocksPerSector(s); foo++) { + if (mfReadOnlyAccessConditions(foo, &bldata[6])) { + PrintAndLogEx(WARNING, "Strict ReadOnly Access Conditions on block " _YELLOW_("%u") " detected", foo); + } + } } if (bytes_read) { @@ -6818,6 +6875,7 @@ static int CmdHF14AMfView(const char *Cmd) { if (verbose) { mf_print_keys(block_cnt, dump); + mf_analyse_acl(block_cnt, dump); } int sector = DetectHID(dump, 0x4910); @@ -6836,7 +6894,7 @@ static int CmdHF14AMfView(const char *Cmd) { } // allocate memory - uint8_t* d = calloc(bytes_read, sizeof(uint8_t)); + uint8_t *d = calloc(bytes_read, sizeof(uint8_t)); if (d == NULL) { return PM3_EMALLOC; } @@ -7324,8 +7382,8 @@ static int CmdHF14AGen4Save(const char *Cmd) { int fnlen = 0; char filename[FILE_PATH_SIZE]; CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); - - bool fill_emulator = arg_get_lit(ctx,7); + + bool fill_emulator = arg_get_lit(ctx, 7); CLIParserFree(ctx); // validations @@ -7420,12 +7478,12 @@ static int CmdHF14AGen4Save(const char *Cmd) { } PrintAndLogEx(NORMAL, ""); - + if (fill_emulator) { PrintAndLogEx(INFO, "uploading to emulator memory" NOLF); // fast push mode g_conn.block_after_ACK = true; - + size_t offset = 0; int cnt = 0; uint16_t bytes_left = bytes ; @@ -7454,7 +7512,7 @@ static int CmdHF14AGen4Save(const char *Cmd) { offset += MFBLOCK_SIZE; bytes_left -= MFBLOCK_SIZE; } - + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "uploaded " _YELLOW_("%d") " bytes to emulator memory", bytes); } diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index c3701a76d..e948360e6 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -4154,7 +4154,7 @@ static int CmdHF14AMfuEView(const char *Cmd) { if (override_end) { ++end ; - } else { + } else { end = dump->pages ; } diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index ba7b72195..66fb3ea42 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -857,12 +857,12 @@ static int CmdLFHitag2Dump(const char *Cmd) { memcpy(htd.pwd.password, key, sizeof(htd.pwd.password)); PrintAndLogEx(INFO, "Authenticating in password mode"); } - + uint16_t cmd = CMD_LF_HITAG_READER; clearCommandBuffer(); SendCommandMIX(cmd, htf, 0, 0, &htd, sizeof(htd)); PacketResponseNG resp; - + if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index 7a5a59130..35640922e 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -404,7 +404,7 @@ static int CmdScriptRun(const char *Cmd) { PyImport_AppendInittab("_pm3", PyInit__pm3); #endif #if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 10 - Py_Initialize(); + Py_Initialize(); #else PyConfig py_conf; PyConfig_InitIsolatedConfig(&py_conf); diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index 5fbf90b0d..af97e8466 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -900,16 +900,16 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr if (use_us) { PrintAndLogEx(NORMAL, " %10.1f | %10.1f | %s |fdt (Frame Delay Time): " _YELLOW_("%.1f"), - (float)time1 / 13.56, - (float)time2 / 13.56, - " ", - (float)(next_hdr->timestamp - end_of_transmission_timestamp) / 13.56); + (float)time1 / 13.56, + (float)time2 / 13.56, + " ", + (float)(next_hdr->timestamp - end_of_transmission_timestamp) / 13.56); } else { PrintAndLogEx(NORMAL, " %10u | %10u | %s |fdt (Frame Delay Time): " _YELLOW_("%d"), - time1, - time2, - " ", - (next_hdr->timestamp - end_of_transmission_timestamp)); + time1, + time2, + " ", + (next_hdr->timestamp - end_of_transmission_timestamp)); } } diff --git a/client/src/mifare/mifare4.c b/client/src/mifare/mifare4.c index a1427bc9f..1ac6b6fed 100644 --- a/client/src/mifare/mifare4.c +++ b/client/src/mifare/mifare4.c @@ -74,22 +74,37 @@ AccessConditions_t MFAccessConditionsTrailer[] = { }; bool mfValidateAccessConditions(const uint8_t *data) { - uint8_t ndata1 = (data[0]) & 0x0f; - uint8_t ndata2 = (data[0] >> 4) & 0x0f; - uint8_t ndata3 = (data[1]) & 0x0f; - uint8_t data1 = (data[1] >> 4) & 0x0f; - uint8_t data2 = (data[2]) & 0x0f; - uint8_t data3 = (data[2] >> 4) & 0x0f; + uint8_t nd1 = NIBBLE_LOW(data[0]); + uint8_t nd2 = NIBBLE_HIGH(data[0]); + uint8_t nd3 = NIBBLE_LOW(data[1]); + uint8_t d1 = NIBBLE_HIGH(data[1]); + uint8_t d2 = NIBBLE_LOW(data[2]); + uint8_t d3 = NIBBLE_HIGH(data[2]); - return ((ndata1 == (data1 ^ 0xF)) && (ndata2 == (data2 ^ 0xF)) && (ndata3 == (data3 ^ 0xF))); + return ((nd1 == (d1 ^ 0xF)) && (nd2 == (d2 ^ 0xF)) && (nd3 == (d3 ^ 0xF))); +} +bool mfReadOnlyAccessConditions(uint8_t blockn, const uint8_t *data) { + + uint8_t d1 = NIBBLE_HIGH(data[1]) >> blockn; + uint8_t d2 = NIBBLE_LOW(data[2]) >> blockn; + uint8_t d3 = NIBBLE_HIGH(data[2]) >> blockn; + uint8_t cond = (d1 & 0x01) << 2 | (d2 & 0x01) << 1 | (d3 & 0x01); + + if (blockn == 3) { + if ((cond == 0x02) || (cond == 0x06) || (cond == 0x07)) return true; + } else { + if ((cond == 0x02) || (cond == 0x05)) return true; + } + return false; } -const char *mfGetAccessConditionsDesc(uint8_t blockn, const uint8_t *data) { - uint8_t data1 = ((data[1] >> 4) & 0x0f) >> blockn; - uint8_t data2 = ((data[2]) & 0x0f) >> blockn; - uint8_t data3 = ((data[2] >> 4) & 0x0f) >> blockn; - uint8_t cond = (data1 & 0x01) << 2 | (data2 & 0x01) << 1 | (data3 & 0x01); +const char *mfGetAccessConditionsDesc(uint8_t blockn, const uint8_t *data) { + uint8_t d1 = NIBBLE_HIGH(data[1]) >> blockn; + uint8_t d2 = NIBBLE_LOW(data[2]) >> blockn; + uint8_t d3 = NIBBLE_HIGH(data[2]) >> blockn; + + uint8_t cond = (d1 & 0x01) << 2 | (d2 & 0x01) << 1 | (d3 & 0x01); if (blockn == 3) { for (int i = 0; i < ARRAYLEN(MFAccessConditionsTrailer); i++) diff --git a/client/src/mifare/mifare4.h b/client/src/mifare/mifare4.h index 7905f3ab6..489add9f3 100644 --- a/client/src/mifare/mifare4.h +++ b/client/src/mifare/mifare4.h @@ -71,6 +71,7 @@ int MFPGetSignature(bool activateField, bool leaveSignalON, uint8_t *dataout, in int MFPGetVersion(bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen); bool mfValidateAccessConditions(const uint8_t *data); +bool mfReadOnlyAccessConditions(uint8_t blockn, const uint8_t *data); const char *mfGetAccessConditionsDesc(uint8_t blockn, const uint8_t *data); uint8_t mfNumBlocksPerSector(uint8_t sectorNo); diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 6b15007c3..de0cb6ace 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -349,6 +349,7 @@ const static vocabulory_t vocabulory[] = { { 0, "hf mf gen3freeze" }, { 0, "hf mf ggetblk" }, { 0, "hf mf gload" }, + { 0, "hf mf gsave" }, { 0, "hf mf gsetblk" }, { 0, "hf mf gview" }, { 0, "hf mf ndefformat" }, @@ -736,6 +737,11 @@ const static vocabulory_t vocabulory[] = { { 0, "nfc barcode read" }, { 0, "nfc barcode sim" }, { 1, "nfc barcode help" }, + { 1, "piv help" }, + { 0, "piv select" }, + { 0, "piv getdata" }, + { 0, "piv scan" }, + { 1, "piv list" }, { 1, "smart help" }, { 1, "smart list" }, { 0, "smart info" }, diff --git a/client/src/ui.h b/client/src/ui.h index 7aff98eba..4042550b3 100644 --- a/client/src/ui.h +++ b/client/src/ui.h @@ -36,7 +36,7 @@ typedef enum emojiMode {EMO_ALIAS, EMO_EMOJI, EMO_ALTTEXT, EMO_NONE} emojiMode_t typedef enum clientdebugLevel {cdbOFF, cdbSIMPLE, cdbFULL} clientdebugLevel_t; // typedef enum devicedebugLevel {ddbOFF, ddbERROR, ddbINFO, ddbDEBUG, ddbEXTENDED} devicedebugLevel_t; - // last item spItemCount used to auto map to number of files +// last item spItemCount used to auto map to number of files typedef enum savePaths {spDefault, spDump, spTrace, spItemCount} savePaths_t; typedef struct {int x; int y; int h; int w;} qtWindow_t; diff --git a/doc/commands.json b/doc/commands.json index a94e5bc6a..7546493bb 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -1030,7 +1030,7 @@ }, "help": { "command": "help", - "description": "help Use ` help` for details of a command prefs { Edit client/device preferences... } -------- ----------------------- Technology ----------------------- analyse { Analyse utils... } data { Plot window / data buffer manipulation... } emv { EMV ISO-14443 / ISO-7816... } hf { High frequency commands... } hw { Hardware commands... } lf { Low frequency commands... } nfc { NFC commands... } reveng { CRC calculations from RevEng software... } smart { Smart card ISO-7816 commands... } script { Scripting commands... } trace { Trace manipulation... } wiegand { Wiegand format manipulation... } -------- ----------------------- General ----------------------- clear Clear screen hints Turn hints on / off msleep Add a pause in milliseconds rem Add a text line in log file quit exit Exit program", + "description": "help Use ` help` for details of a command prefs { Edit client/device preferences... } -------- ----------------------- Technology ----------------------- analyse { Analyse utils... } data { Plot window / data buffer manipulation... } emv { EMV ISO-14443 / ISO-7816... } hf { High frequency commands... } hw { Hardware commands... } lf { Low frequency commands... } nfc { NFC commands... } piv { PIV commands... } reveng { CRC calculations from RevEng software... } smart { Smart card ISO-7816 commands... } script { Scripting commands... } trace { Trace manipulation... } wiegand { Wiegand format manipulation... } -------- ----------------------- General ----------------------- clear Clear screen hints Turn hints on / off msleep Add a pause in milliseconds rem Add a text line in log file quit exit Exit program", "notes": [], "offline": true, "options": [], @@ -2916,9 +2916,10 @@ "-f, --file Dictionary file with default iclass keys", "--credit key is assumed to be the credit key", "--elite elite computations applied to key", - "--raw no computations applied to key (raw)" + "--raw no computations applied to key (raw)", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass chk [-h] -f [--credit] [--elite] [--raw]" + "usage": "hf iclass chk [-h] -f [--credit] [--elite] [--raw] [--shallow]" }, "hf iclass configcard": { "command": "hf iclass configcard", @@ -2970,9 +2971,10 @@ "--raw raw, the key is interpreted as raw block 3/4", "--nr replay of NR/MAC", "-z, --dense dense dump output style", - "--force force unsecure card read" + "--force force unsecure card read", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass dump [-hz] [-f ] [-k ] [--ki ] [--credit ] [--ci ] [--elite] [--raw] [--nr] [--force]" + "usage": "hf iclass dump [-hz] [-f ] [-k ] [--ki ] [--credit ] [--ci ] [--elite] [--raw] [--nr] [--force] [--shallow]" }, "hf iclass eload": { "command": "hf iclass eload", @@ -3008,9 +3010,10 @@ "--enckey 3DES transport key, 16 hex bytes", "--fc facility code", "--cn card number", - "-w, --wiegand see `wiegand list` for available formats" + "-w, --wiegand see `wiegand list` for available formats", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass encode [-h] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ]" + "usage": "hf iclass encode [-h] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ] [--shallow]" }, "hf iclass encrypt": { "command": "hf iclass encrypt", @@ -3077,9 +3080,10 @@ ], "offline": true, "options": [ - "-h, --help This help" + "-h, --help This help", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass info [-h]" + "usage": "hf iclass info [-h] [--shallow]" }, "hf iclass list": { "command": "hf iclass list", @@ -3191,9 +3195,10 @@ "--elite elite computations applied to key", "--raw no computations applied to key", "--nr replay of NR/MAC", - "-v, --verbose verbose output" + "-v, --verbose verbose output", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass rdbl [-hv] [-k ] [--ki ] -b [--credit] [--elite] [--raw] [--nr]" + "usage": "hf iclass rdbl [-hv] [-k ] [--ki ] -b [--credit] [--elite] [--raw] [--nr] [--shallow]" }, "hf iclass reader": { "command": "hf iclass reader", @@ -3204,9 +3209,10 @@ "offline": false, "options": [ "-h, --help This help", - "-@ optional - continuous reader mode" + "-@ optional - continuous reader mode", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass reader [-h@]" + "usage": "hf iclass reader [-h@] [--shallow]" }, "hf iclass restore": { "command": "hf iclass restore", @@ -3227,9 +3233,10 @@ "--credit key is assumed to be the credit key", "--elite elite computations applied to key", "--raw no computations applied to key", - "-v, --verbose verbose output" + "-v, --verbose verbose output", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass restore [-hv] -f [-k ] [--ki ] --first --last [--credit] [--elite] [--raw]" + "usage": "hf iclass restore [-hv] -f [-k ] [--ki ] --first --last [--credit] [--elite] [--raw] [--shallow]" }, "hf iclass sim": { "command": "hf iclass sim", @@ -3301,9 +3308,10 @@ "--elite elite computations applied to key", "--raw no computations applied to key", "--nr replay of NR/MAC", - "-v, --verbose verbose output" + "-v, --verbose verbose output", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass wrbl [-hv] [-k ] [--ki ] -b -d [-m ] [--credit] [--elite] [--raw] [--nr]" + "usage": "hf iclass wrbl [-hv] [-k ] [--ki ] -b -d [-m ] [--credit] [--elite] [--raw] [--nr] [--shallow]" }, "hf jooki clone": { "command": "hf jooki clone", @@ -3391,6 +3399,20 @@ ], "usage": "hf jooki sim [-h] [-b ]" }, + "hf ksx6924 balance": { + "command": "hf ksx6924 balance", + "description": "Gets the current purse balance", + "notes": [ + "hf ksx6924 balance" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-k, --keep keep field ON for next command", + "-a, --apdu Show APDU requests and responses" + ], + "usage": "hf ksx6924 balance [-hka]" + }, "hf ksx6924 help": { "command": "hf ksx6924 help", "description": "help This help", @@ -3399,19 +3421,6 @@ "options": [], "usage": "" }, - "hf ksx6924 select": { - "command": "hf ksx6924 select", - "description": "Selects KS X 6924 application, and leaves field up", - "notes": [ - "hf ksx6924 select" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-a, --apdu Show APDU requests and responses" - ], - "usage": "hf ksx6924 select [-ha]" - }, "hf ksx6924 info": { "command": "hf ksx6924 info", "description": "Get info about a KS X 6924 transit card. This application is used by T-Money (South Korea) and Snapper+ (Wellington, New Zealand).", @@ -3426,23 +3435,9 @@ ], "usage": "hf ksx6924 info [-hka]" }, - "hf ksx6924 balance": { - "command": "hf ksx6924 balance", - "description": "Gets the current purse balance", - "notes": [ - "hf ksx6924 balance" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-k, --keep keep field ON for next command", - "-a, --apdu Show APDU requests and responses" - ], - "usage": "hf ksx6924 balance [-hka]" - }, "hf ksx6924 init": { "command": "hf ksx6924 init", - "description": "Perform transaction initialization (mpda)", + "description": "Perform transaction initialization with Mpda (Money of Purchase Transaction)", "notes": [ "hf ksx6924 init 000003e8 -> Mpda" ], @@ -3468,7 +3463,19 @@ ], "usage": "hf ksx6924 prec [-hka] " }, - + "hf ksx6924 select": { + "command": "hf ksx6924 select", + "description": "Selects KS X 6924 application, and leaves field up", + "notes": [ + "hf ksx6924 select" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-a, --apdu Show APDU requests and responses" + ], + "usage": "hf ksx6924 select [-ha]" + }, "hf legic crc": { "command": "hf legic crc", "description": "Calculates the legic crc8/crc16 on the given data", @@ -3971,7 +3978,7 @@ "--1k MIFARE Classic 1k / S50 (def)", "--2k MIFARE Classic/Plus 2k", "--4k MIFARE Classic 4k / S70", - "--emu from emulator memory" + "--emu to emulator memory" ], "usage": "hf mf csave [-h] [-f ] [--mini] [--1k] [--2k] [--4k] [--emu]" }, @@ -4348,6 +4355,27 @@ ], "usage": "hf mf gload [-hv] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu] [--start ] [--end ]" }, + "hf mf gsave": { + "command": "hf mf gsave", + "description": "Save `magic gen4 gtu` card memory into three files (BIN/EML/JSON)or into emulator memory", + "notes": [ + "hf mf gsave", + "hf mf gsave --4k", + "hf mf gsave -p DEADBEEF -f hf-mf-01020304.json" + ], + "offline": false, + "options": [ + "-h, --help This help", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70", + "-p, --pwd password 4bytes", + "-f, --file filename of dump", + "--emu to emulator memory" + ], + "usage": "hf mf gsave [-h] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu]" + }, "hf mf gsetblk": { "command": "hf mf gsetblk", "description": "Set block data on a magic gen4 GTU card", @@ -6176,7 +6204,7 @@ }, "hf mfu esave": { "command": "hf mfu esave", - "description": "Saves emulator memory to a MIFARE Ultralight/NTAG dump file (bin/eml/json) By default number of pages saved depends on defined tag type. You can overrife this with option --end.", + "description": "Saves emulator memory to a MIFARE Ultralight/NTAG dump file (bin/eml/json) By default number of pages saved depends on defined tag type. You can override this with option --end.", "notes": [ "hf mfu esave", "hf mfu esave --end 255 -> saves whole memory", @@ -6192,7 +6220,7 @@ }, "hf mfu eview": { "command": "hf mfu eview", - "description": "Displays emulator memory By default number of pages shown depends on defined tag type. You can overrife this with option --end.", + "description": "Displays emulator memory By default number of pages shown depends on defined tag type. You can override this with option --end.", "notes": [ "hf mfu eview", "hf mfu eview --end 255 -> dumps whole memory" @@ -10924,6 +10952,93 @@ ], "usage": "hf 14b ndefread [-hv] [-f ]" }, + "piv getdata": { + "command": "piv getdata", + "description": "Get a data container of a given tag", + "notes": [ + "piv getdata -s 5fc102 -> select card, select applet, get card holder unique identifer", + "piv getdata -st 5fc102 -> select card, select applet, get card holder unique identifer, show result in TLV" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-s, -S, --select Activate field and select applet", + "-k, -K, --keep Keep field for next command", + "-a, -A, --apdu Show APDU requests and responses", + "-t, -T, --tlv TLV decode results", + "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", + "--aid Applet ID to select. By default A0000003080000100 will be used", + " Tag ID to read, between 1 and 3 bytes." + ], + "usage": "piv getdata [-hskatw] [--aid ] " + }, + "piv help": { + "command": "piv help", + "description": "help This help list List ISO7816 history", + "notes": [], + "offline": true, + "options": [], + "usage": "" + }, + "piv list": { + "command": "piv list", + "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", + "notes": [ + "piv list --frame -> show frame delay times", + "piv list -1 -> use trace buffer" + ], + "offline": true, + "options": [ + "-h, --help This help", + "-1, --buffer use data from trace buffer", + "--frame show frame delay times", + "-c mark CRC bytes", + "-r show relative times (gap and duration)", + "-u display times in microseconds instead of clock cycles", + "-x show hexdump to convert to pcap(ng)", + "or to import into Wireshark using encapsulation type \"ISO 14443\"", + "-f, --file filename of dictionary" + ], + "usage": "piv list [-h1crux] [--frame] [-f ]" + }, + "piv scan": { + "command": "piv scan", + "description": "Scan a PIV card for known containers", + "notes": [ + "piv scan -s -> select card, select applet and run scan", + "piv scan -st --aid a00000030800001000 -> select card, select applet a00000030800001000, show result of the scan in TLV" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-s, -S, --select Activate field and select applet", + "-k, -K, --keep Keep field for next command", + "-a, -A, --apdu Show APDU requests and responses", + "-t, -T, --tlv TLV decode results", + "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", + "--aid Applet ID to select. By default A0000003080000100 will be used" + ], + "usage": "piv scan [-hskatw] [--aid ]" + }, + "piv select": { + "command": "piv select", + "description": "Executes select applet command", + "notes": [ + "piv select -s -> select card, select applet", + "piv select -st --aid a00000030800001000 -> select card, select applet a00000030800001000, show result in TLV" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-s, -S, --select Activate field and select applet", + "-k, -K, --keep Keep field for next command", + "-a, -A, --apdu Show APDU requests and responses", + "-t, -T, --tlv TLV decode results", + "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", + "--aid Applet ID to select. By default A0000003080000100 will be used" + ], + "usage": "piv select [-hskatw] [--aid ]" + }, "prefs get barmode": { "command": "prefs get barmode", "description": "Get preference of HF/LF tune command styled output in the client", @@ -11616,8 +11731,8 @@ } }, "metadata": { - "commands_extracted": 732, + "commands_extracted": 738, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2022-11-20T20:19:15" + "extracted_on": "2023-01-06T21:37:50" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 4b91901f4..bb4c68869 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -370,7 +370,7 @@ Check column "offline" for their availability. |`hf ksx6924 select `|N |`Select application, and leave field up` |`hf ksx6924 info `|N |`Get info about a KS X 6924 (T-Money, Snapper+) transit card` |`hf ksx6924 balance `|N |`Get current purse balance` -|`hf ksx6924 init `|N |`Perform transaction initialization with Mpda (Money of Purchase Transaction)` +|`hf ksx6924 init `|N |`Perform transaction initialization with Mpda` |`hf ksx6924 prec `|N |`Send proprietary get record command (CLA=90, INS=4C)` @@ -512,6 +512,7 @@ Check column "offline" for their availability. |`hf mf gen3freeze `|N |`Perma lock UID changes. irreversible` |`hf mf ggetblk `|N |`Read block from card` |`hf mf gload `|N |`Load dump to card` +|`hf mf gsave `|N |`Save dump from card into file or emulator` |`hf mf gsetblk `|N |`Write block to card` |`hf mf gview `|N |`View card` |`hf mf ndefformat `|N |`Format MIFARE Classic Tag as NFC Tag` @@ -1333,6 +1334,19 @@ Check column "offline" for their availability. |`nfc barcode help `|Y |`This help` +### piv + + { PIV commands... } + +|command |offline |description +|------- |------- |----------- +|`piv help `|Y |`This help` +|`piv select `|N |`Select the PIV applet` +|`piv getdata `|N |`Gets a container on a PIV card` +|`piv scan `|N |`Scan PIV card for known containers` +|`piv list `|Y |`List ISO7816 history` + + ### reveng { CRC calculations from RevEng software... } From fd39493cac591d0263db8a805c952e1f5ab60564 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 6 Jan 2023 23:57:02 +0100 Subject: [PATCH 458/759] cppcheck fixes --- client/src/cmdhflist.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index 68a050158..5a82db29e 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -942,14 +942,14 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { break; case MFDES_READ_DATA: if (data_size >= 7) { - snprintf(exp, size, "READ DATA (fileId %02x, offset %d, len %d)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); + snprintf(exp, size, "READ DATA (fileId %02x, offset %u, len %u)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); } else { snprintf(exp, size, "READ DATA"); } break; case MFDES_WRITE_DATA: if (data_size >= 7) { - snprintf(exp, size, "WRITE DATA (fileId %02x, offset %d, len %d)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); + snprintf(exp, size, "WRITE DATA (fileId %02x, offset %u, len %u)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); } else { snprintf(exp, size, "WRITE DATA"); } @@ -984,14 +984,14 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { break; case MFDES_WRITE_RECORD: if (data_size >= 7) { - snprintf(exp, size, "WRITE RECORD (fileId %02x, offset %d, len %d)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); + snprintf(exp, size, "WRITE RECORD (fileId %02x, offset %u, len %u)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); } else { snprintf(exp, size, "WRITE RECORD"); } break; case MFDES_READ_RECORDS: if (data_size >= 7) { - snprintf(exp, size, "READ RECORDS (fileId %02x, offset %d, len %d)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); + snprintf(exp, size, "READ RECORDS (fileId %02x, offset %u, len %u)", data[0], MemLeToUint3byte(data + 1), MemLeToUint3byte(data + 4)); } else { snprintf(exp, size, "READ RECORDS"); } @@ -1086,21 +1086,21 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { break; case MFDES_AUTHENTICATE: if (data_size >= 1) { - snprintf(exp, size, "AUTH NATIVE (keyNo %d)", data[0]); + snprintf(exp, size, "AUTH NATIVE (keyNo %u)", data[0]); } else { snprintf(exp, size, "AUTH NATIVE"); } break; // AUTHENTICATE_NATIVE case MFDES_AUTHENTICATE_ISO: if (data_size >= 1) { - snprintf(exp, size, "AUTH ISO (keyNo %d)", data[0]); + snprintf(exp, size, "AUTH ISO (keyNo %u)", data[0]); } else { snprintf(exp, size, "AUTH ISO"); } break; // AUTHENTICATE_STANDARD case MFDES_AUTHENTICATE_AES: if (data_size >= 1) { - snprintf(exp, size, "AUTH AES (keyNo %d)", data[0]); + snprintf(exp, size, "AUTH AES (keyNo %u)", data[0]); } else { snprintf(exp, size, "AUTH AES"); } @@ -1119,14 +1119,14 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { break; case MFDES_CHANGE_KEY: if (data_size >= 1) { - snprintf(exp, size, "CHANGE KEY (keyNo %d)", data[0]); + snprintf(exp, size, "CHANGE KEY (keyNo %u)", data[0]); } else { snprintf(exp, size, "CHANGE KEY"); } break; case MFDES_GET_KEY_VERSION: if (data_size >= 1) { - snprintf(exp, size, "GET KEY VERSION (keyNo %d)", data[0]); + snprintf(exp, size, "GET KEY VERSION (keyNo %u)", data[0]); } else { snprintf(exp, size, "GET KEY VERSION"); } From e6ecc5320fa41ca07523d9b6086613090dcf9eb5 Mon Sep 17 00:00:00 2001 From: nvx Date: Mon, 9 Jan 2023 00:57:28 +1000 Subject: [PATCH 459/759] Update armsrc and bootrom Makefiles with a .FORCE PHONY target for version_pm3.c This fixes issues in ProxSpace where the firmware .elf files are sometimes not rebuilt --- armsrc/Makefile | 4 ++-- bootrom/Makefile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index c0703ccf4..5024aa1de 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -185,7 +185,7 @@ showinfo: .DELETE_ON_ERROR: # version_pm3.c should be remade on every time fullimage.stage1.elf should be remade -version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) +version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE $(info [-] GEN $@) $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ @@ -257,7 +257,7 @@ uninstall: $(info [@] Uninstalling fullimage from $(DESTDIR)$(PREFIX)...) $(Q)$(INSTALLSUDO) $(RM) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(INSTALLFWTAG) -.PHONY: all clean help install uninstall +.PHONY: all clean help install uninstall .FORCE help: @echo Multi-OS Makefile, you are running on $(DETECTED_OS) @echo Possible targets: diff --git a/bootrom/Makefile b/bootrom/Makefile index ec531f1af..edb0cc990 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -48,7 +48,7 @@ INSTALLFW = $(OBJDIR)/bootrom.elf OBJS = $(OBJDIR)/bootrom.s19 # version_pm3.c should be remade on every compilation -version_pm3.c: default_version_pm3.c +version_pm3.c: default_version_pm3.c .FORCE $(info [=] GEN $@) $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@ @@ -82,7 +82,7 @@ uninstall: $(info [@] Uninstalling bootrom from $(DESTDIR)$(PREFIX)...) $(Q)$(INSTALLSUDO) $(RM) $(foreach fw,$(INSTALLFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw))) -.PHONY: all clean help install showinfo +.PHONY: all clean help install showinfo .FORCE help: @echo Multi-OS Makefile, you are running on $(DETECTED_OS) @echo Possible targets: From ab3a8f4121097eed4831989d00f2b786b7c72fa1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Jan 2023 19:27:41 +0100 Subject: [PATCH 460/759] fix helptext --- client/luascripts/lf_ident_json.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/luascripts/lf_ident_json.lua b/client/luascripts/lf_ident_json.lua index fb0d82554..73794547c 100644 --- a/client/luascripts/lf_ident_json.lua +++ b/client/luascripts/lf_ident_json.lua @@ -6,7 +6,7 @@ local ac = require('ansicolors') copyright = '' author = "Christian Herrmann" -version = 'v1.0.0' +version = 'v1.0.1' desc = [[ This script loads a json format file, with the field "data" and a hexbyte array of data. Ie t55x7 dump, it tries to identify which system based on block1, and detect block0 settings. @@ -16,7 +16,7 @@ example = [[ script run lf_ident_json -i lf_t55xx.json ]] usage = [[ -script run lf_en4100_bulk.lua [-h] [-c] [-p password] [-s ] [-v] +script run lf_ident_json.lua [-h] [-c] [-p password] [-s ] [-v] ]] arguments = [[ -h : this help From 2206271ba3c3d042be8040538a85866f54b21c25 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Jan 2023 19:29:02 +0100 Subject: [PATCH 461/759] renamed script to follow name convention --- .../{hf_mf_dump-luxeo.lua => hf_mf_dump_luxeo.lua} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename client/luascripts/{hf_mf_dump-luxeo.lua => hf_mf_dump_luxeo.lua} (98%) diff --git a/client/luascripts/hf_mf_dump-luxeo.lua b/client/luascripts/hf_mf_dump_luxeo.lua similarity index 98% rename from client/luascripts/hf_mf_dump-luxeo.lua rename to client/luascripts/hf_mf_dump_luxeo.lua index 2b2c5d9c7..aaf7d572f 100644 --- a/client/luascripts/hf_mf_dump-luxeo.lua +++ b/client/luascripts/hf_mf_dump_luxeo.lua @@ -1,7 +1,7 @@ --- -- This Lua script is designed to run with Iceman/RRG Proxmark3 fork -- Just copy hf_mf_dump-luxeo.lua to client/luascripts/ --- and run "script run hf_mf_dump-luxeo" +-- and run "script run hf_mf_dump_luxeo" -- requirements local cmds = require('commands') @@ -12,16 +12,16 @@ local ansicolors = require('ansicolors') copyright = '' author = '0xdrrb' -version = 'v0.1.2' +version = 'v0.1.3' desc = [[ This is a script that tries to dump and decrypt the data of a specific type of Mifare laundromat token. OBS! Tag must be on the antenna. ]] example = [[ - script run hf_mf_dump-luxeo + script run hf_mf_dump_luxeo ]] usage = [[ -script run hf_mf_dump-luxeo +script run hf_mf_dump_luxeo ]] arguments = [[ -h This help From 82d4b3194243a3873a0100ffdd3cbef6ccd52598 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Jan 2023 19:30:55 +0100 Subject: [PATCH 462/759] renamed to follow name convention --- .../{hf_mfu_uidkeycalc-italy.lua => hf_mfu_uidkeycalc_italy.lua} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename client/luascripts/{hf_mfu_uidkeycalc-italy.lua => hf_mfu_uidkeycalc_italy.lua} (100%) diff --git a/client/luascripts/hf_mfu_uidkeycalc-italy.lua b/client/luascripts/hf_mfu_uidkeycalc_italy.lua similarity index 100% rename from client/luascripts/hf_mfu_uidkeycalc-italy.lua rename to client/luascripts/hf_mfu_uidkeycalc_italy.lua From d1aa57ac5d0c20d38b1c3e9e60f1e055ea77894b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Jan 2023 19:31:22 +0100 Subject: [PATCH 463/759] update text --- client/luascripts/hf_mfu_uidkeycalc_italy.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/luascripts/hf_mfu_uidkeycalc_italy.lua b/client/luascripts/hf_mfu_uidkeycalc_italy.lua index 4777a186d..d2fbdadde 100644 --- a/client/luascripts/hf_mfu_uidkeycalc_italy.lua +++ b/client/luascripts/hf_mfu_uidkeycalc_italy.lua @@ -6,20 +6,20 @@ local ansicolors = require('ansicolors') copyright = '' author = "Iceman" -version = 'v1.0.1' +version = 'v1.0.2' desc = [[ This script calculates mifare Ultralight-EV1 pwd based on uid diversification for an Italian ticketsystem Algo not found by me. ]] example =[[ -- if called without, it reads tag uid - script run hf_mfu_uidkeycalc-italy + script run hf_mfu_uidkeycalc_italy -- - script run hf_mfu_uidkeycalc-italy -u 11223344556677 + script run hf_mfu_uidkeycalc_italy -u 11223344556677 ]] usage = [[ -script run hf_mfu_uidkeycalc-italy -h -u " +script run hf_mfu_uidkeycalc_italy -h -u " ]] arguments = [[ -h : this help From 19dd580b3b6e54da3ccbbcbbf90096e39666a8cc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Jan 2023 21:52:30 +0100 Subject: [PATCH 464/759] adapt file path checks --- client/src/ui.c | 99 +++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/client/src/ui.c b/client/src/ui.c index 0ffabc341..00eb8d022 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -84,6 +84,43 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam int result; #ifdef _WIN32 struct _stat st; + // Mingw _stat fails if path ends with /, so let's use a stripped path + if (str_endswith(path, PATHSEP)) + + memset(path + (strlen(path) - strlen(PATHSEP)), 0x00, strlen(PATHSEP)); + result = _stat(path, &st); + strncat(path, PATHSEP, strlen(PATHSEP)); +} else { + result = _stat(path, &st); +} +#else + struct stat st; + result = stat(path, &st); +#endif +if ((result != 0) && create_home) { + +#ifdef _WIN32 + if (_mkdir(path)) +#else + if (mkdir(path, 0700)) +#endif + { + fprintf(stderr, "Could not create user directory %s\n", path); + free(path); + return PM3_EFILE; + } +} +if (subdir != NULL) { + pathlen += strlen(subdir); + char *tmp = realloc(path, pathlen * sizeof(char)); + if (tmp == NULL) { + //free(path); + return PM3_EMALLOC; + } + path = tmp; + strcat(path, subdir); + +#ifdef _WIN32 // Mingw _stat fails if path ends with /, so let's use a stripped path if (path[strlen(path) - 1] == '/') { path[strlen(path) - 1] = '\0'; @@ -93,7 +130,6 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam result = _stat(path, &st); } #else - struct stat st; result = stat(path, &st); #endif if ((result != 0) && create_home) { @@ -109,58 +145,23 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam return PM3_EFILE; } } - if (subdir != NULL) { - pathlen += strlen(subdir); - char *tmp = realloc(path, pathlen * sizeof(char)); - if (tmp == NULL) { - //free(path); - return PM3_EMALLOC; - } - path = tmp; - strcat(path, subdir); +} -#ifdef _WIN32 - // Mingw _stat fails if path ends with /, so let's use a stripped path - if (path[strlen(path) - 1] == '/') { - path[strlen(path) - 1] = '\0'; - result = _stat(path, &st); - path[strlen(path)] = '/'; - } else { - result = _stat(path, &st); - } -#else - result = stat(path, &st); -#endif - if ((result != 0) && create_home) { - -#ifdef _WIN32 - if (_mkdir(path)) -#else - if (mkdir(path, 0700)) -#endif - { - fprintf(stderr, "Could not create user directory %s\n", path); - free(path); - return PM3_EFILE; - } - } - } - - if (filename == NULL) { - *foundpath = path; - return PM3_SUCCESS; - } - pathlen += strlen(filename); - char *tmp = realloc(path, pathlen * sizeof(char)); - if (tmp == NULL) { - //free(path); - return PM3_EMALLOC; - } - path = tmp; - strcat(path, filename); +if (filename == NULL) { *foundpath = path; return PM3_SUCCESS; } +pathlen += strlen(filename); +char *tmp = realloc(path, pathlen *sizeof(char)); +if (tmp == NULL) { + //free(path); + return PM3_EMALLOC; +} +path = tmp; +strcat(path, filename); +*foundpath = path; +return PM3_SUCCESS; +} void PrintAndLogOptions(const char *str[][2], size_t size, size_t space) { char buff[2000] = "Options:\n"; From df05e28923a2674275d7f96bd35cd97ef11e990b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Jan 2023 21:54:46 +0100 Subject: [PATCH 465/759] added a fingerprint test for OTP algos --- client/src/cmdhfmfu.c | 74 ++++++++++++++++++++++++++++++++++++++++--- common/generator.c | 6 ++++ common/generator.h | 2 ++ 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index e948360e6..00df6e710 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -65,7 +65,7 @@ static uint8_t default_3des_keys[][16] = { static uint8_t default_pwd_pack[][4] = { {0xFF, 0xFF, 0xFF, 0xFF}, // PACK 0x00,0x00 -- factory default - {0x4E, 0x45, 0x78, 0x54}, + {0x4E, 0x45, 0x78, 0x54}, // NExT }; static uint32_t UL_TYPES_ARRAY[] = { @@ -1144,6 +1144,46 @@ Lego Dimensions, E1 10 12 00 01 03 A0 0C 34 03 13 D1 01 0F 54 02 65 6E */ +typedef struct { + const char *desc; + uint8_t mpos; + uint8_t mlen; + const char *match; + uint32_t (*otp)(const uint8_t *uid); + const char *hint; +} mfu_otp_identify_t; + +static mfu_otp_identify_t mfu_otp_ident_table[] = { + { "SALTO", 12, 4, "534C544F", ul_c_otpgenA, NULL }, +// { "SAFLOK", 12, 4, NULL, ul_c_otpgenB, NULL }, +// { "VINGCARD", 12, 4, NULL, ul_c_otpgenC, NULL }, +// { "DORMA KABA", 12, 4, NULL, ul_c_otpgenD, NULL }, + { NULL, 0, 0, NULL, NULL, NULL } +}; + +static mfu_otp_identify_t *mfu_match_otp_fingerprint(uint8_t *data) { + uint8_t i = 0; + do { + int ml = 0; + uint8_t mtmp[40] = {0}; + + // static or dynamic created OTP to fingerprint. + if (mfu_otp_ident_table[i].match) { + param_gethex_to_eol(mfu_otp_ident_table[i].match, 0, mtmp, sizeof(mtmp), &ml); + } else { + uint32_t otp = mfu_otp_ident_table[i].otp(data); + num_to_bytes(otp, 4, mtmp); + } + + bool m2 = (memcmp(mtmp, data + mfu_otp_ident_table[i].mpos, mfu_otp_ident_table[i].mlen) == 0); + if (m2) { + PrintAndLogEx(DEBUG, "(fingerprint) found %s", mfu_otp_ident_table[i].desc); + return &mfu_otp_ident_table[i]; + } + } while (mfu_otp_ident_table[++i].desc); + return NULL; +} + typedef struct { const char *desc; const char *version; @@ -1184,7 +1224,7 @@ static mfu_identify_t mfu_ident_table[] = { "Snackworld", "0004040101000B03", 9, 7, "483000E1100600", NULL, NULL, - "hf mfu dump -k %08x" + "hf mfu dump -k" }, { "Amiibo", "0004040201001103", @@ -1324,15 +1364,36 @@ static int mfu_fingerprint(TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authke if (item) { PrintAndLogEx(SUCCESS, "Found " _GREEN_("%s"), item->desc); - if (item->Pwd) { + if (item->hint) { + if (item->Pwd) { + char s[40] = {0}; + snprintf(s, sizeof(s), item->hint, item->Pwd(uid)); + PrintAndLogEx(HINT, "Use `" _YELLOW_("%s") "`", s); + } else { + PrintAndLogEx(HINT, "Use `" _YELLOW_("%s") "`", item->hint); + } + } + } + } + + // OTP checks + mfu_otp_identify_t *item = mfu_match_otp_fingerprint(data); + if (item) { + PrintAndLogEx(SUCCESS, "Found " _GREEN_("%s"), item->desc); + + if (item->hint) { + if (item->otp) { char s[40] = {0}; - snprintf(s, sizeof(s), item->hint, item->Pwd(uid)); + snprintf(s, sizeof(s), item->hint, item->otp(uid)); PrintAndLogEx(HINT, "Use `" _YELLOW_("%s") "`", s); } else { PrintAndLogEx(HINT, "Use `" _YELLOW_("%s") "`", item->hint); } } } + // + + out: free(data); @@ -3248,7 +3309,7 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { PrintAndLogEx(INFO, "----------------------------------"); PrintAndLogEx(INFO, " algo | pwd | pack"); PrintAndLogEx(INFO, "-----------------+----------+-----"); - PrintAndLogEx(INFO, " EV1 | %08X | %04X", ul_ev1_pwdgenA(uid), ul_ev1_packgenA(uid)); + PrintAndLogEx(INFO, " Transport EV1 | %08X | %04X", ul_ev1_pwdgenA(uid), ul_ev1_packgenA(uid)); PrintAndLogEx(INFO, " Amiibo | %08X | %04X", ul_ev1_pwdgenB(uid), ul_ev1_packgenB(uid)); PrintAndLogEx(INFO, " Lego Dimension | %08X | %04X", ul_ev1_pwdgenC(uid), ul_ev1_packgenC(uid)); PrintAndLogEx(INFO, " XYZ 3D printer | %08X | %04X", ul_ev1_pwdgenD(uid), ul_ev1_packgenD(uid)); @@ -3256,6 +3317,9 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) { PrintAndLogEx(INFO, " NTAG tools | %08X | %04X", ul_ev1_pwdgenF(uid), ul_ev1_packgen_def(uid)); PrintAndLogEx(INFO, "-----------------+----------+-----"); PrintAndLogEx(INFO, " Vingcard algo"); + PrintAndLogEx(INFO, " Saflok algo"); + PrintAndLogEx(INFO, " SALTO algo"); + PrintAndLogEx(INFO, " Dorma Kaba algo"); PrintAndLogEx(INFO, "----------------------------------"); return PM3_SUCCESS; } diff --git a/common/generator.c b/common/generator.c index 41bd49d89..852ea2b61 100644 --- a/common/generator.c +++ b/common/generator.c @@ -240,6 +240,12 @@ uint16_t ul_ev1_packgen_def(const uint8_t *uid) { return 0x0000; } +// MIFARE ULTRALIGHT OTP generators +uint32_t ul_c_otpgenA(const uint8_t *uid) { + return 0x534C544F; +} + + //------------------------------------ // MFC key generation stuff // Each algo implementation should offer two key generation functions. diff --git a/common/generator.h b/common/generator.h index 5fc81ba25..1008d01fa 100644 --- a/common/generator.h +++ b/common/generator.h @@ -36,6 +36,8 @@ uint16_t ul_ev1_packgenC(const uint8_t *uid); uint16_t ul_ev1_packgenD(const uint8_t *uid); uint16_t ul_ev1_packgenE(const uint8_t *uid); +uint32_t ul_c_otpgenA(const uint8_t *uid); + int mfc_algo_ving_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key); int mfc_algo_ving_all(uint8_t *uid, uint8_t *keys); From 6ad73d25fd49b40c11c87c31af979ccbb609735f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Jan 2023 21:55:38 +0100 Subject: [PATCH 466/759] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4278b6c12..0652edf2b 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] + - Changed `hf mfu info` - now also does a simple OTP fingerprinting (@iceman1001) - Changed `hf mf wrbl` - now checks for strict readonly ACL's in the data to write (@iceman1001) - Changed `hf mf view` - verbose printing if strict readonly ACL's exists in dump file (@iceman1001) - Add command `piv authsign` to get a buffer signed by the selected key (@jmichelp) From 6cbebb29dc20f488a6e30d86b02c8ce78540538f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 8 Jan 2023 21:56:38 +0100 Subject: [PATCH 467/759] mingw seems to doesnt like backslashes --- include/common.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/common.h b/include/common.h index bb3781c4a..a97545996 100644 --- a/include/common.h +++ b/include/common.h @@ -24,8 +24,8 @@ #include #ifdef _WIN32 -#define ABOVE "..\\" -#define PATHSEP "\\" +#define ABOVE "../" +#define PATHSEP "/" #else #define ABOVE "../" #define PATHSEP "/" @@ -60,7 +60,7 @@ struct version_information_t { char clean; /* 1: Tree was clean, no local changes. 0: Tree was unclean. 2: Couldn't be determined */ char gitversion[50]; /* String with the git revision */ char buildtime[30]; /* string with the build time */ - char armsrc[10]; /* sha256sum of sha256sum of armsrc files */ + char armsrc[10]; /* sha256sum of sha256sum of armsrc && common_arm files */ } PACKED; // debug From 52893085451b91486c6ce36e5087a27bd0618c97 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Jan 2023 00:03:46 +0100 Subject: [PATCH 468/759] missing a bracket --- client/src/ui.c | 128 +++++++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 61 deletions(-) diff --git a/client/src/ui.c b/client/src/ui.c index 00eb8d022..ff885af37 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -23,7 +23,6 @@ #endif #include "ui.h" #include "commonutil.h" // ARRAYLEN - #include // for Mingw readline #include #include @@ -62,10 +61,18 @@ pthread_mutex_t g_print_lock = PTHREAD_MUTEX_INITIALIZER; static void fPrintAndLog(FILE *stream, const char *fmt, ...); +#ifdef _WIN32 + #define MKDIR_CHK _mkdir(path) +#else + #define MKDIR_CHK mkdir(path, 0700) +#endif + + // needed by flasher, so let's put it here instead of fileutils.c int searchHomeFilePath(char **foundpath, const char *subdir, const char *filename, bool create_home) { - if (foundpath == NULL) + if (foundpath == NULL) { return PM3_EINVARG; + } const char *user_path = get_my_user_directory(); if (user_path == NULL) { @@ -75,93 +82,92 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam size_t pathlen = strlen(user_path) + strlen(PM3_USER_DIRECTORY) + 1; char *path = calloc(pathlen, sizeof(char)); - if (path == NULL) + if (path == NULL) { return PM3_EMALLOC; + } strcpy(path, user_path); strcat(path, PM3_USER_DIRECTORY); int result; + #ifdef _WIN32 struct _stat st; // Mingw _stat fails if path ends with /, so let's use a stripped path - if (str_endswith(path, PATHSEP)) - - memset(path + (strlen(path) - strlen(PATHSEP)), 0x00, strlen(PATHSEP)); - result = _stat(path, &st); - strncat(path, PATHSEP, strlen(PATHSEP)); -} else { - result = _stat(path, &st); -} -#else - struct stat st; - result = stat(path, &st); -#endif -if ((result != 0) && create_home) { - -#ifdef _WIN32 - if (_mkdir(path)) -#else - if (mkdir(path, 0700)) -#endif - { - fprintf(stderr, "Could not create user directory %s\n", path); - free(path); - return PM3_EFILE; - } -} -if (subdir != NULL) { - pathlen += strlen(subdir); - char *tmp = realloc(path, pathlen * sizeof(char)); - if (tmp == NULL) { - //free(path); - return PM3_EMALLOC; - } - path = tmp; - strcat(path, subdir); - -#ifdef _WIN32 - // Mingw _stat fails if path ends with /, so let's use a stripped path - if (path[strlen(path) - 1] == '/') { - path[strlen(path) - 1] = '\0'; + if (str_endswith(path, PATHSEP)) { + memset(path + (strlen(path) - strlen(PATHSEP)), 0x00, strlen(PATHSEP)); result = _stat(path, &st); - path[strlen(path)] = '/'; + strncat(path, PATHSEP, strlen(PATHSEP)); } else { result = _stat(path, &st); } #else + struct stat st; result = stat(path, &st); #endif + if ((result != 0) && create_home) { -#ifdef _WIN32 - if (_mkdir(path)) -#else - if (mkdir(path, 0700)) -#endif + if (MKDIR_CHK) { fprintf(stderr, "Could not create user directory %s\n", path); free(path); return PM3_EFILE; } } -} -if (filename == NULL) { + if (subdir != NULL) { + pathlen += strlen(subdir); + char *tmp = realloc(path, pathlen * sizeof(char)); + if (tmp == NULL) { + //free(path); + return PM3_EMALLOC; + } + path = tmp; + strcat(path, subdir); + +#ifdef _WIN32 + // Mingw _stat fails if path ends with /, so let's use a stripped path + if (str_endswith(path, PATHSEP)) { + memset(path + (strlen(path) - strlen(PATHSEP)), 0x00, strlen(PATHSEP)); + result = _stat(path, &st); + strncat(path, PATHSEP, strlen(PATHSEP)); + } else { + result = _stat(path, &st); + } +#else + result = stat(path, &st); +#endif + + if ((result != 0) && create_home) { + + if (MKDIR_CHK) + { + fprintf(stderr, "Could not create user directory %s\n", path); + free(path); + return PM3_EFILE; + } + } + } + + if (filename == NULL) { + *foundpath = path; + return PM3_SUCCESS; + } + + pathlen += strlen(filename); + char *tmp = realloc(path, pathlen *sizeof(char)); + if (tmp == NULL) { + //free(path); + return PM3_EMALLOC; + } + + path = tmp; + strcat(path, filename); *foundpath = path; + return PM3_SUCCESS; } -pathlen += strlen(filename); -char *tmp = realloc(path, pathlen *sizeof(char)); -if (tmp == NULL) { - //free(path); - return PM3_EMALLOC; -} -path = tmp; -strcat(path, filename); -*foundpath = path; -return PM3_SUCCESS; -} void PrintAndLogOptions(const char *str[][2], size_t size, size_t space) { char buff[2000] = "Options:\n"; From f2185b393363a61baf4beaac32b6fe13793d5617 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Jan 2023 00:48:42 +0100 Subject: [PATCH 469/759] use strcat instead of strncat, we are adding same as we removed --- client/src/ui.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/src/ui.c b/client/src/ui.c index ff885af37..839dd22b0 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -88,7 +88,6 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam strcpy(path, user_path); strcat(path, PM3_USER_DIRECTORY); - int result; #ifdef _WIN32 @@ -97,7 +96,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam if (str_endswith(path, PATHSEP)) { memset(path + (strlen(path) - strlen(PATHSEP)), 0x00, strlen(PATHSEP)); result = _stat(path, &st); - strncat(path, PATHSEP, strlen(PATHSEP)); + strcat(path, PATHSEP); } else { result = _stat(path, &st); } @@ -131,7 +130,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam if (str_endswith(path, PATHSEP)) { memset(path + (strlen(path) - strlen(PATHSEP)), 0x00, strlen(PATHSEP)); result = _stat(path, &st); - strncat(path, PATHSEP, strlen(PATHSEP)); + strcat(path, PATHSEP); } else { result = _stat(path, &st); } From 90b1cb795400d993e42480dd3149a8043ecb9f0b Mon Sep 17 00:00:00 2001 From: George Talusan Date: Mon, 9 Jan 2023 10:35:15 -0500 Subject: [PATCH 470/759] fix off-by-1 when removing header in hf_mfu_amiibo_restore --- client/luascripts/hf_mfu_amiibo_restore.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/luascripts/hf_mfu_amiibo_restore.lua b/client/luascripts/hf_mfu_amiibo_restore.lua index b83f3feb1..c31db7098 100644 --- a/client/luascripts/hf_mfu_amiibo_restore.lua +++ b/client/luascripts/hf_mfu_amiibo_restore.lua @@ -105,7 +105,7 @@ local function main(args) -- chomp emu header if #hex == 1192 then - hex = hex:sub(112) + hex = hex:sub(113) end local amiibo_offset = 0 From 73a80fb07db22f3cba56f8e3ef7c205f1a378441 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Jan 2023 22:08:59 +0100 Subject: [PATCH 471/759] hf mf wrbl, restore - changed the logic of --force param. It is now used to override warnings about BLOCK0 and bad ACL block data and allow the user to write it regardless of its consequences.\n You can easily brick sectors on genuine or Gen2 cards.\n Be aware, here be dragons! --- client/src/cmdhfmf.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index eba190b5e..2ea197cf7 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -507,7 +507,10 @@ static int CmdHF14AMfWrBl(const char *Cmd) { "Sector 0 / Block 0 - Manufacturer block\n" "When writing to block 0 you must use a VALID block 0 data (UID, BCC, SAK, ATQA)\n" "Writing an invalid block 0 means rendering your Magic GEN2 card undetectable. \n" - "Look in the magic_cards_notes.md file for help to resolve it.", + "Look in the magic_cards_notes.md file for help to resolve it.\n" + " \n" + "`--force` param is used to override warnings like bad ACL and BLOCK 0 writes.\n" + " if not specified, it will exit if detected", "hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 000102030405060708090a0b0c0d0e0f" ); void *argtable[] = { @@ -515,7 +518,7 @@ static int CmdHF14AMfWrBl(const char *Cmd) { arg_int1(NULL, "blk", "", "block number"), arg_lit0("a", NULL, "input key type is key A (def)"), arg_lit0("b", NULL, "input key type is key B"), - arg_lit0(NULL, "force", "enforce block0 writes"), + arg_lit0(NULL, "force", "override warnings"), arg_str0("k", "key", "", "key, 6 hex bytes"), arg_str0("d", "data", "", "bytes to write, 16 hex bytes"), @@ -553,6 +556,8 @@ static int CmdHF14AMfWrBl(const char *Cmd) { if (b > 255) { return PM3_EINVARG; } + + // BLOCK 0 detection if (b == 0 && force == false) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "Targeting Sector 0 / Block 0 - Manufacturer block"); @@ -564,13 +569,14 @@ static int CmdHF14AMfWrBl(const char *Cmd) { uint8_t blockno = (uint8_t)b; - // Warn if ACL is strict read-only + // Sector trailer sanity checks. + // Warn if ACL is strict read-only, or invalid ACL. if (mfIsSectorTrailer(blockno)) { PrintAndLogEx(INFO, "Sector trailer (ST) write detected"); // ensure access right isn't messed up. if (mfValidateAccessConditions(&block[6]) == false) { - PrintAndLogEx(WARNING, "Invalid Access Conditions detected, replacing by default values"); + PrintAndLogEx(WARNING, "Invalid Access Conditions detected, replacing with default values"); memcpy(block + 6, "\xFF\x07\x80\x69", 4); } @@ -583,8 +589,13 @@ static int CmdHF14AMfWrBl(const char *Cmd) { } } if (ro_detected) { - PrintAndLogEx(INFO, "Exiting, please run `" _YELLOW_("hf mf acl -d %s") "` to understand", sprint_hex_inrow(&block[6], 3)); - return PM3_EINVARG; + if (force) { + PrintAndLogEx(WARNING, " --force override, continuing..."); + } else { + PrintAndLogEx(INFO, "Exiting, please run `" _YELLOW_("hf mf acl -d %s") "` to understand", sprint_hex_inrow(&block[6], 3)); + PrintAndLogEx(INFO, "Use `" _YELLOW_("--force") "` to override and write this data"); + return PM3_EINVARG; + } } else { PrintAndLogEx(SUCCESS, "ST passed checks, continuing..."); } @@ -1079,9 +1090,11 @@ static int CmdHF14AMfRestore(const char *Cmd) { "If access rights in dump file is all zeros, it will be replaced with default values\n" "\n" "`--uid` param is used for filename templates `hf-mf--dump.bin` and `hf-mf--key.bin.\n" - " If not specified, it will read the card uid instead.\n" + " if not specified, it will read the card uid instead.\n" " `--ka` param you can indicate that the key file should be used for authentication instead.\n" - " if so we also try both B/A keys", + " if so we also try both B/A keys\n" + "`--force` param is used to override warnings and allow bad ACL block writes.\n" + " if not specified, it will skip blocks with bad ACL.\n", "hf mf restore\n" "hf mf restore --1k --uid 04010203\n" "hf mf restore --1k --uid 04010203 -k hf-mf-AABBCCDD-key.bin\n" @@ -1098,6 +1111,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { arg_str0("f", "file", "", "specify dump filename (bin/eml/json)"), arg_str0("k", "kfn", "", "key filename"), arg_lit0(NULL, "ka", "use specified keyfile to authenticate"), + arg_lit0(NULL, "force", "override warnings"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1120,6 +1134,8 @@ static int CmdHF14AMfRestore(const char *Cmd) { CLIParamStrToBuf(arg_get_str(ctx, 7), (uint8_t *)keyfilename, FILE_PATH_SIZE, &keyfnlen); bool use_keyfile_for_auth = arg_get_lit(ctx, 8); + bool force = arg_get_lit(ctx, 9); + CLIParserFree(ctx); // validations @@ -1256,7 +1272,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { // ensure access right isn't messed up. if (mfValidateAccessConditions(&bldata[6]) == false) { - PrintAndLogEx(WARNING, "Invalid Access Conditions on sector %i, replacing by default values", s); + PrintAndLogEx(WARNING, "Invalid Access Conditions on sector %i, replacing with default values", s); memcpy(bldata + 6, "\xFF\x07\x80\x69", 4); } @@ -1264,6 +1280,12 @@ static int CmdHF14AMfRestore(const char *Cmd) { for (uint8_t foo = 0; foo < mfNumBlocksPerSector(s); foo++) { if (mfReadOnlyAccessConditions(foo, &bldata[6])) { PrintAndLogEx(WARNING, "Strict ReadOnly Access Conditions on block " _YELLOW_("%u") " detected", foo); + + // if --force isn't used, skip writing this block + if (force == false) { + PrintAndLogEx(INFO, "Skipping, use `" _YELLOW_("--force") "` to override and write this data"); + continue; + } } } } From 21de6e750cc2b89990145e0dbe58522e438c9d3f Mon Sep 17 00:00:00 2001 From: Benjamin DELPY Date: Wed, 11 Jan 2023 23:31:23 +0100 Subject: [PATCH 472/759] Added standalone mode for simulatin Nedap ID --- CHANGELOG.md | 1 + armsrc/Standalone/Makefile.hal | 5 +- armsrc/Standalone/Makefile.inc | 4 + armsrc/Standalone/lf_nedap_sim.c | 221 ++++++++++++++++++ .../4_Advanced-compilation-parameters.md | 1 + tools/build_all_firmwares.sh | 2 +- 6 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 armsrc/Standalone/lf_nedap_sim.c diff --git a/CHANGELOG.md b/CHANGELOG.md index 0652edf2b..9867f7f70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - Fixed `make accessrights` on Fedora (@mooey5775) + - Added standalone mode for simulatin Nedap ID ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 6b4510da8..afd144e5d 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -53,6 +53,9 @@ define KNOWN_STANDALONE_DEFINITIONS | LF_NEXID | LF Nexwatch collector to flashmem | | (RDV4 only) | | +----------------------------------------------------------+ +| LF_NEDAP_SIM | LF Nedap ID simple simulator | +| | | ++----------------------------------------------------------+ | LF_PROXBRUTE | HID ProxII bruteforce | | | - Brad Antoniewicz | +----------------------------------------------------------+ @@ -118,7 +121,7 @@ define KNOWN_STANDALONE_DEFINITIONS +----------------------------------------------------------+ endef -STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID +STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID LF_NEDAP_SIM STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI STANDALONE_MODES_REQ_BT := HF_REBLAY STANDALONE_MODES_REQ_SMARTCARD := diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index 05a63f1dd..1df076414 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -133,6 +133,10 @@ endif ifneq (,$(findstring WITH_STANDALONE_HF_MFCSIM,$(APP_CFLAGS))) SRC_STANDALONE = hf_mfcsim.c endif +# WITH_STANDALONE_LF_NEDAP_SIM +ifneq (,$(findstring WITH_STANDALONE_LF_NEDAP_SIM,$(APP_CFLAGS))) + SRC_STANDALONE = lf_nedap_sim.c +endif ifneq (,$(findstring WITH_STANDALONE_DANKARMULTI,$(APP_CFLAGS))) SRC_STANDALONE = dankarmulti.c diff --git a/armsrc/Standalone/lf_nedap_sim.c b/armsrc/Standalone/lf_nedap_sim.c new file mode 100644 index 000000000..491199c27 --- /dev/null +++ b/armsrc/Standalone/lf_nedap_sim.c @@ -0,0 +1,221 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// This simple mode encode, then emulate a Nedap identificator until button pressed +// lots of code from client side, cmdlfnedap, util, etc. +//----------------------------------------------------------------------------- +#include "standalone.h" // standalone definitions +#include "proxmark3_arm.h" +#include "appmain.h" +#include "fpgaloader.h" +#include "lfops.h" +#include "util.h" +#include "dbprint.h" +#include "string.h" +#include "BigBuf.h" +#include "crc16.h" + +#define MODULE_LONG_NAME "LF Nedap simple simulator" + +typedef struct _NEDAP_TAG { + uint8_t subType; + uint16_t customerCode; + uint32_t id; + + uint8_t bIsLong; +} NEDAP_TAG, *PNEDAP_TAG; + +const NEDAP_TAG Tag = {.subType = 0x5, .customerCode = 0x123, .id = 42424, .bIsLong = 1}; + +static int NedapPrepareBigBuffer(const NEDAP_TAG *pTag); +static void biphaseSimBitInverted(uint8_t c, int *n, uint8_t *phase); +static void NedapGen(uint8_t subType, uint16_t customerCode, uint32_t id, bool isLong, uint8_t *data); +static uint8_t isEven_64_63(const uint8_t *data); +static inline uint32_t bitcount32(uint32_t a); +static void bytes_to_bytebits(const void *src, const size_t srclen, void *dest); + +void ModInfo(void) +{ + DbpString(" " MODULE_LONG_NAME); +} + +void RunMod(void) +{ + int n; + + StandAloneMode(); + + Dbprintf("[=] " MODULE_LONG_NAME " -- started"); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + Dbprintf("[=] NEDAP (%s) - ID: " _GREEN_("%05u") " subtype: " _GREEN_("%1u") " customer code: " _GREEN_("%u / 0x%03X"), Tag.bIsLong ? "128b" : "64b", Tag.id, Tag.subType, Tag.customerCode, Tag.customerCode); + + n = NedapPrepareBigBuffer(&Tag); + do + { + WDT_HIT(); + + if (data_available()) + break; + + SimulateTagLowFrequency(n, 0, true); + + } while (BUTTON_HELD(1000) == BUTTON_NO_CLICK); + + Dbprintf("[=] " MODULE_LONG_NAME " -- exiting"); + + LEDsoff(); +} + +static int NedapPrepareBigBuffer(const NEDAP_TAG *pTag) +{ + int ret = 0; + uint8_t data[16], bitStream[sizeof(data) * 8], phase = 0; + uint16_t i, size = pTag->bIsLong ? sizeof(data) : (sizeof(data) / 2); + + NedapGen(pTag->subType, pTag->customerCode, pTag->id, pTag->bIsLong, data); + bytes_to_bytebits(data, size, bitStream); + size <<= 3; + + for (i = 0; i < size; i++) + { + biphaseSimBitInverted(!bitStream[i], &ret, &phase); + } + if (phase == 1) //run a second set inverted to keep phase in check + { + for (i = 0; i < size; i++) + { + biphaseSimBitInverted(!bitStream[i], &ret, &phase); + } + } + + return ret; +} + +static void biphaseSimBitInverted(uint8_t c, int *n, uint8_t *phase) +{ + uint8_t *dest = BigBuf_get_addr(); + + if (c) + { + memset(dest + (*n), c ^ 1 ^ *phase, 32); + memset(dest + (*n) + 32, c ^ *phase, 32); + } + else + { + memset(dest + (*n), c ^ *phase, 64); + *phase ^= 1; + } + *n += 64; +} + +#define FIXED_71 0x71 +#define FIXED_40 0x40 +#define UNKNOWN_A 0x00 +#define UNKNOWN_B 0x00 +static const uint8_t translateTable[10] = {8, 2, 1, 12, 4, 5, 10, 13, 0, 9}; +static void NedapGen(uint8_t subType, uint16_t customerCode, uint32_t id, bool isLong, uint8_t *data) { // 8 or 16 + uint8_t buffer[7]; + + uint8_t r1 = (uint8_t)(id / 10000); + uint8_t r2 = (uint8_t)((id % 10000) / 1000); + uint8_t r3 = (uint8_t)((id % 1000) / 100); + uint8_t r4 = (uint8_t)((id % 100) / 10); + uint8_t r5 = (uint8_t)(id % 10); + + // first part + uint8_t idxC1 = r1; + uint8_t idxC2 = (idxC1 + 1 + r2) % 10; + uint8_t idxC3 = (idxC2 + 1 + r3) % 10; + uint8_t idxC4 = (idxC3 + 1 + r4) % 10; + uint8_t idxC5 = (idxC4 + 1 + r5) % 10; + + buffer[0] = 0xc0 | (subType & 0x0F); + buffer[1] = (customerCode & 0x0FF0) >> 4; + buffer[2] = ((customerCode & 0x000F) << 4) | translateTable[idxC1]; + buffer[3] = (translateTable[idxC2] << 4) | translateTable[idxC3]; + buffer[4] = (translateTable[idxC4] << 4) | translateTable[idxC5]; + + // checksum + init_table(CRC_XMODEM); + uint16_t checksum = crc16_xmodem(buffer, 5); + + buffer[6] = ((checksum & 0x000F) << 4) | (buffer[4] & 0x0F); + buffer[5] = (checksum & 0x00F0) | ((buffer[4] & 0xF0) >> 4); + buffer[4] = ((checksum & 0x0F00) >> 4) | (buffer[3] & 0x0F); + buffer[3] = ((checksum & 0xF000) >> 8) | ((buffer[3] & 0xF0) >> 4); + + // carry calc + uint8_t carry = 0; + for (uint8_t i = 0; i < sizeof(buffer); i++) { + uint8_t tmp = buffer[sizeof(buffer) - 1 - i]; + data[7 - i] = ((tmp & 0x7F) << 1) | carry; + carry = (tmp & 0x80) >> 7; + } + data[0] = 0xFE | carry; + data[7] |= isEven_64_63(data); + + // second part + if (isLong) { + uint8_t id0 = r1; + uint8_t id1 = (r2 << 4) | r3; + uint8_t id2 = (r4 << 4) | r5; + + data[8] = (id2 >> 1); + data[9] = ((id2 & 0x01) << 7) | (id1 >> 2); + data[10] = ((id1 & 0x03) << 6) | (id0 >> 3); + data[11] = ((id0 & 0x07) << 5) | (FIXED_71 >> 4); + data[12] = ((FIXED_71 & 0x0F) << 4) | (FIXED_40 >> 5); + data[13] = ((FIXED_40 & 0x1F) << 3) | (UNKNOWN_A >> 6); + data[14] = ((UNKNOWN_A & 0x3F) << 2) | (UNKNOWN_B >> 7); + data[15] = ((UNKNOWN_B & 0x7F) << 1); + data[15] |= isEven_64_63(data + 8); + } +} + +static uint8_t isEven_64_63(const uint8_t *data) { // 8 + uint32_t tmp[2]; + memcpy(tmp, data, 8); + return (bitcount32(tmp[0]) + (bitcount32(tmp[1] & 0xfeffffff))) & 1; +} + +static void bytes_to_bytebits(const void *src, const size_t srclen, void *dest) +{ + uint8_t *s = (uint8_t *)src, *d = (uint8_t *)dest; + size_t i = srclen * 8, j = srclen; + + while (j--) + { + uint8_t b = s[j]; + d[--i] = (b >> 0) & 1; + d[--i] = (b >> 1) & 1; + d[--i] = (b >> 2) & 1; + d[--i] = (b >> 3) & 1; + d[--i] = (b >> 4) & 1; + d[--i] = (b >> 5) & 1; + d[--i] = (b >> 6) & 1; + d[--i] = (b >> 7) & 1; + } +} + +static inline uint32_t bitcount32(uint32_t a) +{ +#if defined __GNUC__ + return __builtin_popcountl(a); +#else + a = a - ((a >> 1) & 0x55555555); + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); + return (((a + (a >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24; +#endif +} diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index 06040b59e..ee8c63465 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -108,6 +108,7 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo | LF_HIDBRUTE | HID corporate 1000 bruteforce - Federico dotta & Maurizio Agazzini | LF_HIDFCBRUTE | LF HID facility code bruteforce - ss23 | LF_ICEHID | LF HID collector to flashmem - Iceman1001 +| LF_NEDAP_SIM | LF Nedap ID simulator | LF_NEXID | Nexwatch credentials detection mode - jrjgjk & Zolorah | LF_PROXBRUTE | HID ProxII bruteforce - Brad Antoniewicz | LF_SAMYRUN (def)| HID26 read/clone/sim - Samy Kamkar diff --git a/tools/build_all_firmwares.sh b/tools/build_all_firmwares.sh index 5e1076684..a0ef2e1dd 100755 --- a/tools/build_all_firmwares.sh +++ b/tools/build_all_firmwares.sh @@ -30,7 +30,7 @@ mkdir -p "$DEST" mv bootrom/obj/bootrom.elf "$DEST/PM3BOOTROM.elf" # cf armsrc/Standalone/Makefile.hal -STANDALONE_MODES=(LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID) +STANDALONE_MODES=(LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID LF_NEDAP_SIM) STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI) STANDALONE_MODES_REQ_BT=(HF_REBLAY) STANDALONE_MODES_REQ_SMARTCARD=() From 224a83527f6122e758abfc6acec004eaf495b37c Mon Sep 17 00:00:00 2001 From: mwalker33 <51802811+mwalker33@users.noreply.github.com> Date: Sat, 14 Jan 2023 18:16:09 +1100 Subject: [PATCH 473/759] Update cmdlfparadox.c Add FC/CN to clone for paradox --- client/src/cmdlfparadox.c | 65 +++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/client/src/cmdlfparadox.c b/client/src/cmdlfparadox.c index f64c51be8..e1a714c96 100644 --- a/client/src/cmdlfparadox.c +++ b/client/src/cmdlfparadox.c @@ -230,6 +230,7 @@ static int CmdParadoxClone(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf paradox clone", "clone a paradox tag to a T55x7, Q5/T5555 or EM4305/4469 tag.", + "lf paradox clone --fc 96 --cn 40426 -> encode for T55x7 tag with fc and cn\n" "lf paradox clone --raw 0f55555695596a6a9999a59a -> encode for T55x7 tag\n" "lf paradox clone --raw 0f55555695596a6a9999a59a --q5 -> encode for Q5/T5555 tag\n" "lf paradox clone --raw 0f55555695596a6a9999a59a --em -> encode for EM4305/4469" @@ -238,6 +239,8 @@ static int CmdParadoxClone(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_str0("r", "raw", "", "raw hex data. 12 bytes max"), + arg_u64_0(NULL, "fc", "", "facility code"), + arg_u64_0(NULL, "cn", "", "card number"), arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"), arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"), arg_param_end @@ -249,8 +252,10 @@ static int CmdParadoxClone(const char *Cmd) { uint8_t raw[12] = {0}; CLIGetHexWithReturn(ctx, 1, raw, &raw_len); - bool q5 = arg_get_lit(ctx, 2); - bool em = arg_get_lit(ctx, 3); + uint32_t fc = arg_get_u32_def(ctx, 2, 0); + uint32_t cn = arg_get_u32_def(ctx, 3, 0); + bool q5 = arg_get_lit(ctx, 4); + bool em = arg_get_lit(ctx, 5); CLIParserFree(ctx); if (q5 && em) { @@ -258,14 +263,56 @@ static int CmdParadoxClone(const char *Cmd) { return PM3_EINVARG; } - if (raw_len != 12) { - PrintAndLogEx(ERR, "Data must be 12 bytes (24 HEX characters) %d", raw_len); - return PM3_EINVARG; - } - uint32_t blocks[4]; - for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { - blocks[i] = bytes_to_num(raw + ((i - 1) * 4), sizeof(uint32_t)); + + if (raw_len != 0) { + if (raw_len != 12) { + PrintAndLogEx(ERR, "Data must be 12 bytes (24 HEX characters) %d", raw_len); + return PM3_EINVARG; + } + + for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) { + blocks[i] = bytes_to_num(raw + ((i - 1) * 4), sizeof(uint32_t)); + } + } else { + uint8_t manchester[13] = { 0x00 }; // check size needed + uint32_t t1; + + manchester[0] = 0x0F; // preamble + manchester[1] = 0x05; // Leading zeros - Note: from this byte on, is part of the CRC calculation + manchester[2] = 0x55; // Leading zeros its 4 bits out for the CRC, so we need too move + manchester[3] = 0x55; // Leading zeros back 4 bits once we have the crc (done below) + + // add FC + t1 = manchesterEncode2Bytes (fc); + manchester[4] = (t1 >> 8) & 0xFF; + manchester[5] = t1 & 0xFF; + + // add cn + t1 = manchesterEncode2Bytes (cn); + manchester[6] = (t1 >> 24) & 0xFF; + manchester[7] = (t1 >> 16) & 0xFF; + manchester[8] = (t1 >> 8) & 0xFF; + manchester[9] = t1 & 0xFF; + + uint8_t crc = (CRC8Maxim(manchester+1, 9) ^ 0x6) & 0xFF; + + // add crc + t1 = manchesterEncode2Bytes (crc); + manchester[10] = (t1 >> 8) & 0xFF; + manchester[11] = t1 & 0xFF; + + // move left 4 bits left 4 bits - Now that we have the CRC we need to re-align the data. + for (int i = 1; i < 12; i++) + manchester[i] = (manchester[i] << 4) + (manchester[i+1] >> 4); + + // Add trailing 1010 (11) + manchester[11] |= (1 << 3); + manchester[11] |= (1 << 1); + + // move into tag blocks + for (int i = 0; i < 12; i++) + blocks[1 + (i/4)] += (manchester[i] << (8 * (3 - i % 4))); } // Paradox - FSK2a, data rate 50, 3 data blocks From fe63c503fda08b7ca4742a6833b19de14ed6bff9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Jan 2023 12:04:09 +0100 Subject: [PATCH 474/759] added some ISO7816 error code defines --- include/protocols.h | 63 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/include/protocols.h b/include/protocols.h index 563938f52..ebbe78718 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -450,9 +450,68 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ISO7816_MANAGE_CHANNEL 0x70 #define ISO7816_GET_RESPONSE 0xC0 + // ISO7816-4 For response APDU's -#define ISO7816_OK 0x9000 -// 6x xx = ERROR +#define ISO7816_OK 0x9000 + +// 6x xx = APDU ERROR CODES + +// 61 xx +#define ISO7816_BYTES_REMAINING_00 0x6100 // Response bytes remaining + +// 62 xx +#define ISO7816_WARNING_STATE_UNCHANGED 0x6200 // Warning, card state unchanged +#define ISO7816_DATA_CORRUPT 0x6281 // Returned data may be corrupted +#define ISO7816_FILE_EOF 0x6282 // The end of the file has been reached before the end of reading +#define ISO7816_INVALID_DF 0x6283 // Invalid DF +#define ISO7816_INVALID_FILE 0x6284 // Selected file is not valid +#define ISO7816_ 0x6285 + +// 63 xx +#define ISO7816_AUTH_FAILED 0x6300 // Authentification failed +#define ISO7816_FILE_FILLED 0x6381 // File filled up by the last write + +// 65 xx +#define ISO7816_MEMORY_FULL 0x6501 // Memory failure +#define ISO7816_WRITE_MEMORY_ERR 0x6581 // Write problem / Memory failure / Unknown mode + +// 67 xx +#define ISO7816_WRONG_LENGTH 0x6700 // Wrong length + +// 68 xx +#define ISO7816_LOGICAL_CHANNEL_NOT_SUPPORTED 0x6881 // Card does not support the operation on the specified logical channel +#define ISO7816_SECURE_MESSAGING_NOT_SUPPORTED 0x6882 // Card does not support secure messaging +#define ISO7816_LAST_COMMAND_EXPECTED 0x6883 // Last command in chain expected +#define ISO7816_COMMAND_CHAINING_NOT_SUPPORTED 0x6884 // Command chaining not supported + +// 69 xx +#define ISO7816_TRANSACTION_FAIL 0x6900 // No successful transaction executed during session +#define ISO7816_SELECT_FILE_ERR 0x6981 // Cannot select indicated file, command not compatible with file organization +#define ISO7816_SECURITY_STATUS_NOT_SATISFIED 0x6982 // Security condition not satisfied +#define ISO7816_FILE_INVALID 0x6983 // File invalid +#define ISO7816_DATA_INVALID 0x6984 // Data invalid +#define ISO7816_CONDITIONS_NOT_SATISFIED 0x6985 // Conditions of use not satisfied +#define ISO7816_COMMAND_NOT_ALLOWED 0x6986 // Command not allowed (no current EF) +#define ISO7816_SM_DATA_MISSING 0x6987 // Expected SM data objects missing +#define ISO7816_SM_DATA_INCORRECT 0x6988 // SM data objects incorrect +#define ISO7816_APPLET_SELECT_FAILED 0x6999 // Applet selection failed + +// 6A xx +#define ISO7816_INVALID_P1P2 0x6A00 // Bytes P1 and/or P2 are invalid +#define ISO7816_WRONG_DATA 0x6A80 // Wrong data +#define ISO7816_FUNC_NOT_SUPPORTED 0x6A81 // Function not supported +#define ISO7816_FILE_NOT_FOUND 0x6A82 // File not found +#define ISO7816_RECORD_NOT_FOUND 0x6A83 // Record not found +#define ISO7816_FILE_FULL 0x6A84 // Not enough memory space in the file +#define ISO7816_INCORRECT_P1P2 0x6A86 // Incorrect parameters (P1,P2) + +// 6x 00 +#define ISO7816_WRONG_P1P2 0x6B00 // Incorrect parameters (P1,P2) +#define ISO7816_CORRECT_LENGTH_00 0x6C00 // Correct Expected Length (Le) +#define ISO7816_INS_NOT_SUPPORTED 0x6D00 // INS value not supported +#define ISO7816_CLA_NOT_SUPPORTED 0x6E00 // CLA value not supported +#define ISO7816_UNKNOWN 0x6F00 // No precise diagnosis + // MIFARE DESFire command set: #define MFDES_AUTHENTICATE 0x0A // AUTHENTICATE_NATIVE From 8c315716d3f0e2f38eeb2abacbafde6cada39998 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Jan 2023 12:04:45 +0100 Subject: [PATCH 475/759] swapped to defines instead to see if older GCC supports it --- client/src/cmdpiv.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/client/src/cmdpiv.c b/client/src/cmdpiv.c index d73c52fee..3d703e1ec 100644 --- a/client/src/cmdpiv.c +++ b/client/src/cmdpiv.c @@ -29,13 +29,10 @@ #include "cmdhf14a.h" #include "fileutils.h" #include "crypto/asn1utils.h" +#include "protocols.h" static int CmdHelp(const char *Cmd); -static const uint16_t APDU_RES_SUCCESS = 0x9000; -static const uint16_t APDU_RES_NOT_FOUND = 0x6A82; -static const uint16_t APDU_RES_SECURITY = 0x6982; - static uint8_t PIV_APPLET[9] = "\xA0\x00\x00\x03\x08\x00\x00\x10\x00"; enum piv_condition_t { @@ -585,14 +582,14 @@ static int PivGetData(Iso7816CommandChannel channel, const uint8_t tag[], size_t root = new_root; } } - if ((*sw) == APDU_RES_SUCCESS) { + if ((*sw) == ISO7816_OK) { more_data = 0; } } while (more_data > 0); // Now we can try parse the TLV and return it *result = root; - if (*sw == APDU_RES_SUCCESS && tlvdb_parse_root(root) == true) { + if (*sw == ISO7816_OK && tlvdb_parse_root(root) == true) { return PM3_SUCCESS; } if (verbose == true) { @@ -614,17 +611,17 @@ static int PivGetDataByCidAndPrint(Iso7816CommandChannel channel, const struct p if (PivGetData(channel, cid->tlv_tag, cid->len, verbose, &root, &sw) == PM3_SUCCESS) { switch (sw) { - case APDU_RES_SUCCESS: + case ISO7816_OK: if (decodeTLV == true) { PrintTLV(&(root->db)); } else { print_buffer(root->buf, root->len, 0); } break; - case APDU_RES_NOT_FOUND: + case ISO7816_FILE_NOT_FOUND: PrintAndLogEx(FAILED, "Container not found."); break; - case APDU_RES_SECURITY: + case ISO7816_SECURITY_STATUS_NOT_SATISFIED: PrintAndLogEx(WARNING, "Security conditions not met."); break; default: @@ -676,7 +673,7 @@ static int PivAuthenticateSign(Iso7816CommandChannel channel, uint8_t alg_id, ui PrintAndLogEx(FAILED, "Sending APDU failed with code %d", res); return res; } - if (sw != APDU_RES_SUCCESS) { + if (sw != ISO7816_OK) { if (verbose == true) { PrintAndLogEx(INFO, "Unexpected APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); } @@ -701,7 +698,7 @@ static int PivSelect(Iso7816CommandChannel channel, bool activateField, bool lea if ((sw != 0) && (silent == false)) { PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); } - if (res != PM3_SUCCESS || sw != APDU_RES_SUCCESS) { + if (res != PM3_SUCCESS || sw != ISO7816_OK) { PrintAndLogEx(FAILED, "Applet selection failed. Card is not a PIV card."); return res; } From e74a025a27c7cb4b47474eea2e895c91597f7339 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Jan 2023 12:10:48 +0100 Subject: [PATCH 476/759] added some more ISO7816 error return codes, swapped to defines in 14a.c --- client/src/cmdhf14a.c | 26 +++++++++++++------------- include/protocols.h | 7 +++++-- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 4c2498a85..0858150d0 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -2242,8 +2242,8 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) { } } - if (sw == 0x9000 || sw == 0x6283 || sw == 0x6285) { - if (sw == 0x9000) { + if (sw == ISO7816_OK || sw == ISO7816_INVALID_DF || sw == ISO7816_FILE_TERMINATED) { + if (sw == ISO7816_OK) { if (verbose) PrintAndLogEx(SUCCESS, "Application ( " _GREEN_("ok") " )"); } else { if (verbose) PrintAndLogEx(WARNING, "Application ( " _RED_("blocked") " )"); @@ -2380,14 +2380,14 @@ int infoHF14A4Applications(bool verbose) { if (res) break; - if (sw == 0x9000 || sw == 0x6283 || sw == 0x6285) { + if (sw == ISO7816_OK || sw == ISO7816_INVALID_DF || sw == ISO7816_FILE_TERMINATED) { if (!found) { if (verbose) PrintAndLogEx(INFO, "----------------- " _CYAN_("Short AID search") " -----------------"); } found++; - if (sw == 0x9000) { + if (sw == ISO7816_OK) { if (verbose) PrintAndLogEx(SUCCESS, "Application " _CYAN_("%s") " ( " _GREEN_("ok") " )", hintAIDList[i].desc); cardFound[i] = true; @@ -2574,7 +2574,7 @@ retry_ins: // Show response. if (sw_occurrences < error_limit) { logLevel_t log_level = INFO; - if (sw == 0x9000) { + if (sw == ISO7816_OK) { log_level = SUCCESS; } @@ -2674,7 +2674,7 @@ int CmdHF14ANdefRead(const char *Cmd) { } uint16_t sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { // Try NDEF Type 4 Tag v1.0 param_gethex_to_eol("00a4040007d2760000850100", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n); res = ExchangeAPDU14a(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen); @@ -2688,7 +2688,7 @@ int CmdHF14ANdefRead(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting NDEF aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -2714,7 +2714,7 @@ int CmdHF14ANdefRead(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting CC file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -2729,7 +2729,7 @@ int CmdHF14ANdefRead(const char *Cmd) { return res; } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "reading CC file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -2763,7 +2763,7 @@ int CmdHF14ANdefRead(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting NDEF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -2780,7 +2780,7 @@ int CmdHF14ANdefRead(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "reading NDEF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -2819,7 +2819,7 @@ int CmdHF14ANdefRead(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "reading NDEF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); free(ndef_file); @@ -2887,7 +2887,7 @@ int CmdHF14ANdefFormat(const char *Cmd) { bool have_application = true; uint16_t sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { have_application = false; PrintAndLogEx(INFO, "no NDEF application found"); } else { diff --git a/include/protocols.h b/include/protocols.h index ebbe78718..8a00f064c 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -465,7 +465,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ISO7816_FILE_EOF 0x6282 // The end of the file has been reached before the end of reading #define ISO7816_INVALID_DF 0x6283 // Invalid DF #define ISO7816_INVALID_FILE 0x6284 // Selected file is not valid -#define ISO7816_ 0x6285 +#define ISO7816_FILE_TERMINATED 0x6285 // File is terminated // 63 xx #define ISO7816_AUTH_FAILED 0x6300 // Authentification failed @@ -503,7 +503,10 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ISO7816_FILE_NOT_FOUND 0x6A82 // File not found #define ISO7816_RECORD_NOT_FOUND 0x6A83 // Record not found #define ISO7816_FILE_FULL 0x6A84 // Not enough memory space in the file -#define ISO7816_INCORRECT_P1P2 0x6A86 // Incorrect parameters (P1,P2) +#define ISO7816_LC_TLV_CONFLICT 0x6A85 // LC / TLV conlict +#define ISO7816_INCORRECT_P1P2 0x6A86 // Incorrect parameters (P1,P2) +#define ISO7816_FILE_EXISTS 0x6A89 // File exists +#define ISO7816_NOT_IMPLEMENTED 0x6AFF // // 6x 00 #define ISO7816_WRONG_P1P2 0x6B00 // Incorrect parameters (P1,P2) From 6597d14e1061c15e10224adcc1620d678365f6c7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Jan 2023 12:17:10 +0100 Subject: [PATCH 477/759] swapped to defines --- client/src/cmdhf14b.c | 12 +++--- client/src/cmdhfcipurse.c | 91 ++++++++++++++++++++------------------- client/src/cmdhfemrtd.c | 2 +- client/src/cmdhffido.c | 21 ++++----- 4 files changed, 64 insertions(+), 62 deletions(-) diff --git a/client/src/cmdhf14b.c b/client/src/cmdhf14b.c index cddf52365..12440c676 100644 --- a/client/src/cmdhf14b.c +++ b/client/src/cmdhf14b.c @@ -126,8 +126,8 @@ static void hf14b_aid_search(bool verbose) { } } - if (sw == 0x9000 || sw == 0x6283 || sw == 0x6285) { - if (sw == 0x9000) { + if (sw == ISO7816_OK || sw == ISO7816_INVALID_DF || sw == ISO7816_FILE_TERMINATED) { + if (sw == ISO7816_OK) { if (verbose) PrintAndLogEx(SUCCESS, "Application ( " _GREEN_("ok") " )"); } else { if (verbose) PrintAndLogEx(WARNING, "Application ( " _RED_("blocked") " )"); @@ -2035,7 +2035,7 @@ int CmdHF14BNdefRead(const char *Cmd) { } uint16_t sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting NDEF aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); res = PM3_ESOFT; goto out; @@ -2055,7 +2055,7 @@ int CmdHF14BNdefRead(const char *Cmd) { goto out; sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting NDEF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); res = PM3_ESOFT; goto out; @@ -2071,7 +2071,7 @@ int CmdHF14BNdefRead(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "reading NDEF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); res = PM3_ESOFT; goto out; @@ -2090,7 +2090,7 @@ int CmdHF14BNdefRead(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "reading NDEF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); res = PM3_ESOFT; goto out; diff --git a/client/src/cmdhfcipurse.c b/client/src/cmdhfcipurse.c index 83dc300db..f6714c5a2 100644 --- a/client/src/cmdhfcipurse.c +++ b/client/src/cmdhfcipurse.c @@ -40,6 +40,7 @@ #include "util.h" #include "fileutils.h" // laodFileJSONroot #include "crypto/libpcrypto.h" +#include "protocols.h" // ISO7816 APDU return codes const uint8_t PxSE_AID[] = {0xA0, 0x00, 0x00, 0x05, 0x07, 0x01, 0x00}; #define PxSE_AID_LENGTH 7 @@ -104,11 +105,11 @@ static int SelectAndPrintInfoFile(void) { uint16_t sw = 0; int res = CIPURSESelectFile(0x2ff7, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) + if (res != 0 || sw != ISO7816_OK) return PM3_EAPDU_FAIL; res = CIPURSEReadBinary(0, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) + if (res != 0 || sw != ISO7816_OK) return PM3_EAPDU_FAIL; if (len > 0) { @@ -151,7 +152,7 @@ static int CmdHFCipurseInfo(const char *Cmd) { bool mfExist = false; bool infoPrinted = false; int res = CIPURSESelectMFEx(true, true, buf, sizeof(buf), &len, &sw); - if (res == PM3_SUCCESS && sw == 0x9000) { + if (res == PM3_SUCCESS && sw == ISO7816_OK) { mfExist = true; PrintAndLogEx(INFO, _YELLOW_("MasterFile") " exist and can be selected."); @@ -161,7 +162,7 @@ static int CmdHFCipurseInfo(const char *Cmd) { for (int i = 0; i < ARRAYLEN(PxSE_AID_LIST); i++) { res = CIPURSESelectAID(false, true, (uint8_t *)PxSE_AID_LIST[i].aid, PxSE_AID_LENGTH, buf, sizeof(buf), &len, &sw); - if (res == PM3_SUCCESS && sw == 0x9000) { + if (res == PM3_SUCCESS && sw == ISO7816_OK) { mfExist = true; PrintAndLogEx(INFO, _CYAN_("PxSE") " exist: %s", PxSE_AID_LIST[i].name); if (len > 0) { @@ -179,7 +180,7 @@ static int CmdHFCipurseInfo(const char *Cmd) { } PrintAndLogEx(INFO, "Application `" _YELLOW_("AF F1") "` selected " _GREEN_("successfully")); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { if (sw == 0x0000) { PrintAndLogEx(ERR, "APDU exchange error. Card returns 0x0000"); } else { @@ -362,7 +363,7 @@ static int SelectCommandEx(bool selectDefaultFile, bool useAID, uint8_t *aid, si if (useAID && aidLen > 0) { res = CIPURSESelectAID(true, true, aid, aidLen, buf, bufSize, len, sw); - if (res != 0 || *sw != 0x9000) { + if (res != 0 || *sw != ISO7816_OK) { if (verbose) { PrintAndLogEx(ERR, "Cipurse select application " _GREEN_("%s ") _RED_("error") ". Card returns 0x%04x", sprint_hex_inrow(aid, aidLen), *sw); } @@ -375,7 +376,7 @@ static int SelectCommandEx(bool selectDefaultFile, bool useAID, uint8_t *aid, si } else if (useFID) { res = CIPURSESelectFileEx(true, true, fileId, buf, bufSize, len, sw); - if (res != 0 || *sw != 0x9000) { + if (res != 0 || *sw != ISO7816_OK) { if (verbose) { PrintAndLogEx(ERR, "Cipurse select file 0x%04x ( %s )", fileId, _RED_("fail")); PrintAndLogEx(ERR, "Card returns 0x%04x", *sw); @@ -389,7 +390,7 @@ static int SelectCommandEx(bool selectDefaultFile, bool useAID, uint8_t *aid, si } else if (selectDefaultFile) { res = CIPURSESelectMFDefaultFileEx(true, true, buf, bufSize, len, sw); - if (res != 0 || *sw != 0x9000) { + if (res != 0 || *sw != ISO7816_OK) { if (verbose) { PrintAndLogEx(ERR, "Cipurse select default file " _RED_("error") ". Card returns 0x%04x", *sw); } @@ -402,7 +403,7 @@ static int SelectCommandEx(bool selectDefaultFile, bool useAID, uint8_t *aid, si } else { res = CIPURSESelect(true, true, buf, bufSize, len, sw); - if (res != 0 || *sw != 0x9000) { + if (res != 0 || *sw != ISO7816_OK) { if (verbose) { PrintAndLogEx(ERR, "Cipurse select default application " _RED_("error") ". Card returns 0x%04x", *sw); } @@ -419,7 +420,7 @@ static int SelectCommandEx(bool selectDefaultFile, bool useAID, uint8_t *aid, si } res = CIPURSESelectFileEx(false, true, childFileId, buf, bufSize, len, sw); - if (res != 0 || *sw != 0x9000) { + if (res != 0 || *sw != ISO7816_OK) { if (verbose) { PrintAndLogEx(ERR, "Select child file 0x%04x " _RED_("error") ". Card returns 0x%04x", childFileId, *sw); } @@ -487,7 +488,7 @@ static int CmdHFCipurseSelect(const char *Cmd) { size_t len = 0; uint16_t sw = 0; res = SelectCommandEx(selmfd, useAID, aid, aidLen, useFID, fileId, useChildFID, childFileId, true, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { DropField(); return PM3_ESOFT; } @@ -553,7 +554,7 @@ static int CmdHFCipurseAuth(const char *Cmd) { uint8_t buf[APDU_RES_LEN] = {0}; res = SelectCommand(selmfd, useAID, aid, aidLen, useFID, fileId, true, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { DropField(); return PM3_ESOFT; } @@ -635,7 +636,7 @@ static int CmdHFCipurseReadFile(const char *Cmd) { uint8_t buf[APDU_RES_LEN] = {0}; res = CIPURSESelectAID(true, true, aid, aidLen, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Cipurse select application " _CYAN_("%s") " ( " _RED_("error") " ). Card returns 0x%04x", sprint_hex_inrow(aid, aidLen), sw); DropField(); return PM3_ESOFT; @@ -660,7 +661,7 @@ static int CmdHFCipurseReadFile(const char *Cmd) { } res = CIPURSESelectFile(fileId, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { if (verbose == false) PrintAndLogEx(ERR, "File select ( " _RED_("error") " ). Card returns 0x%04x", sw); DropField(); @@ -671,7 +672,7 @@ static int CmdHFCipurseReadFile(const char *Cmd) { PrintAndLogEx(INFO, "Select file 0x%x ( %s )", fileId, _GREEN_("ok")); res = CIPURSEReadBinary(offset, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { if (verbose == false) PrintAndLogEx(ERR, "File read " _RED_("ERROR") ". Card returns 0x%04x", sw); DropField(); @@ -758,7 +759,7 @@ static int CmdHFCipurseWriteFile(const char *Cmd) { uint8_t buf[APDU_RES_LEN] = {0}; res = CIPURSESelectAID(true, true, aid, aidLen, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Cipurse select application " _CYAN_("%s") " ( " _RED_("error") " ). Card returns 0x%04x", sprint_hex_inrow(aid, aidLen), sw); DropField(); return PM3_ESOFT; @@ -789,7 +790,7 @@ static int CmdHFCipurseWriteFile(const char *Cmd) { } res = CIPURSESelectFile(fileId, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { if (verbose == false) PrintAndLogEx(ERR, "File select " _RED_("ERROR") ". Card returns 0x%04x", sw); DropField(); @@ -800,7 +801,7 @@ static int CmdHFCipurseWriteFile(const char *Cmd) { PrintAndLogEx(INFO, "Select file 0x%x ( %s )", fileId, _GREEN_("ok")); res = CIPURSEUpdateBinary(offset, hdata, hdatalen, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { if (verbose == false) PrintAndLogEx(ERR, "File write " _RED_("ERROR") ". Card returns 0x%04x", sw); DropField(); @@ -812,7 +813,7 @@ static int CmdHFCipurseWriteFile(const char *Cmd) { if (needCommit) { sw = 0; res = CIPURSECommitTransaction(&sw); - if (res != 0 || sw != 0x9000) + if (res != 0 || sw != ISO7816_OK) PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw); if (verbose) @@ -883,7 +884,7 @@ static int CmdHFCipurseReadFileAttr(const char *Cmd) { uint16_t sw = 0; res = SelectCommandEx(selmfd, useAID, aid, aidLen, useFID, fileId, useChildFID, childFileId, verbose, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Select command ( " _RED_("error") " )"); DropField(); return PM3_ESOFT; @@ -921,7 +922,7 @@ static int CmdHFCipurseReadFileAttr(const char *Cmd) { } res = CIPURSEReadFileAttributes(buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { if (verbose == false) PrintAndLogEx(ERR, "File read " _RED_("ERROR") ". Card returns 0x%04x", sw); DropField(); @@ -1020,7 +1021,7 @@ static int CmdHFCipurseWriteFileAttr(const char *Cmd) { uint16_t sw = 0; res = SelectCommandEx(selmfd, useAID, aid, aidLen, useFID, fileId, useChildFID, childFileId, verbose, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Select command ( " _RED_("error") " )"); DropField(); return PM3_ESOFT; @@ -1058,7 +1059,7 @@ static int CmdHFCipurseWriteFileAttr(const char *Cmd) { } res = CIPURSEUpdateFileAttributes(hdata, hdatalen, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { if (verbose == false) PrintAndLogEx(ERR, "File attributes update " _RED_("ERROR") ". Card returns 0x%04x", sw); DropField(); @@ -1070,7 +1071,7 @@ static int CmdHFCipurseWriteFileAttr(const char *Cmd) { if (needCommit) { sw = 0; res = CIPURSECommitTransaction(&sw); - if (res != 0 || sw != 0x9000) + if (res != 0 || sw != ISO7816_OK) PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw); if (verbose) @@ -1125,7 +1126,7 @@ static int CmdHFCipurseFormatAll(const char *Cmd) { uint16_t sw = 0; res = CIPURSESelectMFEx(true, true, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Cipurse masterfile select " _RED_("error") ". Card returns 0x%04x", sw); DropField(); return PM3_ESOFT; @@ -1154,7 +1155,7 @@ static int CmdHFCipurseFormatAll(const char *Cmd) { } res = CIPURSEFormatAll(&sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Format " _RED_("ERROR") ". Card returns 0x%04x", sw); DropField(); return PM3_ESOFT; @@ -1239,14 +1240,14 @@ static int CmdHFCipurseCreateDGI(const char *Cmd) { if (useAID || useFID || selmfd) { res = SelectCommand(selmfd, useAID, aid, aidLen, useFID, fileId, verbose, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Select command ( " _RED_("error") " )"); DropField(); return PM3_ESOFT; } } else { res = CIPURSESelectMFEx(true, true, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Cipurse masterfile select " _RED_("error") ". Card returns 0x%04x", sw); DropField(); return PM3_ESOFT; @@ -1277,7 +1278,7 @@ static int CmdHFCipurseCreateDGI(const char *Cmd) { } res = CIPURSECreateFile(hdata, hdatalen, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Create file command " _RED_("ERROR")); PrintAndLogEx(ERR, "0x%04x - %s", sw, GetSpecificAPDUCodeDesc(SelectAPDUCodeDescriptions, ARRAYLEN(SelectAPDUCodeDescriptions), sw)); @@ -1289,7 +1290,7 @@ static int CmdHFCipurseCreateDGI(const char *Cmd) { if (needCommit) { sw = 0; res = CIPURSECommitTransaction(&sw); - if (res != 0 || sw != 0x9000) + if (res != 0 || sw != ISO7816_OK) PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw); if (verbose) @@ -1376,14 +1377,14 @@ static int CmdHFCipurseDeleteFile(const char *Cmd) { if (useChildFID) { res = SelectCommand(false, useAID, aid, aidLen, useFID, fileId, verbose, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Top level select " _RED_("error") ". Card returns 0x%04x", sw); DropField(); return PM3_ESOFT; } } else { res = CIPURSESelectMFEx(true, true, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Cipurse masterfile select " _RED_("error") ". Card returns 0x%04x", sw); DropField(); return PM3_ESOFT; @@ -1405,7 +1406,7 @@ static int CmdHFCipurseDeleteFile(const char *Cmd) { if (useChildFID) { res = CIPURSEDeleteFile(childFileId, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Delete child file " _CYAN_("%04x ") " %s", childFileId, _RED_("ERROR")); PrintAndLogEx(ERR, "0x%04x - %s", sw, @@ -1417,7 +1418,7 @@ static int CmdHFCipurseDeleteFile(const char *Cmd) { PrintAndLogEx(INFO, "Child file id " _CYAN_("%04x") " deleted " _GREEN_("succesfully"), childFileId); } else if (useFID) { res = CIPURSEDeleteFile(fileId, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Delete file " _CYAN_("%04x ") " %s", fileId, _RED_("ERROR")); PrintAndLogEx(ERR, "0x%04x - %s", sw, @@ -1429,7 +1430,7 @@ static int CmdHFCipurseDeleteFile(const char *Cmd) { PrintAndLogEx(INFO, "File id " _CYAN_("%04x") " deleted " _GREEN_("succesfully"), fileId); } else { res = CIPURSEDeleteFileAID(aid, aidLen, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Delete application " _CYAN_("%s ") " %s", sprint_hex_inrow(aid, aidLen), _RED_("ERROR")); PrintAndLogEx(ERR, "0x%04x - %s", sw, @@ -1444,7 +1445,7 @@ static int CmdHFCipurseDeleteFile(const char *Cmd) { if (needCommit) { sw = 0; res = CIPURSECommitTransaction(&sw); - if (res != 0 || sw != 0x9000) + if (res != 0 || sw != ISO7816_OK) PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw); if (verbose) @@ -1588,14 +1589,14 @@ static int CmdHFCipurseUpdateKey(const char *Cmd) { if (useAID || useFID || selmfd) { res = SelectCommand(selmfd, useAID, aid, aidLen, useFID, fileId, verbose, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Select command ( " _RED_("error") " )"); DropField(); return PM3_ESOFT; } } else { res = CIPURSESelectMFEx(true, true, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Cipurse masterfile select " _RED_("error") ". Card returns 0x%04x", sw); DropField(); return PM3_ESOFT; @@ -1626,7 +1627,7 @@ static int CmdHFCipurseUpdateKey(const char *Cmd) { } res = CIPURSEUpdateKey(encKeyId, newKeyId, keydata, sizeof(keydata), buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Update key command " _RED_("ERROR")); PrintAndLogEx(ERR, "0x%04x - %s", sw, GetSpecificAPDUCodeDesc(UAPDpdateKeyCodeDescriptions, ARRAYLEN(UAPDpdateKeyCodeDescriptions), sw)); @@ -1638,7 +1639,7 @@ static int CmdHFCipurseUpdateKey(const char *Cmd) { if (needCommit) { sw = 0; res = CIPURSECommitTransaction(&sw); - if (res != 0 || sw != 0x9000) + if (res != 0 || sw != ISO7816_OK) PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw); if (verbose) @@ -1736,14 +1737,14 @@ static int CmdHFCipurseUpdateKeyAttr(const char *Cmd) { if (useAID || useFID || selmfd) { res = SelectCommand(selmfd, useAID, aid, aidLen, useFID, fileId, verbose, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Select command ( " _RED_("error") " )"); DropField(); return PM3_ESOFT; } } else { res = CIPURSESelectMFEx(true, true, buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Cipurse masterfile select " _RED_("error") ". Card returns 0x%04x", sw); DropField(); return PM3_ESOFT; @@ -1774,7 +1775,7 @@ static int CmdHFCipurseUpdateKeyAttr(const char *Cmd) { } res = CIPURSEUpdateKeyAttrib(trgKeyId, hdata[0], buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000) { + if (res != 0 || sw != ISO7816_OK) { PrintAndLogEx(ERR, "Update key attributes command " _RED_("ERROR")); PrintAndLogEx(ERR, "0x%04x - %s", sw, GetSpecificAPDUCodeDesc(UAPDpdateKeyAttrCodeDescriptions, ARRAYLEN(UAPDpdateKeyAttrCodeDescriptions), sw)); @@ -1786,7 +1787,7 @@ static int CmdHFCipurseUpdateKeyAttr(const char *Cmd) { if (needCommit) { sw = 0; res = CIPURSECommitTransaction(&sw); - if (res != 0 || sw != 0x9000) + if (res != 0 || sw != ISO7816_OK) PrintAndLogEx(WARNING, "Commit ( " _YELLOW_("fail") " ) Card returns 0x%04x", sw); if (verbose) @@ -1803,7 +1804,7 @@ bool CheckCardCipurse(void) { uint16_t sw = 0; int res = CIPURSESelect(true, false, buf, sizeof(buf), &len, &sw); - return (res == 0 && sw == 0x9000); + return (res == 0 && sw == ISO7816_OK); } static int CmdHFCipurseTest(const char *Cmd) { diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index d22df2459..8799dc12e 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -194,7 +194,7 @@ static bool emrtd_exchange_commands(sAPDU_t apdu, bool include_le, uint16_t le, return false; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(DEBUG, "Command failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); return false; } diff --git a/client/src/cmdhffido.c b/client/src/cmdhffido.c index a00206c01..64cc8a43f 100644 --- a/client/src/cmdhffido.c +++ b/client/src/cmdhffido.c @@ -44,6 +44,7 @@ #include "cmdtrace.h" #include "util.h" #include "fileutils.h" // laodFileJSONroot +#include "protocols.h" // ISO7816 APDU return codes #define DEF_FIDO_SIZE 2048 #define DEF_FIDO_PARAM_FILE "hf_fido2_defparams.json" @@ -84,7 +85,7 @@ static int CmdHFFidoInfo(const char *Cmd) { return res; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { if (sw) PrintAndLogEx(INFO, "Not a FIDO card! APDU response: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); else @@ -111,7 +112,7 @@ static int CmdHFFidoInfo(const char *Cmd) { if (res) { return res; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "FIDO2 version doesn't exist (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); return PM3_SUCCESS; } @@ -262,7 +263,7 @@ static int CmdHFFidoRegister(const char *cmd) { return res; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Can't select FIDO application. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); json_decref(root); @@ -277,7 +278,7 @@ static int CmdHFFidoRegister(const char *cmd) { return res; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "ERROR execute register command. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); return PM3_ESOFT; } @@ -584,7 +585,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { return res; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Can't select FIDO application. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); json_decref(root); @@ -599,7 +600,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { return res; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "ERROR execute authentication command. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); json_decref(root); return PM3_ESOFT; @@ -724,7 +725,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) { return res; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Can't select FIDO application. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); json_decref(root); @@ -752,7 +753,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) { return res; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "ERROR execute make credential command. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); json_decref(root); return PM3_EFILE; @@ -843,7 +844,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) { return res; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Can't select FIDO application. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); json_decref(root); @@ -871,7 +872,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) { return res; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "ERROR execute get assertion command. APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); json_decref(root); return PM3_ESOFT; From d3b78e0cf28c7a92796f86b4aa18b5247f3e721f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Jan 2023 12:21:48 +0100 Subject: [PATCH 478/759] swapped to defines --- client/src/cipurse/cipursecore.c | 16 +++++++-------- client/src/cmdhfksx6924.c | 3 ++- client/src/cmdhfseos.c | 5 +++-- client/src/cmdhfst25ta.c | 35 ++++++++++++++++---------------- client/src/emv/cmdemv.c | 9 ++++---- 5 files changed, 35 insertions(+), 33 deletions(-) diff --git a/client/src/cipurse/cipursecore.c b/client/src/cipurse/cipursecore.c index abe8a6bc2..563fda14f 100644 --- a/client/src/cipurse/cipursecore.c +++ b/client/src/cipurse/cipursecore.c @@ -17,17 +17,17 @@ //----------------------------------------------------------------------------- #include "cipursecore.h" -#include // memcpy memset - -#include "commonutil.h" // ARRAYLEN -#include "comms.h" // DropField -#include "util_posix.h" // msleep +#include // memcpy memset +#include "commonutil.h" // ARRAYLEN +#include "comms.h" // DropField +#include "util_posix.h" // msleep #include "cmdhf14a.h" #include "../emv/emvcore.h" #include "../emv/emvjson.h" -#include "../iso7816/apduinfo.h" // sAPDU_t +#include "../iso7816/apduinfo.h" // sAPDU_t #include "ui.h" #include "util.h" +#include "protocols.h" // ISO7816 APDU return codes // context for secure channel CipurseContext_t cipurseContext; @@ -112,7 +112,7 @@ static int CIPURSEExchangeEx(bool activate_field, bool leave_field_on, sAPDU_t a *sw = isw; } - if (isw != 0x9000) { + if (isw != ISO7816_OK) { if (GetAPDULogging()) { if (*sw >> 8 == 0x61) { PrintAndLogEx(ERR, "APDU chaining len:%02x -->", *sw & 0xff); @@ -255,7 +255,7 @@ bool CIPURSEChannelAuthenticate(uint8_t keyindex, uint8_t *key, bool verbose) { // authenticate res = CIPURSEMutualAuthenticate(keyindex, authparams, sizeof(authparams), buf, sizeof(buf), &len, &sw); - if (res != 0 || sw != 0x9000 || len != 16) { + if (res != 0 || sw != ISO7816_OK || len != 16) { if (sw == 0x6988) { if (verbose) { PrintAndLogEx(WARNING, "Authentication ( " _RED_("fail") " ). Wrong key"); diff --git a/client/src/cmdhfksx6924.c b/client/src/cmdhfksx6924.c index 6064a7611..7616ca766 100644 --- a/client/src/cmdhfksx6924.c +++ b/client/src/cmdhfksx6924.c @@ -46,6 +46,7 @@ #include "emv/tlv.h" #include "iso7816/apduinfo.h" #include "cmdhf14a.h" +#include "protocols.h" // ISO7816 APDU return codes static int CmdHelp(const char *Cmd); @@ -126,7 +127,7 @@ static int CmdHFKSX6924Info(const char *Cmd) { return res; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { if (sw) { PrintAndLogEx(INFO, "Not a KS X 6924 card! APDU response: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); diff --git a/client/src/cmdhfseos.c b/client/src/cmdhfseos.c index 350df87f5..896157be4 100644 --- a/client/src/cmdhfseos.c +++ b/client/src/cmdhfseos.c @@ -30,6 +30,7 @@ #include "iso7816/apduinfo.h" // GetAPDUCodeDescription #include "crypto/asn1utils.h" // ASN1 decode / print #include "commonutil.h" // get_sw +#include "protocols.h" // ISO7816 APDU return codes static int CmdHelp(const char *Cmd); @@ -55,7 +56,7 @@ static int seos_select(void) { } uint16_t sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting SEOS applet aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -75,7 +76,7 @@ static int seos_select(void) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting ADF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; diff --git a/client/src/cmdhfst25ta.c b/client/src/cmdhfst25ta.c index 0ccccd5d6..86dfe0584 100644 --- a/client/src/cmdhfst25ta.c +++ b/client/src/cmdhfst25ta.c @@ -31,6 +31,7 @@ #include "nfc/ndef.h" // NDEFRecordsDecodeAndPrint #include "cmdnfc.h" // print_type4_cc_info #include "commonutil.h" // get_sw +#include "protocols.h" // ISO7816 APDU return codes #define TIMEOUT 2000 @@ -136,7 +137,7 @@ static int infoHFST25TA(void) { } uint16_t sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting NDEF aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -156,7 +157,7 @@ static int infoHFST25TA(void) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting CC file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -172,7 +173,7 @@ static int infoHFST25TA(void) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "reading CC file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -192,7 +193,7 @@ static int infoHFST25TA(void) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting system file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -210,7 +211,7 @@ static int infoHFST25TA(void) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "reading system file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -329,7 +330,7 @@ int CmdHFST25TANdefRead(const char *Cmd) { } uint16_t sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting NDEF aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -349,7 +350,7 @@ int CmdHFST25TANdefRead(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting NDEF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -378,7 +379,7 @@ int CmdHFST25TANdefRead(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Verify password failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -397,7 +398,7 @@ int CmdHFST25TANdefRead(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "reading NDEF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -495,7 +496,7 @@ static int CmdHFST25TAProtect(const char *Cmd) { } uint16_t sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting NDEF aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -515,7 +516,7 @@ static int CmdHFST25TAProtect(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting NDEF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -534,7 +535,7 @@ static int CmdHFST25TAProtect(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Verify password failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -553,7 +554,7 @@ static int CmdHFST25TAProtect(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "changing protection failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -639,7 +640,7 @@ static int CmdHFST25TAPwd(const char *Cmd) { } uint16_t sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting NDEF aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -659,7 +660,7 @@ static int CmdHFST25TAPwd(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Selecting NDEF file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -678,7 +679,7 @@ static int CmdHFST25TAPwd(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "Verify password failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; @@ -699,7 +700,7 @@ static int CmdHFST25TAPwd(const char *Cmd) { } sw = get_sw(response, resplen); - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(ERR, "password change failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; diff --git a/client/src/emv/cmdemv.c b/client/src/emv/cmdemv.c index bf1cde60d..71277d87b 100644 --- a/client/src/emv/cmdemv.c +++ b/client/src/emv/cmdemv.c @@ -17,11 +17,9 @@ //----------------------------------------------------------------------------- #include "cmdemv.h" - #include - -#include "comms.h" // DropField -#include "cmdsmartcard.h" // smart_select +#include "comms.h" // DropField +#include "cmdsmartcard.h" // smart_select #include "cmdtrace.h" #include "emvjson.h" #include "test/cryptotest.h" @@ -35,6 +33,7 @@ #include "ui.h" #include "emv_tags.h" #include "fileutils.h" +#include "protocols.h" // ISO7816 APDU return codes static int CmdHelp(const char *Cmd); @@ -1564,7 +1563,7 @@ static int CmdEMVScan(const char *Cmd) { PrintAndLogEx(INFO, "PPSE"); res = EMVSelectPSE(channel, true, true, 2, buf, sizeof(buf), &len, &sw); - if (!res && sw == 0x9000) { + if (!res && sw == ISO7816_OK) { if (decodeTLV) TLVPrintFromBuffer(buf, len); From 67b340d838533bee75ff39657615b1ab5c2e0114 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Jan 2023 12:26:30 +0100 Subject: [PATCH 479/759] swapped to ISO7816 defines --- client/src/emv/emvcore.c | 13 ++++++------- client/src/iso7816/iso7816core.c | 5 ++--- client/src/ksx6924/ksx6924core.c | 9 +++++---- client/src/mifare/desfirecore.c | 24 ++++++++++++------------ 4 files changed, 25 insertions(+), 26 deletions(-) diff --git a/client/src/emv/emvcore.c b/client/src/emv/emvcore.c index 17aa2610e..34aa4d4be 100644 --- a/client/src/emv/emvcore.c +++ b/client/src/emv/emvcore.c @@ -17,13 +17,11 @@ //----------------------------------------------------------------------------- #include "emvcore.h" - #include - -#include "commonutil.h" // ARRAYLEN -#include "comms.h" // DropField +#include "commonutil.h" // ARRAYLEN +#include "comms.h" // DropField #include "cmdparser.h" -#include "cmdsmartcard.h" // ExchangeAPDUSC +#include "cmdsmartcard.h" // ExchangeAPDUSC #include "ui.h" #include "cmdhf14a.h" #include "cmdhf14b.h" @@ -31,6 +29,7 @@ #include "emv_tags.h" #include "emvjson.h" #include "util_posix.h" +#include "protocols.h" // ISO7816 APDU return codes // Got from here. Thanks! // https://eftlab.co.uk/index.php/site-map/knowledge-base/211-emv-aid-rid-pix @@ -392,7 +391,7 @@ int EMVSearchPSE(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFi res = EMVSelectPSE(channel, ActivateField, true, PSENum, data, sizeof(data), &datalen, &sw); if (!res) { - if (sw != 0x9000) { + if (sw != ISO7816_OK) { PrintAndLogEx(FAILED, "Select PSE error. APDU error: %04x.", sw); return 1; } @@ -419,7 +418,7 @@ int EMVSearchPSE(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFi } // error catch! - if (sw != 0x9000) { + if (sw != ISO7816_OK) { sfidatalen[ui] = 0; PrintAndLogEx(FAILED, "PPSE get Error. APDU error: %04x.", sw); break; diff --git a/client/src/iso7816/iso7816core.c b/client/src/iso7816/iso7816core.c index 5db7d32aa..7e0dd2c7f 100644 --- a/client/src/iso7816/iso7816core.c +++ b/client/src/iso7816/iso7816core.c @@ -17,9 +17,7 @@ //----------------------------------------------------------------------------- #include "iso7816core.h" - #include - #include "commonutil.h" // ARRAYLEN #include "comms.h" // DropField #include "cmdparser.h" @@ -29,6 +27,7 @@ #include "cmdhf14b.h" #include "iso14b.h" // iso14b_raw_cmd_t #include "util_posix.h" +#include "protocols.h" // ISO7816 APDU return codes //iceman: this logging setting, should be unified with client debug etc. static bool APDULogging = false; @@ -170,7 +169,7 @@ int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool activate_field, bool l *sw = isw; } - if (isw != 0x9000) { + if (isw != ISO7816_OK) { if (APDULogging) { if (*sw >> 8 == 0x61) { PrintAndLogEx(ERR, "APDU chaining len %02x", *sw & 0xFF); diff --git a/client/src/ksx6924/ksx6924core.c b/client/src/ksx6924/ksx6924core.c index b04f87358..39b390039 100644 --- a/client/src/ksx6924/ksx6924core.c +++ b/client/src/ksx6924/ksx6924core.c @@ -38,6 +38,7 @@ #include "util.h" #include "comms.h" // clearCommandBuffer #include "commonutil.h" // ntohl (pm3 version) +#include "protocols.h" // ISO7816 APDU return codes // Date type. This is the actual on-card format. typedef struct { @@ -402,7 +403,7 @@ bool KSX6924TrySelect(void) { return false; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { if (sw) { PrintAndLogEx(FAILED, "Not a KS X 6924 card! APDU response: %04x - %s", @@ -444,7 +445,7 @@ bool KSX6924GetBalance(uint32_t *result) { return false; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { return false; } @@ -476,7 +477,7 @@ bool KSX6924InitializeCard(uint8_t mpda1, uint8_t mpda2, uint8_t mpda3, uint8_t return false; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { return false; } @@ -574,7 +575,7 @@ bool KSX6924ProprietaryGetRecord(uint8_t id, uint8_t *result, size_t result_len) return false; } - if (sw != 0x9000) { + if (sw != ISO7816_OK) { return false; } diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index ab572b4d0..3e002a7ef 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -32,9 +32,9 @@ #include "aes.h" #include "ui.h" #include "crc.h" -#include "crc16.h" // crc16 ccitt +#include "crc16.h" // crc16 ccitt #include "crc32.h" -#include "protocols.h" +#include "protocols.h" // ISO7816 APDU return codes #include "cmdhf14a.h" #include "iso7816/apduinfo.h" // APDU manipulation / errorcodes #include "iso7816/iso7816core.h" // APDU logging @@ -470,7 +470,7 @@ static int DESFIRESendApduEx(bool activate_field, sAPDU_t apdu, uint16_t le, uin if (sw) *sw = isw; - if (isw != 0x9000 && + if (isw != ISO7816_OK && isw != DESFIRE_GET_ISO_STATUS(MFDES_S_OPERATION_OK) && isw != DESFIRE_GET_ISO_STATUS(MFDES_S_SIGNATURE) && isw != DESFIRE_GET_ISO_STATUS(MFDES_S_ADDITIONAL_FRAME) && @@ -1655,7 +1655,7 @@ static bool DesfireCheckISOAuthCmd(DesfireISOSelectWay way, uint32_t appID, char uint8_t p2 = ((app_level) ? 0x80 : 0x00) | keyNum; res = DesfireExchangeISO(false, &dctx, (sAPDU_t) {0x00, ISO7816_EXTERNAL_AUTHENTICATION, p1, p2, rndlen * 2, piccrnd}, 0, resp, &resplen, &sw); DropField(); - return (sw == 0x9000 || sw == 0x6982); + return (sw == ISO7816_OK || sw == ISO7816_SECURITY_STATUS_NOT_SATISFIED); } void DesfireCheckAuthCommands(DesfireISOSelectWay way, uint32_t appID, char *dfname, uint8_t keyNum, AuthCommandsChk_t *authCmdCheck) { @@ -2859,7 +2859,7 @@ int DesfireISOSelectEx(DesfireContext_t *dctx, bool fieldon, DesfireISOSelectCon size_t xresplen = 0; uint16_t sw = 0; int res = DesfireExchangeISO(fieldon, dctx, (sAPDU_t) {0x00, ISO7816_SELECT_FILE, cntr, ((resp == NULL) ? 0x0C : 0x00), datalen, data}, APDU_INCLUDE_LE_00, xresp, &xresplen, &sw); - if (res == PM3_SUCCESS && sw != 0x9000) + if (res == PM3_SUCCESS && sw != ISO7816_OK) return PM3_ESOFT; if (resp != NULL && resplen != NULL) { @@ -2885,7 +2885,7 @@ int DesfireISOSelectDF(DesfireContext_t *dctx, char *dfname, uint8_t *resp, size int DesfireISOGetChallenge(DesfireContext_t *dctx, DesfireCryptoAlgorithm keytype, uint8_t *resp, size_t *resplen) { uint16_t sw = 0; int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_GET_CHALLENGE, 0x00, 0x00, 0x00, NULL}, DesfireGetRndLenForKey(keytype), resp, resplen, &sw); - if (res == PM3_SUCCESS && sw != 0x9000) + if (res == PM3_SUCCESS && sw != ISO7816_OK) return PM3_ESOFT; return res; @@ -2900,7 +2900,7 @@ int DesfireISOExternalAuth(DesfireContext_t *dctx, bool app_level, uint8_t keynu uint16_t sw = 0; int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_EXTERNAL_AUTHENTICATION, p1, p2, DesfireGetRndLenForKey(keytype) * 2, data}, 0, resp, &resplen, &sw); - if (res == PM3_SUCCESS && sw != 0x9000) + if (res == PM3_SUCCESS && sw != ISO7816_OK) return PM3_ESOFT; return res; @@ -2913,7 +2913,7 @@ int DesfireISOInternalAuth(DesfireContext_t *dctx, bool app_level, uint8_t keynu uint16_t sw = 0; int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_INTERNAL_AUTHENTICATION, p1, p2, keylen, data}, keylen * 2, resp, resplen, &sw); - if (res == PM3_SUCCESS && sw != 0x9000) + if (res == PM3_SUCCESS && sw != ISO7816_OK) return PM3_ESOFT; return res; @@ -2929,7 +2929,7 @@ int DesfireISOReadBinary(DesfireContext_t *dctx, bool use_file_id, uint8_t filei uint16_t sw = 0; int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_READ_BINARY, p1, p2, 0, NULL}, (length == 0) ? APDU_INCLUDE_LE_00 : length, resp, resplen, &sw); - if (res == PM3_SUCCESS && sw != 0x9000) + if (res == PM3_SUCCESS && sw != ISO7816_OK) return PM3_ESOFT; return res; @@ -2948,7 +2948,7 @@ int DesfireISOUpdateBinary(DesfireContext_t *dctx, bool use_file_id, uint8_t fil uint16_t sw = 0; int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_UPDATE_BINARY, p1, p2, datalen, data}, 0, resp, &resplen, &sw); - if (res == PM3_SUCCESS && sw != 0x9000) + if (res == PM3_SUCCESS && sw != ISO7816_OK) return PM3_ESOFT; return res; @@ -2959,7 +2959,7 @@ int DesfireISOReadRecords(DesfireContext_t *dctx, uint8_t recordnum, bool read_a uint16_t sw = 0; int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_READ_RECORDS, recordnum, p2, 0, NULL}, (length == 0) ? APDU_INCLUDE_LE_00 : length, resp, resplen, &sw); - if (res == PM3_SUCCESS && sw != 0x9000) + if (res == PM3_SUCCESS && sw != ISO7816_OK) return PM3_ESOFT; return res; @@ -2973,7 +2973,7 @@ int DesfireISOAppendRecord(DesfireContext_t *dctx, uint8_t fileid, uint8_t *data uint16_t sw = 0; int res = DesfireExchangeISO(false, dctx, (sAPDU_t) {0x00, ISO7816_APPEND_RECORD, 0x00, p2, datalen, data}, 0, resp, &resplen, &sw); - if (res == PM3_SUCCESS && sw != 0x9000) + if (res == PM3_SUCCESS && sw != ISO7816_OK) return PM3_ESOFT; return res; From 838a45cb84dec16cf001fd56ed9ce4965102c7fe Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Jan 2023 18:15:03 +0100 Subject: [PATCH 480/759] text --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9867f7f70..f221d51f6 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 `lf paradox clone` - it now accepts FC/CN (@mwalker33) + - Added standalone mode for simulatin Nedap ID (@anon) - Changed `hf mfu info` - now also does a simple OTP fingerprinting (@iceman1001) - Changed `hf mf wrbl` - now checks for strict readonly ACL's in the data to write (@iceman1001) - Changed `hf mf view` - verbose printing if strict readonly ACL's exists in dump file (@iceman1001) @@ -36,7 +38,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - Fixed `make accessrights` on Fedora (@mooey5775) - - Added standalone mode for simulatin Nedap ID ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) From 35d1bebf0863a9be1356c984f241d29001daa669 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Jan 2023 18:46:49 +0100 Subject: [PATCH 481/759] changed the "path" param to "dir" and added some more help text samples, for binary files, we now check for lower case ".bin" too --- client/src/cmdhfemrtd.c | 68 ++++++++++++++++++++++------------------- client/src/util.c | 8 +++++ client/src/util.h | 3 ++ 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index 8799dc12e..c99c4b939 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -1957,16 +1957,18 @@ int infoHF_EMRTD_offline(const char *path) { uint8_t *data; size_t datalen = 0; char *filepath = calloc(strlen(path) + 100, sizeof(char)); - if (filepath == NULL) + if (filepath == NULL) { return PM3_EMALLOC; + } strcpy(filepath, path); strncat(filepath, PATHSEP, 2); strcat(filepath, dg_table[EF_COM].filename); - if (loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) { - PrintAndLogEx(ERR, "Failed to read EF_COM."); - free(filepath); - return PM3_ESOFT; + if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) && + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) { + PrintAndLogEx(ERR, "Failed to read EF_COM"); + free(filepath); + return PM3_ESOFT; } int res = emrtd_print_ef_com_info(data, datalen); @@ -1996,21 +1998,23 @@ int infoHF_EMRTD_offline(const char *path) { strncat(filepath, PATHSEP, 2); strcat(filepath, dg_table[EF_CardAccess].filename); - if (loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) { - emrtd_print_ef_cardaccess_info(data, datalen); - free(data); + if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) || + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) { + emrtd_print_ef_cardaccess_info(data, datalen); + free(data); } else { - PrintAndLogEx(HINT, "The error above this is normal. It just means that your eMRTD lacks PACE."); + PrintAndLogEx(HINT, "The error above this is normal. It just means that your eMRTD lacks PACE"); } strcpy(filepath, path); strncat(filepath, PATHSEP, 2); strcat(filepath, dg_table[EF_SOD].filename); - if (loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) { - PrintAndLogEx(ERR, "Failed to read EF_SOD."); - free(filepath); - return PM3_ESOFT; + if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) && + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) { + PrintAndLogEx(ERR, "Failed to read EF_SOD"); + free(filepath); + return PM3_ESOFT; } // coverity scan CID 395630, @@ -2020,7 +2024,7 @@ int infoHF_EMRTD_offline(const char *path) { res = emrtd_parse_ef_sod_hashes(data, datalen, *dg_hashes_sod, &hash_algo); if (res != PM3_SUCCESS) { - PrintAndLogEx(ERR, "Failed to read hash list from EF_SOD. Hash checks will fail."); + PrintAndLogEx(ERR, "Failed to read hash list from EF_SOD. Hash checks will fail"); } free(data); @@ -2035,10 +2039,12 @@ int infoHF_EMRTD_offline(const char *path) { strcpy(filepath, path); strncat(filepath, PATHSEP, 2); strcat(filepath, dg->filename); - if (loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) { + if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) || + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) { // we won't halt on parsing errors - if (dg->parser != NULL) + if (dg->parser != NULL) { dg->parser(data, datalen); + } PrintAndLogEx(DEBUG, "EF_DG%i hash algo: %i", dg->dgnum, hash_algo); // Check file hash @@ -2058,13 +2064,6 @@ int infoHF_EMRTD_offline(const char *path) { return PM3_SUCCESS; } -static void text_to_upper(uint8_t *data, int datalen) { - // Loop over text to make lowercase text uppercase - for (int i = 0; i < datalen; i++) { - data[i] = toupper(data[i]); - } -} - static bool validate_date(uint8_t *data, int datalen) { // Date has to be 6 chars if (datalen != 6) { @@ -2085,7 +2084,9 @@ static int CmdHFeMRTDDump(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf emrtd dump", "Dump all files on an eMRTD", - "hf emrtd dump" + "hf emrtd dump\n" + "hf emrtd dump --dir ../dump\n" + "hf emrtd dump -n 123456789 -d 19890101 -e 20250401" ); void *argtable[] = { @@ -2094,7 +2095,7 @@ static int CmdHFeMRTDDump(const char *Cmd) { arg_str0("d", "dateofbirth", "", "date of birth in YYMMDD format"), arg_str0("e", "expiry", "", "expiry in YYMMDD format"), arg_str0("m", "mrz", "<[0-9A-Z<]>", "2nd line of MRZ, 44 chars"), - arg_str0(NULL, "path", "", "save dump to the given dirpath"), + arg_str0(NULL, "dir", "", "save dump to the given dirpath"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -2110,7 +2111,7 @@ static int CmdHFeMRTDDump(const char *Cmd) { if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) { BAC = false; } else { - text_to_upper(docnum, slen); + strn_upper((char*)docnum, slen); if (slen != 9) { // Pad to 9 with < memset(docnum + slen, '<', 9 - slen); @@ -2143,7 +2144,7 @@ static int CmdHFeMRTDDump(const char *Cmd) { error = true; } else { BAC = true; - text_to_upper(mrz, slen); + strn_upper((char*)mrz, slen); memcpy(docnum, &mrz[0], 9); memcpy(dob, &mrz[13], 6); memcpy(expiry, &mrz[21], 6); @@ -2183,7 +2184,10 @@ static int CmdHFeMRTDInfo(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf emrtd info", "Display info about an eMRTD", - "hf emrtd info" + "hf emrtd info\n" + "hf emrtd info --dir ../dumps\n" + "hf emrtd info -n 123456789 -d 19890101 -e 20250401\n" + "hf emrtd info -n 123456789 -d 19890101 -e 20250401 -i" ); void *argtable[] = { @@ -2192,7 +2196,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { arg_str0("d", "dateofbirth", "", "date of birth in YYMMDD format"), arg_str0("e", "expiry", "", "expiry in YYMMDD format"), arg_str0("m", "mrz", "<[0-9A-Z<]>", "2nd line of MRZ, 44 chars (passports only)"), - arg_str0(NULL, "path", "", "display info from offline dump stored in dirpath"), + arg_str0(NULL, "dir", "", "display info from offline dump stored in dirpath"), arg_lit0("i", "images", "show images"), arg_param_end }; @@ -2209,7 +2213,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) { BAC = false; } else { - text_to_upper(docnum, slen); + strn_upper((char*)docnum, slen); if (slen != 9) { memset(docnum + slen, '<', 9 - slen); } @@ -2241,7 +2245,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { error = true; } else { BAC = true; - text_to_upper(mrz, slen); + strn_upper((char*)mrz, slen); memcpy(docnum, &mrz[0], 9); memcpy(dob, &mrz[13], 6); memcpy(expiry, &mrz[21], 6); @@ -2262,7 +2266,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { bool is_offline = CLIParamStrToBuf(arg_get_str(ctx, 5), path, sizeof(path), &slen) == 0 && slen > 0; bool show_images = arg_get_lit(ctx, 6); CLIParserFree(ctx); - if ((! IfPm3Iso14443()) && (! is_offline)) { + if ((IfPm3Iso14443() == false) && (is_offline == false)) { PrintAndLogEx(WARNING, "Only offline mode is available"); error = true; } diff --git a/client/src/util.c b/client/src/util.c index 56eb3164a..dc58eef2c 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -1088,6 +1088,14 @@ void str_lower(char *s) { s[i] = tolower(s[i]); } +void str_upper(char *s) { + strn_upper(s, strlen(s)); +} + +void strn_upper(char *s, size_t n) { + for (size_t i = 0; i < n; i++) + s[i] = toupper(s[i]); +} // check for prefix in string bool str_startswith(const char *s, const char *pre) { return strncmp(pre, s, strlen(pre)) == 0; diff --git a/client/src/util.h b/client/src/util.h index 616272c84..d831a750b 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -129,6 +129,9 @@ uint64_t HornerScheme(uint64_t num, uint64_t divider, uint64_t factor); int num_CPUs(void); // number of logical CPUs void str_lower(char *s); // converts string to lower case +void str_upper(char *s); // converts string to UPPER case +void strn_upper(char *s, size_t n); + bool str_startswith(const char *s, const char *pre); // check for prefix in string bool str_endswith(const char *s, const char *suffix); // check for suffix in string void clean_ascii(unsigned char *buf, size_t len); From aa1f4681a25146b515313190e33980fb7981639f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Jan 2023 18:48:11 +0100 Subject: [PATCH 482/759] text --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f221d51f6..97fa48f5d 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 emrtd info` - looking for lower case .bin extensions (@iceman1001) + - Changed `hf emrtd dump` - looking for lower case .bin extensions (@iceman1001) - Changed `lf paradox clone` - it now accepts FC/CN (@mwalker33) - Added standalone mode for simulatin Nedap ID (@anon) - Changed `hf mfu info` - now also does a simple OTP fingerprinting (@iceman1001) From ad7b18fb2ffb7cc40450bdd210ab813f24b0b5c5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 14 Jan 2023 18:52:59 +0100 Subject: [PATCH 483/759] use env instead --- tools/mkversion.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mkversion.sh b/tools/mkversion.sh index c1819f34e..f741f2980 100755 --- a/tools/mkversion.sh +++ b/tools/mkversion.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env sh # Output a version_pm3.c file that includes information about the current build # From mkversion.pl From 5d5d9d9be0b86d5343378948d5c9c89df9320a7f Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Jan 2023 22:22:04 +0100 Subject: [PATCH 484/759] make style --- armsrc/Standalone/lf_nedap_sim.c | 114 ++++--- client/src/cmdhfemrtd.c | 36 +-- client/src/cmdhfmf.c | 2 +- client/src/cmdhfmfu.c | 8 +- client/src/cmdlfparadox.c | 22 +- client/src/cmdpiv.c | 10 +- client/src/fileutils.c | 6 +- client/src/mifare/mifarehost.c | 40 +-- client/src/pm3line_vocabulory.h | 17 +- client/src/ui.c | 12 +- doc/commands.json | 493 +++++++++---------------------- doc/commands.md | 27 +- include/protocol_vigik.h | 2 +- include/protocols.h | 2 +- 14 files changed, 262 insertions(+), 529 deletions(-) diff --git a/armsrc/Standalone/lf_nedap_sim.c b/armsrc/Standalone/lf_nedap_sim.c index 491199c27..dcd093fee 100644 --- a/armsrc/Standalone/lf_nedap_sim.c +++ b/armsrc/Standalone/lf_nedap_sim.c @@ -30,11 +30,11 @@ #define MODULE_LONG_NAME "LF Nedap simple simulator" typedef struct _NEDAP_TAG { - uint8_t subType; - uint16_t customerCode; - uint32_t id; - - uint8_t bIsLong; + uint8_t subType; + uint16_t customerCode; + uint32_t id; + + uint8_t bIsLong; } NEDAP_TAG, *PNEDAP_TAG; const NEDAP_TAG Tag = {.subType = 0x5, .customerCode = 0x123, .id = 42424, .bIsLong = 1}; @@ -46,78 +46,67 @@ static uint8_t isEven_64_63(const uint8_t *data); static inline uint32_t bitcount32(uint32_t a); static void bytes_to_bytebits(const void *src, const size_t srclen, void *dest); -void ModInfo(void) -{ +void ModInfo(void) { DbpString(" " MODULE_LONG_NAME); } -void RunMod(void) -{ - int n; +void RunMod(void) { + int n; - StandAloneMode(); + StandAloneMode(); Dbprintf("[=] " MODULE_LONG_NAME " -- started"); - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - Dbprintf("[=] NEDAP (%s) - ID: " _GREEN_("%05u") " subtype: " _GREEN_("%1u") " customer code: " _GREEN_("%u / 0x%03X"), Tag.bIsLong ? "128b" : "64b", Tag.id, Tag.subType, Tag.customerCode, Tag.customerCode); - - n = NedapPrepareBigBuffer(&Tag); - do - { + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + Dbprintf("[=] NEDAP (%s) - ID: " _GREEN_("%05u") " subtype: " _GREEN_("%1u") " customer code: " _GREEN_("%u / 0x%03X"), Tag.bIsLong ? "128b" : "64b", Tag.id, Tag.subType, Tag.customerCode, Tag.customerCode); + + n = NedapPrepareBigBuffer(&Tag); + do { WDT_HIT(); if (data_available()) - break; + break; + + SimulateTagLowFrequency(n, 0, true); - SimulateTagLowFrequency(n, 0, true); - } while (BUTTON_HELD(1000) == BUTTON_NO_CLICK); Dbprintf("[=] " MODULE_LONG_NAME " -- exiting"); - + LEDsoff(); } -static int NedapPrepareBigBuffer(const NEDAP_TAG *pTag) -{ - int ret = 0; - uint8_t data[16], bitStream[sizeof(data) * 8], phase = 0; - uint16_t i, size = pTag->bIsLong ? sizeof(data) : (sizeof(data) / 2); - - NedapGen(pTag->subType, pTag->customerCode, pTag->id, pTag->bIsLong, data); - bytes_to_bytebits(data, size, bitStream); - size <<= 3; - - for (i = 0; i < size; i++) - { - biphaseSimBitInverted(!bitStream[i], &ret, &phase); - } - if (phase == 1) //run a second set inverted to keep phase in check - { - for (i = 0; i < size; i++) - { - biphaseSimBitInverted(!bitStream[i], &ret, &phase); - } - } - - return ret; +static int NedapPrepareBigBuffer(const NEDAP_TAG *pTag) { + int ret = 0; + uint8_t data[16], bitStream[sizeof(data) * 8], phase = 0; + uint16_t i, size = pTag->bIsLong ? sizeof(data) : (sizeof(data) / 2); + + NedapGen(pTag->subType, pTag->customerCode, pTag->id, pTag->bIsLong, data); + bytes_to_bytebits(data, size, bitStream); + size <<= 3; + + for (i = 0; i < size; i++) { + biphaseSimBitInverted(!bitStream[i], &ret, &phase); + } + if (phase == 1) { //run a second set inverted to keep phase in check + for (i = 0; i < size; i++) { + biphaseSimBitInverted(!bitStream[i], &ret, &phase); + } + } + + return ret; } -static void biphaseSimBitInverted(uint8_t c, int *n, uint8_t *phase) -{ - uint8_t *dest = BigBuf_get_addr(); +static void biphaseSimBitInverted(uint8_t c, int *n, uint8_t *phase) { + uint8_t *dest = BigBuf_get_addr(); - if (c) - { - memset(dest + (*n), c ^ 1 ^ *phase, 32); - memset(dest + (*n) + 32, c ^ *phase, 32); - } - else - { - memset(dest + (*n), c ^ *phase, 64); - *phase ^= 1; - } - *n += 64; + if (c) { + memset(dest + (*n), c ^ 1 ^ *phase, 32); + memset(dest + (*n) + 32, c ^ *phase, 32); + } else { + memset(dest + (*n), c ^ *phase, 64); + *phase ^= 1; + } + *n += 64; } #define FIXED_71 0x71 @@ -190,13 +179,11 @@ static uint8_t isEven_64_63(const uint8_t *data) { // 8 return (bitcount32(tmp[0]) + (bitcount32(tmp[1] & 0xfeffffff))) & 1; } -static void bytes_to_bytebits(const void *src, const size_t srclen, void *dest) -{ +static void bytes_to_bytebits(const void *src, const size_t srclen, void *dest) { uint8_t *s = (uint8_t *)src, *d = (uint8_t *)dest; size_t i = srclen * 8, j = srclen; - while (j--) - { + while (j--) { uint8_t b = s[j]; d[--i] = (b >> 0) & 1; d[--i] = (b >> 1) & 1; @@ -209,8 +196,7 @@ static void bytes_to_bytebits(const void *src, const size_t srclen, void *dest) } } -static inline uint32_t bitcount32(uint32_t a) -{ +static inline uint32_t bitcount32(uint32_t a) { #if defined __GNUC__ return __builtin_popcountl(a); #else diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index c99c4b939..bb0808a51 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -1964,11 +1964,11 @@ int infoHF_EMRTD_offline(const char *path) { strncat(filepath, PATHSEP, 2); strcat(filepath, dg_table[EF_COM].filename); - if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) && - (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) { - PrintAndLogEx(ERR, "Failed to read EF_COM"); - free(filepath); - return PM3_ESOFT; + if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) && + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) { + PrintAndLogEx(ERR, "Failed to read EF_COM"); + free(filepath); + return PM3_ESOFT; } int res = emrtd_print_ef_com_info(data, datalen); @@ -1999,9 +1999,9 @@ int infoHF_EMRTD_offline(const char *path) { strcat(filepath, dg_table[EF_CardAccess].filename); if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) || - (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) { - emrtd_print_ef_cardaccess_info(data, datalen); - free(data); + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) { + emrtd_print_ef_cardaccess_info(data, datalen); + free(data); } else { PrintAndLogEx(HINT, "The error above this is normal. It just means that your eMRTD lacks PACE"); } @@ -2010,11 +2010,11 @@ int infoHF_EMRTD_offline(const char *path) { strncat(filepath, PATHSEP, 2); strcat(filepath, dg_table[EF_SOD].filename); - if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) && - (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) { - PrintAndLogEx(ERR, "Failed to read EF_SOD"); - free(filepath); - return PM3_ESOFT; + if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) && + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) { + PrintAndLogEx(ERR, "Failed to read EF_SOD"); + free(filepath); + return PM3_ESOFT; } // coverity scan CID 395630, @@ -2040,7 +2040,7 @@ int infoHF_EMRTD_offline(const char *path) { strncat(filepath, PATHSEP, 2); strcat(filepath, dg->filename); if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) || - (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) { + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) { // we won't halt on parsing errors if (dg->parser != NULL) { dg->parser(data, datalen); @@ -2111,7 +2111,7 @@ static int CmdHFeMRTDDump(const char *Cmd) { if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) { BAC = false; } else { - strn_upper((char*)docnum, slen); + strn_upper((char *)docnum, slen); if (slen != 9) { // Pad to 9 with < memset(docnum + slen, '<', 9 - slen); @@ -2144,7 +2144,7 @@ static int CmdHFeMRTDDump(const char *Cmd) { error = true; } else { BAC = true; - strn_upper((char*)mrz, slen); + strn_upper((char *)mrz, slen); memcpy(docnum, &mrz[0], 9); memcpy(dob, &mrz[13], 6); memcpy(expiry, &mrz[21], 6); @@ -2213,7 +2213,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) { BAC = false; } else { - strn_upper((char*)docnum, slen); + strn_upper((char *)docnum, slen); if (slen != 9) { memset(docnum + slen, '<', 9 - slen); } @@ -2245,7 +2245,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { error = true; } else { BAC = true; - strn_upper((char*)mrz, slen); + strn_upper((char *)mrz, slen); memcpy(docnum, &mrz[0], 9); memcpy(dob, &mrz[13], 6); memcpy(expiry, &mrz[21], 6); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 2ea197cf7..98a587cf1 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -569,7 +569,7 @@ static int CmdHF14AMfWrBl(const char *Cmd) { uint8_t blockno = (uint8_t)b; - // Sector trailer sanity checks. + // Sector trailer sanity checks. // Warn if ACL is strict read-only, or invalid ACL. if (mfIsSectorTrailer(blockno)) { PrintAndLogEx(INFO, "Sector trailer (ST) write detected"); diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 00df6e710..bc8c10859 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -1376,7 +1376,7 @@ static int mfu_fingerprint(TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authke } } - // OTP checks + // OTP checks mfu_otp_identify_t *item = mfu_match_otp_fingerprint(data); if (item) { PrintAndLogEx(SUCCESS, "Found " _GREEN_("%s"), item->desc); @@ -1391,9 +1391,9 @@ static int mfu_fingerprint(TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authke } } } - // - - + // + + out: free(data); diff --git a/client/src/cmdlfparadox.c b/client/src/cmdlfparadox.c index e1a714c96..bbd6cd205 100644 --- a/client/src/cmdlfparadox.c +++ b/client/src/cmdlfparadox.c @@ -264,7 +264,7 @@ static int CmdParadoxClone(const char *Cmd) { } uint32_t blocks[4]; - + if (raw_len != 0) { if (raw_len != 12) { PrintAndLogEx(ERR, "Data must be 12 bytes (24 HEX characters) %d", raw_len); @@ -280,39 +280,39 @@ static int CmdParadoxClone(const char *Cmd) { manchester[0] = 0x0F; // preamble manchester[1] = 0x05; // Leading zeros - Note: from this byte on, is part of the CRC calculation - manchester[2] = 0x55; // Leading zeros its 4 bits out for the CRC, so we need too move + manchester[2] = 0x55; // Leading zeros its 4 bits out for the CRC, so we need too move manchester[3] = 0x55; // Leading zeros back 4 bits once we have the crc (done below) // add FC - t1 = manchesterEncode2Bytes (fc); + t1 = manchesterEncode2Bytes(fc); manchester[4] = (t1 >> 8) & 0xFF; manchester[5] = t1 & 0xFF; - + // add cn - t1 = manchesterEncode2Bytes (cn); + t1 = manchesterEncode2Bytes(cn); manchester[6] = (t1 >> 24) & 0xFF; manchester[7] = (t1 >> 16) & 0xFF; manchester[8] = (t1 >> 8) & 0xFF; manchester[9] = t1 & 0xFF; - uint8_t crc = (CRC8Maxim(manchester+1, 9) ^ 0x6) & 0xFF; + uint8_t crc = (CRC8Maxim(manchester + 1, 9) ^ 0x6) & 0xFF; // add crc - t1 = manchesterEncode2Bytes (crc); + t1 = manchesterEncode2Bytes(crc); manchester[10] = (t1 >> 8) & 0xFF; manchester[11] = t1 & 0xFF; // move left 4 bits left 4 bits - Now that we have the CRC we need to re-align the data. for (int i = 1; i < 12; i++) - manchester[i] = (manchester[i] << 4) + (manchester[i+1] >> 4); - + manchester[i] = (manchester[i] << 4) + (manchester[i + 1] >> 4); + // Add trailing 1010 (11) manchester[11] |= (1 << 3); manchester[11] |= (1 << 1); - + // move into tag blocks for (int i = 0; i < 12; i++) - blocks[1 + (i/4)] += (manchester[i] << (8 * (3 - i % 4))); + blocks[1 + (i / 4)] += (manchester[i] << (8 * (3 - i % 4))); } // Paradox - FSK2a, data rate 50, 3 data blocks diff --git a/client/src/cmdpiv.c b/client/src/cmdpiv.c index 3d703e1ec..12b217ebc 100644 --- a/client/src/cmdpiv.c +++ b/client/src/cmdpiv.c @@ -66,7 +66,7 @@ static const struct piv_container PIV_CONTAINERS[] = { {0x0100, PIV_TAG_ID("\x5F\xC1\x0A"), 3, PIV_CONDITIONAL, "X.509 Certificate for Digital Signature (key ref 9C)"}, {0x0102, PIV_TAG_ID("\x5F\xC1\x0B"), 3, PIV_CONDITIONAL, "X.509 Certificate for Key Management (key ref 9D)"}, {0x3001, PIV_TAG_ID("\x5F\xC1\x09"), 3, PIV_OPTIONAL, "Printed Information"}, - {0x6050, PIV_TAG_ID( "\x7E"), 1, PIV_OPTIONAL, "Discovery Object"}, + {0x6050, PIV_TAG_ID("\x7E"), 1, PIV_OPTIONAL, "Discovery Object"}, {0x6060, PIV_TAG_ID("\x5F\xC1\x0C"), 3, PIV_OPTIONAL, "Key History Object"}, {0x1001, PIV_TAG_ID("\x5F\xC1\x0D"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 1 (key ref 82)"}, {0x1002, PIV_TAG_ID("\x5F\xC1\x0E"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 2 (key ref 83)"}, @@ -89,7 +89,7 @@ static const struct piv_container PIV_CONTAINERS[] = { {0x1013, PIV_TAG_ID("\x5F\xC1\x1F"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 19 (key ref 94)"}, {0x1014, PIV_TAG_ID("\x5F\xC1\x20"), 3, PIV_OPTIONAL, "Retired X.509 Certificate for Key Management 20 (key ref 95)"}, {0x1015, PIV_TAG_ID("\x5F\xC1\x21"), 3, PIV_OPTIONAL, "Cardholder Iris Images"}, - {0x1016, PIV_TAG_ID( "\x7F\x61"), 2, PIV_OPTIONAL, "Biometric Information Templates Group Template"}, + {0x1016, PIV_TAG_ID("\x7F\x61"), 2, PIV_OPTIONAL, "Biometric Information Templates Group Template"}, {0x1017, PIV_TAG_ID("\x5F\xC1\x22"), 3, PIV_OPTIONAL, "Secure Messaging Certificate Signer"}, {0x1018, PIV_TAG_ID("\x5F\xC1\x23"), 3, PIV_OPTIONAL, "Pairing Code Reference Data Container"}, PIV_CONTAINER_FINISH, @@ -493,13 +493,13 @@ static void piv_print_cb(void *data, const struct tlv *tlv, int level, bool is_l } } -static void PrintTLV(const struct tlvdb* tlvdb) { +static void PrintTLV(const struct tlvdb *tlvdb) { if (tlvdb) { tlvdb_visit(tlvdb, piv_print_cb, NULL, 0); } } -static void PrintTLVFromBuffer(const uint8_t* buf, size_t len) { +static void PrintTLVFromBuffer(const uint8_t *buf, size_t len) { if (buf == NULL || len == 0) { return; } @@ -598,7 +598,7 @@ static int PivGetData(Iso7816CommandChannel channel, const uint8_t tag[], size_t return PM3_SUCCESS; } -static int PivGetDataByCidAndPrint(Iso7816CommandChannel channel, const struct piv_container* cid, bool decodeTLV, bool verbose) { +static int PivGetDataByCidAndPrint(Iso7816CommandChannel channel, const struct piv_container *cid, bool decodeTLV, bool verbose) { struct tlvdb_root *root = NULL; if (cid == NULL) { diff --git a/client/src/fileutils.c b/client/src/fileutils.c index 22cf3ad5e..e42ac5a16 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -258,13 +258,13 @@ static size_t path_size(savePaths_t a) { if (a == spItemCount) { return 0; } - return strlen( g_session.defaultPaths[a] ); + return strlen(g_session.defaultPaths[a]); } char *newfilenamemcopy(const char *preferredName, const char *suffix) { if (preferredName == NULL || suffix == NULL) { return NULL; - } + } uint16_t p_namelen = strlen(preferredName); if (str_endswith(preferredName, suffix)) @@ -328,7 +328,7 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t } char *fileName = newfilenamemcopy(preferredName, ".eml"); - if (fileName == NULL) { + if (fileName == NULL) { return PM3_EMALLOC; } diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 5ce88123d..0c8c8b274 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1466,7 +1466,7 @@ int convert_mfc_2_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen) ilen -= MFBLOCK_SIZE; *olen += MFBLOCK_SIZE; } - return PM3_SUCCESS; + return PM3_SUCCESS; } static const vigik_pk_t vigik_rsa_pk[] = { @@ -1502,7 +1502,7 @@ static void reverse_array(const uint8_t *src, int src_len, uint8_t *dest) { int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len) { // iso9796 - // Exponent V = 2 + // Exponent V = 2 // n = The public modulus n is the product of the secret prime factors p and q. Its length is 1024 bits. if (g_debugMode == DEBUG) { @@ -1527,7 +1527,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature // signature = h( C || M1 || h(M2) ) // 1024 - 786 - 160 - 16 -1 - // salt C + // salt C // message M = 96 bytes, 768 bits // sha1 hash H = 20 bytes, 160 bits // padding = 20 bytes, 96 bits @@ -1563,18 +1563,18 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature mbedtls_mpi_init(&sqr); mbedtls_mpi_init(&res); - mbedtls_mpi_read_binary(&N, (const unsigned char*)n, PUBLIC_VIGIK_KEYLEN); + mbedtls_mpi_read_binary(&N, (const unsigned char *)n, PUBLIC_VIGIK_KEYLEN); //mbedtls_mpi_read_binary(&s, (const unsigned char*)signature, signature_len); - mbedtls_mpi_read_binary(&s, (const unsigned char*)rev_sig, signature_len); + mbedtls_mpi_read_binary(&s, (const unsigned char *)rev_sig, signature_len); // check is sign < (N/2) - + mbedtls_mpi n_2; mbedtls_mpi_init(&n_2); mbedtls_mpi_copy(&n_2, &N); mbedtls_mpi_shift_r(&n_2, 1); - bool is_less = (mbedtls_mpi_cmp_mpi(&s, &n_2) > 0) ? false : true; + bool is_less = (mbedtls_mpi_cmp_mpi(&s, &n_2) > 0) ? false : true; PrintAndLogEx(DEBUG, "z < (N/2) ..... %s", (is_less) ? _GREEN_("YES") : _RED_("NO")); mbedtls_mpi_free(&n_2); @@ -1644,10 +1644,10 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature PrintAndLogEx(DEBUG, "LSB............ " _GREEN_("%u"), lsb); if (g_debugMode == DEBUG) { - mbedtls_mpi_write_file( "[=] N.............. ", &N, 16, NULL ); - mbedtls_mpi_write_file( "[=] signature...... ", &s, 16, NULL ); - mbedtls_mpi_write_file( "[=] square mod n... ", &sqr, 16, NULL ); - mbedtls_mpi_write_file( "[=] n-fs........... ", &res, 16, NULL ); + mbedtls_mpi_write_file("[=] N.............. ", &N, 16, NULL); + mbedtls_mpi_write_file("[=] signature...... ", &s, 16, NULL); + mbedtls_mpi_write_file("[=] square mod n... ", &sqr, 16, NULL); + mbedtls_mpi_write_file("[=] n-fs........... ", &res, 16, NULL); } @@ -1656,9 +1656,9 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature // xor 0xDC01 int count_zero = 0; - for (int x = 0; x < sizeof(nfs); x +=2) { + for (int x = 0; x < sizeof(nfs); x += 2) { nfs[x] ^= 0xDC; - nfs[x+1] ^= 0x01; + nfs[x + 1] ^= 0x01; if (nfs[x] == 0x00) count_zero++; @@ -1689,10 +1689,10 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature PrintAndLogEx(INFO, "Hash byte... 0x%02X", ts.hash); switch(ts.rsa[126]) { case 0x11: - PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - SHA1"); + PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - SHA1"); break; case 0x22: - PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - RIPEMD"); + PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - RIPEMD"); break; case 0x33: PrintAndLogEx(INFO, "Hash algo ( 0x%02X ) - SHA1"); @@ -1711,7 +1711,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature print_hex_noascii_break(ts.rsa, sizeof(ts.rsa) - 20, 32); } */ - + mbedtls_mpi_free(&N); mbedtls_mpi_free(&s); mbedtls_mpi_free(&res); @@ -1722,7 +1722,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature PrintAndLogEx(INFO, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Tag Signature")); PrintAndLogEx(INFO, "RSA: 1024bit"); - + if (is_valid == false || i == ARRAYLEN(vigik_rsa_pk)) { PrintAndLogEx(INFO, "Signature:"); print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2); @@ -1736,7 +1736,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 64); PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 128); PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 192); - + PrintAndLogEx(INFO, "Signature:"); print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2); @@ -1749,7 +1749,7 @@ int vigik_annotate(uint8_t *d) { if (d == NULL) return PM3_EINVARG; - mfc_vigik_t *foo = (mfc_vigik_t*)d; + mfc_vigik_t *foo = (mfc_vigik_t *)d; PrintAndLogEx(INFO, "Manufacture......... %s", sprint_hex(foo->b0, sizeof(foo->b0))); PrintAndLogEx(INFO, "MAD................. %s", sprint_hex(foo->mad, sizeof(foo->mad))); @@ -1773,4 +1773,4 @@ int vigik_annotate(uint8_t *d) { PrintAndLogEx(INFO, ""); return PM3_SUCCESS; -} \ No newline at end of file +} diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index de0cb6ace..4ea275639 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -244,11 +244,11 @@ const static vocabulory_t vocabulory[] = { { 1, "hf gallagher diversifykey" }, { 1, "hf gallagher decode" }, { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 select" }, - { 0, "hf ksx6924 info" }, { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 init" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 initialize" }, { 0, "hf ksx6924 prec" }, + { 0, "hf ksx6924 select" }, { 1, "hf jooki help" }, { 0, "hf jooki clone" }, { 1, "hf jooki decode" }, @@ -347,10 +347,6 @@ const static vocabulory_t vocabulory[] = { { 0, "hf mf gen3uid" }, { 0, "hf mf gen3blk" }, { 0, "hf mf gen3freeze" }, - { 0, "hf mf ggetblk" }, - { 0, "hf mf gload" }, - { 0, "hf mf gsave" }, - { 0, "hf mf gsetblk" }, { 0, "hf mf gview" }, { 0, "hf mf ndefformat" }, { 0, "hf mf ndefread" }, @@ -380,7 +376,6 @@ const static vocabulory_t vocabulory[] = { { 1, "hf mfu view" }, { 0, "hf mfu wrbl" }, { 0, "hf mfu eload" }, - { 0, "hf mfu esave" }, { 0, "hf mfu eview" }, { 0, "hf mfu sim" }, { 0, "hf mfu setpwd" }, @@ -589,7 +584,6 @@ const static vocabulory_t vocabulory[] = { { 0, "lf idteck clone" }, { 0, "lf idteck sim" }, { 1, "lf indala help" }, - { 0, "lf indala brute" }, { 1, "lf indala demod" }, { 1, "lf indala altdemod" }, { 0, "lf indala reader" }, @@ -737,11 +731,6 @@ const static vocabulory_t vocabulory[] = { { 0, "nfc barcode read" }, { 0, "nfc barcode sim" }, { 1, "nfc barcode help" }, - { 1, "piv help" }, - { 0, "piv select" }, - { 0, "piv getdata" }, - { 0, "piv scan" }, - { 1, "piv list" }, { 1, "smart help" }, { 1, "smart list" }, { 0, "smart info" }, diff --git a/client/src/ui.c b/client/src/ui.c index 839dd22b0..d9f4514cf 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -62,9 +62,9 @@ pthread_mutex_t g_print_lock = PTHREAD_MUTEX_INITIALIZER; static void fPrintAndLog(FILE *stream, const char *fmt, ...); #ifdef _WIN32 - #define MKDIR_CHK _mkdir(path) +#define MKDIR_CHK _mkdir(path) #else - #define MKDIR_CHK mkdir(path, 0700) +#define MKDIR_CHK mkdir(path, 0700) #endif @@ -107,8 +107,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam if ((result != 0) && create_home) { - if (MKDIR_CHK) - { + if (MKDIR_CHK) { fprintf(stderr, "Could not create user directory %s\n", path); free(path); return PM3_EFILE; @@ -140,8 +139,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam if ((result != 0) && create_home) { - if (MKDIR_CHK) - { + if (MKDIR_CHK) { fprintf(stderr, "Could not create user directory %s\n", path); free(path); return PM3_EFILE; @@ -155,7 +153,7 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam } pathlen += strlen(filename); - char *tmp = realloc(path, pathlen *sizeof(char)); + char *tmp = realloc(path, pathlen * sizeof(char)); if (tmp == NULL) { //free(path); return PM3_EMALLOC; diff --git a/doc/commands.json b/doc/commands.json index 7546493bb..47f77d21a 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -761,7 +761,7 @@ "options": [ "-h, --help This help", "-k, -K, --keep Keep field ON for next command", - "-a, -A, --apdu Show APDU requests and responses", + "-a, -A, --apdu Show APDU reqests and responses", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)" ], "usage": "emv challenge [-hkaw]" @@ -777,7 +777,7 @@ "options": [ "-h, --help This help", "-s, -S, --select Activate field and select card", - "-a, -A, --apdu Show APDU requests and responses", + "-a, -A, --apdu Show APDU reqests and responses", "-t, -T, --tlv TLV decode results", "-j, -J, --jload Load transaction parameters from `emv_defparams.json` file", "-f, -F, --forceaid Force search AID. Search AID instead of execute PPSE", @@ -807,7 +807,7 @@ "-d, -D, --decision Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested", "-p, -P, --params Load parameters from `emv_defparams.json` file for CDOLdata making from CDOL and parameters", "-m, -M, --make Make CDOLdata from CDOL (tag 8C and 8D) and parameters (def: use default parameters)", - "-a, -A, --apdu Show APDU requests and responses", + "-a, -A, --apdu Show APDU reqests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " CDOLdata/CDOL" @@ -828,7 +828,7 @@ "-k, -K, --keep Keep field ON for next command", "-p, -P, --params Load parameters from `emv_defparams.json` file for PDOLdata making from PDOL and parameters", "-m, -M, --make Make PDOLdata from PDOL (tag 9F38) and parameters (def: uses default parameters)", - "-a, -A, --apdu Show APDU requests and responses", + "-a, -A, --apdu Show APDU reqests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " PDOLdata/PDOL" @@ -857,7 +857,7 @@ "-k, -K, --keep Keep field ON for next command", "-p, -P, --params Load parameters from `emv_defparams.json` file for DDOLdata making from DDOL and parameters", "-m, -M, --make Make DDOLdata from DDOL (tag 9F49) and parameters (def: use default parameters)", - "-a, -A, --apdu Show APDU requests and responses", + "-a, -A, --apdu Show APDU reqests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " DDOLdata/DDOL" @@ -868,22 +868,22 @@ "command": "emv list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "emv list --frame -> show frame delay times", + "emv list -f -> show frame delay times", "emv list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "emv list [-h1crux] [--frame] [-f ]" + "usage": "emv list [-h1fcrux] [--dict ]" }, "emv pse": { "command": "emv pse", @@ -899,7 +899,7 @@ "-k, -K, --keep Keep field ON for next command", "-1, --pse PSE (1PAY.SYS.DDF01) mode", "-2, --ppse PPSE (2PAY.SYS.DDF01) mode (def)", - "-a, -A, --apdu Show APDU requests and responses", + "-a, -A, --apdu Show APDU reqests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)" ], @@ -916,7 +916,7 @@ "options": [ "-h, --help This help", "-k, -K, --keep Keep field ON for next command", - "-a, -A, --apdu Show APDU requests and responses", + "-a, -A, --apdu Show APDU reqests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " help` for details of a command prefs { Edit client/device preferences... } -------- ----------------------- Technology ----------------------- analyse { Analyse utils... } data { Plot window / data buffer manipulation... } emv { EMV ISO-14443 / ISO-7816... } hf { High frequency commands... } hw { Hardware commands... } lf { Low frequency commands... } nfc { NFC commands... } piv { PIV commands... } reveng { CRC calculations from RevEng software... } smart { Smart card ISO-7816 commands... } script { Scripting commands... } trace { Trace manipulation... } wiegand { Wiegand format manipulation... } -------- ----------------------- General ----------------------- clear Clear screen hints Turn hints on / off msleep Add a pause in milliseconds rem Add a text line in log file quit exit Exit program", + "description": "help Use ` help` for details of a command prefs { Edit client/device preferences... } -------- ----------------------- Technology ----------------------- analyse { Analyse utils... } data { Plot window / data buffer manipulation... } emv { EMV ISO-14443 / ISO-7816... } hf { High frequency commands... } hw { Hardware commands... } lf { Low frequency commands... } nfc { NFC commands... } reveng { CRC calculations from RevEng software... } smart { Smart card ISO-7816 commands... } script { Scripting commands... } trace { Trace manipulation... } wiegand { Wiegand format manipulation... } -------- ----------------------- General ----------------------- clear Clear screen hints Turn hints on / off msleep Add a pause in milliseconds rem Add a text line in log file quit exit Exit program", "notes": [], "offline": true, "options": [], @@ -1145,22 +1145,22 @@ "command": "hf 14a list", "description": "Alias of `trace list -t 14a` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf 14a list --frame -> show frame delay times", + "hf 14a list -f -> show frame delay times", "hf 14a list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf 14a list [-h1crux] [--frame] [-f ]" + "usage": "hf 14a list [-h1fcrux] [--dict ]" }, "hf 14a ndefformat": { "command": "hf 14a ndefformat", @@ -1259,7 +1259,7 @@ }, "hf 14a sim": { "command": "hf 14a sim", - "description": "Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID Use type 7 for Mifare Ultralight EV1, Amiibo (NTAG215 pack 0x8080)", + "description": "Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID", "notes": [ "hf 14a sim -t 1 --uid 11223344 -> MIFARE Classic 1k", "hf 14a sim -t 2 -> MIFARE Ultralight", @@ -1267,7 +1267,7 @@ "hf 14a sim -t 4 -> ISO/IEC 14443-4", "hf 14a sim -t 5 -> MIFARE Tnp3xxx", "hf 14a sim -t 6 -> MIFARE Mini", - "hf 14a sim -t 7 -> MFU EV1 / NTAG 215 Amiibo", + "hf 14a sim -t 7 -> Amiibo (NTAG 215), pack 0x8080", "hf 14a sim -t 8 -> MIFARE Classic 4k", "hf 14a sim -t 9 -> FM11RF005SH Shanghai Metro", "hf 14a sim -t 10 -> ST25TA IKEA Rothult" @@ -1363,22 +1363,22 @@ "command": "hf 14b list", "description": "Alias of `trace list -t 14b` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf 14b list --frame -> show frame delay times", + "hf 14b list -f -> show frame delay times", "hf 14b list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf 14b list [-h1crux] [--frame] [-f ]" + "usage": "hf 14b list [-h1fcrux] [--dict ]" }, "hf 14b ndefread": { "command": "hf 14b ndefread", @@ -1637,22 +1637,22 @@ "command": "hf 15 list", "description": "Alias of `trace list -t 15` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf 15 list --frame -> show frame delay times", + "hf 15 list -f -> show frame delay times", "hf 15 list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf 15 list [-h1crux] [--frame] [-f ]" + "usage": "hf 15 list [-h1fcrux] [--dict ]" }, "hf 15 raw": { "command": "hf 15 raw", @@ -2232,22 +2232,22 @@ "command": "hf emrtd list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf emrtd list --frame -> show frame delay times", + "hf emrtd list -f -> show frame delay times", "hf emrtd list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf emrtd list [-h1crux] [--frame] [-f ]" + "usage": "hf emrtd list [-h1fcrux] [--dict ]" }, "hf epa cnonces": { "command": "hf epa cnonces", @@ -2367,22 +2367,22 @@ "command": "hf felica list", "description": "Alias of `trace list -t felica` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf felica list --frame -> show frame delay times", + "hf felica list -f -> show frame delay times", "hf felica list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf felica list [-h1crux] [--frame] [-f ]" + "usage": "hf felica list [-h1fcrux] [--dict ]" }, "hf felica litedump": { "command": "hf felica litedump", @@ -2575,7 +2575,7 @@ "offline": false, "options": [ "-h, --help This help", - "-a, --apdu Show APDU requests and responses", + "-a, --apdu Show APDU reqests and responses", "-v, --verbose Verbose mode. vv - show full certificates data", "-c, --cbor Show CBOR decoded data", "-l, --list Add CredentialId from json to allowList", @@ -2596,7 +2596,7 @@ "offline": false, "options": [ "-h, --help This help", - "-a, --apdu Show APDU requests and responses", + "-a, --apdu Show APDU reqests and responses", "-v, --verbose Verbose mode", "default mode: dont-enforce-user-presence-and-sign", "-u, --user mode: enforce-user-presence-and-sign", @@ -2635,22 +2635,22 @@ "command": "hf fido list", "description": "Alias of `trace list -t 14a` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf fido list --frame -> show frame delay times", + "hf fido list -f -> show frame delay times", "hf fido list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf fido list [-h1crux] [--frame] [-f ]" + "usage": "hf fido list [-h1fcrux] [--dict ]" }, "hf fido make": { "command": "hf fido make", @@ -2662,7 +2662,7 @@ "offline": false, "options": [ "-h, --help This help", - "-a, --apdu Show APDU requests and responses", + "-a, --apdu Show APDU reqests and responses", "-v, --verbose Verbose mode. vv - show full certificates data", "-t, --tlv Show DER certificate contents in TLV representation", "-c, --cbor Show CBOR decoded data", @@ -2916,10 +2916,9 @@ "-f, --file Dictionary file with default iclass keys", "--credit key is assumed to be the credit key", "--elite elite computations applied to key", - "--raw no computations applied to key (raw)", - "--shallow use shallow (ASK) reader modulation instead of OOK" + "--raw no computations applied to key (raw)" ], - "usage": "hf iclass chk [-h] -f [--credit] [--elite] [--raw] [--shallow]" + "usage": "hf iclass chk [-h] -f [--credit] [--elite] [--raw]" }, "hf iclass configcard": { "command": "hf iclass configcard", @@ -2970,11 +2969,9 @@ "--elite elite computations applied to key", "--raw raw, the key is interpreted as raw block 3/4", "--nr replay of NR/MAC", - "-z, --dense dense dump output style", - "--force force unsecure card read", - "--shallow use shallow (ASK) reader modulation instead of OOK" + "-z, --dense dense dump output style" ], - "usage": "hf iclass dump [-hz] [-f ] [-k ] [--ki ] [--credit ] [--ci ] [--elite] [--raw] [--nr] [--force] [--shallow]" + "usage": "hf iclass dump [-hz] [-f ] [-k ] [--ki ] [--credit ] [--ci ] [--elite] [--raw] [--nr]" }, "hf iclass eload": { "command": "hf iclass eload", @@ -2993,7 +2990,7 @@ }, "hf iclass encode": { "command": "hf iclass encode", - "description": "Encode binary wiegand to block 7,8,9 Use either --bin or --wiegand/--fc/--cn", + "description": "Encode binary wiegand to block 7 Use either --bin or --wiegand/--fc/--cn", "notes": [ "hf iclass encode --bin 10001111100000001010100011 --ki 0 -> FC 31 CN 337", "hf iclass encode --fc 31 --cn 337 --ki 0 -> FC 31 CN 337", @@ -3010,10 +3007,9 @@ "--enckey 3DES transport key, 16 hex bytes", "--fc facility code", "--cn card number", - "-w, --wiegand see `wiegand list` for available formats", - "--shallow use shallow (ASK) reader modulation instead of OOK" + "-w, --wiegand see `wiegand list` for available formats" ], - "usage": "hf iclass encode [-h] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ] [--shallow]" + "usage": "hf iclass encode [-h] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ]" }, "hf iclass encrypt": { "command": "hf iclass encrypt", @@ -3080,31 +3076,30 @@ ], "offline": true, "options": [ - "-h, --help This help", - "--shallow use shallow (ASK) reader modulation instead of OOK" + "-h, --help This help" ], - "usage": "hf iclass info [-h] [--shallow]" + "usage": "hf iclass info [-h]" }, "hf iclass list": { "command": "hf iclass list", "description": "Alias of `trace list -t iclass` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf iclass list --frame -> show frame delay times", + "hf iclass list -f -> show frame delay times", "hf iclass list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf iclass list [-h1crux] [--frame] [-f ]" + "usage": "hf iclass list [-h1fcrux] [--dict ]" }, "hf iclass loclass": { "command": "hf iclass loclass", @@ -3195,10 +3190,9 @@ "--elite elite computations applied to key", "--raw no computations applied to key", "--nr replay of NR/MAC", - "-v, --verbose verbose output", - "--shallow use shallow (ASK) reader modulation instead of OOK" + "-v, --verbose verbose output" ], - "usage": "hf iclass rdbl [-hv] [-k ] [--ki ] -b [--credit] [--elite] [--raw] [--nr] [--shallow]" + "usage": "hf iclass rdbl [-hv] [-k ] [--ki ] -b [--credit] [--elite] [--raw] [--nr]" }, "hf iclass reader": { "command": "hf iclass reader", @@ -3209,10 +3203,9 @@ "offline": false, "options": [ "-h, --help This help", - "-@ optional - continuous reader mode", - "--shallow use shallow (ASK) reader modulation instead of OOK" + "-@ optional - continuous reader mode" ], - "usage": "hf iclass reader [-h@] [--shallow]" + "usage": "hf iclass reader [-h@]" }, "hf iclass restore": { "command": "hf iclass restore", @@ -3233,10 +3226,9 @@ "--credit key is assumed to be the credit key", "--elite elite computations applied to key", "--raw no computations applied to key", - "-v, --verbose verbose output", - "--shallow use shallow (ASK) reader modulation instead of OOK" + "-v, --verbose verbose output" ], - "usage": "hf iclass restore [-hv] -f [-k ] [--ki ] --first --last [--credit] [--elite] [--raw] [--shallow]" + "usage": "hf iclass restore [-hv] -f [-k ] [--ki ] --first --last [--credit] [--elite] [--raw]" }, "hf iclass sim": { "command": "hf iclass sim", @@ -3308,10 +3300,9 @@ "--elite elite computations applied to key", "--raw no computations applied to key", "--nr replay of NR/MAC", - "-v, --verbose verbose output", - "--shallow use shallow (ASK) reader modulation instead of OOK" + "-v, --verbose verbose output" ], - "usage": "hf iclass wrbl [-hv] [-k ] [--ki ] -b -d [-m ] [--credit] [--elite] [--raw] [--nr] [--shallow]" + "usage": "hf iclass wrbl [-hv] [-k ] [--ki ] -b -d [-m ] [--credit] [--elite] [--raw] [--nr]" }, "hf jooki clone": { "command": "hf jooki clone", @@ -3409,7 +3400,7 @@ "options": [ "-h, --help This help", "-k, --keep keep field ON for next command", - "-a, --apdu Show APDU requests and responses" + "-a, --apdu show APDU reqests and responses" ], "usage": "hf ksx6924 balance [-hka]" }, @@ -3431,23 +3422,23 @@ "options": [ "-h, --help This help", "-k, --keep keep field ON for next command", - "-a, --apdu Show APDU requests and responses" + "-a, --apdu show APDU reqests and responses" ], "usage": "hf ksx6924 info [-hka]" }, - "hf ksx6924 init": { - "command": "hf ksx6924 init", - "description": "Perform transaction initialization with Mpda (Money of Purchase Transaction)", + "hf ksx6924 initialize": { + "command": "hf ksx6924 initialize", + "description": "Perform transaction initialization (mpda)", "notes": [ - "hf ksx6924 init 000003e8 -> Mpda" + "hf ksx6924 initialize 000003e8 -> mpda" ], "offline": false, "options": [ "-h, --help This help", "-k, --keep keep field ON for next command", - "-a, --apdu Show APDU requests and responses" + "-a, --apdu show APDU reqests and responses" ], - "usage": "hf ksx6924 init [-hka] " + "usage": "hf ksx6924 initialize [-hka] " }, "hf ksx6924 prec": { "command": "hf ksx6924 prec", @@ -3459,7 +3450,7 @@ "options": [ "-h, --help This help", "-k, --keep keep field ON for next command", - "-a, --apdu Show APDU requests and responses" + "-a, --apdu show APDU reqests and responses" ], "usage": "hf ksx6924 prec [-hka] " }, @@ -3472,7 +3463,7 @@ "offline": false, "options": [ "-h, --help This help", - "-a, --apdu Show APDU requests and responses" + "-a, --apdu show APDU reqests and responses" ], "usage": "hf ksx6924 select [-ha]" }, @@ -3582,22 +3573,22 @@ "command": "hf legic list", "description": "Alias of `trace list -t legic` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf legic list --frame -> show frame delay times", + "hf legic list -f -> show frame delay times", "hf legic list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf legic list [-h1crux] [--frame] [-f ]" + "usage": "hf legic list [-h1fcrux] [--dict ]" }, "hf legic rdbl": { "command": "hf legic rdbl", @@ -3704,22 +3695,22 @@ "command": "hf list", "description": "Alias of `trace list -t raw` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf list --frame -> show frame delay times", + "hf list -f -> show frame delay times", "hf list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf list [-h1crux] [--frame] [-f ]" + "usage": "hf list [-h1fcrux] [--dict ]" }, "hf lto dump": { "command": "hf lto dump", @@ -3758,22 +3749,22 @@ "command": "hf lto list", "description": "Alias of `trace list -t lto` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf lto list --frame -> show frame delay times", + "hf lto list -f -> show frame delay times", "hf lto list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf lto list [-h1crux] [--frame] [-f ]" + "usage": "hf lto list [-h1fcrux] [--dict ]" }, "hf lto rdbl": { "command": "hf lto rdbl", @@ -3978,7 +3969,7 @@ "--1k MIFARE Classic 1k / S50 (def)", "--2k MIFARE Classic/Plus 2k", "--4k MIFARE Classic 4k / S70", - "--emu to emulator memory" + "--emu from emulator memory" ], "usage": "hf mf csave [-h] [-f ] [--mini] [--1k] [--2k] [--4k] [--emu]" }, @@ -4312,85 +4303,6 @@ ], "usage": "hf mf gen3uid [-h] [-u ]" }, - "hf mf ggetblk": { - "command": "hf mf ggetblk", - "description": "Get block data from magic gen4 GTU card.", - "notes": [ - "hf mf ggetblk --blk 0 -> get block 0 (manufacturer)", - "hf mf ggetblk --blk 3 -v -> get block 3, decode sector trailer" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-b, --blk block number", - "-v, --verbose verbose output", - "-p, --pwd password 4bytes" - ], - "usage": "hf mf ggetblk [-hv] -b [-p ]" - }, - "hf mf gload": { - "command": "hf mf gload", - "description": "Load magic gen4 gtu card with data from (bin/eml/json) dump file or from emulator memory.", - "notes": [ - "hf mf gload --emu", - "hf mf gload -f hf-mf-01020304.eml", - "hf mf gload -p AABBCCDD --4k -v -f hf-mf-01020304-dump.bin", - "", - "Card must be configured beforehand with `script run hf_mf_ultimatecard`.", - "Blocks are 16 bytes long." - ], - "offline": false, - "options": [ - "-h, --help This help", - "--mini MIFARE Classic Mini / S20", - "--1k MIFARE Classic 1k / S50 (def)", - "--2k MIFARE Classic/Plus 2k", - "--4k MIFARE Classic 4k / S70", - "-p, --pwd password 4bytes", - "-v, --verbose verbose output", - "-f, --file filename of dump", - "--emu from emulator memory", - "--start index of block to start writing (default 0)", - "--end index of block to end writing (default last block)" - ], - "usage": "hf mf gload [-hv] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu] [--start ] [--end ]" - }, - "hf mf gsave": { - "command": "hf mf gsave", - "description": "Save `magic gen4 gtu` card memory into three files (BIN/EML/JSON)or into emulator memory", - "notes": [ - "hf mf gsave", - "hf mf gsave --4k", - "hf mf gsave -p DEADBEEF -f hf-mf-01020304.json" - ], - "offline": false, - "options": [ - "-h, --help This help", - "--mini MIFARE Classic Mini / S20", - "--1k MIFARE Classic 1k / S50 (def)", - "--2k MIFARE Classic/Plus 2k", - "--4k MIFARE Classic 4k / S70", - "-p, --pwd password 4bytes", - "-f, --file filename of dump", - "--emu to emulator memory" - ], - "usage": "hf mf gsave [-h] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu]" - }, - "hf mf gsetblk": { - "command": "hf mf gsetblk", - "description": "Set block data on a magic gen4 GTU card", - "notes": [ - "hf mf gsetblk --blk 1 -d 000102030405060708090a0b0c0d0e0f" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-b, --blk block number", - "-d, --data bytes to write, 16 hex bytes", - "-p, --pwd password 4bytes" - ], - "usage": "hf mf gsetblk [-h] -b [-d ] [-p ]" - }, "hf mf gview": { "command": "hf mf gview", "description": "View `magic gen4 gtu` card memory", @@ -4412,9 +4324,8 @@ }, "hf mf hardnested": { "command": "hf mf hardnested", - "description": "Nested attack for hardened MIFARE Classic cards. if card is EV1, command can detect and use known key see example below `--i` set type of SIMD instructions. Without this flag programs autodetect it. or hf mf hardnested -r --tk [known target key] Add the known target key to check if it is present in the remaining key space hf mf hardnested --blk 0 -a -k A0A1A2A3A4A5 --tblk 4 --ta --tk FFFFFFFFFFFF", + "description": "Nested attack for hardened MIFARE Classic cards. `--i` set type of SIMD instructions. Without this flag programs autodetect it. or hf mf hardnested -r --tk [known target key] Add the known target key to check if it is present in the remaining key space hf mf hardnested --blk 0 -a -k A0A1A2A3A4A5 --tblk 4 --ta --tk FFFFFFFFFFFF", "notes": [ - "hf mf hardnested --tblk 4 --ta -> works for MFC EV1", "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta", "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -w", "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -f nonces.bin -w -s", @@ -4461,22 +4372,22 @@ "command": "hf mf list", "description": "Alias of `trace list -t mf` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf mf list --frame -> show frame delay times", + "hf mf list -f -> show frame delay times", "hf mf list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf mf list [-h1crux] [--frame] [-f ]" + "usage": "hf mf list [-h1fcrux] [--dict ]" }, "hf mf mad": { "command": "hf mf mad", @@ -5640,22 +5551,22 @@ "command": "hf mfdes list", "description": "Alias of `trace list -t des` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf mfdes list --frame -> show frame delay times", + "hf mfdes list -f -> show frame delay times", "hf mfdes list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf mfdes list [-h1crux] [--frame] [-f ]" + "usage": "hf mfdes list [-h1fcrux] [--dict ]" }, "hf mfdes lsapp": { "command": "hf mfdes lsapp", @@ -6202,35 +6113,17 @@ ], "usage": "hf mfu eload [-h] -f [-q ]" }, - "hf mfu esave": { - "command": "hf mfu esave", - "description": "Saves emulator memory to a MIFARE Ultralight/NTAG dump file (bin/eml/json) By default number of pages saved depends on defined tag type. You can override this with option --end.", - "notes": [ - "hf mfu esave", - "hf mfu esave --end 255 -> saves whole memory", - "hf mfu esave -f hf-mfu-04010203040506-dump.json" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-e, --end index of last block", - "-f, --file filename of dump" - ], - "usage": "hf mfu esave [-h] [-e ] [-f ]" - }, "hf mfu eview": { "command": "hf mfu eview", - "description": "Displays emulator memory By default number of pages shown depends on defined tag type. You can override this with option --end.", + "description": "It displays emulator memory", "notes": [ - "hf mfu eview", - "hf mfu eview --end 255 -> dumps whole memory" + "hf mfu eview" ], "offline": false, "options": [ - "-h, --help This help", - "-e, --end index of last block" + "-h, --help This help" ], - "usage": "hf mfu eview [-h] [-e ]" + "usage": "hf mfu eview [-h]" }, "hf mfu help": { "command": "hf mfu help", @@ -6398,8 +6291,8 @@ "description": "Simulate MIFARE Ultralight family type based upon ISO/IEC 14443 type A tag with 4,7 or 10 byte UID from emulator memory. See `hf mfu eload` first. The UID from emulator memory will be used if not specified. See `hf 14a sim -h` to see available types. You want 2 or 7 usually.", "notes": [ "hf mfu sim -t 2 --uid 11223344556677 -> MIFARE Ultralight", - "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> MFU EV1 / NTAG 215 Amiibo", - "hf mfu sim -t 7 -> MFU EV1 / NTAG 215 Amiibo" + "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> Amiibo (NTAG 215), pack 0x8080", + "hf mfu sim -t 7 -> Amiibo (NTAG 215), pack 0x8080" ], "offline": false, "options": [ @@ -6540,22 +6433,22 @@ "command": "hf seos list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf seos list --frame -> show frame delay times", + "hf seos list -f -> show frame delay times", "hf seos list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf seos list [-h1crux] [--frame] [-f ]" + "usage": "hf seos list [-h1fcrux] [--dict ]" }, "hf sniff": { "command": "hf sniff", @@ -6598,22 +6491,22 @@ "command": "hf st25ta list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf st25ta list --frame -> show frame delay times", + "hf st25ta list -f -> show frame delay times", "hf st25ta list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf st25ta list [-h1crux] [--frame] [-f ]" + "usage": "hf st25ta list [-h1fcrux] [--dict ]" }, "hf st25ta ndefread": { "command": "hf st25ta ndefread", @@ -6748,22 +6641,22 @@ "command": "hf thinfilm list", "description": "Alias of `trace list -t thinfilm` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf thinfilm list --frame -> show frame delay times", + "hf thinfilm list -f -> show frame delay times", "hf thinfilm list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf thinfilm list [-h1crux] [--frame] [-f ]" + "usage": "hf thinfilm list [-h1fcrux] [--dict ]" }, "hf thinfilm sim": { "command": "hf thinfilm sim", @@ -6819,22 +6712,22 @@ "command": "hf topaz list", "description": "Alias of `trace list -t topaz` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf topaz list --frame -> show frame delay times", + "hf topaz list -f -> show frame delay times", "hf topaz list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "hf topaz list [-h1crux] [--frame] [-f ]" + "usage": "hf topaz list [-h1fcrux] [--dict ]" }, "hf topaz raw": { "command": "hf topaz raw", @@ -8562,22 +8455,22 @@ "command": "lf hitag list", "description": "Alias of `trace list -t hitag2` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "lf hitag list --frame -> show frame delay times", + "lf hitag list -f -> show frame delay times", "lf hitag list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "lf hitag list [-h1crux] [--frame] [-f ]" + "usage": "lf hitag list [-h1fcrux] [--dict ]" }, "lf hitag reader": { "command": "lf hitag reader", @@ -8734,28 +8627,6 @@ ], "usage": "lf indala altdemod [-hl]" }, - "lf indala brute": { - "command": "lf indala brute", - "description": "Enables bruteforce of INDALA readers with specified facility code. This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step if cardnumber is not given, it starts with 1 and goes up to 65535", - "notes": [ - "lf indala brute --fc 224", - "lf indala brute --fc 21 -d 2000", - "lf indala brute -v --fc 21 --cn 200 -d 2000", - "lf indala brute -v --fc 21 --cn 200 -d 2000 --up" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-v, --verbose verbose output", - "--fc facility code", - "--cn card number to start with", - "-d, --delay delay betweens attempts in ms. Default 1000ms", - "--up direction to increment card number. (default is both directions)", - "--down direction to decrement card number. (default is both directions)", - "--4041x specify Indala 4041X format" - ], - "usage": "lf indala brute [-hv] [--fc ] [--cn ] [-d ] [--up] [--down] [--4041x]" - }, "lf indala clone": { "command": "lf indala clone", "description": "clone Indala UID to T55x7 or Q5/T5555 tag using different known formats", @@ -8811,8 +8682,6 @@ "description": "Enables simulation of Indala card with specified facility code and card number. Simulation runs until the button is pressed or another USB command is issued.", "notes": [ "lf indala sim --heden 888", - "lf indala sim --fc 123 --cn 1337", - "lf indala sim --fc 123 --cn 1337 --4041x", "lf indala sim --raw a0000000a0002021", "lf indala sim --raw 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5" ], @@ -8820,12 +8689,9 @@ "options": [ "-h, --help This help", "-r, --raw raw bytes", - "--heden Cardnumber for Heden 2L format", - "--fc Facility code (26 bit H10301 format)", - "--cn Card number (26 bit H10301 format)", - "--4041x Optional - specify Indala 4041X format, must use with fc and cn" + "--heden Cardnumber for Heden 2L format" ], - "usage": "lf indala sim [-h] [-r ] [--heden ] [--fc ] [--cn ] [--4041x]" + "usage": "lf indala sim [-h] [-r ] [--heden ]" }, "lf io clone": { "command": "lf io clone", @@ -10952,93 +10818,6 @@ ], "usage": "hf 14b ndefread [-hv] [-f ]" }, - "piv getdata": { - "command": "piv getdata", - "description": "Get a data container of a given tag", - "notes": [ - "piv getdata -s 5fc102 -> select card, select applet, get card holder unique identifer", - "piv getdata -st 5fc102 -> select card, select applet, get card holder unique identifer, show result in TLV" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-s, -S, --select Activate field and select applet", - "-k, -K, --keep Keep field for next command", - "-a, -A, --apdu Show APDU requests and responses", - "-t, -T, --tlv TLV decode results", - "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", - "--aid Applet ID to select. By default A0000003080000100 will be used", - " Tag ID to read, between 1 and 3 bytes." - ], - "usage": "piv getdata [-hskatw] [--aid ] " - }, - "piv help": { - "command": "piv help", - "description": "help This help list List ISO7816 history", - "notes": [], - "offline": true, - "options": [], - "usage": "" - }, - "piv list": { - "command": "piv list", - "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", - "notes": [ - "piv list --frame -> show frame delay times", - "piv list -1 -> use trace buffer" - ], - "offline": true, - "options": [ - "-h, --help This help", - "-1, --buffer use data from trace buffer", - "--frame show frame delay times", - "-c mark CRC bytes", - "-r show relative times (gap and duration)", - "-u display times in microseconds instead of clock cycles", - "-x show hexdump to convert to pcap(ng)", - "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" - ], - "usage": "piv list [-h1crux] [--frame] [-f ]" - }, - "piv scan": { - "command": "piv scan", - "description": "Scan a PIV card for known containers", - "notes": [ - "piv scan -s -> select card, select applet and run scan", - "piv scan -st --aid a00000030800001000 -> select card, select applet a00000030800001000, show result of the scan in TLV" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-s, -S, --select Activate field and select applet", - "-k, -K, --keep Keep field for next command", - "-a, -A, --apdu Show APDU requests and responses", - "-t, -T, --tlv TLV decode results", - "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", - "--aid Applet ID to select. By default A0000003080000100 will be used" - ], - "usage": "piv scan [-hskatw] [--aid ]" - }, - "piv select": { - "command": "piv select", - "description": "Executes select applet command", - "notes": [ - "piv select -s -> select card, select applet", - "piv select -st --aid a00000030800001000 -> select card, select applet a00000030800001000, show result in TLV" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-s, -S, --select Activate field and select applet", - "-k, -K, --keep Keep field for next command", - "-a, -A, --apdu Show APDU requests and responses", - "-t, -T, --tlv TLV decode results", - "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", - "--aid Applet ID to select. By default A0000003080000100 will be used" - ], - "usage": "piv select [-hskatw] [--aid ]" - }, "prefs get barmode": { "command": "prefs get barmode", "description": "Get preference of HF/LF tune command styled output in the client", @@ -11394,22 +11173,22 @@ "command": "smart list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "smart list --frame -> show frame delay times", + "smart list -f -> show frame delay times", "smart list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "smart list [-h1crux] [--frame] [-f ]" + "usage": "smart list [-h1fcrux] [--dict ]" }, "smart raw": { "command": "smart raw", @@ -11516,24 +11295,24 @@ "trace list -t thinfilm -> interpret as Thinfilm", "trace list -t topaz -> interpret as Topaz", "", - "trace list -t mf -f mfc_default_keys.dic -> use default dictionary file", - "trace list -t 14a --frame -> show frame delay times", + "trace list -t mf --dict -> use dictionary keys file", + "trace list -t 14a -f -> show frame delay times", "trace list -t 14a -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "--frame show frame delay times", + "-f show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", "-t, --type protocol to annotate the trace", - "-f, --file filename of dictionary" + "--dict use dictionary keys file" ], - "usage": "trace list [-h1crux] [--frame] [-t ] [-f ]" + "usage": "trace list [-h1fcrux] [-t ] [--dict ]" }, "trace load": { "command": "trace load", @@ -11731,8 +11510,8 @@ } }, "metadata": { - "commands_extracted": 738, + "commands_extracted": 727, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-01-06T21:37:50" + "extracted_on": "2023-01-14T21:16:27" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index bb4c68869..2133d960b 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -367,11 +367,11 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`hf ksx6924 help `|Y |`This help` -|`hf ksx6924 select `|N |`Select application, and leave field up` -|`hf ksx6924 info `|N |`Get info about a KS X 6924 (T-Money, Snapper+) transit card` |`hf ksx6924 balance `|N |`Get current purse balance` -|`hf ksx6924 init `|N |`Perform transaction initialization with Mpda` +|`hf ksx6924 info `|N |`Get info about a KS X 6924 (T-Money, Snapper+) transit card` +|`hf ksx6924 initialize `|N |`Perform transaction initialization (Mpda)` |`hf ksx6924 prec `|N |`Send proprietary get record command (CLA=90, INS=4C)` +|`hf ksx6924 select `|N |`Select application, and leave field up` ### hf jooki @@ -510,10 +510,6 @@ Check column "offline" for their availability. |`hf mf gen3uid `|N |`Set UID without changing manufacturer block` |`hf mf gen3blk `|N |`Overwrite manufacturer block` |`hf mf gen3freeze `|N |`Perma lock UID changes. irreversible` -|`hf mf ggetblk `|N |`Read block from card` -|`hf mf gload `|N |`Load dump to card` -|`hf mf gsave `|N |`Save dump from card into file or emulator` -|`hf mf gsetblk `|N |`Write block to card` |`hf mf gview `|N |`View card` |`hf mf ndefformat `|N |`Format MIFARE Classic Tag as NFC Tag` |`hf mf ndefread `|N |`Read and print NDEF records from card` @@ -558,8 +554,7 @@ Check column "offline" for their availability. |`hf mfu restore `|N |`Restore a dump onto a MFU MAGIC tag` |`hf mfu view `|Y |`Display content from tag dump file` |`hf mfu wrbl `|N |`Write block` -|`hf mfu eload `|N |`Load Ultralight dump file into emulator memory` -|`hf mfu esave `|N |`Save Ultralight dump file from emulator memory` +|`hf mfu eload `|N |`Load Ultralight .eml dump file into emulator memory` |`hf mfu eview `|N |`View emulator memory` |`hf mfu sim `|N |`Simulate MIFARE Ultralight from emulator memory` |`hf mfu setpwd `|N |`Set 3DES key - Ultralight-C` @@ -976,7 +971,6 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`lf indala help `|Y |`This help` -|`lf indala brute `|N |`Demodulate an Indala tag (PSK1) from the GraphBuffer` |`lf indala demod `|Y |`Demodulate an Indala tag (PSK1) from the GraphBuffer` |`lf indala altdemod `|Y |`Alternative method to demodulate samples for Indala 64 bit UID (option '224' for 224 bit)` |`lf indala reader `|N |`Read an Indala tag from the antenna` @@ -1334,19 +1328,6 @@ Check column "offline" for their availability. |`nfc barcode help `|Y |`This help` -### piv - - { PIV commands... } - -|command |offline |description -|------- |------- |----------- -|`piv help `|Y |`This help` -|`piv select `|N |`Select the PIV applet` -|`piv getdata `|N |`Gets a container on a PIV card` -|`piv scan `|N |`Scan PIV card for known containers` -|`piv list `|Y |`List ISO7816 history` - - ### reveng { CRC calculations from RevEng software... } diff --git a/include/protocol_vigik.h b/include/protocol_vigik.h index a61c4ce03..7512c1c2d 100644 --- a/include/protocol_vigik.h +++ b/include/protocol_vigik.h @@ -42,4 +42,4 @@ typedef struct vigik_pk_s { const char *n; } vigik_pk_t; -#endif \ No newline at end of file +#endif diff --git a/include/protocols.h b/include/protocols.h index 8a00f064c..016584098 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -506,7 +506,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ISO7816_LC_TLV_CONFLICT 0x6A85 // LC / TLV conlict #define ISO7816_INCORRECT_P1P2 0x6A86 // Incorrect parameters (P1,P2) #define ISO7816_FILE_EXISTS 0x6A89 // File exists -#define ISO7816_NOT_IMPLEMENTED 0x6AFF // +#define ISO7816_NOT_IMPLEMENTED 0x6AFF // // 6x 00 #define ISO7816_WRONG_P1P2 0x6B00 // Incorrect parameters (P1,P2) From c9984985fdebafcf2975437e18dfe8132f52f450 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Jan 2023 22:23:40 +0100 Subject: [PATCH 485/759] make miscchecks --- armsrc/Standalone/lf_em4100rsww.c | 2 +- armsrc/Standalone/lf_nedap_sim.c | 2 +- armsrc/iso14443b.c | 18 +- client/luascripts/hf_14a_i2crevive.lua | 2 +- client/luascripts/hf_mf_em_util.lua | 4 +- client/luascripts/hf_mf_uidbruteforce.lua | 4 +- client/luascripts/hf_mf_ultimatecard.lua | 488 +++++++++++----------- client/src/cmdhfepa.c | 4 +- client/src/cmdhfxerox.c | 166 ++++---- doc/commands.json | 2 +- include/protocols.h | 2 +- 11 files changed, 347 insertions(+), 347 deletions(-) diff --git a/armsrc/Standalone/lf_em4100rsww.c b/armsrc/Standalone/lf_em4100rsww.c index 727d188a3..dc202d49a 100644 --- a/armsrc/Standalone/lf_em4100rsww.c +++ b/armsrc/Standalone/lf_em4100rsww.c @@ -11,7 +11,7 @@ // then from shell: // hexdump lf.bin -e '5/1 "%02X" /0 "\n"' // -// To recall only LAST stored ID from flash use lf-last instead of lf file. +// To recall only LAST stored ID from flash use lf-last instead of lf file. // //----------------------------------------------------------------------------- // Modes of operation: diff --git a/armsrc/Standalone/lf_nedap_sim.c b/armsrc/Standalone/lf_nedap_sim.c index dcd093fee..726f13ca8 100644 --- a/armsrc/Standalone/lf_nedap_sim.c +++ b/armsrc/Standalone/lf_nedap_sim.c @@ -27,7 +27,7 @@ #include "BigBuf.h" #include "crc16.h" -#define MODULE_LONG_NAME "LF Nedap simple simulator" +#define MODULE_LONG_NAME "LF Nedap simple simulator" typedef struct _NEDAP_TAG { uint8_t subType; diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 760736a5a..e4f1e4e93 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -1814,17 +1814,17 @@ int iso14443b_select_xrx_card(iso14b_card_select_t *card) { static const uint8_t x_wup2[] = { 0x5D, 0x37, 0x21, 0x71, 0x71 }; uint8_t slot_mark[1]; - uint8_t x_atqb[24] = {0x0}; // ATQB len = 18 + uint8_t x_atqb[24] = {0x0}; // ATQB len = 18 uint32_t start_time = 0; uint32_t eof_time = 0; - iso14b_set_timeout(24); // wait for carrier + iso14b_set_timeout(24); // wait for carrier // wup1 CodeAndTransmit14443bAsReader(x_wup1, sizeof(x_wup1), &start_time, &eof_time, true); - start_time = eof_time + US_TO_SSP(9000); // 9ms before next cmd + start_time = eof_time + US_TO_SSP(9000); // 9ms before next cmd // wup2 CodeAndTransmit14443bAsReader(x_wup2, sizeof(x_wup2), &start_time, &eof_time, true); @@ -1836,7 +1836,7 @@ int iso14443b_select_xrx_card(iso14b_card_select_t *card) { int slot; for (slot = 0; slot < 4; slot++) { - start_time = eof_time + ETU_TO_SSP(30); //(24); // next slot after 24 ETU + start_time = eof_time + ETU_TO_SSP(30); //(24); // next slot after 24 ETU retlen = Get14443bAnswerFromTag(x_atqb, sizeof(x_atqb), iso14b_timeout, &eof_time); @@ -1850,14 +1850,14 @@ int iso14443b_select_xrx_card(iso14b_card_select_t *card) { // tx unframed slot-marker - if (Demod.posCount) { // no rx, but subcarrier burst detected + if (Demod.posCount) { // no rx, but subcarrier burst detected uid |= (uint64_t)slot << uid_pos; - slot_mark[0] = 0xB1 + (slot << 1); // ack slot + slot_mark[0] = 0xB1 + (slot << 1); // ack slot CodeAndTransmit14443bAsReader(slot_mark, sizeof(slot_mark), &start_time, &eof_time, false); break; - } else { // no subcarrier burst - slot_mark[0] = 0xA1 + (slot << 1); // nak slot + } else { // no subcarrier burst + slot_mark[0] = 0xA1 + (slot << 1); // nak slot CodeAndTransmit14443bAsReader(slot_mark, sizeof(slot_mark), &start_time, &eof_time, false); } } @@ -1884,7 +1884,7 @@ int iso14443b_select_xrx_card(iso14b_card_select_t *card) { } // VALIDATE CRC - if (check_crc(CRC_14443_B, x_atqb, 18) == false) { // use fixed len because unstable EOF catch + if (check_crc(CRC_14443_B, x_atqb, 18) == false) { // use fixed len because unstable EOF catch return 3; } diff --git a/client/luascripts/hf_14a_i2crevive.lua b/client/luascripts/hf_14a_i2crevive.lua index 3610979b6..59659bb5c 100644 --- a/client/luascripts/hf_14a_i2crevive.lua +++ b/client/luascripts/hf_14a_i2crevive.lua @@ -62,7 +62,7 @@ function main(args) local i local cmds = {} - --check for params + --check for params for o, a in getopt.getopt(args, 'h') do if o == 'h' then return help() end end diff --git a/client/luascripts/hf_mf_em_util.lua b/client/luascripts/hf_mf_em_util.lua index 69537d7dd..e82bc9d1e 100644 --- a/client/luascripts/hf_mf_em_util.lua +++ b/client/luascripts/hf_mf_em_util.lua @@ -63,8 +63,8 @@ local function card_format(key_a,key_b,ab,user,s70) core.console(cmd) print(cmd) core.clearCommandBuffer() - if s70 == false and k > 15 then - return + if s70 == false and k > 15 then + return end end end diff --git a/client/luascripts/hf_mf_uidbruteforce.lua b/client/luascripts/hf_mf_uidbruteforce.lua index 62872e2a3..4835ba03b 100644 --- a/client/luascripts/hf_mf_uidbruteforce.lua +++ b/client/luascripts/hf_mf_uidbruteforce.lua @@ -109,8 +109,8 @@ local function main(args) command = 'hf 14a sim -t 1 -u ' .. uid_format msg('Bruteforcing Mifare Classic card numbers') elseif mftype == 'mfc4' then - command = 'hf 14a sim -t 8 -u ' .. uid_format - msg('Bruteforcing Mifare Classic 4K card numbers') + command = 'hf 14a sim -t 8 -u ' .. uid_format + msg('Bruteforcing Mifare Classic 4K card numbers') elseif mftype == 'mfu' then command = 'hf 14a sim -t 2 -u ' .. uid_format msg('Bruteforcing Mifare Ultralight card numbers') diff --git a/client/luascripts/hf_mf_ultimatecard.lua b/client/luascripts/hf_mf_ultimatecard.lua index aec47e9d0..42a5e1887 100644 --- a/client/luascripts/hf_mf_ultimatecard.lua +++ b/client/luascripts/hf_mf_ultimatecard.lua @@ -50,17 +50,17 @@ arguments = [[ -c read magic configuration -u UID (8-14 hexsymbols), set UID on tag -t tag type to impersonate - 1 = Mifare Mini S20 4-byte 12 = NTAG 210 - 2 = Mifare Mini S20 7-byte 13 = NTAG 212 - 3 = Mifare 1k S50 4-byte 14 = NTAG 213 - 4 = Mifare 1k S50 7-byte 15 = NTAG 215 - 5 = Mifare 4k S70 4-byte 16 = NTAG 216 - 6 = Mifare 4k S70 7-byte 17 = NTAG I2C 1K - *** 7 = UL - NOT WORKING FULLY 18 = NTAG I2C 2K - *** 8 = UL-C - NOT WORKING FULLY 19 = NTAG I2C 1K PLUS - 9 = UL EV1 48b 20 = NTAG I2C 2K PLUS - 10 = UL EV1 128b 21 = NTAG 213F - *** 11 = UL Plus - NOT WORKING YET 22 = NTAG 216F + 1 = Mifare Mini S20 4-byte 12 = NTAG 210 + 2 = Mifare Mini S20 7-byte 13 = NTAG 212 + 3 = Mifare 1k S50 4-byte 14 = NTAG 213 + 4 = Mifare 1k S50 7-byte 15 = NTAG 215 + 5 = Mifare 4k S70 4-byte 16 = NTAG 216 + 6 = Mifare 4k S70 7-byte 17 = NTAG I2C 1K + *** 7 = UL - NOT WORKING FULLY 18 = NTAG I2C 2K + *** 8 = UL-C - NOT WORKING FULLY 19 = NTAG I2C 1K PLUS + 9 = UL EV1 48b 20 = NTAG I2C 2K PLUS + 10 = UL EV1 128b 21 = NTAG 213F + *** 11 = UL Plus - NOT WORKING YET 22 = NTAG 216F -p NTAG password (8 hexsymbols), set NTAG password on tag. -a NTAG pack ( 4 hexsymbols), set NTAG pack on tag. @@ -178,7 +178,7 @@ local function read_config() if not info then return false, "Can't select card" end -- read Ultimate Magic Card CONFIG if magicconfig == nil then - magicconfig = send("CF".._key.."C6") + magicconfig = send("CF".._key.."C6") else print('No Config') end -- extract data from CONFIG - based on CONFIG in https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/magic_cards_notes.md#gen-4-gtu @@ -196,92 +196,92 @@ local function read_config() else atsstr = (string.sub(ats, 3)) end if ulprotocol == '00' then - cardprotocol = 'MIFARE Classic Protocol' - ultype = 'Disabled' - if uidlength == '00' then - uid = send("CF".._key.."CE00"):sub(1,8) - if atqaf == '00 04' and sak == '09' then cardtype = 'MIFARE Mini S20 4-byte UID' - elseif atqaf == '00 04' and sak == '08' then cardtype = 'MIFARE 1k S50 4-byte UID' - elseif atqaf == '00 02' and sak == '18' then cardtype = 'MIFARE 4k S70 4-byte UID' - end - elseif uidlength == '01' then - uid = send("CF".._key.."CE00"):sub(1,14) - if atqaf == '00 44' and sak == '09' then cardtype = 'MIFARE Mini S20 7-byte UID' - elseif atqaf == '00 44' and sak == '08' then cardtype = 'MIFARE 1k S50 7-byte UID' - elseif atqaf == '00 42' and sak == '18' then cardtype = 'MIFARE 4k S70 7-byte UID' - end - end + cardprotocol = 'MIFARE Classic Protocol' + ultype = 'Disabled' + if uidlength == '00' then + uid = send("CF".._key.."CE00"):sub(1,8) + if atqaf == '00 04' and sak == '09' then cardtype = 'MIFARE Mini S20 4-byte UID' + elseif atqaf == '00 04' and sak == '08' then cardtype = 'MIFARE 1k S50 4-byte UID' + elseif atqaf == '00 02' and sak == '18' then cardtype = 'MIFARE 4k S70 4-byte UID' + end + elseif uidlength == '01' then + uid = send("CF".._key.."CE00"):sub(1,14) + if atqaf == '00 44' and sak == '09' then cardtype = 'MIFARE Mini S20 7-byte UID' + elseif atqaf == '00 44' and sak == '08' then cardtype = 'MIFARE 1k S50 7-byte UID' + elseif atqaf == '00 42' and sak == '18' then cardtype = 'MIFARE 4k S70 7-byte UID' + end + end elseif ulprotocol == '01' then - -- Read Ultralight config only if UL protocol is enabled - cardprotocol = 'MIFARE Ultralight/NTAG' - block0 = send("3000") - uid0 = block0:sub(1,6) - uid = uid0..block0:sub(9,16) - if ulmode == '00' then ultype = 'Ultralight EV1' - elseif ulmode == '01' then ultype = 'NTAG21x' - elseif ulmode == '02' then ultype = 'Ultralight-C' - elseif ulmode == '03' then ultype = 'Ultralight' - end - -- read VERSION - cversion = send('30FA'):sub(1,16) - -- pwdblock must be set since the 30F1 and 30F2 special commands don't work on the ntag21x part of the UMC - if ulmode == '03' then versionstr = 'Ultralight' - elseif ulmode == '02' then versionstr = 'Ultralight-C' - elseif cversion == '0004030101000B03' then versionstr = 'UL EV1 48b' - elseif cversion == '0004030101000E03' then versionstr = 'UL EV1 128b' - elseif cversion == '0004040101000B03' then versionstr = 'NTAG 210' - elseif cversion == '0004040101000E03' then versionstr = 'NTAG 212' - elseif cversion == '0004040201000F03' then versionstr = 'NTAG 213' - elseif cversion == '0004040201001103' then versionstr = 'NTAG 215' - elseif cversion == '0004040201001303' then versionstr = 'NTAG 216' - elseif cversion == '0004040502011303' then versionstr = 'NTAG I2C 1K' - elseif cversion == '0004040502011503' then versionstr = 'NTAG I2C 2K' - elseif cversion == '0004040502021303' then versionstr = 'NTAG I2C 1K PLUS' - elseif cversion == '0004040502021503' then versionstr = 'NTAG I2C 2K PLUS' - elseif cversion == '0004040401000F03' then versionstr = 'NTAG 213F' - elseif cversion == '0004040401001303' then versionstr = 'NTAG 216F' - end - -- read PWD - cpwd = send("30F0"):sub(1,8) - pwd = send("30E5"):sub(1,8) - -- 04 response indicates that blocks has been locked down. - if pwd == '04' then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end - -- read PACK - cpack = send("30F1"):sub(1,4) - pack = send("30E6"):sub(1,4) - -- read SIGNATURE - signature1 = send('30F2'):sub(1,32) - signature2 = send('30F6'):sub(1,32) - lib14a.disconnect() + -- Read Ultralight config only if UL protocol is enabled + cardprotocol = 'MIFARE Ultralight/NTAG' + block0 = send("3000") + uid0 = block0:sub(1,6) + uid = uid0..block0:sub(9,16) + if ulmode == '00' then ultype = 'Ultralight EV1' + elseif ulmode == '01' then ultype = 'NTAG21x' + elseif ulmode == '02' then ultype = 'Ultralight-C' + elseif ulmode == '03' then ultype = 'Ultralight' + end + -- read VERSION + cversion = send('30FA'):sub(1,16) + -- pwdblock must be set since the 30F1 and 30F2 special commands don't work on the ntag21x part of the UMC + if ulmode == '03' then versionstr = 'Ultralight' + elseif ulmode == '02' then versionstr = 'Ultralight-C' + elseif cversion == '0004030101000B03' then versionstr = 'UL EV1 48b' + elseif cversion == '0004030101000E03' then versionstr = 'UL EV1 128b' + elseif cversion == '0004040101000B03' then versionstr = 'NTAG 210' + elseif cversion == '0004040101000E03' then versionstr = 'NTAG 212' + elseif cversion == '0004040201000F03' then versionstr = 'NTAG 213' + elseif cversion == '0004040201001103' then versionstr = 'NTAG 215' + elseif cversion == '0004040201001303' then versionstr = 'NTAG 216' + elseif cversion == '0004040502011303' then versionstr = 'NTAG I2C 1K' + elseif cversion == '0004040502011503' then versionstr = 'NTAG I2C 2K' + elseif cversion == '0004040502021303' then versionstr = 'NTAG I2C 1K PLUS' + elseif cversion == '0004040502021503' then versionstr = 'NTAG I2C 2K PLUS' + elseif cversion == '0004040401000F03' then versionstr = 'NTAG 213F' + elseif cversion == '0004040401001303' then versionstr = 'NTAG 216F' + end + -- read PWD + cpwd = send("30F0"):sub(1,8) + pwd = send("30E5"):sub(1,8) + -- 04 response indicates that blocks has been locked down. + if pwd == '04' then lib14a.disconnect(); return nil, "can't read configuration, "..err_lock end + -- read PACK + cpack = send("30F1"):sub(1,4) + pack = send("30E6"):sub(1,4) + -- read SIGNATURE + signature1 = send('30F2'):sub(1,32) + signature2 = send('30F6'):sub(1,32) + lib14a.disconnect() end if _print < 1 then - print(string.rep('=', 88)) - print('\t\t\tUltimate Magic Card Configuration') - print(string.rep('=', 88)) - print(' - Raw Config ', string.sub(magicconfig, 1, -9)) - print(' - Card Protocol ', cardprotocol) - print(' - Ultralight Mode ', ultype) - print(' - ULM Backdoor Key ', readpass) - print(' - GTU Mode ', gtustr) - if ulprotocol == '01' then - print(' - Card Type ', versionstr) - else - print(' - Card Type ', cardtype) - end - print(' - UID ', uid) - print(' - ATQA ', atqaf) - print(' - SAK ', sak) - if ulprotocol == '01' then - print('') - print(string.rep('=', 88)) - print('\t\t\tMagic UL/NTAG 21* Configuration') - print(string.rep('=', 88)) - print(' - ATS ', atsstr) - print(' - Password ', '[0xE5] '..pwd, '[0xF0] '..cpwd) - print(' - Pack ', '[0xE6] '..pack, '[0xF1] '..cpack) - print(' - Version ', cversion) - print(' - Signature ', signature1..signature2) - end + print(string.rep('=', 88)) + print('\t\t\tUltimate Magic Card Configuration') + print(string.rep('=', 88)) + print(' - Raw Config ', string.sub(magicconfig, 1, -9)) + print(' - Card Protocol ', cardprotocol) + print(' - Ultralight Mode ', ultype) + print(' - ULM Backdoor Key ', readpass) + print(' - GTU Mode ', gtustr) + if ulprotocol == '01' then + print(' - Card Type ', versionstr) + else + print(' - Card Type ', cardtype) + end + print(' - UID ', uid) + print(' - ATQA ', atqaf) + print(' - SAK ', sak) + if ulprotocol == '01' then + print('') + print(string.rep('=', 88)) + print('\t\t\tMagic UL/NTAG 21* Configuration') + print(string.rep('=', 88)) + print(' - ATS ', atsstr) + print(' - Password ', '[0xE5] '..pwd, '[0xF0] '..cpwd) + print(' - Pack ', '[0xE6] '..pack, '[0xF1] '..cpack) + print(' - Version ', cversion) + print(' - Signature ', signature1..signature2) + end end lib14a.disconnect() return true, 'Ok' @@ -291,41 +291,41 @@ end local function write_uid(useruid) -- read CONFIG if not magicconfig then - _print = 1 - read_config() + _print = 1 + read_config() end local info = connect() if not info then return false, "Can't select card" end -- Writes a MFC UID with GEN4 magic commands. if ulprotocol == '00' then - -- uid string checks - if useruid == nil then return nil, 'empty uid string' end - if #useruid == 0 then return nil, 'empty uid string' end - if (#useruid ~= 8) and (#useruid ~= 14) then return nil, 'UID wrong length. Should be 4 or 7 hex bytes' end - print('Writing new UID ', useruid) - local uidbytes = utils.ConvertHexToBytes(useruid) - local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), uidbytes[4]) - local block0 = string.format('%02X%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], uidbytes[4], bcc1) - local resp = send('CF'.._key..'CD00'..block0) + -- uid string checks + if useruid == nil then return nil, 'empty uid string' end + if #useruid == 0 then return nil, 'empty uid string' end + if (#useruid ~= 8) and (#useruid ~= 14) then return nil, 'UID wrong length. Should be 4 or 7 hex bytes' end + print('Writing new UID ', useruid) + local uidbytes = utils.ConvertHexToBytes(useruid) + local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), uidbytes[4]) + local block0 = string.format('%02X%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], uidbytes[4], bcc1) + local resp = send('CF'.._key..'CD00'..block0) -- Writes a MFUL UID with bcc1, bcc2 using NTAG21xx commands. elseif ulprotocol == '01' then - -- uid string checks - if useruid == nil then return nil, 'empty uid string' end - if #useruid == 0 then return nil, 'empty uid string' end - if #useruid ~= 14 then return nil, 'uid wrong length. Should be 7 hex bytes' end - print('Writing new UID ', useruid) - local uidbytes = utils.ConvertHexToBytes(useruid) - local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), 0x88) - local bcc2 = bxor(bxor(bxor(uidbytes[4], uidbytes[5]), uidbytes[6]), uidbytes[7]) - local block0 = string.format('%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], bcc1) - local block1 = string.format('%02X%02X%02X%02X', uidbytes[4], uidbytes[5], uidbytes[6], uidbytes[7]) - local block2 = string.format('%02X%02X%02X%02X', bcc2, 0x48, 0x00, 0x00) - local resp - resp = send('A200'..block0) - resp = send('A201'..block1) - resp = send('A202'..block2) + -- uid string checks + if useruid == nil then return nil, 'empty uid string' end + if #useruid == 0 then return nil, 'empty uid string' end + if #useruid ~= 14 then return nil, 'uid wrong length. Should be 7 hex bytes' end + print('Writing new UID ', useruid) + local uidbytes = utils.ConvertHexToBytes(useruid) + local bcc1 = bxor(bxor(bxor(uidbytes[1], uidbytes[2]), uidbytes[3]), 0x88) + local bcc2 = bxor(bxor(bxor(uidbytes[4], uidbytes[5]), uidbytes[6]), uidbytes[7]) + local block0 = string.format('%02X%02X%02X%02X', uidbytes[1], uidbytes[2], uidbytes[3], bcc1) + local block1 = string.format('%02X%02X%02X%02X', uidbytes[4], uidbytes[5], uidbytes[6], uidbytes[7]) + local block2 = string.format('%02X%02X%02X%02X', bcc2, 0x48, 0x00, 0x00) + local resp + resp = send('A200'..block0) + resp = send('A201'..block1) + resp = send('A202'..block2) else - print('Incorrect ul') + print('Incorrect ul') end lib14a.disconnect() if resp ~= nil then @@ -339,8 +339,8 @@ end local function write_atqasak(atqasak) -- read CONFIG if not magicconfig then - _print = 1 - read_config() + _print = 1 + read_config() end if atqasak == nil then return nil, 'Empty ATQA/SAK string' end if #atqasak == 0 then return nil, 'Empty ATQA/SAK string' end @@ -350,25 +350,25 @@ end local atqauserf = atqauser2..atqauser1 local sakuser = atqasak:sub(5,6) if sakuser == '04' then - print('Never set SAK bit 3 (e.g. SAK=04), it indicates an extra cascade level is required') - return nil + print('Never set SAK bit 3 (e.g. SAK=04), it indicates an extra cascade level is required') + return nil elseif (sakuser == '20' or sakuser == '28') and atslen == '00' then - print('When SAK equals 20 or 28, ATS must be turned on') - return nil + print('When SAK equals 20 or 28, ATS must be turned on') + return nil elseif atqauser2 == '40' then - print('ATQA of [00 40] will cause the card to not answer.') - return nil + print('ATQA of [00 40] will cause the card to not answer.') + return nil else - local info = connect() - if not info then return false, "Can't select card" end - print('New ATQA: '..atqauser1..' '..atqauser2..' New SAK: '..sakuser) - local resp = send("CF".._key.."35"..atqauserf..sakuser) - lib14a.disconnect() - if resp == nil then - return nil, oops('Failed to write ATQA/SAK') - else - return true, 'Ok' - end + local info = connect() + if not info then return false, "Can't select card" end + print('New ATQA: '..atqauser1..' '..atqauser2..' New SAK: '..sakuser) + local resp = send("CF".._key.."35"..atqauserf..sakuser) + lib14a.disconnect() + if resp == nil then + return nil, oops('Failed to write ATQA/SAK') + else + return true, 'Ok' + end end end --- @@ -376,8 +376,8 @@ end local function write_ntagpwd(ntagpwd) -- read CONFIG if not magicconfig then - _print = 1 - read_config() + _print = 1 + read_config() end if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end -- PWD string checks @@ -401,8 +401,8 @@ end local function write_pack(userpack) -- read CONFIG if not magicconfig then - _print = 1 - read_config() + _print = 1 + read_config() end if ulprotocol == 0 then return nil, 'Magic Card is not using the Ultralight Protocol' end -- PACK string checks @@ -426,8 +426,8 @@ local function write_otp(block3) if #block3 ~= 8 then return nil, 'OTP wrong length. Should be 4 hex bytes' end -- read CONFIG if not magicconfig then - _print = 1 - read_config() + _print = 1 + read_config() end if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end local info = connect() @@ -450,8 +450,8 @@ local function write_version(data) if #data ~= 16 then return nil, 'version wrong length. Should be 8 hex bytes' end -- read CONFIG if not magicconfig then - _print = 1 - read_config() + _print = 1 + read_config() end if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end print('Writing new version', data) @@ -478,8 +478,8 @@ local function write_signature(data) if #data ~= 64 then return nil, 'data wrong length. Should be 32 hex bytes' end -- read CONFIG if not magicconfig then - _print = 1 - read_config() + _print = 1 + read_config() end local info = connect() if not info then return false, "Can't select card" end @@ -508,19 +508,19 @@ local function write_gtu(gtu) local info = connect() if not info then return false, "Can't select card" end if gtu == '00' then - print('Enabling GTU Pre-Write') - send('CF'.._key..'32'..gtu) + print('Enabling GTU Pre-Write') + send('CF'.._key..'32'..gtu) elseif gtu == '01' then - print('Enabling GTU Restore Mode') - send('CF'.._key..'32'..gtu) + print('Enabling GTU Restore Mode') + send('CF'.._key..'32'..gtu) elseif gtu == '02' then - print('Disabled GTU') - send('CF'.._key..'32'..gtu) + print('Disabled GTU') + send('CF'.._key..'32'..gtu) elseif gtu == '03' then - print('Disabled GTU, high speed R/W mode for Ultralight') - send('CF'.._key..'32'..gtu) + print('Disabled GTU, high speed R/W mode for Ultralight') + send('CF'.._key..'32'..gtu) else - print('Failed to set GTU mode') + print('Failed to set GTU mode') end lib14a.disconnect() return true, 'Ok' @@ -536,13 +536,13 @@ local function write_ats(atsuser) local atscardlendecimal = tonumber(atscardlen, 16) local atsf = string.sub(atsuser, 3) if (#atsf / 2) ~= atscardlendecimal then - oops('Given length of ATS ('..atscardlendecimal..') does not match the ATS_length ('..(#atsf / 2)..')') - return true, 'Ok' + oops('Given length of ATS ('..atscardlendecimal..') does not match the ATS_length ('..(#atsf / 2)..')') + return true, 'Ok' else - local info = connect() - if not info then return false, "Can't select card" end - print('Writing '..atscardlendecimal..' ATS bytes of '..atsf) - send("CF".._key.."34"..atsuser) + local info = connect() + if not info then return false, "Can't select card" end + print('Writing '..atscardlendecimal..' ATS bytes of '..atsf) + send("CF".._key.."34"..atsuser) end lib14a.disconnect() return true, 'Ok' @@ -556,11 +556,11 @@ local function write_ulp(ulp) local info = connect() if not info then return false, "Can't select card" end if ulp == '00' then - print('Changing card to Mifare Classic Protocol') - send("CF".._key.."69"..ulp) + print('Changing card to Mifare Classic Protocol') + send("CF".._key.."69"..ulp) elseif ulp == '01' then - print('Changing card to Ultralight Protocol') - send("CF".._key.."69"..ulp) + print('Changing card to Ultralight Protocol') + send("CF".._key.."69"..ulp) else oops('Protocol needs to be either 00 or 01') end @@ -576,17 +576,17 @@ local function write_ulm(ulm) local info = connect() if not info then return false, "Can't select card" end if ulm == '00' then - print('Changing card UL mode to Ultralight EV1') - send("CF".._key.."6A"..ulm) + print('Changing card UL mode to Ultralight EV1') + send("CF".._key.."6A"..ulm) elseif ulm == '01' then - print('Changing card UL mode to NTAG') - send("CF".._key.."6A"..ulm) + print('Changing card UL mode to NTAG') + send("CF".._key.."6A"..ulm) elseif ulm == '02' then - print('Changing card UL mode to Ultralight-C') - send("CF".._key.."6A"..ulm) + print('Changing card UL mode to Ultralight-C') + send("CF".._key.."6A"..ulm) elseif ulm == '03' then - print('Changing card UL mode to Ultralight') - send("CF".._key.."6A"..ulm) + print('Changing card UL mode to Ultralight') + send("CF".._key.."6A"..ulm) else oops('UL mode needs to be either 00, 01, 02, 03') end @@ -603,50 +603,50 @@ local function set_type(tagtype) if tagtype == 1 then print('Setting: Ultimate Magic card to Mifare mini S20 4-byte') connect() - send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000900") - lib14a.disconnect() + send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000900") + lib14a.disconnect() write_uid('04112233') -- Setting Mifare mini S20 7-byte elseif tagtype == 2 then print('Setting: Ultimate Magic card to Mifare mini S20 7-byte') connect() - send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000900") - lib14a.disconnect() + send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000900") + lib14a.disconnect() write_uid('04112233445566') -- Setting Mifare 1k S50 4--byte elseif tagtype == 3 then print('Setting: Ultimate Magic card to Mifare 1k S50 4-byte') connect() - send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000800") - lib14a.disconnect() + send("CF".._key.."F000000000000002000978009102DABC19101011121314151604000800") + lib14a.disconnect() write_uid('04112233') -- Setting Mifare 1k S50 7-byte elseif tagtype == 4 then print('Setting: Ultimate Magic card to Mifare 1k S50 7-byte') connect() - send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000800") - lib14a.disconnect() + send("CF".._key.."F000010000000002000978009102DABC19101011121314151644000800") + lib14a.disconnect() write_uid('04112233445566') -- Setting Mifare 4k S70 4-byte elseif tagtype == 5 then print('Setting: Ultimate Magic card to Mifare 4k S70 4-byte') connect() - send("CF".._key.."F000000000000002000978009102DABC19101011121314151602001800") - lib14a.disconnect() + send("CF".._key.."F000000000000002000978009102DABC19101011121314151602001800") + lib14a.disconnect() write_uid('04112233') -- Setting Mifare 4k S70 7-byte elseif tagtype == 6 then print('Setting: Ultimate Magic card to Mifare 4k S70 7-byte') connect() - send("CF".._key.."F000010000000002000978009102DABC19101011121314151642001800") - lib14a.disconnect() + send("CF".._key.."F000010000000002000978009102DABC19101011121314151642001800") + lib14a.disconnect() write_uid('04112233445566') -- Setting UL elseif tagtype == 7 then print('Setting: Ultimate Magic card to UL') connect() - send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000003") - lib14a.disconnect() + send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000003") + lib14a.disconnect() write_uid('04112233445566') write_otp('00000000') -- Setting OTP to default 00 00 00 00 write_version('0000000000000000') -- UL-C does not have a version @@ -654,48 +654,48 @@ local function set_type(tagtype) elseif tagtype == 8 then print('Setting: Ultimate Magic card to UL-C') connect() - send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000002") - print('Setting default permissions and 3des key') - send('A22A30000000') -- Auth0 page 48/0x30 and above need authentication - send('A22B80000000') -- Auth1 read and write access restricted - send('A22C42524541') -- Default 3des key - send('A22D4B4D4549') - send('A22E46594F55') - send('A22F43414E21') - lib14a.disconnect() + send("CF".._key.."F0010100000000030A0A78008102DBA0C119402AB5BA4D321A44000002") + print('Setting default permissions and 3des key') + send('A22A30000000') -- Auth0 page 48/0x30 and above need authentication + send('A22B80000000') -- Auth1 read and write access restricted + send('A22C42524541') -- Default 3des key + send('A22D4B4D4549') + send('A22E46594F55') + send('A22F43414E21') + lib14a.disconnect() write_uid('04112233445566') write_otp('00000000') -- Setting OTP to default 00 00 00 00 write_version('0000000000000000') -- UL-C does not have a version elseif tagtype == 9 then print('Setting: Ultimate Magic card to UL-EV1 48') - connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000") + connect() + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000") -- Setting UL-Ev1 default config bl 16,17 - send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block - send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block + send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block + send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block send('a210000000FF') send('a21100050000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_otp('00000000') -- Setting OTP to default 00 00 00 00 write_version('0004030101000b03') -- UL-EV1 (48) 00 04 03 01 01 00 0b 03 elseif tagtype == 10 then print('Setting: Ultimate Magic card to UL-EV1 128') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000000") -- Setting UL-Ev1 default config bl 37,38 - send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block - send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block + send('a2E5FFFFFFFF') -- A2F0 block does not align correctly to actual pwd block + send('a2E6FFFFFFFF') -- A2F1 block does not align correctly to actual pack block send('a225000000FF') send('a22600050000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_otp('00000000') -- Setting OTP to default 00 00 00 00 write_version('0004030101000e03') -- UL-EV1 (128) 00 04 03 01 01 00 0e 03 elseif tagtype == 12 then print('Setting: Ultimate Magic card to NTAG 210') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") -- Setting NTAG210 default CC block456 send('a203e1100600') send('a2040300fe00') @@ -703,13 +703,13 @@ local function set_type(tagtype) -- Setting cfg1/cfg2 send('a210000000FF') send('a21100050000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_version('0004040101000b03') -- NTAG210 00 04 04 01 01 00 0b 03 elseif tagtype == 13 then print('Setting: Ultimate Magic card to NTAG 212') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") -- Setting NTAG212 default CC block456 send('a203e1101000') send('a2040103900a') @@ -717,13 +717,13 @@ local function set_type(tagtype) -- Setting cfg1/cfg2 send('a225000000FF') send('a22600050000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_version('0004040101000E03') -- NTAG212 00 04 04 01 01 00 0E 03 elseif tagtype == 14 then print('Setting: Ultimate Magic card to NTAG 213') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") -- Setting NTAG213 default CC block456 send('a203e1101200') send('a2040103a00c') @@ -731,13 +731,13 @@ local function set_type(tagtype) -- setting cfg1/cfg2 send('a229000000ff') send('a22a00050000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_version('0004040201000F03') -- NTAG213 00 04 04 02 01 00 0f 03 elseif tagtype == 15 then print('Setting: Ultimate Magic card to NTAG 215') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") -- Setting NTAG215 default CC block456 send('a203e1103e00') send('a2040300fe00') @@ -745,13 +745,13 @@ local function set_type(tagtype) -- setting cfg1/cfg2 send('a283000000ff') send('a28400050000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_version('0004040201001103') -- NTAG215 00 04 04 02 01 00 11 03 elseif tagtype == 16 then print('Setting: Ultimate Magic card to NTAG 216') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") -- Setting NTAG216 default CC block456 send('a203e1106d00') send('a2040300fe00') @@ -759,56 +759,56 @@ local function set_type(tagtype) -- setting cfg1/cfg2 send('a2e3000000ff') send('a2e400050000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_version('0004040201001303') -- NTAG216 00 04 04 02 01 00 13 03 elseif tagtype == 17 then print('Setting: Ultimate Magic card to NTAG I2C 1K') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") -- Setting NTAG I2C 1K default CC block456 send('a203e1106D00') send('a2040300fe00') send('a20500000000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_version('0004040502011303') -- NTAG_I2C_1K 00 04 04 05 02 01 13 03 elseif tagtype == 18 then print('Setting: Ultimate Magic card to NTAG I2C 2K') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") -- Setting NTAG I2C 2K default CC block456 send('a203e110EA00') send('a2040300fe00') send('a20500000000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_version('0004040502011503') -- NTAG_I2C_2K 00 04 04 05 02 01 15 03 elseif tagtype == 19 then print('Setting: Ultimate Magic card to NTAG I2C plus 1K') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") -- Setting NTAG I2C 1K default CC block456 send('a203e1106D00') send('a2040300fe00') send('a20500000000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_version('0004040502021303') -- NTAG_I2C_1K 00 04 04 05 02 02 13 03 elseif tagtype == 20 then print('Setting: Ultimate Magic card to NTAG I2C plus 2K') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") -- Setting NTAG I2C 2K default CC block456 send('a203e1106D00') send('a2040300fe00') send('a20500000000') - write_uid('04112233445566') + write_uid('04112233445566') write_version('0004040502021503') -- NTAG_I2C_2K 00 04 04 05 02 02 15 03 elseif tagtype == 21 then print('Setting: Ultimate Magic card to NTAG 213F') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") -- Setting NTAG213 default CC block456 send('a203e1101200') send('a2040103a00c') @@ -816,13 +816,13 @@ local function set_type(tagtype) -- setting cfg1/cfg2 send('a229000000ff') send('a22a00050000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_version('0004040401000F03') -- NTAG213F 00 04 04 04 01 00 0f 03 elseif tagtype == 22 then print('Setting: Ultimate Magic card to NTAG 216F') connect() - send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") + send("CF".._key.."F001010000000003000978009102DABC19101011121314151644000001") -- Setting NTAG216 default CC block456 send('a203e1106d00') send('a2040300fe00') @@ -830,11 +830,11 @@ local function set_type(tagtype) -- setting cfg1/cfg2 send('a2e3000000ff') send('a2e400050000') - lib14a.disconnect() - write_uid('04112233445566') + lib14a.disconnect() + write_uid('04112233445566') write_version('0004040401001303') -- NTAG216F 00 04 04 04 01 00 13 03 else - oops('No matching tag types') + oops('No matching tag types') end lib14a.disconnect() if resp == '04' then diff --git a/client/src/cmdhfepa.c b/client/src/cmdhfepa.c index 7ce9a3e97..66ce37d6b 100644 --- a/client/src/cmdhfepa.c +++ b/client/src/cmdhfepa.c @@ -228,7 +228,7 @@ static int CmdHFEPAPACESimulate(const char *Cmd) { CLIExecWithReturn(ctx, Cmd, argtable, false); // bool use_pc = arg_get_lit(ctx, 1); -// uint8_t pwd_type = 0; +// uint8_t pwd_type = 0; int plen = 0; uint8_t pwd[6] = {0}; @@ -273,7 +273,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, {"cnonces", CmdHFEPACollectPACENonces, IfPm3Iso14443, "Acquire encrypted PACE nonces of specific size"}, {"replay", CmdHFEPAPACEReplay, IfPm3Iso14443, "Perform PACE protocol by replaying given APDUs"}, - {"sim", CmdHFEPAPACESimulate, IfPm3Iso14443, "Simulate PACE protocol"}, + {"sim", CmdHFEPAPACESimulate, IfPm3Iso14443, "Simulate PACE protocol"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmdhfxerox.c b/client/src/cmdhfxerox.c index 578f797e0..9ba1577da 100644 --- a/client/src/cmdhfxerox.c +++ b/client/src/cmdhfxerox.c @@ -15,77 +15,77 @@ #define TIMEOUT 2000 -#define c2l(c,l) (l = ((unsigned long)(*((c)++))), \ - l |= ((unsigned long)(*((c)++))) << 8L, \ - l |= ((unsigned long)(*((c)++))) << 16L, \ - l |= ((unsigned long)(*((c)++))) << 24L) +#define c2l(c,l) (l = ((unsigned long)(*((c)++))), \ + l |= ((unsigned long)(*((c)++))) << 8L, \ + l |= ((unsigned long)(*((c)++))) << 16L, \ + l |= ((unsigned long)(*((c)++))) << 24L) /* NOTE - c is not incremented as per c2l */ -#define c2ln(c,l1,l2,n) { \ - c += n; \ - l1 = l2 = 0; \ - switch (n) { \ - case 8: l2 = ((unsigned long)(*(--(c)))) << 24L; \ - case 7: l2 |= ((unsigned long)(*(--(c)))) << 16L; \ - case 6: l2 |= ((unsigned long)(*(--(c)))) << 8L; \ - case 5: l2 |= ((unsigned long)(*(--(c)))); \ - case 4: l1 = ((unsigned long)(*(--(c)))) << 24L; \ - case 3: l1 |= ((unsigned long)(*(--(c)))) << 16L; \ - case 2: l1 |= ((unsigned long)(*(--(c)))) << 8L; \ - case 1: l1 |= ((unsigned long)(*(--(c)))); \ - } \ - } +#define c2ln(c,l1,l2,n) { \ + c += n; \ + l1 = l2 = 0; \ + switch (n) { \ + case 8: l2 = ((unsigned long)(*(--(c)))) << 24L; \ + case 7: l2 |= ((unsigned long)(*(--(c)))) << 16L; \ + case 6: l2 |= ((unsigned long)(*(--(c)))) << 8L; \ + case 5: l2 |= ((unsigned long)(*(--(c)))); \ + case 4: l1 = ((unsigned long)(*(--(c)))) << 24L; \ + case 3: l1 |= ((unsigned long)(*(--(c)))) << 16L; \ + case 2: l1 |= ((unsigned long)(*(--(c)))) << 8L; \ + case 1: l1 |= ((unsigned long)(*(--(c)))); \ + } \ + } -#define l2c(l,c) (*((c)++) = (uint8_t)(((l)) & 0xff), \ - *((c)++) = (uint8_t)(((l) >> 8L) & 0xff), \ - *((c)++) = (uint8_t)(((l) >> 16L) & 0xff), \ - *((c)++) = (uint8_t)(((l) >> 24L) & 0xff)) +#define l2c(l,c) (*((c)++) = (uint8_t)(((l)) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 8L) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 16L) & 0xff), \ + *((c)++) = (uint8_t)(((l) >> 24L) & 0xff)) /* NOTE - c is not incremented as per l2c */ -#define l2cn(l1,l2,c,n) { \ - c += n; \ - switch (n) { \ - case 8: *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \ - case 7: *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \ - case 6: *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \ - case 5: *(--(c)) = (uint8_t)(((l2)) & 0xff); \ - case 4: *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \ - case 3: *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \ - case 2: *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \ - case 1: *(--(c)) = (uint8_t)(((l1)) & 0xff); \ - } \ - } +#define l2cn(l1,l2,c,n) { \ + c += n; \ + switch (n) { \ + case 8: *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \ + case 7: *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \ + case 6: *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \ + case 5: *(--(c)) = (uint8_t)(((l2)) & 0xff); \ + case 4: *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \ + case 3: *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \ + case 2: *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \ + case 1: *(--(c)) = (uint8_t)(((l1)) & 0xff); \ + } \ + } /* NOTE - c is not incremented as per n2l */ -#define n2ln(c,l1,l2,n) { \ - c += n; \ - l1 = l2 = 0; \ - switch (n) { \ - case 8: l2 = ((unsigned long)(*(--(c)))); \ - case 7: l2 |= ((unsigned long)(*(--(c)))) << 8; \ - case 6: l2 |= ((unsigned long)(*(--(c)))) << 16; \ - case 5: l2 |= ((unsigned long)(*(--(c)))) << 24; \ - case 4: l1 = ((unsigned long)(*(--(c)))); \ - case 3: l1 |= ((unsigned long)(*(--(c)))) << 8; \ - case 2: l1 |= ((unsigned long)(*(--(c)))) << 16; \ - case 1: l1 |= ((unsigned long)(*(--(c)))) << 24; \ - } \ - } +#define n2ln(c,l1,l2,n) { \ + c += n; \ + l1 = l2 = 0; \ + switch (n) { \ + case 8: l2 = ((unsigned long)(*(--(c)))); \ + case 7: l2 |= ((unsigned long)(*(--(c)))) << 8; \ + case 6: l2 |= ((unsigned long)(*(--(c)))) << 16; \ + case 5: l2 |= ((unsigned long)(*(--(c)))) << 24; \ + case 4: l1 = ((unsigned long)(*(--(c)))); \ + case 3: l1 |= ((unsigned long)(*(--(c)))) << 8; \ + case 2: l1 |= ((unsigned long)(*(--(c)))) << 16; \ + case 1: l1 |= ((unsigned long)(*(--(c)))) << 24; \ + } \ + } /* NOTE - c is not incremented as per l2n */ -#define l2nn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c)) = (uint8_t)(((l2)) & 0xff); \ - case 7: *(--(c)) = (uint8_t)(((l2) >> 8) & 0xff); \ - case 6: *(--(c)) = (uint8_t)(((l2) >> 16) & 0xff); \ - case 5: *(--(c)) = (uint8_t)(((l2) >> 24) & 0xff); \ - case 4: *(--(c)) = (uint8_t)(((l1)) & 0xff); \ - case 3: *(--(c)) = (uint8_t)(((l1) >> 8) & 0xff); \ - case 2: *(--(c)) = (uint8_t)(((l1) >> 16) & 0xff); \ - case 1: *(--(c)) = (uint8_t)(((l1) >> 24) & 0xff); \ - } \ - } +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c)) = (uint8_t)(((l2)) & 0xff); \ + case 7: *(--(c)) = (uint8_t)(((l2) >> 8) & 0xff); \ + case 6: *(--(c)) = (uint8_t)(((l2) >> 16) & 0xff); \ + case 5: *(--(c)) = (uint8_t)(((l2) >> 24) & 0xff); \ + case 4: *(--(c)) = (uint8_t)(((l1)) & 0xff); \ + case 3: *(--(c)) = (uint8_t)(((l1) >> 8) & 0xff); \ + case 2: *(--(c)) = (uint8_t)(((l1) >> 16) & 0xff); \ + case 1: *(--(c)) = (uint8_t)(((l1) >> 24) & 0xff); \ + } \ + } #define n2l(c,l) (l = ((unsigned long)(*((c)++))) << 24L, \ l |= ((unsigned long)(*((c)++))) << 16L, \ @@ -98,17 +98,17 @@ *((c)++) = (uint8_t)(((l)) & 0xff)) #define C_RC2(n) \ - t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; \ - x0 = (t << 1) | (t >> 15); \ - t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; \ - x1 = (t << 2) | (t >> 14); \ - t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; \ - x2 = (t << 3) | (t >> 13); \ - t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; \ - x3 = (t << 5) | (t >> 11); + t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; \ + x0 = (t << 1) | (t >> 15); \ + t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; \ + x1 = (t << 2) | (t >> 14); \ + t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; \ + x2 = (t << 3) | (t >> 13); \ + t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; \ + x3 = (t << 5) | (t >> 11); -#define RC2_ENCRYPT 1 -#define RC2_DECRYPT 0 +#define RC2_ENCRYPT 1 +#define RC2_DECRYPT 0 typedef unsigned int RC2_INT; @@ -533,8 +533,8 @@ static int CmdHFXeroxInfo(const char *Cmd) { packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW); packet->rawlen = 11; packet->raw[0] = 0x02; - packet->raw[1] = 0x20; // set command: read mem - memcpy(packet->raw + 2, card.uid, 8); // store uid + packet->raw[1] = 0x20; // set command: read mem + memcpy(packet->raw + 2, card.uid, 8); // store uid for (int retry = 0; (retry < 5 && blocknum < sizeof(info_blocks)); retry++) { @@ -623,7 +623,7 @@ static int CmdHFXeroxDump(const char *Cmd) { } iso14b_card_select_t card; - int status = findXerox(&card, false); // remain RF on + int status = findXerox(&card, false); // remain RF on if (status != PM3_SUCCESS) { free(packet); switch_off_field(); @@ -632,20 +632,20 @@ static int CmdHFXeroxDump(const char *Cmd) { PrintAndLogEx(INFO, "Reading memory from tag UID " _GREEN_("%s"), sprint_hex(card.uid, card.uidlen)); - int blocknum = 1; // block 0 all zeros + int blocknum = 1; // block 0 all zeros uint8_t data[256 * 4] = {0}; // set up the read command packet->flags = (ISO14B_APPEND_CRC | ISO14B_RAW); packet->rawlen = 11; packet->raw[0] = 0x02; - memcpy(packet->raw + 2, card.uid, 8); // store uid + memcpy(packet->raw + 2, card.uid, 8); // store uid PrintAndLogEx(INFO, "." NOLF); for (int retry = 0; (retry < 5 && blocknum < 0x100); retry++) { - packet->raw[1] = (blocknum < 12) ? 0x30 : 0x20; // set command: read ext mem or read mem + packet->raw[1] = (blocknum < 12) ? 0x30 : 0x20; // set command: read ext mem or read mem packet->raw[10] = blocknum & 0xFF; PacketResponseNG resp; @@ -657,7 +657,7 @@ static int CmdHFXeroxDump(const char *Cmd) { resp.cmd, resp.length, resp.magic, resp.status, resp.crc, resp.oldarg[0], resp.oldarg[1], resp.oldarg[2], resp.data.asBytes[0], resp.data.asBytes[1], resp.data.asBytes[2], resp.ng ? 't' : 'f'); */ - if (/*resp.status != 0 ||*/ resp.length < 7) { // 14b raw command send data_len instead of status + if (/*resp.status != 0 ||*/ resp.length < 7) { // 14b raw command send data_len instead of status PrintAndLogEx(FAILED, "retrying one more time"); continue; } @@ -722,8 +722,8 @@ static int CmdHFXeroxDump(const char *Cmd) { memcpy(k1, k2, sizeof(k1)); k1[2] = k2[3] ^ data[0x22 * 4 + 0]; - k1[3] = k2[4] ^ data[0x22 * 4 + 1]; // first_key[7]; - k1[5] = k2[1] ^ 0x01; // 01 = crypto method? rfid[23][2] + k1[3] = k2[4] ^ data[0x22 * 4 + 1]; // first_key[7]; + k1[5] = k2[1] ^ 0x01; // 01 = crypto method? rfid[23][2] RC2_set_key(&exp_key, 8, k1, 64); @@ -747,7 +747,7 @@ static int CmdHFXeroxDump(const char *Cmd) { uint16_t cs, csd; // calc checksum - for (b = 0, cs = 0; b < sizeof(decr) - 2; b += 2) cs += decr[b] | (decr[b + 1] << 8); + for (b = 0, cs = 0; b < sizeof(decr) - 2; b += 2) cs += decr[b] | (decr[b + 1] << 8); cs = ~cs; csd = (decr[7] << 8) | decr[6]; @@ -772,7 +772,7 @@ static int CmdHFXeroxDump(const char *Cmd) { PrintAndLogEx(INFO, "---------+--------------+----------"); PrintAndLogEx(NORMAL, ""); - if (0 == filename[0]) { // generate filename from uid + if (0 == filename[0]) { // generate filename from uid /* PrintAndLogEx(INFO, "Using UID as filename"); diff --git a/doc/commands.json b/doc/commands.json index 47f77d21a..e055a70b4 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -11512,6 +11512,6 @@ "metadata": { "commands_extracted": 727, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-01-14T21:16:27" + "extracted_on": "2023-01-14T21:23:30" } } \ No newline at end of file diff --git a/include/protocols.h b/include/protocols.h index 016584098..9de07e4e7 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -473,7 +473,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. // 65 xx #define ISO7816_MEMORY_FULL 0x6501 // Memory failure -#define ISO7816_WRITE_MEMORY_ERR 0x6581 // Write problem / Memory failure / Unknown mode +#define ISO7816_WRITE_MEMORY_ERR 0x6581 // Write problem / Memory failure / Unknown mode // 67 xx #define ISO7816_WRONG_LENGTH 0x6700 // Wrong length From 6a576701c7d9f1357b21e10a4e917c0d2880960c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Jan 2023 22:40:05 +0100 Subject: [PATCH 486/759] Topaz dump: remove unnecessary casts increasing required alignment and add dump size check --- client/src/cmdhftopaz.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/client/src/cmdhftopaz.c b/client/src/cmdhftopaz.c index 8ad9c23ee..a59cd02be 100644 --- a/client/src/cmdhftopaz.c +++ b/client/src/cmdhftopaz.c @@ -583,9 +583,7 @@ static void topaz_print_lifecycle_state(uint8_t *data) { // to be done } -static void printTopazDumpContents(uint8_t *dump, size_t size) { - - topaz_tag_t *t = (topaz_tag_t *)dump; +static void printTopazDumpContents(topaz_tag_t *dump) { // uses a global var for all PrintAndLogEx(NORMAL, ""); @@ -608,14 +606,14 @@ static void printTopazDumpContents(uint8_t *dump, size_t size) { PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| %s | %s", i, i, - sprint_hex(&t->data_blocks[i][0], 8), + sprint_hex(&dump->data_blocks[i][0], 8), lockstr, block_info ); } - PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| | %s", 0x0D, 0x0D, sprint_hex(&t->data_blocks[0x0D][0], 8), topaz_ks[2]); - PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| | %s", 0x0E, 0x0E, sprint_hex(&t->data_blocks[0x0E][0], 8), topaz_ks[3]); + PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| | %s", 0x0D, 0x0D, sprint_hex(&dump->data_blocks[0x0D][0], 8), topaz_ks[2]); + PrintAndLogEx(SUCCESS, " %3u / 0x%02x | %s| | %s", 0x0E, 0x0E, sprint_hex(&dump->data_blocks[0x0E][0], 8), topaz_ks[3]); PrintAndLogEx(SUCCESS, "------------+-------------------------+---+------------"); PrintAndLogEx(NORMAL, ""); } @@ -797,7 +795,7 @@ static int CmdHFTopazDump(const char *Cmd) { if (status != PM3_SUCCESS) { return status; } - printTopazDumpContents((uint8_t *)&topaz_tag, sizeof(topaz_tag_t)); + printTopazDumpContents(&topaz_tag); bool set_dynamic = false; if (topaz_set_cc_dynamic(&topaz_tag.data_blocks[1][0]) == PM3_SUCCESS) { @@ -853,14 +851,17 @@ static int CmdHFTopazView(const char *Cmd) { CLIParserFree(ctx); // read dump file - uint8_t *dump = NULL; + topaz_tag_t *dump = NULL; size_t bytes_read = TOPAZ_MAX_SIZE; int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, sizeof(topaz_tag_t) + TOPAZ_MAX_SIZE); if (res != PM3_SUCCESS) { return res; } - - printTopazDumpContents(dump, bytes_read); + if (bytes_read < sizeof(topaz_tag_t)) { + free(dump); + return PM3_EFAILED; + } + printTopazDumpContents(dump); if (topaz_set_cc_dynamic(&topaz_tag.data_blocks[1][0]) == PM3_SUCCESS) { From 04bab85557ff9d243436e781c8e78becd4785d32 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Jan 2023 23:02:06 +0100 Subject: [PATCH 487/759] fileutils: replace casts by union and remove warning about increase alignment requirement --- client/src/fileutils.c | 64 ++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/client/src/fileutils.c b/client/src/fileutils.c index e42ac5a16..8c2f7a6f0 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -1162,12 +1162,19 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz goto out; } - uint8_t *udata = (uint8_t *)data; + typedef union UDATA + { + void* v; + uint8_t* bytes; + mfu_dump_t* mfu; + topaz_tag_t* topaz; + } UDATA; + UDATA udata = (UDATA)data; char ctype[100] = {0}; JsonLoadStr(root, "$.FileType", ctype); if (!strcmp(ctype, "raw")) { - JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen); + JsonLoadBufAsHex(root, "$.raw", udata.bytes, maxdatalen, datalen); } if (!strcmp(ctype, "mfcard")) { @@ -1187,7 +1194,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz goto out; } - memcpy(&udata[sptr], block, 16); + memcpy(&udata.bytes[sptr], block, 16); sptr += len; } @@ -1206,7 +1213,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz snprintf(blocks, sizeof(blocks), "$.blocks.%d", i); size_t len = 0; - JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); + JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len); if (!len) break; @@ -1218,18 +1225,16 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz if (!strcmp(ctype, "mfu")) { - mfu_dump_t *mem = (mfu_dump_t *)udata; - - JsonLoadBufAsHex(root, "$.Card.Version", mem->version, sizeof(mem->version), datalen); - JsonLoadBufAsHex(root, "$.Card.TBO_0", mem->tbo, sizeof(mem->tbo), datalen); - JsonLoadBufAsHex(root, "$.Card.TBO_1", mem->tbo1, sizeof(mem->tbo1), datalen); - JsonLoadBufAsHex(root, "$.Card.Signature", mem->signature, sizeof(mem->signature), datalen); - JsonLoadBufAsHex(root, "$.Card.Counter0", &mem->counter_tearing[0][0], 3, datalen); - JsonLoadBufAsHex(root, "$.Card.Tearing0", &mem->counter_tearing[0][3], 1, datalen); - JsonLoadBufAsHex(root, "$.Card.Counter1", &mem->counter_tearing[1][0], 3, datalen); - JsonLoadBufAsHex(root, "$.Card.Tearing1", &mem->counter_tearing[1][3], 1, datalen); - JsonLoadBufAsHex(root, "$.Card.Counter2", &mem->counter_tearing[2][0], 3, datalen); - JsonLoadBufAsHex(root, "$.Card.Tearing2", &mem->counter_tearing[2][3], 1, datalen); + JsonLoadBufAsHex(root, "$.Card.Version", udata.mfu->version, sizeof(udata.mfu->version), datalen); + JsonLoadBufAsHex(root, "$.Card.TBO_0", udata.mfu->tbo, sizeof(udata.mfu->tbo), datalen); + JsonLoadBufAsHex(root, "$.Card.TBO_1", udata.mfu->tbo1, sizeof(udata.mfu->tbo1), datalen); + JsonLoadBufAsHex(root, "$.Card.Signature", udata.mfu->signature, sizeof(udata.mfu->signature), datalen); + JsonLoadBufAsHex(root, "$.Card.Counter0", &udata.mfu->counter_tearing[0][0], 3, datalen); + JsonLoadBufAsHex(root, "$.Card.Tearing0", &udata.mfu->counter_tearing[0][3], 1, datalen); + JsonLoadBufAsHex(root, "$.Card.Counter1", &udata.mfu->counter_tearing[1][0], 3, datalen); + JsonLoadBufAsHex(root, "$.Card.Tearing1", &udata.mfu->counter_tearing[1][3], 1, datalen); + JsonLoadBufAsHex(root, "$.Card.Counter2", &udata.mfu->counter_tearing[2][0], 3, datalen); + JsonLoadBufAsHex(root, "$.Card.Tearing2", &udata.mfu->counter_tearing[2][3], 1, datalen); *datalen = MFU_DUMP_PREFIX_LENGTH; size_t sptr = 0; @@ -1243,15 +1248,15 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz snprintf(blocks, sizeof(blocks), "$.blocks.%d", i); size_t len = 0; - JsonLoadBufAsHex(root, blocks, &mem->data[sptr], MFU_BLOCK_SIZE, &len); + JsonLoadBufAsHex(root, blocks, &udata.mfu->data[sptr], MFU_BLOCK_SIZE, &len); if (!len) break; sptr += len; - mem->pages++; + udata.mfu->pages++; } // remove one, since pages indicates a index rather than number of available pages - --mem->pages; + --udata.mfu->pages; *datalen += sptr; } @@ -1268,7 +1273,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i); size_t len = 0; - JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); + JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len); if (!len) break; @@ -1290,7 +1295,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i); size_t len = 0; - JsonLoadBufAsHex(root, blocks, &udata[sptr], 8, &len); + JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 8, &len); if (!len) break; @@ -1311,7 +1316,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i); size_t len = 0; - JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); + JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len); if (!len) break; @@ -1332,7 +1337,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz snprintf(blocks, sizeof(blocks), "$.blocks.%zu", i); size_t len = 0; - JsonLoadBufAsHex(root, blocks, &udata[sptr], 4, &len); + JsonLoadBufAsHex(root, blocks, &udata.bytes[sptr], 4, &len); if (!len) break; @@ -1342,19 +1347,18 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz } if (!strcmp(ctype, "15693")) { - JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen); + JsonLoadBufAsHex(root, "$.raw", udata.bytes, maxdatalen, datalen); } if (!strcmp(ctype, "legic")) { - JsonLoadBufAsHex(root, "$.raw", udata, maxdatalen, datalen); + JsonLoadBufAsHex(root, "$.raw", udata.bytes, maxdatalen, datalen); } if (!strcmp(ctype, "topaz")) { - topaz_tag_t *mem = (topaz_tag_t *)udata; - JsonLoadBufAsHex(root, "$.Card.UID", mem->uid, sizeof(mem->uid), datalen); - JsonLoadBufAsHex(root, "$.Card.HR01", mem->HR01, sizeof(mem->HR01), datalen); - JsonLoadBufAsHex(root, "$.Card.Size", (uint8_t *) & (mem->size), 2, datalen); + JsonLoadBufAsHex(root, "$.Card.UID", udata.topaz->uid, sizeof(udata.topaz->uid), datalen); + JsonLoadBufAsHex(root, "$.Card.HR01", udata.topaz->HR01, sizeof(udata.topaz->HR01), datalen); + JsonLoadBufAsHex(root, "$.Card.Size", (uint8_t *) & (udata.topaz->size), 2, datalen); size_t sptr = 0; for (int i = 0; i < (TOPAZ_STATIC_MEMORY / 8); i++) { @@ -1368,7 +1372,7 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz snprintf(blocks, sizeof(blocks), "$.blocks.%d", i); size_t len = 0; - JsonLoadBufAsHex(root, blocks, &mem->data_blocks[sptr][0], TOPAZ_BLOCK_SIZE, &len); + JsonLoadBufAsHex(root, blocks, &udata.topaz->data_blocks[sptr][0], TOPAZ_BLOCK_SIZE, &len); if (!len) break; From 46f8b522ca1854de25e2af1e1675b6d81c1fcf26 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Jan 2023 23:05:46 +0100 Subject: [PATCH 488/759] t55: remove cast and warning about increase alignment requirement --- client/src/cmdlft55xx.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index dccacc3b1..ba3df4088 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -2362,7 +2362,7 @@ static int CmdT55xxRestore(const char *Cmd) { } // read dump file - uint8_t *dump = NULL; + uint32_t *dump = NULL; size_t bytes_read = 0; res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (T55x7_BLOCK_COUNT * 4)); if (res != PM3_SUCCESS) { @@ -2387,11 +2387,10 @@ static int CmdT55xxRestore(const char *Cmd) { snprintf(pwdopt, sizeof(pwdopt), "-p %08X", password); } - uint32_t *data = (uint32_t *) dump; uint8_t idx; // Restore endien for writing to card for (idx = 0; idx < 12; idx++) { - data[idx] = BSWAP_32(data[idx]); + dump[idx] = BSWAP_32(dump[idx]); } // Have data ready, lets write @@ -2400,12 +2399,12 @@ static int CmdT55xxRestore(const char *Cmd) { // write blocks 1..3 page 1 // update downlink mode (if needed) and write b 0 downlink_mode = 0; - if ((((data[11] >> 28) & 0xF) == 6) || (((data[11] >> 28) & 0xF) == 9)) - downlink_mode = (data[11] >> 10) & 3; + if ((((dump[11] >> 28) & 0xF) == 6) || (((dump[11] >> 28) & 0xF) == 9)) + downlink_mode = (dump[11] >> 10) & 3; // write out blocks 1-7 page 0 for (idx = 1; idx <= 7; idx++) { - snprintf(wcmd, sizeof(wcmd), "-b %d -d %08X %s", idx, data[idx], pwdopt); + snprintf(wcmd, sizeof(wcmd), "-b %d -d %08X %s", idx, dump[idx], pwdopt); if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx); @@ -2414,12 +2413,12 @@ static int CmdT55xxRestore(const char *Cmd) { // if password was set on the "blank" update as we may have just changed it if (usepwd) { - snprintf(pwdopt, sizeof(pwdopt), "-p %08X", data[7]); + snprintf(pwdopt, sizeof(pwdopt), "-p %08X", dump[7]); } // write out blocks 1-3 page 1 for (idx = 9; idx <= 11; idx++) { - snprintf(wcmd, sizeof(wcmd), "-b %d --pg1 -d %08X %s", idx - 8, data[idx], pwdopt); + snprintf(wcmd, sizeof(wcmd), "-b %d --pg1 -d %08X %s", idx - 8, dump[idx], pwdopt); if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx); @@ -2430,7 +2429,7 @@ static int CmdT55xxRestore(const char *Cmd) { config.downlink_mode = downlink_mode; // Write the page 0 config - snprintf(wcmd, sizeof(wcmd), "-b 0 -d %08X %s", data[0], pwdopt); + snprintf(wcmd, sizeof(wcmd), "-b 0 -d %08X %s", dump[0], pwdopt); if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Warning: error writing blk 0"); } From 0e1ea167a46d40e45c0e161b68bef4b7b6249e6e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Jan 2023 23:29:38 +0100 Subject: [PATCH 489/759] vigik: use mfc_vigik_t in API and remove warning about increased alignment --- client/src/cmdhfmf.c | 18 ++++++++---- client/src/mifare/mifarehost.c | 52 ++++++++++++++++------------------ client/src/mifare/mifarehost.h | 5 ++-- 3 files changed, 40 insertions(+), 35 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 98a587cf1..89cb68023 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6915,9 +6915,15 @@ static int CmdHF14AMfView(const char *Cmd) { return res; } + typedef union UDATA + { + uint8_t *bytes; + mfc_vigik_t *vigik; + } UDATA; // allocate memory - uint8_t *d = calloc(bytes_read, sizeof(uint8_t)); - if (d == NULL) { + UDATA d; + d.bytes = calloc(bytes_read, sizeof(uint8_t)); + if (d.bytes == NULL) { return PM3_EMALLOC; } uint16_t dlen = 0; @@ -6925,14 +6931,14 @@ static int CmdHF14AMfView(const char *Cmd) { // vigik struture sector 0 uint8_t *pdump = dump; - memcpy(d + dlen, pdump, MFBLOCK_SIZE * 3); + memcpy(d.bytes + dlen, pdump, MFBLOCK_SIZE * 3); dlen += MFBLOCK_SIZE * 3; pdump += (MFBLOCK_SIZE * 4); // skip sectortrailer // extract memory from MAD sectors for (int i = 0; i <= madlen; i++) { if (0x4910 == mad[i] || 0x4916 == mad[i]) { - memcpy(d + dlen, pdump, MFBLOCK_SIZE * 3); + memcpy(d.bytes + dlen, pdump, MFBLOCK_SIZE * 3); dlen += MFBLOCK_SIZE * 3; } @@ -6940,8 +6946,8 @@ static int CmdHF14AMfView(const char *Cmd) { } // convert_mfc_2_arr(pdump, bytes_read, d, &dlen); - vigik_annotate(d); - free(d); + vigik_annotate(d.vigik); + free(d.bytes); } free(dump); diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 0c8c8b274..56d10c608 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1499,7 +1499,7 @@ static void reverse_array(const uint8_t *src, int src_len, uint8_t *dest) { } }; -int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len) { +int vigik_verify(mfc_vigik_t *d) { // iso9796 // Exponent V = 2 @@ -1507,16 +1507,16 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature if (g_debugMode == DEBUG) { PrintAndLogEx(INFO, "Raw"); - print_hex_noascii_break(uid, uidlen, MFBLOCK_SIZE * 2); + print_hex_noascii_break((uint8_t *)d, sizeof(*d) - sizeof(d->rsa_signature), MFBLOCK_SIZE * 2); PrintAndLogEx(INFO, "Raw signature"); - print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2); + print_hex_noascii_break(d->rsa_signature, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2); } uint8_t rev_sig[128]; - reverse_array(signature, signature_len, rev_sig); + reverse_array(d->rsa_signature, sizeof(d->rsa_signature), rev_sig); PrintAndLogEx(INFO, "Raw signature reverse"); - print_hex_noascii_break(rev_sig, signature_len, MFBLOCK_SIZE * 2); + print_hex_noascii_break(rev_sig, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2); // t = 0xBC = Implicitly known // t = 0xCC = look at byte before to determine hash function @@ -1566,7 +1566,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature mbedtls_mpi_read_binary(&N, (const unsigned char *)n, PUBLIC_VIGIK_KEYLEN); //mbedtls_mpi_read_binary(&s, (const unsigned char*)signature, signature_len); - mbedtls_mpi_read_binary(&s, (const unsigned char *)rev_sig, signature_len); + mbedtls_mpi_read_binary(&s, (const unsigned char *)rev_sig, sizeof(d->rsa_signature)); // check is sign < (N/2) @@ -1725,7 +1725,7 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature if (is_valid == false || i == ARRAYLEN(vigik_rsa_pk)) { PrintAndLogEx(INFO, "Signature:"); - print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2); + print_hex_noascii_break(d->rsa_signature, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2); PrintAndLogEx(SUCCESS, "Signature verification: " _RED_("failed")); return PM3_ESOFT; } @@ -1738,37 +1738,35 @@ int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature PrintAndLogEx(INFO, "%.64s", vigik_rsa_pk[i].n + 192); PrintAndLogEx(INFO, "Signature:"); - print_hex_noascii_break(signature, signature_len, MFBLOCK_SIZE * 2); + print_hex_noascii_break(d->rsa_signature, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2); PrintAndLogEx(SUCCESS, "Signature verification: " _GREEN_("successful")); return PM3_SUCCESS; } -int vigik_annotate(uint8_t *d) { +int vigik_annotate(mfc_vigik_t *d) { if (d == NULL) return PM3_EINVARG; - mfc_vigik_t *foo = (mfc_vigik_t *)d; - - PrintAndLogEx(INFO, "Manufacture......... %s", sprint_hex(foo->b0, sizeof(foo->b0))); - PrintAndLogEx(INFO, "MAD................. %s", sprint_hex(foo->mad, sizeof(foo->mad))); - PrintAndLogEx(INFO, "Counters............ %u", foo->counters); - PrintAndLogEx(INFO, "rtf................. %s", sprint_hex(foo->rtf, sizeof(foo->rtf))); - PrintAndLogEx(INFO, "Service code........ 0x%08x / %u - " _YELLOW_("%s"), foo->service_code, foo->service_code, vigik_get_service(foo->service_code)); - PrintAndLogEx(INFO, "Info flag........... %u -", foo->info_flag); // , sprint_bin(foo->info_flag, 1)); - PrintAndLogEx(INFO, "Key version......... %u", foo->key_version); - PrintAndLogEx(INFO, "PTR Counter......... %u", foo->ptr_counter); - PrintAndLogEx(INFO, "Counter num......... %u", foo->counter_num); - PrintAndLogEx(INFO, "Slot access date.... %s", sprint_hex(foo->slot_access_date, sizeof(foo->slot_access_date))); - PrintAndLogEx(INFO, "Slot dst duration... %u", foo->slot_dst_duration); - PrintAndLogEx(INFO, "Other Slots......... %s", sprint_hex(foo->other_slots, sizeof(foo->other_slots))); - PrintAndLogEx(INFO, "Services counter.... %u", foo->services_counter); - PrintAndLogEx(INFO, "Loading date........ %s", sprint_hex(foo->loading_date, sizeof(foo->loading_date))); - PrintAndLogEx(INFO, "Reserved null....... %u", foo->reserved_null); + PrintAndLogEx(INFO, "Manufacture......... %s", sprint_hex(d->b0, sizeof(d->b0))); + PrintAndLogEx(INFO, "MAD................. %s", sprint_hex(d->mad, sizeof(d->mad))); + PrintAndLogEx(INFO, "Counters............ %u", d->counters); + PrintAndLogEx(INFO, "rtf................. %s", sprint_hex(d->rtf, sizeof(d->rtf))); + PrintAndLogEx(INFO, "Service code........ 0x%08x / %u - " _YELLOW_("%s"), d->service_code, d->service_code, vigik_get_service(d->service_code)); + PrintAndLogEx(INFO, "Info flag........... %u -", d->info_flag); // , sprint_bin(d->info_flag, 1)); + PrintAndLogEx(INFO, "Key version......... %u", d->key_version); + PrintAndLogEx(INFO, "PTR Counter......... %u", d->ptr_counter); + PrintAndLogEx(INFO, "Counter num......... %u", d->counter_num); + PrintAndLogEx(INFO, "Slot access date.... %s", sprint_hex(d->slot_access_date, sizeof(d->slot_access_date))); + PrintAndLogEx(INFO, "Slot dst duration... %u", d->slot_dst_duration); + PrintAndLogEx(INFO, "Other Slots......... %s", sprint_hex(d->other_slots, sizeof(d->other_slots))); + PrintAndLogEx(INFO, "Services counter.... %u", d->services_counter); + PrintAndLogEx(INFO, "Loading date........ %s", sprint_hex(d->loading_date, sizeof(d->loading_date))); + PrintAndLogEx(INFO, "Reserved null....... %u", d->reserved_null); PrintAndLogEx(INFO, "----------------------------------------------------------------"); PrintAndLogEx(INFO, ""); - vigik_verify(d, 96, foo->rsa_signature, sizeof(foo->rsa_signature)); + vigik_verify(d); PrintAndLogEx(INFO, "----------------------------------------------------------------"); PrintAndLogEx(INFO, ""); return PM3_SUCCESS; diff --git a/client/src/mifare/mifarehost.h b/client/src/mifare/mifarehost.h index 0212dd4f0..ccefbbd40 100644 --- a/client/src/mifare/mifarehost.h +++ b/client/src/mifare/mifarehost.h @@ -23,6 +23,7 @@ #include "common.h" #include "util.h" // FILE_PATH_SIZE +#include "protocol_vigik.h" #define MIFARE_SECTOR_RETRY 10 @@ -113,6 +114,6 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool i // remove all sector trailers in a MFC dump int convert_mfc_2_arr(uint8_t *in, uint16_t ilen, uint8_t *out, uint16_t *olen); const char *vigik_get_service(uint16_t service_code); -int vigik_verify(uint8_t *uid, uint8_t uidlen, uint8_t *signature, int signature_len); -int vigik_annotate(uint8_t *d); +int vigik_verify(mfc_vigik_t *d); +int vigik_annotate(mfc_vigik_t *d); #endif From 2d58c109ba3480411cf49ba9e24672d4ccfd8a1e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 14 Jan 2023 23:39:07 +0100 Subject: [PATCH 490/759] ksx6924: use ARRAYLEN --- client/src/ksx6924/ksx6924core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/ksx6924/ksx6924core.c b/client/src/ksx6924/ksx6924core.c index 39b390039..307573f74 100644 --- a/client/src/ksx6924/ksx6924core.c +++ b/client/src/ksx6924/ksx6924core.c @@ -99,7 +99,7 @@ typedef struct { KEY_TYPE key, const char* defaultValue) { \ struct _ksx6924_enum_ ## KEY_TYPE *r = bsearch( \ &key, KSX6924_ENUM_ ## NAME, \ - sizeof(KSX6924_ENUM_ ## NAME) / sizeof(KSX6924_ENUM_ ## NAME [0]), \ + ARRAYLEN(KSX6924_ENUM_ ## NAME), \ sizeof(KSX6924_ENUM_ ## NAME [0]), \ _ksx6924_ ## KEY_TYPE ## _enum_compare); \ if (r == NULL) { \ From 8ac8e3d7d0016eac9af4b0519213d457fd5e3d59 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 01:43:38 +0100 Subject: [PATCH 491/759] reduce variable scopes --- armsrc/frozen.c | 10 ++++--- armsrc/hitagS.c | 3 +-- armsrc/iclass.c | 3 +-- armsrc/mifareutil.c | 3 +-- client/src/cmdhf15.c | 4 +-- client/src/cmdhfmf.c | 9 +++---- client/src/cmdhfwaveshare.c | 22 ++++++++-------- client/src/cmdhfxerox.c | 8 +++--- client/src/cmdlfem410x.c | 5 ---- client/src/cmdlfem4x05.c | 13 +++++---- client/src/cmdlft55xx.c | 3 +-- client/src/cmdpiv.c | 3 +-- client/src/cmdtrace.c | 4 +-- client/src/emv/emvcore.c | 11 ++++---- client/src/mifare/desfirecore.c | 2 +- client/src/ui.c | 3 +-- common/cryptorf/cryptolib.c | 3 +-- tools/cryptorf/sma.cpp | 11 ++++---- tools/cryptorf/sma_multi.cpp | 42 ++++++++++++------------------ tools/mf_nonce_brute/iso14443crc.c | 3 +-- tools/mfd_aes_brute/randoms.c | 3 +-- 21 files changed, 71 insertions(+), 97 deletions(-) diff --git a/armsrc/frozen.c b/armsrc/frozen.c index 455d9a3f2..963b0a52b 100644 --- a/armsrc/frozen.c +++ b/armsrc/frozen.c @@ -235,9 +235,10 @@ static int json_get_utf8_char_len(unsigned char ch) { /* string = '"' { quoted_printable_chars } '"' */ static int json_parse_string(struct frozen *f) { - int n, ch = 0, len = 0; + int ch = 0; TRY(json_test_and_skip(f, '"')); { + int len = 0; SET_STATE(f, f->cur, "", 0); for (; f->cur < f->end; f->cur += len) { ch = *(unsigned char *) f->cur; @@ -245,6 +246,7 @@ static int json_parse_string(struct frozen *f) { EXPECT(ch >= 32 && len > 0, JSON_STRING_INVALID); /* No control chars */ EXPECT(len <= json_left(f), JSON_STRING_INCOMPLETE); if (ch == '\\') { + int n; EXPECT((n = json_get_escape_len(f->cur + 1, json_left(f))) > 0, n); len += n; } else if (ch == '"') { @@ -295,17 +297,17 @@ static int json_parse_number(struct frozen *f) { #if JSON_ENABLE_ARRAY /* array = '[' [ value { ',' value } ] ']' */ static int json_parse_array(struct frozen *f) { - int i = 0, current_path_len; - char buf[20]; CALL_BACK(f, JSON_TYPE_ARRAY_START, NULL, 0); TRY(json_test_and_skip(f, '[')); { { + int i = 0; SET_STATE(f, f->cur - 1, "", 0); while (json_cur(f) != ']') { + char buf[20]; snprintf(buf, sizeof(buf), "[%d]", i); i++; - current_path_len = json_append_to_path(f, buf, strlen(buf)); + int current_path_len = json_append_to_path(f, buf, strlen(buf)); f->cur_name = f->path + strlen(f->path) - strlen(buf) + 1 /*opening brace*/; f->cur_name_len = strlen(buf) - 2 /*braces*/; diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index a4a3630c7..db219bcf2 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -1268,7 +1268,6 @@ void ReadHitagS(hitag_function htf, hitag_data *htd, bool ledcontrol) { uint8_t rx[HITAG_FRAME_LEN]; size_t rxlen = 0; uint8_t tx[HITAG_FRAME_LEN]; - size_t txlen; int t_wait = HITAG_T_WAIT_MAX; @@ -1284,7 +1283,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd, bool ledcontrol) { WDT_HIT(); //send read request - txlen = 0; + size_t txlen = 0; uint8_t cmd = 0x0c; txlen = concatbits(tx, txlen, &cmd, 8 - 4, 4); uint8_t addr = pageNum; diff --git a/armsrc/iclass.c b/armsrc/iclass.c index a25fbd52c..5a68a8207 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1258,7 +1258,6 @@ static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t * uint16_t timeout, uint32_t *eof_time, bool shallow_mod) { uint16_t resp_len = 0; - int res; while (tries-- > 0) { iclass_send_as_reader(cmd, cmdsize, start_time, eof_time, shallow_mod); @@ -1267,7 +1266,7 @@ static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t * return true; } - res = GetIso15693AnswerFromTag(resp, max_resp_size, timeout, eof_time, false, true, &resp_len); + int res = GetIso15693AnswerFromTag(resp, max_resp_size, timeout, eof_time, false, true, &resp_len); if (res == PM3_SUCCESS && expected_size == resp_len) { return true; } diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index fd9d86ccc..5c0905e68 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -461,7 +461,6 @@ int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo uint16_t len = 0; uint32_t pos = 0; uint8_t par[3] = {0x00, 0x00, 0x00}; // enough for 18 Bytes to send - uint8_t res = 0; uint8_t d_block[18], d_block_enc[18]; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; @@ -495,7 +494,7 @@ int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo len = ReaderReceive(receivedAnswer, receivedAnswerPar); if (len != 0) { // Something not right, len == 0 (no response is ok as its waiting for transfer - res = 0; + uint8_t res = 0; res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 84629d56e..c35df7238 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1384,11 +1384,11 @@ static int CmdHF15WriteAfi(const char *Cmd) { // arg0 (datalen, cmd len? .arg0 == crc?) // arg1 (speed == 0 == 1 of 256, == 1 == 1 of 4 ) // arg2 (recv == 1 == expect a response) - uint8_t read_respone = 1; + uint8_t read_response = 1; PacketResponseNG resp; clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, read_respone, req, reqlen); + SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, read_response, req, reqlen); if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { PrintAndLogEx(ERR, "iso15693 timeout"); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 89cb68023..b00dd5651 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -3688,8 +3688,6 @@ static int CmdHF14AMfSim(const char *Cmd) { } CLIParserFree(ctx); - nonces_t data[1]; - sector_t *k_sector = NULL; //Validations @@ -3780,7 +3778,7 @@ static int CmdHF14AMfSim(const char *Cmd) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue; if (!(flags & FLAG_NR_AR_ATTACK)) break; if ((resp.oldarg[0] & 0xffff) != CMD_HF_MIFARE_SIMULATE) break; - + nonces_t data[1]; memcpy(data, resp.data.asBytes, sizeof(data)); readerAttack(k_sector, k_sectorsCount, data[0], setEmulatorMem, verbose); } @@ -7619,7 +7617,6 @@ static int CmdHF14AMfValue(const char *Cmd) { int64_t decval = (int64_t)arg_get_u64_def(ctx, 5, -1); // Inc by -1 is invalid, so not set. int64_t setval = (int64_t)arg_get_u64_def(ctx, 6, 0x7FFFFFFFFFFFFFFF); // out of bounds (for int32) so not set bool getval = arg_get_lit(ctx, 7); - uint8_t block[MFBLOCK_SIZE] = {0x00}; int dlen = 0; uint8_t data[16] = {0}; CLIGetHexWithReturn(ctx, 9, data, &dlen); @@ -7627,7 +7624,6 @@ static int CmdHF14AMfValue(const char *Cmd) { uint8_t action = 3; // 0 Increment, 1 - Decrement, 2 - Set, 3 - Get, 4 - Decode from data uint32_t value = 0; - uint8_t isok = true; // Need to check we only have 1 of inc/dec/set and get the value from the selected option int optionsprovided = 0; @@ -7683,11 +7679,12 @@ static int CmdHF14AMfValue(const char *Cmd) { } if (action < 3) { - + uint8_t isok = true; if (g_session.pm3_present == false) return PM3_ENOTTY; if (action <= 1) { // increment/decrement value + uint8_t block[MFBLOCK_SIZE] = {0x00}; memcpy(block, (uint8_t *)&value, 4); uint8_t cmddata[26]; memcpy(cmddata, key, sizeof(key)); // Key == 6 data went to 10, so lets offset 9 for inc/dec diff --git a/client/src/cmdhfwaveshare.c b/client/src/cmdhfwaveshare.c index ae2f74582..78c6ef825 100644 --- a/client/src/cmdhfwaveshare.c +++ b/client/src/cmdhfwaveshare.c @@ -660,7 +660,6 @@ static int start_drawing_1in54B(uint8_t model_nr, uint8_t *black, uint8_t *red) } static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { - uint8_t progress; uint8_t step0[2] = {0xcd, 0x0d}; uint8_t step1[3] = {0xcd, 0x00, 10}; // select e-paper type and reset e-paper // 4 :2.13inch e-Paper @@ -687,7 +686,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { // uint8_t step13[2]={0xcd,0x0b}; // Judge whether the power supply is turned off successfully // uint8_t step14[2]={0xcd,0x0c}; // The end of the transmission uint8_t rx[20]; - uint16_t actrxlen[20], i; + uint16_t actrxlen[20]; clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0, NULL, 0); @@ -812,6 +811,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { } // 1.54B Data transfer is complete and wait for refresh } else { + uint8_t progress; PrintAndLogEx(DEBUG, "Step5: e-paper config2"); ret = transceive_blocking(step5, 2, rx, 20, actrxlen, true); // cd 05 if (ret != PM3_SUCCESS) { @@ -831,7 +831,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { } PrintAndLogEx(DEBUG, "Step8: Start data transfer"); if (model_nr == M2in13) { // 2.13inch - for (i = 0; i < 250; i++) { + for (uint16_t i = 0; i < 250; i++) { read_black(i, step8, model_nr, black); ret = transceive_blocking(step8, 19, rx, 20, actrxlen, true); // cd 08 if (ret != PM3_SUCCESS) { @@ -841,7 +841,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { PrintAndLogEx(INPLACE, "Progress: %d %%", progress); } } else if (model_nr == M2in9) { - for (i = 0; i < 296; i++) { + for (uint16_t i = 0; i < 296; i++) { read_black(i, step8, model_nr, black); ret = transceive_blocking(step8, 19, rx, 20, actrxlen, true); // cd 08 if (ret != PM3_SUCCESS) { @@ -851,7 +851,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { PrintAndLogEx(INPLACE, "Progress: %d %%", progress); } } else if (model_nr == M4in2) { //4.2inch - for (i = 0; i < 150; i++) { + for (uint16_t i = 0; i < 150; i++) { read_black(i, step8, model_nr, black); ret = transceive_blocking(step8, 103, rx, 20, actrxlen, true); // cd 08 if (ret != PM3_SUCCESS) { @@ -861,7 +861,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { PrintAndLogEx(INPLACE, "Progress: %d %%", progress); } } else if (model_nr == M7in5) { //7.5inch - for (i = 0; i < 400; i++) { + for (uint16_t i = 0; i < 400; i++) { read_black(i, step8, model_nr, black); ret = transceive_blocking(step8, 123, rx, 20, actrxlen, true); // cd 08 if (ret != PM3_SUCCESS) { @@ -872,7 +872,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { msleep(6); } } else if (model_nr == M2in13B) { //2.13inch B - for (i = 0; i < 26; i++) { + for (uint16_t i = 0; i < 26; i++) { read_black(i, step8, model_nr, black); ret = transceive_blocking(step8, 109, rx, 20, actrxlen, false); // cd 08 if (ret != PM3_SUCCESS) { @@ -883,7 +883,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { } } else if (model_nr == M7in5HD) { //7.5HD - for (i = 0; i < 484; i++) { + for (uint16_t i = 0; i < 484; i++) { read_black(i, step8, model_nr, black); //memset(&step8[3], 0xf0, 120); ret = transceive_blocking(step8, 123, rx, 20, actrxlen, true); // cd 08 @@ -899,7 +899,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { return ret; } } else if (model_nr == M2in7) { //2.7inch - for (i = 0; i < 48; i++) { + for (uint16_t i = 0; i < 48; i++) { //read_black(i,step8, model_nr, black); memset(&step8[3], 0xFF, sizeof(step8) - 3); ret = transceive_blocking(step8, 124, rx, 20, actrxlen, true); // cd 08 @@ -925,7 +925,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { } PrintAndLogEx(DEBUG, "Step9b"); if (model_nr == M2in7) { - for (i = 0; i < 48; i++) { + for (uint16_t i = 0; i < 48; i++) { read_black(i, step13, model_nr, black); ret = transceive_blocking(step13, 124, rx, 20, actrxlen, true); //CD 19 if (ret != PM3_SUCCESS) { @@ -935,7 +935,7 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { PrintAndLogEx(INPLACE, "Progress: %d %%", progress); } } else if (model_nr == M2in13B) { - for (i = 0; i < 26; i++) { + for (uint16_t i = 0; i < 26; i++) { read_red(i, step13, model_nr, red); //memset(&step13[3], 0xfE, 106); ret = transceive_blocking(step13, 109, rx, 20, actrxlen, false); diff --git a/client/src/cmdhfxerox.c b/client/src/cmdhfxerox.c index 9ba1577da..fec69855e 100644 --- a/client/src/cmdhfxerox.c +++ b/client/src/cmdhfxerox.c @@ -202,7 +202,7 @@ void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) { void RC2_encrypt(unsigned long *d, RC2_KEY *key) { int i, n; register RC2_INT *p0, *p1; - register RC2_INT x0, x1, x2, x3, t; + register RC2_INT x0, x1, x2, x3; unsigned long l; l = d[0]; @@ -217,7 +217,7 @@ void RC2_encrypt(unsigned long *d, RC2_KEY *key) { p0 = p1 = &(key->data[0]); for (;;) { - t = (x0 + (x1 & ~x3) + (x2 & x3) + * (p0++)) & 0xffff; + register RC2_INT t = (x0 + (x1 & ~x3) + (x2 & x3) + * (p0++)) & 0xffff; x0 = (t << 1) | (t >> 15); t = (x1 + (x2 & ~x0) + (x3 & x0) + * (p0++)) & 0xffff; x1 = (t << 2) | (t >> 14); @@ -244,7 +244,7 @@ void RC2_encrypt(unsigned long *d, RC2_KEY *key) { void RC2_decrypt(unsigned long *d, RC2_KEY *key) { int i, n; register RC2_INT *p0, *p1; - register RC2_INT x0, x1, x2, x3, t; + register RC2_INT x0, x1, x2, x3; unsigned long l; l = d[0]; @@ -260,7 +260,7 @@ void RC2_decrypt(unsigned long *d, RC2_KEY *key) { p0 = &(key->data[63]); p1 = &(key->data[0]); for (;;) { - t = ((x3 << 11) | (x3 >> 5)) & 0xffff; + register RC2_INT t = ((x3 << 11) | (x3 >> 5)) & 0xffff; x3 = (t - (x0 & ~x2) - (x1 & x2) - * (p0--)) & 0xffff; t = ((x2 << 13) | (x2 >> 3)) & 0xffff; x2 = (t - (x3 & ~x1) - (x0 & x1) - * (p0--)) & 0xffff; diff --git a/client/src/cmdlfem410x.c b/client/src/cmdlfem410x.c index ef9caf959..ea502fc07 100644 --- a/client/src/cmdlfem410x.c +++ b/client/src/cmdlfem410x.c @@ -672,11 +672,6 @@ static int CmdEM410xClone(const char *Cmd) { return PM3_EINVARG; } - char cardtype[16] = {"T55x7"}; - if (q5) { - snprintf(cardtype, sizeof(cardtype), "Q5/T5555"); - } - PrintAndLogEx(SUCCESS, "Preparing to clone EM4102 to " _YELLOW_("%s") " tag with EM Tag ID " _GREEN_("%010" PRIX64) " (RF/%d)", q5 ? "Q5/T5555" : (em ? "EM4305/4469" : "T55x7"), id, clk); struct { diff --git a/client/src/cmdlfem4x05.c b/client/src/cmdlfem4x05.c index 8e6110c62..cff7203d2 100644 --- a/client/src/cmdlfem4x05.c +++ b/client/src/cmdlfem4x05.c @@ -2025,10 +2025,8 @@ int CmdEM4x05Sniff(const char *Cmd) { size_t idx = 0; // loop though sample buffer while (idx < g_GraphTraceLen) { - bool eop = false; bool haveData = false; bool pwd = false; - uint32_t tmpValue; idx = em4x05_Sniff_GetNextBitStart(idx, g_GraphTraceLen, g_GraphBuffer, &pulseSamples); size_t pktOffset = idx; @@ -2044,6 +2042,7 @@ int CmdEM4x05Sniff(const char *Cmd) { memset(bits.ptr, 0, bits.size); bits.idx = 0; + bool eop = false; while ((idx < g_GraphTraceLen) && !eop) { CycleWidth = idx; idx = em4x05_Sniff_GetNextBitStart(idx, g_GraphTraceLen, g_GraphBuffer, &pulseSamples); @@ -2081,7 +2080,7 @@ int CmdEM4x05Sniff(const char *Cmd) { pwd = true; cmdText = "Logon"; strncpy(blkAddr, " ", sizeof(blkAddr)); - tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[4], fwd); + uint32_t tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[4], fwd); snprintf(dataText, sizeof(dataText), "%08X", tmpValue); } @@ -2089,7 +2088,7 @@ int CmdEM4x05Sniff(const char *Cmd) { if ((strncmp(bits.ptr, "0101", 4) == 0) && (bits.idx == 56)) { haveData = true; cmdText = "Write"; - tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3); + uint32_t tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3); snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue); if (tmpValue == 2) { pwd = true; @@ -2103,7 +2102,7 @@ int CmdEM4x05Sniff(const char *Cmd) { haveData = true; pwd = false; cmdText = "Read"; - tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3); + uint32_t tmpValue = (bits.ptr[4] - '0') + ((bits.ptr[5] - '0') << 1) + ((bits.ptr[6] - '0') << 2) + ((bits.ptr[7] - '0') << 3); snprintf(blkAddr, sizeof(blkAddr), "%u", tmpValue); strncpy(dataText, " ", sizeof(dataText)); } @@ -2114,7 +2113,7 @@ int CmdEM4x05Sniff(const char *Cmd) { pwd = false; cmdText = "Protect"; strncpy(blkAddr, " ", sizeof(blkAddr)); - tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd); + uint32_t tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd); snprintf(dataText, sizeof(dataText), "%08X", tmpValue); } @@ -2124,7 +2123,7 @@ int CmdEM4x05Sniff(const char *Cmd) { pwd = false; cmdText = "Disable"; strncpy(blkAddr, " ", sizeof(blkAddr)); - tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd); + uint32_t tmpValue = em4x05_Sniff_GetBlock(&bits.ptr[11], fwd); snprintf(dataText, sizeof(dataText), "%08X", tmpValue); } diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index ba3df4088..f1cb773fb 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -4011,7 +4011,6 @@ static int CmdT55xxSniff(const char *Cmd) { size_t idx = 0; uint32_t usedPassword, blockData; int pulseSamples = 0, pulseIdx = 0; - const char *modeText; char pwdText[100]; char dataText[100]; int pulseBuffer[80] = { 0 }; // max should be 73 +/- - Holds Pulse widths @@ -4037,7 +4036,7 @@ static int CmdT55xxSniff(const char *Cmd) { int maxWidth = 0; data[0] = 0; bool have_data = false; - modeText = "Default"; + const char *modeText = "Default"; strncpy(pwdText, " ", sizeof(pwdText)); strncpy(dataText, " ", sizeof(dataText)); diff --git a/client/src/cmdpiv.c b/client/src/cmdpiv.c index 12b217ebc..dc6584f40 100644 --- a/client/src/cmdpiv.c +++ b/client/src/cmdpiv.c @@ -940,9 +940,8 @@ static int CmdPIVScan(const char *Cmd) { memcpy(applet_id, PIV_APPLET, sizeof(PIV_APPLET)); aid_len = sizeof(PIV_APPLET); } - int res = 0; if (activateField == true) { - res = PivSelect(channel, activateField, true, decodeTLV, true, applet_id, aid_len); + int res = PivSelect(channel, activateField, true, decodeTLV, true, applet_id, aid_len); if (res != PM3_SUCCESS) { if (leaveSignalON == false) { DropFieldEx(channel); diff --git a/client/src/cmdtrace.c b/client/src/cmdtrace.c index af97e8466..d3096307a 100644 --- a/client/src/cmdtrace.c +++ b/client/src/cmdtrace.c @@ -485,8 +485,6 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr uint32_t end_of_transmission_timestamp = 0; uint8_t topaz_reader_command[9]; char explanation[40] = {0}; - uint8_t mfData[32] = {0}; - size_t mfDataLen = 0; tracelog_hdr_t *first_hdr = (tracelog_hdr_t *)(trace); tracelog_hdr_t *hdr = (tracelog_hdr_t *)(trace + tracepos); @@ -871,6 +869,8 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr } if (protocol == PROTO_MIFARE) { + uint8_t mfData[32] = {0}; + size_t mfDataLen = 0; if (DecodeMifareData(frame, data_len, parityBytes, hdr->isResponse, mfData, &mfDataLen, mfDicKeys, mfDicKeysCount)) { memset(explanation, 0x00, sizeof(explanation)); annotateIso14443a(explanation, sizeof(explanation), mfData, mfDataLen, hdr->isResponse); diff --git a/client/src/emv/emvcore.c b/client/src/emv/emvcore.c index 34aa4d4be..fbc59b1c0 100644 --- a/client/src/emv/emvcore.c +++ b/client/src/emv/emvcore.c @@ -381,8 +381,6 @@ static int EMVCheckAID(Iso7816CommandChannel channel, bool decodeTLV, struct tlv int EMVSearchPSE(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t PSENum, bool decodeTLV, struct tlvdb *tlv) { uint8_t data[APDU_RES_LEN] = {0}; size_t datalen = 0; - uint8_t sfidata[0x11][APDU_RES_LEN]; - size_t sfidatalen[0x11] = {0}; uint16_t sw = 0; int res; const char *PSE_or_PPSE = PSENum == 1 ? "PSE" : "PPSE"; @@ -402,6 +400,8 @@ int EMVSearchPSE(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFi // PSE/PPSE with SFI struct tlvdb *tsfi = tlvdb_find_path(t, (tlv_tag_t[]) {0x6f, 0xa5, 0x88, 0x00}); if (tsfi) { + uint8_t sfidata[0x11][APDU_RES_LEN]; + size_t sfidatalen[0x11] = {0}; uint8_t sfin = 0; tlv_get_uint8(tlvdb_get_tlv(tsfi), &sfin); PrintAndLogEx(INFO, "* PPSE get SFI: 0x%02x.", sfin); @@ -669,10 +669,6 @@ static const unsigned char default_ddol_value[] = {0x9f, 0x37, 0x04}; static struct tlv default_ddol_tlv = {.tag = 0x9f49, .len = 3, .value = default_ddol_value }; int trDDA(Iso7816CommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { - uint8_t buf[APDU_RES_LEN] = {0}; - size_t len = 0; - uint16_t sw = 0; - struct emv_pk *pk = get_ca_pk(tlv); if (!pk) { PrintAndLogEx(ERR, "Error: Key not found, exiting"); @@ -767,6 +763,9 @@ int trDDA(Iso7816CommandChannel channel, bool decodeTLV, struct tlvdb *tlv) { tlvdb_free(atc_db); } else { + uint8_t buf[APDU_RES_LEN] = {0}; + size_t len = 0; + uint16_t sw = 0; struct tlvdb *dac_db = emv_pki_recover_dac(issuer_pk, tlv, sda_tlv); if (dac_db) { const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL); diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index 3e002a7ef..9c3326f83 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -2301,9 +2301,9 @@ static const char *GetDesfireKeyType(uint8_t keytype) { } const char *GetDesfireAccessRightStr(uint8_t right) { - static char int_access_str[200]; if (right <= 0x0d) { + static char int_access_str[200]; snprintf(int_access_str, sizeof(int_access_str), "key 0x%02x", right); return int_access_str; } diff --git a/client/src/ui.c b/client/src/ui.c index d9f4514cf..2281497c1 100644 --- a/client/src/ui.c +++ b/client/src/ui.c @@ -531,12 +531,11 @@ void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode uint8_t emojified_token_length = 0; char *current_token = NULL; uint8_t current_token_length = 0; - char current_char; char *rdest = (char *)dest; char *rsrc = (char *)src; uint16_t si = 0; for (size_t i = 0; i < n; i++) { - current_char = rsrc[i]; + char current_char = rsrc[i]; if (current_token_length == 0) { // starting a new token. diff --git a/common/cryptorf/cryptolib.c b/common/cryptorf/cryptolib.c index eded5315c..b4abbdd54 100644 --- a/common/cryptorf/cryptolib.c +++ b/common/cryptorf/cryptolib.c @@ -280,7 +280,6 @@ void cm_auth(const uint8_t *Gc, const uint8_t *Ci, const uint8_t *Q, uint8_t *Ch static void cm_crypt(const CryptoAction ca, const uint8_t offset, const uint8_t len, const uint8_t *in, uint8_t *out, crypto_state s) { size_t pos; - uint8_t bt; next_n(true, 5, 0, s); next(true, offset, s); @@ -288,7 +287,7 @@ static void cm_crypt(const CryptoAction ca, const uint8_t offset, const uint8_t next(true, len, s); for (pos = 0; pos < len; pos++) { // Perform the crypto operation - bt = in[pos] ^ cm_byte(s); + uint8_t bt = in[pos] ^ cm_byte(s); // Generate output if (out) out[pos] = bt; diff --git a/tools/cryptorf/sma.cpp b/tools/cryptorf/sma.cpp index eb9cf3c9d..d15b0e6a2 100644 --- a/tools/cryptorf/sma.cpp +++ b/tools/cryptorf/sma.cpp @@ -331,11 +331,10 @@ static inline uint8_t next_right_fast(uint8_t in, uint64_t *right) { static inline void sm_left_mask(const uint8_t *ks, uint8_t *mask, uint64_t rstate) { size_t pos; - uint8_t bt; for (pos = 0; pos < 16; pos++) { next_right_fast(0, &rstate); - bt = next_right_fast(0, &rstate) << 4; + uint8_t bt = next_right_fast(0, &rstate) << 4; next_right_fast(0, &rstate); bt |= next_right_fast(0, &rstate); @@ -349,7 +348,7 @@ static inline void sm_left_mask(const uint8_t *ks, uint8_t *mask, uint64_t rstat static inline uint32_t sm_right(const uint8_t *ks, uint8_t *mask, vector *pcrstates) { uint8_t tmp_mask[16]; - size_t pos, bits, bit, topbits; + size_t pos, bit, topbits; uint64_t rstate, counter; map bincstates; map::iterator it; @@ -358,7 +357,7 @@ static inline uint32_t sm_right(const uint8_t *ks, uint8_t *mask, vector *pcstates) { map bincstates; map::iterator it; - uint64_t counter, lstate; + uint64_t counter; size_t pos, bits, bit; uint8_t correct_bits[16]; uint8_t bt; @@ -526,7 +525,7 @@ static inline void sm_left(const uint8_t *ks, const uint8_t *mask, vector state.invalid = false; for (counter = 0; counter < 0x800000000ull; counter++) { - lstate = counter; + uint64_t lstate = counter; for (pos = 0; pos < 16; pos++) { lstate = (((lstate) >> 5) | ((uint64_t)left_addition[((lstate) & 0xf801f)] << 30)); diff --git a/tools/cryptorf/sma_multi.cpp b/tools/cryptorf/sma_multi.cpp index 577811f64..f7047d977 100644 --- a/tools/cryptorf/sma_multi.cpp +++ b/tools/cryptorf/sma_multi.cpp @@ -199,18 +199,15 @@ static lookup_entry lookup_right[0x8000]; static uint8_t left_addition[0x100000]; static inline void init_lookup_left() { - uint8_t b3, b6, temp; - int i, index; - - for (i = 0; i < 0x400; i++) { - b6 = i & 0x1f; - b3 = (i >> 5) & 0x1f; - index = (b3 << 15) | b6; + for (int i = 0; i < 0x400; i++) { + uint8_t b6 = i & 0x1f; + uint8_t b3 = (i >> 5) & 0x1f; + int index = (b3 << 15) | b6; // b6 = bit_rotate_l(b6, 5); b6 = BIT_ROL(b6); - temp = mod(b3 + b6, 0x1f); + uint8_t temp = mod(b3 + b6, 0x1f); left_addition[index] = temp; lookup_left[index].addition = temp; lookup_left[index].out = ((temp ^ b3) & 0x0f); @@ -218,15 +215,12 @@ static inline void init_lookup_left() { } static inline void init_lookup_right() { - uint8_t b16, b18, temp; - int i, index; + for (int i = 0; i < 0x400; i++) { + uint8_t b18 = i & 0x1f; + uint8_t b16 = (i >> 5) & 0x1f; + int index = (b16 << 10) | b18; - for (i = 0; i < 0x400; i++) { - b18 = i & 0x1f; - b16 = (i >> 5) & 0x1f; - index = (b16 << 10) | b18; - - temp = mod(b18 + b16, 0x1f); + uint8_t temp = mod(b18 + b16, 0x1f); lookup_right[index].addition = temp; lookup_right[index].out = ((temp ^ b16) & 0x0f); } @@ -589,23 +583,21 @@ static void ice_sm_left(const uint8_t *ks, uint8_t *mask, vector *pcstates static inline uint32_t sm_right(const uint8_t *ks, uint8_t *mask, vector *pcrstates) { uint8_t tmp_mask[16]; - size_t pos, bits, bit, topbits; + size_t topbits = 0; map bincstates; map::iterator it; - uint8_t bt; - topbits = 0; for (uint64_t counter = 0; counter < 0x2000000; counter++) { // Reset the current bitcount of correct bits - bits = 0; + size_t bits = 0; // Copy the state we are going to test uint64_t rstate = counter; - for (pos = 0; pos < 16; pos++) { + for (size_t pos = 0; pos < 16; pos++) { next_right_fast(0, &rstate); - bt = next_right_fast(0, &rstate) << 4; + uint8_t bt = next_right_fast(0, &rstate) << 4; next_right_fast(0, &rstate); bt |= next_right_fast(0, &rstate); @@ -615,7 +607,7 @@ static inline uint32_t sm_right(const uint8_t *ks, uint8_t *mask, vector>= 1; @@ -744,7 +736,7 @@ static inline void search_gc_candidates_right(const uint64_t rstate_before_gc, c static inline void sm_left(const uint8_t *ks, const uint8_t *mask, vector *pcstates) { map bincstates; map::iterator it; - uint64_t counter, lstate; + uint64_t counter; size_t pos, bits; uint8_t correct_bits[16]; uint8_t bt; @@ -756,7 +748,7 @@ static inline void sm_left(const uint8_t *ks, const uint8_t *mask, vector state.invalid = false; for (counter = 0; counter < 0x800000000ull; counter++) { - lstate = counter; + uint64_t lstate = counter; for (pos = 0; pos < 16; pos++) { diff --git a/tools/mf_nonce_brute/iso14443crc.c b/tools/mf_nonce_brute/iso14443crc.c index 60631f4fb..c5acbb9be 100644 --- a/tools/mf_nonce_brute/iso14443crc.c +++ b/tools/mf_nonce_brute/iso14443crc.c @@ -20,11 +20,10 @@ void ComputeCrc14443(int CrcType, const unsigned char *Data, int Length, unsigned char *TransmitFirst, unsigned char *TransmitSecond) { - unsigned char chBlock; unsigned short wCrc = CrcType; do { - chBlock = *Data++; + unsigned char chBlock = *Data++; UpdateCrc14443(chBlock, &wCrc); } while (--Length); diff --git a/tools/mfd_aes_brute/randoms.c b/tools/mfd_aes_brute/randoms.c index c957350ec..523366d9d 100644 --- a/tools/mfd_aes_brute/randoms.c +++ b/tools/mfd_aes_brute/randoms.c @@ -68,13 +68,12 @@ void make_key_turbopascal_n(uint32_t seed, uint8_t key[], const size_t keylen) { void make_key_posix_rand_r_n(uint32_t seed, uint8_t key[], const size_t keylen) { uint32_t lseed = seed; - int result; for (int i = 0; i < keylen; i++) { lseed *= 1103515245; lseed += 12345; - result = (uint16_t)(lseed / 0x10000) % 2048; + int result = (uint16_t)(lseed / 0x10000) % 2048; lseed *= 1103515245; lseed += 12345; From 3936afcca99f716cc63928fbebd0271a51ed3046 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 01:48:45 +0100 Subject: [PATCH 492/759] cppcheck divide by zero --- tools/cryptorf/sma_multi.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/cryptorf/sma_multi.cpp b/tools/cryptorf/sma_multi.cpp index f7047d977..c4e61e37e 100644 --- a/tools/cryptorf/sma_multi.cpp +++ b/tools/cryptorf/sma_multi.cpp @@ -165,6 +165,9 @@ void print_cs(const char *text, pcs s) { } static inline uint8_t mod(uint8_t a, uint8_t m) { + if (m==0) { + return 0; // Actually, divide by zero error + } // Just return the input when this is less or equal than the modular value if (a < m) return a; From 857f0c0d9bce056acbca828155f93a3faa712dec Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 01:50:44 +0100 Subject: [PATCH 493/759] cppcheck fix returnNonBoolInBooleanFunction --- client/src/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index b00dd5651..dfac4dbee 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -369,7 +369,7 @@ static bool mf_write_block(const uint8_t *key, uint8_t keytype, uint8_t blockno, PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { PrintAndLogEx(FAILED, "Command execute timeout"); - return PM3_ETIMEOUT; + return false; } return (resp.oldarg[0] & 0xff); From b8458322e15deb33f143ec170427a380434bbf75 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 01:52:30 +0100 Subject: [PATCH 494/759] cppcheck fix null pointer dereference --- client/src/cmdhw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index f10fa8330..0efa5eafe 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -592,12 +592,12 @@ static int CmdLCD(const char *Cmd) { arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - CLIParserFree(ctx); int r_len = 0; uint8_t raw[1] = {0}; CLIGetHexWithReturn(ctx, 1, raw, &r_len); int j = arg_get_int_def(ctx, 2, 1); + CLIParserFree(ctx); if (j < 1) { PrintAndLogEx(WARNING, "Count must be larger than zero"); return PM3_EINVARG; From 127aebd8b0e540d0b136b6e858c9abdca52356a1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 01:54:10 +0100 Subject: [PATCH 495/759] cppcheck fix uninitialized variable --- client/src/cmdlfparadox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdlfparadox.c b/client/src/cmdlfparadox.c index bbd6cd205..a2fa50f11 100644 --- a/client/src/cmdlfparadox.c +++ b/client/src/cmdlfparadox.c @@ -263,7 +263,7 @@ static int CmdParadoxClone(const char *Cmd) { return PM3_EINVARG; } - uint32_t blocks[4]; + uint32_t blocks[4] = {0}; if (raw_len != 0) { if (raw_len != 12) { From c2eb6395e242986c10155e1917614e6c1dfce112 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 01:55:29 +0100 Subject: [PATCH 496/759] cppcheck clarify boolean result used in bitwise operation --- client/src/cmdhftexkom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhftexkom.c b/client/src/cmdhftexkom.c index 88add72d6..2b54480ca 100644 --- a/client/src/cmdhftexkom.c +++ b/client/src/cmdhftexkom.c @@ -311,7 +311,7 @@ static bool TexcomTK15Decode(uint32_t *implengths, uint32_t implengthslen, char bool prevbit = (implengths[implengthslen - 3] > implengths[implengthslen - 2]); bool thesamebit = (abs(lastimplen - (int)implengths[implengthslen - 3]) < abs(lastimplen - (int)implengths[implengthslen - 2])); - if (prevbit ^ !thesamebit) { + if (prevbit ^ (!thesamebit)) { strcat(bitstring, "10"); strcat(cbitstring, "1"); } else { From 17d7fb8abb600ae6e7a7675efe7892726f11fe38 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 01:58:57 +0100 Subject: [PATCH 497/759] cppcheck test unsigned less than zero --- armsrc/felica.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/felica.c b/armsrc/felica.c index 3cf75a0b4..0a74a30cc 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -298,7 +298,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) { // 8-byte IDm, number of blocks, blocks numbers // number of blocks limited to 4 for FelicaLite(S) static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t *blocks) { - if (blocknum > 4 || blocknum <= 0) + if (blocknum > 4 || blocknum == 0) Dbprintf("Invalid number of blocks, %d != 4", blocknum); uint8_t c = 0, i = 0; From eb23028514e301d878358bf11ce31210517888fc Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 02:02:25 +0100 Subject: [PATCH 498/759] cppcheck: add test to avoid dereferncing null pointer --- client/src/iso7816/apduinfo.c | 3 ++- tools/hitag2crack/common/ht2crackutils.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/client/src/iso7816/apduinfo.c b/client/src/iso7816/apduinfo.c index b2d879b78..b7d77aca9 100644 --- a/client/src/iso7816/apduinfo.c +++ b/client/src/iso7816/apduinfo.c @@ -440,7 +440,8 @@ int APDUDecode(uint8_t *data, int len, APDU_t *apdu) { int APDUEncode(APDU_t *apdu, uint8_t *data, int *len) { if (len) *len = 0; - + if (apdu == NULL) + return 1; if (apdu->le > 0x10000) return 1; diff --git a/tools/hitag2crack/common/ht2crackutils.c b/tools/hitag2crack/common/ht2crackutils.c index cfac2bfd8..492676724 100644 --- a/tools/hitag2crack/common/ht2crackutils.c +++ b/tools/hitag2crack/common/ht2crackutils.c @@ -141,6 +141,8 @@ int fnf(uint64_t s) { // builds the lfsr for the prng (quick calcs for hitag2_nstep()) void buildlfsr(Hitag_State *hstate) { + if (hstate == NULL) + return; uint64_t state = hstate->shiftreg; uint64_t temp = state ^ (state >> 1); hstate->lfsr = state ^ (state >> 6) ^ (state >> 16) From 0a19c3e8917f9fa8d157b60afa7a27cf0e784af5 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 02:05:58 +0100 Subject: [PATCH 499/759] cppcheck remove redundant continue as last loop statement --- client/deps/hardnested/hardnested_bf_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/deps/hardnested/hardnested_bf_core.c b/client/deps/hardnested/hardnested_bf_core.c index 64b0696aa..63eba8eba 100644 --- a/client/deps/hardnested/hardnested_bf_core.c +++ b/client/deps/hardnested/hardnested_bf_core.c @@ -530,7 +530,6 @@ stop_tests: bucket_states_tested += bucket_size[block_idx]; // prepare to set new states state_p = &states[KEYSTREAM_SIZE]; - continue; } } out: From 048291dcb3ea6580699ff48b8d5614cbeb4ec3b0 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 02:12:19 +0100 Subject: [PATCH 500/759] cppcheck: can add const on some params --- client/src/cmdhfmfdes.c | 4 ++-- client/src/cmdhftopaz.c | 2 +- client/src/util.c | 2 +- client/src/util.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index f3da73c2c..00c6306e7 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -306,7 +306,7 @@ static nxp_cardtype_t getCardType(uint8_t major, uint8_t minor) { } // ref: https://www.nxp.com/docs/en/application-note/AN12343.pdf p7 -static nxp_producttype_t getProductType(uint8_t *versionhw) { +static nxp_producttype_t getProductType(const uint8_t *versionhw) { uint8_t product = versionhw[2]; @@ -323,7 +323,7 @@ static nxp_producttype_t getProductType(uint8_t *versionhw) { return DESFIRE_UNKNOWN_PROD; } -static const char *getProductTypeStr(uint8_t *versionhw) { +static const char *getProductTypeStr(const uint8_t *versionhw) { uint8_t product = versionhw[2]; diff --git a/client/src/cmdhftopaz.c b/client/src/cmdhftopaz.c index a59cd02be..6311b50ed 100644 --- a/client/src/cmdhftopaz.c +++ b/client/src/cmdhftopaz.c @@ -292,7 +292,7 @@ static bool topaz_byte_is_locked(uint16_t byteno) { } } -static int topaz_set_cc_dynamic(uint8_t *data) { +static int topaz_set_cc_dynamic(const uint8_t *data) { if (data[0] != 0xE1) { topaz_tag.size = TOPAZ_STATIC_MEMORY; diff --git a/client/src/util.c b/client/src/util.c index dc58eef2c..63141d01c 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -1247,7 +1247,7 @@ inline uint64_t leadingzeros64(uint64_t a) { } -int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen) { +int byte_strstr(const uint8_t *src, size_t srclen, const uint8_t *pattern, size_t plen) { size_t max = srclen - plen + 1; diff --git a/client/src/util.h b/client/src/util.h index d831a750b..c29fbd50f 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -148,7 +148,7 @@ uint64_t bitcount64(uint64_t a); uint32_t leadingzeros32(uint32_t a); uint64_t leadingzeros64(uint64_t a); -int byte_strstr(uint8_t *src, size_t srclen, uint8_t *pattern, size_t plen); +int byte_strstr(const uint8_t *src, size_t srclen, const uint8_t *pattern, size_t plen); struct smartbuf { char *ptr; From 0fbc101ac51f5d4e292a93a2d378a65f8c2c7002 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 02:12:47 +0100 Subject: [PATCH 501/759] cppcheck uninitialized vars (false positive) --- armsrc/frozen.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/armsrc/frozen.c b/armsrc/frozen.c index 963b0a52b..a77d7dd9d 100644 --- a/armsrc/frozen.c +++ b/armsrc/frozen.c @@ -1429,9 +1429,12 @@ static void json_next_cb(void *userdata, const char *name, size_t name_len, static void *json_next(const char *s, int len, void *handle, const char *path, struct json_token *key, struct json_token *val, int *i) { - struct json_token tmpval, *v = val == NULL ? &tmpval : val; - struct json_token tmpkey, *k = key == NULL ? &tmpkey : key; - int tmpidx, *pidx = i == NULL ? &tmpidx : i; + struct json_token tmpval; + struct json_token *v = val == NULL ? &tmpval : val; + struct json_token tmpkey; + struct json_token *k = key == NULL ? &tmpkey : key; + int tmpidx; + int *pidx = i == NULL ? &tmpidx : i; struct next_data data = {handle, path, (int) strlen(path), 0, k, v, pidx}; json_walk(s, len, json_next_cb, &data); return data.found ? data.handle : NULL; From 951d6cd218f26cf0c65ee9dfa2b19befd3724842 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 02:17:14 +0100 Subject: [PATCH 502/759] cppcheck uninitialized vars --- client/src/cmdlfindala.c | 2 +- tools/mf_nonce_brute/mf_nonce_brute.c | 2 ++ tools/mf_nonce_brute/mf_trace_brute.c | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/client/src/cmdlfindala.c b/client/src/cmdlfindala.c index 781db217b..fa59894e1 100644 --- a/client/src/cmdlfindala.c +++ b/client/src/cmdlfindala.c @@ -404,7 +404,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) { uint8_t data[MAX_GRAPH_TRACE_LEN] = {0}; size_t datasize = getFromGraphBuf(data); - uint8_t rawbits[4096]; + uint8_t rawbits[4096] = {0}; int rawbit = 0; int worst = 0, worstPos = 0; diff --git a/tools/mf_nonce_brute/mf_nonce_brute.c b/tools/mf_nonce_brute/mf_nonce_brute.c index 8d98e04cf..161f1c749 100644 --- a/tools/mf_nonce_brute/mf_nonce_brute.c +++ b/tools/mf_nonce_brute/mf_nonce_brute.c @@ -331,6 +331,8 @@ static bool checkValidCmd(uint32_t decrypted) { static bool checkValidCmdByte(uint8_t *cmd, uint16_t n) { bool ok = false; + if (cmd == NULL) + return false; for (int i = 0; i < 8; ++i) { if (cmd[0] == cmds[i][0]) { diff --git a/tools/mf_nonce_brute/mf_trace_brute.c b/tools/mf_nonce_brute/mf_trace_brute.c index 8bc255517..1d8a7c6fb 100644 --- a/tools/mf_nonce_brute/mf_trace_brute.c +++ b/tools/mf_nonce_brute/mf_trace_brute.c @@ -174,6 +174,8 @@ static char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const si static bool checkValidCmdByte(uint8_t *cmd, uint16_t n) { bool ok = false; + if (cmd == NULL) + return false; for (int i = 0; i < 8; ++i) { if (cmd[0] == cmds[i][0]) { From 30ae0bf521fb14d76d56b72682a926ea502d1a6c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 02:24:46 +0100 Subject: [PATCH 503/759] make style --- client/src/cmdhfmf.c | 3 +- client/src/fileutils.c | 11 +- client/src/pm3line_vocabulory.h | 20 +- doc/commands.json | 544 +++++++++++++++++++++++--------- doc/commands.md | 30 +- tools/cryptorf/sma_multi.cpp | 2 +- 6 files changed, 445 insertions(+), 165 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index dfac4dbee..11d101391 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6913,8 +6913,7 @@ static int CmdHF14AMfView(const char *Cmd) { return res; } - typedef union UDATA - { + typedef union UDATA { uint8_t *bytes; mfc_vigik_t *vigik; } UDATA; diff --git a/client/src/fileutils.c b/client/src/fileutils.c index 8c2f7a6f0..3182f47c3 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -1162,12 +1162,11 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz goto out; } - typedef union UDATA - { - void* v; - uint8_t* bytes; - mfu_dump_t* mfu; - topaz_tag_t* topaz; + typedef union UDATA { + void *v; + uint8_t *bytes; + mfu_dump_t *mfu; + topaz_tag_t *topaz; } UDATA; UDATA udata = (UDATA)data; char ctype[100] = {0}; diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 4ea275639..5a517c645 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -244,11 +244,11 @@ const static vocabulory_t vocabulory[] = { { 1, "hf gallagher diversifykey" }, { 1, "hf gallagher decode" }, { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 initialize" }, - { 0, "hf ksx6924 prec" }, { 0, "hf ksx6924 select" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 init" }, + { 0, "hf ksx6924 prec" }, { 1, "hf jooki help" }, { 0, "hf jooki clone" }, { 1, "hf jooki decode" }, @@ -347,6 +347,10 @@ const static vocabulory_t vocabulory[] = { { 0, "hf mf gen3uid" }, { 0, "hf mf gen3blk" }, { 0, "hf mf gen3freeze" }, + { 0, "hf mf ggetblk" }, + { 0, "hf mf gload" }, + { 0, "hf mf gsave" }, + { 0, "hf mf gsetblk" }, { 0, "hf mf gview" }, { 0, "hf mf ndefformat" }, { 0, "hf mf ndefread" }, @@ -376,6 +380,7 @@ const static vocabulory_t vocabulory[] = { { 1, "hf mfu view" }, { 0, "hf mfu wrbl" }, { 0, "hf mfu eload" }, + { 0, "hf mfu esave" }, { 0, "hf mfu eview" }, { 0, "hf mfu sim" }, { 0, "hf mfu setpwd" }, @@ -584,6 +589,7 @@ const static vocabulory_t vocabulory[] = { { 0, "lf idteck clone" }, { 0, "lf idteck sim" }, { 1, "lf indala help" }, + { 0, "lf indala brute" }, { 1, "lf indala demod" }, { 1, "lf indala altdemod" }, { 0, "lf indala reader" }, @@ -731,6 +737,12 @@ const static vocabulory_t vocabulory[] = { { 0, "nfc barcode read" }, { 0, "nfc barcode sim" }, { 1, "nfc barcode help" }, + { 1, "piv help" }, + { 0, "piv select" }, + { 0, "piv getdata" }, + { 0, "piv authsign" }, + { 0, "piv scan" }, + { 1, "piv list" }, { 1, "smart help" }, { 1, "smart list" }, { 0, "smart info" }, diff --git a/doc/commands.json b/doc/commands.json index e055a70b4..1c21f81ba 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -761,7 +761,7 @@ "options": [ "-h, --help This help", "-k, -K, --keep Keep field ON for next command", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)" ], "usage": "emv challenge [-hkaw]" @@ -777,7 +777,7 @@ "options": [ "-h, --help This help", "-s, -S, --select Activate field and select card", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results", "-j, -J, --jload Load transaction parameters from `emv_defparams.json` file", "-f, -F, --forceaid Force search AID. Search AID instead of execute PPSE", @@ -807,7 +807,7 @@ "-d, -D, --decision Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested", "-p, -P, --params Load parameters from `emv_defparams.json` file for CDOLdata making from CDOL and parameters", "-m, -M, --make Make CDOLdata from CDOL (tag 8C and 8D) and parameters (def: use default parameters)", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " CDOLdata/CDOL" @@ -828,7 +828,7 @@ "-k, -K, --keep Keep field ON for next command", "-p, -P, --params Load parameters from `emv_defparams.json` file for PDOLdata making from PDOL and parameters", "-m, -M, --make Make PDOLdata from PDOL (tag 9F38) and parameters (def: uses default parameters)", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " PDOLdata/PDOL" @@ -857,7 +857,7 @@ "-k, -K, --keep Keep field ON for next command", "-p, -P, --params Load parameters from `emv_defparams.json` file for DDOLdata making from DDOL and parameters", "-m, -M, --make Make DDOLdata from DDOL (tag 9F49) and parameters (def: use default parameters)", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " DDOLdata/DDOL" @@ -868,22 +868,22 @@ "command": "emv list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "emv list -f -> show frame delay times", + "emv list --frame -> show frame delay times", "emv list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "emv list [-h1fcrux] [--dict ]" + "usage": "emv list [-h1crux] [--frame] [-f ]" }, "emv pse": { "command": "emv pse", @@ -899,7 +899,7 @@ "-k, -K, --keep Keep field ON for next command", "-1, --pse PSE (1PAY.SYS.DDF01) mode", "-2, --ppse PPSE (2PAY.SYS.DDF01) mode (def)", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)" ], @@ -916,7 +916,7 @@ "options": [ "-h, --help This help", "-k, -K, --keep Keep field ON for next command", - "-a, -A, --apdu Show APDU reqests and responses", + "-a, -A, --apdu Show APDU requests and responses", "-t, -T, --tlv TLV decode results of selected applets", "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", " help` for details of a command prefs { Edit client/device preferences... } -------- ----------------------- Technology ----------------------- analyse { Analyse utils... } data { Plot window / data buffer manipulation... } emv { EMV ISO-14443 / ISO-7816... } hf { High frequency commands... } hw { Hardware commands... } lf { Low frequency commands... } nfc { NFC commands... } reveng { CRC calculations from RevEng software... } smart { Smart card ISO-7816 commands... } script { Scripting commands... } trace { Trace manipulation... } wiegand { Wiegand format manipulation... } -------- ----------------------- General ----------------------- clear Clear screen hints Turn hints on / off msleep Add a pause in milliseconds rem Add a text line in log file quit exit Exit program", + "description": "help Use ` help` for details of a command prefs { Edit client/device preferences... } -------- ----------------------- Technology ----------------------- analyse { Analyse utils... } data { Plot window / data buffer manipulation... } emv { EMV ISO-14443 / ISO-7816... } hf { High frequency commands... } hw { Hardware commands... } lf { Low frequency commands... } nfc { NFC commands... } piv { PIV commands... } reveng { CRC calculations from RevEng software... } smart { Smart card ISO-7816 commands... } script { Scripting commands... } trace { Trace manipulation... } wiegand { Wiegand format manipulation... } -------- ----------------------- General ----------------------- clear Clear screen hints Turn hints on / off msleep Add a pause in milliseconds rem Add a text line in log file quit exit Exit program", "notes": [], "offline": true, "options": [], @@ -1145,22 +1145,22 @@ "command": "hf 14a list", "description": "Alias of `trace list -t 14a` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf 14a list -f -> show frame delay times", + "hf 14a list --frame -> show frame delay times", "hf 14a list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf 14a list [-h1fcrux] [--dict ]" + "usage": "hf 14a list [-h1crux] [--frame] [-f ]" }, "hf 14a ndefformat": { "command": "hf 14a ndefformat", @@ -1259,7 +1259,7 @@ }, "hf 14a sim": { "command": "hf 14a sim", - "description": "Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID", + "description": "Simulate ISO/IEC 14443 type A tag with 4,7 or 10 byte UID Use type 7 for Mifare Ultralight EV1, Amiibo (NTAG215 pack 0x8080)", "notes": [ "hf 14a sim -t 1 --uid 11223344 -> MIFARE Classic 1k", "hf 14a sim -t 2 -> MIFARE Ultralight", @@ -1267,7 +1267,7 @@ "hf 14a sim -t 4 -> ISO/IEC 14443-4", "hf 14a sim -t 5 -> MIFARE Tnp3xxx", "hf 14a sim -t 6 -> MIFARE Mini", - "hf 14a sim -t 7 -> Amiibo (NTAG 215), pack 0x8080", + "hf 14a sim -t 7 -> MFU EV1 / NTAG 215 Amiibo", "hf 14a sim -t 8 -> MIFARE Classic 4k", "hf 14a sim -t 9 -> FM11RF005SH Shanghai Metro", "hf 14a sim -t 10 -> ST25TA IKEA Rothult" @@ -1363,22 +1363,22 @@ "command": "hf 14b list", "description": "Alias of `trace list -t 14b` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf 14b list -f -> show frame delay times", + "hf 14b list --frame -> show frame delay times", "hf 14b list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf 14b list [-h1fcrux] [--dict ]" + "usage": "hf 14b list [-h1crux] [--frame] [-f ]" }, "hf 14b ndefread": { "command": "hf 14b ndefread", @@ -1637,22 +1637,22 @@ "command": "hf 15 list", "description": "Alias of `trace list -t 15` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf 15 list -f -> show frame delay times", + "hf 15 list --frame -> show frame delay times", "hf 15 list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf 15 list [-h1fcrux] [--dict ]" + "usage": "hf 15 list [-h1crux] [--frame] [-f ]" }, "hf 15 raw": { "command": "hf 15 raw", @@ -2189,7 +2189,9 @@ "command": "hf emrtd dump", "description": "Dump all files on an eMRTD", "notes": [ - "hf emrtd dump" + "hf emrtd dump", + "hf emrtd dump --dir ../dump", + "hf emrtd dump -n 123456789 -d 19890101 -e 20250401" ], "offline": false, "options": [ @@ -2198,9 +2200,9 @@ "-d, --dateofbirth date of birth in YYMMDD format", "-e, --expiry expiry in YYMMDD format", "-m, --mrz <[0-9A-Z<]> 2nd line of MRZ, 44 chars", - "--path save dump to the given dirpath" + "--dir save dump to the given dirpath" ], - "usage": "hf emrtd dump [-h] [-n ] [-d ] [-e ] [-m <[0-9A-Z<]>] [--path ]" + "usage": "hf emrtd dump [-h] [-n ] [-d ] [-e ] [-m <[0-9A-Z<]>] [--dir ]" }, "hf emrtd help": { "command": "hf emrtd help", @@ -2214,7 +2216,10 @@ "command": "hf emrtd info", "description": "Display info about an eMRTD", "notes": [ - "hf emrtd info" + "hf emrtd info", + "hf emrtd info --dir ../dumps", + "hf emrtd info -n 123456789 -d 19890101 -e 20250401", + "hf emrtd info -n 123456789 -d 19890101 -e 20250401 -i" ], "offline": true, "options": [ @@ -2223,31 +2228,31 @@ "-d, --dateofbirth date of birth in YYMMDD format", "-e, --expiry expiry in YYMMDD format", "-m, --mrz <[0-9A-Z<]> 2nd line of MRZ, 44 chars (passports only)", - "--path display info from offline dump stored in dirpath", + "--dir display info from offline dump stored in dirpath", "-i, --images show images" ], - "usage": "hf emrtd info [-hi] [-n ] [-d ] [-e ] [-m <[0-9A-Z<]>] [--path ]" + "usage": "hf emrtd info [-hi] [-n ] [-d ] [-e ] [-m <[0-9A-Z<]>] [--dir ]" }, "hf emrtd list": { "command": "hf emrtd list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf emrtd list -f -> show frame delay times", + "hf emrtd list --frame -> show frame delay times", "hf emrtd list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf emrtd list [-h1fcrux] [--dict ]" + "usage": "hf emrtd list [-h1crux] [--frame] [-f ]" }, "hf epa cnonces": { "command": "hf epa cnonces", @@ -2367,22 +2372,22 @@ "command": "hf felica list", "description": "Alias of `trace list -t felica` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf felica list -f -> show frame delay times", + "hf felica list --frame -> show frame delay times", "hf felica list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf felica list [-h1fcrux] [--dict ]" + "usage": "hf felica list [-h1crux] [--frame] [-f ]" }, "hf felica litedump": { "command": "hf felica litedump", @@ -2575,7 +2580,7 @@ "offline": false, "options": [ "-h, --help This help", - "-a, --apdu Show APDU reqests and responses", + "-a, --apdu Show APDU requests and responses", "-v, --verbose Verbose mode. vv - show full certificates data", "-c, --cbor Show CBOR decoded data", "-l, --list Add CredentialId from json to allowList", @@ -2596,7 +2601,7 @@ "offline": false, "options": [ "-h, --help This help", - "-a, --apdu Show APDU reqests and responses", + "-a, --apdu Show APDU requests and responses", "-v, --verbose Verbose mode", "default mode: dont-enforce-user-presence-and-sign", "-u, --user mode: enforce-user-presence-and-sign", @@ -2635,22 +2640,22 @@ "command": "hf fido list", "description": "Alias of `trace list -t 14a` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf fido list -f -> show frame delay times", + "hf fido list --frame -> show frame delay times", "hf fido list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf fido list [-h1fcrux] [--dict ]" + "usage": "hf fido list [-h1crux] [--frame] [-f ]" }, "hf fido make": { "command": "hf fido make", @@ -2662,7 +2667,7 @@ "offline": false, "options": [ "-h, --help This help", - "-a, --apdu Show APDU reqests and responses", + "-a, --apdu Show APDU requests and responses", "-v, --verbose Verbose mode. vv - show full certificates data", "-t, --tlv Show DER certificate contents in TLV representation", "-c, --cbor Show CBOR decoded data", @@ -2916,9 +2921,10 @@ "-f, --file Dictionary file with default iclass keys", "--credit key is assumed to be the credit key", "--elite elite computations applied to key", - "--raw no computations applied to key (raw)" + "--raw no computations applied to key (raw)", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass chk [-h] -f [--credit] [--elite] [--raw]" + "usage": "hf iclass chk [-h] -f [--credit] [--elite] [--raw] [--shallow]" }, "hf iclass configcard": { "command": "hf iclass configcard", @@ -2969,9 +2975,11 @@ "--elite elite computations applied to key", "--raw raw, the key is interpreted as raw block 3/4", "--nr replay of NR/MAC", - "-z, --dense dense dump output style" + "-z, --dense dense dump output style", + "--force force unsecure card read", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass dump [-hz] [-f ] [-k ] [--ki ] [--credit ] [--ci ] [--elite] [--raw] [--nr]" + "usage": "hf iclass dump [-hz] [-f ] [-k ] [--ki ] [--credit ] [--ci ] [--elite] [--raw] [--nr] [--force] [--shallow]" }, "hf iclass eload": { "command": "hf iclass eload", @@ -2990,7 +2998,7 @@ }, "hf iclass encode": { "command": "hf iclass encode", - "description": "Encode binary wiegand to block 7 Use either --bin or --wiegand/--fc/--cn", + "description": "Encode binary wiegand to block 7,8,9 Use either --bin or --wiegand/--fc/--cn", "notes": [ "hf iclass encode --bin 10001111100000001010100011 --ki 0 -> FC 31 CN 337", "hf iclass encode --fc 31 --cn 337 --ki 0 -> FC 31 CN 337", @@ -3007,9 +3015,10 @@ "--enckey 3DES transport key, 16 hex bytes", "--fc facility code", "--cn card number", - "-w, --wiegand see `wiegand list` for available formats" + "-w, --wiegand see `wiegand list` for available formats", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass encode [-h] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ]" + "usage": "hf iclass encode [-h] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ] [--shallow]" }, "hf iclass encrypt": { "command": "hf iclass encrypt", @@ -3076,30 +3085,31 @@ ], "offline": true, "options": [ - "-h, --help This help" + "-h, --help This help", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass info [-h]" + "usage": "hf iclass info [-h] [--shallow]" }, "hf iclass list": { "command": "hf iclass list", "description": "Alias of `trace list -t iclass` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf iclass list -f -> show frame delay times", + "hf iclass list --frame -> show frame delay times", "hf iclass list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf iclass list [-h1fcrux] [--dict ]" + "usage": "hf iclass list [-h1crux] [--frame] [-f ]" }, "hf iclass loclass": { "command": "hf iclass loclass", @@ -3190,9 +3200,10 @@ "--elite elite computations applied to key", "--raw no computations applied to key", "--nr replay of NR/MAC", - "-v, --verbose verbose output" + "-v, --verbose verbose output", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass rdbl [-hv] [-k ] [--ki ] -b [--credit] [--elite] [--raw] [--nr]" + "usage": "hf iclass rdbl [-hv] [-k ] [--ki ] -b [--credit] [--elite] [--raw] [--nr] [--shallow]" }, "hf iclass reader": { "command": "hf iclass reader", @@ -3203,9 +3214,10 @@ "offline": false, "options": [ "-h, --help This help", - "-@ optional - continuous reader mode" + "-@ optional - continuous reader mode", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass reader [-h@]" + "usage": "hf iclass reader [-h@] [--shallow]" }, "hf iclass restore": { "command": "hf iclass restore", @@ -3226,9 +3238,10 @@ "--credit key is assumed to be the credit key", "--elite elite computations applied to key", "--raw no computations applied to key", - "-v, --verbose verbose output" + "-v, --verbose verbose output", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass restore [-hv] -f [-k ] [--ki ] --first --last [--credit] [--elite] [--raw]" + "usage": "hf iclass restore [-hv] -f [-k ] [--ki ] --first --last [--credit] [--elite] [--raw] [--shallow]" }, "hf iclass sim": { "command": "hf iclass sim", @@ -3300,9 +3313,10 @@ "--elite elite computations applied to key", "--raw no computations applied to key", "--nr replay of NR/MAC", - "-v, --verbose verbose output" + "-v, --verbose verbose output", + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass wrbl [-hv] [-k ] [--ki ] -b -d [-m ] [--credit] [--elite] [--raw] [--nr]" + "usage": "hf iclass wrbl [-hv] [-k ] [--ki ] -b -d [-m ] [--credit] [--elite] [--raw] [--nr] [--shallow]" }, "hf jooki clone": { "command": "hf jooki clone", @@ -3400,7 +3414,7 @@ "options": [ "-h, --help This help", "-k, --keep keep field ON for next command", - "-a, --apdu show APDU reqests and responses" + "-a, --apdu Show APDU requests and responses" ], "usage": "hf ksx6924 balance [-hka]" }, @@ -3422,23 +3436,23 @@ "options": [ "-h, --help This help", "-k, --keep keep field ON for next command", - "-a, --apdu show APDU reqests and responses" + "-a, --apdu Show APDU requests and responses" ], "usage": "hf ksx6924 info [-hka]" }, - "hf ksx6924 initialize": { - "command": "hf ksx6924 initialize", - "description": "Perform transaction initialization (mpda)", + "hf ksx6924 init": { + "command": "hf ksx6924 init", + "description": "Perform transaction initialization with Mpda (Money of Purchase Transaction)", "notes": [ - "hf ksx6924 initialize 000003e8 -> mpda" + "hf ksx6924 init 000003e8 -> Mpda" ], "offline": false, "options": [ "-h, --help This help", "-k, --keep keep field ON for next command", - "-a, --apdu show APDU reqests and responses" + "-a, --apdu Show APDU requests and responses" ], - "usage": "hf ksx6924 initialize [-hka] " + "usage": "hf ksx6924 init [-hka] " }, "hf ksx6924 prec": { "command": "hf ksx6924 prec", @@ -3450,7 +3464,7 @@ "options": [ "-h, --help This help", "-k, --keep keep field ON for next command", - "-a, --apdu show APDU reqests and responses" + "-a, --apdu Show APDU requests and responses" ], "usage": "hf ksx6924 prec [-hka] " }, @@ -3463,7 +3477,7 @@ "offline": false, "options": [ "-h, --help This help", - "-a, --apdu show APDU reqests and responses" + "-a, --apdu Show APDU requests and responses" ], "usage": "hf ksx6924 select [-ha]" }, @@ -3573,22 +3587,22 @@ "command": "hf legic list", "description": "Alias of `trace list -t legic` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf legic list -f -> show frame delay times", + "hf legic list --frame -> show frame delay times", "hf legic list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf legic list [-h1fcrux] [--dict ]" + "usage": "hf legic list [-h1crux] [--frame] [-f ]" }, "hf legic rdbl": { "command": "hf legic rdbl", @@ -3695,22 +3709,22 @@ "command": "hf list", "description": "Alias of `trace list -t raw` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf list -f -> show frame delay times", + "hf list --frame -> show frame delay times", "hf list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf list [-h1fcrux] [--dict ]" + "usage": "hf list [-h1crux] [--frame] [-f ]" }, "hf lto dump": { "command": "hf lto dump", @@ -3749,22 +3763,22 @@ "command": "hf lto list", "description": "Alias of `trace list -t lto` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf lto list -f -> show frame delay times", + "hf lto list --frame -> show frame delay times", "hf lto list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf lto list [-h1fcrux] [--dict ]" + "usage": "hf lto list [-h1crux] [--frame] [-f ]" }, "hf lto rdbl": { "command": "hf lto rdbl", @@ -3969,7 +3983,7 @@ "--1k MIFARE Classic 1k / S50 (def)", "--2k MIFARE Classic/Plus 2k", "--4k MIFARE Classic 4k / S70", - "--emu from emulator memory" + "--emu to emulator memory" ], "usage": "hf mf csave [-h] [-f ] [--mini] [--1k] [--2k] [--4k] [--emu]" }, @@ -4303,6 +4317,85 @@ ], "usage": "hf mf gen3uid [-h] [-u ]" }, + "hf mf ggetblk": { + "command": "hf mf ggetblk", + "description": "Get block data from magic gen4 GTU card.", + "notes": [ + "hf mf ggetblk --blk 0 -> get block 0 (manufacturer)", + "hf mf ggetblk --blk 3 -v -> get block 3, decode sector trailer" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-b, --blk block number", + "-v, --verbose verbose output", + "-p, --pwd password 4bytes" + ], + "usage": "hf mf ggetblk [-hv] -b [-p ]" + }, + "hf mf gload": { + "command": "hf mf gload", + "description": "Load magic gen4 gtu card with data from (bin/eml/json) dump file or from emulator memory.", + "notes": [ + "hf mf gload --emu", + "hf mf gload -f hf-mf-01020304.eml", + "hf mf gload -p AABBCCDD --4k -v -f hf-mf-01020304-dump.bin", + "", + "Card must be configured beforehand with `script run hf_mf_ultimatecard`.", + "Blocks are 16 bytes long." + ], + "offline": false, + "options": [ + "-h, --help This help", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70", + "-p, --pwd password 4bytes", + "-v, --verbose verbose output", + "-f, --file filename of dump", + "--emu from emulator memory", + "--start index of block to start writing (default 0)", + "--end index of block to end writing (default last block)" + ], + "usage": "hf mf gload [-hv] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu] [--start ] [--end ]" + }, + "hf mf gsave": { + "command": "hf mf gsave", + "description": "Save `magic gen4 gtu` card memory into three files (BIN/EML/JSON)or into emulator memory", + "notes": [ + "hf mf gsave", + "hf mf gsave --4k", + "hf mf gsave -p DEADBEEF -f hf-mf-01020304.json" + ], + "offline": false, + "options": [ + "-h, --help This help", + "--mini MIFARE Classic Mini / S20", + "--1k MIFARE Classic 1k / S50 (def)", + "--2k MIFARE Classic/Plus 2k", + "--4k MIFARE Classic 4k / S70", + "-p, --pwd password 4bytes", + "-f, --file filename of dump", + "--emu to emulator memory" + ], + "usage": "hf mf gsave [-h] [--mini] [--1k] [--2k] [--4k] [-p ] [-f ] [--emu]" + }, + "hf mf gsetblk": { + "command": "hf mf gsetblk", + "description": "Set block data on a magic gen4 GTU card", + "notes": [ + "hf mf gsetblk --blk 1 -d 000102030405060708090a0b0c0d0e0f" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-b, --blk block number", + "-d, --data bytes to write, 16 hex bytes", + "-p, --pwd password 4bytes" + ], + "usage": "hf mf gsetblk [-h] -b [-d ] [-p ]" + }, "hf mf gview": { "command": "hf mf gview", "description": "View `magic gen4 gtu` card memory", @@ -4324,8 +4417,9 @@ }, "hf mf hardnested": { "command": "hf mf hardnested", - "description": "Nested attack for hardened MIFARE Classic cards. `--i` set type of SIMD instructions. Without this flag programs autodetect it. or hf mf hardnested -r --tk [known target key] Add the known target key to check if it is present in the remaining key space hf mf hardnested --blk 0 -a -k A0A1A2A3A4A5 --tblk 4 --ta --tk FFFFFFFFFFFF", + "description": "Nested attack for hardened MIFARE Classic cards. if card is EV1, command can detect and use known key see example below `--i` set type of SIMD instructions. Without this flag programs autodetect it. or hf mf hardnested -r --tk [known target key] Add the known target key to check if it is present in the remaining key space hf mf hardnested --blk 0 -a -k A0A1A2A3A4A5 --tblk 4 --ta --tk FFFFFFFFFFFF", "notes": [ + "hf mf hardnested --tblk 4 --ta -> works for MFC EV1", "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta", "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -w", "hf mf hardnested --blk 0 -a -k FFFFFFFFFFFF --tblk 4 --ta -f nonces.bin -w -s", @@ -4372,22 +4466,22 @@ "command": "hf mf list", "description": "Alias of `trace list -t mf` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf mf list -f -> show frame delay times", + "hf mf list --frame -> show frame delay times", "hf mf list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf mf list [-h1fcrux] [--dict ]" + "usage": "hf mf list [-h1crux] [--frame] [-f ]" }, "hf mf mad": { "command": "hf mf mad", @@ -4710,7 +4804,7 @@ }, "hf mf wrbl": { "command": "hf mf wrbl", - "description": "Write MIFARE Classic block with 16 hex bytes of data Sector 0 / Block 0 - Manufacturer block When writing to block 0 you must use a VALID block 0 data (UID, BCC, SAK, ATQA) Writing an invalid block 0 means rendering your Magic GEN2 card undetectable. Look in the magic_cards_notes.md file for help to resolve it.", + "description": "Write MIFARE Classic block with 16 hex bytes of data Sector 0 / Block 0 - Manufacturer block When writing to block 0 you must use a VALID block 0 data (UID, BCC, SAK, ATQA) Writing an invalid block 0 means rendering your Magic GEN2 card undetectable. Look in the magic_cards_notes.md file for help to resolve it. `--force` param is used to override warnings like bad ACL and BLOCK 0 writes. if not specified, it will exit if detected", "notes": [ "hf mf wrbl --blk 1 -k FFFFFFFFFFFF -d 000102030405060708090a0b0c0d0e0f" ], @@ -4720,7 +4814,7 @@ "--blk block number", "-a input key type is key A (def)", "-b input key type is key B", - "--force enforce block0 writes", + "--force override warnings", "-k, --key key, 6 hex bytes", "-d, --data bytes to write, 16 hex bytes" ], @@ -5551,22 +5645,22 @@ "command": "hf mfdes list", "description": "Alias of `trace list -t des` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf mfdes list -f -> show frame delay times", + "hf mfdes list --frame -> show frame delay times", "hf mfdes list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf mfdes list [-h1fcrux] [--dict ]" + "usage": "hf mfdes list [-h1crux] [--frame] [-f ]" }, "hf mfdes lsapp": { "command": "hf mfdes lsapp", @@ -6113,17 +6207,35 @@ ], "usage": "hf mfu eload [-h] -f [-q ]" }, - "hf mfu eview": { - "command": "hf mfu eview", - "description": "It displays emulator memory", + "hf mfu esave": { + "command": "hf mfu esave", + "description": "Saves emulator memory to a MIFARE Ultralight/NTAG dump file (bin/eml/json) By default number of pages saved depends on defined tag type. You can override this with option --end.", "notes": [ - "hf mfu eview" + "hf mfu esave", + "hf mfu esave --end 255 -> saves whole memory", + "hf mfu esave -f hf-mfu-04010203040506-dump.json" ], "offline": false, "options": [ - "-h, --help This help" + "-h, --help This help", + "-e, --end index of last block", + "-f, --file filename of dump" ], - "usage": "hf mfu eview [-h]" + "usage": "hf mfu esave [-h] [-e ] [-f ]" + }, + "hf mfu eview": { + "command": "hf mfu eview", + "description": "Displays emulator memory By default number of pages shown depends on defined tag type. You can override this with option --end.", + "notes": [ + "hf mfu eview", + "hf mfu eview --end 255 -> dumps whole memory" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-e, --end index of last block" + ], + "usage": "hf mfu eview [-h] [-e ]" }, "hf mfu help": { "command": "hf mfu help", @@ -6291,8 +6403,8 @@ "description": "Simulate MIFARE Ultralight family type based upon ISO/IEC 14443 type A tag with 4,7 or 10 byte UID from emulator memory. See `hf mfu eload` first. The UID from emulator memory will be used if not specified. See `hf 14a sim -h` to see available types. You want 2 or 7 usually.", "notes": [ "hf mfu sim -t 2 --uid 11223344556677 -> MIFARE Ultralight", - "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> Amiibo (NTAG 215), pack 0x8080", - "hf mfu sim -t 7 -> Amiibo (NTAG 215), pack 0x8080" + "hf mfu sim -t 7 --uid 11223344556677 -n 5 -> MFU EV1 / NTAG 215 Amiibo", + "hf mfu sim -t 7 -> MFU EV1 / NTAG 215 Amiibo" ], "offline": false, "options": [ @@ -6433,22 +6545,22 @@ "command": "hf seos list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf seos list -f -> show frame delay times", + "hf seos list --frame -> show frame delay times", "hf seos list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf seos list [-h1fcrux] [--dict ]" + "usage": "hf seos list [-h1crux] [--frame] [-f ]" }, "hf sniff": { "command": "hf sniff", @@ -6491,22 +6603,22 @@ "command": "hf st25ta list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf st25ta list -f -> show frame delay times", + "hf st25ta list --frame -> show frame delay times", "hf st25ta list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf st25ta list [-h1fcrux] [--dict ]" + "usage": "hf st25ta list [-h1crux] [--frame] [-f ]" }, "hf st25ta ndefread": { "command": "hf st25ta ndefread", @@ -6641,22 +6753,22 @@ "command": "hf thinfilm list", "description": "Alias of `trace list -t thinfilm` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf thinfilm list -f -> show frame delay times", + "hf thinfilm list --frame -> show frame delay times", "hf thinfilm list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf thinfilm list [-h1fcrux] [--dict ]" + "usage": "hf thinfilm list [-h1crux] [--frame] [-f ]" }, "hf thinfilm sim": { "command": "hf thinfilm sim", @@ -6712,22 +6824,22 @@ "command": "hf topaz list", "description": "Alias of `trace list -t topaz` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "hf topaz list -f -> show frame delay times", + "hf topaz list --frame -> show frame delay times", "hf topaz list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "hf topaz list [-h1fcrux] [--dict ]" + "usage": "hf topaz list [-h1crux] [--frame] [-f ]" }, "hf topaz raw": { "command": "hf topaz raw", @@ -8455,22 +8567,22 @@ "command": "lf hitag list", "description": "Alias of `trace list -t hitag2` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "lf hitag list -f -> show frame delay times", + "lf hitag list --frame -> show frame delay times", "lf hitag list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "lf hitag list [-h1fcrux] [--dict ]" + "usage": "lf hitag list [-h1crux] [--frame] [-f ]" }, "lf hitag reader": { "command": "lf hitag reader", @@ -8627,6 +8739,28 @@ ], "usage": "lf indala altdemod [-hl]" }, + "lf indala brute": { + "command": "lf indala brute", + "description": "Enables bruteforce of INDALA readers with specified facility code. This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step if cardnumber is not given, it starts with 1 and goes up to 65535", + "notes": [ + "lf indala brute --fc 224", + "lf indala brute --fc 21 -d 2000", + "lf indala brute -v --fc 21 --cn 200 -d 2000", + "lf indala brute -v --fc 21 --cn 200 -d 2000 --up" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-v, --verbose verbose output", + "--fc facility code", + "--cn card number to start with", + "-d, --delay delay betweens attempts in ms. Default 1000ms", + "--up direction to increment card number. (default is both directions)", + "--down direction to decrement card number. (default is both directions)", + "--4041x specify Indala 4041X format" + ], + "usage": "lf indala brute [-hv] [--fc ] [--cn ] [-d ] [--up] [--down] [--4041x]" + }, "lf indala clone": { "command": "lf indala clone", "description": "clone Indala UID to T55x7 or Q5/T5555 tag using different known formats", @@ -8682,6 +8816,8 @@ "description": "Enables simulation of Indala card with specified facility code and card number. Simulation runs until the button is pressed or another USB command is issued.", "notes": [ "lf indala sim --heden 888", + "lf indala sim --fc 123 --cn 1337", + "lf indala sim --fc 123 --cn 1337 --4041x", "lf indala sim --raw a0000000a0002021", "lf indala sim --raw 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5" ], @@ -8689,9 +8825,12 @@ "options": [ "-h, --help This help", "-r, --raw raw bytes", - "--heden Cardnumber for Heden 2L format" + "--heden Cardnumber for Heden 2L format", + "--fc Facility code (26 bit H10301 format)", + "--cn Card number (26 bit H10301 format)", + "--4041x Optional - specify Indala 4041X format, must use with fc and cn" ], - "usage": "lf indala sim [-h] [-r ] [--heden ]" + "usage": "lf indala sim [-h] [-r ] [--heden ] [--fc ] [--cn ] [--4041x]" }, "lf io clone": { "command": "lf io clone", @@ -9244,6 +9383,7 @@ "command": "lf paradox clone", "description": "clone a paradox tag to a T55x7, Q5/T5555 or EM4305/4469 tag.", "notes": [ + "lf paradox clone --fc 96 --cn 40426 -> encode for T55x7 tag with fc and cn", "lf paradox clone --raw 0f55555695596a6a9999a59a -> encode for T55x7 tag", "lf paradox clone --raw 0f55555695596a6a9999a59a --q5 -> encode for Q5/T5555 tag", "lf paradox clone --raw 0f55555695596a6a9999a59a --em -> encode for EM4305/4469" @@ -9252,10 +9392,12 @@ "options": [ "-h, --help This help", "-r, --raw raw hex data. 12 bytes max", + "--fc facility code", + "--cn card number", "--q5 optional - specify writing to Q5/T5555 tag", "--em optional - specify writing to EM4305/4469 tag" ], - "usage": "lf paradox clone [-h] [-r ] [--q5] [--em]" + "usage": "lf paradox clone [-h] [-r ] [--fc ] [--cn ] [--q5] [--em]" }, "lf paradox demod": { "command": "lf paradox demod", @@ -10818,6 +10960,114 @@ ], "usage": "hf 14b ndefread [-hv] [-f ]" }, + "piv authsign": { + "command": "piv authsign", + "description": "Send a nonce and ask the PIV card to sign it", + "notes": [ + "piv sign -sk -> select card, select applet, sign a NULL nonce" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-s, -S, --select Activate field and select applet", + "-k, -K, --keep Keep field for next command", + "-a, -A, --apdu Show APDU requests and responses", + "-t, -T, --tlv TLV decode results", + "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", + "--aid Applet ID to select. By default A0000003080000100 will be used", + "--nonce Nonce to sign.", + "--slot Slot number. Default will be 0x9E (card auth cert).", + "--alg Algorithm to use to sign. Example values: 06=RSA-1024, 07=RSA-2048, 11=ECC-P256 (default), 14=ECC-P384" + ], + "usage": "piv sign [-hskatw] [--aid ] --nonce [--slot ] [--alg ]" + }, + "piv getdata": { + "command": "piv getdata", + "description": "Get a data container of a given tag", + "notes": [ + "piv getdata -s 5fc102 -> select card, select applet, get card holder unique identifer", + "piv getdata -st 5fc102 -> select card, select applet, get card holder unique identifer, show result in TLV" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-s, -S, --select Activate field and select applet", + "-k, -K, --keep Keep field for next command", + "-a, -A, --apdu Show APDU requests and responses", + "-t, -T, --tlv TLV decode results", + "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", + "--aid Applet ID to select. By default A0000003080000100 will be used", + " Tag ID to read, between 1 and 3 bytes." + ], + "usage": "piv getdata [-hskatw] [--aid ] " + }, + "piv help": { + "command": "piv help", + "description": "help This help list List ISO7816 history", + "notes": [], + "offline": true, + "options": [], + "usage": "" + }, + "piv list": { + "command": "piv list", + "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", + "notes": [ + "piv list --frame -> show frame delay times", + "piv list -1 -> use trace buffer" + ], + "offline": true, + "options": [ + "-h, --help This help", + "-1, --buffer use data from trace buffer", + "--frame show frame delay times", + "-c mark CRC bytes", + "-r show relative times (gap and duration)", + "-u display times in microseconds instead of clock cycles", + "-x show hexdump to convert to pcap(ng)", + "or to import into Wireshark using encapsulation type \"ISO 14443\"", + "-f, --file filename of dictionary" + ], + "usage": "piv list [-h1crux] [--frame] [-f ]" + }, + "piv scan": { + "command": "piv scan", + "description": "Scan a PIV card for known containers", + "notes": [ + "piv scan -s -> select card, select applet and run scan", + "piv scan -st --aid a00000030800001000 -> select card, select applet a00000030800001000, show result of the scan in TLV" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-s, -S, --select Activate field and select applet", + "-k, -K, --keep Keep field for next command", + "-a, -A, --apdu Show APDU requests and responses", + "-t, -T, --tlv TLV decode results", + "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", + "--aid Applet ID to select. By default A0000003080000100 will be used" + ], + "usage": "piv scan [-hskatw] [--aid ]" + }, + "piv select": { + "command": "piv select", + "description": "Executes select applet command", + "notes": [ + "piv select -s -> select card, select applet", + "piv select -st --aid a00000030800001000 -> select card, select applet a00000030800001000, show result in TLV" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-s, -S, --select Activate field and select applet", + "-k, -K, --keep Keep field for next command", + "-a, -A, --apdu Show APDU requests and responses", + "-t, -T, --tlv TLV decode results", + "-w, -W, --wired Send data via contact (iso7816) interface. (def: Contactless interface)", + "--aid Applet ID to select. By default A0000003080000100 will be used" + ], + "usage": "piv select [-hskatw] [--aid ]" + }, "prefs get barmode": { "command": "prefs get barmode", "description": "Get preference of HF/LF tune command styled output in the client", @@ -11173,22 +11423,22 @@ "command": "smart list", "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", "notes": [ - "smart list -f -> show frame delay times", + "smart list --frame -> show frame delay times", "smart list -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "smart list [-h1fcrux] [--dict ]" + "usage": "smart list [-h1crux] [--frame] [-f ]" }, "smart raw": { "command": "smart raw", @@ -11295,24 +11545,24 @@ "trace list -t thinfilm -> interpret as Thinfilm", "trace list -t topaz -> interpret as Topaz", "", - "trace list -t mf --dict -> use dictionary keys file", - "trace list -t 14a -f -> show frame delay times", + "trace list -t mf -f mfc_default_keys.dic -> use default dictionary file", + "trace list -t 14a --frame -> show frame delay times", "trace list -t 14a -1 -> use trace buffer" ], "offline": true, "options": [ "-h, --help This help", "-1, --buffer use data from trace buffer", - "-f show frame delay times", + "--frame show frame delay times", "-c mark CRC bytes", "-r show relative times (gap and duration)", "-u display times in microseconds instead of clock cycles", "-x show hexdump to convert to pcap(ng)", "or to import into Wireshark using encapsulation type \"ISO 14443\"", "-t, --type protocol to annotate the trace", - "--dict use dictionary keys file" + "-f, --file filename of dictionary" ], - "usage": "trace list [-h1fcrux] [-t ] [--dict ]" + "usage": "trace list [-h1crux] [--frame] [-t ] [-f ]" }, "trace load": { "command": "trace load", @@ -11510,8 +11760,8 @@ } }, "metadata": { - "commands_extracted": 727, + "commands_extracted": 739, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-01-14T21:23:30" + "extracted_on": "2023-01-15T01:24:39" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 2133d960b..1c6110cea 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -367,11 +367,11 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`hf ksx6924 help `|Y |`This help` -|`hf ksx6924 balance `|N |`Get current purse balance` -|`hf ksx6924 info `|N |`Get info about a KS X 6924 (T-Money, Snapper+) transit card` -|`hf ksx6924 initialize `|N |`Perform transaction initialization (Mpda)` -|`hf ksx6924 prec `|N |`Send proprietary get record command (CLA=90, INS=4C)` |`hf ksx6924 select `|N |`Select application, and leave field up` +|`hf ksx6924 info `|N |`Get info about a KS X 6924 (T-Money, Snapper+) transit card` +|`hf ksx6924 balance `|N |`Get current purse balance` +|`hf ksx6924 init `|N |`Perform transaction initialization with Mpda` +|`hf ksx6924 prec `|N |`Send proprietary get record command (CLA=90, INS=4C)` ### hf jooki @@ -510,6 +510,10 @@ Check column "offline" for their availability. |`hf mf gen3uid `|N |`Set UID without changing manufacturer block` |`hf mf gen3blk `|N |`Overwrite manufacturer block` |`hf mf gen3freeze `|N |`Perma lock UID changes. irreversible` +|`hf mf ggetblk `|N |`Read block from card` +|`hf mf gload `|N |`Load dump to card` +|`hf mf gsave `|N |`Save dump from card into file or emulator` +|`hf mf gsetblk `|N |`Write block to card` |`hf mf gview `|N |`View card` |`hf mf ndefformat `|N |`Format MIFARE Classic Tag as NFC Tag` |`hf mf ndefread `|N |`Read and print NDEF records from card` @@ -554,7 +558,8 @@ Check column "offline" for their availability. |`hf mfu restore `|N |`Restore a dump onto a MFU MAGIC tag` |`hf mfu view `|Y |`Display content from tag dump file` |`hf mfu wrbl `|N |`Write block` -|`hf mfu eload `|N |`Load Ultralight .eml dump file into emulator memory` +|`hf mfu eload `|N |`Load Ultralight dump file into emulator memory` +|`hf mfu esave `|N |`Save Ultralight dump file from emulator memory` |`hf mfu eview `|N |`View emulator memory` |`hf mfu sim `|N |`Simulate MIFARE Ultralight from emulator memory` |`hf mfu setpwd `|N |`Set 3DES key - Ultralight-C` @@ -971,6 +976,7 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`lf indala help `|Y |`This help` +|`lf indala brute `|N |`Demodulate an Indala tag (PSK1) from the GraphBuffer` |`lf indala demod `|Y |`Demodulate an Indala tag (PSK1) from the GraphBuffer` |`lf indala altdemod `|Y |`Alternative method to demodulate samples for Indala 64 bit UID (option '224' for 224 bit)` |`lf indala reader `|N |`Read an Indala tag from the antenna` @@ -1328,6 +1334,20 @@ Check column "offline" for their availability. |`nfc barcode help `|Y |`This help` +### piv + + { PIV commands... } + +|command |offline |description +|------- |------- |----------- +|`piv help `|Y |`This help` +|`piv select `|N |`Select the PIV applet` +|`piv getdata `|N |`Gets a container on a PIV card` +|`piv authsign `|N |`Authenticate with the card` +|`piv scan `|N |`Scan PIV card for known containers` +|`piv list `|Y |`List ISO7816 history` + + ### reveng { CRC calculations from RevEng software... } diff --git a/tools/cryptorf/sma_multi.cpp b/tools/cryptorf/sma_multi.cpp index c4e61e37e..50b962248 100644 --- a/tools/cryptorf/sma_multi.cpp +++ b/tools/cryptorf/sma_multi.cpp @@ -165,7 +165,7 @@ void print_cs(const char *text, pcs s) { } static inline uint8_t mod(uint8_t a, uint8_t m) { - if (m==0) { + if (m == 0) { return 0; // Actually, divide by zero error } // Just return the input when this is less or equal than the modular value From ad87e2051dba66ff2df7d20bac86cb845dfb0e22 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 02:33:56 +0100 Subject: [PATCH 504/759] build_all_firmwares.sh able to build HF_14ASNIFF HF_15SNIFF without flash --- armsrc/Standalone/Makefile.hal | 2 +- tools/build_all_firmwares.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index afd144e5d..5d571fa74 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -125,7 +125,7 @@ STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4 STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI STANDALONE_MODES_REQ_BT := HF_REBLAY STANDALONE_MODES_REQ_SMARTCARD := -STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_MFCSIM HF_LEGICSIM +STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),) STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE) ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),) diff --git a/tools/build_all_firmwares.sh b/tools/build_all_firmwares.sh index a0ef2e1dd..c6bb8969d 100755 --- a/tools/build_all_firmwares.sh +++ b/tools/build_all_firmwares.sh @@ -34,7 +34,7 @@ STANDALONE_MODES=(LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM410 STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI) STANDALONE_MODES_REQ_BT=(HF_REBLAY) STANDALONE_MODES_REQ_SMARTCARD=() -STANDALONE_MODES_REQ_FLASH=(LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_14ASNIFF HF_15SNIFF HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM) +STANDALONE_MODES_REQ_FLASH=(LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM) # PM3GENERIC 256kb, no flash, need to skip some parts to reduce size From c2546d35f81ad8096616fc2fc200cd5930397fa8 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 02:40:58 +0100 Subject: [PATCH 505/759] experimental_lib/CMakeLists missing files --- client/CMakeLists.txt | 2 +- client/experimental_lib/CMakeLists.txt | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 1622190f9..5519b2e77 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -293,9 +293,9 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdhfseos.c ${PM3_ROOT}/client/src/cmdhfst.c ${PM3_ROOT}/client/src/cmdhfst25ta.c + ${PM3_ROOT}/client/src/cmdhftexkom.c ${PM3_ROOT}/client/src/cmdhfthinfilm.c ${PM3_ROOT}/client/src/cmdhftopaz.c - ${PM3_ROOT}/client/src/cmdhftexkom.c ${PM3_ROOT}/client/src/cmdhfwaveshare.c ${PM3_ROOT}/client/src/cmdhfxerox.c ${PM3_ROOT}/client/src/cmdhw.c diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 5c64fd135..3855d6884 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -276,6 +276,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdhfepa.c ${PM3_ROOT}/client/src/cmdhffelica.c ${PM3_ROOT}/client/src/cmdhffido.c + ${PM3_ROOT}/client/src/cmdhffudan.c ${PM3_ROOT}/client/src/cmdhfgallagher.c ${PM3_ROOT}/client/src/cmdhfcipurse.c ${PM3_ROOT}/client/src/cmdhficlass.c @@ -293,9 +294,11 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdhfseos.c ${PM3_ROOT}/client/src/cmdhfst.c ${PM3_ROOT}/client/src/cmdhfst25ta.c + ${PM3_ROOT}/client/src/cmdhftexkom.c ${PM3_ROOT}/client/src/cmdhfthinfilm.c ${PM3_ROOT}/client/src/cmdhftopaz.c ${PM3_ROOT}/client/src/cmdhfwaveshare.c + ${PM3_ROOT}/client/src/cmdhfxerox.c ${PM3_ROOT}/client/src/cmdhw.c ${PM3_ROOT}/client/src/cmdlf.c ${PM3_ROOT}/client/src/cmdlfawid.c @@ -334,6 +337,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdmain.c ${PM3_ROOT}/client/src/cmdnfc.c ${PM3_ROOT}/client/src/cmdparser.c + ${PM3_ROOT}/client/src/cmdpiv.c ${PM3_ROOT}/client/src/cmdscript.c ${PM3_ROOT}/client/src/cmdsmartcard.c ${PM3_ROOT}/client/src/cmdtrace.c From fe286ed6d76e866baeaa3bddc15ec4b16a8a2014 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 02:50:16 +0100 Subject: [PATCH 506/759] remove Android from release checklist --- .github/ISSUE_TEMPLATE/checklist-for-release.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/checklist-for-release.md b/.github/ISSUE_TEMPLATE/checklist-for-release.md index 514b454d7..437a673b4 100644 --- a/.github/ISSUE_TEMPLATE/checklist-for-release.md +++ b/.github/ISSUE_TEMPLATE/checklist-for-release.md @@ -18,7 +18,6 @@ assignees: doegox, iceman1001 - [ ] `tools/build_all_firmwares.sh` check that the script contains all standalone modes then compile all standalone modes (linux only) - [ ] `experimental_lib` compilation & tests - [ ] `experimental_client_with_swig` compilation & tests -- [ ] Check Android `CMakeLists.txt` list of source file - [ ] GitHub Actions - green across the board ( MacOS, Ubuntu, Windows) # OS compilation and tests From e995a25ec5292aec6c3225e298364b6df5c1c973 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Jan 2023 05:37:43 +0100 Subject: [PATCH 507/759] fix warning on termux --- common/mbedtls/bignum.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/mbedtls/bignum.c b/common/mbedtls/bignum.c index 9b7bcdd1c..200ad7ca0 100644 --- a/common/mbedtls/bignum.c +++ b/common/mbedtls/bignum.c @@ -1442,6 +1442,7 @@ __attribute__((noinline)) #endif void mpi_mul_hlp(size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b) { mbedtls_mpi_uint c = 0, t = 0; + (void)t; #if defined(MULADDC_HUIT) for (; i >= 8; i -= 8) { From 207d8ed7d7110855da7b5ad421d58c1060a90f6b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 12:11:31 +0100 Subject: [PATCH 508/759] Fix INSTALLSUDO usage and adapt release template --- .github/ISSUE_TEMPLATE/checklist-for-release.md | 5 +++-- Makefile | 8 ++++---- Makefile.defs | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/checklist-for-release.md b/.github/ISSUE_TEMPLATE/checklist-for-release.md index 437a673b4..cfc7c9abd 100644 --- a/.github/ISSUE_TEMPLATE/checklist-for-release.md +++ b/.github/ISSUE_TEMPLATE/checklist-for-release.md @@ -25,17 +25,18 @@ assignees: doegox, iceman1001 ```bash #!/usr/bin/env bash +set -x make clean && make -j PLATFORM=PM3GENERIC PLATFORM_EXTRAS= && tools/pm3_tests.sh --long || exit 1 make clean && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS= || exit 1 make clean && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON || exit 1 -make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && sudo make install PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && ( cd /tmp; proxmark3 -c 'data load -f lf_EM4x05.pm3;lf search -1'|grep 'Valid FDX-B ID found' ) && sudo make uninstall || exit 1 - +make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && INSTALLSUDO=sudo make install PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && ( cd /tmp; proxmark3 -c 'data load -f lf_EM4x05.pm3;lf search -1'|grep 'Valid FDX-B ID found' ) && INSTALLSUDO=sudo make uninstall || exit 1 ( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3GENERIC PLATFORM_EXTRAS= && cp -a ../*scripts ../*libs . && ../../tools/pm3_tests.sh --clientbin $(pwd)/proxmark3 client ) || exit 1 ( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS= ) || exit 1 ( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON ) || exit 1 # Hitag2crack, optionally with --long and --opencl ... make hitag2crack/clean && make hitag2crack && tools/pm3_tests.sh hitag2crack || exit 1 +echo PASS ``` - [ ] RPI Zero diff --git a/Makefile b/Makefile index 5452842cc..0cb778ec6 100644 --- a/Makefile +++ b/Makefile @@ -80,20 +80,20 @@ ifneq (,$(INSTALLSHARES)) endif ifneq (,$(INSTALLDOCS)) $(Q)$(INSTALLSUDO) $(RMDIR) $(foreach doc,$(INSTALLDOCS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)$(PATHSEP)$(notdir $(doc))) - $(Q)$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH) + $(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH) endif ifneq (,$(INSTALLTOOLS)) $(Q)$(INSTALLSUDO) $(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool))) endif - $(Q)$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) + $(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) ifneq (,$(INSTALLSIMFW)) $(Q)$(INSTALLSUDO) $(RM) $(foreach fw,$(INSTALLSIMFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw))) endif - $(Q)$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) + $(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) ifeq ($(platform),Linux) $(Q)$(INSTALLSUDO) $(RM) $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules endif - $(Q)$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) + $(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH) # tests mfkey/check: FORCE diff --git a/Makefile.defs b/Makefile.defs index 8f9d5f271..bcbbaa67e 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -29,8 +29,8 @@ GZIP = gzip MKDIR = mkdir -p RM = rm -f RMDIR = rm -rf -# rmdir only if dir is empty, tolerate failure -RMDIR_SOFT = -rmdir +# rmdir only if dir is empty, you must add "-" when using it to tolerate failure +RMDIR_SOFT = rmdir MV = mv TOUCH = touch FALSE = false From 875b1a0aed3304285cbbd7e517db201e07a76f51 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Jan 2023 12:27:34 +0100 Subject: [PATCH 509/759] annotate new magic command (WIP) --- client/src/cmdhflist.c | 12 ++++++++++++ include/protocols.h | 3 +++ 2 files changed, 15 insertions(+) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index 5a82db29e..a19ecdea9 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -318,6 +318,18 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i snprintf(exp, size, "AUTH-B(%d)", cmd[1]); break; } + case MIFARE_MAGIC_GDM_AUTH_KEYA:{ + if (cmdsize > 3) { + snprintf(exp, size, "MAGIC AUTH-A(%d)", cmd[1]); + MifareAuthState = masNt; + } + break; + } + case MIFARE_MAGIC_GDM_AUTH_KEYB: { + MifareAuthState = masNt; + snprintf(exp, size, "MAGIC AUTH-B(%d)", cmd[1]); + break; + } case MIFARE_MAGICWUPC1: snprintf(exp, size, "MAGIC WUPC1"); break; diff --git a/include/protocols.h b/include/protocols.h index 9de07e4e7..1417fa71a 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -190,6 +190,9 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MIFARE_CMD_RESTORE 0xC2 #define MIFARE_CMD_TRANSFER 0xB0 +#define MIFARE_MAGIC_GDM_AUTH_KEYA 0x80 +#define MIFARE_MAGIC_GDM_AUTH_KEYB 0x81 + #define MIFARE_EV1_PERSONAL_UID 0x40 #define MIFARE_EV1_SETMODE 0x43 #define MIFARE_EV1_UIDF0 0x00 From 834c182d63cbb74061c9821585ae0b1c09c4f4ea Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 15 Jan 2023 14:07:17 +0100 Subject: [PATCH 510/759] more intuitive text --- armsrc/appmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 756ca4f4f..76d9ac3c0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -345,7 +345,7 @@ static void print_debug_level(void) { char dbglvlstr[20] = {0}; switch (g_dbglevel) { case DBG_NONE: - sprintf(dbglvlstr, "none"); + sprintf(dbglvlstr, "off"); break; case DBG_ERROR: sprintf(dbglvlstr, "error"); From 8f2362e7b0cc8ba72f9084cdcb7f81580617c876 Mon Sep 17 00:00:00 2001 From: Krzysztof Zdulski Date: Sun, 15 Jan 2023 16:33:32 +0100 Subject: [PATCH 511/759] Fix mifare classic dump when block cannot be read --- client/src/cmdhfmf.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 11d101391..b98f21c01 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1044,11 +1044,9 @@ static int CmdHF14AMfDump(const char *Cmd) { PrintAndLogEx(SUCCESS, "successfully read block %2d of sector %2d.", blockNo, sectorNo); } else { PrintAndLogEx(FAILED, "could not read block %2d of sector %2d", blockNo, sectorNo); - break; } } else { PrintAndLogEx(WARNING, "command execute timeout when trying to read block %2d of sector %2d.", blockNo, sectorNo); - break; } } } From 8d53184c816b49676a844987e4793609f9e8a16b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 18:45:40 +0100 Subject: [PATCH 512/759] shorter long test for mfd_aes_brute --- tools/pm3_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index a39615cb6..d03e488e6 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -293,7 +293,7 @@ while true; do echo -e "\n${C_BLUE}Testing mfd_aes_brute:${C_NC} ${MFDASEBRUTEBIN:=./tools/mfd_aes_brute/mfd_aes_brute}" if ! CheckFileExist "mfd_aes_brute exists" "$MFDASEBRUTEBIN"; then break; fi if ! CheckExecute "mfd_aes_brute test 1/2" "$MFDASEBRUTEBIN 1605394800 bb6aea729414a5b1eff7b16328ce37fd 82f5f498dbc29f7570102397a2e5ef2b6dc14a864f665b3c54d11765af81e95c" "key.................... .*261C07A23F2BC8262F69F10A5BDF3764"; then break; fi - if ! CheckExecute slow "mfd_aes_brute test 2/2" "$MFDASEBRUTEBIN 1136073600 3fda933e2953ca5e6cfbbf95d1b51ddf 97fe4b5de24188458d102959b888938c988e96fb98469ce7426f50f108eaa583" "key.................... .*E757178E13516A4F3171BC6EA85E165A"; then break; fi + if ! CheckExecute slow "mfd_aes_brute test 2/2" "$MFDASEBRUTEBIN 1546300800 3fda933e2953ca5e6cfbbf95d1b51ddf 97fe4b5de24188458d102959b888938c988e96fb98469ce7426f50f108eaa583" "key.................... .*E757178E13516A4F3171BC6EA85E165A"; then break; fi fi # hitag2crack not yet part of "all" # if $TESTALL || $TESTHITAG2CRACK; then From f54dd925d164075159dbdaa6240a87c54ded2213 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 18:46:14 +0100 Subject: [PATCH 513/759] docker & tests --- .../ISSUE_TEMPLATE/checklist-for-release.md | 17 +---------- docker/archlinux/Dockerfile | 3 ++ docker/archlinux/README.md | 8 ++--- docker/archlinux/run_tests.sh | 17 +---------- docker/debian-bullseye/Dockerfile | 4 +++ docker/debian-bullseye/README.md | 11 ++++--- docker/debian-bullseye/run_tests.sh | 8 +++++ docker/kali/Dockerfile | 10 +++++-- docker/kali/README.md | 11 ++++--- docker/kali/run_tests.sh | 30 ++----------------- tools/release_tests.sh | 15 ++++++++++ 11 files changed, 55 insertions(+), 79 deletions(-) create mode 100755 docker/debian-bullseye/run_tests.sh create mode 100755 tools/release_tests.sh diff --git a/.github/ISSUE_TEMPLATE/checklist-for-release.md b/.github/ISSUE_TEMPLATE/checklist-for-release.md index cfc7c9abd..5deb64538 100644 --- a/.github/ISSUE_TEMPLATE/checklist-for-release.md +++ b/.github/ISSUE_TEMPLATE/checklist-for-release.md @@ -22,22 +22,7 @@ assignees: doegox, iceman1001 # OS compilation and tests -```bash -#!/usr/bin/env bash - -set -x -make clean && make -j PLATFORM=PM3GENERIC PLATFORM_EXTRAS= && tools/pm3_tests.sh --long || exit 1 -make clean && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS= || exit 1 -make clean && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON || exit 1 -make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && INSTALLSUDO=sudo make install PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && ( cd /tmp; proxmark3 -c 'data load -f lf_EM4x05.pm3;lf search -1'|grep 'Valid FDX-B ID found' ) && INSTALLSUDO=sudo make uninstall || exit 1 -( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3GENERIC PLATFORM_EXTRAS= && cp -a ../*scripts ../*libs . && ../../tools/pm3_tests.sh --clientbin $(pwd)/proxmark3 client ) || exit 1 -( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS= ) || exit 1 -( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON ) || exit 1 - -# Hitag2crack, optionally with --long and --opencl ... -make hitag2crack/clean && make hitag2crack && tools/pm3_tests.sh hitag2crack || exit 1 -echo PASS -``` +Run `tools/release_tests.sh` on: - [ ] RPI Zero - [ ] Jetson Nano diff --git a/docker/archlinux/Dockerfile b/docker/archlinux/Dockerfile index 709b7b5d4..93584c098 100644 --- a/docker/archlinux/Dockerfile +++ b/docker/archlinux/Dockerfile @@ -10,6 +10,9 @@ RUN pacman -S --noconfirm sudo git base-devel cmake libusb readline bzip2 arm-no RUN pacman -S --noconfirm python-pip RUN python3 -m pip install ansicolors sslcrypto +# OpenCL for hitag2crack +RUN pacman -S --noconfirm ocl-icd + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/archlinux/README.md b/docker/archlinux/README.md index 35fdf0c78..872d46cb4 100644 --- a/docker/archlinux/README.md +++ b/docker/archlinux/README.md @@ -32,18 +32,18 @@ This script does both setup the mirrors and pip install and then run a bunch of different builds with make and cmake together with the different combos of RDV4, GENERIC, BTADDON combos. -If all tests OK, the script will finish. +If all tests OK, the script will finish with PASS. # Notes to run tests -Add first the mirrors, see above, if needed. +Add first the mirrors, see above, if needed. The release test build script is to be run in proxmark root folder inside the docker env. ``` docker/archlinux/run_tests.sh; -``` +``` -Or if you want to run single test, +Or if you want to run single test, ``` make clean; make -j diff --git a/docker/archlinux/run_tests.sh b/docker/archlinux/run_tests.sh index 9c2b4daeb..53eeda9a3 100755 --- a/docker/archlinux/run_tests.sh +++ b/docker/archlinux/run_tests.sh @@ -2,7 +2,6 @@ # Iceman 2022 # # This script is to be run from proxmark root folder inside the docker env -# cd proxmark; # docker/archlinux/run_tests.sh; # # Script contains two phases. @@ -40,18 +39,4 @@ pacman -Ss '^gcc$' # sudo pacman -S testing/gcc # sudo pacman -S gcc -# replace egrep to silence warning -sed -i 's/egrep/grep -E/g' tools/pm3_tests.sh - -# Makefile build tests -make clean; make -j PLATFORM=PM3GENERIC; tools/pm3_tests.sh --long || exit 1 -make clean; make -j PLATFORM=PM3RDV4; tools/pm3_tests.sh --long || exit 1 -make clean; make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON; tools/pm3_tests.sh --long || exit 1 -# sudo make install; pushd /tmp; proxmark3 -c 'data load -f lf_EM4x05.pm3;lf search -1'; popd; sudo make uninstall - -# cmake client build test -#( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 -( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3GENERIC ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 -( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3RDV4 ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 -( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client || exit 1 - +tools/release_tests.sh diff --git a/docker/debian-bullseye/Dockerfile b/docker/debian-bullseye/Dockerfile index 53114b795..ff456b558 100644 --- a/docker/debian-bullseye/Dockerfile +++ b/docker/debian-bullseye/Dockerfile @@ -11,8 +11,12 @@ RUN apt-get update && \ RUN apt-get install -y python3-minimal && \ apt-get install -y python3-pip && \ + apt-get clean && \ python3 -m pip install ansicolors sslcrypto +RUN apt-get install -y opencl-dev && \ + apt-get clean + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/debian-bullseye/README.md b/docker/debian-bullseye/README.md index 1170c19fe..e86881019 100644 --- a/docker/debian-bullseye/README.md +++ b/docker/debian-bullseye/README.md @@ -1,9 +1,8 @@ # Notes on run_tests.sh script -This script does both setup the mirrors and pip install and then run a -bunch of different builds with make and cmake together with the different combos -of RDV4, GENERIC, BTADDON combos. +This script runs a bunch of different builds with make and cmake together +with the different combos of RDV4, GENERIC, BTADDON combos. -If all tests OK, the script will finish. +If all tests OK, the script will finish with PASS. # Notes to run tests @@ -11,9 +10,9 @@ The script is to be run in proxmark root folder inside the docker env. ``` docker/debian-bullseye/run_tests.sh; -``` +``` -Or if you want to run single test, +Or if you want to run single test, ``` sudo apt update diff --git a/docker/debian-bullseye/run_tests.sh b/docker/debian-bullseye/run_tests.sh new file mode 100755 index 000000000..25e6d2a21 --- /dev/null +++ b/docker/debian-bullseye/run_tests.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Iceman 2022 +# +# This script is to be run from proxmark root folder inside the docker env +# docker/debian-bullseye/run_tests.sh; + +sudo apt update && sudo apt upgrade -y +tools/release_tests.sh diff --git a/docker/kali/Dockerfile b/docker/kali/Dockerfile index e8a506dc5..79d4bb9a6 100644 --- a/docker/kali/Dockerfile +++ b/docker/kali/Dockerfile @@ -9,9 +9,13 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean -RUN apt install -y python3-minimal -RUN apt install -y python3-pip -RUN python3 -m pip install ansicolors sslcrypto +RUN apt-get install -y python3-minimal && \ + apt-get install -y python3-pip && \ + apt-get clean && \ + python3 -m pip install ansicolors sslcrypto + +RUN apt-get install -y opencl-dev && \ + apt-get clean # Create rrg user RUN useradd -ms /bin/bash rrg diff --git a/docker/kali/README.md b/docker/kali/README.md index e76d73ae2..dbf1f7f50 100644 --- a/docker/kali/README.md +++ b/docker/kali/README.md @@ -1,9 +1,8 @@ # Notes on run_tests.sh script -This script does both setup the mirrors and pip install and then run a -bunch of different builds with make and cmake together with the different combos -of RDV4, GENERIC, BTADDON combos. +This script runs a bunch of different builds with make and cmake together +with the different combos of RDV4, GENERIC, BTADDON combos. -If all tests OK, the script will finish. +If all tests OK, the script will finish with PASS. # Notes to run tests @@ -11,9 +10,9 @@ The script is to be run in proxmark root folder inside the docker env. ``` docker/kali/run_tests.sh; -``` +``` -Or if you want to run single test, +Or if you want to run single test, ``` sudo apt update make clean; make -j diff --git a/docker/kali/run_tests.sh b/docker/kali/run_tests.sh index 27b1c608f..dec20763b 100755 --- a/docker/kali/run_tests.sh +++ b/docker/kali/run_tests.sh @@ -2,33 +2,7 @@ # Iceman 2022 # # This script is to be run from proxmark root folder inside the docker env -# cd proxmark; -# docker/archlinux/run_tests.sh; -# -# Script contains two phases. -# -# -- Init / setup phase -# Script to be run inside docker env. First install some dependencies for docker image. -# -# -- Build phase begins -# make builds -# cmake client builds -# of the different possible PLATFORM (PM3RDV4 / PM3GENERIC) and BTADDON combos +# docker/kali/run_tests.sh; sudo apt update && sudo apt upgrade -y - -# replace egrep to silence warning -sed -i 's/egrep/grep -E/g' tools/pm3_tests.sh - -# Makefile build tests -make clean; make -j PLATFORM=PM3GENERIC; tools/pm3_tests.sh --long || exit 1 -make clean; make -j PLATFORM=PM3RDV4; tools/pm3_tests.sh --long || exit 1 -make clean; make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON; tools/pm3_tests.sh --long || exit 1 -# sudo make install; pushd /tmp; proxmark3 -c 'data load -f lf_EM4x05.pm3;lf search -1'; popd; sudo make uninstall - -# cmake client build test -#( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 -( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3GENERIC ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 -( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3RDV4 ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client --long || exit 1 -( cd client; rm -rf build; mkdir build;cd build;cmake ..;make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON ); PM3BIN=./client/build/proxmark3 tools/pm3_tests.sh client || exit 1 - +tools/release_tests.sh diff --git a/tools/release_tests.sh b/tools/release_tests.sh new file mode 100755 index 000000000..728e546f3 --- /dev/null +++ b/tools/release_tests.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# To be run from proxmark3 root directory +set -x +make clean && make -j PLATFORM=PM3GENERIC PLATFORM_EXTRAS= && tools/pm3_tests.sh --long || exit 1 +make clean && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS= || exit 1 +make clean && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON || exit 1 +make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && INSTALLSUDO=sudo make install PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON && ( cd /tmp; proxmark3 -c 'data load -f lf_EM4x05.pm3;lf search -1'|grep 'Valid FDX-B ID found' ) && INSTALLSUDO=sudo make uninstall || exit 1 +( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3GENERIC PLATFORM_EXTRAS= && cp -a ../*scripts ../*libs . && ../../tools/pm3_tests.sh --clientbin $(pwd)/proxmark3 client ) || exit 1 +( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS= ) || exit 1 +( cd client; rm -rf build; mkdir build;cd build;cmake .. && make -j PLATFORM=PM3RDV4 PLATFORM_EXTRAS=BTADDON ) || exit 1 + +# Hitag2crack, optionally with --long and --opencl... +make hitag2crack/clean && make hitag2crack && tools/pm3_tests.sh hitag2crack || exit 1 +echo PASS From 65d0e1ef0614d020f4951bcf36f3e7f9c93785ee Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 19:40:52 +0100 Subject: [PATCH 514/759] update docker ubuntu --- .../ISSUE_TEMPLATE/checklist-for-release.md | 2 +- docker/ubuntu-18.04/Dockerfile | 8 +++++-- docker/ubuntu-18.04/README.md | 7 +++---- docker/ubuntu-18.04/run_tests.sh | 8 +++++++ docker/ubuntu-20.04/Dockerfile | 8 +++++-- docker/ubuntu-20.04/README.md | 7 +++---- docker/ubuntu-20.04/run_tests.sh | 8 +++++++ docker/ubuntu-21.04/README.md | 21 ------------------- docker/ubuntu-21.04/docker_build.sh | 3 --- docker/ubuntu-21.04/docker_rm.sh | 4 ---- .../{ubuntu-21.04 => ubuntu-22.04}/Dockerfile | 10 ++++++--- docker/ubuntu-22.04/README.md | 20 ++++++++++++++++++ docker/ubuntu-22.04/docker_build.sh | 3 +++ docker/ubuntu-22.04/docker_rm.sh | 4 ++++ .../docker_run.sh | 2 +- docker/ubuntu-22.04/run_tests.sh | 8 +++++++ 16 files changed, 78 insertions(+), 45 deletions(-) create mode 100755 docker/ubuntu-18.04/run_tests.sh create mode 100755 docker/ubuntu-20.04/run_tests.sh delete mode 100644 docker/ubuntu-21.04/README.md delete mode 100755 docker/ubuntu-21.04/docker_build.sh delete mode 100644 docker/ubuntu-21.04/docker_rm.sh rename docker/{ubuntu-21.04 => ubuntu-22.04}/Dockerfile (76%) create mode 100644 docker/ubuntu-22.04/README.md create mode 100755 docker/ubuntu-22.04/docker_build.sh create mode 100644 docker/ubuntu-22.04/docker_rm.sh rename docker/{ubuntu-21.04 => ubuntu-22.04}/docker_run.sh (67%) create mode 100755 docker/ubuntu-22.04/run_tests.sh diff --git a/.github/ISSUE_TEMPLATE/checklist-for-release.md b/.github/ISSUE_TEMPLATE/checklist-for-release.md index 5deb64538..a30b2fb22 100644 --- a/.github/ISSUE_TEMPLATE/checklist-for-release.md +++ b/.github/ISSUE_TEMPLATE/checklist-for-release.md @@ -32,7 +32,7 @@ Run `tools/release_tests.sh` on: - [ ] Kali - [ ] Debian Stable - [ ] Debian Testing -- [ ] Ubuntu21 +- [ ] Ubuntu 22 - [ ] ParrotOS - [ ] Fedora - [ ] OpenSuse Leap diff --git a/docker/ubuntu-18.04/Dockerfile b/docker/ubuntu-18.04/Dockerfile index 11c5afcd8..29c958a4d 100644 --- a/docker/ubuntu-18.04/Dockerfile +++ b/docker/ubuntu-18.04/Dockerfile @@ -10,10 +10,14 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libssl-dev sudo && \ apt-get clean -RUN apt install -y python3-minimal && \ - apt install -y python3-pip && \ +RUN apt-get install -y python3-minimal && \ + apt-get install -y python3-pip && \ + apt-get clean && \ python3 -m pip install ansicolors sslcrypto +RUN apt-get install -y opencl-dev && \ + apt-get clean + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/ubuntu-18.04/README.md b/docker/ubuntu-18.04/README.md index 0b7d2f748..6cc3b9ef2 100644 --- a/docker/ubuntu-18.04/README.md +++ b/docker/ubuntu-18.04/README.md @@ -1,9 +1,8 @@ # Notes on run_tests.sh script -This script does both setup the mirrors and pip install and then run a -bunch of different builds with make and cmake together with the different combos -of RDV4, GENERIC, BTADDON combos. +This script runs a bunch of different builds with make and cmake together +with the different combos of RDV4, GENERIC, BTADDON combos. -If all tests OK, the script will finish. +If all tests OK, the script will finish with PASS. # Notes to run tests diff --git a/docker/ubuntu-18.04/run_tests.sh b/docker/ubuntu-18.04/run_tests.sh new file mode 100755 index 000000000..25e6d2a21 --- /dev/null +++ b/docker/ubuntu-18.04/run_tests.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Iceman 2022 +# +# This script is to be run from proxmark root folder inside the docker env +# docker/debian-bullseye/run_tests.sh; + +sudo apt update && sudo apt upgrade -y +tools/release_tests.sh diff --git a/docker/ubuntu-20.04/Dockerfile b/docker/ubuntu-20.04/Dockerfile index d9138aa0d..72f6ec6cf 100644 --- a/docker/ubuntu-20.04/Dockerfile +++ b/docker/ubuntu-20.04/Dockerfile @@ -9,10 +9,14 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean -RUN apt install -y python3-minimal && \ - apt install -y python3-pip && \ +RUN apt-get install -y python3-minimal && \ + apt-get install -y python3-pip && \ + apt-get clean && \ python3 -m pip install ansicolors sslcrypto +RUN apt-get install -y opencl-dev && \ + apt-get clean + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/ubuntu-20.04/README.md b/docker/ubuntu-20.04/README.md index d8c7b3f53..4c432eff1 100644 --- a/docker/ubuntu-20.04/README.md +++ b/docker/ubuntu-20.04/README.md @@ -1,9 +1,8 @@ # Notes on run_tests.sh script -This script does both setup the mirrors and pip install and then run a -bunch of different builds with make and cmake together with the different combos -of RDV4, GENERIC, BTADDON combos. +This script runs a bunch of different builds with make and cmake together +with the different combos of RDV4, GENERIC, BTADDON combos. -If all tests OK, the script will finish. +If all tests OK, the script will finish with PASS. # Notes to run tests diff --git a/docker/ubuntu-20.04/run_tests.sh b/docker/ubuntu-20.04/run_tests.sh new file mode 100755 index 000000000..25e6d2a21 --- /dev/null +++ b/docker/ubuntu-20.04/run_tests.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Iceman 2022 +# +# This script is to be run from proxmark root folder inside the docker env +# docker/debian-bullseye/run_tests.sh; + +sudo apt update && sudo apt upgrade -y +tools/release_tests.sh diff --git a/docker/ubuntu-21.04/README.md b/docker/ubuntu-21.04/README.md deleted file mode 100644 index bb90abab8..000000000 --- a/docker/ubuntu-21.04/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Notes on run_tests.sh script -This script does both setup the mirrors and pip install and then run a -bunch of different builds with make and cmake together with the different combos -of RDV4, GENERIC, BTADDON combos. - -If all tests OK, the script will finish. - - -# Notes to run tests -The script is to be run in proxmark root folder inside the docker env. - -``` -docker/ubuntu-21.04/run_tests.sh; -``` - -Or if you want to run single test, -``` -sudo apt update -make clean; make -j -tools/pm3_tests.sh --long -``` diff --git a/docker/ubuntu-21.04/docker_build.sh b/docker/ubuntu-21.04/docker_build.sh deleted file mode 100755 index 70e0349f8..000000000 --- a/docker/ubuntu-21.04/docker_build.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -docker build -t "pm3-ubuntu-21.04:1.0" . diff --git a/docker/ubuntu-21.04/docker_rm.sh b/docker/ubuntu-21.04/docker_rm.sh deleted file mode 100644 index bb848bfe0..000000000 --- a/docker/ubuntu-21.04/docker_rm.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -docker image rm pm3-ubuntu-21.04:1.0 -docker image rm ubuntu:21.04 diff --git a/docker/ubuntu-21.04/Dockerfile b/docker/ubuntu-22.04/Dockerfile similarity index 76% rename from docker/ubuntu-21.04/Dockerfile rename to docker/ubuntu-22.04/Dockerfile index 4350e8aa3..9d867e785 100644 --- a/docker/ubuntu-21.04/Dockerfile +++ b/docker/ubuntu-22.04/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:21.04 +FROM ubuntu:22.04 ENV LANG C ENV DEBIAN_FRONTEND noninteractive @@ -9,10 +9,14 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean -RUN apt install -y python3-minimal && \ - apt install -y python3-pip && \ +RUN apt-get install -y python3-minimal && \ + apt-get install -y python3-pip && \ + apt-get clean && \ python3 -m pip install ansicolors sslcrypto +RUN apt-get install -y opencl-dev && \ + apt-get clean + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/ubuntu-22.04/README.md b/docker/ubuntu-22.04/README.md new file mode 100644 index 000000000..93d4462ad --- /dev/null +++ b/docker/ubuntu-22.04/README.md @@ -0,0 +1,20 @@ +# Notes on run_tests.sh script +This script runs a bunch of different builds with make and cmake together +with the different combos of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish with PASS. + + +# Notes to run tests +The script is to be run in proxmark root folder inside the docker env. + +``` +docker/ubuntu-22.04/run_tests.sh; +``` + +Or if you want to run single test, +``` +sudo apt update +make clean; make -j +tools/pm3_tests.sh --long +``` diff --git a/docker/ubuntu-22.04/docker_build.sh b/docker/ubuntu-22.04/docker_build.sh new file mode 100755 index 000000000..1cfd6c10a --- /dev/null +++ b/docker/ubuntu-22.04/docker_build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker build -t "pm3-ubuntu-22.04:1.0" . diff --git a/docker/ubuntu-22.04/docker_rm.sh b/docker/ubuntu-22.04/docker_rm.sh new file mode 100644 index 000000000..e6a5f0302 --- /dev/null +++ b/docker/ubuntu-22.04/docker_rm.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +docker image rm pm3-ubuntu-22.04:1.0 +docker image rm ubuntu:22.04 diff --git a/docker/ubuntu-21.04/docker_run.sh b/docker/ubuntu-22.04/docker_run.sh similarity index 67% rename from docker/ubuntu-21.04/docker_run.sh rename to docker/ubuntu-22.04/docker_run.sh index d8fd6722f..04f8d99a0 100755 --- a/docker/ubuntu-21.04/docker_run.sh +++ b/docker/ubuntu-22.04/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-ubuntu-21.04:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-ubuntu-22.04:1.0 diff --git a/docker/ubuntu-22.04/run_tests.sh b/docker/ubuntu-22.04/run_tests.sh new file mode 100755 index 000000000..25e6d2a21 --- /dev/null +++ b/docker/ubuntu-22.04/run_tests.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Iceman 2022 +# +# This script is to be run from proxmark root folder inside the docker env +# docker/debian-bullseye/run_tests.sh; + +sudo apt update && sudo apt upgrade -y +tools/release_tests.sh From cb8f1a51adc21f18bf09291a24fbf2abc48ee6cb Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 19:54:56 +0100 Subject: [PATCH 515/759] update parrot docker tests --- docker/parrot-core-latest/Dockerfile | 8 ++++++-- docker/parrot-core-latest/README.md | 11 +++++------ docker/parrot-core-latest/run_tests.sh | 8 ++++++++ docker/ubuntu-18.04/run_tests.sh | 2 +- docker/ubuntu-20.04/run_tests.sh | 2 +- docker/ubuntu-22.04/run_tests.sh | 2 +- 6 files changed, 22 insertions(+), 11 deletions(-) create mode 100755 docker/parrot-core-latest/run_tests.sh diff --git a/docker/parrot-core-latest/Dockerfile b/docker/parrot-core-latest/Dockerfile index 8ca8f9856..a33af1d4c 100644 --- a/docker/parrot-core-latest/Dockerfile +++ b/docker/parrot-core-latest/Dockerfile @@ -9,10 +9,14 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev libbluetooth-dev libpython3-dev libssl-dev sudo && \ apt-get clean -RUN apt install -y python3-minimal && \ - apt install -y python3-pip && \ +RUN apt-get install -y python3-minimal && \ + apt-get install -y python3-pip && \ + apt-get clean && \ python3 -m pip install ansicolors sslcrypto +RUN apt-get install -y opencl-dev && \ + apt-get clean + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/parrot-core-latest/README.md b/docker/parrot-core-latest/README.md index 45ad548df..679c3a1eb 100644 --- a/docker/parrot-core-latest/README.md +++ b/docker/parrot-core-latest/README.md @@ -1,9 +1,8 @@ # Notes on run_tests.sh script -This script does both setup the mirrors and pip install and then run a -bunch of different builds with make and cmake together with the different combos -of RDV4, GENERIC, BTADDON combos. +This script runs a bunch of different builds with make and cmake together +with the different combos of RDV4, GENERIC, BTADDON combos. -If all tests OK, the script will finish. +If all tests OK, the script will finish with PASS. # Notes to run tests @@ -11,9 +10,9 @@ The script is to be run in proxmark root folder inside the docker env. ``` docker/parrot-core-latest/run_tests.sh; -``` +``` -Or if you want to run single test, +Or if you want to run single test, ``` sudo apt update diff --git a/docker/parrot-core-latest/run_tests.sh b/docker/parrot-core-latest/run_tests.sh new file mode 100755 index 000000000..65b0737c4 --- /dev/null +++ b/docker/parrot-core-latest/run_tests.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Iceman 2022 +# +# This script is to be run from proxmark root folder inside the docker env +# docker/parrot-core-latest/run_tests.sh; + +sudo apt update && sudo apt upgrade -y +tools/release_tests.sh diff --git a/docker/ubuntu-18.04/run_tests.sh b/docker/ubuntu-18.04/run_tests.sh index 25e6d2a21..1efdbc060 100755 --- a/docker/ubuntu-18.04/run_tests.sh +++ b/docker/ubuntu-18.04/run_tests.sh @@ -2,7 +2,7 @@ # Iceman 2022 # # This script is to be run from proxmark root folder inside the docker env -# docker/debian-bullseye/run_tests.sh; +# docker/ubuntu-18.04/run_tests.sh; sudo apt update && sudo apt upgrade -y tools/release_tests.sh diff --git a/docker/ubuntu-20.04/run_tests.sh b/docker/ubuntu-20.04/run_tests.sh index 25e6d2a21..aa98bc327 100755 --- a/docker/ubuntu-20.04/run_tests.sh +++ b/docker/ubuntu-20.04/run_tests.sh @@ -2,7 +2,7 @@ # Iceman 2022 # # This script is to be run from proxmark root folder inside the docker env -# docker/debian-bullseye/run_tests.sh; +# docker/ubuntu-20.04/run_tests.sh; sudo apt update && sudo apt upgrade -y tools/release_tests.sh diff --git a/docker/ubuntu-22.04/run_tests.sh b/docker/ubuntu-22.04/run_tests.sh index 25e6d2a21..4f8ce55ea 100755 --- a/docker/ubuntu-22.04/run_tests.sh +++ b/docker/ubuntu-22.04/run_tests.sh @@ -2,7 +2,7 @@ # Iceman 2022 # # This script is to be run from proxmark root folder inside the docker env -# docker/debian-bullseye/run_tests.sh; +# docker/ubuntu-22.04/run_tests.sh; sudo apt update && sudo apt upgrade -y tools/release_tests.sh From 7e02a6457631981727c7bd8e64d929c4ac14e6a3 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 15 Jan 2023 21:53:39 +0100 Subject: [PATCH 516/759] update fedora docker tests --- .../ISSUE_TEMPLATE/checklist-for-release.md | 2 +- docker/fedora-34/README.md | 26 ------------------- docker/fedora-34/docker_build.sh | 3 --- docker/fedora-34/docker_rm.sh | 4 --- docker/fedora-35/README.md | 26 ------------------- docker/fedora-35/docker_build.sh | 3 --- docker/fedora-35/docker_rm.sh | 4 --- docker/{fedora-34 => fedora-36}/Dockerfile | 4 ++- docker/fedora-36/README.md | 21 +++++++++++++++ docker/fedora-36/docker_build.sh | 3 +++ docker/fedora-36/docker_rm.sh | 4 +++ docker/{fedora-34 => fedora-36}/docker_run.sh | 2 +- docker/fedora-36/run_tests.sh | 8 ++++++ docker/{fedora-35 => fedora-37}/Dockerfile | 4 ++- docker/fedora-37/README.md | 20 ++++++++++++++ docker/fedora-37/docker_build.sh | 3 +++ docker/fedora-37/docker_rm.sh | 4 +++ docker/{fedora-35 => fedora-37}/docker_run.sh | 2 +- docker/fedora-37/run_tests.sh | 8 ++++++ 19 files changed, 80 insertions(+), 71 deletions(-) delete mode 100644 docker/fedora-34/README.md delete mode 100755 docker/fedora-34/docker_build.sh delete mode 100644 docker/fedora-34/docker_rm.sh delete mode 100644 docker/fedora-35/README.md delete mode 100755 docker/fedora-35/docker_build.sh delete mode 100644 docker/fedora-35/docker_rm.sh rename docker/{fedora-34 => fedora-36}/Dockerfile (88%) create mode 100644 docker/fedora-36/README.md create mode 100755 docker/fedora-36/docker_build.sh create mode 100644 docker/fedora-36/docker_rm.sh rename docker/{fedora-34 => fedora-36}/docker_run.sh (69%) create mode 100755 docker/fedora-36/run_tests.sh rename docker/{fedora-35 => fedora-37}/Dockerfile (88%) create mode 100644 docker/fedora-37/README.md create mode 100755 docker/fedora-37/docker_build.sh create mode 100644 docker/fedora-37/docker_rm.sh rename docker/{fedora-35 => fedora-37}/docker_run.sh (69%) create mode 100755 docker/fedora-37/run_tests.sh diff --git a/.github/ISSUE_TEMPLATE/checklist-for-release.md b/.github/ISSUE_TEMPLATE/checklist-for-release.md index a30b2fb22..8b5872891 100644 --- a/.github/ISSUE_TEMPLATE/checklist-for-release.md +++ b/.github/ISSUE_TEMPLATE/checklist-for-release.md @@ -34,7 +34,7 @@ Run `tools/release_tests.sh` on: - [ ] Debian Testing - [ ] Ubuntu 22 - [ ] ParrotOS -- [ ] Fedora +- [ ] Fedora 37 - [ ] OpenSuse Leap - [ ] OpenSuse Tumbleweed - [ ] OSX (MacPorts) diff --git a/docker/fedora-34/README.md b/docker/fedora-34/README.md deleted file mode 100644 index 7930f99d0..000000000 --- a/docker/fedora-34/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Notes on run_tests.sh script -This script does both strip the "recover_pk test" in pm3_tests.sh and then run a -bunch of different builds with make and cmake together with the different combos -of RDV4, GENERIC, BTADDON combos. - -If all tests OK, the script will finish. - - -# Notes to run tests -The script is to be run in proxmark root folder inside the docker env. - -``` -docker/fedora-34/run_tests.sh; -``` - -Or if you want to run single test, - -``` -sudo yum -y update -make clean; make -j -tools/pm3_tests.sh --long -``` - -Warning, `recover_pk selftests` will fail on Fedora because they stripped down the available ECC curves in their OpenSSL. - -So just comment the "recover_pk test" \ No newline at end of file diff --git a/docker/fedora-34/docker_build.sh b/docker/fedora-34/docker_build.sh deleted file mode 100755 index 753d223a8..000000000 --- a/docker/fedora-34/docker_build.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -docker build -t "pm3-fedora-34:1.0" . diff --git a/docker/fedora-34/docker_rm.sh b/docker/fedora-34/docker_rm.sh deleted file mode 100644 index eec1ba46c..000000000 --- a/docker/fedora-34/docker_rm.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -docker image rm pm3-fedora-34:1.0 -docker image rm fedora:34 diff --git a/docker/fedora-35/README.md b/docker/fedora-35/README.md deleted file mode 100644 index 966e86e7e..000000000 --- a/docker/fedora-35/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Notes on run_tests.sh script -This script does both strip the "recover_pk test" in pm3_tests.sh and then run a -bunch of different builds with make and cmake together with the different combos -of RDV4, GENERIC, BTADDON combos. - -If all tests OK, the script will finish. - - -# Notes to run tests -The script is to be run in proxmark root folder inside the docker env. - -``` -docker/fedora-35/run_tests.sh; -``` - -Or if you want to run single test, - -``` -sudo yum -y update -make clean; make -j -tools/pm3_tests.sh --long -``` - -Warning, `recover_pk selftests` will fail on Fedora because they stripped down the available ECC curves in their OpenSSL. - -So just comment the "recover_pk test" diff --git a/docker/fedora-35/docker_build.sh b/docker/fedora-35/docker_build.sh deleted file mode 100755 index 57eca95c0..000000000 --- a/docker/fedora-35/docker_build.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -docker build -t "pm3-fedora-35:1.0" . diff --git a/docker/fedora-35/docker_rm.sh b/docker/fedora-35/docker_rm.sh deleted file mode 100644 index 100bd2690..000000000 --- a/docker/fedora-35/docker_rm.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -docker image rm pm3-fedora-35:1.0 -docker image rm fedora:35 diff --git a/docker/fedora-34/Dockerfile b/docker/fedora-36/Dockerfile similarity index 88% rename from docker/fedora-34/Dockerfile rename to docker/fedora-36/Dockerfile index 90765a515..007af68c3 100644 --- a/docker/fedora-34/Dockerfile +++ b/docker/fedora-36/Dockerfile @@ -1,4 +1,4 @@ -FROM fedora:34 +FROM fedora:36 ENV LANG C # qt5-qtbase-devel skipped @@ -8,6 +8,8 @@ RUN yum -y update RUN yum -y install cmake python-pip RUN python3 -m pip install ansicolors sslcrypto +RUN yum -y install mesa-libOpenCL ocl-icd-devel + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/fedora-36/README.md b/docker/fedora-36/README.md new file mode 100644 index 000000000..6648fb28d --- /dev/null +++ b/docker/fedora-36/README.md @@ -0,0 +1,21 @@ +# Notes on run_tests.sh script +This script runs a bunch of different builds with make and cmake together +with the different combos of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish with PASS. + + +# Notes to run tests +The script is to be run in proxmark root folder inside the docker env. + +``` +docker/fedora-36/run_tests.sh; +``` + +Or if you want to run single test, + +``` +sudo yum -y update +make clean; make -j +tools/pm3_tests.sh --long +``` diff --git a/docker/fedora-36/docker_build.sh b/docker/fedora-36/docker_build.sh new file mode 100755 index 000000000..1a2e2d392 --- /dev/null +++ b/docker/fedora-36/docker_build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker build -t "pm3-fedora-36:1.0" . diff --git a/docker/fedora-36/docker_rm.sh b/docker/fedora-36/docker_rm.sh new file mode 100644 index 000000000..ea2b28809 --- /dev/null +++ b/docker/fedora-36/docker_rm.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +docker image rm pm3-fedora-36:1.0 +docker image rm fedora:36 diff --git a/docker/fedora-34/docker_run.sh b/docker/fedora-36/docker_run.sh similarity index 69% rename from docker/fedora-34/docker_run.sh rename to docker/fedora-36/docker_run.sh index 4be59d2c5..0e6e69925 100755 --- a/docker/fedora-34/docker_run.sh +++ b/docker/fedora-36/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-fedora-34:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-fedora-36:1.0 diff --git a/docker/fedora-36/run_tests.sh b/docker/fedora-36/run_tests.sh new file mode 100755 index 000000000..f4f632503 --- /dev/null +++ b/docker/fedora-36/run_tests.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Iceman 2022 +# +# This script is to be run from proxmark root folder inside the docker env +# docker/fedora-36/run_tests.sh; + +sudo apt update && sudo apt upgrade -y +tools/release_tests.sh diff --git a/docker/fedora-35/Dockerfile b/docker/fedora-37/Dockerfile similarity index 88% rename from docker/fedora-35/Dockerfile rename to docker/fedora-37/Dockerfile index 40788b62a..930767853 100644 --- a/docker/fedora-35/Dockerfile +++ b/docker/fedora-37/Dockerfile @@ -1,4 +1,4 @@ -FROM fedora:35 +FROM fedora:37 ENV LANG C # qt5-qtbase-devel skipped @@ -8,6 +8,8 @@ RUN yum -y update RUN yum -y install cmake python-pip RUN python3 -m pip install ansicolors sslcrypto +RUN yum -y install mesa-libOpenCL ocl-icd-devel + # Create rrg user RUN useradd -ms /bin/bash rrg RUN passwd -d rrg diff --git a/docker/fedora-37/README.md b/docker/fedora-37/README.md new file mode 100644 index 000000000..79c88e040 --- /dev/null +++ b/docker/fedora-37/README.md @@ -0,0 +1,20 @@ +# Notes on run_tests.sh script +This script runs a bunch of different builds with make and cmake together +with the different combos of RDV4, GENERIC, BTADDON combos. + +If all tests OK, the script will finish with PASS. + +# Notes to run tests +The script is to be run in proxmark root folder inside the docker env. + +``` +docker/fedora-37/run_tests.sh; +``` + +Or if you want to run single test, + +``` +sudo yum -y update +make clean; make -j +tools/pm3_tests.sh --long +``` diff --git a/docker/fedora-37/docker_build.sh b/docker/fedora-37/docker_build.sh new file mode 100755 index 000000000..5e3049b68 --- /dev/null +++ b/docker/fedora-37/docker_build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker build -t "pm3-fedora-37:1.0" . diff --git a/docker/fedora-37/docker_rm.sh b/docker/fedora-37/docker_rm.sh new file mode 100644 index 000000000..a9359d0fd --- /dev/null +++ b/docker/fedora-37/docker_rm.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +docker image rm pm3-fedora-37:1.0 +docker image rm fedora:37 diff --git a/docker/fedora-35/docker_run.sh b/docker/fedora-37/docker_run.sh similarity index 69% rename from docker/fedora-35/docker_run.sh rename to docker/fedora-37/docker_run.sh index d2e027507..eb51525b7 100755 --- a/docker/fedora-35/docker_run.sh +++ b/docker/fedora-37/docker_run.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-fedora-35:1.0 +docker run --volume=$(pwd)/../..:/home/rrg/proxmark3 -w /home/rrg/proxmark3 -it pm3-fedora-37:1.0 diff --git a/docker/fedora-37/run_tests.sh b/docker/fedora-37/run_tests.sh new file mode 100755 index 000000000..f4f632503 --- /dev/null +++ b/docker/fedora-37/run_tests.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Iceman 2022 +# +# This script is to be run from proxmark root folder inside the docker env +# docker/fedora-36/run_tests.sh; + +sudo apt update && sudo apt upgrade -y +tools/release_tests.sh From 2282d480adbf3e33c37c53c3293e3b3c63832e3d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 16 Jan 2023 00:34:02 +0100 Subject: [PATCH 517/759] update opensuse docker tests and other dockers --- docker/build-all.sh | 2 +- docker/fedora-36/run_tests.sh | 2 +- docker/fedora-37/run_tests.sh | 2 +- docker/opensuse-leap/Dockerfile | 10 ++++++++-- docker/opensuse-leap/README.md | 18 +++++++----------- docker/opensuse-leap/run_tests.sh | 8 ++++++++ docker/opensuse-tumbleweed/Dockerfile | 12 +++++++++--- docker/opensuse-tumbleweed/README.md | 18 +++++++----------- docker/opensuse-tumbleweed/run_tests.sh | 8 ++++++++ 9 files changed, 50 insertions(+), 30 deletions(-) create mode 100755 docker/opensuse-leap/run_tests.sh create mode 100755 docker/opensuse-tumbleweed/run_tests.sh diff --git a/docker/build-all.sh b/docker/build-all.sh index 3116d96dc..aba45382f 100755 --- a/docker/build-all.sh +++ b/docker/build-all.sh @@ -1,5 +1,5 @@ #!/bin/bash -for os in archlinux debian-buster fedora-34 fedora-35 homebrew kali opensuse-leap opensuse-tumbleweed parrot-core-latest ubuntu-18.04 ubuntu-20.04 ubuntu-21.04; do +for os in archlinux debian-buster fedora-36 fedora-37 homebrew kali opensuse-leap opensuse-tumbleweed parrot-core-latest ubuntu-18.04 ubuntu-20.04 ubuntu-22.04; do ( cd $os && ./docker_build.sh ) done diff --git a/docker/fedora-36/run_tests.sh b/docker/fedora-36/run_tests.sh index f4f632503..05cdb7da8 100755 --- a/docker/fedora-36/run_tests.sh +++ b/docker/fedora-36/run_tests.sh @@ -4,5 +4,5 @@ # This script is to be run from proxmark root folder inside the docker env # docker/fedora-36/run_tests.sh; -sudo apt update && sudo apt upgrade -y +sudo yum -y update tools/release_tests.sh diff --git a/docker/fedora-37/run_tests.sh b/docker/fedora-37/run_tests.sh index f4f632503..05cdb7da8 100755 --- a/docker/fedora-37/run_tests.sh +++ b/docker/fedora-37/run_tests.sh @@ -4,5 +4,5 @@ # This script is to be run from proxmark root folder inside the docker env # docker/fedora-36/run_tests.sh; -sudo apt update && sudo apt upgrade -y +sudo yum -y update tools/release_tests.sh diff --git a/docker/opensuse-leap/Dockerfile b/docker/opensuse-leap/Dockerfile index c8a5c7cf1..1af777d23 100644 --- a/docker/opensuse-leap/Dockerfile +++ b/docker/opensuse-leap/Dockerfile @@ -4,8 +4,14 @@ ENV LANG C # libqt5-qtbase-devel skipped RUN zypper --non-interactive install --no-recommends shadow sudo git patterns-devel-base-devel_basis gcc-c++ readline-devel libbz2-devel bluez-devel python3-devel libopenssl-devel -RUN zypper --non-interactive install cmake python3 python3-pip -RUN python3 -m pip install ansicolors sslcrypto +RUN zypper addrepo https://download.opensuse.org/repositories/home:wkazubski/15.4/home:wkazubski.repo && \ + zypper --gpg-auto-import-keys refresh && \ + zypper --non-interactive install cross-arm-none-eabi-gcc12 cross-arm-none-eabi-newlib + +RUN zypper --non-interactive install cmake python3 python3-pip && \ + python3 -m pip install ansicolors sslcrypto + +RUN zypper --non-interactive install ocl-icd-devel # Create rrg user RUN useradd -ms /bin/bash rrg diff --git a/docker/opensuse-leap/README.md b/docker/opensuse-leap/README.md index 47a3b5c32..ecda34706 100644 --- a/docker/opensuse-leap/README.md +++ b/docker/opensuse-leap/README.md @@ -1,24 +1,20 @@ # Notes on run_tests.sh script -This script does both setup and then run a -bunch of different builds with make and cmake together with the different combos -of RDV4, GENERIC, BTADDON combos. - -If all tests OK, the script will finish. +This script runs a bunch of different builds with make and cmake together +with the different combos of RDV4, GENERIC, BTADDON combos. +If all tests OK, the script will finish with PASS. # Notes to run tests The script is to be run in proxmark root folder inside the docker env. ``` docker/opensuse-leap/run_tests.sh; -``` +``` -Or if you want to run single test, +Or if you want to run single test, ``` +sudo zypper refresh && sudo zypper --non-interactive update make clean; make -j -tools/pm3_tests.sh --long mfkey nonce2key mf_nonce_brute fpga_compress common client +tools/pm3_tests.sh --long ``` - - -No ARM compiler available ? diff --git a/docker/opensuse-leap/run_tests.sh b/docker/opensuse-leap/run_tests.sh new file mode 100755 index 000000000..d2d49211b --- /dev/null +++ b/docker/opensuse-leap/run_tests.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Iceman 2022 +# +# This script is to be run from proxmark root folder inside the docker env +# docker/opensuse-leap/run_tests.sh; + +sudo zypper refresh && sudo zypper --non-interactive update +tools/release_tests.sh diff --git a/docker/opensuse-tumbleweed/Dockerfile b/docker/opensuse-tumbleweed/Dockerfile index 5d4adbb8b..169d087c3 100644 --- a/docker/opensuse-tumbleweed/Dockerfile +++ b/docker/opensuse-tumbleweed/Dockerfile @@ -2,10 +2,16 @@ FROM opensuse/tumbleweed ENV LANG C # libqt5-qtbase-devel skipped -RUN zypper --non-interactive install --no-recommends shadow sudo git patterns-devel-base-devel_basis gcc-c++ readline-devel libbz2-devel bluez-devel python3-devel libopenssl-devel cross-arm-none-gcc11 cross-arm-none-newlib-devel +RUN zypper --non-interactive install --no-recommends shadow sudo git patterns-devel-base-devel_basis gcc-c++ readline-devel libbz2-devel bluez-devel python3-devel libopenssl-devel cross-arm-none-gcc12 cross-arm-none-newlib-devel -RUN zypper --non-interactive install cmake python3 python3-pip -RUN python3 -m pip install ansicolors sslcrypto +#RUN zypper addrepo https://download.opensuse.org/repositories/home:wkazubski/openSUSE_Tumbleweed/home:wkazubski.repo && \ +# zypper --gpg-auto-import-keys refresh && \ +# zypper --non-interactive install cross-arm-none-eabi-gcc12 cross-arm-none-eabi-newlib + +RUN zypper --non-interactive install cmake python3 python3-pip && \ + python3 -m pip install ansicolors sslcrypto + +RUN zypper --non-interactive install ocl-icd-devel # Create rrg user RUN useradd -ms /bin/bash rrg diff --git a/docker/opensuse-tumbleweed/README.md b/docker/opensuse-tumbleweed/README.md index 126042512..bd55e0c9d 100644 --- a/docker/opensuse-tumbleweed/README.md +++ b/docker/opensuse-tumbleweed/README.md @@ -1,24 +1,20 @@ # Notes on run_tests.sh script -This script does both setup and then run a -bunch of different builds with make and cmake together with the different combos -of RDV4, GENERIC, BTADDON combos. - -If all tests OK, the script will finish. +This script runs a bunch of different builds with make and cmake together +with the different combos of RDV4, GENERIC, BTADDON combos. +If all tests OK, the script will finish with PASS. # Notes to run tests The script is to be run in proxmark root folder inside the docker env. ``` docker/opensuse-tumbleweed/run_tests.sh; -``` +``` -Or if you want to run single test, +Or if you want to run single test, ``` +sudo zypper refresh && sudo zypper --non-interactive update make clean; make -j -tools/pm3_tests.sh --long mfkey nonce2key mf_nonce_brute fpga_compress common client +tools/pm3_tests.sh --long ``` - - -No ARM compiler available ? diff --git a/docker/opensuse-tumbleweed/run_tests.sh b/docker/opensuse-tumbleweed/run_tests.sh new file mode 100755 index 000000000..9002131e9 --- /dev/null +++ b/docker/opensuse-tumbleweed/run_tests.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Iceman 2022 +# +# This script is to be run from proxmark root folder inside the docker env +# docker/opensuse-tumbleweed/run_tests.sh; + +sudo zypper refresh && sudo zypper --non-interactive update +tools/release_tests.sh From ee8759bc8bc718cad86037535dcbed8969344435 Mon Sep 17 00:00:00 2001 From: zebbe94 <63231705+zebbe-94@users.noreply.github.com> Date: Mon, 16 Jan 2023 01:06:12 +0100 Subject: [PATCH 518/759] fix typo --- client/src/cmdsmartcard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdsmartcard.c b/client/src/cmdsmartcard.c index 5cceb8b48..9c273739d 100644 --- a/client/src/cmdsmartcard.c +++ b/client/src/cmdsmartcard.c @@ -719,7 +719,7 @@ static int CmdSmartInfo(const char *Cmd) { // print header PrintAndLogEx(INFO, "--- " _CYAN_("Smartcard Information") " ---------"); - PrintAndLogEx(INFO, "ISO7618-3 ATR... %s", sprint_hex(card.atr, card.atr_len)); + PrintAndLogEx(INFO, "ISO7816-3 ATR... %s", sprint_hex(card.atr, card.atr_len)); // convert bytes to str. char *hexstr = calloc((card.atr_len << 1) + 1, sizeof(uint8_t)); if (hexstr == NULL) { From 3a7af557244b46c8a991684761f72211ebcb6abf Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Mon, 16 Jan 2023 19:57:42 +0100 Subject: [PATCH 519/759] Fix python initialization to have SWIG work --- client/src/cmdscript.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index 35640922e..57cf54084 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -147,7 +147,7 @@ static int split(char *str, char **arr) { return word_cnt; } -static void set_python_path(char *path) { +static void set_python_path(const char *path) { PyObject *syspath = PySys_GetObject("path"); if (syspath == 0) { PrintAndLogEx(WARNING, "Python failed to getobject"); @@ -172,7 +172,7 @@ static void set_python_paths(void) { char scripts_path[strlen(exec_path) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, exec_path); strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR); -// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD); + // strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD); set_python_path(scripts_path); } @@ -183,7 +183,7 @@ static void set_python_paths(void) { strcpy(scripts_path, user_path); strcat(scripts_path, PM3_USER_DIRECTORY); strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR); -// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD); + // strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD); set_python_path(scripts_path); } @@ -194,7 +194,7 @@ static void set_python_paths(void) { strcpy(scripts_path, exec_path); strcat(scripts_path, PM3_SHARE_RELPATH); strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR); -// strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD); + // strcat(scripts_path, PYTHON_LIBRARIES_WILDCARD); set_python_path(scripts_path); } } @@ -407,12 +407,16 @@ static int CmdScriptRun(const char *Cmd) { Py_Initialize(); #else PyConfig py_conf; - PyConfig_InitIsolatedConfig(&py_conf); - // Despite being isolated we probably want to allow users to use - // the Python packages they installed on their user directory as well - // as system ones. But it seems isolated mode still enforces them off. - py_conf.use_environment = 1; + // We need to use Python mode instead of isolated to avoid breaking stuff. + PyConfig_InitPythonConfig(&py_conf); + // Let's still make things bit safer by being as close as possible to isolated mode. + py_conf.configure_c_stdio = -1; + py_conf.faulthandler = 0; + py_conf.use_hash_seed = 0; + py_conf.install_signal_handlers = 0; + py_conf.parse_argv = 0; py_conf.user_site_directory = 1; + py_conf.use_environment = 0; #endif //int argc, char ** argv @@ -429,8 +433,13 @@ static int CmdScriptRun(const char *Cmd) { #else // The following line will implicitly pre-initialize Python PyConfig_SetBytesArgv(&py_conf, argc + 1, argv); + + // We disallowed in py_conf environment variables interfering with python interpreter's behavior. + // Let's manually enable the ones we truly need. // This is required by Proxspace to work with an isolated Python configuration PyConfig_SetBytesString(&py_conf, &py_conf.home, getenv("PYTHONHOME")); + // This is required for allowing `import pm3` in python scripts + PyConfig_SetBytesString(&py_conf, &py_conf.pythonpath_env, getenv("PYTHONPATH")); Py_InitializeFromConfig(&py_conf); From e1902ffa9668e0dc51d3c32a0648efdf0308cc87 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 18 Jan 2023 03:47:14 +0100 Subject: [PATCH 520/759] The Hack ID by Unicorn Team EM4100 emulator uses a VD/ID format in decimal --- client/src/cmdlfem410x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/src/cmdlfem410x.c b/client/src/cmdlfem410x.c index ea502fc07..29ad61bc9 100644 --- a/client/src/cmdlfem410x.c +++ b/client/src/cmdlfem410x.c @@ -229,6 +229,8 @@ void printEM410x(uint32_t hi, uint64_t id, bool verbose, int type) { uint8_t sebury2 = (id >> 16) & 0x7F; uint32_t sebury3 = id & 0x7FFFFF; PrintAndLogEx(SUCCESS, "Pattern Sebury : %d %d %d [0x%X 0x%X 0x%X]", sebury1, sebury2, sebury3, sebury1, sebury2, sebury3); + PrintAndLogEx(SUCCESS, "VD / ID : %03" PRIu64 " / %010" PRIu64, (id >> 32LL) & 0xFFFF, (id & 0xFFFFFFFF)); + PrintAndLogEx(INFO, "------------------------------------------------"); } } From e1c8c977c2d86f615bf41777bc37fc2284f98162 Mon Sep 17 00:00:00 2001 From: Krzysztof Zdulski Date: Wed, 18 Jan 2023 14:41:57 +0100 Subject: [PATCH 521/759] Check is sector is readable before attempting to read --- client/src/cmdhfmf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index b98f21c01..57de6ee70 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -971,6 +971,11 @@ static int CmdHF14AMfDump(const char *Cmd) { for (blockNo = 0; blockNo < mfNumBlocksPerSector(sectorNo); blockNo++) { bool received = false; current_key = MF_KEY_A; + uint8_t data_area = (sectorNo < 32) ? blockNo : blockNo / 5; + if (rights[sectorNo][data_area] == 0x07) { // no key would work + PrintAndLogEx(WARNING, "access rights do not allow reading of sector %2d block %3d, skipping", sectorNo, blockNo); + continue; + } for (tries = 0; tries < MIFARE_SECTOR_RETRY; tries++) { if (blockNo == mfNumBlocksPerSector(sectorNo) - 1) { // sector trailer. At least the Access Conditions can always be read with key A. @@ -982,7 +987,6 @@ static int CmdHF14AMfDump(const char *Cmd) { SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); } else { // data block. Check if it can be read with key A or key B - uint8_t data_area = (sectorNo < 32) ? blockNo : blockNo / 5; if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; @@ -992,10 +996,6 @@ static int CmdHF14AMfDump(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); - } else if (rights[sectorNo][data_area] == 0x07) { // no key would work - PrintAndLogEx(WARNING, "access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo); - // where do you want to go?? Next sector or block? - break; } else { // key A would work payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; From d96cef2b504155337b0696265dab642377208069 Mon Sep 17 00:00:00 2001 From: colonelborkmundus Date: Wed, 18 Jan 2023 11:36:07 -0500 Subject: [PATCH 522/759] modified: client/dictionaries/mfc_default_keys.dic --- client/dictionaries/mfc_default_keys.dic | 17 + client/src/cmdhflist.c | 2 +- client/src/pm3line_vocabulory.h | 1484 +++++++++++----------- 3 files changed, 760 insertions(+), 743 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index a336a32b5..433a91ce5 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1909,3 +1909,20 @@ D144BD193063 # Keys Swim 8627C10A7014 453857395635 +# +########################################## +# +# added by colonelborkmundus +# "the more, the marriott" mifare project +# +# mifare classic 1k - graduate hotel +0D258FE90296 +17193709ADF4 +# +# mifare classic 1K - marriott + + + + + + diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index a19ecdea9..232d4af19 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -318,7 +318,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i snprintf(exp, size, "AUTH-B(%d)", cmd[1]); break; } - case MIFARE_MAGIC_GDM_AUTH_KEYA:{ + case MIFARE_MAGIC_GDM_AUTH_KEYA: { if (cmdsize > 3) { snprintf(exp, size, "MAGIC AUTH-A(%d)", cmd[1]); MifareAuthState = masNt; diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 5a517c645..91a88a1c0 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -31,747 +31,747 @@ typedef struct vocabulory_s { } vocabulory_t; const static vocabulory_t vocabulory[] = { - { 1, "help" }, - { 0, "auto" }, - { 1, "clear" }, - { 1, "hints" }, - { 1, "msleep" }, - { 1, "rem" }, - { 1, "quit" }, - { 1, "exit" }, - { 1, "prefs help" }, - { 1, "prefs show" }, - { 1, "prefs get barmode" }, - { 1, "prefs get clientdebug" }, - { 1, "prefs get clientdelay" }, - { 1, "prefs get color" }, - { 1, "prefs get savepaths" }, - { 1, "prefs get emoji" }, - { 1, "prefs get hints" }, - { 1, "prefs get output" }, - { 1, "prefs get plotsliders" }, - { 1, "prefs set help" }, - { 1, "prefs set barmode" }, - { 1, "prefs set clientdebug" }, - { 1, "prefs set clientdelay" }, - { 1, "prefs set color" }, - { 1, "prefs set emoji" }, - { 1, "prefs set hints" }, - { 1, "prefs set savepaths" }, - { 1, "prefs set output" }, - { 1, "prefs set plotsliders" }, - { 1, "analyse help" }, - { 1, "analyse lcr" }, - { 1, "analyse crc" }, - { 1, "analyse chksum" }, - { 1, "analyse dates" }, - { 1, "analyse lfsr" }, - { 1, "analyse a" }, - { 1, "analyse nuid" }, - { 1, "analyse demodbuff" }, - { 1, "analyse freq" }, - { 1, "analyse foo" }, - { 1, "analyse units" }, - { 1, "data help" }, - { 1, "data biphaserawdecode" }, - { 1, "data detectclock" }, - { 1, "data fsktonrz" }, - { 1, "data manrawdecode" }, - { 1, "data modulation" }, - { 1, "data rawdemod" }, - { 1, "data askedgedetect" }, - { 1, "data autocorr" }, - { 1, "data dirthreshold" }, - { 1, "data decimate" }, - { 1, "data undecimate" }, - { 1, "data hide" }, - { 1, "data hpf" }, - { 1, "data iir" }, - { 1, "data grid" }, - { 1, "data ltrim" }, - { 1, "data mtrim" }, - { 1, "data norm" }, - { 1, "data plot" }, - { 1, "data rtrim" }, - { 1, "data setgraphmarkers" }, - { 1, "data shiftgraphzero" }, - { 1, "data timescale" }, - { 1, "data zerocrossings" }, - { 1, "data convertbitstream" }, - { 1, "data getbitstream" }, - { 1, "data asn1" }, - { 1, "data bin2hex" }, - { 0, "data bitsamples" }, - { 1, "data clear" }, - { 1, "data diff" }, - { 0, "data hexsamples" }, - { 1, "data hex2bin" }, - { 1, "data load" }, - { 1, "data print" }, - { 0, "data samples" }, - { 1, "data save" }, - { 1, "data setdebugmode" }, - { 0, "data tune" }, - { 1, "emv help" }, - { 0, "emv exec" }, - { 0, "emv pse" }, - { 0, "emv search" }, - { 0, "emv select" }, - { 0, "emv gpo" }, - { 0, "emv readrec" }, - { 0, "emv genac" }, - { 0, "emv challenge" }, - { 0, "emv intauth" }, - { 0, "emv scan" }, - { 1, "emv test" }, - { 1, "emv list" }, - { 0, "emv roca" }, - { 1, "hf help" }, - { 1, "hf list" }, - { 0, "hf plot" }, - { 0, "hf tune" }, - { 1, "hf search" }, - { 0, "hf sniff" }, - { 1, "hf 14a help" }, - { 1, "hf 14a list" }, - { 0, "hf 14a antifuzz" }, - { 0, "hf 14a config" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a info" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a raw" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a apdufind" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a ndefformat" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a ndefwrite" }, - { 1, "hf 14b help" }, - { 0, "hf 14b apdu" }, - { 0, "hf 14b dump" }, - { 0, "hf 14b info" }, - { 1, "hf 14b list" }, - { 0, "hf 14b ndefread" }, - { 0, "hf 14b raw" }, - { 0, "hf 14b reader" }, - { 0, "hf 14b sim" }, - { 0, "hf 14b sniff" }, - { 0, "hf 14b rdbl" }, - { 0, "hf 14b sriwrite" }, - { 1, "hf 14b view" }, - { 1, "hf 15 help" }, - { 1, "hf 15 list" }, - { 1, "hf 15 demod" }, - { 0, "hf 15 dump" }, - { 0, "hf 15 info" }, - { 0, "hf 15 sniff" }, - { 0, "hf 15 raw" }, - { 0, "hf 15 rdbl" }, - { 0, "hf 15 rdmulti" }, - { 0, "hf 15 reader" }, - { 0, "hf 15 restore" }, - { 0, "hf 15 samples" }, - { 0, "hf 15 eload" }, - { 0, "hf 15 esave" }, - { 0, "hf 15 eview" }, - { 0, "hf 15 sim" }, - { 0, "hf 15 slixdisable" }, - { 0, "hf 15 wrbl" }, - { 0, "hf 15 findafi" }, - { 0, "hf 15 writeafi" }, - { 0, "hf 15 writedsfid" }, - { 0, "hf 15 csetuid" }, - { 1, "hf cipurse help" }, - { 0, "hf cipurse info" }, - { 0, "hf cipurse select" }, - { 0, "hf cipurse auth" }, - { 0, "hf cipurse read" }, - { 0, "hf cipurse write" }, - { 0, "hf cipurse aread" }, - { 0, "hf cipurse awrite" }, - { 0, "hf cipurse formatall" }, - { 0, "hf cipurse create" }, - { 0, "hf cipurse delete" }, - { 0, "hf cipurse updkey" }, - { 0, "hf cipurse updakey" }, - { 0, "hf cipurse default" }, - { 1, "hf cipurse test" }, - { 1, "hf epa help" }, - { 0, "hf epa cnonces" }, - { 0, "hf epa replay" }, - { 0, "hf epa sim" }, - { 1, "hf emrtd help" }, - { 0, "hf emrtd dump" }, - { 1, "hf emrtd info" }, - { 1, "hf emrtd list" }, - { 1, "hf felica help" }, - { 1, "hf felica list" }, - { 0, "hf felica reader" }, - { 0, "hf felica info" }, - { 0, "hf felica sniff" }, - { 0, "hf felica raw" }, - { 0, "hf felica rdbl" }, - { 0, "hf felica wrbl" }, - { 0, "hf felica rqservice" }, - { 0, "hf felica rqresponse" }, - { 0, "hf felica scsvcode" }, - { 0, "hf felica rqsyscode" }, - { 0, "hf felica auth1" }, - { 0, "hf felica auth2" }, - { 0, "hf felica rqspecver" }, - { 0, "hf felica resetmode" }, - { 0, "hf felica litesim" }, - { 0, "hf felica litedump" }, - { 1, "hf fido help" }, - { 1, "hf fido list" }, - { 0, "hf fido info" }, - { 0, "hf fido reg" }, - { 0, "hf fido auth" }, - { 0, "hf fido make" }, - { 0, "hf fido assert" }, - { 1, "hf fudan help" }, - { 0, "hf fudan reader" }, - { 0, "hf fudan dump" }, - { 0, "hf fudan rdbl" }, - { 1, "hf fudan view" }, - { 0, "hf fudan wrbl" }, - { 1, "hf gallagher help" }, - { 0, "hf gallagher reader" }, - { 0, "hf gallagher clone" }, - { 0, "hf gallagher delete" }, - { 1, "hf gallagher diversifykey" }, - { 1, "hf gallagher decode" }, - { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 select" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 init" }, - { 0, "hf ksx6924 prec" }, - { 1, "hf jooki help" }, - { 0, "hf jooki clone" }, - { 1, "hf jooki decode" }, - { 1, "hf jooki encode" }, - { 0, "hf jooki sim" }, - { 1, "hf iclass help" }, - { 0, "hf iclass dump" }, - { 1, "hf iclass info" }, - { 1, "hf iclass list" }, - { 0, "hf iclass rdbl" }, - { 0, "hf iclass reader" }, - { 0, "hf iclass restore" }, - { 0, "hf iclass sniff" }, - { 0, "hf iclass wrbl" }, - { 0, "hf iclass chk" }, - { 1, "hf iclass loclass" }, - { 1, "hf iclass lookup" }, - { 0, "hf iclass sim" }, - { 0, "hf iclass eload" }, - { 0, "hf iclass esave" }, - { 0, "hf iclass eview" }, - { 1, "hf iclass configcard" }, - { 1, "hf iclass calcnewkey" }, - { 1, "hf iclass encode" }, - { 1, "hf iclass encrypt" }, - { 1, "hf iclass decrypt" }, - { 1, "hf iclass managekeys" }, - { 1, "hf iclass permutekey" }, - { 1, "hf iclass view" }, - { 1, "hf legic help" }, - { 0, "hf legic dump" }, - { 0, "hf legic info" }, - { 1, "hf legic list" }, - { 0, "hf legic rdbl" }, - { 0, "hf legic reader" }, - { 0, "hf legic restore" }, - { 0, "hf legic wipe" }, - { 0, "hf legic wrbl" }, - { 0, "hf legic sim" }, - { 0, "hf legic eload" }, - { 0, "hf legic esave" }, - { 0, "hf legic eview" }, - { 1, "hf legic crc" }, - { 1, "hf legic view" }, - { 1, "hf lto help" }, - { 0, "hf lto dump" }, - { 0, "hf lto info" }, - { 1, "hf lto list" }, - { 0, "hf lto rdbl" }, - { 0, "hf lto reader" }, - { 0, "hf lto restore" }, - { 0, "hf lto wrbl" }, - { 1, "hf mf help" }, - { 1, "hf mf list" }, - { 0, "hf mf darkside" }, - { 0, "hf mf nested" }, - { 1, "hf mf hardnested" }, - { 0, "hf mf staticnested" }, - { 0, "hf mf autopwn" }, - { 0, "hf mf nack" }, - { 0, "hf mf chk" }, - { 0, "hf mf fchk" }, - { 1, "hf mf decrypt" }, - { 0, "hf mf supercard" }, - { 0, "hf mf auth4" }, - { 1, "hf mf acl" }, - { 0, "hf mf dump" }, - { 1, "hf mf mad" }, - { 0, "hf mf personalize" }, - { 0, "hf mf rdbl" }, - { 0, "hf mf rdsc" }, - { 0, "hf mf restore" }, - { 0, "hf mf setmod" }, - { 1, "hf mf value" }, - { 1, "hf mf view" }, - { 0, "hf mf wipe" }, - { 0, "hf mf wrbl" }, - { 0, "hf mf sim" }, - { 0, "hf mf ecfill" }, - { 0, "hf mf eclr" }, - { 0, "hf mf egetblk" }, - { 0, "hf mf egetsc" }, - { 0, "hf mf ekeyprn" }, - { 0, "hf mf eload" }, - { 0, "hf mf esave" }, - { 0, "hf mf esetblk" }, - { 0, "hf mf eview" }, - { 0, "hf mf cgetblk" }, - { 0, "hf mf cgetsc" }, - { 0, "hf mf cload" }, - { 0, "hf mf csave" }, - { 0, "hf mf csetblk" }, - { 0, "hf mf csetuid" }, - { 0, "hf mf cview" }, - { 0, "hf mf cwipe" }, - { 0, "hf mf gen3uid" }, - { 0, "hf mf gen3blk" }, - { 0, "hf mf gen3freeze" }, - { 0, "hf mf ggetblk" }, - { 0, "hf mf gload" }, - { 0, "hf mf gsave" }, - { 0, "hf mf gsetblk" }, - { 0, "hf mf gview" }, - { 0, "hf mf ndefformat" }, - { 0, "hf mf ndefread" }, - { 0, "hf mf ndefwrite" }, - { 1, "hf mfp help" }, - { 0, "hf mfp info" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp commitp" }, - { 0, "hf mfp auth" }, - { 0, "hf mfp rdbl" }, - { 0, "hf mfp rdsc" }, - { 0, "hf mfp wrbl" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp mad" }, - { 0, "hf mfp ndefread" }, - { 1, "hf mfu help" }, - { 1, "hf mfu keygen" }, - { 1, "hf mfu pwdgen" }, - { 0, "hf mfu otptear" }, - { 0, "hf mfu cauth" }, - { 0, "hf mfu dump" }, - { 0, "hf mfu info" }, - { 0, "hf mfu ndefread" }, - { 0, "hf mfu rdbl" }, - { 0, "hf mfu restore" }, - { 1, "hf mfu view" }, - { 0, "hf mfu wrbl" }, - { 0, "hf mfu eload" }, - { 0, "hf mfu esave" }, - { 0, "hf mfu eview" }, - { 0, "hf mfu sim" }, - { 0, "hf mfu setpwd" }, - { 0, "hf mfu setuid" }, - { 1, "hf mfdes help" }, - { 0, "hf mfdes info" }, - { 0, "hf mfdes getuid" }, - { 0, "hf mfdes default" }, - { 0, "hf mfdes auth" }, - { 0, "hf mfdes chk" }, - { 0, "hf mfdes detect" }, - { 0, "hf mfdes freemem" }, - { 0, "hf mfdes setconfig" }, - { 0, "hf mfdes formatpicc" }, - { 1, "hf mfdes list" }, - { 0, "hf mfdes mad" }, - { 0, "hf mfdes lsapp" }, - { 0, "hf mfdes getaids" }, - { 0, "hf mfdes getappnames" }, - { 0, "hf mfdes bruteaid" }, - { 0, "hf mfdes createapp" }, - { 0, "hf mfdes deleteapp" }, - { 0, "hf mfdes selectapp" }, - { 0, "hf mfdes changekey" }, - { 0, "hf mfdes chkeysettings" }, - { 0, "hf mfdes getkeysettings" }, - { 0, "hf mfdes getkeyversions" }, - { 0, "hf mfdes getfileids" }, - { 0, "hf mfdes getfileisoids" }, - { 0, "hf mfdes lsfiles" }, - { 0, "hf mfdes dump" }, - { 0, "hf mfdes createfile" }, - { 0, "hf mfdes createvaluefile" }, - { 0, "hf mfdes createrecordfile" }, - { 0, "hf mfdes createmacfile" }, - { 0, "hf mfdes deletefile" }, - { 0, "hf mfdes getfilesettings" }, - { 0, "hf mfdes chfilesettings" }, - { 0, "hf mfdes read" }, - { 0, "hf mfdes write" }, - { 0, "hf mfdes value" }, - { 0, "hf mfdes clearrecfile" }, - { 1, "hf mfdes test" }, - { 1, "hf ntag424 help" }, - { 0, "hf ntag424 info" }, - { 0, "hf ntag424 sdm" }, - { 1, "hf ntag424 view" }, - { 1, "hf seos help" }, - { 0, "hf seos info" }, - { 1, "hf seos list" }, - { 1, "hf st25ta help" }, - { 0, "hf st25ta info" }, - { 1, "hf st25ta list" }, - { 1, "hf st25ta ndefread" }, - { 0, "hf st25ta protect" }, - { 0, "hf st25ta pwd" }, - { 0, "hf st25ta sim" }, - { 1, "hf thinfilm help" }, - { 0, "hf thinfilm info" }, - { 1, "hf thinfilm list" }, - { 0, "hf thinfilm sim" }, - { 1, "hf topaz help" }, - { 0, "hf topaz dump" }, - { 1, "hf topaz list" }, - { 0, "hf topaz info" }, - { 0, "hf topaz reader" }, - { 0, "hf topaz sim" }, - { 0, "hf topaz sniff" }, - { 0, "hf topaz raw" }, - { 0, "hf topaz rdbl" }, - { 1, "hf topaz view" }, - { 0, "hf topaz wrbl" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, - { 1, "hf xerox help" }, - { 0, "hf xerox info" }, - { 0, "hf xerox reader" }, - { 0, "hf xerox dump" }, - { 1, "hf waveshare help" }, - { 0, "hf waveshare loadbmp" }, - { 1, "hw help" }, - { 0, "hw break" }, - { 1, "hw connect" }, - { 0, "hw dbg" }, - { 0, "hw detectreader" }, - { 0, "hw fpgaoff" }, - { 0, "hw lcd" }, - { 0, "hw lcdreset" }, - { 0, "hw ping" }, - { 0, "hw readmem" }, - { 0, "hw reset" }, - { 0, "hw setlfdivisor" }, - { 0, "hw setmux" }, - { 0, "hw standalone" }, - { 0, "hw status" }, - { 0, "hw tearoff" }, - { 0, "hw tia" }, - { 0, "hw tune" }, - { 1, "hw version" }, - { 1, "lf help" }, - { 0, "lf config" }, - { 0, "lf cmdread" }, - { 0, "lf read" }, - { 1, "lf search" }, - { 0, "lf sim" }, - { 0, "lf simask" }, - { 0, "lf simfsk" }, - { 0, "lf simpsk" }, - { 0, "lf simbidir" }, - { 0, "lf sniff" }, - { 0, "lf tune" }, - { 1, "lf awid help" }, - { 1, "lf awid demod" }, - { 0, "lf awid reader" }, - { 0, "lf awid clone" }, - { 0, "lf awid sim" }, - { 0, "lf awid brute" }, - { 0, "lf awid watch" }, - { 1, "lf cotag help" }, - { 1, "lf cotag demod" }, - { 0, "lf cotag reader" }, - { 1, "lf destron help" }, - { 1, "lf destron demod" }, - { 0, "lf destron reader" }, - { 0, "lf destron clone" }, - { 0, "lf destron sim" }, - { 1, "lf em help" }, - { 1, "lf em 410x help" }, - { 1, "lf em 410x demod" }, - { 0, "lf em 410x reader" }, - { 0, "lf em 410x sim" }, - { 0, "lf em 410x brute" }, - { 0, "lf em 410x watch" }, - { 0, "lf em 410x spoof" }, - { 0, "lf em 410x clone" }, - { 1, "lf em 4x05 help" }, - { 0, "lf em 4x05 brute" }, - { 0, "lf em 4x05 chk" }, - { 1, "lf em 4x05 demod" }, - { 0, "lf em 4x05 dump" }, - { 0, "lf em 4x05 info" }, - { 0, "lf em 4x05 read" }, - { 1, "lf em 4x05 sniff" }, - { 0, "lf em 4x05 unlock" }, - { 0, "lf em 4x05 wipe" }, - { 0, "lf em 4x05 write" }, - { 1, "lf em 4x50 help" }, - { 0, "lf em 4x50 brute" }, - { 0, "lf em 4x50 chk" }, - { 0, "lf em 4x50 dump" }, - { 0, "lf em 4x50 info" }, - { 0, "lf em 4x50 login" }, - { 0, "lf em 4x50 rdbl" }, - { 0, "lf em 4x50 reader" }, - { 0, "lf em 4x50 restore" }, - { 0, "lf em 4x50 wrbl" }, - { 0, "lf em 4x50 wrpwd" }, - { 0, "lf em 4x50 wipe" }, - { 0, "lf em 4x50 eload" }, - { 0, "lf em 4x50 esave" }, - { 0, "lf em 4x50 eview" }, - { 0, "lf em 4x50 sim" }, - { 1, "lf em 4x70 help" }, - { 0, "lf em 4x70 info" }, - { 0, "lf em 4x70 write" }, - { 0, "lf em 4x70 unlock" }, - { 0, "lf em 4x70 auth" }, - { 0, "lf em 4x70 writepin" }, - { 0, "lf em 4x70 writekey" }, - { 1, "lf fdxb help" }, - { 1, "lf fdxb demod" }, - { 0, "lf fdxb reader" }, - { 0, "lf fdxb clone" }, - { 0, "lf fdxb sim" }, - { 1, "lf gallagher help" }, - { 1, "lf gallagher demod" }, - { 0, "lf gallagher reader" }, - { 0, "lf gallagher clone" }, - { 0, "lf gallagher sim" }, - { 1, "lf gproxii help" }, - { 1, "lf gproxii demod" }, - { 0, "lf gproxii reader" }, - { 0, "lf gproxii clone" }, - { 0, "lf gproxii sim" }, - { 1, "lf hid help" }, - { 1, "lf hid demod" }, - { 0, "lf hid reader" }, - { 0, "lf hid clone" }, - { 0, "lf hid sim" }, - { 0, "lf hid brute" }, - { 0, "lf hid watch" }, - { 1, "lf hitag help" }, - { 0, "lf hitag eload" }, - { 1, "lf hitag list" }, - { 0, "lf hitag info" }, - { 0, "lf hitag reader" }, - { 0, "lf hitag sim" }, - { 0, "lf hitag sniff" }, - { 0, "lf hitag writer" }, - { 0, "lf hitag dump" }, - { 0, "lf hitag cc" }, - { 1, "lf idteck help" }, - { 1, "lf idteck demod" }, - { 0, "lf idteck reader" }, - { 0, "lf idteck clone" }, - { 0, "lf idteck sim" }, - { 1, "lf indala help" }, - { 0, "lf indala brute" }, - { 1, "lf indala demod" }, - { 1, "lf indala altdemod" }, - { 0, "lf indala reader" }, - { 0, "lf indala clone" }, - { 0, "lf indala sim" }, - { 1, "lf io help" }, - { 1, "lf io demod" }, - { 0, "lf io reader" }, - { 0, "lf io clone" }, - { 0, "lf io sim" }, - { 0, "lf io watch" }, - { 1, "lf jablotron help" }, - { 1, "lf jablotron demod" }, - { 0, "lf jablotron reader" }, - { 0, "lf jablotron clone" }, - { 0, "lf jablotron sim" }, - { 1, "lf keri help" }, - { 1, "lf keri demod" }, - { 0, "lf keri reader" }, - { 0, "lf keri clone" }, - { 0, "lf keri sim" }, - { 1, "lf motorola help" }, - { 1, "lf motorola demod" }, - { 0, "lf motorola reader" }, - { 0, "lf motorola clone" }, - { 0, "lf motorola sim" }, - { 1, "lf nedap help" }, - { 1, "lf nedap demod" }, - { 0, "lf nedap reader" }, - { 0, "lf nedap clone" }, - { 0, "lf nedap sim" }, - { 1, "lf nexwatch help" }, - { 1, "lf nexwatch demod" }, - { 0, "lf nexwatch reader" }, - { 0, "lf nexwatch clone" }, - { 0, "lf nexwatch sim" }, - { 1, "lf noralsy help" }, - { 1, "lf noralsy demod" }, - { 0, "lf noralsy reader" }, - { 0, "lf noralsy clone" }, - { 0, "lf noralsy sim" }, - { 1, "lf pac help" }, - { 1, "lf pac demod" }, - { 0, "lf pac reader" }, - { 0, "lf pac clone" }, - { 0, "lf pac sim" }, - { 1, "lf paradox help" }, - { 1, "lf paradox demod" }, - { 0, "lf paradox reader" }, - { 0, "lf paradox clone" }, - { 0, "lf paradox sim" }, - { 1, "lf pcf7931 help" }, - { 0, "lf pcf7931 reader" }, - { 0, "lf pcf7931 write" }, - { 1, "lf pcf7931 config" }, - { 1, "lf presco help" }, - { 1, "lf presco demod" }, - { 0, "lf presco reader" }, - { 0, "lf presco clone" }, - { 0, "lf presco sim" }, - { 1, "lf pyramid help" }, - { 1, "lf pyramid demod" }, - { 0, "lf pyramid reader" }, - { 0, "lf pyramid clone" }, - { 0, "lf pyramid sim" }, - { 1, "lf securakey help" }, - { 1, "lf securakey demod" }, - { 0, "lf securakey reader" }, - { 0, "lf securakey clone" }, - { 0, "lf securakey sim" }, - { 1, "lf ti help" }, - { 1, "lf ti demod" }, - { 0, "lf ti reader" }, - { 0, "lf ti write" }, - { 1, "lf t55xx help" }, - { 0, "lf t55xx clonehelp" }, - { 1, "lf t55xx config" }, - { 0, "lf t55xx dangerraw" }, - { 1, "lf t55xx detect" }, - { 0, "lf t55xx deviceconfig" }, - { 0, "lf t55xx dump" }, - { 1, "lf t55xx info" }, - { 0, "lf t55xx p1detect" }, - { 0, "lf t55xx read" }, - { 0, "lf t55xx resetread" }, - { 0, "lf t55xx restore" }, - { 1, "lf t55xx trace" }, - { 0, "lf t55xx wakeup" }, - { 0, "lf t55xx write" }, - { 0, "lf t55xx bruteforce" }, - { 0, "lf t55xx chk" }, - { 0, "lf t55xx protect" }, - { 0, "lf t55xx recoverpw" }, - { 1, "lf t55xx sniff" }, - { 0, "lf t55xx special" }, - { 0, "lf t55xx wipe" }, - { 1, "lf viking help" }, - { 1, "lf viking demod" }, - { 0, "lf viking reader" }, - { 0, "lf viking clone" }, - { 0, "lf viking sim" }, - { 1, "lf visa2000 help" }, - { 1, "lf visa2000 demod" }, - { 0, "lf visa2000 reader" }, - { 0, "lf visa2000 clone" }, - { 0, "lf visa2000 sim" }, - { 1, "mem help" }, - { 0, "mem baudrate" }, - { 0, "mem dump" }, - { 0, "mem info" }, - { 0, "mem load" }, - { 0, "mem wipe" }, - { 1, "mem spiffs help" }, - { 0, "mem spiffs copy" }, - { 0, "mem spiffs check" }, - { 0, "mem spiffs dump" }, - { 0, "mem spiffs info" }, - { 0, "mem spiffs mount" }, - { 0, "mem spiffs remove" }, - { 0, "mem spiffs rename" }, - { 0, "mem spiffs test" }, - { 0, "mem spiffs tree" }, - { 0, "mem spiffs unmount" }, - { 0, "mem spiffs upload" }, - { 0, "mem spiffs view" }, - { 0, "mem spiffs wipe" }, - { 1, "nfc help" }, - { 1, "nfc decode" }, - { 0, "nfc type1 read" }, - { 1, "nfc type1 help" }, - { 0, "nfc type2 read" }, - { 1, "nfc type2 help" }, - { 0, "nfc type4a format" }, - { 0, "nfc type4a read" }, - { 0, "nfc type4a write" }, - { 0, "nfc type4a st25taread" }, - { 1, "nfc type4a help" }, - { 0, "nfc type4b read" }, - { 1, "nfc type4b help" }, - { 0, "nfc mf cformat" }, - { 0, "nfc mf cread" }, - { 0, "nfc mf cwrite" }, - { 0, "nfc mf pread" }, - { 1, "nfc mf help" }, - { 0, "nfc barcode read" }, - { 0, "nfc barcode sim" }, - { 1, "nfc barcode help" }, - { 1, "piv help" }, - { 0, "piv select" }, - { 0, "piv getdata" }, - { 0, "piv authsign" }, - { 0, "piv scan" }, - { 1, "piv list" }, - { 1, "smart help" }, - { 1, "smart list" }, - { 0, "smart info" }, - { 0, "smart reader" }, - { 0, "smart raw" }, - { 1, "smart upgrade" }, - { 0, "smart setclock" }, - { 0, "smart brute" }, - { 1, "script help" }, - { 1, "script list" }, - { 1, "script run" }, - { 1, "trace help" }, - { 1, "trace extract" }, - { 1, "trace list" }, - { 1, "trace load" }, - { 1, "trace save" }, - { 1, "usart help" }, - { 0, "usart btpin" }, - { 0, "usart btfactory" }, - { 0, "usart tx" }, - { 0, "usart rx" }, - { 0, "usart txrx" }, - { 0, "usart txhex" }, - { 0, "usart rxhex" }, - { 0, "usart config" }, - { 1, "wiegand help" }, - { 1, "wiegand list" }, - { 1, "wiegand encode" }, - { 1, "wiegand decode" }, + { 1, "help" }, + { 0, "auto" }, + { 1, "clear" }, + { 1, "hints" }, + { 1, "msleep" }, + { 1, "rem" }, + { 1, "quit" }, + { 1, "exit" }, + { 1, "prefs help" }, + { 1, "prefs show" }, + { 1, "prefs get barmode" }, + { 1, "prefs get clientdebug" }, + { 1, "prefs get clientdelay" }, + { 1, "prefs get color" }, + { 1, "prefs get savepaths" }, + { 1, "prefs get emoji" }, + { 1, "prefs get hints" }, + { 1, "prefs get output" }, + { 1, "prefs get plotsliders" }, + { 1, "prefs set help" }, + { 1, "prefs set barmode" }, + { 1, "prefs set clientdebug" }, + { 1, "prefs set clientdelay" }, + { 1, "prefs set color" }, + { 1, "prefs set emoji" }, + { 1, "prefs set hints" }, + { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, + { 1, "prefs set plotsliders" }, + { 1, "analyse help" }, + { 1, "analyse lcr" }, + { 1, "analyse crc" }, + { 1, "analyse chksum" }, + { 1, "analyse dates" }, + { 1, "analyse lfsr" }, + { 1, "analyse a" }, + { 1, "analyse nuid" }, + { 1, "analyse demodbuff" }, + { 1, "analyse freq" }, + { 1, "analyse foo" }, + { 1, "analyse units" }, + { 1, "data help" }, + { 1, "data biphaserawdecode" }, + { 1, "data detectclock" }, + { 1, "data fsktonrz" }, + { 1, "data manrawdecode" }, + { 1, "data modulation" }, + { 1, "data rawdemod" }, + { 1, "data askedgedetect" }, + { 1, "data autocorr" }, + { 1, "data dirthreshold" }, + { 1, "data decimate" }, + { 1, "data undecimate" }, + { 1, "data hide" }, + { 1, "data hpf" }, + { 1, "data iir" }, + { 1, "data grid" }, + { 1, "data ltrim" }, + { 1, "data mtrim" }, + { 1, "data norm" }, + { 1, "data plot" }, + { 1, "data rtrim" }, + { 1, "data setgraphmarkers" }, + { 1, "data shiftgraphzero" }, + { 1, "data timescale" }, + { 1, "data zerocrossings" }, + { 1, "data convertbitstream" }, + { 1, "data getbitstream" }, + { 1, "data asn1" }, + { 1, "data bin2hex" }, + { 0, "data bitsamples" }, + { 1, "data clear" }, + { 1, "data diff" }, + { 0, "data hexsamples" }, + { 1, "data hex2bin" }, + { 1, "data load" }, + { 1, "data print" }, + { 0, "data samples" }, + { 1, "data save" }, + { 1, "data setdebugmode" }, + { 0, "data tune" }, + { 1, "emv help" }, + { 0, "emv exec" }, + { 0, "emv pse" }, + { 0, "emv search" }, + { 0, "emv select" }, + { 0, "emv gpo" }, + { 0, "emv readrec" }, + { 0, "emv genac" }, + { 0, "emv challenge" }, + { 0, "emv intauth" }, + { 0, "emv scan" }, + { 1, "emv test" }, + { 1, "emv list" }, + { 0, "emv roca" }, + { 1, "hf help" }, + { 1, "hf list" }, + { 0, "hf plot" }, + { 0, "hf tune" }, + { 1, "hf search" }, + { 0, "hf sniff" }, + { 1, "hf 14a help" }, + { 1, "hf 14a list" }, + { 0, "hf 14a antifuzz" }, + { 0, "hf 14a config" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a info" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a apdu" }, + { 0, "hf 14a apdufind" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a ndefformat" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a ndefwrite" }, + { 1, "hf 14b help" }, + { 0, "hf 14b apdu" }, + { 0, "hf 14b dump" }, + { 0, "hf 14b info" }, + { 1, "hf 14b list" }, + { 0, "hf 14b ndefread" }, + { 0, "hf 14b raw" }, + { 0, "hf 14b reader" }, + { 0, "hf 14b sim" }, + { 0, "hf 14b sniff" }, + { 0, "hf 14b rdbl" }, + { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, + { 1, "hf 15 help" }, + { 1, "hf 15 list" }, + { 1, "hf 15 demod" }, + { 0, "hf 15 dump" }, + { 0, "hf 15 info" }, + { 0, "hf 15 sniff" }, + { 0, "hf 15 raw" }, + { 0, "hf 15 rdbl" }, + { 0, "hf 15 rdmulti" }, + { 0, "hf 15 reader" }, + { 0, "hf 15 restore" }, + { 0, "hf 15 samples" }, + { 0, "hf 15 eload" }, + { 0, "hf 15 esave" }, + { 0, "hf 15 eview" }, + { 0, "hf 15 sim" }, + { 0, "hf 15 slixdisable" }, + { 0, "hf 15 wrbl" }, + { 0, "hf 15 findafi" }, + { 0, "hf 15 writeafi" }, + { 0, "hf 15 writedsfid" }, + { 0, "hf 15 csetuid" }, + { 1, "hf cipurse help" }, + { 0, "hf cipurse info" }, + { 0, "hf cipurse select" }, + { 0, "hf cipurse auth" }, + { 0, "hf cipurse read" }, + { 0, "hf cipurse write" }, + { 0, "hf cipurse aread" }, + { 0, "hf cipurse awrite" }, + { 0, "hf cipurse formatall" }, + { 0, "hf cipurse create" }, + { 0, "hf cipurse delete" }, + { 0, "hf cipurse updkey" }, + { 0, "hf cipurse updakey" }, + { 0, "hf cipurse default" }, + { 1, "hf cipurse test" }, + { 1, "hf epa help" }, + { 0, "hf epa cnonces" }, + { 0, "hf epa replay" }, + { 0, "hf epa sim" }, + { 1, "hf emrtd help" }, + { 0, "hf emrtd dump" }, + { 1, "hf emrtd info" }, + { 1, "hf emrtd list" }, + { 1, "hf felica help" }, + { 1, "hf felica list" }, + { 0, "hf felica reader" }, + { 0, "hf felica info" }, + { 0, "hf felica sniff" }, + { 0, "hf felica raw" }, + { 0, "hf felica rdbl" }, + { 0, "hf felica wrbl" }, + { 0, "hf felica rqservice" }, + { 0, "hf felica rqresponse" }, + { 0, "hf felica scsvcode" }, + { 0, "hf felica rqsyscode" }, + { 0, "hf felica auth1" }, + { 0, "hf felica auth2" }, + { 0, "hf felica rqspecver" }, + { 0, "hf felica resetmode" }, + { 0, "hf felica litesim" }, + { 0, "hf felica litedump" }, + { 1, "hf fido help" }, + { 1, "hf fido list" }, + { 0, "hf fido info" }, + { 0, "hf fido reg" }, + { 0, "hf fido auth" }, + { 0, "hf fido make" }, + { 0, "hf fido assert" }, + { 1, "hf fudan help" }, + { 0, "hf fudan reader" }, + { 0, "hf fudan dump" }, + { 0, "hf fudan rdbl" }, + { 1, "hf fudan view" }, + { 0, "hf fudan wrbl" }, + { 1, "hf gallagher help" }, + { 0, "hf gallagher reader" }, + { 0, "hf gallagher clone" }, + { 0, "hf gallagher delete" }, + { 1, "hf gallagher diversifykey" }, + { 1, "hf gallagher decode" }, + { 1, "hf ksx6924 help" }, + { 0, "hf ksx6924 select" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 init" }, + { 0, "hf ksx6924 prec" }, + { 1, "hf jooki help" }, + { 0, "hf jooki clone" }, + { 1, "hf jooki decode" }, + { 1, "hf jooki encode" }, + { 0, "hf jooki sim" }, + { 1, "hf iclass help" }, + { 0, "hf iclass dump" }, + { 1, "hf iclass info" }, + { 1, "hf iclass list" }, + { 0, "hf iclass rdbl" }, + { 0, "hf iclass reader" }, + { 0, "hf iclass restore" }, + { 0, "hf iclass sniff" }, + { 0, "hf iclass wrbl" }, + { 0, "hf iclass chk" }, + { 1, "hf iclass loclass" }, + { 1, "hf iclass lookup" }, + { 0, "hf iclass sim" }, + { 0, "hf iclass eload" }, + { 0, "hf iclass esave" }, + { 0, "hf iclass eview" }, + { 1, "hf iclass configcard" }, + { 1, "hf iclass calcnewkey" }, + { 1, "hf iclass encode" }, + { 1, "hf iclass encrypt" }, + { 1, "hf iclass decrypt" }, + { 1, "hf iclass managekeys" }, + { 1, "hf iclass permutekey" }, + { 1, "hf iclass view" }, + { 1, "hf legic help" }, + { 0, "hf legic dump" }, + { 0, "hf legic info" }, + { 1, "hf legic list" }, + { 0, "hf legic rdbl" }, + { 0, "hf legic reader" }, + { 0, "hf legic restore" }, + { 0, "hf legic wipe" }, + { 0, "hf legic wrbl" }, + { 0, "hf legic sim" }, + { 0, "hf legic eload" }, + { 0, "hf legic esave" }, + { 0, "hf legic eview" }, + { 1, "hf legic crc" }, + { 1, "hf legic view" }, + { 1, "hf lto help" }, + { 0, "hf lto dump" }, + { 0, "hf lto info" }, + { 1, "hf lto list" }, + { 0, "hf lto rdbl" }, + { 0, "hf lto reader" }, + { 0, "hf lto restore" }, + { 0, "hf lto wrbl" }, + { 1, "hf mf help" }, + { 1, "hf mf list" }, + { 0, "hf mf darkside" }, + { 0, "hf mf nested" }, + { 1, "hf mf hardnested" }, + { 0, "hf mf staticnested" }, + { 0, "hf mf autopwn" }, + { 0, "hf mf nack" }, + { 0, "hf mf chk" }, + { 0, "hf mf fchk" }, + { 1, "hf mf decrypt" }, + { 0, "hf mf supercard" }, + { 0, "hf mf auth4" }, + { 1, "hf mf acl" }, + { 0, "hf mf dump" }, + { 1, "hf mf mad" }, + { 0, "hf mf personalize" }, + { 0, "hf mf rdbl" }, + { 0, "hf mf rdsc" }, + { 0, "hf mf restore" }, + { 0, "hf mf setmod" }, + { 1, "hf mf value" }, + { 1, "hf mf view" }, + { 0, "hf mf wipe" }, + { 0, "hf mf wrbl" }, + { 0, "hf mf sim" }, + { 0, "hf mf ecfill" }, + { 0, "hf mf eclr" }, + { 0, "hf mf egetblk" }, + { 0, "hf mf egetsc" }, + { 0, "hf mf ekeyprn" }, + { 0, "hf mf eload" }, + { 0, "hf mf esave" }, + { 0, "hf mf esetblk" }, + { 0, "hf mf eview" }, + { 0, "hf mf cgetblk" }, + { 0, "hf mf cgetsc" }, + { 0, "hf mf cload" }, + { 0, "hf mf csave" }, + { 0, "hf mf csetblk" }, + { 0, "hf mf csetuid" }, + { 0, "hf mf cview" }, + { 0, "hf mf cwipe" }, + { 0, "hf mf gen3uid" }, + { 0, "hf mf gen3blk" }, + { 0, "hf mf gen3freeze" }, + { 0, "hf mf ggetblk" }, + { 0, "hf mf gload" }, + { 0, "hf mf gsave" }, + { 0, "hf mf gsetblk" }, + { 0, "hf mf gview" }, + { 0, "hf mf ndefformat" }, + { 0, "hf mf ndefread" }, + { 0, "hf mf ndefwrite" }, + { 1, "hf mfp help" }, + { 0, "hf mfp info" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp auth" }, + { 0, "hf mfp rdbl" }, + { 0, "hf mfp rdsc" }, + { 0, "hf mfp wrbl" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp mad" }, + { 0, "hf mfp ndefread" }, + { 1, "hf mfu help" }, + { 1, "hf mfu keygen" }, + { 1, "hf mfu pwdgen" }, + { 0, "hf mfu otptear" }, + { 0, "hf mfu cauth" }, + { 0, "hf mfu dump" }, + { 0, "hf mfu info" }, + { 0, "hf mfu ndefread" }, + { 0, "hf mfu rdbl" }, + { 0, "hf mfu restore" }, + { 1, "hf mfu view" }, + { 0, "hf mfu wrbl" }, + { 0, "hf mfu eload" }, + { 0, "hf mfu esave" }, + { 0, "hf mfu eview" }, + { 0, "hf mfu sim" }, + { 0, "hf mfu setpwd" }, + { 0, "hf mfu setuid" }, + { 1, "hf mfdes help" }, + { 0, "hf mfdes info" }, + { 0, "hf mfdes getuid" }, + { 0, "hf mfdes default" }, + { 0, "hf mfdes auth" }, + { 0, "hf mfdes chk" }, + { 0, "hf mfdes detect" }, + { 0, "hf mfdes freemem" }, + { 0, "hf mfdes setconfig" }, + { 0, "hf mfdes formatpicc" }, + { 1, "hf mfdes list" }, + { 0, "hf mfdes mad" }, + { 0, "hf mfdes lsapp" }, + { 0, "hf mfdes getaids" }, + { 0, "hf mfdes getappnames" }, + { 0, "hf mfdes bruteaid" }, + { 0, "hf mfdes createapp" }, + { 0, "hf mfdes deleteapp" }, + { 0, "hf mfdes selectapp" }, + { 0, "hf mfdes changekey" }, + { 0, "hf mfdes chkeysettings" }, + { 0, "hf mfdes getkeysettings" }, + { 0, "hf mfdes getkeyversions" }, + { 0, "hf mfdes getfileids" }, + { 0, "hf mfdes getfileisoids" }, + { 0, "hf mfdes lsfiles" }, + { 0, "hf mfdes dump" }, + { 0, "hf mfdes createfile" }, + { 0, "hf mfdes createvaluefile" }, + { 0, "hf mfdes createrecordfile" }, + { 0, "hf mfdes createmacfile" }, + { 0, "hf mfdes deletefile" }, + { 0, "hf mfdes getfilesettings" }, + { 0, "hf mfdes chfilesettings" }, + { 0, "hf mfdes read" }, + { 0, "hf mfdes write" }, + { 0, "hf mfdes value" }, + { 0, "hf mfdes clearrecfile" }, + { 1, "hf mfdes test" }, + { 1, "hf ntag424 help" }, + { 0, "hf ntag424 info" }, + { 0, "hf ntag424 sdm" }, + { 1, "hf ntag424 view" }, + { 1, "hf seos help" }, + { 0, "hf seos info" }, + { 1, "hf seos list" }, + { 1, "hf st25ta help" }, + { 0, "hf st25ta info" }, + { 1, "hf st25ta list" }, + { 1, "hf st25ta ndefread" }, + { 0, "hf st25ta protect" }, + { 0, "hf st25ta pwd" }, + { 0, "hf st25ta sim" }, + { 1, "hf thinfilm help" }, + { 0, "hf thinfilm info" }, + { 1, "hf thinfilm list" }, + { 0, "hf thinfilm sim" }, + { 1, "hf topaz help" }, + { 0, "hf topaz dump" }, + { 1, "hf topaz list" }, + { 0, "hf topaz info" }, + { 0, "hf topaz reader" }, + { 0, "hf topaz sim" }, + { 0, "hf topaz sniff" }, + { 0, "hf topaz raw" }, + { 0, "hf topaz rdbl" }, + { 1, "hf topaz view" }, + { 0, "hf topaz wrbl" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, + { 0, "hf xerox dump" }, + { 1, "hf waveshare help" }, + { 0, "hf waveshare loadbmp" }, + { 1, "hw help" }, + { 0, "hw break" }, + { 1, "hw connect" }, + { 0, "hw dbg" }, + { 0, "hw detectreader" }, + { 0, "hw fpgaoff" }, + { 0, "hw lcd" }, + { 0, "hw lcdreset" }, + { 0, "hw ping" }, + { 0, "hw readmem" }, + { 0, "hw reset" }, + { 0, "hw setlfdivisor" }, + { 0, "hw setmux" }, + { 0, "hw standalone" }, + { 0, "hw status" }, + { 0, "hw tearoff" }, + { 0, "hw tia" }, + { 0, "hw tune" }, + { 1, "hw version" }, + { 1, "lf help" }, + { 0, "lf config" }, + { 0, "lf cmdread" }, + { 0, "lf read" }, + { 1, "lf search" }, + { 0, "lf sim" }, + { 0, "lf simask" }, + { 0, "lf simfsk" }, + { 0, "lf simpsk" }, + { 0, "lf simbidir" }, + { 0, "lf sniff" }, + { 0, "lf tune" }, + { 1, "lf awid help" }, + { 1, "lf awid demod" }, + { 0, "lf awid reader" }, + { 0, "lf awid clone" }, + { 0, "lf awid sim" }, + { 0, "lf awid brute" }, + { 0, "lf awid watch" }, + { 1, "lf cotag help" }, + { 1, "lf cotag demod" }, + { 0, "lf cotag reader" }, + { 1, "lf destron help" }, + { 1, "lf destron demod" }, + { 0, "lf destron reader" }, + { 0, "lf destron clone" }, + { 0, "lf destron sim" }, + { 1, "lf em help" }, + { 1, "lf em 410x help" }, + { 1, "lf em 410x demod" }, + { 0, "lf em 410x reader" }, + { 0, "lf em 410x sim" }, + { 0, "lf em 410x brute" }, + { 0, "lf em 410x watch" }, + { 0, "lf em 410x spoof" }, + { 0, "lf em 410x clone" }, + { 1, "lf em 4x05 help" }, + { 0, "lf em 4x05 brute" }, + { 0, "lf em 4x05 chk" }, + { 1, "lf em 4x05 demod" }, + { 0, "lf em 4x05 dump" }, + { 0, "lf em 4x05 info" }, + { 0, "lf em 4x05 read" }, + { 1, "lf em 4x05 sniff" }, + { 0, "lf em 4x05 unlock" }, + { 0, "lf em 4x05 wipe" }, + { 0, "lf em 4x05 write" }, + { 1, "lf em 4x50 help" }, + { 0, "lf em 4x50 brute" }, + { 0, "lf em 4x50 chk" }, + { 0, "lf em 4x50 dump" }, + { 0, "lf em 4x50 info" }, + { 0, "lf em 4x50 login" }, + { 0, "lf em 4x50 rdbl" }, + { 0, "lf em 4x50 reader" }, + { 0, "lf em 4x50 restore" }, + { 0, "lf em 4x50 wrbl" }, + { 0, "lf em 4x50 wrpwd" }, + { 0, "lf em 4x50 wipe" }, + { 0, "lf em 4x50 eload" }, + { 0, "lf em 4x50 esave" }, + { 0, "lf em 4x50 eview" }, + { 0, "lf em 4x50 sim" }, + { 1, "lf em 4x70 help" }, + { 0, "lf em 4x70 info" }, + { 0, "lf em 4x70 write" }, + { 0, "lf em 4x70 unlock" }, + { 0, "lf em 4x70 auth" }, + { 0, "lf em 4x70 writepin" }, + { 0, "lf em 4x70 writekey" }, + { 1, "lf fdxb help" }, + { 1, "lf fdxb demod" }, + { 0, "lf fdxb reader" }, + { 0, "lf fdxb clone" }, + { 0, "lf fdxb sim" }, + { 1, "lf gallagher help" }, + { 1, "lf gallagher demod" }, + { 0, "lf gallagher reader" }, + { 0, "lf gallagher clone" }, + { 0, "lf gallagher sim" }, + { 1, "lf gproxii help" }, + { 1, "lf gproxii demod" }, + { 0, "lf gproxii reader" }, + { 0, "lf gproxii clone" }, + { 0, "lf gproxii sim" }, + { 1, "lf hid help" }, + { 1, "lf hid demod" }, + { 0, "lf hid reader" }, + { 0, "lf hid clone" }, + { 0, "lf hid sim" }, + { 0, "lf hid brute" }, + { 0, "lf hid watch" }, + { 1, "lf hitag help" }, + { 0, "lf hitag eload" }, + { 1, "lf hitag list" }, + { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, + { 0, "lf hitag sim" }, + { 0, "lf hitag sniff" }, + { 0, "lf hitag writer" }, + { 0, "lf hitag dump" }, + { 0, "lf hitag cc" }, + { 1, "lf idteck help" }, + { 1, "lf idteck demod" }, + { 0, "lf idteck reader" }, + { 0, "lf idteck clone" }, + { 0, "lf idteck sim" }, + { 1, "lf indala help" }, + { 0, "lf indala brute" }, + { 1, "lf indala demod" }, + { 1, "lf indala altdemod" }, + { 0, "lf indala reader" }, + { 0, "lf indala clone" }, + { 0, "lf indala sim" }, + { 1, "lf io help" }, + { 1, "lf io demod" }, + { 0, "lf io reader" }, + { 0, "lf io clone" }, + { 0, "lf io sim" }, + { 0, "lf io watch" }, + { 1, "lf jablotron help" }, + { 1, "lf jablotron demod" }, + { 0, "lf jablotron reader" }, + { 0, "lf jablotron clone" }, + { 0, "lf jablotron sim" }, + { 1, "lf keri help" }, + { 1, "lf keri demod" }, + { 0, "lf keri reader" }, + { 0, "lf keri clone" }, + { 0, "lf keri sim" }, + { 1, "lf motorola help" }, + { 1, "lf motorola demod" }, + { 0, "lf motorola reader" }, + { 0, "lf motorola clone" }, + { 0, "lf motorola sim" }, + { 1, "lf nedap help" }, + { 1, "lf nedap demod" }, + { 0, "lf nedap reader" }, + { 0, "lf nedap clone" }, + { 0, "lf nedap sim" }, + { 1, "lf nexwatch help" }, + { 1, "lf nexwatch demod" }, + { 0, "lf nexwatch reader" }, + { 0, "lf nexwatch clone" }, + { 0, "lf nexwatch sim" }, + { 1, "lf noralsy help" }, + { 1, "lf noralsy demod" }, + { 0, "lf noralsy reader" }, + { 0, "lf noralsy clone" }, + { 0, "lf noralsy sim" }, + { 1, "lf pac help" }, + { 1, "lf pac demod" }, + { 0, "lf pac reader" }, + { 0, "lf pac clone" }, + { 0, "lf pac sim" }, + { 1, "lf paradox help" }, + { 1, "lf paradox demod" }, + { 0, "lf paradox reader" }, + { 0, "lf paradox clone" }, + { 0, "lf paradox sim" }, + { 1, "lf pcf7931 help" }, + { 0, "lf pcf7931 reader" }, + { 0, "lf pcf7931 write" }, + { 1, "lf pcf7931 config" }, + { 1, "lf presco help" }, + { 1, "lf presco demod" }, + { 0, "lf presco reader" }, + { 0, "lf presco clone" }, + { 0, "lf presco sim" }, + { 1, "lf pyramid help" }, + { 1, "lf pyramid demod" }, + { 0, "lf pyramid reader" }, + { 0, "lf pyramid clone" }, + { 0, "lf pyramid sim" }, + { 1, "lf securakey help" }, + { 1, "lf securakey demod" }, + { 0, "lf securakey reader" }, + { 0, "lf securakey clone" }, + { 0, "lf securakey sim" }, + { 1, "lf ti help" }, + { 1, "lf ti demod" }, + { 0, "lf ti reader" }, + { 0, "lf ti write" }, + { 1, "lf t55xx help" }, + { 0, "lf t55xx clonehelp" }, + { 1, "lf t55xx config" }, + { 0, "lf t55xx dangerraw" }, + { 1, "lf t55xx detect" }, + { 0, "lf t55xx deviceconfig" }, + { 0, "lf t55xx dump" }, + { 1, "lf t55xx info" }, + { 0, "lf t55xx p1detect" }, + { 0, "lf t55xx read" }, + { 0, "lf t55xx resetread" }, + { 0, "lf t55xx restore" }, + { 1, "lf t55xx trace" }, + { 0, "lf t55xx wakeup" }, + { 0, "lf t55xx write" }, + { 0, "lf t55xx bruteforce" }, + { 0, "lf t55xx chk" }, + { 0, "lf t55xx protect" }, + { 0, "lf t55xx recoverpw" }, + { 1, "lf t55xx sniff" }, + { 0, "lf t55xx special" }, + { 0, "lf t55xx wipe" }, + { 1, "lf viking help" }, + { 1, "lf viking demod" }, + { 0, "lf viking reader" }, + { 0, "lf viking clone" }, + { 0, "lf viking sim" }, + { 1, "lf visa2000 help" }, + { 1, "lf visa2000 demod" }, + { 0, "lf visa2000 reader" }, + { 0, "lf visa2000 clone" }, + { 0, "lf visa2000 sim" }, + { 1, "mem help" }, + { 0, "mem baudrate" }, + { 0, "mem dump" }, + { 0, "mem info" }, + { 0, "mem load" }, + { 0, "mem wipe" }, + { 1, "mem spiffs help" }, + { 0, "mem spiffs copy" }, + { 0, "mem spiffs check" }, + { 0, "mem spiffs dump" }, + { 0, "mem spiffs info" }, + { 0, "mem spiffs mount" }, + { 0, "mem spiffs remove" }, + { 0, "mem spiffs rename" }, + { 0, "mem spiffs test" }, + { 0, "mem spiffs tree" }, + { 0, "mem spiffs unmount" }, + { 0, "mem spiffs upload" }, + { 0, "mem spiffs view" }, + { 0, "mem spiffs wipe" }, + { 1, "nfc help" }, + { 1, "nfc decode" }, + { 0, "nfc type1 read" }, + { 1, "nfc type1 help" }, + { 0, "nfc type2 read" }, + { 1, "nfc type2 help" }, + { 0, "nfc type4a format" }, + { 0, "nfc type4a read" }, + { 0, "nfc type4a write" }, + { 0, "nfc type4a st25taread" }, + { 1, "nfc type4a help" }, + { 0, "nfc type4b read" }, + { 1, "nfc type4b help" }, + { 0, "nfc mf cformat" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf cwrite" }, + { 0, "nfc mf pread" }, + { 1, "nfc mf help" }, + { 0, "nfc barcode read" }, + { 0, "nfc barcode sim" }, + { 1, "nfc barcode help" }, + { 1, "piv help" }, + { 0, "piv select" }, + { 0, "piv getdata" }, + { 0, "piv authsign" }, + { 0, "piv scan" }, + { 1, "piv list" }, + { 1, "smart help" }, + { 1, "smart list" }, + { 0, "smart info" }, + { 0, "smart reader" }, + { 0, "smart raw" }, + { 1, "smart upgrade" }, + { 0, "smart setclock" }, + { 0, "smart brute" }, + { 1, "script help" }, + { 1, "script list" }, + { 1, "script run" }, + { 1, "trace help" }, + { 1, "trace extract" }, + { 1, "trace list" }, + { 1, "trace load" }, + { 1, "trace save" }, + { 1, "usart help" }, + { 0, "usart btpin" }, + { 0, "usart btfactory" }, + { 0, "usart tx" }, + { 0, "usart rx" }, + { 0, "usart txrx" }, + { 0, "usart txhex" }, + { 0, "usart rxhex" }, + { 0, "usart config" }, + { 1, "wiegand help" }, + { 1, "wiegand list" }, + { 1, "wiegand encode" }, + { 1, "wiegand decode" }, {0, NULL} }; @@ -779,4 +779,4 @@ const static vocabulory_t vocabulory[] = { } #endif -#endif \ No newline at end of file +#endif From dbe53506b579665f82b773c97f010e8d5f7b592f Mon Sep 17 00:00:00 2001 From: colonelborkmundus Date: Wed, 18 Jan 2023 12:52:10 -0500 Subject: [PATCH 523/759] added additional keys to graduate hotel card --- client/dictionaries/mfc_default_keys.dic | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 433a91ce5..9255031de 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1919,9 +1919,10 @@ D144BD193063 0D258FE90296 17193709ADF4 # -# mifare classic 1K - marriott - - +# mifare classic 1k - westin +B578F38A5C61 +# +# mifare classic 1k From 88d242d10ab80c5643e78201aa60cd03af144d33 Mon Sep 17 00:00:00 2001 From: colonelborkmundus Date: Wed, 18 Jan 2023 13:36:50 -0500 Subject: [PATCH 524/759] yo dawg i heard you like keys so i added more keys --- client/dictionaries/mfc_default_keys.dic | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 9255031de..c4032b081 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1918,12 +1918,17 @@ D144BD193063 # mifare classic 1k - graduate hotel 0D258FE90296 17193709ADF4 +C49DAE1C6049 +209A2B910545 +752FBB5B7B45 # # mifare classic 1k - westin B578F38A5C61 # -# mifare classic 1k - - - - +# mifare classic 1k EV1 - marriott +D01AFEEB890A +7B4DFC6D6525 +23C9FDD9A366 +3119A70628EB +30AAD6A711EF +1330824CD356 \ No newline at end of file From de3514dc840a823a04b4faec9f76ceb77162ed22 Mon Sep 17 00:00:00 2001 From: colonelborkmundus Date: Wed, 18 Jan 2023 13:53:08 -0500 Subject: [PATCH 525/759] added more keys --- client/dictionaries/mfc_default_keys.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index c4032b081..3ba6ccc10 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1924,6 +1924,8 @@ C49DAE1C6049 # # mifare classic 1k - westin B578F38A5C61 +8C29F8320617 +5697519A8F02 # # mifare classic 1k EV1 - marriott D01AFEEB890A From cc0e5477dd8936c3eb9b9d22ab9117f449aff141 Mon Sep 17 00:00:00 2001 From: colonelborkmundus Date: Wed, 18 Jan 2023 15:25:25 -0500 Subject: [PATCH 526/759] added more keys, removed accidental dupes --- client/dictionaries/mfc_default_keys.dic | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 3ba6ccc10..235cabe20 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1916,21 +1916,29 @@ D144BD193063 # "the more, the marriott" mifare project # # mifare classic 1k - graduate hotel -0D258FE90296 -17193709ADF4 C49DAE1C6049 209A2B910545 -752FBB5B7B45 # # mifare classic 1k - westin -B578F38A5C61 8C29F8320617 5697519A8F02 +7D0A1C277C05 +2058580A941F +C40964215509 +D44CFC178460 # # mifare classic 1k EV1 - marriott -D01AFEEB890A 7B4DFC6D6525 23C9FDD9A366 3119A70628EB 30AAD6A711EF -1330824CD356 \ No newline at end of file +1330824CD356 +# +# mifare classic 1k - AC hotels marriott +8EA8EC3F2320 +# +# mifare classic 1k - the ritz-carlton +30FB20D0EFEF +# +# mifare classic 1k - unknown +722538817225 \ No newline at end of file From f9a65505de7da07248d3e4f6eb1c74728c25dfea Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Jan 2023 20:04:27 +0100 Subject: [PATCH 527/759] added tesla info command, with some of the data that is available. Needed to fix the apdu chaining and a sneaky bug in get_sw since the apdu response was larger then 256 --- client/CMakeLists.txt | 1 + client/Makefile | 1 + client/src/cmdhf.c | 4 +- client/src/cmdhf14a.c | 35 ++++--- client/src/cmdhf14a.h | 3 + client/src/cmdhftesla.c | 221 ++++++++++++++++++++++++++++++++++++++++ client/src/cmdhftesla.h | 26 +++++ common/commonutil.c | 4 +- common/commonutil.h | 2 +- 9 files changed, 281 insertions(+), 16 deletions(-) create mode 100644 client/src/cmdhftesla.c create mode 100644 client/src/cmdhftesla.h diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 5519b2e77..5bd3ebddd 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -293,6 +293,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdhfseos.c ${PM3_ROOT}/client/src/cmdhfst.c ${PM3_ROOT}/client/src/cmdhfst25ta.c + ${PM3_ROOT}/client/src/cmdhftesla.c ${PM3_ROOT}/client/src/cmdhftexkom.c ${PM3_ROOT}/client/src/cmdhfthinfilm.c ${PM3_ROOT}/client/src/cmdhftopaz.c diff --git a/client/Makefile b/client/Makefile index 03f022297..b08eb0acb 100644 --- a/client/Makefile +++ b/client/Makefile @@ -583,6 +583,7 @@ SRCS = mifare/aiddesfire.c \ cmdhfseos.c \ cmdhfst.c \ cmdhfst25ta.c \ + cmdhftesla.c \ cmdhfthinfilm.c \ cmdhftopaz.c \ cmdhftexkom.c \ diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 7bba6d41a..97f7df3c7 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -50,6 +50,7 @@ #include "cmdhftexkom.h" // Texkom #include "cmdhfxerox.h" // Xerox #include "cmdhffudan.h" // Fudan cards +#include "cmdhftesla.h" // Tesla #include "cmdtrace.h" // trace list #include "ui.h" #include "proxgui.h" @@ -493,9 +494,10 @@ static command_t CommandTable[] = { {"ntag424", CmdHF_ntag424, AlwaysAvailable, "{ NXP NTAG 4242 DNA RFIDs... }"}, {"seos", CmdHFSeos, AlwaysAvailable, "{ SEOS RFIDs... }"}, {"st25ta", CmdHFST25TA, AlwaysAvailable, "{ ST25TA RFIDs... }"}, + {"tesla", CmdHFTESLA, AlwaysAvailable, "{ TESLA Cards... }"}, + {"texkom", CmdHFTexkom, AlwaysAvailable, "{ Texkom RFIDs... }"}, {"thinfilm", CmdHFThinfilm, AlwaysAvailable, "{ Thinfilm RFIDs... }"}, {"topaz", CmdHFTopaz, AlwaysAvailable, "{ TOPAZ (NFC Type 1) RFIDs... }"}, - {"texkom", CmdHFTexkom, AlwaysAvailable, "{ Texkom RFIDs... }"}, {"xerox", CmdHFXerox, AlwaysAvailable, "{ Fuji/Xerox cartridge RFIDs... }"}, {"waveshare", CmdHFWaveshare, AlwaysAvailable, "{ Waveshare NFC ePaper... }"}, {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 0858150d0..d0ba31cd0 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -42,7 +42,13 @@ #include "desfire.h" // desfire enums #include "mifare/desfirecore.h" // desfire context -static bool APDUInFramingEnable = true; +static bool g_apdu_in_framing_enable = true; +bool Get_apdu_in_framing(void) { + return g_apdu_in_framing_enable; +} +void Set_apdu_in_framing(bool v) { + g_apdu_in_framing_enable = v; +} static int CmdHelp(const char *Cmd); static int waitCmd(bool i_select, uint32_t timeout, bool verbose); @@ -1050,7 +1056,7 @@ int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool lea int res; // 3 byte here - 1b framing header, 2b crc16 - if (APDUInFramingEnable && + if (g_apdu_in_framing_enable && ((gs_frame_len && (datainlen > gs_frame_len - 3)) || (datainlen > PM3_CMD_DATA_SIZE - 3))) { int clen = 0; @@ -1454,29 +1460,34 @@ static int CmdHF14AChaining(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 14a chaining", "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", - "hf 14a chaining disable -> disable chaining\n" + "hf 14a chaining --off -> disable chaining\n" "hf 14a chaining -> show chaining enable/disable state\n"); void *argtable[] = { arg_param_begin, - arg_str0(NULL, NULL, "", NULL), + arg_lit0("1", "on", "enabled chaining"), + arg_lit0("0", "off", "disable chaining"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - struct arg_str *str = arg_get_str(ctx, 1); - int len = arg_get_str_len(ctx, 1); + bool on = arg_get_lit(ctx, 1); + bool off = arg_get_lit(ctx, 2); - if (len && (!strcmp(str->sval[0], "enable") || !strcmp(str->sval[0], "1"))) - APDUInFramingEnable = true; + if ((on + off) > 1) { + PrintAndLogEx(INFO, "Select only one option"); + return PM3_EINVARG; + } - if (len && (!strcmp(str->sval[0], "disable") || !strcmp(str->sval[0], "0"))) - APDUInFramingEnable = false; + if (on) + Set_apdu_in_framing(true); + + if (off) + Set_apdu_in_framing(false); CLIParserFree(ctx); - PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", APDUInFramingEnable ? "enabled" : "disabled"); - + PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", g_apdu_in_framing_enable ? "enabled" : "disabled"); return PM3_SUCCESS; } diff --git a/client/src/cmdhf14a.h b/client/src/cmdhf14a.h index 2ac2672a1..a811db66b 100644 --- a/client/src/cmdhf14a.h +++ b/client/src/cmdhf14a.h @@ -53,4 +53,7 @@ int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool lea int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode); int SelectCard14443A_4(bool disconnect, bool verbose, iso14a_card_select_t *card); + +bool Get_apdu_in_framing(void); +void Set_apdu_in_framing(bool v); #endif diff --git a/client/src/cmdhftesla.c b/client/src/cmdhftesla.c new file mode 100644 index 000000000..62e3bab18 --- /dev/null +++ b/client/src/cmdhftesla.c @@ -0,0 +1,221 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// High frequency ISO14443A / TESLA commands +//----------------------------------------------------------------------------- + +#include "cmdhftesla.h" +#include +#include +#include "cmdparser.h" // command_t +#include "comms.h" // clearCommandBuffer +#include "cmdtrace.h" +#include "cliparser.h" +#include "cmdhf14a.h" +#include "protocols.h" // definitions of ISO14A/7816 protocol +#include "iso7816/apduinfo.h" // GetAPDUCodeDescription +#include "commonutil.h" // get_sw +#include "protocols.h" // ISO7816 APDU return co-des +#include "ui.h" +#include "cmdhf14a.h" // apdu chaining + +#define TIMEOUT 2000 + +static int CmdHelp(const char *Cmd); + +/** + * 0x80 0x00 0x00 0x00 - get interface object + 0x80 0x01 0x00 0x00 - load data from storage + 0x80 0x02 KEY_INDEX 0x00 - initialize key pair + 0x80 0x03 KEY_INDEX 0x00 - generate key pair + 0x80 0x04 KEY_INDEX 0x00 - get public key + 0x80 0x05 CRT_INDEX 0x00 - load certificate + 0x80 0x06 CRT_INDEX 0x00 - get certificate + 0x80 0x07 0x00 0x00 - get version + 0x80 0x08 0x00 0x00 - confirm prepersonalization + 0x80 0x10 KEY_INDEX 0x00 - sign challenge + 0x80 0x11 KEY_INDEX 0x00 - dh key exchange + +*/ + +// TESLA +static int info_hf_tesla(void) { + + bool activate_field = true; + bool keep_field_on = true; + uint8_t response[PM3_CMD_DATA_SIZE]; + int resplen = 0; + + // --------------- Select TESLA application ---------------- + uint8_t aSELECT_AID[80]; + int aSELECT_AID_n = 0; + param_gethex_to_eol("00a404000a7465736c614c6f676963", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n); + int res = ExchangeAPDU14a(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen); + if (res != PM3_SUCCESS) { + DropField(); + return res; + } + + if (resplen < 2) { + DropField(); + return PM3_ESOFT; + } + + uint16_t sw = get_sw(response, resplen); + if (sw != ISO7816_OK) { + PrintAndLogEx(ERR, "Selecting TESLA aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); + DropField(); + return PM3_ESOFT; + } + + activate_field = false; + keep_field_on = true; + + // --------------- ECDH public key file reading ---------------- + for (uint8_t i = 0; i < 3; i++) { + + uint8_t aSELECT_PK[5] = {0x80, 0x04, i, 0x00, 0x00}; + res = ExchangeAPDU14a(aSELECT_PK, sizeof(aSELECT_PK), activate_field, keep_field_on, response, sizeof(response), &resplen); + if (res != PM3_SUCCESS) { + continue; + } + + sw = get_sw(response, resplen); + if (sw == ISO7816_OK) { + // save PK for later + uint8_t pk[65] = {0}; + memcpy(pk, response, resplen - 2); + + PrintAndLogEx(INFO, "PUBLIC KEY # %i", i); + PrintAndLogEx(INFO, "%s", sprint_hex_inrow(pk, sizeof(pk))); + } + } + + uint8_t aREAD_FORM_FACTOR[30]; + int aREAD_FORM_FACTOR_n = 0; + param_gethex_to_eol("80140000", 0, aREAD_FORM_FACTOR, sizeof(aREAD_FORM_FACTOR), &aREAD_FORM_FACTOR_n); + res = ExchangeAPDU14a(aREAD_FORM_FACTOR, aREAD_FORM_FACTOR_n, activate_field, keep_field_on, response, sizeof(response), &resplen); + if (res != PM3_SUCCESS) { + DropField(); + return res; + } + + sw = get_sw(response, resplen); + if (sw != ISO7816_OK) { + PrintAndLogEx(ERR, "reading FORM FACTOR file failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); + DropField(); + return PM3_ESOFT; + } + + // store form factor for later + uint8_t form_factor[resplen - 2]; + memcpy(form_factor, response, sizeof(form_factor)); + + uint8_t aREAD_VERSION[30]; + int aREAD_VERSION_n = 0; + param_gethex_to_eol("80170000", 0, aREAD_VERSION, sizeof(aREAD_VERSION), &aREAD_VERSION_n); + res = ExchangeAPDU14a(aREAD_VERSION, aREAD_VERSION_n, activate_field, keep_field_on, response, sizeof(response), &resplen); + if (res != PM3_SUCCESS) { + DropField(); + return res; + } + + uint8_t version[resplen - 2]; + + sw = get_sw(response, resplen); + if (sw == ISO7816_OK) { + // store version for later + memcpy(version, response, sizeof(version)); + } + + // --------------- CERT reading ---------------- + Set_apdu_in_framing(true); + for (uint8_t i = 0; i < 4; i++) { + + uint8_t aSELECT_CERT[PM3_CMD_DATA_SIZE] = {0x80, 0x06, i, 0x00, 0x00, 0x00, 0xFF}; + int aSELECT_CERT_n = 7; + + res = ExchangeAPDU14a(aSELECT_CERT, aSELECT_CERT_n, activate_field, keep_field_on, response, PM3_CMD_DATA_SIZE, &resplen); + if (res != PM3_SUCCESS) { + continue; + } + + sw = get_sw(response, resplen); + + if (sw == ISO7816_OK) { + // save CETT for later + uint8_t cert[515] = {0}; + memcpy(cert, response, resplen - 2); + + PrintAndLogEx(INFO, "CERT # %i", i); + PrintAndLogEx(INFO, "%s", sprint_hex_inrow(cert, resplen - 2)); + } + } + Set_apdu_in_framing(false); + keep_field_on = false; + DropField(); + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------"); + PrintAndLogEx(NORMAL, ""); +// PrintAndLogEx(INFO, "PUBLIC KEY"); +// PrintAndLogEx(INFO, "%zu - %s", sizeof(pk), sprint_hex_inrow(pk, sizeof(pk))); + PrintAndLogEx(INFO, "Form factor"); + PrintAndLogEx(INFO, "%zu - %s", sizeof(form_factor), sprint_hex_inrow(form_factor, sizeof(form_factor))); + PrintAndLogEx(INFO, "VERSION"); + PrintAndLogEx(INFO, "%zu - %s", sizeof(version), sprint_hex_inrow(version, sizeof(version))); + + return PM3_SUCCESS; +} + +// menu command to get and print all info known about any known ST25TA tag +static int CmdHFTeslaInfo(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf telsa info", + "Get info about TESLA Key tag", + "hf tesla info" + ); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + return info_hf_tesla(); +} + + +static int CmdHFTeslaList(const char *Cmd) { + return CmdTraceListAlias(Cmd, "hf tesla", "7816"); +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"info", CmdHFTeslaInfo, IfPm3Iso14443a, "Tag information"}, + {"list", CmdHFTeslaList, AlwaysAvailable, "List ISO 14443A/7816 history"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdHFTESLA(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} diff --git a/client/src/cmdhftesla.h b/client/src/cmdhftesla.h new file mode 100644 index 000000000..923ac5fb1 --- /dev/null +++ b/client/src/cmdhftesla.h @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// High frequency ISO14443A / TESLA commands +//----------------------------------------------------------------------------- + +#ifndef CMDHFTESLA_H__ +#define CMDHFTESLA_H__ + +#include "common.h" + +int CmdHFTESLA(const char *Cmd); + +#endif diff --git a/common/commonutil.c b/common/commonutil.c index 2101414ab..601dc20e4 100644 --- a/common/commonutil.c +++ b/common/commonutil.c @@ -262,10 +262,10 @@ uint32_t rotr(uint32_t a, uint8_t n) { return (a >> n) | (a << (32 - n)); } -uint16_t get_sw(const uint8_t *d, uint8_t n) { +uint16_t get_sw(const uint8_t *d, uint16_t n) { if (n < 2) return 0; n -= 2; - return d[n] * 0x0100 + d[n + 1]; + return (d[n] << 8 | d[n + 1]); } diff --git a/common/commonutil.h b/common/commonutil.h index 0d8932a51..8e800f25f 100644 --- a/common/commonutil.h +++ b/common/commonutil.h @@ -85,5 +85,5 @@ void htole24(uint32_t val, uint8_t data[3]); uint32_t rotl(uint32_t a, uint8_t n); uint32_t rotr(uint32_t a, uint8_t n); -uint16_t get_sw(const uint8_t *d, uint8_t n); +uint16_t get_sw(const uint8_t *d, uint16_t n); #endif From 6850cacc699c3a3db3215fee4de3b0e4d244fbdf Mon Sep 17 00:00:00 2001 From: Alejandro <45500329+Alejandro12120@users.noreply.github.com> Date: Sat, 21 Jan 2023 20:28:30 +0100 Subject: [PATCH 528/759] fix typo Signed-off-by: Alejandro <45500329+Alejandro12120@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d931e1ad5..3edd4e786 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ We define generic Proxmark3 platforms as following devices. - **Note**: unknown pin assignments. - ⚠ Ryscorp Proxmark3 Pro - **Note**: device has different fpga and unknown pin assignments. - - **Note**: Company have dissappared, leaving their customers in the dark. + - **Note**: Company have disappeared, leaving their customers in the dark. - ⚠ iCopy-X - **Note**: experimental support, currently incompatible with iCopy-X GUI as Proxmark client commands are now using cliparser. - **Note**: see also [icopyx-community repos](https://github.com/iCopy-X-Community/) for upstream sources, reversed hw etc. From 7c6aa66aa26327c7f4868c51ee7f6429106fd30f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 21 Jan 2023 21:20:22 +0100 Subject: [PATCH 529/759] tesla auth challenge exchange --- client/src/cmdhftesla.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/client/src/cmdhftesla.c b/client/src/cmdhftesla.c index 62e3bab18..b3b5c8939 100644 --- a/client/src/cmdhftesla.c +++ b/client/src/cmdhftesla.c @@ -164,6 +164,30 @@ static int info_hf_tesla(void) { } } Set_apdu_in_framing(false); + + uint8_t aAUTH[90]; + int aAUTH_n = 0; + // vehicle public key , 16 byte CHALLENGE + // 00112233445566778899AABBCCDDEEFF + // 0x51 = 81 dec +// param_gethex_to_eol("8011000051 046F08AE62526ABB5690643458152AC963CF5D7C113949F3C2453D1DDC6E4385B430523524045A22F5747BF236F1B5F60F0EA32DC2B8276D75ACDE9813EF77C330 00112233445566778899AABBCCDDEEFF", 0, aAUTH, sizeof(aAUTH), &aAUTH_n); + param_gethex_to_eol("8011000051046F08AE62526ABB5690643458152AC963CF5D7C113949F3C2453D1DDC6E4385B430523524045A22F5747BF236F1B5F60F0EA32DC2B8276D75ACDE9813EF77C33000112233445566778899AABBCCDDEEFF", 0, aAUTH, sizeof(aAUTH), &aAUTH_n); + res = ExchangeAPDU14a(aAUTH, aAUTH_n, activate_field, keep_field_on, response, sizeof(response), &resplen); + if (res != PM3_SUCCESS) { + DropField(); + return res; + } + + uint8_t auth[resplen - 2]; + + sw = get_sw(response, resplen); + if (sw == ISO7816_OK) { + // store CHALLENGE for later + memcpy(auth, response, sizeof(auth)); + } + + PrintAndLogEx(INFO, "CHALL... %s", sprint_hex_inrow(auth, sizeof(auth))); + keep_field_on = false; DropField(); From f05c6a1f72da7765f1cd9d37b25963e33671bb6c Mon Sep 17 00:00:00 2001 From: Self Not Found Date: Sun, 22 Jan 2023 15:12:33 +0800 Subject: [PATCH 530/759] Fix the types of parameters in BitstreamOut_t BitstreamOut_t in client/src/loclass/cipherutils.h is also used in client/src/cmddata.c for decimatioin, but uint8_t is too small for such application --- armsrc/optimized_cipherutils.h | 8 ++++---- client/src/loclass/cipherutils.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/armsrc/optimized_cipherutils.h b/armsrc/optimized_cipherutils.h index 73fbfc730..1bef017a2 100644 --- a/armsrc/optimized_cipherutils.h +++ b/armsrc/optimized_cipherutils.h @@ -39,14 +39,14 @@ typedef struct { uint8_t *buffer; - uint8_t numbits; - uint8_t position; + uint32_t numbits; + uint32_t position; } BitstreamIn_t; typedef struct { uint8_t *buffer; - uint8_t numbits; - uint8_t position; + uint32_t numbits; + uint32_t position; } BitstreamOut_t; bool headBit(BitstreamIn_t *stream); diff --git a/client/src/loclass/cipherutils.h b/client/src/loclass/cipherutils.h index aeba9f33d..160945f0d 100644 --- a/client/src/loclass/cipherutils.h +++ b/client/src/loclass/cipherutils.h @@ -42,14 +42,14 @@ typedef struct { uint8_t *buffer; - uint8_t numbits; - uint8_t position; + uint32_t numbits; + uint32_t position; } BitstreamIn_t; typedef struct { uint8_t *buffer; - uint8_t numbits; - uint8_t position; + uint32_t numbits; + uint32_t position; } BitstreamOut_t; bool headBit(BitstreamIn_t *stream); From af00fde250c0458de619b6f2d89c475d15b5c18d Mon Sep 17 00:00:00 2001 From: colonelborkmundus Date: Sun, 22 Jan 2023 02:36:19 -0500 Subject: [PATCH 531/759] additional 1k keys, fresh from the oven --- client/dictionaries/mfc_default_keys.dic | 45 +++++++++++++++++++----- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 235cabe20..651a4d547 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1911,15 +1911,14 @@ D144BD193063 453857395635 # ########################################## -# # added by colonelborkmundus # "the more, the marriott" mifare project # -# mifare classic 1k - graduate hotel +# 1k - graduate hotel C49DAE1C6049 209A2B910545 # -# mifare classic 1k - westin +# 1k - westin 8C29F8320617 5697519A8F02 7D0A1C277C05 @@ -1927,18 +1926,48 @@ C49DAE1C6049 C40964215509 D44CFC178460 # -# mifare classic 1k EV1 - marriott +# 1k - marriott 7B4DFC6D6525 23C9FDD9A366 3119A70628EB 30AAD6A711EF 1330824CD356 +43012BD9EB87 +035C70558D7B # -# mifare classic 1k - AC hotels marriott +# 1k - AC hotels marriott 8EA8EC3F2320 # -# mifare classic 1k - the ritz-carlton +# 1k - the ritz-carlton 30FB20D0EFEF +D20289CD9E6E # -# mifare classic 1k - unknown -722538817225 \ No newline at end of file +# 1k - unknown +722538817225 +# +# 1k - aria resort & casino +316B8FAA12EF +A18D9F4E75AF +# +# 1k - fairfield inn & suites marriott +7AEB989A5525 +7B3B589A5525 +215E9DED9DDF +334E91BE3377 +310308EC52EF +# +# 1k - residence inn marriott +F72CD208FDF9 +# +# 1k - sheraton +42FC522DE987 +# +# 1k - millenium hotels +132F641C948B +# +# 1k - moxy hotels +20C166C00ADB +9EE3896C4530 +# +# 1k - residence inn marriott +3122AE5341EB \ No newline at end of file From 239a8646b221b33c262fa32c9929f4627414cfaf Mon Sep 17 00:00:00 2001 From: wh201906 Date: Sun, 22 Jan 2023 15:38:09 +0000 Subject: [PATCH 532/759] Fix the wrong sample count when bps!=8 --- armsrc/lfsampling.c | 4 +++- client/src/cmddata.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index a1ff37356..3844976e1 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -296,7 +296,9 @@ void LFSetupFPGAForADC(int divisor, bool reader_field) { uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold, bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip, bool ledcontrol) { - initSampleBuffer(&sample_size); + initSampleBuffer(&sample_size); // sample size in bytes + sample_size <<= 3; // sample size in bits + sample_size /= bits_per_sample; // sample count if (g_dbglevel >= DBG_DEBUG) { printSamples(); diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 647c062a4..1ebd4b432 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -1779,7 +1779,7 @@ int getSamplesEx(uint32_t start, uint32_t end, bool verbose, bool ignore_lf_conf BitstreamOut_t bout = { got, bits_per_sample * n, 0}; uint32_t j = 0; - for (j = 0; j * bits_per_sample < n * 8 && j < n; j++) { + for (j = 0; j * bits_per_sample < n * 8 && j * bits_per_sample < MAX_GRAPH_TRACE_LEN * 8; j++) { uint8_t sample = getByte(bits_per_sample, &bout); g_GraphBuffer[j] = ((int) sample) - 127; } From f4879fdc172f43bf965a29f2420f7c42030e895c Mon Sep 17 00:00:00 2001 From: wh201906 Date: Sun, 22 Jan 2023 15:41:07 +0000 Subject: [PATCH 533/759] Bypass some functions if bps is not 8 --- armsrc/lfsampling.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 3844976e1..e716fa248 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -370,8 +370,12 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in } // Ensure that DC offset removal and noise check is performed for any device-side processing - removeSignalOffset(data.buffer, samples.total_saved); - computeSignalProperties(data.buffer, samples.total_saved); + if (bits_per_sample == 8) + { + // these functions only consider bps==8 + removeSignalOffset(data.buffer, samples.total_saved); + computeSignalProperties(data.buffer, samples.total_saved); + } return data.numbits; } /** From 8218762e86fa9774bd6d4190f350d0f8bea5c5c3 Mon Sep 17 00:00:00 2001 From: Self Not Found Date: Mon, 23 Jan 2023 00:16:29 +0800 Subject: [PATCH 534/759] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97fa48f5d..978caa8e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - Fixed `make accessrights` on Fedora (@mooey5775) + - Fixed the lf sampling when bits_per_sample is less than 8 (@wh201906) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) From ec8a603aca072cce920ac92301819d9cabb1eef6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 22 Jan 2023 17:47:39 +0100 Subject: [PATCH 535/759] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97fa48f5d..b4cde2d93 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] + - Added `hf tesla info` - intital information command to read TESLA cards (@iceman1001) - Changed `hf emrtd info` - looking for lower case .bin extensions (@iceman1001) - Changed `hf emrtd dump` - looking for lower case .bin extensions (@iceman1001) - Changed `lf paradox clone` - it now accepts FC/CN (@mwalker33) From ad9771b4c0fd7097267d352902d5a4339e0ec8d4 Mon Sep 17 00:00:00 2001 From: colonelborkmundus Date: Sun, 22 Jan 2023 11:57:32 -0500 Subject: [PATCH 536/759] removed modified files from pull request --- client/dictionaries/mfc_default_keys.dic | 16 +- client/src/cmdhflist.c | 2 +- client/src/pm3line_vocabulory.h | 1484 +++++++++++----------- 3 files changed, 758 insertions(+), 744 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 651a4d547..881c72df0 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1934,13 +1934,18 @@ D44CFC178460 1330824CD356 43012BD9EB87 035C70558D7B +9966588CB9A0 +12AB4C37BB8B # # 1k - AC hotels marriott 8EA8EC3F2320 +7B56B2B38725 # # 1k - the ritz-carlton 30FB20D0EFEF D20289CD9E6E +66A3B064CC4B +D18296CD9E6E # # 1k - unknown 722538817225 @@ -1970,4 +1975,13 @@ F72CD208FDF9 9EE3896C4530 # # 1k - residence inn marriott -3122AE5341EB \ No newline at end of file +3122AE5341EB +# +# 1k - americinn +8AC04C1A4A25 +# +# 1k - the industrialist +2158E314C3DF +# +# 1k - waldorf astoria +011C6CF459E8 \ No newline at end of file diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index 232d4af19..a19ecdea9 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -318,7 +318,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i snprintf(exp, size, "AUTH-B(%d)", cmd[1]); break; } - case MIFARE_MAGIC_GDM_AUTH_KEYA: { + case MIFARE_MAGIC_GDM_AUTH_KEYA:{ if (cmdsize > 3) { snprintf(exp, size, "MAGIC AUTH-A(%d)", cmd[1]); MifareAuthState = masNt; diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 91a88a1c0..5a517c645 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -31,747 +31,747 @@ typedef struct vocabulory_s { } vocabulory_t; const static vocabulory_t vocabulory[] = { - { 1, "help" }, - { 0, "auto" }, - { 1, "clear" }, - { 1, "hints" }, - { 1, "msleep" }, - { 1, "rem" }, - { 1, "quit" }, - { 1, "exit" }, - { 1, "prefs help" }, - { 1, "prefs show" }, - { 1, "prefs get barmode" }, - { 1, "prefs get clientdebug" }, - { 1, "prefs get clientdelay" }, - { 1, "prefs get color" }, - { 1, "prefs get savepaths" }, - { 1, "prefs get emoji" }, - { 1, "prefs get hints" }, - { 1, "prefs get output" }, - { 1, "prefs get plotsliders" }, - { 1, "prefs set help" }, - { 1, "prefs set barmode" }, - { 1, "prefs set clientdebug" }, - { 1, "prefs set clientdelay" }, - { 1, "prefs set color" }, - { 1, "prefs set emoji" }, - { 1, "prefs set hints" }, - { 1, "prefs set savepaths" }, - { 1, "prefs set output" }, - { 1, "prefs set plotsliders" }, - { 1, "analyse help" }, - { 1, "analyse lcr" }, - { 1, "analyse crc" }, - { 1, "analyse chksum" }, - { 1, "analyse dates" }, - { 1, "analyse lfsr" }, - { 1, "analyse a" }, - { 1, "analyse nuid" }, - { 1, "analyse demodbuff" }, - { 1, "analyse freq" }, - { 1, "analyse foo" }, - { 1, "analyse units" }, - { 1, "data help" }, - { 1, "data biphaserawdecode" }, - { 1, "data detectclock" }, - { 1, "data fsktonrz" }, - { 1, "data manrawdecode" }, - { 1, "data modulation" }, - { 1, "data rawdemod" }, - { 1, "data askedgedetect" }, - { 1, "data autocorr" }, - { 1, "data dirthreshold" }, - { 1, "data decimate" }, - { 1, "data undecimate" }, - { 1, "data hide" }, - { 1, "data hpf" }, - { 1, "data iir" }, - { 1, "data grid" }, - { 1, "data ltrim" }, - { 1, "data mtrim" }, - { 1, "data norm" }, - { 1, "data plot" }, - { 1, "data rtrim" }, - { 1, "data setgraphmarkers" }, - { 1, "data shiftgraphzero" }, - { 1, "data timescale" }, - { 1, "data zerocrossings" }, - { 1, "data convertbitstream" }, - { 1, "data getbitstream" }, - { 1, "data asn1" }, - { 1, "data bin2hex" }, - { 0, "data bitsamples" }, - { 1, "data clear" }, - { 1, "data diff" }, - { 0, "data hexsamples" }, - { 1, "data hex2bin" }, - { 1, "data load" }, - { 1, "data print" }, - { 0, "data samples" }, - { 1, "data save" }, - { 1, "data setdebugmode" }, - { 0, "data tune" }, - { 1, "emv help" }, - { 0, "emv exec" }, - { 0, "emv pse" }, - { 0, "emv search" }, - { 0, "emv select" }, - { 0, "emv gpo" }, - { 0, "emv readrec" }, - { 0, "emv genac" }, - { 0, "emv challenge" }, - { 0, "emv intauth" }, - { 0, "emv scan" }, - { 1, "emv test" }, - { 1, "emv list" }, - { 0, "emv roca" }, - { 1, "hf help" }, - { 1, "hf list" }, - { 0, "hf plot" }, - { 0, "hf tune" }, - { 1, "hf search" }, - { 0, "hf sniff" }, - { 1, "hf 14a help" }, - { 1, "hf 14a list" }, - { 0, "hf 14a antifuzz" }, - { 0, "hf 14a config" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a info" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a raw" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a apdufind" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a ndefformat" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a ndefwrite" }, - { 1, "hf 14b help" }, - { 0, "hf 14b apdu" }, - { 0, "hf 14b dump" }, - { 0, "hf 14b info" }, - { 1, "hf 14b list" }, - { 0, "hf 14b ndefread" }, - { 0, "hf 14b raw" }, - { 0, "hf 14b reader" }, - { 0, "hf 14b sim" }, - { 0, "hf 14b sniff" }, - { 0, "hf 14b rdbl" }, - { 0, "hf 14b sriwrite" }, - { 1, "hf 14b view" }, - { 1, "hf 15 help" }, - { 1, "hf 15 list" }, - { 1, "hf 15 demod" }, - { 0, "hf 15 dump" }, - { 0, "hf 15 info" }, - { 0, "hf 15 sniff" }, - { 0, "hf 15 raw" }, - { 0, "hf 15 rdbl" }, - { 0, "hf 15 rdmulti" }, - { 0, "hf 15 reader" }, - { 0, "hf 15 restore" }, - { 0, "hf 15 samples" }, - { 0, "hf 15 eload" }, - { 0, "hf 15 esave" }, - { 0, "hf 15 eview" }, - { 0, "hf 15 sim" }, - { 0, "hf 15 slixdisable" }, - { 0, "hf 15 wrbl" }, - { 0, "hf 15 findafi" }, - { 0, "hf 15 writeafi" }, - { 0, "hf 15 writedsfid" }, - { 0, "hf 15 csetuid" }, - { 1, "hf cipurse help" }, - { 0, "hf cipurse info" }, - { 0, "hf cipurse select" }, - { 0, "hf cipurse auth" }, - { 0, "hf cipurse read" }, - { 0, "hf cipurse write" }, - { 0, "hf cipurse aread" }, - { 0, "hf cipurse awrite" }, - { 0, "hf cipurse formatall" }, - { 0, "hf cipurse create" }, - { 0, "hf cipurse delete" }, - { 0, "hf cipurse updkey" }, - { 0, "hf cipurse updakey" }, - { 0, "hf cipurse default" }, - { 1, "hf cipurse test" }, - { 1, "hf epa help" }, - { 0, "hf epa cnonces" }, - { 0, "hf epa replay" }, - { 0, "hf epa sim" }, - { 1, "hf emrtd help" }, - { 0, "hf emrtd dump" }, - { 1, "hf emrtd info" }, - { 1, "hf emrtd list" }, - { 1, "hf felica help" }, - { 1, "hf felica list" }, - { 0, "hf felica reader" }, - { 0, "hf felica info" }, - { 0, "hf felica sniff" }, - { 0, "hf felica raw" }, - { 0, "hf felica rdbl" }, - { 0, "hf felica wrbl" }, - { 0, "hf felica rqservice" }, - { 0, "hf felica rqresponse" }, - { 0, "hf felica scsvcode" }, - { 0, "hf felica rqsyscode" }, - { 0, "hf felica auth1" }, - { 0, "hf felica auth2" }, - { 0, "hf felica rqspecver" }, - { 0, "hf felica resetmode" }, - { 0, "hf felica litesim" }, - { 0, "hf felica litedump" }, - { 1, "hf fido help" }, - { 1, "hf fido list" }, - { 0, "hf fido info" }, - { 0, "hf fido reg" }, - { 0, "hf fido auth" }, - { 0, "hf fido make" }, - { 0, "hf fido assert" }, - { 1, "hf fudan help" }, - { 0, "hf fudan reader" }, - { 0, "hf fudan dump" }, - { 0, "hf fudan rdbl" }, - { 1, "hf fudan view" }, - { 0, "hf fudan wrbl" }, - { 1, "hf gallagher help" }, - { 0, "hf gallagher reader" }, - { 0, "hf gallagher clone" }, - { 0, "hf gallagher delete" }, - { 1, "hf gallagher diversifykey" }, - { 1, "hf gallagher decode" }, - { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 select" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 init" }, - { 0, "hf ksx6924 prec" }, - { 1, "hf jooki help" }, - { 0, "hf jooki clone" }, - { 1, "hf jooki decode" }, - { 1, "hf jooki encode" }, - { 0, "hf jooki sim" }, - { 1, "hf iclass help" }, - { 0, "hf iclass dump" }, - { 1, "hf iclass info" }, - { 1, "hf iclass list" }, - { 0, "hf iclass rdbl" }, - { 0, "hf iclass reader" }, - { 0, "hf iclass restore" }, - { 0, "hf iclass sniff" }, - { 0, "hf iclass wrbl" }, - { 0, "hf iclass chk" }, - { 1, "hf iclass loclass" }, - { 1, "hf iclass lookup" }, - { 0, "hf iclass sim" }, - { 0, "hf iclass eload" }, - { 0, "hf iclass esave" }, - { 0, "hf iclass eview" }, - { 1, "hf iclass configcard" }, - { 1, "hf iclass calcnewkey" }, - { 1, "hf iclass encode" }, - { 1, "hf iclass encrypt" }, - { 1, "hf iclass decrypt" }, - { 1, "hf iclass managekeys" }, - { 1, "hf iclass permutekey" }, - { 1, "hf iclass view" }, - { 1, "hf legic help" }, - { 0, "hf legic dump" }, - { 0, "hf legic info" }, - { 1, "hf legic list" }, - { 0, "hf legic rdbl" }, - { 0, "hf legic reader" }, - { 0, "hf legic restore" }, - { 0, "hf legic wipe" }, - { 0, "hf legic wrbl" }, - { 0, "hf legic sim" }, - { 0, "hf legic eload" }, - { 0, "hf legic esave" }, - { 0, "hf legic eview" }, - { 1, "hf legic crc" }, - { 1, "hf legic view" }, - { 1, "hf lto help" }, - { 0, "hf lto dump" }, - { 0, "hf lto info" }, - { 1, "hf lto list" }, - { 0, "hf lto rdbl" }, - { 0, "hf lto reader" }, - { 0, "hf lto restore" }, - { 0, "hf lto wrbl" }, - { 1, "hf mf help" }, - { 1, "hf mf list" }, - { 0, "hf mf darkside" }, - { 0, "hf mf nested" }, - { 1, "hf mf hardnested" }, - { 0, "hf mf staticnested" }, - { 0, "hf mf autopwn" }, - { 0, "hf mf nack" }, - { 0, "hf mf chk" }, - { 0, "hf mf fchk" }, - { 1, "hf mf decrypt" }, - { 0, "hf mf supercard" }, - { 0, "hf mf auth4" }, - { 1, "hf mf acl" }, - { 0, "hf mf dump" }, - { 1, "hf mf mad" }, - { 0, "hf mf personalize" }, - { 0, "hf mf rdbl" }, - { 0, "hf mf rdsc" }, - { 0, "hf mf restore" }, - { 0, "hf mf setmod" }, - { 1, "hf mf value" }, - { 1, "hf mf view" }, - { 0, "hf mf wipe" }, - { 0, "hf mf wrbl" }, - { 0, "hf mf sim" }, - { 0, "hf mf ecfill" }, - { 0, "hf mf eclr" }, - { 0, "hf mf egetblk" }, - { 0, "hf mf egetsc" }, - { 0, "hf mf ekeyprn" }, - { 0, "hf mf eload" }, - { 0, "hf mf esave" }, - { 0, "hf mf esetblk" }, - { 0, "hf mf eview" }, - { 0, "hf mf cgetblk" }, - { 0, "hf mf cgetsc" }, - { 0, "hf mf cload" }, - { 0, "hf mf csave" }, - { 0, "hf mf csetblk" }, - { 0, "hf mf csetuid" }, - { 0, "hf mf cview" }, - { 0, "hf mf cwipe" }, - { 0, "hf mf gen3uid" }, - { 0, "hf mf gen3blk" }, - { 0, "hf mf gen3freeze" }, - { 0, "hf mf ggetblk" }, - { 0, "hf mf gload" }, - { 0, "hf mf gsave" }, - { 0, "hf mf gsetblk" }, - { 0, "hf mf gview" }, - { 0, "hf mf ndefformat" }, - { 0, "hf mf ndefread" }, - { 0, "hf mf ndefwrite" }, - { 1, "hf mfp help" }, - { 0, "hf mfp info" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp commitp" }, - { 0, "hf mfp auth" }, - { 0, "hf mfp rdbl" }, - { 0, "hf mfp rdsc" }, - { 0, "hf mfp wrbl" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp mad" }, - { 0, "hf mfp ndefread" }, - { 1, "hf mfu help" }, - { 1, "hf mfu keygen" }, - { 1, "hf mfu pwdgen" }, - { 0, "hf mfu otptear" }, - { 0, "hf mfu cauth" }, - { 0, "hf mfu dump" }, - { 0, "hf mfu info" }, - { 0, "hf mfu ndefread" }, - { 0, "hf mfu rdbl" }, - { 0, "hf mfu restore" }, - { 1, "hf mfu view" }, - { 0, "hf mfu wrbl" }, - { 0, "hf mfu eload" }, - { 0, "hf mfu esave" }, - { 0, "hf mfu eview" }, - { 0, "hf mfu sim" }, - { 0, "hf mfu setpwd" }, - { 0, "hf mfu setuid" }, - { 1, "hf mfdes help" }, - { 0, "hf mfdes info" }, - { 0, "hf mfdes getuid" }, - { 0, "hf mfdes default" }, - { 0, "hf mfdes auth" }, - { 0, "hf mfdes chk" }, - { 0, "hf mfdes detect" }, - { 0, "hf mfdes freemem" }, - { 0, "hf mfdes setconfig" }, - { 0, "hf mfdes formatpicc" }, - { 1, "hf mfdes list" }, - { 0, "hf mfdes mad" }, - { 0, "hf mfdes lsapp" }, - { 0, "hf mfdes getaids" }, - { 0, "hf mfdes getappnames" }, - { 0, "hf mfdes bruteaid" }, - { 0, "hf mfdes createapp" }, - { 0, "hf mfdes deleteapp" }, - { 0, "hf mfdes selectapp" }, - { 0, "hf mfdes changekey" }, - { 0, "hf mfdes chkeysettings" }, - { 0, "hf mfdes getkeysettings" }, - { 0, "hf mfdes getkeyversions" }, - { 0, "hf mfdes getfileids" }, - { 0, "hf mfdes getfileisoids" }, - { 0, "hf mfdes lsfiles" }, - { 0, "hf mfdes dump" }, - { 0, "hf mfdes createfile" }, - { 0, "hf mfdes createvaluefile" }, - { 0, "hf mfdes createrecordfile" }, - { 0, "hf mfdes createmacfile" }, - { 0, "hf mfdes deletefile" }, - { 0, "hf mfdes getfilesettings" }, - { 0, "hf mfdes chfilesettings" }, - { 0, "hf mfdes read" }, - { 0, "hf mfdes write" }, - { 0, "hf mfdes value" }, - { 0, "hf mfdes clearrecfile" }, - { 1, "hf mfdes test" }, - { 1, "hf ntag424 help" }, - { 0, "hf ntag424 info" }, - { 0, "hf ntag424 sdm" }, - { 1, "hf ntag424 view" }, - { 1, "hf seos help" }, - { 0, "hf seos info" }, - { 1, "hf seos list" }, - { 1, "hf st25ta help" }, - { 0, "hf st25ta info" }, - { 1, "hf st25ta list" }, - { 1, "hf st25ta ndefread" }, - { 0, "hf st25ta protect" }, - { 0, "hf st25ta pwd" }, - { 0, "hf st25ta sim" }, - { 1, "hf thinfilm help" }, - { 0, "hf thinfilm info" }, - { 1, "hf thinfilm list" }, - { 0, "hf thinfilm sim" }, - { 1, "hf topaz help" }, - { 0, "hf topaz dump" }, - { 1, "hf topaz list" }, - { 0, "hf topaz info" }, - { 0, "hf topaz reader" }, - { 0, "hf topaz sim" }, - { 0, "hf topaz sniff" }, - { 0, "hf topaz raw" }, - { 0, "hf topaz rdbl" }, - { 1, "hf topaz view" }, - { 0, "hf topaz wrbl" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, - { 1, "hf xerox help" }, - { 0, "hf xerox info" }, - { 0, "hf xerox reader" }, - { 0, "hf xerox dump" }, - { 1, "hf waveshare help" }, - { 0, "hf waveshare loadbmp" }, - { 1, "hw help" }, - { 0, "hw break" }, - { 1, "hw connect" }, - { 0, "hw dbg" }, - { 0, "hw detectreader" }, - { 0, "hw fpgaoff" }, - { 0, "hw lcd" }, - { 0, "hw lcdreset" }, - { 0, "hw ping" }, - { 0, "hw readmem" }, - { 0, "hw reset" }, - { 0, "hw setlfdivisor" }, - { 0, "hw setmux" }, - { 0, "hw standalone" }, - { 0, "hw status" }, - { 0, "hw tearoff" }, - { 0, "hw tia" }, - { 0, "hw tune" }, - { 1, "hw version" }, - { 1, "lf help" }, - { 0, "lf config" }, - { 0, "lf cmdread" }, - { 0, "lf read" }, - { 1, "lf search" }, - { 0, "lf sim" }, - { 0, "lf simask" }, - { 0, "lf simfsk" }, - { 0, "lf simpsk" }, - { 0, "lf simbidir" }, - { 0, "lf sniff" }, - { 0, "lf tune" }, - { 1, "lf awid help" }, - { 1, "lf awid demod" }, - { 0, "lf awid reader" }, - { 0, "lf awid clone" }, - { 0, "lf awid sim" }, - { 0, "lf awid brute" }, - { 0, "lf awid watch" }, - { 1, "lf cotag help" }, - { 1, "lf cotag demod" }, - { 0, "lf cotag reader" }, - { 1, "lf destron help" }, - { 1, "lf destron demod" }, - { 0, "lf destron reader" }, - { 0, "lf destron clone" }, - { 0, "lf destron sim" }, - { 1, "lf em help" }, - { 1, "lf em 410x help" }, - { 1, "lf em 410x demod" }, - { 0, "lf em 410x reader" }, - { 0, "lf em 410x sim" }, - { 0, "lf em 410x brute" }, - { 0, "lf em 410x watch" }, - { 0, "lf em 410x spoof" }, - { 0, "lf em 410x clone" }, - { 1, "lf em 4x05 help" }, - { 0, "lf em 4x05 brute" }, - { 0, "lf em 4x05 chk" }, - { 1, "lf em 4x05 demod" }, - { 0, "lf em 4x05 dump" }, - { 0, "lf em 4x05 info" }, - { 0, "lf em 4x05 read" }, - { 1, "lf em 4x05 sniff" }, - { 0, "lf em 4x05 unlock" }, - { 0, "lf em 4x05 wipe" }, - { 0, "lf em 4x05 write" }, - { 1, "lf em 4x50 help" }, - { 0, "lf em 4x50 brute" }, - { 0, "lf em 4x50 chk" }, - { 0, "lf em 4x50 dump" }, - { 0, "lf em 4x50 info" }, - { 0, "lf em 4x50 login" }, - { 0, "lf em 4x50 rdbl" }, - { 0, "lf em 4x50 reader" }, - { 0, "lf em 4x50 restore" }, - { 0, "lf em 4x50 wrbl" }, - { 0, "lf em 4x50 wrpwd" }, - { 0, "lf em 4x50 wipe" }, - { 0, "lf em 4x50 eload" }, - { 0, "lf em 4x50 esave" }, - { 0, "lf em 4x50 eview" }, - { 0, "lf em 4x50 sim" }, - { 1, "lf em 4x70 help" }, - { 0, "lf em 4x70 info" }, - { 0, "lf em 4x70 write" }, - { 0, "lf em 4x70 unlock" }, - { 0, "lf em 4x70 auth" }, - { 0, "lf em 4x70 writepin" }, - { 0, "lf em 4x70 writekey" }, - { 1, "lf fdxb help" }, - { 1, "lf fdxb demod" }, - { 0, "lf fdxb reader" }, - { 0, "lf fdxb clone" }, - { 0, "lf fdxb sim" }, - { 1, "lf gallagher help" }, - { 1, "lf gallagher demod" }, - { 0, "lf gallagher reader" }, - { 0, "lf gallagher clone" }, - { 0, "lf gallagher sim" }, - { 1, "lf gproxii help" }, - { 1, "lf gproxii demod" }, - { 0, "lf gproxii reader" }, - { 0, "lf gproxii clone" }, - { 0, "lf gproxii sim" }, - { 1, "lf hid help" }, - { 1, "lf hid demod" }, - { 0, "lf hid reader" }, - { 0, "lf hid clone" }, - { 0, "lf hid sim" }, - { 0, "lf hid brute" }, - { 0, "lf hid watch" }, - { 1, "lf hitag help" }, - { 0, "lf hitag eload" }, - { 1, "lf hitag list" }, - { 0, "lf hitag info" }, - { 0, "lf hitag reader" }, - { 0, "lf hitag sim" }, - { 0, "lf hitag sniff" }, - { 0, "lf hitag writer" }, - { 0, "lf hitag dump" }, - { 0, "lf hitag cc" }, - { 1, "lf idteck help" }, - { 1, "lf idteck demod" }, - { 0, "lf idteck reader" }, - { 0, "lf idteck clone" }, - { 0, "lf idteck sim" }, - { 1, "lf indala help" }, - { 0, "lf indala brute" }, - { 1, "lf indala demod" }, - { 1, "lf indala altdemod" }, - { 0, "lf indala reader" }, - { 0, "lf indala clone" }, - { 0, "lf indala sim" }, - { 1, "lf io help" }, - { 1, "lf io demod" }, - { 0, "lf io reader" }, - { 0, "lf io clone" }, - { 0, "lf io sim" }, - { 0, "lf io watch" }, - { 1, "lf jablotron help" }, - { 1, "lf jablotron demod" }, - { 0, "lf jablotron reader" }, - { 0, "lf jablotron clone" }, - { 0, "lf jablotron sim" }, - { 1, "lf keri help" }, - { 1, "lf keri demod" }, - { 0, "lf keri reader" }, - { 0, "lf keri clone" }, - { 0, "lf keri sim" }, - { 1, "lf motorola help" }, - { 1, "lf motorola demod" }, - { 0, "lf motorola reader" }, - { 0, "lf motorola clone" }, - { 0, "lf motorola sim" }, - { 1, "lf nedap help" }, - { 1, "lf nedap demod" }, - { 0, "lf nedap reader" }, - { 0, "lf nedap clone" }, - { 0, "lf nedap sim" }, - { 1, "lf nexwatch help" }, - { 1, "lf nexwatch demod" }, - { 0, "lf nexwatch reader" }, - { 0, "lf nexwatch clone" }, - { 0, "lf nexwatch sim" }, - { 1, "lf noralsy help" }, - { 1, "lf noralsy demod" }, - { 0, "lf noralsy reader" }, - { 0, "lf noralsy clone" }, - { 0, "lf noralsy sim" }, - { 1, "lf pac help" }, - { 1, "lf pac demod" }, - { 0, "lf pac reader" }, - { 0, "lf pac clone" }, - { 0, "lf pac sim" }, - { 1, "lf paradox help" }, - { 1, "lf paradox demod" }, - { 0, "lf paradox reader" }, - { 0, "lf paradox clone" }, - { 0, "lf paradox sim" }, - { 1, "lf pcf7931 help" }, - { 0, "lf pcf7931 reader" }, - { 0, "lf pcf7931 write" }, - { 1, "lf pcf7931 config" }, - { 1, "lf presco help" }, - { 1, "lf presco demod" }, - { 0, "lf presco reader" }, - { 0, "lf presco clone" }, - { 0, "lf presco sim" }, - { 1, "lf pyramid help" }, - { 1, "lf pyramid demod" }, - { 0, "lf pyramid reader" }, - { 0, "lf pyramid clone" }, - { 0, "lf pyramid sim" }, - { 1, "lf securakey help" }, - { 1, "lf securakey demod" }, - { 0, "lf securakey reader" }, - { 0, "lf securakey clone" }, - { 0, "lf securakey sim" }, - { 1, "lf ti help" }, - { 1, "lf ti demod" }, - { 0, "lf ti reader" }, - { 0, "lf ti write" }, - { 1, "lf t55xx help" }, - { 0, "lf t55xx clonehelp" }, - { 1, "lf t55xx config" }, - { 0, "lf t55xx dangerraw" }, - { 1, "lf t55xx detect" }, - { 0, "lf t55xx deviceconfig" }, - { 0, "lf t55xx dump" }, - { 1, "lf t55xx info" }, - { 0, "lf t55xx p1detect" }, - { 0, "lf t55xx read" }, - { 0, "lf t55xx resetread" }, - { 0, "lf t55xx restore" }, - { 1, "lf t55xx trace" }, - { 0, "lf t55xx wakeup" }, - { 0, "lf t55xx write" }, - { 0, "lf t55xx bruteforce" }, - { 0, "lf t55xx chk" }, - { 0, "lf t55xx protect" }, - { 0, "lf t55xx recoverpw" }, - { 1, "lf t55xx sniff" }, - { 0, "lf t55xx special" }, - { 0, "lf t55xx wipe" }, - { 1, "lf viking help" }, - { 1, "lf viking demod" }, - { 0, "lf viking reader" }, - { 0, "lf viking clone" }, - { 0, "lf viking sim" }, - { 1, "lf visa2000 help" }, - { 1, "lf visa2000 demod" }, - { 0, "lf visa2000 reader" }, - { 0, "lf visa2000 clone" }, - { 0, "lf visa2000 sim" }, - { 1, "mem help" }, - { 0, "mem baudrate" }, - { 0, "mem dump" }, - { 0, "mem info" }, - { 0, "mem load" }, - { 0, "mem wipe" }, - { 1, "mem spiffs help" }, - { 0, "mem spiffs copy" }, - { 0, "mem spiffs check" }, - { 0, "mem spiffs dump" }, - { 0, "mem spiffs info" }, - { 0, "mem spiffs mount" }, - { 0, "mem spiffs remove" }, - { 0, "mem spiffs rename" }, - { 0, "mem spiffs test" }, - { 0, "mem spiffs tree" }, - { 0, "mem spiffs unmount" }, - { 0, "mem spiffs upload" }, - { 0, "mem spiffs view" }, - { 0, "mem spiffs wipe" }, - { 1, "nfc help" }, - { 1, "nfc decode" }, - { 0, "nfc type1 read" }, - { 1, "nfc type1 help" }, - { 0, "nfc type2 read" }, - { 1, "nfc type2 help" }, - { 0, "nfc type4a format" }, - { 0, "nfc type4a read" }, - { 0, "nfc type4a write" }, - { 0, "nfc type4a st25taread" }, - { 1, "nfc type4a help" }, - { 0, "nfc type4b read" }, - { 1, "nfc type4b help" }, - { 0, "nfc mf cformat" }, - { 0, "nfc mf cread" }, - { 0, "nfc mf cwrite" }, - { 0, "nfc mf pread" }, - { 1, "nfc mf help" }, - { 0, "nfc barcode read" }, - { 0, "nfc barcode sim" }, - { 1, "nfc barcode help" }, - { 1, "piv help" }, - { 0, "piv select" }, - { 0, "piv getdata" }, - { 0, "piv authsign" }, - { 0, "piv scan" }, - { 1, "piv list" }, - { 1, "smart help" }, - { 1, "smart list" }, - { 0, "smart info" }, - { 0, "smart reader" }, - { 0, "smart raw" }, - { 1, "smart upgrade" }, - { 0, "smart setclock" }, - { 0, "smart brute" }, - { 1, "script help" }, - { 1, "script list" }, - { 1, "script run" }, - { 1, "trace help" }, - { 1, "trace extract" }, - { 1, "trace list" }, - { 1, "trace load" }, - { 1, "trace save" }, - { 1, "usart help" }, - { 0, "usart btpin" }, - { 0, "usart btfactory" }, - { 0, "usart tx" }, - { 0, "usart rx" }, - { 0, "usart txrx" }, - { 0, "usart txhex" }, - { 0, "usart rxhex" }, - { 0, "usart config" }, - { 1, "wiegand help" }, - { 1, "wiegand list" }, - { 1, "wiegand encode" }, - { 1, "wiegand decode" }, + { 1, "help" }, + { 0, "auto" }, + { 1, "clear" }, + { 1, "hints" }, + { 1, "msleep" }, + { 1, "rem" }, + { 1, "quit" }, + { 1, "exit" }, + { 1, "prefs help" }, + { 1, "prefs show" }, + { 1, "prefs get barmode" }, + { 1, "prefs get clientdebug" }, + { 1, "prefs get clientdelay" }, + { 1, "prefs get color" }, + { 1, "prefs get savepaths" }, + { 1, "prefs get emoji" }, + { 1, "prefs get hints" }, + { 1, "prefs get output" }, + { 1, "prefs get plotsliders" }, + { 1, "prefs set help" }, + { 1, "prefs set barmode" }, + { 1, "prefs set clientdebug" }, + { 1, "prefs set clientdelay" }, + { 1, "prefs set color" }, + { 1, "prefs set emoji" }, + { 1, "prefs set hints" }, + { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, + { 1, "prefs set plotsliders" }, + { 1, "analyse help" }, + { 1, "analyse lcr" }, + { 1, "analyse crc" }, + { 1, "analyse chksum" }, + { 1, "analyse dates" }, + { 1, "analyse lfsr" }, + { 1, "analyse a" }, + { 1, "analyse nuid" }, + { 1, "analyse demodbuff" }, + { 1, "analyse freq" }, + { 1, "analyse foo" }, + { 1, "analyse units" }, + { 1, "data help" }, + { 1, "data biphaserawdecode" }, + { 1, "data detectclock" }, + { 1, "data fsktonrz" }, + { 1, "data manrawdecode" }, + { 1, "data modulation" }, + { 1, "data rawdemod" }, + { 1, "data askedgedetect" }, + { 1, "data autocorr" }, + { 1, "data dirthreshold" }, + { 1, "data decimate" }, + { 1, "data undecimate" }, + { 1, "data hide" }, + { 1, "data hpf" }, + { 1, "data iir" }, + { 1, "data grid" }, + { 1, "data ltrim" }, + { 1, "data mtrim" }, + { 1, "data norm" }, + { 1, "data plot" }, + { 1, "data rtrim" }, + { 1, "data setgraphmarkers" }, + { 1, "data shiftgraphzero" }, + { 1, "data timescale" }, + { 1, "data zerocrossings" }, + { 1, "data convertbitstream" }, + { 1, "data getbitstream" }, + { 1, "data asn1" }, + { 1, "data bin2hex" }, + { 0, "data bitsamples" }, + { 1, "data clear" }, + { 1, "data diff" }, + { 0, "data hexsamples" }, + { 1, "data hex2bin" }, + { 1, "data load" }, + { 1, "data print" }, + { 0, "data samples" }, + { 1, "data save" }, + { 1, "data setdebugmode" }, + { 0, "data tune" }, + { 1, "emv help" }, + { 0, "emv exec" }, + { 0, "emv pse" }, + { 0, "emv search" }, + { 0, "emv select" }, + { 0, "emv gpo" }, + { 0, "emv readrec" }, + { 0, "emv genac" }, + { 0, "emv challenge" }, + { 0, "emv intauth" }, + { 0, "emv scan" }, + { 1, "emv test" }, + { 1, "emv list" }, + { 0, "emv roca" }, + { 1, "hf help" }, + { 1, "hf list" }, + { 0, "hf plot" }, + { 0, "hf tune" }, + { 1, "hf search" }, + { 0, "hf sniff" }, + { 1, "hf 14a help" }, + { 1, "hf 14a list" }, + { 0, "hf 14a antifuzz" }, + { 0, "hf 14a config" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a info" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a apdu" }, + { 0, "hf 14a apdufind" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a ndefformat" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a ndefwrite" }, + { 1, "hf 14b help" }, + { 0, "hf 14b apdu" }, + { 0, "hf 14b dump" }, + { 0, "hf 14b info" }, + { 1, "hf 14b list" }, + { 0, "hf 14b ndefread" }, + { 0, "hf 14b raw" }, + { 0, "hf 14b reader" }, + { 0, "hf 14b sim" }, + { 0, "hf 14b sniff" }, + { 0, "hf 14b rdbl" }, + { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, + { 1, "hf 15 help" }, + { 1, "hf 15 list" }, + { 1, "hf 15 demod" }, + { 0, "hf 15 dump" }, + { 0, "hf 15 info" }, + { 0, "hf 15 sniff" }, + { 0, "hf 15 raw" }, + { 0, "hf 15 rdbl" }, + { 0, "hf 15 rdmulti" }, + { 0, "hf 15 reader" }, + { 0, "hf 15 restore" }, + { 0, "hf 15 samples" }, + { 0, "hf 15 eload" }, + { 0, "hf 15 esave" }, + { 0, "hf 15 eview" }, + { 0, "hf 15 sim" }, + { 0, "hf 15 slixdisable" }, + { 0, "hf 15 wrbl" }, + { 0, "hf 15 findafi" }, + { 0, "hf 15 writeafi" }, + { 0, "hf 15 writedsfid" }, + { 0, "hf 15 csetuid" }, + { 1, "hf cipurse help" }, + { 0, "hf cipurse info" }, + { 0, "hf cipurse select" }, + { 0, "hf cipurse auth" }, + { 0, "hf cipurse read" }, + { 0, "hf cipurse write" }, + { 0, "hf cipurse aread" }, + { 0, "hf cipurse awrite" }, + { 0, "hf cipurse formatall" }, + { 0, "hf cipurse create" }, + { 0, "hf cipurse delete" }, + { 0, "hf cipurse updkey" }, + { 0, "hf cipurse updakey" }, + { 0, "hf cipurse default" }, + { 1, "hf cipurse test" }, + { 1, "hf epa help" }, + { 0, "hf epa cnonces" }, + { 0, "hf epa replay" }, + { 0, "hf epa sim" }, + { 1, "hf emrtd help" }, + { 0, "hf emrtd dump" }, + { 1, "hf emrtd info" }, + { 1, "hf emrtd list" }, + { 1, "hf felica help" }, + { 1, "hf felica list" }, + { 0, "hf felica reader" }, + { 0, "hf felica info" }, + { 0, "hf felica sniff" }, + { 0, "hf felica raw" }, + { 0, "hf felica rdbl" }, + { 0, "hf felica wrbl" }, + { 0, "hf felica rqservice" }, + { 0, "hf felica rqresponse" }, + { 0, "hf felica scsvcode" }, + { 0, "hf felica rqsyscode" }, + { 0, "hf felica auth1" }, + { 0, "hf felica auth2" }, + { 0, "hf felica rqspecver" }, + { 0, "hf felica resetmode" }, + { 0, "hf felica litesim" }, + { 0, "hf felica litedump" }, + { 1, "hf fido help" }, + { 1, "hf fido list" }, + { 0, "hf fido info" }, + { 0, "hf fido reg" }, + { 0, "hf fido auth" }, + { 0, "hf fido make" }, + { 0, "hf fido assert" }, + { 1, "hf fudan help" }, + { 0, "hf fudan reader" }, + { 0, "hf fudan dump" }, + { 0, "hf fudan rdbl" }, + { 1, "hf fudan view" }, + { 0, "hf fudan wrbl" }, + { 1, "hf gallagher help" }, + { 0, "hf gallagher reader" }, + { 0, "hf gallagher clone" }, + { 0, "hf gallagher delete" }, + { 1, "hf gallagher diversifykey" }, + { 1, "hf gallagher decode" }, + { 1, "hf ksx6924 help" }, + { 0, "hf ksx6924 select" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 init" }, + { 0, "hf ksx6924 prec" }, + { 1, "hf jooki help" }, + { 0, "hf jooki clone" }, + { 1, "hf jooki decode" }, + { 1, "hf jooki encode" }, + { 0, "hf jooki sim" }, + { 1, "hf iclass help" }, + { 0, "hf iclass dump" }, + { 1, "hf iclass info" }, + { 1, "hf iclass list" }, + { 0, "hf iclass rdbl" }, + { 0, "hf iclass reader" }, + { 0, "hf iclass restore" }, + { 0, "hf iclass sniff" }, + { 0, "hf iclass wrbl" }, + { 0, "hf iclass chk" }, + { 1, "hf iclass loclass" }, + { 1, "hf iclass lookup" }, + { 0, "hf iclass sim" }, + { 0, "hf iclass eload" }, + { 0, "hf iclass esave" }, + { 0, "hf iclass eview" }, + { 1, "hf iclass configcard" }, + { 1, "hf iclass calcnewkey" }, + { 1, "hf iclass encode" }, + { 1, "hf iclass encrypt" }, + { 1, "hf iclass decrypt" }, + { 1, "hf iclass managekeys" }, + { 1, "hf iclass permutekey" }, + { 1, "hf iclass view" }, + { 1, "hf legic help" }, + { 0, "hf legic dump" }, + { 0, "hf legic info" }, + { 1, "hf legic list" }, + { 0, "hf legic rdbl" }, + { 0, "hf legic reader" }, + { 0, "hf legic restore" }, + { 0, "hf legic wipe" }, + { 0, "hf legic wrbl" }, + { 0, "hf legic sim" }, + { 0, "hf legic eload" }, + { 0, "hf legic esave" }, + { 0, "hf legic eview" }, + { 1, "hf legic crc" }, + { 1, "hf legic view" }, + { 1, "hf lto help" }, + { 0, "hf lto dump" }, + { 0, "hf lto info" }, + { 1, "hf lto list" }, + { 0, "hf lto rdbl" }, + { 0, "hf lto reader" }, + { 0, "hf lto restore" }, + { 0, "hf lto wrbl" }, + { 1, "hf mf help" }, + { 1, "hf mf list" }, + { 0, "hf mf darkside" }, + { 0, "hf mf nested" }, + { 1, "hf mf hardnested" }, + { 0, "hf mf staticnested" }, + { 0, "hf mf autopwn" }, + { 0, "hf mf nack" }, + { 0, "hf mf chk" }, + { 0, "hf mf fchk" }, + { 1, "hf mf decrypt" }, + { 0, "hf mf supercard" }, + { 0, "hf mf auth4" }, + { 1, "hf mf acl" }, + { 0, "hf mf dump" }, + { 1, "hf mf mad" }, + { 0, "hf mf personalize" }, + { 0, "hf mf rdbl" }, + { 0, "hf mf rdsc" }, + { 0, "hf mf restore" }, + { 0, "hf mf setmod" }, + { 1, "hf mf value" }, + { 1, "hf mf view" }, + { 0, "hf mf wipe" }, + { 0, "hf mf wrbl" }, + { 0, "hf mf sim" }, + { 0, "hf mf ecfill" }, + { 0, "hf mf eclr" }, + { 0, "hf mf egetblk" }, + { 0, "hf mf egetsc" }, + { 0, "hf mf ekeyprn" }, + { 0, "hf mf eload" }, + { 0, "hf mf esave" }, + { 0, "hf mf esetblk" }, + { 0, "hf mf eview" }, + { 0, "hf mf cgetblk" }, + { 0, "hf mf cgetsc" }, + { 0, "hf mf cload" }, + { 0, "hf mf csave" }, + { 0, "hf mf csetblk" }, + { 0, "hf mf csetuid" }, + { 0, "hf mf cview" }, + { 0, "hf mf cwipe" }, + { 0, "hf mf gen3uid" }, + { 0, "hf mf gen3blk" }, + { 0, "hf mf gen3freeze" }, + { 0, "hf mf ggetblk" }, + { 0, "hf mf gload" }, + { 0, "hf mf gsave" }, + { 0, "hf mf gsetblk" }, + { 0, "hf mf gview" }, + { 0, "hf mf ndefformat" }, + { 0, "hf mf ndefread" }, + { 0, "hf mf ndefwrite" }, + { 1, "hf mfp help" }, + { 0, "hf mfp info" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp auth" }, + { 0, "hf mfp rdbl" }, + { 0, "hf mfp rdsc" }, + { 0, "hf mfp wrbl" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp mad" }, + { 0, "hf mfp ndefread" }, + { 1, "hf mfu help" }, + { 1, "hf mfu keygen" }, + { 1, "hf mfu pwdgen" }, + { 0, "hf mfu otptear" }, + { 0, "hf mfu cauth" }, + { 0, "hf mfu dump" }, + { 0, "hf mfu info" }, + { 0, "hf mfu ndefread" }, + { 0, "hf mfu rdbl" }, + { 0, "hf mfu restore" }, + { 1, "hf mfu view" }, + { 0, "hf mfu wrbl" }, + { 0, "hf mfu eload" }, + { 0, "hf mfu esave" }, + { 0, "hf mfu eview" }, + { 0, "hf mfu sim" }, + { 0, "hf mfu setpwd" }, + { 0, "hf mfu setuid" }, + { 1, "hf mfdes help" }, + { 0, "hf mfdes info" }, + { 0, "hf mfdes getuid" }, + { 0, "hf mfdes default" }, + { 0, "hf mfdes auth" }, + { 0, "hf mfdes chk" }, + { 0, "hf mfdes detect" }, + { 0, "hf mfdes freemem" }, + { 0, "hf mfdes setconfig" }, + { 0, "hf mfdes formatpicc" }, + { 1, "hf mfdes list" }, + { 0, "hf mfdes mad" }, + { 0, "hf mfdes lsapp" }, + { 0, "hf mfdes getaids" }, + { 0, "hf mfdes getappnames" }, + { 0, "hf mfdes bruteaid" }, + { 0, "hf mfdes createapp" }, + { 0, "hf mfdes deleteapp" }, + { 0, "hf mfdes selectapp" }, + { 0, "hf mfdes changekey" }, + { 0, "hf mfdes chkeysettings" }, + { 0, "hf mfdes getkeysettings" }, + { 0, "hf mfdes getkeyversions" }, + { 0, "hf mfdes getfileids" }, + { 0, "hf mfdes getfileisoids" }, + { 0, "hf mfdes lsfiles" }, + { 0, "hf mfdes dump" }, + { 0, "hf mfdes createfile" }, + { 0, "hf mfdes createvaluefile" }, + { 0, "hf mfdes createrecordfile" }, + { 0, "hf mfdes createmacfile" }, + { 0, "hf mfdes deletefile" }, + { 0, "hf mfdes getfilesettings" }, + { 0, "hf mfdes chfilesettings" }, + { 0, "hf mfdes read" }, + { 0, "hf mfdes write" }, + { 0, "hf mfdes value" }, + { 0, "hf mfdes clearrecfile" }, + { 1, "hf mfdes test" }, + { 1, "hf ntag424 help" }, + { 0, "hf ntag424 info" }, + { 0, "hf ntag424 sdm" }, + { 1, "hf ntag424 view" }, + { 1, "hf seos help" }, + { 0, "hf seos info" }, + { 1, "hf seos list" }, + { 1, "hf st25ta help" }, + { 0, "hf st25ta info" }, + { 1, "hf st25ta list" }, + { 1, "hf st25ta ndefread" }, + { 0, "hf st25ta protect" }, + { 0, "hf st25ta pwd" }, + { 0, "hf st25ta sim" }, + { 1, "hf thinfilm help" }, + { 0, "hf thinfilm info" }, + { 1, "hf thinfilm list" }, + { 0, "hf thinfilm sim" }, + { 1, "hf topaz help" }, + { 0, "hf topaz dump" }, + { 1, "hf topaz list" }, + { 0, "hf topaz info" }, + { 0, "hf topaz reader" }, + { 0, "hf topaz sim" }, + { 0, "hf topaz sniff" }, + { 0, "hf topaz raw" }, + { 0, "hf topaz rdbl" }, + { 1, "hf topaz view" }, + { 0, "hf topaz wrbl" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, + { 0, "hf xerox dump" }, + { 1, "hf waveshare help" }, + { 0, "hf waveshare loadbmp" }, + { 1, "hw help" }, + { 0, "hw break" }, + { 1, "hw connect" }, + { 0, "hw dbg" }, + { 0, "hw detectreader" }, + { 0, "hw fpgaoff" }, + { 0, "hw lcd" }, + { 0, "hw lcdreset" }, + { 0, "hw ping" }, + { 0, "hw readmem" }, + { 0, "hw reset" }, + { 0, "hw setlfdivisor" }, + { 0, "hw setmux" }, + { 0, "hw standalone" }, + { 0, "hw status" }, + { 0, "hw tearoff" }, + { 0, "hw tia" }, + { 0, "hw tune" }, + { 1, "hw version" }, + { 1, "lf help" }, + { 0, "lf config" }, + { 0, "lf cmdread" }, + { 0, "lf read" }, + { 1, "lf search" }, + { 0, "lf sim" }, + { 0, "lf simask" }, + { 0, "lf simfsk" }, + { 0, "lf simpsk" }, + { 0, "lf simbidir" }, + { 0, "lf sniff" }, + { 0, "lf tune" }, + { 1, "lf awid help" }, + { 1, "lf awid demod" }, + { 0, "lf awid reader" }, + { 0, "lf awid clone" }, + { 0, "lf awid sim" }, + { 0, "lf awid brute" }, + { 0, "lf awid watch" }, + { 1, "lf cotag help" }, + { 1, "lf cotag demod" }, + { 0, "lf cotag reader" }, + { 1, "lf destron help" }, + { 1, "lf destron demod" }, + { 0, "lf destron reader" }, + { 0, "lf destron clone" }, + { 0, "lf destron sim" }, + { 1, "lf em help" }, + { 1, "lf em 410x help" }, + { 1, "lf em 410x demod" }, + { 0, "lf em 410x reader" }, + { 0, "lf em 410x sim" }, + { 0, "lf em 410x brute" }, + { 0, "lf em 410x watch" }, + { 0, "lf em 410x spoof" }, + { 0, "lf em 410x clone" }, + { 1, "lf em 4x05 help" }, + { 0, "lf em 4x05 brute" }, + { 0, "lf em 4x05 chk" }, + { 1, "lf em 4x05 demod" }, + { 0, "lf em 4x05 dump" }, + { 0, "lf em 4x05 info" }, + { 0, "lf em 4x05 read" }, + { 1, "lf em 4x05 sniff" }, + { 0, "lf em 4x05 unlock" }, + { 0, "lf em 4x05 wipe" }, + { 0, "lf em 4x05 write" }, + { 1, "lf em 4x50 help" }, + { 0, "lf em 4x50 brute" }, + { 0, "lf em 4x50 chk" }, + { 0, "lf em 4x50 dump" }, + { 0, "lf em 4x50 info" }, + { 0, "lf em 4x50 login" }, + { 0, "lf em 4x50 rdbl" }, + { 0, "lf em 4x50 reader" }, + { 0, "lf em 4x50 restore" }, + { 0, "lf em 4x50 wrbl" }, + { 0, "lf em 4x50 wrpwd" }, + { 0, "lf em 4x50 wipe" }, + { 0, "lf em 4x50 eload" }, + { 0, "lf em 4x50 esave" }, + { 0, "lf em 4x50 eview" }, + { 0, "lf em 4x50 sim" }, + { 1, "lf em 4x70 help" }, + { 0, "lf em 4x70 info" }, + { 0, "lf em 4x70 write" }, + { 0, "lf em 4x70 unlock" }, + { 0, "lf em 4x70 auth" }, + { 0, "lf em 4x70 writepin" }, + { 0, "lf em 4x70 writekey" }, + { 1, "lf fdxb help" }, + { 1, "lf fdxb demod" }, + { 0, "lf fdxb reader" }, + { 0, "lf fdxb clone" }, + { 0, "lf fdxb sim" }, + { 1, "lf gallagher help" }, + { 1, "lf gallagher demod" }, + { 0, "lf gallagher reader" }, + { 0, "lf gallagher clone" }, + { 0, "lf gallagher sim" }, + { 1, "lf gproxii help" }, + { 1, "lf gproxii demod" }, + { 0, "lf gproxii reader" }, + { 0, "lf gproxii clone" }, + { 0, "lf gproxii sim" }, + { 1, "lf hid help" }, + { 1, "lf hid demod" }, + { 0, "lf hid reader" }, + { 0, "lf hid clone" }, + { 0, "lf hid sim" }, + { 0, "lf hid brute" }, + { 0, "lf hid watch" }, + { 1, "lf hitag help" }, + { 0, "lf hitag eload" }, + { 1, "lf hitag list" }, + { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, + { 0, "lf hitag sim" }, + { 0, "lf hitag sniff" }, + { 0, "lf hitag writer" }, + { 0, "lf hitag dump" }, + { 0, "lf hitag cc" }, + { 1, "lf idteck help" }, + { 1, "lf idteck demod" }, + { 0, "lf idteck reader" }, + { 0, "lf idteck clone" }, + { 0, "lf idteck sim" }, + { 1, "lf indala help" }, + { 0, "lf indala brute" }, + { 1, "lf indala demod" }, + { 1, "lf indala altdemod" }, + { 0, "lf indala reader" }, + { 0, "lf indala clone" }, + { 0, "lf indala sim" }, + { 1, "lf io help" }, + { 1, "lf io demod" }, + { 0, "lf io reader" }, + { 0, "lf io clone" }, + { 0, "lf io sim" }, + { 0, "lf io watch" }, + { 1, "lf jablotron help" }, + { 1, "lf jablotron demod" }, + { 0, "lf jablotron reader" }, + { 0, "lf jablotron clone" }, + { 0, "lf jablotron sim" }, + { 1, "lf keri help" }, + { 1, "lf keri demod" }, + { 0, "lf keri reader" }, + { 0, "lf keri clone" }, + { 0, "lf keri sim" }, + { 1, "lf motorola help" }, + { 1, "lf motorola demod" }, + { 0, "lf motorola reader" }, + { 0, "lf motorola clone" }, + { 0, "lf motorola sim" }, + { 1, "lf nedap help" }, + { 1, "lf nedap demod" }, + { 0, "lf nedap reader" }, + { 0, "lf nedap clone" }, + { 0, "lf nedap sim" }, + { 1, "lf nexwatch help" }, + { 1, "lf nexwatch demod" }, + { 0, "lf nexwatch reader" }, + { 0, "lf nexwatch clone" }, + { 0, "lf nexwatch sim" }, + { 1, "lf noralsy help" }, + { 1, "lf noralsy demod" }, + { 0, "lf noralsy reader" }, + { 0, "lf noralsy clone" }, + { 0, "lf noralsy sim" }, + { 1, "lf pac help" }, + { 1, "lf pac demod" }, + { 0, "lf pac reader" }, + { 0, "lf pac clone" }, + { 0, "lf pac sim" }, + { 1, "lf paradox help" }, + { 1, "lf paradox demod" }, + { 0, "lf paradox reader" }, + { 0, "lf paradox clone" }, + { 0, "lf paradox sim" }, + { 1, "lf pcf7931 help" }, + { 0, "lf pcf7931 reader" }, + { 0, "lf pcf7931 write" }, + { 1, "lf pcf7931 config" }, + { 1, "lf presco help" }, + { 1, "lf presco demod" }, + { 0, "lf presco reader" }, + { 0, "lf presco clone" }, + { 0, "lf presco sim" }, + { 1, "lf pyramid help" }, + { 1, "lf pyramid demod" }, + { 0, "lf pyramid reader" }, + { 0, "lf pyramid clone" }, + { 0, "lf pyramid sim" }, + { 1, "lf securakey help" }, + { 1, "lf securakey demod" }, + { 0, "lf securakey reader" }, + { 0, "lf securakey clone" }, + { 0, "lf securakey sim" }, + { 1, "lf ti help" }, + { 1, "lf ti demod" }, + { 0, "lf ti reader" }, + { 0, "lf ti write" }, + { 1, "lf t55xx help" }, + { 0, "lf t55xx clonehelp" }, + { 1, "lf t55xx config" }, + { 0, "lf t55xx dangerraw" }, + { 1, "lf t55xx detect" }, + { 0, "lf t55xx deviceconfig" }, + { 0, "lf t55xx dump" }, + { 1, "lf t55xx info" }, + { 0, "lf t55xx p1detect" }, + { 0, "lf t55xx read" }, + { 0, "lf t55xx resetread" }, + { 0, "lf t55xx restore" }, + { 1, "lf t55xx trace" }, + { 0, "lf t55xx wakeup" }, + { 0, "lf t55xx write" }, + { 0, "lf t55xx bruteforce" }, + { 0, "lf t55xx chk" }, + { 0, "lf t55xx protect" }, + { 0, "lf t55xx recoverpw" }, + { 1, "lf t55xx sniff" }, + { 0, "lf t55xx special" }, + { 0, "lf t55xx wipe" }, + { 1, "lf viking help" }, + { 1, "lf viking demod" }, + { 0, "lf viking reader" }, + { 0, "lf viking clone" }, + { 0, "lf viking sim" }, + { 1, "lf visa2000 help" }, + { 1, "lf visa2000 demod" }, + { 0, "lf visa2000 reader" }, + { 0, "lf visa2000 clone" }, + { 0, "lf visa2000 sim" }, + { 1, "mem help" }, + { 0, "mem baudrate" }, + { 0, "mem dump" }, + { 0, "mem info" }, + { 0, "mem load" }, + { 0, "mem wipe" }, + { 1, "mem spiffs help" }, + { 0, "mem spiffs copy" }, + { 0, "mem spiffs check" }, + { 0, "mem spiffs dump" }, + { 0, "mem spiffs info" }, + { 0, "mem spiffs mount" }, + { 0, "mem spiffs remove" }, + { 0, "mem spiffs rename" }, + { 0, "mem spiffs test" }, + { 0, "mem spiffs tree" }, + { 0, "mem spiffs unmount" }, + { 0, "mem spiffs upload" }, + { 0, "mem spiffs view" }, + { 0, "mem spiffs wipe" }, + { 1, "nfc help" }, + { 1, "nfc decode" }, + { 0, "nfc type1 read" }, + { 1, "nfc type1 help" }, + { 0, "nfc type2 read" }, + { 1, "nfc type2 help" }, + { 0, "nfc type4a format" }, + { 0, "nfc type4a read" }, + { 0, "nfc type4a write" }, + { 0, "nfc type4a st25taread" }, + { 1, "nfc type4a help" }, + { 0, "nfc type4b read" }, + { 1, "nfc type4b help" }, + { 0, "nfc mf cformat" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf cwrite" }, + { 0, "nfc mf pread" }, + { 1, "nfc mf help" }, + { 0, "nfc barcode read" }, + { 0, "nfc barcode sim" }, + { 1, "nfc barcode help" }, + { 1, "piv help" }, + { 0, "piv select" }, + { 0, "piv getdata" }, + { 0, "piv authsign" }, + { 0, "piv scan" }, + { 1, "piv list" }, + { 1, "smart help" }, + { 1, "smart list" }, + { 0, "smart info" }, + { 0, "smart reader" }, + { 0, "smart raw" }, + { 1, "smart upgrade" }, + { 0, "smart setclock" }, + { 0, "smart brute" }, + { 1, "script help" }, + { 1, "script list" }, + { 1, "script run" }, + { 1, "trace help" }, + { 1, "trace extract" }, + { 1, "trace list" }, + { 1, "trace load" }, + { 1, "trace save" }, + { 1, "usart help" }, + { 0, "usart btpin" }, + { 0, "usart btfactory" }, + { 0, "usart tx" }, + { 0, "usart rx" }, + { 0, "usart txrx" }, + { 0, "usart txhex" }, + { 0, "usart rxhex" }, + { 0, "usart config" }, + { 1, "wiegand help" }, + { 1, "wiegand list" }, + { 1, "wiegand encode" }, + { 1, "wiegand decode" }, {0, NULL} }; @@ -779,4 +779,4 @@ const static vocabulory_t vocabulory[] = { } #endif -#endif +#endif \ No newline at end of file From 6d12f0281a0d7a837879439c9d0e09cdce88544b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Jan 2023 03:26:51 +0100 Subject: [PATCH 537/759] hf telsa info - better text, also added detection of the gauss key applet --- client/src/cmdhftesla.c | 56 +++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/client/src/cmdhftesla.c b/client/src/cmdhftesla.c index b3b5c8939..296323319 100644 --- a/client/src/cmdhftesla.c +++ b/client/src/cmdhftesla.c @@ -64,26 +64,36 @@ static int info_hf_tesla(void) { param_gethex_to_eol("00a404000a7465736c614c6f676963", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n); int res = ExchangeAPDU14a(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen); if (res != PM3_SUCCESS) { - DropField(); - return res; - } - - if (resplen < 2) { - DropField(); - return PM3_ESOFT; - } - - uint16_t sw = get_sw(response, resplen); - if (sw != ISO7816_OK) { - PrintAndLogEx(ERR, "Selecting TESLA aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); DropField(); return PM3_ESOFT; } activate_field = false; + uint16_t sw = get_sw(response, resplen); + + if ((resplen < 2) || (sw != ISO7816_OK)) { + + param_gethex_to_eol("00a404000af465736c614c6f676963", 0, aSELECT_AID, sizeof(aSELECT_AID), &aSELECT_AID_n); + res = ExchangeAPDU14a(aSELECT_AID, aSELECT_AID_n, activate_field, keep_field_on, response, sizeof(response), &resplen); + if (res != PM3_SUCCESS) { + DropField(); + return res; + } + } + + if ((resplen < 2) || (sw != ISO7816_OK)) { + PrintAndLogEx(ERR, "Selecting TESLA aid failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); + // DropField(); + // return PM3_ESOFT; + } + + keep_field_on = true; + // --------------- ECDH public key file reading ---------------- + uint8_t pk[3][65] = {{0}}; + for (uint8_t i = 0; i < 3; i++) { uint8_t aSELECT_PK[5] = {0x80, 0x04, i, 0x00, 0x00}; @@ -94,12 +104,7 @@ static int info_hf_tesla(void) { sw = get_sw(response, resplen); if (sw == ISO7816_OK) { - // save PK for later - uint8_t pk[65] = {0}; - memcpy(pk, response, resplen - 2); - - PrintAndLogEx(INFO, "PUBLIC KEY # %i", i); - PrintAndLogEx(INFO, "%s", sprint_hex_inrow(pk, sizeof(pk))); + memcpy(pk[i], response, resplen - 2); } } @@ -194,13 +199,16 @@ static int info_hf_tesla(void) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------"); PrintAndLogEx(NORMAL, ""); -// PrintAndLogEx(INFO, "PUBLIC KEY"); -// PrintAndLogEx(INFO, "%zu - %s", sizeof(pk), sprint_hex_inrow(pk, sizeof(pk))); - PrintAndLogEx(INFO, "Form factor"); - PrintAndLogEx(INFO, "%zu - %s", sizeof(form_factor), sprint_hex_inrow(form_factor, sizeof(form_factor))); - PrintAndLogEx(INFO, "VERSION"); - PrintAndLogEx(INFO, "%zu - %s", sizeof(version), sprint_hex_inrow(version, sizeof(version))); + PrintAndLogEx(INFO, "PUBLIC KEY"); + for (int i=0; i < 3; i++) { + PrintAndLogEx(INFO, "%d - %s", i, sprint_hex_inrow(pk[i], 65)); + } + PrintAndLogEx(INFO, "Form factor... %s", sprint_hex_inrow(form_factor, sizeof(form_factor))); + PrintAndLogEx(INFO, "Version....... %s", sprint_hex_inrow(version, sizeof(version))); + if ((memcmp(pk[0], pk[1], 65) == 0)) { + PrintAndLogEx(INFO, "GaussKey detected"); + } return PM3_SUCCESS; } From c364a6821c4f7505fbb0d45c884addad473458ae Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 23 Jan 2023 03:32:38 +0100 Subject: [PATCH 538/759] hf tesla info - better textual output --- client/src/cmdhftesla.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/client/src/cmdhftesla.c b/client/src/cmdhftesla.c index 296323319..2680daa90 100644 --- a/client/src/cmdhftesla.c +++ b/client/src/cmdhftesla.c @@ -191,8 +191,6 @@ static int info_hf_tesla(void) { memcpy(auth, response, sizeof(auth)); } - PrintAndLogEx(INFO, "CHALL... %s", sprint_hex_inrow(auth, sizeof(auth))); - keep_field_on = false; DropField(); @@ -203,12 +201,23 @@ static int info_hf_tesla(void) { for (int i=0; i < 3; i++) { PrintAndLogEx(INFO, "%d - %s", i, sprint_hex_inrow(pk[i], 65)); } - PrintAndLogEx(INFO, "Form factor... %s", sprint_hex_inrow(form_factor, sizeof(form_factor))); - PrintAndLogEx(INFO, "Version....... %s", sprint_hex_inrow(version, sizeof(version))); - - if ((memcmp(pk[0], pk[1], 65) == 0)) { - PrintAndLogEx(INFO, "GaussKey detected"); + if (form_factor[1] == 1) { + PrintAndLogEx(INFO, "Form factor... %s (card)", sprint_hex_inrow(form_factor, sizeof(form_factor))); + } else if (form_factor[1] == 2){ + PrintAndLogEx(INFO, "Form factor... %s (phone app)", sprint_hex_inrow(form_factor, sizeof(form_factor))); } + + if (sizeof(version) > 0) { + PrintAndLogEx(INFO, "Version....... %s", sprint_hex_inrow(version, sizeof(version))); + } + + PrintAndLogEx(INFO, "CHALL......... %s", sprint_hex_inrow(auth, sizeof(auth))); + + PrintAndLogEx(INFO, "Fingerprint"); + if ((memcmp(pk[0], pk[1], 65) == 0)) { + PrintAndLogEx(INFO, " GaussKey detected"); + } + // return PM3_SUCCESS; } From 37ec19fdbf63e197af5214825537d460a540c8e4 Mon Sep 17 00:00:00 2001 From: mjacksn Date: Sun, 22 Jan 2023 23:27:09 -0600 Subject: [PATCH 539/759] Correct some parsing of the "get nxp system information" data. I believe that these changes bring it in line with the SLIX "GET NXP SYSTEM INFOMATION" data format (as retrieved from SLIX2 datasheet page 33) --- client/src/cmdhf15.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index c35df7238..d6d933b4b 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -700,14 +700,14 @@ static int NxpSysInfo(uint8_t *uid) { } bool support_signature = (recv[5] & 0x01); - bool support_easmode = (recv[4] & 0x03); + bool support_easmode = (recv[4] & 0x04); PrintAndLogEx(INFO, "--------- " _CYAN_("NXP Sysinfo") " ---------"); PrintAndLogEx(INFO, " raw : %s", sprint_hex(recv, 8)); PrintAndLogEx(INFO, " Password protection configuration:"); PrintAndLogEx(INFO, " * Page L read%s password protected", ((recv[2] & 0x01) ? "" : " not")); PrintAndLogEx(INFO, " * Page L write%s password protected", ((recv[2] & 0x02) ? "" : " not")); - PrintAndLogEx(INFO, " * Page H read%s password protected", ((recv[2] & 0x08) ? "" : " not")); + PrintAndLogEx(INFO, " * Page H read%s password protected", ((recv[2] & 0x10) ? "" : " not")); PrintAndLogEx(INFO, " * Page H write%s password protected", ((recv[2] & 0x20) ? "" : " not")); PrintAndLogEx(INFO, " Lock bits:"); @@ -720,16 +720,16 @@ static int NxpSysInfo(uint8_t *uid) { PrintAndLogEx(INFO, " * User memory password protection%s supported", ((recv[4] & 0x01) ? "" : " not")); PrintAndLogEx(INFO, " * Counter feature%s supported", ((recv[4] & 0x02) ? "" : " not")); PrintAndLogEx(INFO, " * EAS ID%s supported by EAS ALARM command", support_easmode ? "" : " not"); - PrintAndLogEx(INFO, " * EAS password protection%s supported", ((recv[4] & 0x04) ? "" : " not")); + PrintAndLogEx(INFO, " * EAS password protection%s supported", ((recv[4] & 0x08) ? "" : " not")); PrintAndLogEx(INFO, " * AFI password protection%s supported", ((recv[4] & 0x10) ? "" : " not")); PrintAndLogEx(INFO, " * Extended mode%s supported by INVENTORY READ command", ((recv[4] & 0x20) ? "" : " not")); PrintAndLogEx(INFO, " * EAS selection%s supported by extended mode in INVENTORY READ command", ((recv[4] & 0x40) ? "" : " not")); PrintAndLogEx(INFO, " * READ SIGNATURE command%s supported", support_signature ? "" : " not"); PrintAndLogEx(INFO, " * Password protection for READ SIGNATURE command%s supported", ((recv[5] & 0x02) ? "" : " not")); - PrintAndLogEx(INFO, " * STAY QUIET PERSISTENT command%s supported", ((recv[5] & 0x03) ? "" : " not")); + PrintAndLogEx(INFO, " * STAY QUIET PERSISTENT command%s supported", ((recv[5] & 0x04) ? "" : " not")); PrintAndLogEx(INFO, " * ENABLE PRIVACY command%s supported", ((recv[5] & 0x10) ? "" : " not")); PrintAndLogEx(INFO, " * DESTROY command%s supported", ((recv[5] & 0x20) ? "" : " not")); - PrintAndLogEx(INFO, " * Additional 32 bits feature flags are%s transmitted", ((recv[5] & 0x80) ? "" : " not")); + PrintAndLogEx(INFO, " * Additional 32 bits feature flags are%s transmitted", ((recv[7] & 0x80) ? "" : " not")); if (support_easmode) { reqlen = 0; From 8bbc5934b5719ff34773c35bc07bd86dd207cbe9 Mon Sep 17 00:00:00 2001 From: mhjack Date: Sun, 1 Jan 2023 00:59:49 -0600 Subject: [PATCH 540/759] Add detection and info command behavior for NTAG 5 devices, enable EAS status check in info command for SLI, SLIX, SLIX-L, and SLIX-S tags which all support EAS mode (cherry picked from commit a430439f05654fe62c365f4c8f5ee13cb4103dfa) --- client/src/cmdhf15.c | 170 ++++++++++++++++++++++++++----------------- 1 file changed, 102 insertions(+), 68 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index c35df7238..76fc4869a 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -99,6 +99,7 @@ static const productName_t uidmapping[] = { //I-Code SLIX-L [IC id = 03 + bit36 set to 1] { 0xE004000000000000LL, 16, "NXP Semiconductors Germany (Philips)" }, { 0xE004010000000000LL, 24, "NXP(Philips); IC SL2 ICS20/ICS21(SLI) ICS2002/ICS2102(SLIX) ICS2602(SLIX2)" }, + { 0xE004011800000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC NTP53x2/NTP5210/NTA5332(NTAG 5)" }, { 0xE004010000000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS20/ICS21(SLI)" }, { 0xE004011000000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS2002/ICS2102(SLIX)" }, { 0xE004010800000000LL, 0xFFFFFF1800000000LL, "NXP(Philips); IC SL2 ICS2602(SLIX2)" }, @@ -651,6 +652,95 @@ static int CmdHF15Samples(const char *Cmd) { return PM3_SUCCESS; } +static int NxpTestEAS(uint8_t *uid) +{ + uint8_t fast = 1; + uint8_t reply = 1; + PacketResponseNG resp; + uint16_t reqlen = 0; + uint8_t req[PM3_CMD_DATA_SIZE] = {0}; + + req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; + req[reqlen++] = ISO15693_EAS_ALARM; + req[reqlen++] = 0x04; // IC manufacturer code + memcpy(req + 3, uid, 8); // add UID + reqlen += 8; + + AddCrc15(req, reqlen); + reqlen += 2; + + clearCommandBuffer(); + SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen); + + if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "iso15693 timeout"); + } else { + PrintAndLogEx(NORMAL, ""); + + + if (resp.length < 2) { + PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is not active"); + } else { + uint8_t * recv = resp.data.asBytes; + + if (!(recv[0] & ISO15_RES_ERROR)) { + PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is active."); + PrintAndLogEx(INFO, " EAS sequence: %s", sprint_hex(recv + 1, 32)); + } + } + } + + return PM3_SUCCESS; +} + +static int NxpCheckSig(uint8_t *uid) { + uint8_t fast = 1; + uint8_t reply = 1; + PacketResponseNG resp; + uint16_t reqlen = 0; + uint8_t req[PM3_CMD_DATA_SIZE] = {0}; + + // Check if we can also read the signature + req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; + req[reqlen++] = ISO15693_READ_SIGNATURE; + req[reqlen++] = 0x04; // IC manufacturer code + memcpy(req + 3, uid, 8); // add UID + reqlen += 8; + + AddCrc15(req, reqlen); + reqlen += 2; + + clearCommandBuffer(); + SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen); + + if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "iso15693 timeout"); + DropField(); + return PM3_ETIMEOUT; + } + + DropField(); + + if (resp.length < 2) { + PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command"); + return PM3_EWRONGANSWER; + } + + uint8_t *recv = resp.data.asBytes; + + if ((recv[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) { + PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + return PM3_EWRONGANSWER; + } + + uint8_t signature[32] = {0x00}; + memcpy(signature, recv + 1, 32); + + nxp_15693_print_signature(uid, signature); + + return PM3_SUCCESS; +} + // Get NXP system information from SLIX2 tag/VICC static int NxpSysInfo(uint8_t *uid) { @@ -732,77 +822,11 @@ static int NxpSysInfo(uint8_t *uid) { PrintAndLogEx(INFO, " * Additional 32 bits feature flags are%s transmitted", ((recv[5] & 0x80) ? "" : " not")); if (support_easmode) { - reqlen = 0; - req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; - req[reqlen++] = ISO15693_EAS_ALARM; - req[reqlen++] = 0x04; // IC manufacturer code - memcpy(req + 3, uid, 8); // add UID - reqlen += 8; - - AddCrc15(req, reqlen); - reqlen += 2; - - clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen); - - if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { - PrintAndLogEx(WARNING, "iso15693 timeout"); - } else { - PrintAndLogEx(NORMAL, ""); - - - if (resp.length < 2) { - PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is not active"); - } else { - recv = resp.data.asBytes; - - if (!(recv[0] & ISO15_RES_ERROR)) { - PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is active."); - PrintAndLogEx(INFO, " EAS sequence: %s", sprint_hex(recv + 1, 32)); - } - } - } + NxpTestEAS(uid); } if (support_signature) { - // Check if we can also read the signature - reqlen = 0; - req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; - req[reqlen++] = ISO15693_READ_SIGNATURE; - req[reqlen++] = 0x04; // IC manufacturer code - memcpy(req + 3, uid, 8); // add UID - reqlen += 8; - - AddCrc15(req, reqlen); - reqlen += 2; - - clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen); - - if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { - PrintAndLogEx(WARNING, "iso15693 timeout"); - DropField(); - return PM3_ETIMEOUT; - } - - DropField(); - - if (resp.length < 2) { - PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command"); - return PM3_EWRONGANSWER; - } - - recv = resp.data.asBytes; - - if ((recv[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) { - PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return PM3_EWRONGANSWER; - } - - uint8_t signature[32] = {0x00}; - memcpy(signature, recv + 1, 32); - - nxp_15693_print_signature(uid, signature); + NxpCheckSig(uid); } return PM3_SUCCESS; @@ -945,6 +969,16 @@ static int CmdHF15Info(const char *Cmd) { PrintAndLogEx(DEBUG, "SLIX2 Detected, getting NXP System Info"); return NxpSysInfo(uid); } + else if(data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x18) //If it is an NTAG 5 + { + PrintAndLogEx(DEBUG, "NTAG 5 Detected, getting NXP System Info"); + return NxpSysInfo(uid); + } + else if(data[8] == 0x04 && (data[7] == 0x01 || data[7] == 0x02 || data[7] == 0x03)) //If SLI, SLIX, SLIX-l, or SLIX-S check EAS status + { + PrintAndLogEx(DEBUG, "SLI, SLIX, SLIX-L, or SLIX-S Detected checking EAS status"); + return NxpTestEAS(uid); + } PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; From c33ce8f3936dd5f00a960e772ecb474a0b8c1698 Mon Sep 17 00:00:00 2001 From: mjacksn Date: Mon, 23 Jan 2023 10:52:47 -0600 Subject: [PATCH 541/759] changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4cde2d93..c046f0094 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1363,6 +1363,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Mifare simulation, `hf mf sim` (was broken a long time) (@pwpiwi) - Major improvements in LF area and data operations. (@marshmellow42, @iceman1001) - Issues regarding LF simulation (@pwpiwi) + - Issue interpreting NXP "get sys info" command return value for icode tags. (@mjacksn) ### Added - iClass functionality: full simulation of iclass tags, so tags can be simulated with data (not only CSN). Not yet support for write/update, but readers do not seem to enforce update. (@holiman). From 002d0ac24f245012bfe0835bd1cb44a0a176e353 Mon Sep 17 00:00:00 2001 From: mjacksn Date: Mon, 23 Jan 2023 10:57:32 -0600 Subject: [PATCH 542/759] changelog addition --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4cde2d93..c456ac64d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1367,3 +1367,5 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ### Added - iClass functionality: full simulation of iclass tags, so tags can be simulated with data (not only CSN). Not yet support for write/update, but readers do not seem to enforce update. (@holiman). - iClass decryption. Proxmark can now decrypt data on an iclass tag, but requires you to have the HID decryption key locally on your computer, as this is not bundled with the sourcecode. + - `hf 15 info` can detect NTAG 5 tags + - `hf 15 info` include an EAS status check on more of the icode tags which support EAS (SLI, SLIX, SLIX-L, and SLIX-S) \ No newline at end of file From da84eb62064db6387d7424f4974d2d8e46934ed5 Mon Sep 17 00:00:00 2001 From: Alejandro Date: Mon, 23 Jan 2023 20:41:00 +0100 Subject: [PATCH 543/759] proper way --- Makefile.platform.sample | 2 +- client/src/cmdhw.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile.platform.sample b/Makefile.platform.sample index 5dc19e8f0..bfcb5b749 100644 --- a/Makefile.platform.sample +++ b/Makefile.platform.sample @@ -5,7 +5,7 @@ PLATFORM=PM3RDV4 #PLATFORM=PM3GENERIC # If you want more than one PLATFORM_EXTRAS option, separate them by spaces: #PLATFORM_EXTRAS=BTADDON -#STANDALONE=LF_SAMYRUN +STANDALONE=HF_BOG # To accelerate repetitive compilations: # Install package "ccache" -> Debian/Ubuntu: /usr/lib/ccache, Fedora/CentOS/RHEL: /usr/lib64/ccache diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index 0efa5eafe..b3f80e218 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -1202,7 +1202,7 @@ void pm3_version_short(void) { } } - PrintAndLogEx(NORMAL, " Target.... %s", (is_genuine_rdv4) ? _YELLOW_("RDV4") : _RED_("device / fw mismatch")); + PrintAndLogEx(NORMAL, " Target.... %s", (is_genuine_rdv4) ? _YELLOW_("RDV4") : _YELLOW_("PM3 GENERIC")); } else { PrintAndLogEx(NORMAL, " Target.... %s", _YELLOW_("PM3 GENERIC")); } @@ -1291,8 +1291,8 @@ void pm3_version(bool verbose, bool oneliner) { } } - PrintAndLogEx(NORMAL, " device.................... %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _RED_("device / fw mismatch")); - PrintAndLogEx(NORMAL, " firmware.................. %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _YELLOW_("RDV4")); + PrintAndLogEx(NORMAL, " device.................... %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _GREEN_("PM3 GENERIC")); + PrintAndLogEx(NORMAL, " firmware.................. %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _GREEN_("PM3 GENERIC")); PrintAndLogEx(NORMAL, " external flash............ %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " smartcard reader.......... %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent")); From 9a123d943d9a6784092794702404af269bff50d6 Mon Sep 17 00:00:00 2001 From: colonelborkmundus Date: Tue, 24 Jan 2023 00:46:04 -0500 Subject: [PATCH 544/759] add extra keys from flipper unleashed dictionary --- client/dictionaries/mfc_default_keys.dic | 64 ++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 881c72df0..381eabaf5 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1910,6 +1910,70 @@ D144BD193063 8627C10A7014 453857395635 # +# flipper unleashed additions +# +# Transport cards +E954024EE754 +0CD464CDC100 +BC305FE2DA65 +CF0EC6ACF2F9 +F7A545095C49 +6862FD600F78 +72A0C485D3F7 +6A530C91F85B +# RENFE MADRID (TRAIN) Extracted with detect reader +701AA491A4A5 +12BA20088ED3 +# MISC KEYS FROM MY OLD ACCESS CARDS +F18D91EE3033 +0E726E11CFCC +1D14130D1A0B +4ADLE273EAFL +3DFL4C8000A1 +E64Q986Q5D94 +201106141030 +# D144BD193063 (dupe) +01E2C14F1B18 +0380293A9E6D +08A55BC96DC1 +08ED3F92AA53 +0D61BA88789C +190E6242CE7B +1A8CFF2F1BC7 +25FE2B4E4FA9 +321803E38664 +381F84DB8134 +38540EEE8B1C +42F82DB5C4AF +507A6181E4BF +549BB4FD70C4 +57059FFD3EE6 +5E696FA0EAD1 +6036F9D72D68 +6611DFFAAE32 +6AC79644E0CD +735DD20237A9 +79E8B59A51E0 +7B6C00CBAC92 +7C3AF198425F +81C0BBCE32E9 +8D2B780A148D +9001D0E23F8C +A8700E07A58F +AE683AC2A232 +B6728D9B95BA +C290A397F84A +CA22AF33A19B +CBC83E1548B4 +CC5F59A0CE0A +D410EFF9113E +DE5865F29C44 +E108EA397A9A +E10F0E7A8DD5 +F833E24C3F1C +FA8CA10C7D59 +FE98F38F3EE2 +# ########################################## # added by colonelborkmundus # "the more, the marriott" mifare project From 4d2caaebc2a19d048c5fc53d76f1f7d6535aedeb Mon Sep 17 00:00:00 2001 From: Mikhail Elov Date: Tue, 24 Jan 2023 11:15:24 +0300 Subject: [PATCH 545/759] add gen4 GTU magic card command 'Set Ultralight and M1 maximum read/write sectors' --- doc/magic_cards_notes.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index c8decbfe2..07e6cb5d6 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -1086,6 +1086,7 @@ CF 35 <2b ATQA><1b SAK> // Configure ATQA/SAK (swap ATQ CF 68 <00-02> // Configure UID length CF 69 <00-01> // (De)Activate Ultralight mode CF 6A <00-03> // Select Ultralight mode +CF 6B <1b> // Set Ultralight and M1 maximum read/write sectors CF C6 // Dump configuration CF CC // Factory test, returns 6666 CF CD <1b block number><16b block data> // Backdoor write 16b block @@ -1304,6 +1305,19 @@ script run hf_mf_ultimatecard -m 02 ``` Now the card supports the 3DES UL-C authentication. +### Set Ultralight and M1 maximum read/write sectors +^[Top](#top) ^^[Gen4](#g4top) + +``` +hf 14a raw -s -c -t 1000 CF6B<1b blocks> +``` +Hexadecimal, maximum sector data, default 0xFF, range 0x00-0xFF + +Example: set maximum 63 blocks read/write for Mifare Classic 1K + +``` +hf 14a raw -s -c -t 1000 CF000000006B3F +``` ### Set shadow mode (GTU) ^[Top](#top) ^^[Gen4](#g4top) From e6b7efa9dfd6be76de49f96a0961fd934ce48979 Mon Sep 17 00:00:00 2001 From: Mikhail Elov Date: Tue, 24 Jan 2023 12:00:21 +0300 Subject: [PATCH 546/759] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c456ac64d..942100d85 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] + - Added new magic gen4 cards command in docs (@McEloff) - Added `hf tesla info` - intital information command to read TESLA cards (@iceman1001) - Changed `hf emrtd info` - looking for lower case .bin extensions (@iceman1001) - Changed `hf emrtd dump` - looking for lower case .bin extensions (@iceman1001) From 689e9c2179f9565f32acb836ee9504b3b32385bf Mon Sep 17 00:00:00 2001 From: Mikhail Elov Date: Tue, 24 Jan 2023 15:44:28 +0300 Subject: [PATCH 547/759] Add new info about configuration dump gen4 GTU and description of unknown command --- doc/magic_cards_notes.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 07e6cb5d6..db8057e5e 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -1091,6 +1091,7 @@ CF C6 // Dump configuration CF CC // Factory test, returns 6666 CF CD <1b block number><16b block data> // Backdoor write 16b block CF CE <1b block number> // Backdoor read 16b block +CF CF <1b param> // Unknown CF F0 <30b configuration data> // Configure all params in one cmd CF F1 <30b configuration data> // Configure all params in one cmd and fuse the configuration permanently CF FE <4b new_password> // change password @@ -1379,6 +1380,20 @@ Example: write block0 with factory data, default pwd hf 14a raw -s -c -t 1000 CF00000000CD00112233441C000011778185BA18000000 ``` +### Unknown command +^[Top](#top) ^^[Gen4](#g4top) + +This command modifies one byte in configuration dump, but purpose one is unknown. + +``` +hf 14a raw -s -c -t 1000 CFCF<1b param> +``` + * `` + * `??`: ??? + +Example: +hf 14a raw -s -c -t 1000 CF00000000CF02 + ### Change backdoor password ^[Top](#top) ^^[Gen4](#g4top) @@ -1405,8 +1420,10 @@ hf 14a raw -s -c -t 1000 CFC6 ``` Default configuration: ``` -00000000000002000978009102DABC191010111213141516040008004F6B - ^^^^ ?? +00000000000002000978009102DABC191010111213141516040008006B024F6B + ^^^^ ?? + ^^ cf cmd cf: ?? this byte set by cmd cfcf, factory value 0x02 + ^^ cf cmd 6b: maximum read/write sectors, factory value 0x6b ^^ cf cmd 6a: UL mode ^^^^^^ cf cmd 35: ATQA/SAK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cf cmd 34: ATS length & content From 844e6109b80141fa35d626b25b489ecb003ef8b2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 24 Jan 2023 15:09:23 +0100 Subject: [PATCH 548/759] Add LF_PROX2BRUTE to build_all_firmwares.sh --- tools/build_all_firmwares.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_all_firmwares.sh b/tools/build_all_firmwares.sh index c6bb8969d..73e340d70 100755 --- a/tools/build_all_firmwares.sh +++ b/tools/build_all_firmwares.sh @@ -30,7 +30,7 @@ mkdir -p "$DEST" mv bootrom/obj/bootrom.elf "$DEST/PM3BOOTROM.elf" # cf armsrc/Standalone/Makefile.hal -STANDALONE_MODES=(LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID LF_NEDAP_SIM) +STANDALONE_MODES=(LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID LF_NEDAP_SIM) STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI) STANDALONE_MODES_REQ_BT=(HF_REBLAY) STANDALONE_MODES_REQ_SMARTCARD=() From 248cec793c76824fd55be4383e26a107ca27d9ab Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 24 Jan 2023 15:21:59 +0100 Subject: [PATCH 549/759] standalone: respect alphabetical order, else it's a mess to cross-check --- armsrc/Standalone/Makefile.hal | 12 +- armsrc/Standalone/Makefile.inc | 136 +++++++++--------- armsrc/Standalone/readme.md | 10 +- .../4_Advanced-compilation-parameters.md | 2 +- tools/build_all_firmwares.sh | 6 +- 5 files changed, 88 insertions(+), 78 deletions(-) diff --git a/armsrc/Standalone/Makefile.hal b/armsrc/Standalone/Makefile.hal index 6b9343683..cb41bc148 100644 --- a/armsrc/Standalone/Makefile.hal +++ b/armsrc/Standalone/Makefile.hal @@ -50,12 +50,12 @@ define KNOWN_STANDALONE_DEFINITIONS | LF_ICEHID | LF HID collector to flashmem | | (RDV4 only) | | +----------------------------------------------------------+ -| LF_NEXID | LF Nexwatch collector to flashmem | -| (RDV4 only) | | -+----------------------------------------------------------+ | LF_NEDAP_SIM | LF Nedap ID simple simulator | | | | +----------------------------------------------------------+ +| LF_NEXID | LF Nexwatch collector to flashmem | +| (RDV4 only) | | ++----------------------------------------------------------+ | LF_PROXBRUTE | HID ProxII bruteforce | | | - Brad Antoniewicz | +----------------------------------------------------------+ @@ -125,8 +125,10 @@ define KNOWN_STANDALONE_DEFINITIONS endef -STANDALONE_MODES := LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID LF_NEDAP_SIM -STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI +STANDALONE_MODES := LF_SKELETON +STANDALONE_MODES += LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE +STANDALONE_MODES += HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_YOUNG +STANDALONE_MODES += DANKARMULTI STANDALONE_MODES_REQ_BT := HF_REBLAY STANDALONE_MODES_REQ_SMARTCARD := STANDALONE_MODES_REQ_FLASH := LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM diff --git a/armsrc/Standalone/Makefile.inc b/armsrc/Standalone/Makefile.inc index d3f88823e..48ac2217f 100644 --- a/armsrc/Standalone/Makefile.inc +++ b/armsrc/Standalone/Makefile.inc @@ -21,6 +21,42 @@ SRC_STANDALONE = placeholder.c ifneq (,$(findstring WITH_STANDALONE_LF_SKELETON,$(APP_CFLAGS))) SRC_STANDALONE = lf_skeleton.c endif +# WITH_STANDALONE_LF_EM4100EMUL +ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMUL,$(APP_CFLAGS))) + SRC_STANDALONE = lf_em4100emul.c +endif +# WITH_STANDALONE_LF_EM4100RSWB +ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RSWB,$(APP_CFLAGS))) + SRC_STANDALONE = lf_em4100rswb.c +endif +# WITH_STANDALONE_LF_EM4100RSWW +ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RSWW,$(APP_CFLAGS))) + SRC_STANDALONE = lf_em4100rsww.c +endif +# WITH_STANDALONE_LF_EM4100RWC +ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RWC,$(APP_CFLAGS))) + SRC_STANDALONE = lf_em4100rwc.c +endif +# WITH_STANDALONE_LF_HIDBRUTE +ifneq (,$(findstring WITH_STANDALONE_LF_HIDBRUTE,$(APP_CFLAGS))) + SRC_STANDALONE = lf_hidbrute.c +endif +# WITH_STANDALONE_LF_HIDFCBRUTE +ifneq (,$(findstring WITH_STANDALONE_LF_HIDFCBRUTE,$(APP_CFLAGS))) + SRC_STANDALONE = lf_hidfcbrute.c +endif +# WITH_STANDALONE_LF_ICEHID +ifneq (,$(findstring WITH_STANDALONE_LF_ICEHID,$(APP_CFLAGS))) + SRC_STANDALONE = lf_icehid.c +endif +# WITH_STANDALONE_LF_NEDAP_SIM +ifneq (,$(findstring WITH_STANDALONE_LF_NEDAP_SIM,$(APP_CFLAGS))) + SRC_STANDALONE = lf_nedap_sim.c +endif +# WITH_STANDALONE_LF_NEXID +ifneq (,$(findstring WITH_STANDALONE_LF_NEXID,$(APP_CFLAGS))) + SRC_STANDALONE = lf_nexid.c +endif # WITH_STANDALONE_LF_SAMYRUN ifneq (,$(findstring WITH_STANDALONE_LF_SAMYRUN,$(APP_CFLAGS))) SRC_STANDALONE = lf_samyrun.c @@ -33,29 +69,9 @@ endif ifneq (,$(findstring WITH_STANDALONE_LF_PROX2BRUTE,$(APP_CFLAGS))) SRC_STANDALONE = lf_prox2brute.c endif -# WITH_STANDALONE_LF_HIDBRUTE -ifneq (,$(findstring WITH_STANDALONE_LF_HIDBRUTE,$(APP_CFLAGS))) - SRC_STANDALONE = lf_hidbrute.c -endif -# WITH_STANDALONE_LF_HIDFCBRUTE -ifneq (,$(findstring WITH_STANDALONE_LF_HIDFCBRUTE,$(APP_CFLAGS))) - SRC_STANDALONE = lf_hidfcbrute.c -endif -# WITH_STANDALONE_HF_YOUNG -ifneq (,$(findstring WITH_STANDALONE_HF_YOUNG,$(APP_CFLAGS))) - SRC_STANDALONE = hf_young.c -endif -# WITH_STANDALONE_HF_MATTYRUN -ifneq (,$(findstring WITH_STANDALONE_HF_MATTYRUN,$(APP_CFLAGS))) - SRC_STANDALONE = hf_mattyrun.c -endif -# WITH_STANDALONE_HF_COLIN -ifneq (,$(findstring WITH_STANDALONE_HF_COLIN,$(APP_CFLAGS))) - SRC_STANDALONE = vtsend.c hf_colin.c frozen.c nprintf.c -endif -# WITH_STANDALONE_HF_BOG -ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS))) - SRC_STANDALONE = hf_bog.c +# WITH_STANDALONE_LF_THAREXDE +ifneq (,$(findstring WITH_STANDALONE_LF_THAREXDE,$(APP_CFLAGS))) + SRC_STANDALONE = lf_tharexde.c endif # WITH_STANDALONE_HF_14ASNIFF ifneq (,$(findstring WITH_STANDALONE_HF_14ASNIFF,$(APP_CFLAGS))) @@ -73,33 +89,21 @@ endif ifneq (,$(findstring WITH_STANDALONE_HF_AVEFUL,$(APP_CFLAGS))) SRC_STANDALONE = hf_aveful.c endif -# WITH_STANDALONE_HF_TCPRST -ifneq (,$(findstring WITH_STANDALONE_HF_TCPRST,$(APP_CFLAGS))) - SRC_STANDALONE = hf_tcprst.c +# WITH_STANDALONE_HF_BOG +ifneq (,$(findstring WITH_STANDALONE_HF_BOG,$(APP_CFLAGS))) + SRC_STANDALONE = hf_bog.c endif -# WITH_STANDALONE_LF_ICEHID -ifneq (,$(findstring WITH_STANDALONE_LF_ICEHID,$(APP_CFLAGS))) - SRC_STANDALONE = lf_icehid.c +# WITH_STANDALONE_HF_COLIN +ifneq (,$(findstring WITH_STANDALONE_HF_COLIN,$(APP_CFLAGS))) + SRC_STANDALONE = vtsend.c hf_colin.c frozen.c nprintf.c endif -# WITH_STANDALONE_LF_NEXID -ifneq (,$(findstring WITH_STANDALONE_LF_NEXID,$(APP_CFLAGS))) - SRC_STANDALONE = lf_nexid.c +# WITH_STANDALONE_HF_CRAFTBYTE +ifneq (,$(findstring WITH_STANDALONE_HF_CRAFTBYTE,$(APP_CFLAGS))) + SRC_STANDALONE = hf_craftbyte.c endif -# WITH_STANDALONE_LF_EM4100EMUL -ifneq (,$(findstring WITH_STANDALONE_LF_EM4100EMUL,$(APP_CFLAGS))) - SRC_STANDALONE = lf_em4100emul.c -endif -# WITH_STANDALONE_LF_EM4100RSWB -ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RSWB,$(APP_CFLAGS))) - SRC_STANDALONE = lf_em4100rswb.c -endif -# WITH_STANDALONE_LF_EM4100RSWW -ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RSWW,$(APP_CFLAGS))) - SRC_STANDALONE = lf_em4100rsww.c -endif -# WITH_STANDALONE_LF_EM4100RWC -ifneq (,$(findstring WITH_STANDALONE_LF_EM4100RWC,$(APP_CFLAGS))) - SRC_STANDALONE = lf_em4100rwc.c +# WITH_STANDALONE_HF_ICECLASS +ifneq (,$(findstring WITH_STANDALONE_HF_ICECLASS,$(APP_CFLAGS))) + SRC_STANDALONE = hf_iceclass.c endif # WITH_STANDALONE_HF_LEGIC ifneq (,$(findstring WITH_STANDALONE_HF_LEGIC,$(APP_CFLAGS))) @@ -109,37 +113,33 @@ endif ifneq (,$(findstring WITH_STANDALONE_HF_LEGICSIM,$(APP_CFLAGS))) SRC_STANDALONE = hf_legicsim.c endif +# WITH_STANDALONE_HF_MATTYRUN +ifneq (,$(findstring WITH_STANDALONE_HF_MATTYRUN,$(APP_CFLAGS))) + SRC_STANDALONE = hf_mattyrun.c +endif +# WITH_STANDALONE_HF_MFCSIM +ifneq (,$(findstring WITH_STANDALONE_HF_MFCSIM,$(APP_CFLAGS))) + SRC_STANDALONE = hf_mfcsim.c +endif # WITH_STANDALONE_HF_MSDSAL ifneq (,$(findstring WITH_STANDALONE_HF_MSDSAL,$(APP_CFLAGS))) SRC_STANDALONE = hf_msdsal.c endif -# WITH_STANDALONE_HF_ICECLASS -ifneq (,$(findstring WITH_STANDALONE_HF_ICECLASS,$(APP_CFLAGS))) - SRC_STANDALONE = hf_iceclass.c +# WITH_STANDALONE_HF_REBLAY +ifneq (,$(findstring WITH_STANDALONE_HF_REBLAY,$(APP_CFLAGS))) + SRC_STANDALONE = hf_reblay.c endif -# WITH_STANDALONE_LF_THAREXDE -ifneq (,$(findstring WITH_STANDALONE_LF_THAREXDE,$(APP_CFLAGS))) - SRC_STANDALONE = lf_tharexde.c -endif -# WITH_STANDALONE_HF_CRAFTBYTE -ifneq (,$(findstring WITH_STANDALONE_HF_CRAFTBYTE,$(APP_CFLAGS))) - SRC_STANDALONE = hf_craftbyte.c +# WITH_STANDALONE_HF_TCPRST +ifneq (,$(findstring WITH_STANDALONE_HF_TCPRST,$(APP_CFLAGS))) + SRC_STANDALONE = hf_tcprst.c endif # WITH_STANDALONE_HF_TMUDFORD ifneq (,$(findstring WITH_STANDALONE_HF_TMUDFORD,$(APP_CFLAGS))) SRC_STANDALONE = hf_tmudford.c endif - # WITH_STANDALONE_HF_REBLAY -ifneq (,$(findstring WITH_STANDALONE_HF_REBLAY,$(APP_CFLAGS))) - SRC_STANDALONE = hf_reblay.c -endif - # WITH_STANDALONE_HF_MFCSIM -ifneq (,$(findstring WITH_STANDALONE_HF_MFCSIM,$(APP_CFLAGS))) - SRC_STANDALONE = hf_mfcsim.c -endif -# WITH_STANDALONE_LF_NEDAP_SIM -ifneq (,$(findstring WITH_STANDALONE_LF_NEDAP_SIM,$(APP_CFLAGS))) - SRC_STANDALONE = lf_nedap_sim.c +# WITH_STANDALONE_HF_YOUNG +ifneq (,$(findstring WITH_STANDALONE_HF_YOUNG,$(APP_CFLAGS))) + SRC_STANDALONE = hf_young.c endif ifneq (,$(findstring WITH_STANDALONE_DANKARMULTI,$(APP_CFLAGS))) diff --git a/armsrc/Standalone/readme.md b/armsrc/Standalone/readme.md index 8cca3ce03..fe4bdfe1e 100644 --- a/armsrc/Standalone/readme.md +++ b/armsrc/Standalone/readme.md @@ -100,6 +100,8 @@ STANDALONE_MODES_REQ_FLASH := STANDALONE_MODES_REQ_BT := ``` +Please respect alphabetic order! + ## Update MAKEFILE.INC ^[Top](#top) @@ -117,6 +119,8 @@ ifneq (,$(findstring WITH_STANDALONE_LF_FOO,$(APP_CFLAGS))) endif ``` +Please respect alphabetic order! + ## Adding identification string of your mode ^[Top](#top) @@ -174,9 +178,11 @@ Once you're ready to share your mode, please * add a line in CHANGELOG.md * add your mode in the modes table in `doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md` -* add your mode in `tools/build_all_firmwares.sh` +* add your mode in `tools/build_all_firmwares.sh` such that it reflects `armsrc/Standalone/Makefile.hal` list of firmwares to build. -and submit your PR. +Please respect alphabetic order of standalone modes everywhere! + +Then submit your PR. Once approved, add also your mode in https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index ee8c63465..90af8fd8f 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -119,8 +119,8 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo | HF_15SNIFF | 15693 sniff storing to flashmem - Glaser | HF_AVEFUL | MIFARE Ultralight read/simulation - Ave Ozkal | HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth storing in flashmem - Bogito -| HF_CRAFTBYTE | UID stealer - Emulates scanned 14a UID - Anze Jensterle | HF_COLIN | Mifare ultra fast sniff/sim/clone - Colin Brigato +| HF_CRAFTBYTE | UID stealer - Emulates scanned 14a UID - Anze Jensterle | HF_ICECLASS | iCLASS 4-1 mode sim/read & dump/loclass/glitch & config to flashmem - Iceman1001 | HF_LEGIC | HF Legic Prime Read/Store/Sim standalone - uhei | HF_LEGICSIM | HF Legic Prime Simulate standalone - uhei diff --git a/tools/build_all_firmwares.sh b/tools/build_all_firmwares.sh index 73e340d70..b76f7a45a 100755 --- a/tools/build_all_firmwares.sh +++ b/tools/build_all_firmwares.sh @@ -30,8 +30,10 @@ mkdir -p "$DEST" mv bootrom/obj/bootrom.elf "$DEST/PM3BOOTROM.elf" # cf armsrc/Standalone/Makefile.hal -STANDALONE_MODES=(LF_SKELETON LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE LF_NEXID LF_NEDAP_SIM) -STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_TCPRST HF_TMUDFORD HF_YOUNG HF_REBLAY DANKARMULTI) +STANDALONE_MODES=(LF_SKELETON) +STANDALONE_MODES+=(LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE) +STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_YOUNG) +STANDALONE_MODES+=(DANKARMULTI) STANDALONE_MODES_REQ_BT=(HF_REBLAY) STANDALONE_MODES_REQ_SMARTCARD=() STANDALONE_MODES_REQ_FLASH=(LF_HIDFCBRUTE LF_ICEHID LF_NEXID LF_THAREXDE HF_BOG HF_COLIN HF_ICECLASS HF_LEGICSIM HF_MFCSIM) From 1a6bb585502eb16c080f7a87f483219068cd8c6c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 24 Jan 2023 15:37:36 +0100 Subject: [PATCH 550/759] Add LF_PROX2BRUTE to 4_Advanced-compilation-parameters.md --- armsrc/Standalone/lf_prox2brute.c | 2 +- doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/armsrc/Standalone/lf_prox2brute.c b/armsrc/Standalone/lf_prox2brute.c index 0117e91e6..4f092007f 100644 --- a/armsrc/Standalone/lf_prox2brute.c +++ b/armsrc/Standalone/lf_prox2brute.c @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// Copyright (C) Brad Antoniewicz 2011 +// Copyright (C) Yann Gascuel 2023 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. // // This program is free software: you can redistribute it and/or modify diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index 90af8fd8f..fa1021d0c 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -111,6 +111,7 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo | LF_NEDAP_SIM | LF Nedap ID simulator | LF_NEXID | Nexwatch credentials detection mode - jrjgjk & Zolorah | LF_PROXBRUTE | HID ProxII bruteforce - Brad Antoniewicz +| LF_PROX2BRUTE | HID ProxII bruteforce v2 - Yann Gascuel | LF_SAMYRUN (def)| HID26 read/clone/sim - Samy Kamkar | LF_SKELETON | standalone mode skeleton - Iceman1001 | LF_THAREXDE | LF EM4x50 simulator/read standalone mode - tharexde From 40f37c2c4236b4586e82e87fab777309f3fa5697 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 24 Jan 2023 15:41:40 +0100 Subject: [PATCH 551/759] Missing cmdhftesla.c in client/experimental_lib/CMakeLists.txt --- client/experimental_lib/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 3855d6884..675dda225 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -294,6 +294,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdhfseos.c ${PM3_ROOT}/client/src/cmdhfst.c ${PM3_ROOT}/client/src/cmdhfst25ta.c + ${PM3_ROOT}/client/src/cmdhftesla.c ${PM3_ROOT}/client/src/cmdhftexkom.c ${PM3_ROOT}/client/src/cmdhfthinfilm.c ${PM3_ROOT}/client/src/cmdhftopaz.c From 474aaed4b7a527f61a28012b271aa577e3e92b21 Mon Sep 17 00:00:00 2001 From: Alejandro Date: Tue, 24 Jan 2023 23:01:28 +0100 Subject: [PATCH 552/759] Added a proper way to check if it is rdv4 fw --- armsrc/appmain.c | 6 ++++++ client/src/cmdhw.c | 10 +++++++--- client/src/cmdparser.c | 2 +- common_arm/Makefile.hal | 1 + include/pm3_cmd.h | 1 + 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 76d9ac3c0..80b85e93b 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -453,6 +453,12 @@ static void SendCapabilities(void) { capabilities.baudrate = g_usart_baudrate; #endif +#ifdef RDV4 + capabilities.is_rdv4 = true; +#else + capabilities.is_rdv4 = false; +#endif + #ifdef WITH_FLASH capabilities.compiled_with_flash = true; capabilities.hw_available_flash = FlashInit(); diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index b3f80e218..67f404bc9 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -1202,7 +1202,7 @@ void pm3_version_short(void) { } } - PrintAndLogEx(NORMAL, " Target.... %s", (is_genuine_rdv4) ? _YELLOW_("RDV4") : _YELLOW_("PM3 GENERIC")); + PrintAndLogEx(NORMAL, " Target.... %s", (is_genuine_rdv4) ? _YELLOW_("RDV4") : _RED_("device / fw mismatch")); } else { PrintAndLogEx(NORMAL, " Target.... %s", _YELLOW_("PM3 GENERIC")); } @@ -1291,13 +1291,17 @@ void pm3_version(bool verbose, bool oneliner) { } } - PrintAndLogEx(NORMAL, " device.................... %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _GREEN_("PM3 GENERIC")); - PrintAndLogEx(NORMAL, " firmware.................. %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _GREEN_("PM3 GENERIC")); + PrintAndLogEx(NORMAL, " device.................... %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _RED_("device / fw mismatch")); + PrintAndLogEx(NORMAL, " firmware.................. %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _YELLOW_("RDV4")); PrintAndLogEx(NORMAL, " external flash............ %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " smartcard reader.......... %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent")); PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent")); } else { PrintAndLogEx(NORMAL, " firmware.................. %s", _YELLOW_("PM3 GENERIC")); + if (IfPm3Flash()) { + PrintAndLogEx(NORMAL, " external flash............ %s", _GREEN_("present")); + } + if (IfPm3FpcUsartHost()) { PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", _GREEN_("present")); } diff --git a/client/src/cmdparser.c b/client/src/cmdparser.c index 96c5f0fb3..1c360e832 100644 --- a/client/src/cmdparser.c +++ b/client/src/cmdparser.c @@ -38,7 +38,7 @@ bool IfPm3Present(void) { bool IfPm3Rdv4Fw(void) { if (!IfPm3Present()) return false; - return (g_pm3_capabilities.compiled_with_flash) || (g_pm3_capabilities.compiled_with_smartcard); + return (g_pm3_capabilities.is_rdv4); } bool IfPm3Flash(void) { diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index 68417eb60..0e9dd455b 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -95,6 +95,7 @@ ifeq ($(PLATFORM),PM3RDV4) PLATFORM_DEFS = -DWITH_SMARTCARD -DWITH_FLASH -DRDV4 PLTNAME = Proxmark3 RDV4 PLATFORM_FPGA = xc2s30 + RDV4 = yes else ifeq ($(PLATFORM),PM3OTHER) $(warning PLATFORM=PM3OTHER is deprecated, please use PLATFORM=PM3GENERIC) PLTNAME = Proxmark3 generic target diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 95750b9b7..83db2f05d 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -205,6 +205,7 @@ typedef struct { // rdv4 bool hw_available_flash : 1; bool hw_available_smartcard : 1; + bool is_rdv4 : 1; } PACKED capabilities_t; #define CAPABILITIES_VERSION 6 extern capabilities_t g_pm3_capabilities; From 1c3a1a0660974657da46b5f1d075279a52939e39 Mon Sep 17 00:00:00 2001 From: George Talusan Date: Wed, 25 Jan 2023 10:50:20 -0500 Subject: [PATCH 553/759] unconditionally recalculate pwd/pack for amiibo simulation --- client/luascripts/hf_mfu_amiibo_sim.lua | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/client/luascripts/hf_mfu_amiibo_sim.lua b/client/luascripts/hf_mfu_amiibo_sim.lua index 289e0b465..e00248c90 100644 --- a/client/luascripts/hf_mfu_amiibo_sim.lua +++ b/client/luascripts/hf_mfu_amiibo_sim.lua @@ -139,14 +139,10 @@ local function main(args) -- force lock bytes, otherwise the Amiibo won't be recognized blocks[16] = blocks[16]:sub(1, 4)..'0FE0' - -- add PWD and PACK if necessary + -- add PWD and PACK local uid = blocks[14]:sub(1, 6)..blocks[15]:sub(1, 8) - if blocks[147] == nil or blocks[147] == '00000000' then - blocks[147] = ("%08x"):format(bxor(bxor(tonumber(sub(uid, 2, 10), 16), tonumber(sub(uid, 6, 14), 16)), 0xaa55aa55)) - end - if blocks[148] == nil or blocks[148] == '00000000' then - blocks[148] = "80800000" - end + blocks[147] = ("%08x"):format(bxor(bxor(tonumber(sub(uid, 2, 10), 16), tonumber(sub(uid, 6, 14), 16)), 0xaa55aa55)) + blocks[148] = "80800000" err = LoadEmulator(uid, blocks) if err then return oops(err) end From 86d26f9464b9c3301a52f9b297509429aa4866e8 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Thu, 26 Jan 2023 01:13:27 +0100 Subject: [PATCH 554/759] Fix uninitialised stack-based buffers --- client/src/util.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/util.c b/client/src/util.c index 63141d01c..b13c5e3a9 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -266,7 +266,7 @@ void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) { uint8_t mod = len % breaks; if (mod) { - char buf[UTIL_BUFFER_SIZE_SPRINT + 3]; + char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0}; hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 1, true); // add the spaces... @@ -291,7 +291,7 @@ void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t brea uint8_t mod = len % breaks; if (mod) { - char buf[UTIL_BUFFER_SIZE_SPRINT + 3]; + char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0}; hex_to_buffer((uint8_t *)buf, data + i, mod, (sizeof(buf) - 1), 0, 0, true); // add the spaces... @@ -307,7 +307,7 @@ static void print_buffer_ex(const uint8_t *data, const size_t len, int level, ui if ((data == NULL) || (len < 1)) return; - char buf[UTIL_BUFFER_SIZE_SPRINT + 3]; + char buf[UTIL_BUFFER_SIZE_SPRINT + 3] = {0}; int i; for (i = 0; i < len; i += breaks) { @@ -614,7 +614,7 @@ void bytes_to_bytebits(const void *src, const size_t srclen, void *dest) { // hh,gg,ff,ee,dd,cc,bb,aa, pp,oo,nn,mm,ll,kk,jj,ii // up to 64 bytes or 512 bits uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize) { - static uint8_t buf[64]; + static uint8_t buf[64] = {0}; memset(buf, 0x00, 64); uint8_t *tmp = buf; for (uint8_t block = 0; block < (uint8_t)(len / blockSize); block++) { From da470c928c07b65c9737fe27a6af89357bedd2f1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 27 Jan 2023 02:53:54 +0100 Subject: [PATCH 555/759] data raw --fs -i, fix the accidental reverse of the invert param --- client/src/cmddata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 647c062a4..f9a0036d8 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -1230,7 +1230,7 @@ int FSKrawDemod(uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow, bo PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, _YELLOW_("%s") " decoded bitstream", GetFSKType(fchigh, fclow, invert)); PrintAndLogEx(INFO, "-----------------------"); - printDemodBuff(0, false, invert, false); + printDemodBuff(0, false, false, false); } goto out; } else { From 67ef18f4ed00d5aa0b3cddb88c17eac0d46cde96 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 27 Jan 2023 02:54:30 +0100 Subject: [PATCH 556/759] prepping for more colors in the cli --- include/ansi.h | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/include/ansi.h b/include/ansi.h index c06c06e6b..59f546e39 100644 --- a/include/ansi.h +++ b/include/ansi.h @@ -21,18 +21,45 @@ #define AEND "\x1b[0m" -#define _BLUE_(s) "\x1b[34m" s AEND -#define _RED_(s) "\x1b[31m" s AEND -#define _GREEN_(s) "\x1b[32m" s AEND -#define _YELLOW_(s) "\x1b[33m" s AEND -#define _MAGENTA_(s) "\x1b[35m" s AEND -#define _CYAN_(s) "\x1b[36m" s AEND -#define _WHITE_(s) "\x1b[37m" s AEND +#define _BLACK_(s) "\x1b[30m" s AEND +#define _RED_(s) "\x1b[31m" s AEND +#define _GREEN_(s) "\x1b[32m" s AEND +#define _YELLOW_(s) "\x1b[33m" s AEND +#define _BLUE_(s) "\x1b[34m" s AEND +#define _MAGENTA_(s) "\x1b[35m" s AEND +#define _CYAN_(s) "\x1b[36m" s AEND +#define _WHITE_(s) "\x1b[37m" s AEND + +#define _BRIGHT_BLACK_(s) "\x1b[30;1m" s AEND +#define _BRIGHT_RED_(s) "\x1b[31;1m" s AEND +#define _BRIGHT_GREEN_(s) "\x1b[32;1m" s AEND +#define _BRIGHT_YELLOW_(s) "\x1b[33;1m" s AEND +#define _BRIGHT_BLUE_(s) "\x1b[34;1m" s AEND +#define _BRIGHT_MAGENTA_(s) "\x1b[35;1m" s AEND +#define _BRIGHT_CYAN_(s) "\x1b[36;1m" s AEND +#define _BRIGHT_WHITE_(s) "\x1b[37;1m" s AEND + +#define _BACK_BLACK_(s) "\x1b[40m" s AEND +#define _BACK_RED_(s) "\x1b[41m" s AEND +#define _BACK_GREEN_(s) "\x1b[42m" s AEND +#define _BACK_YELLOW_(s) "\x1b[43m" s AEND +#define _BACK_BLUE_(s) "\x1b[44m" s AEND +#define _BACK_MAGENTA_(s) "\x1b[45m" s AEND +#define _BACK_CYAN_(s) "\x1b[46m" s AEND +#define _BACK_WHITE_(s) "\x1b[47m" s AEND + +#define _BACK_BRIGHT_BLACK_(s) "\x1b[40;1m" s AEND +#define _BACK_BRIGHT_RED_(s) "\x1b[41;1m" s AEND +#define _BACK_BRIGHT_GREEN_(s) "\x1b[42;1m" s AEND +#define _BACK_BRIGHT_YELLOW_(s) "\x1b[43;1m" s AEND +#define _BACK_BRIGHT_BLUE_(s) "\x1b[44;1m" s AEND +#define _BACK_BRIGHT_MAGENTA_(s) "\x1b[45;1m" s AEND +#define _BACK_BRIGHT_CYAN_(s) "\x1b[46;1m" s AEND +#define _BACK_BRIGHT_WHITE_(s) "\x1b[47;1m" s AEND #define _CLEAR_ "\x1b[2J" #define _TOP_ "\x1b[1;1f" - #if defined(HAVE_READLINE) // https://wiki.hackzine.org/development/misc/readline-color-prompt.html // Applications may indicate that the prompt contains From 37d059d56fb0415a8a6daecddea69eb40857306f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 27 Jan 2023 03:00:26 +0100 Subject: [PATCH 557/759] style --- armsrc/Standalone/lf_prox2brute.c | 14 ++--- client/src/cmdhf15.c | 95 +++++++++++++++---------------- client/src/cmdhflist.c | 2 +- client/src/cmdhftesla.c | 12 ++-- client/src/cmdscript.c | 2 +- client/src/pm3line_vocabulory.h | 9 ++- doc/commands.json | 55 ++++++++++++++++-- doc/commands.md | 33 +++++++---- 8 files changed, 137 insertions(+), 85 deletions(-) diff --git a/armsrc/Standalone/lf_prox2brute.c b/armsrc/Standalone/lf_prox2brute.c index 4f092007f..ecfaac9e3 100644 --- a/armsrc/Standalone/lf_prox2brute.c +++ b/armsrc/Standalone/lf_prox2brute.c @@ -57,19 +57,19 @@ void RunMod(void) { WDT_HIT(); // exit from SamyRun, send a usbcommand. if (data_available()) { // early exit - DbpString("[=] You can take the shell back :) ..."); + DbpString("[=] You can take the shell back :) ..."); LEDsoff(); return; } } - + LED_C_ON(); WAIT_BUTTON_RELEASED(); // We are now ready to start brutforcing card numbers LEDsoff(); Dbprintf("[=] Starting HID ProxII Bruteforce from card %08x to %08x", CARDNUM_START, MIN(CARDNUM_END, 0xFFFF)); - + for (cardnum = CARDNUM_START ; cardnum <= MIN(CARDNUM_END, 0xFFFF) ; cardnum++) { WDT_HIT(); @@ -92,14 +92,14 @@ void RunMod(void) { // switch leds to be able to know (aproximatly) which card number worked (64 tries loop) LED_A_INV(); // switch led A every try - if ((cardnum-CARDNUM_START) % 8 == 7) // switch led B every 8 tries + if ((cardnum - CARDNUM_START) % 8 == 7) // switch led B every 8 tries LED_B_INV(); - if ((cardnum-CARDNUM_START) % 16 == 15) // switch led C every 16 tries + if ((cardnum - CARDNUM_START) % 16 == 15) // switch led C every 16 tries LED_C_INV(); - if ((cardnum-CARDNUM_START) % 32 == 31) // switch led D every 32 tries + if ((cardnum - CARDNUM_START) % 32 == 31) // switch led D every 32 tries LED_D_INV(); } - + SpinErr((LED_A | LED_B | LED_C | LED_D), 250, 5); // Xmax tree Dbprintf("[=] Ending HID ProxII Bruteforce from card %08x to %08x", CARDNUM_START, cardnum - 1); diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 76fc4869a..035a2218e 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -652,14 +652,13 @@ static int CmdHF15Samples(const char *Cmd) { return PM3_SUCCESS; } -static int NxpTestEAS(uint8_t *uid) -{ - uint8_t fast = 1; +static int NxpTestEAS(uint8_t *uid) { + uint8_t fast = 1; uint8_t reply = 1; PacketResponseNG resp; uint16_t reqlen = 0; uint8_t req[PM3_CMD_DATA_SIZE] = {0}; - + req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; req[reqlen++] = ISO15693_EAS_ALARM; req[reqlen++] = 0x04; // IC manufacturer code @@ -681,7 +680,7 @@ static int NxpTestEAS(uint8_t *uid) if (resp.length < 2) { PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is not active"); } else { - uint8_t * recv = resp.data.asBytes; + uint8_t *recv = resp.data.asBytes; if (!(recv[0] & ISO15_RES_ERROR)) { PrintAndLogEx(INFO, " EAS (Electronic Article Surveillance) is active."); @@ -689,56 +688,56 @@ static int NxpTestEAS(uint8_t *uid) } } } - + return PM3_SUCCESS; -} +} static int NxpCheckSig(uint8_t *uid) { - uint8_t fast = 1; + uint8_t fast = 1; uint8_t reply = 1; PacketResponseNG resp; uint16_t reqlen = 0; uint8_t req[PM3_CMD_DATA_SIZE] = {0}; - - // Check if we can also read the signature - req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; - req[reqlen++] = ISO15693_READ_SIGNATURE; - req[reqlen++] = 0x04; // IC manufacturer code - memcpy(req + 3, uid, 8); // add UID - reqlen += 8; - AddCrc15(req, reqlen); - reqlen += 2; + // Check if we can also read the signature + req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; + req[reqlen++] = ISO15693_READ_SIGNATURE; + req[reqlen++] = 0x04; // IC manufacturer code + memcpy(req + 3, uid, 8); // add UID + reqlen += 8; - clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen); + AddCrc15(req, reqlen); + reqlen += 2; - if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { - PrintAndLogEx(WARNING, "iso15693 timeout"); - DropField(); - return PM3_ETIMEOUT; - } + clearCommandBuffer(); + SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, reply, req, reqlen); - DropField(); + if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "iso15693 timeout"); + DropField(); + return PM3_ETIMEOUT; + } - if (resp.length < 2) { - PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command"); - return PM3_EWRONGANSWER; - } + DropField(); - uint8_t *recv = resp.data.asBytes; + if (resp.length < 2) { + PrintAndLogEx(WARNING, "iso15693 card doesn't answer to READ SIGNATURE command"); + return PM3_EWRONGANSWER; + } - if ((recv[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) { - PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); - return PM3_EWRONGANSWER; - } + uint8_t *recv = resp.data.asBytes; - uint8_t signature[32] = {0x00}; - memcpy(signature, recv + 1, 32); + if ((recv[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) { + PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", recv[0], TagErrorStr(recv[0])); + return PM3_EWRONGANSWER; + } - nxp_15693_print_signature(uid, signature); - - return PM3_SUCCESS; + uint8_t signature[32] = {0x00}; + memcpy(signature, recv + 1, 32); + + nxp_15693_print_signature(uid, signature); + + return PM3_SUCCESS; } // Get NXP system information from SLIX2 tag/VICC @@ -822,11 +821,11 @@ static int NxpSysInfo(uint8_t *uid) { PrintAndLogEx(INFO, " * Additional 32 bits feature flags are%s transmitted", ((recv[5] & 0x80) ? "" : " not")); if (support_easmode) { - NxpTestEAS(uid); + NxpTestEAS(uid); } if (support_signature) { - NxpCheckSig(uid); + NxpCheckSig(uid); } return PM3_SUCCESS; @@ -968,16 +967,12 @@ static int CmdHF15Info(const char *Cmd) { if (data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x08) { PrintAndLogEx(DEBUG, "SLIX2 Detected, getting NXP System Info"); return NxpSysInfo(uid); - } - else if(data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x18) //If it is an NTAG 5 - { - PrintAndLogEx(DEBUG, "NTAG 5 Detected, getting NXP System Info"); + } else if (data[8] == 0x04 && data[7] == 0x01 && nxp_version == 0x18) { //If it is an NTAG 5 + PrintAndLogEx(DEBUG, "NTAG 5 Detected, getting NXP System Info"); return NxpSysInfo(uid); - } - else if(data[8] == 0x04 && (data[7] == 0x01 || data[7] == 0x02 || data[7] == 0x03)) //If SLI, SLIX, SLIX-l, or SLIX-S check EAS status - { - PrintAndLogEx(DEBUG, "SLI, SLIX, SLIX-L, or SLIX-S Detected checking EAS status"); - return NxpTestEAS(uid); + } else if (data[8] == 0x04 && (data[7] == 0x01 || data[7] == 0x02 || data[7] == 0x03)) { //If SLI, SLIX, SLIX-l, or SLIX-S check EAS status + PrintAndLogEx(DEBUG, "SLI, SLIX, SLIX-L, or SLIX-S Detected checking EAS status"); + return NxpTestEAS(uid); } PrintAndLogEx(NORMAL, ""); diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index a19ecdea9..232d4af19 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -318,7 +318,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i snprintf(exp, size, "AUTH-B(%d)", cmd[1]); break; } - case MIFARE_MAGIC_GDM_AUTH_KEYA:{ + case MIFARE_MAGIC_GDM_AUTH_KEYA: { if (cmdsize > 3) { snprintf(exp, size, "MAGIC AUTH-A(%d)", cmd[1]); MifareAuthState = masNt; diff --git a/client/src/cmdhftesla.c b/client/src/cmdhftesla.c index 2680daa90..58f51f4c5 100644 --- a/client/src/cmdhftesla.c +++ b/client/src/cmdhftesla.c @@ -29,7 +29,7 @@ #include "commonutil.h" // get_sw #include "protocols.h" // ISO7816 APDU return co-des #include "ui.h" -#include "cmdhf14a.h" // apdu chaining +#include "cmdhf14a.h" // apdu chaining #define TIMEOUT 2000 @@ -160,10 +160,10 @@ static int info_hf_tesla(void) { sw = get_sw(response, resplen); if (sw == ISO7816_OK) { - // save CETT for later + // save CETT for later uint8_t cert[515] = {0}; memcpy(cert, response, resplen - 2); - + PrintAndLogEx(INFO, "CERT # %i", i); PrintAndLogEx(INFO, "%s", sprint_hex_inrow(cert, resplen - 2)); } @@ -198,12 +198,12 @@ static int info_hf_tesla(void) { PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "PUBLIC KEY"); - for (int i=0; i < 3; i++) { + for (int i = 0; i < 3; i++) { PrintAndLogEx(INFO, "%d - %s", i, sprint_hex_inrow(pk[i], 65)); } if (form_factor[1] == 1) { PrintAndLogEx(INFO, "Form factor... %s (card)", sprint_hex_inrow(form_factor, sizeof(form_factor))); - } else if (form_factor[1] == 2){ + } else if (form_factor[1] == 2) { PrintAndLogEx(INFO, "Form factor... %s (phone app)", sprint_hex_inrow(form_factor, sizeof(form_factor))); } @@ -217,7 +217,7 @@ static int info_hf_tesla(void) { if ((memcmp(pk[0], pk[1], 65) == 0)) { PrintAndLogEx(INFO, " GaussKey detected"); } - // + // return PM3_SUCCESS; } diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index 57cf54084..114205708 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -433,7 +433,7 @@ static int CmdScriptRun(const char *Cmd) { #else // The following line will implicitly pre-initialize Python PyConfig_SetBytesArgv(&py_conf, argc + 1, argv); - + // We disallowed in py_conf environment variables interfering with python interpreter's behavior. // Let's manually enable the ones we truly need. // This is required by Proxspace to work with an isolated Python configuration diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 5a517c645..4cd9457b5 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -438,6 +438,12 @@ const static vocabulory_t vocabulory[] = { { 0, "hf st25ta protect" }, { 0, "hf st25ta pwd" }, { 0, "hf st25ta sim" }, + { 1, "hf tesla help" }, + { 0, "hf tesla info" }, + { 1, "hf tesla list" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, { 1, "hf thinfilm help" }, { 0, "hf thinfilm info" }, { 1, "hf thinfilm list" }, @@ -453,9 +459,6 @@ const static vocabulory_t vocabulory[] = { { 0, "hf topaz rdbl" }, { 1, "hf topaz view" }, { 0, "hf topaz wrbl" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, { 1, "hf xerox help" }, { 0, "hf xerox info" }, { 0, "hf xerox reader" }, diff --git a/doc/commands.json b/doc/commands.json index 1c21f81ba..bb781adb7 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -1101,14 +1101,16 @@ "command": "hf 14a chaining", "description": "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", "notes": [ - "hf 14a chaining disable -> disable chaining", + "hf 14a chaining --off -> disable chaining", "hf 14a chaining -> show chaining enable/disable state" ], "offline": false, "options": [ - "-h, --help This help" + "-h, --help This help", + "-1, --on enabled chaining", + "-0, --off disable chaining" ], - "usage": "hf 14a chaining [-h] []" + "usage": "hf 14a chaining [-h10]" }, "hf 14a config": { "command": "hf 14a config", @@ -2881,7 +2883,7 @@ }, "hf help": { "command": "hf help", - "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } texkom { Texkom RFIDs... } xerox { Fuji/Xerox cartridge RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags", + "description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } jooki { Jooki RFIDs... } iclass { ICLASS RFIDs... } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } tesla { TESLA Cards... } texkom { Texkom RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } xerox { Fuji/Xerox cartridge RFIDs... } waveshare { Waveshare NFC ePaper... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags", "notes": [], "offline": true, "options": [], @@ -6684,6 +6686,47 @@ ], "usage": "hf st25ta sim [-h] -u " }, + "hf tesla help": { + "command": "hf tesla help", + "description": "help This help list List ISO 14443A/7816 history", + "notes": [], + "offline": true, + "options": [], + "usage": "" + }, + "hf tesla info": { + "command": "hf tesla info", + "description": "Get info about TESLA Key tag", + "notes": [ + "hf tesla info" + ], + "offline": false, + "options": [ + "-h, --help This help" + ], + "usage": "hf telsa info [-h]" + }, + "hf tesla list": { + "command": "hf tesla list", + "description": "Alias of `trace list -t 7816` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol", + "notes": [ + "hf tesla list --frame -> show frame delay times", + "hf tesla list -1 -> use trace buffer" + ], + "offline": true, + "options": [ + "-h, --help This help", + "-1, --buffer use data from trace buffer", + "--frame show frame delay times", + "-c mark CRC bytes", + "-r show relative times (gap and duration)", + "-u display times in microseconds instead of clock cycles", + "-x show hexdump to convert to pcap(ng)", + "or to import into Wireshark using encapsulation type \"ISO 14443\"", + "-f, --file filename of dictionary" + ], + "usage": "hf tesla list [-h1crux] [--frame] [-f ]" + }, "hf texkom help": { "command": "hf texkom help", "description": "help This help", @@ -11760,8 +11803,8 @@ } }, "metadata": { - "commands_extracted": 739, + "commands_extracted": 742, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-01-15T01:24:39" + "extracted_on": "2023-01-27T01:57:37" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 1c6110cea..79499915b 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -651,6 +651,28 @@ Check column "offline" for their availability. |`hf st25ta sim `|N |`Fake ISO 14443A/ST tag` +### hf tesla + + { TESLA Cards... } + +|command |offline |description +|------- |------- |----------- +|`hf tesla help `|Y |`This help` +|`hf tesla info `|N |`Tag information` +|`hf tesla list `|Y |`List ISO 14443A/7816 history` + + +### hf texkom + + { Texkom RFIDs... } + +|command |offline |description +|------- |------- |----------- +|`hf texkom help `|Y |`This help` +|`hf texkom reader `|N |`Act like a Texkom reader` +|`hf texkom sim `|N |`Simulate a Texkom tag` + + ### hf thinfilm { Thinfilm RFIDs... } @@ -682,17 +704,6 @@ Check column "offline" for their availability. |`hf topaz wrbl `|N |`Write block` -### hf texkom - - { Texkom RFIDs... } - -|command |offline |description -|------- |------- |----------- -|`hf texkom help `|Y |`This help` -|`hf texkom reader `|N |`Act like a Texkom reader` -|`hf texkom sim `|N |`Simulate a Texkom tag` - - ### hf xerox { Fuji/Xerox cartridge RFIDs... } From 002823dd9b2009203148cc0b9a826611dceb2242 Mon Sep 17 00:00:00 2001 From: George Talusan Date: Wed, 25 Jan 2023 10:24:38 -0500 Subject: [PATCH 558/759] use Amiibo PACK if simulator PWD matches generated Amiibo PWD --- armsrc/iso14443a.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 23b46cf54..f5960626e 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1229,6 +1229,17 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r AddCrc14A(rPPS, sizeof(rPPS) - 2); + if (tagType == 7) { + uint8_t pwd[4]; + uint8_t gen_pwd[4]; + uint16_t start = (*pages - 1) * 4 + MFU_DUMP_PREFIX_LENGTH; + emlGetMemBt(pwd, start, sizeof(pwd)); + Uint4byteToMemBe(gen_pwd, ul_ev1_pwdgenB(data)); + if (memcmp(pwd, gen_pwd, sizeof(pwd)) == 0) { + rPACK[0] = 0x80; + rPACK[1] = 0x80; + } + } AddCrc14A(rPACK, sizeof(rPACK) - 2); static tag_response_info_t responses_init[] = { From 571b763f5c290892264a8207aef39e6c3b1c2a7d Mon Sep 17 00:00:00 2001 From: Alejandro Date: Fri, 27 Jan 2023 15:04:08 +0100 Subject: [PATCH 559/759] Makefile.platform.sample reverted --- Makefile.platform.sample | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.platform.sample b/Makefile.platform.sample index bfcb5b749..4f8f86cd4 100644 --- a/Makefile.platform.sample +++ b/Makefile.platform.sample @@ -5,7 +5,7 @@ PLATFORM=PM3RDV4 #PLATFORM=PM3GENERIC # If you want more than one PLATFORM_EXTRAS option, separate them by spaces: #PLATFORM_EXTRAS=BTADDON -STANDALONE=HF_BOG +#STANDALONE=LF_SAMYRUN # To accelerate repetitive compilations: # Install package "ccache" -> Debian/Ubuntu: /usr/lib/ccache, Fedora/CentOS/RHEL: /usr/lib64/ccache @@ -13,4 +13,4 @@ STANDALONE=HF_BOG #export PATH := /usr/lib64/ccache:/usr/lib/ccache:${PATH} # To install with sudo: -INSTALLSUDO=sudo +INSTALLSUDO=sudo \ No newline at end of file From db01a3b360ab3eb371a33a5a93e6603b2aef64e4 Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Fri, 27 Jan 2023 11:23:00 -0600 Subject: [PATCH 560/759] Detect 50 pF version of NTAG 210u (micro) --- client/src/cmdhfmfu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index bc8c10859..a59859394 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -1472,6 +1472,7 @@ uint32_t GetHF14AMfU_Type(void) { else if (memcmp(version, "\x00\x34\x21\x01\x01\x00\x0E", 7) == 0) { tagtype = UL_EV1_128; break; } // Mikron JSC Russia EV1 41 pages tag else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0B", 7) == 0) { tagtype = NTAG_210; break; } else if (memcmp(version, "\x00\x04\x04\x01\x02\x00\x0B", 7) == 0) { tagtype = NTAG_210u; break; } + else if (memcmp(version, "\x00\x04\x04\x02\x02\x00\x0B", 7) == 0) { tagtype = NTAG_210u; break; } else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0E", 7) == 0) { tagtype = NTAG_212; break; } else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213; break; } else if (memcmp(version, "\x00\x53\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213; break; } //Shanghai Feiju Microelectronics Co. Ltd. China (Xiaomi Air Purifier filter) From 71389e0b17df92a9afb455e50fd3b630271b4563 Mon Sep 17 00:00:00 2001 From: Adrian Teuscher Date: Fri, 27 Jan 2023 19:37:40 +0100 Subject: [PATCH 561/759] Add function to brute force partial key --- armsrc/appmain.c | 4 ++ armsrc/em4x70.c | 106 +++++++++++++++++++++++++++++++++++++-- armsrc/em4x70.h | 1 + client/src/cmdlfem4x70.c | 101 ++++++++++++++++++++++++++++++++++++- client/src/cmdlfem4x70.h | 1 + include/em4x70.h | 3 ++ include/pm3_cmd.h | 1 + 7 files changed, 211 insertions(+), 6 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 756ca4f4f..e4d3354f8 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1221,6 +1221,10 @@ static void PacketReceived(PacketCommandNG *packet) { em4x70_write_key((em4x70_data_t *)packet->data.asBytes, true); break; } + case CMD_LF_EM4X70_BRUTE: { + em4x70_brute((em4x70_data_t *)packet->data.asBytes, true); + break; + } #endif #ifdef WITH_ZX8211 diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 4dad5f236..545491447 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -21,6 +21,7 @@ #include "dbprint.h" #include "lfadc.h" #include "commonutil.h" +#include "optimized_cipherutils.h" #include "em4x70.h" #include "appmain.h" // tear @@ -85,7 +86,7 @@ static int em4x70_receive(uint8_t *bits, size_t length); static bool find_listen_window(bool command); static void init_tag(void) { - memset(tag.data, 0x00, ARRAYLEN(tag.data)); + memset(tag.data, 0x00, sizeof(tag.data)); } static void em4x70_setup_read(void) { @@ -298,14 +299,14 @@ static bool check_ack(void) { // returns true if signal structue corresponds to ACK, anything else is // counted as NAK (-> false) // ACK 64 + 64 - // NACK 64 + 48 + // NAK 64 + 48 if (check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD) && check_pulse_length(get_pulse_length(FALLING_EDGE), 2 * EM4X70_T_TAG_FULL_PERIOD)) { // ACK return true; } - // Othewise it was a NACK or Listen Window + // Otherwise it was a NAK or Listen Window return false; } @@ -339,7 +340,7 @@ static int authenticate(const uint8_t *rnd, const uint8_t *frnd, uint8_t *respon uint8_t grnd[EM4X70_MAX_RECEIVE_LENGTH] = {0}; int num = em4x70_receive(grnd, 20); if (num < 20) { - Dbprintf("Auth failed"); + if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Auth failed"); return PM3_ESOFT; } bits2bytes(grnd, 24, response); @@ -349,6 +350,80 @@ static int authenticate(const uint8_t *rnd, const uint8_t *frnd, uint8_t *respon return PM3_ESOFT; } +static int set_byte(uint8_t *target, int value) { + int c = value > 0xFF; + *target = reflect8(value); + return c; +} + +static int bruteforce(const uint8_t address, const uint8_t *rnd, const uint8_t *frnd, uint16_t start_key, uint8_t *response) { + + uint8_t auth_resp[3] = {0}; + uint8_t rev_rnd[7]; + uint8_t temp_rnd[7]; + + reverse_arraycopy((uint8_t *)rnd, rev_rnd, sizeof(rnd)); + memcpy(temp_rnd, rnd, sizeof(temp_rnd)); + + for (int k = start_key; k <= 0xFFFF; ++k) { + int c = 0; + + WDT_HIT(); + + uint16_t rev_k = reflect16(k); + switch (address) { + case 9: + c = set_byte(&temp_rnd[0], rev_rnd[0] + (rev_k & 0xFF)); + c = set_byte(&temp_rnd[1], rev_rnd[1] + c + ((rev_k >> 8) & 0xFF)); + c = set_byte(&temp_rnd[2], rev_rnd[2] + c); + c = set_byte(&temp_rnd[3], rev_rnd[3] + c); + c = set_byte(&temp_rnd[4], rev_rnd[4] + c); + c = set_byte(&temp_rnd[5], rev_rnd[5] + c); + set_byte(&temp_rnd[6], rev_rnd[6] + c); + break; + + case 8: + c = set_byte(&temp_rnd[2], rev_rnd[2] + (rev_k & 0xFF)); + c = set_byte(&temp_rnd[3], rev_rnd[3] + c + ((rev_k >> 8) & 0xFF)); + c = set_byte(&temp_rnd[4], rev_rnd[4] + c); + c = set_byte(&temp_rnd[5], rev_rnd[5] + c); + set_byte(&temp_rnd[6], rev_rnd[6] + c); + break; + + case 7: + c = set_byte(&temp_rnd[4], rev_rnd[4] + (rev_k & 0xFF)); + c = set_byte(&temp_rnd[5], rev_rnd[5] + c + ((rev_k >> 8) & 0xFF)); + set_byte(&temp_rnd[6], rev_rnd[6] + c); + break; + + default: + Dbprintf("Bad block number given: %d", address); + return PM3_ESOFT; + } + + // Report progress every 256 attempts + if ((k % 0x100) == 0) { + Dbprintf("Trying: %04X", k); + } + + // Due to performance reason, we only try it once. Therefore you need a very stable RFID communcation. + if (authenticate(temp_rnd, frnd, auth_resp) == PM3_SUCCESS) { + if (g_dbglevel >= DBG_INFO) + Dbprintf("Authentication success with rnd: %02X%02X%02X%02X%02X%02X%02X", temp_rnd[0], temp_rnd[1], temp_rnd[2], temp_rnd[3], temp_rnd[4], temp_rnd[5], temp_rnd[6]); + response[0] = (k >> 8) & 0xFF; + response[1] = k & 0xFF; + return PM3_SUCCESS; + } + + if (BUTTON_PRESS() || data_available()) { + Dbprintf("EM4x70 Bruteforce Interrupted"); + return PM3_EOPABORTED; + } + } + + return PM3_ESOFT; +} + static int send_pin(const uint32_t pin) { // sends pin code for unlocking @@ -576,7 +651,7 @@ static int em4x70_receive(uint8_t *bits, size_t length) { } if (!foundheader) { - Dbprintf("Failed to find read header"); + if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Failed to find read header"); return 0; } @@ -738,6 +813,27 @@ void em4x70_auth(em4x70_data_t *etd, bool ledcontrol) { reply_ng(CMD_LF_EM4X70_AUTH, status, response, sizeof(response)); } +void em4x70_brute(em4x70_data_t *etd, bool ledcontrol) { + uint8_t status = 0; + uint8_t response[2] = {0}; + + command_parity = etd->parity; + + init_tag(); + em4x70_setup_read(); + + // Find the Tag + if (get_signalproperties() && find_em4x70_tag()) { + + // Bruteforce partial key + status = bruteforce(etd->address, etd->rnd, etd->frnd, etd->start_key, response) == PM3_SUCCESS; + } + + StopTicks(); + lf_finalize(ledcontrol); + reply_ng(CMD_LF_EM4X70_BRUTE, status, response, sizeof(response)); +} + void em4x70_write_pin(em4x70_data_t *etd, bool ledcontrol) { uint8_t status = 0; diff --git a/armsrc/em4x70.h b/armsrc/em4x70.h index 363f119e3..0fd640f86 100644 --- a/armsrc/em4x70.h +++ b/armsrc/em4x70.h @@ -32,6 +32,7 @@ typedef enum { void em4x70_info(em4x70_data_t *etd, bool ledcontrol); void em4x70_write(em4x70_data_t *etd, bool ledcontrol); +void em4x70_brute(em4x70_data_t *etd, bool ledcontrol); void em4x70_unlock(em4x70_data_t *etd, bool ledcontrol); void em4x70_auth(em4x70_data_t *etd, bool ledcontrol); void em4x70_write_pin(em4x70_data_t *etd, bool ledcontrol); diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index 7021b2b95..f008d9947 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -200,7 +200,7 @@ int CmdEM4x70Write(const char *Cmd) { } etd.address = (uint8_t) addr; - etd.word = BYTES2UINT16(word);; + etd.word = BYTES2UINT16(word); clearCommandBuffer(); SendCommandNG(CMD_LF_EM4X70_WRITE, (uint8_t *)&etd, sizeof(etd)); @@ -220,6 +220,104 @@ int CmdEM4x70Write(const char *Cmd) { return PM3_ESOFT; } +int CmdEM4x70Brute(const char *Cmd) { + + // From paper "Dismantling Megamos Crypto", Roel Verdult, Flavio D. Garcia and Barıs¸ Ege. + // Partial Key-Update Attack (optimized version) + em4x70_data_t etd = {0}; + + CLIParserContext *ctx; + + CLIParserInit(&ctx, "lf em 4x70 brute", + "Optimized partial key-update attack of 16-bit key block 7, 8 or 9 of an EM4x70\n" + "This attack does NOT write anything to the tag.\n" + "Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'.\n" + "After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'\n", + "lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 --> bruteforcing key bits k95...k80\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0(NULL, "par", "Add parity bit when sending commands"), + arg_int1("b", "block", "", "block/word address, dec"), + arg_str1(NULL, "rnd", "", "Random 56-bit"), + arg_str1(NULL, "frn", "", "F(RN) 28-bit as 4 hex bytes"), + arg_str0("s", "start", "", "Start bruteforce enumeration from this key value"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + etd.parity = arg_get_lit(ctx, 1); + + int addr = arg_get_int_def(ctx, 2, 0); + if (addr < 7 || addr > 9) { + PrintAndLogEx(FAILED, "block has to be within range [7, 9] got: %d", addr); + return PM3_EINVARG; + } + etd.address = (uint8_t) addr; + + int rnd_len = 7; + CLIGetHexWithReturn(ctx, 3, etd.rnd, &rnd_len); + + int frnd_len = 4; + CLIGetHexWithReturn(ctx, 4, etd.frnd, &frnd_len); + + uint32_t start_key = 0; + int res = arg_get_u32_hexstr_def_nlen(ctx, 5, 0, &start_key, 2, true); + if (res == 2) { + CLIParserFree(ctx); + PrintAndLogEx(WARNING, "start key parameter must be in range [0, FFFF]"); + return PM3_EINVARG; + } + etd.start_key = start_key; + + CLIParserFree(ctx); + + if (rnd_len != 7) { + PrintAndLogEx(FAILED, "Random number length must be 7 bytes instead of %d", rnd_len); + return PM3_EINVARG; + } + + if (frnd_len != 4) { + PrintAndLogEx(FAILED, "F(RN) length must be 4 bytes instead of %d", frnd_len); + return PM3_EINVARG; + } + + PrintAndLogEx(INFO, "click " _GREEN_("pm3 button") " or press " _GREEN_("Enter") " to exit"); + clearCommandBuffer(); + PacketResponseNG resp; + SendCommandNG(CMD_LF_EM4X70_BRUTE, (uint8_t *)&etd, sizeof(etd)); + + uint32_t timeout = 0; + for (;;) { + + if (kbd_enter_pressed()) { + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + PrintAndLogEx(DEBUG, "User aborted"); + break; + } + + if (WaitForResponseTimeout(CMD_LF_EM4X70_BRUTE, &resp, TIMEOUT)) { + if (resp.status) { + // Response is 16-bit partial key + PrintAndLogEx(INFO, "Partial Key Response: %02X %02X", resp.data.asBytes[0], resp.data.asBytes[1]); + return PM3_SUCCESS; + } + break; + } + + // should be done in about 30 minutes + if (timeout > ((30 * 60000) / TIMEOUT)) { + PrintAndLogEx(WARNING, "\nNo response from Proxmark3. Aborting..."); + break; + } + timeout++; + } + + PrintAndLogEx(FAILED, "Bruteforce of partial key " _RED_("failed")); + return PM3_ESOFT; +} + int CmdEM4x70Unlock(const char *Cmd) { // send pin code to device, unlocking it for writing @@ -452,6 +550,7 @@ int CmdEM4x70WriteKey(const char *Cmd) { static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"brute", CmdEM4x70Brute, IfPm3EM4x70, "Bruteforce EM4X70 to find partial Crypt Key"}, {"info", CmdEM4x70Info, IfPm3EM4x70, "Tag information EM4x70"}, {"write", CmdEM4x70Write, IfPm3EM4x70, "Write EM4x70"}, {"unlock", CmdEM4x70Unlock, IfPm3EM4x70, "Unlock EM4x70 for writing"}, diff --git a/client/src/cmdlfem4x70.h b/client/src/cmdlfem4x70.h index 5d46af3ca..12599713b 100644 --- a/client/src/cmdlfem4x70.h +++ b/client/src/cmdlfem4x70.h @@ -26,6 +26,7 @@ int CmdLFEM4X70(const char *Cmd); int CmdEM4x70Info(const char *Cmd); int CmdEM4x70Write(const char *Cmd); +int CmdEM4x70Brute(const char *Cmd); int CmdEM4x70Unlock(const char *Cmd); int CmdEM4x70Auth(const char *Cmd); int CmdEM4x70WritePIN(const char *Cmd); diff --git a/include/em4x70.h b/include/em4x70.h index bce860bb1..734e83f48 100644 --- a/include/em4x70.h +++ b/include/em4x70.h @@ -42,6 +42,9 @@ typedef struct { // Used to write new key uint8_t crypt_key[12]; + // used for bruteforce the partial key + uint16_t start_key; + } em4x70_data_t; #endif /* EM4X70_H__ */ diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 95750b9b7..4f9917cfd 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -484,6 +484,7 @@ typedef struct { #define CMD_LF_EM4X70_AUTH 0x0263 #define CMD_LF_EM4X70_WRITEPIN 0x0264 #define CMD_LF_EM4X70_WRITEKEY 0x0265 +#define CMD_LF_EM4X70_BRUTE 0x0266 // Sampling configuration for LF reader/sniffer #define CMD_LF_SAMPLING_SET_CONFIG 0x021D #define CMD_LF_FSK_SIMULATE 0x021E From 3c655aeb19df1bd7e904c47dd97f16c0873abe91 Mon Sep 17 00:00:00 2001 From: Adrian Teuscher Date: Fri, 27 Jan 2023 20:24:53 +0100 Subject: [PATCH 562/759] Add entry to CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 942100d85..66ea8299e 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] + - Added `lf em 4x70 brute` command (@adite) - Added new magic gen4 cards command in docs (@McEloff) - Added `hf tesla info` - intital information command to read TESLA cards (@iceman1001) - Changed `hf emrtd info` - looking for lower case .bin extensions (@iceman1001) From 5a49beb83a6fdaf294630170c5de10f15e106580 Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Fri, 27 Jan 2023 19:22:48 -0600 Subject: [PATCH 563/759] added CHANGELOG.md entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 942100d85..f31361d9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - Fixed `make accessrights` on Fedora (@mooey5775) + - Fixed `hf mfu info` - can now identify the 50 pF version of NTAG 210u(micro) (@mjacksn) ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) From 9041627ae55676003e5023507a2da3122d816012 Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Fri, 27 Jan 2023 22:46:40 -0600 Subject: [PATCH 564/759] Add `hf 15` sub-commands for EAS, AFI, privacy mode, and passwords on SLIX tags --- CHANGELOG.md | 2 + armsrc/appmain.c | 68 +++- armsrc/iso15693.c | 391 +++++++++++++++++-- armsrc/iso15693.h | 10 +- client/src/cmdhf15.c | 639 +++++++++++++++++++++++++++----- client/src/pm3line_vocabulory.h | 8 +- include/pm3_cmd.h | 10 +- 7 files changed, 993 insertions(+), 135 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f31361d9d..3a6e2f72c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - Fixed `make accessrights` on Fedora (@mooey5775) - Fixed `hf mfu info` - can now identify the 50 pF version of NTAG 210u(micro) (@mjacksn) + - Added `hf 15` sub-commands for controlling EAS, AFI, privacy mode, and the setting of passwords on SLIX tags (@mjacksn) + ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 76d9ac3c0..b26225ccf 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1287,23 +1287,79 @@ static void PacketReceived(PacketCommandNG *packet) { SetTag15693Uid(payload->uid); break; } - case CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY: { + case CMD_HF_ISO15693_SLIX_DISABLE_EAS: { + struct p { + uint8_t pwd[4]; + bool usepwd; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + DisableEAS_AFISlixIso15693(payload->pwd, payload->usepwd); + break; + } + case CMD_HF_ISO15693_SLIX_ENABLE_EAS: { + struct p { + uint8_t pwd[4]; + bool usepwd; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + EnableEAS_AFISlixIso15693(payload->pwd, payload->usepwd); + break; + } + case CMD_HF_ISO15693_SLIX_WRITE_PWD: { + struct p { + uint8_t old_pwd[4]; + uint8_t new_pwd[4]; + uint8_t pwd_id; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + WritePasswordSlixIso15693(payload->old_pwd, payload->new_pwd, payload->pwd_id); + break; + } + case CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY: { struct p { uint8_t pwd[4]; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - DisablePrivacySlixLIso15693(payload->pwd); + DisablePrivacySlixIso15693(payload->pwd); break; } - case CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI: { + case CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY: { struct p { uint8_t pwd[4]; } PACKED; - struct p *payload = (struct p *) packet->data.asBytes; - DisableEAS_AFISlixLIso15693(payload->pwd); + struct p* payload = (struct p*)packet->data.asBytes; + EnablePrivacySlixIso15693(payload->pwd); break; } - + case CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI: { + struct p { + uint8_t pwd[4]; + } PACKED; + struct p* payload = (struct p*)packet->data.asBytes; + PassProtectAFISlixIso15693(payload->pwd); + break; + } + case CMD_HF_ISO15693_WRITE_AFI: { + struct p { + uint8_t pwd[4]; + bool use_pwd; + uint8_t uid[8]; + bool use_uid; + uint8_t afi; + } PACKED; + struct p* payload = (struct p*)packet->data.asBytes; + WriteAFIIso15693(payload->pwd, payload->use_pwd, payload->uid, payload->use_uid, payload->afi); + break; + } + case CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS: { + struct p { + uint8_t pwd[4]; + } PACKED; + struct p* payload = (struct p*)packet->data.asBytes; + PassProtextEASSlixIso15693(payload->pwd); + break; + } + #endif #ifdef WITH_LEGICRF diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index ab650da8f..3ca186305 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -177,6 +177,37 @@ static void CodeIso15693AsReaderEOF(void) { } +static int get_uid_slix(uint32_t start_time, uint32_t* eof_time, uint8_t* uid) { + + uint8_t *answer = BigBuf_malloc(ISO15693_MAX_RESPONSE_LENGTH); + memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + + uint8_t cmd[5] = {0}; + BuildIdentifyRequest(cmd); + uint16_t recvlen = 0; + SendDataTag(cmd, sizeof(cmd), false, true, answer, ISO15693_MAX_RESPONSE_LENGTH, start_time, ISO15693_READER_TIMEOUT, eof_time, &recvlen); + + if(recvlen != 12) + { + return PM3_ETIMEOUT; + } + + uid[0] = answer[2]; + uid[1] = answer[3]; + uid[2] = answer[4]; + uid[3] = answer[5]; + uid[4] = answer[6]; + uid[5] = answer[7]; + uid[6] = answer[8]; + uid[7] = answer[9]; + + BigBuf_free(); + return PM3_SUCCESS; +} + + // encode data using "1 out of 256" scheme // data rate is 1,66 kbit/s (fc/8192) // is designed for more robust communication over longer distances @@ -2431,6 +2462,8 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint case ISO15693_WRITE_AFI: case ISO15693_LOCK_AFI: case ISO15693_WRITE_DSFID: + case ISO15693_WRITE_PASSWORD: + case ISO15693_PASSWORD_PROTECT_EAS: case ISO15693_LOCK_DSFID: timeout = ISO15693_READER_TIMEOUT_WRITE; request_answer = data[0] & ISO15_REQ_OPTION; @@ -2640,7 +2673,7 @@ void SetTag15693Uid(const uint8_t *uid) { switch_off(); } -static void init_password_15693_slixl(uint8_t *buffer, uint8_t *pwd, const uint8_t *rnd) { +static void init_password_15693_Slix(uint8_t *buffer, uint8_t *pwd, const uint8_t *rnd) { memcpy(buffer, pwd, 4); if (rnd) { buffer[0] ^= rnd[0]; @@ -2650,14 +2683,14 @@ static void init_password_15693_slixl(uint8_t *buffer, uint8_t *pwd, const uint8 } } -static bool get_rnd_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *rnd) { +static bool get_rnd_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *rnd) { // 0x04, == NXP from manufacture id list. uint8_t c[] = {ISO15_REQ_DATARATE_HIGH, ISO15693_GET_RANDOM_NUMBER, 0x04, 0x00, 0x00 }; AddCrc15(c, 3); uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; uint16_t recvlen = 0; - int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + int res = SendDataTag(c, sizeof(c), true, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); if (res != PM3_SUCCESS && recvlen != 5) { return false; } @@ -2668,15 +2701,16 @@ static bool get_rnd_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t return true; } -static uint32_t set_pass_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, uint8_t *password) { +static uint32_t disable_privacy_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t pass_id, uint8_t* password) { + uint8_t rnd[2]; - if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) { + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; } // 0x04, == NXP from manufacture id list. - uint8_t c[] = {ISO15_REQ_DATARATE_HIGH, ISO15693_SET_PASSWORD, 0x04, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - init_password_15693_slixl(&c[4], password, rnd); + uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, ISO15693_SET_PASSWORD, 0x04, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + init_password_15693_Slix(&c[4], password, rnd); AddCrc15(c, 8); start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; @@ -2689,16 +2723,236 @@ static uint32_t set_pass_15693_slixl(uint32_t start_time, uint32_t *eof_time, ui return PM3_SUCCESS; } -/* -static uint32_t enable_privacy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) { +static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t pass_id, uint8_t* password, uint8_t* uid) { + + uint8_t rnd[2]; - if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) { + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { + return PM3_ETIMEOUT; + } + + // 0x04, == NXP from manufacture id list. + uint8_t c[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_SET_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + init_password_15693_Slix(&c[12], password, rnd); + + memcpy(&c[3], uid, 8); + AddCrc15(c, 16); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + + int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + return PM3_SUCCESS; +} + +static uint32_t set_privacy_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t* password) { + uint8_t rnd[2]; + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { + return PM3_ETIMEOUT; + } + + // 0x04, == NXP from manufacture id list. + uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xBA, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + init_password_15693_Slix(&c[3], password, rnd); + AddCrc15(c, 7); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + return PM3_SUCCESS; +} + +static uint32_t disable_eas_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t* password, bool usepwd) { + + uint8_t uid[8]; + get_uid_slix(start_time, eof_time, uid); + + uint8_t rnd[2]; + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { + return PM3_ETIMEOUT; + } + + if(usepwd) + { + + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if(res_setpass != PM3_SUCCESS) + { + return PM3_EWRONGANSWER; + } + } + + // 0x04, == NXP from manufacture id list. + uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA3, 0x04, 0x00, 0x00}; + AddCrc15(c, 3); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + return PM3_SUCCESS; +} + + +static uint32_t enable_eas_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t* password, bool usepwd) { + + uint8_t uid[8]; + get_uid_slix(start_time, eof_time, uid); + + uint8_t rnd[2]; + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { + return PM3_ETIMEOUT; + } + + if(usepwd) + { + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if(res_setpass != PM3_SUCCESS) + { + return PM3_EWRONGANSWER; + } + } + // 0x04, == NXP from manufacture id list. + uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA2, 0x04, 0x00, 0x00}; + //init_password_15693_Slix(&c[3], password, rnd); + AddCrc15(c, 3); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + return PM3_SUCCESS; +} + +static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pwd_id, uint8_t *password, uint8_t* uid) { + + uint8_t new_pwd_cmd[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pwd_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + memcpy(&new_pwd_cmd[3], uid, 8); + memcpy(&new_pwd_cmd[12], password, 4); + + AddCrc15(new_pwd_cmd, 16); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + + int res_wrp = SendDataTag(new_pwd_cmd, sizeof(new_pwd_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res_wrp != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + + return PM3_SUCCESS; +} + +static uint32_t pass_protect_EASAFI_15693_Slix(uint32_t start_time, uint32_t *eof_time, bool set_option_flag, uint8_t* password) { + + uint8_t flags; + + if(set_option_flag) + flags = ISO15_REQ_DATARATE_HIGH | ISO15_REQ_OPTION; + else + flags = ISO15_REQ_DATARATE_HIGH; + + + uint8_t uid[8]; + get_uid_slix(start_time, eof_time, uid); + + uint8_t rnd[2]; + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { + return PM3_ETIMEOUT; + } + + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if(res_setpass != PM3_SUCCESS) + { + return PM3_EWRONGANSWER; + } + + uint8_t new_pass_protect_cmd[] = { flags, ISO15693_PASSWORD_PROTECT_EAS, 0x04, 0x00, 0x00}; + AddCrc15(new_pass_protect_cmd, 3); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + + int res = SendDataTag(new_pass_protect_cmd, sizeof(new_pass_protect_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + + return PM3_SUCCESS; +} + +static uint32_t write_afi_15693(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi) +{ + + if(!use_uid) + { + int res_getuid = get_uid_slix(start_time, eof_time, uid); + + if(res_getuid != PM3_SUCCESS) + { + return res_getuid; + } + } + + if(usepwd) + { + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if(res_setpass != PM3_SUCCESS) + { + return PM3_EWRONGANSWER; + } + } + + uint8_t cmd[] = { ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_AFI, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + memcpy(&cmd[2], uid, 8); + cmd[10] = afi; + AddCrc15(cmd, 11); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + + int res = SendDataTag(cmd, sizeof(cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS || recvlen != 3) { + return PM3_EWRONGANSWER; + } + + return PM3_SUCCESS; +} + +/* +static uint32_t enable_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) { + uint8_t rnd[2]; + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; } uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_ENABLE_PRIVACY, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(&c[3], uid, 8); - init_password_15693_slixl(&c[11], password, rnd); + init_password_15693_Slix(&c[11], password, rnd); AddCrc15(c, 15); start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; @@ -2711,16 +2965,16 @@ static uint32_t enable_privacy_15693_slixl(uint32_t start_time, uint32_t *eof_ti return PM3_SUCCESS; } -static uint32_t write_password_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) { +static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t pass_id, uint8_t *password) { uint8_t rnd[2]; - if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) { + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; } uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(&c[3], uid, 8); c[11] = pass_id; - init_password_15693_slixl(&c[12], password, NULL); + init_password_15693_Slix(&c[12], password, NULL); AddCrc15(c, 16); start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; @@ -2734,16 +2988,16 @@ static uint32_t write_password_15693_slixl(uint32_t start_time, uint32_t *eof_ti return PM3_SUCCESS; } -static uint32_t destroy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t *password) { +static uint32_t destroy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid, uint8_t *password) { uint8_t rnd[2]; - if (get_rnd_15693_slixl(start_time, eof_time, rnd) == false) { + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; } uint8_t c[] = {ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_DESTROY, ISO15693_ENABLE_PRIVACY, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(&c[3], uid, 8); - init_password_15693_slixl(&c[11], password, rnd); + init_password_15693_Slix(&c[11], password, rnd); AddCrc15(c, 15); start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; @@ -2758,8 +3012,33 @@ static uint32_t destroy_15693_slixl(uint32_t start_time, uint32_t *eof_time, uin */ -// Sets a PRIVACY password to all ZEROS -void DisablePrivacySlixLIso15693(uint8_t *password) { +void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + int res = PM3_EFAILED; + + uint8_t uid[8]; + get_uid_slix(start_time, &eof_time, uid); + + res = set_pass_15693_Slix(start_time, &eof_time, pwd_id, old_password, uid); + if(res != PM3_SUCCESS) + { + reply_ng(CMD_HF_ISO15693_SLIX_WRITE_PWD, res, NULL, 0); + switch_off(); + return; + } + + res = write_password_15693_Slix(start_time, &eof_time, pwd_id, new_password, uid); + + reply_ng(CMD_HF_ISO15693_SLIX_WRITE_PWD, res, NULL, 0); + + switch_off(); + +} + +void DisablePrivacySlixIso15693(uint8_t *password) { LED_D_ON(); Iso15693InitReader(); StartCountSspClk(); @@ -2769,13 +3048,12 @@ void DisablePrivacySlixLIso15693(uint8_t *password) { // 0x04 Privacy // 0x08 Destroy SLIX-L // 0x10 EAS/AFI - int res = set_pass_15693_slixl(start_time, &eof_time, 0x04, password); - reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, res, NULL, 0); + int res = disable_privacy_15693_Slix(start_time, &eof_time, 0x04, password); + reply_ng(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, res, NULL, 0); switch_off(); } -// Sets a EAS/AFI password to all ZEROS -void DisableEAS_AFISlixLIso15693(uint8_t *password) { +void EnablePrivacySlixIso15693(uint8_t* password) { LED_D_ON(); Iso15693InitReader(); StartCountSspClk(); @@ -2785,8 +3063,71 @@ void DisableEAS_AFISlixLIso15693(uint8_t *password) { // 0x04 Privacy // 0x08 Destroy SLIX-L // 0x10 EAS/AFI - int res = set_pass_15693_slixl(start_time, &eof_time, 0x10, password); - reply_ng(CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI, res, NULL, 0); + int res = set_privacy_15693_Slix(start_time, &eof_time, password); + reply_ng(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, res, NULL, 0); switch_off(); } + +void DisableEAS_AFISlixIso15693(uint8_t *password, bool usepwd) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + + // Password identifier Password byte + // 0x04 Privacy + // 0x08 Destroy SLIX-L + // 0x10 EAS/AFI + int res = disable_eas_15693_Slix(start_time, &eof_time, password, usepwd); + + + + reply_ng(CMD_HF_ISO15693_SLIX_DISABLE_EAS, res, NULL, 0); + switch_off(); +} + +void EnableEAS_AFISlixIso15693(uint8_t *password, bool usepwd) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + + // Password identifier Password byte + // 0x04 Privacy + // 0x08 Destroy SLIX-L + // 0x10 EAS/AFI + int res = enable_eas_15693_Slix(start_time, &eof_time, password, usepwd); + reply_ng(CMD_HF_ISO15693_SLIX_ENABLE_EAS, res, NULL, 0); + switch_off(); +} + +void PassProtextEASSlixIso15693(uint8_t *password) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + int res = pass_protect_EASAFI_15693_Slix(start_time, &eof_time, false, password); + reply_ng(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, res, NULL, 0); + switch_off(); +} +void PassProtectAFISlixIso15693(uint8_t *password) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + int res = pass_protect_EASAFI_15693_Slix(start_time, &eof_time, true, password); + reply_ng(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, res, NULL, 0); + switch_off(); +} + +void WriteAFIIso15693(uint8_t *password, bool use_pwd, uint8_t *uid, bool use_uid, uint8_t afi) { + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + int res = write_afi_15693(start_time, &eof_time, password, use_pwd, uid, use_uid, afi); + //int res = PM3_SUCCESS; + reply_ng(CMD_HF_ISO15693_WRITE_AFI, res, NULL, 0); + switch_off(); +} \ No newline at end of file diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index 2097b3769..c0ff44929 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -62,6 +62,12 @@ int SendDataTagEOF(uint8_t *recv, uint16_t max_recv_len, uint32_t start_time, ui void SetTag15693Uid(const uint8_t *uid); -void DisablePrivacySlixLIso15693(uint8_t *password); -void DisableEAS_AFISlixLIso15693(uint8_t *password); +void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id); +void DisablePrivacySlixIso15693(uint8_t *password); +void EnablePrivacySlixIso15693(uint8_t* password); +void DisableEAS_AFISlixIso15693(uint8_t *password, bool usepwd); +void EnableEAS_AFISlixIso15693(uint8_t *password, bool usepwd); +void PassProtextEASSlixIso15693(uint8_t *password); +void PassProtectAFISlixIso15693(uint8_t *password); +void WriteAFIIso15693(uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi); #endif diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 035a2218e..46a89a0c9 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -698,7 +698,7 @@ static int NxpCheckSig(uint8_t *uid) { PacketResponseNG resp; uint16_t reqlen = 0; uint8_t req[PM3_CMD_DATA_SIZE] = {0}; - + // Check if we can also read the signature req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; req[reqlen++] = ISO15693_READ_SIGNATURE; @@ -736,7 +736,7 @@ static int NxpCheckSig(uint8_t *uid) { memcpy(signature, recv + 1, 32); nxp_15693_print_signature(uid, signature); - + return PM3_SUCCESS; } @@ -1352,94 +1352,83 @@ static int CmdHF15WriteAfi(const char *Cmd) { CLIParserInit(&ctx, "hf 15 writeafi", "Write AFI on card", "hf 15 writeafi -* --afi 12\n" - "hf 15 writeafi -u E011223344556677 --afi 12" + "hf 15 writeafi -u E011223344556677 --afi 12 -p 0F0F0F0F" ); - void *argtable[6 + 2] = {}; - uint8_t arglen = arg_add_default(argtable); - argtable[arglen++] = arg_int1(NULL, "afi", "", "AFI number (0-255)"); - argtable[arglen++] = arg_param_end; + void *argtable[5] = {}; + argtable[0] = arg_param_begin; + argtable[1] = arg_str0("u", "uid", "", "full UID, 8 bytes"); + argtable[2] = arg_int1(NULL, "afi", "", "AFI number (0-255)"); + argtable[3] = arg_str0("p", "pwd", "", "optional AFI/EAS password"); + argtable[4] = arg_param_end; - CLIExecWithReturn(ctx, Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, true); + + struct { + uint8_t pwd[4]; + bool use_pwd; + uint8_t uid[8]; + bool use_uid; + uint8_t afi; + } PACKED payload; - uint8_t uid[8]; int uidlen = 0; - CLIGetHexWithReturn(ctx, 1, uid, &uidlen); - bool unaddressed = arg_get_lit(ctx, 2); - bool scan = arg_get_lit(ctx, 3); - int fast = (arg_get_lit(ctx, 4) == false); - bool add_option = arg_get_lit(ctx, 5); + CLIGetHexWithReturn(ctx, 1, payload.uid, &uidlen); - int afi = arg_get_int_def(ctx, 6, 0); + payload.afi = arg_get_int_def(ctx, 2, 0); + + int pwdlen; + + CLIGetHexWithReturn(ctx, 3, payload.pwd, &pwdlen); + CLIParserFree(ctx); + + if(pwdlen == 4) + { + payload.use_pwd = true; + } + + if(uidlen == 8) + { + payload.use_uid = true; + } // sanity checks - if ((scan + unaddressed + uidlen) > 1) { - PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid"); + if (uidlen != 0 && uidlen != 8) { + PrintAndLogEx(WARNING, "uid must be 8 hex bytes if provided"); return PM3_EINVARG; } - - // request to be sent to device/card - uint16_t flags = arg_get_raw_flag(uidlen, unaddressed, scan, add_option); - uint8_t req[16] = {flags, ISO15693_WRITE_AFI}; - uint16_t reqlen = 2; - - if (unaddressed == false) { - if (scan) { - if (getUID(false, uid) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "no tag found"); - return PM3_EINVARG; - } - uidlen = 8; - } - - if (uidlen == 8) { - // add UID (scan, uid) - memcpy(req + reqlen, uid, sizeof(uid)); - reqlen += sizeof(uid); - } - PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid)); + + if(pwdlen > 0 && pwdlen != 4) + { + PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); + return PM3_ESOFT; } - // enforce, since we are writing - req[0] |= ISO15_REQ_OPTION; - - req[reqlen++] = (uint8_t)afi; - - AddCrc15(req, reqlen); - reqlen += 2; - - // arg: len, speed, recv? - // arg0 (datalen, cmd len? .arg0 == crc?) - // arg1 (speed == 0 == 1 of 256, == 1 == 1 of 4 ) - // arg2 (recv == 1 == expect a response) - uint8_t read_response = 1; - PacketResponseNG resp; clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO15693_COMMAND, reqlen, fast, read_response, req, reqlen); - - if (WaitForResponseTimeout(CMD_HF_ISO15693_COMMAND, &resp, 2000) == false) { - PrintAndLogEx(ERR, "iso15693 timeout"); + SendCommandNG(CMD_HF_ISO15693_WRITE_AFI, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_WRITE_AFI, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); DropField(); - return PM3_ETIMEOUT; - } - DropField(); - - if (resp.status == PM3_ETEAROFF) { - return resp.status; + return PM3_ESOFT; } - uint8_t *data = resp.data.asBytes; - - if ((data[0] & ISO15_RES_ERROR) == ISO15_RES_ERROR) { - PrintAndLogEx(ERR, "iso15693 card returned error %i: %s", data[0], TagErrorStr(data[0])); - return PM3_EWRONGANSWER; + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "error writing AFI"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", payload.afi); + break; + } } - - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", afi); - return PM3_SUCCESS; + return resp.status; } // Writes the DSFID (Data Storage Format Identifier) of a card @@ -2378,10 +2367,164 @@ static int CmdHF15CSetUID(const char *Cmd) { } } +static int CmdHF15SlixEASEnable(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 slixeasenable", + "Enable EAS mode on SLIX ISO-15693 tag", + "hf 15 slixeasenable -p 0F0F0F0F"); + + void *argtable[] = { + arg_param_begin, + arg_str0("p", "pwd", "", "optional password, 8 hex bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + struct { + uint8_t pwd[4]; + bool usepwd; + } PACKED payload; + int pwdlen = 0; + + int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen); + if((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) + { + PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); + return PM3_ESOFT; + } + + //CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); + CLIParserFree(ctx); + + + if(pwdlen > 0 ) + { + PrintAndLogEx(INFO, "Trying to enable EAS mode using password " _GREEN_("%s") + , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) + ); + payload.usepwd = true; + } + else + { + PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password"); + payload.usepwd = false; + } + + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_ENABLE_EAS, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_ENABLE_EAS, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + if(pwdlen > 0 ) + { + PrintAndLogEx(WARNING, "the password provided was not accepted"); + } + else + { + PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked"); + } + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "EAS mode is now enabled ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; +} + +static int CmdHF15SlixEASDisable(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 slixeasdisable", + "Disable EAS mode on SLIX ISO-15693 tag", + "hf 15 slixeasdisable -p 0F0F0F0F"); + + void *argtable[] = { + arg_param_begin, + arg_str0("p", "pwd", "", "optional password, 8 hex bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + struct { + uint8_t pwd[4]; + bool usepwd; + + } PACKED payload; + int pwdlen = 0; + + int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen); + if((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) + { + PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); + return PM3_ESOFT; + } + + //CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); + CLIParserFree(ctx); + + + if(pwdlen > 0 ) + { + PrintAndLogEx(INFO, "Trying to disable EAS mode using password " _GREEN_("%s") + , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) + ); + payload.usepwd = true; + } + else + { + PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password"); + payload.usepwd = false; + } + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_DISABLE_EAS, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_DISABLE_EAS, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + if(pwdlen > 0 ) + { + PrintAndLogEx(WARNING, "the password provided was not accepted"); + } + else + { + PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked"); + } + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "EAS mode is now disabled ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; +} + static int CmdHF15SlixDisable(const char *Cmd) { CLIParserContext *ctx; - CLIParserInit(&ctx, "hf 15 slixdisable", + CLIParserInit(&ctx, "hf 15 slixprivacydisable", "Disable privacy mode on SLIX ISO-15693 tag", "hf 15 slixdisable -p 0F0F0F0F"); @@ -2404,8 +2547,8 @@ static int CmdHF15SlixDisable(const char *Cmd) { PacketResponseNG resp; clearCommandBuffer(); - SendCommandNG(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload)); - if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY, &resp, 2000) == false) { + SendCommandNG(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY, &resp, 2000) == false) { PrintAndLogEx(WARNING, "timeout while waiting for reply"); DropField(); return PM3_ESOFT; @@ -2428,32 +2571,330 @@ static int CmdHF15SlixDisable(const char *Cmd) { return resp.status; } +static int CmdHF15SlixEnable(const char* Cmd) { + + CLIParserContext* ctx; + CLIParserInit(&ctx, "hf 15 slixprivacyenable", + "Enable privacy mode on SLIX ISO-15693 tag", + "hf 15 slixenable -p 0F0F0F0F"); + + void* argtable[] = { + arg_param_begin, + arg_str1("p", "pwd", "", "password, 8 hex bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + struct { + uint8_t pwd[4]; + } PACKED payload; + int pwdlen = 0; + CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); + CLIParserFree(ctx); + + PrintAndLogEx(INFO, "Trying to enable privacy mode using password " _GREEN_("%s") + , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) + ); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, (uint8_t*)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "password was not accepted"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "privacy mode is now enabled ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; +} + +static int CmdHF15SlixWritePassword(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 slixwritepwd", + "Write a password on a SLIX family ISO-15693 tag", + "hf 15 slixwritepwd -t READ -o 00000000 -n 12131415"); + + void *argtable[] = { + arg_param_begin, + arg_str1("t", "type", "", "which password field to write to (some tags do not support all password types)"), + arg_str0("o", "old", "", "old password (if present), 8 hex bytes"), + arg_str1("n", "new", "", "new password, 8 hex bytes"), + arg_param_end + }; + + CLIExecWithReturn(ctx, Cmd, argtable, false); + + struct { + uint8_t old_pwd[4]; + uint8_t new_pwd[4]; + uint8_t pwd_id; + } PACKED payload; + int pwdlen = 0; + + + + CLIGetHexWithReturn(ctx, 2, payload.old_pwd, &pwdlen); + + if(pwdlen > 0 && pwdlen != 4) + { + PrintAndLogEx(WARNING, "old password must be 4 hex bytes if provided"); + return PM3_ESOFT; + } + + CLIGetHexWithReturn(ctx, 3, payload.new_pwd, &pwdlen); + + if(pwdlen != 4) + { + PrintAndLogEx(WARNING, "new password must be 4 hex bytes"); + return PM3_ESOFT; + } + + int vlen = 0; + char value[10]; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)value, sizeof(value), &vlen); + + if (vlen > 0) { + if (strcmp(value, "read") == 0) + { + PrintAndLogEx(SUCCESS, "Selected read pass"); + payload.pwd_id = 0x01; + } + else if (strcmp(value, "write") == 0) + { + PrintAndLogEx(SUCCESS, "Selected write pass"); + payload.pwd_id = 0x02; + } + else if (strcmp(value, "privacy") == 0) + { + PrintAndLogEx(SUCCESS, "Selected privacy pass"); + payload.pwd_id = 0x04; + } + else if (strcmp(value, "destroy") == 0) + { + PrintAndLogEx(SUCCESS, "Selected destroy pass"); + payload.pwd_id = 0x08; + } + else if (strcmp(value, "easafi") == 0) + { + PrintAndLogEx(SUCCESS, "Selected easafi pass"); + payload.pwd_id = 0x10; + } + else + { + PrintAndLogEx(ERR, "t argument must be 'read', 'write', 'privacy', 'destroy', or 'easafi'"); + return PM3_EINVARG; + } + } + + CLIParserFree(ctx); + + + PrintAndLogEx(INFO, "Trying to write " _YELLOW_("%s") " as " _YELLOW_("%s") " password" + , sprint_hex_inrow(payload.new_pwd, sizeof(payload.new_pwd)), value); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_WRITE_PWD, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_WRITE_PWD, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "password was not accepted"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "password written ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; +} + +static int CmdHF15AFIPassProtect(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 passprotectafi", + "Password protect AFI. Cannot be undone.", + "hf 15 passprotectafi -p 00000000 -c"); + + void *argtable[] = { + arg_param_begin, + arg_str1("p", "password", "", "EAS/AFI password, 8 hex bytes"), + arg_lit0("c", "confirm", "confirm the execution of this irreversible command"), + arg_param_end + }; + + CLIExecWithReturn(ctx, Cmd, argtable, true); + + struct { + uint8_t pwd[4]; + } PACKED payload; + int pwdlen = 0; + + CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); + + bool confirmation = arg_get_lit(ctx, 2); + + if(pwdlen != 4) + { + PrintAndLogEx(WARNING, "password must be 4 hex bytes"); + return PM3_ESOFT; + } + + if(confirmation == 0) + { + PrintAndLogEx(WARNING, "This irreversible command must be confirmed with the -c flag"); + return PM3_ESOFT; + } + + + PrintAndLogEx(INFO, "Trying to enable AFI password protection"); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, (uint8_t*)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "error enabling AFI password protection"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "AFI password protected ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; + +} + +static int CmdHF15EASPassProtect(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 passprotecteas", + "Password protect EAS. Cannot be undone.", + "hf 15 passprotecteas -p 00000000 -c"); + + void *argtable[] = { + arg_param_begin, + arg_str1("p", "password", "", "EAS/AFI password, 8 hex bytes"), + arg_lit0("c", "confirm", "confirm the execution of this irreversible command"), + arg_param_end + }; + + CLIExecWithReturn(ctx, Cmd, argtable, true); + + struct { + uint8_t pwd[4]; + } PACKED payload; + int pwdlen = 0; + + CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); + + bool confirmation = arg_get_lit(ctx, 2); + + if(pwdlen != 4) + { + PrintAndLogEx(WARNING, "password must be 4 hex bytes"); + return PM3_ESOFT; + } + + if(confirmation == 0) + { + PrintAndLogEx(WARNING, "This irreversible command must be confirmed with the -c flag"); + return PM3_ESOFT; + } + + PrintAndLogEx(INFO, "Trying to enable EAS password protection"); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, (uint8_t*)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "error enabling EAS password protection"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "EAS password protected ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; +} + static command_t CommandTable[] = { - {"-----------", CmdHF15Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, - {"help", CmdHF15Help, AlwaysAvailable, "This help"}, - {"list", CmdHF15List, AlwaysAvailable, "List ISO-15693 history"}, - {"demod", CmdHF15Demod, AlwaysAvailable, "Demodulate ISO-15693 from tag"}, - {"dump", CmdHF15Dump, IfPm3Iso15693, "Read all memory pages of an ISO-15693 tag, save to file"}, - {"info", CmdHF15Info, IfPm3Iso15693, "Tag information"}, - {"sniff", CmdHF15Sniff, IfPm3Iso15693, "Sniff ISO-15693 traffic"}, - {"raw", CmdHF15Raw, IfPm3Iso15693, "Send raw hex data to tag"}, - {"rdbl", CmdHF15Readblock, IfPm3Iso15693, "Read a block"}, - {"rdmulti", CmdHF15Readmulti, IfPm3Iso15693, "Reads multiple blocks"}, - {"reader", CmdHF15Reader, IfPm3Iso15693, "Act like an ISO-15693 reader"}, - {"restore", CmdHF15Restore, IfPm3Iso15693, "Restore from file to all memory pages of an ISO-15693 tag"}, - {"samples", CmdHF15Samples, IfPm3Iso15693, "Acquire samples as reader (enables carrier, sends inquiry)"}, - {"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file into emulator to be used by 'sim' command"}, - {"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"}, - {"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"}, - {"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"}, - {"slixdisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"}, - {"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"}, - {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("afi") " -----------------------"}, - {"findafi", CmdHF15FindAfi, IfPm3Iso15693, "Brute force AFI of an ISO-15693 tag"}, - {"writeafi", CmdHF15WriteAfi, IfPm3Iso15693, "Writes the AFI on an ISO-15693 tag"}, - {"writedsfid", CmdHF15WriteDsfid, IfPm3Iso15693, "Writes the DSFID on an ISO-15693 tag"}, - {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("magic") " -----------------------"}, - {"csetuid", CmdHF15CSetUID, IfPm3Iso15693, "Set UID for magic card"}, + {"-----------", CmdHF15Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, + {"help", CmdHF15Help, AlwaysAvailable, "This help"}, + {"list", CmdHF15List, AlwaysAvailable, "List ISO-15693 history"}, + {"demod", CmdHF15Demod, AlwaysAvailable, "Demodulate ISO-15693 from tag"}, + {"dump", CmdHF15Dump, IfPm3Iso15693, "Read all memory pages of an ISO-15693 tag, save to file"}, + {"info", CmdHF15Info, IfPm3Iso15693, "Tag information"}, + {"sniff", CmdHF15Sniff, IfPm3Iso15693, "Sniff ISO-15693 traffic"}, + {"raw", CmdHF15Raw, IfPm3Iso15693, "Send raw hex data to tag"}, + {"rdbl", CmdHF15Readblock, IfPm3Iso15693, "Read a block"}, + {"rdmulti", CmdHF15Readmulti, IfPm3Iso15693, "Reads multiple blocks"}, + {"reader", CmdHF15Reader, IfPm3Iso15693, "Act like an ISO-15693 reader"}, + {"restore", CmdHF15Restore, IfPm3Iso15693, "Restore from file to all memory pages of an ISO-15693 tag"}, + {"samples", CmdHF15Samples, IfPm3Iso15693, "Acquire samples as reader (enables carrier, sends inquiry)"}, + {"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file into emulator to be used by 'sim' command"}, + {"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"}, + {"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"}, + {"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"}, + {"slixwritepwd", CmdHF15SlixWritePassword, IfPm3Iso15693, "Writes a password on a SLIX ISO-15693 tag"}, + {"slixeasdisable", CmdHF15SlixEASDisable, IfPm3Iso15693, "Disable EAS mode on SLIX ISO-15693 tag"}, + {"slixeasenable", CmdHF15SlixEASEnable, IfPm3Iso15693, "Enable EAS mode on SLIX ISO-15693 tag"}, + {"slixprivacydisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"}, + {"slixprivacyenable", CmdHF15SlixEnable, IfPm3Iso15693, "Enable privacy mode on SLIX ISO-15693 tag"}, + {"passprotectafi", CmdHF15AFIPassProtect, IfPm3Iso15693, "Password protect AFI - Cannot be undone"}, + {"passprotecteas", CmdHF15EASPassProtect, IfPm3Iso15693, "Password protect EAS - Cannot be undone"}, + {"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"}, + {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("afi") " -----------------------"}, + {"findafi", CmdHF15FindAfi, IfPm3Iso15693, "Brute force AFI of an ISO-15693 tag"}, + {"writeafi", CmdHF15WriteAfi, IfPm3Iso15693, "Writes the AFI on an ISO-15693 tag"}, + {"writedsfid", CmdHF15WriteDsfid, IfPm3Iso15693, "Writes the DSFID on an ISO-15693 tag"}, + {"-----------", CmdHF15Help, IfPm3Iso15693, "----------------------- " _CYAN_("magic") " -----------------------"}, + {"csetuid", CmdHF15CSetUID, IfPm3Iso15693, "Set UID for magic card"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 4cd9457b5..ee94f7ec0 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -177,7 +177,13 @@ const static vocabulory_t vocabulory[] = { { 0, "hf 15 esave" }, { 0, "hf 15 eview" }, { 0, "hf 15 sim" }, - { 0, "hf 15 slixdisable" }, + { 0, "hf 15 slixwritepwd" }, + { 0, "hf 15 slixeasdisable" }, + { 0, "hf 15 slixeasenable" }, + { 0, "hf 15 slixprivacydisable" }, + { 0, "hf 15 slixprivacyenable" }, + { 0, "hf 15 passprotectafi" }, + { 0, "hf 15 passprotecteas" }, { 0, "hf 15 wrbl" }, { 0, "hf 15 findafi" }, { 0, "hf 15 writeafi" }, diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 95750b9b7..43fd44ac0 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -519,8 +519,14 @@ typedef struct { #define CMD_HF_ISO15693_COMMAND 0x0313 #define CMD_HF_ISO15693_FINDAFI 0x0315 #define CMD_HF_ISO15693_CSETUID 0x0316 -#define CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY 0x0317 -#define CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI 0x0318 +#define CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY 0xA317 +#define CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY 0x0317 +#define CMD_HF_ISO15693_SLIX_DISABLE_EAS 0x0318 +#define CMD_HF_ISO15693_SLIX_ENABLE_EAS 0x0862 +#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI 0x0863 +#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS 0x0864 +#define CMD_HF_ISO15693_SLIX_WRITE_PWD 0x0865 +#define CMD_HF_ISO15693_WRITE_AFI 0x0866 #define CMD_HF_TEXKOM_SIMULATE 0x0320 #define CMD_HF_ISO15693_EML_CLEAR 0x0330 #define CMD_HF_ISO15693_EML_SETMEM 0x0331 From 126beb976c81f40b2613a4163ef91efe9f5d512c Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Sat, 28 Jan 2023 13:11:51 -0600 Subject: [PATCH 565/759] fix tabs --- include/pm3_cmd.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 43fd44ac0..4c4eff049 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -519,12 +519,12 @@ typedef struct { #define CMD_HF_ISO15693_COMMAND 0x0313 #define CMD_HF_ISO15693_FINDAFI 0x0315 #define CMD_HF_ISO15693_CSETUID 0x0316 -#define CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY 0xA317 -#define CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY 0x0317 -#define CMD_HF_ISO15693_SLIX_DISABLE_EAS 0x0318 -#define CMD_HF_ISO15693_SLIX_ENABLE_EAS 0x0862 -#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI 0x0863 -#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS 0x0864 +#define CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY 0xA317 +#define CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY 0x0317 +#define CMD_HF_ISO15693_SLIX_DISABLE_EAS 0x0318 +#define CMD_HF_ISO15693_SLIX_ENABLE_EAS 0x0862 +#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI 0x0863 +#define CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS 0x0864 #define CMD_HF_ISO15693_SLIX_WRITE_PWD 0x0865 #define CMD_HF_ISO15693_WRITE_AFI 0x0866 #define CMD_HF_TEXKOM_SIMULATE 0x0320 From 60f49175e827793c1faed90d8dd2c2a6136ddc9b Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Sat, 28 Jan 2023 13:46:11 -0600 Subject: [PATCH 566/759] change constant value so it follows others --- include/pm3_cmd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 4c4eff049..464aaf0c8 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -519,7 +519,7 @@ typedef struct { #define CMD_HF_ISO15693_COMMAND 0x0313 #define CMD_HF_ISO15693_FINDAFI 0x0315 #define CMD_HF_ISO15693_CSETUID 0x0316 -#define CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY 0xA317 +#define CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY 0x0867 #define CMD_HF_ISO15693_SLIX_DISABLE_PRIVACY 0x0317 #define CMD_HF_ISO15693_SLIX_DISABLE_EAS 0x0318 #define CMD_HF_ISO15693_SLIX_ENABLE_EAS 0x0862 From 104028bd1e2d6600fba0cf7f76111823eb2a9b87 Mon Sep 17 00:00:00 2001 From: mwalker33 <51802811+mwalker33@users.noreply.github.com> Date: Sun, 29 Jan 2023 11:35:49 +1100 Subject: [PATCH 567/759] Update T5577_Guide.md --- doc/T5577_Guide.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/T5577_Guide.md b/doc/T5577_Guide.md index deab49d53..6c4eceaf5 100644 --- a/doc/T5577_Guide.md +++ b/doc/T5577_Guide.md @@ -393,8 +393,8 @@ required, please do not proceed. | Hex Data | Binary Data | |:--------:|:---------------------------------------| - | 00088040 | 000000000000100010000000111***0***0000 | - | 00088050 | 000000000000100010000000111***1***0000 | + | 000880E0 | 000000000000100010000000111***0***0000 | + | 000880F0 | 000000000000100010000000111***1***0000 | See how in the above we changed the bit in location 28 from a 0 to 1 0 = No Password, 1 = Use Password @@ -533,7 +533,7 @@ required, please do not proceed. [=] Downlink mode..... default/fixed bit length [=] Password set...... No ``` - Yes we can! We can see Block 0 is the correct config 00088040 + Yes we can! We can see Block 0 is the correct config 000880E0 # Part 2 – Configuration Blocks ^[Top](#top) From 9bd7e41d39c0961cc2e624e7bb3c54730ea1098d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 04:58:29 +0100 Subject: [PATCH 568/759] add dummy length to pass savejson sanity check. Thanks @mwalker33 --- client/src/preferences.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/preferences.c b/client/src/preferences.c index 28ae4d44f..99fb20d30 100644 --- a/client/src/preferences.c +++ b/client/src/preferences.c @@ -152,7 +152,7 @@ int preferences_save(void) { } uint8_t dummyData = 0x00; - size_t dummyDL = 0x00; + size_t dummyDL = 0x01; if (saveFileJSON(fn, jsfCustom, &dummyData, dummyDL, &preferences_save_callback) != PM3_SUCCESS) PrintAndLogEx(ERR, "Error saving preferences to \"%s\"", fn); From 09f2bf9f02910d4c075221784b0b0b0e4af8a1bb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 04:59:50 +0100 Subject: [PATCH 569/759] style --- armsrc/appmain.c | 16 +- armsrc/iso15693.c | 290 ++++++++++----------- armsrc/iso15693.h | 2 +- client/src/cmdhf15.c | 442 +++++++++++++++----------------- client/src/cmdhw.c | 2 +- client/src/pm3line_vocabulory.h | 6 +- doc/commands.json | 105 +++++++- doc/commands.md | 8 +- 8 files changed, 455 insertions(+), 416 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 734ee85ee..1687767cc 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -455,7 +455,7 @@ static void SendCapabilities(void) { #ifdef RDV4 capabilities.is_rdv4 = true; -#else +#else capabilities.is_rdv4 = false; #endif @@ -1296,7 +1296,7 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_HF_ISO15693_SLIX_DISABLE_EAS: { struct p { uint8_t pwd[4]; - bool usepwd; + bool usepwd; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; DisableEAS_AFISlixIso15693(payload->pwd, payload->usepwd); @@ -1305,7 +1305,7 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_HF_ISO15693_SLIX_ENABLE_EAS: { struct p { uint8_t pwd[4]; - bool usepwd; + bool usepwd; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; EnableEAS_AFISlixIso15693(payload->pwd, payload->usepwd); @@ -1333,7 +1333,7 @@ static void PacketReceived(PacketCommandNG *packet) { struct p { uint8_t pwd[4]; } PACKED; - struct p* payload = (struct p*)packet->data.asBytes; + struct p *payload = (struct p *)packet->data.asBytes; EnablePrivacySlixIso15693(payload->pwd); break; } @@ -1341,7 +1341,7 @@ static void PacketReceived(PacketCommandNG *packet) { struct p { uint8_t pwd[4]; } PACKED; - struct p* payload = (struct p*)packet->data.asBytes; + struct p *payload = (struct p *)packet->data.asBytes; PassProtectAFISlixIso15693(payload->pwd); break; } @@ -1353,7 +1353,7 @@ static void PacketReceived(PacketCommandNG *packet) { bool use_uid; uint8_t afi; } PACKED; - struct p* payload = (struct p*)packet->data.asBytes; + struct p *payload = (struct p *)packet->data.asBytes; WriteAFIIso15693(payload->pwd, payload->use_pwd, payload->uid, payload->use_uid, payload->afi); break; } @@ -1361,11 +1361,11 @@ static void PacketReceived(PacketCommandNG *packet) { struct p { uint8_t pwd[4]; } PACKED; - struct p* payload = (struct p*)packet->data.asBytes; + struct p *payload = (struct p *)packet->data.asBytes; PassProtextEASSlixIso15693(payload->pwd); break; } - + #endif #ifdef WITH_LEGICRF diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 3ca186305..daa84f886 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -177,31 +177,30 @@ static void CodeIso15693AsReaderEOF(void) { } -static int get_uid_slix(uint32_t start_time, uint32_t* eof_time, uint8_t* uid) { +static int get_uid_slix(uint32_t start_time, uint32_t *eof_time, uint8_t *uid) { uint8_t *answer = BigBuf_malloc(ISO15693_MAX_RESPONSE_LENGTH); memset(answer, 0x00, ISO15693_MAX_RESPONSE_LENGTH); start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; - + uint8_t cmd[5] = {0}; BuildIdentifyRequest(cmd); uint16_t recvlen = 0; SendDataTag(cmd, sizeof(cmd), false, true, answer, ISO15693_MAX_RESPONSE_LENGTH, start_time, ISO15693_READER_TIMEOUT, eof_time, &recvlen); - - if(recvlen != 12) - { - return PM3_ETIMEOUT; + + if (recvlen != 12) { + return PM3_ETIMEOUT; } - - uid[0] = answer[2]; - uid[1] = answer[3]; + + uid[0] = answer[2]; + uid[1] = answer[3]; uid[2] = answer[4]; uid[3] = answer[5]; uid[4] = answer[6]; uid[5] = answer[7]; uid[6] = answer[8]; - uid[7] = answer[9]; + uid[7] = answer[9]; BigBuf_free(); return PM3_SUCCESS; @@ -2701,7 +2700,7 @@ static bool get_rnd_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t return true; } -static uint32_t disable_privacy_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t pass_id, uint8_t* password) { +static uint32_t disable_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, uint8_t *password) { uint8_t rnd[2]; if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { @@ -2723,26 +2722,26 @@ static uint32_t disable_privacy_15693_Slix(uint32_t start_time, uint32_t* eof_ti return PM3_SUCCESS; } -static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t pass_id, uint8_t* password, uint8_t* uid) { +static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pass_id, uint8_t *password, uint8_t *uid) { + - uint8_t rnd[2]; if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; } - + // 0x04, == NXP from manufacture id list. - uint8_t c[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_SET_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - + uint8_t c[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_SET_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pass_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + init_password_15693_Slix(&c[12], password, rnd); - + memcpy(&c[3], uid, 8); AddCrc15(c, 16); start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; uint16_t recvlen = 0; - + int res = SendDataTag(c, sizeof(c), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); if (res != PM3_SUCCESS && recvlen != 3) { return PM3_EWRONGANSWER; @@ -2750,7 +2749,7 @@ static uint32_t set_pass_15693_Slix(uint32_t start_time, uint32_t* eof_time, uin return PM3_SUCCESS; } -static uint32_t set_privacy_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t* password) { +static uint32_t set_privacy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *password) { uint8_t rnd[2]; if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; @@ -2771,28 +2770,26 @@ static uint32_t set_privacy_15693_Slix(uint32_t start_time, uint32_t* eof_time, return PM3_SUCCESS; } -static uint32_t disable_eas_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t* password, bool usepwd) { - +static uint32_t disable_eas_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd) { + uint8_t uid[8]; get_uid_slix(start_time, eof_time, uid); - + uint8_t rnd[2]; if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; } - - if(usepwd) - { - - int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); - - if(res_setpass != PM3_SUCCESS) - { - return PM3_EWRONGANSWER; - } - } - - // 0x04, == NXP from manufacture id list. + + if (usepwd) { + + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if (res_setpass != PM3_SUCCESS) { + return PM3_EWRONGANSWER; + } + } + + // 0x04, == NXP from manufacture id list. uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA3, 0x04, 0x00, 0x00}; AddCrc15(c, 3); @@ -2807,24 +2804,22 @@ static uint32_t disable_eas_15693_Slix(uint32_t start_time, uint32_t* eof_time, } -static uint32_t enable_eas_15693_Slix(uint32_t start_time, uint32_t* eof_time, uint8_t* password, bool usepwd) { - +static uint32_t enable_eas_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd) { + uint8_t uid[8]; get_uid_slix(start_time, eof_time, uid); - + uint8_t rnd[2]; if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { return PM3_ETIMEOUT; } - - if(usepwd) - { - int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); - - if(res_setpass != PM3_SUCCESS) - { - return PM3_EWRONGANSWER; - } + + if (usepwd) { + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if (res_setpass != PM3_SUCCESS) { + return PM3_EWRONGANSWER; + } } // 0x04, == NXP from manufacture id list. uint8_t c[] = { ISO15_REQ_DATARATE_HIGH, 0xA2, 0x04, 0x00, 0x00}; @@ -2841,106 +2836,100 @@ static uint32_t enable_eas_15693_Slix(uint32_t start_time, uint32_t* eof_time, u return PM3_SUCCESS; } -static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pwd_id, uint8_t *password, uint8_t* uid) { - +static uint32_t write_password_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint8_t pwd_id, uint8_t *password, uint8_t *uid) { + uint8_t new_pwd_cmd[] = { (ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS), ISO15693_WRITE_PASSWORD, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, pwd_id, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - + memcpy(&new_pwd_cmd[3], uid, 8); memcpy(&new_pwd_cmd[12], password, 4); - + AddCrc15(new_pwd_cmd, 16); start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; uint16_t recvlen = 0; - + int res_wrp = SendDataTag(new_pwd_cmd, sizeof(new_pwd_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); if (res_wrp != PM3_SUCCESS && recvlen != 3) { return PM3_EWRONGANSWER; } - + return PM3_SUCCESS; } - -static uint32_t pass_protect_EASAFI_15693_Slix(uint32_t start_time, uint32_t *eof_time, bool set_option_flag, uint8_t* password) { - - uint8_t flags; - - if(set_option_flag) - flags = ISO15_REQ_DATARATE_HIGH | ISO15_REQ_OPTION; - else - flags = ISO15_REQ_DATARATE_HIGH; - - - uint8_t uid[8]; - get_uid_slix(start_time, eof_time, uid); - uint8_t rnd[2]; - if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { - return PM3_ETIMEOUT; - } - - int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); - - if(res_setpass != PM3_SUCCESS) - { - return PM3_EWRONGANSWER; - } +static uint32_t pass_protect_EASAFI_15693_Slix(uint32_t start_time, uint32_t *eof_time, bool set_option_flag, uint8_t *password) { - uint8_t new_pass_protect_cmd[] = { flags, ISO15693_PASSWORD_PROTECT_EAS, 0x04, 0x00, 0x00}; - AddCrc15(new_pass_protect_cmd, 3); - - start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; - uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; - uint16_t recvlen = 0; + uint8_t flags; - int res = SendDataTag(new_pass_protect_cmd, sizeof(new_pass_protect_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); - if (res != PM3_SUCCESS && recvlen != 3) { - return PM3_EWRONGANSWER; - } - - return PM3_SUCCESS; + if (set_option_flag) + flags = ISO15_REQ_DATARATE_HIGH | ISO15_REQ_OPTION; + else + flags = ISO15_REQ_DATARATE_HIGH; + + + uint8_t uid[8]; + get_uid_slix(start_time, eof_time, uid); + + uint8_t rnd[2]; + if (get_rnd_15693_Slix(start_time, eof_time, rnd) == false) { + return PM3_ETIMEOUT; + } + + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if (res_setpass != PM3_SUCCESS) { + return PM3_EWRONGANSWER; + } + + uint8_t new_pass_protect_cmd[] = { flags, ISO15693_PASSWORD_PROTECT_EAS, 0x04, 0x00, 0x00}; + AddCrc15(new_pass_protect_cmd, 3); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + + int res = SendDataTag(new_pass_protect_cmd, sizeof(new_pass_protect_cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS && recvlen != 3) { + return PM3_EWRONGANSWER; + } + + return PM3_SUCCESS; } -static uint32_t write_afi_15693(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi) -{ - - if(!use_uid) - { - int res_getuid = get_uid_slix(start_time, eof_time, uid); - - if(res_getuid != PM3_SUCCESS) - { - return res_getuid; - } - } - - if(usepwd) - { - int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); - - if(res_setpass != PM3_SUCCESS) - { - return PM3_EWRONGANSWER; - } - } - - uint8_t cmd[] = { ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_AFI, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - memcpy(&cmd[2], uid, 8); - cmd[10] = afi; - AddCrc15(cmd, 11); - - start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; - uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; - uint16_t recvlen = 0; +static uint32_t write_afi_15693(uint32_t start_time, uint32_t *eof_time, uint8_t *password, bool usepwd, uint8_t *uid, bool use_uid, uint8_t afi) { - int res = SendDataTag(cmd, sizeof(cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); - if (res != PM3_SUCCESS || recvlen != 3) { - return PM3_EWRONGANSWER; - } + if (!use_uid) { + int res_getuid = get_uid_slix(start_time, eof_time, uid); - return PM3_SUCCESS; + if (res_getuid != PM3_SUCCESS) { + return res_getuid; + } + } + + if (usepwd) { + int res_setpass = set_pass_15693_Slix(start_time, eof_time, 0x10, password, uid); + + if (res_setpass != PM3_SUCCESS) { + return PM3_EWRONGANSWER; + } + } + + uint8_t cmd[] = { ISO15_REQ_DATARATE_HIGH | ISO15_REQ_ADDRESS, ISO15693_WRITE_AFI, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + memcpy(&cmd[2], uid, 8); + cmd[10] = afi; + AddCrc15(cmd, 11); + + start_time = *eof_time + DELAY_ISO15693_VICC_TO_VCD_READER; + uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH]; + uint16_t recvlen = 0; + + int res = SendDataTag(cmd, sizeof(cmd), false, true, recvbuf, sizeof(recvbuf), start_time, ISO15693_READER_TIMEOUT_WRITE, eof_time, &recvlen); + if (res != PM3_SUCCESS || recvlen != 3) { + return PM3_EWRONGANSWER; + } + + return PM3_SUCCESS; } /* @@ -3013,29 +3002,28 @@ static uint32_t destroy_15693_Slix(uint32_t start_time, uint32_t *eof_time, uint */ void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id) { - LED_D_ON(); - Iso15693InitReader(); - StartCountSspClk(); - uint32_t start_time = 0, eof_time = 0; - int res = PM3_EFAILED; - - uint8_t uid[8]; - get_uid_slix(start_time, &eof_time, uid); + LED_D_ON(); + Iso15693InitReader(); + StartCountSspClk(); + uint32_t start_time = 0, eof_time = 0; + int res = PM3_EFAILED; + + uint8_t uid[8]; + get_uid_slix(start_time, &eof_time, uid); + + res = set_pass_15693_Slix(start_time, &eof_time, pwd_id, old_password, uid); + if (res != PM3_SUCCESS) { + reply_ng(CMD_HF_ISO15693_SLIX_WRITE_PWD, res, NULL, 0); + switch_off(); + return; + } + + res = write_password_15693_Slix(start_time, &eof_time, pwd_id, new_password, uid); - res = set_pass_15693_Slix(start_time, &eof_time, pwd_id, old_password, uid); - if(res != PM3_SUCCESS) - { reply_ng(CMD_HF_ISO15693_SLIX_WRITE_PWD, res, NULL, 0); - switch_off(); - return; - } - res = write_password_15693_Slix(start_time, &eof_time, pwd_id, new_password, uid); - - reply_ng(CMD_HF_ISO15693_SLIX_WRITE_PWD, res, NULL, 0); - - switch_off(); - + switch_off(); + } void DisablePrivacySlixIso15693(uint8_t *password) { @@ -3053,7 +3041,7 @@ void DisablePrivacySlixIso15693(uint8_t *password) { switch_off(); } -void EnablePrivacySlixIso15693(uint8_t* password) { +void EnablePrivacySlixIso15693(uint8_t *password) { LED_D_ON(); Iso15693InitReader(); StartCountSspClk(); @@ -3080,9 +3068,9 @@ void DisableEAS_AFISlixIso15693(uint8_t *password, bool usepwd) { // 0x08 Destroy SLIX-L // 0x10 EAS/AFI int res = disable_eas_15693_Slix(start_time, &eof_time, password, usepwd); - - - + + + reply_ng(CMD_HF_ISO15693_SLIX_DISABLE_EAS, res, NULL, 0); switch_off(); } @@ -3130,4 +3118,4 @@ void WriteAFIIso15693(uint8_t *password, bool use_pwd, uint8_t *uid, bool use_ui //int res = PM3_SUCCESS; reply_ng(CMD_HF_ISO15693_WRITE_AFI, res, NULL, 0); switch_off(); -} \ No newline at end of file +} diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index c0ff44929..b087edd2e 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -64,7 +64,7 @@ void SetTag15693Uid(const uint8_t *uid); void WritePasswordSlixIso15693(uint8_t *old_password, uint8_t *new_password, uint8_t pwd_id); void DisablePrivacySlixIso15693(uint8_t *password); -void EnablePrivacySlixIso15693(uint8_t* password); +void EnablePrivacySlixIso15693(uint8_t *password); void DisableEAS_AFISlixIso15693(uint8_t *password, bool usepwd); void EnableEAS_AFISlixIso15693(uint8_t *password, bool usepwd); void PassProtextEASSlixIso15693(uint8_t *password); diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 590393c61..9c7f1528d 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -698,7 +698,7 @@ static int NxpCheckSig(uint8_t *uid) { PacketResponseNG resp; uint16_t reqlen = 0; uint8_t req[PM3_CMD_DATA_SIZE] = {0}; - + // Check if we can also read the signature req[reqlen++] |= ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; req[reqlen++] = ISO15693_READ_SIGNATURE; @@ -736,7 +736,7 @@ static int NxpCheckSig(uint8_t *uid) { memcpy(signature, recv + 1, 32); nxp_15693_print_signature(uid, signature); - + return PM3_SUCCESS; } @@ -1363,7 +1363,7 @@ static int CmdHF15WriteAfi(const char *Cmd) { argtable[4] = arg_param_end; CLIExecWithReturn(ctx, Cmd, argtable, true); - + struct { uint8_t pwd[4]; bool use_pwd; @@ -1376,21 +1376,19 @@ static int CmdHF15WriteAfi(const char *Cmd) { CLIGetHexWithReturn(ctx, 1, payload.uid, &uidlen); payload.afi = arg_get_int_def(ctx, 2, 0); - + int pwdlen; - + CLIGetHexWithReturn(ctx, 3, payload.pwd, &pwdlen); - + CLIParserFree(ctx); - - if(pwdlen == 4) - { + + if (pwdlen == 4) { payload.use_pwd = true; } - - if(uidlen == 8) - { - payload.use_uid = true; + + if (uidlen == 8) { + payload.use_uid = true; } // sanity checks @@ -1398,11 +1396,10 @@ static int CmdHF15WriteAfi(const char *Cmd) { PrintAndLogEx(WARNING, "uid must be 8 hex bytes if provided"); return PM3_EINVARG; } - - if(pwdlen > 0 && pwdlen != 4) - { + + if (pwdlen > 0 && pwdlen != 4) { PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); - return PM3_ESOFT; + return PM3_ESOFT; } PacketResponseNG resp; @@ -1420,11 +1417,11 @@ static int CmdHF15WriteAfi(const char *Cmd) { break; } case PM3_EWRONGANSWER: { - PrintAndLogEx(WARNING, "error writing AFI"); + PrintAndLogEx(WARNING, "error writing AFI"); break; } case PM3_SUCCESS: { - PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", payload.afi); + PrintAndLogEx(SUCCESS, "Wrote AFI 0x%02X", payload.afi); break; } } @@ -2385,29 +2382,25 @@ static int CmdHF15SlixEASEnable(const char *Cmd) { bool usepwd; } PACKED payload; int pwdlen = 0; - + int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen); - if((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) - { + if ((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) { PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); - return PM3_ESOFT; + return PM3_ESOFT; } - + //CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); CLIParserFree(ctx); - - - if(pwdlen > 0 ) - { - PrintAndLogEx(INFO, "Trying to enable EAS mode using password " _GREEN_("%s") - , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) - ); - payload.usepwd = true; - } - else - { - PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password"); - payload.usepwd = false; + + + if (pwdlen > 0) { + PrintAndLogEx(INFO, "Trying to enable EAS mode using password " _GREEN_("%s") + , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) + ); + payload.usepwd = true; + } else { + PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password"); + payload.usepwd = false; } @@ -2426,13 +2419,10 @@ static int CmdHF15SlixEASEnable(const char *Cmd) { break; } case PM3_EWRONGANSWER: { - if(pwdlen > 0 ) - { - PrintAndLogEx(WARNING, "the password provided was not accepted"); - } - else - { - PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked"); + if (pwdlen > 0) { + PrintAndLogEx(WARNING, "the password provided was not accepted"); + } else { + PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked"); } break; } @@ -2451,7 +2441,7 @@ static int CmdHF15SlixEASDisable(const char *Cmd) { "Disable EAS mode on SLIX ISO-15693 tag", "hf 15 slixeasdisable -p 0F0F0F0F"); - void *argtable[] = { + void *argtable[] = { arg_param_begin, arg_str0("p", "pwd", "", "optional password, 8 hex bytes"), arg_param_end @@ -2460,32 +2450,28 @@ static int CmdHF15SlixEASDisable(const char *Cmd) { struct { uint8_t pwd[4]; bool usepwd; - + } PACKED payload; int pwdlen = 0; - + int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen); - if((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) - { + if ((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) { PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); - return PM3_ESOFT; + return PM3_ESOFT; } - + //CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); CLIParserFree(ctx); - - - if(pwdlen > 0 ) - { - PrintAndLogEx(INFO, "Trying to disable EAS mode using password " _GREEN_("%s") - , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) - ); - payload.usepwd = true; - } - else - { - PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password"); - payload.usepwd = false; + + + if (pwdlen > 0) { + PrintAndLogEx(INFO, "Trying to disable EAS mode using password " _GREEN_("%s") + , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) + ); + payload.usepwd = true; + } else { + PrintAndLogEx(INFO, "Trying to enable EAS mode without using a password"); + payload.usepwd = false; } PacketResponseNG resp; @@ -2503,13 +2489,10 @@ static int CmdHF15SlixEASDisable(const char *Cmd) { break; } case PM3_EWRONGANSWER: { - if(pwdlen > 0 ) - { - PrintAndLogEx(WARNING, "the password provided was not accepted"); - } - else - { - PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked"); + if (pwdlen > 0) { + PrintAndLogEx(WARNING, "the password provided was not accepted"); + } else { + PrintAndLogEx(WARNING, "either a password is required or EAS mode is locked"); } break; } @@ -2571,14 +2554,14 @@ static int CmdHF15SlixDisable(const char *Cmd) { return resp.status; } -static int CmdHF15SlixEnable(const char* Cmd) { +static int CmdHF15SlixEnable(const char *Cmd) { - CLIParserContext* ctx; + CLIParserContext *ctx; CLIParserInit(&ctx, "hf 15 slixprivacyenable", - "Enable privacy mode on SLIX ISO-15693 tag", - "hf 15 slixenable -p 0F0F0F0F"); + "Enable privacy mode on SLIX ISO-15693 tag", + "hf 15 slixenable -p 0F0F0F0F"); - void* argtable[] = { + void *argtable[] = { arg_param_begin, arg_str1("p", "pwd", "", "password, 8 hex bytes"), arg_param_end @@ -2592,12 +2575,12 @@ static int CmdHF15SlixEnable(const char* Cmd) { CLIParserFree(ctx); PrintAndLogEx(INFO, "Trying to enable privacy mode using password " _GREEN_("%s") - , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) - ); + , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) + ); PacketResponseNG resp; clearCommandBuffer(); - SendCommandNG(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, (uint8_t*)&payload, sizeof(payload)); + SendCommandNG(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, (uint8_t *)&payload, sizeof(payload)); if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_ENABLE_PRIVACY, &resp, 2000) == false) { PrintAndLogEx(WARNING, "timeout while waiting for reply"); DropField(); @@ -2605,18 +2588,18 @@ static int CmdHF15SlixEnable(const char* Cmd) { } switch (resp.status) { - case PM3_ETIMEOUT: { - PrintAndLogEx(WARNING, "no tag found"); - break; - } - case PM3_EWRONGANSWER: { - PrintAndLogEx(WARNING, "password was not accepted"); - break; - } - case PM3_SUCCESS: { - PrintAndLogEx(SUCCESS, "privacy mode is now enabled ( " _GREEN_("ok") " ) "); - break; - } + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "password was not accepted"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "privacy mode is now enabled ( " _GREEN_("ok") " ) "); + break; + } } return resp.status; } @@ -2634,73 +2617,60 @@ static int CmdHF15SlixWritePassword(const char *Cmd) { arg_str1("n", "new", "", "new password, 8 hex bytes"), arg_param_end }; - + CLIExecWithReturn(ctx, Cmd, argtable, false); - + struct { uint8_t old_pwd[4]; uint8_t new_pwd[4]; uint8_t pwd_id; } PACKED payload; int pwdlen = 0; - - - + + + CLIGetHexWithReturn(ctx, 2, payload.old_pwd, &pwdlen); - - if(pwdlen > 0 && pwdlen != 4) - { + + if (pwdlen > 0 && pwdlen != 4) { PrintAndLogEx(WARNING, "old password must be 4 hex bytes if provided"); - return PM3_ESOFT; + return PM3_ESOFT; } - + CLIGetHexWithReturn(ctx, 3, payload.new_pwd, &pwdlen); - - if(pwdlen != 4) - { + + if (pwdlen != 4) { PrintAndLogEx(WARNING, "new password must be 4 hex bytes"); - return PM3_ESOFT; + return PM3_ESOFT; } - + int vlen = 0; char value[10]; CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)value, sizeof(value), &vlen); - + if (vlen > 0) { - if (strcmp(value, "read") == 0) - { + if (strcmp(value, "read") == 0) { PrintAndLogEx(SUCCESS, "Selected read pass"); payload.pwd_id = 0x01; - } - else if (strcmp(value, "write") == 0) - { + } else if (strcmp(value, "write") == 0) { PrintAndLogEx(SUCCESS, "Selected write pass"); payload.pwd_id = 0x02; - } - else if (strcmp(value, "privacy") == 0) - { + } else if (strcmp(value, "privacy") == 0) { PrintAndLogEx(SUCCESS, "Selected privacy pass"); payload.pwd_id = 0x04; - } - else if (strcmp(value, "destroy") == 0) - { + } else if (strcmp(value, "destroy") == 0) { PrintAndLogEx(SUCCESS, "Selected destroy pass"); payload.pwd_id = 0x08; - } - else if (strcmp(value, "easafi") == 0) - { + } else if (strcmp(value, "easafi") == 0) { PrintAndLogEx(SUCCESS, "Selected easafi pass"); payload.pwd_id = 0x10; - } - else - { + } else { PrintAndLogEx(ERR, "t argument must be 'read', 'write', 'privacy', 'destroy', or 'easafi'"); return PM3_EINVARG; } } - + CLIParserFree(ctx); - + PrintAndLogEx(INFO, "Trying to write " _YELLOW_("%s") " as " _YELLOW_("%s") " password" , sprint_hex_inrow(payload.new_pwd, sizeof(payload.new_pwd)), value); @@ -2732,135 +2702,131 @@ static int CmdHF15SlixWritePassword(const char *Cmd) { } static int CmdHF15AFIPassProtect(const char *Cmd) { - - CLIParserContext *ctx; - CLIParserInit(&ctx, "hf 15 passprotectafi", - "Password protect AFI. Cannot be undone.", - "hf 15 passprotectafi -p 00000000 -c"); - void *argtable[] = { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 passprotectafi", + "Password protect AFI. Cannot be undone.", + "hf 15 passprotectafi -p 00000000 -c"); + + void *argtable[] = { arg_param_begin, arg_str1("p", "password", "", "EAS/AFI password, 8 hex bytes"), arg_lit0("c", "confirm", "confirm the execution of this irreversible command"), arg_param_end }; - - CLIExecWithReturn(ctx, Cmd, argtable, true); - - struct { - uint8_t pwd[4]; - } PACKED payload; - int pwdlen = 0; - - CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); - - bool confirmation = arg_get_lit(ctx, 2); - - if(pwdlen != 4) - { - PrintAndLogEx(WARNING, "password must be 4 hex bytes"); - return PM3_ESOFT; - } - - if(confirmation == 0) - { - PrintAndLogEx(WARNING, "This irreversible command must be confirmed with the -c flag"); - return PM3_ESOFT; - } - - - PrintAndLogEx(INFO, "Trying to enable AFI password protection"); - - PacketResponseNG resp; - clearCommandBuffer(); - SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, (uint8_t*)&payload, sizeof(payload)); - if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, &resp, 2000) == false) { - PrintAndLogEx(WARNING, "timeout while waiting for reply"); - DropField(); - return PM3_ESOFT; - } - switch (resp.status) { - case PM3_ETIMEOUT: { - PrintAndLogEx(WARNING, "no tag found"); - break; - } - case PM3_EWRONGANSWER: { - PrintAndLogEx(WARNING, "error enabling AFI password protection"); - break; - } - case PM3_SUCCESS: { - PrintAndLogEx(SUCCESS, "AFI password protected ( " _GREEN_("ok") " ) "); - break; - } - } - return resp.status; - + CLIExecWithReturn(ctx, Cmd, argtable, true); + + struct { + uint8_t pwd[4]; + } PACKED payload; + int pwdlen = 0; + + CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); + + bool confirmation = arg_get_lit(ctx, 2); + + if (pwdlen != 4) { + PrintAndLogEx(WARNING, "password must be 4 hex bytes"); + return PM3_ESOFT; + } + + if (confirmation == 0) { + PrintAndLogEx(WARNING, "This irreversible command must be confirmed with the -c flag"); + return PM3_ESOFT; + } + + + PrintAndLogEx(INFO, "Trying to enable AFI password protection"); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_AFI, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "error enabling AFI password protection"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "AFI password protected ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; + } static int CmdHF15EASPassProtect(const char *Cmd) { - - CLIParserContext *ctx; - CLIParserInit(&ctx, "hf 15 passprotecteas", - "Password protect EAS. Cannot be undone.", - "hf 15 passprotecteas -p 00000000 -c"); - - void *argtable[] = { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 passprotecteas", + "Password protect EAS. Cannot be undone.", + "hf 15 passprotecteas -p 00000000 -c"); + + void *argtable[] = { arg_param_begin, arg_str1("p", "password", "", "EAS/AFI password, 8 hex bytes"), arg_lit0("c", "confirm", "confirm the execution of this irreversible command"), arg_param_end }; - CLIExecWithReturn(ctx, Cmd, argtable, true); - - struct { - uint8_t pwd[4]; - } PACKED payload; - int pwdlen = 0; - - CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); - - bool confirmation = arg_get_lit(ctx, 2); - - if(pwdlen != 4) - { - PrintAndLogEx(WARNING, "password must be 4 hex bytes"); - return PM3_ESOFT; - } - - if(confirmation == 0) - { - PrintAndLogEx(WARNING, "This irreversible command must be confirmed with the -c flag"); - return PM3_ESOFT; - } - - PrintAndLogEx(INFO, "Trying to enable EAS password protection"); - - PacketResponseNG resp; - clearCommandBuffer(); - SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, (uint8_t*)&payload, sizeof(payload)); - if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, &resp, 2000) == false) { - PrintAndLogEx(WARNING, "timeout while waiting for reply"); - DropField(); - return PM3_ESOFT; - } + CLIExecWithReturn(ctx, Cmd, argtable, true); - switch (resp.status) { - case PM3_ETIMEOUT: { - PrintAndLogEx(WARNING, "no tag found"); - break; - } - case PM3_EWRONGANSWER: { - PrintAndLogEx(WARNING, "error enabling EAS password protection"); - break; - } - case PM3_SUCCESS: { - PrintAndLogEx(SUCCESS, "EAS password protected ( " _GREEN_("ok") " ) "); - break; - } - } - return resp.status; + struct { + uint8_t pwd[4]; + } PACKED payload; + int pwdlen = 0; + + CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); + + bool confirmation = arg_get_lit(ctx, 2); + + if (pwdlen != 4) { + PrintAndLogEx(WARNING, "password must be 4 hex bytes"); + return PM3_ESOFT; + } + + if (confirmation == 0) { + PrintAndLogEx(WARNING, "This irreversible command must be confirmed with the -c flag"); + return PM3_ESOFT; + } + + PrintAndLogEx(INFO, "Trying to enable EAS password protection"); + + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, (uint8_t *)&payload, sizeof(payload)); + if (WaitForResponseTimeout(CMD_HF_ISO15693_SLIX_PASS_PROTECT_EAS, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); + DropField(); + return PM3_ESOFT; + } + + switch (resp.status) { + case PM3_ETIMEOUT: { + PrintAndLogEx(WARNING, "no tag found"); + break; + } + case PM3_EWRONGANSWER: { + PrintAndLogEx(WARNING, "error enabling EAS password protection"); + break; + } + case PM3_SUCCESS: { + PrintAndLogEx(SUCCESS, "EAS password protected ( " _GREEN_("ok") " ) "); + break; + } + } + return resp.status; } static command_t CommandTable[] = { diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index 67f404bc9..ed208b5f5 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -1301,7 +1301,7 @@ void pm3_version(bool verbose, bool oneliner) { if (IfPm3Flash()) { PrintAndLogEx(NORMAL, " external flash............ %s", _GREEN_("present")); } - + if (IfPm3FpcUsartHost()) { PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", _GREEN_("present")); } diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index ee94f7ec0..bcf196fe9 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -181,9 +181,9 @@ const static vocabulory_t vocabulory[] = { { 0, "hf 15 slixeasdisable" }, { 0, "hf 15 slixeasenable" }, { 0, "hf 15 slixprivacydisable" }, - { 0, "hf 15 slixprivacyenable" }, - { 0, "hf 15 passprotectafi" }, - { 0, "hf 15 passprotecteas" }, + { 0, "hf 15 slixprivacyenable" }, + { 0, "hf 15 passprotectafi" }, + { 0, "hf 15 passprotecteas" }, { 0, "hf 15 wrbl" }, { 0, "hf 15 findafi" }, { 0, "hf 15 writeafi" }, diff --git a/doc/commands.json b/doc/commands.json index bb781adb7..8d028d9e9 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -1656,6 +1656,34 @@ ], "usage": "hf 15 list [-h1crux] [--frame] [-f ]" }, + "hf 15 passprotectafi": { + "command": "hf 15 passprotectafi", + "description": "Password protect AFI. Cannot be undone.", + "notes": [ + "hf 15 passprotectafi -p 00000000 -c" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-p, --password EAS/AFI password, 8 hex bytes", + "-c, --confirm confirm the execution of this irreversible command" + ], + "usage": "hf 15 passprotectafi [-hc] -p " + }, + "hf 15 passprotecteas": { + "command": "hf 15 passprotecteas", + "description": "Password protect EAS. Cannot be undone.", + "notes": [ + "hf 15 passprotecteas -p 00000000 -c" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-p, --password EAS/AFI password, 8 hex bytes", + "-c, --confirm confirm the execution of this irreversible command" + ], + "usage": "hf 15 passprotecteas [-hc] -p " + }, "hf 15 raw": { "command": "hf 15 raw", "description": "Sends raw bytes over ISO-15693 to card", @@ -1776,8 +1804,34 @@ ], "usage": "hf 15 sim [-h] -u <8b hex> [-b ]" }, - "hf 15 slixdisable": { - "command": "hf 15 slixdisable", + "hf 15 slixeasdisable": { + "command": "hf 15 slixeasdisable", + "description": "Disable EAS mode on SLIX ISO-15693 tag", + "notes": [ + "hf 15 slixeasdisable -p 0F0F0F0F" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-p, --pwd optional password, 8 hex bytes" + ], + "usage": "hf 15 slixeasdisable [-h] [-p ]" + }, + "hf 15 slixeasenable": { + "command": "hf 15 slixeasenable", + "description": "Enable EAS mode on SLIX ISO-15693 tag", + "notes": [ + "hf 15 slixeasenable -p 0F0F0F0F" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-p, --pwd optional password, 8 hex bytes" + ], + "usage": "hf 15 slixeasenable [-h] [-p ]" + }, + "hf 15 slixprivacydisable": { + "command": "hf 15 slixprivacydisable", "description": "Disable privacy mode on SLIX ISO-15693 tag", "notes": [ "hf 15 slixdisable -p 0F0F0F0F" @@ -1787,7 +1841,35 @@ "-h, --help This help", "-p, --pwd password, 8 hex bytes" ], - "usage": "hf 15 slixdisable [-h] -p " + "usage": "hf 15 slixprivacydisable [-h] -p " + }, + "hf 15 slixprivacyenable": { + "command": "hf 15 slixprivacyenable", + "description": "Enable privacy mode on SLIX ISO-15693 tag", + "notes": [ + "hf 15 slixenable -p 0F0F0F0F" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-p, --pwd password, 8 hex bytes" + ], + "usage": "hf 15 slixprivacyenable [-h] -p " + }, + "hf 15 slixwritepwd": { + "command": "hf 15 slixwritepwd", + "description": "Write a password on a SLIX family ISO-15693 tag", + "notes": [ + "hf 15 slixwritepwd -t READ -o 00000000 -n 12131415" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-t, --type which password field to write to (some tags do not support all password types)", + "-o, --old old password (if present), 8 hex bytes", + "-n, --new new password, 8 hex bytes" + ], + "usage": "hf 15 slixwritepwd [-h] -t [-o ] -n " }, "hf 15 sniff": { "command": "hf 15 sniff", @@ -1827,19 +1909,16 @@ "description": "Write AFI on card", "notes": [ "hf 15 writeafi -* --afi 12", - "hf 15 writeafi -u E011223344556677 --afi 12" + "hf 15 writeafi -u E011223344556677 --afi 12 -p 0F0F0F0F" ], "offline": false, "options": [ "-h, --help This help", "-u, --uid full UID, 8 bytes", - "--ua unaddressed mode", - "-* scan for tag", - "-2 use slower '1 out of 256' mode", - "-o, --opt set OPTION Flag (needed for TI)", - "--afi AFI number (0-255)" + "--afi AFI number (0-255)", + "-p, --pwd optional AFI/EAS password" ], - "usage": "hf 15 writeafi [-h*2o] [-u ] [--ua] --afi " + "usage": "hf 15 writeafi [-h] [-u ] --afi [-p ]" }, "hf 15 writedsfid": { "command": "hf 15 writedsfid", @@ -11408,7 +11487,7 @@ }, "script help": { "command": "script help", - "description": "This is a feature to run Lua/Cmd/Python scripts. You can place scripts within the luascripts/cmdscripts/pyscripts folders. --------------------------------------------------------------------------------------- script list available offline: yes", + "description": "This is a feature to run Lua/Cmd scripts. You can place scripts within the luascripts/cmdscripts folders. --------------------------------------------------------------------------------------- script list available offline: yes", "notes": [], "offline": true, "options": [], @@ -11803,8 +11882,8 @@ } }, "metadata": { - "commands_extracted": 742, + "commands_extracted": 748, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-01-27T01:57:37" + "extracted_on": "2023-01-29T03:58:53" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 79499915b..382c98b58 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -236,7 +236,13 @@ Check column "offline" for their availability. |`hf 15 esave `|N |`Save emulator memory into image file` |`hf 15 eview `|N |`View emulator memory` |`hf 15 sim `|N |`Fake an ISO-15693 tag` -|`hf 15 slixdisable `|N |`Disable privacy mode on SLIX ISO-15693 tag` +|`hf 15 slixwritepwd `|N |`Writes a password on a SLIX ISO-15693 tag` +|`hf 15 slixeasdisable `|N |`Disable EAS mode on SLIX ISO-15693 tag` +|`hf 15 slixeasenable `|N |`Enable EAS mode on SLIX ISO-15693 tag` +|`hf 15 slixprivacydisable`|N |`Disable privacy mode on SLIX ISO-15693 tag` +|`hf 15 slixprivacyenable`|N |`Enable privacy mode on SLIX ISO-15693 tag` +|`hf 15 passprotectafi `|N |`Password protect AFI - Cannot be undone` +|`hf 15 passprotecteas `|N |`Password protect EAS - Cannot be undone` |`hf 15 wrbl `|N |`Write a block` |`hf 15 findafi `|N |`Brute force AFI of an ISO-15693 tag` |`hf 15 writeafi `|N |`Writes the AFI on an ISO-15693 tag` From cd96fbfcc9daaeb4d154e962c348ef456f7a90ce Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 06:35:31 +0100 Subject: [PATCH 570/759] text --- client/src/proxmark3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 9ca38a2a1..378b9f0dc 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -41,7 +41,7 @@ static int mainret = PM3_ESOFT; #ifndef LIBPM3 #define BANNERMSG1 "" -#define BANNERMSG2 " [ :snowflake: ]" +#define BANNERMSG2 " [ :coffee: ]" #define BANNERMSG3 "" typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode; From 2633a54e11670a0144bcf11ce308b3eba644773c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 29 Jan 2023 15:16:38 +0100 Subject: [PATCH 571/759] build_all_firmwares.sh: skip NFCBARCODE support for 256kb builds --- tools/build_all_firmwares.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build_all_firmwares.sh b/tools/build_all_firmwares.sh index b76f7a45a..a0253e789 100755 --- a/tools/build_all_firmwares.sh +++ b/tools/build_all_firmwares.sh @@ -22,7 +22,7 @@ echo "Destination: ${DEST:=firmware}" echo "Produce stats?: ${STATS:=false}" # Which parts to skip for the 256kb version? -SKIPS256="SKIP_HITAG=1 SKIP_LEGICRF=1 SKIP_FELICA=1 SKIP_EM4x50=1 SKIP_ISO14443b=1" +SKIPS256="SKIP_HITAG=1 SKIP_LEGICRF=1 SKIP_FELICA=1 SKIP_EM4x50=1 SKIP_ISO14443b=1 SKIP_NFCBARCODE=1" make $MKFLAGS bootrom || exit 1 chmod 644 bootrom/obj/bootrom.elf From db6a0ab5efb90f76c7933b29901e03247331932c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 18:02:45 +0100 Subject: [PATCH 572/759] coverity fix #40581, #404580, #40579... --- client/src/cmdhf15.c | 46 +++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 9c7f1528d..5a58162bc 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -1378,15 +1378,16 @@ static int CmdHF15WriteAfi(const char *Cmd) { payload.afi = arg_get_int_def(ctx, 2, 0); int pwdlen; - CLIGetHexWithReturn(ctx, 3, payload.pwd, &pwdlen); CLIParserFree(ctx); + payload.use_pwd = false; if (pwdlen == 4) { payload.use_pwd = true; } + payload.use_uid = false; if (uidlen == 8) { payload.use_uid = true; } @@ -2386,13 +2387,12 @@ static int CmdHF15SlixEASEnable(const char *Cmd) { int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen); if ((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) { PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); + CLIParserFree(ctx); return PM3_ESOFT; } - //CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); CLIParserFree(ctx); - if (pwdlen > 0) { PrintAndLogEx(INFO, "Trying to enable EAS mode using password " _GREEN_("%s") , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) @@ -2627,12 +2627,11 @@ static int CmdHF15SlixWritePassword(const char *Cmd) { } PACKED payload; int pwdlen = 0; - - CLIGetHexWithReturn(ctx, 2, payload.old_pwd, &pwdlen); if (pwdlen > 0 && pwdlen != 4) { PrintAndLogEx(WARNING, "old password must be 4 hex bytes if provided"); + CLIParserFree(ctx); return PM3_ESOFT; } @@ -2640,6 +2639,7 @@ static int CmdHF15SlixWritePassword(const char *Cmd) { if (pwdlen != 4) { PrintAndLogEx(WARNING, "new password must be 4 hex bytes"); + CLIParserFree(ctx); return PM3_ESOFT; } @@ -2671,7 +2671,6 @@ static int CmdHF15SlixWritePassword(const char *Cmd) { CLIParserFree(ctx); - PrintAndLogEx(INFO, "Trying to write " _YELLOW_("%s") " as " _YELLOW_("%s") " password" , sprint_hex_inrow(payload.new_pwd, sizeof(payload.new_pwd)), value); @@ -2705,13 +2704,14 @@ static int CmdHF15AFIPassProtect(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 15 passprotectafi", - "Password protect AFI. Cannot be undone.", - "hf 15 passprotectafi -p 00000000 -c"); + "This command enables the password protect of AFI.\n" + "*** OBS! This action can not be undone! ***", + "hf 15 passprotectafi -p 00000000 --force"); void *argtable[] = { arg_param_begin, - arg_str1("p", "password", "", "EAS/AFI password, 8 hex bytes"), - arg_lit0("c", "confirm", "confirm the execution of this irreversible command"), + arg_str1("p", "pwd", "", "EAS/AFI password, 8 hex bytes"), + arg_lit0(NULL, "force", "Force execution of command (irreversible) "), arg_param_end }; @@ -2724,20 +2724,20 @@ static int CmdHF15AFIPassProtect(const char *Cmd) { CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); - bool confirmation = arg_get_lit(ctx, 2); + bool force = arg_get_lit(ctx, 2); + CLIParserFree(ctx); if (pwdlen != 4) { PrintAndLogEx(WARNING, "password must be 4 hex bytes"); return PM3_ESOFT; } - if (confirmation == 0) { - PrintAndLogEx(WARNING, "This irreversible command must be confirmed with the -c flag"); + if (force == false) { + PrintAndLogEx(WARNING, "Use `--force` flag to override. OBS! Irreversable command"); return PM3_ESOFT; } - - PrintAndLogEx(INFO, "Trying to enable AFI password protection"); + PrintAndLogEx(INFO, "Trying to enable AFI password protection..."); PacketResponseNG resp; clearCommandBuffer(); @@ -2770,13 +2770,14 @@ static int CmdHF15EASPassProtect(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 15 passprotecteas", - "Password protect EAS. Cannot be undone.", - "hf 15 passprotecteas -p 00000000 -c"); + "This command enables the password protect of EAS.\n" + "*** OBS! This action can not be undone! ***", + "hf 15 passprotecteas -p 00000000 --force"); void *argtable[] = { arg_param_begin, arg_str1("p", "password", "", "EAS/AFI password, 8 hex bytes"), - arg_lit0("c", "confirm", "confirm the execution of this irreversible command"), + arg_lit0(NULL, "force", "Force execution of command (irreversible) "), arg_param_end }; @@ -2789,19 +2790,20 @@ static int CmdHF15EASPassProtect(const char *Cmd) { CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); - bool confirmation = arg_get_lit(ctx, 2); + bool force = arg_get_lit(ctx, 2); + CLIParserFree(ctx); if (pwdlen != 4) { PrintAndLogEx(WARNING, "password must be 4 hex bytes"); return PM3_ESOFT; } - if (confirmation == 0) { - PrintAndLogEx(WARNING, "This irreversible command must be confirmed with the -c flag"); + if (force == false) { + PrintAndLogEx(WARNING, "Use `--force` flag to override. OBS! Irreversable command"); return PM3_ESOFT; } - PrintAndLogEx(INFO, "Trying to enable EAS password protection"); + PrintAndLogEx(INFO, "Trying to enable EAS password protection..."); PacketResponseNG resp; clearCommandBuffer(); From 30538c20ae5a839a0869e161ee60cd0e1e9b94b6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 18:05:47 +0100 Subject: [PATCH 573/759] coverity fix #404575 --- client/src/cmdhf15.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 5a58162bc..92e42d717 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -2447,6 +2447,7 @@ static int CmdHF15SlixEASDisable(const char *Cmd) { arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); + struct { uint8_t pwd[4]; bool usepwd; @@ -2455,15 +2456,13 @@ static int CmdHF15SlixEASDisable(const char *Cmd) { int pwdlen = 0; int ret_pwdparse = CLIParamHexToBuf(arg_get_str(ctx, 1), payload.pwd, 4, &pwdlen); + CLIParserFree(ctx); + if ((pwdlen > 0 && pwdlen != 4) || ret_pwdparse != 0) { PrintAndLogEx(WARNING, "password must be 4 hex bytes if provided"); return PM3_ESOFT; } - //CLIGetHexWithReturn(ctx, 1, payload.pwd, &pwdlen); - CLIParserFree(ctx); - - if (pwdlen > 0) { PrintAndLogEx(INFO, "Trying to disable EAS mode using password " _GREEN_("%s") , sprint_hex_inrow(payload.pwd, sizeof(payload.pwd)) @@ -2776,7 +2775,7 @@ static int CmdHF15EASPassProtect(const char *Cmd) { void *argtable[] = { arg_param_begin, - arg_str1("p", "password", "", "EAS/AFI password, 8 hex bytes"), + arg_str1("p", "pwd", "", "EAS/AFI password, 8 hex bytes"), arg_lit0(NULL, "force", "Force execution of command (irreversible) "), arg_param_end }; From b217b4e39d0bed09f3600c59f3db48d514a1674c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 18:07:59 +0100 Subject: [PATCH 574/759] fix coverity #404576 --- client/src/cmdhf14a.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index d0ba31cd0..2c6bc740a 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1460,8 +1460,9 @@ static int CmdHF14AChaining(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 14a chaining", "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", + "hf 14a chaining -> show chaining enable/disable state\n" "hf 14a chaining --off -> disable chaining\n" - "hf 14a chaining -> show chaining enable/disable state\n"); + ); void *argtable[] = { arg_param_begin, @@ -1473,6 +1474,7 @@ static int CmdHF14AChaining(const char *Cmd) { bool on = arg_get_lit(ctx, 1); bool off = arg_get_lit(ctx, 2); + CLIParserFree(ctx); if ((on + off) > 1) { PrintAndLogEx(INFO, "Select only one option"); @@ -1485,8 +1487,6 @@ static int CmdHF14AChaining(const char *Cmd) { if (off) Set_apdu_in_framing(false); - CLIParserFree(ctx); - PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", g_apdu_in_framing_enable ? "enabled" : "disabled"); return PM3_SUCCESS; } From b24d7736c59157640edb036e0dcf132b49acba53 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 18:14:49 +0100 Subject: [PATCH 575/759] fix coverity #322661 --- client/src/cmdflashmem.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/src/cmdflashmem.c b/client/src/cmdflashmem.c index f01531d55..7bbdf74c9 100644 --- a/client/src/cmdflashmem.c +++ b/client/src/cmdflashmem.c @@ -641,6 +641,10 @@ static int CmdFlashMemInfo(const char *Cmd) { // Verify (public key) bool is_verified = (mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device) == 0); + if (got_private == false) { + mbedtls_rsa_free(rsa); + } + mbedtls_pk_free(&pkctx); PrintAndLogEx(NORMAL, ""); From 568e35ca84f54a831a66eba1bd42b61cfe6d314d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 18:32:15 +0100 Subject: [PATCH 576/759] style --- CHANGELOG.md | 12 ++++++++---- client/src/cmdhf14a.c | 2 +- client/src/cmdhf15.c | 6 +++--- doc/commands.json | 26 +++++++++++++------------- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 936e087f5..285cd6bf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ 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] + +## [Nitride][2023-01-29] + - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) + - Fixed some coverity fixes (@iceman1001) + - Fixed `make accessrights` on Fedora (@mooey5775) + - Fixed `hf mfu info` - can now identify the 50 pF version of NTAG 210u(micro) (@mjacksn) + - Added `hf 15` sub-commands for controlling EAS, AFI, privacy mode, and the setting of passwords on SLIX tags (@mjacksn) - Added new magic gen4 cards command in docs (@McEloff) - Added `hf tesla info` - intital information command to read TESLA cards (@iceman1001) - Changed `hf emrtd info` - looking for lower case .bin extensions (@iceman1001) @@ -41,9 +48,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `pm3` shell script now automatically detects WSL2 with USBIPD serial ports (@iceman1001) - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - - Fixed `make accessrights` on Fedora (@mooey5775) - - Fixed `hf mfu info` - can now identify the 50 pF version of NTAG 210u(micro) (@mjacksn) - - Added `hf 15` sub-commands for controlling EAS, AFI, privacy mode, and the setting of passwords on SLIX tags (@mjacksn) ## [Radium.4.15864][2022-10-29] @@ -1373,4 +1377,4 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - iClass functionality: full simulation of iclass tags, so tags can be simulated with data (not only CSN). Not yet support for write/update, but readers do not seem to enforce update. (@holiman). - iClass decryption. Proxmark can now decrypt data on an iclass tag, but requires you to have the HID decryption key locally on your computer, as this is not bundled with the sourcecode. - `hf 15 info` can detect NTAG 5 tags - - `hf 15 info` include an EAS status check on more of the icode tags which support EAS (SLI, SLIX, SLIX-L, and SLIX-S) \ No newline at end of file + - `hf 15 info` include an EAS status check on more of the icode tags which support EAS (SLI, SLIX, SLIX-L, and SLIX-S) diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 2c6bc740a..e1453be3b 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -1462,7 +1462,7 @@ static int CmdHF14AChaining(const char *Cmd) { "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", "hf 14a chaining -> show chaining enable/disable state\n" "hf 14a chaining --off -> disable chaining\n" - ); + ); void *argtable[] = { arg_param_begin, diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 92e42d717..3b92e309b 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -2769,9 +2769,9 @@ static int CmdHF15EASPassProtect(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 15 passprotecteas", - "This command enables the password protect of EAS.\n" - "*** OBS! This action can not be undone! ***", - "hf 15 passprotecteas -p 00000000 --force"); + "This command enables the password protect of EAS.\n" + "*** OBS! This action can not be undone! ***", + "hf 15 passprotecteas -p 00000000 --force"); void *argtable[] = { arg_param_begin, diff --git a/doc/commands.json b/doc/commands.json index 8d028d9e9..6f18da380 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -1101,8 +1101,8 @@ "command": "hf 14a chaining", "description": "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", "notes": [ - "hf 14a chaining --off -> disable chaining", - "hf 14a chaining -> show chaining enable/disable state" + "hf 14a chaining -> show chaining enable/disable state", + "hf 14a chaining --off -> disable chaining" ], "offline": false, "options": [ @@ -1658,31 +1658,31 @@ }, "hf 15 passprotectafi": { "command": "hf 15 passprotectafi", - "description": "Password protect AFI. Cannot be undone.", + "description": "This command enables the password protect of AFI. *** OBS! This action can not be undone! ***", "notes": [ - "hf 15 passprotectafi -p 00000000 -c" + "hf 15 passprotectafi -p 00000000 --force" ], "offline": false, "options": [ "-h, --help This help", - "-p, --password EAS/AFI password, 8 hex bytes", - "-c, --confirm confirm the execution of this irreversible command" + "-p, --pwd EAS/AFI password, 8 hex bytes", + "--force Force execution of command (irreversible)" ], - "usage": "hf 15 passprotectafi [-hc] -p " + "usage": "hf 15 passprotectafi [-h] -p [--force]" }, "hf 15 passprotecteas": { "command": "hf 15 passprotecteas", - "description": "Password protect EAS. Cannot be undone.", + "description": "This command enables the password protect of EAS. *** OBS! This action can not be undone! ***", "notes": [ - "hf 15 passprotecteas -p 00000000 -c" + "hf 15 passprotecteas -p 00000000 --force" ], "offline": false, "options": [ "-h, --help This help", - "-p, --password EAS/AFI password, 8 hex bytes", - "-c, --confirm confirm the execution of this irreversible command" + "-p, --pwd EAS/AFI password, 8 hex bytes", + "--force Force execution of command (irreversible)" ], - "usage": "hf 15 passprotecteas [-hc] -p " + "usage": "hf 15 passprotecteas [-h] -p [--force]" }, "hf 15 raw": { "command": "hf 15 raw", @@ -11884,6 +11884,6 @@ "metadata": { "commands_extracted": 748, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-01-29T03:58:53" + "extracted_on": "2023-01-29T17:29:14" } } \ No newline at end of file From d8b286e5f50219642f6f97a1ec373861b542758b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 18:31:39 +0100 Subject: [PATCH 577/759] adapt to fit GENRIC 256kb firmware images --- tools/build_all_firmwares.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/build_all_firmwares.sh b/tools/build_all_firmwares.sh index a0253e789..644438032 100755 --- a/tools/build_all_firmwares.sh +++ b/tools/build_all_firmwares.sh @@ -22,7 +22,8 @@ echo "Destination: ${DEST:=firmware}" echo "Produce stats?: ${STATS:=false}" # Which parts to skip for the 256kb version? -SKIPS256="SKIP_HITAG=1 SKIP_LEGICRF=1 SKIP_FELICA=1 SKIP_EM4x50=1 SKIP_ISO14443b=1 SKIP_NFCBARCODE=1" +SKIPS256="SKIP_HITAG=1 SKIP_LEGICRF=1 SKIP_FELICA=1 SKIP_EM4x50=1 SKIP_ISO14443b=1 SKIP_NFCBARCODE=1 SKIP_ZX8211=1" + make $MKFLAGS bootrom || exit 1 chmod 644 bootrom/obj/bootrom.elf From 715ae09e7e536e859212ebfe178042be4afe6467 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 18:37:28 +0100 Subject: [PATCH 578/759] fix coverity #404579 --- client/src/cmdhf15.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 3b92e309b..10d239b94 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -2606,12 +2606,13 @@ static int CmdHF15SlixEnable(const char *Cmd) { static int CmdHF15SlixWritePassword(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf 15 slixwritepwd", - "Write a password on a SLIX family ISO-15693 tag", + "Write a password on a SLIX family ISO-15693 tag.n" + "Some tags do not support all different password types.", "hf 15 slixwritepwd -t READ -o 00000000 -n 12131415"); void *argtable[] = { arg_param_begin, - arg_str1("t", "type", "", "which password field to write to (some tags do not support all password types)"), + arg_str1("t", "type", "", "which password field to write to"), arg_str0("o", "old", "", "old password (if present), 8 hex bytes"), arg_str1("n", "new", "", "new password, 8 hex bytes"), arg_param_end @@ -2645,6 +2646,7 @@ static int CmdHF15SlixWritePassword(const char *Cmd) { int vlen = 0; char value[10]; CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)value, sizeof(value), &vlen); + CLIParserFree(ctx); if (vlen > 0) { if (strcmp(value, "read") == 0) { @@ -2668,8 +2670,6 @@ static int CmdHF15SlixWritePassword(const char *Cmd) { } } - CLIParserFree(ctx); - PrintAndLogEx(INFO, "Trying to write " _YELLOW_("%s") " as " _YELLOW_("%s") " password" , sprint_hex_inrow(payload.new_pwd, sizeof(payload.new_pwd)), value); From 5ac42add1a7a590e028d1bfa30de1f0dad290cc8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 18:39:42 +0100 Subject: [PATCH 579/759] make style --- doc/commands.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/commands.json b/doc/commands.json index 6f18da380..3545a9b78 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -11884,6 +11884,6 @@ "metadata": { "commands_extracted": 748, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-01-29T17:29:14" + "extracted_on": "2023-01-29T17:39:28" } } \ No newline at end of file From bec61e9185778afdb08cd4334cc4272f1425a74f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 20:35:17 +0100 Subject: [PATCH 580/759] Release v4.16191 - Nitride --- Makefile.defs | 4 ++-- armsrc/Makefile | 2 +- bootrom/Makefile | 2 +- client/CMakeLists.txt | 4 ++-- client/Makefile | 4 ++-- client/deps/amiibo.cmake | 2 +- client/deps/cliparser.cmake | 2 +- client/deps/hardnested.cmake | 18 +++++++++--------- client/deps/jansson.cmake | 2 +- client/deps/lua.cmake | 2 +- client/deps/mbedtls.cmake | 2 +- client/deps/reveng.cmake | 2 +- client/deps/tinycbor.cmake | 2 +- client/deps/whereami.cmake | 2 +- client/src/proxmark3.c | 2 +- common/default_version_pm3.c | 27 +++++++-------------------- common_arm/Makefile.common | 2 +- 17 files changed, 34 insertions(+), 47 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index bcbbaa67e..b203ebeae 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -104,8 +104,8 @@ ifeq ($(DEBUG),1) DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe DEFLDFLAGS = else - DEFCXXFLAGS = -Wall -Werror -O3 -pipe - DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe + DEFCXXFLAGS = -Wall -O3 -pipe + DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe DEFLDFLAGS = endif diff --git a/armsrc/Makefile b/armsrc/Makefile index 5024aa1de..5c3bb03dc 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -187,7 +187,7 @@ showinfo: # version_pm3.c should be remade on every time fullimage.stage1.elf should be remade version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE $(info [-] GEN $@) - $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(info [-] GEN $@) diff --git a/bootrom/Makefile b/bootrom/Makefile index edb0cc990..8a8a6d360 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -50,7 +50,7 @@ OBJS = $(OBJDIR)/bootrom.s19 # version_pm3.c should be remade on every compilation version_pm3.c: default_version_pm3.c .FORCE $(info [=] GEN $@) - $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ all: showinfo $(OBJS) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 5bd3ebddd..6836e9114 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -364,7 +364,7 @@ set (TARGET_SOURCES add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c - COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c + COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c ) @@ -565,7 +565,7 @@ add_executable(proxmark3 ${ADDITIONAL_SRC} ) -target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) +target_compile_options(proxmark3 PUBLIC -Wall -O3) if (EMBED_READLINE) if (NOT SKIPREADLINE EQUAL 1) add_dependencies(proxmark3 ncurses readline) diff --git a/client/Makefile b/client/Makefile index b08eb0acb..218d19d08 100644 --- a/client/Makefile +++ b/client/Makefile @@ -408,7 +408,7 @@ endif PM3CFLAGS += -DHAVE_SNPRINTF -CXXFLAGS ?= -Wall -Werror -O3 +CXXFLAGS ?= -Wall -O3 CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES) PM3CXXFLAGS = $(CXXFLAGS) @@ -902,7 +902,7 @@ src/pm3_pywrap.c: pm3.i # version_pm3.c should be remade on every compilation src/version_pm3.c: default_version_pm3.c .FORCE $(info [=] GEN $@) - $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ + $(Q)$(CP) $< $@ # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) diff --git a/client/deps/amiibo.cmake b/client/deps/amiibo.cmake index c946c0682..8c524c170 100644 --- a/client/deps/amiibo.cmake +++ b/client/deps/amiibo.cmake @@ -19,7 +19,7 @@ target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE m pm3rrg_rdv4_mbedtls) -target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool diff --git a/client/deps/cliparser.cmake b/client/deps/cliparser.cmake index fccae33b7..a85cc2374 100644 --- a/client/deps/cliparser.cmake +++ b/client/deps/cliparser.cmake @@ -9,5 +9,5 @@ target_include_directories(pm3rrg_rdv4_cliparser PRIVATE ../../include ../src) target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser) -target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index 524d4c939..290415173 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -2,7 +2,7 @@ add_library(pm3rrg_rdv4_hardnested_nosimd OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) -target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE @@ -32,7 +32,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE -mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -47,7 +47,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE -mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -62,7 +62,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE -mmmx -msse2 -mavx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -77,7 +77,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -92,7 +92,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mavx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -116,7 +116,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM64_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE @@ -134,7 +134,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM32_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE -mfpu=neon) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -155,7 +155,7 @@ add_library(pm3rrg_rdv4_hardnested STATIC hardnested/hardnested_bruteforce.c $ ${SIMD_TARGETS}) -target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested PRIVATE ../../common diff --git a/client/deps/jansson.cmake b/client/deps/jansson.cmake index c91a47047..42c701d5e 100644 --- a/client/deps/jansson.cmake +++ b/client/deps/jansson.cmake @@ -14,5 +14,5 @@ add_library(pm3rrg_rdv4_jansson STATIC target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H) target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson) -target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Werror -Wno-unused-function -O3) +target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Wno-unused-function -O3) set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/lua.cmake b/client/deps/lua.cmake index 12870342e..5cf33d724 100644 --- a/client/deps/lua.cmake +++ b/client/deps/lua.cmake @@ -52,5 +52,5 @@ if (NOT MINGW) endif (NOT MINGW) target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua) -target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/mbedtls.cmake b/client/deps/mbedtls.cmake index 40929e1ea..c726ddeba 100644 --- a/client/deps/mbedtls.cmake +++ b/client/deps/mbedtls.cmake @@ -44,5 +44,5 @@ add_library(pm3rrg_rdv4_mbedtls STATIC target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common) target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls) -target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/reveng.cmake b/client/deps/reveng.cmake index d7e3cfd8a..1040730f1 100644 --- a/client/deps/reveng.cmake +++ b/client/deps/reveng.cmake @@ -13,5 +13,5 @@ target_include_directories(pm3rrg_rdv4_reveng PRIVATE ../src ../../include) target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng) -target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/tinycbor.cmake b/client/deps/tinycbor.cmake index 5a6abda25..c74618149 100644 --- a/client/deps/tinycbor.cmake +++ b/client/deps/tinycbor.cmake @@ -11,5 +11,5 @@ add_library(pm3rrg_rdv4_tinycbor STATIC target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor) # Strange errors on Mingw when compiling with -O3 -target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -Werror -O2) +target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -O2) set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/whereami.cmake b/client/deps/whereami.cmake index d2d6a5b2a..721873066 100644 --- a/client/deps/whereami.cmake +++ b/client/deps/whereami.cmake @@ -2,5 +2,5 @@ add_library(pm3rrg_rdv4_whereami STATIC whereami/whereami.c) target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED) target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami) -target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -Werror -O3) +target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -O3) set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 378b9f0dc..6c77bfad3 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -42,7 +42,7 @@ static int mainret = PM3_ESOFT; #ifndef LIBPM3 #define BANNERMSG1 "" #define BANNERMSG2 " [ :coffee: ]" -#define BANNERMSG3 "" +#define BANNERMSG3 "Release v4.16191 - Nitride" typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode; diff --git a/common/default_version_pm3.c b/common/default_version_pm3.c index 46eac57c9..26ba654b1 100644 --- a/common/default_version_pm3.c +++ b/common/default_version_pm3.c @@ -1,20 +1,5 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- #include "common.h" -/* This is the default version_pm3.c file that Makefile.common falls back to if sh is not available */ +/* Generated file, do not edit */ #ifndef ON_DEVICE #define SECTVERSINFO #else @@ -23,8 +8,10 @@ const struct version_information_t SECTVERSINFO g_version_information = { VERSION_INFORMATION_MAGIC, - 1, /* version 1 */ - 0, /* version information not present */ - 2, /* cleanliness couldn't be determined */ - /* Remaining fields: zero */ + 1, + 1, + 1, + "Iceman/master/v4.16191", + "2023-01-29 20:35:17", + "3545f4f98" }; diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index 99f4d9ecd..e40d998a6 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -49,7 +49,7 @@ VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/ INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h ARMCFLAGS = -mthumb-interwork -fno-builtin -DEFCFLAGS = -Wall -Werror -Os -pedantic -fstrict-aliasing -pipe +DEFCFLAGS = -Wall -Os -pedantic -fstrict-aliasing -pipe # Some more warnings we want as errors: DEFCFLAGS += -Wbad-function-cast -Wchar-subscripts -Wundef -Wunused -Wuninitialized -Wpointer-arith -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits From 2bd404b496109857d8bb40668924974f807ce62b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 20:35:17 +0100 Subject: [PATCH 581/759] Revert "Release v4.16191 - Nitride" This reverts commit bec61e9185778afdb08cd4334cc4272f1425a74f. --- Makefile.defs | 4 ++-- armsrc/Makefile | 2 +- bootrom/Makefile | 2 +- client/CMakeLists.txt | 4 ++-- client/Makefile | 4 ++-- client/deps/amiibo.cmake | 2 +- client/deps/cliparser.cmake | 2 +- client/deps/hardnested.cmake | 18 +++++++++--------- client/deps/jansson.cmake | 2 +- client/deps/lua.cmake | 2 +- client/deps/mbedtls.cmake | 2 +- client/deps/reveng.cmake | 2 +- client/deps/tinycbor.cmake | 2 +- client/deps/whereami.cmake | 2 +- client/src/proxmark3.c | 2 +- common/default_version_pm3.c | 27 ++++++++++++++++++++------- common_arm/Makefile.common | 2 +- 17 files changed, 47 insertions(+), 34 deletions(-) diff --git a/Makefile.defs b/Makefile.defs index b203ebeae..bcbbaa67e 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -104,8 +104,8 @@ ifeq ($(DEBUG),1) DEFCFLAGS = -g -O0 -fstrict-aliasing -pipe DEFLDFLAGS = else - DEFCXXFLAGS = -Wall -O3 -pipe - DEFCFLAGS = -Wall -O3 -fstrict-aliasing -pipe + DEFCXXFLAGS = -Wall -Werror -O3 -pipe + DEFCFLAGS = -Wall -Werror -O3 -fstrict-aliasing -pipe DEFLDFLAGS = endif diff --git a/armsrc/Makefile b/armsrc/Makefile index 5c3bb03dc..5024aa1de 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -187,7 +187,7 @@ showinfo: # version_pm3.c should be remade on every time fullimage.stage1.elf should be remade version_pm3.c: default_version_pm3.c $(OBJDIR)/fpga_version_info.o $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ) .FORCE $(info [-] GEN $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR) $(info [-] GEN $@) diff --git a/bootrom/Makefile b/bootrom/Makefile index 8a8a6d360..edb0cc990 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -50,7 +50,7 @@ OBJS = $(OBJDIR)/bootrom.s19 # version_pm3.c should be remade on every compilation version_pm3.c: default_version_pm3.c .FORCE $(info [=] GEN $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(PERL) ../tools/mkversion.pl > $@ || $(CP) $< $@ all: showinfo $(OBJS) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 6836e9114..5bd3ebddd 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -364,7 +364,7 @@ set (TARGET_SOURCES add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/version_pm3.c - COMMAND ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c + COMMAND sh ${PM3_ROOT}/tools/mkversion.sh > ${CMAKE_BINARY_DIR}/version_pm3.c || ${CMAKE_COMMAND} -E copy ${PM3_ROOT}/common/default_version_pm3.c ${CMAKE_BINARY_DIR}/version_pm3.c DEPENDS ${PM3_ROOT}/common/default_version_pm3.c ) @@ -565,7 +565,7 @@ add_executable(proxmark3 ${ADDITIONAL_SRC} ) -target_compile_options(proxmark3 PUBLIC -Wall -O3) +target_compile_options(proxmark3 PUBLIC -Wall -Werror -O3) if (EMBED_READLINE) if (NOT SKIPREADLINE EQUAL 1) add_dependencies(proxmark3 ncurses readline) diff --git a/client/Makefile b/client/Makefile index 218d19d08..b08eb0acb 100644 --- a/client/Makefile +++ b/client/Makefile @@ -408,7 +408,7 @@ endif PM3CFLAGS += -DHAVE_SNPRINTF -CXXFLAGS ?= -Wall -O3 +CXXFLAGS ?= -Wall -Werror -O3 CXXFLAGS += $(MYDEFS) $(MYCXXFLAGS) $(MYINCLUDES) PM3CXXFLAGS = $(CXXFLAGS) @@ -902,7 +902,7 @@ src/pm3_pywrap.c: pm3.i # version_pm3.c should be remade on every compilation src/version_pm3.c: default_version_pm3.c .FORCE $(info [=] GEN $@) - $(Q)$(CP) $< $@ + $(Q)$(SH) ../tools/mkversion.sh > $@ || $(CP) $< $@ # easy printing of MAKE VARIABLES print-%: ; @echo $* = $($*) diff --git a/client/deps/amiibo.cmake b/client/deps/amiibo.cmake index 8c524c170..c946c0682 100644 --- a/client/deps/amiibo.cmake +++ b/client/deps/amiibo.cmake @@ -19,7 +19,7 @@ target_link_libraries(pm3rrg_rdv4_amiibo PRIVATE m pm3rrg_rdv4_mbedtls) -target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_amiibo PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_amiibo PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_amiibo PRIVATE amiitool diff --git a/client/deps/cliparser.cmake b/client/deps/cliparser.cmake index a85cc2374..fccae33b7 100644 --- a/client/deps/cliparser.cmake +++ b/client/deps/cliparser.cmake @@ -9,5 +9,5 @@ target_include_directories(pm3rrg_rdv4_cliparser PRIVATE ../../include ../src) target_include_directories(pm3rrg_rdv4_cliparser INTERFACE cliparser) -target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_cliparser PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_cliparser PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index 290415173..524d4c939 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -2,7 +2,7 @@ add_library(pm3rrg_rdv4_hardnested_nosimd OBJECT hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) -target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_hardnested_nosimd PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested_nosimd PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_nosimd PRIVATE @@ -32,7 +32,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_mmx PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_mmx BEFORE PRIVATE -mmmx -mno-sse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_mmx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -47,7 +47,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_sse2 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_sse2 BEFORE PRIVATE -mmmx -msse2 -mno-avx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_sse2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -62,7 +62,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx BEFORE PRIVATE -mmmx -msse2 -mavx -mno-avx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -77,7 +77,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx2 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx2 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mno-avx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -92,7 +92,7 @@ if ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST X86_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_avx512 PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_avx512 BEFORE PRIVATE -mmmx -msse2 -mavx -mavx2 -mavx512f) set_property(TARGET pm3rrg_rdv4_hardnested_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -116,7 +116,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM64_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested_neon PRIVATE @@ -134,7 +134,7 @@ elseif ("${CMAKE_SYSTEM_PROCESSOR}" IN_LIST ARM32_CPUS) hardnested/hardnested_bf_core.c hardnested/hardnested_bitarray_core.c) - target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -O3) + target_compile_options(pm3rrg_rdv4_hardnested_neon PRIVATE -Wall -Werror -O3) target_compile_options(pm3rrg_rdv4_hardnested_neon BEFORE PRIVATE -mfpu=neon) set_property(TARGET pm3rrg_rdv4_hardnested_neon PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -155,7 +155,7 @@ add_library(pm3rrg_rdv4_hardnested STATIC hardnested/hardnested_bruteforce.c $ ${SIMD_TARGETS}) -target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_hardnested PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_hardnested PROPERTY POSITION_INDEPENDENT_CODE ON) target_include_directories(pm3rrg_rdv4_hardnested PRIVATE ../../common diff --git a/client/deps/jansson.cmake b/client/deps/jansson.cmake index 42c701d5e..c91a47047 100644 --- a/client/deps/jansson.cmake +++ b/client/deps/jansson.cmake @@ -14,5 +14,5 @@ add_library(pm3rrg_rdv4_jansson STATIC target_compile_definitions(pm3rrg_rdv4_jansson PRIVATE HAVE_STDINT_H) target_include_directories(pm3rrg_rdv4_jansson INTERFACE jansson) -target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Wno-unused-function -O3) +target_compile_options(pm3rrg_rdv4_jansson PRIVATE -Wall -Werror -Wno-unused-function -O3) set_property(TARGET pm3rrg_rdv4_jansson PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/lua.cmake b/client/deps/lua.cmake index 5cf33d724..12870342e 100644 --- a/client/deps/lua.cmake +++ b/client/deps/lua.cmake @@ -52,5 +52,5 @@ if (NOT MINGW) endif (NOT MINGW) target_include_directories(pm3rrg_rdv4_lua INTERFACE liblua) -target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_lua PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_lua PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/mbedtls.cmake b/client/deps/mbedtls.cmake index c726ddeba..40929e1ea 100644 --- a/client/deps/mbedtls.cmake +++ b/client/deps/mbedtls.cmake @@ -44,5 +44,5 @@ add_library(pm3rrg_rdv4_mbedtls STATIC target_include_directories(pm3rrg_rdv4_mbedtls PRIVATE ../../common) target_include_directories(pm3rrg_rdv4_mbedtls INTERFACE ../../common/mbedtls) -target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_mbedtls PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_mbedtls PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/reveng.cmake b/client/deps/reveng.cmake index 1040730f1..d7e3cfd8a 100644 --- a/client/deps/reveng.cmake +++ b/client/deps/reveng.cmake @@ -13,5 +13,5 @@ target_include_directories(pm3rrg_rdv4_reveng PRIVATE ../src ../../include) target_include_directories(pm3rrg_rdv4_reveng INTERFACE reveng) -target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_reveng PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_reveng PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/tinycbor.cmake b/client/deps/tinycbor.cmake index c74618149..5a6abda25 100644 --- a/client/deps/tinycbor.cmake +++ b/client/deps/tinycbor.cmake @@ -11,5 +11,5 @@ add_library(pm3rrg_rdv4_tinycbor STATIC target_include_directories(pm3rrg_rdv4_tinycbor INTERFACE tinycbor) # Strange errors on Mingw when compiling with -O3 -target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -O2) +target_compile_options(pm3rrg_rdv4_tinycbor PRIVATE -Wall -Werror -O2) set_property(TARGET pm3rrg_rdv4_tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/deps/whereami.cmake b/client/deps/whereami.cmake index 721873066..d2d6a5b2a 100644 --- a/client/deps/whereami.cmake +++ b/client/deps/whereami.cmake @@ -2,5 +2,5 @@ add_library(pm3rrg_rdv4_whereami STATIC whereami/whereami.c) target_compile_definitions(pm3rrg_rdv4_whereami PRIVATE WAI_PM3_TUNED) target_include_directories(pm3rrg_rdv4_whereami INTERFACE whereami) -target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -O3) +target_compile_options(pm3rrg_rdv4_whereami PRIVATE -Wall -Werror -O3) set_property(TARGET pm3rrg_rdv4_whereami PROPERTY POSITION_INDEPENDENT_CODE ON) diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 6c77bfad3..378b9f0dc 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -42,7 +42,7 @@ static int mainret = PM3_ESOFT; #ifndef LIBPM3 #define BANNERMSG1 "" #define BANNERMSG2 " [ :coffee: ]" -#define BANNERMSG3 "Release v4.16191 - Nitride" +#define BANNERMSG3 "" typedef enum LogoMode { UTF8, ANSI, ASCII } LogoMode; diff --git a/common/default_version_pm3.c b/common/default_version_pm3.c index 26ba654b1..46eac57c9 100644 --- a/common/default_version_pm3.c +++ b/common/default_version_pm3.c @@ -1,5 +1,20 @@ +//----------------------------------------------------------------------------- +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- #include "common.h" -/* Generated file, do not edit */ +/* This is the default version_pm3.c file that Makefile.common falls back to if sh is not available */ #ifndef ON_DEVICE #define SECTVERSINFO #else @@ -8,10 +23,8 @@ const struct version_information_t SECTVERSINFO g_version_information = { VERSION_INFORMATION_MAGIC, - 1, - 1, - 1, - "Iceman/master/v4.16191", - "2023-01-29 20:35:17", - "3545f4f98" + 1, /* version 1 */ + 0, /* version information not present */ + 2, /* cleanliness couldn't be determined */ + /* Remaining fields: zero */ }; diff --git a/common_arm/Makefile.common b/common_arm/Makefile.common index e40d998a6..99f4d9ecd 100644 --- a/common_arm/Makefile.common +++ b/common_arm/Makefile.common @@ -49,7 +49,7 @@ VPATH = . ../common_arm ../common ../common/crapto1 ../common/mbedtls ../common/ INCLUDES = ../include/proxmark3_arm.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/pm3_cmd.h ARMCFLAGS = -mthumb-interwork -fno-builtin -DEFCFLAGS = -Wall -Os -pedantic -fstrict-aliasing -pipe +DEFCFLAGS = -Wall -Werror -Os -pedantic -fstrict-aliasing -pipe # Some more warnings we want as errors: DEFCFLAGS += -Wbad-function-cast -Wchar-subscripts -Wundef -Wunused -Wuninitialized -Wpointer-arith -Wformat -Wformat-security -Winit-self -Wmissing-include-dirs -Wnested-externs -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers -Wtype-limits From 0a5b0d0746b393ef6a888ff76cd3311e157b7a8b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 29 Jan 2023 20:38:33 +0100 Subject: [PATCH 582/759] text --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 285cd6bf7..880ca0998 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] -## [Nitride][2023-01-29] +## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) - Fixed some coverity fixes (@iceman1001) - Fixed `make accessrights` on Fedora (@mooey5775) From 8be70ea5607820a2022b3e0153fac3ea77186990 Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Mon, 30 Jan 2023 23:27:17 +0100 Subject: [PATCH 583/759] Fix minor bugs in `hf tesla info` --- client/src/cmdhftesla.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/client/src/cmdhftesla.c b/client/src/cmdhftesla.c index 58f51f4c5..940687cb4 100644 --- a/client/src/cmdhftesla.c +++ b/client/src/cmdhftesla.c @@ -147,7 +147,7 @@ static int info_hf_tesla(void) { // --------------- CERT reading ---------------- Set_apdu_in_framing(true); - for (uint8_t i = 0; i < 4; i++) { + for (uint8_t i = 0; i < 5; i++) { uint8_t aSELECT_CERT[PM3_CMD_DATA_SIZE] = {0x80, 0x06, i, 0x00, 0x00, 0x00, 0xFF}; int aSELECT_CERT_n = 7; @@ -160,7 +160,7 @@ static int info_hf_tesla(void) { sw = get_sw(response, resplen); if (sw == ISO7816_OK) { - // save CETT for later + // save CERT for later uint8_t cert[515] = {0}; memcpy(cert, response, resplen - 2); @@ -201,10 +201,21 @@ static int info_hf_tesla(void) { for (int i = 0; i < 3; i++) { PrintAndLogEx(INFO, "%d - %s", i, sprint_hex_inrow(pk[i], 65)); } - if (form_factor[1] == 1) { - PrintAndLogEx(INFO, "Form factor... %s (card)", sprint_hex_inrow(form_factor, sizeof(form_factor))); - } else if (form_factor[1] == 2) { - PrintAndLogEx(INFO, "Form factor... %s (phone app)", sprint_hex_inrow(form_factor, sizeof(form_factor))); + PrintAndLogEx(INFO, "Form factor... %s " NOLF, sprint_hex_inrow(form_factor, sizeof(form_factor))); + uint16_t form_factor_value = form_factor[0] << 8 | form_factor[1]; + switch (form_factor_value) { + case 0x0001: + PrintAndLogEx(NORMAL, "(card)"); + break; + case 0x0022: + PrintAndLogEx(NORMAL, "(fob)"); + break; + case 0x0031: + PrintAndLogEx(NORMAL, "(phone app)"); + break; + default: + PrintAndLogEx(NORMAL, "(unknown)"); + break; } if (sizeof(version) > 0) { From 032f304bf9b08d4bdff77e6940bd23ea60755aed Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 31 Jan 2023 01:03:56 -0800 Subject: [PATCH 584/759] Enable use under WSL2 w/Kali Linux distribution * Assign group ownership and permissions in udev rules * Add documentation on WSL2 installation and use --- .../Windows-WSL2-Installation-Instructions.md | 224 ++++++++++++++++++ driver/77-pm3-usb-device-blacklist.rules | 6 +- 2 files changed, 227 insertions(+), 3 deletions(-) create mode 100644 doc/md/Installation_Instructions/Windows-WSL2-Installation-Instructions.md diff --git a/doc/md/Installation_Instructions/Windows-WSL2-Installation-Instructions.md b/doc/md/Installation_Instructions/Windows-WSL2-Installation-Instructions.md new file mode 100644 index 000000000..9519b4849 --- /dev/null +++ b/doc/md/Installation_Instructions/Windows-WSL2-Installation-Instructions.md @@ -0,0 +1,224 @@ + + +# WSL2 Installation instructions + +## Table of Contents +- [WSL2 Installation instructions](#wsl2-installation-instructions) + - [Table of Contents](#table-of-contents) + - [Requirements](#requirements) + - [Install Kali Linux distribution](#install-kali-linux-distribution) + - [Driver installation (Windows 11)](#driver-installation-windows-11) + - [USBIPD hints](#usbipd-hints) + - [WSL2 / Kali Linux Installation](#wsl2--kali-linux-installation) + - [X Server Installation](#x-server-installation) + - [Clone the Iceman repository](#clone-the-iceman-repository) + - [Compile the project](#compile-the-project) + - [Install the udev rules](#install-the-udev-rules) + - [Inform udev that it really, really should work](#inform-udev-that-it-really-really-should-work) + - [Verify Device Exists](#verify-device-exists) + - [Using the client...](#using-the-client) + - [Done!](#done) + +This provides instructions on how to install, build, and use Proxmark3 +on Windows 11, using WSL2 (and Kali Linux). + +## Requirements +^[Top](#top) + +This WSL 2 method requires Windows 11 (Build 22000 or later), +WSL installed and [set to WSL2](https://learn.microsoft.com/en-us/windows/wsl/basic-commands#set-wsl-version-to-1-or-2), + +While WSL 2 does not itself support passing through USB or +serial devices, it can work by using the USB/IP open-source +project, [`usbipd-win`](https://github.com/dorssel/usbipd-win). + + +## Install Kali Linux distribution +^[Top](#top) + +Open the Windows App Store, and install Kali Linux. + +For WSL configuration, see [Manage and configure Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/wsl-config). + +Start the Kali Linux distribution at least once, to ensure it's fully installed. + +## Driver installation (Windows 11) +^[Top](#top) + +On the Windows (host) machine, install the +[latest release](https://github.com/dorssel/usbipd-win/releases) +of `usbpid-win` (typically an `.MSI` file). + +## USBIPD hints +^[Top](#top) + +This is *NOT* intended to be a full description of how to use USBIPD. +Rather, this is intended only to give a starting point, as ***the values +shown here are extremely likely to differ per machine***. + +It's presumed that you've already installed USBIPD. Plug the Proxmark +device into a USB port. Then, from a `cmd.exe` or `wt.exe` ***launched +with administrative permissions***: + +Get a list of attached devices. Example (NOTE: VID/PID for non-proxmark devices redacted) + +```cmd +C:\qwert> usbipd list + +Connected: +BUSID VID:PID DEVICE STATE +1-2 xxxx:xxxx USB Input Device Not shared +2-3 xxxx:xxxx USB Mass Storage Device Not shared +5-3 9ac4:4b8f USB Serial Device (COM31) Not shared + +Persisted: +GUID DEVICE +``` + +Take note of the `BUSID` for the proxmark device, which should show as a USB Serial Device. + +Setup that bus ID to always be redirected to the WSL distribution named `kali-linux`: + +```cmd +C:\qwert> usbipd wsl attach --busid 5-3 --distribution kali-linux --auto-attach +usbipd: info: Starting endless attach loop; press Ctrl+C to quit. +Attached +``` + +NOTE: You must leave that running in the background, to allow the device to automatically +re-attach to the WSL2 instance. + + + +## WSL2 / Kali Linux Installation +^[Top](#top) + +Start the Kali Linux distribution you installed. First, make sure +the distribution is up-to-date: + +```sh +sudo apt-get update +sudo apt-get upgrade -y +sudo apt-get auto-remove -y +``` + +then, install proxmark dependencies: + +```sh +sudo apt-get install --no-install-recommends \ + git ca-certificates build-essential pkg-config \ + libreadline-dev gcc-arm-none-eabi libnewlib-dev \ + libbz2-dev libpython3-dev qtbase5-dev libssl-dev +``` + +_note_ +If you don't need the graphical components of the Proxmark3 client, you can skip the installation of `qtbase5-dev`. +If you don't need support for Python3 scripts in the Proxmark3 client, you can skip the installation of `libpython3-dev`. + +## X Server Installation +^[Top](#top) + +TBD -- Installing [`Win-KeX`](https://www.kali.org/docs/wsl/win-kex/) has worked +to provide a fully integrated experience, with three distinct modes..... +However, WSL2 may have some functionality already built-in? + +## Clone the Iceman repository +^[Top](#top) + +```sh +cd ~/ +git clone https://github.com/RfidResearchGroup/proxmark3.git +``` + +## Compile the project +^[Top](#top) + +```sh +cd ~/proxmark3 +make clean && make -j +``` + +## Install the udev rules + +```sh +sudo make accessrights +sudo make udev +``` + +On Kali, the above does two things: +1. Ensures the user is a member of the `dialout` group +2. Copies the `./driver/77-pm3-usb-device-blacklist.rules` file to the `/etc/udev/rules.d/` directory + +This presumes that the file includes `MODE="660" GROUP="dialout"` at the end of the three match lines. +The goal is that Kali Linux will automatically apply the proper permissions when the device is attached. + +However, it may be necessary to give the `udev` service a kind reminder: + +## Inform udev that it really, really should work + +The following workaround appears to work to get udev to apply the permissions +appropriately. Note that this may need to be run again, such as when the WSL2 +distributions have been restarted. I don't know why ... but it's a small hiccup. + +```sh +sudo udevadm trigger --action=change +``` + +General instructions suggested to use `sudo udevadm control --reload-rules`. However, +this may simply result in the following cryptic error message: + +```sh +$ sudo udevadm control --reload-rules +[sudo] password for root: +Failed to send reload request: No such file or directory +``` + +_Note that the following should **NOT** be required:_ + +```sh +sudo service udev restart +``` + +## Verify Device Exists + +Verify the device exists, and has a symbolic link created: + +```sh +ls -lFA /dev/ttyACM* +ls -lFA /dev/pm3* +``` + + +The first should show the `rw` permissions for both owner +and group, and show the group as `dialout`: + +```sh +┌──(qwert㉿host)-[~] +└─$ ls -lFA /dev/ttyACM* +crw-rw---- 1 root dialout 166, 0 Jan 22 11:28 /dev/ttyACM0 +``` + +The second command should show that a symbolic link exists +from the friendly name `/dev/pm3-0` to the TTY device: + +```sh +┌──(qwert㉿host)-[~] +└─$ ls -lFA /dev/pm3* +lrwxrwxrwx 1 root root 7 Jan 17 19:46 /dev/pm3-0 -> ttyACM0 +``` + +## Using the client... + +```sh +┌──(qwert㉿host)-[~] +└─$ pushd ~/proxmark3 + +┌──(qwert㉿host)-[~] +└─$ ./pm3 +``` + +## Done! +^[Top](#top) + +Full [compilation instructions](/doc/md/Use_of_Proxmark/0_Compilation-Instructions.md) may be helpful. + diff --git a/driver/77-pm3-usb-device-blacklist.rules b/driver/77-pm3-usb-device-blacklist.rules index d939468f2..8d699faca 100644 --- a/driver/77-pm3-usb-device-blacklist.rules +++ b/driver/77-pm3-usb-device-blacklist.rules @@ -10,9 +10,9 @@ ACTION!="add|change", GOTO="pm3_usb_device_blacklist_end" SUBSYSTEM!="tty", GOTO="pm3_ignore" -ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" -ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" -ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" +ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="dialout" +ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="dialout" +ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="dialout" LABEL="pm3_ignore" ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" From bfc3a53ea262f755295a3b1fb1afa359b614ad13 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 31 Jan 2023 09:45:44 -0800 Subject: [PATCH 585/759] Modify Makefile to copy group-specific udev rules --- Makefile | 9 +++++++- ...77-pm3-usb-device-blacklist-dialout.rules} | 0 driver/77-pm3-usb-device-blacklist-uucp.rules | 22 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) rename driver/{77-pm3-usb-device-blacklist.rules => 77-pm3-usb-device-blacklist-dialout.rules} (100%) create mode 100644 driver/77-pm3-usb-device-blacklist-uucp.rules diff --git a/Makefile b/Makefile index 0cb778ec6..9d3e509f8 100644 --- a/Makefile +++ b/Makefile @@ -256,8 +256,15 @@ endif # configure system to ignore PM3 device as a modem (ModemManager blacklist, effective *only* if ModemManager is not using _strict_ policy) # Read doc/md/ModemManager-Must-Be-Discarded.md for more info udev: - $(SUDO) cp -rf driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +ifneq ($(wildcard /etc/arch-release),) +# If user is running ArchLinux, use group 'uucp' + $(SUDO) cp -rf driver/77-pm3-usb-device-blacklist-uucp.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +else ifneq ($(wildcard /etc/fedora-release),) +# Else, use group 'dialout' + $(SUDO) cp -rf driver/77-pm3-usb-device-blacklist-dialout.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +endif $(SUDO) udevadm control --reload-rules + $(SUDO) udevadm trigger --action=change # configure system to add user to the dialout group and if bluetooth group exists, add user to it # you need to logout, relogin to get this access right correct. diff --git a/driver/77-pm3-usb-device-blacklist.rules b/driver/77-pm3-usb-device-blacklist-dialout.rules similarity index 100% rename from driver/77-pm3-usb-device-blacklist.rules rename to driver/77-pm3-usb-device-blacklist-dialout.rules diff --git a/driver/77-pm3-usb-device-blacklist-uucp.rules b/driver/77-pm3-usb-device-blacklist-uucp.rules new file mode 100644 index 000000000..101381d95 --- /dev/null +++ b/driver/77-pm3-usb-device-blacklist-uucp.rules @@ -0,0 +1,22 @@ +# Proxmark3 linux modem-manager de-confliction file +# +# copy this file to /etc/udev/rules.d (or add the entry to the end of an existing file) +# and restart udev hotplug: +# +# 'sudo udevadm control --reload-rules' +# + +# proxmark3 +ACTION!="add|change", GOTO="pm3_usb_device_blacklist_end" +SUBSYSTEM!="tty", GOTO="pm3_ignore" + +ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="uucp" +ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="uucp" +ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" MODE="660" GROUP="uucp" + +LABEL="pm3_ignore" +ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" +ATTRS{idVendor}=="9ac4" ATTRS{idProduct}=="4b8f", ENV{ID_MM_DEVICE_IGNORE}="1" +ATTRS{idVendor}=="502d" ATTRS{idProduct}=="502d", ENV{ID_MM_DEVICE_IGNORE}="1" + +LABEL="pm3_usb_device_blacklist_end" From 1a214b389c1485f90684608fa40352c0ecb72b5d Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 31 Jan 2023 09:49:59 -0800 Subject: [PATCH 586/759] changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba2f8f322..82954446e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] - Fixed the lf sampling when bits_per_sample is less than 8 (@wh201906) - Added `lf em 4x70 brute` command (@adite) - + - Added documentation for usage of Proxmark3 under WSL2 (@henrygab) + - Fixed device permissions via updated `udev` rules (@henrygab) ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) @@ -52,7 +53,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `trace list -c` - annotation of CRC bytes now is colored or squared if no ansi colors is supported (@iceman1001) - Fixed `trace list -t mf` - now also finds UID if anticollision is partial captured, to be used for mfkey (@iceman1001) - ## [Radium.4.15864][2022-10-29] - Changed `lf indala sim` - now accepts fc / cn (@iceman1001) - Added `lf indala brute`- brute forcing of 64b Indala ID (@iceman1001) From 99f24b23b8b9b82e6f0b96b0cf605604dedbed88 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 31 Jan 2023 09:55:46 -0800 Subject: [PATCH 587/759] fix copy/paste error --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9d3e509f8..6c31157e2 100644 --- a/Makefile +++ b/Makefile @@ -259,7 +259,7 @@ udev: ifneq ($(wildcard /etc/arch-release),) # If user is running ArchLinux, use group 'uucp' $(SUDO) cp -rf driver/77-pm3-usb-device-blacklist-uucp.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules -else ifneq ($(wildcard /etc/fedora-release),) +else # Else, use group 'dialout' $(SUDO) cp -rf driver/77-pm3-usb-device-blacklist-dialout.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules endif From c7825a2adf5aa1a4c9021046662e241d8dc1ab4d Mon Sep 17 00:00:00 2001 From: adite Date: Wed, 1 Feb 2023 19:28:31 +0100 Subject: [PATCH 588/759] Fix bug in 'lf em 4x70 brute' command --- armsrc/em4x70.c | 2 +- client/src/cmdlfem4x70.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 545491447..066aad58f 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -362,7 +362,7 @@ static int bruteforce(const uint8_t address, const uint8_t *rnd, const uint8_t * uint8_t rev_rnd[7]; uint8_t temp_rnd[7]; - reverse_arraycopy((uint8_t *)rnd, rev_rnd, sizeof(rnd)); + reverse_arraycopy((uint8_t *)rnd, rev_rnd, sizeof(rev_rnd)); memcpy(temp_rnd, rnd, sizeof(temp_rnd)); for (int k = start_key; k <= 0xFFFF; ++k) { diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index f008d9947..e90c688c1 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -306,8 +306,8 @@ int CmdEM4x70Brute(const char *Cmd) { break; } - // should be done in about 30 minutes - if (timeout > ((30 * 60000) / TIMEOUT)) { + // should be done in about 60 minutes. + if (timeout > ((60 * 60000) / TIMEOUT)) { PrintAndLogEx(WARNING, "\nNo response from Proxmark3. Aborting..."); break; } From 5bd8bd13dcfd7d2be4ed040fde29bc69570dc199 Mon Sep 17 00:00:00 2001 From: adite Date: Wed, 1 Feb 2023 19:33:52 +0100 Subject: [PATCH 589/759] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba2f8f322..1d8a9226b 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 broken `lf em 4x70 brute` command (@adite) - Fixed the lf sampling when bits_per_sample is less than 8 (@wh201906) - Added `lf em 4x70 brute` command (@adite) From 23a3590bba65f61e7390e4254e0abb105e47cd08 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Feb 2023 21:24:34 +0100 Subject: [PATCH 590/759] unify the text comments --- client/dictionaries/mfc_default_keys.dic | 173 ++++++++++++++--------- 1 file changed, 108 insertions(+), 65 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 881c72df0..a522b001b 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -3,36 +3,46 @@ # -- iceman fork version -- # -- contribute to this list, sharing is caring -- # -# Defaultkey(firstkeyusedbyprogramifnouserdefinedkey) +# Default key FFFFFFFFFFFF -# Blankkey +# +# Blank key 000000000000 +# # NFC Forum MADkey A0A1A2A3A4A5 +# # MAD access key A (reversed) A5A4A3A2A1A0 +# # MAD access key B 89ECA97F8C2A # +# B0B1B2B3B4B5 C0C1C2C3C4C5 D0D1D2D3D4D5 AABBCCDDEEFF 4D3A99C351DD 1A982C7E459A +# # key A Wien D3F7D3F7D3F7 +# # key B Wien 5A1B85FCE20A # +# 714C5C886E97 587EE5F9350F A0478CC39091 533CB6C723F6 8FD0A4F256E9 +# # iCopy-X E00000000000 # +# E7D6064C5860 B27CCAB30DBD # @@ -40,6 +50,9 @@ B27CCAB30DBD D2ECE8B9395E # NSCP default key 1494E81663D7 +# +# NFC tools +7c9fb8474242 # # Kiev keys 569369C5A0E5 @@ -54,31 +67,41 @@ F14EE7CAE863 # RKF # Västtrafiken KeyA, RKF ÖstgötaTrafiken KeyA FC00018778F7 +# # Västtrafiken KeyA 0297927C0F77 54726176656C +# # Västtrafiken KeyB 00000FFE2488 776974687573 EE0042F88840 +# # RKF SLKeyA 26940B21FF5D A64598A77478 +# # RKF SLKeyB 5C598C9C58B5 E4D2770A89BE -# RKF RejskortDanmark KeyA +# +# RKF Rejskort Danmark KeyA 722BFCC5375F -# RKF RejskortDanmark KeyB +# +# RKF Rejskort Danmark KeyB F1D83F964314 -# RKF JOJOPRIVAKeyA +# +# RKF JOJOPRIVA KeyA 505249564141 -# RKF JOJOPRIVAKeyB +# +# RKF JOJOPRIVA KeyB 505249564142 -# RKF JOJOGROUPKeyA +# +# RKF JOJOGROUP KeyA 47524F555041 434F4D4D4F41 -# RKF JOJOGROUPKeyB +# +# RKF JOJOGROUP KeyB 47524F555042 434F4D4D4F42 # @@ -108,11 +131,14 @@ F1D83F964314 200000000000 222222222222 27DD91F1FCF1 -# DirectoryandeventlogKeyB +# +# Directory and eventlog KeyB 2BA9621E0A36 -# DirectoryandeventlogKeyA +# +# Directory and eventlog KeyA 4AF9D7ADEBE4 # +# 333333333333 33F974B42769 34D1DF9934C5 @@ -131,9 +157,11 @@ A00000000000 A053A292A4AF A94133013401 AAAAAAAAAAAA -# Keyfromladyada.net +# +# Key from ladyada.net ABCDEF123456 # +# B00000000000 B127C6F41436 BBBBBBBBBBBB @@ -147,7 +175,9 @@ EEEEEEEEEEEE # data from forum FFFFFF545846 # +# F1A97341A9FC +# # hotel system 44AB09010845 85FED980EA5A @@ -157,7 +187,9 @@ F1A97341A9FC # ARD (fr) key B 4A2B29111213 # +# 4143414F5250 +# # Tehran Railway A9B43414F585 1FB235AC1388 @@ -169,13 +201,17 @@ F4A9EF2AFC6D # # S0 B 89EAC97F8C2A +# # S4 A 43C7600DEE6B +# # S6 A 0120BF672A64 +# # S6 B FB0B20DF1F34 # +# A9F953DEF0A3 # # Data from forum @@ -233,14 +269,17 @@ AAFB06045877 # gym # Fysiken A 3E65E4FB65B3 +# # Fysiken B 25094DF6F148 +# # CleverFit A05DBD98E0FC # # Hotel KeyCard D3B595E9DD63 AFBECD121004 +# # SimonsVoss 6471A5EF2D1A # @@ -396,9 +435,11 @@ C52876869800 # Data from mall # playland balikesir ABBA1234FCB0 +# # A trio bowling bahcelievler 314F495254FF 4152414B4E41 +# # karinca park nigde 4E474434FFFF # @@ -477,18 +518,21 @@ D9A37831DCE5 C5CFE06D9EA3 C0DECE673829 # +# A56C2DF9A26D # # Data from https://pastebin.com/vbwast74 -# 68D3F7307C89 +# # Smart Rider. Western Australian Public Transport Cards 568C9083F71C # # Bangkok metro key 97F5DA640B18 +# # Metro Valencia key A8844B0BCA06 +# # HTC Eindhoven key 857464D3AAD1 # @@ -501,6 +545,7 @@ A8844B0BCA06 # French VIGIK # VIGIK1 A 314B49474956 +# # VIGIK1 B 564C505F4D41 BA5B895DA162 @@ -508,16 +553,20 @@ BA5B895DA162 # Vigik mystery Keys Mifare 1k EV1 (S50) # 16 A 5C8FF9990DA2 +# # 17 A 75CCB59C9BED +# # 16 B D01AFEEB890A +# # 17 B 4B791BEA7BCC # # BTCINO UNDETERMINED SPREAKD 0x01->0x13 key 021209197591 # +# 2EF720F2AF76 414C41524F4E 424C41524F4E @@ -676,6 +725,7 @@ F7A39753D018 410B9B40B872 2CB1A90071C8 # +# 8697389ACA26 1AB23CD45EF6 013889343891 @@ -691,6 +741,7 @@ EC0A9B1A9E06 0F230695923F 0000014B5C31 # +# BEDB604CC9D1 B8A1F613CF3D B578F38A5C61 @@ -699,12 +750,15 @@ B66AC040203A 2E641D99AD5B AD4FB33388BF 69FB7B7CD8EE +# # Hotel 2A6D9205E7CA 13B91C226E56 +# # KABA Hotel Locks 2A2C13CC242A # +# 27FBC86A00D0 01FA3FC68349 # @@ -761,8 +815,10 @@ D58023BA2BDC 2ED3B15E7C0F F66224EE1E89 # +# 60012E9BA3FA # +# DE1FCBEC764B 81BFBE8CACBA BFF123126C9B @@ -775,11 +831,13 @@ D80511FC2AB4 BB467463ACD6 E67C8010502D FF58BA1B4478 +# # Data from https://pastebin.com/Kz8xp4ev FBF225DC5D58 # # Data https://pastebin.com/BEm6bdAE # vingcard.txt +# Note: most likely diversified 4708111C8604 3D50D902EA48 96A301BCE267 @@ -801,10 +859,12 @@ D58660D1ACDE 50A11381502C C01FC822C6E5 0854BF31111E -# More keys: +# +# More keys 8A19D40CF2B5 AE8587108640 -# SafLock standalone door locks. +# +# SafLock standalone door locks 135B88A94B8B # # Russian Troika card @@ -863,7 +923,7 @@ F8493407799D 6B8BD9860763 D3A297DC2698 # -# Keys from MifareClassicTool project +# Keys from Mifare Classic Tool project 044CE1872BC3 045CECA15535 0BE5FAC8B06A @@ -918,7 +978,6 @@ FD8705E721B0 00ADA2CD516D # # -## 237A4D0D9119 0ED7846C2BC9 FFFFD06F83E3 @@ -965,12 +1024,13 @@ A2B2C9D187FB # Hotel Adina 9EBC3EB37130 # -# most likely diversed individual keys. +# most likely diversifed individual keys. # data from https://github.com/korsehindi/proxmark3/commit/24fdbfa9a1d5c996aaa5c192bc07e4ab28db4c5c 491CDC863104 A2F63A485632 98631ED2B229 19F1FFE02563 +# # Argentina 563A22C01FC8 43CA22C13091 @@ -983,7 +1043,6 @@ AFBECD120454 842146108088 # # TAPCARD PUBLIC TRANSPORT LA -# EA1B88DF0A76 D1991E71E2C5 05F89678CFCF @@ -1018,7 +1077,6 @@ E3AD9E9BA5D4 6C9EC046C1A4 # # ROC HIGHSCHOOL ACCESSCARD -# B021669B44BB B18CDCDE52B7 A22647F422AE @@ -1050,8 +1108,7 @@ BE7C4F6C7A9A 5EC7938F140A 82D58AA49CCB # -# MELONCARD -# +# MELON CARD 323334353637 # # @@ -1071,7 +1128,6 @@ A7FB4824ACBF 10F3BEBC01DF # # Transportes Insular La Palma -# 0172066B2F03 0000085F0000 1A80B93F7107 @@ -1106,7 +1162,6 @@ B1A862985913 F3F0172066B2 # # Tehran ezpay -# 38A88AEC1C43 CBD2568BC7C6 7BCB4774EC8F @@ -1124,7 +1179,6 @@ D3B1C7EA5C53 BB3D7B11D224 # # Chaco -# B210CFA436D2 B8B1CFA646A8 A9F95891F0A4 @@ -1147,11 +1201,11 @@ A0004A000036 4243414F5250 DFE73BE48AC6 # +# B069D0D03D17 000131B93F28 # # From the DFW Area, TX, USA -# A506370E7C0F 26396F2042E7 70758FDD31E0 @@ -1169,7 +1223,6 @@ B47058139187 67CC03B7D577 # # From the HTL Mödling, NÖ, AT -# A5524645CD91 D964406E67B4 99858A49C119 @@ -1179,7 +1232,6 @@ C27D999912EA 4C60F4B15BA8 # # CAFE + CO, AT -# 35D850D10A24 4B511F4D28DD E45230E7A9E8 @@ -1187,27 +1239,25 @@ E45230E7A9E8 FB6C88B7E279 # # Metro Card, AT -# 223C3427108A # # Unknown, AT -# 23D4CDFF8DA3 E6849FCC324B 12FD3A94DF0E # # Unknown, AT -# 0B83797A9C64 39AD2963D3D1 +# # Hotel Berlin Classic room A KEY 34B16CD59FF8 +# # Hotel Berlin Classic room B KEY BB2C0007D022 # # Coinmatic laundry Smart card # data from: https://pastebin.com/XZQiLtUf -# 0734BFB93DAB 85A438F72A8A # @@ -1215,6 +1265,7 @@ BB2C0007D022 58AC17BF3629 B62307B62307 # +# A2A3CCA2A3CC # # Granada, ES Transport Card @@ -1260,6 +1311,7 @@ B8937130B6BA D7744A1A0C44 82908B57EF4F FE04ECFE5577 +# # comfort inn hotel 4D57414C5648 4D48414C5648 @@ -1306,13 +1358,11 @@ A82045A10949 # # funnivarium # forum ankara -# 2602FFFFFFFF # # macera adasi # ankara kentpark # INACTIVE -# 0A4600FF00FF DFF293979FA7 4D6F62692E45 @@ -1321,21 +1371,17 @@ DFF293979FA7 # petrol ofisi # positive card # ode-gec -# 0406080A0C0E # # konya elkart -# 988ACDECDFB0 120D00FFFFFF # # bowlingo # serdivan avym -# 4AE23A562A80 # -# kart54 -# +# kart 54 2AFFD6F88B97 A9F3F289B70C DB6819558A25 @@ -1346,20 +1392,16 @@ B16B2E573235 # # crazy park # kizilay avm -# 00DD300F4F10 # # kartsistem B -# FEE2A3FBC5B6 # # toru ent # taurus avm -# 005078565703 # # Ving? -# 0602721E8F06 FC0B50AF8700 F7BA51A9434E @@ -1407,7 +1449,6 @@ D0DDDF2933EC # # bursakart # bursa transport card -# 755D49191A78 DAC7E0CBA8FD 68D3263A8CD6 @@ -1418,30 +1459,29 @@ B2FE3B2875A6 # # playland # maltepe park -# ABCC1276FCB0 AABAFFCC7612 # # lunasan # kocaeli fair -# 26107E7006A0 # # gamefactory # ozdilek -# 17D071403C20 # +# 534F4C415249 534F4C303232 # # Nespresso, smart card -# key-gen algo, these keys are for one card +# key-gen algo, these keys are for one card (keys diversified) FF9A84635BD2 6F30126EE7E4 6039ABB101BB F1A1239A4487 # +# B882FD4A9F78 CD7FFFF81C4A AA0857C641A3 @@ -1524,9 +1564,10 @@ ABFEDC124578 5E594208EF02 AF9E38D36582 # -#Norwegian building site identication card. (HMS KORT) +# Norwegian building site identication card. (HMS KORT) # Key a 10DF4D1859C8 +# # Key B B5244E79B0C8 # @@ -1594,7 +1635,6 @@ F53E9F4114A9 AD38C17DE7D2 # # SUBE cards keys (new) -# 2DEB57A3EA8F 32C1BB023F87 70E3AD3F2D29 @@ -1623,7 +1663,6 @@ F5C1B3F62FDA 7E6545076619 # # SUBE cards keys (old) -# 4C5A766DFE3A 32C6768847F5 F68930789631 @@ -1651,7 +1690,9 @@ BFE25035B0C8 D5C172325DD3 992B152E834A CE75D7EADEAF -# Russian Podorozhnik card (Saint-Petersburg transport, may be combined with Troika) +# +# Russian Podorozhnik card (Saint-Petersburg transport) +# may be combined with Troika 038B5F9B5A2A 04DC35277635 0C420A20E056 @@ -1681,11 +1722,12 @@ D27058C6E2C7 E19504C39461 FA1FBB3F0F1F FF16014FEFC7 -################################## -# Keys from Flipper Zero Community # +# Keys from Flipper Zero Community # Last update: Aug 13, 2022 # +# unknown if keys are diversified or static default +# # Strelka Extension 5C83859F2224 66B504430416 @@ -1771,7 +1813,7 @@ CB9D507CE56D # Armenian Underground Ticket A0A1A2A8A4A5 # -# BadgeMaker Leaked from https://github.com/UberGuidoZ +# Badge Maker Leaked from https://github.com/UberGuidoZ 1A1B1C1D1E1F 1665FE2AE945 158B51947A8E @@ -1813,7 +1855,7 @@ D10008074A6F 6F6674776172 6520446F7665 # -# Apartment keyfobs (USA) from Corvette830 +# Apartment keyfobs (USA) (Corvette830) E60F8387F0B9 FFD46FF6C5EE 4F9661ED2E70 @@ -1822,8 +1864,8 @@ FFD46FF6C5EE 16CA203B811B 11AC8C8F3AF2 # -# The Westin Jakarta Indonesia from D4DB0D -# Peppers Hotel Unknown location from D4DB0D +# The Westin Jakarta Indonesia (D4DB0D) +# Peppers Hotel Unknown location (D4D0D) 6E0DD4136B0A 141940E9B71B 3B1D3AAC866E @@ -1836,12 +1878,12 @@ F09BB8DD142D B4B3FFEDBE0A 540E0D2D1D08 # -# Schlage 9691T Keyfob from seasnaill +# Schlage 9691T Keyfob (seasnaill) 7579B671051A 4F4553746B41 # # Vigik ScanBadge App (fr.badgevigik.scanbadge) -# Website https://badge-vigik.fr/ - By Alex` +# Website https://badge-vigik.fr/ (Alex) 0000A2B3C86F 021200C20307 021209197507 @@ -1868,6 +1910,7 @@ B4B3FFEDBE0A 9EB7C8A6D4E3 A22AE12C9013 AFC984A3576E +# # Vigik verified by quantum-x # https://github.com/RfidResearchGroup/proxmark3/pull/1742#issuecomment-1206113976 A00027000099 @@ -1892,8 +1935,8 @@ A00003000057 # iGuard Simple (and reverse) keys AAAAAAFFFFFF FFFFFFAAAAAA -# Added by VideoMan. -# Random Hotel A Key Sec 0 Blk 3 - KABA Lock +# +# Random Hotel A Key Sec 0 Blk 3 - KABA Lock (VideoMan) 3111A3A303EB # Transport system Uruguay - STM # Shared key - sec 0 blk 3 @@ -1910,9 +1953,9 @@ D144BD193063 8627C10A7014 453857395635 # -########################################## -# added by colonelborkmundus -# "the more, the marriott" mifare project +# Data from "the more, the marriott" mifare project (colonel borkmundus) +# +# Isn't theirs Saflok ? # # 1k - graduate hotel C49DAE1C6049 @@ -1984,4 +2027,4 @@ F72CD208FDF9 2158E314C3DF # # 1k - waldorf astoria -011C6CF459E8 \ No newline at end of file +011C6CF459E8 From 3ec3730183865fa89413032c168e358026884b11 Mon Sep 17 00:00:00 2001 From: "U-CHRIS-PC\\Chris" Date: Thu, 2 Feb 2023 15:53:52 -0700 Subject: [PATCH 591/759] Added XOR extraction and flag to Guardall G-Prox II --- client/src/cmdlfguard.c | 64 +++++++++++++++++++++++++---------------- client/src/cmdlfguard.h | 2 +- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/client/src/cmdlfguard.c b/client/src/cmdlfguard.c index 02bd52eb8..0225b2fef 100644 --- a/client/src/cmdlfguard.c +++ b/client/src/cmdlfguard.c @@ -86,9 +86,9 @@ static int demod_guard_raw(uint8_t *raw, uint8_t rlen) { } if (unknown) - PrintAndLogEx(SUCCESS, "G-Prox-II - Unknown len: " _GREEN_("%u") ", Raw: %s", fmtlen, sprint_hex_inrow(raw, rlen)); + PrintAndLogEx(SUCCESS, "G-Prox-II - xorKey: " _GREEN_("%u")" Unknown len: " _GREEN_("%u") ", Raw: %s", xorKey, fmtlen, sprint_hex_inrow(raw, rlen)); else - PrintAndLogEx(SUCCESS, "G-Prox-II - len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") ", Raw: %s", fmtlen, FC, Card, sprint_hex_inrow(raw, rlen)); + PrintAndLogEx(SUCCESS, "G-Prox-II - xorKey: " _GREEN_("%u")" Len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") ", Raw: %s", xorKey, fmtlen, FC, Card, sprint_hex_inrow(raw, rlen)); return PM3_SUCCESS; } @@ -142,9 +142,11 @@ int demodGuard(bool verbose) { // get key and then get all 8 bytes of payload decoded xorKey = (uint8_t)bytebits_to_byteLSBF(bits_no_spacer, 8); + PrintAndLogEx(DEBUG, "DEBUG: gProxII xorKey: %u", xorKey); + for (size_t idx = 0; idx < 8; idx++) { plain[idx] = ((uint8_t)bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8)) ^ xorKey; - PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %zu after xor: %02x", idx, plain[idx]); + PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %zu after xor: %02x (%02x before xor)", idx, plain[idx], bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8)); } setDemodBuff(g_DemodBuffer, 96, preambleIndex); @@ -161,6 +163,12 @@ int demodGuard(bool verbose) { bool unknown = false; switch (fmtLen) { case 36: + PrintAndLogEx(DEBUG, "DEBUG: FC 1: %x", (plain[3] & 0x7F) << 7); + PrintAndLogEx(DEBUG, "DEBUG: FC 2: %x", plain[4] >> 1); + PrintAndLogEx(DEBUG, "DEBUG: Card 1: %x", (plain[4] & 1) << 19); + PrintAndLogEx(DEBUG, "DEBUG: Card 2: %x", plain[5] << 11); + PrintAndLogEx(DEBUG, "DEBUG: Card 3: %x", plain[6] << 3); + PrintAndLogEx(DEBUG, "DEBUG: Card 4: %x", (plain[7] & 0xE0) >> 5); FC = ((plain[3] & 0x7F) << 7) | (plain[4] >> 1); Card = ((plain[4] & 1) << 19) | (plain[5] << 11) | (plain[6] << 3) | ((plain[7] & 0xE0) >> 5); break; @@ -173,9 +181,9 @@ int demodGuard(bool verbose) { break; } if (!unknown) - PrintAndLogEx(SUCCESS, "G-Prox-II - len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") ", Raw: %08x%08x%08x", fmtLen, FC, Card, raw1, raw2, raw3); + PrintAndLogEx(SUCCESS, "G-Prox-II - xorKey: " _GREEN_("%u") " Len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") ", Raw: %08x%08x%08x", xorKey, fmtLen, FC, Card, raw1, raw2, raw3); else - PrintAndLogEx(SUCCESS, "G-Prox-II - Unknown len: " _GREEN_("%u") ", Raw: %08x%08x%08x", fmtLen, raw1, raw2, raw3); + PrintAndLogEx(SUCCESS, "G-Prox-II - xorKey: " _GREEN_("%u") " Unknown len: " _GREEN_("%u") ", Raw: %08x%08x%08x", xorKey, fmtLen, raw1, raw2, raw3); return PM3_SUCCESS; } @@ -243,16 +251,17 @@ static int CmdGuardReader(const char *Cmd) { static int CmdGuardClone(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf gproxii clone", - "clone a Guardall tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n" + "Clone a Guardall tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n" "The facility-code is 8-bit and the card number is 20-bit. Larger values are truncated.\n" "Currently work only on 26 | 36 bit format", - "lf gproxii clone --fmt 26 --fc 123 --cn 1337 -> encode for T55x7 tag\n" - "lf gproxii clone --fmt 26 --fc 123 --cn 1337 --q5 -> encode for Q5/T5555 tag\n" - "lf gproxii clone --fmt 26 --fc 123 --cn 1337 --em -> encode for EM4305/4469" + "lf gproxii clone --xor 141 --fmt 26 --fc 123 --cn 1337 -> encode for T55x7 tag\n" + "lf gproxii clone --xor 141 --fmt 26 --fc 123 --cn 1337 --q5 -> encode for Q5/T5555 tag\n" + "lf gproxii clone --xor 141 --fmt 26 --fc 123 --cn 1337 --em -> encode for EM4305/4469" ); void *argtable[] = { arg_param_begin, + arg_u64_1(NULL, "xor", "", "8-bit xor value (installation dependant)"), arg_u64_1(NULL, "fmt", "", "format length 26|32|36|40"), arg_u64_1(NULL, "fc", "", "8-bit value facility code"), arg_u64_1(NULL, "cn", "", "16-bit value card number"), @@ -262,11 +271,13 @@ static int CmdGuardClone(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, false); - uint32_t fmtlen = arg_get_u32_def(ctx, 1, 0); - uint32_t fc = arg_get_u32_def(ctx, 2, 0); - uint32_t cn = arg_get_u32_def(ctx, 3, 0); - bool q5 = arg_get_lit(ctx, 4); - bool em = arg_get_lit(ctx, 5); + uint32_t xorval = arg_get_u32_def(ctx, 1, 0); + uint32_t fmtlen = arg_get_u32_def(ctx, 2, 0); + uint32_t fc = arg_get_u32_def(ctx, 3, 0); + uint32_t cn = arg_get_u32_def(ctx, 4, 0); + + bool q5 = arg_get_lit(ctx, 5); + bool em = arg_get_lit(ctx, 6); CLIParserFree(ctx); if (q5 && em) { @@ -280,7 +291,7 @@ static int CmdGuardClone(const char *Cmd) { //GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks uint8_t *bs = calloc(96, sizeof(uint8_t)); - if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) { + if (getGuardBits(xorval, fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); free(bs); return PM3_ESOFT; @@ -306,10 +317,11 @@ static int CmdGuardClone(const char *Cmd) { free(bs); - PrintAndLogEx(INFO, "Preparing to clone Guardall to " _YELLOW_("%s") " with Facility Code: " _GREEN_("%u") " Card Number: " _GREEN_("%u") + PrintAndLogEx(INFO, "Preparing to clone Guardall to " _YELLOW_("%s") " with Facility Code: " _GREEN_("%u") " Card Number: " _GREEN_("%u") " xorKey: " _GREEN_("%u") , cardtype , facilitycode , cardnumber + , xorval ); print_blocks(blocks, ARRAYLEN(blocks)); @@ -332,11 +344,12 @@ static int CmdGuardSim(const char *Cmd) { "Simulation runs until the button is pressed or another USB command is issued.\n" "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.\n" "Currently work only on 26 | 36 bit format", - "lf gproxii sim --fmt 26 --fc 123 --cn 1337\n" + "lf gproxii sim --xor 141 --fmt 26 --fc 123 --cn 1337\n" ); void *argtable[] = { arg_param_begin, + arg_u64_1(NULL, "xor", "", "8-bit xor value (installation dependant)"), arg_u64_1(NULL, "fmt", "", "format length 26|32|36|40"), arg_u64_1(NULL, "fc", "", "8-bit value facility code"), arg_u64_1(NULL, "cn", "", "16-bit value card number"), @@ -344,9 +357,10 @@ static int CmdGuardSim(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, false); - uint32_t fmtlen = arg_get_u32_def(ctx, 1, 0); - uint32_t fc = arg_get_u32_def(ctx, 2, 0); - uint32_t cn = arg_get_u32_def(ctx, 3, 0); + uint32_t xorval = arg_get_u32_def(ctx, 1, 0); + uint32_t fmtlen = arg_get_u32_def(ctx, 2, 0); + uint32_t fc = arg_get_u32_def(ctx, 3, 0); + uint32_t cn = arg_get_u32_def(ctx, 4, 0); CLIParserFree(ctx); fmtlen &= 0x7F; @@ -356,12 +370,13 @@ static int CmdGuardSim(const char *Cmd) { uint8_t bs[96]; memset(bs, 0x00, sizeof(bs)); - if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) { + if (getGuardBits(xorval, fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; } - PrintAndLogEx(SUCCESS, "Simulating Guardall Prox - Facility Code: " _YELLOW_("%u") " CardNumber: " _YELLOW_("%u") + PrintAndLogEx(SUCCESS, "Simulating Guardall Prox - xorKey: " _YELLOW_("%u%") " Facility Code: " _YELLOW_("%u") " CardNumber: " _YELLOW_("%u") + , xorval , facilitycode , cardnumber ); @@ -435,9 +450,8 @@ int detectGProxII(uint8_t *bits, size_t *size) { } // Works for 26bits. -int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) { +int getGuardBits(uint8_t xorKey, uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) { - uint8_t xorKey = 0x66; uint8_t i; uint8_t pre[96]; uint8_t rawbytes[12]; @@ -448,7 +462,6 @@ int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) { switch (fmtlen) { case 32: { rawbytes[1] = (32 << 2); - break; } case 36: { @@ -456,6 +469,7 @@ int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) { // Get wiegand from FacilityCode 14bits, CardNumber 20bits uint8_t wiegand[36]; memset(wiegand, 0x00, sizeof(wiegand)); + num_to_bytebits(fc, 14, wiegand); num_to_bytebits(cn, 20, wiegand + 14); diff --git a/client/src/cmdlfguard.h b/client/src/cmdlfguard.h index c68c0d477..cfdf739a4 100644 --- a/client/src/cmdlfguard.h +++ b/client/src/cmdlfguard.h @@ -23,5 +23,5 @@ int CmdLFGuard(const char *Cmd); int detectGProxII(uint8_t *bits, size_t *size); int demodGuard(bool verbose); -int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits); +int getGuardBits(uint8_t xorKey, uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits); #endif From ab9dab32947f10c009e30a0a446e8bd021d41988 Mon Sep 17 00:00:00 2001 From: Marcos Del Sol Vives Date: Fri, 3 Feb 2023 14:41:23 +0100 Subject: [PATCH 592/759] Fix pm3-flash-all -p XXX --- pm3 | 1 + 1 file changed, 1 insertion(+) diff --git a/pm3 b/pm3 index c0b0869b0..52a8ffcc1 100755 --- a/pm3 +++ b/pm3 @@ -441,6 +441,7 @@ done # if a port is already provided, let's just run the command as such for ARG; do + shift if [ "$ARG" == "-p" ]; then CMD "$@" exit $? From a7bc082d2d7daabcaaa2083138a3c041667e1b2f Mon Sep 17 00:00:00 2001 From: Self Not Found Date: Sun, 5 Feb 2023 17:37:13 +0800 Subject: [PATCH 593/759] Add a option to clear the scrollback buffer --- client/src/cmdmain.c | 12 ++++++++++-- include/ansi.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/client/src/cmdmain.c b/client/src/cmdmain.c index 14e198f5c..11f9bfd7b 100644 --- a/client/src/cmdmain.c +++ b/client/src/cmdmain.c @@ -300,15 +300,23 @@ static int CmdClear(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "clear", "Clear the Proxmark3 client terminal screen", - "clear" + "clear -> clear the terminal screen\n" + "clear -b -> clear the terminal screen and the scrollback buffer" ); void *argtable[] = { arg_param_begin, + arg_lit0("b", "back", "also clear the scrollback buffer"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); + bool scrollback = arg_get_lit(ctx, 1); CLIParserFree(ctx); - PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ ""); + + if (!scrollback) + PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ ""); + else + PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ _CLEAR_SCROLLBACK_ ""); + return PM3_SUCCESS; } diff --git a/include/ansi.h b/include/ansi.h index 59f546e39..20815bc03 100644 --- a/include/ansi.h +++ b/include/ansi.h @@ -58,6 +58,7 @@ #define _BACK_BRIGHT_WHITE_(s) "\x1b[47;1m" s AEND #define _CLEAR_ "\x1b[2J" +#define _CLEAR_SCROLLBACK_ "\x1b[3J" #define _TOP_ "\x1b[1;1f" #if defined(HAVE_READLINE) From e139c137f9b8abcab5ba53f7c181810b55ba78be Mon Sep 17 00:00:00 2001 From: Self Not Found Date: Sun, 5 Feb 2023 17:47:55 +0800 Subject: [PATCH 594/759] Add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d8a9226b..44a16b154 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed broken `lf em 4x70 brute` command (@adite) - Fixed the lf sampling when bits_per_sample is less than 8 (@wh201906) - Added `lf em 4x70 brute` command (@adite) + - Added `--back` option to `clear` command to clear the scrollback buffer (@wh201906) ## [Nitride.4.16191][2023-01-29] From f9dbf1e34d06de5bf2958bb946edb9dac5f38ecf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 6 Feb 2023 21:44:31 +0100 Subject: [PATCH 595/759] added suggestion how to generate 256kb image in sample file --- Makefile.platform.sample | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Makefile.platform.sample b/Makefile.platform.sample index 4f8f86cd4..21fb2137e 100644 --- a/Makefile.platform.sample +++ b/Makefile.platform.sample @@ -7,10 +7,23 @@ PLATFORM=PM3RDV4 #PLATFORM_EXTRAS=BTADDON #STANDALONE=LF_SAMYRUN +# Uncomment the lines below in order to make a 256KB image +# and comment out the lines above + +#PLATFORM=PM3GENERIC +#PLATFORM_SIZE=256 +#STANDALONE= +#SKIP_HITAG=1 +#SKIP_FELICA=1 +#SKIP_HFPLOT=1 +#SKIP_NFCBARCODE=1 +#SKIP_ZX8211=1 +#SKIP_LF=1 + # To accelerate repetitive compilations: # Install package "ccache" -> Debian/Ubuntu: /usr/lib/ccache, Fedora/CentOS/RHEL: /usr/lib64/ccache # And uncomment the following line #export PATH := /usr/lib64/ccache:/usr/lib/ccache:${PATH} # To install with sudo: -INSTALLSUDO=sudo \ No newline at end of file +INSTALLSUDO=sudo From c6b6f2b6a7aaebf96ef8d2944ac4b84e2e13495e Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Tue, 7 Feb 2023 19:20:42 -0800 Subject: [PATCH 596/759] Option for PR 1902 --- Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6c31157e2..c482af694 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,13 @@ ifneq (,$(INSTALLSIMFW)) endif ifeq ($(platform),Linux) $(Q)$(INSTALLSUDO) $(MKDIR) $(DESTDIR)$(UDEV_PREFIX) - $(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +# If user is running ArchLinux, use group 'uucp' +# Else, use group 'dialout' + ifneq ($(wildcard /etc/arch-release),) + $(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist-uucp.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules + else + $(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist-dialout.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules + endif endif uninstall: common/uninstall From cb6f3f381dfea446f8c44a48f6e1cef30273a475 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 8 Feb 2023 23:17:19 +0100 Subject: [PATCH 597/759] text --- doc/md/Use_of_Proxmark/1_Validation.md | 47 +++++--------------------- 1 file changed, 9 insertions(+), 38 deletions(-) diff --git a/doc/md/Use_of_Proxmark/1_Validation.md b/doc/md/Use_of_Proxmark/1_Validation.md index 51a701388..a283b0d47 100644 --- a/doc/md/Use_of_Proxmark/1_Validation.md +++ b/doc/md/Use_of_Proxmark/1_Validation.md @@ -15,7 +15,7 @@ If all went well you should get some information about the firmware and memory usage as well as the prompt, something like this. ``` -[=] Session log /home/iceman/.proxmark3/logs/log_20220213.txt +[=] Session log /home/iceman/.proxmark3/logs/log_20230208.txt [+] loaded from JSON file /home/iceman/.proxmark3/preferences.json [=] Using UART port /dev/ttyS3 [=] Communicating with PM3 over USB-CDC @@ -28,48 +28,19 @@ If all went well you should get some information about the firmware and memory u 8888888P" 888 Y888P 888 "Y8b. 888 888 Y8P 888 888 888 888 888 " 888 Y88b d88P - 888 888 888 "Y8888P" [ Iceman ❄️ ] - + 888 888 888 "Y8888P" [ ☕ ] [ Proxmark3 RFID instrument ] - [ CLIENT ] - RRG/Iceman/master/v4.14831-269 2022-02-13 05:03:08 - compiled with............. GCC 10.3.0 - platform.................. Linux / x86_64 - Readline support.......... present - QT GUI support............ present - native BT support......... absent - Python script support..... present - Lua SWIG support.......... present - Python SWIG support....... present - - [ PROXMARK3 ] - device.................... RDV4 - firmware.................. RDV4 - external flash............ present - smartcard reader.......... present - FPC USART for BT add-on... absent - - [ ARM ] - bootrom: RRG/Iceman/master/v4.14831-269 2022-02-13 05:03:55 - os: RRG/Iceman/master/v4.14831-269 2022-02-13 05:03:49 - compiled with GCC 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599] - - [ FPGA ] - LF image 2s30vq100 2022-03-20 09:28:32 - HF image 2s30vq100 2022-03-20 09:02:07 - HF FeliCa image 2s30vq100 2022-03-20 09:28:28 - HF 15 image 2s30vq100 2022-03-20 09:01:59 - - [ Hardware ] - --= uC: AT91SAM7S512 Rev A - --= Embedded Processor: ARM7TDMI - --= Internal SRAM size: 64K bytes - --= Architecture identifier: AT91SAM7Sxx Series - --= Embedded flash memory 512K bytes ( 59% used ) + MCU....... AT91SAM7S512 Rev A + Memory.... 512 Kb ( 66% used ) + Client.... Iceman/master/v4.16191 2023-02-08 22:54:30 + Bootrom... Iceman/master/v4.16191 2023-02-08 22:54:26 + OS........ Iceman/master/v4.16191 2023-02-08 22:54:27 + Target.... RDV4 + [usb] pm3 --> ``` From b0dcfdf2c5f9a56f8f0e4585cc6f2a40c5d7b38b Mon Sep 17 00:00:00 2001 From: ah01 Date: Thu, 9 Feb 2023 01:22:04 +0100 Subject: [PATCH 598/759] Add new UID of Waveshare 1.54" NFC ePaper (probably new HW revision) --- client/src/cmdhfwaveshare.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfwaveshare.c b/client/src/cmdhfwaveshare.c index 78c6ef825..8df62bcc1 100644 --- a/client/src/cmdhfwaveshare.c +++ b/client/src/cmdhfwaveshare.c @@ -712,17 +712,17 @@ static int start_drawing(uint8_t model_nr, uint8_t *black, uint8_t *red) { return PM3_ESOFT; } - if ((card.uidlen != 7) || ((memcmp(card.uid, "FSTN10m", 7) != 0) && (memcmp(card.uid, "WSDZ10m", 7) != 0))) { + if ((card.uidlen != 7) || ((memcmp(card.uid, "FSTN10m", 7) != 0) && (memcmp(card.uid, "FSTN11m", 7) != 0) && (memcmp(card.uid, "WSDZ10m", 7) != 0))) { PrintAndLogEx(WARNING, "Card doesn't look like Waveshare tag"); DropField(); return PM3_ESOFT; } - if (((model_nr != M1in54B) && (memcmp(card.uid, "FSTN10m", 7) == 0))) { + if (((model_nr != M1in54B) && ((memcmp(card.uid, "FSTN10m", 7) == 0) || (memcmp(card.uid, "FSTN11m", 7) == 0)))) { PrintAndLogEx(WARNING, "Card is a Waveshare tag 1.54\", not %s", models[model_nr].desc); DropField(); return PM3_ESOFT; } - if (((model_nr == M1in54B) && (memcmp(card.uid, "FSTN10m", 7) != 0))) { + if (((model_nr == M1in54B) && (memcmp(card.uid, "FSTN10m", 7) != 0) && (memcmp(card.uid, "FSTN11m", 7) != 0))) { PrintAndLogEx(WARNING, "Card is not a Waveshare tag 1.54\", check your model number"); DropField(); return PM3_ESOFT; From b1fb181f7171caf0605939d1180c331acff55c12 Mon Sep 17 00:00:00 2001 From: Nate Sales Date: Wed, 8 Feb 2023 20:31:40 -0500 Subject: [PATCH 599/759] feat: add standalone ICECLASS read/sim mode --- CHANGELOG.md | 1 + armsrc/Standalone/hf_iceclass.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81df05142..a86fac6e1 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] + - Add ICECLASS standalone read/sim mode (@natesales) - Fixed `lf em 4x70 brute` - now works as expected (@adite) - Fixed the lf sampling when bits_per_sample is less than 8 (@wh201906) - Added `lf em 4x70 brute` command (@adite) diff --git a/armsrc/Standalone/hf_iceclass.c b/armsrc/Standalone/hf_iceclass.c index 7d69e867a..9b9a03ed5 100644 --- a/armsrc/Standalone/hf_iceclass.c +++ b/armsrc/Standalone/hf_iceclass.c @@ -43,9 +43,10 @@ #define ICE_STATE_ATTACK 2 #define ICE_STATE_READER 3 #define ICE_STATE_CONFIGCARD 4 -#define ICE_STATE_DUMP_SIM 5 +#define ICE_STATE_DUMP_SIM 5 +#define ICE_STATE_READ_SIM 6 -#define HF_ICLASS_NUM_MODES 6 +#define HF_ICLASS_NUM_MODES 7 // ==================================================== // Select which standalone function to be active. @@ -56,6 +57,7 @@ //#define ICE_USE ICE_STATE_READER //#define ICE_USE ICE_STATE_CONFIGCARD //#define ICE_USE ICE_STATE_DUMP_SIM +//#define ICE_USE ICE_STATE_READ_SIM // ==================================================== @@ -720,6 +722,15 @@ void RunMod(void) { mode = ICE_STATE_NONE; break; } + case ICE_STATE_READ_SIM: { + DbpString("Entering reader dump mode"); + reader_dump_mode(); + SpinDelay(1200); // debounce button press + DbpString("Entering fullsim mode"); + fullsim_mode(); + DbpString("Exiting fullsim mode"); + LEDsoff(); + } } } From 5133d4a512be5cffb579e0e55e6aee2ad6362bf4 Mon Sep 17 00:00:00 2001 From: Nate Sales Date: Wed, 8 Feb 2023 19:58:07 -0500 Subject: [PATCH 600/759] feat: add -v verbose flag to "hf iclass encode" --- CHANGELOG.md | 1 + client/src/cmdhficlass.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81df05142..e1ef467cb 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] + - Added verbose flag to `hf iclass encode` (@natesales) - Fixed `lf em 4x70 brute` - now works as expected (@adite) - Fixed the lf sampling when bits_per_sample is less than 8 (@wh201906) - Added `lf em 4x70 brute` command (@adite) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 94d710f98..36bd3b3d2 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -3832,6 +3832,7 @@ static int CmdHFiClassEncode(const char *Cmd) { arg_u64_0(NULL, "cn", "", "card number"), arg_str0("w", "wiegand", "", "see " _YELLOW_("`wiegand list`") " for available formats"), arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"), + arg_lit0("v", NULL, "verbose (print encoded blocks)"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -3877,6 +3878,7 @@ static int CmdHFiClassEncode(const char *Cmd) { CLIParamStrToBuf(arg_get_str(ctx, 9), (uint8_t *)format, sizeof(format), &format_len); bool shallow_mod = arg_get_lit(ctx, 10); + bool verbose = arg_get_lit(ctx, 11); CLIParserFree(ctx); @@ -3996,6 +3998,17 @@ static int CmdHFiClassEncode(const char *Cmd) { iclass_encrypt_block_data(credential + 24, enc_key); } + if (verbose) { + for (uint8_t i = 0; i < 4; i++) { + PrintAndLogEx(INFO, "Block %d/0x0%x -> " _YELLOW_("%s"), 6 + i, 6 + i, sprint_hex_inrow(credential + (i * 8), 8)); + } + } + + if (!g_session.pm3_present) { + PrintAndLogEx(ERR, "Device offline\n"); + return PM3_EFAILED; + } + int isok = PM3_SUCCESS; // write for (uint8_t i = 0; i < 4; i++) { From 55f85a82c979fe77427d3d4a61099222c2a8ce11 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Wed, 8 Feb 2023 23:01:50 -0800 Subject: [PATCH 601/759] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81df05142..b5cc2ea57 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 `Makefile` regression that broke `make install` (@henrygab) - Fixed `lf em 4x70 brute` - now works as expected (@adite) - Fixed the lf sampling when bits_per_sample is less than 8 (@wh201906) - Added `lf em 4x70 brute` command (@adite) From a7b699b27e07460a852bc4202311bd278053dffb Mon Sep 17 00:00:00 2001 From: Yann GASCUEL <34003959+lnv42@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:24:58 +0100 Subject: [PATCH 602/759] fix infinity loop in SpinDelayUs() and SpinDelayUsPrecision() I don't know why : but AT91C_BASE_PWMC_CH0->PWMC_CCNTR value is never equal to 0, so if start+ticks was equal to 0, it was inifity looping. This fix may produce bit longer wait than expected in some case, depending on if AT91C_BASE_PWMC_CH0->PWMC_CCNTR delay between 0xFFFF and 0x0001 is just 1 step or 2... /!\ Figure out why AT91C_BASE_PWMC_CH0->PWMC_CCNTR is never 0 and fix it there is probably a better way to fix this infinity loop issue /!\ --- armsrc/ticks.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/armsrc/ticks.c b/armsrc/ticks.c index 61089595c..3cf2c54dc 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -35,11 +35,14 @@ void SpinDelayUsPrecision(int us) { AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xFFFF; // Channel Period Register - uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + uint16_t end = AT91C_BASE_PWMC_CH0->PWMC_CCNTR + ticks; + if (end == 0) // AT91C_BASE_PWMC_CH0->PWMC_CCNTR is never == 0 + end++; // so we have to end++ to avoid inivity loop for (;;) { uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - if (now == (uint16_t)(start + ticks)) + + if (now == end) return; WDT_HIT(); @@ -59,13 +62,15 @@ void SpinDelayUs(int us) { AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; // Channel Period Register - uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + uint16_t end = AT91C_BASE_PWMC_CH0->PWMC_CCNTR + ticks; + if (end == 0) // AT91C_BASE_PWMC_CH0->PWMC_CCNTR is never == 0 + end++; // so we have to end++ to avoid inivity loop for (;;) { uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - if (now == (uint16_t)(start + ticks)) - return; + if (now == end) + return; WDT_HIT(); } } From c42aa99d050deff733259a98c030a86443815f47 Mon Sep 17 00:00:00 2001 From: Nate Sales Date: Fri, 10 Feb 2023 21:55:23 -0500 Subject: [PATCH 603/759] refactor: add iceclass read sim info --- armsrc/Standalone/hf_iceclass.c | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/Standalone/hf_iceclass.c b/armsrc/Standalone/hf_iceclass.c index 9b9a03ed5..481475bbc 100644 --- a/armsrc/Standalone/hf_iceclass.c +++ b/armsrc/Standalone/hf_iceclass.c @@ -723,6 +723,7 @@ void RunMod(void) { break; } case ICE_STATE_READ_SIM: { + DbpString("-=[ enter " _CYAN_("`read & sim`") " mode, read cards, then sim after button press ]=-"); DbpString("Entering reader dump mode"); reader_dump_mode(); SpinDelay(1200); // debounce button press From 08d2c2f1a59a805417f9f2dabe18f9ac369448b9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 11 Feb 2023 11:42:58 +0100 Subject: [PATCH 604/759] style --- armsrc/em4x70.c | 4 +- armsrc/lfsampling.c | 3 +- client/src/pm3line_vocabulory.h | 1502 +++++++++++++++---------------- 3 files changed, 754 insertions(+), 755 deletions(-) diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 066aad58f..806442f7f 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -367,7 +367,7 @@ static int bruteforce(const uint8_t address, const uint8_t *rnd, const uint8_t * for (int k = start_key; k <= 0xFFFF; ++k) { int c = 0; - + WDT_HIT(); uint16_t rev_k = reflect16(k); @@ -405,7 +405,7 @@ static int bruteforce(const uint8_t address, const uint8_t *rnd, const uint8_t * if ((k % 0x100) == 0) { Dbprintf("Trying: %04X", k); } - + // Due to performance reason, we only try it once. Therefore you need a very stable RFID communcation. if (authenticate(temp_rnd, frnd, auth_resp) == PM3_SUCCESS) { if (g_dbglevel >= DBG_INFO) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index e716fa248..a56e013ee 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -370,8 +370,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in } // Ensure that DC offset removal and noise check is performed for any device-side processing - if (bits_per_sample == 8) - { + if (bits_per_sample == 8) { // these functions only consider bps==8 removeSignalOffset(data.buffer, samples.total_saved); computeSignalProperties(data.buffer, samples.total_saved); diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index bcf196fe9..b6d08d325 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -31,756 +31,756 @@ typedef struct vocabulory_s { } vocabulory_t; const static vocabulory_t vocabulory[] = { - { 1, "help" }, - { 0, "auto" }, - { 1, "clear" }, - { 1, "hints" }, - { 1, "msleep" }, - { 1, "rem" }, - { 1, "quit" }, - { 1, "exit" }, - { 1, "prefs help" }, - { 1, "prefs show" }, - { 1, "prefs get barmode" }, - { 1, "prefs get clientdebug" }, - { 1, "prefs get clientdelay" }, - { 1, "prefs get color" }, - { 1, "prefs get savepaths" }, - { 1, "prefs get emoji" }, - { 1, "prefs get hints" }, - { 1, "prefs get output" }, - { 1, "prefs get plotsliders" }, - { 1, "prefs set help" }, - { 1, "prefs set barmode" }, - { 1, "prefs set clientdebug" }, - { 1, "prefs set clientdelay" }, - { 1, "prefs set color" }, - { 1, "prefs set emoji" }, - { 1, "prefs set hints" }, - { 1, "prefs set savepaths" }, - { 1, "prefs set output" }, - { 1, "prefs set plotsliders" }, - { 1, "analyse help" }, - { 1, "analyse lcr" }, - { 1, "analyse crc" }, - { 1, "analyse chksum" }, - { 1, "analyse dates" }, - { 1, "analyse lfsr" }, - { 1, "analyse a" }, - { 1, "analyse nuid" }, - { 1, "analyse demodbuff" }, - { 1, "analyse freq" }, - { 1, "analyse foo" }, - { 1, "analyse units" }, - { 1, "data help" }, - { 1, "data biphaserawdecode" }, - { 1, "data detectclock" }, - { 1, "data fsktonrz" }, - { 1, "data manrawdecode" }, - { 1, "data modulation" }, - { 1, "data rawdemod" }, - { 1, "data askedgedetect" }, - { 1, "data autocorr" }, - { 1, "data dirthreshold" }, - { 1, "data decimate" }, - { 1, "data undecimate" }, - { 1, "data hide" }, - { 1, "data hpf" }, - { 1, "data iir" }, - { 1, "data grid" }, - { 1, "data ltrim" }, - { 1, "data mtrim" }, - { 1, "data norm" }, - { 1, "data plot" }, - { 1, "data rtrim" }, - { 1, "data setgraphmarkers" }, - { 1, "data shiftgraphzero" }, - { 1, "data timescale" }, - { 1, "data zerocrossings" }, - { 1, "data convertbitstream" }, - { 1, "data getbitstream" }, - { 1, "data asn1" }, - { 1, "data bin2hex" }, - { 0, "data bitsamples" }, - { 1, "data clear" }, - { 1, "data diff" }, - { 0, "data hexsamples" }, - { 1, "data hex2bin" }, - { 1, "data load" }, - { 1, "data print" }, - { 0, "data samples" }, - { 1, "data save" }, - { 1, "data setdebugmode" }, - { 0, "data tune" }, - { 1, "emv help" }, - { 0, "emv exec" }, - { 0, "emv pse" }, - { 0, "emv search" }, - { 0, "emv select" }, - { 0, "emv gpo" }, - { 0, "emv readrec" }, - { 0, "emv genac" }, - { 0, "emv challenge" }, - { 0, "emv intauth" }, - { 0, "emv scan" }, - { 1, "emv test" }, - { 1, "emv list" }, - { 0, "emv roca" }, - { 1, "hf help" }, - { 1, "hf list" }, - { 0, "hf plot" }, - { 0, "hf tune" }, - { 1, "hf search" }, - { 0, "hf sniff" }, - { 1, "hf 14a help" }, - { 1, "hf 14a list" }, - { 0, "hf 14a antifuzz" }, - { 0, "hf 14a config" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a info" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a raw" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a apdufind" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a ndefformat" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a ndefwrite" }, - { 1, "hf 14b help" }, - { 0, "hf 14b apdu" }, - { 0, "hf 14b dump" }, - { 0, "hf 14b info" }, - { 1, "hf 14b list" }, - { 0, "hf 14b ndefread" }, - { 0, "hf 14b raw" }, - { 0, "hf 14b reader" }, - { 0, "hf 14b sim" }, - { 0, "hf 14b sniff" }, - { 0, "hf 14b rdbl" }, - { 0, "hf 14b sriwrite" }, - { 1, "hf 14b view" }, - { 1, "hf 15 help" }, - { 1, "hf 15 list" }, - { 1, "hf 15 demod" }, - { 0, "hf 15 dump" }, - { 0, "hf 15 info" }, - { 0, "hf 15 sniff" }, - { 0, "hf 15 raw" }, - { 0, "hf 15 rdbl" }, - { 0, "hf 15 rdmulti" }, - { 0, "hf 15 reader" }, - { 0, "hf 15 restore" }, - { 0, "hf 15 samples" }, - { 0, "hf 15 eload" }, - { 0, "hf 15 esave" }, - { 0, "hf 15 eview" }, - { 0, "hf 15 sim" }, - { 0, "hf 15 slixwritepwd" }, - { 0, "hf 15 slixeasdisable" }, - { 0, "hf 15 slixeasenable" }, - { 0, "hf 15 slixprivacydisable" }, - { 0, "hf 15 slixprivacyenable" }, - { 0, "hf 15 passprotectafi" }, - { 0, "hf 15 passprotecteas" }, - { 0, "hf 15 wrbl" }, - { 0, "hf 15 findafi" }, - { 0, "hf 15 writeafi" }, - { 0, "hf 15 writedsfid" }, - { 0, "hf 15 csetuid" }, - { 1, "hf cipurse help" }, - { 0, "hf cipurse info" }, - { 0, "hf cipurse select" }, - { 0, "hf cipurse auth" }, - { 0, "hf cipurse read" }, - { 0, "hf cipurse write" }, - { 0, "hf cipurse aread" }, - { 0, "hf cipurse awrite" }, - { 0, "hf cipurse formatall" }, - { 0, "hf cipurse create" }, - { 0, "hf cipurse delete" }, - { 0, "hf cipurse updkey" }, - { 0, "hf cipurse updakey" }, - { 0, "hf cipurse default" }, - { 1, "hf cipurse test" }, - { 1, "hf epa help" }, - { 0, "hf epa cnonces" }, - { 0, "hf epa replay" }, - { 0, "hf epa sim" }, - { 1, "hf emrtd help" }, - { 0, "hf emrtd dump" }, - { 1, "hf emrtd info" }, - { 1, "hf emrtd list" }, - { 1, "hf felica help" }, - { 1, "hf felica list" }, - { 0, "hf felica reader" }, - { 0, "hf felica info" }, - { 0, "hf felica sniff" }, - { 0, "hf felica raw" }, - { 0, "hf felica rdbl" }, - { 0, "hf felica wrbl" }, - { 0, "hf felica rqservice" }, - { 0, "hf felica rqresponse" }, - { 0, "hf felica scsvcode" }, - { 0, "hf felica rqsyscode" }, - { 0, "hf felica auth1" }, - { 0, "hf felica auth2" }, - { 0, "hf felica rqspecver" }, - { 0, "hf felica resetmode" }, - { 0, "hf felica litesim" }, - { 0, "hf felica litedump" }, - { 1, "hf fido help" }, - { 1, "hf fido list" }, - { 0, "hf fido info" }, - { 0, "hf fido reg" }, - { 0, "hf fido auth" }, - { 0, "hf fido make" }, - { 0, "hf fido assert" }, - { 1, "hf fudan help" }, - { 0, "hf fudan reader" }, - { 0, "hf fudan dump" }, - { 0, "hf fudan rdbl" }, - { 1, "hf fudan view" }, - { 0, "hf fudan wrbl" }, - { 1, "hf gallagher help" }, - { 0, "hf gallagher reader" }, - { 0, "hf gallagher clone" }, - { 0, "hf gallagher delete" }, - { 1, "hf gallagher diversifykey" }, - { 1, "hf gallagher decode" }, - { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 select" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 init" }, - { 0, "hf ksx6924 prec" }, - { 1, "hf jooki help" }, - { 0, "hf jooki clone" }, - { 1, "hf jooki decode" }, - { 1, "hf jooki encode" }, - { 0, "hf jooki sim" }, - { 1, "hf iclass help" }, - { 0, "hf iclass dump" }, - { 1, "hf iclass info" }, - { 1, "hf iclass list" }, - { 0, "hf iclass rdbl" }, - { 0, "hf iclass reader" }, - { 0, "hf iclass restore" }, - { 0, "hf iclass sniff" }, - { 0, "hf iclass wrbl" }, - { 0, "hf iclass chk" }, - { 1, "hf iclass loclass" }, - { 1, "hf iclass lookup" }, - { 0, "hf iclass sim" }, - { 0, "hf iclass eload" }, - { 0, "hf iclass esave" }, - { 0, "hf iclass eview" }, - { 1, "hf iclass configcard" }, - { 1, "hf iclass calcnewkey" }, - { 1, "hf iclass encode" }, - { 1, "hf iclass encrypt" }, - { 1, "hf iclass decrypt" }, - { 1, "hf iclass managekeys" }, - { 1, "hf iclass permutekey" }, - { 1, "hf iclass view" }, - { 1, "hf legic help" }, - { 0, "hf legic dump" }, - { 0, "hf legic info" }, - { 1, "hf legic list" }, - { 0, "hf legic rdbl" }, - { 0, "hf legic reader" }, - { 0, "hf legic restore" }, - { 0, "hf legic wipe" }, - { 0, "hf legic wrbl" }, - { 0, "hf legic sim" }, - { 0, "hf legic eload" }, - { 0, "hf legic esave" }, - { 0, "hf legic eview" }, - { 1, "hf legic crc" }, - { 1, "hf legic view" }, - { 1, "hf lto help" }, - { 0, "hf lto dump" }, - { 0, "hf lto info" }, - { 1, "hf lto list" }, - { 0, "hf lto rdbl" }, - { 0, "hf lto reader" }, - { 0, "hf lto restore" }, - { 0, "hf lto wrbl" }, - { 1, "hf mf help" }, - { 1, "hf mf list" }, - { 0, "hf mf darkside" }, - { 0, "hf mf nested" }, - { 1, "hf mf hardnested" }, - { 0, "hf mf staticnested" }, - { 0, "hf mf autopwn" }, - { 0, "hf mf nack" }, - { 0, "hf mf chk" }, - { 0, "hf mf fchk" }, - { 1, "hf mf decrypt" }, - { 0, "hf mf supercard" }, - { 0, "hf mf auth4" }, - { 1, "hf mf acl" }, - { 0, "hf mf dump" }, - { 1, "hf mf mad" }, - { 0, "hf mf personalize" }, - { 0, "hf mf rdbl" }, - { 0, "hf mf rdsc" }, - { 0, "hf mf restore" }, - { 0, "hf mf setmod" }, - { 1, "hf mf value" }, - { 1, "hf mf view" }, - { 0, "hf mf wipe" }, - { 0, "hf mf wrbl" }, - { 0, "hf mf sim" }, - { 0, "hf mf ecfill" }, - { 0, "hf mf eclr" }, - { 0, "hf mf egetblk" }, - { 0, "hf mf egetsc" }, - { 0, "hf mf ekeyprn" }, - { 0, "hf mf eload" }, - { 0, "hf mf esave" }, - { 0, "hf mf esetblk" }, - { 0, "hf mf eview" }, - { 0, "hf mf cgetblk" }, - { 0, "hf mf cgetsc" }, - { 0, "hf mf cload" }, - { 0, "hf mf csave" }, - { 0, "hf mf csetblk" }, - { 0, "hf mf csetuid" }, - { 0, "hf mf cview" }, - { 0, "hf mf cwipe" }, - { 0, "hf mf gen3uid" }, - { 0, "hf mf gen3blk" }, - { 0, "hf mf gen3freeze" }, - { 0, "hf mf ggetblk" }, - { 0, "hf mf gload" }, - { 0, "hf mf gsave" }, - { 0, "hf mf gsetblk" }, - { 0, "hf mf gview" }, - { 0, "hf mf ndefformat" }, - { 0, "hf mf ndefread" }, - { 0, "hf mf ndefwrite" }, - { 1, "hf mfp help" }, - { 0, "hf mfp info" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp commitp" }, - { 0, "hf mfp auth" }, - { 0, "hf mfp rdbl" }, - { 0, "hf mfp rdsc" }, - { 0, "hf mfp wrbl" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp mad" }, - { 0, "hf mfp ndefread" }, - { 1, "hf mfu help" }, - { 1, "hf mfu keygen" }, - { 1, "hf mfu pwdgen" }, - { 0, "hf mfu otptear" }, - { 0, "hf mfu cauth" }, - { 0, "hf mfu dump" }, - { 0, "hf mfu info" }, - { 0, "hf mfu ndefread" }, - { 0, "hf mfu rdbl" }, - { 0, "hf mfu restore" }, - { 1, "hf mfu view" }, - { 0, "hf mfu wrbl" }, - { 0, "hf mfu eload" }, - { 0, "hf mfu esave" }, - { 0, "hf mfu eview" }, - { 0, "hf mfu sim" }, - { 0, "hf mfu setpwd" }, - { 0, "hf mfu setuid" }, - { 1, "hf mfdes help" }, - { 0, "hf mfdes info" }, - { 0, "hf mfdes getuid" }, - { 0, "hf mfdes default" }, - { 0, "hf mfdes auth" }, - { 0, "hf mfdes chk" }, - { 0, "hf mfdes detect" }, - { 0, "hf mfdes freemem" }, - { 0, "hf mfdes setconfig" }, - { 0, "hf mfdes formatpicc" }, - { 1, "hf mfdes list" }, - { 0, "hf mfdes mad" }, - { 0, "hf mfdes lsapp" }, - { 0, "hf mfdes getaids" }, - { 0, "hf mfdes getappnames" }, - { 0, "hf mfdes bruteaid" }, - { 0, "hf mfdes createapp" }, - { 0, "hf mfdes deleteapp" }, - { 0, "hf mfdes selectapp" }, - { 0, "hf mfdes changekey" }, - { 0, "hf mfdes chkeysettings" }, - { 0, "hf mfdes getkeysettings" }, - { 0, "hf mfdes getkeyversions" }, - { 0, "hf mfdes getfileids" }, - { 0, "hf mfdes getfileisoids" }, - { 0, "hf mfdes lsfiles" }, - { 0, "hf mfdes dump" }, - { 0, "hf mfdes createfile" }, - { 0, "hf mfdes createvaluefile" }, - { 0, "hf mfdes createrecordfile" }, - { 0, "hf mfdes createmacfile" }, - { 0, "hf mfdes deletefile" }, - { 0, "hf mfdes getfilesettings" }, - { 0, "hf mfdes chfilesettings" }, - { 0, "hf mfdes read" }, - { 0, "hf mfdes write" }, - { 0, "hf mfdes value" }, - { 0, "hf mfdes clearrecfile" }, - { 1, "hf mfdes test" }, - { 1, "hf ntag424 help" }, - { 0, "hf ntag424 info" }, - { 0, "hf ntag424 sdm" }, - { 1, "hf ntag424 view" }, - { 1, "hf seos help" }, - { 0, "hf seos info" }, - { 1, "hf seos list" }, - { 1, "hf st25ta help" }, - { 0, "hf st25ta info" }, - { 1, "hf st25ta list" }, - { 1, "hf st25ta ndefread" }, - { 0, "hf st25ta protect" }, - { 0, "hf st25ta pwd" }, - { 0, "hf st25ta sim" }, - { 1, "hf tesla help" }, - { 0, "hf tesla info" }, - { 1, "hf tesla list" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, - { 1, "hf thinfilm help" }, - { 0, "hf thinfilm info" }, - { 1, "hf thinfilm list" }, - { 0, "hf thinfilm sim" }, - { 1, "hf topaz help" }, - { 0, "hf topaz dump" }, - { 1, "hf topaz list" }, - { 0, "hf topaz info" }, - { 0, "hf topaz reader" }, - { 0, "hf topaz sim" }, - { 0, "hf topaz sniff" }, - { 0, "hf topaz raw" }, - { 0, "hf topaz rdbl" }, - { 1, "hf topaz view" }, - { 0, "hf topaz wrbl" }, - { 1, "hf xerox help" }, - { 0, "hf xerox info" }, - { 0, "hf xerox reader" }, - { 0, "hf xerox dump" }, - { 1, "hf waveshare help" }, - { 0, "hf waveshare loadbmp" }, - { 1, "hw help" }, - { 0, "hw break" }, - { 1, "hw connect" }, - { 0, "hw dbg" }, - { 0, "hw detectreader" }, - { 0, "hw fpgaoff" }, - { 0, "hw lcd" }, - { 0, "hw lcdreset" }, - { 0, "hw ping" }, - { 0, "hw readmem" }, - { 0, "hw reset" }, - { 0, "hw setlfdivisor" }, - { 0, "hw setmux" }, - { 0, "hw standalone" }, - { 0, "hw status" }, - { 0, "hw tearoff" }, - { 0, "hw tia" }, - { 0, "hw tune" }, - { 1, "hw version" }, - { 1, "lf help" }, - { 0, "lf config" }, - { 0, "lf cmdread" }, - { 0, "lf read" }, - { 1, "lf search" }, - { 0, "lf sim" }, - { 0, "lf simask" }, - { 0, "lf simfsk" }, - { 0, "lf simpsk" }, - { 0, "lf simbidir" }, - { 0, "lf sniff" }, - { 0, "lf tune" }, - { 1, "lf awid help" }, - { 1, "lf awid demod" }, - { 0, "lf awid reader" }, - { 0, "lf awid clone" }, - { 0, "lf awid sim" }, - { 0, "lf awid brute" }, - { 0, "lf awid watch" }, - { 1, "lf cotag help" }, - { 1, "lf cotag demod" }, - { 0, "lf cotag reader" }, - { 1, "lf destron help" }, - { 1, "lf destron demod" }, - { 0, "lf destron reader" }, - { 0, "lf destron clone" }, - { 0, "lf destron sim" }, - { 1, "lf em help" }, - { 1, "lf em 410x help" }, - { 1, "lf em 410x demod" }, - { 0, "lf em 410x reader" }, - { 0, "lf em 410x sim" }, - { 0, "lf em 410x brute" }, - { 0, "lf em 410x watch" }, - { 0, "lf em 410x spoof" }, - { 0, "lf em 410x clone" }, - { 1, "lf em 4x05 help" }, - { 0, "lf em 4x05 brute" }, - { 0, "lf em 4x05 chk" }, - { 1, "lf em 4x05 demod" }, - { 0, "lf em 4x05 dump" }, - { 0, "lf em 4x05 info" }, - { 0, "lf em 4x05 read" }, - { 1, "lf em 4x05 sniff" }, - { 0, "lf em 4x05 unlock" }, - { 0, "lf em 4x05 wipe" }, - { 0, "lf em 4x05 write" }, - { 1, "lf em 4x50 help" }, - { 0, "lf em 4x50 brute" }, - { 0, "lf em 4x50 chk" }, - { 0, "lf em 4x50 dump" }, - { 0, "lf em 4x50 info" }, - { 0, "lf em 4x50 login" }, - { 0, "lf em 4x50 rdbl" }, - { 0, "lf em 4x50 reader" }, - { 0, "lf em 4x50 restore" }, - { 0, "lf em 4x50 wrbl" }, - { 0, "lf em 4x50 wrpwd" }, - { 0, "lf em 4x50 wipe" }, - { 0, "lf em 4x50 eload" }, - { 0, "lf em 4x50 esave" }, - { 0, "lf em 4x50 eview" }, - { 0, "lf em 4x50 sim" }, - { 1, "lf em 4x70 help" }, - { 0, "lf em 4x70 info" }, - { 0, "lf em 4x70 write" }, - { 0, "lf em 4x70 unlock" }, - { 0, "lf em 4x70 auth" }, - { 0, "lf em 4x70 writepin" }, - { 0, "lf em 4x70 writekey" }, - { 1, "lf fdxb help" }, - { 1, "lf fdxb demod" }, - { 0, "lf fdxb reader" }, - { 0, "lf fdxb clone" }, - { 0, "lf fdxb sim" }, - { 1, "lf gallagher help" }, - { 1, "lf gallagher demod" }, - { 0, "lf gallagher reader" }, - { 0, "lf gallagher clone" }, - { 0, "lf gallagher sim" }, - { 1, "lf gproxii help" }, - { 1, "lf gproxii demod" }, - { 0, "lf gproxii reader" }, - { 0, "lf gproxii clone" }, - { 0, "lf gproxii sim" }, - { 1, "lf hid help" }, - { 1, "lf hid demod" }, - { 0, "lf hid reader" }, - { 0, "lf hid clone" }, - { 0, "lf hid sim" }, - { 0, "lf hid brute" }, - { 0, "lf hid watch" }, - { 1, "lf hitag help" }, - { 0, "lf hitag eload" }, - { 1, "lf hitag list" }, - { 0, "lf hitag info" }, - { 0, "lf hitag reader" }, - { 0, "lf hitag sim" }, - { 0, "lf hitag sniff" }, - { 0, "lf hitag writer" }, - { 0, "lf hitag dump" }, - { 0, "lf hitag cc" }, - { 1, "lf idteck help" }, - { 1, "lf idteck demod" }, - { 0, "lf idteck reader" }, - { 0, "lf idteck clone" }, - { 0, "lf idteck sim" }, - { 1, "lf indala help" }, - { 0, "lf indala brute" }, - { 1, "lf indala demod" }, - { 1, "lf indala altdemod" }, - { 0, "lf indala reader" }, - { 0, "lf indala clone" }, - { 0, "lf indala sim" }, - { 1, "lf io help" }, - { 1, "lf io demod" }, - { 0, "lf io reader" }, - { 0, "lf io clone" }, - { 0, "lf io sim" }, - { 0, "lf io watch" }, - { 1, "lf jablotron help" }, - { 1, "lf jablotron demod" }, - { 0, "lf jablotron reader" }, - { 0, "lf jablotron clone" }, - { 0, "lf jablotron sim" }, - { 1, "lf keri help" }, - { 1, "lf keri demod" }, - { 0, "lf keri reader" }, - { 0, "lf keri clone" }, - { 0, "lf keri sim" }, - { 1, "lf motorola help" }, - { 1, "lf motorola demod" }, - { 0, "lf motorola reader" }, - { 0, "lf motorola clone" }, - { 0, "lf motorola sim" }, - { 1, "lf nedap help" }, - { 1, "lf nedap demod" }, - { 0, "lf nedap reader" }, - { 0, "lf nedap clone" }, - { 0, "lf nedap sim" }, - { 1, "lf nexwatch help" }, - { 1, "lf nexwatch demod" }, - { 0, "lf nexwatch reader" }, - { 0, "lf nexwatch clone" }, - { 0, "lf nexwatch sim" }, - { 1, "lf noralsy help" }, - { 1, "lf noralsy demod" }, - { 0, "lf noralsy reader" }, - { 0, "lf noralsy clone" }, - { 0, "lf noralsy sim" }, - { 1, "lf pac help" }, - { 1, "lf pac demod" }, - { 0, "lf pac reader" }, - { 0, "lf pac clone" }, - { 0, "lf pac sim" }, - { 1, "lf paradox help" }, - { 1, "lf paradox demod" }, - { 0, "lf paradox reader" }, - { 0, "lf paradox clone" }, - { 0, "lf paradox sim" }, - { 1, "lf pcf7931 help" }, - { 0, "lf pcf7931 reader" }, - { 0, "lf pcf7931 write" }, - { 1, "lf pcf7931 config" }, - { 1, "lf presco help" }, - { 1, "lf presco demod" }, - { 0, "lf presco reader" }, - { 0, "lf presco clone" }, - { 0, "lf presco sim" }, - { 1, "lf pyramid help" }, - { 1, "lf pyramid demod" }, - { 0, "lf pyramid reader" }, - { 0, "lf pyramid clone" }, - { 0, "lf pyramid sim" }, - { 1, "lf securakey help" }, - { 1, "lf securakey demod" }, - { 0, "lf securakey reader" }, - { 0, "lf securakey clone" }, - { 0, "lf securakey sim" }, - { 1, "lf ti help" }, - { 1, "lf ti demod" }, - { 0, "lf ti reader" }, - { 0, "lf ti write" }, - { 1, "lf t55xx help" }, - { 0, "lf t55xx clonehelp" }, - { 1, "lf t55xx config" }, - { 0, "lf t55xx dangerraw" }, - { 1, "lf t55xx detect" }, - { 0, "lf t55xx deviceconfig" }, - { 0, "lf t55xx dump" }, - { 1, "lf t55xx info" }, - { 0, "lf t55xx p1detect" }, - { 0, "lf t55xx read" }, - { 0, "lf t55xx resetread" }, - { 0, "lf t55xx restore" }, - { 1, "lf t55xx trace" }, - { 0, "lf t55xx wakeup" }, - { 0, "lf t55xx write" }, - { 0, "lf t55xx bruteforce" }, - { 0, "lf t55xx chk" }, - { 0, "lf t55xx protect" }, - { 0, "lf t55xx recoverpw" }, - { 1, "lf t55xx sniff" }, - { 0, "lf t55xx special" }, - { 0, "lf t55xx wipe" }, - { 1, "lf viking help" }, - { 1, "lf viking demod" }, - { 0, "lf viking reader" }, - { 0, "lf viking clone" }, - { 0, "lf viking sim" }, - { 1, "lf visa2000 help" }, - { 1, "lf visa2000 demod" }, - { 0, "lf visa2000 reader" }, - { 0, "lf visa2000 clone" }, - { 0, "lf visa2000 sim" }, - { 1, "mem help" }, - { 0, "mem baudrate" }, - { 0, "mem dump" }, - { 0, "mem info" }, - { 0, "mem load" }, - { 0, "mem wipe" }, - { 1, "mem spiffs help" }, - { 0, "mem spiffs copy" }, - { 0, "mem spiffs check" }, - { 0, "mem spiffs dump" }, - { 0, "mem spiffs info" }, - { 0, "mem spiffs mount" }, - { 0, "mem spiffs remove" }, - { 0, "mem spiffs rename" }, - { 0, "mem spiffs test" }, - { 0, "mem spiffs tree" }, - { 0, "mem spiffs unmount" }, - { 0, "mem spiffs upload" }, - { 0, "mem spiffs view" }, - { 0, "mem spiffs wipe" }, - { 1, "nfc help" }, - { 1, "nfc decode" }, - { 0, "nfc type1 read" }, - { 1, "nfc type1 help" }, - { 0, "nfc type2 read" }, - { 1, "nfc type2 help" }, - { 0, "nfc type4a format" }, - { 0, "nfc type4a read" }, - { 0, "nfc type4a write" }, - { 0, "nfc type4a st25taread" }, - { 1, "nfc type4a help" }, - { 0, "nfc type4b read" }, - { 1, "nfc type4b help" }, - { 0, "nfc mf cformat" }, - { 0, "nfc mf cread" }, - { 0, "nfc mf cwrite" }, - { 0, "nfc mf pread" }, - { 1, "nfc mf help" }, - { 0, "nfc barcode read" }, - { 0, "nfc barcode sim" }, - { 1, "nfc barcode help" }, - { 1, "piv help" }, - { 0, "piv select" }, - { 0, "piv getdata" }, - { 0, "piv authsign" }, - { 0, "piv scan" }, - { 1, "piv list" }, - { 1, "smart help" }, - { 1, "smart list" }, - { 0, "smart info" }, - { 0, "smart reader" }, - { 0, "smart raw" }, - { 1, "smart upgrade" }, - { 0, "smart setclock" }, - { 0, "smart brute" }, - { 1, "script help" }, - { 1, "script list" }, - { 1, "script run" }, - { 1, "trace help" }, - { 1, "trace extract" }, - { 1, "trace list" }, - { 1, "trace load" }, - { 1, "trace save" }, - { 1, "usart help" }, - { 0, "usart btpin" }, - { 0, "usart btfactory" }, - { 0, "usart tx" }, - { 0, "usart rx" }, - { 0, "usart txrx" }, - { 0, "usart txhex" }, - { 0, "usart rxhex" }, - { 0, "usart config" }, - { 1, "wiegand help" }, - { 1, "wiegand list" }, - { 1, "wiegand encode" }, - { 1, "wiegand decode" }, + { 1, "help" }, + { 0, "auto" }, + { 1, "clear" }, + { 1, "hints" }, + { 1, "msleep" }, + { 1, "rem" }, + { 1, "quit" }, + { 1, "exit" }, + { 1, "prefs help" }, + { 1, "prefs show" }, + { 1, "prefs get barmode" }, + { 1, "prefs get clientdebug" }, + { 1, "prefs get clientdelay" }, + { 1, "prefs get color" }, + { 1, "prefs get savepaths" }, + { 1, "prefs get emoji" }, + { 1, "prefs get hints" }, + { 1, "prefs get output" }, + { 1, "prefs get plotsliders" }, + { 1, "prefs set help" }, + { 1, "prefs set barmode" }, + { 1, "prefs set clientdebug" }, + { 1, "prefs set clientdelay" }, + { 1, "prefs set color" }, + { 1, "prefs set emoji" }, + { 1, "prefs set hints" }, + { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, + { 1, "prefs set plotsliders" }, + { 1, "analyse help" }, + { 1, "analyse lcr" }, + { 1, "analyse crc" }, + { 1, "analyse chksum" }, + { 1, "analyse dates" }, + { 1, "analyse lfsr" }, + { 1, "analyse a" }, + { 1, "analyse nuid" }, + { 1, "analyse demodbuff" }, + { 1, "analyse freq" }, + { 1, "analyse foo" }, + { 1, "analyse units" }, + { 1, "data help" }, + { 1, "data biphaserawdecode" }, + { 1, "data detectclock" }, + { 1, "data fsktonrz" }, + { 1, "data manrawdecode" }, + { 1, "data modulation" }, + { 1, "data rawdemod" }, + { 1, "data askedgedetect" }, + { 1, "data autocorr" }, + { 1, "data dirthreshold" }, + { 1, "data decimate" }, + { 1, "data undecimate" }, + { 1, "data hide" }, + { 1, "data hpf" }, + { 1, "data iir" }, + { 1, "data grid" }, + { 1, "data ltrim" }, + { 1, "data mtrim" }, + { 1, "data norm" }, + { 1, "data plot" }, + { 1, "data rtrim" }, + { 1, "data setgraphmarkers" }, + { 1, "data shiftgraphzero" }, + { 1, "data timescale" }, + { 1, "data zerocrossings" }, + { 1, "data convertbitstream" }, + { 1, "data getbitstream" }, + { 1, "data asn1" }, + { 1, "data bin2hex" }, + { 0, "data bitsamples" }, + { 1, "data clear" }, + { 1, "data diff" }, + { 0, "data hexsamples" }, + { 1, "data hex2bin" }, + { 1, "data load" }, + { 1, "data print" }, + { 0, "data samples" }, + { 1, "data save" }, + { 1, "data setdebugmode" }, + { 0, "data tune" }, + { 1, "emv help" }, + { 0, "emv exec" }, + { 0, "emv pse" }, + { 0, "emv search" }, + { 0, "emv select" }, + { 0, "emv gpo" }, + { 0, "emv readrec" }, + { 0, "emv genac" }, + { 0, "emv challenge" }, + { 0, "emv intauth" }, + { 0, "emv scan" }, + { 1, "emv test" }, + { 1, "emv list" }, + { 0, "emv roca" }, + { 1, "hf help" }, + { 1, "hf list" }, + { 0, "hf plot" }, + { 0, "hf tune" }, + { 1, "hf search" }, + { 0, "hf sniff" }, + { 1, "hf 14a help" }, + { 1, "hf 14a list" }, + { 0, "hf 14a antifuzz" }, + { 0, "hf 14a config" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a info" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a apdu" }, + { 0, "hf 14a apdufind" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a ndefformat" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a ndefwrite" }, + { 1, "hf 14b help" }, + { 0, "hf 14b apdu" }, + { 0, "hf 14b dump" }, + { 0, "hf 14b info" }, + { 1, "hf 14b list" }, + { 0, "hf 14b ndefread" }, + { 0, "hf 14b raw" }, + { 0, "hf 14b reader" }, + { 0, "hf 14b sim" }, + { 0, "hf 14b sniff" }, + { 0, "hf 14b rdbl" }, + { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, + { 1, "hf 15 help" }, + { 1, "hf 15 list" }, + { 1, "hf 15 demod" }, + { 0, "hf 15 dump" }, + { 0, "hf 15 info" }, + { 0, "hf 15 sniff" }, + { 0, "hf 15 raw" }, + { 0, "hf 15 rdbl" }, + { 0, "hf 15 rdmulti" }, + { 0, "hf 15 reader" }, + { 0, "hf 15 restore" }, + { 0, "hf 15 samples" }, + { 0, "hf 15 eload" }, + { 0, "hf 15 esave" }, + { 0, "hf 15 eview" }, + { 0, "hf 15 sim" }, + { 0, "hf 15 slixwritepwd" }, + { 0, "hf 15 slixeasdisable" }, + { 0, "hf 15 slixeasenable" }, + { 0, "hf 15 slixprivacydisable" }, + { 0, "hf 15 slixprivacyenable" }, + { 0, "hf 15 passprotectafi" }, + { 0, "hf 15 passprotecteas" }, + { 0, "hf 15 wrbl" }, + { 0, "hf 15 findafi" }, + { 0, "hf 15 writeafi" }, + { 0, "hf 15 writedsfid" }, + { 0, "hf 15 csetuid" }, + { 1, "hf cipurse help" }, + { 0, "hf cipurse info" }, + { 0, "hf cipurse select" }, + { 0, "hf cipurse auth" }, + { 0, "hf cipurse read" }, + { 0, "hf cipurse write" }, + { 0, "hf cipurse aread" }, + { 0, "hf cipurse awrite" }, + { 0, "hf cipurse formatall" }, + { 0, "hf cipurse create" }, + { 0, "hf cipurse delete" }, + { 0, "hf cipurse updkey" }, + { 0, "hf cipurse updakey" }, + { 0, "hf cipurse default" }, + { 1, "hf cipurse test" }, + { 1, "hf epa help" }, + { 0, "hf epa cnonces" }, + { 0, "hf epa replay" }, + { 0, "hf epa sim" }, + { 1, "hf emrtd help" }, + { 0, "hf emrtd dump" }, + { 1, "hf emrtd info" }, + { 1, "hf emrtd list" }, + { 1, "hf felica help" }, + { 1, "hf felica list" }, + { 0, "hf felica reader" }, + { 0, "hf felica info" }, + { 0, "hf felica sniff" }, + { 0, "hf felica raw" }, + { 0, "hf felica rdbl" }, + { 0, "hf felica wrbl" }, + { 0, "hf felica rqservice" }, + { 0, "hf felica rqresponse" }, + { 0, "hf felica scsvcode" }, + { 0, "hf felica rqsyscode" }, + { 0, "hf felica auth1" }, + { 0, "hf felica auth2" }, + { 0, "hf felica rqspecver" }, + { 0, "hf felica resetmode" }, + { 0, "hf felica litesim" }, + { 0, "hf felica litedump" }, + { 1, "hf fido help" }, + { 1, "hf fido list" }, + { 0, "hf fido info" }, + { 0, "hf fido reg" }, + { 0, "hf fido auth" }, + { 0, "hf fido make" }, + { 0, "hf fido assert" }, + { 1, "hf fudan help" }, + { 0, "hf fudan reader" }, + { 0, "hf fudan dump" }, + { 0, "hf fudan rdbl" }, + { 1, "hf fudan view" }, + { 0, "hf fudan wrbl" }, + { 1, "hf gallagher help" }, + { 0, "hf gallagher reader" }, + { 0, "hf gallagher clone" }, + { 0, "hf gallagher delete" }, + { 1, "hf gallagher diversifykey" }, + { 1, "hf gallagher decode" }, + { 1, "hf ksx6924 help" }, + { 0, "hf ksx6924 select" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 init" }, + { 0, "hf ksx6924 prec" }, + { 1, "hf jooki help" }, + { 0, "hf jooki clone" }, + { 1, "hf jooki decode" }, + { 1, "hf jooki encode" }, + { 0, "hf jooki sim" }, + { 1, "hf iclass help" }, + { 0, "hf iclass dump" }, + { 1, "hf iclass info" }, + { 1, "hf iclass list" }, + { 0, "hf iclass rdbl" }, + { 0, "hf iclass reader" }, + { 0, "hf iclass restore" }, + { 0, "hf iclass sniff" }, + { 0, "hf iclass wrbl" }, + { 0, "hf iclass chk" }, + { 1, "hf iclass loclass" }, + { 1, "hf iclass lookup" }, + { 0, "hf iclass sim" }, + { 0, "hf iclass eload" }, + { 0, "hf iclass esave" }, + { 0, "hf iclass eview" }, + { 1, "hf iclass configcard" }, + { 1, "hf iclass calcnewkey" }, + { 1, "hf iclass encode" }, + { 1, "hf iclass encrypt" }, + { 1, "hf iclass decrypt" }, + { 1, "hf iclass managekeys" }, + { 1, "hf iclass permutekey" }, + { 1, "hf iclass view" }, + { 1, "hf legic help" }, + { 0, "hf legic dump" }, + { 0, "hf legic info" }, + { 1, "hf legic list" }, + { 0, "hf legic rdbl" }, + { 0, "hf legic reader" }, + { 0, "hf legic restore" }, + { 0, "hf legic wipe" }, + { 0, "hf legic wrbl" }, + { 0, "hf legic sim" }, + { 0, "hf legic eload" }, + { 0, "hf legic esave" }, + { 0, "hf legic eview" }, + { 1, "hf legic crc" }, + { 1, "hf legic view" }, + { 1, "hf lto help" }, + { 0, "hf lto dump" }, + { 0, "hf lto info" }, + { 1, "hf lto list" }, + { 0, "hf lto rdbl" }, + { 0, "hf lto reader" }, + { 0, "hf lto restore" }, + { 0, "hf lto wrbl" }, + { 1, "hf mf help" }, + { 1, "hf mf list" }, + { 0, "hf mf darkside" }, + { 0, "hf mf nested" }, + { 1, "hf mf hardnested" }, + { 0, "hf mf staticnested" }, + { 0, "hf mf autopwn" }, + { 0, "hf mf nack" }, + { 0, "hf mf chk" }, + { 0, "hf mf fchk" }, + { 1, "hf mf decrypt" }, + { 0, "hf mf supercard" }, + { 0, "hf mf auth4" }, + { 1, "hf mf acl" }, + { 0, "hf mf dump" }, + { 1, "hf mf mad" }, + { 0, "hf mf personalize" }, + { 0, "hf mf rdbl" }, + { 0, "hf mf rdsc" }, + { 0, "hf mf restore" }, + { 0, "hf mf setmod" }, + { 1, "hf mf value" }, + { 1, "hf mf view" }, + { 0, "hf mf wipe" }, + { 0, "hf mf wrbl" }, + { 0, "hf mf sim" }, + { 0, "hf mf ecfill" }, + { 0, "hf mf eclr" }, + { 0, "hf mf egetblk" }, + { 0, "hf mf egetsc" }, + { 0, "hf mf ekeyprn" }, + { 0, "hf mf eload" }, + { 0, "hf mf esave" }, + { 0, "hf mf esetblk" }, + { 0, "hf mf eview" }, + { 0, "hf mf cgetblk" }, + { 0, "hf mf cgetsc" }, + { 0, "hf mf cload" }, + { 0, "hf mf csave" }, + { 0, "hf mf csetblk" }, + { 0, "hf mf csetuid" }, + { 0, "hf mf cview" }, + { 0, "hf mf cwipe" }, + { 0, "hf mf gen3uid" }, + { 0, "hf mf gen3blk" }, + { 0, "hf mf gen3freeze" }, + { 0, "hf mf ggetblk" }, + { 0, "hf mf gload" }, + { 0, "hf mf gsave" }, + { 0, "hf mf gsetblk" }, + { 0, "hf mf gview" }, + { 0, "hf mf ndefformat" }, + { 0, "hf mf ndefread" }, + { 0, "hf mf ndefwrite" }, + { 1, "hf mfp help" }, + { 0, "hf mfp info" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp auth" }, + { 0, "hf mfp rdbl" }, + { 0, "hf mfp rdsc" }, + { 0, "hf mfp wrbl" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp mad" }, + { 0, "hf mfp ndefread" }, + { 1, "hf mfu help" }, + { 1, "hf mfu keygen" }, + { 1, "hf mfu pwdgen" }, + { 0, "hf mfu otptear" }, + { 0, "hf mfu cauth" }, + { 0, "hf mfu dump" }, + { 0, "hf mfu info" }, + { 0, "hf mfu ndefread" }, + { 0, "hf mfu rdbl" }, + { 0, "hf mfu restore" }, + { 1, "hf mfu view" }, + { 0, "hf mfu wrbl" }, + { 0, "hf mfu eload" }, + { 0, "hf mfu esave" }, + { 0, "hf mfu eview" }, + { 0, "hf mfu sim" }, + { 0, "hf mfu setpwd" }, + { 0, "hf mfu setuid" }, + { 1, "hf mfdes help" }, + { 0, "hf mfdes info" }, + { 0, "hf mfdes getuid" }, + { 0, "hf mfdes default" }, + { 0, "hf mfdes auth" }, + { 0, "hf mfdes chk" }, + { 0, "hf mfdes detect" }, + { 0, "hf mfdes freemem" }, + { 0, "hf mfdes setconfig" }, + { 0, "hf mfdes formatpicc" }, + { 1, "hf mfdes list" }, + { 0, "hf mfdes mad" }, + { 0, "hf mfdes lsapp" }, + { 0, "hf mfdes getaids" }, + { 0, "hf mfdes getappnames" }, + { 0, "hf mfdes bruteaid" }, + { 0, "hf mfdes createapp" }, + { 0, "hf mfdes deleteapp" }, + { 0, "hf mfdes selectapp" }, + { 0, "hf mfdes changekey" }, + { 0, "hf mfdes chkeysettings" }, + { 0, "hf mfdes getkeysettings" }, + { 0, "hf mfdes getkeyversions" }, + { 0, "hf mfdes getfileids" }, + { 0, "hf mfdes getfileisoids" }, + { 0, "hf mfdes lsfiles" }, + { 0, "hf mfdes dump" }, + { 0, "hf mfdes createfile" }, + { 0, "hf mfdes createvaluefile" }, + { 0, "hf mfdes createrecordfile" }, + { 0, "hf mfdes createmacfile" }, + { 0, "hf mfdes deletefile" }, + { 0, "hf mfdes getfilesettings" }, + { 0, "hf mfdes chfilesettings" }, + { 0, "hf mfdes read" }, + { 0, "hf mfdes write" }, + { 0, "hf mfdes value" }, + { 0, "hf mfdes clearrecfile" }, + { 1, "hf mfdes test" }, + { 1, "hf ntag424 help" }, + { 0, "hf ntag424 info" }, + { 0, "hf ntag424 sdm" }, + { 1, "hf ntag424 view" }, + { 1, "hf seos help" }, + { 0, "hf seos info" }, + { 1, "hf seos list" }, + { 1, "hf st25ta help" }, + { 0, "hf st25ta info" }, + { 1, "hf st25ta list" }, + { 1, "hf st25ta ndefread" }, + { 0, "hf st25ta protect" }, + { 0, "hf st25ta pwd" }, + { 0, "hf st25ta sim" }, + { 1, "hf tesla help" }, + { 0, "hf tesla info" }, + { 1, "hf tesla list" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, + { 1, "hf thinfilm help" }, + { 0, "hf thinfilm info" }, + { 1, "hf thinfilm list" }, + { 0, "hf thinfilm sim" }, + { 1, "hf topaz help" }, + { 0, "hf topaz dump" }, + { 1, "hf topaz list" }, + { 0, "hf topaz info" }, + { 0, "hf topaz reader" }, + { 0, "hf topaz sim" }, + { 0, "hf topaz sniff" }, + { 0, "hf topaz raw" }, + { 0, "hf topaz rdbl" }, + { 1, "hf topaz view" }, + { 0, "hf topaz wrbl" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, + { 0, "hf xerox dump" }, + { 1, "hf waveshare help" }, + { 0, "hf waveshare loadbmp" }, + { 1, "hw help" }, + { 0, "hw break" }, + { 1, "hw connect" }, + { 0, "hw dbg" }, + { 0, "hw detectreader" }, + { 0, "hw fpgaoff" }, + { 0, "hw lcd" }, + { 0, "hw lcdreset" }, + { 0, "hw ping" }, + { 0, "hw readmem" }, + { 0, "hw reset" }, + { 0, "hw setlfdivisor" }, + { 0, "hw setmux" }, + { 0, "hw standalone" }, + { 0, "hw status" }, + { 0, "hw tearoff" }, + { 0, "hw tia" }, + { 0, "hw tune" }, + { 1, "hw version" }, + { 1, "lf help" }, + { 0, "lf config" }, + { 0, "lf cmdread" }, + { 0, "lf read" }, + { 1, "lf search" }, + { 0, "lf sim" }, + { 0, "lf simask" }, + { 0, "lf simfsk" }, + { 0, "lf simpsk" }, + { 0, "lf simbidir" }, + { 0, "lf sniff" }, + { 0, "lf tune" }, + { 1, "lf awid help" }, + { 1, "lf awid demod" }, + { 0, "lf awid reader" }, + { 0, "lf awid clone" }, + { 0, "lf awid sim" }, + { 0, "lf awid brute" }, + { 0, "lf awid watch" }, + { 1, "lf cotag help" }, + { 1, "lf cotag demod" }, + { 0, "lf cotag reader" }, + { 1, "lf destron help" }, + { 1, "lf destron demod" }, + { 0, "lf destron reader" }, + { 0, "lf destron clone" }, + { 0, "lf destron sim" }, + { 1, "lf em help" }, + { 1, "lf em 410x help" }, + { 1, "lf em 410x demod" }, + { 0, "lf em 410x reader" }, + { 0, "lf em 410x sim" }, + { 0, "lf em 410x brute" }, + { 0, "lf em 410x watch" }, + { 0, "lf em 410x spoof" }, + { 0, "lf em 410x clone" }, + { 1, "lf em 4x05 help" }, + { 0, "lf em 4x05 brute" }, + { 0, "lf em 4x05 chk" }, + { 1, "lf em 4x05 demod" }, + { 0, "lf em 4x05 dump" }, + { 0, "lf em 4x05 info" }, + { 0, "lf em 4x05 read" }, + { 1, "lf em 4x05 sniff" }, + { 0, "lf em 4x05 unlock" }, + { 0, "lf em 4x05 wipe" }, + { 0, "lf em 4x05 write" }, + { 1, "lf em 4x50 help" }, + { 0, "lf em 4x50 brute" }, + { 0, "lf em 4x50 chk" }, + { 0, "lf em 4x50 dump" }, + { 0, "lf em 4x50 info" }, + { 0, "lf em 4x50 login" }, + { 0, "lf em 4x50 rdbl" }, + { 0, "lf em 4x50 reader" }, + { 0, "lf em 4x50 restore" }, + { 0, "lf em 4x50 wrbl" }, + { 0, "lf em 4x50 wrpwd" }, + { 0, "lf em 4x50 wipe" }, + { 0, "lf em 4x50 eload" }, + { 0, "lf em 4x50 esave" }, + { 0, "lf em 4x50 eview" }, + { 0, "lf em 4x50 sim" }, + { 1, "lf em 4x70 help" }, + { 0, "lf em 4x70 info" }, + { 0, "lf em 4x70 write" }, + { 0, "lf em 4x70 unlock" }, + { 0, "lf em 4x70 auth" }, + { 0, "lf em 4x70 writepin" }, + { 0, "lf em 4x70 writekey" }, + { 1, "lf fdxb help" }, + { 1, "lf fdxb demod" }, + { 0, "lf fdxb reader" }, + { 0, "lf fdxb clone" }, + { 0, "lf fdxb sim" }, + { 1, "lf gallagher help" }, + { 1, "lf gallagher demod" }, + { 0, "lf gallagher reader" }, + { 0, "lf gallagher clone" }, + { 0, "lf gallagher sim" }, + { 1, "lf gproxii help" }, + { 1, "lf gproxii demod" }, + { 0, "lf gproxii reader" }, + { 0, "lf gproxii clone" }, + { 0, "lf gproxii sim" }, + { 1, "lf hid help" }, + { 1, "lf hid demod" }, + { 0, "lf hid reader" }, + { 0, "lf hid clone" }, + { 0, "lf hid sim" }, + { 0, "lf hid brute" }, + { 0, "lf hid watch" }, + { 1, "lf hitag help" }, + { 0, "lf hitag eload" }, + { 1, "lf hitag list" }, + { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, + { 0, "lf hitag sim" }, + { 0, "lf hitag sniff" }, + { 0, "lf hitag writer" }, + { 0, "lf hitag dump" }, + { 0, "lf hitag cc" }, + { 1, "lf idteck help" }, + { 1, "lf idteck demod" }, + { 0, "lf idteck reader" }, + { 0, "lf idteck clone" }, + { 0, "lf idteck sim" }, + { 1, "lf indala help" }, + { 0, "lf indala brute" }, + { 1, "lf indala demod" }, + { 1, "lf indala altdemod" }, + { 0, "lf indala reader" }, + { 0, "lf indala clone" }, + { 0, "lf indala sim" }, + { 1, "lf io help" }, + { 1, "lf io demod" }, + { 0, "lf io reader" }, + { 0, "lf io clone" }, + { 0, "lf io sim" }, + { 0, "lf io watch" }, + { 1, "lf jablotron help" }, + { 1, "lf jablotron demod" }, + { 0, "lf jablotron reader" }, + { 0, "lf jablotron clone" }, + { 0, "lf jablotron sim" }, + { 1, "lf keri help" }, + { 1, "lf keri demod" }, + { 0, "lf keri reader" }, + { 0, "lf keri clone" }, + { 0, "lf keri sim" }, + { 1, "lf motorola help" }, + { 1, "lf motorola demod" }, + { 0, "lf motorola reader" }, + { 0, "lf motorola clone" }, + { 0, "lf motorola sim" }, + { 1, "lf nedap help" }, + { 1, "lf nedap demod" }, + { 0, "lf nedap reader" }, + { 0, "lf nedap clone" }, + { 0, "lf nedap sim" }, + { 1, "lf nexwatch help" }, + { 1, "lf nexwatch demod" }, + { 0, "lf nexwatch reader" }, + { 0, "lf nexwatch clone" }, + { 0, "lf nexwatch sim" }, + { 1, "lf noralsy help" }, + { 1, "lf noralsy demod" }, + { 0, "lf noralsy reader" }, + { 0, "lf noralsy clone" }, + { 0, "lf noralsy sim" }, + { 1, "lf pac help" }, + { 1, "lf pac demod" }, + { 0, "lf pac reader" }, + { 0, "lf pac clone" }, + { 0, "lf pac sim" }, + { 1, "lf paradox help" }, + { 1, "lf paradox demod" }, + { 0, "lf paradox reader" }, + { 0, "lf paradox clone" }, + { 0, "lf paradox sim" }, + { 1, "lf pcf7931 help" }, + { 0, "lf pcf7931 reader" }, + { 0, "lf pcf7931 write" }, + { 1, "lf pcf7931 config" }, + { 1, "lf presco help" }, + { 1, "lf presco demod" }, + { 0, "lf presco reader" }, + { 0, "lf presco clone" }, + { 0, "lf presco sim" }, + { 1, "lf pyramid help" }, + { 1, "lf pyramid demod" }, + { 0, "lf pyramid reader" }, + { 0, "lf pyramid clone" }, + { 0, "lf pyramid sim" }, + { 1, "lf securakey help" }, + { 1, "lf securakey demod" }, + { 0, "lf securakey reader" }, + { 0, "lf securakey clone" }, + { 0, "lf securakey sim" }, + { 1, "lf ti help" }, + { 1, "lf ti demod" }, + { 0, "lf ti reader" }, + { 0, "lf ti write" }, + { 1, "lf t55xx help" }, + { 0, "lf t55xx clonehelp" }, + { 1, "lf t55xx config" }, + { 0, "lf t55xx dangerraw" }, + { 1, "lf t55xx detect" }, + { 0, "lf t55xx deviceconfig" }, + { 0, "lf t55xx dump" }, + { 1, "lf t55xx info" }, + { 0, "lf t55xx p1detect" }, + { 0, "lf t55xx read" }, + { 0, "lf t55xx resetread" }, + { 0, "lf t55xx restore" }, + { 1, "lf t55xx trace" }, + { 0, "lf t55xx wakeup" }, + { 0, "lf t55xx write" }, + { 0, "lf t55xx bruteforce" }, + { 0, "lf t55xx chk" }, + { 0, "lf t55xx protect" }, + { 0, "lf t55xx recoverpw" }, + { 1, "lf t55xx sniff" }, + { 0, "lf t55xx special" }, + { 0, "lf t55xx wipe" }, + { 1, "lf viking help" }, + { 1, "lf viking demod" }, + { 0, "lf viking reader" }, + { 0, "lf viking clone" }, + { 0, "lf viking sim" }, + { 1, "lf visa2000 help" }, + { 1, "lf visa2000 demod" }, + { 0, "lf visa2000 reader" }, + { 0, "lf visa2000 clone" }, + { 0, "lf visa2000 sim" }, + { 1, "mem help" }, + { 0, "mem baudrate" }, + { 0, "mem dump" }, + { 0, "mem info" }, + { 0, "mem load" }, + { 0, "mem wipe" }, + { 1, "mem spiffs help" }, + { 0, "mem spiffs copy" }, + { 0, "mem spiffs check" }, + { 0, "mem spiffs dump" }, + { 0, "mem spiffs info" }, + { 0, "mem spiffs mount" }, + { 0, "mem spiffs remove" }, + { 0, "mem spiffs rename" }, + { 0, "mem spiffs test" }, + { 0, "mem spiffs tree" }, + { 0, "mem spiffs unmount" }, + { 0, "mem spiffs upload" }, + { 0, "mem spiffs view" }, + { 0, "mem spiffs wipe" }, + { 1, "nfc help" }, + { 1, "nfc decode" }, + { 0, "nfc type1 read" }, + { 1, "nfc type1 help" }, + { 0, "nfc type2 read" }, + { 1, "nfc type2 help" }, + { 0, "nfc type4a format" }, + { 0, "nfc type4a read" }, + { 0, "nfc type4a write" }, + { 0, "nfc type4a st25taread" }, + { 1, "nfc type4a help" }, + { 0, "nfc type4b read" }, + { 1, "nfc type4b help" }, + { 0, "nfc mf cformat" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf cwrite" }, + { 0, "nfc mf pread" }, + { 1, "nfc mf help" }, + { 0, "nfc barcode read" }, + { 0, "nfc barcode sim" }, + { 1, "nfc barcode help" }, + { 1, "piv help" }, + { 0, "piv select" }, + { 0, "piv getdata" }, + { 0, "piv authsign" }, + { 0, "piv scan" }, + { 1, "piv list" }, + { 1, "smart help" }, + { 1, "smart list" }, + { 0, "smart info" }, + { 0, "smart reader" }, + { 0, "smart raw" }, + { 1, "smart upgrade" }, + { 0, "smart setclock" }, + { 0, "smart brute" }, + { 1, "script help" }, + { 1, "script list" }, + { 1, "script run" }, + { 1, "trace help" }, + { 1, "trace extract" }, + { 1, "trace list" }, + { 1, "trace load" }, + { 1, "trace save" }, + { 1, "usart help" }, + { 0, "usart btpin" }, + { 0, "usart btfactory" }, + { 0, "usart tx" }, + { 0, "usart rx" }, + { 0, "usart txrx" }, + { 0, "usart txhex" }, + { 0, "usart rxhex" }, + { 0, "usart config" }, + { 1, "wiegand help" }, + { 1, "wiegand list" }, + { 1, "wiegand encode" }, + { 1, "wiegand decode" }, {0, NULL} }; @@ -788,4 +788,4 @@ const static vocabulory_t vocabulory[] = { } #endif -#endif \ No newline at end of file +#endif From 8f977ef989237c213be3ffbcb1e88d659968ae8b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 11 Feb 2023 11:43:29 +0100 Subject: [PATCH 605/759] fix #1909 intendation breaks the makefile --- Makefile | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index c482af694..be4af6682 100644 --- a/Makefile +++ b/Makefile @@ -67,11 +67,11 @@ ifeq ($(platform),Linux) $(Q)$(INSTALLSUDO) $(MKDIR) $(DESTDIR)$(UDEV_PREFIX) # If user is running ArchLinux, use group 'uucp' # Else, use group 'dialout' - ifneq ($(wildcard /etc/arch-release),) - $(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist-uucp.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules - else - $(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist-dialout.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules - endif +ifneq ($(wildcard /etc/arch-release),) + $(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist-uucp.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +else + $(Q)$(INSTALLSUDO) $(CP) driver/77-pm3-usb-device-blacklist-dialout.rules $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules +endif endif uninstall: common/uninstall @@ -81,21 +81,28 @@ common/uninstall: ifneq (,$(INSTALLSCRIPTS)) $(Q)$(INSTALLSUDO) $(RM) $(foreach script,$(INSTALLSCRIPTS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLBINRELPATH)$(PATHSEP)$(notdir $(script))) endif + ifneq (,$(INSTALLSHARES)) $(Q)$(INSTALLSUDO) $(RMDIR) $(foreach share,$(INSTALLSHARES),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLSHARERELPATH)$(PATHSEP)$(notdir $(share))) endif + ifneq (,$(INSTALLDOCS)) $(Q)$(INSTALLSUDO) $(RMDIR) $(foreach doc,$(INSTALLDOCS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH)$(PATHSEP)$(notdir $(doc))) $(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLDOCSRELPATH) endif + ifneq (,$(INSTALLTOOLS)) $(Q)$(INSTALLSUDO) $(RM) $(foreach tool,$(INSTALLTOOLS),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH)$(PATHSEP)$(notdir $(tool))) endif + $(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLTOOLSRELPATH) + ifneq (,$(INSTALLSIMFW)) $(Q)$(INSTALLSUDO) $(RM) $(foreach fw,$(INSTALLSIMFW),$(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH)$(PATHSEP)$(notdir $(fw))) endif + $(Q)-$(INSTALLSUDO) $(RMDIR_SOFT) $(DESTDIR)$(PREFIX)$(PATHSEP)$(INSTALLFWRELPATH) + ifeq ($(platform),Linux) $(Q)$(INSTALLSUDO) $(RM) $(DESTDIR)$(UDEV_PREFIX)/77-pm3-usb-device-blacklist.rules endif From 3ee7ac32547d2aa1fcaf2ade0b9681d7801d0039 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 11 Feb 2023 11:53:20 +0100 Subject: [PATCH 606/759] style --- client/src/pm3line_vocabulory.h | 1503 ++++++++++++++++--------------- doc/commands.json | 38 +- doc/commands.md | 1 + 3 files changed, 782 insertions(+), 760 deletions(-) diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index b6d08d325..a0e386270 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -31,756 +31,757 @@ typedef struct vocabulory_s { } vocabulory_t; const static vocabulory_t vocabulory[] = { - { 1, "help" }, - { 0, "auto" }, - { 1, "clear" }, - { 1, "hints" }, - { 1, "msleep" }, - { 1, "rem" }, - { 1, "quit" }, - { 1, "exit" }, - { 1, "prefs help" }, - { 1, "prefs show" }, - { 1, "prefs get barmode" }, - { 1, "prefs get clientdebug" }, - { 1, "prefs get clientdelay" }, - { 1, "prefs get color" }, - { 1, "prefs get savepaths" }, - { 1, "prefs get emoji" }, - { 1, "prefs get hints" }, - { 1, "prefs get output" }, - { 1, "prefs get plotsliders" }, - { 1, "prefs set help" }, - { 1, "prefs set barmode" }, - { 1, "prefs set clientdebug" }, - { 1, "prefs set clientdelay" }, - { 1, "prefs set color" }, - { 1, "prefs set emoji" }, - { 1, "prefs set hints" }, - { 1, "prefs set savepaths" }, - { 1, "prefs set output" }, - { 1, "prefs set plotsliders" }, - { 1, "analyse help" }, - { 1, "analyse lcr" }, - { 1, "analyse crc" }, - { 1, "analyse chksum" }, - { 1, "analyse dates" }, - { 1, "analyse lfsr" }, - { 1, "analyse a" }, - { 1, "analyse nuid" }, - { 1, "analyse demodbuff" }, - { 1, "analyse freq" }, - { 1, "analyse foo" }, - { 1, "analyse units" }, - { 1, "data help" }, - { 1, "data biphaserawdecode" }, - { 1, "data detectclock" }, - { 1, "data fsktonrz" }, - { 1, "data manrawdecode" }, - { 1, "data modulation" }, - { 1, "data rawdemod" }, - { 1, "data askedgedetect" }, - { 1, "data autocorr" }, - { 1, "data dirthreshold" }, - { 1, "data decimate" }, - { 1, "data undecimate" }, - { 1, "data hide" }, - { 1, "data hpf" }, - { 1, "data iir" }, - { 1, "data grid" }, - { 1, "data ltrim" }, - { 1, "data mtrim" }, - { 1, "data norm" }, - { 1, "data plot" }, - { 1, "data rtrim" }, - { 1, "data setgraphmarkers" }, - { 1, "data shiftgraphzero" }, - { 1, "data timescale" }, - { 1, "data zerocrossings" }, - { 1, "data convertbitstream" }, - { 1, "data getbitstream" }, - { 1, "data asn1" }, - { 1, "data bin2hex" }, - { 0, "data bitsamples" }, - { 1, "data clear" }, - { 1, "data diff" }, - { 0, "data hexsamples" }, - { 1, "data hex2bin" }, - { 1, "data load" }, - { 1, "data print" }, - { 0, "data samples" }, - { 1, "data save" }, - { 1, "data setdebugmode" }, - { 0, "data tune" }, - { 1, "emv help" }, - { 0, "emv exec" }, - { 0, "emv pse" }, - { 0, "emv search" }, - { 0, "emv select" }, - { 0, "emv gpo" }, - { 0, "emv readrec" }, - { 0, "emv genac" }, - { 0, "emv challenge" }, - { 0, "emv intauth" }, - { 0, "emv scan" }, - { 1, "emv test" }, - { 1, "emv list" }, - { 0, "emv roca" }, - { 1, "hf help" }, - { 1, "hf list" }, - { 0, "hf plot" }, - { 0, "hf tune" }, - { 1, "hf search" }, - { 0, "hf sniff" }, - { 1, "hf 14a help" }, - { 1, "hf 14a list" }, - { 0, "hf 14a antifuzz" }, - { 0, "hf 14a config" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a info" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a raw" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a apdufind" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a ndefformat" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a ndefwrite" }, - { 1, "hf 14b help" }, - { 0, "hf 14b apdu" }, - { 0, "hf 14b dump" }, - { 0, "hf 14b info" }, - { 1, "hf 14b list" }, - { 0, "hf 14b ndefread" }, - { 0, "hf 14b raw" }, - { 0, "hf 14b reader" }, - { 0, "hf 14b sim" }, - { 0, "hf 14b sniff" }, - { 0, "hf 14b rdbl" }, - { 0, "hf 14b sriwrite" }, - { 1, "hf 14b view" }, - { 1, "hf 15 help" }, - { 1, "hf 15 list" }, - { 1, "hf 15 demod" }, - { 0, "hf 15 dump" }, - { 0, "hf 15 info" }, - { 0, "hf 15 sniff" }, - { 0, "hf 15 raw" }, - { 0, "hf 15 rdbl" }, - { 0, "hf 15 rdmulti" }, - { 0, "hf 15 reader" }, - { 0, "hf 15 restore" }, - { 0, "hf 15 samples" }, - { 0, "hf 15 eload" }, - { 0, "hf 15 esave" }, - { 0, "hf 15 eview" }, - { 0, "hf 15 sim" }, - { 0, "hf 15 slixwritepwd" }, - { 0, "hf 15 slixeasdisable" }, - { 0, "hf 15 slixeasenable" }, - { 0, "hf 15 slixprivacydisable" }, - { 0, "hf 15 slixprivacyenable" }, - { 0, "hf 15 passprotectafi" }, - { 0, "hf 15 passprotecteas" }, - { 0, "hf 15 wrbl" }, - { 0, "hf 15 findafi" }, - { 0, "hf 15 writeafi" }, - { 0, "hf 15 writedsfid" }, - { 0, "hf 15 csetuid" }, - { 1, "hf cipurse help" }, - { 0, "hf cipurse info" }, - { 0, "hf cipurse select" }, - { 0, "hf cipurse auth" }, - { 0, "hf cipurse read" }, - { 0, "hf cipurse write" }, - { 0, "hf cipurse aread" }, - { 0, "hf cipurse awrite" }, - { 0, "hf cipurse formatall" }, - { 0, "hf cipurse create" }, - { 0, "hf cipurse delete" }, - { 0, "hf cipurse updkey" }, - { 0, "hf cipurse updakey" }, - { 0, "hf cipurse default" }, - { 1, "hf cipurse test" }, - { 1, "hf epa help" }, - { 0, "hf epa cnonces" }, - { 0, "hf epa replay" }, - { 0, "hf epa sim" }, - { 1, "hf emrtd help" }, - { 0, "hf emrtd dump" }, - { 1, "hf emrtd info" }, - { 1, "hf emrtd list" }, - { 1, "hf felica help" }, - { 1, "hf felica list" }, - { 0, "hf felica reader" }, - { 0, "hf felica info" }, - { 0, "hf felica sniff" }, - { 0, "hf felica raw" }, - { 0, "hf felica rdbl" }, - { 0, "hf felica wrbl" }, - { 0, "hf felica rqservice" }, - { 0, "hf felica rqresponse" }, - { 0, "hf felica scsvcode" }, - { 0, "hf felica rqsyscode" }, - { 0, "hf felica auth1" }, - { 0, "hf felica auth2" }, - { 0, "hf felica rqspecver" }, - { 0, "hf felica resetmode" }, - { 0, "hf felica litesim" }, - { 0, "hf felica litedump" }, - { 1, "hf fido help" }, - { 1, "hf fido list" }, - { 0, "hf fido info" }, - { 0, "hf fido reg" }, - { 0, "hf fido auth" }, - { 0, "hf fido make" }, - { 0, "hf fido assert" }, - { 1, "hf fudan help" }, - { 0, "hf fudan reader" }, - { 0, "hf fudan dump" }, - { 0, "hf fudan rdbl" }, - { 1, "hf fudan view" }, - { 0, "hf fudan wrbl" }, - { 1, "hf gallagher help" }, - { 0, "hf gallagher reader" }, - { 0, "hf gallagher clone" }, - { 0, "hf gallagher delete" }, - { 1, "hf gallagher diversifykey" }, - { 1, "hf gallagher decode" }, - { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 select" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 init" }, - { 0, "hf ksx6924 prec" }, - { 1, "hf jooki help" }, - { 0, "hf jooki clone" }, - { 1, "hf jooki decode" }, - { 1, "hf jooki encode" }, - { 0, "hf jooki sim" }, - { 1, "hf iclass help" }, - { 0, "hf iclass dump" }, - { 1, "hf iclass info" }, - { 1, "hf iclass list" }, - { 0, "hf iclass rdbl" }, - { 0, "hf iclass reader" }, - { 0, "hf iclass restore" }, - { 0, "hf iclass sniff" }, - { 0, "hf iclass wrbl" }, - { 0, "hf iclass chk" }, - { 1, "hf iclass loclass" }, - { 1, "hf iclass lookup" }, - { 0, "hf iclass sim" }, - { 0, "hf iclass eload" }, - { 0, "hf iclass esave" }, - { 0, "hf iclass eview" }, - { 1, "hf iclass configcard" }, - { 1, "hf iclass calcnewkey" }, - { 1, "hf iclass encode" }, - { 1, "hf iclass encrypt" }, - { 1, "hf iclass decrypt" }, - { 1, "hf iclass managekeys" }, - { 1, "hf iclass permutekey" }, - { 1, "hf iclass view" }, - { 1, "hf legic help" }, - { 0, "hf legic dump" }, - { 0, "hf legic info" }, - { 1, "hf legic list" }, - { 0, "hf legic rdbl" }, - { 0, "hf legic reader" }, - { 0, "hf legic restore" }, - { 0, "hf legic wipe" }, - { 0, "hf legic wrbl" }, - { 0, "hf legic sim" }, - { 0, "hf legic eload" }, - { 0, "hf legic esave" }, - { 0, "hf legic eview" }, - { 1, "hf legic crc" }, - { 1, "hf legic view" }, - { 1, "hf lto help" }, - { 0, "hf lto dump" }, - { 0, "hf lto info" }, - { 1, "hf lto list" }, - { 0, "hf lto rdbl" }, - { 0, "hf lto reader" }, - { 0, "hf lto restore" }, - { 0, "hf lto wrbl" }, - { 1, "hf mf help" }, - { 1, "hf mf list" }, - { 0, "hf mf darkside" }, - { 0, "hf mf nested" }, - { 1, "hf mf hardnested" }, - { 0, "hf mf staticnested" }, - { 0, "hf mf autopwn" }, - { 0, "hf mf nack" }, - { 0, "hf mf chk" }, - { 0, "hf mf fchk" }, - { 1, "hf mf decrypt" }, - { 0, "hf mf supercard" }, - { 0, "hf mf auth4" }, - { 1, "hf mf acl" }, - { 0, "hf mf dump" }, - { 1, "hf mf mad" }, - { 0, "hf mf personalize" }, - { 0, "hf mf rdbl" }, - { 0, "hf mf rdsc" }, - { 0, "hf mf restore" }, - { 0, "hf mf setmod" }, - { 1, "hf mf value" }, - { 1, "hf mf view" }, - { 0, "hf mf wipe" }, - { 0, "hf mf wrbl" }, - { 0, "hf mf sim" }, - { 0, "hf mf ecfill" }, - { 0, "hf mf eclr" }, - { 0, "hf mf egetblk" }, - { 0, "hf mf egetsc" }, - { 0, "hf mf ekeyprn" }, - { 0, "hf mf eload" }, - { 0, "hf mf esave" }, - { 0, "hf mf esetblk" }, - { 0, "hf mf eview" }, - { 0, "hf mf cgetblk" }, - { 0, "hf mf cgetsc" }, - { 0, "hf mf cload" }, - { 0, "hf mf csave" }, - { 0, "hf mf csetblk" }, - { 0, "hf mf csetuid" }, - { 0, "hf mf cview" }, - { 0, "hf mf cwipe" }, - { 0, "hf mf gen3uid" }, - { 0, "hf mf gen3blk" }, - { 0, "hf mf gen3freeze" }, - { 0, "hf mf ggetblk" }, - { 0, "hf mf gload" }, - { 0, "hf mf gsave" }, - { 0, "hf mf gsetblk" }, - { 0, "hf mf gview" }, - { 0, "hf mf ndefformat" }, - { 0, "hf mf ndefread" }, - { 0, "hf mf ndefwrite" }, - { 1, "hf mfp help" }, - { 0, "hf mfp info" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp commitp" }, - { 0, "hf mfp auth" }, - { 0, "hf mfp rdbl" }, - { 0, "hf mfp rdsc" }, - { 0, "hf mfp wrbl" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp mad" }, - { 0, "hf mfp ndefread" }, - { 1, "hf mfu help" }, - { 1, "hf mfu keygen" }, - { 1, "hf mfu pwdgen" }, - { 0, "hf mfu otptear" }, - { 0, "hf mfu cauth" }, - { 0, "hf mfu dump" }, - { 0, "hf mfu info" }, - { 0, "hf mfu ndefread" }, - { 0, "hf mfu rdbl" }, - { 0, "hf mfu restore" }, - { 1, "hf mfu view" }, - { 0, "hf mfu wrbl" }, - { 0, "hf mfu eload" }, - { 0, "hf mfu esave" }, - { 0, "hf mfu eview" }, - { 0, "hf mfu sim" }, - { 0, "hf mfu setpwd" }, - { 0, "hf mfu setuid" }, - { 1, "hf mfdes help" }, - { 0, "hf mfdes info" }, - { 0, "hf mfdes getuid" }, - { 0, "hf mfdes default" }, - { 0, "hf mfdes auth" }, - { 0, "hf mfdes chk" }, - { 0, "hf mfdes detect" }, - { 0, "hf mfdes freemem" }, - { 0, "hf mfdes setconfig" }, - { 0, "hf mfdes formatpicc" }, - { 1, "hf mfdes list" }, - { 0, "hf mfdes mad" }, - { 0, "hf mfdes lsapp" }, - { 0, "hf mfdes getaids" }, - { 0, "hf mfdes getappnames" }, - { 0, "hf mfdes bruteaid" }, - { 0, "hf mfdes createapp" }, - { 0, "hf mfdes deleteapp" }, - { 0, "hf mfdes selectapp" }, - { 0, "hf mfdes changekey" }, - { 0, "hf mfdes chkeysettings" }, - { 0, "hf mfdes getkeysettings" }, - { 0, "hf mfdes getkeyversions" }, - { 0, "hf mfdes getfileids" }, - { 0, "hf mfdes getfileisoids" }, - { 0, "hf mfdes lsfiles" }, - { 0, "hf mfdes dump" }, - { 0, "hf mfdes createfile" }, - { 0, "hf mfdes createvaluefile" }, - { 0, "hf mfdes createrecordfile" }, - { 0, "hf mfdes createmacfile" }, - { 0, "hf mfdes deletefile" }, - { 0, "hf mfdes getfilesettings" }, - { 0, "hf mfdes chfilesettings" }, - { 0, "hf mfdes read" }, - { 0, "hf mfdes write" }, - { 0, "hf mfdes value" }, - { 0, "hf mfdes clearrecfile" }, - { 1, "hf mfdes test" }, - { 1, "hf ntag424 help" }, - { 0, "hf ntag424 info" }, - { 0, "hf ntag424 sdm" }, - { 1, "hf ntag424 view" }, - { 1, "hf seos help" }, - { 0, "hf seos info" }, - { 1, "hf seos list" }, - { 1, "hf st25ta help" }, - { 0, "hf st25ta info" }, - { 1, "hf st25ta list" }, - { 1, "hf st25ta ndefread" }, - { 0, "hf st25ta protect" }, - { 0, "hf st25ta pwd" }, - { 0, "hf st25ta sim" }, - { 1, "hf tesla help" }, - { 0, "hf tesla info" }, - { 1, "hf tesla list" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, - { 1, "hf thinfilm help" }, - { 0, "hf thinfilm info" }, - { 1, "hf thinfilm list" }, - { 0, "hf thinfilm sim" }, - { 1, "hf topaz help" }, - { 0, "hf topaz dump" }, - { 1, "hf topaz list" }, - { 0, "hf topaz info" }, - { 0, "hf topaz reader" }, - { 0, "hf topaz sim" }, - { 0, "hf topaz sniff" }, - { 0, "hf topaz raw" }, - { 0, "hf topaz rdbl" }, - { 1, "hf topaz view" }, - { 0, "hf topaz wrbl" }, - { 1, "hf xerox help" }, - { 0, "hf xerox info" }, - { 0, "hf xerox reader" }, - { 0, "hf xerox dump" }, - { 1, "hf waveshare help" }, - { 0, "hf waveshare loadbmp" }, - { 1, "hw help" }, - { 0, "hw break" }, - { 1, "hw connect" }, - { 0, "hw dbg" }, - { 0, "hw detectreader" }, - { 0, "hw fpgaoff" }, - { 0, "hw lcd" }, - { 0, "hw lcdreset" }, - { 0, "hw ping" }, - { 0, "hw readmem" }, - { 0, "hw reset" }, - { 0, "hw setlfdivisor" }, - { 0, "hw setmux" }, - { 0, "hw standalone" }, - { 0, "hw status" }, - { 0, "hw tearoff" }, - { 0, "hw tia" }, - { 0, "hw tune" }, - { 1, "hw version" }, - { 1, "lf help" }, - { 0, "lf config" }, - { 0, "lf cmdread" }, - { 0, "lf read" }, - { 1, "lf search" }, - { 0, "lf sim" }, - { 0, "lf simask" }, - { 0, "lf simfsk" }, - { 0, "lf simpsk" }, - { 0, "lf simbidir" }, - { 0, "lf sniff" }, - { 0, "lf tune" }, - { 1, "lf awid help" }, - { 1, "lf awid demod" }, - { 0, "lf awid reader" }, - { 0, "lf awid clone" }, - { 0, "lf awid sim" }, - { 0, "lf awid brute" }, - { 0, "lf awid watch" }, - { 1, "lf cotag help" }, - { 1, "lf cotag demod" }, - { 0, "lf cotag reader" }, - { 1, "lf destron help" }, - { 1, "lf destron demod" }, - { 0, "lf destron reader" }, - { 0, "lf destron clone" }, - { 0, "lf destron sim" }, - { 1, "lf em help" }, - { 1, "lf em 410x help" }, - { 1, "lf em 410x demod" }, - { 0, "lf em 410x reader" }, - { 0, "lf em 410x sim" }, - { 0, "lf em 410x brute" }, - { 0, "lf em 410x watch" }, - { 0, "lf em 410x spoof" }, - { 0, "lf em 410x clone" }, - { 1, "lf em 4x05 help" }, - { 0, "lf em 4x05 brute" }, - { 0, "lf em 4x05 chk" }, - { 1, "lf em 4x05 demod" }, - { 0, "lf em 4x05 dump" }, - { 0, "lf em 4x05 info" }, - { 0, "lf em 4x05 read" }, - { 1, "lf em 4x05 sniff" }, - { 0, "lf em 4x05 unlock" }, - { 0, "lf em 4x05 wipe" }, - { 0, "lf em 4x05 write" }, - { 1, "lf em 4x50 help" }, - { 0, "lf em 4x50 brute" }, - { 0, "lf em 4x50 chk" }, - { 0, "lf em 4x50 dump" }, - { 0, "lf em 4x50 info" }, - { 0, "lf em 4x50 login" }, - { 0, "lf em 4x50 rdbl" }, - { 0, "lf em 4x50 reader" }, - { 0, "lf em 4x50 restore" }, - { 0, "lf em 4x50 wrbl" }, - { 0, "lf em 4x50 wrpwd" }, - { 0, "lf em 4x50 wipe" }, - { 0, "lf em 4x50 eload" }, - { 0, "lf em 4x50 esave" }, - { 0, "lf em 4x50 eview" }, - { 0, "lf em 4x50 sim" }, - { 1, "lf em 4x70 help" }, - { 0, "lf em 4x70 info" }, - { 0, "lf em 4x70 write" }, - { 0, "lf em 4x70 unlock" }, - { 0, "lf em 4x70 auth" }, - { 0, "lf em 4x70 writepin" }, - { 0, "lf em 4x70 writekey" }, - { 1, "lf fdxb help" }, - { 1, "lf fdxb demod" }, - { 0, "lf fdxb reader" }, - { 0, "lf fdxb clone" }, - { 0, "lf fdxb sim" }, - { 1, "lf gallagher help" }, - { 1, "lf gallagher demod" }, - { 0, "lf gallagher reader" }, - { 0, "lf gallagher clone" }, - { 0, "lf gallagher sim" }, - { 1, "lf gproxii help" }, - { 1, "lf gproxii demod" }, - { 0, "lf gproxii reader" }, - { 0, "lf gproxii clone" }, - { 0, "lf gproxii sim" }, - { 1, "lf hid help" }, - { 1, "lf hid demod" }, - { 0, "lf hid reader" }, - { 0, "lf hid clone" }, - { 0, "lf hid sim" }, - { 0, "lf hid brute" }, - { 0, "lf hid watch" }, - { 1, "lf hitag help" }, - { 0, "lf hitag eload" }, - { 1, "lf hitag list" }, - { 0, "lf hitag info" }, - { 0, "lf hitag reader" }, - { 0, "lf hitag sim" }, - { 0, "lf hitag sniff" }, - { 0, "lf hitag writer" }, - { 0, "lf hitag dump" }, - { 0, "lf hitag cc" }, - { 1, "lf idteck help" }, - { 1, "lf idteck demod" }, - { 0, "lf idteck reader" }, - { 0, "lf idteck clone" }, - { 0, "lf idteck sim" }, - { 1, "lf indala help" }, - { 0, "lf indala brute" }, - { 1, "lf indala demod" }, - { 1, "lf indala altdemod" }, - { 0, "lf indala reader" }, - { 0, "lf indala clone" }, - { 0, "lf indala sim" }, - { 1, "lf io help" }, - { 1, "lf io demod" }, - { 0, "lf io reader" }, - { 0, "lf io clone" }, - { 0, "lf io sim" }, - { 0, "lf io watch" }, - { 1, "lf jablotron help" }, - { 1, "lf jablotron demod" }, - { 0, "lf jablotron reader" }, - { 0, "lf jablotron clone" }, - { 0, "lf jablotron sim" }, - { 1, "lf keri help" }, - { 1, "lf keri demod" }, - { 0, "lf keri reader" }, - { 0, "lf keri clone" }, - { 0, "lf keri sim" }, - { 1, "lf motorola help" }, - { 1, "lf motorola demod" }, - { 0, "lf motorola reader" }, - { 0, "lf motorola clone" }, - { 0, "lf motorola sim" }, - { 1, "lf nedap help" }, - { 1, "lf nedap demod" }, - { 0, "lf nedap reader" }, - { 0, "lf nedap clone" }, - { 0, "lf nedap sim" }, - { 1, "lf nexwatch help" }, - { 1, "lf nexwatch demod" }, - { 0, "lf nexwatch reader" }, - { 0, "lf nexwatch clone" }, - { 0, "lf nexwatch sim" }, - { 1, "lf noralsy help" }, - { 1, "lf noralsy demod" }, - { 0, "lf noralsy reader" }, - { 0, "lf noralsy clone" }, - { 0, "lf noralsy sim" }, - { 1, "lf pac help" }, - { 1, "lf pac demod" }, - { 0, "lf pac reader" }, - { 0, "lf pac clone" }, - { 0, "lf pac sim" }, - { 1, "lf paradox help" }, - { 1, "lf paradox demod" }, - { 0, "lf paradox reader" }, - { 0, "lf paradox clone" }, - { 0, "lf paradox sim" }, - { 1, "lf pcf7931 help" }, - { 0, "lf pcf7931 reader" }, - { 0, "lf pcf7931 write" }, - { 1, "lf pcf7931 config" }, - { 1, "lf presco help" }, - { 1, "lf presco demod" }, - { 0, "lf presco reader" }, - { 0, "lf presco clone" }, - { 0, "lf presco sim" }, - { 1, "lf pyramid help" }, - { 1, "lf pyramid demod" }, - { 0, "lf pyramid reader" }, - { 0, "lf pyramid clone" }, - { 0, "lf pyramid sim" }, - { 1, "lf securakey help" }, - { 1, "lf securakey demod" }, - { 0, "lf securakey reader" }, - { 0, "lf securakey clone" }, - { 0, "lf securakey sim" }, - { 1, "lf ti help" }, - { 1, "lf ti demod" }, - { 0, "lf ti reader" }, - { 0, "lf ti write" }, - { 1, "lf t55xx help" }, - { 0, "lf t55xx clonehelp" }, - { 1, "lf t55xx config" }, - { 0, "lf t55xx dangerraw" }, - { 1, "lf t55xx detect" }, - { 0, "lf t55xx deviceconfig" }, - { 0, "lf t55xx dump" }, - { 1, "lf t55xx info" }, - { 0, "lf t55xx p1detect" }, - { 0, "lf t55xx read" }, - { 0, "lf t55xx resetread" }, - { 0, "lf t55xx restore" }, - { 1, "lf t55xx trace" }, - { 0, "lf t55xx wakeup" }, - { 0, "lf t55xx write" }, - { 0, "lf t55xx bruteforce" }, - { 0, "lf t55xx chk" }, - { 0, "lf t55xx protect" }, - { 0, "lf t55xx recoverpw" }, - { 1, "lf t55xx sniff" }, - { 0, "lf t55xx special" }, - { 0, "lf t55xx wipe" }, - { 1, "lf viking help" }, - { 1, "lf viking demod" }, - { 0, "lf viking reader" }, - { 0, "lf viking clone" }, - { 0, "lf viking sim" }, - { 1, "lf visa2000 help" }, - { 1, "lf visa2000 demod" }, - { 0, "lf visa2000 reader" }, - { 0, "lf visa2000 clone" }, - { 0, "lf visa2000 sim" }, - { 1, "mem help" }, - { 0, "mem baudrate" }, - { 0, "mem dump" }, - { 0, "mem info" }, - { 0, "mem load" }, - { 0, "mem wipe" }, - { 1, "mem spiffs help" }, - { 0, "mem spiffs copy" }, - { 0, "mem spiffs check" }, - { 0, "mem spiffs dump" }, - { 0, "mem spiffs info" }, - { 0, "mem spiffs mount" }, - { 0, "mem spiffs remove" }, - { 0, "mem spiffs rename" }, - { 0, "mem spiffs test" }, - { 0, "mem spiffs tree" }, - { 0, "mem spiffs unmount" }, - { 0, "mem spiffs upload" }, - { 0, "mem spiffs view" }, - { 0, "mem spiffs wipe" }, - { 1, "nfc help" }, - { 1, "nfc decode" }, - { 0, "nfc type1 read" }, - { 1, "nfc type1 help" }, - { 0, "nfc type2 read" }, - { 1, "nfc type2 help" }, - { 0, "nfc type4a format" }, - { 0, "nfc type4a read" }, - { 0, "nfc type4a write" }, - { 0, "nfc type4a st25taread" }, - { 1, "nfc type4a help" }, - { 0, "nfc type4b read" }, - { 1, "nfc type4b help" }, - { 0, "nfc mf cformat" }, - { 0, "nfc mf cread" }, - { 0, "nfc mf cwrite" }, - { 0, "nfc mf pread" }, - { 1, "nfc mf help" }, - { 0, "nfc barcode read" }, - { 0, "nfc barcode sim" }, - { 1, "nfc barcode help" }, - { 1, "piv help" }, - { 0, "piv select" }, - { 0, "piv getdata" }, - { 0, "piv authsign" }, - { 0, "piv scan" }, - { 1, "piv list" }, - { 1, "smart help" }, - { 1, "smart list" }, - { 0, "smart info" }, - { 0, "smart reader" }, - { 0, "smart raw" }, - { 1, "smart upgrade" }, - { 0, "smart setclock" }, - { 0, "smart brute" }, - { 1, "script help" }, - { 1, "script list" }, - { 1, "script run" }, - { 1, "trace help" }, - { 1, "trace extract" }, - { 1, "trace list" }, - { 1, "trace load" }, - { 1, "trace save" }, - { 1, "usart help" }, - { 0, "usart btpin" }, - { 0, "usart btfactory" }, - { 0, "usart tx" }, - { 0, "usart rx" }, - { 0, "usart txrx" }, - { 0, "usart txhex" }, - { 0, "usart rxhex" }, - { 0, "usart config" }, - { 1, "wiegand help" }, - { 1, "wiegand list" }, - { 1, "wiegand encode" }, - { 1, "wiegand decode" }, + { 1, "help" }, + { 0, "auto" }, + { 1, "clear" }, + { 1, "hints" }, + { 1, "msleep" }, + { 1, "rem" }, + { 1, "quit" }, + { 1, "exit" }, + { 1, "prefs help" }, + { 1, "prefs show" }, + { 1, "prefs get barmode" }, + { 1, "prefs get clientdebug" }, + { 1, "prefs get clientdelay" }, + { 1, "prefs get color" }, + { 1, "prefs get savepaths" }, + { 1, "prefs get emoji" }, + { 1, "prefs get hints" }, + { 1, "prefs get output" }, + { 1, "prefs get plotsliders" }, + { 1, "prefs set help" }, + { 1, "prefs set barmode" }, + { 1, "prefs set clientdebug" }, + { 1, "prefs set clientdelay" }, + { 1, "prefs set color" }, + { 1, "prefs set emoji" }, + { 1, "prefs set hints" }, + { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, + { 1, "prefs set plotsliders" }, + { 1, "analyse help" }, + { 1, "analyse lcr" }, + { 1, "analyse crc" }, + { 1, "analyse chksum" }, + { 1, "analyse dates" }, + { 1, "analyse lfsr" }, + { 1, "analyse a" }, + { 1, "analyse nuid" }, + { 1, "analyse demodbuff" }, + { 1, "analyse freq" }, + { 1, "analyse foo" }, + { 1, "analyse units" }, + { 1, "data help" }, + { 1, "data biphaserawdecode" }, + { 1, "data detectclock" }, + { 1, "data fsktonrz" }, + { 1, "data manrawdecode" }, + { 1, "data modulation" }, + { 1, "data rawdemod" }, + { 1, "data askedgedetect" }, + { 1, "data autocorr" }, + { 1, "data dirthreshold" }, + { 1, "data decimate" }, + { 1, "data undecimate" }, + { 1, "data hide" }, + { 1, "data hpf" }, + { 1, "data iir" }, + { 1, "data grid" }, + { 1, "data ltrim" }, + { 1, "data mtrim" }, + { 1, "data norm" }, + { 1, "data plot" }, + { 1, "data rtrim" }, + { 1, "data setgraphmarkers" }, + { 1, "data shiftgraphzero" }, + { 1, "data timescale" }, + { 1, "data zerocrossings" }, + { 1, "data convertbitstream" }, + { 1, "data getbitstream" }, + { 1, "data asn1" }, + { 1, "data bin2hex" }, + { 0, "data bitsamples" }, + { 1, "data clear" }, + { 1, "data diff" }, + { 0, "data hexsamples" }, + { 1, "data hex2bin" }, + { 1, "data load" }, + { 1, "data print" }, + { 0, "data samples" }, + { 1, "data save" }, + { 1, "data setdebugmode" }, + { 0, "data tune" }, + { 1, "emv help" }, + { 0, "emv exec" }, + { 0, "emv pse" }, + { 0, "emv search" }, + { 0, "emv select" }, + { 0, "emv gpo" }, + { 0, "emv readrec" }, + { 0, "emv genac" }, + { 0, "emv challenge" }, + { 0, "emv intauth" }, + { 0, "emv scan" }, + { 1, "emv test" }, + { 1, "emv list" }, + { 0, "emv roca" }, + { 1, "hf help" }, + { 1, "hf list" }, + { 0, "hf plot" }, + { 0, "hf tune" }, + { 1, "hf search" }, + { 0, "hf sniff" }, + { 1, "hf 14a help" }, + { 1, "hf 14a list" }, + { 0, "hf 14a antifuzz" }, + { 0, "hf 14a config" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a info" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a apdu" }, + { 0, "hf 14a apdufind" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a ndefformat" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a ndefwrite" }, + { 1, "hf 14b help" }, + { 0, "hf 14b apdu" }, + { 0, "hf 14b dump" }, + { 0, "hf 14b info" }, + { 1, "hf 14b list" }, + { 0, "hf 14b ndefread" }, + { 0, "hf 14b raw" }, + { 0, "hf 14b reader" }, + { 0, "hf 14b sim" }, + { 0, "hf 14b sniff" }, + { 0, "hf 14b rdbl" }, + { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, + { 1, "hf 15 help" }, + { 1, "hf 15 list" }, + { 1, "hf 15 demod" }, + { 0, "hf 15 dump" }, + { 0, "hf 15 info" }, + { 0, "hf 15 sniff" }, + { 0, "hf 15 raw" }, + { 0, "hf 15 rdbl" }, + { 0, "hf 15 rdmulti" }, + { 0, "hf 15 reader" }, + { 0, "hf 15 restore" }, + { 0, "hf 15 samples" }, + { 0, "hf 15 eload" }, + { 0, "hf 15 esave" }, + { 0, "hf 15 eview" }, + { 0, "hf 15 sim" }, + { 0, "hf 15 slixwritepwd" }, + { 0, "hf 15 slixeasdisable" }, + { 0, "hf 15 slixeasenable" }, + { 0, "hf 15 slixprivacydisable" }, + { 0, "hf 15 slixprivacyenable" }, + { 0, "hf 15 passprotectafi" }, + { 0, "hf 15 passprotecteas" }, + { 0, "hf 15 wrbl" }, + { 0, "hf 15 findafi" }, + { 0, "hf 15 writeafi" }, + { 0, "hf 15 writedsfid" }, + { 0, "hf 15 csetuid" }, + { 1, "hf cipurse help" }, + { 0, "hf cipurse info" }, + { 0, "hf cipurse select" }, + { 0, "hf cipurse auth" }, + { 0, "hf cipurse read" }, + { 0, "hf cipurse write" }, + { 0, "hf cipurse aread" }, + { 0, "hf cipurse awrite" }, + { 0, "hf cipurse formatall" }, + { 0, "hf cipurse create" }, + { 0, "hf cipurse delete" }, + { 0, "hf cipurse updkey" }, + { 0, "hf cipurse updakey" }, + { 0, "hf cipurse default" }, + { 1, "hf cipurse test" }, + { 1, "hf epa help" }, + { 0, "hf epa cnonces" }, + { 0, "hf epa replay" }, + { 0, "hf epa sim" }, + { 1, "hf emrtd help" }, + { 0, "hf emrtd dump" }, + { 1, "hf emrtd info" }, + { 1, "hf emrtd list" }, + { 1, "hf felica help" }, + { 1, "hf felica list" }, + { 0, "hf felica reader" }, + { 0, "hf felica info" }, + { 0, "hf felica sniff" }, + { 0, "hf felica raw" }, + { 0, "hf felica rdbl" }, + { 0, "hf felica wrbl" }, + { 0, "hf felica rqservice" }, + { 0, "hf felica rqresponse" }, + { 0, "hf felica scsvcode" }, + { 0, "hf felica rqsyscode" }, + { 0, "hf felica auth1" }, + { 0, "hf felica auth2" }, + { 0, "hf felica rqspecver" }, + { 0, "hf felica resetmode" }, + { 0, "hf felica litesim" }, + { 0, "hf felica litedump" }, + { 1, "hf fido help" }, + { 1, "hf fido list" }, + { 0, "hf fido info" }, + { 0, "hf fido reg" }, + { 0, "hf fido auth" }, + { 0, "hf fido make" }, + { 0, "hf fido assert" }, + { 1, "hf fudan help" }, + { 0, "hf fudan reader" }, + { 0, "hf fudan dump" }, + { 0, "hf fudan rdbl" }, + { 1, "hf fudan view" }, + { 0, "hf fudan wrbl" }, + { 1, "hf gallagher help" }, + { 0, "hf gallagher reader" }, + { 0, "hf gallagher clone" }, + { 0, "hf gallagher delete" }, + { 1, "hf gallagher diversifykey" }, + { 1, "hf gallagher decode" }, + { 1, "hf ksx6924 help" }, + { 0, "hf ksx6924 select" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 init" }, + { 0, "hf ksx6924 prec" }, + { 1, "hf jooki help" }, + { 0, "hf jooki clone" }, + { 1, "hf jooki decode" }, + { 1, "hf jooki encode" }, + { 0, "hf jooki sim" }, + { 1, "hf iclass help" }, + { 0, "hf iclass dump" }, + { 1, "hf iclass info" }, + { 1, "hf iclass list" }, + { 0, "hf iclass rdbl" }, + { 0, "hf iclass reader" }, + { 0, "hf iclass restore" }, + { 0, "hf iclass sniff" }, + { 0, "hf iclass wrbl" }, + { 0, "hf iclass chk" }, + { 1, "hf iclass loclass" }, + { 1, "hf iclass lookup" }, + { 0, "hf iclass sim" }, + { 0, "hf iclass eload" }, + { 0, "hf iclass esave" }, + { 0, "hf iclass eview" }, + { 1, "hf iclass configcard" }, + { 1, "hf iclass calcnewkey" }, + { 1, "hf iclass encode" }, + { 1, "hf iclass encrypt" }, + { 1, "hf iclass decrypt" }, + { 1, "hf iclass managekeys" }, + { 1, "hf iclass permutekey" }, + { 1, "hf iclass view" }, + { 1, "hf legic help" }, + { 0, "hf legic dump" }, + { 0, "hf legic info" }, + { 1, "hf legic list" }, + { 0, "hf legic rdbl" }, + { 0, "hf legic reader" }, + { 0, "hf legic restore" }, + { 0, "hf legic wipe" }, + { 0, "hf legic wrbl" }, + { 0, "hf legic sim" }, + { 0, "hf legic eload" }, + { 0, "hf legic esave" }, + { 0, "hf legic eview" }, + { 1, "hf legic crc" }, + { 1, "hf legic view" }, + { 1, "hf lto help" }, + { 0, "hf lto dump" }, + { 0, "hf lto info" }, + { 1, "hf lto list" }, + { 0, "hf lto rdbl" }, + { 0, "hf lto reader" }, + { 0, "hf lto restore" }, + { 0, "hf lto wrbl" }, + { 1, "hf mf help" }, + { 1, "hf mf list" }, + { 0, "hf mf darkside" }, + { 0, "hf mf nested" }, + { 1, "hf mf hardnested" }, + { 0, "hf mf staticnested" }, + { 0, "hf mf autopwn" }, + { 0, "hf mf nack" }, + { 0, "hf mf chk" }, + { 0, "hf mf fchk" }, + { 1, "hf mf decrypt" }, + { 0, "hf mf supercard" }, + { 0, "hf mf auth4" }, + { 1, "hf mf acl" }, + { 0, "hf mf dump" }, + { 1, "hf mf mad" }, + { 0, "hf mf personalize" }, + { 0, "hf mf rdbl" }, + { 0, "hf mf rdsc" }, + { 0, "hf mf restore" }, + { 0, "hf mf setmod" }, + { 1, "hf mf value" }, + { 1, "hf mf view" }, + { 0, "hf mf wipe" }, + { 0, "hf mf wrbl" }, + { 0, "hf mf sim" }, + { 0, "hf mf ecfill" }, + { 0, "hf mf eclr" }, + { 0, "hf mf egetblk" }, + { 0, "hf mf egetsc" }, + { 0, "hf mf ekeyprn" }, + { 0, "hf mf eload" }, + { 0, "hf mf esave" }, + { 0, "hf mf esetblk" }, + { 0, "hf mf eview" }, + { 0, "hf mf cgetblk" }, + { 0, "hf mf cgetsc" }, + { 0, "hf mf cload" }, + { 0, "hf mf csave" }, + { 0, "hf mf csetblk" }, + { 0, "hf mf csetuid" }, + { 0, "hf mf cview" }, + { 0, "hf mf cwipe" }, + { 0, "hf mf gen3uid" }, + { 0, "hf mf gen3blk" }, + { 0, "hf mf gen3freeze" }, + { 0, "hf mf ggetblk" }, + { 0, "hf mf gload" }, + { 0, "hf mf gsave" }, + { 0, "hf mf gsetblk" }, + { 0, "hf mf gview" }, + { 0, "hf mf ndefformat" }, + { 0, "hf mf ndefread" }, + { 0, "hf mf ndefwrite" }, + { 1, "hf mfp help" }, + { 0, "hf mfp info" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp auth" }, + { 0, "hf mfp rdbl" }, + { 0, "hf mfp rdsc" }, + { 0, "hf mfp wrbl" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp mad" }, + { 0, "hf mfp ndefread" }, + { 1, "hf mfu help" }, + { 1, "hf mfu keygen" }, + { 1, "hf mfu pwdgen" }, + { 0, "hf mfu otptear" }, + { 0, "hf mfu cauth" }, + { 0, "hf mfu dump" }, + { 0, "hf mfu info" }, + { 0, "hf mfu ndefread" }, + { 0, "hf mfu rdbl" }, + { 0, "hf mfu restore" }, + { 1, "hf mfu view" }, + { 0, "hf mfu wrbl" }, + { 0, "hf mfu eload" }, + { 0, "hf mfu esave" }, + { 0, "hf mfu eview" }, + { 0, "hf mfu sim" }, + { 0, "hf mfu setpwd" }, + { 0, "hf mfu setuid" }, + { 1, "hf mfdes help" }, + { 0, "hf mfdes info" }, + { 0, "hf mfdes getuid" }, + { 0, "hf mfdes default" }, + { 0, "hf mfdes auth" }, + { 0, "hf mfdes chk" }, + { 0, "hf mfdes detect" }, + { 0, "hf mfdes freemem" }, + { 0, "hf mfdes setconfig" }, + { 0, "hf mfdes formatpicc" }, + { 1, "hf mfdes list" }, + { 0, "hf mfdes mad" }, + { 0, "hf mfdes lsapp" }, + { 0, "hf mfdes getaids" }, + { 0, "hf mfdes getappnames" }, + { 0, "hf mfdes bruteaid" }, + { 0, "hf mfdes createapp" }, + { 0, "hf mfdes deleteapp" }, + { 0, "hf mfdes selectapp" }, + { 0, "hf mfdes changekey" }, + { 0, "hf mfdes chkeysettings" }, + { 0, "hf mfdes getkeysettings" }, + { 0, "hf mfdes getkeyversions" }, + { 0, "hf mfdes getfileids" }, + { 0, "hf mfdes getfileisoids" }, + { 0, "hf mfdes lsfiles" }, + { 0, "hf mfdes dump" }, + { 0, "hf mfdes createfile" }, + { 0, "hf mfdes createvaluefile" }, + { 0, "hf mfdes createrecordfile" }, + { 0, "hf mfdes createmacfile" }, + { 0, "hf mfdes deletefile" }, + { 0, "hf mfdes getfilesettings" }, + { 0, "hf mfdes chfilesettings" }, + { 0, "hf mfdes read" }, + { 0, "hf mfdes write" }, + { 0, "hf mfdes value" }, + { 0, "hf mfdes clearrecfile" }, + { 1, "hf mfdes test" }, + { 1, "hf ntag424 help" }, + { 0, "hf ntag424 info" }, + { 0, "hf ntag424 sdm" }, + { 1, "hf ntag424 view" }, + { 1, "hf seos help" }, + { 0, "hf seos info" }, + { 1, "hf seos list" }, + { 1, "hf st25ta help" }, + { 0, "hf st25ta info" }, + { 1, "hf st25ta list" }, + { 1, "hf st25ta ndefread" }, + { 0, "hf st25ta protect" }, + { 0, "hf st25ta pwd" }, + { 0, "hf st25ta sim" }, + { 1, "hf tesla help" }, + { 0, "hf tesla info" }, + { 1, "hf tesla list" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, + { 1, "hf thinfilm help" }, + { 0, "hf thinfilm info" }, + { 1, "hf thinfilm list" }, + { 0, "hf thinfilm sim" }, + { 1, "hf topaz help" }, + { 0, "hf topaz dump" }, + { 1, "hf topaz list" }, + { 0, "hf topaz info" }, + { 0, "hf topaz reader" }, + { 0, "hf topaz sim" }, + { 0, "hf topaz sniff" }, + { 0, "hf topaz raw" }, + { 0, "hf topaz rdbl" }, + { 1, "hf topaz view" }, + { 0, "hf topaz wrbl" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, + { 0, "hf xerox dump" }, + { 1, "hf waveshare help" }, + { 0, "hf waveshare loadbmp" }, + { 1, "hw help" }, + { 0, "hw break" }, + { 1, "hw connect" }, + { 0, "hw dbg" }, + { 0, "hw detectreader" }, + { 0, "hw fpgaoff" }, + { 0, "hw lcd" }, + { 0, "hw lcdreset" }, + { 0, "hw ping" }, + { 0, "hw readmem" }, + { 0, "hw reset" }, + { 0, "hw setlfdivisor" }, + { 0, "hw setmux" }, + { 0, "hw standalone" }, + { 0, "hw status" }, + { 0, "hw tearoff" }, + { 0, "hw tia" }, + { 0, "hw tune" }, + { 1, "hw version" }, + { 1, "lf help" }, + { 0, "lf config" }, + { 0, "lf cmdread" }, + { 0, "lf read" }, + { 1, "lf search" }, + { 0, "lf sim" }, + { 0, "lf simask" }, + { 0, "lf simfsk" }, + { 0, "lf simpsk" }, + { 0, "lf simbidir" }, + { 0, "lf sniff" }, + { 0, "lf tune" }, + { 1, "lf awid help" }, + { 1, "lf awid demod" }, + { 0, "lf awid reader" }, + { 0, "lf awid clone" }, + { 0, "lf awid sim" }, + { 0, "lf awid brute" }, + { 0, "lf awid watch" }, + { 1, "lf cotag help" }, + { 1, "lf cotag demod" }, + { 0, "lf cotag reader" }, + { 1, "lf destron help" }, + { 1, "lf destron demod" }, + { 0, "lf destron reader" }, + { 0, "lf destron clone" }, + { 0, "lf destron sim" }, + { 1, "lf em help" }, + { 1, "lf em 410x help" }, + { 1, "lf em 410x demod" }, + { 0, "lf em 410x reader" }, + { 0, "lf em 410x sim" }, + { 0, "lf em 410x brute" }, + { 0, "lf em 410x watch" }, + { 0, "lf em 410x spoof" }, + { 0, "lf em 410x clone" }, + { 1, "lf em 4x05 help" }, + { 0, "lf em 4x05 brute" }, + { 0, "lf em 4x05 chk" }, + { 1, "lf em 4x05 demod" }, + { 0, "lf em 4x05 dump" }, + { 0, "lf em 4x05 info" }, + { 0, "lf em 4x05 read" }, + { 1, "lf em 4x05 sniff" }, + { 0, "lf em 4x05 unlock" }, + { 0, "lf em 4x05 wipe" }, + { 0, "lf em 4x05 write" }, + { 1, "lf em 4x50 help" }, + { 0, "lf em 4x50 brute" }, + { 0, "lf em 4x50 chk" }, + { 0, "lf em 4x50 dump" }, + { 0, "lf em 4x50 info" }, + { 0, "lf em 4x50 login" }, + { 0, "lf em 4x50 rdbl" }, + { 0, "lf em 4x50 reader" }, + { 0, "lf em 4x50 restore" }, + { 0, "lf em 4x50 wrbl" }, + { 0, "lf em 4x50 wrpwd" }, + { 0, "lf em 4x50 wipe" }, + { 0, "lf em 4x50 eload" }, + { 0, "lf em 4x50 esave" }, + { 0, "lf em 4x50 eview" }, + { 0, "lf em 4x50 sim" }, + { 1, "lf em 4x70 help" }, + { 0, "lf em 4x70 brute" }, + { 0, "lf em 4x70 info" }, + { 0, "lf em 4x70 write" }, + { 0, "lf em 4x70 unlock" }, + { 0, "lf em 4x70 auth" }, + { 0, "lf em 4x70 writepin" }, + { 0, "lf em 4x70 writekey" }, + { 1, "lf fdxb help" }, + { 1, "lf fdxb demod" }, + { 0, "lf fdxb reader" }, + { 0, "lf fdxb clone" }, + { 0, "lf fdxb sim" }, + { 1, "lf gallagher help" }, + { 1, "lf gallagher demod" }, + { 0, "lf gallagher reader" }, + { 0, "lf gallagher clone" }, + { 0, "lf gallagher sim" }, + { 1, "lf gproxii help" }, + { 1, "lf gproxii demod" }, + { 0, "lf gproxii reader" }, + { 0, "lf gproxii clone" }, + { 0, "lf gproxii sim" }, + { 1, "lf hid help" }, + { 1, "lf hid demod" }, + { 0, "lf hid reader" }, + { 0, "lf hid clone" }, + { 0, "lf hid sim" }, + { 0, "lf hid brute" }, + { 0, "lf hid watch" }, + { 1, "lf hitag help" }, + { 0, "lf hitag eload" }, + { 1, "lf hitag list" }, + { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, + { 0, "lf hitag sim" }, + { 0, "lf hitag sniff" }, + { 0, "lf hitag writer" }, + { 0, "lf hitag dump" }, + { 0, "lf hitag cc" }, + { 1, "lf idteck help" }, + { 1, "lf idteck demod" }, + { 0, "lf idteck reader" }, + { 0, "lf idteck clone" }, + { 0, "lf idteck sim" }, + { 1, "lf indala help" }, + { 0, "lf indala brute" }, + { 1, "lf indala demod" }, + { 1, "lf indala altdemod" }, + { 0, "lf indala reader" }, + { 0, "lf indala clone" }, + { 0, "lf indala sim" }, + { 1, "lf io help" }, + { 1, "lf io demod" }, + { 0, "lf io reader" }, + { 0, "lf io clone" }, + { 0, "lf io sim" }, + { 0, "lf io watch" }, + { 1, "lf jablotron help" }, + { 1, "lf jablotron demod" }, + { 0, "lf jablotron reader" }, + { 0, "lf jablotron clone" }, + { 0, "lf jablotron sim" }, + { 1, "lf keri help" }, + { 1, "lf keri demod" }, + { 0, "lf keri reader" }, + { 0, "lf keri clone" }, + { 0, "lf keri sim" }, + { 1, "lf motorola help" }, + { 1, "lf motorola demod" }, + { 0, "lf motorola reader" }, + { 0, "lf motorola clone" }, + { 0, "lf motorola sim" }, + { 1, "lf nedap help" }, + { 1, "lf nedap demod" }, + { 0, "lf nedap reader" }, + { 0, "lf nedap clone" }, + { 0, "lf nedap sim" }, + { 1, "lf nexwatch help" }, + { 1, "lf nexwatch demod" }, + { 0, "lf nexwatch reader" }, + { 0, "lf nexwatch clone" }, + { 0, "lf nexwatch sim" }, + { 1, "lf noralsy help" }, + { 1, "lf noralsy demod" }, + { 0, "lf noralsy reader" }, + { 0, "lf noralsy clone" }, + { 0, "lf noralsy sim" }, + { 1, "lf pac help" }, + { 1, "lf pac demod" }, + { 0, "lf pac reader" }, + { 0, "lf pac clone" }, + { 0, "lf pac sim" }, + { 1, "lf paradox help" }, + { 1, "lf paradox demod" }, + { 0, "lf paradox reader" }, + { 0, "lf paradox clone" }, + { 0, "lf paradox sim" }, + { 1, "lf pcf7931 help" }, + { 0, "lf pcf7931 reader" }, + { 0, "lf pcf7931 write" }, + { 1, "lf pcf7931 config" }, + { 1, "lf presco help" }, + { 1, "lf presco demod" }, + { 0, "lf presco reader" }, + { 0, "lf presco clone" }, + { 0, "lf presco sim" }, + { 1, "lf pyramid help" }, + { 1, "lf pyramid demod" }, + { 0, "lf pyramid reader" }, + { 0, "lf pyramid clone" }, + { 0, "lf pyramid sim" }, + { 1, "lf securakey help" }, + { 1, "lf securakey demod" }, + { 0, "lf securakey reader" }, + { 0, "lf securakey clone" }, + { 0, "lf securakey sim" }, + { 1, "lf ti help" }, + { 1, "lf ti demod" }, + { 0, "lf ti reader" }, + { 0, "lf ti write" }, + { 1, "lf t55xx help" }, + { 0, "lf t55xx clonehelp" }, + { 1, "lf t55xx config" }, + { 0, "lf t55xx dangerraw" }, + { 1, "lf t55xx detect" }, + { 0, "lf t55xx deviceconfig" }, + { 0, "lf t55xx dump" }, + { 1, "lf t55xx info" }, + { 0, "lf t55xx p1detect" }, + { 0, "lf t55xx read" }, + { 0, "lf t55xx resetread" }, + { 0, "lf t55xx restore" }, + { 1, "lf t55xx trace" }, + { 0, "lf t55xx wakeup" }, + { 0, "lf t55xx write" }, + { 0, "lf t55xx bruteforce" }, + { 0, "lf t55xx chk" }, + { 0, "lf t55xx protect" }, + { 0, "lf t55xx recoverpw" }, + { 1, "lf t55xx sniff" }, + { 0, "lf t55xx special" }, + { 0, "lf t55xx wipe" }, + { 1, "lf viking help" }, + { 1, "lf viking demod" }, + { 0, "lf viking reader" }, + { 0, "lf viking clone" }, + { 0, "lf viking sim" }, + { 1, "lf visa2000 help" }, + { 1, "lf visa2000 demod" }, + { 0, "lf visa2000 reader" }, + { 0, "lf visa2000 clone" }, + { 0, "lf visa2000 sim" }, + { 1, "mem help" }, + { 0, "mem baudrate" }, + { 0, "mem dump" }, + { 0, "mem info" }, + { 0, "mem load" }, + { 0, "mem wipe" }, + { 1, "mem spiffs help" }, + { 0, "mem spiffs copy" }, + { 0, "mem spiffs check" }, + { 0, "mem spiffs dump" }, + { 0, "mem spiffs info" }, + { 0, "mem spiffs mount" }, + { 0, "mem spiffs remove" }, + { 0, "mem spiffs rename" }, + { 0, "mem spiffs test" }, + { 0, "mem spiffs tree" }, + { 0, "mem spiffs unmount" }, + { 0, "mem spiffs upload" }, + { 0, "mem spiffs view" }, + { 0, "mem spiffs wipe" }, + { 1, "nfc help" }, + { 1, "nfc decode" }, + { 0, "nfc type1 read" }, + { 1, "nfc type1 help" }, + { 0, "nfc type2 read" }, + { 1, "nfc type2 help" }, + { 0, "nfc type4a format" }, + { 0, "nfc type4a read" }, + { 0, "nfc type4a write" }, + { 0, "nfc type4a st25taread" }, + { 1, "nfc type4a help" }, + { 0, "nfc type4b read" }, + { 1, "nfc type4b help" }, + { 0, "nfc mf cformat" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf cwrite" }, + { 0, "nfc mf pread" }, + { 1, "nfc mf help" }, + { 0, "nfc barcode read" }, + { 0, "nfc barcode sim" }, + { 1, "nfc barcode help" }, + { 1, "piv help" }, + { 0, "piv select" }, + { 0, "piv getdata" }, + { 0, "piv authsign" }, + { 0, "piv scan" }, + { 1, "piv list" }, + { 1, "smart help" }, + { 1, "smart list" }, + { 0, "smart info" }, + { 0, "smart reader" }, + { 0, "smart raw" }, + { 1, "smart upgrade" }, + { 0, "smart setclock" }, + { 0, "smart brute" }, + { 1, "script help" }, + { 1, "script list" }, + { 1, "script run" }, + { 1, "trace help" }, + { 1, "trace extract" }, + { 1, "trace list" }, + { 1, "trace load" }, + { 1, "trace save" }, + { 1, "usart help" }, + { 0, "usart btpin" }, + { 0, "usart btfactory" }, + { 0, "usart tx" }, + { 0, "usart rx" }, + { 0, "usart txrx" }, + { 0, "usart txhex" }, + { 0, "usart rxhex" }, + { 0, "usart config" }, + { 1, "wiegand help" }, + { 1, "wiegand list" }, + { 1, "wiegand encode" }, + { 1, "wiegand decode" }, {0, NULL} }; @@ -788,4 +789,4 @@ const static vocabulory_t vocabulory[] = { } #endif -#endif +#endif \ No newline at end of file diff --git a/doc/commands.json b/doc/commands.json index 3545a9b78..cb68d6069 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -175,13 +175,15 @@ "command": "clear", "description": "Clear the Proxmark3 client terminal screen", "notes": [ - "clear" + "clear -> clear the terminal screen", + "clear -b -> clear the terminal screen and the scrollback buffer" ], "offline": true, "options": [ - "-h, --help This help" + "-h, --help This help", + "-b, --back also clear the scrollback buffer" ], - "usage": "clear [-h]" + "usage": "clear [-hb]" }, "data askedgedetect": { "command": "data askedgedetect", @@ -1858,14 +1860,14 @@ }, "hf 15 slixwritepwd": { "command": "hf 15 slixwritepwd", - "description": "Write a password on a SLIX family ISO-15693 tag", + "description": "Write a password on a SLIX family ISO-15693 tag.nSome tags do not support all different password types.", "notes": [ "hf 15 slixwritepwd -t READ -o 00000000 -n 12131415" ], "offline": false, "options": [ "-h, --help This help", - "-t, --type which password field to write to (some tags do not support all password types)", + "-t, --type which password field to write to", "-o, --old old password (if present), 8 hex bytes", "-n, --new new password, 8 hex bytes" ], @@ -3097,9 +3099,10 @@ "--fc facility code", "--cn card number", "-w, --wiegand see `wiegand list` for available formats", - "--shallow use shallow (ASK) reader modulation instead of OOK" + "--shallow use shallow (ASK) reader modulation instead of OOK", + "-v verbose (print encoded blocks)" ], - "usage": "hf iclass encode [-h] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ] [--shallow]" + "usage": "hf iclass encode [-hv] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ] [--shallow]" }, "hf iclass encrypt": { "command": "hf iclass encrypt", @@ -8190,6 +8193,23 @@ ], "usage": "lf em 4x70 auth [-h] [--par] --rnd --frn " }, + "lf em 4x70 brute": { + "command": "lf em 4x70 brute", + "description": "Optimized partial key-update attack of 16-bit key block 7, 8 or 9 of an EM4x70 This attack does NOT write anything to the tag. Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'. After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'", + "notes": [ + "lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 -> bruteforcing key bits k95...k80" + ], + "offline": false, + "options": [ + "-h, --help This help", + "--par Add parity bit when sending commands", + "-b, --block block/word address, dec", + "--rnd Random 56-bit", + "--frn F(RN) 28-bit as 4 hex bytes", + "-s, --start Start bruteforce enumeration from this key value" + ], + "usage": "lf em 4x70 brute [-h] [--par] -b --rnd --frn [-s ]" + }, "lf em 4x70 help": { "command": "lf em 4x70 help", "description": "help This help", @@ -11882,8 +11902,8 @@ } }, "metadata": { - "commands_extracted": 748, + "commands_extracted": 749, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-01-29T17:39:28" + "extracted_on": "2023-02-11T10:42:29" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 382c98b58..0dbad2544 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -893,6 +893,7 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`lf em 4x70 help `|Y |`This help` +|`lf em 4x70 brute `|N |`Bruteforce EM4X70 to find partial Crypt Key` |`lf em 4x70 info `|N |`Tag information EM4x70` |`lf em 4x70 write `|N |`Write EM4x70` |`lf em 4x70 unlock `|N |`Unlock EM4x70 for writing` From 5a2c6406d88dd04fdc359731f8af48369639e47d Mon Sep 17 00:00:00 2001 From: Jean-Michel Picod Date: Mon, 13 Feb 2023 21:58:34 +0100 Subject: [PATCH 607/759] Allow current directory to import python libraries also fixed a bunch of wrong comments. --- client/src/cmdscript.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/client/src/cmdscript.c b/client/src/cmdscript.c index 114205708..0abab9b01 100644 --- a/client/src/cmdscript.c +++ b/client/src/cmdscript.c @@ -164,11 +164,18 @@ static void set_python_path(const char *path) { } static void set_python_paths(void) { - //--add to the LUA_PATH (package.path in lua) - // so we can load scripts from various places: + // Prepending to sys.path so we can load scripts from various places. + // This means the following directories are in reverse order of + // priority for search python modules. + + // Allow current working directory because it seems that's what users want. + // But put it with lower search priority than the typical pm3 scripts directories + // but still with a higher priority than the pip installed libraries to mimic + // Python interpreter behavior. That should be confusing the users the least. + set_python_path("."); const char *exec_path = get_my_executable_directory(); if (exec_path != NULL) { - // from the ./luascripts/ directory + // from the ./pyscripts/ directory char scripts_path[strlen(exec_path) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, exec_path); strcat(scripts_path, PYTHON_SCRIPTS_SUBDIR); @@ -178,7 +185,7 @@ static void set_python_paths(void) { const char *user_path = get_my_user_directory(); if (user_path != NULL) { - // from the $HOME/.proxmark3/luascripts/ directory + // from the $HOME/.proxmark3/pyscripts/ directory char scripts_path[strlen(user_path) + strlen(PM3_USER_DIRECTORY) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, user_path); strcat(scripts_path, PM3_USER_DIRECTORY); @@ -189,7 +196,7 @@ static void set_python_paths(void) { } if (exec_path != NULL) { - // from the $PREFIX/share/proxmark3/luascripts/ directory + // from the $PREFIX/share/proxmark3/pyscripts/ directory char scripts_path[strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(PYTHON_SCRIPTS_SUBDIR) + strlen(PYTHON_LIBRARIES_WILDCARD) + 1]; strcpy(scripts_path, exec_path); strcat(scripts_path, PM3_SHARE_RELPATH); From 736d24cdabe18001c8dd1c49d700f52a8a199816 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 Feb 2023 21:16:38 +0100 Subject: [PATCH 608/759] increased the readline package to 8.2 --- client/CMakeLists.txt | 2 +- client/experimental_lib/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 5bd3ebddd..0bd8bd5cc 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -121,7 +121,7 @@ if (NOT SKIPREADLINE EQUAL 1) ExternalProject_Add_StepTargets(ncurses configure build install) ExternalProject_Add(readline - URL ftp://ftp.gnu.org/gnu/readline/readline-8.1.tar.gz + URL ftp://ftp.gnu.org/gnu/readline/readline-8.2.tar.gz PREFIX deps/readline DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index 675dda225..bdc122e58 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -122,7 +122,7 @@ if (NOT SKIPREADLINE EQUAL 1) ExternalProject_Add_StepTargets(ncurses configure build install) ExternalProject_Add(readline - URL ftp://ftp.gnu.org/gnu/readline/readline-8.1.tar.gz + URL ftp://ftp.gnu.org/gnu/readline/readline-8.2.tar.gz PREFIX deps/readline DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/readline CONFIGURE_COMMAND ./configure CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} --host=arm --enable-static From e8d448e6d0c44dcbf266e48e74e94b18062ac711 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 14 Feb 2023 21:17:19 +0100 Subject: [PATCH 609/759] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b56f26a9..81b881e6e 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] + - Changed the readline package to v8.2 in the CMAKE files for the client (@iceman1001) - Add ICECLASS standalone read/sim mode (@natesales) - Added verbose flag to `hf iclass encode` (@natesales) - Fixed `Makefile` regression that broke `make install` (@henrygab) From 5d4fe5b8df6b8ae20c1b6f3e73c0387534d1c2cd Mon Sep 17 00:00:00 2001 From: Boris Fersing Date: Thu, 16 Feb 2023 13:24:44 -0500 Subject: [PATCH 610/759] - Mark the credentials as decrypted when decrypting a dump - In the view command, show the credentials if the input dump is decrypted --- CHANGELOG.md | 2 + client/src/cmdhficlass.c | 89 +++++++++++++++++++++++++--------------- 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81b881e6e..668e2c32c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added documentation for usage of Proxmark3 under WSL2 (@henrygab) - Fixed device permissions via updated `udev` rules (@henrygab) - Added `--back` option to `clear` command to clear the scrollback buffer (@wh201906) + - Mark credentials as decrypted in the dump generated by `hf iclass decrypt` + - Show credentials when using `hf iclass view` on a decrypted dump ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 36bd3b3d2..08a3c1a0f 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1202,6 +1202,35 @@ static int CmdHFiClassEView(const char *Cmd) { return PM3_SUCCESS; } +static void iclass_decode_credentials(uint8_t *data) { + BLOCK79ENCRYPTION encryption = (data[(6 * 8) + 7] & 0x03); + bool has_values = (memcmp(data + (8 * 7), empty, 8) != 0) && (memcmp(data + (8 * 7), zeros, 8) != 0); + if (has_values && encryption == None) { + + //todo: remove preamble/sentinel + uint32_t top = 0, mid = 0, bot = 0; + + PrintAndLogEx(INFO, "Block 7 decoder"); + + char hexstr[16 + 1] = {0}; + hex_to_buffer((uint8_t *)hexstr, data + (8 * 7), 8, sizeof(hexstr) - 1, 0, 0, true); + hexstring_to_u96(&top, &mid, &bot, hexstr); + + char binstr[64 + 1]; + hextobinstring(binstr, hexstr); + char *pbin = binstr; + while (strlen(pbin) && *(++pbin) == '0'); + + PrintAndLogEx(SUCCESS, "Binary..................... " _GREEN_("%s"), pbin); + + PrintAndLogEx(INFO, "Wiegand decode"); + wiegand_message_t packed = initialize_message_object(top, mid, bot, 0); + HIDTryUnpack(&packed); + } else { + PrintAndLogEx(INFO, "No credential found"); + } +} + static int CmdHFiClassDecrypt(const char *Cmd) { CLIParserContext *clictx; CLIParserInit(&clictx, "hf iclass decrypt", @@ -1356,21 +1385,36 @@ static int CmdHFiClassDecrypt(const char *Cmd) { //uint8_t numblocks4userid = GetNumberBlocksForUserId(decrypted + (6 * 8)); + bool decrypted_block789 = false; for (uint8_t blocknum = 0; blocknum < limit; ++blocknum) { uint16_t idx = blocknum * 8; memcpy(enc_data, decrypted + idx, 8); - if (aa1_encryption == RFU || aa1_encryption == None) - continue; + switch (aa1_encryption) { + // Right now, only 3DES is supported + case TRIPLEDES: + // Decrypt block 7,8,9 if configured. + if (blocknum > 6 && blocknum <= 9 && memcmp(enc_data, empty, 8) != 0) { + if (use_sc) { + Decrypt(enc_data, decrypted + idx); + } else { + mbedtls_des3_crypt_ecb(&ctx, enc_data, decrypted + idx); + } + decrypted_block789 = true; + } + break; + case DES: + case RFU: + case None: + // Nothing to do for None anyway... + default: + continue; + } - // Decrypted block 7,8,9 if configured. - if (blocknum > 6 && blocknum <= 9 && memcmp(enc_data, empty, 8) != 0) { - if (use_sc) { - Decrypt(enc_data, decrypted + idx); - } else { - mbedtls_des3_crypt_ecb(&ctx, enc_data, decrypted + idx); - } + if (decrypted_block789) { + // Set the 2 last bits of block6 to 0 to mark the data as decrypted + decrypted[(6 * 8) + 7] = decrypted[(6 * 8) + 7] & 0xfc; } } @@ -1404,31 +1448,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { } // decode block 7-8-9 - has_values = (memcmp(decrypted + (8 * 7), empty, 8) != 0) && (memcmp(decrypted + (8 * 7), zeros, 8) != 0); - if (has_values) { - - //todo: remove preamble/sentinel - uint32_t top = 0, mid = 0, bot = 0; - - PrintAndLogEx(INFO, "Block 7 decoder"); - - char hexstr[16 + 1] = {0}; - hex_to_buffer((uint8_t *)hexstr, decrypted + (8 * 7), 8, sizeof(hexstr) - 1, 0, 0, true); - hexstring_to_u96(&top, &mid, &bot, hexstr); - - char binstr[64 + 1]; - hextobinstring(binstr, hexstr); - char *pbin = binstr; - while (strlen(pbin) && *(++pbin) == '0'); - - PrintAndLogEx(SUCCESS, "Binary..................... " _GREEN_("%s"), pbin); - - PrintAndLogEx(INFO, "Wiegand decode"); - wiegand_message_t packed = initialize_message_object(top, mid, bot, 0); - HIDTryUnpack(&packed); - } else { - PrintAndLogEx(INFO, "No credential found"); - } + iclass_decode_credentials(decrypted); // decode block 9 has_values = (memcmp(decrypted + (8 * 9), empty, 8) != 0) && (memcmp(decrypted + (8 * 9), zeros, 8) != 0); @@ -2840,6 +2860,7 @@ static int CmdHFiClassView(const char *Cmd) { print_picopass_header((picopass_hdr_t *) dump); print_picopass_info((picopass_hdr_t *) dump); printIclassDumpContents(dump, startblock, endblock, bytes_read, dense_output); + iclass_decode_credentials(dump); if (verbose) { printIclassSIO(dump); From 2a150b8c6b9b6e9efc600e0821e176ba7ed2682a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 17 Feb 2023 16:37:03 +0100 Subject: [PATCH 611/759] Fix bug preventing args to be passed to the client Bug introduced by ab9dab32947f10c009e30a0a446e8bd021d41988 It was not possible to pass args anymore, e.g. `pm3 -l myscript.lua` --- pm3 | 1 + 1 file changed, 1 insertion(+) diff --git a/pm3 b/pm3 index 52a8ffcc1..e418a3103 100755 --- a/pm3 +++ b/pm3 @@ -446,6 +446,7 @@ for ARG; do CMD "$@" exit $? fi + set -- "$@" "$ARG" done if [ "$1" == "--list" ]; then From 944d6ee5962ed74fdb5ac16fff4002c7c3725d21 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 17 Feb 2023 17:51:59 +0100 Subject: [PATCH 612/759] simpler --- client/src/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 08a3c1a0f..84a6e563d 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1414,7 +1414,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { if (decrypted_block789) { // Set the 2 last bits of block6 to 0 to mark the data as decrypted - decrypted[(6 * 8) + 7] = decrypted[(6 * 8) + 7] & 0xfc; + decrypted[(6 * 8) + 7] &= 0xFC; } } From 5784c8de77f6cabf4d27c76f412dd3a9b441ff63 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Fri, 17 Feb 2023 15:42:46 -0800 Subject: [PATCH 613/759] Update USB Serial Number from SPI flash's uniqueID Also allow flash to be separately enabled via PLATFORM_EXTRAS. NOTE: this does *NOT* enable the serial number in the bootrom. Still investigating options there. --- Makefile.platform.sample | 2 ++ armsrc/appmain.c | 16 +++++++++++++- armsrc/flashmem.c | 8 +++---- common_arm/Makefile.hal | 4 ++++ common_arm/usb_cdc.c | 45 ++++++++++++++++++++++++++++++++++++++++ common_arm/usb_cdc.h | 1 + 6 files changed, 71 insertions(+), 5 deletions(-) diff --git a/Makefile.platform.sample b/Makefile.platform.sample index 21fb2137e..aeb541cee 100644 --- a/Makefile.platform.sample +++ b/Makefile.platform.sample @@ -5,6 +5,8 @@ PLATFORM=PM3RDV4 #PLATFORM=PM3GENERIC # If you want more than one PLATFORM_EXTRAS option, separate them by spaces: #PLATFORM_EXTRAS=BTADDON +#PLATFORM_EXTRAS=FLASH +#PLATFORM_EXTRAS=BTADDON FLASH #STANDALONE=LF_SAMYRUN # Uncomment the lines below in order to make a 256KB image diff --git a/armsrc/appmain.c b/armsrc/appmain.c index bc22f1834..f3a42ed09 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2471,8 +2471,11 @@ static void PacketReceived(PacketCommandNG *packet) { LED_B_OFF(); break; } - if (page < 3) + if (page < 3) { isok = Flash_WipeMemoryPage(page); + // let spiffs check and update its info post flash erase + rdv40_spiffs_check(); + } reply_mix(CMD_ACK, isok, 0, 0, 0, 0); LED_B_OFF(); @@ -2677,6 +2680,17 @@ void __attribute__((noreturn)) AppMain(void) { I2C_init(false); #endif +#ifdef WITH_FLASH + if (FlashInit()) { + uint64_t flash_uniqueID = 0; + if (!Flash_CheckBusy(BUSY_TIMEOUT)) { // OK because firmware was built for devices with flash + Flash_UniqueID((uint8_t*)&(flash_uniqueID)); + } + FlashStop(); + usb_update_serial(flash_uniqueID); + } +#endif + #ifdef WITH_FPC_USART usart_init(USART_BAUD_RATE, USART_PARITY); #endif diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index ba882eaa7..4b6d39b91 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -22,7 +22,7 @@ #include "ticks.h" #include "dbprint.h" #include "string.h" -#include "spiffs.h" +#include "usb_cdc.h" /* here: use NCPS2 @ PA10: */ #define SPI_CSR_NUM 2 @@ -436,7 +436,9 @@ out: return len; } - +// WARNING -- if callers are using a file system (such as SPIFFS), +// they should inform the file system of this change +// e.g., rdv40_spiffs_check() bool Flash_WipeMemoryPage(uint8_t page) { if (!FlashInit()) { if (g_dbglevel > 3) Dbprintf("Flash_WriteData init fail"); @@ -451,8 +453,6 @@ bool Flash_WipeMemoryPage(uint8_t page) { FlashStop(); - // let spiffs check and update its info post flash erase - rdv40_spiffs_check(); return true; } // Wipes flash memory completely, fills with 0xFF diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index 0e9dd455b..a65514784 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -114,6 +114,10 @@ endif # parsing additional PLATFORM_EXTRAS tokens PLATFORM_EXTRAS_TMP:=$(PLATFORM_EXTRAS) +ifneq (,$(findstring FLASH,$(PLATFORM_EXTRAS_TMP))) + PLATFORM_DEFS += -DWITH_FLASH + PLATFORM_EXTRAS_TMP := $(strip $(filter-out FLASH,$(PLATFORM_EXTRAS_TMP))) +endif ifneq (,$(findstring BTADDON,$(PLATFORM_EXTRAS_TMP))) PLATFORM_DEFS += -DWITH_FPC_USART_HOST PLATFORM_EXTRAS_TMP := $(strip $(filter-out BTADDON,$(PLATFORM_EXTRAS_TMP))) diff --git a/common_arm/usb_cdc.c b/common_arm/usb_cdc.c index 0ccf25aef..f805d1797 100644 --- a/common_arm/usb_cdc.c +++ b/common_arm/usb_cdc.c @@ -366,11 +366,56 @@ static const char StrProduct[] = { 'p', 0, 'r', 0, 'o', 0, 'x', 0, 'm', 0, 'a', 0, 'r', 0, 'k', 0, '3', 0 }; +#ifndef WITH_FLASH static const char StrSerialNumber[] = { 14, // Length 0x03, // Type is string 'i', 0, 'c', 0, 'e', 0, 'm', 0, 'a', 0, 'n', 0 }; +#else // WITH_FLASH is defined + +// Manually calculated size of descriptor with unique ID: +// offset 0, lengt h 1: total length field +// offset 1, length 1: descriptor type field +// offset 2, length 12: 6x unicode chars (original string) +// offset 14, length 4: 2x unicode chars (underscores) [[ to avoid descriptor being (size % 8) == 0, OS bug workaround ]] +// offset 18, length 32: 16x unicode chars (8-byte serial as hex characters) +// ============================ +// total: 50 bytes + +#define USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH 50 +char StrSerialNumber[] = { + 14, // Length is initially identical to non-unique version ... The length updated at boot, if unique serial is available + 0x03, // Type is string + 'i', 0, 'c', 0, 'e', 0, 'm', 0, 'a', 0, 'n', 0, + '_', 0, '_', 0, + 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, + 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, +}; +void usb_update_serial(uint64_t newSerialNumber) { + static bool configured = false; // TODO: enable by setting to false here... + if (configured) { + return; + } + // run this only once per boot... even if it fails to find serial number + configured = true; + if ((newSerialNumber == 0x0000000000000000) || (newSerialNumber == 0xFFFFFFFFFFFFFFFF)) { + return; + } + // Descriptor is, effectively, initially identical to non-unique serial + // number because it reports the shorter length in the first byte. + // Convert uniqueID's eight bytes to 16 unicode characters in the + // descriptor and, finally, update the descriptor's length, which + // causes the serial number to become visible. + for (uint8_t i = 0; i < 16; i++) { + uint8_t nibble = (uint8_t)((newSerialNumber >> (60 - (4*i))) & 0xFu); + char c = nibble < 10 ? '0' + nibble : 'A' + (nibble-10); + StrSerialNumber[18+(2*i)] = c; // [ 18, 20, 22, .., 46, 48 ] + } + StrSerialNumber[0] = USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH; +} +#endif + // size includes their own field. static const char StrMS_OSDescriptor[] = { diff --git a/common_arm/usb_cdc.h b/common_arm/usb_cdc.h index a09d3fc33..e7f6f3d09 100644 --- a/common_arm/usb_cdc.h +++ b/common_arm/usb_cdc.h @@ -31,6 +31,7 @@ bool usb_poll_validate_length(void); uint32_t usb_read(uint8_t *data, size_t len); int usb_write(const uint8_t *data, const size_t len); uint32_t usb_read_ng(uint8_t *data, size_t len); +void usb_update_serial(uint64_t newSerialNumber); void SetUSBreconnect(int value); int GetUSBreconnect(void); From 44676bde724fb8718a6ddf6eaa7af3bdbbc259b6 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Fri, 17 Feb 2023 16:59:00 -0800 Subject: [PATCH 614/759] Bootrom: Enable serial number from flash * Add `.ramfunc` section to bootrom loader script * exclude spiffs functionality from flashmem.h/flashmem.c (allows bootrom to use flashmem) * hide unused tick.h / flashmem.h functions from bootrom (not technically necessary; see comments) * bootrom: add source files, include path, and defines when `PLATFORM_DEFS` defines `WITH_FLASH` * Define `AS_BOOTROM` to indicate code is building for bootrom --- armsrc/appmain.c | 2 +- bootrom/Makefile | 8 +- bootrom/bootrom.c | 16 +- bootrom/ldscript-flash | 1 + {armsrc => common_arm}/flashmem.c | 431 +++++++++++++++--------------- {armsrc => common_arm}/flashmem.h | 65 ++++- {armsrc => common_arm}/ticks.c | 85 +++--- {armsrc => common_arm}/ticks.h | 23 +- common_arm/usb_cdc.c | 14 +- 9 files changed, 373 insertions(+), 272 deletions(-) rename {armsrc => common_arm}/flashmem.c (98%) rename {armsrc => common_arm}/flashmem.h (76%) rename {armsrc => common_arm}/ticks.c (99%) rename {armsrc => common_arm}/ticks.h (89%) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index f3a42ed09..90681c324 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2684,7 +2684,7 @@ void __attribute__((noreturn)) AppMain(void) { if (FlashInit()) { uint64_t flash_uniqueID = 0; if (!Flash_CheckBusy(BUSY_TIMEOUT)) { // OK because firmware was built for devices with flash - Flash_UniqueID((uint8_t*)&(flash_uniqueID)); + Flash_UniqueID((uint8_t*)(&flash_uniqueID)); } FlashStop(); usb_update_serial(flash_uniqueID); diff --git a/bootrom/Makefile b/bootrom/Makefile index edb0cc990..cad3e17d1 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -34,11 +34,17 @@ VERSIONSRC = version_pm3.c # THUMBSRC := # stdint.h provided locally until GCC 4.5 becomes C99 compliant -APP_CFLAGS = -I. -ffunction-sections -fdata-sections +APP_CFLAGS = -I. -ffunction-sections -fdata-sections -DAS_BOOTROM # stack-protect , no-pie reduces size on Gentoo Hardened 8.2 gcc, no-common makes sure uninitialized vars don't end up in COMMON area APP_CFLAGS += -fno-stack-protector -fno-pie -fno-common +ifneq (,$(findstring WITH_FLASH,$(PLATFORM_DEFS))) + APP_CFLAGS += -DWITH_FLASH + APP_CFLAGS += -I../common_arm + THUMBSRC += flashmem.c ticks.c +endif + # Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC include ../common_arm/Makefile.common diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 93c4d605e..c94c23481 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -20,6 +20,10 @@ #include "clocks.h" #include "usb_cdc.h" +#ifdef WITH_FLASH +#include "flashmem.h" +#endif + #include "proxmark3_arm.h" #define DEBUG 0 @@ -214,8 +218,18 @@ static void flash_mode(void) { bootrom_unlocked = false; uint8_t rx[sizeof(PacketCommandOLD)]; g_common_area.command = COMMON_AREA_COMMAND_NONE; - if (!g_common_area.flags.button_pressed && BUTTON_PRESS()) + if (!g_common_area.flags.button_pressed && BUTTON_PRESS()) { g_common_area.flags.button_pressed = 1; + } + +#ifdef WITH_FLASH + if (FlashInit()) { // checks for existence of flash also ... OK because bootrom was built for devices with flash + uint64_t flash_uniqueID = 0; + Flash_UniqueID((uint8_t*)&flash_uniqueID); + FlashStop(); + usb_update_serial(flash_uniqueID); + } +#endif usb_enable(); diff --git a/bootrom/ldscript-flash b/bootrom/ldscript-flash index 5d63f9689..374c2d6c7 100644 --- a/bootrom/ldscript-flash +++ b/bootrom/ldscript-flash @@ -53,6 +53,7 @@ SECTIONS *(.rodata.*) *(.data) *(.data.*) + *(.ramfunc) . = ALIGN(4); } >ram AT>bootphase2 :phase2 diff --git a/armsrc/flashmem.c b/common_arm/flashmem.c similarity index 98% rename from armsrc/flashmem.c rename to common_arm/flashmem.c index 4b6d39b91..0a60d43c0 100644 --- a/armsrc/flashmem.c +++ b/common_arm/flashmem.c @@ -20,7 +20,11 @@ #include "proxmark3_arm.h" #include "ticks.h" + +#ifndef AS_BOOTROM #include "dbprint.h" +#endif // AS_BOOTROM + #include "string.h" #include "usb_cdc.h" @@ -37,197 +41,13 @@ static uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD; #define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST) +#ifndef AS_BOOTROM + void FlashmemSetSpiBaudrate(uint32_t baudrate) { FLASHMEM_SPIBAUDRATE = baudrate; Dbprintf("Spi Baudrate : %dMHz", FLASHMEM_SPIBAUDRATE / 1000000); } -// initialize -bool FlashInit(void) { - FlashSetup(FLASHMEM_SPIBAUDRATE); - - StartTicks(); - - if (Flash_CheckBusy(BUSY_TIMEOUT)) { - StopTicks(); - return false; - } - - return true; -} - -void FlashSetup(uint32_t baudrate) { - //WDT_DISABLE - AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; - - // PA10 -> SPI_NCS2 chip select (FLASHMEM) - // PA11 -> SPI_NCS0 chip select (FPGA) - // PA12 -> SPI_MISO Master-In Slave-Out - // PA13 -> SPI_MOSI Master-Out Slave-In - // PA14 -> SPI_SPCK Serial Clock - - // Disable PIO control of the following pins, allows use by the SPI peripheral - AT91C_BASE_PIOA->PIO_PDR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2); - - // Pull-up Enable - AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2); - - // Peripheral A - AT91C_BASE_PIOA->PIO_ASR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK); - - // Peripheral B - AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2; - - //enable the SPI Peripheral clock - AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI); - - - //reset spi needs double SWRST, see atmel's errata on this case - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; - - // Enable SPI - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; - - // NPCS2 Mode 0 - AT91C_BASE_SPI->SPI_MR = - (0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT: - // If DLYBCS is less than or equal to six, six MCK periods - // will be inserted by default. - SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10) - (0 << 7) | // Disable LLB (1=MOSI2MISO test mode) - (1 << 4) | // Disable ModeFault Protection - (0 << 3) | // makes spi operate at MCK (1 is MCK/2) - (0 << 2) | // Chip selects connected directly to peripheral - AT91C_SPI_PS_FIXED | // Fixed Peripheral Select - AT91C_SPI_MSTR; // Master Mode - - uint8_t csaat = 1; - uint32_t dlybct = 0; - uint8_t ncpha = 1; - uint8_t cpol = 0; - if (baudrate > FLASH_MINFAST) { - baudrate = FLASH_FASTBAUD; - //csaat = 0; - dlybct = 1500; - ncpha = 0; - cpol = 0; - } - - AT91C_BASE_SPI->SPI_CSR[2] = - SPI_DLYBCT(dlybct, MCK) | // Delay between Consecutive Transfers (32 MCK periods) - SPI_DLYBS(0, MCK) | // Delay Beforce SPCK CLock - SPI_SCBR(baudrate, MCK) | // SPI Baudrate Selection - AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits) - //AT91C_SPI_CSAAT | // Chip Select inactive after transfer - // 40.4.6.2 SPI: Bad tx_ready Behavior when CSAAT = 1 and SCBR = 1 - // If the SPI is programmed with CSAAT = 1, SCBR(baudrate) = 1 and two transfers are performed consecutively on - // the same slave with an IDLE state between them, the tx_ready signal does not rise after the second data has been - // transferred in the shifter. This can imply for example, that the second data is sent twice. - // COLIN :: For now we STILL use CSAAT=1 to avoid having to (de)assert NPCS manually via PIO lines and we deal with delay - (csaat << 3) | - /* Spi modes: - Mode CPOL CPHA NCPHA - 0 0 0 1 clock normally low read on rising edge - 1 0 1 0 clock normally low read on falling edge - 2 1 0 1 clock normally high read on falling edge - 3 1 1 0 clock normally high read on rising edge - However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI - master mode the ATSAM7S512/256/128/64/321/32 does not sample the data - (MISO) on the opposite edge where data clocks out (MOSI) but the same - edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3 - shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and - that the data changes sometime after the rising edge (about 2 ns). To - be consistent with normal SPI operation, it is probably safe to say - that the data changes on the falling edge and should be sampled on the - rising edge. Therefore, it appears that NCPHA should be treated the - same as CPHA. Thus: - Mode CPOL CPHA NCPHA - 0 0 0 0 clock normally low read on rising edge - 1 0 1 1 clock normally low read on falling edge - 2 1 0 0 clock normally high read on falling edge - 3 1 1 1 clock normally high read on rising edge - Update: for 24MHz, writing is more stable with ncpha=1, else bitflips occur. - */ - (ncpha << 1) | // Clock Phase data captured on leading edge, changes on following edge - (cpol << 0); // Clock Polarity inactive state is logic 0 - - // read first, empty buffer - if (AT91C_BASE_SPI->SPI_RDR == 0) {}; -} - -void FlashStop(void) { - //Bof - //* Reset all the Chip Select register - AT91C_BASE_SPI->SPI_CSR[0] = 0; - AT91C_BASE_SPI->SPI_CSR[1] = 0; - AT91C_BASE_SPI->SPI_CSR[2] = 0; - AT91C_BASE_SPI->SPI_CSR[3] = 0; - - // Reset the SPI mode - AT91C_BASE_SPI->SPI_MR = 0; - - // Disable all interrupts - AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF; - - // SPI disable - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS; - - if (g_dbglevel > 3) Dbprintf("FlashStop"); - - StopTicks(); -} - -// send one byte over SPI -uint16_t FlashSendByte(uint32_t data) { - - // wait until SPI is ready for transfer - //if you are checking for incoming data returned then the TXEMPTY flag is redundant - //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {}; - - // send the data - AT91C_BASE_SPI->SPI_TDR = data; - - //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){}; - - // wait receive transfer is complete - while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0) {}; - - // reading incoming data - return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF); -} - -// send last byte over SPI -uint16_t FlashSendLastByte(uint32_t data) { - return FlashSendByte(data | AT91C_SPI_LASTXFER); -} - -// read state register 1 -uint8_t Flash_ReadStat1(void) { - FlashSendByte(READSTAT1); - return FlashSendLastByte(0xFF); -} - -bool Flash_CheckBusy(uint32_t timeout) { - WaitUS(WINBOND_WRITE_DELAY); - StartCountUS(); - uint32_t _time = GetCountUS(); - - if (g_dbglevel > 3) Dbprintf("Checkbusy in..."); - - do { - if (!(Flash_ReadStat1() & BUSY)) { - return false; - } - } while ((GetCountUS() - _time) < timeout); - - if (timeout <= (GetCountUS() - _time)) { - return true; - } - - return false; -} - // read ID out uint8_t Flash_ReadID(void) { @@ -250,28 +70,6 @@ uint8_t Flash_ReadID(void) { return 0; } -// read unique id for chip. -void Flash_UniqueID(uint8_t *uid) { - - if (Flash_CheckBusy(BUSY_TIMEOUT)) return; - - // reading unique serial number - FlashSendByte(UNIQUE_ID); - FlashSendByte(0xFF); - FlashSendByte(0xFF); - FlashSendByte(0xFF); - FlashSendByte(0xFF); - - uid[7] = FlashSendByte(0xFF); - uid[6] = FlashSendByte(0xFF); - uid[5] = FlashSendByte(0xFF); - uid[4] = FlashSendByte(0xFF); - uid[3] = FlashSendByte(0xFF); - uid[2] = FlashSendByte(0xFF); - uid[1] = FlashSendByte(0xFF); - uid[0] = FlashSendLastByte(0xFF); -} - uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) { if (!FlashInit()) return 0; @@ -326,7 +124,6 @@ uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) { return len; } - //////////////////////////////////////// // Write data can only program one page. A page has 256 bytes. // if len > 256, it might wrap around and overwrite pos 0. @@ -372,7 +169,6 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) { return len; } - // length should never be zero // Max 256 bytes write // out-of-range @@ -571,7 +367,7 @@ void Flashmem_print_status(void) { uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0}; Flash_UniqueID(uid); - Dbprintf(" Unique ID............... 0x%02X%02X%02X%02X%02X%02X%02X%02X", + Dbprintf( " Unique ID............... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"), uid[7], uid[6], uid[5], uid[4], uid[3], uid[2], uid[1], uid[0] ); @@ -616,4 +412,217 @@ void Flashmem_print_info(void) { FlashStop(); } +#endif // #ifndef AS_BOOTROM + +// initialize +bool FlashInit(void) { + FlashSetup(FLASHMEM_SPIBAUDRATE); + + StartTicks(); + + if (Flash_CheckBusy(BUSY_TIMEOUT)) { + StopTicks(); + return false; + } + + return true; +} + +// read unique id for chip. +void Flash_UniqueID(uint8_t *uid) { + + if (Flash_CheckBusy(BUSY_TIMEOUT)) return; + + // reading unique serial number + FlashSendByte(UNIQUE_ID); + FlashSendByte(0xFF); + FlashSendByte(0xFF); + FlashSendByte(0xFF); + FlashSendByte(0xFF); + + uid[7] = FlashSendByte(0xFF); + uid[6] = FlashSendByte(0xFF); + uid[5] = FlashSendByte(0xFF); + uid[4] = FlashSendByte(0xFF); + uid[3] = FlashSendByte(0xFF); + uid[2] = FlashSendByte(0xFF); + uid[1] = FlashSendByte(0xFF); + uid[0] = FlashSendLastByte(0xFF); +} + +void FlashStop(void) { + //Bof + //* Reset all the Chip Select register + AT91C_BASE_SPI->SPI_CSR[0] = 0; + AT91C_BASE_SPI->SPI_CSR[1] = 0; + AT91C_BASE_SPI->SPI_CSR[2] = 0; + AT91C_BASE_SPI->SPI_CSR[3] = 0; + + // Reset the SPI mode + AT91C_BASE_SPI->SPI_MR = 0; + + // Disable all interrupts + AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF; + + // SPI disable + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS; + +#ifndef AS_BOOTROM + if (g_dbglevel > 3) Dbprintf("FlashStop"); +#endif // AS_BOOTROM + + StopTicks(); +} + +void FlashSetup(uint32_t baudrate) { + //WDT_DISABLE + AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; + + // PA10 -> SPI_NCS2 chip select (FLASHMEM) + // PA11 -> SPI_NCS0 chip select (FPGA) + // PA12 -> SPI_MISO Master-In Slave-Out + // PA13 -> SPI_MOSI Master-Out Slave-In + // PA14 -> SPI_SPCK Serial Clock + + // Disable PIO control of the following pins, allows use by the SPI peripheral + AT91C_BASE_PIOA->PIO_PDR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2); + + // Pull-up Enable + AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2); + + // Peripheral A + AT91C_BASE_PIOA->PIO_ASR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK); + + // Peripheral B + AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2; + + //enable the SPI Peripheral clock + AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI); + + + //reset spi needs double SWRST, see atmel's errata on this case + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; + + // Enable SPI + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; + + // NPCS2 Mode 0 + AT91C_BASE_SPI->SPI_MR = + (0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT: + // If DLYBCS is less than or equal to six, six MCK periods + // will be inserted by default. + SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10) + (0 << 7) | // Disable LLB (1=MOSI2MISO test mode) + (1 << 4) | // Disable ModeFault Protection + (0 << 3) | // makes spi operate at MCK (1 is MCK/2) + (0 << 2) | // Chip selects connected directly to peripheral + AT91C_SPI_PS_FIXED | // Fixed Peripheral Select + AT91C_SPI_MSTR; // Master Mode + + uint8_t csaat = 1; + uint32_t dlybct = 0; + uint8_t ncpha = 1; + uint8_t cpol = 0; + if (baudrate > FLASH_MINFAST) { + baudrate = FLASH_FASTBAUD; + //csaat = 0; + dlybct = 1500; + ncpha = 0; + cpol = 0; + } + + AT91C_BASE_SPI->SPI_CSR[2] = + SPI_DLYBCT(dlybct, MCK) | // Delay between Consecutive Transfers (32 MCK periods) + SPI_DLYBS(0, MCK) | // Delay Beforce SPCK CLock + SPI_SCBR(baudrate, MCK) | // SPI Baudrate Selection + AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits) + //AT91C_SPI_CSAAT | // Chip Select inactive after transfer + // 40.4.6.2 SPI: Bad tx_ready Behavior when CSAAT = 1 and SCBR = 1 + // If the SPI is programmed with CSAAT = 1, SCBR(baudrate) = 1 and two transfers are performed consecutively on + // the same slave with an IDLE state between them, the tx_ready signal does not rise after the second data has been + // transferred in the shifter. This can imply for example, that the second data is sent twice. + // COLIN :: For now we STILL use CSAAT=1 to avoid having to (de)assert NPCS manually via PIO lines and we deal with delay + (csaat << 3) | + /* Spi modes: + Mode CPOL CPHA NCPHA + 0 0 0 1 clock normally low read on rising edge + 1 0 1 0 clock normally low read on falling edge + 2 1 0 1 clock normally high read on falling edge + 3 1 1 0 clock normally high read on rising edge + However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI + master mode the ATSAM7S512/256/128/64/321/32 does not sample the data + (MISO) on the opposite edge where data clocks out (MOSI) but the same + edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3 + shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and + that the data changes sometime after the rising edge (about 2 ns). To + be consistent with normal SPI operation, it is probably safe to say + that the data changes on the falling edge and should be sampled on the + rising edge. Therefore, it appears that NCPHA should be treated the + same as CPHA. Thus: + Mode CPOL CPHA NCPHA + 0 0 0 0 clock normally low read on rising edge + 1 0 1 1 clock normally low read on falling edge + 2 1 0 0 clock normally high read on falling edge + 3 1 1 1 clock normally high read on rising edge + Update: for 24MHz, writing is more stable with ncpha=1, else bitflips occur. + */ + (ncpha << 1) | // Clock Phase data captured on leading edge, changes on following edge + (cpol << 0); // Clock Polarity inactive state is logic 0 + + // read first, empty buffer + if (AT91C_BASE_SPI->SPI_RDR == 0) {}; +} + +bool Flash_CheckBusy(uint32_t timeout) { + WaitUS(WINBOND_WRITE_DELAY); + StartCountUS(); + uint32_t _time = GetCountUS(); + +#ifndef AS_BOOTROM + if (g_dbglevel > 3) Dbprintf("Checkbusy in..."); +#endif // AS_BOOTROM + + do { + if (!(Flash_ReadStat1() & BUSY)) { + return false; + } + } while ((GetCountUS() - _time) < timeout); + + if (timeout <= (GetCountUS() - _time)) { + return true; + } + + return false; +} + +// read state register 1 +uint8_t Flash_ReadStat1(void) { + FlashSendByte(READSTAT1); + return FlashSendLastByte(0xFF); +} + +// send one byte over SPI +uint16_t FlashSendByte(uint32_t data) { + + // wait until SPI is ready for transfer + //if you are checking for incoming data returned then the TXEMPTY flag is redundant + //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {}; + + // send the data + AT91C_BASE_SPI->SPI_TDR = data; + + //while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){}; + + // wait receive transfer is complete + while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0) {}; + + // reading incoming data + return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF); +} + +// send last byte over SPI +uint16_t FlashSendLastByte(uint32_t data) { + return FlashSendByte(data | AT91C_SPI_LASTXFER); +} diff --git a/armsrc/flashmem.h b/common_arm/flashmem.h similarity index 76% rename from armsrc/flashmem.h rename to common_arm/flashmem.h index 2b829c378..3578fa933 100644 --- a/armsrc/flashmem.h +++ b/common_arm/flashmem.h @@ -100,17 +100,67 @@ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -void FlashmemSetSpiBaudrate(uint32_t baudrate); bool FlashInit(void); -void FlashSetup(uint32_t baudrate); +void Flash_UniqueID(uint8_t *uid); void FlashStop(void); -bool Flash_WaitIdle(void); + +void FlashSetup(uint32_t baudrate); +bool Flash_CheckBusy(uint32_t timeout); uint8_t Flash_ReadStat1(void); -uint8_t Flash_ReadStat2(void); uint16_t FlashSendByte(uint32_t data); +uint16_t FlashSendLastByte(uint32_t data); + + +#ifndef AS_BOOTROM + // Bootrom does not require these functions. + // Wrap in #ifndef to avoid accidental bloat of bootrom + // Bootrom needs only enough to get uniqueID from flash. + // It calls three functions. Full call trees listed: + // + // FlashInit() + // | + // \____ FlashSetup() + // | \____ leaf + // | + // \____ StartTicks() + // | \____ leaf + // | + // \____ Flash_CheckBusy() [*] + // | \____ WaitUS() + // | | \____ WaitTicks() + // | | \____ leaf + // | | + // | \____ StartCountUS() + // | | \____ leaf + // | | + // | \____ GetCountUS() + // | | \____ leaf + // | | + // | \____ Flash_ReadStat1() + // | \____ FlashSendByte() + // | | \____ leaf + // | | + // | \____ FlashSendLastByte() + // | \____ FlashSendByte() + // | \____ leaf + // | + // \____ StopTicks() + // \____ leaf + // + // Flash_UniqueID() + // \____ FlashCheckBusy() (see FlashInit) + // \____ FlashSendByteByte() (see FlashInit) + // \____ FlashSendByteLastByte() (see FlashInit) + // + // + // FlashStop() [*] + + + +void FlashmemSetSpiBaudrate(uint32_t baudrate); +bool Flash_WaitIdle(void); void Flash_TransferAdresse(uint32_t address); -bool Flash_CheckBusy(uint32_t timeout); void Flash_WriteEnable(void); bool Flash_WipeMemoryPage(uint8_t page); @@ -119,7 +169,6 @@ bool Flash_Erase4k(uint8_t block, uint8_t sector); //bool Flash_Erase32k(uint32_t address); bool Flash_Erase64k(uint8_t block); -void Flash_UniqueID(uint8_t *uid); uint8_t Flash_ReadID(void); uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len); uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len); @@ -128,6 +177,8 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len); uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len); void Flashmem_print_status(void); void Flashmem_print_info(void); -uint16_t FlashSendLastByte(uint32_t data); + +#endif // #ifndef AS_BOOTROM + #endif diff --git a/armsrc/ticks.c b/common_arm/ticks.c similarity index 99% rename from armsrc/ticks.c rename to common_arm/ticks.c index 3cf2c54dc..34c480061 100644 --- a/armsrc/ticks.c +++ b/common_arm/ticks.c @@ -19,9 +19,13 @@ #include "ticks.h" #include "proxmark3_arm.h" -#include "dbprint.h" +#ifndef AS_BOOTROM + #include "dbprint.h" +#endif +#ifndef AS_BOOTROM + // timer counts in 666ns increments (32/48MHz), rounding applies // WARNING: timer can't measure more than 43ms (666ns * 0xFFFF) void SpinDelayUsPrecision(int us) { @@ -117,40 +121,6 @@ uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks) { return (UINT32_MAX - start_ticks) + stop_ticks; } -// ------------------------------------------------------------------------- -// microseconds timer -// ------------------------------------------------------------------------- -void StartCountUS(void) { - AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); - AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; - - // fast clock - // tick=1.5mks - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable - AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32 - AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR | - AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET; - AT91C_BASE_TC0->TC_RA = 1; - AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000 - - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable - AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // from timer 0 - - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - - // Assert a sync signal. This sets all timers to 0 on next active clock edge - AT91C_BASE_TCB->TCB_BCR = 1; - - while (AT91C_BASE_TC1->TC_CV > 0); -} - -uint32_t RAMFUNC GetCountUS(void) { - //return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10); - // By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548 - return ((uint32_t)AT91C_BASE_TC1->TC_CV) * 0x8000 + (((uint32_t)AT91C_BASE_TC0->TC_CV) * 2) / 3; -} - // ------------------------------------------------------------------------- // Timer for iso14443 commands. Uses ssp_clk from FPGA // ------------------------------------------------------------------------- @@ -246,6 +216,47 @@ uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start) { return (UINT32_MAX - start) + stop; } +void WaitMS(uint32_t ms) { + WaitTicks((ms & 0x1FFFFF) * 1500); +} + +#endif // #ifndef AS_BOOTROM + +// ------------------------------------------------------------------------- +// microseconds timer +// ------------------------------------------------------------------------- +void StartCountUS(void) { + AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); + AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; + + // fast clock + // tick=1.5mks + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable + AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32 + AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR | + AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET; + AT91C_BASE_TC0->TC_RA = 1; + AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000 + + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable + AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // from timer 0 + + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + + // Assert a sync signal. This sets all timers to 0 on next active clock edge + AT91C_BASE_TCB->TCB_BCR = 1; + + while (AT91C_BASE_TC1->TC_CV > 0); +} + +uint32_t RAMFUNC GetCountUS(void) { + //return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10); + // By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548 + return ((uint32_t)AT91C_BASE_TC1->TC_CV) * 0x8000 + (((uint32_t)AT91C_BASE_TC0->TC_CV) * 2) / 3; +} + + // ------------------------------------------------------------------------- // Timer for bitbanging, or LF stuff when you need a very precis timer // 1us = 1.5ticks @@ -282,7 +293,6 @@ void StartTicks(void) { AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; while (AT91C_BASE_TC0->TC_CV > 0); } - uint32_t GetTicks(void) { uint32_t hi, lo; @@ -307,9 +317,6 @@ void WaitTicks(uint32_t ticks) { void WaitUS(uint32_t us) { WaitTicks((us & 0x3FFFFFFF) * 3 / 2); } -void WaitMS(uint32_t ms) { - WaitTicks((ms & 0x1FFFFF) * 1500); -} // stop clock void StopTicks(void) { diff --git a/armsrc/ticks.h b/common_arm/ticks.h similarity index 89% rename from armsrc/ticks.h rename to common_arm/ticks.h index 7ad4486fa..4a2276268 100644 --- a/armsrc/ticks.h +++ b/common_arm/ticks.h @@ -26,6 +26,19 @@ #define GET_TICKS GetTicks() #endif +void StartTicks(void); +uint32_t GetTicks(void); +void WaitUS(uint32_t us); +void WaitTicks(uint32_t ticks); +void StartCountUS(void); +uint32_t RAMFUNC GetCountUS(void); +void StopTicks(void); + + +#ifndef AS_BOOTROM ////////////////////////////////////////////////////////////// +// Bootrom does not require these functions. +// Wrap in #ifndef to avoid accidental bloat of bootrom + void SpinDelay(int ms); void SpinDelayUs(int us); void SpinDelayUsPrecision(int us); // precision 0.6us , running for 43ms before @@ -34,8 +47,6 @@ void StartTickCount(void); uint32_t RAMFUNC GetTickCount(void); uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks); -void StartCountUS(void); -uint32_t RAMFUNC GetCountUS(void); void ResetUSClock(void); void SpinDelayCountUs(uint32_t us); @@ -44,12 +55,10 @@ void ResetSspClk(void); uint32_t RAMFUNC GetCountSspClk(void); uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start); -void StartTicks(void); -uint32_t GetTicks(void); -void WaitTicks(uint32_t ticks); -void WaitUS(uint32_t us); void WaitMS(uint32_t ms); -void StopTicks(void); +#endif // #ifndef AS_BOOTROM + + #endif diff --git a/common_arm/usb_cdc.c b/common_arm/usb_cdc.c index f805d1797..82fc6d0e1 100644 --- a/common_arm/usb_cdc.c +++ b/common_arm/usb_cdc.c @@ -382,7 +382,6 @@ static const char StrSerialNumber[] = { // offset 18, length 32: 16x unicode chars (8-byte serial as hex characters) // ============================ // total: 50 bytes - #define USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH 50 char StrSerialNumber[] = { 14, // Length is initially identical to non-unique version ... The length updated at boot, if unique serial is available @@ -399,6 +398,7 @@ void usb_update_serial(uint64_t newSerialNumber) { } // run this only once per boot... even if it fails to find serial number configured = true; + // reject serial number if all-zero or all-ones if ((newSerialNumber == 0x0000000000000000) || (newSerialNumber == 0xFFFFFFFFFFFFFFFF)) { return; } @@ -407,10 +407,14 @@ void usb_update_serial(uint64_t newSerialNumber) { // Convert uniqueID's eight bytes to 16 unicode characters in the // descriptor and, finally, update the descriptor's length, which // causes the serial number to become visible. - for (uint8_t i = 0; i < 16; i++) { - uint8_t nibble = (uint8_t)((newSerialNumber >> (60 - (4*i))) & 0xFu); - char c = nibble < 10 ? '0' + nibble : 'A' + (nibble-10); - StrSerialNumber[18+(2*i)] = c; // [ 18, 20, 22, .., 46, 48 ] + for (uint8_t i = 0; i < 8; i++) { + // order of nibbles chosen to match display order from `hw status` + uint8_t nibble1 = (newSerialNumber >> ((8*i) + 4)) & 0xFu; // bitmasks [0xF0, 0xF000, 0xF00000, ... 0xF000000000000000] + uint8_t nibble2 = (newSerialNumber >> ((8*i) + 0)) & 0xFu; // bitmasks [0x0F, 0x0F00, 0x0F0000, ... 0x0F00000000000000] + char c1 = nibble1 < 10 ? '0' + nibble1 : 'A' + (nibble1-10); + char c2 = nibble2 < 10 ? '0' + nibble2 : 'A' + (nibble2-10); + StrSerialNumber[46-(4*i)] = c1; // [ 46, 42, .., 22, 18 ] + StrSerialNumber[48-(4*i)] = c2; // [ 48, 44, .., 24, 20 ] } StrSerialNumber[0] = USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH; } From 6eea476076ff0aad0eb2c2cb2a2058e9e35c92ee Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Fri, 17 Feb 2023 17:19:01 -0800 Subject: [PATCH 615/759] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 668e2c32c..e865190c1 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] + - Enable unique USB serial numbers when built with `FLASH` -- **_UPDATES BOOTROM ALSO_** - Changed the readline package to v8.2 in the CMAKE files for the client (@iceman1001) - Add ICECLASS standalone read/sim mode (@natesales) - Added verbose flag to `hf iclass encode` (@natesales) From 48ca513a964d3d76b22f1207b37132f2e0863827 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Fri, 17 Feb 2023 17:27:07 -0800 Subject: [PATCH 616/759] updates from `make style` --- armsrc/appmain.c | 2 +- bootrom/bootrom.c | 2 +- client/src/cmdhficlass.c | 2 +- common_arm/flashmem.c | 2 +- common_arm/flashmem.h | 46 ---------------------------------------- common_arm/ticks.c | 2 +- common_arm/usb_cdc.c | 14 ++++++------ doc/commands.json | 9 ++++---- 8 files changed, 16 insertions(+), 63 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 90681c324..66d1380b5 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2684,7 +2684,7 @@ void __attribute__((noreturn)) AppMain(void) { if (FlashInit()) { uint64_t flash_uniqueID = 0; if (!Flash_CheckBusy(BUSY_TIMEOUT)) { // OK because firmware was built for devices with flash - Flash_UniqueID((uint8_t*)(&flash_uniqueID)); + Flash_UniqueID((uint8_t *)(&flash_uniqueID)); } FlashStop(); usb_update_serial(flash_uniqueID); diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index c94c23481..9ca0dc430 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -225,7 +225,7 @@ static void flash_mode(void) { #ifdef WITH_FLASH if (FlashInit()) { // checks for existence of flash also ... OK because bootrom was built for devices with flash uint64_t flash_uniqueID = 0; - Flash_UniqueID((uint8_t*)&flash_uniqueID); + Flash_UniqueID((uint8_t *)&flash_uniqueID); FlashStop(); usb_update_serial(flash_uniqueID); } diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 84a6e563d..53bb483ec 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1407,7 +1407,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { case DES: case RFU: case None: - // Nothing to do for None anyway... + // Nothing to do for None anyway... default: continue; } diff --git a/common_arm/flashmem.c b/common_arm/flashmem.c index 0a60d43c0..a81576c5f 100644 --- a/common_arm/flashmem.c +++ b/common_arm/flashmem.c @@ -367,7 +367,7 @@ void Flashmem_print_status(void) { uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0}; Flash_UniqueID(uid); - Dbprintf( " Unique ID............... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"), + Dbprintf(" Unique ID............... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"), uid[7], uid[6], uid[5], uid[4], uid[3], uid[2], uid[1], uid[0] ); diff --git a/common_arm/flashmem.h b/common_arm/flashmem.h index 3578fa933..b2456ac76 100644 --- a/common_arm/flashmem.h +++ b/common_arm/flashmem.h @@ -112,56 +112,10 @@ uint16_t FlashSendLastByte(uint32_t data); #ifndef AS_BOOTROM - // Bootrom does not require these functions. - // Wrap in #ifndef to avoid accidental bloat of bootrom - // Bootrom needs only enough to get uniqueID from flash. - // It calls three functions. Full call trees listed: - // - // FlashInit() - // | - // \____ FlashSetup() - // | \____ leaf - // | - // \____ StartTicks() - // | \____ leaf - // | - // \____ Flash_CheckBusy() [*] - // | \____ WaitUS() - // | | \____ WaitTicks() - // | | \____ leaf - // | | - // | \____ StartCountUS() - // | | \____ leaf - // | | - // | \____ GetCountUS() - // | | \____ leaf - // | | - // | \____ Flash_ReadStat1() - // | \____ FlashSendByte() - // | | \____ leaf - // | | - // | \____ FlashSendLastByte() - // | \____ FlashSendByte() - // | \____ leaf - // | - // \____ StopTicks() - // \____ leaf - // - // Flash_UniqueID() - // \____ FlashCheckBusy() (see FlashInit) - // \____ FlashSendByteByte() (see FlashInit) - // \____ FlashSendByteLastByte() (see FlashInit) - // - // - // FlashStop() [*] - - - void FlashmemSetSpiBaudrate(uint32_t baudrate); bool Flash_WaitIdle(void); void Flash_TransferAdresse(uint32_t address); - void Flash_WriteEnable(void); bool Flash_WipeMemoryPage(uint8_t page); bool Flash_WipeMemory(void); diff --git a/common_arm/ticks.c b/common_arm/ticks.c index 34c480061..342aa3cab 100644 --- a/common_arm/ticks.c +++ b/common_arm/ticks.c @@ -20,7 +20,7 @@ #include "proxmark3_arm.h" #ifndef AS_BOOTROM - #include "dbprint.h" +#include "dbprint.h" #endif diff --git a/common_arm/usb_cdc.c b/common_arm/usb_cdc.c index 82fc6d0e1..8a17c4f89 100644 --- a/common_arm/usb_cdc.c +++ b/common_arm/usb_cdc.c @@ -405,16 +405,16 @@ void usb_update_serial(uint64_t newSerialNumber) { // Descriptor is, effectively, initially identical to non-unique serial // number because it reports the shorter length in the first byte. // Convert uniqueID's eight bytes to 16 unicode characters in the - // descriptor and, finally, update the descriptor's length, which + // descriptor and, finally, update the descriptor's length, which // causes the serial number to become visible. for (uint8_t i = 0; i < 8; i++) { // order of nibbles chosen to match display order from `hw status` - uint8_t nibble1 = (newSerialNumber >> ((8*i) + 4)) & 0xFu; // bitmasks [0xF0, 0xF000, 0xF00000, ... 0xF000000000000000] - uint8_t nibble2 = (newSerialNumber >> ((8*i) + 0)) & 0xFu; // bitmasks [0x0F, 0x0F00, 0x0F0000, ... 0x0F00000000000000] - char c1 = nibble1 < 10 ? '0' + nibble1 : 'A' + (nibble1-10); - char c2 = nibble2 < 10 ? '0' + nibble2 : 'A' + (nibble2-10); - StrSerialNumber[46-(4*i)] = c1; // [ 46, 42, .., 22, 18 ] - StrSerialNumber[48-(4*i)] = c2; // [ 48, 44, .., 24, 20 ] + uint8_t nibble1 = (newSerialNumber >> ((8 * i) + 4)) & 0xFu; // bitmasks [0xF0, 0xF000, 0xF00000, ... 0xF000000000000000] + uint8_t nibble2 = (newSerialNumber >> ((8 * i) + 0)) & 0xFu; // bitmasks [0x0F, 0x0F00, 0x0F0000, ... 0x0F00000000000000] + char c1 = nibble1 < 10 ? '0' + nibble1 : 'A' + (nibble1 - 10); + char c2 = nibble2 < 10 ? '0' + nibble2 : 'A' + (nibble2 - 10); + StrSerialNumber[46 - (4 * i)] = c1; // [ 46, 42, .., 22, 18 ] + StrSerialNumber[48 - (4 * i)] = c2; // [ 48, 44, .., 24, 20 ] } StrSerialNumber[0] = USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH; } diff --git a/doc/commands.json b/doc/commands.json index cb68d6069..b8e7be6be 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -3099,10 +3099,9 @@ "--fc facility code", "--cn card number", "-w, --wiegand see `wiegand list` for available formats", - "--shallow use shallow (ASK) reader modulation instead of OOK", - "-v verbose (print encoded blocks)" + "--shallow use shallow (ASK) reader modulation instead of OOK" ], - "usage": "hf iclass encode [-hv] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ] [--shallow]" + "usage": "hf iclass encode [-h] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ] [--shallow]" }, "hf iclass encrypt": { "command": "hf iclass encrypt", @@ -11507,7 +11506,7 @@ }, "script help": { "command": "script help", - "description": "This is a feature to run Lua/Cmd scripts. You can place scripts within the luascripts/cmdscripts folders. --------------------------------------------------------------------------------------- script list available offline: yes", + "description": "This is a feature to run Lua/Cmd/Python scripts. You can place scripts within the luascripts/cmdscripts/pyscripts folders. --------------------------------------------------------------------------------------- script list available offline: yes", "notes": [], "offline": true, "options": [], @@ -11904,6 +11903,6 @@ "metadata": { "commands_extracted": 749, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-02-11T10:42:29" + "extracted_on": "2023-02-18T01:26:44" } } \ No newline at end of file From cd554d67ab28aa79ccb439b6f7fd7a41c1677690 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 18 Feb 2023 15:01:39 +0100 Subject: [PATCH 617/759] if more than one device is connected the tr command does not split the line resulting in `pm3 --list` to fail. --- pm3 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pm3 b/pm3 index e418a3103..516bdbbfb 100755 --- a/pm3 +++ b/pm3 @@ -182,7 +182,8 @@ function get_pm3_list_WSL { PM3LIST=() # Normal SERIAL PORTS (COM) - for DEV in $($PSHEXE -command "Get-CimInstance -ClassName Win32_serialport | Where-Object {\$_.PNPDeviceID -like '*VID_9AC4&PID_4B8F*' -or \$_.PNPDeviceID -like '*VID_2D2D&PID_504D*'} | Select -expandproperty DeviceID" 2>/dev/null | tr -dc '[:print:]'); do + for DEV in $($PSHEXE -command "Get-CimInstance -ClassName Win32_serialport | Where-Object {\$_.PNPDeviceID -like '*VID_9AC4&PID_4B8F*' -or \$_.PNPDeviceID -like '*VID_2D2D&PID_504D*'} | Select -expandproperty DeviceID" 2>/dev/null); do + DEV=$(echo $DEV | tr -dc '[:print:]') _comport=$DEV DEV=$(echo $DEV | sed -nr 's#^COM([0-9]+)\b#/dev/ttyS\1#p') # ttyS counterpart takes some more time to appear From 08ff2698030f5194dfd4b976da1e1461e05fa26c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 18 Feb 2023 15:13:15 +0100 Subject: [PATCH 618/759] text --- pm3 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pm3 b/pm3 index 516bdbbfb..f92ce9bd7 100755 --- a/pm3 +++ b/pm3 @@ -255,7 +255,7 @@ Quick helper script for proxmark3 client when working with a Proxmark3 device Description: The usage is the same as for the proxmark3 client, with the following differences: * the correct port name will be automatically guessed; - * the script will wait for a Proxmark to be connected (same as option -w of the client). + * the script will wait for a Proxmark3 to be connected (same as option -w of the client). You can also specify a first option -n N to access the Nth Proxmark3 connected. To see a list of available ports, use --list. @@ -302,7 +302,7 @@ elif [ "$SCRIPT" = "pm3-flash" ]; then } HELP() { cat << EOF -Quick helper script for flashing a Proxmark device via USB +Quick helper script for flashing a Proxmark3 device via USB Description: The usage is similar to the old proxmark3-flasher binary, except that the correct port name will be automatically guessed. @@ -340,7 +340,7 @@ elif [ "$SCRIPT" = "pm3-flash-all" ]; then } HELP() { cat << EOF -Quick helper script for flashing a Proxmark device via USB +Quick helper script for flashing a Proxmark3 device via USB Description: The correct port name will be automatically guessed and the stock bootloader and firmware image will be flashed. @@ -370,7 +370,7 @@ elif [ "$SCRIPT" = "pm3-flash-fullimage" ]; then } HELP() { cat << EOF -Quick helper script for flashing a Proxmark device via USB +Quick helper script for flashing a Proxmark3 device via USB Description: The correct port name will be automatically guessed and the stock firmware image will be flashed. @@ -400,7 +400,7 @@ elif [ "$SCRIPT" = "pm3-flash-bootrom" ]; then } HELP() { cat << EOF -Quick helper script for flashing a Proxmark device via USB +Quick helper script for flashing a Proxmark3 device via USB Description: The correct port name will be automatically guessed and the stock bootloader will be flashed. @@ -459,7 +459,7 @@ if [ "$1" == "--list" ]; then SHOWLIST=true fi -# Number of the proxmark3 we're interested in +# Number of the Proxmark3 we're interested in N=1 if [ "$1" == "-n" ]; then shift @@ -518,7 +518,7 @@ if $SHOWLIST; then exit 0 fi -# Wait till we get at least N proxmark3 devices +# Wait till we get at least N Proxmark3 devices $GETPM3LIST "$N" if [ ${#PM3LIST} -lt "$N" ]; then echo >&2 "[=] Waiting for Proxmark3 to appear..." From b520f1ff5d67a1a792a97314f5d38ed8b8707141 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sat, 18 Feb 2023 11:17:06 -0800 Subject: [PATCH 619/759] check daughterboard connection for SIM issues Signed-off-by: Henry Gabryjelski --- doc/md/Installation_Instructions/Troubleshooting.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index 710b2de26..59735da34 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -135,6 +135,8 @@ See [details here](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md) (RDV4 only) Make sure you've the latest SIM firmware according to the [configuration documentation](/doc/md/Use_of_Proxmark/2_Configuration-and-Verification.md#verify-sim-module-firmware-version). +Check that the SIM daughterboard is properly seated onto the mainboard. Pressure on the edges of the daughterboard could cause the connector to partially disconnect (especially good to check if problems began after installation of the bluetooth module, for example). + ## Troubles with t5577 commands or MFC/iClass/T55x7 dictionaries ^[Top](#top) From 229454963b1bd46d97ba5c927800fd0657782577 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sat, 18 Feb 2023 12:16:50 -0800 Subject: [PATCH 620/759] standardize flash uniqueID to big-endian --- common_arm/flashmem.c | 54 +++++++++++++++++++++---------------------- common_arm/flashmem.h | 7 +++++- common_arm/usb_cdc.c | 4 ++-- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/common_arm/flashmem.c b/common_arm/flashmem.c index a81576c5f..eae8f3bef 100644 --- a/common_arm/flashmem.c +++ b/common_arm/flashmem.c @@ -49,9 +49,9 @@ void FlashmemSetSpiBaudrate(uint32_t baudrate) { } // read ID out -uint8_t Flash_ReadID(void) { +bool Flash_ReadID_90(flash_device_type_90_t* result) { - if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0; + if (Flash_CheckBusy(BUSY_TIMEOUT)) return false; // Manufacture ID / device ID FlashSendByte(ID); @@ -59,15 +59,10 @@ uint8_t Flash_ReadID(void) { FlashSendByte(0x00); FlashSendByte(0x00); - uint8_t man_id = FlashSendByte(0xFF); - uint8_t dev_id = FlashSendLastByte(0xFF); + result->manufacturer_id = FlashSendByte(0xFF); + result->device_id = FlashSendLastByte(0xFF); - if (g_dbglevel > 3) Dbprintf("Flash ReadID | Man ID %02x | Device ID %02x", man_id, dev_id); - - if ((man_id == WINBOND_MANID) && (dev_id == WINBOND_DEVID)) - return dev_id; - - return 0; + return true; } uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) { @@ -349,29 +344,32 @@ void Flashmem_print_status(void) { } DbpString(" Init.................... " _GREEN_("OK")); - uint8_t dev_id = Flash_ReadID(); - switch (dev_id) { - case 0x11 : - DbpString(" Memory size............. " _YELLOW_("2 mbits / 256 kb")); - break; - case 0x10 : - DbpString(" Memory size..... ....... " _YELLOW_("1 mbits / 128 kb")); - break; - case 0x05 : - DbpString(" Memory size............. " _YELLOW_("512 kbits / 64 kb")); - break; - default : - DbpString(" Device ID............... " _YELLOW_(" --> Unknown <--")); - break; + // NOTE: It would likely be more useful to use JDEC ID command 9F, + // as it provides a third byte indicative of capacity. + flash_device_type_90_t device_type = {0}; + if (!Flash_ReadID_90(&device_type)) { + DbpString(" Device ID............... " _RED_(" --> Not Found <--")); + } else { + if ((device_type.manufacturer_id == WINBOND_MANID) && (device_type.device_id == WINBOND_DEVID)) { + DbpString(" Memory size............. " _GREEN_("2 mbits / 256 kb")); + } else { + Dbprintf(" Device ID............... " _YELLOW_("%02X / %02X (unknown)"), + device_type.manufacturer_id, device_type.device_id ); + } } uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0}; Flash_UniqueID(uid); - Dbprintf(" Unique ID............... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"), - uid[7], uid[6], uid[5], uid[4], - uid[3], uid[2], uid[1], uid[0] + Dbprintf(" Unique ID (be).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X" ), + uid[0], uid[1], uid[2], uid[3], + uid[4], uid[5], uid[6], uid[7] ); - + if (g_dbglevel > 3) { + Dbprintf(" Unique ID (le).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X" ), + uid[7], uid[6], uid[5], uid[4], + uid[3], uid[2], uid[1], uid[0] + ); + } FlashStop(); } diff --git a/common_arm/flashmem.h b/common_arm/flashmem.h index b2456ac76..72cc3e8b7 100644 --- a/common_arm/flashmem.h +++ b/common_arm/flashmem.h @@ -123,7 +123,12 @@ bool Flash_Erase4k(uint8_t block, uint8_t sector); //bool Flash_Erase32k(uint32_t address); bool Flash_Erase64k(uint8_t block); -uint8_t Flash_ReadID(void); +typedef struct { + uint8_t manufacturer_id; + uint8_t device_id; +} flash_device_type_90_t; // to differentiate from JDEC ID via cmd 9F +bool Flash_ReadID_90(flash_device_type_90_t* result); + uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len); uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len); uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len); diff --git a/common_arm/usb_cdc.c b/common_arm/usb_cdc.c index 8a17c4f89..6e758c8aa 100644 --- a/common_arm/usb_cdc.c +++ b/common_arm/usb_cdc.c @@ -413,8 +413,8 @@ void usb_update_serial(uint64_t newSerialNumber) { uint8_t nibble2 = (newSerialNumber >> ((8 * i) + 0)) & 0xFu; // bitmasks [0x0F, 0x0F00, 0x0F0000, ... 0x0F00000000000000] char c1 = nibble1 < 10 ? '0' + nibble1 : 'A' + (nibble1 - 10); char c2 = nibble2 < 10 ? '0' + nibble2 : 'A' + (nibble2 - 10); - StrSerialNumber[46 - (4 * i)] = c1; // [ 46, 42, .., 22, 18 ] - StrSerialNumber[48 - (4 * i)] = c2; // [ 48, 44, .., 24, 20 ] + StrSerialNumber[18 + (4*i) + 0] = c1; // [ 18, 22, .., 42, 46 ] + StrSerialNumber[18 + (4*i) + 2] = c2; // [ 20, 24, .., 44, 48 ] } StrSerialNumber[0] = USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH; } From c531bd0f65576d560738d808ef08acf9402d6483 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sat, 18 Feb 2023 12:20:43 -0800 Subject: [PATCH 621/759] make style updates --- common_arm/flashmem.c | 16 ++++++++-------- common_arm/flashmem.h | 2 +- common_arm/usb_cdc.c | 4 ++-- doc/commands.json | 7 ++++--- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/common_arm/flashmem.c b/common_arm/flashmem.c index eae8f3bef..5a115da1a 100644 --- a/common_arm/flashmem.c +++ b/common_arm/flashmem.c @@ -49,7 +49,7 @@ void FlashmemSetSpiBaudrate(uint32_t baudrate) { } // read ID out -bool Flash_ReadID_90(flash_device_type_90_t* result) { +bool Flash_ReadID_90(flash_device_type_90_t *result) { if (Flash_CheckBusy(BUSY_TIMEOUT)) return false; @@ -354,20 +354,20 @@ void Flashmem_print_status(void) { DbpString(" Memory size............. " _GREEN_("2 mbits / 256 kb")); } else { Dbprintf(" Device ID............... " _YELLOW_("%02X / %02X (unknown)"), - device_type.manufacturer_id, device_type.device_id ); + device_type.manufacturer_id, device_type.device_id); } } uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0}; Flash_UniqueID(uid); - Dbprintf(" Unique ID (be).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X" ), - uid[0], uid[1], uid[2], uid[3], - uid[4], uid[5], uid[6], uid[7] + Dbprintf(" Unique ID (be).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"), + uid[0], uid[1], uid[2], uid[3], + uid[4], uid[5], uid[6], uid[7] ); if (g_dbglevel > 3) { - Dbprintf(" Unique ID (le).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X" ), - uid[7], uid[6], uid[5], uid[4], - uid[3], uid[2], uid[1], uid[0] + Dbprintf(" Unique ID (le).......... " _YELLOW_("0x%02X%02X%02X%02X%02X%02X%02X%02X"), + uid[7], uid[6], uid[5], uid[4], + uid[3], uid[2], uid[1], uid[0] ); } FlashStop(); diff --git a/common_arm/flashmem.h b/common_arm/flashmem.h index 72cc3e8b7..f60b73c58 100644 --- a/common_arm/flashmem.h +++ b/common_arm/flashmem.h @@ -127,7 +127,7 @@ typedef struct { uint8_t manufacturer_id; uint8_t device_id; } flash_device_type_90_t; // to differentiate from JDEC ID via cmd 9F -bool Flash_ReadID_90(flash_device_type_90_t* result); +bool Flash_ReadID_90(flash_device_type_90_t *result); uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len); uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len); diff --git a/common_arm/usb_cdc.c b/common_arm/usb_cdc.c index 6e758c8aa..cb2d0c64a 100644 --- a/common_arm/usb_cdc.c +++ b/common_arm/usb_cdc.c @@ -413,8 +413,8 @@ void usb_update_serial(uint64_t newSerialNumber) { uint8_t nibble2 = (newSerialNumber >> ((8 * i) + 0)) & 0xFu; // bitmasks [0x0F, 0x0F00, 0x0F0000, ... 0x0F00000000000000] char c1 = nibble1 < 10 ? '0' + nibble1 : 'A' + (nibble1 - 10); char c2 = nibble2 < 10 ? '0' + nibble2 : 'A' + (nibble2 - 10); - StrSerialNumber[18 + (4*i) + 0] = c1; // [ 18, 22, .., 42, 46 ] - StrSerialNumber[18 + (4*i) + 2] = c2; // [ 20, 24, .., 44, 48 ] + StrSerialNumber[18 + (4 * i) + 0] = c1; // [ 18, 22, .., 42, 46 ] + StrSerialNumber[18 + (4 * i) + 2] = c2; // [ 20, 24, .., 44, 48 ] } StrSerialNumber[0] = USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH; } diff --git a/doc/commands.json b/doc/commands.json index b8e7be6be..3b1ac6aca 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -3099,9 +3099,10 @@ "--fc facility code", "--cn card number", "-w, --wiegand see `wiegand list` for available formats", - "--shallow use shallow (ASK) reader modulation instead of OOK" + "--shallow use shallow (ASK) reader modulation instead of OOK", + "-v verbose (print encoded blocks)" ], - "usage": "hf iclass encode [-h] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ] [--shallow]" + "usage": "hf iclass encode [-hv] [--bin ] --ki [--credit] [--elite] [--raw] [--enckey ] [--fc ] [--cn ] [-w ] [--shallow]" }, "hf iclass encrypt": { "command": "hf iclass encrypt", @@ -11903,6 +11904,6 @@ "metadata": { "commands_extracted": 749, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-02-18T01:26:44" + "extracted_on": "2023-02-18T20:20:19" } } \ No newline at end of file From 89ce0acf31b5765d48b4f9ee6712cb66fc115d02 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sat, 18 Feb 2023 12:34:16 -0800 Subject: [PATCH 622/759] improve const correctness --- armsrc/cmd.c | 2 +- armsrc/cmd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/armsrc/cmd.c b/armsrc/cmd.c index 8857fc66f..c179ed2a9 100644 --- a/armsrc/cmd.c +++ b/armsrc/cmd.c @@ -131,7 +131,7 @@ static int reply_ng_internal(uint16_t cmd, int16_t status, const uint8_t *data, return PM3_SUCCESS; } -int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len) { +int reply_ng(uint16_t cmd, int16_t status, const uint8_t *data, size_t len) { return reply_ng_internal(cmd, status, data, len, true); } diff --git a/armsrc/cmd.h b/armsrc/cmd.h index 4a42d9898..b578db8e8 100644 --- a/armsrc/cmd.h +++ b/armsrc/cmd.h @@ -28,7 +28,7 @@ extern bool g_reply_via_fpc; extern bool g_reply_via_usb; int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); -int reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len); +int reply_ng(uint16_t cmd, int16_t status, const uint8_t *data, size_t len); int reply_mix(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); int receive_ng(PacketCommandNG *rx); From 28af1a870d36ab83e1d8904610bca46024f3a507 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sat, 18 Feb 2023 12:50:05 -0800 Subject: [PATCH 623/759] Prevent buffer overflow in `AppendGraph()` --- client/src/graph.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/client/src/graph.c b/client/src/graph.c index 5914c8585..851e49d5a 100644 --- a/client/src/graph.c +++ b/client/src/graph.c @@ -29,21 +29,39 @@ int g_GraphBuffer[MAX_GRAPH_TRACE_LEN]; size_t g_GraphTraceLen; /* write a manchester bit to the graph -TODO, verfy that this doesn't overflow buffer (iceman) */ void AppendGraph(bool redraw, uint16_t clock, int bit) { - uint8_t half = clock / 2; + uint16_t half = clock / 2; + uint16_t end = clock; uint16_t i; + + // overflow/underflow safe checks ... Assumptions: + // _Assert(g_GraphTraceLen >= 0); + // _Assert(g_GraphTraceLen <= MAX_GRAPH_TRACE_LEN); + // If this occurs, allow partial rendering, up to the last sample... + if ((MAX_GRAPH_TRACE_LEN - g_GraphTraceLen) < half) { + PrintAndLogEx(DEBUG, "WARNING: AppendGraph() - Request exceeds max graph length"); + end = MAX_GRAPH_TRACE_LEN - g_GraphTraceLen; + half = end; + } + if ((MAX_GRAPH_TRACE_LEN - g_GraphTraceLen) < end) { + PrintAndLogEx(DEBUG, "WARNING: AppendGraph() - Request exceeds max graph length"); + end = MAX_GRAPH_TRACE_LEN - g_GraphTraceLen; + } + //set first half the clock bit (all 1's or 0's for a 0 or 1 bit) - for (i = 0; i < half; ++i) + for (i = 0; i < half; ++i) { g_GraphBuffer[g_GraphTraceLen++] = bit; + } //set second half of the clock bit (all 0's or 1's for a 0 or 1 bit) - for (; i < clock; ++i) + for (; i < end; ++i) { g_GraphBuffer[g_GraphTraceLen++] = bit ^ 1; + } - if (redraw) + if (redraw) { RepaintGraphWindow(); + } } // clear out our graph window From 475bbe183d3f7c694813ceed320cd3ebda4bdaf5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 18 Feb 2023 22:02:20 +0100 Subject: [PATCH 624/759] some generic devices has other sizes of flash --- common_arm/flashmem.c | 24 +++++++++++++++++------- common_arm/flashmem.h | 7 +++++-- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/common_arm/flashmem.c b/common_arm/flashmem.c index 5a115da1a..435f51a57 100644 --- a/common_arm/flashmem.c +++ b/common_arm/flashmem.c @@ -350,11 +350,25 @@ void Flashmem_print_status(void) { if (!Flash_ReadID_90(&device_type)) { DbpString(" Device ID............... " _RED_(" --> Not Found <--")); } else { - if ((device_type.manufacturer_id == WINBOND_MANID) && (device_type.device_id == WINBOND_DEVID)) { - DbpString(" Memory size............. " _GREEN_("2 mbits / 256 kb")); + if (device_type.manufacturer_id == WINBOND_MANID) { + switch (device_type.device_id) { + case WINBOND_2MB_DEVID: + DbpString(" Memory size............. " _YELLOW_("2 mbits / 256 kb")); + break; + case WINBOND_1MB_DEVID: + DbpString(" Memory size..... ....... " _YELLOW_("1 mbits / 128 kb")); + break; + case WINBOND_512KB_DEVID: + DbpString(" Memory size............. " _YELLOW_("512 kbits / 64 kb")); + break; + default: + break; + } } else { Dbprintf(" Device ID............... " _YELLOW_("%02X / %02X (unknown)"), - device_type.manufacturer_id, device_type.device_id); + device_type.manufacturer_id, + device_type.device_id + ); } } @@ -578,10 +592,6 @@ bool Flash_CheckBusy(uint32_t timeout) { StartCountUS(); uint32_t _time = GetCountUS(); -#ifndef AS_BOOTROM - if (g_dbglevel > 3) Dbprintf("Checkbusy in..."); -#endif // AS_BOOTROM - do { if (!(Flash_ReadStat1() & BUSY)) { return false; diff --git a/common_arm/flashmem.h b/common_arm/flashmem.h index f60b73c58..f23a2786d 100644 --- a/common_arm/flashmem.h +++ b/common_arm/flashmem.h @@ -54,8 +54,11 @@ // Flash busy timeout: 20ms is the strict minimum when writing 256kb #define BUSY_TIMEOUT 200000L -#define WINBOND_MANID 0xEF -#define WINBOND_DEVID 0x11 +#define WINBOND_MANID 0xEF +#define WINBOND_2MB_DEVID 0x11 +#define WINBOND_1MB_DEVID 0x10 +#define WINBOND_512KB_DEVID 0x05 + #define PAGESIZE 0x100 #define WINBOND_WRITE_DELAY 0x02 From 029d5aa3584c49fd767a5df70e6d88a5c9a710ae Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 18 Feb 2023 22:51:44 +0100 Subject: [PATCH 625/759] fix cid #404827 - resource leak --- client/src/cmdlfem4x70.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index e90c688c1..d7bc3811a 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -252,6 +252,7 @@ int CmdEM4x70Brute(const char *Cmd) { int addr = arg_get_int_def(ctx, 2, 0); if (addr < 7 || addr > 9) { PrintAndLogEx(FAILED, "block has to be within range [7, 9] got: %d", addr); + CLIParserFree(ctx); return PM3_EINVARG; } etd.address = (uint8_t) addr; @@ -265,8 +266,8 @@ int CmdEM4x70Brute(const char *Cmd) { uint32_t start_key = 0; int res = arg_get_u32_hexstr_def_nlen(ctx, 5, 0, &start_key, 2, true); if (res == 2) { - CLIParserFree(ctx); PrintAndLogEx(WARNING, "start key parameter must be in range [0, FFFF]"); + CLIParserFree(ctx); return PM3_EINVARG; } etd.start_key = start_key; From 3399cbd4f01d392ab1d5ae86ccd1779c1b9e27e0 Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Sat, 18 Feb 2023 23:48:32 -0600 Subject: [PATCH 626/759] support for NTAG213TT tamper feature --- client/src/cmdhfmfu.c | 298 +++++++++++++++++++++++++++++++- client/src/cmdhfmfu.h | 1 + client/src/pm3line_vocabulory.h | 1 + include/protocols.h | 3 + 4 files changed, 299 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index a59859394..f28c76369 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -392,6 +392,12 @@ static int ul_auth_select(iso14a_card_select_t *card, TagTypeUL_t tagtype, bool return PM3_SUCCESS; } +static int ntagtt_getTamperStatus(uint8_t *response, uint16_t responseLength) { + uint8_t cmd[] = {NTAGTT_CMD_READ_TT, 0x00}; + int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength); + return len; +} + static int ulev1_getVersion(uint8_t *response, uint16_t responseLength) { uint8_t cmd[] = {MIFARE_ULEV1_VERSION}; int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength); @@ -748,8 +754,80 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st PrintAndLogEx(INFO, " cfg0 [%u/0x%02X]: %s", startPage, startPage, sprint_hex(data, 4)); - if ((tagtype & (NTAG_213_F | NTAG_213_TT | NTAG_216_F))) { - uint8_t mirror_conf = (data[0] & 0xC0); + //NTAG213TT has different ASCII mirroring options and config bytes interpretation from other ulev1 class tags + if (tagtype & NTAG_213_TT) { + uint8_t mirror_conf = ((data[0] & 0xE0) >> 5); + uint8_t mirror_byte = ((data[0] & 0x18) >> 3); + uint8_t tt_msg_lock = (data[1] & 0x04); + uint8_t mirror_page = data[2]; + + switch (mirror_conf) { + case 0: + PrintAndLogEx(INFO, " - no ASCII mirror"); + break; + case 1: + PrintAndLogEx(INFO, " - UID ASCII mirror"); + break; + case 2: + PrintAndLogEx(INFO, " - NFC counter ASCII mirror"); + break; + case 3: + PrintAndLogEx(INFO, " - UID and NFC counter ASCII mirror"); + break; + case 4: + PrintAndLogEx(INFO, " - tag tamper ASCII mirror"); + break; + case 5: + PrintAndLogEx(INFO, " - UID and tag tamper ASCII mirror"); + break; + case 6: + PrintAndLogEx(INFO, " - NFC counter and tag tamper ASCII mirror"); + break; + case 7: + PrintAndLogEx(INFO, " - UID, NFC counter, and tag tamper ASCII mirror"); + break; + default: + break; + } + + if(mirror_conf) { + uint8_t mirror_user_mem_start_byte = (4*(mirror_page-4)) + mirror_byte; + uint8_t bytes_required_for_mirror_data = 0; + + switch (mirror_conf) { + case 1: + bytes_required_for_mirror_data = 14; + break; + case 2: + bytes_required_for_mirror_data = 6; + break; + case 3: + bytes_required_for_mirror_data = 8; + break; + case 4: + bytes_required_for_mirror_data = 21; + break; + case 5: + bytes_required_for_mirror_data = 23; + break; + case 6: + bytes_required_for_mirror_data = 15; + break; + case 7: + bytes_required_for_mirror_data = 30; + break; + default: + break; + } + PrintAndLogEx(INFO, " mirror start page %02X | byte pos %02X - %s", mirror_page, mirror_byte, (mirror_page >= 0x4 && ((mirror_user_mem_start_byte + bytes_required_for_mirror_data) <= 144)) ? _GREEN_("OK") : _YELLOW_("Invalid value")); + } + + if(tt_msg_lock) { + PrintAndLogEx(INFO, " - tag tamper message is permanently locked"); + } + + } else if (tagtype & (NTAG_213_F | NTAG_216_F)) { + uint8_t mirror_conf = ((data[0] & 0xC0) >> 6); uint8_t mirror_byte = (data[0] & 0x30); bool sleep_en = (data[0] & 0x08); strg_mod_en = (data[0] & 0x04); @@ -791,7 +869,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st break; } // valid mirror start page and byte position within start page. - if ((tagtype & NTAG_213_F) || (tagtype & NTAG_213_TT)) { + if (tagtype & NTAG_213_F) { switch (mirror_conf) { case 1: { PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x24) ? "OK" : "Invalid value"); break;} @@ -822,6 +900,35 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st else PrintAndLogEx(INFO, " - pages don't need authentication"); + uint8_t tt_enabled = 0; + uint8_t tt_message[4] = {0x00}; + uint8_t tt_msg_resp_len; + uint8_t tt_status_resp[5] = {0x00}; + + if(tagtype & NTAG_213_TT) { + tt_enabled = (data[1] & 0x02); + tt_msg_resp_len = ul_read(45, tt_message, 4); + + PrintAndLogEx(INFO, " - tamper detection is %s" + , (tt_enabled) ? _GREEN_("ENABLED") : "disabled" + ); + + switch (data[1] & 0x06) { + case 0x00: + PrintAndLogEx(INFO, " - tamper message is unlocked and read/write enabled"); + break; + case 0x02: + PrintAndLogEx(INFO, " - tamper message is reversibly read/write protected in memory while the tamper feature is enabled"); + break; + case 0x04: + case 0x06: + PrintAndLogEx(INFO, " - tamper message is permanently read/write protected in memory"); + break; + default: + break; + } + } + PrintAndLogEx(INFO, " cfg1 [%u/0x%02X]: %s", startPage + 1, startPage + 1, sprint_hex(data + 4, 4)); if (authlim == 0) PrintAndLogEx(INFO, " - " _GREEN_("Unlimited password attempts")); @@ -837,6 +944,54 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st PrintAndLogEx(INFO, " PWD [%u/0x%02X]: %s- (cannot be read)", startPage + 2, startPage + 2, sprint_hex(data + 8, 4)); PrintAndLogEx(INFO, " PACK [%u/0x%02X]: %s - (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 12, 2)); PrintAndLogEx(INFO, " RFU [%u/0x%02X]: %s- (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 14, 2)); + + if(tagtype & NTAG_213_TT) { + if(data[1] & 0x06) { + PrintAndLogEx(INFO, "TT_MSG [45/0x2D]: %s- (cannot be read)", sprint_hex(tt_message, tt_msg_resp_len)); + PrintAndLogEx(INFO, " - tamper message is masked in memory"); + } else { + PrintAndLogEx(INFO, "TT_MSG [45/0x2D]: %s", sprint_hex(tt_message, tt_msg_resp_len)); + PrintAndLogEx(INFO, " - tamper message is %s", sprint_hex(tt_message, tt_msg_resp_len)); + } + } + + if ((tagtype & NTAG_213_TT) && tt_enabled) { //The tag only returns meaningful information for the fields below if the tamper feature is enabled + + uint8_t tt_status_len = ntagtt_getTamperStatus(tt_status_resp, 5); + + if(tt_status_len != 5) { + PrintAndLogEx(WARNING, "Error requesting tamper status from tag\n"); + return PM3_ESOFT; + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Tamper Status")); + PrintAndLogEx(INFO, " READ_TT_STATUS: %s", sprint_hex(tt_status_resp, 5)); + + PrintAndLogEx(INFO, " Tamper detection result from this power-up:"); + switch(tt_status_resp[4]) { + case 0x43: + PrintAndLogEx(INFO, " - Tamper wire was detcted as closed during this power-up"); + break; + case 0x4F: + PrintAndLogEx(INFO, " - Tamper wire was detected as open during this power-up"); + break; + case 0x49: + PrintAndLogEx(INFO, " - No tamper wire measurement from this power-up is available"); + break; + default: + break; + } + + PrintAndLogEx(INFO, " Tamper detection permanent memory:"); + if((tt_status_resp[0] | tt_status_resp [1] | tt_status_resp[2] | tt_status_resp[3]) == 0x00) + + PrintAndLogEx(INFO, " - Tamper wire has never been detected as open during power-up"); + else { + PrintAndLogEx(INFO, " - Tamper wire has previously been detected as open during power-up"); + PrintAndLogEx(INFO, " - Tamper message: %s", sprint_hex(tt_status_resp, 4)); + } + } return PM3_SUCCESS; } @@ -1757,7 +1912,6 @@ static int CmdHF14AMfUInfo(const char *Cmd) { uint8_t startconfigblock = 0; uint8_t ulev1_conf[16] = {0x00}; - // config blocks always are last 4 pages for (uint8_t i = 0; i < ARRAYLEN(UL_TYPES_ARRAY); i++) { if (tagtype & UL_TYPES_ARRAY[i]) { startconfigblock = UL_MEMORY_ARRAY[i] - 3; @@ -2529,6 +2683,141 @@ static void wait4response(uint8_t b) { } } +// +//Configure tamper feature of NTAG 213TT +// +int CmdHF14MfUTamper(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfu tamper", + "Set the congiguration of the NTAG 213TT tamper feature\n" + "Supports:\n" + "NTAG 213TT\n", + "hf mfu tamper -e -> enable tamper feature\n" + "hf mfu tamper -d -> disable tamper feature\n" + "hf mfu tamper -m 0A0A0A0A -> set the tamper message to 0A0A0A0A\n" + "hf mfu tamper --lockmessage -> permanently lock the tamper message and mask it from memory\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0("e", "enable", "Enable the tamper feature"), + arg_lit0("d", "disable", "Disable the tamper feature"), + arg_str0("m", "message", "", "Set the tamper message (4 bytes)"), + arg_lit0(NULL, "lockmessage", "Permanently lock the tamper message and mask it from memory (does not lock tamper feature itself)"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int tt_cfg_page = 41; + int tt_msg_page = 45; + int msg_len = 0; + uint8_t msg_data[4] = {0x00}; + CLIGetHexWithReturn(ctx, 3, msg_data, &msg_len); + bool use_msg = (msg_len > 0); + + if(use_msg && msg_len != 4) { + PrintAndLogEx(WARNING, "The tamper message must be 4 hex bytes if provided"); + DropField(); + return PM3_ESOFT; + } + + bool lock_msg = arg_get_lit(ctx, 4); + bool enable = arg_get_lit(ctx, 1); + bool disable = arg_get_lit(ctx, 2); + + TagTypeUL_t tagtype = GetHF14AMfU_Type(); + if (tagtype == UL_ERROR) { + PrintAndLogEx(WARNING, "Tag type not detected"); + DropField(); + return PM3_ESOFT; + } + if(tagtype != NTAG_213_TT) { + PrintAndLogEx(WARNING, "Tag type not NTAG 213TT"); + DropField(); + return PM3_ESOFT; + } + + DropField(); + iso14a_card_select_t card; + + if(enable && disable) { + PrintAndLogEx(WARNING, "You can only select one of the options enable/disable tamper feature"); + DropField(); + return PM3_ESOFT; + } + + if(use_msg) + { + if (ul_select(&card) == false) { + DropField(); + return UL_ERROR; + } + PrintAndLogEx(INFO, "Trying to write tamper message\n"); + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, tt_msg_page, 0, 0, msg_data, 4); + + PacketResponseNG resp; + + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + uint8_t isOK = resp.oldarg[0] & 0xff; + if (!isOK) + PrintAndLogEx(WARNING, "Failed to write tamper message"); + else + PrintAndLogEx(SUCCESS, "Tamper message written successfully"); + } else { + PrintAndLogEx(WARNING, "Command execute timeout"); + } + } + + if(enable | disable | lock_msg) { + + if (ul_select(&card) == false) { + PrintAndLogEx(ERR, "Unable to select tag"); + DropField(); + return UL_ERROR; + } + + uint8_t cfg_page[4] = {0x00}; + uint8_t cmd[] = {ISO14443A_CMD_READBLOCK, tt_cfg_page}; + int status = ul_send_cmd_raw(cmd, sizeof(cmd), cfg_page, 4); + DropField(); + + if(status <= 0) { + PrintAndLogEx(WARNING, "Problem reading current config from tag"); + DropField(); + return PM3_ESOFT; + } + + if(enable) { + cfg_page[1] = cfg_page[1] | 0x02; + PrintAndLogEx(INFO, "Enabling tamper feature"); + } + if(disable) { + cfg_page[1] = cfg_page[1] & 0xFD; + PrintAndLogEx(INFO, "Disabling tamper feature"); + } + if(lock_msg) { + cfg_page[1] = cfg_page[1] | 0x04; + PrintAndLogEx(INFO, "Locking tamper message"); + } + + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, tt_cfg_page, 0, 0, cfg_page, 4); + PacketResponseNG resp; + + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + uint8_t isOK = resp.oldarg[0] & 0xff; + if (!isOK) + PrintAndLogEx(WARNING, "Failed to write tamper configuration"); + else + PrintAndLogEx(SUCCESS, "Tamper configuration written successfully"); + } else { + PrintAndLogEx(WARNING, "Command execute timeout"); + } + } + + DropField(); + return PM3_SUCCESS; +} + // // Restore dump file onto tag // @@ -4406,6 +4695,7 @@ static command_t CommandTable[] = { {"restore", CmdHF14AMfURestore, IfPm3Iso14443a, "Restore a dump onto a MFU MAGIC tag"}, {"view", CmdHF14AMfuView, AlwaysAvailable, "Display content from tag dump file"}, {"wrbl", CmdHF14AMfUWrBl, IfPm3Iso14443a, "Write block"}, + {"tamper", CmdHF14MfUTamper, IfPm3Iso14443a, "Cofigure the tamper feature on an NTAG 213TT"}, {"---------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"}, {"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "Load Ultralight dump file into emulator memory"}, {"esave", CmdHF14AMfuESave, IfPm3Iso14443a, "Save Ultralight dump file from emulator memory"}, diff --git a/client/src/cmdhfmfu.h b/client/src/cmdhfmfu.h index 568e3c4a9..1ed652e79 100644 --- a/client/src/cmdhfmfu.h +++ b/client/src/cmdhfmfu.h @@ -50,6 +50,7 @@ int trace_mfuc_try_default_3des_keys(uint8_t **correct_key, int state, uint8_t ( int CmdHFMFUltra(const char *Cmd); int CmdHF14MfuNDEFRead(const char *Cmd); +int CmdHF14MfUTamper(const char *Cmd); uint16_t ul_ev1_packgen_VCNEW(uint8_t *uid, uint32_t pwd); uint32_t ul_ev1_otpgenA(uint8_t *uid); diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index a0e386270..8e775bd3e 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -384,6 +384,7 @@ const static vocabulory_t vocabulory[] = { { 0, "hf mfu rdbl" }, { 0, "hf mfu restore" }, { 1, "hf mfu view" }, + { 0, "hf mfu tamper" }, { 0, "hf mfu wrbl" }, { 0, "hf mfu eload" }, { 0, "hf mfu esave" }, diff --git a/include/protocols.h b/include/protocols.h index 1417fa71a..e4437d90a 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -223,6 +223,9 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define NTAG_I2C_SELECT_SECTOR 0xC2 #define NTAG_I2C_FASTWRITE 0xA6 +//NTAG 213TT (tamper) command +#define NTAGTT_CMD_READ_TT 0xA4 + // mifare 4bit card answers #define CARD_ACK 0x0A // 1010 - ACK #define CARD_NACK_IV 0x00 // 0000 - NACK, invalid argument (invalid page address) From cf6b2d95971de1894c6d116000c0441fdfc8a618 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 19 Feb 2023 08:07:32 +0100 Subject: [PATCH 627/759] fix WSL2 detection route. some linux distro spells with small letters --- pm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pm3 b/pm3 index f92ce9bd7..79ea38768 100755 --- a/pm3 +++ b/pm3 @@ -474,7 +474,7 @@ fi HOSTOS=$(uname | awk '{print toupper($0)}') if [ "$HOSTOS" = "LINUX" ]; then - if uname -a|grep -q Microsoft; then + if uname -a|grep -qi Microsoft; then # First try finding it using the PATH environment variable PSHEXE=$(command -v powershell.exe 2>/dev/null) From e5adfb0b29d9149bb3173441f81346c196480464 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 19 Feb 2023 08:17:05 +0100 Subject: [PATCH 628/759] text --- CHANGELOG.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e865190c1..d2f5c1dc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,15 @@ 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] - - Enable unique USB serial numbers when built with `FLASH` -- **_UPDATES BOOTROM ALSO_** + - Fixed `pm3` script to correctly identify WSL enabled distros (@henrygab) + - Changed device enumeration with "unique USB serial numbers when built with `FLASH` -- **_UPDATES BOOTROM ALSO_**" (@henrygab) - Changed the readline package to v8.2 in the CMAKE files for the client (@iceman1001) + - Fixed `pm3` script for passing arguments (@doegox) + - Fixed python paths to include current directory (@jmichelp) + - Fixed infinite loops in spindelayus (@lnv42) - Add ICECLASS standalone read/sim mode (@natesales) - - Added verbose flag to `hf iclass encode` (@natesales) + - Changed `hf iclass encode` - added verbose flag (@natesales) + - Changed `hf waveshare` - now identify 1.54 nfc epaper correct (@ah01) - Fixed `Makefile` regression that broke `make install` (@henrygab) - Fixed `lf em 4x70 brute` - now works as expected (@adite) - Fixed the lf sampling when bits_per_sample is less than 8 (@wh201906) @@ -14,8 +19,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added documentation for usage of Proxmark3 under WSL2 (@henrygab) - Fixed device permissions via updated `udev` rules (@henrygab) - Added `--back` option to `clear` command to clear the scrollback buffer (@wh201906) - - Mark credentials as decrypted in the dump generated by `hf iclass decrypt` - - Show credentials when using `hf iclass view` on a decrypted dump + - Changed `hf iclass decrypt` - mark credentials as decrypted in the dump (@natesales) + - Changed `hf iclass view` - show credentials on a decrypted dump (@natesales) ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) From fe98b3821fe2df28ae0081df05041cb59e9cd14c Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sat, 18 Feb 2023 23:48:08 -0800 Subject: [PATCH 629/759] Prevent double-enumeration under WSL2 --- pm3 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pm3 b/pm3 index 79ea38768..a3df5717b 100755 --- a/pm3 +++ b/pm3 @@ -68,11 +68,12 @@ function get_pm3_list_Linux { fi fi # WSL2 with usbipd detection - doesn't report same things as WSL1 - if grep -q "proxmark.org" "/sys/class/tty/${DEV#/dev/}/../../../manufacturer" 2>/dev/null; then - PM3LIST+=("$DEV") - if [ ${#PM3LIST[*]} -ge "$N" ]; then - return + if !( echo "${PM3LIST[*]}" | grep -q "${DEV}" ); then + PM3LIST+=("$DEV") + if [ ${#PM3LIST[*]} -ge "$N" ]; then + return + fi fi fi done @@ -474,7 +475,7 @@ fi HOSTOS=$(uname | awk '{print toupper($0)}') if [ "$HOSTOS" = "LINUX" ]; then - if uname -a|grep -qi Microsoft; then + if uname -a|grep -q Microsoft; then # First try finding it using the PATH environment variable PSHEXE=$(command -v powershell.exe 2>/dev/null) From ce85fe0099ef2e1b72e236de8761a44b3d813b60 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sun, 19 Feb 2023 01:44:15 -0800 Subject: [PATCH 630/759] allow case-insensitive match of WSL strings --- pm3 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pm3 b/pm3 index a3df5717b..7c1d0e289 100755 --- a/pm3 +++ b/pm3 @@ -69,7 +69,7 @@ function get_pm3_list_Linux { fi # WSL2 with usbipd detection - doesn't report same things as WSL1 if grep -q "proxmark.org" "/sys/class/tty/${DEV#/dev/}/../../../manufacturer" 2>/dev/null; then - if !( echo "${PM3LIST[*]}" | grep -q "${DEV}" ); then + if echo "${PM3LIST[*]}" | grep -qv "${DEV}"; then PM3LIST+=("$DEV") if [ ${#PM3LIST[*]} -ge "$N" ]; then return @@ -475,7 +475,8 @@ fi HOSTOS=$(uname | awk '{print toupper($0)}') if [ "$HOSTOS" = "LINUX" ]; then - if uname -a|grep -q Microsoft; then + # Detect when running under WSL1 (but exclude WSL2) + if uname -a | grep -qi Microsoft && uname -a | grep -qvi WSL2; then # First try finding it using the PATH environment variable PSHEXE=$(command -v powershell.exe 2>/dev/null) From 147475ab4056c249b800a782c3bc9f0ed47cb8f8 Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Mon, 20 Feb 2023 00:34:06 -0600 Subject: [PATCH 631/759] CHANGELOG.md and text changes --- CHANGELOG.md | 1 + client/src/cmdhfmfu.c | 136 +++++++++++++++++++++--------------------- include/protocols.h | 2 +- 3 files changed, 70 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e865190c1..7c5527897 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `--back` option to `clear` command to clear the scrollback buffer (@wh201906) - Mark credentials as decrypted in the dump generated by `hf iclass decrypt` - Show credentials when using `hf iclass view` on a decrypted dump + - Show NTAG213TT tamper info in `hf mfu info` and add commands for configuring it's tamper feature (@mjaksn) ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index f28c76369..31823adeb 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -758,7 +758,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st if (tagtype & NTAG_213_TT) { uint8_t mirror_conf = ((data[0] & 0xE0) >> 5); uint8_t mirror_byte = ((data[0] & 0x18) >> 3); - uint8_t tt_msg_lock = (data[1] & 0x04); + uint8_t tt_msg_lock = (data[1] & 0x04); uint8_t mirror_page = data[2]; switch (mirror_conf) { @@ -790,41 +790,41 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st break; } - if(mirror_conf) { - uint8_t mirror_user_mem_start_byte = (4*(mirror_page-4)) + mirror_byte; + if (mirror_conf) { + uint8_t mirror_user_mem_start_byte = (4 * (mirror_page - 4)) + mirror_byte; uint8_t bytes_required_for_mirror_data = 0; switch (mirror_conf) { - case 1: - bytes_required_for_mirror_data = 14; - break; - case 2: - bytes_required_for_mirror_data = 6; - break; - case 3: - bytes_required_for_mirror_data = 8; - break; - case 4: - bytes_required_for_mirror_data = 21; - break; - case 5: - bytes_required_for_mirror_data = 23; - break; - case 6: - bytes_required_for_mirror_data = 15; - break; - case 7: - bytes_required_for_mirror_data = 30; - break; - default: - break; + case 1: + bytes_required_for_mirror_data = 14; + break; + case 2: + bytes_required_for_mirror_data = 6; + break; + case 3: + bytes_required_for_mirror_data = 8; + break; + case 4: + bytes_required_for_mirror_data = 21; + break; + case 5: + bytes_required_for_mirror_data = 23; + break; + case 6: + bytes_required_for_mirror_data = 15; + break; + case 7: + bytes_required_for_mirror_data = 30; + break; + default: + break; } PrintAndLogEx(INFO, " mirror start page %02X | byte pos %02X - %s", mirror_page, mirror_byte, (mirror_page >= 0x4 && ((mirror_user_mem_start_byte + bytes_required_for_mirror_data) <= 144)) ? _GREEN_("OK") : _YELLOW_("Invalid value")); } - if(tt_msg_lock) { - PrintAndLogEx(INFO, " - tag tamper message is permanently locked"); - } + if (tt_msg_lock) { + PrintAndLogEx(INFO, " - tamper message is permanently locked and cannot be written or read from memory"); + } } else if (tagtype & (NTAG_213_F | NTAG_216_F)) { uint8_t mirror_conf = ((data[0] & 0xC0) >> 6); @@ -905,24 +905,24 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st uint8_t tt_msg_resp_len; uint8_t tt_status_resp[5] = {0x00}; - if(tagtype & NTAG_213_TT) { - tt_enabled = (data[1] & 0x02); + if (tagtype & NTAG_213_TT) { + tt_enabled = (data[1] & 0x02); tt_msg_resp_len = ul_read(45, tt_message, 4); - PrintAndLogEx(INFO, " - tamper detection is %s" - , (tt_enabled) ? _GREEN_("ENABLED") : "disabled" - ); + PrintAndLogEx(INFO, " - tamper detection feature is %s" + , (tt_enabled) ? _GREEN_("ENABLED") : "disabled" + ); switch (data[1] & 0x06) { case 0x00: - PrintAndLogEx(INFO, " - tamper message is unlocked and read/write enabled"); + PrintAndLogEx(INFO, " - tamper message is unlocked and read/write enabled"); break; case 0x02: - PrintAndLogEx(INFO, " - tamper message is reversibly read/write protected in memory while the tamper feature is enabled"); + PrintAndLogEx(INFO, " - tamper message is reversibly read/write locked in memory while the tamper feature is enabled"); break; case 0x04: case 0x06: - PrintAndLogEx(INFO, " - tamper message is permanently read/write protected in memory"); + PrintAndLogEx(INFO, " - tamper message is permanently read/write locked in memory"); break; default: break; @@ -944,52 +944,53 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st PrintAndLogEx(INFO, " PWD [%u/0x%02X]: %s- (cannot be read)", startPage + 2, startPage + 2, sprint_hex(data + 8, 4)); PrintAndLogEx(INFO, " PACK [%u/0x%02X]: %s - (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 12, 2)); PrintAndLogEx(INFO, " RFU [%u/0x%02X]: %s- (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data + 14, 2)); - - if(tagtype & NTAG_213_TT) { - if(data[1] & 0x06) { + + if (tagtype & NTAG_213_TT) { + if (data[1] & 0x06) { PrintAndLogEx(INFO, "TT_MSG [45/0x2D]: %s- (cannot be read)", sprint_hex(tt_message, tt_msg_resp_len)); - PrintAndLogEx(INFO, " - tamper message is masked in memory"); + PrintAndLogEx(INFO, " - tamper message is masked in memory, but can be revealed in the READ_TT_STATUS command response if tampering was detected"); } else { PrintAndLogEx(INFO, "TT_MSG [45/0x2D]: %s", sprint_hex(tt_message, tt_msg_resp_len)); - PrintAndLogEx(INFO, " - tamper message is %s", sprint_hex(tt_message, tt_msg_resp_len)); + PrintAndLogEx(INFO, " - tamper message (read from memory) is %s", sprint_hex(tt_message, tt_msg_resp_len)); } } - if ((tagtype & NTAG_213_TT) && tt_enabled) { //The tag only returns meaningful information for the fields below if the tamper feature is enabled - + //The NTAG213TT only returns meaningful information for the fields below if the tamper feature is enabled + if ((tagtype & NTAG_213_TT) && tt_enabled) { + uint8_t tt_status_len = ntagtt_getTamperStatus(tt_status_resp, 5); - if(tt_status_len != 5) { - PrintAndLogEx(WARNING, "Error requesting tamper status from tag\n"); + if (tt_status_len != 5) { + PrintAndLogEx(WARNING, "Error sending the read TT status command to tag\n"); return PM3_ESOFT; } - + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("Tamper Status")); PrintAndLogEx(INFO, " READ_TT_STATUS: %s", sprint_hex(tt_status_resp, 5)); - PrintAndLogEx(INFO, " Tamper detection result from this power-up:"); - switch(tt_status_resp[4]) { + PrintAndLogEx(INFO, " Tamper status result from this power-up:"); + switch (tt_status_resp[4]) { case 0x43: - PrintAndLogEx(INFO, " - Tamper wire was detcted as closed during this power-up"); + PrintAndLogEx(INFO, " - Tamper loop was detcted as closed during this power-up"); break; case 0x4F: - PrintAndLogEx(INFO, " - Tamper wire was detected as open during this power-up"); + PrintAndLogEx(INFO, " - Tamper loop was detected as open during this power-up"); break; case 0x49: - PrintAndLogEx(INFO, " - No tamper wire measurement from this power-up is available"); + PrintAndLogEx(INFO, " - Tamper loop measurement from this power-up was not enabled or not valid"); break; default: break; } PrintAndLogEx(INFO, " Tamper detection permanent memory:"); - if((tt_status_resp[0] | tt_status_resp [1] | tt_status_resp[2] | tt_status_resp[3]) == 0x00) + if ((tt_status_resp[0] | tt_status_resp [1] | tt_status_resp[2] | tt_status_resp[3]) == 0x00) - PrintAndLogEx(INFO, " - Tamper wire has never been detected as open during power-up"); + PrintAndLogEx(INFO, " - Tamper loop has never been detected as open during power-up"); else { - PrintAndLogEx(INFO, " - Tamper wire has previously been detected as open during power-up"); - PrintAndLogEx(INFO, " - Tamper message: %s", sprint_hex(tt_status_resp, 4)); + PrintAndLogEx(INFO, " - Tamper loop was detected as open during power-up at least once"); + PrintAndLogEx(INFO, " - Tamper message returned by READ_TT_STATUS command: %s", sprint_hex(tt_status_resp, 4)); } } return PM3_SUCCESS; @@ -2715,7 +2716,7 @@ int CmdHF14MfUTamper(const char *Cmd) { CLIGetHexWithReturn(ctx, 3, msg_data, &msg_len); bool use_msg = (msg_len > 0); - if(use_msg && msg_len != 4) { + if (use_msg && msg_len != 4) { PrintAndLogEx(WARNING, "The tamper message must be 4 hex bytes if provided"); DropField(); return PM3_ESOFT; @@ -2731,7 +2732,7 @@ int CmdHF14MfUTamper(const char *Cmd) { DropField(); return PM3_ESOFT; } - if(tagtype != NTAG_213_TT) { + if (tagtype != NTAG_213_TT) { PrintAndLogEx(WARNING, "Tag type not NTAG 213TT"); DropField(); return PM3_ESOFT; @@ -2740,18 +2741,17 @@ int CmdHF14MfUTamper(const char *Cmd) { DropField(); iso14a_card_select_t card; - if(enable && disable) { + if (enable && disable) { PrintAndLogEx(WARNING, "You can only select one of the options enable/disable tamper feature"); DropField(); return PM3_ESOFT; } - if(use_msg) - { + if (use_msg) { if (ul_select(&card) == false) { DropField(); return UL_ERROR; - } + } PrintAndLogEx(INFO, "Trying to write tamper message\n"); SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, tt_msg_page, 0, 0, msg_data, 4); @@ -2768,34 +2768,34 @@ int CmdHF14MfUTamper(const char *Cmd) { } } - if(enable | disable | lock_msg) { + if (enable | disable | lock_msg) { if (ul_select(&card) == false) { PrintAndLogEx(ERR, "Unable to select tag"); DropField(); return UL_ERROR; - } + } uint8_t cfg_page[4] = {0x00}; uint8_t cmd[] = {ISO14443A_CMD_READBLOCK, tt_cfg_page}; int status = ul_send_cmd_raw(cmd, sizeof(cmd), cfg_page, 4); DropField(); - if(status <= 0) { + if (status <= 0) { PrintAndLogEx(WARNING, "Problem reading current config from tag"); DropField(); return PM3_ESOFT; } - if(enable) { + if (enable) { cfg_page[1] = cfg_page[1] | 0x02; PrintAndLogEx(INFO, "Enabling tamper feature"); } - if(disable) { + if (disable) { cfg_page[1] = cfg_page[1] & 0xFD; PrintAndLogEx(INFO, "Disabling tamper feature"); } - if(lock_msg) { + if (lock_msg) { cfg_page[1] = cfg_page[1] | 0x04; PrintAndLogEx(INFO, "Locking tamper message"); } diff --git a/include/protocols.h b/include/protocols.h index e4437d90a..0cc89abb7 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -223,7 +223,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define NTAG_I2C_SELECT_SECTOR 0xC2 #define NTAG_I2C_FASTWRITE 0xA6 -//NTAG 213TT (tamper) command +//NTAG 213TT (tamper) command #define NTAGTT_CMD_READ_TT 0xA4 // mifare 4bit card answers From dc1f302fa2adcd8765f9c2f36a151f3829b79376 Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Mon, 20 Feb 2023 02:20:08 -0600 Subject: [PATCH 632/759] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2f5c1dc4..7321da285 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `--back` option to `clear` command to clear the scrollback buffer (@wh201906) - Changed `hf iclass decrypt` - mark credentials as decrypted in the dump (@natesales) - Changed `hf iclass view` - show credentials on a decrypted dump (@natesales) + - Show NTAG213TT tamper info in `hf mfu info` and add commands for configuring it's tamper feature (@mjaksn) ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) From 3e952b80369483406f42974d5f8b5184226012ce Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Tue, 21 Feb 2023 01:50:33 +0100 Subject: [PATCH 633/759] bugfix: wrong text in hf mfdes list when no data exists in trace --- client/src/cmdhflist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index 232d4af19..fc3f94d7a 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -898,7 +898,7 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) { snprintf(exp, size, "R-block NACK(%d)", (cmd[0] & 0x01)); } // I-block 000xCN1x - else if ((cmd[0] & 0xC0) == 0x00) { + else if (((cmd[0] & 0xC0) == 0x00) && (cmdsize > 2)) { // PCB [CID] [NAD] [INF] CRC CRC int pos = 1; From 49a475899acd1fdba06f04eb3f8c1fe99053615f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Feb 2023 04:40:48 +0100 Subject: [PATCH 634/759] time is 64b better to accept the same size input timestamps --- tools/mfd_aes_brute/brute_key.c | 5 ++++- tools/mfd_aes_brute/mfd_aes_brute.c | 3 ++- tools/mfd_aes_brute/mfd_multi_brute.c | 5 +++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/mfd_aes_brute/brute_key.c b/tools/mfd_aes_brute/brute_key.c index 41c91f3c7..654fed6c6 100644 --- a/tools/mfd_aes_brute/brute_key.c +++ b/tools/mfd_aes_brute/brute_key.c @@ -111,7 +111,8 @@ int main(int argc, char *argv[]) { uint8_t tag_challenge[16] = {0x00}; uint8_t lock_challenge[32] = {0x00}; - uint64_t timestamp = atoi(argv[1]); + uint64_t timestamp = 0; + sscanf(argv[1], "%lu", ×tamp); if (argc != 4) { printf("\nusage: %s <16 byte tag challenge> <32 byte lock challenge>\n\n", argv[0]); @@ -124,8 +125,10 @@ int main(int argc, char *argv[]) { if (hexstr_to_byte_array(argv[3], lock_challenge, sizeof(lock_challenge))) return 3; + // current time uint64_t start_time = time(NULL); + // from a time before up until current time. for (; timestamp < start_time; timestamp++) { make_key(timestamp, key); diff --git a/tools/mfd_aes_brute/mfd_aes_brute.c b/tools/mfd_aes_brute/mfd_aes_brute.c index d4bca2bb8..4eba06051 100644 --- a/tools/mfd_aes_brute/mfd_aes_brute.c +++ b/tools/mfd_aes_brute/mfd_aes_brute.c @@ -233,7 +233,8 @@ int main(int argc, char *argv[]) { if (argc != 4) return usage(argv[0]); - uint64_t start_time = atoi(argv[1]); + uint64_t start_time = 0; + sscanf(argv[1], "%lu", &start_time); uint8_t tag_challenge[16] = {0x00}; if (hexstr_to_byte_array(argv[2], tag_challenge, sizeof(tag_challenge))) diff --git a/tools/mfd_aes_brute/mfd_multi_brute.c b/tools/mfd_aes_brute/mfd_multi_brute.c index 704796255..bbd213a35 100644 --- a/tools/mfd_aes_brute/mfd_multi_brute.c +++ b/tools/mfd_aes_brute/mfd_multi_brute.c @@ -172,7 +172,7 @@ static void print_time(uint64_t at) { char res[32]; strftime(res, sizeof(res), "%Y-%m-%d %H:%M:%S", <); - printf("%u ( '%s' )\n", (unsigned)t, res); + printf("%"PRIu64" ( '%s' )\n", t, res); } static void *brute_thread(void *arguments) { @@ -378,7 +378,8 @@ int main(int argc, char *argv[]) { return 1; } - uint64_t start_time = atoi(argv[3]); + uint64_t start_time = 0; + sscanf(argv[3], "%lu", &start_time); printf("Crypto algo............ " _GREEN_("%s") "\n", algostr); printf("LCR Random generator... " _GREEN_("%s") "\n", generators[g_idx].Name); From 6ee817aa72779474fc60c7feb8f3936c1d93b300 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Feb 2023 04:41:11 +0100 Subject: [PATCH 635/759] init array w zero --- armsrc/desfire_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/desfire_crypto.c b/armsrc/desfire_crypto.c index 84361e2c3..2358fa8b1 100644 --- a/armsrc/desfire_crypto.c +++ b/armsrc/desfire_crypto.c @@ -755,7 +755,7 @@ void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, memcpy(ovect, data, block_size); } - uint8_t edata[DESFIRE_MAX_CRYPTO_BLOCK_SIZE]; + uint8_t edata[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0}; switch (key->type) { case T_DES: From 64cc21b890ef12bf6c03bc94c0b5b315f1a5ee57 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Feb 2023 04:41:42 +0100 Subject: [PATCH 636/759] init structure with zeros --- armsrc/mifaredesfire.c | 1 + 1 file changed, 1 insertion(+) diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index 08d7a9379..3530dfd9b 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -139,6 +139,7 @@ void MifareDesfireGetInformation(void) { uint8_t details[14]; } PACKED payload; + memset(&payload, 0x00, sizeof(payload)); /* 1 = PCB 1 2 = cid 2 From 4807fae885f9800749b94771c4b13f700394edd3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Feb 2023 04:42:24 +0100 Subject: [PATCH 637/759] in private case we calloc, need to free that memory --- client/src/cmdflashmem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/cmdflashmem.c b/client/src/cmdflashmem.c index 7bbdf74c9..e8db64885 100644 --- a/client/src/cmdflashmem.c +++ b/client/src/cmdflashmem.c @@ -643,6 +643,7 @@ static int CmdFlashMemInfo(const char *Cmd) { if (got_private == false) { mbedtls_rsa_free(rsa); + free(rsa); } mbedtls_pk_free(&pkctx); From b86e29fca1fef059d66445cc2de7ce515e544e0c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Feb 2023 04:42:51 +0100 Subject: [PATCH 638/759] init structure with zeros --- client/src/cmdlfhid.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index 1ce02f4ed..4cfa41ef8 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -80,12 +80,14 @@ static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, boo ); } - lf_hidsim_t payload; - payload.Q5 = false; - payload.hi2 = packed.Top; - payload.hi = packed.Mid; - payload.lo = packed.Bot; - payload.longFMT = (packed.Mid > 0xFFF); + lf_hidsim_t payload = { + .EM = false, + .Q5 = false, + .hi2 = packed.Top, + .hi = packed.Mid, + .lo = packed.Bot, + .longFMT = (packed.Mid > 0xFFF) + }; clearCommandBuffer(); From 628140fd88f48c04e2bc8ab12e6980c172814e66 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Feb 2023 16:20:34 +0100 Subject: [PATCH 639/759] correct string formatter in sscanf --- tools/mfd_aes_brute/brute_key.c | 2 +- tools/mfd_aes_brute/mfd_aes_brute.c | 2 +- tools/mfd_aes_brute/mfd_multi_brute.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/mfd_aes_brute/brute_key.c b/tools/mfd_aes_brute/brute_key.c index 654fed6c6..e02a597e2 100644 --- a/tools/mfd_aes_brute/brute_key.c +++ b/tools/mfd_aes_brute/brute_key.c @@ -112,7 +112,7 @@ int main(int argc, char *argv[]) { uint8_t lock_challenge[32] = {0x00}; uint64_t timestamp = 0; - sscanf(argv[1], "%lu", ×tamp); + sscanf(argv[1], "%"PRIu64, ×tamp); if (argc != 4) { printf("\nusage: %s <16 byte tag challenge> <32 byte lock challenge>\n\n", argv[0]); diff --git a/tools/mfd_aes_brute/mfd_aes_brute.c b/tools/mfd_aes_brute/mfd_aes_brute.c index 4eba06051..b92eee31c 100644 --- a/tools/mfd_aes_brute/mfd_aes_brute.c +++ b/tools/mfd_aes_brute/mfd_aes_brute.c @@ -234,7 +234,7 @@ int main(int argc, char *argv[]) { if (argc != 4) return usage(argv[0]); uint64_t start_time = 0; - sscanf(argv[1], "%lu", &start_time); + sscanf(argv[1], "%"PRIu64, &start_time); uint8_t tag_challenge[16] = {0x00}; if (hexstr_to_byte_array(argv[2], tag_challenge, sizeof(tag_challenge))) diff --git a/tools/mfd_aes_brute/mfd_multi_brute.c b/tools/mfd_aes_brute/mfd_multi_brute.c index bbd213a35..4279fba62 100644 --- a/tools/mfd_aes_brute/mfd_multi_brute.c +++ b/tools/mfd_aes_brute/mfd_multi_brute.c @@ -379,7 +379,7 @@ int main(int argc, char *argv[]) { } uint64_t start_time = 0; - sscanf(argv[3], "%lu", &start_time); + sscanf(argv[3], "%"PRIu64, &start_time); printf("Crypto algo............ " _GREEN_("%s") "\n", algostr); printf("LCR Random generator... " _GREEN_("%s") "\n", generators[g_idx].Name); From a39b474884b9b38c4e6c436e4936645aec0c6bb8 Mon Sep 17 00:00:00 2001 From: ch3lt Date: Wed, 22 Feb 2023 10:12:18 +0100 Subject: [PATCH 640/759] Fixed CmdHF15Write/Readblock/Readmulti bug on sanity check when '-u ' argument is passed in command. Formating. --- client/src/cmdhf15.c | 80 ++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 10d239b94..d1b7289e8 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -48,6 +48,7 @@ #define Logic1 Iso15693Logic1 #define FrameEOF Iso15693FrameEOF #define CARD_MEMORY_SIZE 4096 +#define HF15_UID_LENGTH 8 #ifndef Crc15 # define Crc15(data, len) Crc16ex(CRC_15693, (data), (len)) @@ -222,6 +223,16 @@ static const productName_t uidmapping[] = { { 0, 0, "no tag-info available" } // must be the last entry }; +static inline void reverse(uint8_t *buff, uint8_t length) { + uint8_t upper_bound = (length % 2 == 0) ? length / 2 : (length / 2) + 1; + uint8_t tmp = 0; + for (int start = 0, end = length - 1; end >= upper_bound; ++start, --end) { + tmp = buff[end]; + buff[end] = buff[start]; + buff[start] = tmp; + } +} + static int CmdHF15Help(const char *Cmd); static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { @@ -1774,11 +1785,13 @@ static int CmdHF15Readmulti(const char *Cmd) { CLIExecWithReturn(ctx, Cmd, argtable, false); - uint8_t uid[8]; + uint8_t uid[HF15_UID_LENGTH]; int uidlen = 0; CLIGetHexWithReturn(ctx, 1, uid, &uidlen); + bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false; + bool unaddressed = arg_get_lit(ctx, 2); - bool scan = arg_get_lit(ctx, 3); + bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; //Default fallback to scan for tag. Overriding unaddressed parameter. int fast = (arg_get_lit(ctx, 4) == false); bool add_option = arg_get_lit(ctx, 5); @@ -1793,7 +1806,7 @@ static int CmdHF15Readmulti(const char *Cmd) { return PM3_EINVARG; } - if ((scan + unaddressed + uidlen) > 1) { + if ((scan + unaddressed + uid_set) > 1) { PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid"); return PM3_EINVARG; } @@ -1809,14 +1822,13 @@ static int CmdHF15Readmulti(const char *Cmd) { PrintAndLogEx(WARNING, "no tag found"); return PM3_EINVARG; } - uidlen = 8; + } else { + reverse(uid, HF15_UID_LENGTH); } + // add UID (scan, uid) + memcpy(req + reqlen, uid, HF15_UID_LENGTH); + reqlen += HF15_UID_LENGTH; - if (uidlen == 8) { - // add UID (scan, uid) - memcpy(req + reqlen, uid, sizeof(uid)); - reqlen += sizeof(uid); - } PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid)); } // add OPTION flag, in order to get lock-info @@ -1908,11 +1920,13 @@ static int CmdHF15Readblock(const char *Cmd) { CLIExecWithReturn(ctx, Cmd, argtable, false); - uint8_t uid[8]; + uint8_t uid[HF15_UID_LENGTH]; int uidlen = 0; CLIGetHexWithReturn(ctx, 1, uid, &uidlen); + bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false; + bool unaddressed = arg_get_lit(ctx, 2); - bool scan = arg_get_lit(ctx, 3); + bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; //Default fallback to scan for tag. Overriding unaddressed parameter. int fast = (arg_get_lit(ctx, 4) == false); bool add_option = arg_get_lit(ctx, 5); @@ -1920,36 +1934,31 @@ static int CmdHF15Readblock(const char *Cmd) { CLIParserFree(ctx); // sanity checks - if ((scan + unaddressed + uidlen) > 1) { + if ((scan + unaddressed + uid_set) > 1) { PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid"); return PM3_EINVARG; } - // default fallback to scan for tag. - // overriding unaddress parameter :) - if (uidlen != 8) { - scan = true; - } - // request to be sent to device/card uint16_t flags = arg_get_raw_flag(uidlen, unaddressed, scan, add_option); uint8_t req[PM3_CMD_DATA_SIZE] = {flags, ISO15693_READBLOCK}; uint16_t reqlen = 2; if (unaddressed == false) { + // default fallback to scan for tag. + // overriding unaddress parameter :) if (scan) { if (getUID(false, uid) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "no tag found"); return PM3_EINVARG; } - uidlen = 8; + } else { + reverse(uid, HF15_UID_LENGTH); } + // add UID (scan, uid) + memcpy(req + reqlen, uid, HF15_UID_LENGTH); + reqlen += HF15_UID_LENGTH; - if (uidlen == 8) { - // add UID (scan, uid) - memcpy(req + reqlen, uid, sizeof(uid)); - reqlen += sizeof(uid); - } PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid)); } // add OPTION flag, in order to get lock-info @@ -2073,11 +2082,13 @@ static int CmdHF15Write(const char *Cmd) { argtable[arglen++] = arg_param_end; CLIExecWithReturn(ctx, Cmd, argtable, false); - uint8_t uid[8]; + uint8_t uid[HF15_UID_LENGTH]; int uidlen = 0; CLIGetHexWithReturn(ctx, 1, uid, &uidlen); + bool uid_set = (uidlen == HF15_UID_LENGTH) ? true : false; + bool unaddressed = arg_get_lit(ctx, 2); - bool scan = arg_get_lit(ctx, 3); + bool scan = (arg_get_lit(ctx, 3) || (!uid_set && !unaddressed)) ? true : false; //Default fallback to scan for tag. Overriding unaddressed parameter. int fast = (arg_get_lit(ctx, 4) == false); bool add_option = arg_get_lit(ctx, 5); @@ -2090,7 +2101,7 @@ static int CmdHF15Write(const char *Cmd) { CLIParserFree(ctx); // sanity checks - if ((scan + unaddressed + uidlen) > 1) { + if ((scan + unaddressed + uid_set) > 1) { PrintAndLogEx(WARNING, "Select only one option /scan/unaddress/uid"); return PM3_EINVARG; } @@ -2102,9 +2113,6 @@ static int CmdHF15Write(const char *Cmd) { // default fallback to scan for tag. // overriding unaddress parameter :) - if (uidlen != 8) { - scan = true; - } // request to be sent to device/card uint16_t flags = arg_get_raw_flag(uidlen, unaddressed, scan, add_option); @@ -2120,18 +2128,16 @@ static int CmdHF15Write(const char *Cmd) { PrintAndLogEx(WARNING, "no tag found"); return PM3_EINVARG; } - uidlen = 8; + } else { + reverse(uid, HF15_UID_LENGTH); } + // add UID (scan, uid) + memcpy(req + reqlen, uid, HF15_UID_LENGTH); + reqlen += HF15_UID_LENGTH; - if (uidlen == 8) { - // add UID (scan, uid) - memcpy(req + reqlen, uid, sizeof(uid)); - reqlen += sizeof(uid); - } PrintAndLogEx(SUCCESS, "Using UID... " _GREEN_("%s"), iso15693_sprintUID(NULL, uid)); } - req[reqlen++] = (uint8_t)block; memcpy(req + reqlen, d, sizeof(d)); reqlen += sizeof(d); From 690eb0fc8a4c66f1fd27f66c09900e1c0ca087ed Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Wed, 22 Feb 2023 07:40:04 -0600 Subject: [PATCH 641/759] add missing CLIParserFree(ctx) , init variable to zero, and small text change --- client/src/cmdhfmfu.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 31823adeb..9c8514241 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -758,7 +758,6 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st if (tagtype & NTAG_213_TT) { uint8_t mirror_conf = ((data[0] & 0xE0) >> 5); uint8_t mirror_byte = ((data[0] & 0x18) >> 3); - uint8_t tt_msg_lock = (data[1] & 0x04); uint8_t mirror_page = data[2]; switch (mirror_conf) { @@ -822,10 +821,6 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st PrintAndLogEx(INFO, " mirror start page %02X | byte pos %02X - %s", mirror_page, mirror_byte, (mirror_page >= 0x4 && ((mirror_user_mem_start_byte + bytes_required_for_mirror_data) <= 144)) ? _GREEN_("OK") : _YELLOW_("Invalid value")); } - if (tt_msg_lock) { - PrintAndLogEx(INFO, " - tamper message is permanently locked and cannot be written or read from memory"); - } - } else if (tagtype & (NTAG_213_F | NTAG_216_F)) { uint8_t mirror_conf = ((data[0] & 0xC0) >> 6); uint8_t mirror_byte = (data[0] & 0x30); @@ -902,7 +897,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st uint8_t tt_enabled = 0; uint8_t tt_message[4] = {0x00}; - uint8_t tt_msg_resp_len; + uint8_t tt_msg_resp_len = 0; uint8_t tt_status_resp[5] = {0x00}; if (tagtype & NTAG_213_TT) { @@ -948,10 +943,10 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st if (tagtype & NTAG_213_TT) { if (data[1] & 0x06) { PrintAndLogEx(INFO, "TT_MSG [45/0x2D]: %s- (cannot be read)", sprint_hex(tt_message, tt_msg_resp_len)); - PrintAndLogEx(INFO, " - tamper message is masked in memory, but can be revealed in the READ_TT_STATUS command response if tampering was detected"); + PrintAndLogEx(INFO, " - tamper message is masked in memory"); } else { PrintAndLogEx(INFO, "TT_MSG [45/0x2D]: %s", sprint_hex(tt_message, tt_msg_resp_len)); - PrintAndLogEx(INFO, " - tamper message (read from memory) is %s", sprint_hex(tt_message, tt_msg_resp_len)); + PrintAndLogEx(INFO, " - tamper message is %s and is readable/writablbe in memory", sprint_hex(tt_message, tt_msg_resp_len)); } } @@ -961,7 +956,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st uint8_t tt_status_len = ntagtt_getTamperStatus(tt_status_resp, 5); if (tt_status_len != 5) { - PrintAndLogEx(WARNING, "Error sending the read TT status command to tag\n"); + PrintAndLogEx(WARNING, "Error sending the READ_TT_STATUS command to tag\n"); return PM3_ESOFT; } @@ -978,7 +973,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st PrintAndLogEx(INFO, " - Tamper loop was detected as open during this power-up"); break; case 0x49: - PrintAndLogEx(INFO, " - Tamper loop measurement from this power-up was not enabled or not valid"); + PrintAndLogEx(INFO, " - Tamper loop measurement was not enabled or not valid during this power-up"); break; default: break; @@ -2725,6 +2720,7 @@ int CmdHF14MfUTamper(const char *Cmd) { bool lock_msg = arg_get_lit(ctx, 4); bool enable = arg_get_lit(ctx, 1); bool disable = arg_get_lit(ctx, 2); + CLIParserFree(ctx); TagTypeUL_t tagtype = GetHF14AMfU_Type(); if (tagtype == UL_ERROR) { From 75fd0c2034492ad73baedc474a787da430191831 Mon Sep 17 00:00:00 2001 From: Matthew Jackson <123390480+mjaksn@users.noreply.github.com> Date: Thu, 23 Feb 2023 01:52:07 -0600 Subject: [PATCH 642/759] fixed another missing CLIParserFree(ctx); Signed-off-by: Matthew Jackson <123390480+mjaksn@users.noreply.github.com> --- client/src/cmdhfmfu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 9c8514241..d5ac6537b 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -2714,6 +2714,7 @@ int CmdHF14MfUTamper(const char *Cmd) { if (use_msg && msg_len != 4) { PrintAndLogEx(WARNING, "The tamper message must be 4 hex bytes if provided"); DropField(); + CLIParserFree(ctx); return PM3_ESOFT; } From 9a2e07e1a8d783773169b97d45276261bff7b687 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 23 Feb 2023 12:33:24 +0100 Subject: [PATCH 643/759] should fix time_t printing issues --- tools/mfd_aes_brute/mfd_multi_brute.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/mfd_aes_brute/mfd_multi_brute.c b/tools/mfd_aes_brute/mfd_multi_brute.c index 4279fba62..3474d81d9 100644 --- a/tools/mfd_aes_brute/mfd_multi_brute.c +++ b/tools/mfd_aes_brute/mfd_multi_brute.c @@ -169,10 +169,10 @@ static void print_time(uint64_t at) { (void)localtime_r(&t, <); #endif - char res[32]; - strftime(res, sizeof(res), "%Y-%m-%d %H:%M:%S", <); + char res[70]; + strftime(res, sizeof(res), "%s ('%Y-%m-%d %H:%M:%S')", <); - printf("%"PRIu64" ( '%s' )\n", t, res); + printf("%s\n", res); } static void *brute_thread(void *arguments) { From 601b442b6c49ab3df80b17d73fd31c5f130548bf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 23 Feb 2023 20:35:07 +0100 Subject: [PATCH 644/759] fix warning in GH actions --- .github/workflows/windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index d639eebc4..4d971faa6 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -98,7 +98,7 @@ jobs: steps: - name: WSL setup - uses: Vampire/setup-wsl@v1 + uses: Vampire/setup-wsl@v2 with: distribution: Ubuntu-20.04 update: "true" From a4bf1c5710c87a44a9d6a22705ae7c802fe37ef7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 23 Feb 2023 20:36:27 +0100 Subject: [PATCH 645/759] update to 22.04 --- .github/workflows/windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 4d971faa6..77c3dc70c 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -100,7 +100,7 @@ jobs: - name: WSL setup uses: Vampire/setup-wsl@v2 with: - distribution: Ubuntu-20.04 + distribution: Ubuntu-22.04 update: "true" additional-packages: git ca-certificates From dd7c9daa8d0ee60f1399acbe21cd9489de385cb1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 23 Feb 2023 20:53:53 +0100 Subject: [PATCH 646/759] fix CID #405002 - invalid string formatter --- client/src/cmdlfguard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdlfguard.c b/client/src/cmdlfguard.c index 0225b2fef..c31629c5a 100644 --- a/client/src/cmdlfguard.c +++ b/client/src/cmdlfguard.c @@ -375,7 +375,7 @@ static int CmdGuardSim(const char *Cmd) { return PM3_ESOFT; } - PrintAndLogEx(SUCCESS, "Simulating Guardall Prox - xorKey: " _YELLOW_("%u%") " Facility Code: " _YELLOW_("%u") " CardNumber: " _YELLOW_("%u") + PrintAndLogEx(SUCCESS, "Simulating Guardall Prox - xorKey: " _YELLOW_("%u") " Facility Code: " _YELLOW_("%u") " CardNumber: " _YELLOW_("%u") , xorval , facilitycode , cardnumber From 02a801f6655ac82d7a7e168bc7120577e276e668 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 23 Feb 2023 20:58:45 +0100 Subject: [PATCH 647/759] fix CID #404863 printing --- tools/mfd_aes_brute/mfd_aes_brute.c | 7 +++---- tools/mfd_aes_brute/mfd_multi_brute.c | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/mfd_aes_brute/mfd_aes_brute.c b/tools/mfd_aes_brute/mfd_aes_brute.c index b92eee31c..0cf1028b3 100644 --- a/tools/mfd_aes_brute/mfd_aes_brute.c +++ b/tools/mfd_aes_brute/mfd_aes_brute.c @@ -139,10 +139,9 @@ static void print_time(uint64_t at) { (void)localtime_r(&t, <); #endif - char res[32]; - strftime(res, sizeof(res), "%Y-%m-%d %H:%M:%S", <); - - printf("%u ( '%s' )\n", (unsigned)t, res); + char res[70]; + strftime(res, sizeof(res), "%s ('%Y-%m-%d %H:%M:%S')", <); + printf("%s\n", res); } static void *brute_thread(void *arguments) { diff --git a/tools/mfd_aes_brute/mfd_multi_brute.c b/tools/mfd_aes_brute/mfd_multi_brute.c index 3474d81d9..4e7579e8f 100644 --- a/tools/mfd_aes_brute/mfd_multi_brute.c +++ b/tools/mfd_aes_brute/mfd_multi_brute.c @@ -171,7 +171,6 @@ static void print_time(uint64_t at) { char res[70]; strftime(res, sizeof(res), "%s ('%Y-%m-%d %H:%M:%S')", <); - printf("%s\n", res); } From 93d7d46776fc1ca849ba6ccbdafc9b9dadb1a45e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 24 Feb 2023 20:57:42 +0100 Subject: [PATCH 648/759] fix proxspace build --- tools/mfd_aes_brute/mfd_aes_brute.c | 4 ++++ tools/mfd_aes_brute/mfd_multi_brute.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tools/mfd_aes_brute/mfd_aes_brute.c b/tools/mfd_aes_brute/mfd_aes_brute.c index 0cf1028b3..b19885f34 100644 --- a/tools/mfd_aes_brute/mfd_aes_brute.c +++ b/tools/mfd_aes_brute/mfd_aes_brute.c @@ -140,7 +140,11 @@ static void print_time(uint64_t at) { #endif char res[70]; +#if defined(__MINGW32__) || defined(__MINGW64__) + strftime(res, sizeof(res), "('%Y-%m-%d %H:%M:%S')", <); +#else strftime(res, sizeof(res), "%s ('%Y-%m-%d %H:%M:%S')", <); +#endif printf("%s\n", res); } diff --git a/tools/mfd_aes_brute/mfd_multi_brute.c b/tools/mfd_aes_brute/mfd_multi_brute.c index 4e7579e8f..bb2456aa1 100644 --- a/tools/mfd_aes_brute/mfd_multi_brute.c +++ b/tools/mfd_aes_brute/mfd_multi_brute.c @@ -170,7 +170,11 @@ static void print_time(uint64_t at) { #endif char res[70]; +#if defined(__MINGW32__) || defined(__MINGW64__) + strftime(res, sizeof(res), "('%Y-%m-%d %H:%M:%S')", <); +#else strftime(res, sizeof(res), "%s ('%Y-%m-%d %H:%M:%S')", <); +#endif printf("%s\n", res); } From b05a2d4525bbf54f8b3506c934945e7ea9ae251a Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Fri, 24 Feb 2023 00:55:49 +0100 Subject: [PATCH 649/759] Add mfc signature support to gen4 lua script --- client/luascripts/hf_mf_ultimatecard.lua | 34 ++++++++++++++++-------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/client/luascripts/hf_mf_ultimatecard.lua b/client/luascripts/hf_mf_ultimatecard.lua index 42a5e1887..aca2cccb7 100644 --- a/client/luascripts/hf_mf_ultimatecard.lua +++ b/client/luascripts/hf_mf_ultimatecard.lua @@ -483,17 +483,29 @@ local function write_signature(data) end local info = connect() if not info then return false, "Can't select card" end - if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end - print('Writing new signature',data) - local b,c - local cmd = 'A2F%d%s' - local j = 2 - for i = 1, #data, 8 do - b = data:sub(i,i+7) - c = cmd:format(j,b) - local resp = send(c) - if resp ~= '0A' then lib14a.disconnect(); return nil, oops('Failed to write signature') end - j = j + 1 + if ulprotocol == '00' then + print('Writing new MFC signature',data) + send('CF'.._key..'6B48') + lib14a.disconnect() + connect() -- not 100% sure why it's needed, but without this blocks aren't actually written + local sig1 = data:sub(1, 32) + local sig2 = data:sub(33, 64) + + send('CF'.._key..'CD45'..sig1) + send('CF'.._key..'CD46'..sig2) + send('CF'.._key..'CD475C8FF9990DA270F0F8694B791BEA7BCC') + else + print('Writing new MFUL signature',data) + local b,c + local cmd = 'A2F%d%s' + local j = 2 + for i = 1, #data, 8 do + b = data:sub(i,i+7) + c = cmd:format(j,b) + local resp = send(c) + if resp ~= '0A' then lib14a.disconnect(); return nil, oops('Failed to write signature') end + j = j + 1 + end end lib14a.disconnect() return true, 'Ok' From 7834db8be756bbbb944f45bc5e5632a3ecdd6cd5 Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Fri, 24 Feb 2023 00:59:35 +0100 Subject: [PATCH 650/759] Add CHANGELOG.md entry, bump script version --- CHANGELOG.md | 1 + client/luascripts/hf_mf_ultimatecard.lua | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7321da285..c49a7c08e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed `hf iclass decrypt` - mark credentials as decrypted in the dump (@natesales) - Changed `hf iclass view` - show credentials on a decrypted dump (@natesales) - Show NTAG213TT tamper info in `hf mfu info` and add commands for configuring it's tamper feature (@mjaksn) + - Add Mifare Classic EV1 signature write support to gen4 magic tag lua script (@augustozanellato) ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) diff --git a/client/luascripts/hf_mf_ultimatecard.lua b/client/luascripts/hf_mf_ultimatecard.lua index aca2cccb7..93e64e333 100644 --- a/client/luascripts/hf_mf_ultimatecard.lua +++ b/client/luascripts/hf_mf_ultimatecard.lua @@ -13,7 +13,7 @@ local err_lock = 'use -k or change cfg0 block' local _print = 0 copyright = '' author = 'Nathan Glaser' -version = 'v1.0.4' +version = 'v1.0.5' date = 'Created - Jan 2022' desc = 'This script enables easy programming of an Ultimate Mifare Magic card' example = [[ From 85ca342567213617ea4cd3b9f930638b017d515d Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Mon, 27 Feb 2023 13:02:16 -0700 Subject: [PATCH 651/759] Add bruteforce functionality to HID facility code --- client/src/cmdlfhid.c | 124 +++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 49 deletions(-) mode change 100644 => 100755 client/src/cmdlfhid.c diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c old mode 100644 new mode 100755 index 4cfa41ef8..fa6399b9e --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -475,26 +475,27 @@ static int CmdHIDClone(const char *Cmd) { static int CmdHIDBrute(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf hid brute", - "Enables bruteforce of HID readers with specified facility code.\n" - "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step\n" - "if cardnumber is not given, it starts with 1 and goes up to 65535", - "lf hid brute -w H10301 --fc 224\n" - "lf hid brute -w H10301 --fc 21 -d 2000\n" - "lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000\n" - "lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000 --up\n" + "Enables bruteforce of HID readers while maintaining specific parameter values.\n" + "If the field being bruteforced is provided, it starts with it and goes up / down one step while maintaining other supplied values.\n" + "If the field being bruteforced is not provided, it will iterate through the full range while maintaining other supplied values.", + "lf hid brute -w H10301 -f fc --fc 224 --cn 6278\n" + "lf hid brute -w H10301 -f cn --fc 21 -d 2000\n" + "lf hid brute -v -w H10301 -f cn --fc 21 --cn 200 -d 2000\n" + "lf hid brute -v -w H10301 -f fc --fc 21 --cn 200 -d 2000 --up\n" ); void *argtable[] = { arg_param_begin, arg_lit0("v", "verbose", "verbose output"), arg_str1("w", "wiegand", "", "see " _YELLOW_("`wiegand list`") " for available formats"), + arg_str1("f", "field", "", "field to bruteforce"), arg_u64_0(NULL, "fc", "", "facility code"), - arg_u64_0(NULL, "cn", "", "card number to start with"), + arg_u64_0(NULL, "cn", "", "card number"), arg_u64_0("i", "issue", "", "issue level"), arg_u64_0("o", "oem", "", "OEM code"), - arg_u64_0("d", "delay", "", "delay betweens attempts in ms. Default 1000ms"), - arg_lit0(NULL, "up", "direction to increment card number. (default is both directions)"), - arg_lit0(NULL, "down", "direction to decrement card number. (default is both directions)"), + arg_u64_0("d", "delay", "", "delay betweens attempts in ms. (default is 1000)"), + arg_lit0(NULL, "up", "direction to increment field value. (default is both directions)"), + arg_lit0(NULL, "down", "direction to decrement field value. (default is both directions)"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -512,22 +513,26 @@ static int CmdHIDBrute(const char *Cmd) { return PM3_EINVARG; } - wiegand_card_t cn_hi, cn_low; - memset(&cn_hi, 0, sizeof(wiegand_card_t)); + wiegand_card_t card_hi, card_low; + memset(&card_hi, 0, sizeof(wiegand_card_t)); + + char field[3] = {0}; + int field_len = 0; + CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)field, sizeof(field), &field_len); - cn_hi.FacilityCode = arg_get_u32_def(ctx, 3, 0); - cn_hi.CardNumber = arg_get_u32_def(ctx, 4, 0); - cn_hi.IssueLevel = arg_get_u32_def(ctx, 5, 0); - cn_hi.OEM = arg_get_u32_def(ctx, 6, 0); + card_hi.FacilityCode = arg_get_u32_def(ctx, 4, 0); + card_hi.CardNumber = arg_get_u32_def(ctx, 5, 0); + card_hi.IssueLevel = arg_get_u32_def(ctx, 6, 0); + card_hi.OEM = arg_get_u32_def(ctx, 7, 0); - uint32_t delay = arg_get_u32_def(ctx, 7, 1000); + uint32_t delay = arg_get_u32_def(ctx, 8, 1000); int direction = 0; - if (arg_get_lit(ctx, 8) && arg_get_lit(ctx, 9)) { + if (arg_get_lit(ctx, 9) && arg_get_lit(ctx, 10)) { direction = 0; - } else if (arg_get_lit(ctx, 8)) { - direction = 1; } else if (arg_get_lit(ctx, 9)) { + direction = 1; + } else if (arg_get_lit(ctx, 10)) { direction = 2; } @@ -535,34 +540,38 @@ static int CmdHIDBrute(const char *Cmd) { if (verbose) { PrintAndLogEx(INFO, "Wiegand format... %i", format_idx); - PrintAndLogEx(INFO, "OEM.............. %u", cn_hi.OEM); - PrintAndLogEx(INFO, "ISSUE............ %u", cn_hi.IssueLevel); - PrintAndLogEx(INFO, "Facility code.... %u", cn_hi.FacilityCode); - PrintAndLogEx(INFO, "Card number...... %" PRIu64, cn_hi.CardNumber); + PrintAndLogEx(INFO, "OEM.............. %u", card_hi.OEM); + PrintAndLogEx(INFO, "ISSUE............ %u", card_hi.IssueLevel); + PrintAndLogEx(INFO, "Facility code.... %u", card_hi.FacilityCode); + PrintAndLogEx(INFO, "Card number...... %" PRIu64, card_hi.CardNumber); PrintAndLogEx(INFO, "Delay............ " _YELLOW_("%d"), delay); + if (strcmp(field, "fc") == 0) { + PrintAndLogEx(INFO, "Field............ " _YELLOW_("fc")); + } else if (strcmp(field, "cn") == 0) { + PrintAndLogEx(INFO, "Field............ " _YELLOW_("cn")); + } switch (direction) { case 0: - PrintAndLogEx(INFO, "Direction........ " _YELLOW_("BOTH")); + PrintAndLogEx(INFO, "Direction........ " _YELLOW_("both")); break; case 1: - PrintAndLogEx(INFO, "Direction........ " _YELLOW_("UP")); + PrintAndLogEx(INFO, "Direction........ " _YELLOW_("up")); break; case 2: - PrintAndLogEx(INFO, "Direction........ " _YELLOW_("DOWN")); + PrintAndLogEx(INFO, "Direction........ " _YELLOW_("down")); break; default: break; } } PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "Started brute-forcing HID Prox reader"); + PrintAndLogEx(INFO, "Started bruteforcing HID Prox reader"); PrintAndLogEx(INFO, "Press " _GREEN_("") " or pm3-button to abort simulation"); PrintAndLogEx(NORMAL, ""); // copy values to low. - cn_low = cn_hi; + card_low = card_hi; // main loop - // iceman: could add options for bruteforcing OEM, ISSUE or FC as well.. bool exitloop = false; bool fin_hi, fin_low; fin_hi = fin_low = false; @@ -578,27 +587,43 @@ static int CmdHIDBrute(const char *Cmd) { return sendPing(); } - // do one up - if (direction != 2) { - if (cn_hi.CardNumber < 0xFFFF) { - if (sendTry(format_idx, &cn_hi, delay, verbose) != PM3_SUCCESS) { - return PM3_ESOFT; + // do one up + if (direction != 2 && fin_hi != true) { + if (sendTry(format_idx, &card_hi, delay, verbose) != PM3_SUCCESS) { + return PM3_ESOFT; + } + if (strcmp(field, "fc") == 0) { + if (card_hi.FacilityCode < 0xFF) { + card_hi.FacilityCode++; + } else { + fin_hi = true; + } + } else if (strcmp(field, "cn") == 0) { + if (card_hi.CardNumber < 0xFFFF) { + card_hi.CardNumber++; + } else { + fin_hi = true; } - cn_hi.CardNumber++; - } else { - fin_hi = true; } } // do one down - if (direction != 1) { - if (cn_low.CardNumber > 0) { - cn_low.CardNumber--; - if (sendTry(format_idx, &cn_low, delay, verbose) != PM3_SUCCESS) { - return PM3_ESOFT; + if (direction != 1 && fin_low != true) { + if (sendTry(format_idx, &card_low, delay, verbose) != PM3_SUCCESS) { + return PM3_ESOFT; + } + if (strcmp(field, "fc") == 0) { + if (card_low.FacilityCode > 0) { + card_low.FacilityCode--; + } else { + fin_low = true; + } + } else if (strcmp(field, "cn") == 0) { + if (card_low.CardNumber > 0) { + card_low.CardNumber--; + } else { + fin_low = true; } - } else { - fin_low = true; } } @@ -620,7 +645,8 @@ static int CmdHIDBrute(const char *Cmd) { } while (exitloop == false); - PrintAndLogEx(INFO, "Brute forcing finished"); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "Bruteforcing finished"); return PM3_SUCCESS; } @@ -630,8 +656,8 @@ static command_t CommandTable[] = { {"reader", CmdHIDReader, IfPm3Lf, "attempt to read and extract tag data"}, {"clone", CmdHIDClone, IfPm3Lf, "clone HID tag to T55x7"}, {"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"}, - {"brute", CmdHIDBrute, IfPm3Lf, "bruteforce card number against reader"}, - {"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, + {"brute", CmdHIDBrute, IfPm3Lf, "bruteforce HID tag while maintaining specific parameter values"}, + {"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards"}, {NULL, NULL, NULL, NULL} }; From 702716b59750b26e00d08780e6b3256d98e759ef Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Mon, 27 Feb 2023 13:05:16 -0700 Subject: [PATCH 652/759] Fix formatting --- client/src/cmdlfhid.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index fa6399b9e..de2e9dc29 100755 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -476,7 +476,7 @@ static int CmdHIDBrute(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf hid brute", "Enables bruteforce of HID readers while maintaining specific parameter values.\n" - "If the field being bruteforced is provided, it starts with it and goes up / down one step while maintaining other supplied values.\n" + "If the field being bruteforced is provided, it starts with it and goes up / down one step while maintaining other supplied values.\n" "If the field being bruteforced is not provided, it will iterate through the full range while maintaining other supplied values.", "lf hid brute -w H10301 -f fc --fc 224 --cn 6278\n" "lf hid brute -w H10301 -f cn --fc 21 -d 2000\n" @@ -488,12 +488,12 @@ static int CmdHIDBrute(const char *Cmd) { arg_param_begin, arg_lit0("v", "verbose", "verbose output"), arg_str1("w", "wiegand", "", "see " _YELLOW_("`wiegand list`") " for available formats"), - arg_str1("f", "field", "", "field to bruteforce"), - arg_u64_0(NULL, "fc", "", "facility code"), - arg_u64_0(NULL, "cn", "", "card number"), - arg_u64_0("i", "issue", "", "issue level"), - arg_u64_0("o", "oem", "", "OEM code"), - arg_u64_0("d", "delay", "", "delay betweens attempts in ms. (default is 1000)"), + arg_str1("f", "field", "", "field to bruteforce"), + arg_u64_0(NULL, "fc", "", "facility code"), + arg_u64_0(NULL, "cn", "", "card number"), + arg_u64_0("i", "issue", "", "issue level"), + arg_u64_0("o", "oem", "", "OEM code"), + arg_u64_0("d", "delay", "", "delay betweens attempts in ms. (default is 1000)"), arg_lit0(NULL, "up", "direction to increment field value. (default is both directions)"), arg_lit0(NULL, "down", "direction to decrement field value. (default is both directions)"), arg_param_end From 21a1defa88840596614012ee5aa99c2f41c62043 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Mon, 27 Feb 2023 13:06:38 -0700 Subject: [PATCH 653/759] Fix formatting --- client/src/cmdlfhid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index de2e9dc29..d6349e9ad 100755 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -488,7 +488,7 @@ static int CmdHIDBrute(const char *Cmd) { arg_param_begin, arg_lit0("v", "verbose", "verbose output"), arg_str1("w", "wiegand", "", "see " _YELLOW_("`wiegand list`") " for available formats"), - arg_str1("f", "field", "", "field to bruteforce"), + arg_str1("f", "field", "", "field to bruteforce"), arg_u64_0(NULL, "fc", "", "facility code"), arg_u64_0(NULL, "cn", "", "card number"), arg_u64_0("i", "issue", "", "issue level"), From 3bcac0cc64e8b7e918f70ccb2d4826e43c3b2cf7 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Tue, 28 Feb 2023 07:24:24 -0700 Subject: [PATCH 654/759] Updated arguments and help text --- client/src/cmdlfhid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index d6349e9ad..424c043c4 100755 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -488,7 +488,7 @@ static int CmdHIDBrute(const char *Cmd) { arg_param_begin, arg_lit0("v", "verbose", "verbose output"), arg_str1("w", "wiegand", "", "see " _YELLOW_("`wiegand list`") " for available formats"), - arg_str1("f", "field", "", "field to bruteforce"), + arg_str1(NULL, "field", "", "field to bruteforce. can be _YELLOW("`fc`") for facility code, or _YELLOW("`cn`") for card number"), arg_u64_0(NULL, "fc", "", "facility code"), arg_u64_0(NULL, "cn", "", "card number"), arg_u64_0("i", "issue", "", "issue level"), @@ -656,8 +656,8 @@ static command_t CommandTable[] = { {"reader", CmdHIDReader, IfPm3Lf, "attempt to read and extract tag data"}, {"clone", CmdHIDClone, IfPm3Lf, "clone HID tag to T55x7"}, {"sim", CmdHIDSim, IfPm3Lf, "simulate HID tag"}, - {"brute", CmdHIDBrute, IfPm3Lf, "bruteforce HID tag while maintaining specific parameter values"}, - {"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards"}, + {"brute", CmdHIDBrute, IfPm3Lf, "bruteforce facility code or card number against reader"}, + {"watch", CmdHIDWatch, IfPm3Lf, "continuously watch for cards. Reader mode"}, {NULL, NULL, NULL, NULL} }; From cd5fa61683f742ea835c84d982fa6c0d2c00918a Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Tue, 28 Feb 2023 07:28:06 -0700 Subject: [PATCH 655/759] Update help text --- client/src/cmdlfhid.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index 424c043c4..19c7a3ea0 100755 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -475,13 +475,13 @@ static int CmdHIDClone(const char *Cmd) { static int CmdHIDBrute(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf hid brute", - "Enables bruteforce of HID readers while maintaining specific parameter values.\n" + "Enables bruteforce of HID readers with specified facility code or card number. This is an attack against the reader.\n" "If the field being bruteforced is provided, it starts with it and goes up / down one step while maintaining other supplied values.\n" "If the field being bruteforced is not provided, it will iterate through the full range while maintaining other supplied values.", - "lf hid brute -w H10301 -f fc --fc 224 --cn 6278\n" - "lf hid brute -w H10301 -f cn --fc 21 -d 2000\n" - "lf hid brute -v -w H10301 -f cn --fc 21 --cn 200 -d 2000\n" - "lf hid brute -v -w H10301 -f fc --fc 21 --cn 200 -d 2000 --up\n" + "lf hid brute -w H10301 --field fc --fc 224 --cn 6278\n" + "lf hid brute -w H10301 --field cn --fc 21 -d 2000\n" + "lf hid brute -v -w H10301 --field cn --fc 21 --cn 200 -d 2000\n" + "lf hid brute -v -w H10301 --field fc --fc 21 --cn 200 -d 2000 --up\n" ); void *argtable[] = { From b486f3bba4855bf31daee88a126215ddbed7b62c Mon Sep 17 00:00:00 2001 From: weejhsteve <92703857+weejhsteve@users.noreply.github.com> Date: Wed, 1 Mar 2023 11:23:14 +0800 Subject: [PATCH 656/759] Update mfc_default_keys.dic # Food GEM 6686FADE5566 Signed-off-by: weejhsteve <92703857+weejhsteve@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index a522b001b..f3118f946 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2028,3 +2028,5 @@ F72CD208FDF9 # # 1k - waldorf astoria 011C6CF459E8 +# Food GEM +6686FADE5566 From 194895e9af9df0e817fd70f5c2d2dce4f07f29bc Mon Sep 17 00:00:00 2001 From: weejhsteve <92703857+weejhsteve@users.noreply.github.com> Date: Wed, 1 Mar 2023 15:48:22 +0800 Subject: [PATCH 657/759] Update mfc_default_keys.dic Tidying up. forgot leave a blank comment line. Signed-off-by: weejhsteve <92703857+weejhsteve@users.noreply.github.com> --- client/dictionaries/mfc_default_keys.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index f3118f946..098cd3019 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -2028,5 +2028,6 @@ F72CD208FDF9 # # 1k - waldorf astoria 011C6CF459E8 +# # Food GEM 6686FADE5566 From 13e43b1eb5ac53b5c63d2dd52de56d3d7711a2e8 Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Fri, 3 Mar 2023 15:57:35 +0100 Subject: [PATCH 658/759] hf mfdes: Examples where using -s instead of --schann --- client/src/cmdhfmfdes.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 00c6306e7..cf6699180 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -2196,9 +2196,9 @@ static int CmdHF14ADesSetConfiguration(const char *Cmd) { "\n" "hf mfdes setconfig --param 03 --data 0428 -> set SAK\n" "hf mfdes setconfig --param 02 --data 0875778102637264 -> set ATS (first byte - length)\n" - "hf mfdes setconfig --isoid df01 -t aes -s ev2 --param 05 --data 00000000020000000000 -> set LRP mode enable for Desfire Light\n" - "hf mfdes setconfig --isoid df01 -t aes -s ev2 --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light\n" - "hf mfdes setconfig --isoid df01 -t aes -s lrp --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light via lrp"); + "hf mfdes setconfig --isoid df01 -t aes --schann ev2 --param 05 --data 00000000020000000000 -> set LRP mode enable for Desfire Light\n" + "hf mfdes setconfig --isoid df01 -t aes --schann ev2 --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light\n" + "hf mfdes setconfig --isoid df01 -t aes --schann lrp --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light via lrp"); void *argtable[] = { arg_param_begin, @@ -2305,7 +2305,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) { "but for APP keys crypto algorithm is set by createapp command and can't be changed wo application delete\n" "\n" "hf mfdes changekey --aid 123456 -> execute with default factory setup. change des key 0 in the app 123456 from 00..00 to 00..00\n" - "hf mfdes changekey --isoid df01 -t aes -s lrp --newkeyno 01 -> change key 01 via lrp channel" + "hf mfdes changekey --isoid df01 -t aes --schann lrp --newkeyno 01 -> change key 01 via lrp channel" "hf mfdes changekey -t des --newalgo aes --newkey 11223344556677889900112233445566 --newver a5 -> change card master key to AES one\n" "hf mfdes changekey --aid 123456 -t aes --key 00000000000000000000000000000000 --newkey 11223344556677889900112233445566 -> change app master key\n" "hf mfdes changekey --aid 123456 -t des -n 0 --newkeyno 1 --oldkey 5555555555555555 --newkey 1122334455667788 -> change key 1 with auth from key 0\n" @@ -2706,7 +2706,7 @@ static int CmdHF14ADesGetUID(const char *Cmd) { CLIParserInit(&ctx, "hf mfdes getuid", "Get UID from card. Get the real UID if the random UID bit is on and get the same UID as in anticollision if not. Any card's key needs to be provided. ", "hf mfdes getuid -> execute with default factory setup\n" - "hf mfdes getuid --isoid df01 -t aes -s lrp -> for desfire lights default settings"); + "hf mfdes getuid --isoid df01 -t aes --schan lrp -> for desfire lights default settings"); void *argtable[] = { arg_param_begin, @@ -3375,7 +3375,7 @@ static int CmdHF14ADesGetFileISOIDs(const char *Cmd) { "hf mfdes getfileisoids --aid 123456 -> execute with defaults from `default` command\n" "hf mfdes getfileisoids -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 -> execute with default factory setup\n" "hf mfdes getfileisoids --isoid df01 -> get iso file ids from Desfire Light with factory card settings\n" - "hf mfdes getfileisoids --isoid df01 -s lrp -t aes -> get iso file ids from Desfire Light via lrp channel with default key authentication"); + "hf mfdes getfileisoids --isoid df01 --schann lrp -t aes -> get iso file ids from Desfire Light via lrp channel with default key authentication"); void *argtable[] = { arg_param_begin, @@ -3618,7 +3618,7 @@ static int CmdHF14ADesChFileSettings(const char *Cmd) { "hf mfdes chfilesettings --aid 123456 --fid 01 --amode plain --rrights free --wrights free --rwrights free --chrights key0 -> change file settings app=123456, file=01 with defaults from `default` command\n" "hf mfdes chfilesettings -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 --rawdata 00EEEE -> execute with default factory setup\n" "hf mfdes chfilesettings --aid 123456 --fid 01 --rawdata 810000021f112f22 -> change file settings with additional rights for keys 1 and 2\n" - "hf mfdes chfilesettings --isoid df01 --fid 00 --amode plain --rawrights eee0 -s lrp -t aes -> change file settings via lrp channel"); + "hf mfdes chfilesettings --isoid df01 --fid 00 --amode plain --rawrights eee0 --schann lrp -t aes -> change file settings via lrp channel"); void *argtable[] = { arg_param_begin, @@ -4143,8 +4143,8 @@ static int CmdHF14ADesCreateTrMACFile(const char *Cmd) { "hf mfdes createmacfile --aid 123456 --fid 01 --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file with parameters. Rights from default. Authentication with defaults from `default` command\n" "hf mfdes createmacfile --aid 123456 --fid 01 --amode plain --rrights free --wrights deny --rwrights free --chrights key0 --mackey 00112233445566778899aabbccddeeff -> create file app=123456, file=01, with key, and mentioned rights with defaults from `default` command\n" "hf mfdes createmacfile -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> execute with default factory setup. key and keyver == 0x00..00\n" - "hf mfdes createmacfile --isoid df01 --fid 0f -s lrp -t aes --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel\n" - "hf mfdes createmacfile --isoid df01 --fid 0f -s lrp -t aes --rawrights 0F10 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel with CommitReaderID command enable"); + "hf mfdes createmacfile --isoid df01 --fid 0f --schann lrp -t aes --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel\n" + "hf mfdes createmacfile --isoid df01 --fid 0f --schann lrp -t aes --rawrights 0F10 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel with CommitReaderID command enable"); void *argtable[] = { arg_param_begin, @@ -4261,7 +4261,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) { CLIParserInit(&ctx, "hf mfdes deletefile", "Delete file from application. Master key needs to be provided or flag --no-auth set (depend on cards settings).", "hf mfdes deletefile --aid 123456 --fid 01 -> delete file for: app=123456, file=01 with defaults from `default` command\n" - "hf mfdes deletefile --isoid df01 --fid 0f -s lrp -t aes -> delete file for lrp channel"); + "hf mfdes deletefile --isoid df01 --fid 0f --schann lrp -t aes -> delete file for lrp channel"); void *argtable[] = { arg_param_begin, @@ -4338,8 +4338,8 @@ static int CmdHF14ADesValueOperations(const char *Cmd) { "hf mfdes value --aid 123456 --fid 01 -> get value app=123456, file=01 with defaults from `default` command\n" "hf mfdes value --aid 123456 --fid 01 --op credit -d 00000001 -> credit value app=123456, file=01 with defaults from `default` command\n" "hf mfdes value -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> get value with default factory setup\n" - "hf mfdes val --isoid df01 --fid 03 -s lrp -t aes -n 1 --op credit --d 00000001 -m encrypt -> credit value in the lrp encrypted mode\n" - "hf mfdes val --isoid df01 --fid 03 -s lrp -t aes -n 1 --op get -m plain -> get value in plain (nevertheless of mode) works for desfire light (look SetConfiguration option 0x09)"); + "hf mfdes val --isoid df01 --fid 03 --schann lrp -t aes -n 1 --op credit --d 00000001 -m encrypt -> credit value in the lrp encrypted mode\n" + "hf mfdes val --isoid df01 --fid 03 --schann lrp -t aes -n 1 --op get -m plain -> get value in plain (nevertheless of mode) works for desfire light (look SetConfiguration option 0x09)"); void *argtable[] = { arg_param_begin, @@ -4511,7 +4511,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) { CLIParserInit(&ctx, "hf mfdes clearrecfile", "Clear record file. Master key needs to be provided or flag --no-auth set (depend on cards settings).", "hf mfdes clearrecfile --aid 123456 --fid 01 -> clear record file for: app=123456, file=01 with defaults from `default` command\n" - "hf mfdes clearrecfile --isoid df01 --fid 01 -s lrp -t aes -n 3 -> clear record file for lrp channel with key number 3"); + "hf mfdes clearrecfile --isoid df01 --fid 01 --schann lrp -t aes -n 3 -> clear record file for lrp channel with key number 3"); void *argtable[] = { arg_param_begin, @@ -4910,8 +4910,8 @@ static int CmdHF14ADesReadData(const char *Cmd) { "hf mfdes read --isoid 0102 --fileisoid 1000 --type data -c iso -> read file via ISO channel: app iso id=0102, iso id=1000, offset=0. Select via ISO commands\n" "hf mfdes read --isoid 0102 --fileisoid 1100 --type record -c iso --offset 000005 --length 000001 -> get one record (number 5) from file 1100 via iso commands\n" "hf mfdes read --isoid 0102 --fileisoid 1100 --type record -c iso --offset 000005 --length 000000 -> get all record (from 5 to 1) from file 1100 via iso commands\n" - "hf mfdes read --isoid df01 --fid 00 -s lrp -t aes --length 000010 -> read via lrp channel\n" - "hf mfdes read --isoid df01 --fid 00 -s ev2 -t aes --length 000010 --isochain -> read Desfire Light via ev2 channel"); + "hf mfdes read --isoid df01 --fid 00 --schann lrp -t aes --length 000010 -> read via lrp channel\n" + "hf mfdes read --isoid df01 --fid 00 --schann ev2 -t aes --length 000010 --isochain -> read Desfire Light via ev2 channel"); void *argtable[] = { arg_param_begin, @@ -5082,7 +5082,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) { "hf mfdes write --isoid 1234 --fileisoid 1000 --type data -c iso -d 01020304 -> write data to std/backup file via iso commandset\n" "hf mfdes write --isoid 1234 --fileisoid 2000 --type record -c iso -d 01020304 -> send record to record file via iso commandset\n" "hf mfdes write --aid 123456 --fid 01 -d 01020304 --readerid 010203 -> write data to file with CommitReaderID command before write and CommitTransaction after write\n" - "hf mfdes write --isoid df01 --fid 04 -d 01020304 --trkey 00112233445566778899aabbccddeeff --readerid 5532 -t aes -s lrp -> advanced CommitReaderID via lrp channel sample"); + "hf mfdes write --isoid df01 --fid 04 -d 01020304 --trkey 00112233445566778899aabbccddeeff --readerid 5532 -t aes --schann lrp -> advanced CommitReaderID via lrp channel sample"); void *argtable[] = { arg_param_begin, @@ -5560,7 +5560,7 @@ static int CmdHF14ADesDump(const char *Cmd) { CLIParserInit(&ctx, "hf mfdes dump", "For each application show fil list and then file content. Key needs to be provided for authentication or flag --no-auth set (depend on cards settings).", "hf mfdes dump --aid 123456 -> show file dump for: app=123456 with channel defaults from `default` command/n" - "hf mfdes dump --isoid df01 -s lrp -t aes --length 000090 -> lrp default settings with length limit"); + "hf mfdes dump --isoid df01 --schann lrp -t aes --length 000090 -> lrp default settings with length limit"); void *argtable[] = { arg_param_begin, From d319b0dee34a1fa8b902176fde04379b791032f0 Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Fri, 3 Mar 2023 16:03:30 +0100 Subject: [PATCH 659/759] hf mfdes: Use hex in error message, consistent with cmdline --- client/src/cmdhfmfdes.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index cf6699180..2f45b5165 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -4307,7 +4307,7 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) { CLIParserFree(ctx); if (fnum > 0x1F) { - PrintAndLogEx(ERR, "File number range is invalid (exp 0 - 31), got %d", fnum); + PrintAndLogEx(ERR, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum); return PM3_EINVARG; } @@ -4557,7 +4557,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) { CLIParserFree(ctx); if (fnum > 0x1F) { - PrintAndLogEx(ERR, "File number range is invalid (exp 0 - 31), got %d", fnum); + PrintAndLogEx(ERR, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum); return PM3_EINVARG; } @@ -4989,7 +4989,7 @@ static int CmdHF14ADesReadData(const char *Cmd) { CLIParserFree(ctx); if (fnum > 0x1F) { - PrintAndLogEx(ERR, "File number range is invalid (exp 0 - 31), got %d", fnum); + PrintAndLogEx(ERR, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum); return PM3_EINVARG; } @@ -5188,7 +5188,7 @@ static int CmdHF14ADesWriteData(const char *Cmd) { CLIParserFree(ctx); if (fnum > 0x1F) { - PrintAndLogEx(ERR, "File number range is invalid (exp 0 - 31), got %d", fnum); + PrintAndLogEx(ERR, "File number range is invalid (exp 0x00 - 0x1f), got 0x%02x", fnum); return PM3_EINVARG; } From fc4e912fc1d42e13a8f858072ee7b2513ed84d4b Mon Sep 17 00:00:00 2001 From: DidierA <1620015+DidierA@users.noreply.github.com> Date: Fri, 3 Mar 2023 17:33:38 +0100 Subject: [PATCH 660/759] MifareFesFireGetInformation(): warningw when tag answer is too short --- armsrc/mifaredesfire.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index 3530dfd9b..04de05f21 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -182,6 +182,12 @@ void MifareDesfireGetInformation(void) { return; } + if (len < sizeof(payload.versionHW)+1) { + Dbprintf("Tag answer to MFDES_GET_VERSION was too short: data in Hardware Information is probably invalid."); + print_result("Answer", resp, len); + memset(resp+len, 0xFF, sizeof(payload.versionHW)+1 - len); // clear remaining bytes + } + memcpy(payload.versionHW, resp + 1, sizeof(payload.versionHW)); // ADDITION_FRAME 1 @@ -194,6 +200,13 @@ void MifareDesfireGetInformation(void) { switch_off(); return; } + + if (len < sizeof(payload.versionSW)+1) { + Dbprintf("Tag answer to MFDES_ADDITIONAL_FRAME 1 was too short: data in Software Information is probably invalid."); + print_result("Answer", resp, len); + memset(resp+len, 0xFF, sizeof(payload.versionSW)+1 - len); // clear remaining bytes + } + memcpy(payload.versionSW, resp + 1, sizeof(payload.versionSW)); // ADDITION_FRAME 2 @@ -206,6 +219,12 @@ void MifareDesfireGetInformation(void) { return; } + if (len < sizeof(payload.details)+1) { + Dbprintf("Tag answer to MFDES_ADDITIONAL_FRAME 2 was too short: data in Batch number and Production date is probably invalid"); + print_result("Answer", resp, len); + memset(resp+len, 0xFF, sizeof(payload.details)+1 - len); // clear remaining bytes + } + memcpy(payload.details, resp + 1, sizeof(payload.details)); LED_B_ON(); From 3444b5e38a431c1a7574d23e7ac8887c154947f7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 10:23:55 +0100 Subject: [PATCH 661/759] text --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c49a7c08e..b9f26516a 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] + - Fixed `hf mfdes info`- now handles incorrect tag answers better (@didiera) + - Fixed `hf mfdes` generic help text is now correct (@didiera) - Fixed `pm3` script to correctly identify WSL enabled distros (@henrygab) - Changed device enumeration with "unique USB serial numbers when built with `FLASH` -- **_UPDATES BOOTROM ALSO_**" (@henrygab) - Changed the readline package to v8.2 in the CMAKE files for the client (@iceman1001) From f424667d0c00e3da4570754ae8922a6eb799783c Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Sat, 4 Mar 2023 10:40:19 -0700 Subject: [PATCH 662/759] Fix syntax --- client/src/cmdlfhid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index 19c7a3ea0..d04de6cda 100755 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -488,7 +488,7 @@ static int CmdHIDBrute(const char *Cmd) { arg_param_begin, arg_lit0("v", "verbose", "verbose output"), arg_str1("w", "wiegand", "", "see " _YELLOW_("`wiegand list`") " for available formats"), - arg_str1(NULL, "field", "", "field to bruteforce. can be _YELLOW("`fc`") for facility code, or _YELLOW("`cn`") for card number"), + arg_str1(NULL, "field", "", "field to bruteforce. can be " _YELLOW("`fc`") " for facility code, or " _YELLOW("`cn`") " for card number"), arg_u64_0(NULL, "fc", "", "facility code"), arg_u64_0(NULL, "cn", "", "card number"), arg_u64_0("i", "issue", "", "issue level"), From 060f452530a038232b9baf69f6fbc90949ce0f22 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 20:03:53 +0100 Subject: [PATCH 663/759] fix text --- client/src/cmdlfhid.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index d04de6cda..f98ebb16d 100755 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -488,14 +488,14 @@ static int CmdHIDBrute(const char *Cmd) { arg_param_begin, arg_lit0("v", "verbose", "verbose output"), arg_str1("w", "wiegand", "", "see " _YELLOW_("`wiegand list`") " for available formats"), - arg_str1(NULL, "field", "", "field to bruteforce. can be " _YELLOW("`fc`") " for facility code, or " _YELLOW("`cn`") " for card number"), + arg_str1(NULL, "field", "", "field to bruteforce"), arg_u64_0(NULL, "fc", "", "facility code"), arg_u64_0(NULL, "cn", "", "card number"), arg_u64_0("i", "issue", "", "issue level"), arg_u64_0("o", "oem", "", "OEM code"), - arg_u64_0("d", "delay", "", "delay betweens attempts in ms. (default is 1000)"), - arg_lit0(NULL, "up", "direction to increment field value. (default is both directions)"), - arg_lit0(NULL, "down", "direction to decrement field value. (default is both directions)"), + arg_u64_0("d", "delay", "", "delay betweens attempts in ms. (def is 1000)"), + arg_lit0(NULL, "up", "direction to increment field value. (def is both directions)"), + arg_lit0(NULL, "down", "direction to decrement field value. (def is both directions)"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); From 8f20eed914997fa5071f4f8801f117face61965a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 20:10:46 +0100 Subject: [PATCH 664/759] fix CID #405232 --- client/src/cmdlfem4x05.c | 3 +- client/src/cmdlfguard.c | 18 +- client/src/cmdlfhid.c | 6 +- client/src/pm3line_vocabulory.h | 1504 ++++++++++++------------- common_arm/flashmem.c | 4 +- tools/mfd_aes_brute/mfd_aes_brute.c | 2 +- tools/mfd_aes_brute/mfd_multi_brute.c | 2 +- 7 files changed, 770 insertions(+), 769 deletions(-) diff --git a/client/src/cmdlfem4x05.c b/client/src/cmdlfem4x05.c index cff7203d2..c21540f45 100644 --- a/client/src/cmdlfem4x05.c +++ b/client/src/cmdlfem4x05.c @@ -1265,7 +1265,8 @@ int CmdEM4x05Info(const char *Cmd) { // read word 1 (serial #) doesn't need pwd // continue if failed, .. non blocking fail. - em4x05_read_word_ext(EM_SERIAL_BLOCK, 0, false, &serial); + int res = em4x05_read_word_ext(EM_SERIAL_BLOCK, 0, false, &serial); + (void)res; printEM4x05info(block0, serial); diff --git a/client/src/cmdlfguard.c b/client/src/cmdlfguard.c index c31629c5a..d39cff47c 100644 --- a/client/src/cmdlfguard.c +++ b/client/src/cmdlfguard.c @@ -163,12 +163,12 @@ int demodGuard(bool verbose) { bool unknown = false; switch (fmtLen) { case 36: - PrintAndLogEx(DEBUG, "DEBUG: FC 1: %x", (plain[3] & 0x7F) << 7); - PrintAndLogEx(DEBUG, "DEBUG: FC 2: %x", plain[4] >> 1); - PrintAndLogEx(DEBUG, "DEBUG: Card 1: %x", (plain[4] & 1) << 19); - PrintAndLogEx(DEBUG, "DEBUG: Card 2: %x", plain[5] << 11); - PrintAndLogEx(DEBUG, "DEBUG: Card 3: %x", plain[6] << 3); - PrintAndLogEx(DEBUG, "DEBUG: Card 4: %x", (plain[7] & 0xE0) >> 5); + PrintAndLogEx(DEBUG, "DEBUG: FC 1: %x", (plain[3] & 0x7F) << 7); + PrintAndLogEx(DEBUG, "DEBUG: FC 2: %x", plain[4] >> 1); + PrintAndLogEx(DEBUG, "DEBUG: Card 1: %x", (plain[4] & 1) << 19); + PrintAndLogEx(DEBUG, "DEBUG: Card 2: %x", plain[5] << 11); + PrintAndLogEx(DEBUG, "DEBUG: Card 3: %x", plain[6] << 3); + PrintAndLogEx(DEBUG, "DEBUG: Card 4: %x", (plain[7] & 0xE0) >> 5); FC = ((plain[3] & 0x7F) << 7) | (plain[4] >> 1); Card = ((plain[4] & 1) << 19) | (plain[5] << 11) | (plain[6] << 3) | ((plain[7] & 0xE0) >> 5); break; @@ -271,7 +271,7 @@ static int CmdGuardClone(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, false); - uint32_t xorval = arg_get_u32_def(ctx, 1, 0); + uint32_t xorval = arg_get_u32_def(ctx, 1, 0); uint32_t fmtlen = arg_get_u32_def(ctx, 2, 0); uint32_t fc = arg_get_u32_def(ctx, 3, 0); uint32_t cn = arg_get_u32_def(ctx, 4, 0); @@ -357,7 +357,7 @@ static int CmdGuardSim(const char *Cmd) { }; CLIExecWithReturn(ctx, Cmd, argtable, false); - uint32_t xorval = arg_get_u32_def(ctx, 1, 0); + uint32_t xorval = arg_get_u32_def(ctx, 1, 0); uint32_t fmtlen = arg_get_u32_def(ctx, 2, 0); uint32_t fc = arg_get_u32_def(ctx, 3, 0); uint32_t cn = arg_get_u32_def(ctx, 4, 0); @@ -376,7 +376,7 @@ static int CmdGuardSim(const char *Cmd) { } PrintAndLogEx(SUCCESS, "Simulating Guardall Prox - xorKey: " _YELLOW_("%u") " Facility Code: " _YELLOW_("%u") " CardNumber: " _YELLOW_("%u") - , xorval + , xorval , facilitycode , cardnumber ); diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index f98ebb16d..d197a6dcb 100755 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -488,7 +488,7 @@ static int CmdHIDBrute(const char *Cmd) { arg_param_begin, arg_lit0("v", "verbose", "verbose output"), arg_str1("w", "wiegand", "", "see " _YELLOW_("`wiegand list`") " for available formats"), - arg_str1(NULL, "field", "", "field to bruteforce"), + arg_str1(NULL, "field", "", "field to bruteforce"), arg_u64_0(NULL, "fc", "", "facility code"), arg_u64_0(NULL, "cn", "", "card number"), arg_u64_0("i", "issue", "", "issue level"), @@ -515,7 +515,7 @@ static int CmdHIDBrute(const char *Cmd) { wiegand_card_t card_hi, card_low; memset(&card_hi, 0, sizeof(wiegand_card_t)); - + char field[3] = {0}; int field_len = 0; CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)field, sizeof(field), &field_len); @@ -587,7 +587,7 @@ static int CmdHIDBrute(const char *Cmd) { return sendPing(); } - // do one up + // do one up if (direction != 2 && fin_hi != true) { if (sendTry(format_idx, &card_hi, delay, verbose) != PM3_SUCCESS) { return PM3_ESOFT; diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 8e775bd3e..2b42cf4fd 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -31,758 +31,758 @@ typedef struct vocabulory_s { } vocabulory_t; const static vocabulory_t vocabulory[] = { - { 1, "help" }, - { 0, "auto" }, - { 1, "clear" }, - { 1, "hints" }, - { 1, "msleep" }, - { 1, "rem" }, - { 1, "quit" }, - { 1, "exit" }, - { 1, "prefs help" }, - { 1, "prefs show" }, - { 1, "prefs get barmode" }, - { 1, "prefs get clientdebug" }, - { 1, "prefs get clientdelay" }, - { 1, "prefs get color" }, - { 1, "prefs get savepaths" }, - { 1, "prefs get emoji" }, - { 1, "prefs get hints" }, - { 1, "prefs get output" }, - { 1, "prefs get plotsliders" }, - { 1, "prefs set help" }, - { 1, "prefs set barmode" }, - { 1, "prefs set clientdebug" }, - { 1, "prefs set clientdelay" }, - { 1, "prefs set color" }, - { 1, "prefs set emoji" }, - { 1, "prefs set hints" }, - { 1, "prefs set savepaths" }, - { 1, "prefs set output" }, - { 1, "prefs set plotsliders" }, - { 1, "analyse help" }, - { 1, "analyse lcr" }, - { 1, "analyse crc" }, - { 1, "analyse chksum" }, - { 1, "analyse dates" }, - { 1, "analyse lfsr" }, - { 1, "analyse a" }, - { 1, "analyse nuid" }, - { 1, "analyse demodbuff" }, - { 1, "analyse freq" }, - { 1, "analyse foo" }, - { 1, "analyse units" }, - { 1, "data help" }, - { 1, "data biphaserawdecode" }, - { 1, "data detectclock" }, - { 1, "data fsktonrz" }, - { 1, "data manrawdecode" }, - { 1, "data modulation" }, - { 1, "data rawdemod" }, - { 1, "data askedgedetect" }, - { 1, "data autocorr" }, - { 1, "data dirthreshold" }, - { 1, "data decimate" }, - { 1, "data undecimate" }, - { 1, "data hide" }, - { 1, "data hpf" }, - { 1, "data iir" }, - { 1, "data grid" }, - { 1, "data ltrim" }, - { 1, "data mtrim" }, - { 1, "data norm" }, - { 1, "data plot" }, - { 1, "data rtrim" }, - { 1, "data setgraphmarkers" }, - { 1, "data shiftgraphzero" }, - { 1, "data timescale" }, - { 1, "data zerocrossings" }, - { 1, "data convertbitstream" }, - { 1, "data getbitstream" }, - { 1, "data asn1" }, - { 1, "data bin2hex" }, - { 0, "data bitsamples" }, - { 1, "data clear" }, - { 1, "data diff" }, - { 0, "data hexsamples" }, - { 1, "data hex2bin" }, - { 1, "data load" }, - { 1, "data print" }, - { 0, "data samples" }, - { 1, "data save" }, - { 1, "data setdebugmode" }, - { 0, "data tune" }, - { 1, "emv help" }, - { 0, "emv exec" }, - { 0, "emv pse" }, - { 0, "emv search" }, - { 0, "emv select" }, - { 0, "emv gpo" }, - { 0, "emv readrec" }, - { 0, "emv genac" }, - { 0, "emv challenge" }, - { 0, "emv intauth" }, - { 0, "emv scan" }, - { 1, "emv test" }, - { 1, "emv list" }, - { 0, "emv roca" }, - { 1, "hf help" }, - { 1, "hf list" }, - { 0, "hf plot" }, - { 0, "hf tune" }, - { 1, "hf search" }, - { 0, "hf sniff" }, - { 1, "hf 14a help" }, - { 1, "hf 14a list" }, - { 0, "hf 14a antifuzz" }, - { 0, "hf 14a config" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a info" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a raw" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a apdufind" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a ndefformat" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a ndefwrite" }, - { 1, "hf 14b help" }, - { 0, "hf 14b apdu" }, - { 0, "hf 14b dump" }, - { 0, "hf 14b info" }, - { 1, "hf 14b list" }, - { 0, "hf 14b ndefread" }, - { 0, "hf 14b raw" }, - { 0, "hf 14b reader" }, - { 0, "hf 14b sim" }, - { 0, "hf 14b sniff" }, - { 0, "hf 14b rdbl" }, - { 0, "hf 14b sriwrite" }, - { 1, "hf 14b view" }, - { 1, "hf 15 help" }, - { 1, "hf 15 list" }, - { 1, "hf 15 demod" }, - { 0, "hf 15 dump" }, - { 0, "hf 15 info" }, - { 0, "hf 15 sniff" }, - { 0, "hf 15 raw" }, - { 0, "hf 15 rdbl" }, - { 0, "hf 15 rdmulti" }, - { 0, "hf 15 reader" }, - { 0, "hf 15 restore" }, - { 0, "hf 15 samples" }, - { 0, "hf 15 eload" }, - { 0, "hf 15 esave" }, - { 0, "hf 15 eview" }, - { 0, "hf 15 sim" }, - { 0, "hf 15 slixwritepwd" }, - { 0, "hf 15 slixeasdisable" }, - { 0, "hf 15 slixeasenable" }, - { 0, "hf 15 slixprivacydisable" }, - { 0, "hf 15 slixprivacyenable" }, - { 0, "hf 15 passprotectafi" }, - { 0, "hf 15 passprotecteas" }, - { 0, "hf 15 wrbl" }, - { 0, "hf 15 findafi" }, - { 0, "hf 15 writeafi" }, - { 0, "hf 15 writedsfid" }, - { 0, "hf 15 csetuid" }, - { 1, "hf cipurse help" }, - { 0, "hf cipurse info" }, - { 0, "hf cipurse select" }, - { 0, "hf cipurse auth" }, - { 0, "hf cipurse read" }, - { 0, "hf cipurse write" }, - { 0, "hf cipurse aread" }, - { 0, "hf cipurse awrite" }, - { 0, "hf cipurse formatall" }, - { 0, "hf cipurse create" }, - { 0, "hf cipurse delete" }, - { 0, "hf cipurse updkey" }, - { 0, "hf cipurse updakey" }, - { 0, "hf cipurse default" }, - { 1, "hf cipurse test" }, - { 1, "hf epa help" }, - { 0, "hf epa cnonces" }, - { 0, "hf epa replay" }, - { 0, "hf epa sim" }, - { 1, "hf emrtd help" }, - { 0, "hf emrtd dump" }, - { 1, "hf emrtd info" }, - { 1, "hf emrtd list" }, - { 1, "hf felica help" }, - { 1, "hf felica list" }, - { 0, "hf felica reader" }, - { 0, "hf felica info" }, - { 0, "hf felica sniff" }, - { 0, "hf felica raw" }, - { 0, "hf felica rdbl" }, - { 0, "hf felica wrbl" }, - { 0, "hf felica rqservice" }, - { 0, "hf felica rqresponse" }, - { 0, "hf felica scsvcode" }, - { 0, "hf felica rqsyscode" }, - { 0, "hf felica auth1" }, - { 0, "hf felica auth2" }, - { 0, "hf felica rqspecver" }, - { 0, "hf felica resetmode" }, - { 0, "hf felica litesim" }, - { 0, "hf felica litedump" }, - { 1, "hf fido help" }, - { 1, "hf fido list" }, - { 0, "hf fido info" }, - { 0, "hf fido reg" }, - { 0, "hf fido auth" }, - { 0, "hf fido make" }, - { 0, "hf fido assert" }, - { 1, "hf fudan help" }, - { 0, "hf fudan reader" }, - { 0, "hf fudan dump" }, - { 0, "hf fudan rdbl" }, - { 1, "hf fudan view" }, - { 0, "hf fudan wrbl" }, - { 1, "hf gallagher help" }, - { 0, "hf gallagher reader" }, - { 0, "hf gallagher clone" }, - { 0, "hf gallagher delete" }, - { 1, "hf gallagher diversifykey" }, - { 1, "hf gallagher decode" }, - { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 select" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 init" }, - { 0, "hf ksx6924 prec" }, - { 1, "hf jooki help" }, - { 0, "hf jooki clone" }, - { 1, "hf jooki decode" }, - { 1, "hf jooki encode" }, - { 0, "hf jooki sim" }, - { 1, "hf iclass help" }, - { 0, "hf iclass dump" }, - { 1, "hf iclass info" }, - { 1, "hf iclass list" }, - { 0, "hf iclass rdbl" }, - { 0, "hf iclass reader" }, - { 0, "hf iclass restore" }, - { 0, "hf iclass sniff" }, - { 0, "hf iclass wrbl" }, - { 0, "hf iclass chk" }, - { 1, "hf iclass loclass" }, - { 1, "hf iclass lookup" }, - { 0, "hf iclass sim" }, - { 0, "hf iclass eload" }, - { 0, "hf iclass esave" }, - { 0, "hf iclass eview" }, - { 1, "hf iclass configcard" }, - { 1, "hf iclass calcnewkey" }, - { 1, "hf iclass encode" }, - { 1, "hf iclass encrypt" }, - { 1, "hf iclass decrypt" }, - { 1, "hf iclass managekeys" }, - { 1, "hf iclass permutekey" }, - { 1, "hf iclass view" }, - { 1, "hf legic help" }, - { 0, "hf legic dump" }, - { 0, "hf legic info" }, - { 1, "hf legic list" }, - { 0, "hf legic rdbl" }, - { 0, "hf legic reader" }, - { 0, "hf legic restore" }, - { 0, "hf legic wipe" }, - { 0, "hf legic wrbl" }, - { 0, "hf legic sim" }, - { 0, "hf legic eload" }, - { 0, "hf legic esave" }, - { 0, "hf legic eview" }, - { 1, "hf legic crc" }, - { 1, "hf legic view" }, - { 1, "hf lto help" }, - { 0, "hf lto dump" }, - { 0, "hf lto info" }, - { 1, "hf lto list" }, - { 0, "hf lto rdbl" }, - { 0, "hf lto reader" }, - { 0, "hf lto restore" }, - { 0, "hf lto wrbl" }, - { 1, "hf mf help" }, - { 1, "hf mf list" }, - { 0, "hf mf darkside" }, - { 0, "hf mf nested" }, - { 1, "hf mf hardnested" }, - { 0, "hf mf staticnested" }, - { 0, "hf mf autopwn" }, - { 0, "hf mf nack" }, - { 0, "hf mf chk" }, - { 0, "hf mf fchk" }, - { 1, "hf mf decrypt" }, - { 0, "hf mf supercard" }, - { 0, "hf mf auth4" }, - { 1, "hf mf acl" }, - { 0, "hf mf dump" }, - { 1, "hf mf mad" }, - { 0, "hf mf personalize" }, - { 0, "hf mf rdbl" }, - { 0, "hf mf rdsc" }, - { 0, "hf mf restore" }, - { 0, "hf mf setmod" }, - { 1, "hf mf value" }, - { 1, "hf mf view" }, - { 0, "hf mf wipe" }, - { 0, "hf mf wrbl" }, - { 0, "hf mf sim" }, - { 0, "hf mf ecfill" }, - { 0, "hf mf eclr" }, - { 0, "hf mf egetblk" }, - { 0, "hf mf egetsc" }, - { 0, "hf mf ekeyprn" }, - { 0, "hf mf eload" }, - { 0, "hf mf esave" }, - { 0, "hf mf esetblk" }, - { 0, "hf mf eview" }, - { 0, "hf mf cgetblk" }, - { 0, "hf mf cgetsc" }, - { 0, "hf mf cload" }, - { 0, "hf mf csave" }, - { 0, "hf mf csetblk" }, - { 0, "hf mf csetuid" }, - { 0, "hf mf cview" }, - { 0, "hf mf cwipe" }, - { 0, "hf mf gen3uid" }, - { 0, "hf mf gen3blk" }, - { 0, "hf mf gen3freeze" }, - { 0, "hf mf ggetblk" }, - { 0, "hf mf gload" }, - { 0, "hf mf gsave" }, - { 0, "hf mf gsetblk" }, - { 0, "hf mf gview" }, - { 0, "hf mf ndefformat" }, - { 0, "hf mf ndefread" }, - { 0, "hf mf ndefwrite" }, - { 1, "hf mfp help" }, - { 0, "hf mfp info" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp commitp" }, - { 0, "hf mfp auth" }, - { 0, "hf mfp rdbl" }, - { 0, "hf mfp rdsc" }, - { 0, "hf mfp wrbl" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp mad" }, - { 0, "hf mfp ndefread" }, - { 1, "hf mfu help" }, - { 1, "hf mfu keygen" }, - { 1, "hf mfu pwdgen" }, - { 0, "hf mfu otptear" }, - { 0, "hf mfu cauth" }, - { 0, "hf mfu dump" }, - { 0, "hf mfu info" }, - { 0, "hf mfu ndefread" }, - { 0, "hf mfu rdbl" }, - { 0, "hf mfu restore" }, - { 1, "hf mfu view" }, + { 1, "help" }, + { 0, "auto" }, + { 1, "clear" }, + { 1, "hints" }, + { 1, "msleep" }, + { 1, "rem" }, + { 1, "quit" }, + { 1, "exit" }, + { 1, "prefs help" }, + { 1, "prefs show" }, + { 1, "prefs get barmode" }, + { 1, "prefs get clientdebug" }, + { 1, "prefs get clientdelay" }, + { 1, "prefs get color" }, + { 1, "prefs get savepaths" }, + { 1, "prefs get emoji" }, + { 1, "prefs get hints" }, + { 1, "prefs get output" }, + { 1, "prefs get plotsliders" }, + { 1, "prefs set help" }, + { 1, "prefs set barmode" }, + { 1, "prefs set clientdebug" }, + { 1, "prefs set clientdelay" }, + { 1, "prefs set color" }, + { 1, "prefs set emoji" }, + { 1, "prefs set hints" }, + { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, + { 1, "prefs set plotsliders" }, + { 1, "analyse help" }, + { 1, "analyse lcr" }, + { 1, "analyse crc" }, + { 1, "analyse chksum" }, + { 1, "analyse dates" }, + { 1, "analyse lfsr" }, + { 1, "analyse a" }, + { 1, "analyse nuid" }, + { 1, "analyse demodbuff" }, + { 1, "analyse freq" }, + { 1, "analyse foo" }, + { 1, "analyse units" }, + { 1, "data help" }, + { 1, "data biphaserawdecode" }, + { 1, "data detectclock" }, + { 1, "data fsktonrz" }, + { 1, "data manrawdecode" }, + { 1, "data modulation" }, + { 1, "data rawdemod" }, + { 1, "data askedgedetect" }, + { 1, "data autocorr" }, + { 1, "data dirthreshold" }, + { 1, "data decimate" }, + { 1, "data undecimate" }, + { 1, "data hide" }, + { 1, "data hpf" }, + { 1, "data iir" }, + { 1, "data grid" }, + { 1, "data ltrim" }, + { 1, "data mtrim" }, + { 1, "data norm" }, + { 1, "data plot" }, + { 1, "data rtrim" }, + { 1, "data setgraphmarkers" }, + { 1, "data shiftgraphzero" }, + { 1, "data timescale" }, + { 1, "data zerocrossings" }, + { 1, "data convertbitstream" }, + { 1, "data getbitstream" }, + { 1, "data asn1" }, + { 1, "data bin2hex" }, + { 0, "data bitsamples" }, + { 1, "data clear" }, + { 1, "data diff" }, + { 0, "data hexsamples" }, + { 1, "data hex2bin" }, + { 1, "data load" }, + { 1, "data print" }, + { 0, "data samples" }, + { 1, "data save" }, + { 1, "data setdebugmode" }, + { 0, "data tune" }, + { 1, "emv help" }, + { 0, "emv exec" }, + { 0, "emv pse" }, + { 0, "emv search" }, + { 0, "emv select" }, + { 0, "emv gpo" }, + { 0, "emv readrec" }, + { 0, "emv genac" }, + { 0, "emv challenge" }, + { 0, "emv intauth" }, + { 0, "emv scan" }, + { 1, "emv test" }, + { 1, "emv list" }, + { 0, "emv roca" }, + { 1, "hf help" }, + { 1, "hf list" }, + { 0, "hf plot" }, + { 0, "hf tune" }, + { 1, "hf search" }, + { 0, "hf sniff" }, + { 1, "hf 14a help" }, + { 1, "hf 14a list" }, + { 0, "hf 14a antifuzz" }, + { 0, "hf 14a config" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a info" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a apdu" }, + { 0, "hf 14a apdufind" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a ndefformat" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a ndefwrite" }, + { 1, "hf 14b help" }, + { 0, "hf 14b apdu" }, + { 0, "hf 14b dump" }, + { 0, "hf 14b info" }, + { 1, "hf 14b list" }, + { 0, "hf 14b ndefread" }, + { 0, "hf 14b raw" }, + { 0, "hf 14b reader" }, + { 0, "hf 14b sim" }, + { 0, "hf 14b sniff" }, + { 0, "hf 14b rdbl" }, + { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, + { 1, "hf 15 help" }, + { 1, "hf 15 list" }, + { 1, "hf 15 demod" }, + { 0, "hf 15 dump" }, + { 0, "hf 15 info" }, + { 0, "hf 15 sniff" }, + { 0, "hf 15 raw" }, + { 0, "hf 15 rdbl" }, + { 0, "hf 15 rdmulti" }, + { 0, "hf 15 reader" }, + { 0, "hf 15 restore" }, + { 0, "hf 15 samples" }, + { 0, "hf 15 eload" }, + { 0, "hf 15 esave" }, + { 0, "hf 15 eview" }, + { 0, "hf 15 sim" }, + { 0, "hf 15 slixwritepwd" }, + { 0, "hf 15 slixeasdisable" }, + { 0, "hf 15 slixeasenable" }, + { 0, "hf 15 slixprivacydisable" }, + { 0, "hf 15 slixprivacyenable" }, + { 0, "hf 15 passprotectafi" }, + { 0, "hf 15 passprotecteas" }, + { 0, "hf 15 wrbl" }, + { 0, "hf 15 findafi" }, + { 0, "hf 15 writeafi" }, + { 0, "hf 15 writedsfid" }, + { 0, "hf 15 csetuid" }, + { 1, "hf cipurse help" }, + { 0, "hf cipurse info" }, + { 0, "hf cipurse select" }, + { 0, "hf cipurse auth" }, + { 0, "hf cipurse read" }, + { 0, "hf cipurse write" }, + { 0, "hf cipurse aread" }, + { 0, "hf cipurse awrite" }, + { 0, "hf cipurse formatall" }, + { 0, "hf cipurse create" }, + { 0, "hf cipurse delete" }, + { 0, "hf cipurse updkey" }, + { 0, "hf cipurse updakey" }, + { 0, "hf cipurse default" }, + { 1, "hf cipurse test" }, + { 1, "hf epa help" }, + { 0, "hf epa cnonces" }, + { 0, "hf epa replay" }, + { 0, "hf epa sim" }, + { 1, "hf emrtd help" }, + { 0, "hf emrtd dump" }, + { 1, "hf emrtd info" }, + { 1, "hf emrtd list" }, + { 1, "hf felica help" }, + { 1, "hf felica list" }, + { 0, "hf felica reader" }, + { 0, "hf felica info" }, + { 0, "hf felica sniff" }, + { 0, "hf felica raw" }, + { 0, "hf felica rdbl" }, + { 0, "hf felica wrbl" }, + { 0, "hf felica rqservice" }, + { 0, "hf felica rqresponse" }, + { 0, "hf felica scsvcode" }, + { 0, "hf felica rqsyscode" }, + { 0, "hf felica auth1" }, + { 0, "hf felica auth2" }, + { 0, "hf felica rqspecver" }, + { 0, "hf felica resetmode" }, + { 0, "hf felica litesim" }, + { 0, "hf felica litedump" }, + { 1, "hf fido help" }, + { 1, "hf fido list" }, + { 0, "hf fido info" }, + { 0, "hf fido reg" }, + { 0, "hf fido auth" }, + { 0, "hf fido make" }, + { 0, "hf fido assert" }, + { 1, "hf fudan help" }, + { 0, "hf fudan reader" }, + { 0, "hf fudan dump" }, + { 0, "hf fudan rdbl" }, + { 1, "hf fudan view" }, + { 0, "hf fudan wrbl" }, + { 1, "hf gallagher help" }, + { 0, "hf gallagher reader" }, + { 0, "hf gallagher clone" }, + { 0, "hf gallagher delete" }, + { 1, "hf gallagher diversifykey" }, + { 1, "hf gallagher decode" }, + { 1, "hf ksx6924 help" }, + { 0, "hf ksx6924 select" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 init" }, + { 0, "hf ksx6924 prec" }, + { 1, "hf jooki help" }, + { 0, "hf jooki clone" }, + { 1, "hf jooki decode" }, + { 1, "hf jooki encode" }, + { 0, "hf jooki sim" }, + { 1, "hf iclass help" }, + { 0, "hf iclass dump" }, + { 1, "hf iclass info" }, + { 1, "hf iclass list" }, + { 0, "hf iclass rdbl" }, + { 0, "hf iclass reader" }, + { 0, "hf iclass restore" }, + { 0, "hf iclass sniff" }, + { 0, "hf iclass wrbl" }, + { 0, "hf iclass chk" }, + { 1, "hf iclass loclass" }, + { 1, "hf iclass lookup" }, + { 0, "hf iclass sim" }, + { 0, "hf iclass eload" }, + { 0, "hf iclass esave" }, + { 0, "hf iclass eview" }, + { 1, "hf iclass configcard" }, + { 1, "hf iclass calcnewkey" }, + { 1, "hf iclass encode" }, + { 1, "hf iclass encrypt" }, + { 1, "hf iclass decrypt" }, + { 1, "hf iclass managekeys" }, + { 1, "hf iclass permutekey" }, + { 1, "hf iclass view" }, + { 1, "hf legic help" }, + { 0, "hf legic dump" }, + { 0, "hf legic info" }, + { 1, "hf legic list" }, + { 0, "hf legic rdbl" }, + { 0, "hf legic reader" }, + { 0, "hf legic restore" }, + { 0, "hf legic wipe" }, + { 0, "hf legic wrbl" }, + { 0, "hf legic sim" }, + { 0, "hf legic eload" }, + { 0, "hf legic esave" }, + { 0, "hf legic eview" }, + { 1, "hf legic crc" }, + { 1, "hf legic view" }, + { 1, "hf lto help" }, + { 0, "hf lto dump" }, + { 0, "hf lto info" }, + { 1, "hf lto list" }, + { 0, "hf lto rdbl" }, + { 0, "hf lto reader" }, + { 0, "hf lto restore" }, + { 0, "hf lto wrbl" }, + { 1, "hf mf help" }, + { 1, "hf mf list" }, + { 0, "hf mf darkside" }, + { 0, "hf mf nested" }, + { 1, "hf mf hardnested" }, + { 0, "hf mf staticnested" }, + { 0, "hf mf autopwn" }, + { 0, "hf mf nack" }, + { 0, "hf mf chk" }, + { 0, "hf mf fchk" }, + { 1, "hf mf decrypt" }, + { 0, "hf mf supercard" }, + { 0, "hf mf auth4" }, + { 1, "hf mf acl" }, + { 0, "hf mf dump" }, + { 1, "hf mf mad" }, + { 0, "hf mf personalize" }, + { 0, "hf mf rdbl" }, + { 0, "hf mf rdsc" }, + { 0, "hf mf restore" }, + { 0, "hf mf setmod" }, + { 1, "hf mf value" }, + { 1, "hf mf view" }, + { 0, "hf mf wipe" }, + { 0, "hf mf wrbl" }, + { 0, "hf mf sim" }, + { 0, "hf mf ecfill" }, + { 0, "hf mf eclr" }, + { 0, "hf mf egetblk" }, + { 0, "hf mf egetsc" }, + { 0, "hf mf ekeyprn" }, + { 0, "hf mf eload" }, + { 0, "hf mf esave" }, + { 0, "hf mf esetblk" }, + { 0, "hf mf eview" }, + { 0, "hf mf cgetblk" }, + { 0, "hf mf cgetsc" }, + { 0, "hf mf cload" }, + { 0, "hf mf csave" }, + { 0, "hf mf csetblk" }, + { 0, "hf mf csetuid" }, + { 0, "hf mf cview" }, + { 0, "hf mf cwipe" }, + { 0, "hf mf gen3uid" }, + { 0, "hf mf gen3blk" }, + { 0, "hf mf gen3freeze" }, + { 0, "hf mf ggetblk" }, + { 0, "hf mf gload" }, + { 0, "hf mf gsave" }, + { 0, "hf mf gsetblk" }, + { 0, "hf mf gview" }, + { 0, "hf mf ndefformat" }, + { 0, "hf mf ndefread" }, + { 0, "hf mf ndefwrite" }, + { 1, "hf mfp help" }, + { 0, "hf mfp info" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp auth" }, + { 0, "hf mfp rdbl" }, + { 0, "hf mfp rdsc" }, + { 0, "hf mfp wrbl" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp mad" }, + { 0, "hf mfp ndefread" }, + { 1, "hf mfu help" }, + { 1, "hf mfu keygen" }, + { 1, "hf mfu pwdgen" }, + { 0, "hf mfu otptear" }, + { 0, "hf mfu cauth" }, + { 0, "hf mfu dump" }, + { 0, "hf mfu info" }, + { 0, "hf mfu ndefread" }, + { 0, "hf mfu rdbl" }, + { 0, "hf mfu restore" }, + { 1, "hf mfu view" }, { 0, "hf mfu tamper" }, - { 0, "hf mfu wrbl" }, - { 0, "hf mfu eload" }, - { 0, "hf mfu esave" }, - { 0, "hf mfu eview" }, - { 0, "hf mfu sim" }, - { 0, "hf mfu setpwd" }, - { 0, "hf mfu setuid" }, - { 1, "hf mfdes help" }, - { 0, "hf mfdes info" }, - { 0, "hf mfdes getuid" }, - { 0, "hf mfdes default" }, - { 0, "hf mfdes auth" }, - { 0, "hf mfdes chk" }, - { 0, "hf mfdes detect" }, - { 0, "hf mfdes freemem" }, - { 0, "hf mfdes setconfig" }, - { 0, "hf mfdes formatpicc" }, - { 1, "hf mfdes list" }, - { 0, "hf mfdes mad" }, - { 0, "hf mfdes lsapp" }, - { 0, "hf mfdes getaids" }, - { 0, "hf mfdes getappnames" }, - { 0, "hf mfdes bruteaid" }, - { 0, "hf mfdes createapp" }, - { 0, "hf mfdes deleteapp" }, - { 0, "hf mfdes selectapp" }, - { 0, "hf mfdes changekey" }, - { 0, "hf mfdes chkeysettings" }, - { 0, "hf mfdes getkeysettings" }, - { 0, "hf mfdes getkeyversions" }, - { 0, "hf mfdes getfileids" }, - { 0, "hf mfdes getfileisoids" }, - { 0, "hf mfdes lsfiles" }, - { 0, "hf mfdes dump" }, - { 0, "hf mfdes createfile" }, - { 0, "hf mfdes createvaluefile" }, - { 0, "hf mfdes createrecordfile" }, - { 0, "hf mfdes createmacfile" }, - { 0, "hf mfdes deletefile" }, - { 0, "hf mfdes getfilesettings" }, - { 0, "hf mfdes chfilesettings" }, - { 0, "hf mfdes read" }, - { 0, "hf mfdes write" }, - { 0, "hf mfdes value" }, - { 0, "hf mfdes clearrecfile" }, - { 1, "hf mfdes test" }, - { 1, "hf ntag424 help" }, - { 0, "hf ntag424 info" }, - { 0, "hf ntag424 sdm" }, - { 1, "hf ntag424 view" }, - { 1, "hf seos help" }, - { 0, "hf seos info" }, - { 1, "hf seos list" }, - { 1, "hf st25ta help" }, - { 0, "hf st25ta info" }, - { 1, "hf st25ta list" }, - { 1, "hf st25ta ndefread" }, - { 0, "hf st25ta protect" }, - { 0, "hf st25ta pwd" }, - { 0, "hf st25ta sim" }, - { 1, "hf tesla help" }, - { 0, "hf tesla info" }, - { 1, "hf tesla list" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, - { 1, "hf thinfilm help" }, - { 0, "hf thinfilm info" }, - { 1, "hf thinfilm list" }, - { 0, "hf thinfilm sim" }, - { 1, "hf topaz help" }, - { 0, "hf topaz dump" }, - { 1, "hf topaz list" }, - { 0, "hf topaz info" }, - { 0, "hf topaz reader" }, - { 0, "hf topaz sim" }, - { 0, "hf topaz sniff" }, - { 0, "hf topaz raw" }, - { 0, "hf topaz rdbl" }, - { 1, "hf topaz view" }, - { 0, "hf topaz wrbl" }, - { 1, "hf xerox help" }, - { 0, "hf xerox info" }, - { 0, "hf xerox reader" }, - { 0, "hf xerox dump" }, - { 1, "hf waveshare help" }, - { 0, "hf waveshare loadbmp" }, - { 1, "hw help" }, - { 0, "hw break" }, - { 1, "hw connect" }, - { 0, "hw dbg" }, - { 0, "hw detectreader" }, - { 0, "hw fpgaoff" }, - { 0, "hw lcd" }, - { 0, "hw lcdreset" }, - { 0, "hw ping" }, - { 0, "hw readmem" }, - { 0, "hw reset" }, - { 0, "hw setlfdivisor" }, - { 0, "hw setmux" }, - { 0, "hw standalone" }, - { 0, "hw status" }, - { 0, "hw tearoff" }, - { 0, "hw tia" }, - { 0, "hw tune" }, - { 1, "hw version" }, - { 1, "lf help" }, - { 0, "lf config" }, - { 0, "lf cmdread" }, - { 0, "lf read" }, - { 1, "lf search" }, - { 0, "lf sim" }, - { 0, "lf simask" }, - { 0, "lf simfsk" }, - { 0, "lf simpsk" }, - { 0, "lf simbidir" }, - { 0, "lf sniff" }, - { 0, "lf tune" }, - { 1, "lf awid help" }, - { 1, "lf awid demod" }, - { 0, "lf awid reader" }, - { 0, "lf awid clone" }, - { 0, "lf awid sim" }, - { 0, "lf awid brute" }, - { 0, "lf awid watch" }, - { 1, "lf cotag help" }, - { 1, "lf cotag demod" }, - { 0, "lf cotag reader" }, - { 1, "lf destron help" }, - { 1, "lf destron demod" }, - { 0, "lf destron reader" }, - { 0, "lf destron clone" }, - { 0, "lf destron sim" }, - { 1, "lf em help" }, - { 1, "lf em 410x help" }, - { 1, "lf em 410x demod" }, - { 0, "lf em 410x reader" }, - { 0, "lf em 410x sim" }, - { 0, "lf em 410x brute" }, - { 0, "lf em 410x watch" }, - { 0, "lf em 410x spoof" }, - { 0, "lf em 410x clone" }, - { 1, "lf em 4x05 help" }, - { 0, "lf em 4x05 brute" }, - { 0, "lf em 4x05 chk" }, - { 1, "lf em 4x05 demod" }, - { 0, "lf em 4x05 dump" }, - { 0, "lf em 4x05 info" }, - { 0, "lf em 4x05 read" }, - { 1, "lf em 4x05 sniff" }, - { 0, "lf em 4x05 unlock" }, - { 0, "lf em 4x05 wipe" }, - { 0, "lf em 4x05 write" }, - { 1, "lf em 4x50 help" }, - { 0, "lf em 4x50 brute" }, - { 0, "lf em 4x50 chk" }, - { 0, "lf em 4x50 dump" }, - { 0, "lf em 4x50 info" }, - { 0, "lf em 4x50 login" }, - { 0, "lf em 4x50 rdbl" }, - { 0, "lf em 4x50 reader" }, - { 0, "lf em 4x50 restore" }, - { 0, "lf em 4x50 wrbl" }, - { 0, "lf em 4x50 wrpwd" }, - { 0, "lf em 4x50 wipe" }, - { 0, "lf em 4x50 eload" }, - { 0, "lf em 4x50 esave" }, - { 0, "lf em 4x50 eview" }, - { 0, "lf em 4x50 sim" }, - { 1, "lf em 4x70 help" }, - { 0, "lf em 4x70 brute" }, - { 0, "lf em 4x70 info" }, - { 0, "lf em 4x70 write" }, - { 0, "lf em 4x70 unlock" }, - { 0, "lf em 4x70 auth" }, - { 0, "lf em 4x70 writepin" }, - { 0, "lf em 4x70 writekey" }, - { 1, "lf fdxb help" }, - { 1, "lf fdxb demod" }, - { 0, "lf fdxb reader" }, - { 0, "lf fdxb clone" }, - { 0, "lf fdxb sim" }, - { 1, "lf gallagher help" }, - { 1, "lf gallagher demod" }, - { 0, "lf gallagher reader" }, - { 0, "lf gallagher clone" }, - { 0, "lf gallagher sim" }, - { 1, "lf gproxii help" }, - { 1, "lf gproxii demod" }, - { 0, "lf gproxii reader" }, - { 0, "lf gproxii clone" }, - { 0, "lf gproxii sim" }, - { 1, "lf hid help" }, - { 1, "lf hid demod" }, - { 0, "lf hid reader" }, - { 0, "lf hid clone" }, - { 0, "lf hid sim" }, - { 0, "lf hid brute" }, - { 0, "lf hid watch" }, - { 1, "lf hitag help" }, - { 0, "lf hitag eload" }, - { 1, "lf hitag list" }, - { 0, "lf hitag info" }, - { 0, "lf hitag reader" }, - { 0, "lf hitag sim" }, - { 0, "lf hitag sniff" }, - { 0, "lf hitag writer" }, - { 0, "lf hitag dump" }, - { 0, "lf hitag cc" }, - { 1, "lf idteck help" }, - { 1, "lf idteck demod" }, - { 0, "lf idteck reader" }, - { 0, "lf idteck clone" }, - { 0, "lf idteck sim" }, - { 1, "lf indala help" }, - { 0, "lf indala brute" }, - { 1, "lf indala demod" }, - { 1, "lf indala altdemod" }, - { 0, "lf indala reader" }, - { 0, "lf indala clone" }, - { 0, "lf indala sim" }, - { 1, "lf io help" }, - { 1, "lf io demod" }, - { 0, "lf io reader" }, - { 0, "lf io clone" }, - { 0, "lf io sim" }, - { 0, "lf io watch" }, - { 1, "lf jablotron help" }, - { 1, "lf jablotron demod" }, - { 0, "lf jablotron reader" }, - { 0, "lf jablotron clone" }, - { 0, "lf jablotron sim" }, - { 1, "lf keri help" }, - { 1, "lf keri demod" }, - { 0, "lf keri reader" }, - { 0, "lf keri clone" }, - { 0, "lf keri sim" }, - { 1, "lf motorola help" }, - { 1, "lf motorola demod" }, - { 0, "lf motorola reader" }, - { 0, "lf motorola clone" }, - { 0, "lf motorola sim" }, - { 1, "lf nedap help" }, - { 1, "lf nedap demod" }, - { 0, "lf nedap reader" }, - { 0, "lf nedap clone" }, - { 0, "lf nedap sim" }, - { 1, "lf nexwatch help" }, - { 1, "lf nexwatch demod" }, - { 0, "lf nexwatch reader" }, - { 0, "lf nexwatch clone" }, - { 0, "lf nexwatch sim" }, - { 1, "lf noralsy help" }, - { 1, "lf noralsy demod" }, - { 0, "lf noralsy reader" }, - { 0, "lf noralsy clone" }, - { 0, "lf noralsy sim" }, - { 1, "lf pac help" }, - { 1, "lf pac demod" }, - { 0, "lf pac reader" }, - { 0, "lf pac clone" }, - { 0, "lf pac sim" }, - { 1, "lf paradox help" }, - { 1, "lf paradox demod" }, - { 0, "lf paradox reader" }, - { 0, "lf paradox clone" }, - { 0, "lf paradox sim" }, - { 1, "lf pcf7931 help" }, - { 0, "lf pcf7931 reader" }, - { 0, "lf pcf7931 write" }, - { 1, "lf pcf7931 config" }, - { 1, "lf presco help" }, - { 1, "lf presco demod" }, - { 0, "lf presco reader" }, - { 0, "lf presco clone" }, - { 0, "lf presco sim" }, - { 1, "lf pyramid help" }, - { 1, "lf pyramid demod" }, - { 0, "lf pyramid reader" }, - { 0, "lf pyramid clone" }, - { 0, "lf pyramid sim" }, - { 1, "lf securakey help" }, - { 1, "lf securakey demod" }, - { 0, "lf securakey reader" }, - { 0, "lf securakey clone" }, - { 0, "lf securakey sim" }, - { 1, "lf ti help" }, - { 1, "lf ti demod" }, - { 0, "lf ti reader" }, - { 0, "lf ti write" }, - { 1, "lf t55xx help" }, - { 0, "lf t55xx clonehelp" }, - { 1, "lf t55xx config" }, - { 0, "lf t55xx dangerraw" }, - { 1, "lf t55xx detect" }, - { 0, "lf t55xx deviceconfig" }, - { 0, "lf t55xx dump" }, - { 1, "lf t55xx info" }, - { 0, "lf t55xx p1detect" }, - { 0, "lf t55xx read" }, - { 0, "lf t55xx resetread" }, - { 0, "lf t55xx restore" }, - { 1, "lf t55xx trace" }, - { 0, "lf t55xx wakeup" }, - { 0, "lf t55xx write" }, - { 0, "lf t55xx bruteforce" }, - { 0, "lf t55xx chk" }, - { 0, "lf t55xx protect" }, - { 0, "lf t55xx recoverpw" }, - { 1, "lf t55xx sniff" }, - { 0, "lf t55xx special" }, - { 0, "lf t55xx wipe" }, - { 1, "lf viking help" }, - { 1, "lf viking demod" }, - { 0, "lf viking reader" }, - { 0, "lf viking clone" }, - { 0, "lf viking sim" }, - { 1, "lf visa2000 help" }, - { 1, "lf visa2000 demod" }, - { 0, "lf visa2000 reader" }, - { 0, "lf visa2000 clone" }, - { 0, "lf visa2000 sim" }, - { 1, "mem help" }, - { 0, "mem baudrate" }, - { 0, "mem dump" }, - { 0, "mem info" }, - { 0, "mem load" }, - { 0, "mem wipe" }, - { 1, "mem spiffs help" }, - { 0, "mem spiffs copy" }, - { 0, "mem spiffs check" }, - { 0, "mem spiffs dump" }, - { 0, "mem spiffs info" }, - { 0, "mem spiffs mount" }, - { 0, "mem spiffs remove" }, - { 0, "mem spiffs rename" }, - { 0, "mem spiffs test" }, - { 0, "mem spiffs tree" }, - { 0, "mem spiffs unmount" }, - { 0, "mem spiffs upload" }, - { 0, "mem spiffs view" }, - { 0, "mem spiffs wipe" }, - { 1, "nfc help" }, - { 1, "nfc decode" }, - { 0, "nfc type1 read" }, - { 1, "nfc type1 help" }, - { 0, "nfc type2 read" }, - { 1, "nfc type2 help" }, - { 0, "nfc type4a format" }, - { 0, "nfc type4a read" }, - { 0, "nfc type4a write" }, - { 0, "nfc type4a st25taread" }, - { 1, "nfc type4a help" }, - { 0, "nfc type4b read" }, - { 1, "nfc type4b help" }, - { 0, "nfc mf cformat" }, - { 0, "nfc mf cread" }, - { 0, "nfc mf cwrite" }, - { 0, "nfc mf pread" }, - { 1, "nfc mf help" }, - { 0, "nfc barcode read" }, - { 0, "nfc barcode sim" }, - { 1, "nfc barcode help" }, - { 1, "piv help" }, - { 0, "piv select" }, - { 0, "piv getdata" }, - { 0, "piv authsign" }, - { 0, "piv scan" }, - { 1, "piv list" }, - { 1, "smart help" }, - { 1, "smart list" }, - { 0, "smart info" }, - { 0, "smart reader" }, - { 0, "smart raw" }, - { 1, "smart upgrade" }, - { 0, "smart setclock" }, - { 0, "smart brute" }, - { 1, "script help" }, - { 1, "script list" }, - { 1, "script run" }, - { 1, "trace help" }, - { 1, "trace extract" }, - { 1, "trace list" }, - { 1, "trace load" }, - { 1, "trace save" }, - { 1, "usart help" }, - { 0, "usart btpin" }, - { 0, "usart btfactory" }, - { 0, "usart tx" }, - { 0, "usart rx" }, - { 0, "usart txrx" }, - { 0, "usart txhex" }, - { 0, "usart rxhex" }, - { 0, "usart config" }, - { 1, "wiegand help" }, - { 1, "wiegand list" }, - { 1, "wiegand encode" }, - { 1, "wiegand decode" }, + { 0, "hf mfu wrbl" }, + { 0, "hf mfu eload" }, + { 0, "hf mfu esave" }, + { 0, "hf mfu eview" }, + { 0, "hf mfu sim" }, + { 0, "hf mfu setpwd" }, + { 0, "hf mfu setuid" }, + { 1, "hf mfdes help" }, + { 0, "hf mfdes info" }, + { 0, "hf mfdes getuid" }, + { 0, "hf mfdes default" }, + { 0, "hf mfdes auth" }, + { 0, "hf mfdes chk" }, + { 0, "hf mfdes detect" }, + { 0, "hf mfdes freemem" }, + { 0, "hf mfdes setconfig" }, + { 0, "hf mfdes formatpicc" }, + { 1, "hf mfdes list" }, + { 0, "hf mfdes mad" }, + { 0, "hf mfdes lsapp" }, + { 0, "hf mfdes getaids" }, + { 0, "hf mfdes getappnames" }, + { 0, "hf mfdes bruteaid" }, + { 0, "hf mfdes createapp" }, + { 0, "hf mfdes deleteapp" }, + { 0, "hf mfdes selectapp" }, + { 0, "hf mfdes changekey" }, + { 0, "hf mfdes chkeysettings" }, + { 0, "hf mfdes getkeysettings" }, + { 0, "hf mfdes getkeyversions" }, + { 0, "hf mfdes getfileids" }, + { 0, "hf mfdes getfileisoids" }, + { 0, "hf mfdes lsfiles" }, + { 0, "hf mfdes dump" }, + { 0, "hf mfdes createfile" }, + { 0, "hf mfdes createvaluefile" }, + { 0, "hf mfdes createrecordfile" }, + { 0, "hf mfdes createmacfile" }, + { 0, "hf mfdes deletefile" }, + { 0, "hf mfdes getfilesettings" }, + { 0, "hf mfdes chfilesettings" }, + { 0, "hf mfdes read" }, + { 0, "hf mfdes write" }, + { 0, "hf mfdes value" }, + { 0, "hf mfdes clearrecfile" }, + { 1, "hf mfdes test" }, + { 1, "hf ntag424 help" }, + { 0, "hf ntag424 info" }, + { 0, "hf ntag424 sdm" }, + { 1, "hf ntag424 view" }, + { 1, "hf seos help" }, + { 0, "hf seos info" }, + { 1, "hf seos list" }, + { 1, "hf st25ta help" }, + { 0, "hf st25ta info" }, + { 1, "hf st25ta list" }, + { 1, "hf st25ta ndefread" }, + { 0, "hf st25ta protect" }, + { 0, "hf st25ta pwd" }, + { 0, "hf st25ta sim" }, + { 1, "hf tesla help" }, + { 0, "hf tesla info" }, + { 1, "hf tesla list" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, + { 1, "hf thinfilm help" }, + { 0, "hf thinfilm info" }, + { 1, "hf thinfilm list" }, + { 0, "hf thinfilm sim" }, + { 1, "hf topaz help" }, + { 0, "hf topaz dump" }, + { 1, "hf topaz list" }, + { 0, "hf topaz info" }, + { 0, "hf topaz reader" }, + { 0, "hf topaz sim" }, + { 0, "hf topaz sniff" }, + { 0, "hf topaz raw" }, + { 0, "hf topaz rdbl" }, + { 1, "hf topaz view" }, + { 0, "hf topaz wrbl" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, + { 0, "hf xerox dump" }, + { 1, "hf waveshare help" }, + { 0, "hf waveshare loadbmp" }, + { 1, "hw help" }, + { 0, "hw break" }, + { 1, "hw connect" }, + { 0, "hw dbg" }, + { 0, "hw detectreader" }, + { 0, "hw fpgaoff" }, + { 0, "hw lcd" }, + { 0, "hw lcdreset" }, + { 0, "hw ping" }, + { 0, "hw readmem" }, + { 0, "hw reset" }, + { 0, "hw setlfdivisor" }, + { 0, "hw setmux" }, + { 0, "hw standalone" }, + { 0, "hw status" }, + { 0, "hw tearoff" }, + { 0, "hw tia" }, + { 0, "hw tune" }, + { 1, "hw version" }, + { 1, "lf help" }, + { 0, "lf config" }, + { 0, "lf cmdread" }, + { 0, "lf read" }, + { 1, "lf search" }, + { 0, "lf sim" }, + { 0, "lf simask" }, + { 0, "lf simfsk" }, + { 0, "lf simpsk" }, + { 0, "lf simbidir" }, + { 0, "lf sniff" }, + { 0, "lf tune" }, + { 1, "lf awid help" }, + { 1, "lf awid demod" }, + { 0, "lf awid reader" }, + { 0, "lf awid clone" }, + { 0, "lf awid sim" }, + { 0, "lf awid brute" }, + { 0, "lf awid watch" }, + { 1, "lf cotag help" }, + { 1, "lf cotag demod" }, + { 0, "lf cotag reader" }, + { 1, "lf destron help" }, + { 1, "lf destron demod" }, + { 0, "lf destron reader" }, + { 0, "lf destron clone" }, + { 0, "lf destron sim" }, + { 1, "lf em help" }, + { 1, "lf em 410x help" }, + { 1, "lf em 410x demod" }, + { 0, "lf em 410x reader" }, + { 0, "lf em 410x sim" }, + { 0, "lf em 410x brute" }, + { 0, "lf em 410x watch" }, + { 0, "lf em 410x spoof" }, + { 0, "lf em 410x clone" }, + { 1, "lf em 4x05 help" }, + { 0, "lf em 4x05 brute" }, + { 0, "lf em 4x05 chk" }, + { 1, "lf em 4x05 demod" }, + { 0, "lf em 4x05 dump" }, + { 0, "lf em 4x05 info" }, + { 0, "lf em 4x05 read" }, + { 1, "lf em 4x05 sniff" }, + { 0, "lf em 4x05 unlock" }, + { 0, "lf em 4x05 wipe" }, + { 0, "lf em 4x05 write" }, + { 1, "lf em 4x50 help" }, + { 0, "lf em 4x50 brute" }, + { 0, "lf em 4x50 chk" }, + { 0, "lf em 4x50 dump" }, + { 0, "lf em 4x50 info" }, + { 0, "lf em 4x50 login" }, + { 0, "lf em 4x50 rdbl" }, + { 0, "lf em 4x50 reader" }, + { 0, "lf em 4x50 restore" }, + { 0, "lf em 4x50 wrbl" }, + { 0, "lf em 4x50 wrpwd" }, + { 0, "lf em 4x50 wipe" }, + { 0, "lf em 4x50 eload" }, + { 0, "lf em 4x50 esave" }, + { 0, "lf em 4x50 eview" }, + { 0, "lf em 4x50 sim" }, + { 1, "lf em 4x70 help" }, + { 0, "lf em 4x70 brute" }, + { 0, "lf em 4x70 info" }, + { 0, "lf em 4x70 write" }, + { 0, "lf em 4x70 unlock" }, + { 0, "lf em 4x70 auth" }, + { 0, "lf em 4x70 writepin" }, + { 0, "lf em 4x70 writekey" }, + { 1, "lf fdxb help" }, + { 1, "lf fdxb demod" }, + { 0, "lf fdxb reader" }, + { 0, "lf fdxb clone" }, + { 0, "lf fdxb sim" }, + { 1, "lf gallagher help" }, + { 1, "lf gallagher demod" }, + { 0, "lf gallagher reader" }, + { 0, "lf gallagher clone" }, + { 0, "lf gallagher sim" }, + { 1, "lf gproxii help" }, + { 1, "lf gproxii demod" }, + { 0, "lf gproxii reader" }, + { 0, "lf gproxii clone" }, + { 0, "lf gproxii sim" }, + { 1, "lf hid help" }, + { 1, "lf hid demod" }, + { 0, "lf hid reader" }, + { 0, "lf hid clone" }, + { 0, "lf hid sim" }, + { 0, "lf hid brute" }, + { 0, "lf hid watch" }, + { 1, "lf hitag help" }, + { 0, "lf hitag eload" }, + { 1, "lf hitag list" }, + { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, + { 0, "lf hitag sim" }, + { 0, "lf hitag sniff" }, + { 0, "lf hitag writer" }, + { 0, "lf hitag dump" }, + { 0, "lf hitag cc" }, + { 1, "lf idteck help" }, + { 1, "lf idteck demod" }, + { 0, "lf idteck reader" }, + { 0, "lf idteck clone" }, + { 0, "lf idteck sim" }, + { 1, "lf indala help" }, + { 0, "lf indala brute" }, + { 1, "lf indala demod" }, + { 1, "lf indala altdemod" }, + { 0, "lf indala reader" }, + { 0, "lf indala clone" }, + { 0, "lf indala sim" }, + { 1, "lf io help" }, + { 1, "lf io demod" }, + { 0, "lf io reader" }, + { 0, "lf io clone" }, + { 0, "lf io sim" }, + { 0, "lf io watch" }, + { 1, "lf jablotron help" }, + { 1, "lf jablotron demod" }, + { 0, "lf jablotron reader" }, + { 0, "lf jablotron clone" }, + { 0, "lf jablotron sim" }, + { 1, "lf keri help" }, + { 1, "lf keri demod" }, + { 0, "lf keri reader" }, + { 0, "lf keri clone" }, + { 0, "lf keri sim" }, + { 1, "lf motorola help" }, + { 1, "lf motorola demod" }, + { 0, "lf motorola reader" }, + { 0, "lf motorola clone" }, + { 0, "lf motorola sim" }, + { 1, "lf nedap help" }, + { 1, "lf nedap demod" }, + { 0, "lf nedap reader" }, + { 0, "lf nedap clone" }, + { 0, "lf nedap sim" }, + { 1, "lf nexwatch help" }, + { 1, "lf nexwatch demod" }, + { 0, "lf nexwatch reader" }, + { 0, "lf nexwatch clone" }, + { 0, "lf nexwatch sim" }, + { 1, "lf noralsy help" }, + { 1, "lf noralsy demod" }, + { 0, "lf noralsy reader" }, + { 0, "lf noralsy clone" }, + { 0, "lf noralsy sim" }, + { 1, "lf pac help" }, + { 1, "lf pac demod" }, + { 0, "lf pac reader" }, + { 0, "lf pac clone" }, + { 0, "lf pac sim" }, + { 1, "lf paradox help" }, + { 1, "lf paradox demod" }, + { 0, "lf paradox reader" }, + { 0, "lf paradox clone" }, + { 0, "lf paradox sim" }, + { 1, "lf pcf7931 help" }, + { 0, "lf pcf7931 reader" }, + { 0, "lf pcf7931 write" }, + { 1, "lf pcf7931 config" }, + { 1, "lf presco help" }, + { 1, "lf presco demod" }, + { 0, "lf presco reader" }, + { 0, "lf presco clone" }, + { 0, "lf presco sim" }, + { 1, "lf pyramid help" }, + { 1, "lf pyramid demod" }, + { 0, "lf pyramid reader" }, + { 0, "lf pyramid clone" }, + { 0, "lf pyramid sim" }, + { 1, "lf securakey help" }, + { 1, "lf securakey demod" }, + { 0, "lf securakey reader" }, + { 0, "lf securakey clone" }, + { 0, "lf securakey sim" }, + { 1, "lf ti help" }, + { 1, "lf ti demod" }, + { 0, "lf ti reader" }, + { 0, "lf ti write" }, + { 1, "lf t55xx help" }, + { 0, "lf t55xx clonehelp" }, + { 1, "lf t55xx config" }, + { 0, "lf t55xx dangerraw" }, + { 1, "lf t55xx detect" }, + { 0, "lf t55xx deviceconfig" }, + { 0, "lf t55xx dump" }, + { 1, "lf t55xx info" }, + { 0, "lf t55xx p1detect" }, + { 0, "lf t55xx read" }, + { 0, "lf t55xx resetread" }, + { 0, "lf t55xx restore" }, + { 1, "lf t55xx trace" }, + { 0, "lf t55xx wakeup" }, + { 0, "lf t55xx write" }, + { 0, "lf t55xx bruteforce" }, + { 0, "lf t55xx chk" }, + { 0, "lf t55xx protect" }, + { 0, "lf t55xx recoverpw" }, + { 1, "lf t55xx sniff" }, + { 0, "lf t55xx special" }, + { 0, "lf t55xx wipe" }, + { 1, "lf viking help" }, + { 1, "lf viking demod" }, + { 0, "lf viking reader" }, + { 0, "lf viking clone" }, + { 0, "lf viking sim" }, + { 1, "lf visa2000 help" }, + { 1, "lf visa2000 demod" }, + { 0, "lf visa2000 reader" }, + { 0, "lf visa2000 clone" }, + { 0, "lf visa2000 sim" }, + { 1, "mem help" }, + { 0, "mem baudrate" }, + { 0, "mem dump" }, + { 0, "mem info" }, + { 0, "mem load" }, + { 0, "mem wipe" }, + { 1, "mem spiffs help" }, + { 0, "mem spiffs copy" }, + { 0, "mem spiffs check" }, + { 0, "mem spiffs dump" }, + { 0, "mem spiffs info" }, + { 0, "mem spiffs mount" }, + { 0, "mem spiffs remove" }, + { 0, "mem spiffs rename" }, + { 0, "mem spiffs test" }, + { 0, "mem spiffs tree" }, + { 0, "mem spiffs unmount" }, + { 0, "mem spiffs upload" }, + { 0, "mem spiffs view" }, + { 0, "mem spiffs wipe" }, + { 1, "nfc help" }, + { 1, "nfc decode" }, + { 0, "nfc type1 read" }, + { 1, "nfc type1 help" }, + { 0, "nfc type2 read" }, + { 1, "nfc type2 help" }, + { 0, "nfc type4a format" }, + { 0, "nfc type4a read" }, + { 0, "nfc type4a write" }, + { 0, "nfc type4a st25taread" }, + { 1, "nfc type4a help" }, + { 0, "nfc type4b read" }, + { 1, "nfc type4b help" }, + { 0, "nfc mf cformat" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf cwrite" }, + { 0, "nfc mf pread" }, + { 1, "nfc mf help" }, + { 0, "nfc barcode read" }, + { 0, "nfc barcode sim" }, + { 1, "nfc barcode help" }, + { 1, "piv help" }, + { 0, "piv select" }, + { 0, "piv getdata" }, + { 0, "piv authsign" }, + { 0, "piv scan" }, + { 1, "piv list" }, + { 1, "smart help" }, + { 1, "smart list" }, + { 0, "smart info" }, + { 0, "smart reader" }, + { 0, "smart raw" }, + { 1, "smart upgrade" }, + { 0, "smart setclock" }, + { 0, "smart brute" }, + { 1, "script help" }, + { 1, "script list" }, + { 1, "script run" }, + { 1, "trace help" }, + { 1, "trace extract" }, + { 1, "trace list" }, + { 1, "trace load" }, + { 1, "trace save" }, + { 1, "usart help" }, + { 0, "usart btpin" }, + { 0, "usart btfactory" }, + { 0, "usart tx" }, + { 0, "usart rx" }, + { 0, "usart txrx" }, + { 0, "usart txhex" }, + { 0, "usart rxhex" }, + { 0, "usart config" }, + { 1, "wiegand help" }, + { 1, "wiegand list" }, + { 1, "wiegand encode" }, + { 1, "wiegand decode" }, {0, NULL} }; @@ -790,4 +790,4 @@ const static vocabulory_t vocabulory[] = { } #endif -#endif \ No newline at end of file +#endif diff --git a/common_arm/flashmem.c b/common_arm/flashmem.c index 435f51a57..94dcf1fd3 100644 --- a/common_arm/flashmem.c +++ b/common_arm/flashmem.c @@ -366,8 +366,8 @@ void Flashmem_print_status(void) { } } else { Dbprintf(" Device ID............... " _YELLOW_("%02X / %02X (unknown)"), - device_type.manufacturer_id, - device_type.device_id + device_type.manufacturer_id, + device_type.device_id ); } } diff --git a/tools/mfd_aes_brute/mfd_aes_brute.c b/tools/mfd_aes_brute/mfd_aes_brute.c index b19885f34..19bb54ce5 100644 --- a/tools/mfd_aes_brute/mfd_aes_brute.c +++ b/tools/mfd_aes_brute/mfd_aes_brute.c @@ -144,7 +144,7 @@ static void print_time(uint64_t at) { strftime(res, sizeof(res), "('%Y-%m-%d %H:%M:%S')", <); #else strftime(res, sizeof(res), "%s ('%Y-%m-%d %H:%M:%S')", <); -#endif +#endif printf("%s\n", res); } diff --git a/tools/mfd_aes_brute/mfd_multi_brute.c b/tools/mfd_aes_brute/mfd_multi_brute.c index bb2456aa1..226fd9f7f 100644 --- a/tools/mfd_aes_brute/mfd_multi_brute.c +++ b/tools/mfd_aes_brute/mfd_multi_brute.c @@ -174,7 +174,7 @@ static void print_time(uint64_t at) { strftime(res, sizeof(res), "('%Y-%m-%d %H:%M:%S')", <); #else strftime(res, sizeof(res), "%s ('%Y-%m-%d %H:%M:%S')", <); -#endif +#endif printf("%s\n", res); } From b3652c28bee689c23d7cadc979ff06255475305c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 20:12:00 +0100 Subject: [PATCH 665/759] fixc CID #405232 - init array --- client/src/cmdhffelica.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhffelica.c b/client/src/cmdhffelica.c index 773556543..191a481de 100644 --- a/client/src/cmdhffelica.c +++ b/client/src/cmdhffelica.c @@ -702,7 +702,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) { PrintAndLogEx(INFO, "Reader challenge (unencrypted): %s", sprint_hex(nonce, 8)); // Create M1c Challenge with 3DES (3 Keys = 24, 2 Keys = 16) - uint8_t master_key[24]; + uint8_t master_key[24] = {0}; mbedtls_des3_context des3_ctx; mbedtls_des3_init(&des3_ctx); From 173841b53351f242f2ac69f7dd74d69cc959fd24 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 20:14:09 +0100 Subject: [PATCH 666/759] fix CID #405231 - resource leak --- client/src/cmdhfmfhard.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/src/cmdhfmfhard.c b/client/src/cmdhfmfhard.c index 7d930a8a3..4cb7873af 100644 --- a/client/src/cmdhfmfhard.c +++ b/client/src/cmdhfmfhard.c @@ -1481,6 +1481,9 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_ if (got_match == false) { PrintAndLogEx(FAILED, "No match for the First_Byte_Sum (%u), is the card a genuine MFC Ev1? ", first_byte_Sum); + if (nonce_file_write) { + fclose(fnonces); + } return PM3_EWRONGANSWER; } From 95a19405d8c58a033372529b3e62207772b8a8d0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 20:17:06 +0100 Subject: [PATCH 667/759] fix CID #405230 - array too small --- client/src/cmdcrc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/cmdcrc.c b/client/src/cmdcrc.c index 98befcc00..ae424662c 100644 --- a/client/src/cmdcrc.c +++ b/client/src/cmdcrc.c @@ -424,8 +424,8 @@ static int CmdrevengSearch(const char *Cmd) { uint8_t width[NMODELS] = {0}; int count = 0; - char result[30]; - char revResult[30]; + char result[50 + 1] = {0}; + char revResult[50 + 1] = {0}; int ans = GetModels(Models, &count, width); bool found = false; if (!ans) { @@ -461,7 +461,7 @@ static int CmdrevengSearch(const char *Cmd) { continue; } - memset(result, 0, 30); + memset(result, 0, sizeof(result)); char *inCRC = calloc(crcChars + 1, sizeof(char)); if (inCRC == NULL) { return 0; From a0feb580c2173042e75cb75e0bdf940055be8af3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 20:20:10 +0100 Subject: [PATCH 668/759] fix CID #405227 - wrong comparision for the first fix --- client/src/cmdhfemrtd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index bb0808a51..c8edd2054 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -2018,7 +2018,7 @@ int infoHF_EMRTD_offline(const char *path) { } // coverity scan CID 395630, - if (data != NULL) { + if (data == NULL) { return PM3_ESOFT; } From b6be8d9532d548a3a485bebd952ff3a2d0a04046 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 20:24:20 +0100 Subject: [PATCH 669/759] fix CID # 405226 --- client/src/cmdhfmfdes.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 2f45b5165..18b160a9a 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -4843,14 +4843,17 @@ static int DesfileReadFileAndPrint(DesfireContext_t *dctx, } } - if (resplen > 0) { + if (resplen > 0 && reclen > 0) { size_t reccount = resplen / reclen; PrintAndLogEx(SUCCESS, "Read %zu bytes from file 0x%02x from record %d record count %zu record length %zu", resplen, fnum, offset, reccount, reclen); - if (reccount > 1) + if (reccount > 1) { PrintAndLogEx(SUCCESS, "Lastest record at the bottom."); + } + for (int i = 0; i < reccount; i++) { - if (i != 0) + if (i != 0) { PrintAndLogEx(SUCCESS, "Record %zu", reccount - (i + offset + 1)); + } print_buffer_with_offset(&resp[i * reclen], reclen, offset, (i == 0)); } } else { From 7504413f0bfc83c64af5b0f179d6dbe70ce6d727 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 20:29:39 +0100 Subject: [PATCH 670/759] fix CID #405225 --- client/src/cmdhfmf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 57de6ee70..1a497c132 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -884,7 +884,7 @@ static int CmdHF14AMfDump(const char *Cmd) { if (fptr == NULL) return PM3_ESOFT; - strcpy(keyFilename, fptr); + strncpy(keyFilename, fptr, sizeof(keyFilename) - 1); free(fptr); } @@ -1179,7 +1179,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { if (fptr == NULL) return PM3_ESOFT; - strcpy(keyfilename, fptr); + strncpy(keyfilename, fptr, sizeof(keyfilename) - 1); free(fptr); } @@ -6009,7 +6009,7 @@ int CmdHFMFNDEFFormat(const char *Cmd) { if (keyfnlen == 0) { char *fptr = GenerateFilename("hf-mf-", "-key.bin"); if (fptr) { - strcpy(keyFilename, fptr); + strncpy(keyFilename, fptr, sizeof(keyFilename) - 1); } free(fptr); DropField(); @@ -6733,7 +6733,7 @@ static int CmdHF14AMfWipe(const char *Cmd) { if (fptr == NULL) return PM3_ESOFT; - strcpy(keyFilename, fptr); + strncpy(keyFilename, fptr, sizeof(keyFilename) - 1); free(fptr); } From f9da8615e4be9b776aadaafa61803365f03005c3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 20:32:34 +0100 Subject: [PATCH 671/759] fix CID #405224 --- client/src/cmdhfmf.c | 5 +++-- client/src/cmdhfmfu.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 1a497c132..d5a629e90 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -2973,7 +2973,8 @@ all_found: free(fptr); return PM3_ESOFT; } - strcpy(filename, fptr); + + strncpy(filename, fptr, sizeof(filename) - 1); free(fptr); saveFile(filename, ".bin", dump, bytes); @@ -5411,7 +5412,7 @@ static int CmdHF14AMfice(const char *Cmd) { fptr = GenerateFilename("hf-mf-", "-nonces.bin"); if (fptr == NULL) return PM3_EFILE; - strcpy(filename, fptr); + strncpy(filename, fptr, sizeof(filename) - 1); free(fptr); } diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index d5ac6537b..963786ebc 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -2870,7 +2870,7 @@ static int CmdHF14AMfURestore(const char *Cmd) { if (fnlen == 0) { char *fptr = GenerateFilename("hf-mfu-", "-dump.bin"); if (fptr != NULL) { - strcpy(filename, fptr); + strncpy(filename, fptr, sizeof(filename) - 1); } else { snprintf(filename, sizeof(filename), "dumpdata.bin"); } From aebbdaea2da45a4a12c101fba3b20fed2a665d05 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 20:36:28 +0100 Subject: [PATCH 672/759] fix CID #405223 - use after free, all callers must handle bad returns properly --- client/src/cmdhfmfdes.c | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 18b160a9a..d1451dae9 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -3572,7 +3572,6 @@ static int DesfireCreateFileParameters( bool userawfrights = false; if (frightsid) { if (CLIGetUint32Hex(ctx, frightsid, 0xeeee, &frights, &userawfrights, 2, "File rights must have 2 bytes length")) { - CLIParserFree(ctx); return PM3_EINVARG; } } From c6a8f8cc8901cef63004425e14db33043e2a8b49 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 21:25:23 +0100 Subject: [PATCH 673/759] fix test --- client/src/cmdlfguard.c | 10 +++++----- tools/pm3_tests.sh | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/cmdlfguard.c b/client/src/cmdlfguard.c index d39cff47c..4ba98d903 100644 --- a/client/src/cmdlfguard.c +++ b/client/src/cmdlfguard.c @@ -86,9 +86,9 @@ static int demod_guard_raw(uint8_t *raw, uint8_t rlen) { } if (unknown) - PrintAndLogEx(SUCCESS, "G-Prox-II - xorKey: " _GREEN_("%u")" Unknown len: " _GREEN_("%u") ", Raw: %s", xorKey, fmtlen, sprint_hex_inrow(raw, rlen)); + PrintAndLogEx(SUCCESS, "G-Prox-II - Unknown len: " _GREEN_("%u") "xor: " _GREEN_("%u")", Raw: %s", fmtlen, xorKey, sprint_hex_inrow(raw, rlen)); else - PrintAndLogEx(SUCCESS, "G-Prox-II - xorKey: " _GREEN_("%u")" Len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") ", Raw: %s", xorKey, fmtlen, FC, Card, sprint_hex_inrow(raw, rlen)); + PrintAndLogEx(SUCCESS, "G-Prox-II - Len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") "xor: " _GREEN_("%u")", Raw: %s", fmtlen, FC, Card, xorKey, sprint_hex_inrow(raw, rlen)); return PM3_SUCCESS; } @@ -180,10 +180,10 @@ int demodGuard(bool verbose) { unknown = true; break; } - if (!unknown) - PrintAndLogEx(SUCCESS, "G-Prox-II - xorKey: " _GREEN_("%u") " Len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") ", Raw: %08x%08x%08x", xorKey, fmtLen, FC, Card, raw1, raw2, raw3); + if (unknown) + PrintAndLogEx(SUCCESS, "G-Prox-II - Unknown len: " _GREEN_("%u") " xor: " _GREEN_("%u")", Raw: %08x%08x%08x ", fmtLen, xorKey, raw1, raw2, raw3); else - PrintAndLogEx(SUCCESS, "G-Prox-II - xorKey: " _GREEN_("%u") " Unknown len: " _GREEN_("%u") ", Raw: %08x%08x%08x", xorKey, fmtLen, raw1, raw2, raw3); + PrintAndLogEx(SUCCESS, "G-Prox-II - Len: " _GREEN_("%u")" FC: " _GREEN_("%u") " Card: " _GREEN_("%u") " xor: " _GREEN_("%u") ", Raw: %08x%08x%08x", fmtLen, FC, Card, xorKey, raw1, raw2, raw3); return PM3_SUCCESS; } diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index d03e488e6..f116de2b1 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -428,7 +428,7 @@ while true; do "GALLAGHER - Region: 1 Facility: 16640 Card No.: 201 Issue Level: 1"; then break; fi if ! CheckExecute slow "lf T55 gproxii test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gproxii.pm3; lf search -1'" "Guardall G-Prox II ID found"; then break; fi if ! CheckExecute slow "lf T55 gproxii test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_gproxii.pm3; lf gproxii demod'" \ - "G-Prox-II - len: 26 FC: 123 Card: 11223, Raw: f98c7038c63356c7ac26398c"; then break; fi + "G-Prox-II - Len: 26 FC: 123 Card: 11223 xor: 102, Raw: f98c7038c63356c7ac26398c"; then break; fi if ! CheckExecute slow "lf T55 hid test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid.pm3; lf search -1'" "HID Prox ID found"; then break; fi if ! CheckExecute slow "lf T55 hid test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_hid.pm3; lf hid demod'" \ "FC: 118 CN: 1603"; then break; fi From 855f13d76312e8b69e508b8408e406af0673b6fb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 21:25:44 +0100 Subject: [PATCH 674/759] string formatter --- client/src/nfc/ndef.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/nfc/ndef.c b/client/src/nfc/ndef.c index 2fa05d4ad..b995a3e19 100644 --- a/client/src/nfc/ndef.c +++ b/client/src/nfc/ndef.c @@ -1069,16 +1069,16 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "--- " _CYAN_("NDEF Memory Control") " ---"); if (len != 3) { - PrintAndLogEx(WARNING, "NDEF Memory Control block size must be 3 instead of %d", len); + PrintAndLogEx(WARNING, "NDEF Memory Control block size must be 3 instead of %u", len); } else { uint8_t pages_addr = (ndef[indx] >> 4) & 0x0f; uint8_t byte_offset = ndef[indx] & 0x0f; uint8_t Size = ndef[indx + 1]; uint8_t bytes_per_page = ndef[indx + 2] & 0x0f; - PrintAndLogEx(SUCCESS, "Pages addr (number of pages).... %d", pages_addr); - PrintAndLogEx(SUCCESS, "Byte offset (number of bytes)... %d", byte_offset); - PrintAndLogEx(SUCCESS, "Reserved area size in bits...... %d ( %d bytes )", Size, Size / 8); - PrintAndLogEx(SUCCESS, " Number of bytes / page... %d", bytes_per_page); + PrintAndLogEx(SUCCESS, "Pages addr (number of pages).... %u", pages_addr); + PrintAndLogEx(SUCCESS, "Byte offset (number of bytes)... %u", byte_offset); + PrintAndLogEx(SUCCESS, "Reserved area size in bits...... %u ( %u bytes )", Size, Size / 8); + PrintAndLogEx(SUCCESS, " Number of bytes / page... %u", bytes_per_page); } indx += len; break; @@ -1091,7 +1091,7 @@ int NDEFDecodeAndPrint(uint8_t *ndef, size_t ndefLen, bool verbose) { if (len == 0) { PrintAndLogEx(SUCCESS, "Found NDEF message w zero length"); } else { - PrintAndLogEx(SUCCESS, "Found NDEF message ( " _YELLOW_("%d") " bytes )", len); + PrintAndLogEx(SUCCESS, "Found NDEF message ( " _YELLOW_("%u") " bytes )", len); int res = NDEFRecordsDecodeAndPrint(&ndef[indx], len, verbose); if (res != PM3_SUCCESS) From 514626a0ab766655512bf0f37f3f009942b7f883 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 4 Mar 2023 21:26:12 +0100 Subject: [PATCH 675/759] init array --- client/src/cmdlfem4x50.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index 3bed45d1d..9b5bac06b 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -555,7 +555,7 @@ int em4x50_read(em4x50_data_t *etd, em4x50_word_t *out) { return PM3_ESOFT; uint8_t *data = resp.data.asBytes; - em4x50_word_t words[EM4X50_NO_WORDS]; + em4x50_word_t words[EM4X50_NO_WORDS] = {0}; prepare_result(data, etd->addresses & 0xFF, (etd->addresses >> 8) & 0xFF, words); if (out != NULL) From 37ecae658f8c268086bb300b30980f725f967102 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Mar 2023 08:20:10 +0100 Subject: [PATCH 676/759] added data num command. Takes dec or hex or binary and convert between them. Uses big_int so no issue with hex -> dec limits. It also does a Prime number check, where it will a line in the case of a number happens to be prime. --- CHANGELOG.md | 3 +- client/src/cmddata.c | 148 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 144 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9f26516a..937c092ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +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] - - Fixed `hf mfdes info`- now handles incorrect tag answers better (@didiera) + - Added `data num` - easy convert between dec/hex/bin (@iceman1001) + - Fixed `hf mfdes info` - now handles incorrect tag answers better (@didiera) - Fixed `hf mfdes` generic help text is now correct (@didiera) - Fixed `pm3` script to correctly identify WSL enabled distros (@henrygab) - Changed device enumeration with "unique USB serial numbers when built with `FLASH` -- **_UPDATES BOOTROM ALSO_**" (@henrygab) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index b9ca854f1..724bc5c65 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -35,6 +35,9 @@ #include "cmdlft55xx.h" // print... #include "crypto/asn1utils.h" // ASN1 decode / print #include "cmdflashmemspiffs.h" // SPIFFS flash memory download +#include "mbedtls/bignum.h" // big num +#include "mbedtls/entropy.h" // +#include "mbedtls/ctr_drbg.h" // random generator uint8_t g_DemodBuffer[MAX_DEMOD_BUF_LEN]; size_t g_DemodBufferLen = 0; @@ -2425,6 +2428,19 @@ static int CmdZerocrossings(const char *Cmd) { return PM3_SUCCESS; } +static bool data_verify_hex(uint8_t *d, size_t n) { + if (d == NULL) + return false; + + for (size_t i = 0; i < n; i++) { + if (isxdigit(d[i]) == false) { + PrintAndLogEx(ERR, "Non hex digit found"); + return false; + } + } + return true; +} + /** * @brief Utility for conversion via cmdline. * @param Cmd @@ -2501,12 +2517,8 @@ static int Cmdhex2bin(const char *Cmd) { return PM3_EINVARG; } - for (int i = 0; i < dlen; i++) { - char x = data[i]; - if (isxdigit(x) == false) { - PrintAndLogEx(ERR, "Non hex digit found"); - return PM3_EINVARG; - } + if (data_verify_hex((uint8_t*)data, dlen) == false) { + return PM3_EINVARG; } PrintAndLogEx(SUCCESS, "" NOLF); @@ -3166,6 +3178,129 @@ static int CmdDiff(const char *Cmd) { return PM3_SUCCESS; } +static int CmdNumCon(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "data num", + "Function takes a decimal or hexdecimal number and print it in decimal/hex/binary\n" + "Will print message if number is a prime number\n", + "data num --dec 2023\n" + "data num --hex 0x1000\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_str0(NULL, "dec", "", "decimal value"), + arg_str0(NULL, "hex", "", "hexadecimal value"), + arg_str0(NULL, "bin", "", "binary value"), + arg_lit0("i", NULL, "print inverted value"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int dlen = 256; + char dec[256]; + memset(dec, 0, sizeof(dec)); + int res = CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)dec, sizeof(dec), &dlen); + + + int hlen = 256; + char hex[256]; + memset(hex, 0, sizeof(hex)); + res = CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)hex, sizeof(hex), &hlen); + + int blen = 256; + char bin[256]; + memset(bin, 0, sizeof(bin)); + res = CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)bin, sizeof(bin), &blen); + + bool shall_invert = arg_get_lit(ctx, 4); + CLIParserFree(ctx); + + // sanity checks + if (res) { + PrintAndLogEx(FAILED, "Error parsing bytes"); + return PM3_EINVARG; + } + + // results for MPI actions + bool ret = false; + + // container of big number + mbedtls_mpi N; + mbedtls_mpi_init(&N); + + + // hex + if (hlen > 0) { + if (data_verify_hex((uint8_t*)hex, hlen) == false) { + return PM3_EINVARG; + } + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16, hex)); + } + + // decimal + if (dlen > 0) { + // should have decimal string check here too + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 10, dec)); + } + + // binary + if (blen > 0) { + // should have bianry string check here too + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 2, bin)); + } + + mbedtls_mpi base; + mbedtls_mpi_init(&base); + mbedtls_mpi_add_int(&base, &base, 10); + + if (shall_invert) { + PrintAndLogEx(INFO, "should invert"); + MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&N, &N, &base)); + } + + // printing + typedef struct { + const char* desc; + uint8_t radix; + } radix_t; + + radix_t radix[] = { + {"dec..... ", 10}, + {"hex..... 0x", 16}, + {"bin..... 0b", 2} + }; + + char s[600] = {0}; + size_t slen = 0; + + for (uint8_t i=0; i < ARRAYLEN(radix); i++) { + MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(&N, radix[i].radix, s, sizeof(s), &slen)); + if (slen > 0) { + PrintAndLogEx(INFO, "%s%s", radix[i].desc, s); + } + } + + // check if number is a prime + mbedtls_entropy_context entropy; + mbedtls_ctr_drbg_context ctr_drbg; + mbedtls_ctr_drbg_init(&ctr_drbg); + mbedtls_entropy_init(&entropy); + + MBEDTLS_MPI_CHK(mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0 )); + + res = mbedtls_mpi_is_prime_ext( &N, 50, mbedtls_ctr_drbg_random, &ctr_drbg ); + if (res == 0) { + PrintAndLogEx(INFO, "prime... " _YELLOW_("yes")); + } + +cleanup: + mbedtls_mpi_free(&N); + mbedtls_mpi_free(&base); + mbedtls_entropy_free(&entropy); + mbedtls_ctr_drbg_free(&ctr_drbg); + return PM3_SUCCESS; +} static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, @@ -3209,6 +3344,7 @@ static command_t CommandTable[] = { {"hexsamples", CmdHexsamples, IfPm3Present, "Dump big buffer as hex bytes"}, {"hex2bin", Cmdhex2bin, AlwaysAvailable, "Converts hexadecimal to binary"}, {"load", CmdLoad, AlwaysAvailable, "Load contents of file into graph window"}, + {"num", CmdNumCon, AlwaysAvailable, "Converts dec/hex/bin"}, {"print", CmdPrintDemodBuff, AlwaysAvailable, "Print the data in the DemodBuffer"}, {"samples", CmdSamples, IfPm3Present, "Get raw samples for graph window (GraphBuffer)"}, {"save", CmdSave, AlwaysAvailable, "Save signal trace data (from graph window)"}, From 47908df32ee6575a7d74f062b6c86081375df492 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Mar 2023 08:21:09 +0100 Subject: [PATCH 677/759] more text changes to hf tesla info --- client/src/cmdhftesla.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/client/src/cmdhftesla.c b/client/src/cmdhftesla.c index 940687cb4..32b9872e8 100644 --- a/client/src/cmdhftesla.c +++ b/client/src/cmdhftesla.c @@ -202,19 +202,21 @@ static int info_hf_tesla(void) { PrintAndLogEx(INFO, "%d - %s", i, sprint_hex_inrow(pk[i], 65)); } PrintAndLogEx(INFO, "Form factor... %s " NOLF, sprint_hex_inrow(form_factor, sizeof(form_factor))); - uint16_t form_factor_value = form_factor[0] << 8 | form_factor[1]; + + uint16_t form_factor_value = MemBeToUint2byte(form_factor); + switch (form_factor_value) { case 0x0001: - PrintAndLogEx(NORMAL, "(card)"); + PrintAndLogEx(NORMAL, "( card )"); break; case 0x0022: - PrintAndLogEx(NORMAL, "(fob)"); + PrintAndLogEx(NORMAL, "( fob )"); break; case 0x0031: - PrintAndLogEx(NORMAL, "(phone app)"); + PrintAndLogEx(NORMAL, "( phone app )"); break; default: - PrintAndLogEx(NORMAL, "(unknown)"); + PrintAndLogEx(NORMAL, "( unknown )"); break; } @@ -249,7 +251,6 @@ static int CmdHFTeslaInfo(const char *Cmd) { return info_hf_tesla(); } - static int CmdHFTeslaList(const char *Cmd) { return CmdTraceListAlias(Cmd, "hf tesla", "7816"); } @@ -270,4 +271,4 @@ static int CmdHelp(const char *Cmd) { int CmdHFTESLA(const char *Cmd) { clearCommandBuffer(); return CmdsParse(CommandTable, Cmd); -} +} \ No newline at end of file From 7584a7a617b7ff12de7d713220d48e2fdf50864a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Mar 2023 08:22:01 +0100 Subject: [PATCH 678/759] style --- client/src/cmdpiv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/client/src/cmdpiv.c b/client/src/cmdpiv.c index dc6584f40..4d23a9b4b 100644 --- a/client/src/cmdpiv.c +++ b/client/src/cmdpiv.c @@ -698,10 +698,12 @@ static int PivSelect(Iso7816CommandChannel channel, bool activateField, bool lea if ((sw != 0) && (silent == false)) { PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff)); } + if (res != PM3_SUCCESS || sw != ISO7816_OK) { PrintAndLogEx(FAILED, "Applet selection failed. Card is not a PIV card."); return res; } + if (silent == false) { if (decodeTLV == true) { PrintTLVFromBuffer(buf, len); @@ -736,8 +738,10 @@ static int CmdPIVSelect(const char *Cmd) { bool APDULogging = arg_get_lit(ctx, 3); bool decodeTLV = arg_get_lit(ctx, 4); Iso7816CommandChannel channel = CC_CONTACTLESS; - if (arg_get_lit(ctx, 5)) + if (arg_get_lit(ctx, 5)) { channel = CC_CONTACT; + } + PrintChannel(channel); uint8_t applet_id[APDU_AID_LEN] = {0}; @@ -970,7 +974,6 @@ static command_t CommandTable[] = { {"getdata", CmdPIVGetData, IfPm3Iso14443, "Gets a container on a PIV card"}, {"authsign", CmdPIVAuthenticateSign, IfPm3Iso14443, "Authenticate with the card"}, {"scan", CmdPIVScan, IfPm3Iso14443, "Scan PIV card for known containers"}, - {"list", CmdPIVList, AlwaysAvailable, "List ISO7816 history"}, {NULL, NULL, NULL, NULL} }; From bd99523edc7e67068a671c6ce8d6deb553f65850 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Mar 2023 08:22:21 +0100 Subject: [PATCH 679/759] style --- client/src/cmdlfawid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/cmdlfawid.c b/client/src/cmdlfawid.c index 11db5fc83..5d735a650 100644 --- a/client/src/cmdlfawid.c +++ b/client/src/cmdlfawid.c @@ -274,7 +274,8 @@ int demodAWID(bool verbose) { } free(bits); - PrintAndLogEx(DEBUG, "DEBUG: AWID idx: %d, Len: %zu Printing DemodBuffer:", idx, size); + PrintAndLogEx(DEBUG, "DEBUG: AWID idx: %d, Len: %zu", idx, size); + PrintAndLogEx(DEBUG, "DEBUG: Printing DemodBuffer:"); if (g_debugMode) { printDemodBuff(0, false, false, true); printDemodBuff(0, false, false, false); From 7abfff4095c3d2eae9eb85d243e3ea7f1a030a33 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 5 Mar 2023 19:19:15 +0100 Subject: [PATCH 680/759] moved and unified some reverse array fct --- client/src/cmdhf15.c | 38 ++++++++++------------------------ client/src/mifare/mifarehost.c | 22 +++++++++++--------- client/src/util.c | 1 - common/commonutil.c | 24 +++++++++++++++++++++ common/commonutil.h | 4 ++++ 5 files changed, 51 insertions(+), 38 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index d1b7289e8..c80f8cac4 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -223,16 +223,6 @@ static const productName_t uidmapping[] = { { 0, 0, "no tag-info available" } // must be the last entry }; -static inline void reverse(uint8_t *buff, uint8_t length) { - uint8_t upper_bound = (length % 2 == 0) ? length / 2 : (length / 2) + 1; - uint8_t tmp = 0; - for (int start = 0, end = length - 1; end >= upper_bound; ++start, --end) { - tmp = buff[end]; - buff[end] = buff[start]; - buff[start] = tmp; - } -} - static int CmdHF15Help(const char *Cmd); static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { @@ -287,16 +277,14 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) { } }; */ - uint8_t i; - uint8_t revuid[8]; - for (i = 0; i < sizeof(revuid); i++) { - revuid[i] = uid[7 - i]; - } - uint8_t revsign[32]; - for (i = 0; i < sizeof(revsign); i++) { - revsign[i] = signature[31 - i]; - } + uint8_t revuid[8] = {0}; + reverse_array_copy(uid, sizeof(revuid), revuid); + + uint8_t revsign[32] = {0}; + reverse_array_copy(signature, sizeof(revsign), revsign); + + uint8_t i; int reason = 0; bool is_valid = false; for (i = 0; i < ARRAYLEN(nxp_15693_public_keys); i++) { @@ -1823,7 +1811,7 @@ static int CmdHF15Readmulti(const char *Cmd) { return PM3_EINVARG; } } else { - reverse(uid, HF15_UID_LENGTH); + reverse_array(uid, HF15_UID_LENGTH); } // add UID (scan, uid) memcpy(req + reqlen, uid, HF15_UID_LENGTH); @@ -1953,7 +1941,7 @@ static int CmdHF15Readblock(const char *Cmd) { return PM3_EINVARG; } } else { - reverse(uid, HF15_UID_LENGTH); + reverse_array(uid, HF15_UID_LENGTH); } // add UID (scan, uid) memcpy(req + reqlen, uid, HF15_UID_LENGTH); @@ -2129,7 +2117,7 @@ static int CmdHF15Write(const char *Cmd) { return PM3_EINVARG; } } else { - reverse(uid, HF15_UID_LENGTH); + reverse_array(uid, HF15_UID_LENGTH); } // add UID (scan, uid) memcpy(req + reqlen, uid, HF15_UID_LENGTH); @@ -2356,11 +2344,7 @@ static int CmdHF15CSetUID(const char *Cmd) { // reverse cardUID to compare uint8_t revuid[8] = {0}; - uint8_t i = 0; - while (i < sizeof(revuid)) { - revuid[i] = carduid[7 - i]; - i++; - } + reverse_array_copy(carduid, sizeof(carduid), revuid); if (memcmp(revuid, payload.uid, 8) != 0) { PrintAndLogEx(FAILED, "setting new UID ( " _RED_("fail") " )"); diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index 56d10c608..fe2cd1897 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1493,13 +1493,9 @@ const char *vigik_get_service(uint16_t service_code) { return vigik_rsa_pk[ARRAYLEN(vigik_rsa_pk) - 1].desc; } -static void reverse_array(const uint8_t *src, int src_len, uint8_t *dest) { - for (int i = 0; i < src_len; i++) { - dest[i] = src[(src_len - 1) - i]; - } -}; int vigik_verify(mfc_vigik_t *d) { +#define PUBLIC_VIGIK_KEYLEN 128 // iso9796 // Exponent V = 2 @@ -1512,8 +1508,18 @@ int vigik_verify(mfc_vigik_t *d) { PrintAndLogEx(INFO, "Raw signature"); print_hex_noascii_break(d->rsa_signature, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2); } + +/* + int dl = 0; + + param_gethex_to_eol("1C07D46DA3849326D24B3468BD76673F4F3C41827DC413E81E4F3C7804FAC727213059B21D047510D6432448643A92EBFC67FBEDDAB468D13D948B172F5EBC79A0E3FEFDFAF4E81FC7108E070F1E3CD0", 0, signature, PUBLIC_VIGIK_KEYLEN, &dl); + + param_gethex_to_eol("1AB86FE0C17FFFFE4379D5E15A4B2FAFFEFCFA0F1F3F7FA03E7DDDF1E3C78FFFB1F0E23F7FFF51584771C5C18307FEA36CA74E60AA6B0409ACA66A9EC155F4E9112345708A2B8457E722608EE1157408", 0, signature, PUBLIC_VIGIK_KEYLEN, &dl); + signature_len = dl; + */ + uint8_t rev_sig[128]; - reverse_array(d->rsa_signature, sizeof(d->rsa_signature), rev_sig); + reverse_array_copy(d->rsa_signature, sizeof(d->rsa_signature), rev_sig); PrintAndLogEx(INFO, "Raw signature reverse"); print_hex_noascii_break(rev_sig, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2); @@ -1532,10 +1538,6 @@ int vigik_verify(mfc_vigik_t *d) { // sha1 hash H = 20 bytes, 160 bits // padding = 20 bytes, 96 bits - -// ref: MIFARE Classic EV1 Originality Signature Validation -#define PUBLIC_VIGIK_KEYLEN 128 - uint8_t i; bool is_valid = false; diff --git a/client/src/util.c b/client/src/util.c index b13c5e3a9..ea33de446 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -300,7 +300,6 @@ void print_hex_noascii_break(const uint8_t *data, const size_t len, uint8_t brea } } - static void print_buffer_ex(const uint8_t *data, const size_t len, int level, uint8_t breaks) { // sanity checks diff --git a/common/commonutil.c b/common/commonutil.c index 601dc20e4..c346d7bf7 100644 --- a/common/commonutil.c +++ b/common/commonutil.c @@ -269,3 +269,27 @@ uint16_t get_sw(const uint8_t *d, uint16_t n) { n -= 2; return (d[n] << 8 | d[n + 1]); } + +// reverse same array +void reverse_array(uint8_t *d, size_t n) { + if (d == NULL || n < 2) { + return; + } + + for (int i = 0, j = n - 1; i < j; ++i, --j) { + d[i] ^= d[j]; + d[j] ^= d[i]; + d[i] ^= d[j]; + } +} + +// reverse src array into dest array +void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest) { + if (src == NULL || src_len == 0 || dest == NULL) { + return; + } + + for (int i = 0; i < src_len; i++) { + dest[i] = src[(src_len - 1) - i]; + } +} \ No newline at end of file diff --git a/common/commonutil.h b/common/commonutil.h index 8e800f25f..7beb95355 100644 --- a/common/commonutil.h +++ b/common/commonutil.h @@ -86,4 +86,8 @@ uint32_t rotl(uint32_t a, uint8_t n); uint32_t rotr(uint32_t a, uint8_t n); uint16_t get_sw(const uint8_t *d, uint16_t n); + +void reverse_array(uint8_t *d, size_t n); +void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest); + #endif From 0f70df5de3da99293741a668786b076bb68ff548 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Mon, 6 Mar 2023 19:55:41 +0800 Subject: [PATCH 681/759] Add TCP connection support on Windows The Windows Sockets 2 API is similar to the BSD Sockets API, so I can reuse a lot of code in uart_posix.c --- client/src/uart/uart_win32.c | 258 ++++++++++++++++++++++++++++++++--- 1 file changed, 241 insertions(+), 17 deletions(-) diff --git a/client/src/uart/uart_win32.c b/client/src/uart/uart_win32.c index 1e57daeb2..cd610c8fa 100644 --- a/client/src/uart/uart_win32.c +++ b/client/src/uart/uart_win32.c @@ -27,14 +27,24 @@ // The windows serial port implementation #ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN #include +#include +#include typedef struct { HANDLE hPort; // Serial port handle DCB dcb; // Device control settings COMMTIMEOUTS ct; // Serial port time-out configuration + SOCKET hSocket; // Socket handle } serial_port_windows_t; +// this is for TCP connection +struct timeval timeout = { + .tv_sec = 0, // 0 second + .tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000 +}; + uint32_t newtimeout_value = 0; bool newtimeout_pending = false; @@ -69,11 +79,111 @@ static int uart_reconfigure_timeouts_polling(serial_port sp) { serial_port uart_open(const char *pcPortName, uint32_t speed) { char acPortName[255] = {0}; serial_port_windows_t *sp = calloc(sizeof(serial_port_windows_t), sizeof(uint8_t)); + sp->hSocket = INVALID_SOCKET; // default: serial port if (sp == 0) { PrintAndLogEx(WARNING, "UART failed to allocate memory\n"); return INVALID_SERIAL_PORT; } + + char *prefix = strdup(pcPortName); + if (prefix == NULL) { + PrintAndLogEx(ERR, "error: string duplication"); + free(sp); + return INVALID_SERIAL_PORT; + } + str_lower(prefix); + + if (memcmp(prefix, "tcp:", 4) == 0) { + free(prefix); + + if (strlen(pcPortName) <= 4) { + free(sp); + return INVALID_SERIAL_PORT; + } + + struct addrinfo *addr = NULL, *rp; + + char *addrstr = strdup(pcPortName + 4); + if (addrstr == NULL) { + PrintAndLogEx(ERR, "error: string duplication"); + free(sp); + return INVALID_SERIAL_PORT; + } + + timeout.tv_usec = UART_TCP_CLIENT_RX_TIMEOUT_MS * 1000; + + char *colon = strrchr(addrstr, ':'); + const char *portstr; + if (colon) { + portstr = colon + 1; + *colon = '\0'; + } else { + portstr = "18888"; + } + + WSADATA wsaData; + struct addrinfo info; + int iResult; + + iResult = WSAStartup(MAKEWORD(2,2), &wsaData); + if (iResult != 0) { + PrintAndLogEx(ERR, "error: WSAStartup failed with error: %d", iResult); + free(sp); + return INVALID_SERIAL_PORT; + } + + memset(&info, 0, sizeof(info)); + info.ai_socktype = SOCK_STREAM; + info.ai_protocol = IPPROTO_TCP; + + int s = getaddrinfo(addrstr, portstr, &info, &addr); + if (s != 0) { + PrintAndLogEx(ERR, "error: getaddrinfo: %s", gai_strerror(s)); + freeaddrinfo(addr); + free(addrstr); + free(sp); + WSACleanup(); + return INVALID_SERIAL_PORT; + } + + SOCKET hSocket = INVALID_SOCKET; + for (rp = addr; rp != NULL; rp = rp->ai_next) { + hSocket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + + if (hSocket == INVALID_SOCKET) + continue; + + if (connect(hSocket, rp->ai_addr, (int)rp->ai_addrlen) != INVALID_SOCKET) + break; + + closesocket(hSocket); + hSocket = INVALID_SOCKET; + } + + freeaddrinfo(addr); + free(addrstr); + + if (rp == NULL) { /* No address succeeded */ + PrintAndLogEx(ERR, "error: Could not connect"); + WSACleanup(); + free(sp); + return INVALID_SERIAL_PORT; + } + + sp->hSocket = hSocket; + + int one = 1; + int res = setsockopt(sp->hSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)); + if (res != 0) { + closesocket(hSocket); + WSACleanup(); + free(sp); + return INVALID_SERIAL_PORT; + } + return sp; + } + // Copy the input "com?" to "\\.\COM?" format snprintf(acPortName, sizeof(acPortName), "\\\\.\\%s", pcPortName); _strupr(acPortName); @@ -120,8 +230,14 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { } void uart_close(const serial_port sp) { - if (((serial_port_windows_t *)sp)->hPort != INVALID_HANDLE_VALUE) - CloseHandle(((serial_port_windows_t *)sp)->hPort); + serial_port_windows_t *spw = (serial_port_windows_t *)sp; + if (spw->hSocket != INVALID_SOCKET){ + shutdown(spw->hSocket, SD_BOTH); + closesocket(spw->hSocket); + WSACleanup(); + } + if (spw->hPort != INVALID_HANDLE_VALUE) + CloseHandle(spw->hPort); free(sp); } @@ -163,31 +279,139 @@ uint32_t uart_get_speed(const serial_port sp) { } int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uint32_t *pszRxLen) { - uart_reconfigure_timeouts_polling(sp); - int res = ReadFile(((serial_port_windows_t *)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL); - if (res) - return PM3_SUCCESS; + serial_port_windows_t *spw = (serial_port_windows_t *)sp; + if (spw->hSocket == INVALID_SOCKET) { // serial port + uart_reconfigure_timeouts_polling(sp); - int errorcode = GetLastError(); + int res = ReadFile(((serial_port_windows_t *)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL); + if (res) + return PM3_SUCCESS; - if (res == 0 && errorcode == 2) { - return PM3_EIO; + int errorcode = GetLastError(); + + if (res == 0 && errorcode == 2) { + return PM3_EIO; + } + + return PM3_ENOTTY; } + else { // TCP + uint32_t byteCount; // FIONREAD returns size on 32b + fd_set rfds; + struct timeval tv; - return PM3_ENOTTY; + if (newtimeout_pending) { + timeout.tv_usec = newtimeout_value * 1000; + newtimeout_pending = false; + } + // Reset the output count + *pszRxLen = 0; + do { + // Reset file descriptor + FD_ZERO(&rfds); + FD_SET(spw->hSocket, &rfds); + tv = timeout; + // the first argument nfds is ignored in Windows + int res = select(0, &rfds, NULL, NULL, &tv); + + // Read error + if (res == SOCKET_ERROR) { + return PM3_EIO; + } + + // Read time-out + if (res == 0) { + if (*pszRxLen == 0) { + // We received no data + return PM3_ENODATA; + } else { + // We received some data, but nothing more is available + return PM3_SUCCESS; + } + } + + // Retrieve the count of the incoming bytes + res = ioctlsocket(spw->hSocket, FIONREAD, (u_long *)&byteCount); + // PrintAndLogEx(ERR, "UART:: RX ioctl res %d byteCount %u", res, byteCount); + if (res == SOCKET_ERROR) return PM3_ENOTTY; + + // Cap the number of bytes, so we don't overrun the buffer + if (pszMaxRxLen - (*pszRxLen) < byteCount) { + // PrintAndLogEx(ERR, "UART:: RX prevent overrun (have %u, need %u)", pszMaxRxLen - (*pszRxLen), byteCount); + byteCount = pszMaxRxLen - (*pszRxLen); + } + + // There is something available, read the data + res = recv(spw->hSocket, (char *)pbtRx + (*pszRxLen), byteCount, 0); + + // Stop if the OS has some troubles reading the data + if (res <= 0) { // includes 0(gracefully closed) and -1(SOCKET_ERROR) + return PM3_EIO; + } + + *pszRxLen += res; + + if (*pszRxLen == pszMaxRxLen) { + // We have all the data we wanted. + return PM3_SUCCESS; + } + } while (byteCount); + + return PM3_SUCCESS; + } } int uart_send(const serial_port sp, const uint8_t *p_tx, const uint32_t len) { - DWORD txlen = 0; - int res = WriteFile(((serial_port_windows_t *)sp)->hPort, p_tx, len, &txlen, NULL); - if (res) + serial_port_windows_t *spw = (serial_port_windows_t *)sp; + if (spw->hSocket == INVALID_SOCKET) { // serial port + DWORD txlen = 0; + int res = WriteFile(((serial_port_windows_t *)sp)->hPort, p_tx, len, &txlen, NULL); + if (res) + return PM3_SUCCESS; + + int errorcode = GetLastError(); + if (res == 0 && errorcode == 2) { + return PM3_EIO; + } + return PM3_ENOTTY; + } + else { // TCP + uint32_t pos = 0; + fd_set wfds; + struct timeval tv; + + while (pos < len) { + // Reset file descriptor + FD_ZERO(&wfds); + FD_SET(spw->hSocket, &wfds); + tv = timeout; + // the first argument nfds is ignored in Windows + int res = select(0, NULL, &wfds, NULL, &tv); + + // Write error + if (res == SOCKET_ERROR) { + PrintAndLogEx(ERR, "UART:: write error (%d)", res); + return PM3_ENOTTY; + } + + // Write time-out + if (res == 0) { + PrintAndLogEx(ERR, "UART:: write time-out"); + return PM3_ETIMEOUT; + } + + // Send away the bytes + res = send(spw->hSocket, (const char *)p_tx + pos, len - pos, 0); + + // Stop if the OS has some troubles sending the data + if (res <= 0) + return PM3_EIO; + + pos += res; + } return PM3_SUCCESS; - int errorcode = GetLastError(); - if (res == 0 && errorcode == 2) { - return PM3_EIO; } - return PM3_ENOTTY; } #endif From d61c972ff9aec9e5fe5a0ee5d7af55c74dd5fb52 Mon Sep 17 00:00:00 2001 From: Self Not Found Date: Mon, 6 Mar 2023 20:26:34 +0800 Subject: [PATCH 682/759] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 937c092ea..56143f08e 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] + - Added TCP connection support on Windows (@wh201906) - Added `data num` - easy convert between dec/hex/bin (@iceman1001) - Fixed `hf mfdes info` - now handles incorrect tag answers better (@didiera) - Fixed `hf mfdes` generic help text is now correct (@didiera) From dba8d811fddcb45468350a863f4b12af4fa36962 Mon Sep 17 00:00:00 2001 From: Self Not Found Date: Mon, 6 Mar 2023 22:02:33 +0800 Subject: [PATCH 683/759] Link ws2_32 --- client/CMakeLists.txt | 3 +++ client/Makefile | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 0bd8bd5cc..894af00e7 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -584,6 +584,9 @@ if (MINGW) set(CMAKE_C_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS "-mno-ms-bitfields -fexec-charset=cp850 ${CMAKE_CXX_FLAGS}") + + # link Winsock2 + set(ADDITIONAL_LNK ws2_32 ${ADDITIONAL_LNK}) endif (MINGW) target_include_directories(proxmark3 PRIVATE diff --git a/client/Makefile b/client/Makefile index b08eb0acb..d0cee355e 100644 --- a/client/Makefile +++ b/client/Makefile @@ -93,7 +93,6 @@ LUALIBLD = LUAPLATFORM = generic ifneq (,$(findstring MINGW,$(platform))) LUAPLATFORM = mingw - LDLIBS += -lws2_32 else ifeq ($(platform),Darwin) LUAPLATFORM = macosx @@ -103,6 +102,11 @@ else endif endif +## Winsock2 +ifneq (,$(findstring MINGW,$(platform))) + LDLIBS += -lws2_32 +endif + ## Reveng REVENGLIBPATH = ./deps/reveng REVENGLIBINC = -I$(REVENGLIBPATH) From ceeb98bd389b41f895432dd4210bd6d9d64c068a Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 7 Mar 2023 11:20:23 +0800 Subject: [PATCH 684/759] Update Troubleshooting, libQt5Core.so.5 not found Update the version number of Ubuntu which has the same problem I checked newer Ubuntu version 22.04 WSL 1 still have problem and solved by same solution sudo strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 Signed-off-by: Jack --- doc/md/Installation_Instructions/Troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/md/Installation_Instructions/Troubleshooting.md b/doc/md/Installation_Instructions/Troubleshooting.md index 59735da34..d3fbab571 100644 --- a/doc/md/Installation_Instructions/Troubleshooting.md +++ b/doc/md/Installation_Instructions/Troubleshooting.md @@ -224,7 +224,7 @@ Try running it with ## libQt5Core.so.5 not found ^[Top](#top) -On WSL1 / updated to Ubuntu 20.04, there is a slight chance you experience problems when compiling the repo with QT5. +On WSL1 / updated to Ubuntu 20.04 and 22.04, there is a slight chance you experience problems when compiling the repo with QT5. The following steps is needed to make the development environment happy again. ``` sudo apt reinstall qtbase5-dev From adefd302f55174d74fb5a30332188a035b8e589b Mon Sep 17 00:00:00 2001 From: astrid rowland Date: Wed, 8 Mar 2023 12:45:08 -0600 Subject: [PATCH 685/759] cleaned up original patch (same keys), added new keys from The Horde --- client/dictionaries/mfc_default_keys.dic | 120 +++++++++++------------ 1 file changed, 57 insertions(+), 63 deletions(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 381eabaf5..3c43a350f 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1978,74 +1978,68 @@ FE98F38F3EE2 # added by colonelborkmundus # "the more, the marriott" mifare project # -# 1k - graduate hotel -C49DAE1C6049 -209A2B910545 -# -# 1k - westin -8C29F8320617 -5697519A8F02 +# 20230125-01, Elite Member Marriott Rewards +43012BD9EB87 +# 20230125-02, Elite Member Marriott Rewards +3119A70628EB +# 20230125-03, Elite Member Marriott Rewards +23C9FDD9A366 +# 20230125-04, Elite Member Marriott Rewards +7B4DFC6D6525 +# 20230125-05, Elite Member Marriott Rewards +1330824CD356 +# 20230125-06, Elite Member Marriott Rewards +30AAD6A711EF +# 20230125-07, Fairfield Inn & Suites Marriott +7B3B589A5525 +# 20230125-08, Moxy Hotels +20C166C00ADB +# 20230125-09, Westin Hotels & Resorts 7D0A1C277C05 2058580A941F +8C29F8320617 +# 20230125-10, Westin Hotels & Resorts C40964215509 D44CFC178460 -# -# 1k - marriott -7B4DFC6D6525 -23C9FDD9A366 -3119A70628EB -30AAD6A711EF -1330824CD356 -43012BD9EB87 -035C70558D7B -9966588CB9A0 -12AB4C37BB8B -# -# 1k - AC hotels marriott -8EA8EC3F2320 +5697519A8F02 +# 20230125-12, AC Hotels Marriott 7B56B2B38725 -# -# 1k - the ritz-carlton -30FB20D0EFEF -D20289CD9E6E -66A3B064CC4B -D18296CD9E6E -# -# 1k - unknown -722538817225 -# -# 1k - aria resort & casino -316B8FAA12EF +# 20230125-13, AC Hotels Marriott +8EA8EC3F2320 +# 20230125-14, Waldorf Astoria Chicago +011C6CF459E8 +# 20230125-24, Aria Resort & Casino A18D9F4E75AF -# -# 1k - fairfield inn & suites marriott -7AEB989A5525 -7B3B589A5525 -215E9DED9DDF -334E91BE3377 -310308EC52EF -# -# 1k - residence inn marriott -F72CD208FDF9 -# -# 1k - sheraton -42FC522DE987 -# -# 1k - millenium hotels -132F641C948B -# -# 1k - moxy hotels -20C166C00ADB -9EE3896C4530 -# -# 1k - residence inn marriott +# 20230125-25, Aria Resort & Casino +316B8FAA12EF +# 20230125-26, Residence Inn Mariott 3122AE5341EB -# -# 1k - americinn -8AC04C1A4A25 -# -# 1k - the industrialist +# 20230125-27, Residence Inn Mariott +F72CD208FDF9 +# 20230125-28, Marriott +035C70558D7B +# 20230125-29, Marriott +12AB4C37BB8B +# 20230125-30, Marriott +9966588CB9A0 +# 20230125-31, Sheraton +42FC522DE987 +# 20230125-32, The Industrialist 2158E314C3DF -# -# 1k - waldorf astoria -011C6CF459E8 \ No newline at end of file +# 20230125-39, The Ritz-Carlton Balharbour +30FB20D0EFEF +# 20230125-40, The Ritz-Carlton Balharbour +66A3B064CC4B +# 20230125-41, The Ritz-Carlton Balharbour +D18296CD9E6E +# 20230125-42, The Ritz-Carlton Balharbour +D20289CD9E6E +# 20230125-44, Graduate Hotels +209A2B910545 +C49DAE1C6049 +# 20230125-46, AmericInn +8AC04C1A4A25 +# 20230129-53, Marriott Bonvoy +6E029927600D +3E173F64C01C +C670A9AD6066 \ No newline at end of file From 68c74fd3aec6533b2b6fdd674fb3ccbf2e6af478 Mon Sep 17 00:00:00 2001 From: astrid rowland Date: Wed, 8 Mar 2023 13:14:20 -0600 Subject: [PATCH 686/759] removed unconfirmed unleashed keys --- client/dictionaries/mfc_default_keys.dic | 66 +---------- how q | 142 +++++++++++++++++++++++ 2 files changed, 143 insertions(+), 65 deletions(-) create mode 100644 how q diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 3c43a350f..68bb83ae5 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1910,70 +1910,6 @@ D144BD193063 8627C10A7014 453857395635 # -# flipper unleashed additions -# -# Transport cards -E954024EE754 -0CD464CDC100 -BC305FE2DA65 -CF0EC6ACF2F9 -F7A545095C49 -6862FD600F78 -72A0C485D3F7 -6A530C91F85B -# RENFE MADRID (TRAIN) Extracted with detect reader -701AA491A4A5 -12BA20088ED3 -# MISC KEYS FROM MY OLD ACCESS CARDS -F18D91EE3033 -0E726E11CFCC -1D14130D1A0B -4ADLE273EAFL -3DFL4C8000A1 -E64Q986Q5D94 -201106141030 -# D144BD193063 (dupe) -01E2C14F1B18 -0380293A9E6D -08A55BC96DC1 -08ED3F92AA53 -0D61BA88789C -190E6242CE7B -1A8CFF2F1BC7 -25FE2B4E4FA9 -321803E38664 -381F84DB8134 -38540EEE8B1C -42F82DB5C4AF -507A6181E4BF -549BB4FD70C4 -57059FFD3EE6 -5E696FA0EAD1 -6036F9D72D68 -6611DFFAAE32 -6AC79644E0CD -735DD20237A9 -79E8B59A51E0 -7B6C00CBAC92 -7C3AF198425F -81C0BBCE32E9 -8D2B780A148D -9001D0E23F8C -A8700E07A58F -AE683AC2A232 -B6728D9B95BA -C290A397F84A -CA22AF33A19B -CBC83E1548B4 -CC5F59A0CE0A -D410EFF9113E -DE5865F29C44 -E108EA397A9A -E10F0E7A8DD5 -F833E24C3F1C -FA8CA10C7D59 -FE98F38F3EE2 -# ########################################## # added by colonelborkmundus # "the more, the marriott" mifare project @@ -2042,4 +1978,4 @@ C49DAE1C6049 # 20230129-53, Marriott Bonvoy 6E029927600D 3E173F64C01C -C670A9AD6066 \ No newline at end of file +C670A9AD6066i \ No newline at end of file diff --git a/how q b/how q new file mode 100644 index 000000000..a3e923d6d --- /dev/null +++ b/how q @@ -0,0 +1,142 @@ +commit 1aa93869204215ebf232ae9bbf5ed8b911481b9f (HEAD -> origin/dictionaries) +Author: astrid rowland +Date: Wed Mar 8 12:45:08 2023 -0600 + + cleaned up original patch (same keys), added new keys from The Horde + +diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic +index 881c72df0..8368eee31 100644 +--- a/client/dictionaries/mfc_default_keys.dic ++++ b/client/dictionaries/mfc_default_keys.dic +@@ -1914,74 +1914,68 @@ D144BD193063 + # added by colonelborkmundus + # "the more, the marriott" mifare project + # +-# 1k - graduate hotel +-C49DAE1C6049 +-209A2B910545 +-# +-# 1k - westin +-8C29F8320617 +-5697519A8F02 ++# 20230125-01, Elite Member Marriott Rewards ++43012BD9EB87 ++# 20230125-02, Elite Member Marriott Rewards ++3119A70628EB ++# 20230125-03, Elite Member Marriott Rewards ++23C9FDD9A366 ++# 20230125-04, Elite Member Marriott Rewards ++7B4DFC6D6525 ++# 20230125-05, Elite Member Marriott Rewards ++1330824CD356 ++# 20230125-06, Elite Member Marriott Rewards ++30AAD6A711EF ++# 20230125-07, Fairfield Inn & Suites Marriott ++7B3B589A5525 ++# 20230125-08, Moxy Hotels ++20C166C00ADB ++# 20230125-09, Westin Hotels & Resorts + 7D0A1C277C05 + 2058580A941F ++8C29F8320617 ++# 20230125-10, Westin Hotels & Resorts + C40964215509 + D44CFC178460 +-# +-# 1k - marriott +-7B4DFC6D6525 +-23C9FDD9A366 +-3119A70628EB +-30AAD6A711EF +-1330824CD356 +-43012BD9EB87 ++5697519A8F02 ++# 20230125-12, AC Hotels Marriott ++7B56B2B38725 ++# 20230125-13, AC Hotels Marriott ++8EA8EC3F2320 ++# 20230125-14, Waldorf Astoria Chicago ++011C6CF459E8 ++# 20230125-24, Aria Resort & Casino ++A18D9F4E75AF ++# 20230125-25, Aria Resort & Casino ++316B8FAA12EF ++# 20230125-26, Residence Inn Mariott ++3122AE5341EB ++# 20230125-27, Residence Inn Mariott ++F72CD208FDF9 ++# 20230125-28, Marriott + 035C70558D7B +-9966588CB9A0 ++# 20230125-29, Marriott + 12AB4C37BB8B +-# +-# 1k - AC hotels marriott +-8EA8EC3F2320 +-7B56B2B38725 +-# +-# 1k - the ritz-carlton ++# 20230125-30, Marriott ++9966588CB9A0 ++# 20230125-31, Sheraton ++42FC522DE987 ++# 20230125-32, The Industrialist ++2158E314C3DF ++# 20230125-39, The Ritz-Carlton Balharbour + 30FB20D0EFEF +-D20289CD9E6E ++# 20230125-40, The Ritz-Carlton Balharbour + 66A3B064CC4B ++# 20230125-41, The Ritz-Carlton Balharbour + D18296CD9E6E +-# +-# 1k - unknown +-722538817225 +-# +-# 1k - aria resort & casino +-316B8FAA12EF +-A18D9F4E75AF +-# +-# 1k - fairfield inn & suites marriott +-7AEB989A5525 +-7B3B589A5525 +-215E9DED9DDF +-334E91BE3377 +-310308EC52EF +-# +-# 1k - residence inn marriott +-F72CD208FDF9 +-# +-# 1k - sheraton +-42FC522DE987 +-# +-# 1k - millenium hotels +-132F641C948B +-# +-# 1k - moxy hotels +-20C166C00ADB +-9EE3896C4530 +-# +-# 1k - residence inn marriott +-3122AE5341EB +-# +-# 1k - americinn  ++# 20230125-42, The Ritz-Carlton Balharbour ++D20289CD9E6E ++# 20230125-44, Graduate Hotels ++209A2B910545 ++C49DAE1C6049 ++# 20230125-46, AmericInn + 8AC04C1A4A25 +-# +-# 1k - the industrialist +-2158E314C3DF +-# +-# 1k - waldorf astoria +-011C6CF459E8 +\ No newline at end of file ++# 20230129-53, Marriott Bonvoy ++6E029927600D ++3E173F64C01C ++C670A9AD6066 +\ No newline at end of file From 2658b2c52fe9a884648a6fe66fac5821c719a85e Mon Sep 17 00:00:00 2001 From: astrid rowland Date: Wed, 8 Mar 2023 13:19:30 -0600 Subject: [PATCH 687/759] deleted unnecessary file --- how q | 142 ---------------------------------------------------------- 1 file changed, 142 deletions(-) delete mode 100644 how q diff --git a/how q b/how q deleted file mode 100644 index a3e923d6d..000000000 --- a/how q +++ /dev/null @@ -1,142 +0,0 @@ -commit 1aa93869204215ebf232ae9bbf5ed8b911481b9f (HEAD -> origin/dictionaries) -Author: astrid rowland -Date: Wed Mar 8 12:45:08 2023 -0600 - - cleaned up original patch (same keys), added new keys from The Horde - -diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic -index 881c72df0..8368eee31 100644 ---- a/client/dictionaries/mfc_default_keys.dic -+++ b/client/dictionaries/mfc_default_keys.dic -@@ -1914,74 +1914,68 @@ D144BD193063 - # added by colonelborkmundus - # "the more, the marriott" mifare project - # --# 1k - graduate hotel --C49DAE1C6049 --209A2B910545 --# --# 1k - westin --8C29F8320617 --5697519A8F02 -+# 20230125-01, Elite Member Marriott Rewards -+43012BD9EB87 -+# 20230125-02, Elite Member Marriott Rewards -+3119A70628EB -+# 20230125-03, Elite Member Marriott Rewards -+23C9FDD9A366 -+# 20230125-04, Elite Member Marriott Rewards -+7B4DFC6D6525 -+# 20230125-05, Elite Member Marriott Rewards -+1330824CD356 -+# 20230125-06, Elite Member Marriott Rewards -+30AAD6A711EF -+# 20230125-07, Fairfield Inn & Suites Marriott -+7B3B589A5525 -+# 20230125-08, Moxy Hotels -+20C166C00ADB -+# 20230125-09, Westin Hotels & Resorts - 7D0A1C277C05 - 2058580A941F -+8C29F8320617 -+# 20230125-10, Westin Hotels & Resorts - C40964215509 - D44CFC178460 --# --# 1k - marriott --7B4DFC6D6525 --23C9FDD9A366 --3119A70628EB --30AAD6A711EF --1330824CD356 --43012BD9EB87 -+5697519A8F02 -+# 20230125-12, AC Hotels Marriott -+7B56B2B38725 -+# 20230125-13, AC Hotels Marriott -+8EA8EC3F2320 -+# 20230125-14, Waldorf Astoria Chicago -+011C6CF459E8 -+# 20230125-24, Aria Resort & Casino -+A18D9F4E75AF -+# 20230125-25, Aria Resort & Casino -+316B8FAA12EF -+# 20230125-26, Residence Inn Mariott -+3122AE5341EB -+# 20230125-27, Residence Inn Mariott -+F72CD208FDF9 -+# 20230125-28, Marriott - 035C70558D7B --9966588CB9A0 -+# 20230125-29, Marriott - 12AB4C37BB8B --# --# 1k - AC hotels marriott --8EA8EC3F2320 --7B56B2B38725 --# --# 1k - the ritz-carlton -+# 20230125-30, Marriott -+9966588CB9A0 -+# 20230125-31, Sheraton -+42FC522DE987 -+# 20230125-32, The Industrialist -+2158E314C3DF -+# 20230125-39, The Ritz-Carlton Balharbour - 30FB20D0EFEF --D20289CD9E6E -+# 20230125-40, The Ritz-Carlton Balharbour - 66A3B064CC4B -+# 20230125-41, The Ritz-Carlton Balharbour - D18296CD9E6E --# --# 1k - unknown --722538817225 --# --# 1k - aria resort & casino --316B8FAA12EF --A18D9F4E75AF --# --# 1k - fairfield inn & suites marriott --7AEB989A5525 --7B3B589A5525 --215E9DED9DDF --334E91BE3377 --310308EC52EF --# --# 1k - residence inn marriott --F72CD208FDF9 --# --# 1k - sheraton --42FC522DE987 --# --# 1k - millenium hotels --132F641C948B --# --# 1k - moxy hotels --20C166C00ADB --9EE3896C4530 --# --# 1k - residence inn marriott --3122AE5341EB --# --# 1k - americinn  -+# 20230125-42, The Ritz-Carlton Balharbour -+D20289CD9E6E -+# 20230125-44, Graduate Hotels -+209A2B910545 -+C49DAE1C6049 -+# 20230125-46, AmericInn - 8AC04C1A4A25 --# --# 1k - the industrialist --2158E314C3DF --# --# 1k - waldorf astoria --011C6CF459E8 -\ No newline at end of file -+# 20230129-53, Marriott Bonvoy -+6E029927600D -+3E173F64C01C -+C670A9AD6066 -\ No newline at end of file From f56e066e50c524967ceade653c07bf54a6af2d9a Mon Sep 17 00:00:00 2001 From: astrid rowland Date: Wed, 8 Mar 2023 13:24:12 -0600 Subject: [PATCH 688/759] accidentally a typo, thanks vim --- client/dictionaries/mfc_default_keys.dic | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 68bb83ae5..8368eee31 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1978,4 +1978,4 @@ C49DAE1C6049 # 20230129-53, Marriott Bonvoy 6E029927600D 3E173F64C01C -C670A9AD6066i \ No newline at end of file +C670A9AD6066 \ No newline at end of file From 917b37178e400110a0b720d6facce7fbea50f635 Mon Sep 17 00:00:00 2001 From: GuruSteve Date: Thu, 9 Mar 2023 16:34:50 -0700 Subject: [PATCH 689/759] Updated verbiage WRT KeyAccess to make it clearer --- client/src/cmdhficlass.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 53bb483ec..1c67f98c4 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -594,17 +594,17 @@ static void mem_app_config(const picopass_hdr_t *hdr) { PrintAndLogEx(INFO, " * Kd, Debit key, AA1 Kc, Credit key, AA2 *"); uint8_t keyAccess = isset(mem, 0x01); if (keyAccess) { - PrintAndLogEx(INFO, " Read A....... debit"); - PrintAndLogEx(INFO, " Read B....... credit"); - PrintAndLogEx(INFO, " Write A...... debit"); - PrintAndLogEx(INFO, " Write B...... credit"); + PrintAndLogEx(INFO, " Read AA1....... debit"); + PrintAndLogEx(INFO, " Write AA1...... debit"); + PrintAndLogEx(INFO, " Read AA2....... credit"); + PrintAndLogEx(INFO, " Write AA2...... credit"); PrintAndLogEx(INFO, " Debit........ debit or credit"); PrintAndLogEx(INFO, " Credit....... credit"); } else { - PrintAndLogEx(INFO, " Read A....... debit or credit"); - PrintAndLogEx(INFO, " Read B....... debit or credit"); - PrintAndLogEx(INFO, " Write A...... credit"); - PrintAndLogEx(INFO, " Write B...... credit"); + PrintAndLogEx(INFO, " Read AA1....... debit or credit"); + PrintAndLogEx(INFO, " Write AA1...... credit"); + PrintAndLogEx(INFO, " Read AA2....... debit or credit"); + PrintAndLogEx(INFO, " Write AA2...... credit"); PrintAndLogEx(INFO, " Debit........ debit or credit"); PrintAndLogEx(INFO, " Credit....... credit"); } From 359bb534f9cc74ce5827905b5ff5901128e37345 Mon Sep 17 00:00:00 2001 From: GuruSteve Date: Thu, 9 Mar 2023 18:58:46 -0700 Subject: [PATCH 690/759] Updated verbiage WRT iClass info (KeyAccess) to make it clearer --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56143f08e..b8634480f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed `hf iclass view` - show credentials on a decrypted dump (@natesales) - Show NTAG213TT tamper info in `hf mfu info` and add commands for configuring it's tamper feature (@mjaksn) - Add Mifare Classic EV1 signature write support to gen4 magic tag lua script (@augustozanellato) + - ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) @@ -176,7 +177,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added new standalone mode `lf_em4100rsww` (@zabszk) - Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz) - Added `script run hf_mf_hid_sim.lua` (@micsen) - + - Changed verbiage on `hf iclass info` KeyAccess area to be congruent with AA1 and AA2 areas (@GuruSteve) ## [Frostbit.4.14831][2022-01-11] - Changed Wiegand format lookup - now case-insensitive (@iceman1001) From 0f206ccef4fff3cf04e3e74bf249d280e759d034 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Sat, 11 Mar 2023 00:27:48 +0800 Subject: [PATCH 691/759] Fix client build on Android Tested with: cmake 3.10.2.4988404/3.24.1 ndk 25.2.9519653 Build command: cmake \ -DCMAKE_TOOLCHAIN_FILE=/home/gitpod/androidsdk/ndk/25.2.9519653/build/cmake/android.toolchain.cmake \ -DANDROID_ABI=armeabi-v7a \ -DANDROID_NATIVE_API_LEVEL=android-19 \ -DSKIPBT=1 -DSKIPPYTHON=1 -DSKIPPTHREAD=1 (armeabi-v7a, arm64-v8a, x86 and x86_64 are all tested) --- client/CMakeLists.txt | 3 ++- client/deps/hardnested.cmake | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 894af00e7..ee1ddcc25 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -163,11 +163,12 @@ endif (NOT SKIPJANSSONSYSTEM EQUAL 1) if(EMBED_BZIP2) set(BZIP2_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/deps/bzip2/src/bzip2) + # Specify SOURCE_DIR will cause some errors ExternalProject_Add(bzip2 GIT_REPOSITORY https://android.googlesource.com/platform/external/bzip2 GIT_TAG platform-tools-30.0.2 PREFIX deps/bzip2 - SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/bzip2 + # SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/bzip2 CONFIGURE_COMMAND mkdir -p ${BZIP2_BUILD_DIR} && git archive --format tar HEAD | tar -C ${BZIP2_BUILD_DIR} -x BUILD_IN_SOURCE ON BUILD_COMMAND make -C ${BZIP2_BUILD_DIR} -j4 CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} LD=${CMAKE_C_COMPILER} AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} ${CFLAGS_EXTERNAL_LIB} libbz2.a diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index 524d4c939..cab2aba86 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -17,7 +17,7 @@ target_compile_definitions(pm3rrg_rdv4_hardnested_nosimd PRIVATE NOSIMD_BUILD) ## Mingw platforms: AMD64 set(X86_CPUS x86 x86_64 i686 AMD64) set(ARM64_CPUS arm64 aarch64) -set(ARM32_CPUS armel armhf) +set(ARM32_CPUS armel armv7-a) message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") From 62816a042915796646a516077ed6ac694eb3e7d5 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Sat, 11 Mar 2023 00:44:06 +0800 Subject: [PATCH 692/759] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8634480f..5d180053a 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 the client build on Android (@wh201906) - Added TCP connection support on Windows (@wh201906) - Added `data num` - easy convert between dec/hex/bin (@iceman1001) - Fixed `hf mfdes info` - now handles incorrect tag answers better (@didiera) From adcfab2775df3cd6c2e7fa18e51bacd091d91415 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Sat, 11 Mar 2023 00:47:24 +0800 Subject: [PATCH 693/759] Fix hardnested.cmake --- client/deps/hardnested.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/deps/hardnested.cmake b/client/deps/hardnested.cmake index cab2aba86..ec545e2a8 100644 --- a/client/deps/hardnested.cmake +++ b/client/deps/hardnested.cmake @@ -17,7 +17,7 @@ target_compile_definitions(pm3rrg_rdv4_hardnested_nosimd PRIVATE NOSIMD_BUILD) ## Mingw platforms: AMD64 set(X86_CPUS x86 x86_64 i686 AMD64) set(ARM64_CPUS arm64 aarch64) -set(ARM32_CPUS armel armv7-a) +set(ARM32_CPUS armel armhf armv7-a) message(STATUS "CMAKE_SYSTEM_PROCESSOR := ${CMAKE_SYSTEM_PROCESSOR}") From f63957748dadc3d86c54283c85f20ea9c14a79d7 Mon Sep 17 00:00:00 2001 From: GuruSteve Date: Sat, 11 Mar 2023 02:58:34 -0700 Subject: [PATCH 694/759] Previous PR added change to CHANGELOG.md in wrong place --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d180053a..d17b8a97d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed `hf iclass view` - show credentials on a decrypted dump (@natesales) - Show NTAG213TT tamper info in `hf mfu info` and add commands for configuring it's tamper feature (@mjaksn) - Add Mifare Classic EV1 signature write support to gen4 magic tag lua script (@augustozanellato) + - Changed verbiage on `hf iclass info` KeyAccess area to be congruent with AA1 and AA2 areas (@GuruSteve) - ## [Nitride.4.16191][2023-01-29] @@ -178,7 +179,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added new standalone mode `lf_em4100rsww` (@zabszk) - Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz) - Added `script run hf_mf_hid_sim.lua` (@micsen) - - Changed verbiage on `hf iclass info` KeyAccess area to be congruent with AA1 and AA2 areas (@GuruSteve) ## [Frostbit.4.14831][2022-01-11] - Changed Wiegand format lookup - now case-insensitive (@iceman1001) From ce8c210dbb80380e37d72f75410f5e1175624bbf Mon Sep 17 00:00:00 2001 From: GuruSteve Date: Sat, 11 Mar 2023 03:07:15 -0700 Subject: [PATCH 695/759] Additional update to CHANGELOG.md from previous PR --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d17b8a97d..2840bf892 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed `hf iclass view` - show credentials on a decrypted dump (@natesales) - Show NTAG213TT tamper info in `hf mfu info` and add commands for configuring it's tamper feature (@mjaksn) - Add Mifare Classic EV1 signature write support to gen4 magic tag lua script (@augustozanellato) + - Added XOR key extraction and flag to Guardall G-Prox II (@GuruSteve) - Changed verbiage on `hf iclass info` KeyAccess area to be congruent with AA1 and AA2 areas (@GuruSteve) - From 70f47aa93e452109bc06c3c0873ea673229afba8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 11 Mar 2023 12:02:51 +0100 Subject: [PATCH 696/759] added a new public key found for MIFARE Plus troika cards --- CHANGELOG.md | 1 + client/src/cmdhfmfp.c | 3 ++- tools/recover_pk.py | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d180053a..3856331b2 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] + - Added new public key for signature MIFARE Plus Troika (@iceman100) - Fixed the client build on Android (@wh201906) - Added TCP connection support on Windows (@wh201906) - Added `data num` - easy convert between dec/hex/bin (@iceman1001) diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index fe11836e1..aa7480953 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -171,7 +171,8 @@ static int plus_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signature #define PUBLIC_PLUS_ECDA_KEYLEN 57 const ecdsa_publickey_t nxp_plus_public_keys[] = { {"MIFARE Plus EV1", "044409ADC42F91A8394066BA83D872FB1D16803734E911170412DDF8BAD1A4DADFD0416291AFE1C748253925DA39A5F39A1C557FFACD34C62E"}, - {"MIFARE Plus Ev_x", "04BB49AE4447E6B1B6D21C098C1538B594A11A4A1DBF3D5E673DEACDEB3CC512D1C08AFA1A2768CE20A200BACD2DC7804CD7523A0131ABF607"} + {"MIFARE Plus Ev_x", "04BB49AE4447E6B1B6D21C098C1538B594A11A4A1DBF3D5E673DEACDEB3CC512D1C08AFA1A2768CE20A200BACD2DC7804CD7523A0131ABF607"}, + {"MIFARE Plus Trojka", "040F732E0EA7DF2B38F791BF89425BF7DCDF3EE4D976669E3831F324FF15751BD52AFF1782F72FF2731EEAD5F63ABE7D126E03C856FFB942AF"} }; uint8_t i; diff --git a/tools/recover_pk.py b/tools/recover_pk.py index b9f8dde4b..7ef149ceb 100755 --- a/tools/recover_pk.py +++ b/tools/recover_pk.py @@ -158,6 +158,11 @@ def selftests(): # # uses secp256r1?, SHA-256, # 'samples': ["aa", "DF0E506DFF8FCFC4B7B979D917644445F1230D2C7CDC342AFA842CA240C210BE7275F62073A9670F2DCEFC602CBEE771C2B4CD4A04F3D1EA11F49ABDF7E8B721"], # 'pk': ""}, + {'name': "MIFARE Plus Trojka", + # uses secp224r1, None, + 'samples': ["04B59F6A226F82", "6F577EB7F570D74DB6250477427F68A0088762BD318767537122919A7916597149F9D16D8B135E9BF826FB28AE293F3168661CD4A049FAED", + "04B44A82D80F92", "A0868ECF26733D3C3C838D055968B4559F77693CC3E346E3A4741BC826801F8360FD88857BEC440AAD3A21153D64302DEB6F5ED40B15C3F7"], + 'pk': "040F732E0EA7DF2B38F791BF89425BF7DCDF3EE4D976669E3831F324FF15751BD52AFF1782F72FF2731EEAD5F63ABE7D126E03C856FFB942AF"}, ] succeeded = True for t in tests: From 906e3f4c3262b456c3bb83982e930381f8c96def Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 11 Mar 2023 12:07:31 +0100 Subject: [PATCH 697/759] added pk for signature verification --- client/src/cmdhfmfdes.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index d1451dae9..b2cd1f7a5 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -396,6 +396,7 @@ static int desfire_print_signature(uint8_t *uid, uint8_t uidlen, uint8_t *signat {"MIFARE Plus Ev1", "044409ADC42F91A8394066BA83D872FB1D16803734E911170412DDF8BAD1A4DADFD0416291AFE1C748253925DA39A5F39A1C557FFACD34C62E"}, {"MIFARE Plus EvX", "04BB49AE4447E6B1B6D21C098C1538B594A11A4A1DBF3D5E673DEACDEB3CC512D1C08AFA1A2768CE20A200BACD2DC7804CD7523A0131ABF607"}, {"DESFire Ev2 XL", "04CD5D45E50B1502F0BA4656FF37669597E7E183251150F9574CC8DA56BF01C7ABE019E29FEA48F9CE22C3EA4029A765E1BC95A89543BAD1BC"}, + {"MIFARE Plus Troika", "040F732E0EA7DF2B38F791BF89425BF7DCDF3EE4D976669E3831F324FF15751BD52AFF1782F72FF2731EEAD5F63ABE7D126E03C856FFB942AF"}, }; From 2e8bacb00f68324396b28b79ef91b034a0e5d006 Mon Sep 17 00:00:00 2001 From: Christian Herrmann Date: Sat, 11 Mar 2023 18:59:33 +0100 Subject: [PATCH 698/759] Fixed `data asn1` - now handles bad input better by doing correct root free of obj --- CHANGELOG.md | 1 + client/src/cmdpiv.c | 3 +- client/src/emv/emvcore.c | 7 ++-- client/src/emv/tlv.c | 89 ++++++++++++++++++++++++++-------------- 4 files changed, 66 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b34aa61d..3f0253e58 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 `data asn1` - now handles bad input better (@iceman1001) - Added new public key for signature MIFARE Plus Troika (@iceman100) - Fixed the client build on Android (@wh201906) - Added TCP connection support on Windows (@wh201906) diff --git a/client/src/cmdpiv.c b/client/src/cmdpiv.c index 4d23a9b4b..8264c5936 100644 --- a/client/src/cmdpiv.c +++ b/client/src/cmdpiv.c @@ -576,7 +576,8 @@ static int PivGetData(Iso7816CommandChannel channel, const uint8_t tag[], size_t struct tlvdb_root *new_root = realloc(root, sizeof(*root) + capacity); if (new_root == NULL) { PrintAndLogEx(FAILED, "Running out of memory while re-allocating buffer"); - free(root); + //free(root); + tlvdb_root_free(root); return PM3_EMALLOC; } root = new_root; diff --git a/client/src/emv/emvcore.c b/client/src/emv/emvcore.c index fbc59b1c0..0628fcf76 100644 --- a/client/src/emv/emvcore.c +++ b/client/src/emv/emvcore.c @@ -177,7 +177,7 @@ bool TLVPrintFromBuffer(uint8_t *data, int datalen) { } void TLVPrintFromTLVLev(struct tlvdb *tlv, int level) { - if (!tlv) + if (tlv == NULL) return; tlvdb_visit(tlv, emv_print_cb, NULL, level); @@ -193,15 +193,16 @@ void TLVPrintAIDlistFromSelectTLV(struct tlvdb *tlv) { PrintAndLogEx(INFO, "|------------------+--------+-------------------------|"); struct tlvdb *ttmp = tlvdb_find(tlv, 0x6f); - if (!ttmp) + if (ttmp == NULL) PrintAndLogEx(INFO, "| none |"); while (ttmp) { const struct tlv *tgAID = tlvdb_get_inchild(ttmp, 0x84, NULL); const struct tlv *tgName = tlvdb_get_inchild(ttmp, 0x50, NULL); const struct tlv *tgPrio = tlvdb_get_inchild(ttmp, 0x87, NULL); - if (!tgAID) + if (!tgAID) { break; + } PrintAndLogEx(INFO, "| %s| %s | %s|", sprint_hex_inrow_ex(tgAID->value, tgAID->len, 17), (tgPrio) ? sprint_hex(tgPrio->value, 1) : " ", diff --git a/client/src/emv/tlv.c b/client/src/emv/tlv.c index 67fa51b58..f025fbe27 100644 --- a/client/src/emv/tlv.c +++ b/client/src/emv/tlv.c @@ -197,9 +197,7 @@ struct tlvdb *tlvdb_parse(const unsigned char *buf, size_t len) { return &root->db; err: - tlvdb_free(&root->db); - - free(root); + tlvdb_root_free(root); return NULL; } @@ -208,22 +206,32 @@ struct tlvdb *tlvdb_parse_multi(const unsigned char *buf, size_t len) { const unsigned char *tmp; size_t left; - if (!len || !buf) + if (len == 0 || buf == NULL) { return NULL; + } root = calloc(1, sizeof(*root) + len); + if (root == NULL) { + return NULL; + } + root->len = len; memcpy(root->buf, buf, len); tmp = root->buf; left = len; - if (!tlvdb_parse_one(&root->db, NULL, &tmp, &left)) + if (tlvdb_parse_one(&root->db, NULL, &tmp, &left) == false) { goto err; + } while (left != 0) { struct tlvdb *db = calloc(1, sizeof(*db)); - if (!tlvdb_parse_one(db, NULL, &tmp, &left)) { + if (db == NULL ) { + goto err; + } + + if (tlvdb_parse_one(db, NULL, &tmp, &left) == false) { free(db); goto err; } @@ -234,9 +242,7 @@ struct tlvdb *tlvdb_parse_multi(const unsigned char *buf, size_t len) { return &root->db; err: - tlvdb_free(&root->db); - - free(root); + tlvdb_root_free(root); return NULL; } @@ -313,8 +319,9 @@ struct tlvdb *tlvdb_external(tlv_tag_t tag, size_t len, const unsigned char *val void tlvdb_free(struct tlvdb *tlvdb) { struct tlvdb *next = NULL; - if (!tlvdb) + if (tlvdb == NULL) { return; + } for (; tlvdb; tlvdb = next) { next = tlvdb->next; @@ -339,36 +346,42 @@ void tlvdb_root_free(struct tlvdb_root *root) { } struct tlvdb *tlvdb_find_next(struct tlvdb *tlvdb, tlv_tag_t tag) { - if (!tlvdb) + if (tlvdb == NULL) { return NULL; + } return tlvdb_find(tlvdb->next, tag); } struct tlvdb *tlvdb_find(struct tlvdb *tlvdb, tlv_tag_t tag) { - if (!tlvdb) + if (tlvdb == NULL) { return NULL; + } for (; tlvdb; tlvdb = tlvdb->next) { - if (tlvdb->tag.tag == tag) + if (tlvdb->tag.tag == tag) { return tlvdb; + } } return NULL; } struct tlvdb *tlvdb_find_full(struct tlvdb *tlvdb, tlv_tag_t tag) { - if (!tlvdb) + if (tlvdb == NULL) { return NULL; + } for (; tlvdb; tlvdb = tlvdb->next) { - if (tlvdb->tag.tag == tag) + if (tlvdb->tag.tag == tag) { return tlvdb; + } if (tlvdb->children) { struct tlvdb *ch = tlvdb_find_full(tlvdb->children, tag); - if (ch) + if (ch) { return ch; + } } } @@ -391,12 +404,14 @@ struct tlvdb *tlvdb_find_path(struct tlvdb *tlvdb, tlv_tag_t tag[]) { } void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other) { - if (tlvdb == other) + if (tlvdb == other) { return; + } while (tlvdb->next) { - if (tlvdb->next == other) + if (tlvdb->next == other) { return; + } tlvdb = tlvdb->next; } @@ -405,17 +420,21 @@ void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other) { } void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value, struct tlvdb **tlvdb_elm) { + struct tlvdb *telm = tlvdb_find_full(tlvdb, tag); if (telm == NULL) { // new tlv element struct tlvdb *elm = tlvdb_fixed(tag, len, value); tlvdb_add(tlvdb, elm); - if (tlvdb_elm) + if (tlvdb_elm) { *tlvdb_elm = elm; + } + } else { // the same tlv structure - if (telm->tag.tag == tag && telm->tag.len == len && !memcmp(telm->tag.value, value, len)) + if (telm->tag.tag == tag && telm->tag.len == len && !memcmp(telm->tag.value, value, len)) { return; + } // replace tlv element struct tlvdb *tnewelm = tlvdb_fixed(tag, len, value); @@ -434,8 +453,9 @@ void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, // elm in root struct tlvdb *celm = tlvdb; // elm in child list of node - if (telm->parent && telm->parent->children) + if (telm->parent && telm->parent->children) { celm = telm->parent->children; + } // find previous element for (; celm; celm = celm->next) { @@ -455,7 +475,8 @@ void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, *tlvdb_elm = tnewelm; tnewelm_linked = true; } - if (! tnewelm_linked) { + + if (!tnewelm_linked) { tlvdb_free(tnewelm); } } @@ -470,8 +491,9 @@ void tlvdb_change_or_add_node(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, co void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data, int level) { struct tlvdb *next = NULL; - if (!tlvdb) + if (tlvdb == NULL) { return; + } for (; tlvdb; tlvdb = next) { next = tlvdb->next; @@ -481,12 +503,14 @@ void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data, int level) { } static const struct tlvdb *tlvdb_next(const struct tlvdb *tlvdb) { - if (tlvdb->children) + if (tlvdb->children) { return tlvdb->children; + } while (tlvdb) { - if (tlvdb->next) + if (tlvdb->next) { return tlvdb->next; + } tlvdb = tlvdb->parent; } @@ -502,8 +526,9 @@ const struct tlv *tlvdb_get(const struct tlvdb *tlvdb, tlv_tag_t tag, const stru while (tlvdb) { - if (tlvdb->tag.tag == tag) + if (tlvdb->tag.tag == tag) { return &tlvdb->tag; + } tlvdb = tlvdb_next(tlvdb); } @@ -570,11 +595,13 @@ bool tlv_is_constructed(const struct tlv *tlv) { } bool tlv_equal(const struct tlv *a, const struct tlv *b) { - if (!a && !b) + if (a == NULL && b == NULL) { return true; + } - if (!a || !b) + if (a == NULL || b == NULL) { return false; + } return a->tag == b->tag && a->len == b->len && !memcmp(a->value, b->value, a->len); } @@ -599,8 +626,9 @@ bool tlvdb_get_uint8(struct tlvdb *tlvRoot, tlv_tag_t tag, uint8_t *value) { bool tlv_get_uint8(const struct tlv *etlv, uint8_t *value) { *value = 0; if (etlv) { - if (etlv->len == 0) + if (etlv->len == 0) { return true; + } if (etlv->len == 1) { *value = etlv->value[0]; @@ -613,8 +641,9 @@ bool tlv_get_uint8(const struct tlv *etlv, uint8_t *value) { bool tlv_get_int(const struct tlv *etlv, int *value) { *value = 0; if (etlv) { - if (etlv->len == 0) + if (etlv->len == 0) { return true; + } if (etlv->len <= 4) { for (int i = 0; i < etlv->len; i++) { From d02e8daba0fe7703738ff90e3fbf9607cac4241e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Mar 2023 09:53:23 +0100 Subject: [PATCH 699/759] Changed CLI max string argument length limit from 512 to 4096. `data asn1` now handles 2048 hex bytes input --- CHANGELOG.md | 1 + client/deps/cliparser/cliparser.c | 101 +++++++++++++++++------------- client/deps/cliparser/cliparser.h | 6 +- client/src/cmddata.c | 6 +- client/src/cmdparser.c | 91 +++++++++++++++------------ 5 files changed, 118 insertions(+), 87 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f0253e58..ffcac2de5 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] + - Changed CLI max string argument length limit from 512 to 4096 (@iceman1001) - Fixed `data asn1` - now handles bad input better (@iceman1001) - Added new public key for signature MIFARE Plus Troika (@iceman100) - Fixed the client build on Android (@wh201906) diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index bcdb4b3d8..e5e8f946c 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -11,10 +11,10 @@ #include "cliparser.h" #include #include -#include // Get color constants -#include // get PrintAndLogEx -#include // tolower -#include // PRIu64 +#include // color constants +#include // PrintAndLogEx +#include // tolower +#include // PRIu64 #ifndef ARRAYLEN # define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0])) @@ -22,10 +22,10 @@ // Custom Colors // To default the color return s -#define _SectionTagColor_(s) _GREEN_(s) -#define _ExampleColor_(s) _YELLOW_(s) -#define _CommandColor_(s) _RED_(s) -#define _DescriptionColor_(s) _CYAN_(s) +#define _SectionTagColor_(s) _GREEN_(s) +#define _ExampleColor_(s) _YELLOW_(s) +#define _CommandColor_(s) _RED_(s) +#define _DescriptionColor_(s) _CYAN_(s) #define _ArgColor_(s) s #define _ArgHelpColor_(s) s // End Custom Colors @@ -34,65 +34,78 @@ int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) { *ctx = calloc(sizeof(CLIParserContext), sizeof(uint8_t)); - if (!*ctx) { + if (*ctx == NULL) { PrintAndLogEx(ERR, "ERROR: Insufficient memory\n"); return 2; } + (*ctx)->argtable = NULL; (*ctx)->argtableLen = 0; (*ctx)->programName = vprogramName; (*ctx)->programHint = vprogramHint; (*ctx)->programHelp = vprogramHelp; memset((*ctx)->buf, 0x00, sizeof((*ctx)->buf)); - return 0; + + return PM3_SUCCESS; } void CLIParserPrintHelp(CLIParserContext *ctx) { - if (ctx->programHint) + if (ctx->programHint) { PrintAndLogEx(NORMAL, "\n"_DescriptionColor_("%s"), ctx->programHint); + } PrintAndLogEx(NORMAL, "\n"_SectionTagColor_("usage:")); PrintAndLogEx(NORMAL, " "_CommandColor_("%s")NOLF, ctx->programName); arg_print_syntax(stdout, ctx->argtable, "\n\n"); PrintAndLogEx(NORMAL, _SectionTagColor_("options:")); - arg_print_glossary(stdout, ctx->argtable, " "_ArgColor_("%-30s")" "_ArgHelpColor_("%s")"\n"); - PrintAndLogEx(NORMAL, ""); - if (ctx->programHelp) { - PrintAndLogEx(NORMAL, _SectionTagColor_("examples/notes:")); - char *buf = NULL; - int idx = 0; - buf = realloc(buf, strlen(ctx->programHelp) + 1); // more then enough as we are splitting - char *p2; // pointer to split example from comment. + if (ctx->programHelp) { + + // allocate more then enough memory as we are splitting + char *s = calloc(strlen(ctx->programHelp) + 1, sizeof(uint8_t)); + if (s == NULL) { + PrintAndLogEx(FAILED, "cannot allocate memory"); + return; + } + + PrintAndLogEx(NORMAL, _SectionTagColor_("examples/notes:")); + + // pointer to split example from comment. + char *p2; + + int idx = 0; int egWidth = 30; for (int i = 0; i <= strlen(ctx->programHelp); i++) { // <= so to get string terminator. - buf[idx++] = ctx->programHelp[i]; + + s[idx++] = ctx->programHelp[i]; + if ((ctx->programHelp[i] == '\n') || (ctx->programHelp[i] == 0x00)) { - buf[idx - 1] = 0x00; - p2 = strstr(buf, "->"); // See if the example has a comment. + + s[idx - 1] = 0x00; + p2 = strstr(s, "->"); // See if the example has a comment. + if (p2 != NULL) { *(p2 - 1) = 0x00; - if (strlen(buf) > 28) - egWidth = strlen(buf) + 5; + if (strlen(s) > 28) + egWidth = strlen(s) + 5; else egWidth = 30; - PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s")" %s", egWidth, buf, p2); + PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s")" %s", egWidth, s, p2); } else { - PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s"), egWidth, buf); + PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s"), egWidth, s); } + idx = 0; } } - + free(s); PrintAndLogEx(NORMAL, ""); - free(buf); } - fflush(stdout); } @@ -127,7 +140,7 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta return 3; } - return 0; + return PM3_SUCCESS; } enum ParserState { @@ -144,21 +157,25 @@ int CLIParserParseString(CLIParserContext *ctx, const char *str, void *vargtable int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) { int argc = 0; - char *argv[200] = {NULL}; + char *argv[MAX_INPUT_ARG_LENGTH] = {NULL}; int len = strlen(str); + memset(ctx->buf, 0x00, ARRAYLEN(ctx->buf)); + char *bufptr = ctx->buf; char *bufptrend = ctx->buf + ARRAYLEN(ctx->buf) - 1; char *spaceptr = NULL; enum ParserState state = PS_FIRST; argv[argc++] = bufptr; - // param0 = program name - memcpy(ctx->buf, ctx->programName, strlen(ctx->programName) + 1); // with 0x00 + // param0 = program name + with 0x00 + memcpy(ctx->buf, ctx->programName, strlen(ctx->programName) + 1); + bufptr += strlen(ctx->programName) + 1; - if (len) + if (len) { argv[argc++] = bufptr; + } // parse params for (int i = 0; i < len; i++) { @@ -214,10 +231,9 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen = 0; int tmplen = 0; - uint8_t tmpstr[(256 * 2) + 1] = {0}; + uint8_t tmpstr[MAX_INPUT_ARG_LENGTH + 1] = {0}; // concat all strings in argstr into tmpstr[] - // int res = CLIParamStrToBuf(argstr, tmpstr, sizeof(tmpstr), &tmplen); if (res || (tmplen == 0)) { return res; @@ -242,7 +258,7 @@ int CLIParamBinToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen = 0; int tmplen = 0; - uint8_t tmpstr[(256 * 2) + 1] = {0}; + uint8_t tmpstr[MAX_INPUT_ARG_LENGTH + 1] = {0}; // concat all strings in argstr into tmpstr[] // @@ -268,7 +284,7 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int if (!argstr->count) return 0; - uint8_t tmpstr[(512 * 2) + 1] = {0}; + uint8_t tmpstr[MAX_INPUT_ARG_LENGTH + 1] = {0}; int ibuf = 0; for (int i = 0; i < argstr->count; i++) { @@ -303,7 +319,7 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int int CLIGetOptionList(struct arg_str *argstr, const CLIParserOption *option_array, int *value) { char data[200] = {0}; - int datalen = 0; + int datalen = 200; int res = CLIParamStrToBuf(argstr, (uint8_t *)data, sizeof(data), &datalen); if (res) return res; @@ -316,7 +332,7 @@ int CLIGetOptionList(struct arg_str *argstr, const CLIParserOption *option_array int val = -1; int cntr = 0; - for (int i = 0; i < CLI_MAX_OPTLIST_LEN && option_array[i].text != NULL; i++) { + for (int i = 0; (i < CLI_MAX_OPTLIST_LEN) && (option_array[i].text != NULL); i++) { // exact match if (strcmp(option_array[i].text, data) == 0) { *value = option_array[i].code; @@ -346,9 +362,10 @@ int CLIGetOptionList(struct arg_str *argstr, const CLIParserOption *option_array const char *CLIGetOptionListStr(const CLIParserOption *option_array, int value) { static const char *errmsg = "n/a"; - for (int i = 0; i < CLI_MAX_OPTLIST_LEN && option_array[i].text != NULL; i++) { - if (option_array[i].code == value) + for (int i = 0; (i < CLI_MAX_OPTLIST_LEN) && (option_array[i].text != NULL); i++) { + if (option_array[i].code == value) { return option_array[i].text; + } } return errmsg; } diff --git a/client/deps/cliparser/cliparser.h b/client/deps/cliparser/cliparser.h index f50fec2ee..812b44506 100644 --- a/client/deps/cliparser/cliparser.h +++ b/client/deps/cliparser/cliparser.h @@ -12,6 +12,7 @@ #define __CLIPARSER_H #include "argtable3.h" #include +#include #include "util.h" #define arg_param_begin arg_lit0("h", "help", "This help") @@ -53,13 +54,16 @@ #define CLIGetOptionListWithReturn(ctx, paramnum, option_array, option_array_len, value) if (CLIGetOptionList(arg_get_str((ctx), (paramnum)), (option_array), (option_array_len), (value))) {CLIParserFree((ctx)); return PM3_ESOFT;} +#define MAX_INPUT_ARG_LENGTH 4096 + + typedef struct { void **argtable; size_t argtableLen; const char *programName; const char *programHint; const char *programHelp; - char buf[1024 + 60]; + char buf[MAX_INPUT_ARG_LENGTH + 60]; } CLIParserContext; #define CLI_MAX_OPTLIST_LEN 50 diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 724bc5c65..3d153022d 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -2915,8 +2915,8 @@ static int CmdAsn1Decoder(const char *Cmd) { arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); - int dlen = 256; - uint8_t data[256]; + int dlen = 2048; + uint8_t data[2048]; CLIGetHexWithReturn(ctx, 1, data, &dlen); CLIParserFree(ctx); @@ -2927,8 +2927,6 @@ static int CmdAsn1Decoder(const char *Cmd) { return PM3_SUCCESS; } - - static int CmdDiff(const char *Cmd) { CLIParserContext *ctx; diff --git a/client/src/cmdparser.c b/client/src/cmdparser.c index 1c360e832..39a6c98ad 100644 --- a/client/src/cmdparser.c +++ b/client/src/cmdparser.c @@ -25,6 +25,9 @@ #include "comms.h" #include "util_posix.h" // msleep + +#define MAX_PM3_INPUT_ARGS_LENGTH 4096 + bool AlwaysAvailable(void) { return true; } @@ -36,54 +39,55 @@ bool IfPm3Present(void) { } bool IfPm3Rdv4Fw(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return (g_pm3_capabilities.is_rdv4); } bool IfPm3Flash(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; - if (!g_pm3_capabilities.compiled_with_flash) + if (g_pm3_capabilities.compiled_with_flash == false) return false; return g_pm3_capabilities.hw_available_flash; } bool IfPm3Smartcard(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; - if (!g_pm3_capabilities.compiled_with_smartcard) + if (g_pm3_capabilities.compiled_with_smartcard == false) return false; return g_pm3_capabilities.hw_available_smartcard; } bool IfPm3FpcUsart(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_fpc_usart; } bool IfPm3FpcUsartHost(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_fpc_usart_host; } bool IfPm3FpcUsartHostFromUsb(void) { // true if FPC USART Host support and if talking from USB-CDC interface - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; - if (!g_pm3_capabilities.compiled_with_fpc_usart_host) + if (g_pm3_capabilities.compiled_with_fpc_usart_host == false) return false; return !g_conn.send_via_fpc_usart; } bool IfPm3FpcUsartDevFromUsb(void) { // true if FPC USART developer support and if talking from USB-CDC interface - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; - if (!g_pm3_capabilities.compiled_with_fpc_usart_dev) + if (g_pm3_capabilities.compiled_with_fpc_usart_dev == false) return false; + return !g_conn.send_via_fpc_usart; } @@ -93,103 +97,101 @@ bool IfPm3FpcUsartFromUsb(void) { } bool IfPm3Lf(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_lf; } bool IfPm3Hitag(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_hitag; } bool IfPm3EM4x50(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_em4x50; } bool IfPm3EM4x70(void) { - - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_em4x70; } bool IfPm3Hfsniff(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_hfsniff; } bool IfPm3Hfplot(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_hfplot; } bool IfPm3Iso14443a(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_iso14443a; } bool IfPm3Iso14443b(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_iso14443b; } bool IfPm3Iso14443(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_iso14443a || g_pm3_capabilities.compiled_with_iso14443b; } bool IfPm3Iso15693(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_iso15693; } bool IfPm3Felica(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_felica; } bool IfPm3Legicrf(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_legicrf; } bool IfPm3Iclass(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_iclass; } bool IfPm3NfcBarcode(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_nfcbarcode; } bool IfPm3Lcd(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_lcd; } bool IfPm3Zx8211(void) { - if (!IfPm3Present()) + if (IfPm3Present() == false) return false; return g_pm3_capabilities.compiled_with_zx8211; } - void CmdsHelp(const command_t Commands[]) { if (Commands[0].Name == NULL) return; int i = 0; @@ -259,7 +261,7 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { } - char cmd_name[128]; + char cmd_name[128] = {0}; memset(cmd_name, 0, sizeof(cmd_name)); int len = 0; @@ -275,8 +277,10 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { // find args, check for -h / --help int tmplen = len; - while (Cmd[tmplen] == ' ') + while (Cmd[tmplen] == ' ') { ++tmplen; + } + bool request_help = (strcmp(Cmd + tmplen, "-h") == 0) || (strcmp(Cmd + tmplen, "--help") == 0); int i = 0; @@ -305,12 +309,15 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { matches++; } } - if (matches == 1) i = last_match; + if (matches == 1) { + i = last_match; + } } if (Commands[i].Name) { - while (Cmd[len] == ' ') + while (Cmd[len] == ' ') { ++len; + } return Commands[i].Parse(Cmd + len); } else { // show help for selected hierarchy or if command not recognised @@ -320,7 +327,7 @@ int CmdsParse(const command_t Commands[], const char *Cmd) { return PM3_SUCCESS; } -static char pparent[512] = {0}; +static char pparent[MAX_PM3_INPUT_ARGS_LENGTH] = {0}; static char *parent = pparent; void dumpCommandsRecursive(const command_t cmds[], int markdown, bool full_help) { @@ -346,11 +353,13 @@ void dumpCommandsRecursive(const command_t cmds[], int markdown, bool full_help) const char *cmd_offline = "N"; - if (cmds[i].IsAvailable()) + if (cmds[i].IsAvailable()) { cmd_offline = "Y"; - if (markdown) + } + + if (markdown) { PrintAndLogEx(NORMAL, "|`%s%-*s`|%-*s|`%s`", parent, w_cmd - (int)strlen(parent) - 2, cmds[i].Name, w_off, cmd_offline, cmds[i].Help); - else if (full_help) { + } else if (full_help) { PrintAndLogEx(NORMAL, "---------------------------------------------------------------------------------------"); PrintAndLogEx(NORMAL, _RED_("%s%-*s\n") "available offline: %s", parent, w_cmd - (int)strlen(parent), cmds[i].Name, cmds[i].IsAvailable() ? _GREEN_("yes") : _RED_("no")); cmds[i].Parse("--help"); @@ -374,15 +383,17 @@ void dumpCommandsRecursive(const command_t cmds[], int markdown, bool full_help) } else { PrintAndLogEx(NORMAL, "### %s%s\n\n %s\n", parent, cmds[i].Name, cmds[i].Help); } - char currentparent[512] = {0}; + + char currentparent[MAX_PM3_INPUT_ARGS_LENGTH] = {0}; snprintf(currentparent, sizeof currentparent, "%s%s ", parent, cmds[i].Name); + char *old_parent = parent; parent = currentparent; // This is what causes the recursion, since commands Parse-implementation // in turn calls the CmdsParse above. - if (markdown) + if (markdown) { cmds[i].Parse("XX_internal_command_dump_markdown_XX"); - else if (full_help) { + } else if (full_help) { cmds[i].Parse("XX_internal_command_dump_full_XX"); } else { cmds[i].Parse("XX_internal_command_dump_XX"); From 5938938226a17d68ba422a848325edc1aa3deae7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Mar 2023 18:54:53 +0100 Subject: [PATCH 700/759] print the string and hex --- client/src/crypto/asn1dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index 4bab148be..a7197a35d 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -166,7 +166,7 @@ static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag } static void asn1_tag_dump_string(const struct tlv *tlv, const struct asn1_tag *tag, int level) { - PrintAndLogEx(NORMAL, " value: '%s'", sprint_hex(tlv->value, tlv->len)); + PrintAndLogEx(NORMAL, " value: '%.*s' hex: '%s'", tlv->len, tlv->value, sprint_hex(tlv->value, tlv->len)); } static void asn1_tag_dump_hex(const struct tlv *tlv, const struct asn1_tag *tag, int level) { From 4a7713070b8a4260f20857b776a0aaf7a70c04f7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Mar 2023 18:59:53 +0100 Subject: [PATCH 701/759] fix object strings. Integers is now 64b which isnt enough. Will need to use big_num here --- client/src/crypto/asn1dump.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index a7197a35d..548a80c49 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -96,7 +96,6 @@ static const struct asn1_tag asn1_tags[] = { { 0xa5, "[5]", ASN1_TAG_GENERIC }, }; - static int asn1_sort_tag(tlv_tag_t tag) { return (int)(tag >= 0x100 ? tag : tag << 8); } @@ -109,9 +108,7 @@ static int asn1_tlv_compare(const void *a, const void *b) { } static const struct asn1_tag *asn1_get_tag(const struct tlv *tlv) { - struct asn1_tag *tag = bsearch(tlv, asn1_tags, ARRAYLEN(asn1_tags), - sizeof(asn1_tags[0]), asn1_tlv_compare); - + struct asn1_tag *tag = bsearch(tlv, asn1_tags, ARRAYLEN(asn1_tags), sizeof(asn1_tags[0]), asn1_tlv_compare); return tag ? tag : &asn1_tags[0]; } @@ -189,8 +186,8 @@ static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_ } } -static unsigned long asn1_value_integer(const struct tlv *tlv, unsigned start, unsigned end) { - unsigned long ret = 0; +static uint64_t asn1_value_integer(const struct tlv *tlv, unsigned start, unsigned end) { + uint64_t ret = 0; unsigned i; if (end > tlv->len * 2) @@ -238,8 +235,8 @@ static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag * PrintAndLogEx(NORMAL, " value: %d (0x%08X)", val, val); return; } - uint32_t val = asn1_value_integer(tlv, 0, tlv->len * 2); - PrintAndLogEx(NORMAL, " value: %" PRIu32 " (0x%X)", val, val); + uint64_t val = asn1_value_integer(tlv, 0, tlv->len * 2); + PrintAndLogEx(NORMAL, " value: %" PRIu64 " (0x%X)", val, val); } static char *asn1_oid_description(const char *oid, bool with_group_desc) { @@ -293,7 +290,7 @@ static void asn1_tag_dump_object_id(const struct tlv *tlv, const struct asn1_tag char pstr[300]; mbedtls_oid_get_numeric_string(pstr, sizeof(pstr), &asn1_buf); - PrintAndLogEx(INFO, "%*s %s" NOLF, (level * 4), " ", pstr); + PrintAndLogEx(NORMAL, "%*s %s" NOLF, (level * 4), " ", pstr); char *jsondesc = asn1_oid_description(pstr, true); if (jsondesc) { From d11d1fbc33ed7d6b5051837a19df73ce5bfff10b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 12 Mar 2023 19:18:55 +0100 Subject: [PATCH 702/759] data asn1 now decodes timestamp correct... Or I hope so. And strings values are now highlighted with GREEN --- client/src/crypto/asn1dump.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index 548a80c49..db0b2b687 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -116,7 +116,7 @@ static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag int len = tlv->len; *needdump = false; - int startindx = longyear ? 4 : 2; + int startidx = longyear ? 4 : 2; if (len > 4) { PrintAndLogEx(NORMAL, " value: '" NOLF); @@ -125,34 +125,38 @@ static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag if (longyear == false) PrintAndLogEx(NORMAL, "20" NOLF); - PrintAndLogEx(NORMAL, "%s-" NOLF, sprint_hex(tlv->value, startindx)); + PrintAndLogEx(NORMAL, "%.*s-" NOLF, startidx, tlv->value); - if (len < startindx + 2) + if (len < startidx + 2) break; // month - PrintAndLogEx(NORMAL, "%02x%02x-" NOLF, tlv->value[startindx], tlv->value[startindx + 1]); - if (len < startindx + 4) + PrintAndLogEx(NORMAL, "%.*s-" NOLF, 2, tlv->value + startidx ); + if (len < startidx + 4) break; // day - PrintAndLogEx(NORMAL, "%02x%02x " NOLF, tlv->value[startindx + 2], tlv->value[startindx + 3]); - if (len < startindx + 6) + PrintAndLogEx(NORMAL, "%.*s " NOLF, 2, tlv->value + startidx + 2); + if (len < startidx + 6) break; + // hour - PrintAndLogEx(NORMAL, "%02x%02x:" NOLF, tlv->value[startindx + 4], tlv->value[startindx + 5]); - if (len < startindx + 8) + PrintAndLogEx(NORMAL, "%.*s:" NOLF, 2, tlv->value + startidx + 4); + if (len < startidx + 8) break; + // min - PrintAndLogEx(NORMAL, "%02x%02x:" NOLF, tlv->value[startindx + 6], tlv->value[startindx + 7]); - if (len < startindx + 10) + PrintAndLogEx(NORMAL, "%.*s:" NOLF, 2, tlv->value + startidx + 6); + if (len < startidx + 10) break; + // sec - PrintAndLogEx(NORMAL, "%02x%02x" NOLF, tlv->value[startindx + 8], tlv->value[startindx + 9]); - if (len < startindx + 11) + PrintAndLogEx(NORMAL, "%.*s" NOLF, 2, tlv->value + startidx + 8); + if (len < startidx + 11) break; + // time zone - PrintAndLogEx(NORMAL, " zone: %.*s" NOLF, len - 10 - (longyear ? 4 : 2), &tlv->value[startindx + 10]); + PrintAndLogEx(NORMAL, " zone: %.*s" NOLF, len - 10 - (longyear ? 4 : 2), tlv->value + startidx + 10); break; } PrintAndLogEx(NORMAL, "'"); @@ -163,7 +167,7 @@ static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag } static void asn1_tag_dump_string(const struct tlv *tlv, const struct asn1_tag *tag, int level) { - PrintAndLogEx(NORMAL, " value: '%.*s' hex: '%s'", tlv->len, tlv->value, sprint_hex(tlv->value, tlv->len)); + PrintAndLogEx(NORMAL, " value: '" _GREEN_("%.*s") "' hex: '%s'", tlv->len, tlv->value, sprint_hex(tlv->value, tlv->len)); } static void asn1_tag_dump_hex(const struct tlv *tlv, const struct asn1_tag *tag, int level) { From 04173fc961059f49192c52d3dff9b83956446e82 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 13 Mar 2023 21:36:59 +0100 Subject: [PATCH 703/759] added bit string printing in ASN1 decoder --- client/src/crypto/asn1dump.c | 55 +++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index db0b2b687..4136c002d 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -44,6 +44,7 @@ enum asn1_tag_t { ASN1_TAG_STR_TIME, ASN1_TAG_OBJECT_ID, ASN1_TAG_HEX, + ASN1_TAG_BIT_STRING, }; struct asn1_tag { @@ -62,7 +63,7 @@ static const struct asn1_tag asn1_tags[] = { // ASN.1 { 0x01, "BOOLEAN", ASN1_TAG_BOOLEAN }, { 0x02, "INTEGER", ASN1_TAG_INTEGER }, - { 0x03, "BIT STRING", ASN1_TAG_GENERIC }, + { 0x03, "BIT STRING", ASN1_TAG_BIT_STRING }, { 0x04, "OCTET STRING", ASN1_TAG_OCTET_STRING }, { 0x05, "NULL", ASN1_TAG_GENERIC }, { 0x06, "OBJECT IDENTIFIER", ASN1_TAG_OBJECT_ID }, @@ -170,6 +171,54 @@ static void asn1_tag_dump_string(const struct tlv *tlv, const struct asn1_tag *t PrintAndLogEx(NORMAL, " value: '" _GREEN_("%.*s") "' hex: '%s'", tlv->len, tlv->value, sprint_hex(tlv->value, tlv->len)); } +static void asn1_tag_dump_bitstring(const struct tlv *tlv, const struct asn1_tag *tag, int level) { + + size_t len = tlv->len; + size_t n = (len * 8); + bool skip = false; + + if (tlv->value[0] == 0) { + n -= 8; + len--; + skip = true; + } + + uint8_t *d = calloc(n, sizeof(uint8_t)); + if (d == NULL) { + return; + } + + if (skip) + bytes_to_bytebits(tlv->value + 1, len, d); + else + bytes_to_bytebits(tlv->value, len, d); + + level++; + PrintAndLogEx(NORMAL, " (%zu bit)", n); + PrintAndLogEx(INFO, "%*s" NOLF, 1 + (level * 4), ""); + + for (int i = 0; i < n; i++) { + + char c = d[i]; + if (c < 2) { + c += '0'; + } else { + goto out; + } + + PrintAndLogEx(NORMAL, "%c" NOLF, c); + + if (((i + 1) % 64) == 0) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "%*s" NOLF, 1 + (level * 4), ""); + } + } + +out: + free(d); + PrintAndLogEx(NORMAL, ""); +} + static void asn1_tag_dump_hex(const struct tlv *tlv, const struct asn1_tag *tag, int level) { PrintAndLogEx(NORMAL, " value: '%s'", sprint_hex_inrow(tlv->value, tlv->len)); } @@ -378,6 +427,10 @@ bool asn1_tag_dump(const struct tlv *tlv, int level, bool *candump) { asn1_tag_dump_hex(tlv, tag, level); *candump = false; break; + case ASN1_TAG_BIT_STRING: + asn1_tag_dump_bitstring(tlv, tag, level); + *candump = false; + break; }; return true; From 1cc19c3429076865a31af8aa846cd8d27b2a58ac Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 13 Mar 2023 22:09:30 +0100 Subject: [PATCH 704/759] asn1 decoder now handles big integers --- client/src/crypto/asn1dump.c | 68 +++++++++++++++--------------------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index 4136c002d..1b6eede1c 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -26,6 +26,7 @@ #include #include #include +#include "mbedtls/bignum.h" // big num #include #include "emv/emv_tags.h" #include "emv/emvjson.h" @@ -239,36 +240,6 @@ static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_ } } -static uint64_t asn1_value_integer(const struct tlv *tlv, unsigned start, unsigned end) { - uint64_t ret = 0; - unsigned i; - - if (end > tlv->len * 2) - return ret; - if (start >= end) - return ret; - - if (start & 1) { - ret += tlv->value[start / 2] & 0xf; - i = start + 1; - } else - i = start; - - for (; i < end - 1; i += 2) { - ret = ret << 4; // was: ret*=10 - ret += tlv->value[i / 2] >> 4; - ret = ret << 4; // was: ret*=10 - ret += tlv->value[i / 2] & 0xf; - } - - if (end & 1) { - ret = ret << 4; // was: ret*=10 - ret += tlv->value[end / 2] >> 4; - } - - return ret; -} - static void asn1_tag_dump_boolean(const struct tlv *tlv, const struct asn1_tag *tag, int level) { PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); if (tlv->len > 0) { @@ -279,17 +250,34 @@ static void asn1_tag_dump_boolean(const struct tlv *tlv, const struct asn1_tag * } static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag *tag, int level) { - PrintAndLogEx(NORMAL, "%*s" NOLF, (level * 4), " "); - if (tlv->len == 4) { - int32_t val = 0; - for (size_t i = 0; i < tlv->len; i++) { - val = (val << 8) + tlv->value[i]; - } - PrintAndLogEx(NORMAL, " value: %d (0x%08X)", val, val); + + size_t n = (tlv->len * 2); + char *hex = calloc(n + 1, sizeof(uint8_t)); + if (hex == NULL) { return; } - uint64_t val = asn1_value_integer(tlv, 0, tlv->len * 2); - PrintAndLogEx(NORMAL, " value: %" PRIu64 " (0x%X)", val, val); + + hex_to_buffer((uint8_t*)hex, tlv->value, tlv->len, tlv->len, 0, 0, false); + + // results for MPI actions + bool ret = false; + + // container of big number + mbedtls_mpi N; + mbedtls_mpi_init(&N); + + MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16, hex)); + + char s[600] = {0}; + size_t slen = 0; + MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(&N, 10, s, sizeof(s), &slen)); + if (slen > 0) { + PrintAndLogEx(NORMAL, "%*s value: %s", (level ), "", s); + } + +cleanup: + mbedtls_mpi_free(&N); + free(hex); } static char *asn1_oid_description(const char *oid, bool with_group_desc) { @@ -343,7 +331,7 @@ static void asn1_tag_dump_object_id(const struct tlv *tlv, const struct asn1_tag char pstr[300]; mbedtls_oid_get_numeric_string(pstr, sizeof(pstr), &asn1_buf); - PrintAndLogEx(NORMAL, "%*s %s" NOLF, (level * 4), " ", pstr); + PrintAndLogEx(NORMAL, "%*s %s" NOLF, (level), " ", pstr); char *jsondesc = asn1_oid_description(pstr, true); if (jsondesc) { From 03f6ad02f33e7c4dab180e109c17f5a904ff1d21 Mon Sep 17 00:00:00 2001 From: Fabian Schneebauer Date: Thu, 16 Mar 2023 17:01:57 +0100 Subject: [PATCH 705/759] legic: info command available for more sources, add memory check. --- client/src/cmdhflegic.c | 192 ++++++++++++++++++++++++++++++++-------- 1 file changed, 153 insertions(+), 39 deletions(-) diff --git a/client/src/cmdhflegic.c b/client/src/cmdhflegic.c index 35b1ac886..5ca53ecd3 100644 --- a/client/src/cmdhflegic.c +++ b/client/src/cmdhflegic.c @@ -57,54 +57,28 @@ static bool legic_xor(uint8_t *data, uint16_t cardsize) { return true; } -/* - * Output BigBuf and deobfuscate LEGIC RF tag data. - * This is based on information given in the talk held - * by Henryk Ploetz and Karsten Nohl at 26c3 - */ -static int CmdLegicInfo(const char *Cmd) { - CLIParserContext *ctx; - CLIParserInit(&ctx, "hf legic info", - "Gets information from a LEGIC Prime tag like systemarea, user areas, etc", - "hf legic info"); - - void *argtable[] = { - arg_param_begin, - arg_param_end - }; - CLIExecWithReturn(ctx, Cmd, argtable, true); - CLIParserFree(ctx); - +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; - uint16_t datalen = 0; char token_type[6] = {0, 0, 0, 0, 0, 0}; int dcf = 0; int bIsSegmented = 0; + int return_value = PM3_SUCCESS; - // tagtype - legic_card_select_t card; - if (legic_get_type(&card) != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Failed to identify tagtype"); - return PM3_ESOFT; + 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)"); + return_value = PM3_EFAILED; + return PM3_EFAILED; } - PrintAndLogEx(SUCCESS, "Reading full tag memory of " _YELLOW_("%d") " bytes...", card.cardsize); - - // allocate receiver buffer - uint8_t *data = calloc(card.cardsize, sizeof(uint8_t)); + // copy input buffer into newly allocated buffer, because the existing code mutates the data inside. + uint8_t *data = calloc(card_size, sizeof(uint8_t)); if (!data) { PrintAndLogEx(WARNING, "Cannot allocate memory"); return PM3_EMALLOC; } - - int status = legic_read_mem(0, card.cardsize, 0x55, data, &datalen); - if (status != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Failed reading memory"); - free(data); - return status; - } + memcpy(data, input_buffer, card_size); // Output CDF System area (9 bytes) plus remaining header area (12 bytes) crc = data[4]; @@ -217,9 +191,10 @@ static int CmdLegicInfo(const char *Cmd) { uint32_t segCalcCRC = 0; uint32_t segCRC = 0; - // Not Data card? - if (dcf > 60000) + // Not a data card by dcf or too small to contain data (MIM22)? + if (dcf > 60000 || card_size == LEGIC_PRIME_MIM22) { goto out; + } PrintAndLogEx(SUCCESS, _CYAN_("ADF: User Area")); PrintAndLogEx(NORMAL, "------------------------------------------------------"); @@ -231,6 +206,13 @@ static int CmdLegicInfo(const char *Cmd) { // decode segments for (segmentNum = 1; segmentNum < 128; segmentNum++) { + // for decoding the segment header we need at least 4 bytes left in buffer + if ((i + 4) > card_size) { + PrintAndLogEx(FAILED, "Cannot read segment header, because the input buffer is too small. " + "Please check that the data is correct and properly aligned. "); + return_value = PM3_EOUTOFBOUND; + goto out; + } segment_len = ((data[i + 1] ^ crc) & 0x0f) * 256 + (data[i] ^ crc); segment_flag = ((data[i + 1] ^ crc) & 0xf0) >> 4; wrp = (data[i + 2] ^ crc); @@ -277,6 +259,14 @@ static int CmdLegicInfo(const char *Cmd) { i += 5; + // for printing the complete segment we need at least wrc + wrp_len + remain_seg_payload_len bytes + if ((i + wrc + wrp_len + remain_seg_payload_len) > card_size) { + PrintAndLogEx(FAILED, "Cannot read segment body, because the input buffer is too small. " + "Please check that the data is correct and properly aligned. "); + return_value = PM3_EOUTOFBOUND; + goto out; + } + if (hasWRC) { PrintAndLogEx(SUCCESS, "\nWRC protected area: (I %d | K %d| WRC %d)", i, k, wrc); PrintAndLogEx(NORMAL, "\nrow | data"); @@ -330,7 +320,6 @@ static int CmdLegicInfo(const char *Cmd) { } // end for loop } else { - // Data start point on unsegmented cards i = 8; @@ -340,7 +329,7 @@ static int CmdLegicInfo(const char *Cmd) { bool hasWRC = (wrc > 0); bool hasWRP = (wrp > wrc); int wrp_len = (wrp - wrc); - int remain_seg_payload_len = (card.cardsize - 22 - wrp); + int remain_seg_payload_len = (card_size - 22 - wrp); PrintAndLogEx(SUCCESS, "Unsegmented card - WRP: %02u, WRC: %02u, RD: %01u", wrp, @@ -348,6 +337,14 @@ static int CmdLegicInfo(const char *Cmd) { (data[7] & 0x80) >> 7 ); + // for printing the complete segment we need at least wrc + wrp_len + remain_seg_payload_len bytes + if ((i + wrc + wrp_len + remain_seg_payload_len) > card_size) { + PrintAndLogEx(FAILED, "Cannot read segment body, because the input buffer is too small. " + "Please check that the data is correct and properly aligned. "); + return_value = PM3_EOUTOFBOUND; + goto out; + } + if (hasWRC) { PrintAndLogEx(SUCCESS, "WRC protected area: (I %d | WRC %d)", i, wrc); PrintAndLogEx(NORMAL, "\nrow | data"); @@ -386,6 +383,55 @@ static int CmdLegicInfo(const char *Cmd) { } out: + free(data); + return (return_value); +} + +/* + * Output BigBuf and deobfuscate LEGIC RF tag data. + * This is based on information given in the talk held + * by Henryk Ploetz and Karsten Nohl at 26c3 + */ +static int CmdLegicInfo(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf legic info", + "Gets information from a LEGIC Prime tag like systemarea, user areas, etc", + "hf legic info"); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + + uint16_t datalen = 0; + + // tagtype + legic_card_select_t card; + if (legic_get_type(&card) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Failed to identify tagtype"); + return PM3_ESOFT; + } + + PrintAndLogEx(SUCCESS, "Reading full tag memory of " _YELLOW_("%d") " bytes...", card.cardsize); + + // allocate receiver buffer + uint8_t *data = calloc(card.cardsize, sizeof(uint8_t)); + if (!data) { + PrintAndLogEx(WARNING, "Cannot allocate memory"); + return PM3_EMALLOC; + } + + int status = legic_read_mem(0, card.cardsize, 0x55, data, &datalen); + if (status != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Failed reading memory"); + free(data); + return status; + } + + decode_and_print_memory(card.cardsize, data); + free(data); return PM3_SUCCESS; } @@ -1174,6 +1220,41 @@ static int CmdLegicEView(const char *Cmd) { return PM3_SUCCESS; } +static int CmdLegicEInfo(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf legic einfo", + "It decodes and displays emulator memory", + "hf legic einfo\n" + ); + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + + size_t card_size = LEGIC_PRIME_MIM256; + + uint8_t *dump = calloc(card_size, sizeof(uint8_t)); + if (dump == NULL) { + PrintAndLogEx(WARNING, "Fail, cannot allocate memory"); + return PM3_EMALLOC; + } + + PrintAndLogEx(INFO, "downloading emulator memory"); + if (GetFromDevice(BIG_BUF_EML, dump, card_size, 0, NULL, 0, NULL, 2500, false) == false) { + PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); + free(dump); + return PM3_ETIMEOUT; + } + + decode_and_print_memory(card_size, dump); + + free(dump); + return PM3_SUCCESS; +} + static int CmdLegicWipe(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf legic wipe", @@ -1290,6 +1371,37 @@ static int CmdLegicView(const char *Cmd) { return PM3_SUCCESS; } +static int CmdLegicDInfo(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf legic view", + "Print a LEGIC Prime dump file (bin/eml/json)", + "hf legic view -f hf-legic-01020304-dump.bin" + ); + void *argtable[] = { + arg_param_begin, + arg_str1("f", "file", "", "Filename of dump"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + int fnlen = 0; + char filename[FILE_PATH_SIZE]; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + CLIParserFree(ctx); + + // read dump file + uint8_t *dump = NULL; + size_t bytes_read = 0; + int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, LEGIC_PRIME_MIM1024); + if (res != PM3_SUCCESS) { + return res; + } + + decode_and_print_memory(bytes_read, dump); + + free(dump); + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("operations") " ---------------------"}, {"help", CmdHelp, AlwaysAvailable, "This help"}, @@ -1306,9 +1418,11 @@ static command_t CommandTable[] = { {"eload", CmdLegicELoad, IfPm3Legicrf, "Load binary dump to emulator memory"}, {"esave", CmdLegicESave, IfPm3Legicrf, "Save emulator memory to binary file"}, {"eview", CmdLegicEView, IfPm3Legicrf, "View emulator memory"}, + {"einfo", CmdLegicEInfo, IfPm3Legicrf, "Display deobfuscated and decoded emulator memory"}, {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("utils") " ---------------------"}, {"crc", CmdLegicCalcCrc, AlwaysAvailable, "Calculate Legic CRC over given bytes"}, {"view", CmdLegicView, AlwaysAvailable, "Display content from tag dump file"}, + {"dinfo", CmdLegicDInfo, AlwaysAvailable, "Display deobfuscated and decoded content from tag dump file"}, {NULL, NULL, NULL, NULL} }; From 4b3e64fbd03c08e53523a1f93c4dd91d3f2e226c Mon Sep 17 00:00:00 2001 From: Fabian Schneebauer Date: Thu, 16 Mar 2023 17:17:44 +0100 Subject: [PATCH 706/759] Add change to changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffcac2de5..178acff1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Add Mifare Classic EV1 signature write support to gen4 magic tag lua script (@augustozanellato) - Added XOR key extraction and flag to Guardall G-Prox II (@GuruSteve) - Changed verbiage on `hf iclass info` KeyAccess area to be congruent with AA1 and AA2 areas (@GuruSteve) + - Added `hf legic info` command for other sources: `hf legic einfo`, `hf legic dinfo` - ## [Nitride.4.16191][2023-01-29] From fb46e8bae746e8924998fd4d9afd25a3b4553134 Mon Sep 17 00:00:00 2001 From: Fabian Schneebauer Date: Thu, 16 Mar 2023 20:38:13 +0100 Subject: [PATCH 707/759] Merge functionality of view and dinfo. --- CHANGELOG.md | 2 +- client/src/cmdhflegic.c | 32 ++------------------------------ 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 178acff1c..59959b489 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Add Mifare Classic EV1 signature write support to gen4 magic tag lua script (@augustozanellato) - Added XOR key extraction and flag to Guardall G-Prox II (@GuruSteve) - Changed verbiage on `hf iclass info` KeyAccess area to be congruent with AA1 and AA2 areas (@GuruSteve) - - Added `hf legic info` command for other sources: `hf legic einfo`, `hf legic dinfo` + - Added `hf legic info` command for other sources: `hf legic einfo`, `hf legic view` (@0xdeb) - ## [Nitride.4.16191][2023-01-29] diff --git a/client/src/cmdhflegic.c b/client/src/cmdhflegic.c index 5ca53ecd3..02a43e0aa 100644 --- a/client/src/cmdhflegic.c +++ b/client/src/cmdhflegic.c @@ -1367,35 +1367,8 @@ static int CmdLegicView(const char *Cmd) { 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_read, 16); - free(dump); - return PM3_SUCCESS; -} - -static int CmdLegicDInfo(const char *Cmd) { - CLIParserContext *ctx; - CLIParserInit(&ctx, "hf legic view", - "Print a LEGIC Prime dump file (bin/eml/json)", - "hf legic view -f hf-legic-01020304-dump.bin" - ); - void *argtable[] = { - arg_param_begin, - arg_str1("f", "file", "", "Filename of dump"), - arg_param_end - }; - CLIExecWithReturn(ctx, Cmd, argtable, false); - int fnlen = 0; - char filename[FILE_PATH_SIZE]; - CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); - CLIParserFree(ctx); - - // read dump file - uint8_t *dump = NULL; - size_t bytes_read = 0; - int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, LEGIC_PRIME_MIM1024); - if (res != PM3_SUCCESS) { - return res; - } + PrintAndLogEx(NORMAL, ""); decode_and_print_memory(bytes_read, dump); free(dump); @@ -1421,8 +1394,7 @@ static command_t CommandTable[] = { {"einfo", CmdLegicEInfo, IfPm3Legicrf, "Display deobfuscated and decoded emulator memory"}, {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("utils") " ---------------------"}, {"crc", CmdLegicCalcCrc, AlwaysAvailable, "Calculate Legic CRC over given bytes"}, - {"view", CmdLegicView, AlwaysAvailable, "Display content from tag dump file"}, - {"dinfo", CmdLegicDInfo, AlwaysAvailable, "Display deobfuscated and decoded content from tag dump file"}, + {"view", CmdLegicView, AlwaysAvailable, "Display deobfuscated and decoded content from tag dump file"}, {NULL, NULL, NULL, NULL} }; From 69e43b362e0c2c08494a4f8015c9e029f3924386 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 19 Mar 2023 12:47:24 +0100 Subject: [PATCH 708/759] fix asn1 parsing of dates --- client/src/crypto/asn1dump.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index 1b6eede1c..17c38bf55 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -123,12 +123,20 @@ static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag if (len > 4) { PrintAndLogEx(NORMAL, " value: '" NOLF); while (true) { + // year - if (longyear == false) - PrintAndLogEx(NORMAL, "20" NOLF); + if (longyear == false) { + int short_year = (tlv->value[0] - '0') * 10 + (tlv->value[1] - '0'); + if (short_year >= 0 && short_year <= 99) { + if (short_year > 50) { + PrintAndLogEx(NORMAL, "19" NOLF); + } else { + PrintAndLogEx(NORMAL, "20" NOLF); + } + } + } PrintAndLogEx(NORMAL, "%.*s-" NOLF, startidx, tlv->value); - if (len < startidx + 2) break; @@ -154,11 +162,11 @@ static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag // sec PrintAndLogEx(NORMAL, "%.*s" NOLF, 2, tlv->value + startidx + 8); - if (len < startidx + 11) + if (len < startidx + 12) break; // time zone - PrintAndLogEx(NORMAL, " zone: %.*s" NOLF, len - 10 - (longyear ? 4 : 2), tlv->value + startidx + 10); + PrintAndLogEx(NORMAL, " zone: %.*s" NOLF, len - startidx - 10, tlv->value + startidx + 10); break; } PrintAndLogEx(NORMAL, "'"); From 23926a7a146ce4867f02fa027c12bbda161a1a31 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 19 Mar 2023 12:48:47 +0100 Subject: [PATCH 709/759] fix leading zero call --- client/src/util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/util.c b/client/src/util.c index ea33de446..723f3e758 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -45,7 +45,7 @@ bool g_pendingPrompt = false; #include #endif -#define MAX_BIN_BREAK_LENGTH (3072+384+1) +#define MAX_BIN_BREAK_LENGTH (3072 + 384 + 1) #ifndef _WIN32 #include @@ -1229,7 +1229,7 @@ inline uint64_t bitcount64(uint64_t a) { inline uint32_t leadingzeros32(uint32_t a) { #if defined __GNUC__ - return __builtin_clzl(a); + return __builtin_clz(a); #else PrintAndLogEx(FAILED, "Was not compiled with fct bitcount64"); return 0; From 9399d4e40076ff8b9459f02b301013414ff7b5a2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 19 Mar 2023 12:49:38 +0100 Subject: [PATCH 710/759] fix hex 2 binstring functions --- client/src/util.c | 30 ++++++++++++++++++++---------- client/src/util.h | 4 ++++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/client/src/util.c b/client/src/util.c index 723f3e758..51408a524 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -911,27 +911,32 @@ https://github.com/ApertureLabsLtd/RFIDler/blob/master/firmware/Pic32/RFIDler.X/ // convert hex to sequence of 0/1 bit values // returns number of bits converted int hextobinarray(char *target, char *source) { - int length, i, count = 0; + return hextobinarray_n(target, source, strlen(source)); +} + +int hextobinarray_n(char *target, char *source, int sourcelen) { + int i, count = 0; char *start = source; - length = strlen(source); // process 4 bits (1 hex digit) at a time - while (length--) { + while (sourcelen--) { char x = *(source++); // capitalize - if (x >= 'a' && x <= 'f') + if (x >= 'a' && x <= 'f') { x -= 32; + } // convert to numeric value - if (x >= '0' && x <= '9') + if (x >= '0' && x <= '9') { x -= '0'; - else if (x >= 'A' && x <= 'F') + } else if (x >= 'A' && x <= 'F') { x -= 'A' - 10; - else { + } else { PrintAndLogEx(INFO, "(hextobinarray) discovered unknown character %c %d at idx %d of %s", x, x, (int16_t)(source - start), start); return 0; } // output - for (i = 0 ; i < 4 ; ++i, ++count) + for (i = 0 ; i < 4 ; ++i, ++count) { *(target++) = (x >> (3 - i)) & 1; + } } return count; @@ -939,9 +944,14 @@ int hextobinarray(char *target, char *source) { // convert hex to human readable binary string int hextobinstring(char *target, char *source) { - int length = hextobinarray(target, source); - if (length == 0) + return hextobinstring_n(target, source, strlen(source)); +} + +int hextobinstring_n(char *target, char *source, int sourcelen) { + int length = hextobinarray_n(target, source, sourcelen); + if (length == 0) { return 0; + } binarraytobinstring(target, target, length); return length; } diff --git a/client/src/util.h b/client/src/util.h index c29fbd50f..4dab9ae06 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -112,7 +112,11 @@ int param_getbin_to_eol(const char *line, int paramnum, uint8_t *data, int maxda int param_getstr(const char *line, int paramnum, char *str, size_t buffersize); int hextobinarray(char *target, char *source); +int hextobinarray_n(char *target, char *source, int sourcelen); + int hextobinstring(char *target, char *source); +int hextobinstring_n(char *target, char *source, int sourcelen); + int binarraytohex(char *target, const size_t targetlen, const char *source, size_t srclen); void binarraytobinstring(char *target, char *source, int length); int binstring2binarray(uint8_t *target, char *source, int length); From 390720144a393d864b5fa1d176ae8ad3510a96bf Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 20 Mar 2023 20:28:57 +0100 Subject: [PATCH 711/759] added another gen3 test to detect gdm --- armsrc/mifarecmd.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 74e75ddce..e198d37c7 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2356,6 +2356,7 @@ void MifareCIdent(bool is_mfc) { uint8_t rats[4] = { ISO14443A_CMD_RATS, 0x80, 0x31, 0x73 }; uint8_t rdblf0[4] = { ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f}; uint8_t rdbl00[4] = { ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8}; + uint8_t gen3gmd[4] = { MIFARE_MAGIC_GDM_AUTH_KEYA, 0x00, 0x6C, 0x92}; uint8_t gen4GetConf[8] = { GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0}; uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); @@ -2479,7 +2480,7 @@ void MifareCIdent(bool is_mfc) { } } } else { - // magic MFC Gen3 test + // magic MFC Gen3 test 1 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(40); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -2491,6 +2492,21 @@ void MifareCIdent(bool is_mfc) { isGen = MAGIC_GEN_3; } } + + // magic MFC Gen3 test 2 + if (isGen != MAGIC_GEN_3) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(40); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); + if (res == 2) { + ReaderTransmit(gen3gmd, sizeof(gen3gmd), NULL); + res = ReaderReceive(buf, par); + if (res == 4) { + isGen = MAGIC_GEN_3; + } + } + } } }; From 07f61627801576a17dcc6af835e3d6691739fa5a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Mar 2023 19:49:52 +0100 Subject: [PATCH 712/759] added support for the magic card called GDM. --- CHANGELOG.md | 2 + armsrc/appmain.c | 16 ++++++- armsrc/mifarecmd.c | 75 ++++++++++++++++++++++++++++-- armsrc/mifarecmd.h | 5 ++ armsrc/mifareutil.c | 22 +++++++-- armsrc/mifareutil.h | 2 + client/src/cmdhfmf.c | 84 ++++++++++++++++++++++++++++++++++ client/src/mifare/mifarehost.c | 4 ++ include/pm3_cmd.h | 4 ++ include/protocols.h | 2 + 10 files changed, 205 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59959b489..1cceee09b 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 `hf mf gdmsetblk` - Support Gen4 GDM write block (@iceman1001) + - Changed `hf 14a info` - detect Gen GDM magic tags (@iceman1001) - Changed CLI max string argument length limit from 512 to 4096 (@iceman1001) - Fixed `data asn1` - now handles bad input better (@iceman1001) - Added new public key for signature MIFARE Plus Troika (@iceman100) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 66d1380b5..d435f9967 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1686,7 +1686,7 @@ static void PacketReceived(PacketCommandNG *packet) { MifareECardLoadExt(payload->sectorcnt, payload->keytype); break; } - // Work with "magic Chinese" card + // Gen1a / 1b - "magic Chinese" card case CMD_HF_MIFARE_CSETBL: { MifareCSetBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; @@ -1713,6 +1713,7 @@ static void PacketReceived(PacketCommandNG *packet) { MifareGen3Freez(); break; } + // Gen 4 GTU magic cards case CMD_HF_MIFARE_G4_RDBL: { struct p { uint8_t blockno; @@ -1723,7 +1724,6 @@ static void PacketReceived(PacketCommandNG *packet) { MifareG4ReadBlk(payload->blockno, payload->pwd, payload->workFlags); break; } - // Gen 4 GTU magic cards case CMD_HF_MIFARE_G4_WRBL: { struct p { uint8_t blockno; @@ -1735,6 +1735,18 @@ static void PacketReceived(PacketCommandNG *packet) { MifareG4WriteBlk(payload->blockno, payload->pwd, payload->data, payload->workFlags); break; } + + case CMD_HF_MIFARE_G4_GDM_WRBL: { + struct p { + uint8_t blockno; + uint8_t keytype; + uint8_t key[6]; + uint8_t data[16]; // data to be written + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + MifareWriteBlockGDM(payload->blockno, payload->keytype, payload->key, payload->data); + break; + } case CMD_HF_MIFARE_PERSONALIZE_UID: { struct p { uint8_t keytype; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index e198d37c7..448cadc8f 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -446,6 +446,73 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { set_tracing(false); } +void MifareWriteBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key, uint8_t *datain) { + + int retval = PM3_SUCCESS; + + // check args + if (datain == NULL) { + retval = PM3_EINVARG; + goto OUT; + } + + uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); + if (par == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + + uint8_t *uid = BigBuf_malloc(10); + if (uid == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + + // variables + uint32_t cuid = 0; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + + uint64_t ui64key = bytes_to_num(key, 6); + + if (iso14443a_select_card(uid, NULL, &cuid, true, 0, true) == false) { + retval = PM3_ESOFT; + goto OUT; + } + + if (mifare_classic_authex_2(pcs, cuid, blockno, keytype, ui64key, AUTH_FIRST, NULL, NULL, true)) { + retval = PM3_ESOFT; + goto OUT; + }; + + if (mifare_classic_writeblock_ex(pcs, cuid, blockno, datain, true)) { + retval = PM3_ESOFT; + goto OUT; + }; + + if (mifare_classic_halt(pcs, cuid)) { + retval = PM3_ESOFT; + goto OUT; + }; + + if (g_dbglevel >= 2) DbpString("WRITE BLOCK FINISHED"); + +OUT: + crypto1_deinit(pcs); + + reply_ng(CMD_HF_MIFARE_G4_GDM_WRBL, retval, NULL, 0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); + BigBuf_free(); +} + + void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t *datain) { // params uint8_t blockNo = arg0; @@ -2356,7 +2423,7 @@ void MifareCIdent(bool is_mfc) { uint8_t rats[4] = { ISO14443A_CMD_RATS, 0x80, 0x31, 0x73 }; uint8_t rdblf0[4] = { ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f}; uint8_t rdbl00[4] = { ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8}; - uint8_t gen3gmd[4] = { MIFARE_MAGIC_GDM_AUTH_KEYA, 0x00, 0x6C, 0x92}; + uint8_t gen4gmd[4] = { MIFARE_MAGIC_GDM_AUTH_KEYA, 0x00, 0x6C, 0x92}; uint8_t gen4GetConf[8] = { GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0}; uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); @@ -2493,17 +2560,17 @@ void MifareCIdent(bool is_mfc) { } } - // magic MFC Gen3 test 2 + // magic MFC Gen4 GDM test if (isGen != MAGIC_GEN_3) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(40); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { - ReaderTransmit(gen3gmd, sizeof(gen3gmd), NULL); + ReaderTransmit(gen4gmd, sizeof(gen4gmd), NULL); res = ReaderReceive(buf, par); if (res == 4) { - isGen = MAGIC_GEN_3; + isGen = MAGIC_GEN_4GDM; } } } diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 30179aa3b..f471ccecc 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -46,16 +46,21 @@ void MifareEMemGet(uint8_t blockno, uint8_t blockcnt); int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype); int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype); +// MFC GEN1a /1b void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); void MifareCIdent(bool is_mfc); // is "magic chinese" card? void MifareHasStaticNonce(void); // Has the tag a static nonce? +// MFC GEN3 int DoGen3Cmd(uint8_t *cmd, uint8_t cmd_len); void MifareGen3UID(uint8_t uidlen, uint8_t *uid); // Gen 3 magic card set UID without manufacturer block void MifareGen3Blk(uint8_t block_len, uint8_t *block); // Gen 3 magic card overwrite manufacturer block void MifareGen3Freez(void); // Gen 3 magic card lock further UID changes +// MFC GEN4 GDM +void MifareWriteBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key, uint8_t *datain); + // MFC GEN4 GTU void MifareG4ReadBlk(uint8_t blockno, uint8_t *pwd, uint8_t workFlags); void MifareG4WriteBlk(uint8_t blockno, uint8_t *pwd, uint8_t *data, uint8_t workFlags); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 5c0905e68..c349860dd 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -137,8 +137,10 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested) { return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL); } - int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) { + return mifare_classic_authex_2(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL, false); +} +int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing, bool is_gdm) { int len; uint32_t pos, nt, ntpp; // Supplied tag nonce uint8_t par[1] = {0x00}; @@ -150,8 +152,9 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN // "random" reader nonce: num_to_bytes(prng_successor(GetTickCount(), 32), 4, nr); - // Transmit MIFARE_CLASSIC_AUTH - len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing); + // Transmit MIFARE_CLASSIC_AUTH 0x60, 0x61 or GDM 0x80 + uint8_t cmdbyte = (is_gdm) ? MIFARE_MAGIC_GDM_AUTH_KEYA : MIFARE_AUTH_KEYA + (keyType & 0x01); + len = mifare_sendcmd_short(pcs, isNested, cmdbyte, blockNo, receivedAnswer, receivedAnswerPar, timing); if (len != 4) return 1; // Save the tag nonce (nt) @@ -411,6 +414,10 @@ int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData) { } int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { + return mifare_classic_writeblock_ex(pcs, uid, blockNo, blockData, false); +} + +int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, bool is_gdm) { // variables uint16_t len = 0; uint32_t pos = 0; @@ -421,8 +428,12 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - // command MIFARE_CLASSIC_WRITEBLOCK - len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); + // command MIFARE_MAGIC_GDM_WRITEBLOCK + if (is_gdm) { + len = mifare_sendcmd_short(pcs, 1, MIFARE_MAGIC_GDM_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); + } else { + len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); + } if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); @@ -456,6 +467,7 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl return 0; } + int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t action) { // variables uint16_t len = 0; diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index aa5ef7e59..c7c6b4a94 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -72,10 +72,12 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t // mifare classic int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested); int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing); +int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing, bool is_gdm); int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); int mifare_classic_halt_ex(struct Crypto1State *pcs); int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); +int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, bool is_gdm); int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t action); // Ultralight/NTAG... diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index d5a629e90..900f201d2 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -7560,6 +7560,88 @@ static int CmdHF14AGen4Save(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf gdmsetblk", + "Set block data on a magic gen4 GDM card", + "hf mf gdmsetblk --blk 1 -d 000102030405060708090a0b0c0d0e0f" + ); + void *argtable[] = { + arg_param_begin, + arg_int1(NULL, "blk", "", "block number"), + arg_lit0("a", NULL, "input key type is key A (def)"), + arg_lit0("b", NULL, "input key type is key B"), + arg_str0("k", "key", "", "key, 6 hex bytes"), + arg_str0("d", "data", "", "bytes to write, 16 hex bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int b = arg_get_int_def(ctx, 1, 1); + + uint8_t keytype = MF_KEY_A; + if (arg_get_lit(ctx, 2) && arg_get_lit(ctx, 3)) { + CLIParserFree(ctx); + PrintAndLogEx(WARNING, "Input key type must be A or B"); + return PM3_EINVARG; + } else if (arg_get_lit(ctx, 3)) { + keytype = MF_KEY_B;; + } + + int keylen = 0; + uint8_t key[6] = {0}; + CLIGetHexWithReturn(ctx, 4, key, &keylen); + + uint8_t block[MFBLOCK_SIZE] = {0x00}; + int blen = 0; + CLIGetHexWithReturn(ctx, 5, block, &blen); + CLIParserFree(ctx); + + if (blen != MFBLOCK_SIZE) { + PrintAndLogEx(WARNING, "expected 16 HEX bytes. got %i", blen); + return PM3_EINVARG; + } + + if (b < 0 || b >= MIFARE_4K_MAXBLOCK) { + PrintAndLogEx(FAILED, "target block number out-of-range, got %i", b); + return PM3_EINVARG; + } + + uint8_t blockno = (uint8_t)b; + + PrintAndLogEx(INFO, "Writing block no %d, key %c - %s", blockno, (keytype == MF_KEY_B) ? 'B' : 'A', sprint_hex_inrow(key, sizeof(key))); + PrintAndLogEx(INFO, "data: %s", sprint_hex(block, sizeof(block))); + + struct p { + uint8_t blockno; + uint8_t keytype; + uint8_t key[6]; + uint8_t data[MFBLOCK_SIZE]; // data to be written + } PACKED payload; + + payload.blockno = blockno; + payload.keytype = keytype; + memcpy(payload.key, key, sizeof(payload.key)); + memcpy(payload.data, block, sizeof(payload.data)); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_G4_GDM_WRBL, (uint8_t *)&payload, sizeof(payload)); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_HF_MIFARE_G4_GDM_WRBL, &resp, 1500) == false) { + PrintAndLogEx(WARNING, "command execute timeout"); + return PM3_ETIMEOUT; + } + + if (resp.status == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )"); + PrintAndLogEx(HINT, "try `" _YELLOW_("hf mf rdbl") "` to verify"); + } else { + PrintAndLogEx(FAILED, "Write ( " _RED_("fail") " )"); + PrintAndLogEx(HINT, "Maybe access rights? Try specify keytype `" _YELLOW_("hf mf gdmsetblk -%c ...") "` instead", (keytype == MF_KEY_A) ? 'b' : 'a'); + } + return PM3_SUCCESS; +} static int CmdHF14AMfValue(const char *Cmd) { @@ -7825,6 +7907,8 @@ static command_t CommandTable[] = { {"gsave", CmdHF14AGen4Save, IfPm3Iso14443a, "Save dump from card into file or emulator"}, {"gsetblk", CmdHF14AGen4SetBlk, IfPm3Iso14443a, "Write block to card"}, {"gview", CmdHF14AGen4View, IfPm3Iso14443a, "View card"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GDM") " --------------------------"}, + {"gdmsetblk", CmdHF14AGen4_GDM_SetBlk, IfPm3Iso14443a, "Write block to card"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"}, // {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, {"ndefformat", CmdHFMFNDEFFormat, IfPm3Iso14443a, "Format MIFARE Classic Tag as NFC Tag"}, diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index fe2cd1897..a897a507e 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1214,6 +1214,7 @@ int mfG4SetBlock(uint8_t *pwd, uint8_t blockno, uint8_t *data, uint8_t workFlags return PM3_SUCCESS; } + // variables uint32_t cuid = 0; // uid part used for crypto1. @@ -1414,6 +1415,9 @@ int detect_mf_magic(bool is_mfc) { case MAGIC_GEN_4GTU: PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Gen 4 GTU")); break; + case MAGIC_GEN_4GDM: + PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Gen 4 GDM")); + break; case MAGIC_GEN_UNFUSED: PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Write Once / FUID")); break; diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 40a263442..f490cc419 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -686,6 +686,10 @@ typedef struct { #define CMD_HF_MIFARE_G4_RDBL 0x0860 #define CMD_HF_MIFARE_G4_WRBL 0x0861 +// Gen 4 GDM magic cards +#define CMD_HF_MIFARE_G4_GDM_RDBL 0x0870 +#define CMD_HF_MIFARE_G4_GDM_WRBL 0x0871 + #define CMD_UNKNOWN 0xFFFF //Mifare simulation flags diff --git a/include/protocols.h b/include/protocols.h index 0cc89abb7..333dcdb71 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -192,6 +192,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MIFARE_MAGIC_GDM_AUTH_KEYA 0x80 #define MIFARE_MAGIC_GDM_AUTH_KEYB 0x81 +#define MIFARE_MAGIC_GDM_WRITEBLOCK 0xA8 #define MIFARE_EV1_PERSONAL_UID 0x40 #define MIFARE_EV1_SETMODE 0x43 @@ -259,6 +260,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MAGIC_NTAG21X 7 #define MAGIC_GEN_3 8 #define MAGIC_GEN_4GTU 9 +#define MAGIC_GEN_4GDM 10 // Commands for configuration of Gen4 GTU cards. // see https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/magic_cards_notes.md From e1d90b3de205ba91b00a7e4e316a24855011a973 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Mar 2023 19:58:31 +0100 Subject: [PATCH 713/759] annotate the GDM magic write --- client/src/cmdhflist.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index fc3f94d7a..d4778b8be 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -330,6 +330,10 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i snprintf(exp, size, "MAGIC AUTH-B(%d)", cmd[1]); break; } + case MIFARE_MAGIC_GDM_WRITEBLOCK: { + snprintf(exp, size, "MAGIC WRITEBLOCK(%d)", cmd[1]); + break; + } case MIFARE_MAGICWUPC1: snprintf(exp, size, "MAGIC WUPC1"); break; From 97dced62f4db438bd3762b31b57032581fe7163a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Mar 2023 20:55:06 +0100 Subject: [PATCH 714/759] fix CID# 405674 - array uninitialized --- armsrc/mifarecmd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 448cadc8f..aaf1d795a 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1905,6 +1905,8 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) { bool found; } PACKED keyresult; keyresult.found = false; + memset(keyresult.key, 0x00, sizeof(keyresult.key)); + bool have_uid = false; uint8_t keyType = datain[0]; From aa05e2eeaec0133dd16724fc63bc4b9d25885687 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 21 Mar 2023 20:55:57 +0100 Subject: [PATCH 715/759] textual and cleanup --- client/src/crypto/asn1dump.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index 17c38bf55..8445b4cd4 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -166,7 +166,7 @@ static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag break; // time zone - PrintAndLogEx(NORMAL, " zone: %.*s" NOLF, len - startidx - 10, tlv->value + startidx + 10); + PrintAndLogEx(NORMAL, " zone: UTC %.*s" NOLF, len - startidx - 10, tlv->value + startidx + 10); break; } PrintAndLogEx(NORMAL, "'"); @@ -177,7 +177,7 @@ static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag } static void asn1_tag_dump_string(const struct tlv *tlv, const struct asn1_tag *tag, int level) { - PrintAndLogEx(NORMAL, " value: '" _GREEN_("%.*s") "' hex: '%s'", tlv->len, tlv->value, sprint_hex(tlv->value, tlv->len)); + PrintAndLogEx(NORMAL, " value: '" _GREEN_("%.*s") "' hex: '%s'", (int)tlv->len, tlv->value, sprint_hex(tlv->value, tlv->len)); } static void asn1_tag_dump_bitstring(const struct tlv *tlv, const struct asn1_tag *tag, int level) { @@ -232,20 +232,17 @@ static void asn1_tag_dump_hex(const struct tlv *tlv, const struct asn1_tag *tag, PrintAndLogEx(NORMAL, " value: '%s'", sprint_hex_inrow(tlv->value, tlv->len)); } -static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_tag *tag, int level, bool *needdump) { - *needdump = false; - for (size_t i = 0; i < tlv->len; i++) +static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_tag *tag, int level) { +/* + for (size_t i = 0; i < tlv->len; i++) { if (!isspace(tlv->value[i]) && !isprint(tlv->value[i])) { *needdump = true; break; } - - if (*needdump) { - PrintAndLogEx(NORMAL, ""); - } else { + } + */ PrintAndLogEx(NORMAL, " " NOLF); asn1_tag_dump_string(tlv, tag, level); - } } static void asn1_tag_dump_boolean(const struct tlv *tlv, const struct asn1_tag *tag, int level) { @@ -399,7 +396,8 @@ bool asn1_tag_dump(const struct tlv *tlv, int level, bool *candump) { *candump = false; break; case ASN1_TAG_OCTET_STRING: - asn1_tag_dump_octet_string(tlv, tag, level, candump); + asn1_tag_dump_octet_string(tlv, tag, level); + *candump = false; break; case ASN1_TAG_BOOLEAN: asn1_tag_dump_boolean(tlv, tag, level); From 693b6487fbf7afd03adfcba6e1ef3692ec4cb5af Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 23 Mar 2023 08:10:02 +0100 Subject: [PATCH 716/759] changed 14a / mifare annotations to more easily see block numbers involved --- client/src/cmdhflist.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index d4778b8be..263a4baa1 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -176,7 +176,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i if (is_response == false) { if ((gs_ntag_i2c_state == 1) && (cmdsize == 6) && (memcmp(cmd + 1, "\x00\x00\x00", 3) == 0)) { - snprintf(exp, size, "SECTOR(%d)", cmd[0]); + snprintf(exp, size, "SECTOR(" _MAGENTA_("%d") ")", cmd[0]); gs_ntag_i2c_state = 0; return PM3_SUCCESS; } @@ -260,10 +260,10 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i snprintf(exp, size, "REQA"); break; case ISO14443A_CMD_READBLOCK: - snprintf(exp, size, "READBLOCK(%d)", cmd[1]); + snprintf(exp, size, "READBLOCK(" _MAGENTA_("%d") ")", cmd[1]); break; case ISO14443A_CMD_WRITEBLOCK: - snprintf(exp, size, "WRITEBLOCK(%d)", cmd[1]); + snprintf(exp, size, "WRITEBLOCK(" _MAGENTA_("%d") ")", cmd[1]); break; case ISO14443A_CMD_HALT: snprintf(exp, size, "HALT"); @@ -279,10 +279,10 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i snprintf(exp, size, "OPTIONAL TIMESLOT"); break; case MIFARE_CMD_INC: - snprintf(exp, size, "INC(%d)", cmd[1]); + snprintf(exp, size, "INC(" _MAGENTA_("%d") ")", cmd[1]); break; case MIFARE_CMD_DEC: - snprintf(exp, size, "DEC(%d)", cmd[1]); + snprintf(exp, size, "DEC(" _MAGENTA_("%d") ")", cmd[1]); break; case MIFARE_CMD_RESTORE: @@ -293,7 +293,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i snprintf(exp, size, "SELECT SECTOR"); gs_ntag_i2c_state = 1; } else { - snprintf(exp, size, "RESTORE(%d)", cmd[1]); + snprintf(exp, size, "RESTORE(" _MAGENTA_("%d") ")", cmd[1]); } } else { return PM3_ESOFT; @@ -301,11 +301,11 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i break; case MIFARE_CMD_TRANSFER: - snprintf(exp, size, "TRANSFER(%d)", cmd[1]); + snprintf(exp, size, "TRANSFER(" _MAGENTA_("%d") ")", cmd[1]); break; case MIFARE_AUTH_KEYA: { if (cmdsize > 3) { - snprintf(exp, size, "AUTH-A(%d)", cmd[1]); + snprintf(exp, size, "AUTH-A(" _MAGENTA_("%d") ")", cmd[1]); MifareAuthState = masNt; } else { // case MIFARE_ULEV1_VERSION : both 0x60. @@ -315,23 +315,23 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i } case MIFARE_AUTH_KEYB: { MifareAuthState = masNt; - snprintf(exp, size, "AUTH-B(%d)", cmd[1]); + snprintf(exp, size, "AUTH-B(" _MAGENTA_("%d") ")", cmd[1]); break; } case MIFARE_MAGIC_GDM_AUTH_KEYA: { if (cmdsize > 3) { - snprintf(exp, size, "MAGIC AUTH-A(%d)", cmd[1]); + snprintf(exp, size, "MAGIC AUTH-A(" _MAGENTA_("%d") ")", cmd[1]); MifareAuthState = masNt; } break; } case MIFARE_MAGIC_GDM_AUTH_KEYB: { MifareAuthState = masNt; - snprintf(exp, size, "MAGIC AUTH-B(%d)", cmd[1]); + snprintf(exp, size, "MAGIC AUTH-B(" _MAGENTA_("%d") ")", cmd[1]); break; } case MIFARE_MAGIC_GDM_WRITEBLOCK: { - snprintf(exp, size, "MAGIC WRITEBLOCK(%d)", cmd[1]); + snprintf(exp, size, "MAGIC WRITEBLOCK(" _MAGENTA_("%d") ")", cmd[1]); break; } case MIFARE_MAGICWUPC1: @@ -371,30 +371,30 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i break; case MIFARE_ULEV1_FASTREAD : { if (cmdsize >= 3 && cmd[2] <= 0xE6) - snprintf(exp, size, "READ RANGE (%d-%d)", cmd[1], cmd[2]); + snprintf(exp, size, "READ RANGE (" _MAGENTA_("%d-%d") ")", cmd[1], cmd[2]); else // outside limits, useful for some tags... - snprintf(exp, size, "READ RANGE (%d-%d) (?)", cmd[1], cmd[2]); + snprintf(exp, size, "READ RANGE (" _MAGENTA_("%d-%d") ") (?)", cmd[1], cmd[2]); break; } case MIFARE_ULC_WRITE : { if (cmd[1] < 0x21) - snprintf(exp, size, "WRITEBLOCK(%d)", cmd[1]); + snprintf(exp, size, "WRITEBLOCK(" _MAGENTA_("%d") ")", cmd[1]); else // outside limits, useful for some tags... - snprintf(exp, size, "WRITEBLOCK(%d) (?)", cmd[1]); + snprintf(exp, size, "WRITEBLOCK(" _MAGENTA_("%d") ") (?)", cmd[1]); break; } case MIFARE_ULEV1_READ_CNT : { if (cmd[1] < 5) - snprintf(exp, size, "READ CNT(%d)", cmd[1]); + snprintf(exp, size, "READ CNT(" _MAGENTA_("%d") ")", cmd[1]); else snprintf(exp, size, "?"); break; } case MIFARE_ULEV1_INCR_CNT : { if (cmd[1] < 5) - snprintf(exp, size, "INCR(%d)", cmd[1]); + snprintf(exp, size, "INCR(" _MAGENTA_("%d") ")", cmd[1]); else snprintf(exp, size, "?"); break; @@ -403,7 +403,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i snprintf(exp, size, "READ SIG"); break; case MIFARE_ULEV1_CHECKTEAR: - snprintf(exp, size, "CHK TEARING(%d)", cmd[1]); + snprintf(exp, size, "CHK TEARING(" _MAGENTA_("%d") ")", cmd[1]); break; case MIFARE_ULEV1_VCSL: snprintf(exp, size, "VCSL"); @@ -422,7 +422,7 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i } case NTAG_I2C_FASTWRITE: if (cmdsize == 69) - snprintf(exp, size, "FAST WRITE (%d - %d)", cmd[1], cmd[2]); + snprintf(exp, size, "FAST WRITE (" _MAGENTA_("%d-%d") ")", cmd[1], cmd[2]); else snprintf(exp, size, "?"); From 368bf576616ea0d5b686cef748a8903f39aaecd5 Mon Sep 17 00:00:00 2001 From: Self Not Found Date: Fri, 24 Mar 2023 18:44:28 +0800 Subject: [PATCH 717/759] Fix the example of msleep --- client/src/cmdmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdmain.c b/client/src/cmdmain.c index 11f9bfd7b..a9c2cb474 100644 --- a/client/src/cmdmain.c +++ b/client/src/cmdmain.c @@ -250,7 +250,7 @@ static int CmdMsleep(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "msleep", "Sleep for given amount of milliseconds", - "msleep 100" + "msleep -t 100" ); void *argtable[] = { From 2661a2a034a7c5f3a3e18991151c5c6174922928 Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Sat, 25 Mar 2023 02:00:08 +0300 Subject: [PATCH 718/759] Supercard UID changing from backdoor command --- CHANGELOG.md | 1 + client/src/cmdhfmf.c | 46 ++++++++++++++++++++++++++++++++++++-------- doc/commands.json | 5 +++-- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cceee09b..cc2be3390 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] + - Changed `hf mf supercard` - Support editing UID (@AloneLiberty) - Added `hf mf gdmsetblk` - Support Gen4 GDM write block (@iceman1001) - Changed `hf 14a info` - detect Gen GDM magic tags (@iceman1001) - Changed CLI max string argument length limit from 512 to 4096 (@iceman1001) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 900f201d2..e3ba0c1df 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6572,29 +6572,62 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf supercard", "Extract info from a `super card`", - "hf mf supercard"); + "hf mf supercard -> recover key\n" + "hf mf supercard -r -> reset card\n" + "hf mf supercard -u 11223344 -> change UID\n"); void *argtable[] = { arg_param_begin, - arg_lit0("r", "reset", "reset card"), + arg_lit0("r", "reset", "reset card"), + arg_str0("u", "uid", "", "New UID (4 hex bytes)"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); bool reset_card = arg_get_lit(ctx, 1); + uint8_t uid[4]; + int uidlen = 0; + CLIParamHexToBuf(arg_get_str(ctx, 2), uid, sizeof(uid), &uidlen); CLIParserFree(ctx); + if (uidlen && uidlen != 4) { + PrintAndLogEx(ERR, "UID must include 8 HEX symbols"); + return PM3_EINVARG; + } + bool activate_field = true; bool keep_field_on = true; int res = 0; - if (reset_card) { + // Commands: + // a0 - set UID + // b0 - read traces + // c0 - clear card + if (uidlen) { + keep_field_on = false; + uint8_t response[6]; + int resplen = 0; + // --------------- CHANGE UID ---------------- + uint8_t aCHANGE[] = {0x00, 0xa6, 0xa0, 0x00, 0x05, 0xff, 0xff, 0xff, 0xff, 0x00}; + memcpy(aCHANGE + 5, uid, uidlen); + res = ExchangeAPDU14a(aCHANGE, sizeof(aCHANGE), activate_field, keep_field_on, response, sizeof(response), &resplen); + if (res != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Super card UID change [ " _RED_("fail") " ]"); + DropField(); + return res; + } + + PrintAndLogEx(SUCCESS, "Super card UID change ( " _GREEN_("ok") " )"); + return PM3_SUCCESS; + } + + if (reset_card) { keep_field_on = false; uint8_t response[6]; int resplen = 0; // --------------- RESET CARD ---------------- - uint8_t aRESET[] = { 0x00, 0xa6, 0xc0, 0x00 }; + uint8_t aRESET[] = { 0x00, 0xa6, 0xc0, 0x00 }; res = ExchangeAPDU14a(aRESET, sizeof(aRESET), activate_field, keep_field_on, response, sizeof(response), &resplen); if (res != PM3_SUCCESS) { PrintAndLogEx(FAILED, "Super card reset [ " _RED_("fail") " ]"); @@ -6630,9 +6663,6 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { return res; } -// uint8_t inA[] = { 0x72, 0xD7, 0xF4, 0x3E, 0xFD, 0xAB, 0xF2, 0x35, 0xFD, 0x49, 0xEE, 0xDC, 0x44, 0x95, 0x43, 0xC4}; -// uint8_t inB[] = { 0xF0, 0xA2, 0x67, 0x6A, 0x04, 0x6A, 0x72, 0x12, 0x76, 0xA4, 0x1D, 0x02, 0x1F, 0xEA, 0x20, 0x85}; - uint8_t outA[16] = {0}; uint8_t outB[16] = {0}; @@ -6670,7 +6700,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { // second NT0 = (outB[6] << 8) | outB[7]; - data.nonce2 = prng_successor(NT0, 31);; + data.nonce2 = prng_successor(NT0, 31); data.nr2 = bytes_to_num(outB + 8, 4); data.ar2 = bytes_to_num(outB + 12, 4); data.sector = mfSectorNum(outA[5]); diff --git a/doc/commands.json b/doc/commands.json index 3b1ac6aca..636fdf50a 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -4827,9 +4827,10 @@ "offline": false, "options": [ "-h, --help This help", - "-r, --reset reset card" + "-r, --reset Reset card", + "-u, --uid Change UID" ], - "usage": "hf mf supercard [-hr]" + "usage": "hf mf supercard [-hru]" }, "hf mf value": { "command": "hf mf value", From b903d0bbe227dc497c938ce28f837f6a70fe3164 Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Sat, 25 Mar 2023 02:15:07 +0300 Subject: [PATCH 719/759] Supercard keys recovery from second generation card --- CHANGELOG.md | 2 +- client/src/cmdhfmf.c | 326 +++++++++++++++++++++++++++---------------- 2 files changed, 206 insertions(+), 122 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc2be3390..3dd2f9b3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +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] - - Changed `hf mf supercard` - Support editing UID (@AloneLiberty) + - Changed `hf mf supercard` - Support editing UID and recovery of keys from second generation card (@AloneLiberty) - Added `hf mf gdmsetblk` - Support Gen4 GDM write block (@iceman1001) - Changed `hf 14a info` - detect Gen GDM magic tags (@iceman1001) - Changed CLI max string argument length limit from 512 to 4096 (@iceman1001) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index e3ba0c1df..0abc1eb1f 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6568,7 +6568,6 @@ static int CmdHf14AGen3Freeze(const char *Cmd) { } static int CmdHf14AMfSuperCard(const char *Cmd) { - CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf supercard", "Extract info from a `super card`", @@ -6594,139 +6593,224 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { return PM3_EINVARG; } - bool activate_field = true; - bool keep_field_on = true; - int res = 0; + uint32_t trace = 0; + uint8_t traces[7][16]; + for (trace = 0; trace < 7; trace++) { + uint8_t data[] = {0x30, 0x00 + trace}; + uint32_t flags = ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_RATS; - // Commands: - // a0 - set UID - // b0 - read traces - // c0 - clear card - if (uidlen) { - keep_field_on = false; - uint8_t response[6]; - int resplen = 0; + clearCommandBuffer(); + SendCommandOLD(CMD_HF_ISO14443A_READER, flags, sizeof(data), 0, data, sizeof(data)); - // --------------- CHANGE UID ---------------- - uint8_t aCHANGE[] = {0x00, 0xa6, 0xa0, 0x00, 0x05, 0xff, 0xff, 0xff, 0xff, 0x00}; - memcpy(aCHANGE + 5, uid, uidlen); - res = ExchangeAPDU14a(aCHANGE, sizeof(aCHANGE), activate_field, keep_field_on, response, sizeof(response), &resplen); - if (res != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Super card UID change [ " _RED_("fail") " ]"); - DropField(); - return res; + if (!WaitForResponseTimeout(CMD_ACK, NULL, 1500)) { + break; // Select card } - PrintAndLogEx(SUCCESS, "Super card UID change ( " _GREEN_("ok") " )"); - return PM3_SUCCESS; - } - - if (reset_card) { - keep_field_on = false; - uint8_t response[6]; - int resplen = 0; - - // --------------- RESET CARD ---------------- - uint8_t aRESET[] = { 0x00, 0xa6, 0xc0, 0x00 }; - res = ExchangeAPDU14a(aRESET, sizeof(aRESET), activate_field, keep_field_on, response, sizeof(response), &resplen); - if (res != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Super card reset [ " _RED_("fail") " ]"); - DropField(); - return res; + PacketResponseNG resp; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + break; // Data not received } - PrintAndLogEx(SUCCESS, "Super card reset ( " _GREEN_("ok") " )"); - return PM3_SUCCESS; + + uint16_t len = resp.oldarg[0] & 0xFFFF; + if (len != 18) { + break; // Not trace data + } + + memcpy(&traces[trace], resp.data.asBytes, len - 2); } + if (trace == 7) { + if (uidlen || reset_card) { + PrintAndLogEx(FAILED, "Not supported on this card"); + return PM3_SUCCESS; + } - uint8_t responseA[22]; - uint8_t responseB[22]; - int respAlen = 0; - int respBlen = 0; + for (trace = 0; trace < 7; trace++) { + uint8_t *trace_data = traces[trace]; + nonces_t data; - // --------------- First ---------------- - uint8_t aFIRST[] = { 0x00, 0xa6, 0xb0, 0x00, 0x10 }; - res = ExchangeAPDU14a(aFIRST, sizeof(aFIRST), activate_field, keep_field_on, responseA, sizeof(responseA), &respAlen); - if (res != PM3_SUCCESS) { - DropField(); - return res; - } + // first + uint16_t NT0 = (trace_data[6] << 8) | trace_data[7]; + data.cuid = bytes_to_num(trace_data, 4); + data.nonce = prng_successor(NT0, 31); + data.nr = bytes_to_num(trace_data + 8, 4); + data.ar = bytes_to_num(trace_data + 12, 4); + data.at = 0; - // --------------- Second ---------------- - activate_field = false; - keep_field_on = false; + // second + for (uint8_t s_strace = trace + 1; s_strace < 7; s_strace++) { + uint8_t *s_trace_data = traces[s_strace]; + if (mfSectorNum(s_trace_data[5]) == mfSectorNum(trace_data[5])) { + NT0 = (s_trace_data[6] << 8) | s_trace_data[7]; + data.nonce2 = prng_successor(NT0, 31); + data.nr2 = bytes_to_num(s_trace_data + 8, 4); + data.ar2 = bytes_to_num(s_trace_data + 12, 4); + data.sector = mfSectorNum(trace_data[5]); + data.keytype = trace_data[4]; + data.state = FIRST; - uint8_t aSECOND[] = { 0x00, 0xa6, 0xb0, 0x01, 0x10 }; - res = ExchangeAPDU14a(aSECOND, sizeof(aSECOND), activate_field, keep_field_on, responseB, sizeof(responseB), &respBlen); - if (res != PM3_SUCCESS) { - DropField(); - return res; - } + uint64_t key64 = -1; + int res = mfkey32_moebius(&data, &key64); - uint8_t outA[16] = {0}; - uint8_t outB[16] = {0}; - - uint8_t key[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; - for (uint8_t i = 0; i < 16; i += 8) { - des_decrypt(outA + i, responseA + i, key); - des_decrypt(outB + i, responseB + i, key); - } - - PrintAndLogEx(DEBUG, " in : %s", sprint_hex_inrow(responseA, respAlen)); - PrintAndLogEx(DEBUG, "out : %s", sprint_hex_inrow(outA, sizeof(outA))); - PrintAndLogEx(DEBUG, " in : %s", sprint_hex_inrow(responseB, respAlen)); - PrintAndLogEx(DEBUG, "out : %s", sprint_hex_inrow(outB, sizeof(outB))); - - if (memcmp(outA, "\x01\x01\x01\x01\x01\x01\x01\x01", 8) == 0) { - PrintAndLogEx(INFO, "No trace recorded"); - return PM3_SUCCESS; - } - - // second trace? - if (memcmp(outB, "\x01\x01\x01\x01\x01\x01\x01\x01", 8) == 0) { - PrintAndLogEx(INFO, "Only one trace recorded"); - return PM3_SUCCESS; - } - - nonces_t data; - - // first - uint16_t NT0 = (outA[6] << 8) | outA[7]; - data.cuid = bytes_to_num(outA, 4); - data.nonce = prng_successor(NT0, 31); - data.nr = bytes_to_num(outA + 8, 4); - data.ar = bytes_to_num(outA + 12, 4); - data.at = 0; - - // second - NT0 = (outB[6] << 8) | outB[7]; - data.nonce2 = prng_successor(NT0, 31); - data.nr2 = bytes_to_num(outB + 8, 4); - data.ar2 = bytes_to_num(outB + 12, 4); - data.sector = mfSectorNum(outA[5]); - data.keytype = outA[4]; - data.state = FIRST; - - PrintAndLogEx(DEBUG, "A Sector %02x", data.sector); - PrintAndLogEx(DEBUG, "A NT %08x", data.nonce); - PrintAndLogEx(DEBUG, "A NR %08x", data.nr); - PrintAndLogEx(DEBUG, "A AR %08x", data.ar); - PrintAndLogEx(DEBUG, ""); - PrintAndLogEx(DEBUG, "B NT %08x", data.nonce2); - PrintAndLogEx(DEBUG, "B NR %08x", data.nr2); - PrintAndLogEx(DEBUG, "B AR %08x", data.ar2); - - uint64_t key64 = -1; - res = mfkey32_moebius(&data, &key64); - - if (res) { - PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ " _GREEN_("%12" PRIX64) " ]" - , sprint_hex_inrow(outA, 4) - , data.sector - , (data.keytype == 0x60) ? 'A' : 'B' - , key64); + if (res) { + PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ " + _GREEN_("%012" + PRIX64) " ]", sprint_hex_inrow(trace_data, 4), data.sector, (data.keytype == 0x60) ? 'A' + : 'B', key64); + break; + } + } + } + } } else { - PrintAndLogEx(FAILED, "failed to recover any key"); + // Commands: + // a0 - set UID + // b0 - read traces + // c0 - clear card + + bool activate_field = true; + bool keep_field_on = true; + int res = 0; + if (uidlen) { + keep_field_on = false; + uint8_t response[6]; + int resplen = 0; + + // --------------- CHANGE UID ---------------- + uint8_t aCHANGE[] = {0x00, 0xa6, 0xa0, 0x00, 0x05, 0xff, 0xff, 0xff, 0xff, 0x00}; + memcpy(aCHANGE + 5, uid, uidlen); + res = ExchangeAPDU14a(aCHANGE, sizeof(aCHANGE), activate_field, keep_field_on, response, sizeof(response), + &resplen); + if (res != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Super card UID change [ " + _RED_("fail") + " ]"); + DropField(); + return res; + } + + PrintAndLogEx(SUCCESS, "Super card UID change ( " + _GREEN_("ok") + " )"); + return PM3_SUCCESS; + } + + if (reset_card) { + keep_field_on = false; + uint8_t response[6]; + int resplen = 0; + + // --------------- RESET CARD ---------------- + uint8_t aRESET[] = {0x00, 0xa6, 0xc0, 0x00}; + res = ExchangeAPDU14a(aRESET, sizeof(aRESET), activate_field, keep_field_on, response, sizeof(response), + &resplen); + if (res != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Super card reset [ " + _RED_("fail") + " ]"); + DropField(); + return res; + } + PrintAndLogEx(SUCCESS, "Super card reset ( " + _GREEN_("ok") + " )"); + return PM3_SUCCESS; + } + + + uint8_t responseA[22]; + uint8_t responseB[22]; + int respAlen = 0; + int respBlen = 0; + + // --------------- First ---------------- + uint8_t aFIRST[] = {0x00, 0xa6, 0xb0, 0x00, 0x10}; + res = ExchangeAPDU14a(aFIRST, sizeof(aFIRST), activate_field, keep_field_on, responseA, sizeof(responseA), + &respAlen); + if (res != PM3_SUCCESS) { + DropField(); + return res; + } + + // --------------- Second ---------------- + activate_field = false; + keep_field_on = false; + + uint8_t aSECOND[] = {0x00, 0xa6, 0xb0, 0x01, 0x10}; + res = ExchangeAPDU14a(aSECOND, sizeof(aSECOND), activate_field, keep_field_on, responseB, sizeof(responseB), + &respBlen); + if (res != PM3_SUCCESS) { + DropField(); + return res; + } + + uint8_t outA[16] = {0}; + uint8_t outB[16] = {0}; + + uint8_t key[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; + for (uint8_t i = 0; i < 16; i += 8) { + des_decrypt(outA + i, responseA + i, key); + des_decrypt(outB + i, responseB + i, key); + } + + PrintAndLogEx(DEBUG, " in : %s", sprint_hex_inrow(responseA, respAlen)); + PrintAndLogEx(DEBUG, "out : %s", sprint_hex_inrow(outA, sizeof(outA))); + PrintAndLogEx(DEBUG, " in : %s", sprint_hex_inrow(responseB, respAlen)); + PrintAndLogEx(DEBUG, "out : %s", sprint_hex_inrow(outB, sizeof(outB))); + + if (memcmp(outA, "\x01\x01\x01\x01\x01\x01\x01\x01", 8) == 0) { + PrintAndLogEx(INFO, "No trace recorded"); + return PM3_SUCCESS; + } + + // second trace? + if (memcmp(outB, "\x01\x01\x01\x01\x01\x01\x01\x01", 8) == 0) { + PrintAndLogEx(INFO, "Only one trace recorded"); + return PM3_SUCCESS; + } + + nonces_t data; + + // first + uint16_t NT0 = (outA[6] << 8) | outA[7]; + data.cuid = bytes_to_num(outA, 4); + data.nonce = prng_successor(NT0, 31); + data.nr = bytes_to_num(outA + 8, 4); + data.ar = bytes_to_num(outA + 12, 4); + data.at = 0; + + // second + NT0 = (outB[6] << 8) | outB[7]; + data.nonce2 = prng_successor(NT0, 31); + data.nr2 = bytes_to_num(outB + 8, 4); + data.ar2 = bytes_to_num(outB + 12, 4); + data.sector = mfSectorNum(outA[5]); + data.keytype = outA[4]; + data.state = FIRST; + + PrintAndLogEx(DEBUG, "A Sector %02x", data.sector); + PrintAndLogEx(DEBUG, "A NT %08x", data.nonce); + PrintAndLogEx(DEBUG, "A NR %08x", data.nr); + PrintAndLogEx(DEBUG, "A AR %08x", data.ar); + PrintAndLogEx(DEBUG, ""); + PrintAndLogEx(DEBUG, "B NT %08x", data.nonce2); + PrintAndLogEx(DEBUG, "B NR %08x", data.nr2); + PrintAndLogEx(DEBUG, "B AR %08x", data.ar2); + + uint64_t key64 = -1; + res = mfkey32_moebius(&data, &key64); + + if (res) { + PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ " + _GREEN_("%12" + PRIX64) " ]" + , sprint_hex_inrow(outA, 4) + , data.sector + , (data.keytype == 0x60) ? 'A' : 'B' + , key64); + } else { + PrintAndLogEx(FAILED, "failed to recover any key"); + } } return PM3_SUCCESS; } From 761ea6e81a8a8543e386cc584a4eed39c664747c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 25 Mar 2023 14:47:51 +0100 Subject: [PATCH 720/759] updated section about GDM styled tags --- doc/magic_cards_notes.md | 86 +++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index db8057e5e..02ad66746 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -68,6 +68,7 @@ To restore anticollision config of the Proxmark3: ``` hf 14a config --std ``` + # MIFARE Classic ^[Top](#top) @@ -89,7 +90,7 @@ UID 4b: (actually NUID as there are no more "unique" IDs on 4b) ``` -Computing BCC on UID 11223344: `hf analyse lcr -d 11223344` = `44` +Computing BCC on UID 11223344: `analyse lcr -d 11223344` = `44` UID 7b: @@ -262,6 +263,8 @@ hf 14a info * Read: `40(7)`, `30xx` * Write: `40(7)`, `A0xx`+crc, `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`+crc + + ## MIFARE Classic DirectWrite aka Gen2 aka CUID ^[Top](#top) @@ -396,6 +399,7 @@ hf mf wrbl --blk 0 -k FFFFFFFFFFFF -d 04112233445566184200626364656667 # for 4k hf 14a config --std hf 14a reader ``` + ## MIFARE Classic DirectWrite, FUID version aka 1-write ^[Top](#top) @@ -436,14 +440,6 @@ hf 14a raw -k -c e100 hf 14a raw -c 85000000000000000000000000000008 ``` -## MIFARE Classic, other versions -^[Top](#top) - -**TODO** - -* ZXUID, EUID, ICUID ? -* Some cards exhibit a specific SAK=28 ?? - ## MIFARE Classic Gen3 aka APDU ^[Top](#top) @@ -517,6 +513,71 @@ hf 14a raw -s -c -t 2000 90F0CCCC10 041219c3219316984200e32000000000 hf 14a raw -s -c 90FD111100 ``` +## MIFARE Classic Gen4 aka GDM +^[Top](#top) +Tag has shadow mode enabled from start. +Meaning every write or changes to normal MFC memory is restored back to a copy from persistent memory after about 3 seconds +off rfid field. +Tag also seems to support Gen2 style, direct write, to block 0 to the normal MFC memory. + +The persistent memory is also writable. For that tag uses its own backdoor commands. +for example to write, you must use a customer authentication byte, 0x80, to authenticate with an all zeros key, 0x0000000000. +Then send the data to be written. + +** OBS ** +When writing to persistent memory it is possible to write _bad_ ACL and perm-brick the tag. + + +### Identify +^[Top](#top) + +``` +hf 14a info +... +[+] Magic capabilities : Gen 4 GDM +``` +### Magic commands +^[Top](#top) + +* Auth: `80xx`+crc +* Write: `A8xx`+crc, `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`+crc +* Read : `E000`+crc (unidentified) + +### Characteristics +^[Top](#top) +Have no access to card, no knowledge in ATQA/SAK/BCC quirks or if there is a wipe, softbrick recover +* Its magic part seem to be three identified custom command. +* Auth command 0x80, with the key 0x0000000000, Write 0xA8 allows writing to persistent memory, Read 0xE0 which seems to return a configuration. This is unknown today what these bytes are. + +It is also unknown what kind of block 0 changes the tag supports today +* UID: 4b +* ATQA/SAK: unknown +* BCC: unknown +* ATS: none + +### Proxmark3 commands +^[Top](#top) +``` +# Write to persistent memory +hf mf gdmsetblk + +# Read 0xE0 configuration: +hf mf gdmgetblk + +``` + +### libnfc commands +^[Top](#top) +No implemented commands today + +## MIFARE Classic, other versions +^[Top](#top) + +**TODO** + +* ZXUID, EUID, ICUID ? +* Some cards exhibit a specific SAK=28 ?? + ## MIFARE Classic Super ^[Top](#top) @@ -972,7 +1033,6 @@ script run hf_15_magic -u E004013344556677 A.k.a ultimate magic card, most promenent feature is shadow mode (GTU) and optional password protected backdoor commands. - Can emulate MIFARE Classic, Ultralight/NTAG families, 14b UID & App Data - [Identify](#identify) @@ -1010,6 +1070,7 @@ The card will be identified only if the password is the default one. One can ide hf 14a raw -s -c -t 1000 CF00000000C6 ``` If the card is an Ultimate Magic Card, it returns 30 or 32 bytes. + ### Magic commands ^[Top](#top) ^^[Gen4](#g4top) @@ -1156,6 +1217,7 @@ OR (Note the script will correct the ATQA correctly) ``` script run hf_mf_ultimatecard -q 004428 ``` + ### Change ATS ^[Top](#top) ^^[Gen4](#g4top) @@ -1193,6 +1255,7 @@ Example: set UID length to 7 bytes, default pwd ``` hf 14a raw -s -c -t 1000 CF000000006801 ``` + ### Set 14443A UID ^[Top](#top) ^^[Gen4](#g4top) @@ -1306,6 +1369,7 @@ script run hf_mf_ultimatecard -m 02 ``` Now the card supports the 3DES UL-C authentication. + ### Set Ultralight and M1 maximum read/write sectors ^[Top](#top) ^^[Gen4](#g4top) @@ -1319,6 +1383,7 @@ Example: set maximum 63 blocks read/write for Mifare Classic 1K ``` hf 14a raw -s -c -t 1000 CF000000006B3F ``` + ### Set shadow mode (GTU) ^[Top](#top) ^^[Gen4](#g4top) @@ -1432,6 +1497,7 @@ Default configuration: ^^ cf cmd 68: UID length ^^ cf cmd 69: Ultralight protocol ``` + ### Fast configuration ^[Top](#top) ^^[Gen4](#g4top) From 2668fc9a4a3e3eaa3b092d174d011a1240cb9b6d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 25 Mar 2023 14:50:51 +0100 Subject: [PATCH 721/759] textual --- CHANGELOG.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cceee09b..b9e28fad3 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] + - Changed magic note to include a section about GDM tags (@iceman1001) - Added `hf mf gdmsetblk` - Support Gen4 GDM write block (@iceman1001) - Changed `hf 14a info` - detect Gen GDM magic tags (@iceman1001) - Changed CLI max string argument length limit from 512 to 4096 (@iceman1001) @@ -19,7 +20,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Fixed `pm3` script for passing arguments (@doegox) - Fixed python paths to include current directory (@jmichelp) - Fixed infinite loops in spindelayus (@lnv42) - - Add ICECLASS standalone read/sim mode (@natesales) + - Changed ICECLASS standalone to support a read/sim mode (@natesales) - Changed `hf iclass encode` - added verbose flag (@natesales) - Changed `hf waveshare` - now identify 1.54 nfc epaper correct (@ah01) - Fixed `Makefile` regression that broke `make install` (@henrygab) @@ -31,12 +32,13 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added `--back` option to `clear` command to clear the scrollback buffer (@wh201906) - Changed `hf iclass decrypt` - mark credentials as decrypted in the dump (@natesales) - Changed `hf iclass view` - show credentials on a decrypted dump (@natesales) - - Show NTAG213TT tamper info in `hf mfu info` and add commands for configuring it's tamper feature (@mjaksn) - - Add Mifare Classic EV1 signature write support to gen4 magic tag lua script (@augustozanellato) + - Changed `hf mfu info` - NTAG213TT tamper info (mjaksn) + - Added commands for configuring NTAG213TT tamper featue (@mjaksn) + - Added Mifare Classic EV1 signature write support to gen4 magic tag lua script (@augustozanellato) - Added XOR key extraction and flag to Guardall G-Prox II (@GuruSteve) - Changed verbiage on `hf iclass info` KeyAccess area to be congruent with AA1 and AA2 areas (@GuruSteve) - Added `hf legic info` command for other sources: `hf legic einfo`, `hf legic view` (@0xdeb) - - + ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) From 22a193a7f2fcd042fc5afc38d38415942d1186d9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 25 Mar 2023 14:52:44 +0100 Subject: [PATCH 722/759] text --- doc/magic_cards_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 02ad66746..86a5329a2 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -20,6 +20,7 @@ Useful docs: * [MIFARE Classic DirectWrite, UFUID version](#mifare-classic-directwrite-ufuid-version) * [MIFARE Classic, other versions](#mifare-classic-other-versions) * [MIFARE Classic Gen3 aka APDU](#mifare-classic-gen3-aka-apdu) + * [MIFARE Classic Gen4 aka GDM](#mifare-classic-gen4-aka-gdm) * [MIFARE Classic Super](#mifare-classic-super) - [MIFARE Ultralight](#mifare-ultralight) * [MIFARE Ultralight blocks 0..2](#mifare-ultralight-blocks-02) From 7b93de7a81c6049eb34886abf520cbe0e38f151f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 25 Mar 2023 15:00:58 +0100 Subject: [PATCH 723/759] added GDM read configuration block --- CHANGELOG.md | 1 + armsrc/appmain.c | 11 +++++- armsrc/mifarecmd.c | 59 ++++++++++++++++++++++++++++++++ armsrc/mifarecmd.h | 1 + armsrc/mifareutil.h | 3 ++ client/src/cmdhfmf.c | 80 +++++++++++++++++++++++++++++++++++++++++++- include/protocols.h | 1 + 7 files changed, 154 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9e28fad3..f6e9c9811 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] + - Added `hf mf gdmgetblk` - Support Gen4 GDM read configuration block (@iceman1001) - Changed magic note to include a section about GDM tags (@iceman1001) - Added `hf mf gdmsetblk` - Support Gen4 GDM write block (@iceman1001) - Changed `hf 14a info` - detect Gen GDM magic tags (@iceman1001) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index d435f9967..c90640828 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1735,7 +1735,16 @@ static void PacketReceived(PacketCommandNG *packet) { MifareG4WriteBlk(payload->blockno, payload->pwd, payload->data, payload->workFlags); break; } - + case CMD_HF_MIFARE_G4_GDM_RDBL: { + struct p { + uint8_t blockno; + uint8_t keytype; + uint8_t key[6]; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + MifareReadBlockGDM(payload->blockno, payload->keytype, payload->key); + break; + } case CMD_HF_MIFARE_G4_GDM_WRBL: { struct p { uint8_t blockno; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index aaf1d795a..0bcb4fd74 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -214,6 +214,65 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { LEDsoff(); } +void MifareReadBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key) { + + int retval = PM3_SUCCESS; + + uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); + if (par == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + + uint8_t *uid = BigBuf_malloc(10); + if (uid == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + + // variables + uint32_t cuid = 0; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + + uint64_t ui64key = bytes_to_num(key, 6); + uint8_t outbuf[16] = {0x00}; + + if (iso14443a_select_card(uid, NULL, &cuid, true, 0, true) == false) { + retval = PM3_ESOFT; + goto OUT; + } + + if (mifare_classic_authex_2(pcs, cuid, blockno, keytype, ui64key, AUTH_FIRST, NULL, NULL, true)) { + retval = PM3_ESOFT; + goto OUT; + }; + + if (mifare_classic_readblock_ex(pcs, cuid, blockno, outbuf, true)) { + retval = PM3_ESOFT; + goto OUT; + }; + + if (mifare_classic_halt(pcs, cuid)) { + retval = PM3_ESOFT; + goto OUT; + }; + +OUT: + crypto1_deinit(pcs); + + reply_ng(CMD_HF_MIFARE_G4_GDM_RDBL, retval, outbuf, sizeof(outbuf)); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); + BigBuf_free(); +} + //----------------------------------------------------------------------------- // Select, Authenticate, Read a MIFARE tag. // read sector (data = 4 x 16 bytes = 64 bytes, or 16 x 16 bytes = 256 bytes) diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index f471ccecc..062c02367 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -59,6 +59,7 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block); // Gen 3 magic card overw void MifareGen3Freez(void); // Gen 3 magic card lock further UID changes // MFC GEN4 GDM +void MifareReadBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key); void MifareWriteBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key, uint8_t *datain); // MFC GEN4 GTU diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index c7c6b4a94..37b1b1294 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -73,7 +73,10 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested); int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing); int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing, bool is_gdm); + int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); +int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, bool is_gdm); + int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); int mifare_classic_halt_ex(struct Crypto1State *pcs); int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 900f201d2..a0a2c6961 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -7560,6 +7560,78 @@ static int CmdHF14AGen4Save(const char *Cmd) { return PM3_SUCCESS; } +static int CmdHF14AGen4_GDM_GetBlk(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf gdmgetblk", + "Get block data from magic gen4 GDM card.", + "hf mf gdmgetblk --blk 0 --> get block 0 (manufacturer)\n" + "hf mf gdmgetblk --blk 3 -v --> get block 3, decode sector trailer\n" + ); + void *argtable[] = { + arg_param_begin, + arg_int1("b", "blk", "", "block number"), + arg_lit0("v", "verbose", "verbose output"), + arg_str0("k", "key", "", "key 6 bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + int b = arg_get_int_def(ctx, 1, 0); + bool verbose = arg_get_lit(ctx, 2); + + int keylen = 0; + uint8_t key[6] = {0}; + CLIGetHexWithReturn(ctx, 3, key, &keylen); + CLIParserFree(ctx); + + // validate args + if (b < 0 || b >= MIFARE_4K_MAXBLOCK) { + PrintAndLogEx(FAILED, "target block number out-of-range, got %i", b); + return PM3_EINVARG; + } + + if (keylen != 6 && keylen != 0) { + PrintAndLogEx(FAILED, "Must specify 6 bytes, got " _YELLOW_("%u"), keylen); + return PM3_EINVARG; + } + + uint8_t blockno = (uint8_t)b; + PrintAndLogEx(NORMAL, "Block: %x", blockno) ; + + struct p { + uint8_t blockno; + uint8_t keytype; + uint8_t key[6]; + } PACKED payload; + + payload.blockno = blockno; + payload.keytype = 0; + memcpy(payload.key, key, sizeof(payload.key)); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_G4_GDM_RDBL, (uint8_t *)&payload, sizeof(payload)); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_HF_MIFARE_G4_GDM_RDBL, &resp, 1500) == false) { + PrintAndLogEx(WARNING, "command execute timeout"); + return PM3_ETIMEOUT; + } + + if (resp.status == PM3_SUCCESS) { + uint8_t sector = mfSectorNum(blockno); + mf_print_sector_hdr(sector); + + uint8_t *d = resp.data.asBytes; + mf_print_block_one(blockno, d, verbose); + + if (verbose) { + decode_print_st(blockno, d); + } else { + PrintAndLogEx(NORMAL, ""); + } + } + + return resp.status; +} + static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { CLIParserContext *ctx; @@ -7599,7 +7671,7 @@ static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { CLIParserFree(ctx); if (blen != MFBLOCK_SIZE) { - PrintAndLogEx(WARNING, "expected 16 HEX bytes. got %i", blen); + PrintAndLogEx(WARNING, "expected %u HEX bytes. got %i", MFBLOCK_SIZE, blen); return PM3_EINVARG; } @@ -7608,6 +7680,11 @@ static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { return PM3_EINVARG; } + if (keylen != 6 && keylen != 0) { + PrintAndLogEx(FAILED, "Must specify 6 bytes, got " _YELLOW_("%u"), keylen); + return PM3_EINVARG; + } + uint8_t blockno = (uint8_t)b; PrintAndLogEx(INFO, "Writing block no %d, key %c - %s", blockno, (keytype == MF_KEY_B) ? 'B' : 'A', sprint_hex_inrow(key, sizeof(key))); @@ -7908,6 +7985,7 @@ static command_t CommandTable[] = { {"gsetblk", CmdHF14AGen4SetBlk, IfPm3Iso14443a, "Write block to card"}, {"gview", CmdHF14AGen4View, IfPm3Iso14443a, "View card"}, {"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GDM") " --------------------------"}, + {"gdmgetblk", CmdHF14AGen4_GDM_GetBlk, IfPm3Iso14443a, "Read block from card"}, {"gdmsetblk", CmdHF14AGen4_GDM_SetBlk, IfPm3Iso14443a, "Write block to card"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"}, // {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, diff --git a/include/protocols.h b/include/protocols.h index 333dcdb71..8450dc58a 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -193,6 +193,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MIFARE_MAGIC_GDM_AUTH_KEYA 0x80 #define MIFARE_MAGIC_GDM_AUTH_KEYB 0x81 #define MIFARE_MAGIC_GDM_WRITEBLOCK 0xA8 +#define MIFARE_MAGIC_GDM_READBLOCK 0xE0 #define MIFARE_EV1_PERSONAL_UID 0x40 #define MIFARE_EV1_SETMODE 0x43 From 266ca65dc8eac9269d8058cea4def8e1d90b2e06 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 25 Mar 2023 15:03:05 +0100 Subject: [PATCH 724/759] text --- doc/magic_cards_notes.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 86a5329a2..36846614a 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -546,11 +546,12 @@ hf 14a info ### Characteristics ^[Top](#top) -Have no access to card, no knowledge in ATQA/SAK/BCC quirks or if there is a wipe, softbrick recover -* Its magic part seem to be three identified custom command. -* Auth command 0x80, with the key 0x0000000000, Write 0xA8 allows writing to persistent memory, Read 0xE0 which seems to return a configuration. This is unknown today what these bytes are. -It is also unknown what kind of block 0 changes the tag supports today +* Have no knowledge in ATQA/SAK/BCC quirks or if there is a wipe, softbrick recover +* Its magic part seem to be three identified custom command. +* Auth command 0x80, with the key 0x0000000000, Write 0xA8 allows writing to persistent memory, Read 0xE0 which seems to return a configuration. This is unknown today what these bytes are. + +It is unknown what kind of block 0 changes the tag supports * UID: 4b * ATQA/SAK: unknown * BCC: unknown From ebe7cbf05ff4e841470a616eb4c6bad5446a7e25 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 25 Mar 2023 15:52:18 +0100 Subject: [PATCH 725/759] missing... --- armsrc/mifareutil.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index c349860dd..29754538a 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -230,13 +230,20 @@ int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t bloc } int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { + return mifare_classic_readblock_ex(pcs, uid, blockNo, blockData, false); +} +int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, bool is_gdm) { - int len; - uint8_t bt[2] = {0x00, 0x00}; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); + uint16_t len; + if (is_gdm) { + len = mifare_sendcmd_short(pcs, 1, MIFARE_MAGIC_GDM_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); + } else { + len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); + } + if (len == 1) { if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error %02x", receivedAnswer[0]); return 1; @@ -246,6 +253,7 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo return 2; } + uint8_t bt[2] = {0x00, 0x00}; memcpy(bt, receivedAnswer + 16, 2); AddCrc14A(receivedAnswer, 16); if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) { @@ -416,19 +424,14 @@ int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData) { int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { return mifare_classic_writeblock_ex(pcs, uid, blockNo, blockData, false); } - int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, bool is_gdm) { - // variables - uint16_t len = 0; - uint32_t pos = 0; - uint8_t par[3] = {0x00, 0x00, 0x00}; // enough for 18 Bytes to send - uint8_t res = 0; - uint8_t d_block[18], d_block_enc[18]; + // variables uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; // command MIFARE_MAGIC_GDM_WRITEBLOCK + uint16_t len; if (is_gdm) { len = mifare_sendcmd_short(pcs, 1, MIFARE_MAGIC_GDM_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); } else { @@ -440,11 +443,14 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t return 1; } + uint8_t d_block[18], d_block_enc[18]; memcpy(d_block, blockData, 16); AddCrc14A(d_block, 16); + // enough for 18 Bytes to send + uint8_t par[3] = {0x00, 0x00, 0x00}; // crypto - for (pos = 0; pos < 18; pos++) { + for (uint32_t pos = 0; pos < 18; pos++) { d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos]; par[pos >> 3] |= (((filter(pcs->odd) ^ oddparity8(d_block[pos])) & 0x01) << (7 - (pos & 0x0007))); } @@ -452,9 +458,10 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL); // Receive the response + len = ReaderReceive(receivedAnswer, receivedAnswerPar); - res = 0; + uint8_t res = 0; res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; From a81a875df970c2a103988fae65853e92926e44ec Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Sat, 25 Mar 2023 18:03:33 +0300 Subject: [PATCH 726/759] Update supercard docs --- doc/magic_cards_notes.md | 59 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index db8057e5e..0e487f8a2 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -520,19 +520,66 @@ hf 14a raw -s -c 90FD111100 ## MIFARE Classic Super ^[Top](#top) -It behaves like DirectWrite but records reader auth attempts. +It behaves like regular Mifare Classic but records reader auth attempts. -To change UID: same commands as for MFC DirectWrite +#### MIFARE Classic Super Gen1 +^[Top](#top) -To do reader-only attack: at least two versions exist. +Old type of cards, hard to obtain. They are DirectWrite, UID can be changed via 0 block or backdoor commands. -* type 1: https://github.com/nfc-tools/nfc-supercard for card with ATS: 0978009102DABC1910F005 -* type 2: https://github.com/netscylla/super-card/blob/master/libnfc-1.7.1/utils/nfc-super.c for ?? +* UID: 4b version +* ATQA/SAK: fixed +* BCC: auto +* ATS: fixed, 0978009102DABC1910F005 + +ATQA/SAK matches 1k card, but works as 4k card. + +Backdoor commands provided over APDU. Format: + +``` +00 A6 A0 00 05 FF FF FF FF 00 +^^ ^^ Backdoor command header + ^^ Backdoor command (A0 - set UID/B0 - get trace/C0 - reset card) + ^^ Type of answer (used in key recovery to select trace number) + ^^ Length of user provided data + ^^ ^^ ^^ ^^ ^^ User data +``` + +👉 You can't change UID with backdoor command if incorrect data is written to the 0 sector trailer! + +#### MIFARE Classic Super Gen1B + +DirectWrite card, ATS unknown. Probably same as Gen1, except backdoor commands. +Implementation: https://github.com/netscylla/super-card/blob/master/libnfc-1.7.1/utils/nfc-super.c + +#### MIFARE Classic Super Gen2 +^[Top](#top) + +New generation of cards, based on limited Gen4 chip. Emulates Gen1 backdoor protocol, but can store up to 7 different traces. + +Card always answer `ff ff ff ff` to auth, so writing/reading it via Mifare protocol is impossible. + +UID is changeable via Gen4 backdoor write to 0 block. + +* UID: 4b and 7b versions +* ATQA/SAK: fixed +* BCC: auto +* ATS: changeable, default as Gen1 + +Gen4 commands available: + +``` +CF 34 <1b length><0-16b ATS> // Configure ATS +CF CC // Factory test, returns 00 00 00 02 AA +CF CD <1b block number><16b block data> // Backdoor write 16b block +CF CE <1b block number> // Backdoor read 16b block +CF FE <4b new_password> // Change password +``` ### Identify ^[Top](#top) -Only type 1 at the moment: +Only Gen1 at the moment: ``` hf 14a info From 581b48f3f93833c351c6b3438d335746c260cc51 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 25 Mar 2023 18:48:07 +0100 Subject: [PATCH 727/759] textual --- doc/magic_cards_notes.md | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 36846614a..5750b8c8d 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -370,7 +370,7 @@ Android compatible ^[Top](#top) ``` -hf mf wrbl --blk 0 -k FFFFFFFFFFFF -d 11223344440804006263646566676869 +hf mf wrbl --blk 0 -k FFFFFFFFFFFF -d 11223344440804006263646566676869 --force hf mf wipe --gen2 ``` @@ -385,8 +385,13 @@ e.g. for 4b UID: ``` hf 14a config --atqa force --bcc ignore --cl2 skip --rats skip -hf mf wrbl --blk 0 -k FFFFFFFFFFFF -d 11223344440804006263646566676869 # for 1k -hf mf wrbl --blk 0 -k FFFFFFFFFFFF -d 11223344441802006263646566676869 # for 4k + +# for 1k +hf mf wrbl --blk 0 -k FFFFFFFFFFFF -d 11223344440804006263646566676869 --force + +# for 4k +hf mf wrbl --blk 0 -k FFFFFFFFFFFF -d 11223344441802006263646566676869 --force + hf 14a config --std hf 14a reader ``` @@ -395,8 +400,13 @@ e.g. for 7b UID: ``` hf 14a config --atqa force --bcc ignore --cl2 force --cl3 skip --rats skip -hf mf wrbl --blk 0 -k FFFFFFFFFFFF -d 04112233445566084400626364656667 # for 1k -hf mf wrbl --blk 0 -k FFFFFFFFFFFF -d 04112233445566184200626364656667 # for 4k + +# for 1k +hf mf wrbl --blk 0 -k FFFFFFFFFFFF -d 04112233445566084400626364656667 --force + +# for 4k +hf mf wrbl --blk 0 -k FFFFFFFFFFFF -d 04112233445566184200626364656667 --force + hf 14a config --std hf 14a reader ``` From 5bf5d9a28285745c8f2a07d01d7cfe544eaaf7a7 Mon Sep 17 00:00:00 2001 From: KurisuWaifu <96349419+KurisuWaifu@users.noreply.github.com> Date: Sat, 25 Mar 2023 23:25:57 +0100 Subject: [PATCH 728/759] Explain "Unknown Command" behaviour Edited the Magic Gen 4 section Signed-off-by: KurisuWaifu <96349419+KurisuWaifu@users.noreply.github.com> --- doc/magic_cards_notes.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 5750b8c8d..cd3dfa58e 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -1164,7 +1164,7 @@ CF C6 // Dump configuration CF CC // Factory test, returns 6666 CF CD <1b block number><16b block data> // Backdoor write 16b block CF CE <1b block number> // Backdoor read 16b block -CF CF <1b param> // Unknown +CF CF <1b param> // (De)Activate direct write to block 0 CF F0 <30b configuration data> // Configure all params in one cmd CF F1 <30b configuration data> // Configure all params in one cmd and fuse the configuration permanently CF FE <4b new_password> // change password @@ -1457,19 +1457,27 @@ Example: write block0 with factory data, default pwd hf 14a raw -s -c -t 1000 CF00000000CD00112233441C000011778185BA18000000 ``` -### Unknown command +### (De)Activate direct write to block 0 ^[Top](#top) ^^[Gen4](#g4top) -This command modifies one byte in configuration dump, but purpose one is unknown. +This command enables/disables direct writes to block 0. ``` hf 14a raw -s -c -t 1000 CFCF<1b param> ``` * `` - * `??`: ??? + * `00`: Activate direct write to block 0 (Same behaviour of Gen2 cards. Some readers may identify the card as magic) + * `01`: Deactivate direct write to block 0 (Same behaviour of vanilla cards) + * `02`: Default value. (Same behaviour as `00` (?)) -Example: -hf 14a raw -s -c -t 1000 CF00000000CF02 +Example: enable direct writes to block 0, default pwd +``` +hf 14a raw -s -c -t 1000 CF00000000CF00 +``` +Example: disable direct writes to block 0, default pwd +``` +hf 14a raw -s -c -t 1000 CF00000000CF01 +``` ### Change backdoor password ^[Top](#top) ^^[Gen4](#g4top) @@ -1620,4 +1628,3 @@ hf mfu wrbl -b 250 -d 00040402 --force hf mfu wrbl -b 251 -d 01001303 --force hf mfu info ``` - From c436a97aeef75c43452555dfcb23e28a58f62bf0 Mon Sep 17 00:00:00 2001 From: KurisuWaifu <96349419+KurisuWaifu@users.noreply.github.com> Date: Sun, 26 Mar 2023 01:24:38 +0100 Subject: [PATCH 729/759] Small corrections Added "Activate direct write to block 0" to gen 4 gtu index. Edited the "dump configuration" section Signed-off-by: KurisuWaifu <96349419+KurisuWaifu@users.noreply.github.com> --- doc/magic_cards_notes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index cd3dfa58e..158fa98a5 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -1060,6 +1060,7 @@ Can emulate MIFARE Classic, Ultralight/NTAG families, 14b UID & App Data - [Select Ultralight mode](#select-ultralight-mode) - [Set shadow mode (GTU)](#set-shadow-mode-gtu) - [Direct block read and write](#direct-block-read-and-write) +- [(De)Activate direct write to block 0](#deactivate-direct-write-to-block-0) - [Change backdoor password](#change-backdoor-password) - [Dump configuration](#dump-configuration) - [Fast configuration](#fast-configuration) @@ -1507,7 +1508,7 @@ Default configuration: ``` 00000000000002000978009102DABC191010111213141516040008006B024F6B ^^^^ ?? - ^^ cf cmd cf: ?? this byte set by cmd cfcf, factory value 0x02 + ^^ cf cmd cf: block0 direct write setting, factory value 0x02 ^^ cf cmd 6b: maximum read/write sectors, factory value 0x6b ^^ cf cmd 6a: UL mode ^^^^^^ cf cmd 35: ATQA/SAK From 5e8a08c7145ca5d786ddf6ba790a1e89471c31be Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 26 Mar 2023 03:08:01 +0200 Subject: [PATCH 730/759] updated text about configuration GDM --- doc/magic_cards_notes.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 158fa98a5..a8792767a 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -535,9 +535,14 @@ The persistent memory is also writable. For that tag uses its own backdoor comma for example to write, you must use a customer authentication byte, 0x80, to authenticate with an all zeros key, 0x0000000000. Then send the data to be written. +This tag has simular commands to the [UFUID](#mifare-classic-directwrite-ufuid-version) +It seems to be developed by the same person. + ** OBS ** When writing to persistent memory it is possible to write _bad_ ACL and perm-brick the tag. +** OBS ** +It is possible to write a configuration that perma locks the tag, ie no more magic ### Identify ^[Top](#top) @@ -552,7 +557,8 @@ hf 14a info * Auth: `80xx`+crc * Write: `A8xx`+crc, `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`+crc -* Read : `E000`+crc (unidentified) +* Read config: `E000`+crc (unidentified) +* Write config: `E100`+crc ### Characteristics ^[Top](#top) @@ -561,6 +567,21 @@ hf 14a info * Its magic part seem to be three identified custom command. * Auth command 0x80, with the key 0x0000000000, Write 0xA8 allows writing to persistent memory, Read 0xE0 which seems to return a configuration. This is unknown today what these bytes are. +Read config: +1. sending custom auth with all zeros key +2. send 0xE000, will return the configuration bytes. +`results: 850000000000000000005A5A00000008` + +Write config: +1. sending custom auth with all zeros key +2. send 0xE100 +3. send 16 bytes + +** Warning ** +Example of configuration to Perma lock tag: +`85000000000000000000000000000008` + + It is unknown what kind of block 0 changes the tag supports * UID: 4b * ATQA/SAK: unknown From f61a8a774b609b1ddeeb294aedad229e6ba14541 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 26 Mar 2023 03:08:39 +0200 Subject: [PATCH 731/759] textual --- doc/magic_cards_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index a8792767a..324340794 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -526,6 +526,7 @@ hf 14a raw -s -c 90FD111100 ## MIFARE Classic Gen4 aka GDM ^[Top](#top) + Tag has shadow mode enabled from start. Meaning every write or changes to normal MFC memory is restored back to a copy from persistent memory after about 3 seconds off rfid field. From 0d085488a69b4fa0bf1219bfa226fa5cab559c1e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 26 Mar 2023 03:11:05 +0200 Subject: [PATCH 732/759] textual --- doc/magic_cards_notes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 324340794..1a8726de2 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -539,10 +539,10 @@ Then send the data to be written. This tag has simular commands to the [UFUID](#mifare-classic-directwrite-ufuid-version) It seems to be developed by the same person. -** OBS ** +*** OBS *** When writing to persistent memory it is possible to write _bad_ ACL and perm-brick the tag. -** OBS ** +*** OBS *** It is possible to write a configuration that perma locks the tag, ie no more magic ### Identify From 932e345c43562e2fd6dce196935c5bd843c1ddda Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 26 Mar 2023 03:16:35 +0200 Subject: [PATCH 733/759] textual --- doc/magic_cards_notes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 1a8726de2..8071f7ea7 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -539,10 +539,10 @@ Then send the data to be written. This tag has simular commands to the [UFUID](#mifare-classic-directwrite-ufuid-version) It seems to be developed by the same person. -*** OBS *** +**OBS** When writing to persistent memory it is possible to write _bad_ ACL and perm-brick the tag. -*** OBS *** +**OBS** It is possible to write a configuration that perma locks the tag, ie no more magic ### Identify @@ -578,7 +578,7 @@ Write config: 2. send 0xE100 3. send 16 bytes -** Warning ** +**Warning** Example of configuration to Perma lock tag: `85000000000000000000000000000008` From 97e16ba764d4b3cfe345c20920c55ce629df378c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 26 Mar 2023 03:41:12 +0200 Subject: [PATCH 734/759] renamed gdm getblk to config since that is what it does --- armsrc/appmain.c | 6 +- armsrc/mifarecmd.c | 8 +-- armsrc/mifarecmd.h | 2 +- armsrc/mifareutil.c | 15 ++-- armsrc/mifareutil.h | 2 +- client/src/cmdhfmf.c | 145 +++++++++++++++++++-------------------- doc/magic_cards_notes.md | 5 +- include/pm3_cmd.h | 1 + include/protocols.h | 1 + 9 files changed, 88 insertions(+), 97 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index c90640828..969513d39 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1735,14 +1735,12 @@ static void PacketReceived(PacketCommandNG *packet) { MifareG4WriteBlk(payload->blockno, payload->pwd, payload->data, payload->workFlags); break; } - case CMD_HF_MIFARE_G4_GDM_RDBL: { + case CMD_HF_MIFARE_G4_GDM_CONFIG: { struct p { - uint8_t blockno; - uint8_t keytype; uint8_t key[6]; } PACKED; struct p *payload = (struct p *) packet->data.asBytes; - MifareReadBlockGDM(payload->blockno, payload->keytype, payload->key); + MifareReadConfigBlockGDM(payload->key); break; } case CMD_HF_MIFARE_G4_GDM_WRBL: { diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 0bcb4fd74..9eb44da5a 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -214,7 +214,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { LEDsoff(); } -void MifareReadBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key) { +void MifareReadConfigBlockGDM(uint8_t *key) { int retval = PM3_SUCCESS; @@ -248,12 +248,12 @@ void MifareReadBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key) { goto OUT; } - if (mifare_classic_authex_2(pcs, cuid, blockno, keytype, ui64key, AUTH_FIRST, NULL, NULL, true)) { + if (mifare_classic_authex_2(pcs, cuid, 0, 0, ui64key, AUTH_FIRST, NULL, NULL, true)) { retval = PM3_ESOFT; goto OUT; }; - if (mifare_classic_readblock_ex(pcs, cuid, blockno, outbuf, true)) { + if (mifare_classic_readblock_ex(pcs, cuid, 0, outbuf, MIFARE_MAGIC_GDM_READBLOCK)) { retval = PM3_ESOFT; goto OUT; }; @@ -266,7 +266,7 @@ void MifareReadBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key) { OUT: crypto1_deinit(pcs); - reply_ng(CMD_HF_MIFARE_G4_GDM_RDBL, retval, outbuf, sizeof(outbuf)); + reply_ng(CMD_HF_MIFARE_G4_GDM_CONFIG, retval, outbuf, sizeof(outbuf)); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); set_tracing(false); diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 062c02367..6363423fd 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -59,7 +59,7 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block); // Gen 3 magic card overw void MifareGen3Freez(void); // Gen 3 magic card lock further UID changes // MFC GEN4 GDM -void MifareReadBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key); +void MifareReadConfigBlockGDM(uint8_t *key); void MifareWriteBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key, uint8_t *datain); // MFC GEN4 GTU diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 29754538a..11009031b 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -153,7 +153,7 @@ int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t bloc num_to_bytes(prng_successor(GetTickCount(), 32), 4, nr); // Transmit MIFARE_CLASSIC_AUTH 0x60, 0x61 or GDM 0x80 - uint8_t cmdbyte = (is_gdm) ? MIFARE_MAGIC_GDM_AUTH_KEYA : MIFARE_AUTH_KEYA + (keyType & 0x01); + uint8_t cmdbyte = (is_gdm) ? MIFARE_MAGIC_GDM_AUTH_KEYA + (keyType & 0x01) : MIFARE_AUTH_KEYA + (keyType & 0x01); len = mifare_sendcmd_short(pcs, isNested, cmdbyte, blockNo, receivedAnswer, receivedAnswerPar, timing); if (len != 4) return 1; @@ -230,20 +230,14 @@ int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t bloc } int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { - return mifare_classic_readblock_ex(pcs, uid, blockNo, blockData, false); + return mifare_classic_readblock_ex(pcs, uid, blockNo, blockData, ISO14443A_CMD_READBLOCK); } -int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, bool is_gdm) { +int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t iso_byte) { uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - uint16_t len; - if (is_gdm) { - len = mifare_sendcmd_short(pcs, 1, MIFARE_MAGIC_GDM_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); - } else { - len = mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); - } - + uint16_t len = mifare_sendcmd_short(pcs, 1, iso_byte, blockNo, receivedAnswer, receivedAnswerPar, NULL); if (len == 1) { if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error %02x", receivedAnswer[0]); return 1; @@ -458,7 +452,6 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL); // Receive the response - len = ReaderReceive(receivedAnswer, receivedAnswerPar); uint8_t res = 0; diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index 37b1b1294..bcc813d00 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -75,7 +75,7 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing, bool is_gdm); int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); -int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, bool is_gdm); +int mifare_classic_readblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t iso_byte); int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid); int mifare_classic_halt_ex(struct Crypto1State *pcs); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index a0a2c6961..0ba8aac98 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -400,6 +400,47 @@ static void mf_analyse_acl(uint16_t n, uint8_t *d) { } } +/* + Sector trailer sanity checks. + Warn if ACL is strict read-only, or invalid ACL. +*/ +static int mf_analyse_st_block(uint8_t blockno, uint8_t *block, bool force){ + + if (mfIsSectorTrailer(blockno) == false) { + return PM3_SUCCESS; + } + + PrintAndLogEx(INFO, "Sector trailer (ST) write detected"); + + // ensure access right isn't messed up. + if (mfValidateAccessConditions(&block[6]) == false) { + PrintAndLogEx(WARNING, "Invalid Access Conditions detected, replacing with default values"); + memcpy(block + 6, "\xFF\x07\x80\x69", 4); + } + + bool ro_detected = false; + uint8_t bar = mfNumBlocksPerSector(mfSectorNum(blockno)); + for (uint8_t foo = 0; foo < bar; foo++) { + if (mfReadOnlyAccessConditions(foo, &block[6])) { + PrintAndLogEx(WARNING, "Strict ReadOnly Access Conditions on block " _YELLOW_("%u") " detected", blockno - bar + 1 + foo); + ro_detected = true; + } + } + if (ro_detected) { + if (force) { + PrintAndLogEx(WARNING, " --force override, continuing..."); + } else { + PrintAndLogEx(INFO, "Exiting, please run `" _YELLOW_("hf mf acl -d %s") "` to understand", sprint_hex_inrow(&block[6], 3)); + PrintAndLogEx(INFO, "Use `" _YELLOW_("--force") "` to override and write this data"); + return PM3_EINVARG; + } + } else { + PrintAndLogEx(SUCCESS, "ST passed checks, continuing..."); + } + + return PM3_SUCCESS; +} + static int CmdHF14AMfAcl(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf acl", @@ -521,7 +562,6 @@ static int CmdHF14AMfWrBl(const char *Cmd) { arg_lit0(NULL, "force", "override warnings"), arg_str0("k", "key", "", "key, 6 hex bytes"), arg_str0("d", "data", "", "bytes to write, 16 hex bytes"), - arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -569,36 +609,8 @@ static int CmdHF14AMfWrBl(const char *Cmd) { uint8_t blockno = (uint8_t)b; - // Sector trailer sanity checks. - // Warn if ACL is strict read-only, or invalid ACL. - if (mfIsSectorTrailer(blockno)) { - PrintAndLogEx(INFO, "Sector trailer (ST) write detected"); - - // ensure access right isn't messed up. - if (mfValidateAccessConditions(&block[6]) == false) { - PrintAndLogEx(WARNING, "Invalid Access Conditions detected, replacing with default values"); - memcpy(block + 6, "\xFF\x07\x80\x69", 4); - } - - bool ro_detected = false; - uint8_t bar = mfNumBlocksPerSector(mfSectorNum(blockno)); - for (uint8_t foo = 0; foo < bar; foo++) { - if (mfReadOnlyAccessConditions(foo, &block[6])) { - PrintAndLogEx(WARNING, "Strict ReadOnly Access Conditions on block " _YELLOW_("%u") " detected", blockno - bar + 1 + foo); - ro_detected = true; - } - } - if (ro_detected) { - if (force) { - PrintAndLogEx(WARNING, " --force override, continuing..."); - } else { - PrintAndLogEx(INFO, "Exiting, please run `" _YELLOW_("hf mf acl -d %s") "` to understand", sprint_hex_inrow(&block[6], 3)); - PrintAndLogEx(INFO, "Use `" _YELLOW_("--force") "` to override and write this data"); - return PM3_EINVARG; - } - } else { - PrintAndLogEx(SUCCESS, "ST passed checks, continuing..."); - } + if (mf_analyse_st_block(blockno, block, force) != PM3_SUCCESS) { + return PM3_EINVARG; } PrintAndLogEx(INFO, "Writing block no %d, key %c - %s", blockno, (keytype == MF_KEY_B) ? 'B' : 'A', sprint_hex_inrow(key, sizeof(key))); @@ -7560,73 +7572,47 @@ static int CmdHF14AGen4Save(const char *Cmd) { return PM3_SUCCESS; } -static int CmdHF14AGen4_GDM_GetBlk(const char *Cmd) { +static int CmdHF14AGen4_GDM_ConfigBlk(const char *Cmd) { CLIParserContext *ctx; - CLIParserInit(&ctx, "hf mf gdmgetblk", - "Get block data from magic gen4 GDM card.", - "hf mf gdmgetblk --blk 0 --> get block 0 (manufacturer)\n" - "hf mf gdmgetblk --blk 3 -v --> get block 3, decode sector trailer\n" + CLIParserInit(&ctx, "hf mf gdmconfig", + "Get configuration data from magic gen4 GDM card.", + "hf mf gdmconfig\n" ); void *argtable[] = { arg_param_begin, - arg_int1("b", "blk", "", "block number"), - arg_lit0("v", "verbose", "verbose output"), arg_str0("k", "key", "", "key 6 bytes"), arg_param_end }; - CLIExecWithReturn(ctx, Cmd, argtable, false); - int b = arg_get_int_def(ctx, 1, 0); - bool verbose = arg_get_lit(ctx, 2); + CLIExecWithReturn(ctx, Cmd, argtable, true); int keylen = 0; uint8_t key[6] = {0}; - CLIGetHexWithReturn(ctx, 3, key, &keylen); + CLIGetHexWithReturn(ctx, 1, key, &keylen); CLIParserFree(ctx); // validate args - if (b < 0 || b >= MIFARE_4K_MAXBLOCK) { - PrintAndLogEx(FAILED, "target block number out-of-range, got %i", b); - return PM3_EINVARG; - } - if (keylen != 6 && keylen != 0) { PrintAndLogEx(FAILED, "Must specify 6 bytes, got " _YELLOW_("%u"), keylen); return PM3_EINVARG; } - uint8_t blockno = (uint8_t)b; - PrintAndLogEx(NORMAL, "Block: %x", blockno) ; - struct p { - uint8_t blockno; - uint8_t keytype; uint8_t key[6]; } PACKED payload; - - payload.blockno = blockno; - payload.keytype = 0; memcpy(payload.key, key, sizeof(payload.key)); clearCommandBuffer(); - SendCommandNG(CMD_HF_MIFARE_G4_GDM_RDBL, (uint8_t *)&payload, sizeof(payload)); + SendCommandNG(CMD_HF_MIFARE_G4_GDM_CONFIG, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_HF_MIFARE_G4_GDM_RDBL, &resp, 1500) == false) { + if (WaitForResponseTimeout(CMD_HF_MIFARE_G4_GDM_CONFIG, &resp, 1500) == false) { PrintAndLogEx(WARNING, "command execute timeout"); return PM3_ETIMEOUT; } if (resp.status == PM3_SUCCESS) { - uint8_t sector = mfSectorNum(blockno); - mf_print_sector_hdr(sector); - uint8_t *d = resp.data.asBytes; - mf_print_block_one(blockno, d, verbose); - - if (verbose) { - decode_print_st(blockno, d); - } else { - PrintAndLogEx(NORMAL, ""); - } + PrintAndLogEx(SUCCESS, "config... %s", sprint_hex(d, resp.length)); + PrintAndLogEx(NORMAL, ""); } return resp.status; @@ -7636,7 +7622,9 @@ static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf gdmsetblk", - "Set block data on a magic gen4 GDM card", + "Set block data on a magic gen4 GDM card\n" + "`--force` param is used to override warnings like bad ACL writes.\n" + " if not specified, it will exit if detected", "hf mf gdmsetblk --blk 1 -d 000102030405060708090a0b0c0d0e0f" ); void *argtable[] = { @@ -7644,8 +7632,9 @@ static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { arg_int1(NULL, "blk", "", "block number"), arg_lit0("a", NULL, "input key type is key A (def)"), arg_lit0("b", NULL, "input key type is key B"), - arg_str0("k", "key", "", "key, 6 hex bytes"), arg_str0("d", "data", "", "bytes to write, 16 hex bytes"), + arg_str0("k", "key", "", "key, 6 hex bytes"), + arg_lit0(NULL, "force", "override warnings"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -7661,13 +7650,15 @@ static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { keytype = MF_KEY_B;; } - int keylen = 0; - uint8_t key[6] = {0}; - CLIGetHexWithReturn(ctx, 4, key, &keylen); - uint8_t block[MFBLOCK_SIZE] = {0x00}; int blen = 0; - CLIGetHexWithReturn(ctx, 5, block, &blen); + CLIGetHexWithReturn(ctx, 4, block, &blen); + + int keylen = 0; + uint8_t key[6] = {0}; + CLIGetHexWithReturn(ctx, 5, key, &keylen); + + bool force = arg_get_lit(ctx, 6); CLIParserFree(ctx); if (blen != MFBLOCK_SIZE) { @@ -7687,6 +7678,10 @@ static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { uint8_t blockno = (uint8_t)b; + if (mf_analyse_st_block(blockno, block, force) != PM3_SUCCESS) { + return PM3_EINVARG; + } + PrintAndLogEx(INFO, "Writing block no %d, key %c - %s", blockno, (keytype == MF_KEY_B) ? 'B' : 'A', sprint_hex_inrow(key, sizeof(key))); PrintAndLogEx(INFO, "data: %s", sprint_hex(block, sizeof(block))); @@ -7985,7 +7980,7 @@ static command_t CommandTable[] = { {"gsetblk", CmdHF14AGen4SetBlk, IfPm3Iso14443a, "Write block to card"}, {"gview", CmdHF14AGen4View, IfPm3Iso14443a, "View card"}, {"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GDM") " --------------------------"}, - {"gdmgetblk", CmdHF14AGen4_GDM_GetBlk, IfPm3Iso14443a, "Read block from card"}, + {"gdmconfig", CmdHF14AGen4_GDM_ConfigBlk, IfPm3Iso14443a, "Read config block from card"}, {"gdmsetblk", CmdHF14AGen4_GDM_SetBlk, IfPm3Iso14443a, "Write block to card"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"}, // {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 8071f7ea7..9f4be7376 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -540,9 +540,11 @@ This tag has simular commands to the [UFUID](#mifare-classic-directwrite-ufuid-v It seems to be developed by the same person. **OBS** + When writing to persistent memory it is possible to write _bad_ ACL and perm-brick the tag. **OBS** + It is possible to write a configuration that perma locks the tag, ie no more magic ### Identify @@ -579,6 +581,7 @@ Write config: 3. send 16 bytes **Warning** + Example of configuration to Perma lock tag: `85000000000000000000000000000008` @@ -596,7 +599,7 @@ It is unknown what kind of block 0 changes the tag supports hf mf gdmsetblk # Read 0xE0 configuration: -hf mf gdmgetblk +hf mf gdmconfig ``` diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index f490cc419..b99bb8430 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -689,6 +689,7 @@ typedef struct { // Gen 4 GDM magic cards #define CMD_HF_MIFARE_G4_GDM_RDBL 0x0870 #define CMD_HF_MIFARE_G4_GDM_WRBL 0x0871 +#define CMD_HF_MIFARE_G4_GDM_CONFIG 0x0872 #define CMD_UNKNOWN 0xFFFF diff --git a/include/protocols.h b/include/protocols.h index 8450dc58a..5900b377c 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -194,6 +194,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MIFARE_MAGIC_GDM_AUTH_KEYB 0x81 #define MIFARE_MAGIC_GDM_WRITEBLOCK 0xA8 #define MIFARE_MAGIC_GDM_READBLOCK 0xE0 +#define MIFARE_MAGIC_GDM_READBLOCK_1 0xE1 #define MIFARE_EV1_PERSONAL_UID 0x40 #define MIFARE_EV1_SETMODE 0x43 From 96bc2e7a1d13a6f6718f5f78dde969e065d3547a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 26 Mar 2023 13:56:01 +0200 Subject: [PATCH 735/759] text --- doc/magic_cards_notes.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 9f4be7376..e90845c74 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -537,7 +537,7 @@ for example to write, you must use a customer authentication byte, 0x80, to aut Then send the data to be written. This tag has simular commands to the [UFUID](#mifare-classic-directwrite-ufuid-version) -It seems to be developed by the same person. +This indicates that both tagtypes are developed by the same person. **OBS** @@ -560,8 +560,8 @@ hf 14a info * Auth: `80xx`+crc * Write: `A8xx`+crc, `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`+crc -* Read config: `E000`+crc (unidentified) -* Write config: `E100`+crc +* Read config: `E000`+crc +* Write config: `E100`+crc, `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`+crc ### Characteristics ^[Top](#top) @@ -612,7 +612,7 @@ No implemented commands today **TODO** -* ZXUID, EUID, ICUID ? +* ZXUID, EUID, ICUID, KUID, HUID, RFUID ? * Some cards exhibit a specific SAK=28 ?? ## MIFARE Classic Super From 82f5c8512de36fee38b1e72643d24eac848f4958 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 26 Mar 2023 13:58:27 +0200 Subject: [PATCH 736/759] mfc writes now support tear off --- armsrc/mifarecmd.c | 61 +++++++++++++++++++++++--------------------- armsrc/mifareutil.c | 26 +++++++++++-------- client/src/cmdhfmf.c | 41 +++++++++++++++++++---------- 3 files changed, 76 insertions(+), 52 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 9eb44da5a..0d14ffb92 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -453,7 +453,6 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { memcpy(blockdata, datain + 10, 16); // variables - uint8_t isOK = 0; uint8_t uid[10] = {0x00}; uint32_t cuid = 0; struct Crypto1State mpcs = {0, 0}; @@ -469,37 +468,39 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { LED_B_OFF(); LED_C_OFF(); - while (true) { - if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); - break; - }; + uint8_t retval = 0; - if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error"); - break; - }; + if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card"); + goto OUT; + }; - if (mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); - break; - }; + if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error"); + goto OUT; + }; - if (mifare_classic_halt(pcs, cuid)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); - break; - }; - - isOK = 1; - break; + int res = mifare_classic_writeblock(pcs, cuid, blockNo, blockdata); + if (res == PM3_ETEAROFF) { + retval = PM3_ETEAROFF; + goto OUT; + } else if (res) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Write block error"); + retval = PM3_ESOFT; + goto OUT; } + if (mifare_classic_halt(pcs, cuid)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); + goto OUT; + }; + + retval = 1; + +OUT: crypto1_deinit(pcs); - if (g_dbglevel >= 2) DbpString("WRITE BLOCK FINISHED"); - - reply_mix(CMD_ACK, isOK, 0, 0, 0, 0); - + reply_mix(CMD_ACK, retval, 0, 0, 0, 0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); set_tracing(false); @@ -549,18 +550,20 @@ void MifareWriteBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key, uint8_t goto OUT; }; - if (mifare_classic_writeblock_ex(pcs, cuid, blockno, datain, true)) { + int res = mifare_classic_writeblock_ex(pcs, cuid, blockno, datain, true); + if (res == PM3_ETEAROFF) { + retval = PM3_ETEAROFF; + goto OUT; + } else if (res) { retval = PM3_ESOFT; goto OUT; - }; + } if (mifare_classic_halt(pcs, cuid)) { retval = PM3_ESOFT; goto OUT; }; - if (g_dbglevel >= 2) DbpString("WRITE BLOCK FINISHED"); - OUT: crypto1_deinit(pcs); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 11009031b..fd9260e23 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -18,6 +18,7 @@ //----------------------------------------------------------------------------- #include "mifareutil.h" +#include "appmain.h" // tearoff hook #include "string.h" #include "BigBuf.h" #include "iso14443a.h" @@ -451,18 +452,23 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL); - // Receive the response - len = ReaderReceive(receivedAnswer, receivedAnswerPar); + // tearoff occurred + if (tearoff_hook() == PM3_ETEAROFF) { + return PM3_ETEAROFF; + } else { + // Receive the response + len = ReaderReceive(receivedAnswer, receivedAnswerPar); - uint8_t res = 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; - res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; + uint8_t res = 0; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; - if ((len != 1) || (res != 0x0A)) { - if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res); - return 2; + if ((len != 1) || (res != 0x0A)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res); + return 2; + } } return 0; } diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 0ba8aac98..8093c818d 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -628,10 +628,12 @@ static int CmdHF14AMfWrBl(const char *Cmd) { return PM3_ETIMEOUT; } - uint8_t isok = resp.oldarg[0] & 0xff; - if (isok) { + int status = resp.oldarg[0]; + if (status) { PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )"); PrintAndLogEx(HINT, "try `" _YELLOW_("hf mf rdbl") "` to verify"); + } else if (status == PM3_ETEAROFF) { + return status; } else { PrintAndLogEx(FAILED, "Write ( " _RED_("fail") " )"); // suggest the opposite keytype than what was used. @@ -7708,7 +7710,9 @@ static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { if (resp.status == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )"); PrintAndLogEx(HINT, "try `" _YELLOW_("hf mf rdbl") "` to verify"); - } else { + } else if (resp.status == PM3_ETEAROFF) { + return resp.status; + } else { PrintAndLogEx(FAILED, "Write ( " _RED_("fail") " )"); PrintAndLogEx(HINT, "Maybe access rights? Try specify keytype `" _YELLOW_("hf mf gdmsetblk -%c ...") "` instead", (keytype == MF_KEY_A) ? 'b' : 'a'); } @@ -7831,7 +7835,7 @@ static int CmdHF14AMfValue(const char *Cmd) { } if (action < 3) { - uint8_t isok = true; + if (g_session.pm3_present == false) return PM3_ENOTTY; @@ -7858,7 +7862,15 @@ static int CmdHF14AMfValue(const char *Cmd) { PrintAndLogEx(FAILED, "Command execute timeout"); return PM3_ETIMEOUT; } - isok = resp.oldarg[0] & 0xff; + + if (resp.oldarg[0] & 0xFF) { + // all ok so set flag to read current value + getval = true; + PrintAndLogEx(SUCCESS, "Update ( " _GREEN_("success") " )"); + } else { + PrintAndLogEx(FAILED, "Update ( " _RED_("failed") " )"); + } + } else { // set value // To set a value block (or setup) we can use the normal mifare classic write block // So build the command options can call CMD_HF_MIFARE_WRITEBL @@ -7883,14 +7895,17 @@ static int CmdHF14AMfValue(const char *Cmd) { PrintAndLogEx(FAILED, "Command execute timeout"); return PM3_ETIMEOUT; } - isok = resp.oldarg[0] & 0xff; - } - - if (isok) { - PrintAndLogEx(SUCCESS, "Update ... : " _GREEN_("success")); - getval = true; // all ok so set flag to read current value - } else { - PrintAndLogEx(FAILED, "Update ... : " _RED_("failed")); + int status = resp.oldarg[0]; + if (status) { + // all ok so set flag to read current value + getval = true; + PrintAndLogEx(SUCCESS, "Update ( " _GREEN_("success") " )"); + } else if (status == PM3_ETEAROFF) { + // all ok so set flag to read current value + getval = true; + } else { + PrintAndLogEx(FAILED, "Update ( " _RED_("failed") " )"); + } } } From fae8ffda4454a94e94affbcd31ebd8557c8dce34 Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Sun, 26 Mar 2023 16:12:39 +0300 Subject: [PATCH 737/759] Fix formatting and run make style --- armsrc/mifaredesfire.c | 12 +- client/src/cmddata.c | 24 +- client/src/cmdhfmf.c | 33 +- client/src/cmdhftesla.c | 2 +- client/src/cmdparser.c | 2 +- client/src/crypto/asn1dump.c | 24 +- client/src/emv/tlv.c | 2 +- client/src/mifare/mifarehost.c | 18 +- client/src/pm3line_vocabulory.h | 1510 ++++++++++++++++--------------- client/src/uart/uart_win32.c | 14 +- common/commonutil.c | 4 +- doc/commands.json | 170 +++- doc/commands.md | 9 +- 13 files changed, 949 insertions(+), 875 deletions(-) diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index 04de05f21..de2a76a6a 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -182,10 +182,10 @@ void MifareDesfireGetInformation(void) { return; } - if (len < sizeof(payload.versionHW)+1) { + if (len < sizeof(payload.versionHW) + 1) { Dbprintf("Tag answer to MFDES_GET_VERSION was too short: data in Hardware Information is probably invalid."); print_result("Answer", resp, len); - memset(resp+len, 0xFF, sizeof(payload.versionHW)+1 - len); // clear remaining bytes + memset(resp + len, 0xFF, sizeof(payload.versionHW) + 1 - len); // clear remaining bytes } memcpy(payload.versionHW, resp + 1, sizeof(payload.versionHW)); @@ -201,10 +201,10 @@ void MifareDesfireGetInformation(void) { return; } - if (len < sizeof(payload.versionSW)+1) { + if (len < sizeof(payload.versionSW) + 1) { Dbprintf("Tag answer to MFDES_ADDITIONAL_FRAME 1 was too short: data in Software Information is probably invalid."); print_result("Answer", resp, len); - memset(resp+len, 0xFF, sizeof(payload.versionSW)+1 - len); // clear remaining bytes + memset(resp + len, 0xFF, sizeof(payload.versionSW) + 1 - len); // clear remaining bytes } memcpy(payload.versionSW, resp + 1, sizeof(payload.versionSW)); @@ -219,10 +219,10 @@ void MifareDesfireGetInformation(void) { return; } - if (len < sizeof(payload.details)+1) { + if (len < sizeof(payload.details) + 1) { Dbprintf("Tag answer to MFDES_ADDITIONAL_FRAME 2 was too short: data in Batch number and Production date is probably invalid"); print_result("Answer", resp, len); - memset(resp+len, 0xFF, sizeof(payload.details)+1 - len); // clear remaining bytes + memset(resp + len, 0xFF, sizeof(payload.details) + 1 - len); // clear remaining bytes } memcpy(payload.details, resp + 1, sizeof(payload.details)); diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 3d153022d..9524cbc63 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -36,7 +36,7 @@ #include "crypto/asn1utils.h" // ASN1 decode / print #include "cmdflashmemspiffs.h" // SPIFFS flash memory download #include "mbedtls/bignum.h" // big num -#include "mbedtls/entropy.h" // +#include "mbedtls/entropy.h" // #include "mbedtls/ctr_drbg.h" // random generator uint8_t g_DemodBuffer[MAX_DEMOD_BUF_LEN]; @@ -2429,7 +2429,7 @@ static int CmdZerocrossings(const char *Cmd) { } static bool data_verify_hex(uint8_t *d, size_t n) { - if (d == NULL) + if (d == NULL) return false; for (size_t i = 0; i < n; i++) { @@ -2517,7 +2517,7 @@ static int Cmdhex2bin(const char *Cmd) { return PM3_EINVARG; } - if (data_verify_hex((uint8_t*)data, dlen) == false) { + if (data_verify_hex((uint8_t *)data, dlen) == false) { return PM3_EINVARG; } @@ -3230,7 +3230,7 @@ static int CmdNumCon(const char *Cmd) { // hex if (hlen > 0) { - if (data_verify_hex((uint8_t*)hex, hlen) == false) { + if (data_verify_hex((uint8_t *)hex, hlen) == false) { return PM3_EINVARG; } MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16, hex)); @@ -3257,22 +3257,22 @@ static int CmdNumCon(const char *Cmd) { MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&N, &N, &base)); } - // printing + // printing typedef struct { - const char* desc; + const char *desc; uint8_t radix; } radix_t; radix_t radix[] = { - {"dec..... ", 10}, - {"hex..... 0x", 16}, - {"bin..... 0b", 2} + {"dec..... ", 10}, + {"hex..... 0x", 16}, + {"bin..... 0b", 2} }; char s[600] = {0}; size_t slen = 0; - for (uint8_t i=0; i < ARRAYLEN(radix); i++) { + for (uint8_t i = 0; i < ARRAYLEN(radix); i++) { MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(&N, radix[i].radix, s, sizeof(s), &slen)); if (slen > 0) { PrintAndLogEx(INFO, "%s%s", radix[i].desc, s); @@ -3285,9 +3285,9 @@ static int CmdNumCon(const char *Cmd) { mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_entropy_init(&entropy); - MBEDTLS_MPI_CHK(mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0 )); + MBEDTLS_MPI_CHK(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)); - res = mbedtls_mpi_is_prime_ext( &N, 50, mbedtls_ctr_drbg_random, &ctr_drbg ); + res = mbedtls_mpi_is_prime_ext(&N, 50, mbedtls_ctr_drbg_random, &ctr_drbg); if (res == 0) { PrintAndLogEx(INFO, "prime... " _YELLOW_("yes")); } diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 51d6ccddb..828666a57 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -404,7 +404,7 @@ static void mf_analyse_acl(uint16_t n, uint8_t *d) { Sector trailer sanity checks. Warn if ACL is strict read-only, or invalid ACL. */ -static int mf_analyse_st_block(uint8_t blockno, uint8_t *block, bool force){ +static int mf_analyse_st_block(uint8_t blockno, uint8_t *block, bool force) { if (mfIsSectorTrailer(blockno) == false) { return PM3_SUCCESS; @@ -6665,10 +6665,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { int res = mfkey32_moebius(&data, &key64); if (res) { - PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ " - _GREEN_("%012" - PRIX64) " ]", sprint_hex_inrow(trace_data, 4), data.sector, (data.keytype == 0x60) ? 'A' - : 'B', key64); + PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ "_GREEN_("%012" PRIX64) " ]", sprint_hex_inrow(trace_data, 4), data.sector, (data.keytype == 0x60) ? 'A' : 'B', key64); break; } } @@ -6694,16 +6691,12 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { res = ExchangeAPDU14a(aCHANGE, sizeof(aCHANGE), activate_field, keep_field_on, response, sizeof(response), &resplen); if (res != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Super card UID change [ " - _RED_("fail") - " ]"); + PrintAndLogEx(FAILED, "Super card UID change [ " _RED_("fail") " ]"); DropField(); return res; } - PrintAndLogEx(SUCCESS, "Super card UID change ( " - _GREEN_("ok") - " )"); + PrintAndLogEx(SUCCESS, "Super card UID change ( " _GREEN_("ok") " )"); return PM3_SUCCESS; } @@ -6717,15 +6710,11 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { res = ExchangeAPDU14a(aRESET, sizeof(aRESET), activate_field, keep_field_on, response, sizeof(response), &resplen); if (res != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "Super card reset [ " - _RED_("fail") - " ]"); + PrintAndLogEx(FAILED, "Super card reset [ " _RED_("fail") " ]"); DropField(); return res; } - PrintAndLogEx(SUCCESS, "Super card reset ( " - _GREEN_("ok") - " )"); + PrintAndLogEx(SUCCESS, "Super card reset ( " _GREEN_("ok") " )"); return PM3_SUCCESS; } @@ -6813,13 +6802,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { res = mfkey32_moebius(&data, &key64); if (res) { - PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ " - _GREEN_("%12" - PRIX64) " ]" - , sprint_hex_inrow(outA, 4) - , data.sector - , (data.keytype == 0x60) ? 'A' : 'B' - , key64); + PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ " _GREEN_("%12" PRIX64) " ]", sprint_hex_inrow(outA, 4), data.sector, (data.keytype == 0x60) ? 'A' : 'B', key64); } else { PrintAndLogEx(FAILED, "failed to recover any key"); } @@ -8093,7 +8076,7 @@ static command_t CommandTable[] = { {"gsave", CmdHF14AGen4Save, IfPm3Iso14443a, "Save dump from card into file or emulator"}, {"gsetblk", CmdHF14AGen4SetBlk, IfPm3Iso14443a, "Write block to card"}, {"gview", CmdHF14AGen4View, IfPm3Iso14443a, "View card"}, - {"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GDM") " --------------------------"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GDM") " --------------------------"}, {"gdmconfig", CmdHF14AGen4_GDM_ConfigBlk, IfPm3Iso14443a, "Read config block from card"}, {"gdmsetblk", CmdHF14AGen4_GDM_SetBlk, IfPm3Iso14443a, "Write block to card"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"}, diff --git a/client/src/cmdhftesla.c b/client/src/cmdhftesla.c index 32b9872e8..e1687a170 100644 --- a/client/src/cmdhftesla.c +++ b/client/src/cmdhftesla.c @@ -271,4 +271,4 @@ static int CmdHelp(const char *Cmd) { int CmdHFTESLA(const char *Cmd) { clearCommandBuffer(); return CmdsParse(CommandTable, Cmd); -} \ No newline at end of file +} diff --git a/client/src/cmdparser.c b/client/src/cmdparser.c index 39a6c98ad..fe7243c5e 100644 --- a/client/src/cmdparser.c +++ b/client/src/cmdparser.c @@ -386,7 +386,7 @@ void dumpCommandsRecursive(const command_t cmds[], int markdown, bool full_help) char currentparent[MAX_PM3_INPUT_ARGS_LENGTH] = {0}; snprintf(currentparent, sizeof currentparent, "%s%s ", parent, cmds[i].Name); - + char *old_parent = parent; parent = currentparent; // This is what causes the recursion, since commands Parse-implementation diff --git a/client/src/crypto/asn1dump.c b/client/src/crypto/asn1dump.c index 8445b4cd4..5fcabe20a 100644 --- a/client/src/crypto/asn1dump.c +++ b/client/src/crypto/asn1dump.c @@ -141,7 +141,7 @@ static void asn1_tag_dump_str_time(const struct tlv *tlv, const struct asn1_tag break; // month - PrintAndLogEx(NORMAL, "%.*s-" NOLF, 2, tlv->value + startidx ); + PrintAndLogEx(NORMAL, "%.*s-" NOLF, 2, tlv->value + startidx); if (len < startidx + 4) break; @@ -233,16 +233,16 @@ static void asn1_tag_dump_hex(const struct tlv *tlv, const struct asn1_tag *tag, } static void asn1_tag_dump_octet_string(const struct tlv *tlv, const struct asn1_tag *tag, int level) { -/* - for (size_t i = 0; i < tlv->len; i++) { - if (!isspace(tlv->value[i]) && !isprint(tlv->value[i])) { - *needdump = true; - break; + /* + for (size_t i = 0; i < tlv->len; i++) { + if (!isspace(tlv->value[i]) && !isprint(tlv->value[i])) { + *needdump = true; + break; + } } - } - */ - PrintAndLogEx(NORMAL, " " NOLF); - asn1_tag_dump_string(tlv, tag, level); + */ + PrintAndLogEx(NORMAL, " " NOLF); + asn1_tag_dump_string(tlv, tag, level); } static void asn1_tag_dump_boolean(const struct tlv *tlv, const struct asn1_tag *tag, int level) { @@ -262,7 +262,7 @@ static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag * return; } - hex_to_buffer((uint8_t*)hex, tlv->value, tlv->len, tlv->len, 0, 0, false); + hex_to_buffer((uint8_t *)hex, tlv->value, tlv->len, tlv->len, 0, 0, false); // results for MPI actions bool ret = false; @@ -277,7 +277,7 @@ static void asn1_tag_dump_integer(const struct tlv *tlv, const struct asn1_tag * size_t slen = 0; MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(&N, 10, s, sizeof(s), &slen)); if (slen > 0) { - PrintAndLogEx(NORMAL, "%*s value: %s", (level ), "", s); + PrintAndLogEx(NORMAL, "%*s value: %s", (level), "", s); } cleanup: diff --git a/client/src/emv/tlv.c b/client/src/emv/tlv.c index f025fbe27..737300fe0 100644 --- a/client/src/emv/tlv.c +++ b/client/src/emv/tlv.c @@ -227,7 +227,7 @@ struct tlvdb *tlvdb_parse_multi(const unsigned char *buf, size_t len) { while (left != 0) { struct tlvdb *db = calloc(1, sizeof(*db)); - if (db == NULL ) { + if (db == NULL) { goto err; } diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index a897a507e..d8390b3f5 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1512,16 +1512,16 @@ int vigik_verify(mfc_vigik_t *d) { PrintAndLogEx(INFO, "Raw signature"); print_hex_noascii_break(d->rsa_signature, sizeof(d->rsa_signature), MFBLOCK_SIZE * 2); } - -/* - int dl = 0; - - param_gethex_to_eol("1C07D46DA3849326D24B3468BD76673F4F3C41827DC413E81E4F3C7804FAC727213059B21D047510D6432448643A92EBFC67FBEDDAB468D13D948B172F5EBC79A0E3FEFDFAF4E81FC7108E070F1E3CD0", 0, signature, PUBLIC_VIGIK_KEYLEN, &dl); - param_gethex_to_eol("1AB86FE0C17FFFFE4379D5E15A4B2FAFFEFCFA0F1F3F7FA03E7DDDF1E3C78FFFB1F0E23F7FFF51584771C5C18307FEA36CA74E60AA6B0409ACA66A9EC155F4E9112345708A2B8457E722608EE1157408", 0, signature, PUBLIC_VIGIK_KEYLEN, &dl); - signature_len = dl; - */ - + /* + int dl = 0; + + param_gethex_to_eol("1C07D46DA3849326D24B3468BD76673F4F3C41827DC413E81E4F3C7804FAC727213059B21D047510D6432448643A92EBFC67FBEDDAB468D13D948B172F5EBC79A0E3FEFDFAF4E81FC7108E070F1E3CD0", 0, signature, PUBLIC_VIGIK_KEYLEN, &dl); + + param_gethex_to_eol("1AB86FE0C17FFFFE4379D5E15A4B2FAFFEFCFA0F1F3F7FA03E7DDDF1E3C78FFFB1F0E23F7FFF51584771C5C18307FEA36CA74E60AA6B0409ACA66A9EC155F4E9112345708A2B8457E722608EE1157408", 0, signature, PUBLIC_VIGIK_KEYLEN, &dl); + signature_len = dl; + */ + uint8_t rev_sig[128]; reverse_array_copy(d->rsa_signature, sizeof(d->rsa_signature), rev_sig); diff --git a/client/src/pm3line_vocabulory.h b/client/src/pm3line_vocabulory.h index 2b42cf4fd..e6d6dc438 100644 --- a/client/src/pm3line_vocabulory.h +++ b/client/src/pm3line_vocabulory.h @@ -31,758 +31,762 @@ typedef struct vocabulory_s { } vocabulory_t; const static vocabulory_t vocabulory[] = { - { 1, "help" }, - { 0, "auto" }, - { 1, "clear" }, - { 1, "hints" }, - { 1, "msleep" }, - { 1, "rem" }, - { 1, "quit" }, - { 1, "exit" }, - { 1, "prefs help" }, - { 1, "prefs show" }, - { 1, "prefs get barmode" }, - { 1, "prefs get clientdebug" }, - { 1, "prefs get clientdelay" }, - { 1, "prefs get color" }, - { 1, "prefs get savepaths" }, - { 1, "prefs get emoji" }, - { 1, "prefs get hints" }, - { 1, "prefs get output" }, - { 1, "prefs get plotsliders" }, - { 1, "prefs set help" }, - { 1, "prefs set barmode" }, - { 1, "prefs set clientdebug" }, - { 1, "prefs set clientdelay" }, - { 1, "prefs set color" }, - { 1, "prefs set emoji" }, - { 1, "prefs set hints" }, - { 1, "prefs set savepaths" }, - { 1, "prefs set output" }, - { 1, "prefs set plotsliders" }, - { 1, "analyse help" }, - { 1, "analyse lcr" }, - { 1, "analyse crc" }, - { 1, "analyse chksum" }, - { 1, "analyse dates" }, - { 1, "analyse lfsr" }, - { 1, "analyse a" }, - { 1, "analyse nuid" }, - { 1, "analyse demodbuff" }, - { 1, "analyse freq" }, - { 1, "analyse foo" }, - { 1, "analyse units" }, - { 1, "data help" }, - { 1, "data biphaserawdecode" }, - { 1, "data detectclock" }, - { 1, "data fsktonrz" }, - { 1, "data manrawdecode" }, - { 1, "data modulation" }, - { 1, "data rawdemod" }, - { 1, "data askedgedetect" }, - { 1, "data autocorr" }, - { 1, "data dirthreshold" }, - { 1, "data decimate" }, - { 1, "data undecimate" }, - { 1, "data hide" }, - { 1, "data hpf" }, - { 1, "data iir" }, - { 1, "data grid" }, - { 1, "data ltrim" }, - { 1, "data mtrim" }, - { 1, "data norm" }, - { 1, "data plot" }, - { 1, "data rtrim" }, - { 1, "data setgraphmarkers" }, - { 1, "data shiftgraphzero" }, - { 1, "data timescale" }, - { 1, "data zerocrossings" }, - { 1, "data convertbitstream" }, - { 1, "data getbitstream" }, - { 1, "data asn1" }, - { 1, "data bin2hex" }, - { 0, "data bitsamples" }, - { 1, "data clear" }, - { 1, "data diff" }, - { 0, "data hexsamples" }, - { 1, "data hex2bin" }, - { 1, "data load" }, - { 1, "data print" }, - { 0, "data samples" }, - { 1, "data save" }, - { 1, "data setdebugmode" }, - { 0, "data tune" }, - { 1, "emv help" }, - { 0, "emv exec" }, - { 0, "emv pse" }, - { 0, "emv search" }, - { 0, "emv select" }, - { 0, "emv gpo" }, - { 0, "emv readrec" }, - { 0, "emv genac" }, - { 0, "emv challenge" }, - { 0, "emv intauth" }, - { 0, "emv scan" }, - { 1, "emv test" }, - { 1, "emv list" }, - { 0, "emv roca" }, - { 1, "hf help" }, - { 1, "hf list" }, - { 0, "hf plot" }, - { 0, "hf tune" }, - { 1, "hf search" }, - { 0, "hf sniff" }, - { 1, "hf 14a help" }, - { 1, "hf 14a list" }, - { 0, "hf 14a antifuzz" }, - { 0, "hf 14a config" }, - { 0, "hf 14a cuids" }, - { 0, "hf 14a info" }, - { 0, "hf 14a sim" }, - { 0, "hf 14a sniff" }, - { 0, "hf 14a raw" }, - { 0, "hf 14a reader" }, - { 0, "hf 14a apdu" }, - { 0, "hf 14a apdufind" }, - { 0, "hf 14a chaining" }, - { 0, "hf 14a ndefformat" }, - { 0, "hf 14a ndefread" }, - { 0, "hf 14a ndefwrite" }, - { 1, "hf 14b help" }, - { 0, "hf 14b apdu" }, - { 0, "hf 14b dump" }, - { 0, "hf 14b info" }, - { 1, "hf 14b list" }, - { 0, "hf 14b ndefread" }, - { 0, "hf 14b raw" }, - { 0, "hf 14b reader" }, - { 0, "hf 14b sim" }, - { 0, "hf 14b sniff" }, - { 0, "hf 14b rdbl" }, - { 0, "hf 14b sriwrite" }, - { 1, "hf 14b view" }, - { 1, "hf 15 help" }, - { 1, "hf 15 list" }, - { 1, "hf 15 demod" }, - { 0, "hf 15 dump" }, - { 0, "hf 15 info" }, - { 0, "hf 15 sniff" }, - { 0, "hf 15 raw" }, - { 0, "hf 15 rdbl" }, - { 0, "hf 15 rdmulti" }, - { 0, "hf 15 reader" }, - { 0, "hf 15 restore" }, - { 0, "hf 15 samples" }, - { 0, "hf 15 eload" }, - { 0, "hf 15 esave" }, - { 0, "hf 15 eview" }, - { 0, "hf 15 sim" }, - { 0, "hf 15 slixwritepwd" }, - { 0, "hf 15 slixeasdisable" }, - { 0, "hf 15 slixeasenable" }, - { 0, "hf 15 slixprivacydisable" }, - { 0, "hf 15 slixprivacyenable" }, - { 0, "hf 15 passprotectafi" }, - { 0, "hf 15 passprotecteas" }, - { 0, "hf 15 wrbl" }, - { 0, "hf 15 findafi" }, - { 0, "hf 15 writeafi" }, - { 0, "hf 15 writedsfid" }, - { 0, "hf 15 csetuid" }, - { 1, "hf cipurse help" }, - { 0, "hf cipurse info" }, - { 0, "hf cipurse select" }, - { 0, "hf cipurse auth" }, - { 0, "hf cipurse read" }, - { 0, "hf cipurse write" }, - { 0, "hf cipurse aread" }, - { 0, "hf cipurse awrite" }, - { 0, "hf cipurse formatall" }, - { 0, "hf cipurse create" }, - { 0, "hf cipurse delete" }, - { 0, "hf cipurse updkey" }, - { 0, "hf cipurse updakey" }, - { 0, "hf cipurse default" }, - { 1, "hf cipurse test" }, - { 1, "hf epa help" }, - { 0, "hf epa cnonces" }, - { 0, "hf epa replay" }, - { 0, "hf epa sim" }, - { 1, "hf emrtd help" }, - { 0, "hf emrtd dump" }, - { 1, "hf emrtd info" }, - { 1, "hf emrtd list" }, - { 1, "hf felica help" }, - { 1, "hf felica list" }, - { 0, "hf felica reader" }, - { 0, "hf felica info" }, - { 0, "hf felica sniff" }, - { 0, "hf felica raw" }, - { 0, "hf felica rdbl" }, - { 0, "hf felica wrbl" }, - { 0, "hf felica rqservice" }, - { 0, "hf felica rqresponse" }, - { 0, "hf felica scsvcode" }, - { 0, "hf felica rqsyscode" }, - { 0, "hf felica auth1" }, - { 0, "hf felica auth2" }, - { 0, "hf felica rqspecver" }, - { 0, "hf felica resetmode" }, - { 0, "hf felica litesim" }, - { 0, "hf felica litedump" }, - { 1, "hf fido help" }, - { 1, "hf fido list" }, - { 0, "hf fido info" }, - { 0, "hf fido reg" }, - { 0, "hf fido auth" }, - { 0, "hf fido make" }, - { 0, "hf fido assert" }, - { 1, "hf fudan help" }, - { 0, "hf fudan reader" }, - { 0, "hf fudan dump" }, - { 0, "hf fudan rdbl" }, - { 1, "hf fudan view" }, - { 0, "hf fudan wrbl" }, - { 1, "hf gallagher help" }, - { 0, "hf gallagher reader" }, - { 0, "hf gallagher clone" }, - { 0, "hf gallagher delete" }, - { 1, "hf gallagher diversifykey" }, - { 1, "hf gallagher decode" }, - { 1, "hf ksx6924 help" }, - { 0, "hf ksx6924 select" }, - { 0, "hf ksx6924 info" }, - { 0, "hf ksx6924 balance" }, - { 0, "hf ksx6924 init" }, - { 0, "hf ksx6924 prec" }, - { 1, "hf jooki help" }, - { 0, "hf jooki clone" }, - { 1, "hf jooki decode" }, - { 1, "hf jooki encode" }, - { 0, "hf jooki sim" }, - { 1, "hf iclass help" }, - { 0, "hf iclass dump" }, - { 1, "hf iclass info" }, - { 1, "hf iclass list" }, - { 0, "hf iclass rdbl" }, - { 0, "hf iclass reader" }, - { 0, "hf iclass restore" }, - { 0, "hf iclass sniff" }, - { 0, "hf iclass wrbl" }, - { 0, "hf iclass chk" }, - { 1, "hf iclass loclass" }, - { 1, "hf iclass lookup" }, - { 0, "hf iclass sim" }, - { 0, "hf iclass eload" }, - { 0, "hf iclass esave" }, - { 0, "hf iclass eview" }, - { 1, "hf iclass configcard" }, - { 1, "hf iclass calcnewkey" }, - { 1, "hf iclass encode" }, - { 1, "hf iclass encrypt" }, - { 1, "hf iclass decrypt" }, - { 1, "hf iclass managekeys" }, - { 1, "hf iclass permutekey" }, - { 1, "hf iclass view" }, - { 1, "hf legic help" }, - { 0, "hf legic dump" }, - { 0, "hf legic info" }, - { 1, "hf legic list" }, - { 0, "hf legic rdbl" }, - { 0, "hf legic reader" }, - { 0, "hf legic restore" }, - { 0, "hf legic wipe" }, - { 0, "hf legic wrbl" }, - { 0, "hf legic sim" }, - { 0, "hf legic eload" }, - { 0, "hf legic esave" }, - { 0, "hf legic eview" }, - { 1, "hf legic crc" }, - { 1, "hf legic view" }, - { 1, "hf lto help" }, - { 0, "hf lto dump" }, - { 0, "hf lto info" }, - { 1, "hf lto list" }, - { 0, "hf lto rdbl" }, - { 0, "hf lto reader" }, - { 0, "hf lto restore" }, - { 0, "hf lto wrbl" }, - { 1, "hf mf help" }, - { 1, "hf mf list" }, - { 0, "hf mf darkside" }, - { 0, "hf mf nested" }, - { 1, "hf mf hardnested" }, - { 0, "hf mf staticnested" }, - { 0, "hf mf autopwn" }, - { 0, "hf mf nack" }, - { 0, "hf mf chk" }, - { 0, "hf mf fchk" }, - { 1, "hf mf decrypt" }, - { 0, "hf mf supercard" }, - { 0, "hf mf auth4" }, - { 1, "hf mf acl" }, - { 0, "hf mf dump" }, - { 1, "hf mf mad" }, - { 0, "hf mf personalize" }, - { 0, "hf mf rdbl" }, - { 0, "hf mf rdsc" }, - { 0, "hf mf restore" }, - { 0, "hf mf setmod" }, - { 1, "hf mf value" }, - { 1, "hf mf view" }, - { 0, "hf mf wipe" }, - { 0, "hf mf wrbl" }, - { 0, "hf mf sim" }, - { 0, "hf mf ecfill" }, - { 0, "hf mf eclr" }, - { 0, "hf mf egetblk" }, - { 0, "hf mf egetsc" }, - { 0, "hf mf ekeyprn" }, - { 0, "hf mf eload" }, - { 0, "hf mf esave" }, - { 0, "hf mf esetblk" }, - { 0, "hf mf eview" }, - { 0, "hf mf cgetblk" }, - { 0, "hf mf cgetsc" }, - { 0, "hf mf cload" }, - { 0, "hf mf csave" }, - { 0, "hf mf csetblk" }, - { 0, "hf mf csetuid" }, - { 0, "hf mf cview" }, - { 0, "hf mf cwipe" }, - { 0, "hf mf gen3uid" }, - { 0, "hf mf gen3blk" }, - { 0, "hf mf gen3freeze" }, - { 0, "hf mf ggetblk" }, - { 0, "hf mf gload" }, - { 0, "hf mf gsave" }, - { 0, "hf mf gsetblk" }, - { 0, "hf mf gview" }, - { 0, "hf mf ndefformat" }, - { 0, "hf mf ndefread" }, - { 0, "hf mf ndefwrite" }, - { 1, "hf mfp help" }, - { 0, "hf mfp info" }, - { 0, "hf mfp wrp" }, - { 0, "hf mfp initp" }, - { 0, "hf mfp commitp" }, - { 0, "hf mfp auth" }, - { 0, "hf mfp rdbl" }, - { 0, "hf mfp rdsc" }, - { 0, "hf mfp wrbl" }, - { 0, "hf mfp chk" }, - { 0, "hf mfp mad" }, - { 0, "hf mfp ndefread" }, - { 1, "hf mfu help" }, - { 1, "hf mfu keygen" }, - { 1, "hf mfu pwdgen" }, - { 0, "hf mfu otptear" }, - { 0, "hf mfu cauth" }, - { 0, "hf mfu dump" }, - { 0, "hf mfu info" }, - { 0, "hf mfu ndefread" }, - { 0, "hf mfu rdbl" }, - { 0, "hf mfu restore" }, - { 1, "hf mfu view" }, - { 0, "hf mfu tamper" }, - { 0, "hf mfu wrbl" }, - { 0, "hf mfu eload" }, - { 0, "hf mfu esave" }, - { 0, "hf mfu eview" }, - { 0, "hf mfu sim" }, - { 0, "hf mfu setpwd" }, - { 0, "hf mfu setuid" }, - { 1, "hf mfdes help" }, - { 0, "hf mfdes info" }, - { 0, "hf mfdes getuid" }, - { 0, "hf mfdes default" }, - { 0, "hf mfdes auth" }, - { 0, "hf mfdes chk" }, - { 0, "hf mfdes detect" }, - { 0, "hf mfdes freemem" }, - { 0, "hf mfdes setconfig" }, - { 0, "hf mfdes formatpicc" }, - { 1, "hf mfdes list" }, - { 0, "hf mfdes mad" }, - { 0, "hf mfdes lsapp" }, - { 0, "hf mfdes getaids" }, - { 0, "hf mfdes getappnames" }, - { 0, "hf mfdes bruteaid" }, - { 0, "hf mfdes createapp" }, - { 0, "hf mfdes deleteapp" }, - { 0, "hf mfdes selectapp" }, - { 0, "hf mfdes changekey" }, - { 0, "hf mfdes chkeysettings" }, - { 0, "hf mfdes getkeysettings" }, - { 0, "hf mfdes getkeyversions" }, - { 0, "hf mfdes getfileids" }, - { 0, "hf mfdes getfileisoids" }, - { 0, "hf mfdes lsfiles" }, - { 0, "hf mfdes dump" }, - { 0, "hf mfdes createfile" }, - { 0, "hf mfdes createvaluefile" }, - { 0, "hf mfdes createrecordfile" }, - { 0, "hf mfdes createmacfile" }, - { 0, "hf mfdes deletefile" }, - { 0, "hf mfdes getfilesettings" }, - { 0, "hf mfdes chfilesettings" }, - { 0, "hf mfdes read" }, - { 0, "hf mfdes write" }, - { 0, "hf mfdes value" }, - { 0, "hf mfdes clearrecfile" }, - { 1, "hf mfdes test" }, - { 1, "hf ntag424 help" }, - { 0, "hf ntag424 info" }, - { 0, "hf ntag424 sdm" }, - { 1, "hf ntag424 view" }, - { 1, "hf seos help" }, - { 0, "hf seos info" }, - { 1, "hf seos list" }, - { 1, "hf st25ta help" }, - { 0, "hf st25ta info" }, - { 1, "hf st25ta list" }, - { 1, "hf st25ta ndefread" }, - { 0, "hf st25ta protect" }, - { 0, "hf st25ta pwd" }, - { 0, "hf st25ta sim" }, - { 1, "hf tesla help" }, - { 0, "hf tesla info" }, - { 1, "hf tesla list" }, - { 1, "hf texkom help" }, - { 0, "hf texkom reader" }, - { 0, "hf texkom sim" }, - { 1, "hf thinfilm help" }, - { 0, "hf thinfilm info" }, - { 1, "hf thinfilm list" }, - { 0, "hf thinfilm sim" }, - { 1, "hf topaz help" }, - { 0, "hf topaz dump" }, - { 1, "hf topaz list" }, - { 0, "hf topaz info" }, - { 0, "hf topaz reader" }, - { 0, "hf topaz sim" }, - { 0, "hf topaz sniff" }, - { 0, "hf topaz raw" }, - { 0, "hf topaz rdbl" }, - { 1, "hf topaz view" }, - { 0, "hf topaz wrbl" }, - { 1, "hf xerox help" }, - { 0, "hf xerox info" }, - { 0, "hf xerox reader" }, - { 0, "hf xerox dump" }, - { 1, "hf waveshare help" }, - { 0, "hf waveshare loadbmp" }, - { 1, "hw help" }, - { 0, "hw break" }, - { 1, "hw connect" }, - { 0, "hw dbg" }, - { 0, "hw detectreader" }, - { 0, "hw fpgaoff" }, - { 0, "hw lcd" }, - { 0, "hw lcdreset" }, - { 0, "hw ping" }, - { 0, "hw readmem" }, - { 0, "hw reset" }, - { 0, "hw setlfdivisor" }, - { 0, "hw setmux" }, - { 0, "hw standalone" }, - { 0, "hw status" }, - { 0, "hw tearoff" }, - { 0, "hw tia" }, - { 0, "hw tune" }, - { 1, "hw version" }, - { 1, "lf help" }, - { 0, "lf config" }, - { 0, "lf cmdread" }, - { 0, "lf read" }, - { 1, "lf search" }, - { 0, "lf sim" }, - { 0, "lf simask" }, - { 0, "lf simfsk" }, - { 0, "lf simpsk" }, - { 0, "lf simbidir" }, - { 0, "lf sniff" }, - { 0, "lf tune" }, - { 1, "lf awid help" }, - { 1, "lf awid demod" }, - { 0, "lf awid reader" }, - { 0, "lf awid clone" }, - { 0, "lf awid sim" }, - { 0, "lf awid brute" }, - { 0, "lf awid watch" }, - { 1, "lf cotag help" }, - { 1, "lf cotag demod" }, - { 0, "lf cotag reader" }, - { 1, "lf destron help" }, - { 1, "lf destron demod" }, - { 0, "lf destron reader" }, - { 0, "lf destron clone" }, - { 0, "lf destron sim" }, - { 1, "lf em help" }, - { 1, "lf em 410x help" }, - { 1, "lf em 410x demod" }, - { 0, "lf em 410x reader" }, - { 0, "lf em 410x sim" }, - { 0, "lf em 410x brute" }, - { 0, "lf em 410x watch" }, - { 0, "lf em 410x spoof" }, - { 0, "lf em 410x clone" }, - { 1, "lf em 4x05 help" }, - { 0, "lf em 4x05 brute" }, - { 0, "lf em 4x05 chk" }, - { 1, "lf em 4x05 demod" }, - { 0, "lf em 4x05 dump" }, - { 0, "lf em 4x05 info" }, - { 0, "lf em 4x05 read" }, - { 1, "lf em 4x05 sniff" }, - { 0, "lf em 4x05 unlock" }, - { 0, "lf em 4x05 wipe" }, - { 0, "lf em 4x05 write" }, - { 1, "lf em 4x50 help" }, - { 0, "lf em 4x50 brute" }, - { 0, "lf em 4x50 chk" }, - { 0, "lf em 4x50 dump" }, - { 0, "lf em 4x50 info" }, - { 0, "lf em 4x50 login" }, - { 0, "lf em 4x50 rdbl" }, - { 0, "lf em 4x50 reader" }, - { 0, "lf em 4x50 restore" }, - { 0, "lf em 4x50 wrbl" }, - { 0, "lf em 4x50 wrpwd" }, - { 0, "lf em 4x50 wipe" }, - { 0, "lf em 4x50 eload" }, - { 0, "lf em 4x50 esave" }, - { 0, "lf em 4x50 eview" }, - { 0, "lf em 4x50 sim" }, - { 1, "lf em 4x70 help" }, - { 0, "lf em 4x70 brute" }, - { 0, "lf em 4x70 info" }, - { 0, "lf em 4x70 write" }, - { 0, "lf em 4x70 unlock" }, - { 0, "lf em 4x70 auth" }, - { 0, "lf em 4x70 writepin" }, - { 0, "lf em 4x70 writekey" }, - { 1, "lf fdxb help" }, - { 1, "lf fdxb demod" }, - { 0, "lf fdxb reader" }, - { 0, "lf fdxb clone" }, - { 0, "lf fdxb sim" }, - { 1, "lf gallagher help" }, - { 1, "lf gallagher demod" }, - { 0, "lf gallagher reader" }, - { 0, "lf gallagher clone" }, - { 0, "lf gallagher sim" }, - { 1, "lf gproxii help" }, - { 1, "lf gproxii demod" }, - { 0, "lf gproxii reader" }, - { 0, "lf gproxii clone" }, - { 0, "lf gproxii sim" }, - { 1, "lf hid help" }, - { 1, "lf hid demod" }, - { 0, "lf hid reader" }, - { 0, "lf hid clone" }, - { 0, "lf hid sim" }, - { 0, "lf hid brute" }, - { 0, "lf hid watch" }, - { 1, "lf hitag help" }, - { 0, "lf hitag eload" }, - { 1, "lf hitag list" }, - { 0, "lf hitag info" }, - { 0, "lf hitag reader" }, - { 0, "lf hitag sim" }, - { 0, "lf hitag sniff" }, - { 0, "lf hitag writer" }, - { 0, "lf hitag dump" }, - { 0, "lf hitag cc" }, - { 1, "lf idteck help" }, - { 1, "lf idteck demod" }, - { 0, "lf idteck reader" }, - { 0, "lf idteck clone" }, - { 0, "lf idteck sim" }, - { 1, "lf indala help" }, - { 0, "lf indala brute" }, - { 1, "lf indala demod" }, - { 1, "lf indala altdemod" }, - { 0, "lf indala reader" }, - { 0, "lf indala clone" }, - { 0, "lf indala sim" }, - { 1, "lf io help" }, - { 1, "lf io demod" }, - { 0, "lf io reader" }, - { 0, "lf io clone" }, - { 0, "lf io sim" }, - { 0, "lf io watch" }, - { 1, "lf jablotron help" }, - { 1, "lf jablotron demod" }, - { 0, "lf jablotron reader" }, - { 0, "lf jablotron clone" }, - { 0, "lf jablotron sim" }, - { 1, "lf keri help" }, - { 1, "lf keri demod" }, - { 0, "lf keri reader" }, - { 0, "lf keri clone" }, - { 0, "lf keri sim" }, - { 1, "lf motorola help" }, - { 1, "lf motorola demod" }, - { 0, "lf motorola reader" }, - { 0, "lf motorola clone" }, - { 0, "lf motorola sim" }, - { 1, "lf nedap help" }, - { 1, "lf nedap demod" }, - { 0, "lf nedap reader" }, - { 0, "lf nedap clone" }, - { 0, "lf nedap sim" }, - { 1, "lf nexwatch help" }, - { 1, "lf nexwatch demod" }, - { 0, "lf nexwatch reader" }, - { 0, "lf nexwatch clone" }, - { 0, "lf nexwatch sim" }, - { 1, "lf noralsy help" }, - { 1, "lf noralsy demod" }, - { 0, "lf noralsy reader" }, - { 0, "lf noralsy clone" }, - { 0, "lf noralsy sim" }, - { 1, "lf pac help" }, - { 1, "lf pac demod" }, - { 0, "lf pac reader" }, - { 0, "lf pac clone" }, - { 0, "lf pac sim" }, - { 1, "lf paradox help" }, - { 1, "lf paradox demod" }, - { 0, "lf paradox reader" }, - { 0, "lf paradox clone" }, - { 0, "lf paradox sim" }, - { 1, "lf pcf7931 help" }, - { 0, "lf pcf7931 reader" }, - { 0, "lf pcf7931 write" }, - { 1, "lf pcf7931 config" }, - { 1, "lf presco help" }, - { 1, "lf presco demod" }, - { 0, "lf presco reader" }, - { 0, "lf presco clone" }, - { 0, "lf presco sim" }, - { 1, "lf pyramid help" }, - { 1, "lf pyramid demod" }, - { 0, "lf pyramid reader" }, - { 0, "lf pyramid clone" }, - { 0, "lf pyramid sim" }, - { 1, "lf securakey help" }, - { 1, "lf securakey demod" }, - { 0, "lf securakey reader" }, - { 0, "lf securakey clone" }, - { 0, "lf securakey sim" }, - { 1, "lf ti help" }, - { 1, "lf ti demod" }, - { 0, "lf ti reader" }, - { 0, "lf ti write" }, - { 1, "lf t55xx help" }, - { 0, "lf t55xx clonehelp" }, - { 1, "lf t55xx config" }, - { 0, "lf t55xx dangerraw" }, - { 1, "lf t55xx detect" }, - { 0, "lf t55xx deviceconfig" }, - { 0, "lf t55xx dump" }, - { 1, "lf t55xx info" }, - { 0, "lf t55xx p1detect" }, - { 0, "lf t55xx read" }, - { 0, "lf t55xx resetread" }, - { 0, "lf t55xx restore" }, - { 1, "lf t55xx trace" }, - { 0, "lf t55xx wakeup" }, - { 0, "lf t55xx write" }, - { 0, "lf t55xx bruteforce" }, - { 0, "lf t55xx chk" }, - { 0, "lf t55xx protect" }, - { 0, "lf t55xx recoverpw" }, - { 1, "lf t55xx sniff" }, - { 0, "lf t55xx special" }, - { 0, "lf t55xx wipe" }, - { 1, "lf viking help" }, - { 1, "lf viking demod" }, - { 0, "lf viking reader" }, - { 0, "lf viking clone" }, - { 0, "lf viking sim" }, - { 1, "lf visa2000 help" }, - { 1, "lf visa2000 demod" }, - { 0, "lf visa2000 reader" }, - { 0, "lf visa2000 clone" }, - { 0, "lf visa2000 sim" }, - { 1, "mem help" }, - { 0, "mem baudrate" }, - { 0, "mem dump" }, - { 0, "mem info" }, - { 0, "mem load" }, - { 0, "mem wipe" }, - { 1, "mem spiffs help" }, - { 0, "mem spiffs copy" }, - { 0, "mem spiffs check" }, - { 0, "mem spiffs dump" }, - { 0, "mem spiffs info" }, - { 0, "mem spiffs mount" }, - { 0, "mem spiffs remove" }, - { 0, "mem spiffs rename" }, - { 0, "mem spiffs test" }, - { 0, "mem spiffs tree" }, - { 0, "mem spiffs unmount" }, - { 0, "mem spiffs upload" }, - { 0, "mem spiffs view" }, - { 0, "mem spiffs wipe" }, - { 1, "nfc help" }, - { 1, "nfc decode" }, - { 0, "nfc type1 read" }, - { 1, "nfc type1 help" }, - { 0, "nfc type2 read" }, - { 1, "nfc type2 help" }, - { 0, "nfc type4a format" }, - { 0, "nfc type4a read" }, - { 0, "nfc type4a write" }, - { 0, "nfc type4a st25taread" }, - { 1, "nfc type4a help" }, - { 0, "nfc type4b read" }, - { 1, "nfc type4b help" }, - { 0, "nfc mf cformat" }, - { 0, "nfc mf cread" }, - { 0, "nfc mf cwrite" }, - { 0, "nfc mf pread" }, - { 1, "nfc mf help" }, - { 0, "nfc barcode read" }, - { 0, "nfc barcode sim" }, - { 1, "nfc barcode help" }, - { 1, "piv help" }, - { 0, "piv select" }, - { 0, "piv getdata" }, - { 0, "piv authsign" }, - { 0, "piv scan" }, - { 1, "piv list" }, - { 1, "smart help" }, - { 1, "smart list" }, - { 0, "smart info" }, - { 0, "smart reader" }, - { 0, "smart raw" }, - { 1, "smart upgrade" }, - { 0, "smart setclock" }, - { 0, "smart brute" }, - { 1, "script help" }, - { 1, "script list" }, - { 1, "script run" }, - { 1, "trace help" }, - { 1, "trace extract" }, - { 1, "trace list" }, - { 1, "trace load" }, - { 1, "trace save" }, - { 1, "usart help" }, - { 0, "usart btpin" }, - { 0, "usart btfactory" }, - { 0, "usart tx" }, - { 0, "usart rx" }, - { 0, "usart txrx" }, - { 0, "usart txhex" }, - { 0, "usart rxhex" }, - { 0, "usart config" }, - { 1, "wiegand help" }, - { 1, "wiegand list" }, - { 1, "wiegand encode" }, - { 1, "wiegand decode" }, + { 1, "help" }, + { 0, "auto" }, + { 1, "clear" }, + { 1, "hints" }, + { 1, "msleep" }, + { 1, "rem" }, + { 1, "quit" }, + { 1, "exit" }, + { 1, "prefs help" }, + { 1, "prefs show" }, + { 1, "prefs get barmode" }, + { 1, "prefs get clientdebug" }, + { 1, "prefs get clientdelay" }, + { 1, "prefs get color" }, + { 1, "prefs get savepaths" }, + { 1, "prefs get emoji" }, + { 1, "prefs get hints" }, + { 1, "prefs get output" }, + { 1, "prefs get plotsliders" }, + { 1, "prefs set help" }, + { 1, "prefs set barmode" }, + { 1, "prefs set clientdebug" }, + { 1, "prefs set clientdelay" }, + { 1, "prefs set color" }, + { 1, "prefs set emoji" }, + { 1, "prefs set hints" }, + { 1, "prefs set savepaths" }, + { 1, "prefs set output" }, + { 1, "prefs set plotsliders" }, + { 1, "analyse help" }, + { 1, "analyse lcr" }, + { 1, "analyse crc" }, + { 1, "analyse chksum" }, + { 1, "analyse dates" }, + { 1, "analyse lfsr" }, + { 1, "analyse a" }, + { 1, "analyse nuid" }, + { 1, "analyse demodbuff" }, + { 1, "analyse freq" }, + { 1, "analyse foo" }, + { 1, "analyse units" }, + { 1, "data help" }, + { 1, "data biphaserawdecode" }, + { 1, "data detectclock" }, + { 1, "data fsktonrz" }, + { 1, "data manrawdecode" }, + { 1, "data modulation" }, + { 1, "data rawdemod" }, + { 1, "data askedgedetect" }, + { 1, "data autocorr" }, + { 1, "data dirthreshold" }, + { 1, "data decimate" }, + { 1, "data undecimate" }, + { 1, "data hide" }, + { 1, "data hpf" }, + { 1, "data iir" }, + { 1, "data grid" }, + { 1, "data ltrim" }, + { 1, "data mtrim" }, + { 1, "data norm" }, + { 1, "data plot" }, + { 1, "data rtrim" }, + { 1, "data setgraphmarkers" }, + { 1, "data shiftgraphzero" }, + { 1, "data timescale" }, + { 1, "data zerocrossings" }, + { 1, "data convertbitstream" }, + { 1, "data getbitstream" }, + { 1, "data asn1" }, + { 1, "data bin2hex" }, + { 0, "data bitsamples" }, + { 1, "data clear" }, + { 1, "data diff" }, + { 0, "data hexsamples" }, + { 1, "data hex2bin" }, + { 1, "data load" }, + { 1, "data num" }, + { 1, "data print" }, + { 0, "data samples" }, + { 1, "data save" }, + { 1, "data setdebugmode" }, + { 0, "data tune" }, + { 1, "emv help" }, + { 0, "emv exec" }, + { 0, "emv pse" }, + { 0, "emv search" }, + { 0, "emv select" }, + { 0, "emv gpo" }, + { 0, "emv readrec" }, + { 0, "emv genac" }, + { 0, "emv challenge" }, + { 0, "emv intauth" }, + { 0, "emv scan" }, + { 1, "emv test" }, + { 1, "emv list" }, + { 0, "emv roca" }, + { 1, "hf help" }, + { 1, "hf list" }, + { 0, "hf plot" }, + { 0, "hf tune" }, + { 1, "hf search" }, + { 0, "hf sniff" }, + { 1, "hf 14a help" }, + { 1, "hf 14a list" }, + { 0, "hf 14a antifuzz" }, + { 0, "hf 14a config" }, + { 0, "hf 14a cuids" }, + { 0, "hf 14a info" }, + { 0, "hf 14a sim" }, + { 0, "hf 14a sniff" }, + { 0, "hf 14a raw" }, + { 0, "hf 14a reader" }, + { 0, "hf 14a apdu" }, + { 0, "hf 14a apdufind" }, + { 0, "hf 14a chaining" }, + { 0, "hf 14a ndefformat" }, + { 0, "hf 14a ndefread" }, + { 0, "hf 14a ndefwrite" }, + { 1, "hf 14b help" }, + { 0, "hf 14b apdu" }, + { 0, "hf 14b dump" }, + { 0, "hf 14b info" }, + { 1, "hf 14b list" }, + { 0, "hf 14b ndefread" }, + { 0, "hf 14b raw" }, + { 0, "hf 14b reader" }, + { 0, "hf 14b sim" }, + { 0, "hf 14b sniff" }, + { 0, "hf 14b rdbl" }, + { 0, "hf 14b sriwrite" }, + { 1, "hf 14b view" }, + { 1, "hf 15 help" }, + { 1, "hf 15 list" }, + { 1, "hf 15 demod" }, + { 0, "hf 15 dump" }, + { 0, "hf 15 info" }, + { 0, "hf 15 sniff" }, + { 0, "hf 15 raw" }, + { 0, "hf 15 rdbl" }, + { 0, "hf 15 rdmulti" }, + { 0, "hf 15 reader" }, + { 0, "hf 15 restore" }, + { 0, "hf 15 samples" }, + { 0, "hf 15 eload" }, + { 0, "hf 15 esave" }, + { 0, "hf 15 eview" }, + { 0, "hf 15 sim" }, + { 0, "hf 15 slixwritepwd" }, + { 0, "hf 15 slixeasdisable" }, + { 0, "hf 15 slixeasenable" }, + { 0, "hf 15 slixprivacydisable" }, + { 0, "hf 15 slixprivacyenable" }, + { 0, "hf 15 passprotectafi" }, + { 0, "hf 15 passprotecteas" }, + { 0, "hf 15 wrbl" }, + { 0, "hf 15 findafi" }, + { 0, "hf 15 writeafi" }, + { 0, "hf 15 writedsfid" }, + { 0, "hf 15 csetuid" }, + { 1, "hf cipurse help" }, + { 0, "hf cipurse info" }, + { 0, "hf cipurse select" }, + { 0, "hf cipurse auth" }, + { 0, "hf cipurse read" }, + { 0, "hf cipurse write" }, + { 0, "hf cipurse aread" }, + { 0, "hf cipurse awrite" }, + { 0, "hf cipurse formatall" }, + { 0, "hf cipurse create" }, + { 0, "hf cipurse delete" }, + { 0, "hf cipurse updkey" }, + { 0, "hf cipurse updakey" }, + { 0, "hf cipurse default" }, + { 1, "hf cipurse test" }, + { 1, "hf epa help" }, + { 0, "hf epa cnonces" }, + { 0, "hf epa replay" }, + { 0, "hf epa sim" }, + { 1, "hf emrtd help" }, + { 0, "hf emrtd dump" }, + { 1, "hf emrtd info" }, + { 1, "hf emrtd list" }, + { 1, "hf felica help" }, + { 1, "hf felica list" }, + { 0, "hf felica reader" }, + { 0, "hf felica info" }, + { 0, "hf felica sniff" }, + { 0, "hf felica raw" }, + { 0, "hf felica rdbl" }, + { 0, "hf felica wrbl" }, + { 0, "hf felica rqservice" }, + { 0, "hf felica rqresponse" }, + { 0, "hf felica scsvcode" }, + { 0, "hf felica rqsyscode" }, + { 0, "hf felica auth1" }, + { 0, "hf felica auth2" }, + { 0, "hf felica rqspecver" }, + { 0, "hf felica resetmode" }, + { 0, "hf felica litesim" }, + { 0, "hf felica litedump" }, + { 1, "hf fido help" }, + { 1, "hf fido list" }, + { 0, "hf fido info" }, + { 0, "hf fido reg" }, + { 0, "hf fido auth" }, + { 0, "hf fido make" }, + { 0, "hf fido assert" }, + { 1, "hf fudan help" }, + { 0, "hf fudan reader" }, + { 0, "hf fudan dump" }, + { 0, "hf fudan rdbl" }, + { 1, "hf fudan view" }, + { 0, "hf fudan wrbl" }, + { 1, "hf gallagher help" }, + { 0, "hf gallagher reader" }, + { 0, "hf gallagher clone" }, + { 0, "hf gallagher delete" }, + { 1, "hf gallagher diversifykey" }, + { 1, "hf gallagher decode" }, + { 1, "hf ksx6924 help" }, + { 0, "hf ksx6924 select" }, + { 0, "hf ksx6924 info" }, + { 0, "hf ksx6924 balance" }, + { 0, "hf ksx6924 init" }, + { 0, "hf ksx6924 prec" }, + { 1, "hf jooki help" }, + { 0, "hf jooki clone" }, + { 1, "hf jooki decode" }, + { 1, "hf jooki encode" }, + { 0, "hf jooki sim" }, + { 1, "hf iclass help" }, + { 0, "hf iclass dump" }, + { 1, "hf iclass info" }, + { 1, "hf iclass list" }, + { 0, "hf iclass rdbl" }, + { 0, "hf iclass reader" }, + { 0, "hf iclass restore" }, + { 0, "hf iclass sniff" }, + { 0, "hf iclass wrbl" }, + { 0, "hf iclass chk" }, + { 1, "hf iclass loclass" }, + { 1, "hf iclass lookup" }, + { 0, "hf iclass sim" }, + { 0, "hf iclass eload" }, + { 0, "hf iclass esave" }, + { 0, "hf iclass eview" }, + { 1, "hf iclass configcard" }, + { 1, "hf iclass calcnewkey" }, + { 1, "hf iclass encode" }, + { 1, "hf iclass encrypt" }, + { 1, "hf iclass decrypt" }, + { 1, "hf iclass managekeys" }, + { 1, "hf iclass permutekey" }, + { 1, "hf iclass view" }, + { 1, "hf legic help" }, + { 0, "hf legic dump" }, + { 0, "hf legic info" }, + { 1, "hf legic list" }, + { 0, "hf legic rdbl" }, + { 0, "hf legic reader" }, + { 0, "hf legic restore" }, + { 0, "hf legic wipe" }, + { 0, "hf legic wrbl" }, + { 0, "hf legic sim" }, + { 0, "hf legic eload" }, + { 0, "hf legic esave" }, + { 0, "hf legic eview" }, + { 0, "hf legic einfo" }, + { 1, "hf legic crc" }, + { 1, "hf legic view" }, + { 1, "hf lto help" }, + { 0, "hf lto dump" }, + { 0, "hf lto info" }, + { 1, "hf lto list" }, + { 0, "hf lto rdbl" }, + { 0, "hf lto reader" }, + { 0, "hf lto restore" }, + { 0, "hf lto wrbl" }, + { 1, "hf mf help" }, + { 1, "hf mf list" }, + { 0, "hf mf darkside" }, + { 0, "hf mf nested" }, + { 1, "hf mf hardnested" }, + { 0, "hf mf staticnested" }, + { 0, "hf mf autopwn" }, + { 0, "hf mf nack" }, + { 0, "hf mf chk" }, + { 0, "hf mf fchk" }, + { 1, "hf mf decrypt" }, + { 0, "hf mf supercard" }, + { 0, "hf mf auth4" }, + { 1, "hf mf acl" }, + { 0, "hf mf dump" }, + { 1, "hf mf mad" }, + { 0, "hf mf personalize" }, + { 0, "hf mf rdbl" }, + { 0, "hf mf rdsc" }, + { 0, "hf mf restore" }, + { 0, "hf mf setmod" }, + { 1, "hf mf value" }, + { 1, "hf mf view" }, + { 0, "hf mf wipe" }, + { 0, "hf mf wrbl" }, + { 0, "hf mf sim" }, + { 0, "hf mf ecfill" }, + { 0, "hf mf eclr" }, + { 0, "hf mf egetblk" }, + { 0, "hf mf egetsc" }, + { 0, "hf mf ekeyprn" }, + { 0, "hf mf eload" }, + { 0, "hf mf esave" }, + { 0, "hf mf esetblk" }, + { 0, "hf mf eview" }, + { 0, "hf mf cgetblk" }, + { 0, "hf mf cgetsc" }, + { 0, "hf mf cload" }, + { 0, "hf mf csave" }, + { 0, "hf mf csetblk" }, + { 0, "hf mf csetuid" }, + { 0, "hf mf cview" }, + { 0, "hf mf cwipe" }, + { 0, "hf mf gen3uid" }, + { 0, "hf mf gen3blk" }, + { 0, "hf mf gen3freeze" }, + { 0, "hf mf ggetblk" }, + { 0, "hf mf gload" }, + { 0, "hf mf gsave" }, + { 0, "hf mf gsetblk" }, + { 0, "hf mf gview" }, + { 0, "hf mf gdmconfig" }, + { 0, "hf mf gdmsetblk" }, + { 0, "hf mf ndefformat" }, + { 0, "hf mf ndefread" }, + { 0, "hf mf ndefwrite" }, + { 1, "hf mfp help" }, + { 0, "hf mfp info" }, + { 0, "hf mfp wrp" }, + { 0, "hf mfp initp" }, + { 0, "hf mfp commitp" }, + { 0, "hf mfp auth" }, + { 0, "hf mfp rdbl" }, + { 0, "hf mfp rdsc" }, + { 0, "hf mfp wrbl" }, + { 0, "hf mfp chk" }, + { 0, "hf mfp mad" }, + { 0, "hf mfp ndefread" }, + { 1, "hf mfu help" }, + { 1, "hf mfu keygen" }, + { 1, "hf mfu pwdgen" }, + { 0, "hf mfu otptear" }, + { 0, "hf mfu cauth" }, + { 0, "hf mfu dump" }, + { 0, "hf mfu info" }, + { 0, "hf mfu ndefread" }, + { 0, "hf mfu rdbl" }, + { 0, "hf mfu restore" }, + { 1, "hf mfu view" }, + { 0, "hf mfu wrbl" }, + { 0, "hf mfu tamper" }, + { 0, "hf mfu eload" }, + { 0, "hf mfu esave" }, + { 0, "hf mfu eview" }, + { 0, "hf mfu sim" }, + { 0, "hf mfu setpwd" }, + { 0, "hf mfu setuid" }, + { 1, "hf mfdes help" }, + { 0, "hf mfdes info" }, + { 0, "hf mfdes getuid" }, + { 0, "hf mfdes default" }, + { 0, "hf mfdes auth" }, + { 0, "hf mfdes chk" }, + { 0, "hf mfdes detect" }, + { 0, "hf mfdes freemem" }, + { 0, "hf mfdes setconfig" }, + { 0, "hf mfdes formatpicc" }, + { 1, "hf mfdes list" }, + { 0, "hf mfdes mad" }, + { 0, "hf mfdes lsapp" }, + { 0, "hf mfdes getaids" }, + { 0, "hf mfdes getappnames" }, + { 0, "hf mfdes bruteaid" }, + { 0, "hf mfdes createapp" }, + { 0, "hf mfdes deleteapp" }, + { 0, "hf mfdes selectapp" }, + { 0, "hf mfdes changekey" }, + { 0, "hf mfdes chkeysettings" }, + { 0, "hf mfdes getkeysettings" }, + { 0, "hf mfdes getkeyversions" }, + { 0, "hf mfdes getfileids" }, + { 0, "hf mfdes getfileisoids" }, + { 0, "hf mfdes lsfiles" }, + { 0, "hf mfdes dump" }, + { 0, "hf mfdes createfile" }, + { 0, "hf mfdes createvaluefile" }, + { 0, "hf mfdes createrecordfile" }, + { 0, "hf mfdes createmacfile" }, + { 0, "hf mfdes deletefile" }, + { 0, "hf mfdes getfilesettings" }, + { 0, "hf mfdes chfilesettings" }, + { 0, "hf mfdes read" }, + { 0, "hf mfdes write" }, + { 0, "hf mfdes value" }, + { 0, "hf mfdes clearrecfile" }, + { 1, "hf mfdes test" }, + { 1, "hf ntag424 help" }, + { 0, "hf ntag424 info" }, + { 0, "hf ntag424 sdm" }, + { 1, "hf ntag424 view" }, + { 1, "hf seos help" }, + { 0, "hf seos info" }, + { 1, "hf seos list" }, + { 1, "hf st25ta help" }, + { 0, "hf st25ta info" }, + { 1, "hf st25ta list" }, + { 1, "hf st25ta ndefread" }, + { 0, "hf st25ta protect" }, + { 0, "hf st25ta pwd" }, + { 0, "hf st25ta sim" }, + { 1, "hf tesla help" }, + { 0, "hf tesla info" }, + { 1, "hf tesla list" }, + { 1, "hf texkom help" }, + { 0, "hf texkom reader" }, + { 0, "hf texkom sim" }, + { 1, "hf thinfilm help" }, + { 0, "hf thinfilm info" }, + { 1, "hf thinfilm list" }, + { 0, "hf thinfilm sim" }, + { 1, "hf topaz help" }, + { 0, "hf topaz dump" }, + { 1, "hf topaz list" }, + { 0, "hf topaz info" }, + { 0, "hf topaz reader" }, + { 0, "hf topaz sim" }, + { 0, "hf topaz sniff" }, + { 0, "hf topaz raw" }, + { 0, "hf topaz rdbl" }, + { 1, "hf topaz view" }, + { 0, "hf topaz wrbl" }, + { 1, "hf xerox help" }, + { 0, "hf xerox info" }, + { 0, "hf xerox reader" }, + { 0, "hf xerox dump" }, + { 1, "hf waveshare help" }, + { 0, "hf waveshare loadbmp" }, + { 1, "hw help" }, + { 0, "hw break" }, + { 1, "hw connect" }, + { 0, "hw dbg" }, + { 0, "hw detectreader" }, + { 0, "hw fpgaoff" }, + { 0, "hw lcd" }, + { 0, "hw lcdreset" }, + { 0, "hw ping" }, + { 0, "hw readmem" }, + { 0, "hw reset" }, + { 0, "hw setlfdivisor" }, + { 0, "hw setmux" }, + { 0, "hw standalone" }, + { 0, "hw status" }, + { 0, "hw tearoff" }, + { 0, "hw tia" }, + { 0, "hw tune" }, + { 1, "hw version" }, + { 1, "lf help" }, + { 0, "lf config" }, + { 0, "lf cmdread" }, + { 0, "lf read" }, + { 1, "lf search" }, + { 0, "lf sim" }, + { 0, "lf simask" }, + { 0, "lf simfsk" }, + { 0, "lf simpsk" }, + { 0, "lf simbidir" }, + { 0, "lf sniff" }, + { 0, "lf tune" }, + { 1, "lf awid help" }, + { 1, "lf awid demod" }, + { 0, "lf awid reader" }, + { 0, "lf awid clone" }, + { 0, "lf awid sim" }, + { 0, "lf awid brute" }, + { 0, "lf awid watch" }, + { 1, "lf cotag help" }, + { 1, "lf cotag demod" }, + { 0, "lf cotag reader" }, + { 1, "lf destron help" }, + { 1, "lf destron demod" }, + { 0, "lf destron reader" }, + { 0, "lf destron clone" }, + { 0, "lf destron sim" }, + { 1, "lf em help" }, + { 1, "lf em 410x help" }, + { 1, "lf em 410x demod" }, + { 0, "lf em 410x reader" }, + { 0, "lf em 410x sim" }, + { 0, "lf em 410x brute" }, + { 0, "lf em 410x watch" }, + { 0, "lf em 410x spoof" }, + { 0, "lf em 410x clone" }, + { 1, "lf em 4x05 help" }, + { 0, "lf em 4x05 brute" }, + { 0, "lf em 4x05 chk" }, + { 1, "lf em 4x05 demod" }, + { 0, "lf em 4x05 dump" }, + { 0, "lf em 4x05 info" }, + { 0, "lf em 4x05 read" }, + { 1, "lf em 4x05 sniff" }, + { 0, "lf em 4x05 unlock" }, + { 0, "lf em 4x05 wipe" }, + { 0, "lf em 4x05 write" }, + { 1, "lf em 4x50 help" }, + { 0, "lf em 4x50 brute" }, + { 0, "lf em 4x50 chk" }, + { 0, "lf em 4x50 dump" }, + { 0, "lf em 4x50 info" }, + { 0, "lf em 4x50 login" }, + { 0, "lf em 4x50 rdbl" }, + { 0, "lf em 4x50 reader" }, + { 0, "lf em 4x50 restore" }, + { 0, "lf em 4x50 wrbl" }, + { 0, "lf em 4x50 wrpwd" }, + { 0, "lf em 4x50 wipe" }, + { 0, "lf em 4x50 eload" }, + { 0, "lf em 4x50 esave" }, + { 0, "lf em 4x50 eview" }, + { 0, "lf em 4x50 sim" }, + { 1, "lf em 4x70 help" }, + { 0, "lf em 4x70 brute" }, + { 0, "lf em 4x70 info" }, + { 0, "lf em 4x70 write" }, + { 0, "lf em 4x70 unlock" }, + { 0, "lf em 4x70 auth" }, + { 0, "lf em 4x70 writepin" }, + { 0, "lf em 4x70 writekey" }, + { 1, "lf fdxb help" }, + { 1, "lf fdxb demod" }, + { 0, "lf fdxb reader" }, + { 0, "lf fdxb clone" }, + { 0, "lf fdxb sim" }, + { 1, "lf gallagher help" }, + { 1, "lf gallagher demod" }, + { 0, "lf gallagher reader" }, + { 0, "lf gallagher clone" }, + { 0, "lf gallagher sim" }, + { 1, "lf gproxii help" }, + { 1, "lf gproxii demod" }, + { 0, "lf gproxii reader" }, + { 0, "lf gproxii clone" }, + { 0, "lf gproxii sim" }, + { 1, "lf hid help" }, + { 1, "lf hid demod" }, + { 0, "lf hid reader" }, + { 0, "lf hid clone" }, + { 0, "lf hid sim" }, + { 0, "lf hid brute" }, + { 0, "lf hid watch" }, + { 1, "lf hitag help" }, + { 0, "lf hitag eload" }, + { 1, "lf hitag list" }, + { 0, "lf hitag info" }, + { 0, "lf hitag reader" }, + { 0, "lf hitag sim" }, + { 0, "lf hitag sniff" }, + { 0, "lf hitag writer" }, + { 0, "lf hitag dump" }, + { 0, "lf hitag cc" }, + { 1, "lf idteck help" }, + { 1, "lf idteck demod" }, + { 0, "lf idteck reader" }, + { 0, "lf idteck clone" }, + { 0, "lf idteck sim" }, + { 1, "lf indala help" }, + { 0, "lf indala brute" }, + { 1, "lf indala demod" }, + { 1, "lf indala altdemod" }, + { 0, "lf indala reader" }, + { 0, "lf indala clone" }, + { 0, "lf indala sim" }, + { 1, "lf io help" }, + { 1, "lf io demod" }, + { 0, "lf io reader" }, + { 0, "lf io clone" }, + { 0, "lf io sim" }, + { 0, "lf io watch" }, + { 1, "lf jablotron help" }, + { 1, "lf jablotron demod" }, + { 0, "lf jablotron reader" }, + { 0, "lf jablotron clone" }, + { 0, "lf jablotron sim" }, + { 1, "lf keri help" }, + { 1, "lf keri demod" }, + { 0, "lf keri reader" }, + { 0, "lf keri clone" }, + { 0, "lf keri sim" }, + { 1, "lf motorola help" }, + { 1, "lf motorola demod" }, + { 0, "lf motorola reader" }, + { 0, "lf motorola clone" }, + { 0, "lf motorola sim" }, + { 1, "lf nedap help" }, + { 1, "lf nedap demod" }, + { 0, "lf nedap reader" }, + { 0, "lf nedap clone" }, + { 0, "lf nedap sim" }, + { 1, "lf nexwatch help" }, + { 1, "lf nexwatch demod" }, + { 0, "lf nexwatch reader" }, + { 0, "lf nexwatch clone" }, + { 0, "lf nexwatch sim" }, + { 1, "lf noralsy help" }, + { 1, "lf noralsy demod" }, + { 0, "lf noralsy reader" }, + { 0, "lf noralsy clone" }, + { 0, "lf noralsy sim" }, + { 1, "lf pac help" }, + { 1, "lf pac demod" }, + { 0, "lf pac reader" }, + { 0, "lf pac clone" }, + { 0, "lf pac sim" }, + { 1, "lf paradox help" }, + { 1, "lf paradox demod" }, + { 0, "lf paradox reader" }, + { 0, "lf paradox clone" }, + { 0, "lf paradox sim" }, + { 1, "lf pcf7931 help" }, + { 0, "lf pcf7931 reader" }, + { 0, "lf pcf7931 write" }, + { 1, "lf pcf7931 config" }, + { 1, "lf presco help" }, + { 1, "lf presco demod" }, + { 0, "lf presco reader" }, + { 0, "lf presco clone" }, + { 0, "lf presco sim" }, + { 1, "lf pyramid help" }, + { 1, "lf pyramid demod" }, + { 0, "lf pyramid reader" }, + { 0, "lf pyramid clone" }, + { 0, "lf pyramid sim" }, + { 1, "lf securakey help" }, + { 1, "lf securakey demod" }, + { 0, "lf securakey reader" }, + { 0, "lf securakey clone" }, + { 0, "lf securakey sim" }, + { 1, "lf ti help" }, + { 1, "lf ti demod" }, + { 0, "lf ti reader" }, + { 0, "lf ti write" }, + { 1, "lf t55xx help" }, + { 0, "lf t55xx clonehelp" }, + { 1, "lf t55xx config" }, + { 0, "lf t55xx dangerraw" }, + { 1, "lf t55xx detect" }, + { 0, "lf t55xx deviceconfig" }, + { 0, "lf t55xx dump" }, + { 1, "lf t55xx info" }, + { 0, "lf t55xx p1detect" }, + { 0, "lf t55xx read" }, + { 0, "lf t55xx resetread" }, + { 0, "lf t55xx restore" }, + { 1, "lf t55xx trace" }, + { 0, "lf t55xx wakeup" }, + { 0, "lf t55xx write" }, + { 0, "lf t55xx bruteforce" }, + { 0, "lf t55xx chk" }, + { 0, "lf t55xx protect" }, + { 0, "lf t55xx recoverpw" }, + { 1, "lf t55xx sniff" }, + { 0, "lf t55xx special" }, + { 0, "lf t55xx wipe" }, + { 1, "lf viking help" }, + { 1, "lf viking demod" }, + { 0, "lf viking reader" }, + { 0, "lf viking clone" }, + { 0, "lf viking sim" }, + { 1, "lf visa2000 help" }, + { 1, "lf visa2000 demod" }, + { 0, "lf visa2000 reader" }, + { 0, "lf visa2000 clone" }, + { 0, "lf visa2000 sim" }, + { 1, "mem help" }, + { 0, "mem baudrate" }, + { 0, "mem dump" }, + { 0, "mem info" }, + { 0, "mem load" }, + { 0, "mem wipe" }, + { 1, "mem spiffs help" }, + { 0, "mem spiffs copy" }, + { 0, "mem spiffs check" }, + { 0, "mem spiffs dump" }, + { 0, "mem spiffs info" }, + { 0, "mem spiffs mount" }, + { 0, "mem spiffs remove" }, + { 0, "mem spiffs rename" }, + { 0, "mem spiffs test" }, + { 0, "mem spiffs tree" }, + { 0, "mem spiffs unmount" }, + { 0, "mem spiffs upload" }, + { 0, "mem spiffs view" }, + { 0, "mem spiffs wipe" }, + { 1, "nfc help" }, + { 1, "nfc decode" }, + { 0, "nfc type1 read" }, + { 1, "nfc type1 help" }, + { 0, "nfc type2 read" }, + { 1, "nfc type2 help" }, + { 0, "nfc type4a format" }, + { 0, "nfc type4a read" }, + { 0, "nfc type4a write" }, + { 0, "nfc type4a st25taread" }, + { 1, "nfc type4a help" }, + { 0, "nfc type4b read" }, + { 1, "nfc type4b help" }, + { 0, "nfc mf cformat" }, + { 0, "nfc mf cread" }, + { 0, "nfc mf cwrite" }, + { 0, "nfc mf pread" }, + { 1, "nfc mf help" }, + { 0, "nfc barcode read" }, + { 0, "nfc barcode sim" }, + { 1, "nfc barcode help" }, + { 1, "piv help" }, + { 0, "piv select" }, + { 0, "piv getdata" }, + { 0, "piv authsign" }, + { 0, "piv scan" }, + { 1, "piv list" }, + { 1, "smart help" }, + { 1, "smart list" }, + { 0, "smart info" }, + { 0, "smart reader" }, + { 0, "smart raw" }, + { 1, "smart upgrade" }, + { 0, "smart setclock" }, + { 0, "smart brute" }, + { 1, "script help" }, + { 1, "script list" }, + { 1, "script run" }, + { 1, "trace help" }, + { 1, "trace extract" }, + { 1, "trace list" }, + { 1, "trace load" }, + { 1, "trace save" }, + { 1, "usart help" }, + { 0, "usart btpin" }, + { 0, "usart btfactory" }, + { 0, "usart tx" }, + { 0, "usart rx" }, + { 0, "usart txrx" }, + { 0, "usart txhex" }, + { 0, "usart rxhex" }, + { 0, "usart config" }, + { 1, "wiegand help" }, + { 1, "wiegand list" }, + { 1, "wiegand encode" }, + { 1, "wiegand decode" }, {0, NULL} }; @@ -790,4 +794,4 @@ const static vocabulory_t vocabulory[] = { } #endif -#endif +#endif \ No newline at end of file diff --git a/client/src/uart/uart_win32.c b/client/src/uart/uart_win32.c index cd610c8fa..9cdcc41d1 100644 --- a/client/src/uart/uart_win32.c +++ b/client/src/uart/uart_win32.c @@ -126,7 +126,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { struct addrinfo info; int iResult; - iResult = WSAStartup(MAKEWORD(2,2), &wsaData); + iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { PrintAndLogEx(ERR, "error: WSAStartup failed with error: %d", iResult); free(sp); @@ -231,7 +231,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { void uart_close(const serial_port sp) { serial_port_windows_t *spw = (serial_port_windows_t *)sp; - if (spw->hSocket != INVALID_SOCKET){ + if (spw->hSocket != INVALID_SOCKET) { shutdown(spw->hSocket, SD_BOTH); closesocket(spw->hSocket); WSACleanup(); @@ -294,8 +294,7 @@ int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uin } return PM3_ENOTTY; - } - else { // TCP + } else { // TCP uint32_t byteCount; // FIONREAD returns size on 32b fd_set rfds; struct timeval tv; @@ -332,12 +331,12 @@ int uart_receive(const serial_port sp, uint8_t *pbtRx, uint32_t pszMaxRxLen, uin // Retrieve the count of the incoming bytes res = ioctlsocket(spw->hSocket, FIONREAD, (u_long *)&byteCount); - // PrintAndLogEx(ERR, "UART:: RX ioctl res %d byteCount %u", res, byteCount); + // PrintAndLogEx(ERR, "UART:: RX ioctl res %d byteCount %u", res, byteCount); if (res == SOCKET_ERROR) return PM3_ENOTTY; // Cap the number of bytes, so we don't overrun the buffer if (pszMaxRxLen - (*pszRxLen) < byteCount) { - // PrintAndLogEx(ERR, "UART:: RX prevent overrun (have %u, need %u)", pszMaxRxLen - (*pszRxLen), byteCount); + // PrintAndLogEx(ERR, "UART:: RX prevent overrun (have %u, need %u)", pszMaxRxLen - (*pszRxLen), byteCount); byteCount = pszMaxRxLen - (*pszRxLen); } @@ -374,8 +373,7 @@ int uart_send(const serial_port sp, const uint8_t *p_tx, const uint32_t len) { return PM3_EIO; } return PM3_ENOTTY; - } - else { // TCP + } else { // TCP uint32_t pos = 0; fd_set wfds; struct timeval tv; diff --git a/common/commonutil.c b/common/commonutil.c index c346d7bf7..4af16b3c0 100644 --- a/common/commonutil.c +++ b/common/commonutil.c @@ -280,7 +280,7 @@ void reverse_array(uint8_t *d, size_t n) { d[i] ^= d[j]; d[j] ^= d[i]; d[i] ^= d[j]; - } + } } // reverse src array into dest array @@ -292,4 +292,4 @@ void reverse_array_copy(const uint8_t *src, int src_len, uint8_t *dest) { for (int i = 0; i < src_len; i++) { dest[i] = src[(src_len - 1) - i]; } -} \ No newline at end of file +} diff --git a/doc/commands.json b/doc/commands.json index 636fdf50a..4ef1ec680 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -406,7 +406,7 @@ }, "data help": { "command": "data help", - "description": "help This help ----------- ------------------------- Modulation------------------------- biphaserawdecode Biphase decode bin stream in DemodBuffer detectclock Detect ASK, FSK, NRZ, PSK clock rate of wave in GraphBuffer fsktonrz Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk) manrawdecode Manchester decode binary stream in DemodBuffer modulation Identify LF signal for clock and modulation rawdemod Demodulate the data in the GraphBuffer and output binary ----------- ------------------------- Graph------------------------- askedgedetect Adjust Graph for manual ASK demod using the length of sample differences to detect the edge of a wave autocorr Autocorrelation over window dirthreshold Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev. decimate Decimate samples undecimate Un-decimate samples hide Hide graph window hpf Remove DC offset from trace iir Apply IIR buttersworth filter on plot data grid overlay grid on graph window ltrim Trim samples from left of trace mtrim Trim out samples from the specified start to the specified stop norm Normalize max/min to +/-128 plot Show graph window rtrim Trim samples from right of trace setgraphmarkers Set blue and orange marker in graph window shiftgraphzero Shift 0 for Graphed wave + or - shift value timescale Set a timescale to get a differential reading between the yellow and purple markers as time duration zerocrossings Count time between zero-crossings convertbitstream Convert GraphBuffer's 0/1 values to 127 / -127 getbitstream Convert GraphBuffer's >=1 values to 1 and <1 to 0 ----------- ------------------------- General------------------------- asn1 asn1 decoder bin2hex Converts binary to hexadecimal clear Clears bigbuf on deviceside and graph window diff diff of input files hex2bin Converts hexadecimal to binary load Load contents of file into graph window print Print the data in the DemodBuffer save Save signal trace data (from graph window) setdebugmode Set Debugging Level on client side", + "description": "help This help ----------- ------------------------- Modulation------------------------- biphaserawdecode Biphase decode bin stream in DemodBuffer detectclock Detect ASK, FSK, NRZ, PSK clock rate of wave in GraphBuffer fsktonrz Convert fsk2 to nrz wave for alternate fsk demodulating (for weak fsk) manrawdecode Manchester decode binary stream in DemodBuffer modulation Identify LF signal for clock and modulation rawdemod Demodulate the data in the GraphBuffer and output binary ----------- ------------------------- Graph------------------------- askedgedetect Adjust Graph for manual ASK demod using the length of sample differences to detect the edge of a wave autocorr Autocorrelation over window dirthreshold Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev. decimate Decimate samples undecimate Un-decimate samples hide Hide graph window hpf Remove DC offset from trace iir Apply IIR buttersworth filter on plot data grid overlay grid on graph window ltrim Trim samples from left of trace mtrim Trim out samples from the specified start to the specified stop norm Normalize max/min to +/-128 plot Show graph window rtrim Trim samples from right of trace setgraphmarkers Set blue and orange marker in graph window shiftgraphzero Shift 0 for Graphed wave + or - shift value timescale Set a timescale to get a differential reading between the yellow and purple markers as time duration zerocrossings Count time between zero-crossings convertbitstream Convert GraphBuffer's 0/1 values to 127 / -127 getbitstream Convert GraphBuffer's >=1 values to 1 and <1 to 0 ----------- ------------------------- General------------------------- asn1 asn1 decoder bin2hex Converts binary to hexadecimal clear Clears bigbuf on deviceside and graph window diff diff of input files hex2bin Converts hexadecimal to binary load Load contents of file into graph window num Converts dec/hex/bin print Print the data in the DemodBuffer save Save signal trace data (from graph window) setdebugmode Set Debugging Level on client side", "notes": [], "offline": true, "options": [], @@ -557,6 +557,23 @@ ], "usage": "data norm [-h]" }, + "data num": { + "command": "data num", + "description": "Function takes a decimal or hexdecimal number and print it in decimal/hex/binary Will print message if number is a prime number", + "notes": [ + "data num --dec 2023", + "data num --hex 0x1000" + ], + "offline": true, + "options": [ + "-h, --help This help", + "--dec decimal value", + "--hex hexadecimal value", + "--bin binary value", + "-i print inverted value" + ], + "usage": "data num [-hi] [--dec ] [--hex ] [--bin ]" + }, "data plot": { "command": "data plot", "description": "Show graph window hit 'h' in window for detail keystroke help available", @@ -3597,6 +3614,18 @@ ], "usage": "hf legic dump [-h] [-f ] [--de]" }, + "hf legic einfo": { + "command": "hf legic einfo", + "description": "It decodes and displays emulator memory", + "notes": [ + "hf legic einfo" + ], + "offline": false, + "options": [ + "-h, --help This help" + ], + "usage": "hf legic einfo [-h]" + }, "hf legic eload": { "command": "hf legic eload", "description": "Loads a LEGIC Prime dump file into emulator memory", @@ -3649,7 +3678,7 @@ }, "hf legic help": { "command": "hf legic help", - "description": "----------- --------------------- operations --------------------- help This help list List LEGIC history ----------- --------------------- simulation --------------------- ----------- --------------------- utils --------------------- crc Calculate Legic CRC over given bytes view Display content from tag dump file", + "description": "----------- --------------------- operations --------------------- help This help list List LEGIC history ----------- --------------------- simulation --------------------- ----------- --------------------- utils --------------------- crc Calculate Legic CRC over given bytes view Display deobfuscated and decoded content from tag dump file", "notes": [], "offline": true, "options": [], @@ -4371,6 +4400,37 @@ ], "usage": "hf mf fchk [-h] [-k ]... [--mini] [--1k] [--2k] [--4k] [--emu] [--dump] [--mem] [-f ]" }, + "hf mf gdmconfig": { + "command": "hf mf gdmconfig", + "description": "Get configuration data from magic gen4 GDM card.", + "notes": [ + "hf mf gdmconfig" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-k, --key key 6 bytes" + ], + "usage": "hf mf gdmconfig [-h] [-k ]" + }, + "hf mf gdmsetblk": { + "command": "hf mf gdmsetblk", + "description": "Set block data on a magic gen4 GDM card `--force` param is used to override warnings like bad ACL writes. if not specified, it will exit if detected", + "notes": [ + "hf mf gdmsetblk --blk 1 -d 000102030405060708090a0b0c0d0e0f" + ], + "offline": false, + "options": [ + "-h, --help This help", + "--blk block number", + "-a input key type is key A (def)", + "-b input key type is key B", + "-d, --data bytes to write, 16 hex bytes", + "-k, --key key, 6 hex bytes", + "--force override warnings" + ], + "usage": "hf mf gdmsetblk [-hab] --blk [-d ] [-k ] [--force]" + }, "hf mf gen3blk": { "command": "hf mf gen3blk", "description": "Overwrite full manufacturer block for magic Gen3 card - You can specify part of manufacturer block as 4/7-bytes for UID change only", @@ -4822,15 +4882,17 @@ "command": "hf mf supercard", "description": "Extract info from a `super card`", "notes": [ - "hf mf supercard" + "hf mf supercard -> recover key", + "hf mf supercard -r -> reset card", + "hf mf supercard -u 11223344 -> change UID" ], "offline": false, "options": [ "-h, --help This help", - "-r, --reset Reset card", - "-u, --uid Change UID" + "-r, --reset reset card", + "-u, --uid New UID (4 hex bytes)" ], - "usage": "hf mf supercard [-hru]" + "usage": "hf mf supercard [-hr] [-u ]" }, "hf mf value": { "command": "hf mf value", @@ -4958,7 +5020,7 @@ "but for APP keys crypto algorithm is set by createapp command and can't be changed wo application delete", "", "hf mfdes changekey --aid 123456 -> execute with default factory setup. change des key 0 in the app 123456 from 00..00 to 00..00", - "hf mfdes changekey --isoid df01 -t aes -s lrp --newkeyno 01 -> change key 01 via lrp channelhf mfdes changekey -t des --newalgo aes --newkey 11223344556677889900112233445566 --newver a5 -> change card master key to AES one", + "hf mfdes changekey --isoid df01 -t aes --schann lrp --newkeyno 01 -> change key 01 via lrp channelhf mfdes changekey -t des --newalgo aes --newkey 11223344556677889900112233445566 --newver a5 -> change card master key to AES one", "hf mfdes changekey --aid 123456 -t aes --key 00000000000000000000000000000000 --newkey 11223344556677889900112233445566 -> change app master key", "hf mfdes changekey --aid 123456 -t des -n 0 --newkeyno 1 --oldkey 5555555555555555 --newkey 1122334455667788 -> change key 1 with auth from key 0", "hf mfdes changekey --aid 123456 -t 3tdea --newkey 112233445566778899001122334455667788990011223344 -> change 3tdea key 0 from default 00..00 to provided" @@ -4994,7 +5056,7 @@ "hf mfdes chfilesettings --aid 123456 --fid 01 --amode plain --rrights free --wrights free --rwrights free --chrights key0 -> change file settings app=123456, file=01 with defaults from `default` command", "hf mfdes chfilesettings -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 --rawdata 00EEEE -> execute with default factory setup", "hf mfdes chfilesettings --aid 123456 --fid 01 --rawdata 810000021f112f22 -> change file settings with additional rights for keys 1 and 2", - "hf mfdes chfilesettings --isoid df01 --fid 00 --amode plain --rawrights eee0 -s lrp -t aes -> change file settings via lrp channel" + "hf mfdes chfilesettings --isoid df01 --fid 00 --amode plain --rawrights eee0 --schann lrp -t aes -> change file settings via lrp channel" ], "offline": false, "options": [ @@ -5080,7 +5142,7 @@ "description": "Clear record file. Master key needs to be provided or flag --no-auth set (depend on cards settings).", "notes": [ "hf mfdes clearrecfile --aid 123456 --fid 01 -> clear record file for: app=123456, file=01 with defaults from `default` command", - "hf mfdes clearrecfile --isoid df01 --fid 01 -s lrp -t aes -n 3 -> clear record file for lrp channel with key number 3" + "hf mfdes clearrecfile --isoid df01 --fid 01 --schann lrp -t aes -n 3 -> clear record file for lrp channel with key number 3" ], "offline": false, "options": [ @@ -5218,8 +5280,8 @@ "hf mfdes createmacfile --aid 123456 --fid 01 --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file with parameters. Rights from default. Authentication with defaults from `default` command", "hf mfdes createmacfile --aid 123456 --fid 01 --amode plain --rrights free --wrights deny --rwrights free --chrights key0 --mackey 00112233445566778899aabbccddeeff -> create file app=123456, file=01, with key, and mentioned rights with defaults from `default` command", "hf mfdes createmacfile -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> execute with default factory setup. key and keyver == 0x00..00", - "hf mfdes createmacfile --isoid df01 --fid 0f -s lrp -t aes --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel", - "hf mfdes createmacfile --isoid df01 --fid 0f -s lrp -t aes --rawrights 0F10 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel with CommitReaderID command enable" + "hf mfdes createmacfile --isoid df01 --fid 0f --schann lrp -t aes --rawrights 0FF0 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel", + "hf mfdes createmacfile --isoid df01 --fid 0f --schann lrp -t aes --rawrights 0F10 --mackey 00112233445566778899aabbccddeeff --mackeyver 01 -> create transaction mac file via lrp channel with CommitReaderID command enable" ], "offline": false, "options": [ @@ -5375,7 +5437,7 @@ "description": "Delete file from application. Master key needs to be provided or flag --no-auth set (depend on cards settings).", "notes": [ "hf mfdes deletefile --aid 123456 --fid 01 -> delete file for: app=123456, file=01 with defaults from `default` command", - "hf mfdes deletefile --isoid df01 --fid 0f -s lrp -t aes -> delete file for lrp channel" + "hf mfdes deletefile --isoid df01 --fid 0f --schann lrp -t aes -> delete file for lrp channel" ], "offline": false, "options": [ @@ -5431,7 +5493,7 @@ "command": "hf mfdes dump", "description": "For each application show fil list and then file content. Key needs to be provided for authentication or flag --no-auth set (depend on cards settings).", "notes": [ - "hf mfdes dump --aid 123456 -> show file dump for: app=123456 with channel defaults from `default` command/nhf mfdes dump --isoid df01 -s lrp -t aes --length 000090 -> lrp default settings with length limit" + "hf mfdes dump --aid 123456 -> show file dump for: app=123456 with channel defaults from `default` command/nhf mfdes dump --isoid df01 --schann lrp -t aes --length 000090 -> lrp default settings with length limit" ], "offline": false, "options": [ @@ -5578,7 +5640,7 @@ "hf mfdes getfileisoids --aid 123456 -> execute with defaults from `default` command", "hf mfdes getfileisoids -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 -> execute with default factory setup", "hf mfdes getfileisoids --isoid df01 -> get iso file ids from Desfire Light with factory card settings", - "hf mfdes getfileisoids --isoid df01 -s lrp -t aes -> get iso file ids from Desfire Light via lrp channel with default key authentication" + "hf mfdes getfileisoids --isoid df01 --schann lrp -t aes -> get iso file ids from Desfire Light via lrp channel with default key authentication" ], "offline": false, "options": [ @@ -5686,7 +5748,7 @@ "description": "Get UID from card. Get the real UID if the random UID bit is on and get the same UID as in anticollision if not. Any card's key needs to be provided.", "notes": [ "hf mfdes getuid -> execute with default factory setup", - "hf mfdes getuid --isoid df01 -t aes -s lrp -> for desfire lights default settings" + "hf mfdes getuid --isoid df01 -t aes --schan lrp -> for desfire lights default settings" ], "offline": false, "options": [ @@ -5843,8 +5905,8 @@ "hf mfdes read --isoid 0102 --fileisoid 1000 --type data -c iso -> read file via ISO channel: app iso id=0102, iso id=1000, offset=0. Select via ISO commands", "hf mfdes read --isoid 0102 --fileisoid 1100 --type record -c iso --offset 000005 --length 000001 -> get one record (number 5) from file 1100 via iso commands", "hf mfdes read --isoid 0102 --fileisoid 1100 --type record -c iso --offset 000005 --length 000000 -> get all record (from 5 to 1) from file 1100 via iso commands", - "hf mfdes read --isoid df01 --fid 00 -s lrp -t aes --length 000010 -> read via lrp channel", - "hf mfdes read --isoid df01 --fid 00 -s ev2 -t aes --length 000010 --isochain -> read Desfire Light via ev2 channel" + "hf mfdes read --isoid df01 --fid 00 --schann lrp -t aes --length 000010 -> read via lrp channel", + "hf mfdes read --isoid df01 --fid 00 --schann ev2 -t aes --length 000010 --isochain -> read Desfire Light via ev2 channel" ], "offline": false, "options": [ @@ -5922,9 +5984,9 @@ "", "hf mfdes setconfig --param 03 --data 0428 -> set SAK", "hf mfdes setconfig --param 02 --data 0875778102637264 -> set ATS (first byte - length)", - "hf mfdes setconfig --isoid df01 -t aes -s ev2 --param 05 --data 00000000020000000000 -> set LRP mode enable for Desfire Light", - "hf mfdes setconfig --isoid df01 -t aes -s ev2 --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light", - "hf mfdes setconfig --isoid df01 -t aes -s lrp --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light via lrp" + "hf mfdes setconfig --isoid df01 -t aes --schann ev2 --param 05 --data 00000000020000000000 -> set LRP mode enable for Desfire Light", + "hf mfdes setconfig --isoid df01 -t aes --schann ev2 --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light", + "hf mfdes setconfig --isoid df01 -t aes --schann lrp --param 0a --data 00ffffffff -> Disable failed auth counters for Desfire Light via lrp" ], "offline": false, "options": [ @@ -5965,8 +6027,8 @@ "hf mfdes value --aid 123456 --fid 01 -> get value app=123456, file=01 with defaults from `default` command", "hf mfdes value --aid 123456 --fid 01 --op credit -d 00000001 -> credit value app=123456, file=01 with defaults from `default` command", "hf mfdes value -n 0 -t des -k 0000000000000000 --kdf none --aid 123456 --fid 01 -> get value with default factory setup", - "hf mfdes val --isoid df01 --fid 03 -s lrp -t aes -n 1 --op credit --d 00000001 -m encrypt -> credit value in the lrp encrypted mode", - "hf mfdes val --isoid df01 --fid 03 -s lrp -t aes -n 1 --op get -m plain -> get value in plain (nevertheless of mode) works for desfire light (look SetConfiguration option 0x09)" + "hf mfdes val --isoid df01 --fid 03 --schann lrp -t aes -n 1 --op credit --d 00000001 -m encrypt -> credit value in the lrp encrypted mode", + "hf mfdes val --isoid df01 --fid 03 --schann lrp -t aes -n 1 --op get -m plain -> get value in plain (nevertheless of mode) works for desfire light (look SetConfiguration option 0x09)" ], "offline": false, "options": [ @@ -6008,7 +6070,7 @@ "hf mfdes write --isoid 1234 --fileisoid 1000 --type data -c iso -d 01020304 -> write data to std/backup file via iso commandset", "hf mfdes write --isoid 1234 --fileisoid 2000 --type record -c iso -d 01020304 -> send record to record file via iso commandset", "hf mfdes write --aid 123456 --fid 01 -d 01020304 --readerid 010203 -> write data to file with CommitReaderID command before write and CommitTransaction after write", - "hf mfdes write --isoid df01 --fid 04 -d 01020304 --trkey 00112233445566778899aabbccddeeff --readerid 5532 -t aes -s lrp -> advanced CommitReaderID via lrp channel sample" + "hf mfdes write --isoid df01 --fid 04 -d 01020304 --trkey 00112233445566778899aabbccddeeff --readerid 5532 -t aes --schann lrp -> advanced CommitReaderID via lrp channel sample" ], "offline": false, "options": [ @@ -6501,6 +6563,25 @@ ], "usage": "hf mfu sim [-hv] -t <1..10> [-u ] [-n ]" }, + "hf mfu tamper": { + "command": "hf mfu tamper", + "description": "Set the congiguration of the NTAG 213TT tamper feature Supports: NTAG 213TT", + "notes": [ + "hf mfu tamper -e -> enable tamper feature", + "hf mfu tamper -d -> disable tamper feature", + "hf mfu tamper -m 0A0A0A0A -> set the tamper message to 0A0A0A0A", + "hf mfu tamper --lockmessage -> permanently lock the tamper message and mask it from memory" + ], + "offline": false, + "options": [ + "-h, --help This help", + "-e, --enable Enable the tamper feature", + "-d, --disable Disable the tamper feature", + "-m, --message Set the tamper message (4 bytes)", + "--lockmessage Permanently lock the tamper message and mask it from memory (does not lock tamper feature itself)" + ], + "usage": "hf mfu tamper [-hed] [-m ] [--lockmessage]" + }, "hf mfu view": { "command": "hf mfu view", "description": "Print a MIFARE Ultralight/NTAG dump file (bin/eml/json)", @@ -8447,22 +8528,23 @@ }, "lf gproxii clone": { "command": "lf gproxii clone", - "description": "clone a Guardall tag to a T55x7, Q5/T5555 or EM4305/4469 tag. The facility-code is 8-bit and the card number is 20-bit. Larger values are truncated. Currently work only on 26 | 36 bit format", + "description": "Clone a Guardall tag to a T55x7, Q5/T5555 or EM4305/4469 tag. The facility-code is 8-bit and the card number is 20-bit. Larger values are truncated. Currently work only on 26 | 36 bit format", "notes": [ - "lf gproxii clone --fmt 26 --fc 123 --cn 1337 -> encode for T55x7 tag", - "lf gproxii clone --fmt 26 --fc 123 --cn 1337 --q5 -> encode for Q5/T5555 tag", - "lf gproxii clone --fmt 26 --fc 123 --cn 1337 --em -> encode for EM4305/4469" + "lf gproxii clone --xor 141 --fmt 26 --fc 123 --cn 1337 -> encode for T55x7 tag", + "lf gproxii clone --xor 141 --fmt 26 --fc 123 --cn 1337 --q5 -> encode for Q5/T5555 tag", + "lf gproxii clone --xor 141 --fmt 26 --fc 123 --cn 1337 --em -> encode for EM4305/4469" ], "offline": false, "options": [ "-h, --help This help", + "--xor 8-bit xor value (installation dependant)", "--fmt format length 26|32|36|40", "--fc 8-bit value facility code", "--cn 16-bit value card number", "--q5 optional - specify writing to Q5/T5555 tag", "--em optional - specify writing to EM4305/4469 tag" ], - "usage": "lf gproxii clone [-h] --fmt --fc --cn [--q5] [--em]" + "usage": "lf gproxii clone [-h] --xor --fmt --fc --cn [--q5] [--em]" }, "lf gproxii demod": { "command": "lf gproxii demod", @@ -8503,16 +8585,17 @@ "command": "lf gproxii sim", "description": "Enables simulation of Guardall card with specified card number. Simulation runs until the button is pressed or another USB command is issued. The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated. Currently work only on 26 | 36 bit format", "notes": [ - "lf gproxii sim --fmt 26 --fc 123 --cn 1337" + "lf gproxii sim --xor 141 --fmt 26 --fc 123 --cn 1337" ], "offline": false, "options": [ "-h, --help This help", + "--xor 8-bit xor value (installation dependant)", "--fmt format length 26|32|36|40", "--fc 8-bit value facility code", "--cn 16-bit value card number" ], - "usage": "lf gproxii sim [-h] --fmt --fc --cn " + "usage": "lf gproxii sim [-h] --xor --fmt --fc --cn " }, "lf help": { "command": "lf help", @@ -8524,27 +8607,28 @@ }, "lf hid brute": { "command": "lf hid brute", - "description": "Enables bruteforce of HID readers with specified facility code. This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step if cardnumber is not given, it starts with 1 and goes up to 65535", + "description": "Enables bruteforce of HID readers with specified facility code or card number. This is an attack against the reader. If the field being bruteforced is provided, it starts with it and goes up / down one step while maintaining other supplied values. If the field being bruteforced is not provided, it will iterate through the full range while maintaining other supplied values.", "notes": [ - "lf hid brute -w H10301 --fc 224", - "lf hid brute -w H10301 --fc 21 -d 2000", - "lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000", - "lf hid brute -v -w H10301 --fc 21 --cn 200 -d 2000 --up" + "lf hid brute -w H10301 --field fc --fc 224 --cn 6278", + "lf hid brute -w H10301 --field cn --fc 21 -d 2000", + "lf hid brute -v -w H10301 --field cn --fc 21 --cn 200 -d 2000", + "lf hid brute -v -w H10301 --field fc --fc 21 --cn 200 -d 2000 --up" ], "offline": false, "options": [ "-h, --help This help", "-v, --verbose verbose output", "-w, --wiegand see `wiegand list` for available formats", + "--field field to bruteforce", "--fc facility code", - "--cn card number to start with", + "--cn card number", "-i, --issue issue level", "-o, --oem OEM code", - "-d, --delay delay betweens attempts in ms. Default 1000ms", - "--up direction to increment card number. (default is both directions)", - "--down direction to decrement card number. (default is both directions)" + "-d, --delay delay betweens attempts in ms. (def is 1000)", + "--up direction to increment field value. (def is both directions)", + "--down direction to decrement field value. (def is both directions)" ], - "usage": "lf hid brute [-hv] -w [--fc ] [--cn ] [-i ] [-o ] [-d ] [--up] [--down]" + "usage": "lf hid brute [-hv] -w --field [--fc ] [--cn ] [-i ] [-o ] [-d ] [--up] [--down]" }, "lf hid clone": { "command": "lf hid clone", @@ -10816,7 +10900,7 @@ "command": "msleep", "description": "Sleep for given amount of milliseconds", "notes": [ - "msleep 100" + "msleep -t 100" ], "offline": true, "options": [ @@ -11903,8 +11987,8 @@ } }, "metadata": { - "commands_extracted": 749, + "commands_extracted": 754, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-02-18T20:20:19" + "extracted_on": "2023-03-26T13:11:48" } } \ No newline at end of file diff --git a/doc/commands.md b/doc/commands.md index 0dbad2544..487cea0c9 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -126,6 +126,7 @@ Check column "offline" for their availability. |`data hexsamples `|N |`Dump big buffer as hex bytes` |`data hex2bin `|Y |`Converts hexadecimal to binary` |`data load `|Y |`Load contents of file into graph window` +|`data num `|Y |`Converts dec/hex/bin` |`data print `|Y |`Print the data in the DemodBuffer` |`data samples `|N |`Get raw samples for graph window (GraphBuffer)` |`data save `|Y |`Save signal trace data (from graph window)` @@ -444,8 +445,9 @@ Check column "offline" for their availability. |`hf legic eload `|N |`Load binary dump to emulator memory` |`hf legic esave `|N |`Save emulator memory to binary file` |`hf legic eview `|N |`View emulator memory` +|`hf legic einfo `|N |`Display deobfuscated and decoded emulator memory` |`hf legic crc `|Y |`Calculate Legic CRC over given bytes` -|`hf legic view `|Y |`Display content from tag dump file` +|`hf legic view `|Y |`Display deobfuscated and decoded content from tag dump file` ### hf lto @@ -521,6 +523,8 @@ Check column "offline" for their availability. |`hf mf gsave `|N |`Save dump from card into file or emulator` |`hf mf gsetblk `|N |`Write block to card` |`hf mf gview `|N |`View card` +|`hf mf gdmconfig `|N |`Read config block from card` +|`hf mf gdmsetblk `|N |`Write block to card` |`hf mf ndefformat `|N |`Format MIFARE Classic Tag as NFC Tag` |`hf mf ndefread `|N |`Read and print NDEF records from card` |`hf mf ndefwrite `|N |`Write NDEF records to card` @@ -564,6 +568,7 @@ Check column "offline" for their availability. |`hf mfu restore `|N |`Restore a dump onto a MFU MAGIC tag` |`hf mfu view `|Y |`Display content from tag dump file` |`hf mfu wrbl `|N |`Write block` +|`hf mfu tamper `|N |`Cofigure the tamper feature on an NTAG 213TT` |`hf mfu eload `|N |`Load Ultralight dump file into emulator memory` |`hf mfu esave `|N |`Save Ultralight dump file from emulator memory` |`hf mfu eview `|N |`View emulator memory` @@ -952,7 +957,7 @@ Check column "offline" for their availability. |`lf hid reader `|N |`attempt to read and extract tag data` |`lf hid clone `|N |`clone HID tag to T55x7` |`lf hid sim `|N |`simulate HID tag` -|`lf hid brute `|N |`bruteforce card number against reader` +|`lf hid brute `|N |`bruteforce facility code or card number against reader` |`lf hid watch `|N |`continuously watch for cards. Reader mode` From fade240031e9711ca57a5f407de0159360a0a2ad Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Sun, 26 Mar 2023 16:16:03 +0300 Subject: [PATCH 738/759] Fix formatting and run make style --- client/src/cmdhfmf.c | 2 +- doc/commands.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 828666a57..7c8c7235f 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6589,7 +6589,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { void *argtable[] = { arg_param_begin, - arg_lit0("r", "reset", "reset card"), + arg_lit0("r", "reset", "Reset card"), arg_str0("u", "uid", "", "New UID (4 hex bytes)"), arg_param_end }; diff --git a/doc/commands.json b/doc/commands.json index 4ef1ec680..3a59e6f7c 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -11989,6 +11989,6 @@ "metadata": { "commands_extracted": 754, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-03-26T13:11:48" + "extracted_on": "2023-03-26T13:15:37" } } \ No newline at end of file From d434eeae60cd236ac8f4c24f68fde94cc34cc319 Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Sun, 26 Mar 2023 17:50:17 +0300 Subject: [PATCH 739/759] Supercard gen1/gen2 detection in MifareCIdent --- armsrc/mifarecmd.c | 42 +++++++++++++++++++++------------- client/src/mifare/mifarehost.c | 7 ++++-- doc/magic_cards_notes.md | 4 ++-- include/protocols.h | 11 +++++---- 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 9eb44da5a..cb5644fc8 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2481,11 +2481,13 @@ void MifareCIdent(bool is_mfc) { uint8_t isGen = 0; uint8_t rec[1] = {0x00}; uint8_t recpar[1] = {0x00}; - uint8_t rats[4] = { ISO14443A_CMD_RATS, 0x80, 0x31, 0x73 }; - uint8_t rdblf0[4] = { ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f}; - uint8_t rdbl00[4] = { ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8}; - uint8_t gen4gmd[4] = { MIFARE_MAGIC_GDM_AUTH_KEYA, 0x00, 0x6C, 0x92}; - uint8_t gen4GetConf[8] = { GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0}; + uint8_t rats[4] = {ISO14443A_CMD_RATS, 0x80, 0x31, 0x73}; + uint8_t rdblf0[4] = {ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f}; + uint8_t rdbl00[4] = {ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8}; + uint8_t gen4gmd[4] = {MIFARE_MAGIC_GDM_AUTH_KEYA, 0x00, 0x6C, 0x92}; + uint8_t gen4GetConf[8] = {GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0}; + uint8_t superGen1[9] = {0x0A, 0x00, 0x00, 0xA6, 0xB0, 0x00, 0x10, 0x14, 0x1D}; + uint8_t superGen2[4] = {0x30, 0x00, 0x02, 0xA8}; uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); uint8_t *uid = BigBuf_malloc(10); @@ -2518,8 +2520,7 @@ void MifareCIdent(bool is_mfc) { int res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { - - // Check for Magic Gen4 GTU with default password : + // Check for Magic Gen4 GTU with default password: // Get config should return 30 or 32 bytes AddCrc14A(gen4GetConf, sizeof(gen4GetConf) - 2); ReaderTransmit(gen4GetConf, sizeof(gen4GetConf), NULL); @@ -2537,7 +2538,6 @@ void MifareCIdent(bool is_mfc) { res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true); if (res == 2) { - if (cuid == 0xAA55C396) { isGen = MAGIC_GEN_UNFUSED; goto OUT; @@ -2546,19 +2546,29 @@ void MifareCIdent(bool is_mfc) { ReaderTransmit(rats, sizeof(rats), NULL); res = ReaderReceive(buf, par); if (res) { + // test for super card + ReaderTransmit(superGen1, sizeof(superGen1), NULL); + res = ReaderReceive(buf, par); + if (res == 22) { + isGen = MAGIC_SUPER_GEN1; - // test for some MFC gen2 - if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10\xF0\x05", 11) == 0) { + // check for super card gen2 + // not available after RATS, reset card before executing + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(40); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - // super card ident - uint8_t super[] = {0x0A, 0x00, 0x00, 0xA6, 0xB0, 0x00, 0x10, 0x14, 0x1D}; - ReaderTransmit(super, sizeof(super), NULL); + iso14443a_select_card(uid, NULL, &cuid, true, 0, true); + ReaderTransmit(superGen2, sizeof(superGen2), NULL); res = ReaderReceive(buf, par); - if (res == 22) { - isGen = MAGIC_SUPER; - goto OUT; + if (res == 18) { + isGen = MAGIC_SUPER_GEN2; } + goto OUT; + } + // test for some MFC gen2 + if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10\xF0\x05", 11) == 0) { isGen = MAGIC_GEN_2; goto OUT; } diff --git a/client/src/mifare/mifarehost.c b/client/src/mifare/mifarehost.c index d8390b3f5..70e601431 100644 --- a/client/src/mifare/mifarehost.c +++ b/client/src/mifare/mifarehost.c @@ -1421,8 +1421,11 @@ int detect_mf_magic(bool is_mfc) { case MAGIC_GEN_UNFUSED: PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Write Once / FUID")); break; - case MAGIC_SUPER: - PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("super card")); + case MAGIC_SUPER_GEN1: + PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Super card (") _CYAN_("Gen 1") _GREEN_(")")); + break; + case MAGIC_SUPER_GEN2: + PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("Super card (") _CYAN_("Gen 2") _GREEN_(")")); break; case MAGIC_NTAG21X: PrintAndLogEx(SUCCESS, "Magic capabilities : " _GREEN_("NTAG21x")); diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 24d259b44..2d4cd259c 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -677,12 +677,12 @@ CF FE <4b new_password> // Change password ### Identify ^[Top](#top) -Only Gen1 at the moment: +Only Gen1/Gen2 at this moment (Gen1B is unsupported): ``` hf 14a info ... -[+] Magic capabilities : super card +[+] Magic capabilities : Super card (Gen ?) ``` # MIFARE Ultralight diff --git a/include/protocols.h b/include/protocols.h index 5900b377c..54a8ba446 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -258,11 +258,12 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MAGIC_GEN_1B 2 #define MAGIC_GEN_2 4 #define MAGIC_GEN_UNFUSED 5 -#define MAGIC_SUPER 6 -#define MAGIC_NTAG21X 7 -#define MAGIC_GEN_3 8 -#define MAGIC_GEN_4GTU 9 -#define MAGIC_GEN_4GDM 10 +#define MAGIC_SUPER_GEN1 6 +#define MAGIC_SUPER_GEN2 7 +#define MAGIC_NTAG21X 8 +#define MAGIC_GEN_3 9 +#define MAGIC_GEN_4GTU 10 +#define MAGIC_GEN_4GDM 11 // Commands for configuration of Gen4 GTU cards. // see https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/magic_cards_notes.md From 71ddee1386e60b1f8b09d7b86e64df80b0413239 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 26 Mar 2023 16:50:59 +0200 Subject: [PATCH 740/759] added "hf mf gdmsetcfg" to write GDM configuration --- CHANGELOG.md | 3 +- armsrc/appmain.c | 8 +++++ armsrc/mifarecmd.c | 71 ++++++++++++++++++++++++++++++++++++++++-- armsrc/mifarecmd.h | 1 + armsrc/mifareutil.c | 71 ++++++++++++++++++++++++++++++++++-------- armsrc/mifareutil.h | 1 + client/src/cmdhflist.c | 9 ++---- client/src/cmdhfmf.c | 57 ++++++++++++++++++++++++++++++--- include/pm3_cmd.h | 1 + include/protocols.h | 7 ++--- 10 files changed, 197 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6e9c9811..4121234df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +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 `hf mf gdmgetblk` - Support Gen4 GDM read configuration block (@iceman1001) + - Added `hf mf gdmsetcfg` - Supprt Gen4 GDM write configuration block (@iceman1001) + - Added `hf mf gdmcfg` - Support Gen4 GDM read configuration block (@iceman1001) - Changed magic note to include a section about GDM tags (@iceman1001) - Added `hf mf gdmsetblk` - Support Gen4 GDM write block (@iceman1001) - Changed `hf 14a info` - detect Gen GDM magic tags (@iceman1001) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 969513d39..6901973f2 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1743,6 +1743,14 @@ static void PacketReceived(PacketCommandNG *packet) { MifareReadConfigBlockGDM(payload->key); break; } + case CMD_HF_MIFARE_G4_GDM_WRCFG: { + struct p { + uint8_t data[16]; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + MifareWriteConfigBlockGDM(payload->data); + break; + } case CMD_HF_MIFARE_G4_GDM_WRBL: { struct p { uint8_t blockno; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 0d14ffb92..7eaad3e23 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -253,7 +253,7 @@ void MifareReadConfigBlockGDM(uint8_t *key) { goto OUT; }; - if (mifare_classic_readblock_ex(pcs, cuid, 0, outbuf, MIFARE_MAGIC_GDM_READBLOCK)) { + if (mifare_classic_readblock_ex(pcs, cuid, 0, outbuf, MIFARE_MAGIC_GDM_READ_CFG)) { retval = PM3_ESOFT; goto OUT; }; @@ -574,6 +574,73 @@ OUT: BigBuf_free(); } +void MifareWriteConfigBlockGDM(uint8_t *datain) { + + int retval = PM3_SUCCESS; + + // check args + if (datain == NULL) { + retval = PM3_EINVARG; + goto OUT; + } + + uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); + if (par == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + + uint8_t *uid = BigBuf_malloc(10); + if (uid == NULL) { + retval = PM3_EMALLOC; + goto OUT; + } + + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + clear_trace(); + set_tracing(true); + + // variables + uint32_t cuid = 0; + struct Crypto1State mpcs = {0, 0}; + struct Crypto1State *pcs; + pcs = &mpcs; + + if (iso14443a_select_card(uid, NULL, &cuid, true, 0, true) == false) { + retval = PM3_ESOFT; + goto OUT; + } + + uint64_t key = 0; + if (mifare_classic_authex_2(pcs, cuid, 0, 0, key, AUTH_FIRST, NULL, NULL, true)) { + retval = PM3_ESOFT; + goto OUT; + }; + + int res = mifare_classic_write_cfg_block_gdm(pcs, cuid, datain); + if (res == PM3_ETEAROFF) { + retval = PM3_ETEAROFF; + goto OUT; + } else if (res) { + retval = PM3_ESOFT; + goto OUT; + } + + if (mifare_classic_halt(pcs, cuid)) { + retval = PM3_ESOFT; + goto OUT; + }; + +OUT: + crypto1_deinit(pcs); + + reply_ng(CMD_HF_MIFARE_G4_GDM_WRCFG, retval, NULL, 0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); + set_tracing(false); + BigBuf_free(); +} + void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t *datain) { // params @@ -2487,7 +2554,7 @@ void MifareCIdent(bool is_mfc) { uint8_t rats[4] = { ISO14443A_CMD_RATS, 0x80, 0x31, 0x73 }; uint8_t rdblf0[4] = { ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f}; uint8_t rdbl00[4] = { ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8}; - uint8_t gen4gmd[4] = { MIFARE_MAGIC_GDM_AUTH_KEYA, 0x00, 0x6C, 0x92}; + uint8_t gen4gmd[4] = { MIFARE_MAGIC_GDM_AUTH_KEY, 0x00, 0x6C, 0x92}; uint8_t gen4GetConf[8] = { GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0}; uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 6363423fd..415e0333d 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -60,6 +60,7 @@ void MifareGen3Freez(void); // Gen 3 magic card lock further UID changes // MFC GEN4 GDM void MifareReadConfigBlockGDM(uint8_t *key); +void MifareWriteConfigBlockGDM(uint8_t *datain); void MifareWriteBlockGDM(uint8_t blockno, uint8_t keytype, uint8_t *key, uint8_t *datain); // MFC GEN4 GTU diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index fd9260e23..b11625339 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -142,24 +142,21 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN return mifare_classic_authex_2(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL, false); } int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing, bool is_gdm) { - int len; - uint32_t pos, nt, ntpp; // Supplied tag nonce - uint8_t par[1] = {0x00}; + + // "random" reader nonce: uint8_t nr[4]; - uint8_t mf_nr_ar[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + num_to_bytes(prng_successor(GetTickCount(), 32), 4, nr); + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; - // "random" reader nonce: - num_to_bytes(prng_successor(GetTickCount(), 32), 4, nr); - // Transmit MIFARE_CLASSIC_AUTH 0x60, 0x61 or GDM 0x80 - uint8_t cmdbyte = (is_gdm) ? MIFARE_MAGIC_GDM_AUTH_KEYA + (keyType & 0x01) : MIFARE_AUTH_KEYA + (keyType & 0x01); - len = mifare_sendcmd_short(pcs, isNested, cmdbyte, blockNo, receivedAnswer, receivedAnswerPar, timing); + uint8_t cmdbyte = (is_gdm) ? MIFARE_MAGIC_GDM_AUTH_KEY : MIFARE_AUTH_KEYA + (keyType & 0x01); + int len = mifare_sendcmd_short(pcs, isNested, cmdbyte, blockNo, receivedAnswer, receivedAnswerPar, timing); if (len != 4) return 1; // Save the tag nonce (nt) - nt = bytes_to_num(receivedAnswer, 4); + uint32_t nt = bytes_to_num(receivedAnswer, 4); // ----------------------------- crypto1 create if (isNested) @@ -185,7 +182,9 @@ int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t bloc *ntptr = nt; // Generate (encrypted) nr+parity by loading it into the cipher (Nr) - par[0] = 0; + uint32_t pos; + uint8_t par[1] = {0x00}; + uint8_t mf_nr_ar[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; for (pos = 0; pos < 4; pos++) { mf_nr_ar[pos] = crypto1_byte(pcs, nr[pos], 0) ^ nr[pos]; par[0] |= (((filter(pcs->odd) ^ oddparity8(nr[pos])) & 0x01) << (7 - pos)); @@ -221,8 +220,8 @@ int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t bloc return 2; } - ntpp = prng_successor(nt, 32) ^ crypto1_word(pcs, 0, 0); - + // Supplied tag nonce + uint32_t ntpp = prng_successor(nt, 32) ^ crypto1_word(pcs, 0, 0); if (ntpp != bytes_to_num(receivedAnswer, 4)) { if (g_dbglevel >= DBG_EXTENDED) Dbprintf("Authentication failed. Error card response"); return 3; @@ -473,6 +472,52 @@ int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t return 0; } +int mifare_classic_write_cfg_block_gdm(struct Crypto1State *pcs, uint32_t uid, uint8_t *blockData) { + + // variables + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00}; + + uint16_t len = mifare_sendcmd_short(pcs, 1, MIFARE_MAGIC_GDM_WRITE_CFG, 0, receivedAnswer, receivedAnswerPar, NULL); + if ((len != 1) || (receivedAnswer[0] != 0x0A)) { + return 1; + } + + uint8_t d_block[18], d_block_enc[18]; + memcpy(d_block, blockData, 16); + AddCrc14A(d_block, 16); + + // enough for 18 Bytes to send + uint8_t par[3] = {0x00, 0x00, 0x00}; + // crypto + for (uint32_t pos = 0; pos < 18; pos++) { + d_block_enc[pos] = crypto1_byte(pcs, 0x00, 0) ^ d_block[pos]; + par[pos >> 3] |= (((filter(pcs->odd) ^ oddparity8(d_block[pos])) & 0x01) << (7 - (pos & 0x0007))); + } + + ReaderTransmitPar(d_block_enc, sizeof(d_block_enc), par, NULL); + + // tearoff occurred + if (tearoff_hook() == PM3_ETEAROFF) { + return PM3_ETEAROFF; + } else { + // Receive the response + len = ReaderReceive(receivedAnswer, receivedAnswerPar); + + uint8_t res = 0; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 0)) << 0; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 1)) << 1; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 2)) << 2; + res |= (crypto1_bit(pcs, 0, 0) ^ BIT(receivedAnswer[0], 3)) << 3; + + if ((len != 1) || (res != 0x0A)) { + return 2; + } + } + return 0; +} + + int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t action) { // variables diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index bcc813d00..e5731ce36 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -82,6 +82,7 @@ int mifare_classic_halt_ex(struct Crypto1State *pcs); int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData); int mifare_classic_writeblock_ex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, bool is_gdm); int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData, uint8_t action); +int mifare_classic_write_cfg_block_gdm(struct Crypto1State *pcs, uint32_t uid, uint8_t *blockData); // Ultralight/NTAG... int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack); diff --git a/client/src/cmdhflist.c b/client/src/cmdhflist.c index 263a4baa1..7207e50f9 100644 --- a/client/src/cmdhflist.c +++ b/client/src/cmdhflist.c @@ -318,18 +318,13 @@ int applyIso14443a(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize, bool i snprintf(exp, size, "AUTH-B(" _MAGENTA_("%d") ")", cmd[1]); break; } - case MIFARE_MAGIC_GDM_AUTH_KEYA: { + case MIFARE_MAGIC_GDM_AUTH_KEY: { if (cmdsize > 3) { - snprintf(exp, size, "MAGIC AUTH-A(" _MAGENTA_("%d") ")", cmd[1]); + snprintf(exp, size, "MAGIC AUTH (" _MAGENTA_("%d") ")", cmd[1]); MifareAuthState = masNt; } break; } - case MIFARE_MAGIC_GDM_AUTH_KEYB: { - MifareAuthState = masNt; - snprintf(exp, size, "MAGIC AUTH-B(" _MAGENTA_("%d") ")", cmd[1]); - break; - } case MIFARE_MAGIC_GDM_WRITEBLOCK: { snprintf(exp, size, "MAGIC WRITEBLOCK(" _MAGENTA_("%d") ")", cmd[1]); break; diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 8093c818d..d5d0e913b 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -7574,11 +7574,11 @@ static int CmdHF14AGen4Save(const char *Cmd) { return PM3_SUCCESS; } -static int CmdHF14AGen4_GDM_ConfigBlk(const char *Cmd) { +static int CmdHF14AGen4_GDM_Cfg(const char *Cmd) { CLIParserContext *ctx; - CLIParserInit(&ctx, "hf mf gdmconfig", + CLIParserInit(&ctx, "hf mf gdmcfg", "Get configuration data from magic gen4 GDM card.", - "hf mf gdmconfig\n" + "hf mf gdmcfg\n" ); void *argtable[] = { arg_param_begin, @@ -7620,6 +7620,52 @@ static int CmdHF14AGen4_GDM_ConfigBlk(const char *Cmd) { return resp.status; } +static int CmdHF14AGen4_GDM_SetCfg(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf gdmsetcfg", + "Set configuration data on a magic gen4 GDM card", + "hf mf gdmsetcfg -d 850000000000000000005A5A00000008" + ); + void *argtable[] = { + arg_param_begin, + arg_str1("d", "data", "", "bytes to write, 16 hex bytes"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + uint8_t block[MFBLOCK_SIZE] = {0x00}; + int blen = 0; + CLIGetHexWithReturn(ctx, 1, block, &blen); + CLIParserFree(ctx); + + if (blen != MFBLOCK_SIZE) { + PrintAndLogEx(WARNING, "expected %u HEX bytes. got %i", MFBLOCK_SIZE, blen); + return PM3_EINVARG; + } + + struct p { + uint8_t data[MFBLOCK_SIZE]; + } PACKED payload; + + memcpy(payload.data, block, sizeof(payload.data)); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_G4_GDM_WRCFG, (uint8_t *)&payload, sizeof(payload)); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_HF_MIFARE_G4_GDM_WRCFG, &resp, 1500) == false) { + PrintAndLogEx(WARNING, "command execute timeout"); + return PM3_ETIMEOUT; + } + + if (resp.status == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )"); + PrintAndLogEx(HINT, "try `" _YELLOW_("hf mf gdmcfg") "` to verify"); + } else { + PrintAndLogEx(FAILED, "Write ( " _RED_("fail") " )"); + } + return PM3_SUCCESS; +} + static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { CLIParserContext *ctx; @@ -7995,8 +8041,9 @@ static command_t CommandTable[] = { {"gsetblk", CmdHF14AGen4SetBlk, IfPm3Iso14443a, "Write block to card"}, {"gview", CmdHF14AGen4View, IfPm3Iso14443a, "View card"}, {"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GDM") " --------------------------"}, - {"gdmconfig", CmdHF14AGen4_GDM_ConfigBlk, IfPm3Iso14443a, "Read config block from card"}, - {"gdmsetblk", CmdHF14AGen4_GDM_SetBlk, IfPm3Iso14443a, "Write block to card"}, + {"gdmcfg", CmdHF14AGen4_GDM_Cfg, IfPm3Iso14443a, "Read config block from card"}, + {"gdmsetcfg", CmdHF14AGen4_GDM_SetCfg, IfPm3Iso14443a, "Write config block to card"}, + {"gdmsetblk", CmdHF14AGen4_GDM_SetBlk, IfPm3Iso14443a, "Write block to card"}, {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("ndef") " -----------------------"}, // {"ice", CmdHF14AMfice, IfPm3Iso14443a, "collect MIFARE Classic nonces to file"}, {"ndefformat", CmdHFMFNDEFFormat, IfPm3Iso14443a, "Format MIFARE Classic Tag as NFC Tag"}, diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index b99bb8430..7a19e6dbe 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -690,6 +690,7 @@ typedef struct { #define CMD_HF_MIFARE_G4_GDM_RDBL 0x0870 #define CMD_HF_MIFARE_G4_GDM_WRBL 0x0871 #define CMD_HF_MIFARE_G4_GDM_CONFIG 0x0872 +#define CMD_HF_MIFARE_G4_GDM_WRCFG 0x0873 #define CMD_UNKNOWN 0xFFFF diff --git a/include/protocols.h b/include/protocols.h index 5900b377c..7b318a9f5 100644 --- a/include/protocols.h +++ b/include/protocols.h @@ -190,11 +190,10 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define MIFARE_CMD_RESTORE 0xC2 #define MIFARE_CMD_TRANSFER 0xB0 -#define MIFARE_MAGIC_GDM_AUTH_KEYA 0x80 -#define MIFARE_MAGIC_GDM_AUTH_KEYB 0x81 +#define MIFARE_MAGIC_GDM_AUTH_KEY 0x80 #define MIFARE_MAGIC_GDM_WRITEBLOCK 0xA8 -#define MIFARE_MAGIC_GDM_READBLOCK 0xE0 -#define MIFARE_MAGIC_GDM_READBLOCK_1 0xE1 +#define MIFARE_MAGIC_GDM_READ_CFG 0xE0 +#define MIFARE_MAGIC_GDM_WRITE_CFG 0xE1 #define MIFARE_EV1_PERSONAL_UID 0x40 #define MIFARE_EV1_SETMODE 0x43 From 5696dd31cc606b2105c84bef41ef1f89330f2704 Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Sun, 26 Mar 2023 17:52:48 +0300 Subject: [PATCH 741/759] Use rdbl00 instead superGen2 --- armsrc/mifarecmd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index cb5644fc8..39aa166b8 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2487,7 +2487,6 @@ void MifareCIdent(bool is_mfc) { uint8_t gen4gmd[4] = {MIFARE_MAGIC_GDM_AUTH_KEYA, 0x00, 0x6C, 0x92}; uint8_t gen4GetConf[8] = {GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0}; uint8_t superGen1[9] = {0x0A, 0x00, 0x00, 0xA6, 0xB0, 0x00, 0x10, 0x14, 0x1D}; - uint8_t superGen2[4] = {0x30, 0x00, 0x02, 0xA8}; uint8_t *par = BigBuf_malloc(MAX_PARITY_SIZE); uint8_t *buf = BigBuf_malloc(PM3_CMD_DATA_SIZE); uint8_t *uid = BigBuf_malloc(10); @@ -2559,7 +2558,7 @@ void MifareCIdent(bool is_mfc) { iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_select_card(uid, NULL, &cuid, true, 0, true); - ReaderTransmit(superGen2, sizeof(superGen2), NULL); + ReaderTransmit(rdbl00, sizeof(rdbl00), NULL); res = ReaderReceive(buf, par); if (res == 18) { isGen = MAGIC_SUPER_GEN2; From eaee87497e9196915f9e5c4951ba9ea633612135 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 26 Mar 2023 16:53:12 +0200 Subject: [PATCH 742/759] text about setcfg --- doc/magic_cards_notes.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index e90845c74..fb7ba7fd2 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -598,9 +598,11 @@ It is unknown what kind of block 0 changes the tag supports # Write to persistent memory hf mf gdmsetblk -# Read 0xE0 configuration: -hf mf gdmconfig +# Read configuration (0xE0): +hf mf gdmcfg +# Write configuration (0xE1): +hf mf gdmsetcfg ``` ### libnfc commands From 9a4c363549842edf027ef7eb03f85fee4d77cd16 Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Sun, 26 Mar 2023 18:03:46 +0300 Subject: [PATCH 743/759] Leading zeros in key --- client/src/cmdhfmf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 5aede7d00..7b50a1a9e 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6804,7 +6804,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { res = mfkey32_moebius(&data, &key64); if (res) { - PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ " _GREEN_("%12" PRIX64) " ]", sprint_hex_inrow(outA, 4), data.sector, (data.keytype == 0x60) ? 'A' : 'B', key64); + PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ " _GREEN_("%012" PRIX64) " ]", sprint_hex_inrow(outA, 4), data.sector, (data.keytype == 0x60) ? 'A' : 'B', key64); } else { PrintAndLogEx(FAILED, "failed to recover any key"); } From d10d8c00396d571dcdd426932afbc0b73e8eefa9 Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Sun, 26 Mar 2023 18:05:11 +0300 Subject: [PATCH 744/759] And make style --- armsrc/mifarecmd.c | 2 +- armsrc/mifareutil.c | 2 +- client/src/cmdhfmf.c | 10 +++++----- doc/commands.json | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index feabf15a1..a1c86c2e8 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -497,7 +497,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { retval = 1; -OUT: +OUT: crypto1_deinit(pcs); reply_mix(CMD_ACK, retval, 0, 0, 0, 0); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index b11625339..6f04cc3e7 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -183,7 +183,7 @@ int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t bloc // Generate (encrypted) nr+parity by loading it into the cipher (Nr) uint32_t pos; - uint8_t par[1] = {0x00}; + uint8_t par[1] = {0x00}; uint8_t mf_nr_ar[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; for (pos = 0; pos < 4; pos++) { mf_nr_ar[pos] = crypto1_byte(pcs, nr[pos], 0) ^ nr[pos]; diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 7b50a1a9e..5703afad4 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -633,7 +633,7 @@ static int CmdHF14AMfWrBl(const char *Cmd) { PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )"); PrintAndLogEx(HINT, "try `" _YELLOW_("hf mf rdbl") "` to verify"); } else if (status == PM3_ETEAROFF) { - return status; + return status; } else { PrintAndLogEx(FAILED, "Write ( " _RED_("fail") " )"); // suggest the opposite keytype than what was used. @@ -7855,7 +7855,7 @@ static int CmdHF14AGen4_GDM_SetBlk(const char *Cmd) { PrintAndLogEx(HINT, "try `" _YELLOW_("hf mf rdbl") "` to verify"); } else if (resp.status == PM3_ETEAROFF) { return resp.status; - } else { + } else { PrintAndLogEx(FAILED, "Write ( " _RED_("fail") " )"); PrintAndLogEx(HINT, "Maybe access rights? Try specify keytype `" _YELLOW_("hf mf gdmsetblk -%c ...") "` instead", (keytype == MF_KEY_A) ? 'b' : 'a'); } @@ -8007,7 +8007,7 @@ static int CmdHF14AMfValue(const char *Cmd) { } if (resp.oldarg[0] & 0xFF) { - // all ok so set flag to read current value + // all ok so set flag to read current value getval = true; PrintAndLogEx(SUCCESS, "Update ( " _GREEN_("success") " )"); } else { @@ -8040,7 +8040,7 @@ static int CmdHF14AMfValue(const char *Cmd) { } int status = resp.oldarg[0]; if (status) { - // all ok so set flag to read current value + // all ok so set flag to read current value getval = true; PrintAndLogEx(SUCCESS, "Update ( " _GREEN_("success") " )"); } else if (status == PM3_ETEAROFF) { @@ -8137,7 +8137,7 @@ static command_t CommandTable[] = { {"gsave", CmdHF14AGen4Save, IfPm3Iso14443a, "Save dump from card into file or emulator"}, {"gsetblk", CmdHF14AGen4SetBlk, IfPm3Iso14443a, "Write block to card"}, {"gview", CmdHF14AGen4View, IfPm3Iso14443a, "View card"}, - {"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GDM") " --------------------------"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "-------------------- " _CYAN_("magic gen4 GDM") " --------------------------"}, {"gdmcfg", CmdHF14AGen4_GDM_Cfg, IfPm3Iso14443a, "Read config block from card"}, {"gdmsetcfg", CmdHF14AGen4_GDM_SetCfg, IfPm3Iso14443a, "Write config block to card"}, {"gdmsetblk", CmdHF14AGen4_GDM_SetBlk, IfPm3Iso14443a, "Write block to card"}, diff --git a/doc/commands.json b/doc/commands.json index 3a59e6f7c..703ff688c 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -4889,7 +4889,7 @@ "offline": false, "options": [ "-h, --help This help", - "-r, --reset reset card", + "-r, --reset Reset card", "-u, --uid New UID (4 hex bytes)" ], "usage": "hf mf supercard [-hr] [-u ]" @@ -11989,6 +11989,6 @@ "metadata": { "commands_extracted": 754, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2023-03-26T13:15:37" + "extracted_on": "2023-03-26T15:04:49" } } \ No newline at end of file From 4c3265daec524232c713ae9b35be76ce5fbec08b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 26 Mar 2023 20:26:50 +0200 Subject: [PATCH 745/759] text --- doc/magic_cards_notes.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index fb7ba7fd2..da545a24b 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -575,6 +575,13 @@ Read config: 2. send 0xE000, will return the configuration bytes. `results: 850000000000000000005A5A00000008` + +Mapping of configuration bytes so far: +``` +850000000000000000005A5A00000008 + ^^ --> SAK +``` + Write config: 1. sending custom auth with all zeros key 2. send 0xE100 From 0f0a5d7f043632d4b540215141cf9fb16e9b6106 Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Tue, 28 Mar 2023 17:25:03 +0300 Subject: [PATCH 746/759] Fix lost arguments --- armsrc/mifareutil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index b11625339..6f8acc348 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -139,7 +139,7 @@ int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL); } int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) { - return mifare_classic_authex_2(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL, false); + return mifare_classic_authex_2(pcs, uid, blockNo, keyType, ui64Key, isNested, ntptr, timing, false); } int mifare_classic_authex_2(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing, bool is_gdm) { From a9b3a69100fe0e97eb28b8a936f0c544fa91decc Mon Sep 17 00:00:00 2001 From: Einstein2150 Date: Wed, 29 Mar 2023 20:37:02 +0200 Subject: [PATCH 747/759] Update Mac-OS-X-Homebrew-Installation-Instructions.md Fix for Apple Silicon (M1) installation with arch -arm64 prefix Signed-off-by: Einstein2150 --- .../Mac-OS-X-Homebrew-Installation-Instructions.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md index 4de2ec373..3b2e31530 100644 --- a/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md +++ b/doc/md/Installation_Instructions/Mac-OS-X-Homebrew-Installation-Instructions.md @@ -54,6 +54,8 @@ Then you are missing Rosetta 2 and need to install it: `/usr/sbin/softwareupdate Homebrew has changed their prefix to differentiate between native Apple Silicon and Intel compiled binaries. The Makefile attempts to account for this but please note that whichever terminal or application you're using must be running under Architecture "Apple" as seen by Activity Monitor as all child processes inherit the Rosetta 2 environment of their parent. You can check which architecture you're currently running under with a `uname -m` in your terminal. +The fastest option is to run the brew command with the `arch -arm64` prefix i.e. `arch -arm64 brew install --HEAD --with-blueshark proxmark3`. This doesn't require running the whole terminal in Rosetta 2. + Visual Studio Code still runs under Rosetta 2 and if you're developing for proxmark3 on an Apple Silicon Mac you might want to consider running the Insiders build which has support for running natively on Apple Silicon. ## Install Proxmark3 tools From ee79e5acb7a6bf634c5c17763998188d139a0320 Mon Sep 17 00:00:00 2001 From: GuruSteve Date: Wed, 29 Mar 2023 15:44:52 -0600 Subject: [PATCH 748/759] Added default iClass credit key to table; reorganized key order --- CHANGELOG.md | 1 + client/src/cmdhficlass.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4121234df..0c5260e11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added XOR key extraction and flag to Guardall G-Prox II (@GuruSteve) - Changed verbiage on `hf iclass info` KeyAccess area to be congruent with AA1 and AA2 areas (@GuruSteve) - Added `hf legic info` command for other sources: `hf legic einfo`, `hf legic view` (@0xdeb) + - Added iClass credit key to default iClass key table and reorganized key order (@GuruSteve) ## [Nitride.4.16191][2023-01-29] diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 1c67f98c4..b328436bb 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -63,9 +63,9 @@ static void printIclassSIO(uint8_t *iclass_dump); static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = { { 0xAE, 0xA6, 0x84, 0xA6, 0xDA, 0xB2, 0x32, 0x78 }, - { 0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x00 }, + { 0xFD, 0xCB, 0x5A, 0x52, 0xEA, 0x8F, 0x30, 0x90 }, { 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x76, 0x65, 0x54, 0x43, 0x32, 0x21, 0x10, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, From dab3171ba6fd409b63efc965c6bf88ef0224ba1c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Mar 2023 22:38:03 +0200 Subject: [PATCH 749/759] added loadbinarykeys fct which takes fn and loads binary MFC keys into two arrays KeyA, KeyB. --- client/src/fileutils.c | 80 ++++++++++++++++++++++++++++++++++-------- client/src/fileutils.h | 16 +++++++++ 2 files changed, 82 insertions(+), 14 deletions(-) diff --git a/client/src/fileutils.c b/client/src/fileutils.c index 3182f47c3..8a6049d3c 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -304,12 +304,12 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si return PM3_EMALLOC; } - /* We should have a valid filename now, e.g. dumpdata-3.bin */ + // We should have a valid filename now, e.g. dumpdata-3.bin - /*Opening file for writing in binary mode*/ + // Opening file for writing in binary mode FILE *f = fopen(fileName, "wb"); if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", fileName); free(fileName); return PM3_EFILE; } @@ -336,12 +336,12 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t int blocks = datalen / blocksize; uint16_t currblock = 1; - /* We should have a valid filename now, e.g. dumpdata-3.bin */ + // We should have a valid filename now, e.g. dumpdata-3.bin - /*Opening file for writing in text mode*/ + // Opening file for writing in text mode FILE *f = fopen(fileName, "w+"); if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName); + PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", fileName); retval = PM3_EFILE; goto out; } @@ -770,7 +770,7 @@ int saveFileWAVE(const char *preferredName, const int *data, size_t datalen) { FILE *wave_file = fopen(fileName, "wb"); if (!wave_file) { - PrintAndLogEx(WARNING, "file not found or locked. "_YELLOW_("'%s'"), fileName); + PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", fileName); retval = PM3_EFILE; goto out; } @@ -806,7 +806,7 @@ int saveFilePM3(const char *preferredName, int *data, size_t datalen) { FILE *f = fopen(fileName, "w"); if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. "_YELLOW_("'%s'"), fileName); + PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", fileName); retval = PM3_EFILE; goto out; } @@ -939,7 +939,7 @@ int loadFile_safeEx(const char *preferredName, const char *suffix, void **pdata, FILE *f = fopen(path, "rb"); if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); + PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path); free(path); return PM3_EFILE; } @@ -1050,7 +1050,7 @@ int loadFileEML_safe(const char *preferredName, void **pdata, size_t *datalen) { FILE *f = fopen(path, "r"); if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); + PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path); free(path); return PM3_EFILE; } @@ -1427,6 +1427,7 @@ int loadFileJSONroot(const char *preferredName, void **proot, bool verbose) { return retval; } +// iceman: todo - move all unsafe functions like this from client source. int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint32_t *keycnt) { // t5577 == 4 bytes // mifare == 6 bytes @@ -1463,7 +1464,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale FILE *f = fopen(path, "r"); if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); + PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path); retval = PM3_EFILE; goto out; } @@ -1566,7 +1567,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key FILE *f = fopen(path, "r"); if (!f) { - PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", path); + PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path); retval = PM3_EFILE; goto out; } @@ -1619,6 +1620,57 @@ out: return retval; } +int loadFileBinaryKey(const char *preferredName, const char *suffix, void **keya, void **keyb, size_t *alen, size_t *blen) { + + char *path; + int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, suffix, false); + if (res != PM3_SUCCESS) { + return PM3_EFILE; + } + + FILE *f = fopen(path, "rb"); + if (!f) { + PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", path); + free(path); + return PM3_EFILE; + } + free(path); + + // get filesize in order to malloc memory + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); + + if (fsize <= 0) { + PrintAndLogEx(FAILED, "error, when getting filesize"); + fclose(f); + return PM3_EFILE; + } + + // Half is KEY A, half is KEY B + fsize /= 2; + + *keya = calloc(fsize, sizeof(uint8_t)); + if (*keya == NULL) { + PrintAndLogEx(FAILED, "error, cannot allocate memory"); + fclose(f); + return PM3_EMALLOC; + } + + *alen = fread(*keya, 1, fsize, f); + + *keyb = calloc(fsize, sizeof(uint8_t)); + if (*keyb == NULL) { + PrintAndLogEx(FAILED, "error, cannot allocate memory"); + fclose(f); + return PM3_EMALLOC; + } + + *blen = fread(*keyb, 1, fsize, f); + fclose(f); + return PM3_SUCCESS; +} + mfu_df_e detect_mfu_dump_format(uint8_t **dump, size_t *dumplen, bool verbose) { mfu_df_e retval = MFU_DF_UNKNOWN; @@ -2058,7 +2110,7 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl } if (res != PM3_SUCCESS) { - PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", fn); + PrintAndLogEx(WARNING, "file not found or locked `" _YELLOW_("%s") "`", fn); return PM3_EFILE; } @@ -2068,7 +2120,7 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl int pm3_save_dump(const char *fn, uint8_t *d, size_t n, JSONFileType jsft, size_t blocksize) { if (d == NULL || n == 0) { - PrintAndLogEx(INFO, "No data to save. Skipping..."); + PrintAndLogEx(INFO, "No data to save, skipping..."); return PM3_EINVARG; } diff --git a/client/src/fileutils.h b/client/src/fileutils.h index fc5d274aa..18e0fbd7e 100644 --- a/client/src/fileutils.h +++ b/client/src/fileutils.h @@ -236,6 +236,7 @@ int loadFileDICTIONARYEx(const char *preferredName, void *data, size_t maxdatale */ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t keylen, uint32_t *keycnt); +int loadFileBinaryKey(const char *preferredName, const char *suffix, void **keya, void **keyb, size_t *alen, size_t *blen); typedef enum { MFU_DF_UNKNOWN, @@ -276,5 +277,20 @@ DumpFileType_t getfiletype(const char *filename); */ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumplen); + +/** STUB + * @brief Utility function to save data to three file files (BIN/EML/JSON). + * It also tries to save according to user preferences set dump folder paths. + * E.g. dumpdata.bin + * E.g. dumpdata.eml + * E.g. dumpdata.json + + * @param fn + * @param d The binary data to write to the file + * @param n the length of the data + * @param jsft json format type for the different memory cards (MFC, MFUL, LEGIC, 14B, 15, ICLASS etc) + * @param blocksize + * @return PM3_SUCCESS if OK + */ int pm3_save_dump(const char *fn, uint8_t *d, size_t n, JSONFileType jsft, size_t blocksize); #endif // FILEUTILS_H From 27b3ba041255b434678251cde4508159295c38a2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Mar 2023 22:38:27 +0200 Subject: [PATCH 750/759] text --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4121234df..a8f8d819b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,8 +39,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added Mifare Classic EV1 signature write support to gen4 magic tag lua script (@augustozanellato) - Added XOR key extraction and flag to Guardall G-Prox II (@GuruSteve) - Changed verbiage on `hf iclass info` KeyAccess area to be congruent with AA1 and AA2 areas (@GuruSteve) - - Added `hf legic info` command for other sources: `hf legic einfo`, `hf legic view` (@0xdeb) - + - Added `hf legic info` command for other sources (@0xdeb) + - Added `hf legic einfo` - views emulator menory (@0xdeb) + - Changed `hf legic view` - now also print the decoded info of the dump file (@0xdeb) ## [Nitride.4.16191][2023-01-29] - Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox) From 4d28c852acab53d1654f5f95270ff75a4e6fb145 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Mar 2023 22:40:26 +0200 Subject: [PATCH 751/759] extracted load keys and mfc tag memory based on @didierA and @alejandro12120 PR. --- client/src/cmdhfmf.c | 459 ++++++++++++++++++++++--------------------- 1 file changed, 238 insertions(+), 221 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index d5d0e913b..e4b15c19e 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -38,15 +38,22 @@ #include "wiegand_formats.h" #include "wiegand_formatutils.h" -#define MIFARE_4K_MAXBLOCK 256 -#define MIFARE_2K_MAXBLOCK 128 -#define MIFARE_1K_MAXBLOCK 64 -#define MIFARE_MINI_MAXBLOCK 20 +#define MIFARE_4K_MAXBLOCK 256 +#define MIFARE_2K_MAXBLOCK 128 +#define MIFARE_1K_MAXBLOCK 64 +#define MIFARE_MINI_MAXBLOCK 20 -#define MIFARE_MINI_MAXSECTOR 5 -#define MIFARE_1K_MAXSECTOR 16 -#define MIFARE_2K_MAXSECTOR 32 -#define MIFARE_4K_MAXSECTOR 40 +#define MIFARE_4K_MAXSECTOR 40 +#define MIFARE_2K_MAXSECTOR 32 +#define MIFARE_1K_MAXSECTOR 16 +#define MIFARE_MINI_MAXSECTOR 5 + +#define MIFARE_4K_MAX_BYTES 4096 +#define MIFARE_2K_MAX_BYTES 2048 +#define MIFARE_1K_MAX_BYTES 1024 +#define MIFARE_MINI_MAX_BYTES 320 + +#define MIFARE_KEY_SIZE 6 static int CmdHelp(const char *Cmd); @@ -319,9 +326,9 @@ static int mf_print_keys(uint16_t n, uint8_t *d) { for (uint16_t i = 0; i < n; i++) { if (mfIsSectorTrailer(i)) { e_sector[mfSectorNum(i)].foundKey[0] = 1; - e_sector[mfSectorNum(i)].Key[0] = bytes_to_num(d + (i * MFBLOCK_SIZE), 6); + e_sector[mfSectorNum(i)].Key[0] = bytes_to_num(d + (i * MFBLOCK_SIZE), MIFARE_KEY_SIZE); e_sector[mfSectorNum(i)].foundKey[1] = 1; - e_sector[mfSectorNum(i)].Key[1] = bytes_to_num(d + (i * MFBLOCK_SIZE) + 10, 6); + e_sector[mfSectorNum(i)].Key[1] = bytes_to_num(d + (i * MFBLOCK_SIZE) + 10, MIFARE_KEY_SIZE); } } printKeyTable(sectors, e_sector); @@ -441,6 +448,191 @@ static int mf_analyse_st_block(uint8_t blockno, uint8_t *block, bool force){ return PM3_SUCCESS; } +/* Reads data from tag + * @param card: (output) card info + * @param carddata: (output) card data + * @param numSectors: size of the card + * @param keyFileName: filename containing keys or NULL. +*/ +static int mfc_read_tag(iso14a_card_select_t *card, uint8_t *carddata, uint8_t numSectors, char *keyfn){ + + // Select card to get UID/UIDLEN/ATQA/SAK information + clearCommandBuffer(); + SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { + PrintAndLogEx(WARNING, "iso14443a card select timeout"); + return PM3_ETIMEOUT; + } + + uint64_t select_status = resp.oldarg[0]; + if (select_status == 0) { + PrintAndLogEx(WARNING, "iso14443a card select failed"); + return PM3_SUCCESS; + } + + // store card info + memcpy(card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); + + char *fptr = NULL; + if (keyfn == NULL || keyfn[0] == '\0') { + fptr = GenerateFilename("hf-mf-", "-key.bin"); + if (fptr == NULL) + return PM3_ESOFT; + + keyfn = fptr ; + } + + PrintAndLogEx(INFO, "Using... %s", keyfn); + + size_t alen = 0, blen = 0; + uint8_t *keyA, *keyB; + if (loadFileBinaryKey(keyfn, "", (void**)&keyA, (void**)&keyB, &alen, &blen) != PM3_SUCCESS) { + free(fptr); + return PM3_ESOFT; + } + + PrintAndLogEx(INFO, "Reading sector access bits..."); + PrintAndLogEx(INFO, "." NOLF); + + uint8_t rights[40][4] = {0}; + + mf_readblock_t payload; + uint8_t current_key; + for (uint8_t sectorNo = 0; sectorNo < numSectors; sectorNo++) { + current_key = MF_KEY_A; + for (uint8_t tries = 0; tries < MIFARE_SECTOR_RETRY; tries++) { + PrintAndLogEx(NORMAL, "." NOLF); + fflush(stdout); + + payload.blockno = mfFirstBlockOfSector(sectorNo) + mfNumBlocksPerSector(sectorNo) - 1; + payload.keytype = current_key; + + memcpy(payload.key, (current_key == MF_KEY_A) ? keyA + (sectorNo * MIFARE_KEY_SIZE) : keyB + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + + if (WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) { + + uint8_t *data = resp.data.asBytes; + if (resp.status == PM3_SUCCESS) { + rights[sectorNo][0] = ((data[7] & 0x10) >> 2) | ((data[8] & 0x1) << 1) | ((data[8] & 0x10) >> 4); // C1C2C3 for data area 0 + rights[sectorNo][1] = ((data[7] & 0x20) >> 3) | ((data[8] & 0x2) << 0) | ((data[8] & 0x20) >> 5); // C1C2C3 for data area 1 + rights[sectorNo][2] = ((data[7] & 0x40) >> 4) | ((data[8] & 0x4) >> 1) | ((data[8] & 0x40) >> 6); // C1C2C3 for data area 2 + rights[sectorNo][3] = ((data[7] & 0x80) >> 5) | ((data[8] & 0x8) >> 2) | ((data[8] & 0x80) >> 7); // C1C2C3 for sector trailer + break; + } else if (tries == (MIFARE_SECTOR_RETRY / 2)) { // after half unsuccessful tries, give key B a go + PrintAndLogEx(WARNING, "\ntrying with key B instead..."); + current_key = MF_KEY_B; + PrintAndLogEx(INFO, "." NOLF); + } else if (tries == (MIFARE_SECTOR_RETRY - 1)) { // on last try set defaults + PrintAndLogEx(FAILED, "\ncould not get access rights for sector %2d. Trying with defaults...", sectorNo); + rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = 0x00; + rights[sectorNo][3] = 0x01; + } + } else { + PrintAndLogEx(FAILED, "\ncommand execute timeout when trying to read access rights for sector %2d. Trying with defaults...", sectorNo); + rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = 0x00; + rights[sectorNo][3] = 0x01; + } + } + } + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Finished reading sector access bits"); + PrintAndLogEx(INFO, "Dumping all blocks from card..."); + + for (uint8_t sectorNo = 0; sectorNo < numSectors; sectorNo++) { + for (uint8_t blockNo = 0; blockNo < mfNumBlocksPerSector(sectorNo); blockNo++) { + bool received = false; + current_key = MF_KEY_A; + uint8_t data_area = (sectorNo < 32) ? blockNo : blockNo / 5; + if (rights[sectorNo][data_area] == 0x07) { // no key would work + PrintAndLogEx(WARNING, "access rights do not allow reading of sector %2d block %3d, skipping", sectorNo, blockNo); + continue; + } + + for (uint8_t tries = 0; tries < MIFARE_SECTOR_RETRY; tries++) { + if (mfIsSectorTrailer(blockNo)) { + + // sector trailer. At least the Access Conditions can always be read with key A. + payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; + payload.keytype = current_key; + memcpy(payload.key, (current_key == MF_KEY_A) ? keyA + (sectorNo * MIFARE_KEY_SIZE) : keyB + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); + } else { + // data block. Check if it can be read with key A or key B + if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { + // only key B would work + payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; + payload.keytype = MF_KEY_B; + memcpy(payload.key, keyB + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); + } else { + // key A would work + payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; + payload.keytype = current_key; + memcpy(payload.key, (current_key == MF_KEY_A) ? keyA + (sectorNo * MIFARE_KEY_SIZE) : keyB + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); + received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); + } + } + + if (received) { + if (resp.status == PM3_SUCCESS) { + // break the re-try loop + break; + } + if ((current_key == MF_KEY_A) && (tries == (MIFARE_SECTOR_RETRY / 2))) { + // Half the tries failed with key A. Swap for key B + current_key = MF_KEY_B; + + // clear out keyA since it failed. + memset(keyA + (sectorNo * MIFARE_KEY_SIZE), 0x00, MIFARE_KEY_SIZE); + } + } + } + + if (received) { + + if (resp.status == PM3_SUCCESS) { + + uint8_t *data = resp.data.asBytes; + + if (mfIsSectorTrailer(blockNo)) { + // sector trailer. Fill in the keys. + memcpy(data , keyA + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + memcpy(data + 10, keyB + (sectorNo * MIFARE_KEY_SIZE), MIFARE_KEY_SIZE); + } + + memcpy(carddata + (MFBLOCK_SIZE * (mfFirstBlockOfSector(sectorNo) + blockNo)), data, MFBLOCK_SIZE); + PrintAndLogEx(SUCCESS, "successfully read block %2d of sector %2d.", blockNo, sectorNo); + } else { + PrintAndLogEx(FAILED, "could not read block %2d of sector %2d", blockNo, sectorNo); + } + } else { + PrintAndLogEx(WARNING, "command execute timeout when trying to read block %2d of sector %2d.", blockNo, sectorNo); + } + } + } + + free(fptr); + free(keyA); + free(keyB); + + PrintAndLogEx(SUCCESS, "\nSucceeded in dumping all blocks"); + return PM3_SUCCESS ; +} + static int CmdHF14AMfAcl(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf acl", @@ -820,6 +1012,7 @@ static int CmdHF14AMfDump(const char *Cmd) { arg_lit0(NULL, "1k", "MIFARE Classic 1k / S50 (def)"), arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), + arg_lit0(NULL, "ns", "no save to file"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -836,7 +1029,7 @@ static int CmdHF14AMfDump(const char *Cmd) { bool m1 = arg_get_lit(ctx, 4); bool m2 = arg_get_lit(ctx, 5); bool m4 = arg_get_lit(ctx, 6); - + bool nosave = arg_get_lit(ctx, 7); CLIParserFree(ctx); uint64_t t1 = msclock(); @@ -850,244 +1043,68 @@ static int CmdHF14AMfDump(const char *Cmd) { } uint8_t numSectors = MIFARE_1K_MAXSECTOR; + uint16_t bytes = MIFARE_1K_MAX_BYTES; if (m0) { numSectors = MIFARE_MINI_MAXSECTOR; + bytes = MIFARE_MINI_MAX_BYTES; } else if (m1) { numSectors = MIFARE_1K_MAXSECTOR; + bytes = MIFARE_1K_MAX_BYTES; } else if (m2) { numSectors = MIFARE_2K_MAXSECTOR; - } else if (m4) { + bytes = MIFARE_2K_MAX_BYTES; + } else if (m4) { numSectors = MIFARE_4K_MAXSECTOR; + bytes = MIFARE_4K_MAX_BYTES; } else { PrintAndLogEx(WARNING, "Please specify a MIFARE Type"); return PM3_EINVARG; } - uint8_t sectorNo, blockNo; - uint8_t keyA[40][6]; - uint8_t keyB[40][6]; - uint8_t rights[40][4]; - uint8_t carddata[256][16]; - - FILE *f; - PacketResponseNG resp; - - char *fptr; - - // Select card to get UID/UIDLEN/ATQA/SAK information - clearCommandBuffer(); - SendCommandMIX(CMD_HF_ISO14443A_READER, ISO14A_CONNECT, 0, 0, NULL, 0); - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { - PrintAndLogEx(WARNING, "iso14443a card select timeout"); - return PM3_ETIMEOUT; + // read card + iso14a_card_select_t card ; + uint8_t *mem = calloc(MIFARE_4K_MAXBLOCK * MFBLOCK_SIZE, sizeof(uint8_t)); + if (mem == NULL) { + PrintAndLogEx(ERR, "failed to allocate memory"); + return PM3_EMALLOC; } - - uint64_t select_status = resp.oldarg[0]; - if (select_status == 0) { - PrintAndLogEx(WARNING, "iso14443a card select failed"); - return PM3_SUCCESS; - } - - // store card info - iso14a_card_select_t card; - memcpy(&card, (iso14a_card_select_t *)resp.data.asBytes, sizeof(iso14a_card_select_t)); - - if (keyFilename[0] == 0x00) { - fptr = GenerateFilename("hf-mf-", "-key.bin"); - if (fptr == NULL) - return PM3_ESOFT; - - strncpy(keyFilename, fptr, sizeof(keyFilename) - 1); - free(fptr); - } - - if ((f = fopen(keyFilename, "rb")) == NULL) { - PrintAndLogEx(WARNING, "Could not find file " _YELLOW_("%s"), keyFilename); - return PM3_EFILE; - } - - PrintAndLogEx(INFO, "Using `" _YELLOW_("%s") "`", keyFilename); - - // Read keys A from file - size_t bytes_read; - for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { - bytes_read = fread(keyA[sectorNo], 1, MFKEY_SIZE, f); - if (bytes_read != MFKEY_SIZE) { - PrintAndLogEx(ERR, "File reading error."); - fclose(f); - return PM3_EFILE; - } - } - - // Read keys B from file - for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { - bytes_read = fread(keyB[sectorNo], 1, MFKEY_SIZE, f); - if (bytes_read != MFKEY_SIZE) { - PrintAndLogEx(ERR, "File reading error."); - fclose(f); - return PM3_EFILE; - } - } - - fclose(f); - - PrintAndLogEx(INFO, "Reading sector access bits..."); - PrintAndLogEx(INFO, "." NOLF); - - uint8_t tries; - mf_readblock_t payload; - uint8_t current_key; - for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { - current_key = MF_KEY_A; - for (tries = 0; tries < MIFARE_SECTOR_RETRY; tries++) { - PrintAndLogEx(NORMAL, "." NOLF); - fflush(stdout); - - payload.blockno = mfFirstBlockOfSector(sectorNo) + mfNumBlocksPerSector(sectorNo) - 1; - payload.keytype = current_key; - - memcpy(payload.key, current_key == MF_KEY_A ? keyA[sectorNo] : keyB[sectorNo], sizeof(payload.key)); - - clearCommandBuffer(); - SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); - - if (WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500)) { - - uint8_t *data = resp.data.asBytes; - if (resp.status == PM3_SUCCESS) { - rights[sectorNo][0] = ((data[7] & 0x10) >> 2) | ((data[8] & 0x1) << 1) | ((data[8] & 0x10) >> 4); // C1C2C3 for data area 0 - rights[sectorNo][1] = ((data[7] & 0x20) >> 3) | ((data[8] & 0x2) << 0) | ((data[8] & 0x20) >> 5); // C1C2C3 for data area 1 - rights[sectorNo][2] = ((data[7] & 0x40) >> 4) | ((data[8] & 0x4) >> 1) | ((data[8] & 0x40) >> 6); // C1C2C3 for data area 2 - rights[sectorNo][3] = ((data[7] & 0x80) >> 5) | ((data[8] & 0x8) >> 2) | ((data[8] & 0x80) >> 7); // C1C2C3 for sector trailer - break; - } else if (tries == (MIFARE_SECTOR_RETRY / 2)) { // after half unsuccessful tries, give key B a go - PrintAndLogEx(WARNING, "\ntrying with key B instead..."); - current_key = MF_KEY_B; - PrintAndLogEx(INFO, "." NOLF); - } else if (tries == (MIFARE_SECTOR_RETRY - 1)) { // on last try set defaults - PrintAndLogEx(FAILED, "\ncould not get access rights for sector %2d. Trying with defaults...", sectorNo); - rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = 0x00; - rights[sectorNo][3] = 0x01; - } - } else { - PrintAndLogEx(FAILED, "\ncommand execute timeout when trying to read access rights for sector %2d. Trying with defaults...", sectorNo); - rights[sectorNo][0] = rights[sectorNo][1] = rights[sectorNo][2] = 0x00; - rights[sectorNo][3] = 0x01; - } - } - } - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, "Finished reading sector access bits"); - PrintAndLogEx(INFO, "Dumping all blocks from card..."); - - for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { - for (blockNo = 0; blockNo < mfNumBlocksPerSector(sectorNo); blockNo++) { - bool received = false; - current_key = MF_KEY_A; - uint8_t data_area = (sectorNo < 32) ? blockNo : blockNo / 5; - if (rights[sectorNo][data_area] == 0x07) { // no key would work - PrintAndLogEx(WARNING, "access rights do not allow reading of sector %2d block %3d, skipping", sectorNo, blockNo); - continue; - } - for (tries = 0; tries < MIFARE_SECTOR_RETRY; tries++) { - if (blockNo == mfNumBlocksPerSector(sectorNo) - 1) { // sector trailer. At least the Access Conditions can always be read with key A. - - payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; - payload.keytype = current_key; - memcpy(payload.key, current_key == MF_KEY_A ? keyA[sectorNo] : keyB[sectorNo], sizeof(payload.key)); - - clearCommandBuffer(); - SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); - received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); - } else { // data block. Check if it can be read with key A or key B - if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work - - payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; - payload.keytype = MF_KEY_B; - memcpy(payload.key, keyB[sectorNo], sizeof(payload.key)); - - clearCommandBuffer(); - SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); - received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); - } else { // key A would work - - payload.blockno = mfFirstBlockOfSector(sectorNo) + blockNo; - payload.keytype = current_key; - memcpy(payload.key, current_key == MF_KEY_A ? keyA[sectorNo] : keyB[sectorNo], sizeof(payload.key)); - - clearCommandBuffer(); - SendCommandNG(CMD_HF_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t)); - received = WaitForResponseTimeout(CMD_HF_MIFARE_READBL, &resp, 1500); - } - } - if (received) { - if (resp.status == PM3_SUCCESS) { - // break the re-try loop - break; - } - if ((current_key == MF_KEY_A) && (tries == (MIFARE_SECTOR_RETRY / 2))) { - // Half the tries failed with key A. Swap for key B - current_key = MF_KEY_B; - - // clear out keyA since it failed. - memset(keyA[sectorNo], 0x00, sizeof(keyA[sectorNo])); - } - } - } - - if (received) { - uint8_t *data = resp.data.asBytes; - if (blockNo == mfNumBlocksPerSector(sectorNo) - 1) { // sector trailer. Fill in the keys. - data[0] = (keyA[sectorNo][0]); - data[1] = (keyA[sectorNo][1]); - data[2] = (keyA[sectorNo][2]); - data[3] = (keyA[sectorNo][3]); - data[4] = (keyA[sectorNo][4]); - data[5] = (keyA[sectorNo][5]); - - data[10] = (keyB[sectorNo][0]); - data[11] = (keyB[sectorNo][1]); - data[12] = (keyB[sectorNo][2]); - data[13] = (keyB[sectorNo][3]); - data[14] = (keyB[sectorNo][4]); - data[15] = (keyB[sectorNo][5]); - } - if (resp.status == PM3_SUCCESS) { - memcpy(carddata[mfFirstBlockOfSector(sectorNo) + blockNo], data, 16); - PrintAndLogEx(SUCCESS, "successfully read block %2d of sector %2d.", blockNo, sectorNo); - } else { - PrintAndLogEx(FAILED, "could not read block %2d of sector %2d", blockNo, sectorNo); - } - } else { - PrintAndLogEx(WARNING, "command execute timeout when trying to read block %2d of sector %2d.", blockNo, sectorNo); - } - } + int res = mfc_read_tag(&card, mem, numSectors, keyFilename); + if (res != PM3_SUCCESS) { + free(mem); + return res; } PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds\n", (msclock() - t1) / 1000); - PrintAndLogEx(SUCCESS, "\nSucceeded in dumping all blocks"); + // Skip saving card data to file + if (nosave) { + PrintAndLogEx(INFO, "Called with no save option"); + free(mem); + return PM3_SUCCESS; + } + // Save to file if (strlen(dataFilename) < 1) { - fptr = GenerateFilename("hf-mf-", "-dump"); - if (fptr == NULL) + char *fptr = GenerateFilename("hf-mf-", "-dump"); + if (fptr == NULL) { + free(mem); return PM3_ESOFT; + } strcpy(dataFilename, fptr); free(fptr); } - uint16_t bytes = 16 * (mfFirstBlockOfSector(numSectors - 1) + mfNumBlocksPerSector(numSectors - 1)); - - saveFile(dataFilename, ".bin", (uint8_t *)carddata, bytes); - saveFileEML(dataFilename, (uint8_t *)carddata, bytes, MFBLOCK_SIZE); + saveFile(dataFilename, ".bin", mem, bytes); + saveFileEML(dataFilename, mem, bytes, MFBLOCK_SIZE); iso14a_mf_extdump_t xdump; xdump.card_info = card; - xdump.dump = (uint8_t *)carddata; + xdump.dump = mem; xdump.dumplen = bytes; saveFileJSON(dataFilename, jsfCardMemory, (uint8_t *)&xdump, sizeof(xdump), NULL); + free(mem); return PM3_SUCCESS; } @@ -6892,11 +6909,11 @@ static int CmdHF14AMfView(const char *Cmd) { } uint16_t block_cnt = MIN(MIFARE_1K_MAXBLOCK, (bytes_read / MFBLOCK_SIZE)); - if (bytes_read == 320) + if (bytes_read == MIFARE_MINI_MAX_BYTES) block_cnt = MIFARE_MINI_MAXBLOCK; - else if (bytes_read == 2048) + else if (bytes_read == MIFARE_2K_MAX_BYTES) block_cnt = MIFARE_2K_MAXBLOCK; - else if (bytes_read == 4096) + else if (bytes_read == MIFARE_4K_MAX_BYTES) block_cnt = MIFARE_4K_MAXBLOCK; if (verbose) { From e03f7ed6d2db7dcd1e4ce262984fdaab51d6d234 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 30 Mar 2023 22:41:44 +0200 Subject: [PATCH 752/759] text --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8f8d819b..bf31728a6 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] + - Change `hf mf dump --ns` - dump command now supports `no save` of MFC card memory (@iceman1001) - Added `hf mf gdmsetcfg` - Supprt Gen4 GDM write configuration block (@iceman1001) - Added `hf mf gdmcfg` - Support Gen4 GDM read configuration block (@iceman1001) - Changed magic note to include a section about GDM tags (@iceman1001) From 222ef4e084d969012c1ddf1fe1ea09145d230a58 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 1 Apr 2023 12:24:32 +0200 Subject: [PATCH 753/759] addded static encrypted nonce checks to nested --- armsrc/mifarecmd.c | 33 +++++++++++++++++++++++++++++++-- client/src/cmdhfmf.c | 29 ++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 7eaad3e23..918e977bd 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1154,7 +1154,12 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, } memcpy(prev_enc_nt, receivedAnswer, 4); if (prev_counter == 5) { - if (g_dbglevel >= DBG_EXTENDED) DbpString("Static encrypted nonce detected, exiting..."); + if (g_dbglevel >= DBG_EXTENDED) { + DbpString("Static encrypted nonce detected, exiting..."); + uint32_t a = bytes_to_num(prev_enc_nt, 4); + uint32_t b = bytes_to_num(receivedAnswer, 4); + Dbprintf("( %08x vs %08x )", a, b); + } isOK = PM3_ESTATIC_NONCE; break; } @@ -1224,6 +1229,9 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 LED_B_ON(); WDT_HIT(); + uint8_t prev_enc_nt[] = {0, 0, 0, 0}; + uint8_t prev_counter = 0; + uint16_t unsuccessful_tries = 0; uint16_t davg = 0; dmax = 0; @@ -1266,11 +1274,13 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 }; // cards with fixed nonce + /* if (nt1 == nt2) { Dbprintf("Nested: %08x vs %08x", nt1, nt2); break; } - + */ + uint32_t nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160 for (i = 101; i < 1200; i++) { nttmp = prng_successor(nttmp, 1); @@ -1292,6 +1302,25 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 isOK = PM3_EFAILED; } } + + if (prev_enc_nt[0] == receivedAnswer[0] && + prev_enc_nt[1] == receivedAnswer[1] && + prev_enc_nt[2] == receivedAnswer[2] && + prev_enc_nt[3] == receivedAnswer[3] + ) { + prev_counter++; + } + memcpy(prev_enc_nt, receivedAnswer, 4); + if (prev_counter == 5) { + if (g_dbglevel >= DBG_EXTENDED) { + DbpString("Static encrypted nonce detected, exiting..."); + uint32_t a = bytes_to_num(prev_enc_nt, 4); + uint32_t b = bytes_to_num(receivedAnswer, 4); + Dbprintf("( %08x vs %08x )", a, b); + } + isOK = PM3_ESTATIC_NONCE; + break; + } } if (rtr > 1) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index e4b15c19e..725a3dff4 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1528,7 +1528,7 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't PrintAndLogEx(ERR, "Command execute timeout\n"); break; case PM3_EOPABORTED: - PrintAndLogEx(WARNING, "Button pressed. Aborted.\n"); + PrintAndLogEx(WARNING, "Button pressed. Aborted\n"); break; case PM3_EFAILED: PrintAndLogEx(FAILED, "Tag isn't vulnerable to Nested Attack (PRNG is not predictable).\n"); @@ -1536,6 +1536,9 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't case PM3_ESOFT: PrintAndLogEx(FAILED, "No valid key found"); break; + case PM3_ESTATIC_NONCE: + PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); + break; case PM3_SUCCESS: key64 = bytes_to_num(keyBlock, 6); @@ -1560,7 +1563,7 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't } return PM3_SUCCESS; default : - PrintAndLogEx(ERR, "Unknown error.\n"); + PrintAndLogEx(ERR, "Unknown error\n"); } return PM3_SUCCESS; @@ -1608,15 +1611,18 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't PrintAndLogEx(ERR, "Command execute timeout\n"); break; case PM3_EOPABORTED: - PrintAndLogEx(WARNING, "button pressed. Aborted.\n"); + PrintAndLogEx(WARNING, "button pressed. Aborted\n"); break; case PM3_EFAILED : - PrintAndLogEx(FAILED, "Tag isn't vulnerable to Nested Attack (PRNG is not predictable).\n"); + PrintAndLogEx(FAILED, "Tag isn't vulnerable to Nested Attack (PRNG is not predictable)\n"); break; case PM3_ESOFT: //key not found calibrate = false; continue; + case PM3_ESTATIC_NONCE: + PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); + break; case PM3_SUCCESS: calibrate = false; e_sector[sectorNo].foundKey[trgKeyType] = 1; @@ -1625,7 +1631,7 @@ static int CmdHF14AMfNested(const char *Cmd) { //TODO: single mode broken? can't mfCheckKeys_fast(SectorsCnt, true, true, 2, 1, keyBlock, e_sector, false); continue; default : - PrintAndLogEx(ERR, "Unknown error.\n"); + PrintAndLogEx(ERR, "Unknown error\n"); } free(e_sector); return PM3_ESOFT; @@ -2179,13 +2185,13 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { if (isOK) { switch (isOK) { case PM3_ETIMEOUT : - PrintAndLogEx(ERR, "Error: No response from Proxmark3.\n"); + PrintAndLogEx(ERR, "Error: No response from Proxmark3\n"); break; case PM3_EOPABORTED: - PrintAndLogEx(WARNING, "Button pressed. Aborted.\n"); + PrintAndLogEx(WARNING, "Button pressed. Aborted\n"); break; case PM3_ESTATIC_NONCE: - PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted.\n"); + PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); break; default : break; @@ -2841,6 +2847,11 @@ tryNested: } break; } + case PM3_ESTATIC_NONCE: + PrintAndLogEx(ERR, "Error: Static encrypted nonce detected. Aborted\n"); + free(e_sector); + free(fptr); + return isOK; case PM3_SUCCESS: { calibrate = false; e_sector[current_sector_i].Key[current_key_type_i] = bytes_to_num(tmp_key, 6); @@ -2878,7 +2889,7 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack break; } case PM3_ESTATIC_NONCE: { - PrintAndLogEx(ERR, "\nError: Static encrypted nonce detected. Aborted.\n"); + PrintAndLogEx(ERR, "\nError: Static encrypted nonce detected. Aborted\n"); break; } default: { From 6e0a6aa1e630c6863e81aace77f20278ca1fbd71 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 1 Apr 2023 12:43:34 +0200 Subject: [PATCH 754/759] fix detection --- armsrc/mifarecmd.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 918e977bd..f5e88a34c 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1229,7 +1229,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 LED_B_ON(); WDT_HIT(); - uint8_t prev_enc_nt[] = {0, 0, 0, 0}; + uint32_t prev_enc_nt = 0; uint8_t prev_counter = 0; uint16_t unsuccessful_tries = 0; @@ -1303,20 +1303,16 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 } } - if (prev_enc_nt[0] == receivedAnswer[0] && - prev_enc_nt[1] == receivedAnswer[1] && - prev_enc_nt[2] == receivedAnswer[2] && - prev_enc_nt[3] == receivedAnswer[3] - ) { + + if (nt1 == nt2) { prev_counter++; } - memcpy(prev_enc_nt, receivedAnswer, 4); + prev_enc_nt = nt2; + if (prev_counter == 5) { if (g_dbglevel >= DBG_EXTENDED) { DbpString("Static encrypted nonce detected, exiting..."); - uint32_t a = bytes_to_num(prev_enc_nt, 4); - uint32_t b = bytes_to_num(receivedAnswer, 4); - Dbprintf("( %08x vs %08x )", a, b); + Dbprintf("( %08x vs %08x )", prev_enc_nt, nt2); } isOK = PM3_ESTATIC_NONCE; break; From 3524306bf48f73e15749ade6b0ebf85a5c6f6cef Mon Sep 17 00:00:00 2001 From: AloneLiberty <111039319+AloneLiberty@users.noreply.github.com> Date: Sat, 1 Apr 2023 20:49:15 +0300 Subject: [PATCH 755/759] Implement transfer to other block in `hf mf value` --- CHANGELOG.md | 1 + armsrc/appmain.c | 2 +- armsrc/mifarecmd.c | 26 ++++++- armsrc/mifarecmd.h | 2 +- armsrc/mifareutil.c | 9 +-- client/src/cmdhfmf.c | 163 +++++++++++++++++++++++++++---------------- 6 files changed, 133 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf31728a6..22850bbae 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] + - Changed `hf mf value` - ability to use transfer on different block (@AloneLiberty) - Change `hf mf dump --ns` - dump command now supports `no save` of MFC card memory (@iceman1001) - Added `hf mf gdmsetcfg` - Supprt Gen4 GDM write configuration block (@iceman1001) - Added `hf mf gdmcfg` - Support Gen4 GDM read configuration block (@iceman1001) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 6901973f2..ebc7ecb27 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1584,7 +1584,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_MIFARE_VALUE: { - MifareValue(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); + MifareValue(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); break; } case CMD_HF_MIFAREU_WRITEBL: { diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index f5e88a34c..3cc8b1937 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -642,21 +642,28 @@ OUT: } -void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t *datain) { +void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { // params uint8_t blockNo = arg0; uint8_t keyType = arg1; + uint8_t transferKeyType = arg2; uint64_t ui64Key = 0; + uint64_t transferUi64Key = 0; uint8_t blockdata[16] = {0x00}; ui64Key = bytes_to_num(datain, 6); - memcpy(blockdata, datain + 10, 16); + memcpy(blockdata, datain + 11, 16); + transferUi64Key = bytes_to_num(datain + 27, 6); // variables uint8_t action = datain[9]; + uint8_t transferBlk = datain[10]; + bool needAuth = datain[33]; uint8_t isOK = 0; uint8_t uid[10] = {0x00}; uint32_t cuid = 0; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; + uint8_t len = 0; struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; pcs = &mpcs; @@ -686,6 +693,21 @@ void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t *datain) { break; }; + if (needAuth) { + // transfer to other sector + if (mifare_classic_auth(pcs, cuid, transferBlk, transferKeyType, transferUi64Key, AUTH_NESTED)) { + if (g_dbglevel >= DBG_ERROR) Dbprintf("Nested auth error"); + break; + } + } + + // send transfer (commit the change) + len = mifare_sendcmd_short(pcs, 1, MIFARE_CMD_TRANSFER, (transferBlk != 0) ? transferBlk : blockNo, receivedAnswer, NULL, NULL); + if (len != 1 && receivedAnswer[0] != 0x0A) { // 0x0a - ACK + if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error in transfer: %02x", receivedAnswer[0]); + break; + } + if (mifare_classic_halt(pcs, cuid)) { if (g_dbglevel >= DBG_ERROR) Dbprintf("Halt error"); break; diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 415e0333d..a6623c006 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -26,7 +26,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes); void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain); void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); -void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t *datain); +void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain); void MifareUWriteBlockCompat(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 6f8acc348..668a544b5 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -533,6 +533,8 @@ int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo if (action == 0x01) command = MIFARE_CMD_DEC; + if (action == 0x02) + command = MIFARE_CMD_RESTORE; // Send increment or decrement command len = mifare_sendcmd_short(pcs, 1, command, blockNo, receivedAnswer, receivedAnswerPar, NULL); @@ -567,13 +569,6 @@ int mifare_classic_value(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd send data2 Error: %02x", res); return 2; } - } else { - // send trnasfer (commit the change) - len = mifare_sendcmd_short(pcs, 1, MIFARE_CMD_TRANSFER, blockNo, receivedAnswer, receivedAnswerPar, NULL); - if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK - if (g_dbglevel >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); - return 1; - } } return 0; diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 725a3dff4..233d403ee 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -7802,24 +7802,30 @@ static int CmdHF14AMfValue(const char *Cmd) { "hf mf value --blk 16 -k FFFFFFFFFFFF --inc 10\n" "hf mf value --blk 16 -k FFFFFFFFFFFF -b --dec 10\n" "hf mf value --blk 16 -k FFFFFFFFFFFF -b --get\n" + "hf mf value --blk 16 -k FFFFFFFFFFFF --res --transfer 30 --tk FFFFFFFFFFFF --> transfer block 16 value to block 30 (even if block can't be incremented by ACL)\n" "hf mf value --get -d 87D612007829EDFF87D6120011EE11EE\n" - ); + ); void *argtable[] = { - arg_param_begin, - arg_str0("k", "key", "", "key, 6 hex bytes"), - arg_lit0("a", NULL, "input key type is key A (def)"), - arg_lit0("b", NULL, "input key type is key B"), - arg_u64_0(NULL, "inc", "", "Incremenet value by X (0 - 2147483647)"), - arg_u64_0(NULL, "dec", "", "Dcrement value by X (0 - 2147483647)"), - arg_u64_0(NULL, "set", "", "Set value to X (-2147483647 - 2147483647)"), - arg_lit0(NULL, "get", "Get value from block"), - arg_int0(NULL, "blk", "", "block number"), - arg_str0("d", "data", "", "block data to extract values from (16 hex bytes)"), - arg_param_end + arg_param_begin, + arg_str0("k", "key", "", "key, 6 hex bytes"), + arg_lit0("a", NULL, "input key type is key A (def)"), + arg_lit0("b", NULL, "input key type is key B"), + arg_u64_0(NULL, "inc", "", "Increment value by X (0 - 2147483647)"), + arg_u64_0(NULL, "dec", "", "Decrement value by X (0 - 2147483647)"), + arg_u64_0(NULL, "set", "", "Set value to X (-2147483647 - 2147483647)"), + arg_u64_0(NULL, "transfer", "", "Transfer value to other block (after inc/dec/restore)"), + arg_str0(NULL, "tkey", "", "transfer key, 6 hex bytes (if transfer is preformed to other sector)"), + arg_lit0(NULL, "ta", "transfer key type is key A (def)"), + arg_lit0(NULL, "tb", "transfer key type is key B"), + arg_lit0(NULL, "get", "Get value from block"), + arg_lit0(NULL, "res", "Restore (copy value to card buffer, should be used with --transfer)"), + arg_int0(NULL, "blk", "", "block number"), + arg_str0("d", "data", "", "block data to extract values from (16 hex bytes)"), + arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); - uint8_t blockno = (uint8_t)arg_get_int_def(ctx, 8, 1); + uint8_t blockno = (uint8_t)arg_get_int_def(ctx, 13, 1); uint8_t keytype = MF_KEY_A; if (arg_get_lit(ctx, 2) && arg_get_lit(ctx, 3)) { @@ -7830,29 +7836,44 @@ static int CmdHF14AMfValue(const char *Cmd) { keytype = MF_KEY_B;; } + uint8_t transferkeytype = MF_KEY_A; + if (arg_get_lit(ctx, 9) && arg_get_lit(ctx, 10)) { + CLIParserFree(ctx); + PrintAndLogEx(WARNING, "Input key type must be A or B"); + return PM3_EINVARG; + } else if (arg_get_lit(ctx, 10)) { + keytype = MF_KEY_B;; + } + int keylen = 0; uint8_t key[6] = {0}; CLIGetHexWithReturn(ctx, 1, key, &keylen); + int transferkeylen = 0; + uint8_t transferkey[6] = {0}; + CLIGetHexWithReturn(ctx, 8, transferkey, &transferkeylen); + /* Value /Value Value BLK /BLK BLK /BLK 00000000 FFFFFFFF 00000000 10 EF 10 EF - BLK is used to referece where the backup come from, I suspect its just the current block for the actual value ? + BLK is used to reference where the backup come from, I suspect it's just the current block for the actual value ? increment and decrement are an unsigned value set value is a signed value - We are getting signed and/or bigger values to allow a defult to be set meaning users did not supply that option. + We are getting signed and/or bigger values to allow a default to be set meaning users did not supply that option. */ int64_t incval = (int64_t)arg_get_u64_def(ctx, 4, -1); // Inc by -1 is invalid, so not set. - int64_t decval = (int64_t)arg_get_u64_def(ctx, 5, -1); // Inc by -1 is invalid, so not set. + int64_t decval = (int64_t)arg_get_u64_def(ctx, 5, -1); // Dec by -1 is invalid, so not set. int64_t setval = (int64_t)arg_get_u64_def(ctx, 6, 0x7FFFFFFFFFFFFFFF); // out of bounds (for int32) so not set - bool getval = arg_get_lit(ctx, 7); + int64_t trnval = (int64_t)arg_get_u64_def(ctx, 7, -1); // block to transfer to + bool getval = arg_get_lit(ctx, 11); + bool resval = arg_get_lit(ctx, 12); int dlen = 0; uint8_t data[16] = {0}; - CLIGetHexWithReturn(ctx, 9, data, &dlen); + CLIGetHexWithReturn(ctx, 14, data, &dlen); CLIParserFree(ctx); - uint8_t action = 3; // 0 Increment, 1 - Decrement, 2 - Set, 3 - Get, 4 - Decode from data + uint8_t action = 4; // 0 Increment, 1 - Decrement, 2 - Restore, 3 - Set, 4 - Get, 5 - Decode from data uint32_t value = 0; // Need to check we only have 1 of inc/dec/set and get the value from the selected option @@ -7880,7 +7901,7 @@ static int CmdHF14AMfValue(const char *Cmd) { if (setval != 0x7FFFFFFFFFFFFFFF) { optionsprovided++; - action = 2; + action = 3; if ((setval < -2147483647) || (setval > 2147483647)) { PrintAndLogEx(WARNING, "set value must be between -2147483647 and 2147483647. Got %lli", setval); return PM3_EINVARG; @@ -7888,9 +7909,19 @@ static int CmdHF14AMfValue(const char *Cmd) { value = (uint32_t)setval; } + if (resval) { + if (trnval == -1) { + PrintAndLogEx(WARNING, "You can't use restore without using transfer"); + return PM3_EINVARG; + } + + optionsprovided++; + action = 2; + } + if (dlen != 0) { optionsprovided++; - action = 4; + action = 5; if (dlen != 16) { PrintAndLogEx(WARNING, "date length must be 16 hex bytes long, got %d", dlen); return PM3_EINVARG; @@ -7902,49 +7933,59 @@ static int CmdHF14AMfValue(const char *Cmd) { return PM3_EINVARG; } - // dont want to write value data and break something - if ((blockno == 0) || (mfIsSectorTrailer(blockno))) { - PrintAndLogEx(WARNING, "invlaid block number, should be a data block "); + if (trnval != -1 && action > 2) { + PrintAndLogEx(WARNING, "You can't use transfer without using --inc, --dec or --res"); return PM3_EINVARG; } - if (action < 3) { + if (trnval != -1 && transferkeylen == 0 && mfSectorNum(trnval) != mfSectorNum(blockno)) { + PrintAndLogEx(WARNING, "Transfer is preformed to other sector, but no key for new sector provided"); + return PM3_EINVARG; + } + // don't want to write value data and break something + if ((blockno == 0) || (mfIsSectorTrailer(blockno)) || (trnval == 0) || (trnval != -1 && mfIsSectorTrailer(trnval))) { + PrintAndLogEx(WARNING, "invalid block number, should be a data block"); + return PM3_EINVARG; + } + + if (action < 4) { + uint8_t isok = true; if (g_session.pm3_present == false) return PM3_ENOTTY; - - if (action <= 1) { // increment/decrement value + // 0 Increment, 1 - Decrement, 2 - Restore, 3 - Set, 4 - Get, 5 - Decode from data + if (action <= 2) { // increment/decrement/restore value uint8_t block[MFBLOCK_SIZE] = {0x00}; memcpy(block, (uint8_t *)&value, 4); - uint8_t cmddata[26]; + uint8_t cmddata[34]; memcpy(cmddata, key, sizeof(key)); // Key == 6 data went to 10, so lets offset 9 for inc/dec if (action == 0) - PrintAndLogEx(INFO, "value increment by : %d", value); - else - PrintAndLogEx(INFO, "value decrement by : %d", value); + PrintAndLogEx(INFO, "Value incremented by : %d", value); + if (action == 1) + PrintAndLogEx(INFO, "Value decremented by : %d", value); - PrintAndLogEx(INFO, "Writing block no %d, key %c - %s", blockno, (keytype == MF_KEY_B) ? 'B' : 'A', sprint_hex_inrow(key, sizeof(key))); - - cmddata[9] = action; // 00 if increment, 01 if decrement. - memcpy(cmddata + 10, block, sizeof(block)); + cmddata[9] = action; // 00 if increment, 01 if decrement, 02 if restore + if (trnval != -1) { + cmddata[10] = trnval; // transfer to block + memcpy(cmddata + 27, transferkey, sizeof(transferkey)); + if (mfSectorNum(trnval) != mfSectorNum(blockno)) + cmddata[33] = 1; // should send nested auth + PrintAndLogEx(INFO, "Transfer block no %d to block %d", blockno, trnval); + } else { + cmddata[10] = 0; + PrintAndLogEx(INFO, "Writing block no %d, key %c - %s", blockno, (keytype == MF_KEY_B) ? 'B' : 'A', sprint_hex_inrow(key, sizeof(key))); + } + memcpy(cmddata + 11, block, sizeof(block)); clearCommandBuffer(); - SendCommandMIX(CMD_HF_MIFARE_VALUE, blockno, keytype, 0, cmddata, sizeof(cmddata)); + SendCommandMIX(CMD_HF_MIFARE_VALUE, blockno, keytype, transferkeytype, cmddata, sizeof(cmddata)); PacketResponseNG resp; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { PrintAndLogEx(FAILED, "Command execute timeout"); return PM3_ETIMEOUT; } - - if (resp.oldarg[0] & 0xFF) { - // all ok so set flag to read current value - getval = true; - PrintAndLogEx(SUCCESS, "Update ( " _GREEN_("success") " )"); - } else { - PrintAndLogEx(FAILED, "Update ( " _RED_("failed") " )"); - } - + isok = resp.oldarg[0] & 0xff; } else { // set value // To set a value block (or setup) we can use the normal mifare classic write block // So build the command options can call CMD_HF_MIFARE_WRITEBL @@ -7969,17 +8010,14 @@ static int CmdHF14AMfValue(const char *Cmd) { PrintAndLogEx(FAILED, "Command execute timeout"); return PM3_ETIMEOUT; } - int status = resp.oldarg[0]; - if (status) { - // all ok so set flag to read current value - getval = true; - PrintAndLogEx(SUCCESS, "Update ( " _GREEN_("success") " )"); - } else if (status == PM3_ETEAROFF) { - // all ok so set flag to read current value - getval = true; - } else { - PrintAndLogEx(FAILED, "Update ( " _RED_("failed") " )"); - } + isok = resp.oldarg[0] & 0xff; + } + + if (isok) { + PrintAndLogEx(SUCCESS, "Update ... : " _GREEN_("success")); + getval = true; // all ok so set flag to read current value + } else { + PrintAndLogEx(FAILED, "Update ... : " _RED_("failed")); } } @@ -7988,10 +8026,17 @@ static int CmdHF14AMfValue(const char *Cmd) { int32_t readvalue; int res = -1; - if (action == 4) { - res = PM3_SUCCESS; // alread have data from command line + if (action == 5) { + res = PM3_SUCCESS; // already have data from command line } else { - res = mfReadBlock(blockno, keytype, key, data); + if (trnval == -1) { + res = mfReadBlock(blockno, keytype, key, data); + } else { + if (mfSectorNum(trnval) != mfSectorNum(blockno)) + res = mfReadBlock(trnval, transferkeytype, transferkey, data); + else + res = mfReadBlock(trnval, keytype, key, data); + } } if (res == PM3_SUCCESS) { From 0b106665d49706174ae007f130237be6cd5f418b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 2 Apr 2023 06:58:59 +0200 Subject: [PATCH 756/759] MFU ev1 adaptations --- armsrc/iso14443a.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index f5960626e..637215cc3 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1053,6 +1053,30 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r // some first pages of UL/NTAG dump is special data mfu_dump_t *mfu_header = (mfu_dump_t *) BigBuf_get_EM_addr(); *pages = MAX(mfu_header->pages, 15); + + // counters and tearing flags + // for old dumps with all zero headers, we need to set default values. + for (uint8_t i = 0; i < 3; i++) { + + counters[i] = le24toh(mfu_header->counter_tearing[i]); + + if (mfu_header->counter_tearing[i][3] != 0x00) { + tearings[i] = mfu_header->counter_tearing[i][3]; + } + } + + // GET_VERSION + if (memcmp(mfu_header->version, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) == 0) { + memcpy(rVERSION, "\x00\x04\x04\x02\x01\x00\x11\x03", 8); + } else { + memcpy(rVERSION, mfu_header->version, 8); + } + AddCrc14A(rVERSION, sizeof(rVERSION) - 2); + + // READ_SIG + memcpy(rSIGN, mfu_header->signature, 32); + AddCrc14A(rSIGN, sizeof(rSIGN) - 2); + } break; case 3: { // MIFARE DESFire @@ -2577,7 +2601,7 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint uint8_t fudan_read[] = { 0x30, 0x01, 0x8B, 0xB9}; ReaderTransmit(fudan_read, sizeof(fudan_read), NULL); if (!ReaderReceive(resp, resp_par)) { - Dbprintf("Card didn't answer to select all"); + if (g_dbglevel >= DBG_INFO) Dbprintf("Card didn't answer to select all"); return 0; } @@ -2626,7 +2650,7 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint // SELECT_ALL ReaderTransmit(sel_all, sizeof(sel_all), NULL); if (!ReaderReceive(resp, resp_par)) { - Dbprintf("Card didn't answer to CL%i select all", cascade_level + 1); + if (g_dbglevel >= DBG_INFO) Dbprintf("Card didn't answer to CL%i select all", cascade_level + 1); return 0; } @@ -2704,7 +2728,7 @@ int iso14443a_select_cardEx(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint // Receive the SAK if (!ReaderReceive(resp, resp_par)) { - Dbprintf("Card didn't answer to select"); + if (g_dbglevel >= DBG_INFO) Dbprintf("Card didn't answer to select"); return 0; } sak = resp[0]; From bb4dad45d974b9cec9cd01578bd721363150c0b6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 2 Apr 2023 07:00:48 +0200 Subject: [PATCH 757/759] style --- armsrc/mifarecmd.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 3cc8b1937..3ae1933f4 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1356,10 +1356,13 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 LED_C_ON(); // get crypted nonces for target sector - for (i = 0; i < 2 && !isOK; i++) { // look for exactly two different nonces + for (i = 0; ((i < 2) && (isOK == PM3_SUCCESS)); i++) { + + // look for exactly two different nonces target_nt[i] = 0; - while (target_nt[i] == 0) { // continue until we have an unambiguous nonce + // continue until we have an unambiguous nonce + while (target_nt[i] == 0) { // Test if the action was cancelled if (BUTTON_PRESS() || data_available()) { @@ -1373,7 +1376,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 continue; } - if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { + if (iso14443a_select_card(uid, NULL, &cuid, true, 0, true) == false) { if (g_dbglevel >= DBG_INFO) Dbprintf("Nested: Can't select card"); continue; }; @@ -1452,6 +1455,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8 memcpy(payload.nt_b, &target_nt[1], 4); memcpy(payload.ks_b, &target_ks[1], 4); + LED_B_ON(); reply_ng(CMD_HF_MIFARE_NESTED, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload)); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); @@ -1497,7 +1501,7 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, continue; }; - // first colleciton + // first collection if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) { continue; }; @@ -1519,7 +1523,7 @@ void MifareStaticNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, nt2 = bytes_to_num(receivedAnswer, 4); target_ks[0] = nt2 ^ target_nt[0]; - // second colleciton + // second collection if (mifare_classic_halt(pcs, cuid)) { continue; @@ -2074,7 +2078,6 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) { uint64_t key = 0; uint32_t cuid = 0; - int i, res; uint8_t cascade_levels = 0; struct { uint8_t key[6]; @@ -2113,12 +2116,12 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) { set_tracing(false); - for (i = 0; i < key_count; i++) { + for (uint16_t i = 0; i < key_count; i++) { // Iceman: use piwi's faster nonce collecting part in hardnested. - if (!have_uid) { // need a full select cycle to get the uid first + if (have_uid == false) { // need a full select cycle to get the uid first iso14a_card_select_t card_info; - if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) { + if (iso14443a_select_card(uid, &card_info, &cuid, true, 0, true) == false) { if (g_dbglevel >= DBG_ERROR) Dbprintf("ChkKeys: Can't select card (ALL)"); --i; // try same key once again continue; @@ -2138,7 +2141,7 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) { } have_uid = true; } else { // no need for anticollision. We can directly select the card - if (!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels, true)) { + if (iso14443a_select_card(uid, NULL, NULL, false, cascade_levels, true) == false) { if (g_dbglevel >= DBG_ERROR) Dbprintf("ChkKeys: Can't select card (UID)"); --i; // try same key once again continue; @@ -2146,12 +2149,10 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) { } key = bytes_to_num(datain + i * 6, 6); - res = mifare_classic_auth(pcs, cuid, blockNo, keyType, key, AUTH_FIRST); - + if (mifare_classic_auth(pcs, cuid, blockNo, keyType, key, AUTH_FIRST)) { // CHK_TIMEOUT(); - - if (res) continue; + } memcpy(keyresult.key, datain + i * 6, 6); keyresult.found = true; @@ -2159,14 +2160,12 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) { } LED_B_ON(); + crypto1_deinit(pcs); reply_ng(CMD_HF_MIFARE_CHKKEYS, PM3_SUCCESS, (uint8_t *)&keyresult, sizeof(keyresult)); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - set_tracing(false); - crypto1_deinit(pcs); - g_dbglevel = oldbg; } From d33fbf1347fb8e361f475d909b5211e6a36411f5 Mon Sep 17 00:00:00 2001 From: Self Not Found Date: Thu, 6 Apr 2023 20:54:00 +0800 Subject: [PATCH 758/759] Fix units --- README.md | 8 ++-- bootrom/bootrom.c | 4 +- client/src/cmdhw.c | 2 +- doc/ext_flash_notes.md | 6 +-- .../4_Advanced-compilation-parameters.md | 42 +++++++++---------- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 3edd4e786..20416bdbb 100644 --- a/README.md +++ b/README.md @@ -102,21 +102,21 @@ We define generic Proxmark3 platforms as following devices. When it comes to these new unknown models we are depending on the community to report in if this repo works and what they did to make it work. -**256kb flash memory size of generic Proxmark3 platforms** +**256KB flash memory size of generic Proxmark3 platforms** > ⚠ **Note**: > You need to keep a eye on how large your ARM chip built-in flash memory is. -> With 512kb you are fine but if its 256kb you need to compile this repo with even less functionality. +> With 512KB you are fine but if its 256KB you need to compile this repo with even less functionality. > When running the `./pm3-flash-all` you can see which size your device have if you have the bootloader from this repo installed. > Otherwise you will find the size reported in the start message when running the Proxmark3 client `./pm3`. > -> [OBS! Read the 256kb flash memory advisory](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md#256kb-versions) +> [OBS! Read the 256KB flash memory advisory](/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md#256KB-versions) # What has changed? Proxmark3 RDV4 hardware modifications: - * added flash memory 256kb + * added flash memory 256KB * added smart card module * added FPC connector for peripherals such as Bluetooth+battery addon * improved antennas diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 9ca0dc430..4c87a65b0 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -310,10 +310,10 @@ void BootROM(void) { LED_B_OFF(); LED_A_OFF(); - // Set the first 256kb memory flashspeed + // Set the first 256KB memory flashspeed AT91C_BASE_EFC0->EFC_FMR = AT91C_MC_FWS_1FWS | MC_FLASH_MODE_MASTER_CLK_IN_MHZ(48); - // 9 = 256, 10+ is 512kb + // 9 = 256, 10+ is 512KB uint8_t id = (*(AT91C_DBGU_CIDR) & 0xF00) >> 8; if (id > 9) AT91C_BASE_EFC1->EFC_FMR = AT91C_MC_FWS_1FWS | MC_FLASH_MODE_MASTER_CLK_IN_MHZ(48); diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c index ed208b5f5..3ddd98189 100644 --- a/client/src/cmdhw.c +++ b/client/src/cmdhw.c @@ -133,7 +133,7 @@ static void lookup_chipid_short(uint32_t iChipID, uint32_t mem_used) { break; } - PrintAndLogEx(NORMAL, " Memory.... " _YELLOW_("%u") " Kb ( " _YELLOW_("%2.0f%%") " used )" + PrintAndLogEx(NORMAL, " Memory.... " _YELLOW_("%u") " KB ( " _YELLOW_("%2.0f%%") " used )" , mem_avail , mem_avail == 0 ? 0.0f : (float)mem_used / (mem_avail * 1024) * 100 ); diff --git a/doc/ext_flash_notes.md b/doc/ext_flash_notes.md index 4b2452d2f..d38b56de6 100644 --- a/doc/ext_flash_notes.md +++ b/doc/ext_flash_notes.md @@ -19,9 +19,9 @@ External 256kbytes flash is a unique feature of the RDV4 edition. Flash memory is -* 256kb (0x40000= 262144) -* divided into 4 pages of 64kb (0x10000 = 65536) -* 4 pages divided into 16 sectors of 4kb (0x1000 = 4096), so last sector is at 0x3F000 +* 256KB (0x40000= 262144) +* divided into 4 pages of 64KB (0x10000 = 65536) +* 4 pages divided into 16 sectors of 4KB (0x1000 = 4096), so last sector is at 0x3F000 Therefore a flash address can be interpreted as such: ``` diff --git a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md index fa1021d0c..5ead60b1a 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -10,7 +10,7 @@ - [PLATFORM](#platform) - [PLATFORM_EXTRAS](#platform_extras) - [STANDALONE](#standalone) - - [256kb versions](#256kb-versions) + - [256KB versions](#256KB-versions) - [Next step](#next-step) @@ -48,10 +48,10 @@ make SKIPBT=1 ## Firmware ^[Top](#top) -By default, the firmware is of course tuned for the Proxmark3 RDV4 device, which has built-in support for 256kb onboard flash SPI memory, Sim module (smart card support), FPC connector. +By default, the firmware is of course tuned for the Proxmark3 RDV4 device, which has built-in support for 256KB onboard flash SPI memory, Sim module (smart card support), FPC connector. These features make it very different from all other Proxmark3 devices, there is non other like this one. -**Recommendation**: if you don't have a RDV4, we strongly recommend your device to have at least a 512kb arm chip, since this repo is crossing 256kb limit. There is still a way to skip parts to make it fit on a 256kb device, see below. +**Recommendation**: if you don't have a RDV4, we strongly recommend your device to have at least a 512KB arm chip, since this repo is crossing 256KB limit. There is still a way to skip parts to make it fit on a 256KB device, see below. If you need to tune things and save the configuration, create a file `Makefile.platform` in the root directory of the repository, see `Makefile.platform.sample`. For an up-to-date exhaustive list of options, you can run `make PLATFORM=`. @@ -73,7 +73,7 @@ The MCU version (256 or 512) will be detected automatically during flashing. Known issues: -* 256kb Arm chip devices: The compiled firmware image from this repo may/will be too large for your device. +* 256KB Arm chip devices: The compiled firmware image from this repo may/will be too large for your device. * PM3 Evo: it has a different led/button pin assignment. It tends to be messed up. * Proxmark Pro: it has different fpga and unknown pin assignments. Unsupported. @@ -136,10 +136,10 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo By default `STANDALONE=LF_SAMYRUN`. -## 256kb versions +## 256KB versions ^[Top](#top) -If you own a Proxmark3 Easy with only 256kb, you can use a few definitions to help you getting a smaller firmware. +If you own a Proxmark3 Easy with only 256KB, you can use a few definitions to help you getting a smaller firmware. First thing is of course to use the `PLATFORM=PM3GENERIC`. Adding `PLATFORM_SIZE=256` will provoke an error during compilation of the recovery image if your image is too big, so you can detect the problem before trying to flash the Proxmark3, e.g. @@ -155,22 +155,22 @@ a series of `SKIP_*` allow to skip some of the functionalities and to get a smal | Definitions | Rough estimation of the saved space | |---------------------|-------------------------------------| -|STANDALONE= | 3.6kb -|SKIP_LF=1 | 25.8kb -|SKIP_HITAG=1 | 24.2kb -|SKIP_EM4x50=1 | 2.9kb -|SKIP_ISO15693=1 | 3.2kb -|SKIP_LEGICRF=1 | 3.9kb -|SKIP_ISO14443b=1 | 3.7kb -|SKIP_ISO14443a=1 | 63.0kb -|SKIP_ICLASS=1 | 10.5kb -|SKIP_FELICA=1 | 4.0kb -|SKIP_NFCBARCODE=1 | 1.4kb -|SKIP_HFSNIFF=1 | 0.5kb -|SKIP_HFPLOT=1 | 0.3kb -|SKIP_ZX8211=1 | 0.3kb +|STANDALONE= | 3.6KB +|SKIP_LF=1 | 25.8KB +|SKIP_HITAG=1 | 24.2KB +|SKIP_EM4x50=1 | 2.9KB +|SKIP_ISO15693=1 | 3.2KB +|SKIP_LEGICRF=1 | 3.9KB +|SKIP_ISO14443b=1 | 3.7KB +|SKIP_ISO14443a=1 | 63.0KB +|SKIP_ICLASS=1 | 10.5KB +|SKIP_FELICA=1 | 4.0KB +|SKIP_NFCBARCODE=1 | 1.4KB +|SKIP_HFSNIFF=1 | 0.5KB +|SKIP_HFPLOT=1 | 0.3KB +|SKIP_ZX8211=1 | 0.3KB -So for example, at the time of writing, this is a valid `Makefile.platform` compiling an image for 256k: +So for example, at the time of writing, this is a valid `Makefile.platform` compiling an image for 256KB: ``` PLATFORM=PM3GENERIC PLATFORM_SIZE=256 From 82fe8dbe36cddedccc7bccf3b8a6da887fdcadb8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 6 Apr 2023 19:32:07 +0200 Subject: [PATCH 759/759] fix some coverity findings --- client/src/cmdhfmf.c | 58 ++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 42436530a..adcb39d13 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -6627,30 +6627,33 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { bool reset_card = arg_get_lit(ctx, 1); uint8_t uid[4]; int uidlen = 0; - CLIParamHexToBuf(arg_get_str(ctx, 2), uid, sizeof(uid), &uidlen); + int res = CLIParamHexToBuf(arg_get_str(ctx, 2), uid, sizeof(uid), &uidlen); CLIParserFree(ctx); - if (uidlen && uidlen != 4) { + if (res || (!res && uidlen && uidlen != sizeof(uid))) { PrintAndLogEx(ERR, "UID must include 8 HEX symbols"); return PM3_EINVARG; } - uint32_t trace = 0; - uint8_t traces[7][16]; - for (trace = 0; trace < 7; trace++) { + #define SUPER_MAX_TRACES 7 + + uint8_t trace = 0; + uint8_t traces[SUPER_MAX_TRACES][16]; + + // read 7 traces from super card + for (trace = 0; trace < SUPER_MAX_TRACES; trace++) { + uint8_t data[] = {0x30, 0x00 + trace}; uint32_t flags = ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_RATS; - clearCommandBuffer(); - SendCommandOLD(CMD_HF_ISO14443A_READER, flags, sizeof(data), 0, data, sizeof(data)); - - if (!WaitForResponseTimeout(CMD_ACK, NULL, 1500)) { - break; // Select card + SendCommandMIX(CMD_HF_ISO14443A_READER, flags, sizeof(data), 0, data, sizeof(data)); + if (WaitForResponseTimeout(CMD_ACK, NULL, 1500) == false) { + break; } PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - break; // Data not received + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500) == false) { + break; } uint16_t len = resp.oldarg[0] & 0xFFFF; @@ -6661,13 +6664,17 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { memcpy(&traces[trace], resp.data.asBytes, len - 2); } - if (trace == 7) { + // Super card generation 2 + if (trace == SUPER_MAX_TRACES) { + + // no reset on super card generation 2. if (uidlen || reset_card) { PrintAndLogEx(FAILED, "Not supported on this card"); return PM3_SUCCESS; } - for (trace = 0; trace < 7; trace++) { + // recover key from collected traces + for (trace = 0; trace < SUPER_MAX_TRACES; trace++) { uint8_t *trace_data = traces[trace]; nonces_t data; @@ -6692,24 +6699,26 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { data.state = FIRST; uint64_t key64 = -1; - int res = mfkey32_moebius(&data, &key64); - - if (res) { + if (mfkey32_moebius(&data, &key64)) { PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ "_GREEN_("%012" PRIX64) " ]", sprint_hex_inrow(trace_data, 4), data.sector, (data.keytype == 0x60) ? 'A' : 'B', key64); break; } } } } + } else { + + // Super card generation 1 + // Commands: // a0 - set UID // b0 - read traces // c0 - clear card - bool activate_field = true; bool keep_field_on = true; - int res = 0; + + // change UID on a super card generation 1 if (uidlen) { keep_field_on = false; uint8_t response[6]; @@ -6730,6 +6739,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { return PM3_SUCCESS; } + // reset a super card generation 1 if (reset_card) { keep_field_on = false; uint8_t response[6]; @@ -6756,8 +6766,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { // --------------- First ---------------- uint8_t aFIRST[] = {0x00, 0xa6, 0xb0, 0x00, 0x10}; - res = ExchangeAPDU14a(aFIRST, sizeof(aFIRST), activate_field, keep_field_on, responseA, sizeof(responseA), - &respAlen); + res = ExchangeAPDU14a(aFIRST, sizeof(aFIRST), activate_field, keep_field_on, responseA, sizeof(responseA), &respAlen); if (res != PM3_SUCCESS) { DropField(); return res; @@ -6768,8 +6777,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { keep_field_on = false; uint8_t aSECOND[] = {0x00, 0xa6, 0xb0, 0x01, 0x10}; - res = ExchangeAPDU14a(aSECOND, sizeof(aSECOND), activate_field, keep_field_on, responseB, sizeof(responseB), - &respBlen); + res = ExchangeAPDU14a(aSECOND, sizeof(aSECOND), activate_field, keep_field_on, responseB, sizeof(responseB), &respBlen); if (res != PM3_SUCCESS) { DropField(); return res; @@ -6829,9 +6837,7 @@ static int CmdHf14AMfSuperCard(const char *Cmd) { PrintAndLogEx(DEBUG, "B AR %08x", data.ar2); uint64_t key64 = -1; - res = mfkey32_moebius(&data, &key64); - - if (res) { + if (mfkey32_moebius(&data, &key64)) { PrintAndLogEx(SUCCESS, "UID: %s Sector %02x key %c [ " _GREEN_("%012" PRIX64) " ]", sprint_hex_inrow(outA, 4), data.sector, (data.keytype == 0x60) ? 'A' : 'B', key64); } else { PrintAndLogEx(FAILED, "failed to recover any key");