From 39e7a58389bfc90e23548e7333067f3f34830a8d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 4 Mar 2021 09:53:01 +0100 Subject: [PATCH 01/34] default to oem 900 for C15001 format --- client/src/wiegand_formats.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/src/wiegand_formats.c b/client/src/wiegand_formats.c index d39d648cd..9dff61229 100644 --- a/client/src/wiegand_formats.c +++ b/client/src/wiegand_formats.c @@ -483,6 +483,9 @@ static bool Pack_C15001(wiegand_card_t *card, wiegand_message_t *packed, bool pr if (card->IssueLevel > 0) return false; // Not used in this format if (card->OEM > 0x000003FF) return false; // Can't encode OEM. + if (card->OEM == 0) + card->OEM = 900; + packed->Length = 36; // Set number of bits set_linear_field(packed, card->OEM, 1, 10); set_linear_field(packed, card->FacilityCode, 11, 8); From 9e07acbe8805177367de3998ffcaeb9415c0e052 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 4 Mar 2021 11:56:52 +0100 Subject: [PATCH 02/34] new icode slix2 signature --- tools/recover_pk.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/recover_pk.py b/tools/recover_pk.py index c71064cf3..0f01337a7 100755 --- a/tools/recover_pk.py +++ b/tools/recover_pk.py @@ -130,7 +130,8 @@ def selftests(): {'name': "ICODE DNA, ICODE SLIX2", # ! tag UID is considered inverted: E0040118009B5FEE => EE5F9B00180104E0 # TODO one more ICODE-DNA... - 'samples': ["EE5F9B00180104E0", "32D9E7579CD77E6F1FA11419231E874826984C5F189FDE1421684563A9663377"], + 'samples': ["EE5F9B00180104E0", "32D9E7579CD77E6F1FA11419231E874826984C5F189FDE1421684563A9663377", + "838ED22A080104E0", "CAE8183CB4823C765AFDEB78C9D66C959990FD52A5820E76E1D6E025D76EAD79"], 'pk': "048878A2A2D3EEC336B4F261A082BD71F9BE11C4E2E896648B32EFA59CEA6E59F0"}, # {'name': "Minecraft Earth", # # uses secp256r1?, SHA-256, From 3f300d917ec0e385376c9d86218cba8a3b56f806 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Mar 2021 10:15:22 +0100 Subject: [PATCH 03/34] maur --- 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 21319bc3e..15b70cddf 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -433,6 +433,9 @@ cc6b3b3cd263 157c9a513fa5 e2a5dc8e066f # +# Data from forum, schlage 9691T fob +ef1232ab18a0 +# # Data from a oyster card 374bf468607f bfc8e353af63 From 24ee8080e178e5df0a5b8a9895b07c378381d255 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Mar 2021 10:18:02 +0100 Subject: [PATCH 04/34] large dma size for demod signals --- armsrc/BigBuf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index ff444f3c8..6bdf4e331 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -19,7 +19,7 @@ #define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC #define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these #define CARD_MEMORY_SIZE 4096 -#define DMA_BUFFER_SIZE 256 +#define DMA_BUFFER_SIZE 512 // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits #define TOSEND_BUFFER_SIZE (9 * MAX_FRAME_SIZE + 1 + 1 + 2) From 4c845fb85950d440044172fdb1049288e81008d6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Mar 2021 10:18:34 +0100 Subject: [PATCH 05/34] endless happiness --- client/src/uart/uart_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/uart/uart_posix.c b/client/src/uart/uart_posix.c index 406bf6d7c..4a41b7958 100644 --- a/client/src/uart/uart_posix.c +++ b/client/src/uart/uart_posix.c @@ -130,7 +130,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed) { portstr = colon + 1; *colon = '\0'; } else { - portstr = "7901"; + portstr = "18888"; } struct addrinfo info; From 3275decfb091b6ed92a41df1729733eaee7e27c7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Mar 2021 10:21:02 +0100 Subject: [PATCH 06/34] cppchecker --- armsrc/hitag2.c | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 66b3f4573..c2916bfe2 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -53,13 +53,21 @@ static bool bCollision; static bool bPwd; static bool bSuccessful; +/* +Password Mode : 0x06 - 0000 0110 +Crypto Mode : 0x0E - 0000 1110 +Public Mode A : 0x02 - 0000 0010 +Public Mode B : 0x00 - 0000 0000 +Public Mode C : 0x04 - 0000 0100 +*/ + static struct hitag2_tag tag = { .state = TAG_STATE_RESET, - .sectors = { // Password mode: | Crypto mode: + .sectors = { // Password mode: | Crypto mode: [0] = { 0x02, 0x4e, 0x02, 0x20}, // UID | UID [1] = { 0x4d, 0x49, 0x4b, 0x52}, // Password RWD | 32 bit LSB key [2] = { 0x20, 0xf0, 0x4f, 0x4e}, // Reserved | 16 bit MSB key, 16 bit reserved - [3] = { 0x0e, 0xaa, 0x48, 0x54}, // Configuration, password TAG | Configuration, password TAG + [3] = { 0x06, 0xaa, 0x48, 0x54}, // Configuration, password TAG | Configuration, password TAG [4] = { 0x46, 0x5f, 0x4f, 0x4b}, // Data: F_OK [5] = { 0x55, 0x55, 0x55, 0x55}, // Data: UUUU [6] = { 0xaa, 0xaa, 0xaa, 0xaa}, // Data: .... @@ -91,7 +99,7 @@ static uint8_t key[8]; static uint8_t writedata[4]; static uint8_t logdata_0[4], logdata_1[4]; static uint8_t nonce[4]; -static bool key_no; +static uint8_t key_no; static uint64_t cipher_state; static int16_t blocknr; @@ -375,16 +383,15 @@ static uint32_t hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) return wait; } -static uint8_t hitag_crc(uint8_t *data, size_t length) { - uint8_t crc = 0xff; - unsigned int byte, bit; - for (byte = 0; byte < ((length + 7) / 8); byte++) { - crc ^= *(data + byte); - bit = length < (8 * (byte + 1)) ? (length % 8) : 8; +static uint8_t hitag_crc(uint8_t *data, size_t n) { + uint8_t crc = 0xFF; + for (size_t i = 0; i < ((n + 7) / 8); i++) { + crc ^= *(data + i); + uint8_t bit = n < (8 * (i + 1)) ? (n % 8) : 8; while (bit--) { if (crc & 0x80) { crc <<= 1; - crc ^= 0x1d; + crc ^= 0x1D; } else { crc <<= 1; } @@ -414,7 +421,6 @@ void fix_ac_decoding(uint8_t *input, size_t len) { // 0 = collision? // 32 = good response static bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) { - uint8_t crc; *txlen = 0; switch (rxlen) { case 0: { @@ -435,6 +441,7 @@ static bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *tx return true; } case 32: { + uint8_t crc; if (bCollision) { // Select card by serial from response tx[0] = 0x00 | rx[0] >> 5; @@ -1001,7 +1008,6 @@ void SniffHitag2(void) { g_logging = false; - size_t periods = 0; uint8_t periods_bytes[4]; // int16_t checked = 0; @@ -1010,7 +1016,7 @@ void SniffHitag2(void) { LED_C_ON(); uint32_t signal_size = 10000; - while (!BUTTON_PRESS()) { + while (BUTTON_PRESS() == false) { // use malloc initSampleBufferEx(&signal_size, false); @@ -1035,7 +1041,7 @@ void SniffHitag2(void) { // lf_reset_counter(); // Wait "infinite" for reader modulation - periods = lf_detect_gap(10000); + size_t periods = lf_detect_gap(10000); // Test if we detected the first reader modulation edge if (periods != 0) { @@ -1070,9 +1076,7 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { int response = 0; uint8_t rx[HITAG_FRAME_LEN] = {0}; - size_t rxlen = 0; uint8_t tx[HITAG_FRAME_LEN] = {0}; - size_t txlen = 0; auth_table_len = 0; auth_table_pos = 0; @@ -1106,10 +1110,8 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { Dbprintf("| %d | %08x |", i, block); } - uint8_t reader_modulation; size_t max_nrzs = 8 * HITAG_FRAME_LEN + 5; uint8_t nrz_samples[max_nrzs]; - size_t nrzs = 0, periods = 0; // uint32_t command_start = 0, command_duration = 0; // int16_t checked = 0; @@ -1139,8 +1141,7 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { } ++checked; */ - - rxlen = 0; + size_t rxlen = 0, txlen = 0; // Keep administration of the first edge detection bool waiting_for_first_edge = true; @@ -1149,14 +1150,14 @@ void SimulateHitag2(bool tag_mem_supplied, uint8_t *data) { bool detected_modulation = false; // Use the current modulation state as starting point - reader_modulation = lf_get_reader_modulation(); + uint8_t reader_modulation = lf_get_reader_modulation(); // Receive frame, watch for at most max_nrzs periods // Reset the number of NRZ samples and use edge detection to detect them - nrzs = 0; + size_t nrzs = 0; while (nrzs < max_nrzs) { // Get the timing of the next edge in number of wave periods - periods = lf_count_edge_periods(128); + size_t periods = lf_count_edge_periods(128); // Just break out of loop after an initial time-out (tag is probably not available) // The function lf_count_edge_periods() returns 0 when a time-out occurs @@ -1336,7 +1337,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) { memset(logdata_1, 0x00, 4); byte_value = 0; key_no = htd->ht1auth.key_no; - DBG Dbprintf("Authenticating using key #%d:", key_no); + DBG Dbprintf("Authenticating using key #%u :", key_no); DBG Dbhexdump(4, key, false); DBG DbpString("Nonce:"); DBG Dbhexdump(4, nonce, false); From 928c0e41626a443b7e70e03a973a9dbafebbbec1 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Mar 2021 10:21:25 +0100 Subject: [PATCH 07/34] cppchecker overflow integer warning --- armsrc/iso14443b.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index c3c61e980..09c5e775e 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -41,7 +41,7 @@ // defaults to 2000ms #ifndef FWT_TIMEOUT_14B -# define FWT_TIMEOUT_14B 35312 +# define FWT_TIMEOUT_14B 35312U #endif // 1 tick == 1/13.56 mhz @@ -178,7 +178,7 @@ static void CodeIso14443bAsTag(const uint8_t *cmd, int len) { // Send TR1. // 10-11 ETU * 4times samples ONES - for (i = 0; i < 20; i++) { + for (i = 0; i < 10; i++) { SEND4STUFFBIT(1); } @@ -321,7 +321,7 @@ static void Demod14bInit(uint8_t *data, uint16_t max_len) { * @param timeout is in frame wait time, fwt, measured in ETUs */ static void iso14b_set_timeout(uint32_t timeout) { -#define MAX_TIMEOUT 40542464 // 13560000Hz * 1000ms / (2^32-1) * (8*16) +#define MAX_TIMEOUT 40542464U // 13560000Hz * 1000ms / (2^32-1) * (8*16) if (timeout > MAX_TIMEOUT) timeout = MAX_TIMEOUT; From f61d19276ba17091742c7a56c70e6eb2c26af007 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Mar 2021 10:22:12 +0100 Subject: [PATCH 08/34] cppchecker --- include/hitag.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hitag.h b/include/hitag.h index 14231bdeb..168d3f439 100644 --- a/include/hitag.h +++ b/include/hitag.h @@ -50,7 +50,7 @@ typedef struct { } PACKED rht2d_crypto; typedef struct { - bool key_no; + uint8_t key_no; uint8_t logdata_0[4]; uint8_t logdata_1[4]; uint8_t nonce[4]; From 886104e4cb151a0f1bccd626e893ce5bb5801cf2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Mar 2021 10:22:35 +0100 Subject: [PATCH 09/34] cppchecker out-of-bounds, I believe it was a false positive but... --- armsrc/usart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/armsrc/usart.c b/armsrc/usart.c index 75b005b6d..c26a28ea8 100644 --- a/armsrc/usart.c +++ b/armsrc/usart.c @@ -146,9 +146,9 @@ uint32_t usart_read_ng(uint8_t *data, size_t len) { } len -= packetSize; while (packetSize--) { - data[bytes_rcv++] = us_rxfifo[us_rxfifo_low++]; if (us_rxfifo_low == sizeof(us_rxfifo)) us_rxfifo_low = 0; + data[bytes_rcv++] = us_rxfifo[us_rxfifo_low++]; } if (try++ == maxtry) { // Dbprintf_usb("Dbg USART TIMEOUT"); From 741604574785438d427bb4fc6b4e4253dba7e20a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Mar 2021 10:23:51 +0100 Subject: [PATCH 10/34] demonstrate amiitool integration with mfu commands. --- client/src/cmdhfmfu.c | 77 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 8227a55c0..4e4f5c6f4 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -23,6 +23,8 @@ #include "mifare/ndef.h" #include "cliparser.h" #include "cmdmain.h" +#include "amiibo.h" // amiiboo fcts +#include "base64.h" #define MAX_UL_BLOCKS 0x0F #define MAX_ULC_BLOCKS 0x2F @@ -3717,6 +3719,13 @@ static int CmdHF14AMfuEv1CounterTearoff(const char *Cmd) { */ +// +// name, identifying bytes, decode function, hints text +// identifying bits +// 1. getversion data must match. +// 2. magic bytes in the readable payload + + static int CmdHF14MfuNDEF(const char *Cmd) { int keylen; @@ -3845,6 +3854,25 @@ static int CmdHF14MfuNDEF(const char *Cmd) { } } } + char *mattel = strstr((char*)records, ".pid.mattel/"); + if (mattel) { + mattel += 12; + while (mattel) { + if ((*mattel) != '/') + mattel++; + else { + mattel++; + char b64[33] = {0}; + strncpy(b64, mattel, 32); + uint8_t arr[24] = {0}; + size_t arrlen = 0; + mbedtls_base64_decode(arr, sizeof(arr), &arrlen, (const unsigned char *)b64, 32); + + PrintAndLogEx(INFO, "decoded... %s", sprint_hex(arr, arrlen)); + break; + } + } + } free(records); return status; @@ -3893,17 +3921,57 @@ static int CmdHF14AMfuEView(const char *Cmd) { return PM3_SUCCESS; } +/* +static int CmdHF14AMfUCDecryptAmiibo(const char *Cmd){ + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfu decrypt", + "Tries to read all memory from amiibo tag and decrypt it", + "hf mfu decrypt" + ); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + + uint16_t elen = 0, dlen = 0; + uint8_t *encrypted = NULL; + + int res = mfu_dump_tag( MAX_NTAG_215, (void **)&encrypted, &elen); + if (res == PM3_SUCCESS) { + + PrintAndLogEx(INFO, "32 first bytes of tag dump"); + PrintAndLogEx(INFO, "%s", sprint_hex(encrypted, 32)); + PrintAndLogEx(INFO, "-----------------------"); + + uint8_t decrypted[NFC3D_AMIIBO_SIZE] = {0}; + res = mfu_decrypt_amiibo(encrypted, elen, decrypted, &dlen); + if ( res == PM3_SUCCESS) { + + for (uint8_t i = 0; i < dlen/16; i++ ) { + PrintAndLogEx(INFO, "[%d] %s", i, sprint_hex_ascii(decrypted + (i * 16), 16)); + } + } + free(encrypted); + } + return PM3_SUCCESS; +} +*/ + //------------------------------------ // Menu Stuff //------------------------------------ static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("recovery") " -----------------------"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("recovery") " -------------------------"}, {"keygen", CmdHF14AMfUGenDiverseKeys, AlwaysAvailable, "Generate 3DES MIFARE diversified keys"}, {"pwdgen", CmdHF14AMfUPwdGen, AlwaysAvailable, "Generate pwd from known algos"}, {"otptear", CmdHF14AMfuOtpTearoff, IfPm3Iso14443a, "Tear-off test on OTP bits"}, // {"tear_cnt", CmdHF14AMfuEv1CounterTearoff, IfPm3Iso14443a, "Tear-off test on Ev1/NTAG Counter bits"}, - {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("operations") " -----------------------"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("operations") " -----------------------"}, {"cauth", CmdHF14AMfUCAuth, IfPm3Iso14443a, "Authentication - Ultralight-C"}, {"dump", CmdHF14AMfUDump, IfPm3Iso14443a, "Dump MIFARE Ultralight family tag to binary file"}, {"info", CmdHF14AMfUInfo, IfPm3Iso14443a, "Tag information"}, @@ -3911,12 +3979,15 @@ static command_t CommandTable[] = { {"rdbl", CmdHF14AMfURdBl, IfPm3Iso14443a, "Read block"}, {"restore", CmdHF14AMfURestore, IfPm3Iso14443a, "Restore a dump onto a MFU MAGIC tag"}, {"wrbl", CmdHF14AMfUWrBl, IfPm3Iso14443a, "Write block"}, - {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"}, {"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "load Ultralight .eml dump file into emulator memory"}, {"eview", CmdHF14AMfuEView, IfPm3Iso14443a, "View emulator memory"}, {"sim", CmdHF14AMfUSim, IfPm3Iso14443a, "Simulate MIFARE Ultralight from emulator memory"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("magic") " ----------------------------"}, {"setpwd", CmdHF14AMfUCSetPwd, IfPm3Iso14443a, "Set 3DES key - Ultralight-C"}, {"setuid", CmdHF14AMfUCSetUid, IfPm3Iso14443a, "Set UID - MAGIC tags only"}, + {"-----------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("amiibo") " ----------------------------"}, +// {"decrypt", CmdHF14AMfUCDecryptAmiibo, IfPm3Iso14443a, "Decrypt a amiibo tag"}, {NULL, NULL, NULL, NULL} }; From 59a1f15f5d174b011b93472762583f27ec565d2c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Mar 2021 10:46:44 +0100 Subject: [PATCH 11/34] cryptoRF sniff of anticollision / select --- traces/hf_14b_cryptorf_select.trace | Bin 0 -> 217 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 traces/hf_14b_cryptorf_select.trace diff --git a/traces/hf_14b_cryptorf_select.trace b/traces/hf_14b_cryptorf_select.trace new file mode 100644 index 0000000000000000000000000000000000000000..410403190f594ca74f25c687dfe68ff335a94eb6 GIT binary patch literal 217 zcmX@Zqt7hD!^*(Qz)<*~;lK<%W`-Ah4FUflK#4&h(4vZgVTyqvvknh8gDe9Ga4<6L zp2NVfCFv=qAdB_{78xFP2CxY|o(w&n(^(Ma-?%q}MT3V6Vh+@pCDWW)k#!uH;LOTk e!Q8-5@qrm0{k@985a2)_8R6V)? literal 0 HcmV?d00001 From 89d2e4fe8f0fed549bc8b4bb21aea44f4c089fb4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Mar 2021 10:49:00 +0100 Subject: [PATCH 12/34] text --- traces/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/traces/README.md b/traces/README.md index b8d4d1c4d..9817b259e 100644 --- a/traces/README.md +++ b/traces/README.md @@ -89,4 +89,5 @@ |hf_14a_mfu.trace |Reading of a password-protected MFU| |hf_14a_mfu-sim.trace |Trace seen from a Proxmark3 simulating a MFU| |hf_14b_reader.trace |Execution of `hf 14b reader` against a card| -|hf_15_reader.trace |Execution of `hf 15 reader` against a card| +|hf_14b_cryptorf_select.trace |Sniff of libnfc select / anticollision ofa cryptoRF tag| +|hf_15_reader.trace |Execution of `hf 15 reader` against a card| \ No newline at end of file From 547e4624223716dd635906ce4dd88e1c7a3e22b9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 5 Mar 2021 12:55:28 +0100 Subject: [PATCH 13/34] spelling --- 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 9693d8803..2f5f037c3 100644 --- a/client/src/flash.c +++ b/client/src/flash.c @@ -412,7 +412,7 @@ static void flash_suggest_update_bootloader(void) { PrintAndLogEx(ERR, _RED_("reboot the Proxmark3 then only update the main firmware") "\n"); PrintAndLogEx(ERR, "Follow these steps :"); PrintAndLogEx(ERR, " 1) ./pm3-flash-bootrom"); - PrintAndLogEx(ERR, " 2) ./pm3-flash-flash-all"); + PrintAndLogEx(ERR, " 2) ./pm3-flash-all"); PrintAndLogEx(ERR, " 3) ./pm3"); PrintAndLogEx(INFO, "--------------------------------------------------------"); g_printed_msg = true; From 6aa9b98afce27cf810b414bc2c309d93a64b40c6 Mon Sep 17 00:00:00 2001 From: mwalker33 <51802811+mwalker33@users.noreply.github.com> Date: Sat, 6 Mar 2021 17:36:42 +1100 Subject: [PATCH 14/34] Update cmdlft55xx.c T55xx detect - set default to try all downlink modes - ensured when trying all downlink modes it starts at fixed bit. --- client/src/cmdlft55xx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 1c3993454..969eb46e1 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -997,10 +997,12 @@ static int CmdT55xxDetect(const char *Cmd) { downlink_mode = refLeading0; else if (r3) downlink_mode = ref1of4; - - if (ra) + else // This will set the default to user all d/l modes which will cover the ra flag as well. try_all_dl_modes = true; + // if (ra) + // try_all_dl_modes = true; + bool try_with_pwd = false; bool found = false; bool usewake = false; @@ -1026,9 +1028,9 @@ static int CmdT55xxDetect(const char *Cmd) { do { // do ... while to check without password then loop back if password supplied do { - if (try_all_dl_modes) { - for (uint8_t m = downlink_mode; m < 4; m++) { + // Loop from 1st d/l mode refFixedBit to the last d/l mode ref1of4 + for (uint8_t m = refFixedBit; m <= ref1of4; m++) { if (usewake) { // call wake if (try_with_pwd) From 17eefbcbb628ba4f5c5b61dae82f5dc9151578e7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sat, 6 Mar 2021 17:13:05 +0100 Subject: [PATCH 15/34] maur --- client/dictionaries/mfc_default_keys.dic | 72 ++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic index 15b70cddf..a0c8b9943 100644 --- a/client/dictionaries/mfc_default_keys.dic +++ b/client/dictionaries/mfc_default_keys.dic @@ -1296,3 +1296,75 @@ ff9a84635bd2 f1a1239a4487 # b882fd4a9f78 +CD7FFFF81C4A +AA0857C641A3 +C8AACD7CF3D1 +9FFDA233B496 +26B85DCA4321 +D4B2D140CB2D +A7395CCB42A0 +541C417E57C0 +D14E615E0545 +69D92108C8B5 +703265497350 +D75971531042 +10510049D725 +35C649004000 +5B0C7EC83645 +05F5EC05133C +521B517352C7 +94B6A644DFF6 +2CA4A4D68B8E +A7765C952DDF +E2F14D0A0E28 +DC018FC1D126 +4927C97F1D57 +046154274C11 +155332417E00 +6B13935CD550 +C151D998C669 +D973D917A4C7 +130662240200 +9386E2A48280 +52750A0E592A +541C417E57C0 +D14E615E0545 +075D1A4DD323 +32CA52054416 +460661C93045 +5429D67E1F57 +0C734F230E13 +1F0128447C00 +411053C05273 +42454C4C4147 +C428C4550A75 +730956C72BC2 +28D70900734C +4F75030AD12B +6307417353C1 +D65561530174 +D1F71E05AD9D +F7FA2F629BB1 +0E620691B9FE +43E69C28F08C +735175696421 +424C0FFBF657 +D01AFEEB890A +75CCB59C9BED +4B791BEA7BCC +51E97FFF51E9 +E7316853E731 +5C8FF9990DA2 +00460740D722 +35D152154017 +5D0762D13401 +0F35D5660653 +1170553E4304 +0C4233587119 +F678905568C3 +50240A68D1D8 +69D92108C8B5 +2E71D3BD262A +540D5E6355CC +D1417E431949 +4BF6DE347FB6 \ No newline at end of file From dff732840f9dfa0b05a30f16d80a625e478d73af Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 08:56:36 +0100 Subject: [PATCH 16/34] mem info - now accepts input id to facility easy testing. Signature offset also triggers erase before to enable easy updates --- armsrc/appmain.c | 4 +++ client/src/cmdflashmem.c | 64 +++++++++++++++++++++++++++++++--------- doc/ext_flash_notes.md | 9 +++--- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 6a6058d3b..d9162dda8 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2202,6 +2202,10 @@ static void PacketReceived(PacketCommandNG *packet) { Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable(); Flash_Erase4k(3, 0xB); + } else if (startidx == FLASH_MEM_SIGNATURE_OFFSET) { + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); + Flash_Erase4k(3, 0xF); } res = Flash_Write(startidx, data, len); diff --git a/client/src/cmdflashmem.c b/client/src/cmdflashmem.c index 23acad47d..2f807fa7f 100644 --- a/client/src/cmdflashmem.c +++ b/client/src/cmdflashmem.c @@ -39,7 +39,10 @@ static int CmdHelp(const char *Cmd); "9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33" \ "DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5" +//------------------------------------------------------------------------------------- +// Sample private RSA Key // Following example RSA-1024 keypair, for test purposes (from common/polarssl/rsa.c) + // private key - Exponent D #define RSA_D "24BF6185468786FDD303083D25E64EFC" \ "66CA472BC44D253102F8B4A9D3BFA750" \ @@ -445,29 +448,39 @@ static int CmdFlashMemInfo(const char *Cmd) { CLIParserInit(&ctx, "mem info", "Collect signature and verify it from flash memory", "mem info" -// "mem info -s" +// "mem info -s -d 0102030405060708" ); void *argtable[] = { arg_param_begin, -// arg_lit0("s", NULL, "create a signature"), -// arg_lit0("w", NULL, "write signature to flash memory"), + arg_lit0("s", "sign", "create a signature"), + arg_str0("d", NULL, "", "flash memory id, 8 hex bytes"), +// arg_lit0("w", "write", "write signature to flash memory"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); bool shall_sign = false, shall_write = false; -// shall_sign = arg_get_lit(ctx, 1); -// shall_write = arg_get_lit(ctx, 2); + shall_sign = arg_get_lit(ctx, 1); + + int dlen = 0; + uint8_t id[8] = {0}; + int res = CLIParamHexToBuf(arg_get_str(ctx, 2), id, sizeof(id), &dlen); + +// shall_write = arg_get_lit(ctx, 3); CLIParserFree(ctx); - // validate signature data + if (dlen > 0 && dlen < sizeof(id) ) { + PrintAndLogEx(FAILED, "Error parsing flash memory id, expect 8, got %d", dlen); + return PM3_EINVARG; + } + + // validate devicesignature data rdv40_validation_t mem; - int res = rdv4_get_signature(&mem); + res = rdv4_get_signature(&mem); if (res != PM3_SUCCESS) { return res; } - res = rdv4_validate(&mem); // Flash ID hash (sha1) @@ -479,6 +492,11 @@ static int CmdFlashMemInfo(const char *Cmd) { PrintAndLogEx(INFO, "--- " _CYAN_("Flash memory Information") " ---------"); PrintAndLogEx(INFO, "ID................... %s", sprint_hex_inrow(mem.flashid, sizeof(mem.flashid))); PrintAndLogEx(INFO, "SHA1................. %s", sprint_hex_inrow(sha_hash, sizeof(sha_hash))); + PrintAndLogEx( + (res == PM3_SUCCESS) ? SUCCESS : FAILED, + "Signature............ ( %s )", + (res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail") + ); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(INFO, "--- " _CYAN_("RDV4 RSA signature") " ---------------"); for (int i = 0; i < (sizeof(mem.signature) / 32); i++) { @@ -520,13 +538,21 @@ static int CmdFlashMemInfo(const char *Cmd) { PrintAndLogEx(INFO, " %.64s", str_pk + 192); PrintAndLogEx(NORMAL, ""); - bool is_keyok = (mbedtls_rsa_check_pubkey(&rsa) == 0 || mbedtls_rsa_check_privkey(&rsa) == 0); + bool is_keyok = (mbedtls_rsa_check_pubkey(&rsa) == 0); PrintAndLogEx( (is_keyok) ? SUCCESS : FAILED, - "RSA key validation... ( %s )", + "RSA public key validation.... ( %s )", (is_keyok) ? _GREEN_("ok") : _RED_("fail") ); + is_keyok = (mbedtls_rsa_check_privkey(&rsa) == 0); + PrintAndLogEx( + (is_keyok) ? SUCCESS : FAILED, + "RSA private key validation... ( %s )", + (is_keyok) ? _GREEN_("ok") : _RED_("fail") + ); + + // to be verified uint8_t from_device[RRG_RSA_KEY_LEN]; memcpy(from_device, mem.signature, RRG_RSA_KEY_LEN); @@ -537,6 +563,13 @@ static int CmdFlashMemInfo(const char *Cmd) { // Signing (private key) if (shall_sign) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Enter signing") " --------------------"); + + if (dlen == 8) { + mbedtls_sha1(id, sizeof(id), sha_hash); + } + PrintAndLogEx(INFO, "Signing %s", sprint_hex_inrow(sha_hash, sizeof(sha_hash))); int is_signed = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 20, sha_hash, sign); PrintAndLogEx( @@ -555,14 +588,17 @@ static int CmdFlashMemInfo(const char *Cmd) { } // Verify (public key) - int is_verified = mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device); + bool is_verified = (mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device) == 0); mbedtls_rsa_free(&rsa); PrintAndLogEx( - (is_verified == 0) ? SUCCESS : FAILED, - "RSA verification..... ( %s )", - (is_verified == 0) ? _GREEN_("ok") : _RED_("fail") + (is_verified) ? SUCCESS : FAILED, + "RSA verification..... ( %s )", + (is_verified) ? _GREEN_("ok") : _RED_("fail") ); + if (is_verified) { + PrintAndLogEx(SUCCESS, "Genuine Proxmark3 RDV4 signature detected"); + } PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; diff --git a/doc/ext_flash_notes.md b/doc/ext_flash_notes.md index 46059d9ca..f6e462421 100644 --- a/doc/ext_flash_notes.md +++ b/doc/ext_flash_notes.md @@ -39,8 +39,8 @@ Page 3: * used by Proxmark3 RDV4 specific functions: flash signature and keys dictionaries, see below for details * to dump it: `mem dump f page3_dump o 196608 l 65536` * to erase it: - * **Beware** it will erase your flash signature (see below) so better to back it up first as you won't be able to regenerate it by yourself! - * It's possible to erase completely page 3 by erase the entire flash memory with the voluntarily undocumented command `mem wipe i`. + * **Beware** it will erase your flash signature so better to back it up first as you won't be able to regenerate it by yourself! + * edit the source code to enable Page 3 as a valid input in the `mem wipe` command. * Updating keys dictionaries doesn't require to erase page 3. ## Page3 Layout @@ -64,7 +64,7 @@ Page3 is used as follows by the Proxmark3 RDV4 firmware: * length: 1 sector (actually only a few bytes are used to store `t55xx_config` structure) * **RSA SIGNATURE**, see below for details - * offset: page 3 sector 15 (0xF) offset 0xF7F @ 3*0x10000+15*0x1000+0xF7F=0x3FF7F + * offset: page 3 sector 15 (0xF) offset 0xF7F @ 3*0x10000+15*0x1000+0xF7F=0x3FF7F (decimal 262015) * length: 128 bytes * offset should have been 0x3FF80 but historically it's one byte off and therefore the last byte of the flash is unused @@ -91,5 +91,6 @@ You can verify it with: `mem info` [+] RSA Verification ok ``` -For a backup of the signature: `mem dump p f flash_signature_dump o 262015 l 128` +To make a backup of the signature to file: +`mem dump p f flash_signature_dump o 262015 l 128` From 14d62bf38046be7f3137bac3c7cfac19f378a09a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 08:58:16 +0100 Subject: [PATCH 17/34] some lf reader used this configblock, dont remember if it was discussed on forum or discord --- client/src/cmdlft55xx.h | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/cmdlft55xx.h b/client/src/cmdlft55xx.h index 83a35b848..1a31772eb 100644 --- a/client/src/cmdlft55xx.h +++ b/client/src/cmdlft55xx.h @@ -32,6 +32,7 @@ #define T55X7_NORALSY_CONFIG_BLOCK 0x00088C6A // ASK, compat mode, (NORALSY - KCP3000), data rate 32, 3 data blocks #define T55X7_PRESCO_CONFIG_BLOCK 0x00088088 // ASK, data rate 32, Manchester, 4 data blocks, STT #define T55X7_SECURAKEY_CONFIG_BLOCK 0x000C8060 // ASK, Manchester, data rate 40, 3 data blocks +#define T55X7_UNK_CONFIG_BLOCK 0x000880FA // ASK, Manchester, data rate 32, 7 data blocks STT, Inverse ... // FDXB requires data inversion and BiPhase 57 is simply BiPhase 50 inverted, so we can either do it using the modulation scheme or the inversion flag // we've done both below to prove that it works either way, and the modulation value for BiPhase 50 in the Atmel data sheet of binary "10001" (17) is a typo, From 346113b168b5c6cb45fd512c59890b7f9d2b935c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 10:18:50 +0100 Subject: [PATCH 18/34] text --- doc/ext_flash_notes.md | 45 ++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/doc/ext_flash_notes.md b/doc/ext_flash_notes.md index f6e462421..76b4d9279 100644 --- a/doc/ext_flash_notes.md +++ b/doc/ext_flash_notes.md @@ -73,24 +73,39 @@ Page3 is used as follows by the Proxmark3 RDV4 firmware: To ensure your Proxmark3 RDV4 is not a counterfeit product, its external flash contains a RSA signature of the flash unique ID. You can verify it with: `mem info` + +Here below is a sample output of a RDV4 device. ``` -[usb] pm3 --> mem info - -[=] --- Flash memory Information --------- - -[=] ------------------------------------------------------------- -[=] ID | xx xx xx xx xx xx xx xx -[=] SHA1 | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx -[=] RSA SIGNATURE | -[00] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx -[01] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx -[02] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx -[03] | xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx -[=] KEY length | 128 -[+] RSA key validation ok -[+] RSA Verification ok +[usb] pm3 --> mem info + +[=] --- Flash memory Information --------- +[=] ID................... 25AD99A782A867D5 +[=] SHA1................. 67C3B9BA2FA90AD4B283926B70017066C082C156 +[+] Signature............ ( ok ) + +[=] --- RDV4 RSA signature --------------- +[=] C7C7DF7FA3A2391A2B36E97D227C746ED8BB475E8766F54A13BAA9AAB29299BE +[=] 37546AACCC29157ABF8AFBF3A1CFB24275442D565F7E996C6B08090528ADE25E +[=] ED1498E3089C72C68348D83CBD13F1247327BDBC9D75B09ECE3E051E19FE19BB +[=] 98CB038757F2EDFD2DC5060D05C3296BC19A6F768290D555DFD50407E0E13A70 + +[=] --- RDV4 RSA Public key -------------- +[=] Len.................. 128 +[=] Exponent............. 010001 +[=] Public key modulus N +[=] E28D809BF323171D11D1ACA4C32A5B7E0A8974FD171E75AD120D60E9B76968FF +[=] 4B0A6364AE50583F9555B8EE1A725F279E949246DF0EFCE4C02B9F3ACDCC623F +[=] 9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33 +[=] DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5 + +[+] RSA public key validation.... ( ok ) +[+] RSA private key validation... ( ok ) +[+] RSA verification..... ( ok ) +[+] Genuine Proxmark3 RDV4 signature detected ``` +# backup first! To make a backup of the signature to file: + `mem dump p f flash_signature_dump o 262015 l 128` From e4753011d8a33331d16e4cd0044578a5eb55d907 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 10:19:52 +0100 Subject: [PATCH 19/34] text --- client/src/cmdflashmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdflashmem.c b/client/src/cmdflashmem.c index 2f807fa7f..5bb3b8cd9 100644 --- a/client/src/cmdflashmem.c +++ b/client/src/cmdflashmem.c @@ -139,7 +139,7 @@ static int rdv4_sign_write(uint8_t *signature, uint8_t slen){ if (!resp.oldarg[0]) { PrintAndLogEx(FAILED, "Writing signature ( "_RED_("fail") ")"); } else { - PrintAndLogEx(SUCCESS, "Writing signature ( "_GREEN_("ok") " ) at offset %u", FLASH_MEM_SIGNATURE_OFFSET); + PrintAndLogEx(SUCCESS, "Writing signature at offset %u ( "_GREEN_("ok") " )", FLASH_MEM_SIGNATURE_OFFSET); return PM3_SUCCESS; } } From 70bcfb7ffe9d74cdaa0ec6ca345febdb95efe2f3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 10:44:21 +0100 Subject: [PATCH 20/34] textual, pushing a point --- client/src/cmdlft55xx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 969eb46e1..bf688c76d 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -4193,8 +4193,12 @@ static int CmdT55xxSniff(const char *Cmd) { } static command_t CommandTable[] = { - {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("operations") " ---------------------"}, + {"-----------", CmdHelp, AlwaysAvailable, "---------------------------- " _CYAN_("notice") " -----------------------------"}, + {"", CmdHelp, AlwaysAvailable, "Remember to run `" _YELLOW_("lf t55xx detect") "` first whenever "}, + {"", CmdHelp, AlwaysAvailable, "a new card is placed on the Proxmark3 or the config block changed."}, + {"", CmdHelp, AlwaysAvailable, ""}, {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("operations") " ---------------------"}, {"clonehelp", CmdT55xxCloneHelp, IfPm3Lf, "Shows the available clone commands"}, {"config", CmdT55xxSetConfig, AlwaysAvailable, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"}, {"dangerraw", CmdT55xxDangerousRaw, IfPm3Lf, "Sends raw bitstream. Dangerous, do not use!!"}, From d5ea600289d440e783fb522795c67bae720db883 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 11:25:17 +0100 Subject: [PATCH 21/34] lf t55 dump - now uses cliparser --- client/src/cmdlft55xx.c | 153 +++++++++++++++++++++------------------- 1 file changed, 82 insertions(+), 71 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index bf688c76d..7578d3cfb 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -208,20 +208,7 @@ static int usage_t55xx_info(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_dump(void) { - PrintAndLogEx(NORMAL, "Usage: lf t55xx dump [r ] [p [o]]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); - PrintAndLogEx(NORMAL, " o - OPTIONAL override, force pwd read despite danger to card"); - PrintAndLogEx(NORMAL, " f - override filename prefix (optional). Default is based on blk 0"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx dump")); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx dump p feedbeef o")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} + static int usage_t55xx_restore(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx restore f [p password]"); PrintAndLogEx(NORMAL, "Options:"); @@ -2198,48 +2185,66 @@ static int CmdT55xxInfo(const char *Cmd) { static int CmdT55xxDump(const char *Cmd) { - uint32_t password = 0; - uint8_t override = 0; - uint8_t downlink_mode = config.downlink_mode; + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf t55xx dump", + "This command dumps a T55xx card Page 0 block 0-7.\n" + "It will create three files (bin/eml/json)", + "lf t55xx dump\n" + "lf t55xx dump -p aabbccdd --override\n" + "lf t55xx dump -f my_lf_dump" + ); + + // 1 (help) + 3 (two user specified params) + (5 T55XX_DLMODE_SINGLE) + void *argtable[4 + 5] = { + arg_param_begin, + arg_str0("f", "filename", "", "filename (default is generated on blk 0"), + arg_lit0("o", "override", "override, force pwd read despite danger to card"), + arg_str0("p", "pwd", "", "password (4 hex bytes)"), + }; + uint8_t idx = 4; + arg_add_t55xx_downloadlink(argtable, &idx, T55XX_DLMODE_SINGLE, T55XX_DLMODE_SINGLE); + 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); + + uint8_t override = arg_get_lit(ctx, 2) ? 1 : 0; + bool usepwd = false; - bool errors = false; - uint8_t cmdp = 0; - char preferredName[FILE_PATH_SIZE] = {0}; - bool success = true; - - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_t55xx_dump(); - case 'r': - downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) - downlink_mode = 0; - - cmdp += 2; - break; - case 'p': - password = param_get32ex(Cmd, cmdp + 1, 0, 16); - usepwd = true; - cmdp += 2; - break; - case 'o': - override = 1; - cmdp++; - break; - case 'f': - param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); - cmdp += 2; - if (strlen(preferredName) == 0) - errors = true; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } + uint32_t password = 0; + int res = arg_get_u32_hexstr_def_nlen(ctx, 3, 0, &password, 4, true); + if (res == 0 || res == 2) { + PrintAndLogEx(ERR, "Password should be 4 hex bytes"); + CLIParserFree(ctx); + return PM3_EINVARG; } - if (errors) return usage_t55xx_dump(); + if (res == 1) { + usepwd = true; + } + + bool r0 = arg_get_lit(ctx, 4); + bool r1 = arg_get_lit(ctx, 5); + bool r2 = arg_get_lit(ctx, 6); + bool r3 = arg_get_lit(ctx, 7); + CLIParserFree(ctx); + + if ((r0 + r1 + r2 + r3) > 1) { + PrintAndLogEx(FAILED, "Error multiple downlink encoding"); + return PM3_EINVARG; + } + + uint8_t downlink_mode = config.downlink_mode; + if (r0) + downlink_mode = refFixedBit; + else if (r1) + downlink_mode = refLongLeading; + else if (r2) + downlink_mode = refLeading0; + else if (r3) + downlink_mode = ref1of4; + + bool success = true; // Due to the few different T55xx cards and number of blocks supported // will save the dump file if ALL page 0 is OK @@ -2247,39 +2252,45 @@ static int CmdT55xxDump(const char *Cmd) { for (uint8_t i = 0; i < 8; ++i) { if (T55xxReadBlock(i, 0, usepwd, override, password, downlink_mode) != PM3_SUCCESS) success = false; - // idea for better user experience and display. + // only show override warning on the first block read - if (override == 1) override++; // flag not to show safty for 2nd and on. + if (override == 1) { + override++; + } } printT5xxHeader(1); for (uint8_t i = 0; i < 4; i++) if (T55xxReadBlock(i, 1, usepwd, override, password, downlink_mode) != PM3_SUCCESS) T55x7_SaveBlockData(8 + i, 0x00); + // all ok, save dump to file + if (success) { - if (success) { // all ok save dump to file - // saveFileEML will add .eml extension to filename - // saveFile (binary) passes in the .bin extension. - if (strcmp(preferredName, "") == 0) { // Set default filename, if not set by user - strcpy(preferredName, "lf-t55xx"); + // set default filename, if not set by user + if (strlen(filename) == 0) { + strcpy(filename, "lf-t55xx"); for (uint8_t i = 1; i <= 7; i++) { - if ((cardmem[i].blockdata != 0x00) && (cardmem[i].blockdata != 0xFFFFFFFF)) - snprintf(preferredName + strlen(preferredName), sizeof(preferredName) - strlen(preferredName), "-%08X", cardmem[i].blockdata); - else + if ((cardmem[i].blockdata != 0x00) && (cardmem[i].blockdata != 0xFFFFFFFF)) { + snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename), "-%08X", cardmem[i].blockdata); + } else { break; + } } - strcat(preferredName, "-dump"); + strcat(filename, "-dump"); } // Swap endian so the files match the txt display uint32_t data[T55x7_BLOCK_COUNT]; - for (int i = 0; i < T55x7_BLOCK_COUNT; i++) + for (int i = 0; i < T55x7_BLOCK_COUNT; i++) { data[i] = BSWAP_32(cardmem[i].blockdata); + } - saveFileJSON(preferredName, jsfT55x7, (uint8_t *)data, T55x7_BLOCK_COUNT * sizeof(uint32_t), NULL); - saveFileEML(preferredName, (uint8_t *)data, T55x7_BLOCK_COUNT * sizeof(uint32_t), sizeof(uint32_t)); - saveFile(preferredName, ".bin", data, sizeof(data)); + // saveFileEML will add .eml extension to filename + // saveFile (binary) passes in the .bin extension. + saveFileJSON(filename, jsfT55x7, (uint8_t *)data, T55x7_BLOCK_COUNT * sizeof(uint32_t), NULL); + saveFileEML(filename, (uint8_t *)data, T55x7_BLOCK_COUNT * sizeof(uint32_t), sizeof(uint32_t)); + saveFile(filename, ".bin", data, sizeof(data)); } return PM3_SUCCESS; @@ -4194,8 +4205,8 @@ static int CmdT55xxSniff(const char *Cmd) { static command_t CommandTable[] = { {"-----------", CmdHelp, AlwaysAvailable, "---------------------------- " _CYAN_("notice") " -----------------------------"}, - {"", CmdHelp, AlwaysAvailable, "Remember to run `" _YELLOW_("lf t55xx detect") "` first whenever "}, - {"", CmdHelp, AlwaysAvailable, "a new card is placed on the Proxmark3 or the config block changed."}, + {"", CmdHelp, AlwaysAvailable, "Remember to run `" _YELLOW_("lf t55xx detect") "` first whenever a new card"}, + {"", CmdHelp, AlwaysAvailable, "is placed on the Proxmark3 or the config block changed."}, {"", CmdHelp, AlwaysAvailable, ""}, {"help", CmdHelp, AlwaysAvailable, "This help"}, {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("operations") " ---------------------"}, From 450c7fab5bb59d9ed71bafe3cd644a69e41de2d8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 11:42:23 +0100 Subject: [PATCH 22/34] lf t55xx restore - now uses cliparser --- client/src/cmdlft55xx.c | 222 ++++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 112 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 7578d3cfb..677b9417b 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -209,20 +209,6 @@ static int usage_t55xx_info(void) { return PM3_SUCCESS; } -static int usage_t55xx_restore(void) { - PrintAndLogEx(NORMAL, "Usage: lf t55xx restore f [p password]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " f - filename of the dump file (.bin/.eml)"); - PrintAndLogEx(NORMAL, " p - optional password if target card has password set"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, _YELLOW_(" Assumes lf t55 detect has been run first!")); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx restore f lf-t55xx-00148040-dump.bin")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - static int usage_t55xx_clonehelp(void) { PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:"); PrintAndLogEx(NORMAL, _GREEN_("lf awid clone")); @@ -2197,7 +2183,7 @@ static int CmdT55xxDump(const char *Cmd) { // 1 (help) + 3 (two user specified params) + (5 T55XX_DLMODE_SINGLE) void *argtable[4 + 5] = { arg_param_begin, - arg_str0("f", "filename", "", "filename (default is generated on blk 0"), + arg_str0("f", "filename", "", "filename (default is generated on blk 0)"), arg_lit0("o", "override", "override, force pwd read despite danger to card"), arg_str0("p", "pwd", "", "password (4 hex bytes)"), }; @@ -2297,118 +2283,130 @@ static int CmdT55xxDump(const char *Cmd) { } static int CmdT55xxRestore(const char *Cmd) { - bool errors = false; - uint8_t cmdp = 0; - char preferredName[FILE_PATH_SIZE] = {0}; - char ext[FILE_PATH_SIZE] = {0}; - int success = PM3_ESOFT; - uint32_t password = 0x00; - bool usepwd = false; - uint32_t data[12] = {0}; - size_t datalen = 0; - uint8_t blockidx; - uint8_t downlink_mode; - char writeCmdOpt[100]; - char pwdOpt [11] = {0}; // p XXXXXXXX + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf t55xx restore", + "This command restores T55xx card page 0/1 n blocks", + "lf t55xx restore -f lf-t55xx-00148040-dump.bin" + ); - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_t55xx_restore(); - case 'f': - param_getstr(Cmd, cmdp + 1, preferredName, FILE_PATH_SIZE); - if (strlen(preferredName) == 0) - errors = true; - cmdp += 2; - break; - case 'p': - password = param_get32ex(Cmd, cmdp + 1, 0, 16); - usepwd = true; - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } + void *argtable[] = { + arg_param_begin, + arg_str0("f", "filename", "", "filename of the dump file (bin|eml)"), + arg_str0("p", "pwd", "", "password if target card has password set (4 hex bytes)"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int fnlen = 0; + char filename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, sizeof(filename), &fnlen); + + bool usepwd = false; + uint32_t password = 0; + int res = arg_get_u32_hexstr_def_nlen(ctx, 2, 0, &password, 4, true); + if (res == 0 || res == 2) { + PrintAndLogEx(ERR, "Password should be 4 hex bytes"); + CLIParserFree(ctx); + return PM3_EINVARG; + } + if (res == 1) { + usepwd = true; + } + CLIParserFree(ctx); + + if (fnlen == 0) { + PrintAndLogEx(ERR, "Must specify a filename"); + return PM3_EINVARG; } - // File name expected to be .eml .bin or .json so sould be at least 4 - if (errors || (strlen(preferredName) == 0)) return usage_t55xx_restore(); + char ext[FILE_PATH_SIZE] = {0}; + uint32_t data[12] = {0}; + size_t datalen = 0; - // split file name into prefix and ext. - int fnLength; - - fnLength = strlen(preferredName); - - success = PM3_ESOFT; - if (fnLength > 4) { // Holds extension [.bin|.eml] - memcpy(ext, &preferredName[fnLength - 4], 4); + int retval = PM3_ESOFT; + if (fnlen > 4) { // Holds extension [.bin|.eml] + memcpy(ext, &filename[fnlen - 4], 4); ext[5] = 0x00; // check if valid file extension and attempt to load data - if (memcmp(ext, ".bin", 4) == 0) { - preferredName[fnLength - 4] = 0x00; - success = loadFile(preferredName, ".bin", data, sizeof(data), &datalen); + filename[fnlen - 4] = 0x00; + retval = loadFile(filename, ".bin", data, sizeof(data), &datalen); } else if (memcmp(ext, ".eml", 4) == 0) { - preferredName[fnLength - 4] = 0x00; + filename[fnlen - 4] = 0x00; datalen = 12; - success = loadFileEML(preferredName, (uint8_t *)data, &datalen); + retval = loadFileEML(filename, (uint8_t *)data, &datalen); - } else - PrintAndLogEx(WARNING, "\nWarning: invalid dump filename "_YELLOW_("%s")" to restore!\n", preferredName); - } - - if (success == PM3_SUCCESS) { // Got data, so write to cards - if (datalen == T55x7_BLOCK_COUNT * 4) { // 12 blocks * 4 bytes per block - if (usepwd) - snprintf(pwdOpt, sizeof(pwdOpt), "p %08X", password); - - // Restore endien for writing to card - for (blockidx = 0; blockidx < 12; blockidx++) - data[blockidx] = BSWAP_32(data[blockidx]); - - // Have data ready, lets write - // Order - // write blocks 1..7 page 0 - // 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; - - // write out blocks 1-7 page 0 - for (blockidx = 1; blockidx <= 7; blockidx++) { - snprintf(writeCmdOpt, sizeof(writeCmdOpt), "b %d d %08X %s", blockidx, data[blockidx], pwdOpt); - - if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) - PrintAndLogEx(WARNING, "Warning: error writing blk %d", blockidx); - } - - // 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]); - - // write out blocks 1-3 page 1 - for (blockidx = 9; blockidx <= 11; blockidx++) { - snprintf(writeCmdOpt, sizeof(writeCmdOpt), "b %d 1 d %08X %s", blockidx - 8, data[blockidx], pwdOpt); - - if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) - PrintAndLogEx(WARNING, "Warning: error writing blk %d", blockidx); - } - - // Update downlink mode for the page 0 config write. - config.downlink_mode = downlink_mode; - - // Write the page 0 config - snprintf(writeCmdOpt, sizeof(writeCmdOpt), "b 0 d %08X %s", data[0], pwdOpt); - if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) - PrintAndLogEx(WARNING, "Warning: error writing blk 0"); + } else { + PrintAndLogEx(WARNING, "\nWarning: invalid dump filename "_YELLOW_("%s")" to restore!\n", filename); } } + if (retval != PM3_SUCCESS) { + return retval; + } + + if (datalen == T55x7_BLOCK_COUNT * 4) { + // 12 blocks * 4 bytes per block + + // this fct creats strings to call "lf t55 write" command. + // + // + uint8_t downlink_mode; + char writeCmdOpt[100]; + char pwdOpt [11] = {0}; // p XXXXXXXX + + if (usepwd) + snprintf(pwdOpt, sizeof(pwdOpt), "p %08X", password); + + uint8_t idx; + // Restore endien for writing to card + for (idx = 0; idx < 12; idx++) { + data[idx] = BSWAP_32(data[idx]); + } + + // Have data ready, lets write + // Order + // write blocks 1..7 page 0 + // 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; + + // write out blocks 1-7 page 0 + for (idx = 1; idx <= 7; idx++) { + snprintf(writeCmdOpt, sizeof(writeCmdOpt), "b %d d %08X %s", idx, data[idx], pwdOpt); + + if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx); + } + } + + // 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]); + } + + // write out blocks 1-3 page 1 + for (idx = 9; idx <= 11; idx++) { + snprintf(writeCmdOpt, sizeof(writeCmdOpt), "b %d 1 d %08X %s", idx - 8, data[idx], pwdOpt); + + if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx); + } + } + + // Update downlink mode for the page 0 config write. + config.downlink_mode = downlink_mode; + + // Write the page 0 config + snprintf(writeCmdOpt, sizeof(writeCmdOpt), "b 0 d %08X %s", data[0], pwdOpt); + if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Warning: error writing blk 0"); + } + } return PM3_SUCCESS; } /* From caf9e9cecc746a74afa966d1ef3b62cebb4cd8de Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 15:01:56 +0100 Subject: [PATCH 23/34] lf t55xx trace, info - now uses cliparser --- client/src/cmdlft55xx.c | 382 +++++++++++++++++++++------------------- 1 file changed, 204 insertions(+), 178 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 677b9417b..0637859a5 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -176,38 +176,6 @@ static int usage_t55xx_write(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_trace(void) { - PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1] [r mode]"); - PrintAndLogEx(NORMAL, "Options:"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); - PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx trace")); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx trace 1")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} -static int usage_t55xx_info(void) { - PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1] [r ] [c [q]]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " (default) - read data from tag."); - PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex symbols)"); - PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer instead of reading tag."); - PrintAndLogEx(NORMAL, " c - set configuration from a block0"); - PrintAndLogEx(NORMAL, " if set, use these data instead of reading tag."); - PrintAndLogEx(NORMAL, " q - if set, provided data are interpreted as Q5 config."); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx info")); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx info 1")); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx info d 00083040")); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx info d 6001805A q")); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx info p 11223344")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} static int usage_t55xx_clonehelp(void) { PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:"); @@ -973,8 +941,6 @@ static int CmdT55xxDetect(const char *Cmd) { else // This will set the default to user all d/l modes which will cover the ra flag as well. try_all_dl_modes = true; - // if (ra) - // try_all_dl_modes = true; bool try_with_pwd = false; bool found = false; @@ -1713,36 +1679,46 @@ static int CmdT55xxDangerousRaw(const char *Cmd) { static int CmdT55xxReadTrace(const char *Cmd) { - bool frombuff = false; - uint8_t downlink_mode = config.downlink_mode; - uint8_t cmdp = 0; - bool errors = false; + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf t55xx trace", + "Show T55x7 configuration data (page 0/ blk 0) from reading the configuration block", + "lf t55xx trace\n" + "lf t55xx trace -1" + ); - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_t55xx_trace(); - case 'r': - downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) - downlink_mode = 0; + // 1 (help) + 1 (one user specified params) + (5 T55XX_DLMODE_SINGLE) + void *argtable[2 + 5] = { + arg_param_begin, + arg_lit0("1", NULL, "extract using data from graphbuffer"), + }; + uint8_t idx = 2; + arg_add_t55xx_downloadlink(argtable, &idx, T55XX_DLMODE_SINGLE, config.downlink_mode); + CLIExecWithReturn(ctx, Cmd, argtable, true); - cmdp += 2; - break; - case '1': - frombuff = true; - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } + bool use_gb = arg_get_lit(ctx, 1); + + bool r0 = arg_get_lit(ctx, 2); + bool r1 = arg_get_lit(ctx, 3); + bool r2 = arg_get_lit(ctx, 4); + bool r3 = arg_get_lit(ctx, 5); + CLIParserFree(ctx); + + if ((r0 + r1 + r2 + r3) > 1) { + PrintAndLogEx(FAILED, "Error multiple downlink encoding"); + return PM3_EINVARG; } - if (errors) return usage_t55xx_trace(); + uint8_t downlink_mode = config.downlink_mode; + if (r0) + downlink_mode = refFixedBit; + else if (r1) + downlink_mode = refLongLeading; + else if (r2) + downlink_mode = refLeading0; + else if (r3) + downlink_mode = ref1of4; - if (!frombuff) { + if (use_gb == false) { // sanity check. if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA; @@ -1755,12 +1731,18 @@ static int CmdT55xxReadTrace(const char *Cmd) { } if (config.Q5) { - if (!DecodeT5555TraceBlock()) return PM3_ESOFT; + if (DecodeT5555TraceBlock() == false) { + return PM3_ESOFT; + } } else { - if (!DecodeT55xxBlock()) return PM3_ESOFT; + if (DecodeT55xxBlock() == false) { + return PM3_ESOFT; + } } - if (!DemodBufferLen) return PM3_ESOFT; + if (DemodBufferLen == 0){ + return PM3_ESOFT; + } RepaintGraphWindow(); uint8_t repeat = (config.offset > 5) ? 32 : 0; @@ -1865,22 +1847,21 @@ static int CmdT55xxReadTrace(const char *Cmd) { } void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat) { - PrintAndLogEx(NORMAL, "--- " _CYAN_("T55x7 Trace Information") " ----------------------------------"); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - PrintAndLogEx(NORMAL, " ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", data.acl, data.acl); - PrintAndLogEx(NORMAL, " MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d) - %s", data.mfc, data.mfc, getTagInfo(data.mfc)); - PrintAndLogEx(NORMAL, " CID : 0x%02X (%d) - %s", data.cid, data.cid, GetModelStrFromCID(data.cid)); - PrintAndLogEx(NORMAL, " ICR IC Revision : %d", data.icr); - PrintAndLogEx(NORMAL, " Manufactured"); - PrintAndLogEx(NORMAL, " Year/Quarter : %d/%d", data.year, data.quarter); - PrintAndLogEx(NORMAL, " Lot ID : %d", data.lotid); - PrintAndLogEx(NORMAL, " Wafer number : %d", data.wafer); - PrintAndLogEx(NORMAL, " Die Number : %d", data.dw); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - PrintAndLogEx(NORMAL, " Raw Data - Page 1"); - PrintAndLogEx(NORMAL, " Block 1 : 0x%08X %s", data.bl1, sprint_bin(DemodBuffer + config.offset + repeat, 32)); - PrintAndLogEx(NORMAL, " Block 2 : 0x%08X %s", data.bl2, sprint_bin(DemodBuffer + config.offset + repeat + 32, 32)); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, "--- " _CYAN_("T55x7 Trace Information") " ----------------------------------"); + PrintAndLogEx(INFO, " ACL Allocation class (ISO/IEC 15963-1) : 0x%02X ( %d )", data.acl, data.acl); + PrintAndLogEx(INFO, " MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X ( %d ) - %s", data.mfc, data.mfc, getTagInfo(data.mfc)); + PrintAndLogEx(INFO, " CID : 0x%02X ( %d ) - %s", data.cid, data.cid, GetModelStrFromCID(data.cid)); + PrintAndLogEx(INFO, " ICR IC Revision : %d", data.icr); + PrintAndLogEx(INFO, " Manufactured"); + PrintAndLogEx(INFO, " Year/Quarter... %d/%d", data.year, data.quarter); + PrintAndLogEx(INFO, " Lot ID......... %d", data.lotid); + PrintAndLogEx(INFO, " Wafer number... %d", data.wafer); + PrintAndLogEx(INFO, " Die Number..... %d", data.dw); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, " Raw Data - Page 1"); + PrintAndLogEx(INFO, " Block 1... %08X - %s", data.bl1, sprint_bin(DemodBuffer + config.offset + repeat, 32)); + PrintAndLogEx(INFO, " Block 2... %08X - %s", data.bl2, sprint_bin(DemodBuffer + config.offset + repeat + 32, 32)); + PrintAndLogEx(NORMAL, ""); /* Trace info. @@ -1912,16 +1893,15 @@ void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat) { } void printT5555Trace(t5555_tracedata_t data, uint8_t repeat) { - PrintAndLogEx(NORMAL, "--- " _CYAN_("Q5/T5555 Trace Information") " ---------------------------"); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - PrintAndLogEx(NORMAL, " ICR IC Revision : %d", data.icr); - PrintAndLogEx(NORMAL, " Lot : %c%d", data.lotidc, data.lotid); - PrintAndLogEx(NORMAL, " Wafer number : %d", data.wafer); - PrintAndLogEx(NORMAL, " Die Number : %d", data.dw); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - PrintAndLogEx(NORMAL, " Raw Data - Page 1"); - PrintAndLogEx(NORMAL, " Block 1 : 0x%08X %s", data.bl1, sprint_bin(DemodBuffer + config.offset + repeat, 32)); - PrintAndLogEx(NORMAL, " Block 2 : 0x%08X %s", data.bl2, sprint_bin(DemodBuffer + config.offset + repeat + 32, 32)); + PrintAndLogEx(INFO, "--- " _CYAN_("Q5/T5555 Trace Information") " ---------------------------"); + PrintAndLogEx(INFO, " ICR IC Revision.... %d", data.icr); + PrintAndLogEx(INFO, " Lot ID......... %c%d", data.lotidc, data.lotid); + PrintAndLogEx(INFO, " Wafer number... %d", data.wafer); + PrintAndLogEx(INFO, " Die Number..... %d", data.dw); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, " Raw Data - Page 1"); + PrintAndLogEx(INFO, " Block 1... %08X - %s", data.bl1, sprint_bin(DemodBuffer + config.offset + repeat, 32)); + PrintAndLogEx(INFO, " Block 2... %08X - %s", data.bl2, sprint_bin(DemodBuffer + config.offset + repeat + 32, 32)); /* ** Q5 ** @@ -2015,75 +1995,121 @@ static void printT5x7KnownBlock0(uint32_t b0) { break; } - if (strlen(s) > 0) - PrintAndLogEx(SUCCESS, "\nConfig block match : " _YELLOW_("%s"), s); + if (strlen(s) > 0) { + PrintAndLogEx(SUCCESS, "Config block match : " _YELLOW_("%s"), s); + } } static int CmdT55xxInfo(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf t55xx info", + "Show T55x7 configuration data (page 0/ blk 0) from reading the configuration block\n" + "from tag. Use `-c` to specify a config block data to be used instead of reading tag.", + "lf t55xx info\n" + "lf t55xx info -1\n" + "lf t55xx info -p 11223344\n" + "lf t55xx info -c 00083040\n" + "lf t55xx info -c 6001805A --q5" + ); + + // 1 (help) + 4 (four user specified params) + (5 T55XX_DLMODE_SINGLE) + void *argtable[5 + 5] = { + arg_param_begin, + arg_lit0("1", NULL, "extract using data from graphbuffer"), + arg_str0("p", "pwd", "", "password (4 hex bytes)"), + arg_str0("c", "blk0", "", "use these data instead (4 hex bytes)"), + arg_lit0(NULL, "q5", "interprete provided data as T5555/Q5 config"), + }; + uint8_t idx = 5; + arg_add_t55xx_downloadlink(argtable, &idx, T55XX_DLMODE_SINGLE, config.downlink_mode); + CLIExecWithReturn(ctx, Cmd, argtable, true); + + bool use_gb = arg_get_lit(ctx, 1); + + bool usepwd = false; + uint32_t password = 0; + int res = arg_get_u32_hexstr_def_nlen(ctx, 2, 0, &password, 4, true); + if (res == 0 || res == 2) { + PrintAndLogEx(ERR, "Password must be 4 hex bytes"); + CLIParserFree(ctx); + return PM3_EINVARG; + } + if (res == 1) { + usepwd = true; + } + + bool gotdata = false; + uint32_t block0 = 0; + res = arg_get_u32_hexstr_def_nlen(ctx, 3, 0, &block0, 4, true); + if (res == 0 || res == 2) { + PrintAndLogEx(ERR, "block0 data must be 4 hex bytes"); + CLIParserFree(ctx); + return PM3_EINVARG; + } + if (res == 1) { + gotdata = true; + } + + bool dataasq5 = arg_get_lit(ctx, 4); + + bool r0 = arg_get_lit(ctx, 5); + bool r1 = arg_get_lit(ctx, 6); + bool r2 = arg_get_lit(ctx, 7); + bool r3 = arg_get_lit(ctx, 8); + CLIParserFree(ctx); + + if (gotdata && use_gb) { + PrintAndLogEx(FAILED, "Must select one of user supplied data and use graphbuffer"); + return PM3_EINVARG; + } + + if (dataasq5 && gotdata == false) { + PrintAndLogEx(FAILED, "Must specify user supplied Q5 data"); + return PM3_EINVARG; + } + + if ((r0 + r1 + r2 + r3) > 1) { + PrintAndLogEx(FAILED, "Error multiple downlink encoding"); + return PM3_EINVARG; + } + + uint8_t downlink_mode = config.downlink_mode; + if (r0) + downlink_mode = refFixedBit; + else if (r1) + downlink_mode = refLongLeading; + else if (r2) + downlink_mode = refLeading0; + else if (r3) + downlink_mode = ref1of4; + + /* Page 0 Block 0 Configuration data. Normal mode Extended mode */ - bool frombuff = false, gotdata = false, dataasq5 = false, usepwd = false; - uint8_t cmdp = 0; - uint8_t downlink_mode = config.downlink_mode; - uint32_t block0 = 0, password = 0; - while (param_getchar(Cmd, cmdp) != 0x00) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_t55xx_info(); - case 'c': - block0 = param_get32ex(Cmd, cmdp + 1, 0, 16); - gotdata = true; - cmdp += 2; - break; - case 'p': - password = param_get32ex(Cmd, cmdp + 1, 0, 16); - usepwd = true; - cmdp += 2; - break; - case '1': - frombuff = true; - cmdp += 2; - break; - case 'q': - dataasq5 = true; - cmdp += 2; - break; - case 'r': - downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) - downlink_mode = 0; + if (use_gb == false && gotdata == false) { + // sanity check. + if (SanityOfflineCheck(false) != PM3_SUCCESS) { + return PM3_ENODATA; + } - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - return usage_t55xx_info(); + if (!AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) { + return PM3_ENODATA; } } - if (gotdata && frombuff) - return usage_t55xx_info(); - - if (dataasq5 && !gotdata) - return usage_t55xx_info(); - - if (!frombuff && !gotdata) { - // sanity check. - if (SanityOfflineCheck(false) != PM3_SUCCESS) return PM3_ENODATA; - - if (!AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, downlink_mode)) - return PM3_ENODATA; - } - - if (!gotdata) { - if (!DecodeT55xxBlock()) return PM3_ESOFT; + if (gotdata == false) { + if (DecodeT55xxBlock() == false) { + return PM3_ESOFT; + } // too little space to start with - if (DemodBufferLen < 32 + config.offset) return PM3_ESOFT; + if (DemodBufferLen < 32 + config.offset) { + return PM3_ESOFT; + } //PrintAndLogEx(NORMAL, "Offset+32 ==%d\n DemodLen == %d", config.offset + 32, DemodBufferLen); block0 = PackBits(config.offset, 32, DemodBuffer); @@ -2102,19 +2128,18 @@ static int CmdT55xxInfo(const char *Cmd) { uint32_t datamod = (block0 >> (32 - 28)) & 0x07; uint32_t maxblk = (block0 >> (32 - 31)) & 0x07; uint32_t st = block0 & 0x01; - PrintAndLogEx(NORMAL, "--- " _CYAN_("Q5 Configuration & Information") " ------------"); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - PrintAndLogEx(NORMAL, " Header : 0x%03X%s", header, (header != 0x600) ? _RED_(" - Warning") : ""); - PrintAndLogEx(NORMAL, " Page select : %d", ps); - PrintAndLogEx(NORMAL, " Fast Write : %s", (fw) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, " Data bit rate : %s", GetBitRateStr(dbr, 1)); - PrintAndLogEx(NORMAL, " AOR - Answer on Request : %s", (aor) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, " Password mode : %s", (pwd) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, " PSK clock frequency : %s", GetPskCfStr(pskcf, 1)); - PrintAndLogEx(NORMAL, " Inverse data : %s", (inv) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, " Modulation : %s", GetQ5ModulationStr(datamod)); - PrintAndLogEx(NORMAL, " Max block : %d", maxblk); - PrintAndLogEx(NORMAL, " Sequence Terminator : %s", (st) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, "--- " _CYAN_("Q5 Configuration & Information") " ------------"); + PrintAndLogEx(INFO, " Header : 0x%03X%s", header, (header != 0x600) ? _RED_(" - Warning") : ""); + PrintAndLogEx(INFO, " Page select : %d", ps); + PrintAndLogEx(INFO, " Fast Write : %s", (fw) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, " Data bit rate : %s", GetBitRateStr(dbr, 1)); + PrintAndLogEx(INFO, " AOR - Answer on Request : %s", (aor) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, " Password mode : %s", (pwd) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, " PSK clock frequency : %s", GetPskCfStr(pskcf, 1)); + PrintAndLogEx(INFO, " Inverse data : %s", (inv) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, " Modulation : %s", GetQ5ModulationStr(datamod)); + PrintAndLogEx(INFO, " Max block : %d", maxblk); + PrintAndLogEx(INFO, " Sequence Terminator : %s", (st) ? _GREEN_("Yes") : "No"); } else { uint32_t safer = (block0 >> (32 - 4)) & 0x0F; uint32_t extend = (block0 >> (32 - 15)) & 0x01; @@ -2137,35 +2162,36 @@ static int CmdT55xxInfo(const char *Cmd) { uint32_t inv = (block0 >> (32 - 31)) & 0x01; uint32_t por = (block0 >> (32 - 32)) & 0x01; - PrintAndLogEx(NORMAL, "--- " _CYAN_("T55x7 Configuration & Information") " ---------"); - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - PrintAndLogEx(NORMAL, " Safer key : %s", GetSaferStr(safer)); - PrintAndLogEx(NORMAL, " reserved : %d", resv); - PrintAndLogEx(NORMAL, " Data bit rate : %s", GetBitRateStr(dbr, extend)); - PrintAndLogEx(NORMAL, " eXtended mode : %s", (extend) ? _YELLOW_("Yes - Warning") : "No"); - PrintAndLogEx(NORMAL, " Modulation : %s", GetModulationStr(datamod, extend)); - PrintAndLogEx(NORMAL, " PSK clock frequency : %s", GetPskCfStr(pskcf, 0)); - PrintAndLogEx(NORMAL, " AOR - Answer on Request : %s", (aor) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, " OTP - One Time Pad : %s", (otp) ? ((extend) ? _YELLOW_("Yes - Warning") : _RED_("Yes - Warning")) : "No"); - PrintAndLogEx(NORMAL, " Max block : %d", maxblk); - PrintAndLogEx(NORMAL, " Password mode : %s", (pwd) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, " Sequence %-12s : %s", (extend) ? "Start Marker" : "Terminator", (sst) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(NORMAL, " Fast Write : %s", (fw) ? ((extend) ? _GREEN_("Yes") : _RED_("Yes - Warning")) : "No"); - PrintAndLogEx(NORMAL, " Inverse data : %s", (inv) ? ((extend) ? _GREEN_("Yes") : _RED_("Yes - Warning")) : "No"); - PrintAndLogEx(NORMAL, " POR-Delay : %s", (por) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, "--- " _CYAN_("T55x7 Configuration & Information") " ---------"); + PrintAndLogEx(INFO, " Safer key : %s", GetSaferStr(safer)); + PrintAndLogEx(INFO, " reserved : %d", resv); + PrintAndLogEx(INFO, " Data bit rate : %s", GetBitRateStr(dbr, extend)); + PrintAndLogEx(INFO, " eXtended mode : %s", (extend) ? _YELLOW_("Yes - Warning") : "No"); + PrintAndLogEx(INFO, " Modulation : %s", GetModulationStr(datamod, extend)); + PrintAndLogEx(INFO, " PSK clock frequency : %s", GetPskCfStr(pskcf, 0)); + PrintAndLogEx(INFO, " AOR - Answer on Request : %s", (aor) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, " OTP - One Time Pad : %s", (otp) ? ((extend) ? _YELLOW_("Yes - Warning") : _RED_("Yes - Warning")) : "No"); + PrintAndLogEx(INFO, " Max block : %d", maxblk); + PrintAndLogEx(INFO, " Password mode : %s", (pwd) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, " Sequence %-12s : %s", (extend) ? "Start Marker" : "Terminator", (sst) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, " Fast Write : %s", (fw) ? ((extend) ? _GREEN_("Yes") : _RED_("Yes - Warning")) : "No"); + PrintAndLogEx(INFO, " Inverse data : %s", (inv) ? ((extend) ? _GREEN_("Yes") : _RED_("Yes - Warning")) : "No"); + PrintAndLogEx(INFO, " POR-Delay : %s", (por) ? _GREEN_("Yes") : "No"); } - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - PrintAndLogEx(NORMAL, " Raw Data - Page 0, block 0"); + PrintAndLogEx(INFO, "-------------------------------------------------------------"); + PrintAndLogEx(INFO, " Raw Data - Page 0, block 0"); if (gotdata) - PrintAndLogEx(NORMAL, " 0x" _GREEN_("%08X"), block0); + PrintAndLogEx(INFO, " " _GREEN_("%08X"), block0); else - PrintAndLogEx(NORMAL, " 0x" _GREEN_("%08X") " %s", block0, sprint_bin(DemodBuffer + config.offset, 32)); + PrintAndLogEx(INFO, " " _GREEN_("%08X") " - %s", block0, sprint_bin(DemodBuffer + config.offset, 32)); - if (((!gotdata) && (!config.Q5)) || (gotdata && (!dataasq5))) + if (((!gotdata) && (!config.Q5)) || (gotdata && (!dataasq5))) { + PrintAndLogEx(INFO, "--- " _CYAN_("Fingerprint") " ------------"); printT5x7KnownBlock0(block0); + } - PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); - + PrintAndLogEx(NORMAL, ""); + //PrintAndLogEx(INFO, "-------------------------------------------------------------"); return PM3_SUCCESS; } From 964aee329f2346c05e4f43bc029f12df20768c09 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 15:08:38 +0100 Subject: [PATCH 24/34] lf t55xx resetread - now uses cliparser --- client/src/cmdlft55xx.c | 74 ++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 0637859a5..30d60ff61 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -147,17 +147,7 @@ static int usage_t55xx_read(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_t55xx_resetread(void) { - PrintAndLogEx(NORMAL, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx resetread [r ]"); - PrintAndLogEx(NORMAL, "Options:"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx resetread")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} + static int usage_t55xx_write(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r ] b d [p ] [1] [t] [v]"); PrintAndLogEx(NORMAL, "Options:"); @@ -2818,38 +2808,51 @@ static void t55x7_create_config_block(int tagtype) { static int CmdResetRead(const char *Cmd) { - uint8_t downlink_mode = config.downlink_mode; - uint8_t flags = 0; - uint8_t cmdp = 0; - bool errors = false; + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf t55xx resetread", + "Send Reset Cmd then `lf read` the stream to attempt\n" + "to identify the start of it (needs a demod and/or plot after)", + "lf t55xx resetread" + ); - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_t55xx_resetread(); - case 'r': - downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) - downlink_mode = 0; + // 1 (help) + 0(one user specified params) + (5 T55XX_DLMODE_SINGLE) + void *argtable[0 + 5] = { + arg_param_begin, + arg_lit0("1", NULL, "extract using data from graphbuffer"), + }; + uint8_t idx = 1; + arg_add_t55xx_downloadlink(argtable, &idx, T55XX_DLMODE_SINGLE, config.downlink_mode); + CLIExecWithReturn(ctx, Cmd, argtable, true); - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } + bool r0 = arg_get_lit(ctx, 1); + bool r1 = arg_get_lit(ctx, 2); + bool r2 = arg_get_lit(ctx, 3); + bool r3 = arg_get_lit(ctx, 4); + CLIParserFree(ctx); + + if ((r0 + r1 + r2 + r3) > 1) { + PrintAndLogEx(FAILED, "Error multiple downlink encoding"); + return PM3_EINVARG; } - if (errors) return usage_t55xx_resetread(); + uint8_t downlink_mode = config.downlink_mode; + if (r0) + downlink_mode = refFixedBit; + else if (r1) + downlink_mode = refLongLeading; + else if (r2) + downlink_mode = refLeading0; + else if (r3) + downlink_mode = ref1of4; - flags = downlink_mode << 3; + uint8_t flags = downlink_mode << 3; + + PrintAndLogEx(INFO, "Sending reset command..."); PacketResponseNG resp; - clearCommandBuffer(); SendCommandNG(CMD_LF_T55XX_RESET_READ, &flags, sizeof(flags)); - if (!WaitForResponseTimeout(CMD_LF_T55XX_RESET_READ, &resp, 2500)) { + if (WaitForResponseTimeout(CMD_LF_T55XX_RESET_READ, &resp, 2500) == false) { PrintAndLogEx(WARNING, "command execution time out"); return PM3_ETIMEOUT; } @@ -2863,6 +2866,7 @@ static int CmdResetRead(const char *Cmd) { return PM3_EMALLOC; } + PrintAndLogEx(INFO, "Downloading samples..."); if (!GetFromDevice(BIG_BUF, got, gotsize, 0, NULL, 0, NULL, 2500, false)) { PrintAndLogEx(WARNING, "command execution time out"); free(got); @@ -2871,6 +2875,8 @@ static int CmdResetRead(const char *Cmd) { setGraphBuf(got, gotsize); free(got); } + + PrintAndLogEx(INFO, "Done"); return PM3_SUCCESS; } From 0067a9b7fa61a4f1a6e2250a17eae21eb9296ece Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 18:55:48 +0100 Subject: [PATCH 25/34] for commands with many params --- client/deps/cliparser/argtable3.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/deps/cliparser/argtable3.c b/client/deps/cliparser/argtable3.c index 783bd303b..dfcccb81b 100644 --- a/client/deps/cliparser/argtable3.c +++ b/client/deps/cliparser/argtable3.c @@ -4639,11 +4639,13 @@ void arg_print_syntax(FILE *fp, void * *argtable, const char *suffix) { /* print GNU style [OPTION] string */ arg_print_gnuswitch(fp, table); + size_t len = 0; + /* print remaining options in abbreviated style */ for (tabindex = 0; table[tabindex] && !(table[tabindex]->flag & ARG_TERMINATOR); tabindex++) { - char syntax[200] = ""; + char syntax[400] = ""; const char *shortopts, *longopts, *datatype; /* skip short options without arg values (they were printed by arg_print_gnu_switch) */ @@ -4681,6 +4683,12 @@ void arg_print_syntax(FILE *fp, void * *argtable, const char *suffix) { break; } } + + len += strlen(syntax); + if (len > 60) { + fprintf(fp, "\n "); + len = 0; + } } if (suffix) From 827c529aea08a654ac0ca20a0083fd2c356d982a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 18:56:37 +0100 Subject: [PATCH 26/34] lf t55 config - now uses cliparser... and texts --- client/src/cmdlft55xx.c | 348 +++++++++++++++++++++------------------- client/src/cmdlft55xx.h | 8 +- 2 files changed, 189 insertions(+), 167 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 30d60ff61..4f4e6ca27 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -50,7 +50,7 @@ t55xx_conf_block_t config = { .inverted = false, .offset = 0x00, .block0 = 0x00, - .block0Status = notSet, + .block0Status = NOTSET, .Q5 = false, .usepwd = false, .downlink_mode = refFixedBit @@ -106,27 +106,7 @@ static void arg_add_t55xx_downloadlink(void *at[], uint8_t *idx, uint8_t show, u *idx = n; } -static int usage_t55xx_config(void) { - PrintAndLogEx(NORMAL, "Usage: lf t55xx config [c ] [d ] [i [0/1]] [o ] [Q5 [0/1]] [ST [0/1]]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h - This help"); - PrintAndLogEx(NORMAL, " c - set configuration from a block0"); - PrintAndLogEx(NORMAL, " b <8|16|32|40|50|64|100|128> - Set bitrate"); - PrintAndLogEx(NORMAL, " d - Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A"); - PrintAndLogEx(NORMAL, " i [0/1] - Set/reset data signal inversion"); - PrintAndLogEx(NORMAL, " o [offset] - Set offset, where data should start decode in bitstream"); - PrintAndLogEx(NORMAL, " Q5 [0/1] - Set/reset as Q5/T5555 chip instead of T55x7"); - PrintAndLogEx(NORMAL, " ST [0/1] - Set/reset Sequence Terminator on"); - PrintAndLogEx(NORMAL, ""); // layout is a little differnet, so seperate until a better fix - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx config d FSK") " - FSK demodulation"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx config d FSK i 1") " - FSK demodulation, inverse data"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx config d FSK i 1 o 3") " - FSK demodulation, inverse data, offset=3,start from position 3 to decode data"); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} + static int usage_t55xx_read(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx read [r ] b [p ] [o] "); PrintAndLogEx(NORMAL, "Options:"); @@ -489,141 +469,183 @@ void SetConfigWithBlock0Ex(uint32_t block0, uint8_t offset, bool Q5) { } static int CmdT55xxSetConfig(const char *Cmd) { - // No args - if (strlen(Cmd) == 0) return printConfiguration(config); + if (strlen(Cmd) == 0) { + PrintAndLogEx(INFO, "--- " _CYAN_("current t55xx config") " --------------------------"); + return printConfiguration(config); + } + + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf t55xx config", + "Set/Get T55XX configuration of the pm3 client. Like modulation, inverted, offset, rate etc.\n" + "Offset is start position to decode data.", + "lf t55xx config --FSK --> FSK demodulation\n" + "lf t55xx config --FSK -i --> FSK demodulation, inverse data\n" + "lf t55xx config --FSK -i -o 3 --> FSK demodulation, inverse data, offset 3\n" + ); + + // 1 (help) + 19 (user specified params) + (5 T55XX_DLMODE_SINGLE) + void *argtable[1 + 12 + 6 + 5] = { + arg_param_begin, + arg_lit0(NULL, "FSK", "set demodulation FSK"), + arg_lit0(NULL, "FSK1", "set demodulation FSK 1"), + arg_lit0(NULL, "FSK1A", "set demodulation FSK 1a (inv)"), + arg_lit0(NULL, "FSK2", "set demodulation FSK 2"), + arg_lit0(NULL, "FSK2A", "set demodulation FSK 2a (inv)"), + arg_lit0(NULL, "ASK", "set demodulation ASK"), + arg_lit0(NULL, "PSK1", "set demodulation PSK 1"), + arg_lit0(NULL, "PSK2", "set demodulation PSK 2"), + arg_lit0(NULL, "PSK3", "set demodulation PSK 3"), + arg_lit0(NULL, "NRZ", "set demodulation NRZ"), + arg_lit0(NULL, "BI", "set demodulation Biphase"), + arg_lit0(NULL, "BIA", "set demodulation Diphase (inverted biphase)"), + arg_lit0("i", "inv", "set/reset data signal inversion"), + arg_lit0(NULL, "q5", "set/reset as Q5/T5555 chip instead of T55x7"), + arg_lit0(NULL, "st", "set/reset Sequence Terminator on"), + arg_int0(NULL, "rate", "", "set bitrate <8|16|32|40|50|64|100|128>"), + arg_str0("c", "blk0", "", "set configuration from a block0 (4 hex bytes)"), + arg_int0("o", "offset", "", "set offset, where data should start decode in bitstream"), + }; + + uint8_t idx = 19; + arg_add_t55xx_downloadlink(argtable, &idx, T55XX_DLMODE_SINGLE, config.downlink_mode); + CLIExecWithReturn(ctx, Cmd, argtable, true); + + idx = 1; + bool mods[12]; + int verify_mods = 0; + while (idx - 1 < sizeof(mods)) { + mods[idx - 1] = arg_get_lit(ctx, idx); + verify_mods += mods[idx - 1]; + idx++; + } + + bool invert = arg_get_lit(ctx, idx++); + bool use_q5 = arg_get_lit(ctx, idx++); + bool use_st = arg_get_lit(ctx, idx++); + + int bitrate = arg_get_int_def(ctx, idx++, -1); - uint8_t offset = 0, bitRate = 0; - char modulation[6] = {0x00}; - uint8_t rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0}; - uint8_t cmdp = 0; - uint8_t downlink_mode = 0; - bool errors = false; - uint32_t block0 = 0; bool gotconf = false; + uint32_t block0 = 0; + int res = arg_get_u32_hexstr_def_nlen(ctx, idx++, 0, &block0, 4, true); + if (res == 0 || res == 2) { + PrintAndLogEx(ERR, "block0 data must be 4 hex bytes"); + CLIParserFree(ctx); + return PM3_EINVARG; + } + if (res == 1) { + gotconf = true; + } - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - char tmp = tolower(param_getchar(Cmd, cmdp)); - switch (tmp) { - case 'h': - return usage_t55xx_config(); - case 'b': - errors |= param_getdec(Cmd, cmdp + 1, &bitRate); - if (!errors) { - uint8_t i = 0; - for (; i < 9; i++) { - if (rates[i] == bitRate) { - config.bitrate = i; - config.block0 = ((config.block0 & ~(0x1c0000)) | (i << 18)); - break; - } - } - if (i == 9) errors = true; - } - cmdp += 2; - break; - case 'c': - block0 = param_get32ex(Cmd, cmdp + 1, 0, 16); - gotconf = true; - cmdp += 2; - break; - case 'd': - param_getstr(Cmd, cmdp + 1, modulation, sizeof(modulation)); - cmdp += 2; + int offset = arg_get_int_def(ctx, idx++, -1); - if (strcmp(modulation, "FSK") == 0) { - config.modulation = DEMOD_FSK; - } else if (strcmp(modulation, "FSK1") == 0) { - config.modulation = DEMOD_FSK1; - config.inverted = 1; - } else if (strcmp(modulation, "FSK1a") == 0) { - config.modulation = DEMOD_FSK1a; - config.inverted = 0; - } else if (strcmp(modulation, "FSK2") == 0) { - config.modulation = DEMOD_FSK2; - config.inverted = 0; - } else if (strcmp(modulation, "FSK2a") == 0) { - config.modulation = DEMOD_FSK2a; - config.inverted = 1; - } else if (strcmp(modulation, "ASK") == 0) { - config.modulation = DEMOD_ASK; - } else if (strcmp(modulation, "NRZ") == 0) { - config.modulation = DEMOD_NRZ; - } else if (strcmp(modulation, "PSK1") == 0) { - config.modulation = DEMOD_PSK1; - } else if (strcmp(modulation, "PSK2") == 0) { - config.modulation = DEMOD_PSK2; - } else if (strcmp(modulation, "PSK3") == 0) { - config.modulation = DEMOD_PSK3; - } else if (strcmp(modulation, "BIa") == 0) { - config.modulation = DEMOD_BIa; - config.inverted = 1; - } else if (strcmp(modulation, "BI") == 0) { - config.modulation = DEMOD_BI; - config.inverted = 0; - } else { - PrintAndLogEx(WARNING, "Unknown modulation '%s'", modulation); - errors = true; - } - config.block0 = ((config.block0 & ~(0x1f000)) | (config.modulation << 12)); - break; - case 'i': - if ((param_getchar(Cmd, cmdp + 1) == '0') || (param_getchar(Cmd, cmdp + 1) == '1')) { - config.inverted = param_getchar(Cmd, cmdp + 1) == '1'; - cmdp += 2; - } else { - config.inverted = true; - cmdp += 1; - } - break; - case 'o': - errors |= param_getdec(Cmd, cmdp + 1, &offset); - if (!errors) - config.offset = offset; - cmdp += 2; - break; - case 'q': - if ((param_getchar(Cmd, cmdp + 1) == '0') || (param_getchar(Cmd, cmdp + 1) == '1')) { - config.Q5 = param_getchar(Cmd, cmdp + 1) == '1'; - cmdp += 2; - } else { - config.Q5 = true; - cmdp += 1; - } - break; - case 's': - if ((param_getchar(Cmd, cmdp + 1) == '0') || (param_getchar(Cmd, cmdp + 1) == '1')) { - config.ST = param_getchar(Cmd, cmdp + 1) == '1'; - cmdp += 2; - } else { - config.ST = true; - cmdp += 1; - } - config.block0 = ((config.block0 & ~(0x8)) | (config.ST << 3)); - break; - case 'r': - errors = param_getdec(Cmd, cmdp + 1, &downlink_mode); - if (downlink_mode > 3) - downlink_mode = 0; - if (!errors) - config.downlink_mode = downlink_mode; - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; + bool r0 = arg_get_lit(ctx, idx++); + bool r1 = arg_get_lit(ctx, idx++); + bool r2 = arg_get_lit(ctx, idx++); + bool r3 = arg_get_lit(ctx, idx++); + CLIParserFree(ctx); + + // validate user specified downlink mode + if ((r0 + r1 + r2 + r3) > 1) { + PrintAndLogEx(FAILED, "Error multiple downlink encoding"); + return PM3_EINVARG; + } + + // validate user specified modulation FSK,FSK1,...BIA + if (verify_mods > 1) { + PrintAndLogEx(FAILED, "Error multiple demodulations, select one"); + return PM3_EINVARG; + } + + // validate user specified bitrate + uint8_t rates[9] = {8, 16, 32, 40, 50, 64, 100, 128, 0}; + if (bitrate != -1) { + uint8_t i = 0; + for (; i < ARRAYLEN(rates); i++) { + if (rates[i] == bitrate) { + config.bitrate = i; + config.block0 = ((config.block0 & ~(0x1c0000)) | (i << 18)); break; + } + } + if (i == 9){ + PrintAndLogEx(FAILED, "Error select a valid bitrate"); + return PM3_EINVARG; } } - //Validations - if (errors) return usage_t55xx_config(); + // validate user specified offset + if (offset > -1) { + config.offset = offset; + } - config.block0Status = userSet; + // validate user specific T5555 / Q5 + config.Q5 = use_q5; + + // validate user specific sequence terminator + config.ST = use_st; + if (use_st) { + config.block0 = ((config.block0 & ~(0x8)) | (config.ST << 3)); + } + + // validate user specific invert + config.inverted = invert; + + // validate user specific downlink mode + uint8_t downlink_mode = config.downlink_mode; + if (r0) + downlink_mode = refFixedBit; + else if (r1) + downlink_mode = refLongLeading; + else if (r2) + downlink_mode = refLeading0; + else if (r3) + downlink_mode = ref1of4; + + config.downlink_mode = downlink_mode; + + // validate user specific modulation + if (mods[0]){ + config.modulation = DEMOD_FSK; + } else if (mods[1]) { + config.modulation = DEMOD_FSK1; + config.inverted = 0; + } else if (mods[2]) { + config.modulation = DEMOD_FSK1a; + config.inverted = 1; + } else if (mods[3]) { + config.modulation = DEMOD_FSK2; + config.inverted = 0; + } else if (mods[4]) { + config.modulation = DEMOD_FSK2a; + config.inverted = 1; + } else if (mods[5]) { + config.modulation = DEMOD_ASK; + } else if (mods[6]) { + config.modulation = DEMOD_PSK1; + } else if (mods[7]) { + config.modulation = DEMOD_PSK2; + } else if (mods[8]) { + config.modulation = DEMOD_PSK3; + } else if (mods[9]) { + config.modulation = DEMOD_NRZ; + } else if (mods[10]) { + config.modulation = DEMOD_BI; + config.inverted = 0; + } else if (mods[11]) { + config.modulation = DEMOD_BIa; + config.inverted = 1; + } + + config.block0 = ((config.block0 & ~(0x1f000)) | (config.modulation << 12)); + + config.block0Status = USERSET; if (gotconf) { SetConfigWithBlock0Ex(block0, config.offset, config.Q5); } + PrintAndLogEx(INFO, "--- " _CYAN_("current t55xx config") " --------------------------"); return printConfiguration(config); } int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode) { @@ -1201,7 +1223,7 @@ bool t55xxTryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32 config.pwd = pwd & 0xffffffff; } - config.block0Status = autoDetect; + config.block0Status = AUTODETECT; if (print_config) printConfiguration(config); @@ -1237,7 +1259,7 @@ bool t55xxTryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32 PrintAndLogEx(NORMAL, "--[%d]---------------", i + 1); } - config.block0Status = autoDetect; + config.block0Status = AUTODETECT; if (print_config) printConfiguration(tests[i]); } @@ -1514,17 +1536,17 @@ int CmdT55xxSpecial(const char *Cmd) { } int printConfiguration(t55xx_conf_block_t b) { - PrintAndLogEx(INFO, " Chip Type : " _GREEN_("%s"), (b.Q5) ? "Q5/T5555" : "T55x7"); - PrintAndLogEx(INFO, " Modulation : " _GREEN_("%s"), GetSelectedModulationStr(b.modulation)); - PrintAndLogEx(INFO, " Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); - PrintAndLogEx(INFO, " Inverted : %s", (b.inverted) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(INFO, " Offset : %d", b.offset); - PrintAndLogEx(INFO, " Seq. Term. : %s", (b.ST) ? _GREEN_("Yes") : "No"); - PrintAndLogEx(INFO, " Block0 : 0x%08X %s", b.block0, GetConfigBlock0Source(b.block0Status)); - PrintAndLogEx(INFO, " Downlink Mode : %s", GetDownlinkModeStr(b.downlink_mode)); - PrintAndLogEx(INFO, " Password Set : %s", (b.usepwd) ? _RED_("Yes") : _GREEN_("No")); + PrintAndLogEx(INFO, " Chip type......... " _GREEN_("%s"), (b.Q5) ? "Q5/T5555" : "T55x7"); + PrintAndLogEx(INFO, " Modulation........ " _GREEN_("%s"), GetSelectedModulationStr(b.modulation)); + PrintAndLogEx(INFO, " Bit rate.......... %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); + PrintAndLogEx(INFO, " Inverted.......... %s", (b.inverted) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, " Offset............ %d", b.offset); + PrintAndLogEx(INFO, " Seq. terminator... %s", (b.ST) ? _GREEN_("Yes") : "No"); + PrintAndLogEx(INFO, " Block0............ %08X %s", b.block0, GetConfigBlock0Source(b.block0Status)); + PrintAndLogEx(INFO, " Downlink mode..... %s", GetDownlinkModeStr(b.downlink_mode)); + PrintAndLogEx(INFO, " Password set...... %s", (b.usepwd) ? _RED_("Yes") : _GREEN_("No")); if (b.usepwd) { - PrintAndLogEx(INFO, " Password : %08X", b.pwd); + PrintAndLogEx(INFO, " Password.......... %08X", b.pwd); } PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; @@ -2714,17 +2736,17 @@ char *GetConfigBlock0Source(uint8_t id) { char *retStr = buf; switch (id) { - case autoDetect: - snprintf(retStr, sizeof(buf), _YELLOW_("(Auto detect)")); + case AUTODETECT: + snprintf(retStr, sizeof(buf), _YELLOW_("(auto detect)")); break; - case userSet: - snprintf(retStr, sizeof(buf), _YELLOW_("(User set)")); + case USERSET: + snprintf(retStr, sizeof(buf), _YELLOW_("(user set)")); break; - case tagRead: - snprintf(retStr, sizeof(buf), _GREEN_("(Tag read)")); + case TAGREAD: + snprintf(retStr, sizeof(buf), _GREEN_("(tag read)")); break; default: - snprintf(retStr, sizeof(buf), _RED_("(Unknown)")); + snprintf(retStr, sizeof(buf), _RED_("(n/a)")); break; } return buf; @@ -4249,7 +4271,7 @@ static command_t CommandTable[] = { {"info", CmdT55xxInfo, AlwaysAvailable, "Show T55x7 configuration data (page 0/ blk 0)"}, {"p1detect", CmdT55xxDetectPage1, IfPm3Lf, "Try detecting if this is a t55xx tag by reading page 1"}, {"read", CmdT55xxReadBlock, IfPm3Lf, "Read T55xx block data"}, - {"resetread", CmdResetRead, IfPm3Lf, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"}, + {"resetread", CmdResetRead, IfPm3Lf, "Send Reset Cmd then lf read the stream to attempt to identify the start of it"}, {"restore", CmdT55xxRestore, IfPm3Lf, "Restore T55xx card Page 0 / Page 1 blocks"}, {"trace", CmdT55xxReadTrace, AlwaysAvailable, "Show T55x7 traceability data (page 1/ blk 0-1)"}, {"wakeup", CmdT55xxWakeUp, IfPm3Lf, "Send AOR wakeup command"}, diff --git a/client/src/cmdlft55xx.h b/client/src/cmdlft55xx.h index 1a31772eb..d9061d039 100644 --- a/client/src/cmdlft55xx.h +++ b/client/src/cmdlft55xx.h @@ -127,10 +127,10 @@ typedef struct { uint8_t offset; uint32_t block0; enum { - notSet = 0x00, - autoDetect = 0x01, - userSet = 0x02, - tagRead = 0x03, + NOTSET = 0x00, + AUTODETECT = 0x01, + USERSET = 0x02, + TAGREAD = 0x03, } block0Status; enum { RF_8 = 0x00, From e9b8ed71a70154803b4de009b23fce5c771fccd5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 18:58:55 +0100 Subject: [PATCH 27/34] text --- doc/cliparser_todo.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/doc/cliparser_todo.txt b/doc/cliparser_todo.txt index 44f0bac7d..a7e55eba5 100644 --- a/doc/cliparser_todo.txt +++ b/doc/cliparser_todo.txt @@ -32,7 +32,6 @@ data print data samples data setdebugmode data tune -hf 14b sriwrite hf 15 dump hf 15 info hf 15 raw @@ -94,12 +93,6 @@ lf hitag sim lf hitag writer lf hitag dump lf hitag cc -lf t55xx config -lf t55xx dump -lf t55xx info lf t55xx read -lf t55xx resetread -lf t55xx restore -lf t55xx trace lf t55xx write script run From d93bcd40744dc0f5df437c6d850f9de5f0502487 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 19:04:14 +0100 Subject: [PATCH 28/34] text --- client/src/cmdlft55xx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 4f4e6ca27..eae67d01e 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -151,10 +151,10 @@ static int usage_t55xx_clonehelp(void) { PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:"); PrintAndLogEx(NORMAL, _GREEN_("lf awid clone")); PrintAndLogEx(NORMAL, _GREEN_("lf destron clone")); - PrintAndLogEx(NORMAL, _GREEN_("lf em 410x_clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf em 410x clone")); // todo: implement restore -// PrintAndLogEx(NORMAL, _GREEN_("lf em 4x05_write")); -// PrintAndLogEx(NORMAL, _GREEN_("lf em 4x50_write")); +// PrintAndLogEx(NORMAL, _GREEN_("lf em 4x05 write")); +// PrintAndLogEx(NORMAL, _GREEN_("lf em 4x50 write")); PrintAndLogEx(NORMAL, _GREEN_("lf fdxb clone")); PrintAndLogEx(NORMAL, _GREEN_("lf gallagher clone")); PrintAndLogEx(NORMAL, _GREEN_("lf gproxii clone")); @@ -163,9 +163,10 @@ static int usage_t55xx_clonehelp(void) { PrintAndLogEx(NORMAL, _GREEN_("lf io clone")); PrintAndLogEx(NORMAL, _GREEN_("lf jablotron clone")); PrintAndLogEx(NORMAL, _GREEN_("lf keri clone")); - PrintAndLogEx(NORMAL, _GREEN_("lf nedap clone")); - PrintAndLogEx(NORMAL, _GREEN_("lf noralsy clone")); PrintAndLogEx(NORMAL, _GREEN_("lf motorola clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf nedap clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf nexwatch clone")); + PrintAndLogEx(NORMAL, _GREEN_("lf noralsy clone")); PrintAndLogEx(NORMAL, _GREEN_("lf pac clone")); PrintAndLogEx(NORMAL, _GREEN_("lf paradox clone")); PrintAndLogEx(NORMAL, _GREEN_("lf presco clone")); From a3b42e27cf6b7cbe39d5cc98509e1ded8d58c635 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 20:24:13 +0100 Subject: [PATCH 29/34] lf t55xx read - now uses cliparser --- client/src/cmdlft55xx.c | 150 +++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 80 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index eae67d01e..fd0b4f893 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -66,6 +66,8 @@ void Set_t55xx_Config(t55xx_conf_block_t conf) { config = conf; } +static int CmdHelp(const char *Cmd); + static void print_usage_t55xx_downloadlink(uint8_t ShowAll, uint8_t dl_mode_default) { if (ShowAll == T55XX_DLMODE_ALL) PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3|4"); @@ -106,28 +108,6 @@ static void arg_add_t55xx_downloadlink(void *at[], uint8_t *idx, uint8_t show, u *idx = n; } - -static int usage_t55xx_read(void) { - PrintAndLogEx(NORMAL, "Usage: lf t55xx read [r ] b [p ] [o] "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " b - block number to read. Between 0-7"); - PrintAndLogEx(NORMAL, " p - OPTIONAL password (8 hex characters)"); - PrintAndLogEx(NORMAL, " o - OPTIONAL override safety check"); - PrintAndLogEx(NORMAL, " 1 - OPTIONAL 0|1 read Page 1 instead of Page 0"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); - PrintAndLogEx(NORMAL, " " _RED_("**** WARNING ****")); - PrintAndLogEx(NORMAL, " Use of read with password on a tag not configured"); - PrintAndLogEx(NORMAL, " for a password can damage the tag"); - PrintAndLogEx(NORMAL, " " _RED_("*****************")); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx read b 0") " - read data from block 0"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx read b 0 p feedbeef") " - read data from block 0 password feedbeef"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx read b 0 p feedbeef o") " - read data from block 0 password feedbeef safety check"); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - static int usage_t55xx_write(void) { PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r ] b d [p ] [1] [t] [v]"); PrintAndLogEx(NORMAL, "Options:"); @@ -147,7 +127,8 @@ static int usage_t55xx_write(void) { return PM3_SUCCESS; } -static int usage_t55xx_clonehelp(void) { +static int CmdT55xxCloneHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:"); PrintAndLogEx(NORMAL, _GREEN_("lf awid clone")); PrintAndLogEx(NORMAL, _GREEN_("lf destron clone")); @@ -177,13 +158,6 @@ static int usage_t55xx_clonehelp(void) { return PM3_SUCCESS; } -static int CmdHelp(const char *Cmd); - -static int CmdT55xxCloneHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - return usage_t55xx_clonehelp(); -} - static void T55x7_SaveBlockData(uint8_t idx, uint32_t data) { if (idx < T55x7_BLOCK_COUNT) { cardmem[idx].valid = true; @@ -665,6 +639,7 @@ int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, u if (t55xxTryDetectModulationEx(downlink_mode, false, 0, password) == false) { PrintAndLogEx(WARNING, "Safety check: Could not detect if PWD bit is set in config block. Exits."); + PrintAndLogEx(HINT, "Consider using the override parameter to force read."); return PM3_EWRONGANSWER; } else { PrintAndLogEx(WARNING, "Safety check: PWD bit is NOT set in config block. Reading without password..."); @@ -689,51 +664,67 @@ int T55xxReadBlockEx(uint8_t block, bool page1, bool usepwd, uint8_t override, u } static int CmdT55xxReadBlock(const char *Cmd) { - uint8_t block = REGULAR_READ_MODE_BLOCK; - uint8_t override = 0; - uint8_t cmdp = 0; - uint8_t downlink_mode = config.downlink_mode; - uint32_t password = 0; //default to blank Block 7 + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf t55xx read", + "Read T55xx block data. This commands defaults to page 0.\n\n" + _RED_(" * * * WARNING * * *") "\n" + _CYAN_("Use of read with password on a tag not configured") "\n" + _CYAN_("for a password can damage the tag") "\n" + _RED_(" * * * * * * * * * *"), + "lf t55xx read -b 0 --> read data from block 0\n" + "lf t55xx read -b 0 --pwd 01020304 --> read data from block 0, pwd 01020304\n" + "lf t55xx read -b 0 --pwd 01020304 -o --> read data from block 0, pwd 01020304, override\n" + ); + + // 1 (help) + 4(four user specified params) + (5 T55XX_DLMODE_SINGLE) + void *argtable[5 + 5] = { + arg_param_begin, + arg_int1("b", "blk", "<0-7>", "block number to read"), + arg_str0("p", "pwd", "", "password (4 hex bytes)"), + arg_lit0("o", "override", "override safety check"), + arg_lit0(NULL, "pg1", "read page 1"), + }; + uint8_t idx = 5; + arg_add_t55xx_downloadlink(argtable, &idx, T55XX_DLMODE_SINGLE, config.downlink_mode); + CLIExecWithReturn(ctx, Cmd, argtable, true); + + int block = arg_get_int_def(ctx, 1, REGULAR_READ_MODE_BLOCK); + bool usepwd = false; - bool page1 = false; - bool errors = false; - - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_t55xx_read(); - case 'b': - errors |= param_getdec(Cmd, cmdp + 1, &block); - cmdp += 2; - break; - case 'o': - override = 1; - cmdp++; - break; - case 'p': - password = param_get32ex(Cmd, cmdp + 1, 0, 16); - usepwd = true; - cmdp += 2; - break; - case '1': - page1 = true; - cmdp++; - break; - case 'r': - downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) - downlink_mode = 0; - - cmdp += 2; - break; - - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } + uint32_t password = 0; + int res = arg_get_u32_hexstr_def_nlen(ctx, 2, 0, &password, 4, true); + if (res == 0 || res == 2) { + PrintAndLogEx(ERR, "Password should be 4 hex bytes"); + CLIParserFree(ctx); + return PM3_EINVARG; } - if (errors || cmdp == 0) return usage_t55xx_read(); + if (res == 1) { + usepwd = true; + } + + uint8_t override = arg_get_lit(ctx, 3); + bool page1 = arg_get_lit(ctx, 4); + + bool r0 = arg_get_lit(ctx, 5); + bool r1 = arg_get_lit(ctx, 6); + bool r2 = arg_get_lit(ctx, 7); + bool r3 = arg_get_lit(ctx, 8); + CLIParserFree(ctx); + + if ((r0 + r1 + r2 + r3) > 1) { + PrintAndLogEx(FAILED, "Error multiple downlink encoding"); + return PM3_EINVARG; + } + + uint8_t downlink_mode = config.downlink_mode; + if (r0) + downlink_mode = refFixedBit; + else if (r1) + downlink_mode = refLongLeading; + else if (r2) + downlink_mode = refLeading0; + else if (r3) + downlink_mode = ref1of4; if (block > 7 && block != REGULAR_READ_MODE_BLOCK) { PrintAndLogEx(NORMAL, "Block must be between 0 and 7"); @@ -1316,17 +1307,16 @@ bool GetT55xxBlockData(uint32_t *blockdata) { void printT55xxBlock(uint8_t blockNum, bool page1) { - uint32_t blockData = 0; - uint8_t bytes[4] = {0}; - - if (GetT55xxBlockData(&blockData) == false) + uint32_t val = 0; + if (GetT55xxBlockData(&val) == false) return; - num_to_bytes(blockData, 4, bytes); + uint8_t bytes[4] = {0}; + num_to_bytes(val, 4, bytes); - T55x7_SaveBlockData((page1) ? blockNum + 8 : blockNum, blockData); + T55x7_SaveBlockData((page1) ? blockNum + 8 : blockNum, val); - PrintAndLogEx(SUCCESS, " %02d | %08X | %s | %s", blockNum, blockData, sprint_bin(DemodBuffer + config.offset, 32), sprint_ascii(bytes, 4)); + PrintAndLogEx(SUCCESS, " %02d | %08X | %s | %s", blockNum, val, sprint_bin(DemodBuffer + config.offset, 32), sprint_ascii(bytes, 4)); } static bool testModulation(uint8_t mode, uint8_t modread) { From 214fe8ce7492a16756ab010cdf84c0b91cca1db9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 20:38:51 +0100 Subject: [PATCH 30/34] updated text --- doc/T5577_Guide.md | 234 +++++++++++++++++++++++---------------------- 1 file changed, 120 insertions(+), 114 deletions(-) diff --git a/doc/T5577_Guide.md b/doc/T5577_Guide.md index cdffadd20..8e22aab86 100644 --- a/doc/T5577_Guide.md +++ b/doc/T5577_Guide.md @@ -1,8 +1,9 @@ # T5577 Introduction Guide -### Based on RRG proxmark3 fork. +### Based on RRG/Iceman Proxmark3 repo ### Ver.1 8 Sep 2019 +### Ver.2 7 March 2021 | Contents | | ----------------------------------------------------------------------------------- | @@ -79,14 +80,16 @@ examples shown, it will be assumed you have run the detect command. ``` You should see a results simular to the following: ``` - Chip Type : T55x7 - Modulation : ASK - Bit Rate : 2 - RF/32 - Inverted : No - Offset : 32 - Seq. Term. : Yes - Block0 : 0x000880E0 - Downlink Mode : default/fixed bit length + [=] Chip type......... T55x7 + [=] Modulation........ ASK + [=] Bit rate.......... 2 - RF/32 + [=] Inverted.......... No + [=] Offset............ 33 + [=] Seq. terminator... Yes + [=] Block0............ 000880E0 (auto detect) + [=] Downlink mode..... default/fixed bit length + [=] Password set...... No + ``` Now that the proxmark3 has detected a T55x7 chip, and found some information about it, we should be able to see all the data on the chip. @@ -140,7 +143,7 @@ can see the card) as, run a low frequency (lf) command for the T55xx chip (t55xx) and read block (b) number 1. ``` - [usb] pm3 --> lf t55xx read b 1 + [usb] pm3 --> lf t55xx read -b 1 ``` result: ``` @@ -164,7 +167,7 @@ can see the card) ``` 3) Now, lets check if the data was written. ``` - [usb] pm3 --> lf t55xx read b 1 + [usb] pm3 --> lf t55xx read -b 1 ``` result: ``` @@ -210,7 +213,7 @@ can see the card) ``` and check ``` - [usb] pm3 --> lf t55xx read b 1 + [usb] pm3 --> lf t55xx read -b 1 ``` result: ``` @@ -272,9 +275,10 @@ required, please do not proceed. ``` Result: ``` - [=] Begin wiping T55x7 tag + [=] Target T55x7 tag + [=] Default configuration block 000880E0 - [=] Default configation block 000880E0 + [=] Begin wiping... [=] Writing page 0 block: 00 data: 0x000880E0 [=] Writing page 0 block: 01 data: 0x00000000 [=] Writing page 0 block: 02 data: 0x00000000 @@ -291,14 +295,15 @@ required, please do not proceed. ``` result: ``` - Chip Type : T55x7 - Modulation : ASK - Bit Rate : 2 - RF/32 - Inverted : No - Offset : 32 - Seq. Term. : Yes - Block0 : 0x000880E0 - Downlink Mode : default/fixed bit length + [=] Chip type......... T55x7 + [=] Modulation........ ASK + [=] Bit rate.......... 2 - RF/32 + [=] Inverted.......... No + [=] Offset............ 33 + [=] Seq. terminator... Yes + [=] Block0............ 000880E0 (auto detect) + [=] Downlink mode..... default/fixed bit length + [=] Password set...... No ``` If block 0 does not hold the hex data **0x00088040 resolve this @@ -412,18 +417,20 @@ required, please do not proceed. Lets try again, but this time supply the password. We use the option p followed by the password. ``` - [usb] pm3 --> lf t55 detect p 12345678 + [usb] pm3 --> lf t55 detect -p 12345678 ``` result: ``` - Chip Type : T55x7 - Modulation : ASK - Bit Rate : 2 - RF/32 - Inverted : No - Offset : 32 - Seq. Term. : Yes - Block0 : 0x00088050 - Downlink Mode : default/fixed bit length + [=] Chip type......... T55x7 + [=] Modulation........ ASK + [=] Bit rate.......... 2 - RF/32 + [=] Inverted.......... No + [=] Offset............ 33 + [=] Seq. terminator... Yes + [=] Block0............ 00088050 (auto detect) + [=] Downlink mode..... default/fixed bit length + [=] Password set...... Yes + [=] Password.......... 00000000 ``` 7) Write a block of data with a password @@ -445,7 +452,7 @@ required, please do not proceed. The proxmark3 has a safety check\! ``` - [usb] pm3 --> lf t55xx read b 1 p 12345678 + [usb] pm3 --> lf t55xx read -b 1 -p 12345678 ``` result: ``` @@ -453,6 +460,7 @@ required, please do not proceed. [+] blk | hex data | binary | ascii [+] ----+----------+----------------------------------+------- [!] Safety check: Could not detect if PWD bit is set in config block. Exits. + [?] Consider using the override parameter to force read. ``` Note that the proxmark3 did not read the block, the safty kicked in @@ -460,7 +468,7 @@ required, please do not proceed. Lets try again with the ‘o’ option as we know the password is set. ``` - [usb] pm3 --> lf t55xx read b 1 p 12345678 o + [usb] pm3 --> lf t55xx read -b 1 -p 12345678 -o ``` result: ``` @@ -498,14 +506,15 @@ required, please do not proceed. ``` result: ``` - Chip Type : T55x7 - Modulation : ASK - Bit Rate : 2 - RF/32 - Inverted : No - Offset : 32 - Seq. Term. : Yes - Block0 : 0x00088040 - Downlink Mode : default/fixed bit length + [=] Chip type......... T55x7 + [=] Modulation........ ASK + [=] Bit rate.......... 2 - RF/32 + [=] Inverted.......... No + [=] Offset............ 33 + [=] Seq. terminator... Yes + [=] Block0............ 00088040 (auto detect) + [=] Downlink mode..... default/fixed bit length + [=] Password set...... No ``` Yes we can and we can see Block 0 is the correct config 00088040 @@ -571,14 +580,16 @@ password set (if not, review and get you card back to this state). 1) Lets turn you T5577 into an EM4100 with ID 1122334455 ``` - [usb] pm3 --> lf em 410x_write 1122334455 1 + [usb] pm3 --> lf em 410x clone --id 1122334455 ``` result: ``` - [+] Writing T55x7 tag with UID 0x1122334455 (clock rate: 64) - #db# Started writing T55x7 tag ... - #db# Clock rate: 64 - #db# Tag T55x7 written with 0xff8c65298c94a940 + [+] Preparing to clone EM4102 to T55x7 tag with ID 0F0368568B (RF/64) + [#] Clock rate: 64 + [#] Tag T55x7 written with 0xff83c03322a646e4 + + [+] Done + [?] Hint: try `lf em 410x reader` to verify ``` 2) Check this has work. @@ -586,42 +597,38 @@ password set (if not, review and get you card back to this state). [usb] pm3 --> lf search ``` result: - ``` - [=] NOTE: some demods output possible binary - [=] if it finds something that looks like a tag - [=] False Positives ARE possible - [=] - [=] Checking for known tags... - - [+] EM410x pattern found - - EM TAG ID : 1122334455 - - Possible de-scramble patterns - - Unique TAG ID : 8844CC22AA - HoneyWell IdentKey { - DEZ 8 : 03359829 - DEZ 10 : 0573785173 - DEZ 5.5 : 08755.17493 - DEZ 3.5A : 017.17493 - DEZ 3.5B : 034.17493 - DEZ 3.5C : 051.17493 - DEZ 14/IK2 : 00073588229205 - DEZ 15/IK3 : 000585269781162 - DEZ 20/ZK : 08080404121202021010 - } - Other : 17493_051_03359829 - Pattern Paxton : 289899093 [0x11478255] - Pattern 1 : 5931804 [0x5A831C] - Pattern Sebury : 17493 51 3359829 [0x4455 0x33 0x334455] - - [+] Valid EM410x ID found! - - - [+] Chipset detection : T55xx found - - [+] Try `lf t55xx` commands + ``` + [=] NOTE: some demods output possible binary + [=] if it finds something that looks like a tag + [=] False Positives ARE possible + [=] + [=] Checking for known tags... + [=] + [+] EM 410x ID 0F0368568B + [+] EM410x ( RF/64 ) + [=] -------- Possible de-scramble patterns --------- + [+] Unique TAG ID : F0C0166AD1 + [=] HoneyWell IdentKey + [+] DEZ 8 : 06837899 + [+] DEZ 10 : 0057169547 + [+] DEZ 5.5 : 00872.22155 + [+] DEZ 3.5A : 015.22155 + [+] DEZ 3.5B : 003.22155 + [+] DEZ 3.5C : 104.22155 + [+] DEZ 14/IK2 : 00064481678987 + [+] DEZ 15/IK3 : 001034014845649 + [+] DEZ 20/ZK : 15001200010606101301 + [=] + [+] Other : 22155_104_06837899 + [+] Pattern Paxton : 259822731 [0xF7C948B] + [+] Pattern 1 : 9750181 [0x94C6A5] + [+] Pattern Sebury : 22155 104 6837899 [0x568B 0x68 0x68568B] + [=] ------------------------------------------------ + + [+] Valid EM410x ID found! + + [+] Chipset detection: T55xx + [?] Hint: try `lf t55xx` commands ``` Looks good. @@ -631,44 +638,43 @@ password set (if not, review and get you card back to this state). ``` result: ``` - [usb] pm3 --> lf t55 detect - Chip Type : T55x7 - Modulation : ASK - Bit Rate : 5 - RF/64 - Inverted : No - Offset : 32 - Seq. Term. : Yes - Block0 : 0x00148040 - Downlink Mode : default/fixed bit length + [=] Chip type......... T55x7 + [=] Modulation........ ASK + [=] Bit rate.......... 5 - RF/64 + [=] Inverted.......... No + [=] Offset............ 33 + [=] Seq. terminator... Yes + [=] Block0............ 00148040 (auto detect) + [=] Downlink mode..... default/fixed bit length + [=] Password set...... No ``` ``` [usb] pm3 --> lf t55xx info ``` result: ``` - - -- T55x7 Configuration & Tag Information -------------------- - ------------------------------------------------------------- - Safer key : 0 - reserved : 0 - Data bit rate : 5 - RF/64 - eXtended mode : No - Modulation : 8 - Manchester - PSK clock frequency : 0 - RF/2 - AOR - Answer on Request : No - OTP - One Time Pad : No - Max block : 2 - Password mode : No - Sequence Terminator : No - Fast Write : No - Inverse data : No - POR-Delay : No - ------------------------------------------------------------- - Raw Data - Page 0 - Block 0 : 0x00148040 00000000000101001000000001000000 - - Config block match : EM unique, Paxton - ------------------------------------------------------------- + + [=] --- T55x7 Configuration & Information --------- + [=] Safer key : 0 + [=] reserved : 0 + [=] Data bit rate : 5 - RF/64 + [=] eXtended mode : No + [=] Modulation : 8 - Manchester + [=] PSK clock frequency : 0 - RF/2 + [=] AOR - Answer on Request : No + [=] OTP - One Time Pad : No + [=] Max block : 2 + [=] Password mode : No + [=] Sequence Terminator : No + [=] Fast Write : No + [=] Inverse data : No + [=] POR-Delay : No + [=] ------------------------------------------------------------- + [=] Raw Data - Page 0, block 0 + [=] 00148040 - 00000000000101001000000001000000 + [=] --- Fingerprint ------------ + [+] Config block match : EM unique, Paxton + ``` We can see that the info gave us more information and confirmed what we decoded by hand. But remember, the detect is still needed so the From 7377a45bd0667332620547aa821152a09c4e7328 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 22:00:33 +0100 Subject: [PATCH 31/34] lf t55xx write - now uses cliparser --- .../luascripts/tests/lf_t55xx_defaultask.lua | 4 +- .../luascripts/tests/lf_t55xx_defaultbi.lua | 4 +- .../luascripts/tests/lf_t55xx_defaultfsk.lua | 4 +- .../luascripts/tests/lf_t55xx_defaultpsk.lua | 4 +- .../luascripts/tests/lf_t55xx_writetest.lua | 12 +- client/src/cmdlft55xx.c | 182 ++++++++---------- doc/T5577_Guide.md | 12 +- doc/cloner_notes.md | 4 +- 8 files changed, 103 insertions(+), 123 deletions(-) diff --git a/client/luascripts/tests/lf_t55xx_defaultask.lua b/client/luascripts/tests/lf_t55xx_defaultask.lua index efb6ce8fe..9e81110b3 100644 --- a/client/luascripts/tests/lf_t55xx_defaultask.lua +++ b/client/luascripts/tests/lf_t55xx_defaultask.lua @@ -20,7 +20,7 @@ The outlined procedure is as following: -- manchester -- bit rate -"lf t55xx write b 0 d 00008040" +"lf t55xx write -b 0 -d 00008040" "lf t55xx detect" "lf t55xx info" @@ -118,7 +118,7 @@ local function test() elseif _ == 1 then local config = pcmd:format(config1, y, config2) - dbg(('lf t55xx write b 0 d %s'):format(config)) + dbg(('lf t55xx write -b 0 -d %s'):format(config)) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) local wc = Command:newNG{cmd = cmds.CMD_LF_T55XX_WRITEBL, data = data} diff --git a/client/luascripts/tests/lf_t55xx_defaultbi.lua b/client/luascripts/tests/lf_t55xx_defaultbi.lua index 495faef02..2590dc38b 100644 --- a/client/luascripts/tests/lf_t55xx_defaultbi.lua +++ b/client/luascripts/tests/lf_t55xx_defaultbi.lua @@ -14,7 +14,7 @@ The outlined procedure is as following: --BIPHASE 00010040 -- -"lf t55xx write b 0 d 00010040" +"lf t55xx write -b 0 -d 00010040" "lf t55xx detect" "lf t55xx info" @@ -112,7 +112,7 @@ local function test() elseif _ == 1 then local config = pcmd:format(config1, y, config2) - dbg(('lf t55xx write b 0 d %s'):format(config)) + dbg(('lf t55xx write -b 0 -d %s'):format(config)) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) diff --git a/client/luascripts/tests/lf_t55xx_defaultfsk.lua b/client/luascripts/tests/lf_t55xx_defaultfsk.lua index 2a5c272c4..9aa50f641 100644 --- a/client/luascripts/tests/lf_t55xx_defaultfsk.lua +++ b/client/luascripts/tests/lf_t55xx_defaultfsk.lua @@ -17,7 +17,7 @@ The outlined procedure is as following: -- FSK1 -- bit rate -"lf t55xx write b 0 d 00007040" +"lf t55xx write -b 0 -d 00007040" "lf t55xx detect" "lf t55xx info" @@ -114,7 +114,7 @@ local function test(modulation) elseif _ == 1 then local config = pcmd:format(config1, y, modulation, config2) - dbg(('lf t55xx write b 0 d %s'):format(config)) + dbg(('lf t55xx write -b 0 -d %s'):format(config)) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) local wc = Command:newNG{cmd = cmds.CMD_LF_T55XX_WRITEBL, data = data} diff --git a/client/luascripts/tests/lf_t55xx_defaultpsk.lua b/client/luascripts/tests/lf_t55xx_defaultpsk.lua index 8b4f0447a..09a4063e8 100644 --- a/client/luascripts/tests/lf_t55xx_defaultpsk.lua +++ b/client/luascripts/tests/lf_t55xx_defaultpsk.lua @@ -11,7 +11,7 @@ desc = [[ This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00088040 The outlined procedure is as following: -"lf t55xx write b 0 d 00088040" +"lf t55xx write -b 0 -d 00088040" "lf t55xx detect" "lf t55xx info" @@ -118,7 +118,7 @@ local function test(modulation) dbg('Writing to T55x7 TAG') local config = cmd:format(bitrate, modulation, clockrate) - dbg(('lf t55xx write b 0 d %s'):format(config)) + dbg(('lf t55xx write -b 0 -d %s'):format(config)) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(config, 32), password, block, flags) diff --git a/client/luascripts/tests/lf_t55xx_writetest.lua b/client/luascripts/tests/lf_t55xx_writetest.lua index cfe46d565..48053db5d 100644 --- a/client/luascripts/tests/lf_t55xx_writetest.lua +++ b/client/luascripts/tests/lf_t55xx_writetest.lua @@ -17,10 +17,10 @@ It will then try to detect and read back those block data and compare if read da lf t55xx wipe lf t55xx detect -lf t55xx write b 1 d 00000000 -lf t55xx write b 2 d ffffffff -lf t55xx write b 3 d 80000000 -lf t55xx write b 4 d 00000001 +lf t55xx write -b 1 -d 00000000 +lf t55xx write -b 2 -d ffffffff +lf t55xx write -b 3 -d 80000000 +lf t55xx write -b 4 -d 00000001 Loop: @@ -278,7 +278,7 @@ local function WipeCard() core.console('rem [ERR:DETECT:WIPED] Failed to detect after wipe') return false else - local wipe_data_cmd = 'lf t55xx write b %s d %s' + local wipe_data_cmd = 'lf t55xx write -b %s -d %s' for _ = 1, #data_blocks_cmds do local val = data_blocks_cmds[_] local c = string.format(wipe_data_cmd, _, val) @@ -321,7 +321,7 @@ local function test(modulation) core.clearCommandBuffer() -- Write Config block - dbg(('lf t55xx write b 0 d %s'):format(p_config_cmd)) + dbg(('lf t55xx write -b 0 -d %s'):format(p_config_cmd)) local data = ('%s%s%s%s'):format(utils.SwapEndiannessStr(p_config_cmd, 32), password, block, flags) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index fd0b4f893..f3993adcc 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -68,19 +68,6 @@ void Set_t55xx_Config(t55xx_conf_block_t conf) { static int CmdHelp(const char *Cmd); -static void print_usage_t55xx_downloadlink(uint8_t ShowAll, uint8_t dl_mode_default) { - if (ShowAll == T55XX_DLMODE_ALL) - PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3|4"); - else - PrintAndLogEx(NORMAL, " r - downlink encoding 0|1|2|3"); - PrintAndLogEx(NORMAL, " 0 - fixed bit length%s", (dl_mode_default == 0) ? " (detected default)" : ""); // default will be whats in config struct - PrintAndLogEx(NORMAL, " 1 - long leading reference%s", (dl_mode_default == 1) ? " (detected default)" : ""); - PrintAndLogEx(NORMAL, " 2 - leading zero%s", (dl_mode_default == 2) ? " (detected default)" : ""); - PrintAndLogEx(NORMAL, " 3 - 1 of 4 coding reference%s", (dl_mode_default == 3) ? " (detected default)" : ""); - if (ShowAll == T55XX_DLMODE_ALL) - PrintAndLogEx(NORMAL, " 4 - Try all downlink modes%s", (dl_mode_default == 4) ? " (default)" : ""); -} - static void arg_add_t55xx_downloadlink(void *at[], uint8_t *idx, uint8_t show, uint8_t dl_mode_def) { char *r0 = (char *)calloc(56, sizeof(uint8_t)); @@ -108,25 +95,6 @@ static void arg_add_t55xx_downloadlink(void *at[], uint8_t *idx, uint8_t show, u *idx = n; } -static int usage_t55xx_write(void) { - PrintAndLogEx(NORMAL, "Usage: lf t55xx write [r ] b d [p ] [1] [t] [v]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " b - block number to write. Between 0-7"); - PrintAndLogEx(NORMAL, " d - 4 bytes of data to write (8 hex characters)"); - PrintAndLogEx(NORMAL, " p - OPTIONAL password 4bytes (8 hex characters)"); - PrintAndLogEx(NORMAL, " 1 - OPTIONAL write Page 1 instead of Page 0"); - PrintAndLogEx(NORMAL, " t - OPTIONAL test mode write - ****DANGER****"); - PrintAndLogEx(NORMAL, " v - OPTIONAL validate data afterwards"); - print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx write b 3 d 11223344") " - write 11223344 to block 3"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx write b 3 d 11223344 p feedbeef") " - write 11223344 to block 3 password feedbeef"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx write b 3 d 11223344 v") " - write 11223344 to block 3 and try to validate data"); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - static int CmdT55xxCloneHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:"); @@ -1544,74 +1512,86 @@ int printConfiguration(t55xx_conf_block_t b) { } static int CmdT55xxWriteBlock(const char *Cmd) { - uint8_t block = 0xFF; // default to invalid block - uint32_t data = 0; // default to blank Block - uint32_t password = 0; // default to blank Block 7 - bool usepwd = false; - bool page1 = false; - bool gotdata = false; - bool testMode = false; - bool errors = false; - bool validate = false; - uint8_t cmdp = 0; - uint32_t downlink_mode = config.downlink_mode; + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf t55xx write", + "Write T55xx block data", + "lf t55xx write -b 3 -d 11223344 --> write 11223344 to block 3\n" + "lf t55xx write -b 3 -d 11223344 --pwd 01020304 --> write 11223344 to block 3, pwd 01020304\n" + "lf t55xx write -b 3 -d 11223344 --pwd 01020304 --verify --> write 11223344 to block 3 and try validating write" + ); - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_t55xx_write(); - case 'b': - errors |= param_getdec(Cmd, cmdp + 1, &block); - cmdp += 2; + // 1 (help) + 6 (six user specified params) + (5 T55XX_DLMODE_SINGLE) + void *argtable[7 + 5] = { + arg_param_begin, + arg_int1("b", "blk", "<0-7>", "block number to write"), + arg_str0("d", "data", "", "data to write (4 hex bytes)"), + arg_str0("p", "pwd", "", "password (4 hex bytes)"), + arg_lit0("t", "tm", "test mode write ( " _RED_("danger") " )"), + arg_lit0(NULL, "pg1", "write page 1"), + arg_lit0(NULL, "verify", "try validate data afterward"), + }; + uint8_t idx = 7; + arg_add_t55xx_downloadlink(argtable, &idx, T55XX_DLMODE_SINGLE, config.downlink_mode); + CLIExecWithReturn(ctx, Cmd, argtable, true); - if (block > 7) { - PrintAndLogEx(WARNING, "Block number must be between 0 and 7"); - errors = true; - } - break; - case 'd': - data = param_get32ex(Cmd, cmdp + 1, 0, 16); - gotdata = true; - cmdp += 2; - break; - case 'p': - password = param_get32ex(Cmd, cmdp + 1, 0, 16); - usepwd = true; - cmdp += 2; - break; - case 't': - testMode = true; - cmdp++; - break; - case '1': - page1 = true; - cmdp++; - break; - case 'r': - downlink_mode = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (downlink_mode > 3) - downlink_mode = 0; + int block = arg_get_int_def(ctx, 1, REGULAR_READ_MODE_BLOCK); - cmdp += 2; - break; - case 'v': - validate = true; - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } + uint32_t data = 0; // default to blank Block + int res = arg_get_u32_hexstr_def_nlen(ctx, 2, 0, &data, 4, true); + if (res == 0 || res == 2) { + PrintAndLogEx(ERR, "data must be 4 hex bytes"); + CLIParserFree(ctx); + return PM3_EINVARG; } - if (errors || !gotdata) return usage_t55xx_write(); - char pwdStr[16] = {0}; - snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password); + bool usepwd = false; + uint32_t password = 0; // default to blank Block 7 + res = arg_get_u32_hexstr_def_nlen(ctx, 3, 0, &password, 4, true); + if (res == 0 || res == 2) { + PrintAndLogEx(ERR, "Password should be 4 hex bytes"); + CLIParserFree(ctx); + return PM3_EINVARG; + } + if (res == 1) { + usepwd = true; + } - PrintAndLogEx(INFO, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : ""); + bool testmode = arg_get_lit(ctx, 4); + bool page1 = arg_get_lit(ctx, 5); + bool validate = arg_get_lit(ctx, 6); - if (t55xxWrite(block, page1, usepwd, testMode, password, downlink_mode, data) != PM3_SUCCESS) { + bool r0 = arg_get_lit(ctx, 7); + bool r1 = arg_get_lit(ctx, 8); + bool r2 = arg_get_lit(ctx, 9); + bool r3 = arg_get_lit(ctx, 10); + CLIParserFree(ctx); + + if ((r0 + r1 + r2 + r3) > 1) { + PrintAndLogEx(FAILED, "Error multiple downlink encoding"); + return PM3_EINVARG; + } + + uint8_t downlink_mode = config.downlink_mode; + if (r0) + downlink_mode = refFixedBit; + else if (r1) + downlink_mode = refLongLeading; + else if (r2) + downlink_mode = refLeading0; + else if (r3) + downlink_mode = ref1of4; + + if (block > 7 && block != REGULAR_READ_MODE_BLOCK) { + PrintAndLogEx(NORMAL, "Block must be between 0 and 7"); + return PM3_ESOFT; + } + + char pwdstr[16] = {0}; + snprintf(pwdstr, sizeof(pwdstr), "pwd: 0x%08X", password); + + PrintAndLogEx(INFO, "Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdstr : ""); + + if (t55xxWrite(block, page1, usepwd, testmode, password, downlink_mode, data) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Write failed"); return PM3_ESOFT; } @@ -2387,7 +2367,7 @@ static int CmdT55xxRestore(const char *Cmd) { char pwdOpt [11] = {0}; // p XXXXXXXX if (usepwd) - snprintf(pwdOpt, sizeof(pwdOpt), "p %08X", password); + snprintf(pwdOpt, sizeof(pwdOpt), "-p %08X", password); uint8_t idx; // Restore endien for writing to card @@ -2406,7 +2386,7 @@ static int CmdT55xxRestore(const char *Cmd) { // write out blocks 1-7 page 0 for (idx = 1; idx <= 7; idx++) { - snprintf(writeCmdOpt, sizeof(writeCmdOpt), "b %d d %08X %s", idx, data[idx], pwdOpt); + snprintf(writeCmdOpt, sizeof(writeCmdOpt), "-b %d -d %08X %s", idx, data[idx], pwdOpt); if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx); @@ -2415,12 +2395,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", data[7]); } // write out blocks 1-3 page 1 for (idx = 9; idx <= 11; idx++) { - snprintf(writeCmdOpt, sizeof(writeCmdOpt), "b %d 1 d %08X %s", idx - 8, data[idx], pwdOpt); + snprintf(writeCmdOpt, sizeof(writeCmdOpt), "-b %d --pg1 -d %08X %s", idx - 8, data[idx], pwdOpt); if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx); @@ -2431,7 +2411,7 @@ static int CmdT55xxRestore(const char *Cmd) { config.downlink_mode = downlink_mode; // Write the page 0 config - snprintf(writeCmdOpt, sizeof(writeCmdOpt), "b 0 d %08X %s", data[0], pwdOpt); + snprintf(writeCmdOpt, sizeof(writeCmdOpt), "-b 0 -d %08X %s", data[0], pwdOpt); if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Warning: error writing blk 0"); } @@ -2961,7 +2941,7 @@ static int CmdT55xxWipe(const char *Cmd) { // Creating cmd string for write block :) char writeData[36] = {0}; char *ptrData = writeData; - snprintf(ptrData, sizeof(writeData), "b 0 "); + snprintf(ptrData, sizeof(writeData), "-b 0 "); if (usepwd) { snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "p %08x ", password); @@ -2973,7 +2953,7 @@ static int CmdT55xxWipe(const char *Cmd) { for (uint8_t blk = 1; blk < 8; blk++) { - snprintf(ptrData, sizeof(writeData), "b %d d 0", blk); + snprintf(ptrData, sizeof(writeData), "-b %d -d 0", blk); if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk %d", blk); @@ -2983,7 +2963,7 @@ static int CmdT55xxWipe(const char *Cmd) { // Check and rest t55xx downlink mode. if (config.downlink_mode != T55XX_DLMODE_FIXED) { // Detect found a different mode so card must support - snprintf(ptrData, sizeof(writeData), "b 3 1 d 00000000"); + snprintf(ptrData, sizeof(writeData), "-b 3 --pg1 -d 00000000"); if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Warning: failed writing block 3 page 1 (config)"); } diff --git a/doc/T5577_Guide.md b/doc/T5577_Guide.md index 8e22aab86..4bd8f30c6 100644 --- a/doc/T5577_Guide.md +++ b/doc/T5577_Guide.md @@ -159,7 +159,7 @@ can see the card) We use the d option to supply the data ‘12345678’ ``` - [usb] pm3 --> lf t55xx write b 1 d 12345678 + [usb] pm3 --> lf t55xx write -b 1 -d 12345678 ``` result: ``` @@ -205,7 +205,7 @@ can see the card) Lets try and write 89ABCDEF ``` - [usb] pm3 --> lf t55xx write b 1 d 89abcdef + [usb] pm3 --> lf t55xx write -b 1 -d 89abcdef ``` result: ``` @@ -314,7 +314,7 @@ required, please do not proceed. The password is saved in block 7 of page 0. ``` - [usb] pm3 --> lf t55xx write b 7 d 12345678 + [usb] pm3 --> lf t55xx write -b 7 -d 12345678 ``` result: ``` @@ -394,7 +394,7 @@ required, please do not proceed. If you have completed all steps and have the exact same results, we are ready to apply the new configuration. ``` - [usb] pm3 --> lf t55xx write b 0 d 00088050 + [usb] pm3 --> lf t55xx write -b 0 -d 00088050 ``` result: ``` @@ -435,7 +435,7 @@ required, please do not proceed. 7) Write a block of data with a password ``` - [usb] pm3 --> lf t55xx write b 1 d 1234abcd p 12345678 + [usb] pm3 --> lf t55xx write -b 1 -d 1234abcd -p 12345678 ``` result: ``` @@ -494,7 +494,7 @@ required, please do not proceed. In our examples we know what it should be : 00088040 ``` - [usb] pm3 --> lf t55xx write b 0 d 00088040 p 12345678 + [usb] pm3 --> lf t55xx write -b 0 -d 00088040 -p 12345678 ``` result: ``` diff --git a/doc/cloner_notes.md b/doc/cloner_notes.md index 71cada411..92de920ad 100644 --- a/doc/cloner_notes.md +++ b/doc/cloner_notes.md @@ -60,8 +60,8 @@ Standard password is normally (for T55xx): AA55BBBB # Restore page1 data ``` -lf t55xx write b 1 d E0150A48 1 -If t55xx write b 2 d 2D782308 1 +lf t55xx write -b 1 -d E0150A48 --pg1 +If t55xx write -b 2 -d 2D782308 --pg1 ``` # Sniffing the comms From e0b69871ac701eb987d4284eba811003e978c24f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 22:01:06 +0100 Subject: [PATCH 32/34] text --- doc/cliparser_todo.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/cliparser_todo.txt b/doc/cliparser_todo.txt index a7e55eba5..f3cc3500c 100644 --- a/doc/cliparser_todo.txt +++ b/doc/cliparser_todo.txt @@ -93,6 +93,4 @@ lf hitag sim lf hitag writer lf hitag dump lf hitag cc -lf t55xx read -lf t55xx write script run From fe25e70e6fbb6ba9c7eeb27b0882ee7853b15cd2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 22:24:37 +0100 Subject: [PATCH 33/34] string too small fix --- client/src/cmdlft55xx.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index f3993adcc..7e86e1c78 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -2363,11 +2363,11 @@ static int CmdT55xxRestore(const char *Cmd) { // // uint8_t downlink_mode; - char writeCmdOpt[100]; - char pwdOpt [11] = {0}; // p XXXXXXXX + char wcmd[100]; + char pwdopt [14] = {0}; // p XXXXXXXX if (usepwd) - snprintf(pwdOpt, sizeof(pwdOpt), "-p %08X", password); + snprintf(pwdopt, sizeof(pwdopt), "-p %08X", password); uint8_t idx; // Restore endien for writing to card @@ -2386,23 +2386,23 @@ static int CmdT55xxRestore(const char *Cmd) { // write out blocks 1-7 page 0 for (idx = 1; idx <= 7; idx++) { - snprintf(writeCmdOpt, sizeof(writeCmdOpt), "-b %d -d %08X %s", idx, data[idx], pwdOpt); + snprintf(wcmd, sizeof(wcmd), "-b %d -d %08X %s", idx, data[idx], pwdopt); - if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) { + if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx); } } // 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", data[7]); } // write out blocks 1-3 page 1 for (idx = 9; idx <= 11; idx++) { - snprintf(writeCmdOpt, sizeof(writeCmdOpt), "-b %d --pg1 -d %08X %s", idx - 8, data[idx], pwdOpt); + snprintf(wcmd, sizeof(wcmd), "-b %d --pg1 -d %08X %s", idx - 8, data[idx], pwdopt); - if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) { + if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Warning: error writing blk %d", idx); } } @@ -2411,8 +2411,8 @@ static int CmdT55xxRestore(const char *Cmd) { config.downlink_mode = downlink_mode; // Write the page 0 config - snprintf(writeCmdOpt, sizeof(writeCmdOpt), "-b 0 -d %08X %s", data[0], pwdOpt); - if (CmdT55xxWriteBlock(writeCmdOpt) != PM3_SUCCESS) { + snprintf(wcmd, sizeof(wcmd), "-b 0 -d %08X %s", data[0], pwdopt); + if (CmdT55xxWriteBlock(wcmd) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Warning: error writing blk 0"); } } From 55ccd18afd5437bf5a9affe1ca3dc661f55d62f9 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Sun, 7 Mar 2021 22:27:37 +0100 Subject: [PATCH 34/34] lf hitag cc - now uses cliparser --- client/src/cmdlfhitag.c | 87 +++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 52 deletions(-) diff --git a/client/src/cmdlfhitag.c b/client/src/cmdlfhitag.c index b98d83705..cb711a65c 100644 --- a/client/src/cmdlfhitag.c +++ b/client/src/cmdlfhitag.c @@ -113,19 +113,6 @@ static int usage_hitag_writer(void) { PrintAndLogEx(NORMAL, " 27 Write page, password mode. Default: 4D494B52 (\"MIKR\")"); return PM3_SUCCESS; } -static int usage_hitag_checkchallenges(void) { - PrintAndLogEx(NORMAL, "Check challenges, load a file with save hitag crypto challenges and test them all."); - PrintAndLogEx(NORMAL, "The file should be 8 * 60 bytes long, the file extension defaults to " _YELLOW_("`.cc`")); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf hitag cc [h] f "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, " f Load data from BIN file"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf hitag cc f lf-hitag-challenges"); - return PM3_SUCCESS; -} static int CmdLFHitagList(const char *Cmd) { char args[128] = {0}; @@ -614,50 +601,46 @@ static int CmdLFHitagReader(const char *Cmd) { static int CmdLFHitagCheckChallenges(const char *Cmd) { - char filename[FILE_PATH_SIZE] = { 0x00 }; - size_t datalen = 0; - int res = 0; - bool file_given = false; - bool errors = false; - uint8_t cmdp = 0; - uint8_t *data = calloc(8 * 60, sizeof(uint8_t)); + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf hitag cc", + "Check challenges, load a file with saved hitag crypto challenges and test them all.\n" + "The file should be 8 * 60 bytes long, the file extension defaults to " _YELLOW_("`.cc`") " ", + "lf hitag cc -f my_hitag_challenges" + ); - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - free(data); - return usage_hitag_checkchallenges(); - case 'f': - //file with all the challenges to try - param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); - res = loadFile(filename, ".cc", data, 8 * 60, &datalen); - if (res > 0) { - errors = true; - break; - } - file_given = true; - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } + void *argtable[] = { + arg_param_begin, + arg_str0("f", "filename", "", "filename to load from"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); - //Validations - if (errors || strlen(Cmd) == 0) { - free(data); - return usage_hitag_checkchallenges(); - } + int fnlen = 0; + char filename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + + CLIParserFree(ctx); clearCommandBuffer(); - if (file_given) - SendCommandOLD(CMD_LF_HITAGS_TEST_TRACES, 1, 0, 0, data, datalen); - else - SendCommandMIX(CMD_LF_HITAGS_TEST_TRACES, 0, 0, 0, NULL, 0); - free(data); + if (fnlen > 0) { + uint8_t *data = NULL; + size_t datalen = 0; + int res = loadFile_safe(filename, ".cc", (void **)&data, &datalen); + if (res == PM3_SUCCESS) { + if (datalen == (8 * 60) ) { + SendCommandOLD(CMD_LF_HITAGS_TEST_TRACES, 1, 0, 0, data, datalen); + } else { + PrintAndLogEx(ERR, "Error, file length mismatch. Expected %d, got %d", 8*60, datalen); + } + } + if (data) { + free(data); + } + } else { + SendCommandMIX(CMD_LF_HITAGS_TEST_TRACES, 0, 0, 0, NULL, 0); + } + return PM3_SUCCESS; }