From 955b5365cfb7759ed0a04eea992fad19b27669b2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 00:16:51 +0100 Subject: [PATCH 01/35] fix coverity 307536 --- client/src/cmdhflto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhflto.c b/client/src/cmdhflto.c index 61b4b7b97..7c8545629 100644 --- a/client/src/cmdhflto.c +++ b/client/src/cmdhflto.c @@ -128,7 +128,7 @@ static int CmdHfLTOInfo(const char *Cmd) { arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - + CLIParserFree(ctx); return infoLTO(true); } From 31e475764eb818c8f816fa8913a33f4605af7441 Mon Sep 17 00:00:00 2001 From: Ave Date: Tue, 1 Dec 2020 02:09:39 +0300 Subject: [PATCH 02/35] gui: Show a warning if user does not have gui support qt gui: Split no-DISPLAY warning into two lines And add XQuartz link qt gui: Account for proxspace on no-DISPLAY warning gui: Move no-DISPLAY warning from Qt to generic code, fix bugs --- client/src/proxgui.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/src/proxgui.cpp b/client/src/proxgui.cpp index 525e64da6..f8dd10fa4 100644 --- a/client/src/proxgui.cpp +++ b/client/src/proxgui.cpp @@ -13,6 +13,7 @@ #include #include "proxguiqt.h" #include "proxmark3.h" +#include "ui.h" // for prints static ProxGuiQT *gui = NULL; static WorkerThread *main_loop_thread = NULL; @@ -28,8 +29,15 @@ void WorkerThread::run() { } extern "C" void ShowGraphWindow(void) { - if (!gui) + if (!gui) { + // Show a notice if X11/XQuartz isn't available +#if defined(__MACH__) && defined(__APPLE__) + PrintAndLogEx(WARNING, "You appear to be on a MacOS device without XQuartz.\nYou may need to install XQuartz (https://www.xquartz.org/) to make the plot work."); +#else + PrintAndLogEx(WARNING, "You appear to be on an environment without an X11 server or without DISPLAY environment variable set.\nPlot may not work until you resolve these issues."); +#endif return; + } gui->ShowGraphWindow(); } From e6d1e3bbfc495abcc90d8d5b753127aa8b95b8d6 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 1 Dec 2020 01:23:36 +0100 Subject: [PATCH 03/35] Makefile: fix unnecessary recompilations when no Standalone mode is defined --- common_arm/Makefile.hal | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index 2ab6e1ddf..40e0a2c51 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -139,7 +139,9 @@ endif ifneq ($(strip $(filter $(PLATFORM_DEFS),$(STANDALONE_REQ_DEFS))),$(strip $(STANDALONE_REQ_DEFS))) $(error Chosen Standalone mode $(STANDALONE) requires $(strip $(STANDALONE_REQ_DEFS)), unsupported by $(PLTNAME)) endif -PLATFORM_DEFS+=$(STANDALONE_PLATFORM_DEFS) +ifneq (,$(STANDALONE_PLATFORM_DEFS)) + PLATFORM_DEFS+=$(STANDALONE_PLATFORM_DEFS) +endif $(info $(findstring WITH_STANDALONE_*,$(PLATFORM_DEFS))) From 076781a794397273930a1962908eeb48b3a6c11c Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 1 Dec 2020 01:52:25 +0100 Subject: [PATCH 04/35] magic gen2: add MCT --- doc/magic_cards_notes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 23ab192a2..720b38605 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -10,7 +10,7 @@ Useful docs: * [MIFARE Classic block0](#mifare-classic-block0) * [MIFARE Classic Gen1A aka UID](#mifare-classic-gen1a-aka-uid) * [MIFARE Classic Gen1B](#mifare-classic-gen1b) - * [MIFARE Classic DirectWrite aka Gen2 aka CUID](#mifare-classic-directwrite-aka-gen2-aka-cuid) + * [MIFARE Classic DirectWrite aka Gen2 aka CUID aka MCT](#mifare-classic-directwrite-aka-gen2-aka-cuid-aka-mct) * [MIFARE Classic DirectWrite, FUID version aka 1-write](#mifare-classic-directwrite-fuid-version-aka-1-write) * [MIFARE Classic DirectWrite, UFUID version](#mifare-classic-directwrite-ufuid-version) * [MIFARE Classic, other versions](#mifare-classic-other-versions) @@ -236,7 +236,7 @@ hf 14a info * Read: `40(7)`, `30xx` * Write: `40(7)`, `A0xx`+crc, `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`+crc -## MIFARE Classic DirectWrite aka Gen2 aka CUID +## MIFARE Classic DirectWrite aka Gen2 aka CUID aka MCT ### Identify From 03c902852aad6a5e801feb2711c5e71404aa0913 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 1 Dec 2020 01:55:20 +0100 Subject: [PATCH 05/35] textual --- doc/magic_cards_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 720b38605..4c4e45132 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -238,6 +238,8 @@ hf 14a info ## MIFARE Classic DirectWrite aka Gen2 aka CUID aka MCT +(MCT is sometimes used by sellers as it can be written to with Mifare Classic Tool) + ### Identify ``` From af07bb02544c3dcd346d741c20a62ae29072b374 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 1 Dec 2020 09:21:44 +0100 Subject: [PATCH 06/35] textual --- doc/magic_cards_notes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/magic_cards_notes.md b/doc/magic_cards_notes.md index 4c4e45132..4f9cb2f68 100644 --- a/doc/magic_cards_notes.md +++ b/doc/magic_cards_notes.md @@ -10,7 +10,7 @@ Useful docs: * [MIFARE Classic block0](#mifare-classic-block0) * [MIFARE Classic Gen1A aka UID](#mifare-classic-gen1a-aka-uid) * [MIFARE Classic Gen1B](#mifare-classic-gen1b) - * [MIFARE Classic DirectWrite aka Gen2 aka CUID aka MCT](#mifare-classic-directwrite-aka-gen2-aka-cuid-aka-mct) + * [MIFARE Classic DirectWrite aka Gen2 aka CUID](#mifare-classic-directwrite-aka-gen2-aka-cuid) * [MIFARE Classic DirectWrite, FUID version aka 1-write](#mifare-classic-directwrite-fuid-version-aka-1-write) * [MIFARE Classic DirectWrite, UFUID version](#mifare-classic-directwrite-ufuid-version) * [MIFARE Classic, other versions](#mifare-classic-other-versions) @@ -236,9 +236,9 @@ hf 14a info * Read: `40(7)`, `30xx` * Write: `40(7)`, `A0xx`+crc, `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`+crc -## MIFARE Classic DirectWrite aka Gen2 aka CUID aka MCT +## MIFARE Classic DirectWrite aka Gen2 aka CUID -(MCT is sometimes used by sellers as it can be written to with Mifare Classic Tool) +(also referred as MCT compatible by some sellers) ### Identify From 3764a4dd3b39171bf7be13b26487abcbde9ab2d5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 10:41:28 +0100 Subject: [PATCH 07/35] fix coverity 307527 --- client/src/cmdlffdxb.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/client/src/cmdlffdxb.c b/client/src/cmdlffdxb.c index 95e152716..f44182483 100644 --- a/client/src/cmdlffdxb.c +++ b/client/src/cmdlffdxb.c @@ -47,7 +47,7 @@ static int CmdHelp(const char *Cmd); -static int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is_animal, uint8_t is_extended, uint16_t extended, uint8_t *bits) { +static int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is_animal, uint8_t is_extended, uint32_t extended, uint8_t *bits) { // add preamble ten 0x00 and one 0x01 memset(bits, 0x00, 10); @@ -103,7 +103,7 @@ static int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is } // clearing the topbit needed for the preambl detection. -static void verify_values(uint64_t *animalid, uint32_t *countryid, uint16_t *extended) { +static void verify_values(uint64_t *animalid, uint32_t *countryid, uint32_t *extended) { if ((*animalid & 0x3FFFFFFFFF) != *animalid) { *animalid &= 0x3FFFFFFFFF; PrintAndLogEx(INFO, "Animal ID truncated to 38bits: " _YELLOW_("%"PRIx64), *animalid); @@ -112,8 +112,8 @@ static void verify_values(uint64_t *animalid, uint32_t *countryid, uint16_t *ext *countryid &= 0x3FF; PrintAndLogEx(INFO, "Country ID truncated to 10bits:" _YELLOW_("%03d"), *countryid); } - if ((*extended & 0xFFF) != *extended) { - *extended &= 0xFFF; + if ((*extended & 0xFFFFFF) != *extended) { + *extended &= 0xFFFFFF; PrintAndLogEx(INFO, "Extended truncated to 24bits: " _YELLOW_("0x%03X"), *extended); } } @@ -713,7 +713,7 @@ static int CmdFdxBClone(const char *Cmd) { uint64_t national_code = arg_get_u64_def(ctx, 2, 0); int extended_len = 0; - uint8_t edata[2] = {0}; + uint8_t edata[3] = {0}; CLIGetHexWithReturn(ctx, 3, edata, &extended_len); bool is_animal = arg_get_lit(ctx, 4); @@ -726,7 +726,7 @@ static int CmdFdxBClone(const char *Cmd) { return PM3_EINVARG; } - uint16_t extended = 0; + uint32_t extended = 0; bool has_extended = false; if (extended_len) { extended = bytes_to_num(edata, extended_len); @@ -813,13 +813,13 @@ static int CmdFdxBSim(const char *Cmd) { uint32_t country_code = arg_get_u32_def(ctx, 1, 0); uint64_t national_code = arg_get_u64_def(ctx, 2, 0); int extended_len = 0; - uint8_t edata[2] = {0}; + uint8_t edata[3] = {0}; CLIGetHexWithReturn(ctx, 3, edata, &extended_len); bool is_animal = arg_get_lit(ctx, 4); CLIParserFree(ctx); - uint16_t extended = 0; + uint32_t extended = 0; bool has_extended = false; if (extended_len) { extended = bytes_to_num(edata, extended_len); From 51e27d1a48cf1c4702f1400ca401b5f5fd439824 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 10:42:55 +0100 Subject: [PATCH 08/35] adapt the brute --- client/src/cmdlfhid.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index dc112913b..3a757896e 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -45,8 +45,7 @@ static int CmdHelp(const char *Cmd); // sending three times. Didn't seem to break the previous sim? static int sendPing(void) { - SendCommandNG(CMD_PING, NULL, 0); - SendCommandNG(CMD_PING, NULL, 0); + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); SendCommandNG(CMD_PING, NULL, 0); clearCommandBuffer(); PacketResponseNG resp; @@ -223,7 +222,8 @@ static int CmdHIDSim(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf hid sim", - "Enables simulation of HID card with card number.", + "Enables simulation of HID card with card number.\n" + "Simulation runs until the button is pressed or another USB command is issued.", "lf hid sim -r 2006ec0c86 -> HID 10301 26 bit\n" "lf hid sim -r 2e0ec00c87 -> HID Corporate 35 bit\n" "lf hid sim -r 01f0760643c3 -> HID P10001 40 bit\n" From ae853ede79a0f7e07d5357ebca5a002930ec1636 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 11:26:54 +0100 Subject: [PATCH 09/35] reader - textual --- client/src/cmdlfawid.c | 4 ++++ client/src/cmdlfdestron.c | 4 ++++ client/src/cmdlfgallagher.c | 4 ++++ client/src/cmdlfguard.c | 4 ++++ client/src/cmdlfhid.c | 4 ++++ client/src/cmdlfidteck.c | 4 ++++ client/src/cmdlfindala.c | 4 ++++ client/src/cmdlfjablotron.c | 4 ++++ client/src/cmdlfkeri.c | 4 ++++ client/src/cmdlfmotorola.c | 4 ++++ client/src/cmdlfnexwatch.c | 4 ++++ client/src/cmdlfnoralsy.c | 4 ++++ client/src/cmdlfpac.c | 4 ++++ client/src/cmdlfparadox.c | 4 ++++ client/src/cmdlfpresco.c | 4 ++++ client/src/cmdlfpyramid.c | 4 ++++ client/src/cmdlfsecurakey.c | 4 ++++ client/src/cmdlfti.c | 4 ++++ client/src/cmdlfviking.c | 4 ++++ client/src/cmdlfvisa2000.c | 4 ++++ 20 files changed, 80 insertions(+) diff --git a/client/src/cmdlfawid.c b/client/src/cmdlfawid.c index 185e9a2f4..6591e1364 100644 --- a/client/src/cmdlfawid.c +++ b/client/src/cmdlfawid.c @@ -313,6 +313,10 @@ static int CmdAWIDReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 12000); demodAWID(!cm); diff --git a/client/src/cmdlfdestron.c b/client/src/cmdlfdestron.c index aa73c1f79..ec5e67a28 100644 --- a/client/src/cmdlfdestron.c +++ b/client/src/cmdlfdestron.c @@ -113,6 +113,10 @@ static int CmdDestronReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 16000); demodDestron(!cm); diff --git a/client/src/cmdlfgallagher.c b/client/src/cmdlfgallagher.c index dcd15180b..cf0488877 100644 --- a/client/src/cmdlfgallagher.c +++ b/client/src/cmdlfgallagher.c @@ -154,6 +154,10 @@ static int CmdGallagherReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 4096 * 2 + 20); demodGallagher(!cm); diff --git a/client/src/cmdlfguard.c b/client/src/cmdlfguard.c index 051437242..ec49b46c5 100644 --- a/client/src/cmdlfguard.c +++ b/client/src/cmdlfguard.c @@ -147,6 +147,10 @@ static int CmdGuardReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 10000); demodGuard(!cm); diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index 3a757896e..5fde70350 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -182,6 +182,10 @@ static int CmdHIDReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 16000); demodHID(!cm); diff --git a/client/src/cmdlfidteck.c b/client/src/cmdlfidteck.c index 076f3fc8e..36c24846e 100644 --- a/client/src/cmdlfidteck.c +++ b/client/src/cmdlfidteck.c @@ -117,6 +117,10 @@ static int CmdIdteckReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 5000); demodIdteck(!cm); diff --git a/client/src/cmdlfindala.c b/client/src/cmdlfindala.c index c932ca164..35d02bcd7 100644 --- a/client/src/cmdlfindala.c +++ b/client/src/cmdlfindala.c @@ -520,6 +520,10 @@ static int CmdIndalaReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 4); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 30000); demodIndalaEx(clk, invert, max_err, !cm); diff --git a/client/src/cmdlfjablotron.c b/client/src/cmdlfjablotron.c index 25f6f3afd..0f9672012 100644 --- a/client/src/cmdlfjablotron.c +++ b/client/src/cmdlfjablotron.c @@ -151,6 +151,10 @@ static int CmdJablotronReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 16000); demodJablotron(!cm); diff --git a/client/src/cmdlfkeri.c b/client/src/cmdlfkeri.c index dfd0153fd..82fc04a22 100644 --- a/client/src/cmdlfkeri.c +++ b/client/src/cmdlfkeri.c @@ -206,6 +206,10 @@ static int CmdKeriReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 10000); demodKeri(!cm); diff --git a/client/src/cmdlfmotorola.c b/client/src/cmdlfmotorola.c index cf3f79137..f56990011 100644 --- a/client/src/cmdlfmotorola.c +++ b/client/src/cmdlfmotorola.c @@ -148,6 +148,10 @@ static int CmdMotorolaReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + // Motorola Flexpass seem to work at 74 kHz // and take about 4400 samples to befor modulating sample_config sc = { diff --git a/client/src/cmdlfnexwatch.c b/client/src/cmdlfnexwatch.c index ea69535f3..eefbd03ad 100644 --- a/client/src/cmdlfnexwatch.c +++ b/client/src/cmdlfnexwatch.c @@ -248,6 +248,10 @@ static int CmdNexWatchReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 20000); demodNexWatch(!cm); diff --git a/client/src/cmdlfnoralsy.c b/client/src/cmdlfnoralsy.c index 73a027c33..91e03f961 100644 --- a/client/src/cmdlfnoralsy.c +++ b/client/src/cmdlfnoralsy.c @@ -134,6 +134,10 @@ static int CmdNoralsyReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 8000); demodNoralsy(!cm); diff --git a/client/src/cmdlfpac.c b/client/src/cmdlfpac.c index 99495641f..5c2ccd98c 100644 --- a/client/src/cmdlfpac.c +++ b/client/src/cmdlfpac.c @@ -189,6 +189,10 @@ static int CmdPacReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 4096 * 2 + 20); demodPac(!cm); diff --git a/client/src/cmdlfparadox.c b/client/src/cmdlfparadox.c index f740721e9..612338cae 100644 --- a/client/src/cmdlfparadox.c +++ b/client/src/cmdlfparadox.c @@ -201,6 +201,10 @@ static int CmdParadoxReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 10000); demodParadox(!cm); diff --git a/client/src/cmdlfpresco.c b/client/src/cmdlfpresco.c index d629e1224..2c78d5e8f 100644 --- a/client/src/cmdlfpresco.c +++ b/client/src/cmdlfpresco.c @@ -144,6 +144,10 @@ static int CmdPrescoReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 12000); demodPresco(!cm); diff --git a/client/src/cmdlfpyramid.c b/client/src/cmdlfpyramid.c index b21c5c974..84fed3729 100644 --- a/client/src/cmdlfpyramid.c +++ b/client/src/cmdlfpyramid.c @@ -209,6 +209,10 @@ static int CmdPyramidReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 15000); demodPyramid(true); diff --git a/client/src/cmdlfsecurakey.c b/client/src/cmdlfsecurakey.c index 4c3fa6ba3..80a58bfa9 100644 --- a/client/src/cmdlfsecurakey.c +++ b/client/src/cmdlfsecurakey.c @@ -145,6 +145,10 @@ static int CmdSecurakeyReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 8000); demodSecurakey(!cm); diff --git a/client/src/cmdlfti.c b/client/src/cmdlfti.c index f6e8b3027..b02ad2e34 100644 --- a/client/src/cmdlfti.c +++ b/client/src/cmdlfti.c @@ -304,6 +304,10 @@ static int CmdTIReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { clearCommandBuffer(); SendCommandNG(CMD_LF_TI_READ, NULL, 0); diff --git a/client/src/cmdlfviking.c b/client/src/cmdlfviking.c index 0727a7f96..35f33ebc0 100644 --- a/client/src/cmdlfviking.c +++ b/client/src/cmdlfviking.c @@ -87,6 +87,10 @@ static int CmdVikingReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 10000); demodViking(true); diff --git a/client/src/cmdlfvisa2000.c b/client/src/cmdlfvisa2000.c index 582b29686..1788d1ffc 100644 --- a/client/src/cmdlfvisa2000.c +++ b/client/src/cmdlfvisa2000.c @@ -165,6 +165,10 @@ static int CmdVisa2kReader(const char *Cmd) { bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + do { lf_read(false, 20000); demodVisa2k(!cm); From 0c39d227f3d4c9c3c12080a258e37ad758537aec Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 11:33:55 +0100 Subject: [PATCH 10/35] text --- doc/cliparser_todo.txt | 3 --- doc/commands.md | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/cliparser_todo.txt b/doc/cliparser_todo.txt index 5cf24f1e8..af0b6bc64 100644 --- a/doc/cliparser_todo.txt +++ b/doc/cliparser_todo.txt @@ -197,7 +197,6 @@ lf em 4x50_write lf em 4x50_write_password lf em 4x50_read lf em 4x50_wipe -lf hid read lf hitag info lf hitag reader lf hitag sim @@ -209,8 +208,6 @@ lf indala demod lf indala altdemod lf indala sim lf io clone -lf io sim -lf io watch lf jablotron sim lf nedap generate lf nedap read diff --git a/doc/commands.md b/doc/commands.md index f4bab39da..8e77bcf57 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -649,7 +649,7 @@ Check column "offline" for their availability. |------- |------- |----------- |`lf hid help `|Y |`this help` |`lf hid demod `|Y |`demodulate HID Prox tag from the GraphBuffer` -|`lf hid read `|N |`attempt to read and extract tag data` +|`lf hid reader `|N |`attempt to read and extract tag data` |`lf hid clone `|N |`clone HID tag to T55x7` |`lf hid sim `|N |`simulate HID tag` |`lf hid brute `|N |`bruteforce card number against reader` From 584e1faba539d1c61d99c0beae830ad3a842d3db Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 11:47:03 +0100 Subject: [PATCH 11/35] lf io - now uses cliparser, support continuous mode, EM (untested) --- client/src/cmdlfhid.c | 3 +- client/src/cmdlfio.c | 179 ++++++++++++++++++++++------------------- doc/cliparser_todo.txt | 1 - 3 files changed, 98 insertions(+), 85 deletions(-) diff --git a/client/src/cmdlfhid.c b/client/src/cmdlfhid.c index 5fde70350..674aad661 100644 --- a/client/src/cmdlfhid.c +++ b/client/src/cmdlfhid.c @@ -316,7 +316,8 @@ static int CmdHIDClone(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf hid clone", - "Clone HID to T55x7. Tag must be on antenna!", + "clone a HID Prox tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n" + "Tag must be on the antenna when issuing this command.", "lf hid clone -r 2006ec0c86 -> HID 10301 26 bit\n" "lf hid clone -r 2e0ec00c87 -> HID Corporate 35 bit\n" "lf hid clone -r 01f0760643c3 -> HID P10001 40 bit\n" diff --git a/client/src/cmdlfio.c b/client/src/cmdlfio.c index 123fc56fc..b82439263 100644 --- a/client/src/cmdlfio.c +++ b/client/src/cmdlfio.c @@ -1,4 +1,5 @@ //----------------------------------------------------------------------------- +// marshmellow // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -28,58 +29,22 @@ static int CmdHelp(const char *Cmd); -static int usage_lf_io_watch(void) { - PrintAndLogEx(NORMAL, "Enables IOProx compatible reader mode printing details of scanned tags."); - PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf io watch"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf io watch")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - -static int usage_lf_io_sim(void) { - PrintAndLogEx(NORMAL, "Enables simulation of IOProx card with specified facility-code and card number."); - PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf io sim [h] "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " : 8bit version (" _YELLOW_("decimal") ")"); - PrintAndLogEx(NORMAL, " : 8bit value facility code (" _YELLOW_("hex") ")"); - PrintAndLogEx(NORMAL, " : 16bit value card number (" _YELLOW_("decimal") ")"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf io sim 01 101 1337")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - -static int usage_lf_io_clone(void) { - PrintAndLogEx(NORMAL, "Enables cloning of IOProx card with specified facility-code and card number onto T55x7 or Q5/T5555 tag"); - PrintAndLogEx(NORMAL, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process."); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf io clone [h] "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " : 8bit version (" _YELLOW_("decimal") ")"); - PrintAndLogEx(NORMAL, " : 8bit value facility code (" _YELLOW_("hex") ")"); - PrintAndLogEx(NORMAL, " : 16bit value card number (" _YELLOW_("decimal") ")"); - PrintAndLogEx(NORMAL, " : optional - specify writing to Q5/T5555 tag"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf io clone 01 101 1337")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - // this read loops on device side. // uses the demod in lfops.c static int CmdIOProxWatch(const char *Cmd) { - uint8_t c = tolower(param_getchar(Cmd, 0)); - if (c == 'h') return usage_lf_io_watch(); + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf io watch", + "Enables IOProx compatible reader mode printing details.\n" + "By default, values are printed and logged until the button is pressed or another USB command is issued.", + "lf io watch" + ); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); PrintAndLogEx(SUCCESS, "Watching for IO Prox cards - place tag on antenna"); PrintAndLogEx(INFO, "Press pm3-button to stop reading cards"); @@ -91,7 +56,6 @@ static int CmdIOProxWatch(const char *Cmd) { return resp.status; } -//by marshmellow //IO-Prox demod - FSK RF/64 with preamble of 000000001 //print ioprox ID and some format details int demodIOProx(bool verbose) { @@ -193,8 +157,8 @@ int demodIOProx(bool verbose) { static int CmdIOProxDemod(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf io demod", - "Try to find IO Prox preamble, if found decode / descramble data", - "lf io demod\n" + "Try to find IOProx preamble, if found decode / descramble data", + "lf io demod" ); void *argtable[] = { @@ -209,7 +173,7 @@ static int CmdIOProxDemod(const char *Cmd) { static int CmdIOProxReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf io reader", - "read a IO Prox tag", + "read a IOProx tag", "lf io reader -@ -> continuous reader mode" ); @@ -229,29 +193,42 @@ static int CmdIOProxReader(const char *Cmd) { return PM3_SUCCESS; } + static int CmdIOProxSim(const char *Cmd) { - uint16_t cn = 0; - uint8_t version = 0, fc = 0; - uint8_t bs[64]; - memset(bs, 0x00, sizeof(bs)); - char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_sim(); + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf io sim", + "Enables simulation of IOProx card with specified facility-code and card number.\n" + "Simulation runs until the button is pressed or another USB command is issued.", + "lf io sim --vn 1 --fc 101 --cn 1337" + ); - version = param_get8(Cmd, 0); - fc = param_get8ex(Cmd, 1, 0, 16); - cn = param_get32ex(Cmd, 2, 0, 10); + void *argtable[] = { + arg_param_begin, + arg_u64_1(NULL, "vn", "", "8bit version"), + arg_u64_1(NULL, "fc", "", "8bit facility code"), + arg_u64_1(NULL, "cn", "", "16bit card number"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); - if (!version || !fc || !cn) return usage_lf_io_sim(); + uint8_t version = arg_get_u32_def(ctx, 1, 0); + uint8_t fc = arg_get_u32_def(ctx, 2, 0); + uint16_t cn = arg_get_u32_def(ctx, 3, 0); + + CLIParserFree(ctx); if ((cn & 0xFFFF) != cn) { cn &= 0xFFFF; PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn); } - PrintAndLogEx(SUCCESS, "Simulating IOProx version: %u FC: %u; CN: %u\n", version, fc, cn); + PrintAndLogEx(SUCCESS, "Simulating IOProx version: " _YELLOW_("%u") " FC: " _YELLOW_("%u (0x%02x)") " CN: " _YELLOW_("%u"), version, fc, fc, cn); PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command"); + uint8_t bs[64]; + memset(bs, 0x00, sizeof(bs)); + if (getIOProxBits(version, fc, cn, bs) != PM3_SUCCESS) { PrintAndLogEx(ERR, "Error with tag bitstream generation."); return PM3_ESOFT; @@ -270,10 +247,8 @@ static int CmdIOProxSim(const char *Cmd) { clearCommandBuffer(); SendCommandNG(CMD_LF_FSK_SIMULATE, (uint8_t *)payload, sizeof(lf_fsksim_t) + sizeof(bs)); free(payload); - PacketResponseNG resp; WaitForResponse(CMD_LF_FSK_SIMULATE, &resp); - PrintAndLogEx(INFO, "Done"); if (resp.status != PM3_EOPABORTED) return resp.status; @@ -282,20 +257,39 @@ static int CmdIOProxSim(const char *Cmd) { static int CmdIOProxClone(const char *Cmd) { - uint16_t cn = 0; - uint8_t version = 0, fc = 0; + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf io clone", + "Enables simulation of IOProx card with specified facility-code and card number.\n" + "Tag must be on the antenna when issuing this command.", + "lf io clone --vn 1 --fc 101 --cn 1337" + ); + + void *argtable[] = { + arg_param_begin, + arg_u64_1(NULL, "vn", "", "8bit version"), + arg_u64_1(NULL, "fc", "", "8bit facility code"), + arg_u64_1(NULL, "cn", "", "16bit card number"), + arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"), + arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + uint8_t version = arg_get_u32_def(ctx, 1, 0); + uint8_t fc = arg_get_u32_def(ctx, 2, 0); + uint16_t cn = arg_get_u32_def(ctx, 3, 0); + bool q5 = arg_get_lit(ctx, 4); + bool em = arg_get_lit(ctx, 5); + CLIParserFree(ctx); + + if (q5 && em) { + PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time"); + return PM3_EINVARG; + } + uint8_t bits[64]; memset(bits, 0, sizeof(bits)); - char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_clone(); - - version = param_get8(Cmd, 0); - fc = param_get8ex(Cmd, 1, 0, 16); - cn = param_get32ex(Cmd, 2, 0, 10); - - if (!version || !fc || !cn) return usage_lf_io_clone(); - if ((cn & 0xFFFF) != cn) { cn &= 0xFFFF; PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn); @@ -307,20 +301,39 @@ static int CmdIOProxClone(const char *Cmd) { } uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; - - bool q5 = tolower(param_getchar(Cmd, 3) == 'q'); - if (q5) + char cardtype[16] = {"T55x7"}; + // Q5 + if (q5) { blocks[0] = T5555_FIXED | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT; + snprintf(cardtype, sizeof(cardtype), "Q5/T5555"); + } + + // EM4305 + if (em) { + blocks[0] = EM4305_IOPROX_CONFIG_BLOCK; + snprintf(cardtype, sizeof(cardtype), "EM4305/4469"); + } blocks[1] = bytebits_to_byte(bits, 32); blocks[2] = bytebits_to_byte(bits + 32, 32); - PrintAndLogEx(INFO, "Preparing to clone IOProx to " _YELLOW_("%s") " with Version: %u FC: %u, CN: %u", (q5) ? "Q5/T5555" : "T55x7", version, fc, cn); + PrintAndLogEx(INFO, "Preparing to clone IOProx to " _YELLOW_("%s") " with Version: " _GREEN_("%u") " FC: " _GREEN_("%u (0x%02x)") " CN: " _GREEN_("%u") + , cardtype + , version + , fc + , fc + , cn + ); print_blocks(blocks, ARRAYLEN(blocks)); - int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + int res; + if (em) { + res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false); + } else { + res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + } PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf io read`") " to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf io reader`") " to verify"); return res; } diff --git a/doc/cliparser_todo.txt b/doc/cliparser_todo.txt index af0b6bc64..a3fd1a5dc 100644 --- a/doc/cliparser_todo.txt +++ b/doc/cliparser_todo.txt @@ -207,7 +207,6 @@ lf hitag cc lf indala demod lf indala altdemod lf indala sim -lf io clone lf jablotron sim lf nedap generate lf nedap read From e8fe88b50ac959324c0acc45773de93e4fc41c79 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 12:18:07 +0100 Subject: [PATCH 12/35] lf jablotron sim, uses cliparser --- client/src/cmdlfjablotron.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/client/src/cmdlfjablotron.c b/client/src/cmdlfjablotron.c index 0f9672012..7e1f81557 100644 --- a/client/src/cmdlfjablotron.c +++ b/client/src/cmdlfjablotron.c @@ -29,21 +29,6 @@ static int CmdHelp(const char *Cmd); -static int usage_lf_jablotron_sim(void) { - PrintAndLogEx(NORMAL, "Enables simulation of jablotron card with specified card number."); - PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf jablotron sim [h] "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " : jablotron card ID"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf jablotron sim 112233")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - static uint8_t jablontron_chksum(uint8_t *bits) { uint8_t chksum = 0; for (int i = 16; i < 56; i += 8) { @@ -251,12 +236,26 @@ static int CmdJablotronClone(const char *Cmd) { } static int CmdJablotronSim(const char *Cmd) { - uint64_t fullcode = 0; + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf jablotron sim", + "Enables simulation of jablotron card with specified card number.\n" + "Simulation runs until the button is pressed or another USB command is issued.", + "lf jablotron sim --cn 01b669" + ); - char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_jablotron_sim(); + void *argtable[] = { + arg_param_begin, + arg_str1(NULL, "cn", "", "Jablotron card ID - 5 bytes max"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); - fullcode = param_get64ex(Cmd, 0, 0, 16); + int raw_len = 0; + uint8_t raw[5] = {0}; + CLIGetHexWithReturn(ctx, 1, raw, &raw_len); + CLIParserFree(ctx); + + uint64_t fullcode = bytes_to_num(raw, raw_len); // clearing the topbit needed for the preambl detection. if ((fullcode & 0x7FFFFFFFFF) != fullcode) { From fccef24aeac8c9e51b9bc5ea9c290b9bb30ad3bb Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 15:13:30 +0100 Subject: [PATCH 13/35] fix 'auto' - correct param when saving --- client/src/cmdmain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdmain.c b/client/src/cmdmain.c index c55c7792e..d6ff5edea 100644 --- a/client/src/cmdmain.c +++ b/client/src/cmdmain.c @@ -155,7 +155,7 @@ static int CmdAuto(const char *Cmd) { CmdPlot(""); lf_read(false, 40000); char *fname = calloc(100, sizeof(uint8_t)); - AppendDate(fname, 100, "f lf_unknown_%Y-%m-%d_%H:%M"); + AppendDate(fname, 100, "-f lf_unknown_%Y-%m-%d_%H:%M"); CmdSave(fname); free(fname); return PM3_SUCCESS; From aa5d72a7a603d20cf83462cf0548ddf849845b1b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 15:16:23 +0100 Subject: [PATCH 14/35] rem - now uses cliparser' --- client/src/cmdmain.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/client/src/cmdmain.c b/client/src/cmdmain.c index d6ff5edea..9b26512f1 100644 --- a/client/src/cmdmain.c +++ b/client/src/cmdmain.c @@ -162,6 +162,19 @@ static int CmdAuto(const char *Cmd) { } int CmdRem(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "rem", + "Add a text line in log file", + "rem" + ); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + char buf[22] = {0}; AppendDate(buf, sizeof(buf), NULL); PrintAndLogEx(NORMAL, "%s remark: %s", buf, Cmd); From 03f709f27f0348e0aaccb2ed2d15176c0b20ff8b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 15:18:28 +0100 Subject: [PATCH 15/35] text --- doc/cliparser_todo.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/cliparser_todo.txt b/doc/cliparser_todo.txt index a3fd1a5dc..ba27198d9 100644 --- a/doc/cliparser_todo.txt +++ b/doc/cliparser_todo.txt @@ -1,6 +1,5 @@ clear pref -rem analyse lcr analyse crc analyse chksum @@ -207,7 +206,6 @@ lf hitag cc lf indala demod lf indala altdemod lf indala sim -lf jablotron sim lf nedap generate lf nedap read lf nedap clone From 480241645d38495d968fc578d6fee4ecab98ab80 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 16:41:48 +0100 Subject: [PATCH 16/35] fix lf search - false positive motorola --- client/src/cmdlfmotorola.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/src/cmdlfmotorola.c b/client/src/cmdlfmotorola.c index f56990011..3f2ce059c 100644 --- a/client/src/cmdlfmotorola.c +++ b/client/src/cmdlfmotorola.c @@ -33,6 +33,7 @@ int demodMotorola(bool verbose) { PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: PSK Demod failed"); return PM3_ESOFT; } + size_t size = DemodBufferLen; int ans = detectMotorola(DemodBuffer, &size); if (ans < 0) { @@ -165,10 +166,11 @@ static int CmdMotorolaReader(const char *Cmd) { }; lf_config(&sc); + int res; do { // 64 * 32 * 2 * n-ish lf_read(false, 5000); - demodMotorola(!cm); + res = demodMotorola(!cm); } while (cm && !kbd_enter_pressed()); // reset back to 125 kHz @@ -176,7 +178,7 @@ static int CmdMotorolaReader(const char *Cmd) { sc.samples_to_skip = 0; lf_config(&sc); - return PM3_SUCCESS; + return res; } static int CmdMotorolaClone(const char *Cmd) { From 2cabfd7e9d41e596b67e288dfb956e4b57b83514 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 16:42:33 +0100 Subject: [PATCH 17/35] fix lf search - false positive cotag --- client/src/cmdlfcotag.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdlfcotag.c b/client/src/cmdlfcotag.c index a85ff8c3c..c339f677a 100644 --- a/client/src/cmdlfcotag.c +++ b/client/src/cmdlfcotag.c @@ -170,5 +170,5 @@ int CmdLFCOTAG(const char *Cmd) { } int readCOTAGUid(void) { - return (CmdCOTAGReader("") == PM3_SUCCESS); + return (CmdCOTAGReader("-2") == PM3_SUCCESS); } From 2613284dfce598a9e69cd559cb64cc9ef6ac5bfc Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 17:06:49 +0100 Subject: [PATCH 18/35] fix lf search - cotag exiting on deviceside --- armsrc/lfsampling.c | 23 ++++++++++++++++++++++- client/src/cmdlf.c | 2 +- client/src/cmdlfcotag.c | 11 +++++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index d31342ac0..7a42367dc 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -509,10 +509,21 @@ void doCotagAcquisition(void) { bool firsthigh = false, firstlow = false; uint16_t i = 0, noise_counter = 0; + uint16_t checker = 0; + while ((i < bufsize - 1) && (noise_counter < COTAG_T1 << 1)) { if (BUTTON_PRESS()) break; + + if (checker == 4000) { + if (data_available()) + break; + else + checker = 0; + } else { + ++checker; + } WDT_HIT(); @@ -567,12 +578,22 @@ uint16_t doCotagAcquisitionManchester(uint8_t *dest, uint16_t destlen) { bool firsthigh = false, firstlow = false; uint8_t curr = 0, prev = 0; uint16_t i = 0; - uint16_t period = 0; + uint16_t period = 0, checker = 0; while ((i < destlen) && BUTTON_PRESS() == false) { WDT_HIT(); + if (checker == 4000) { + if (data_available()) + break; + else + checker = 0; + } else { + ++checker; + } + + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index 77dda02f1..7cd9d801e 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -1434,8 +1434,8 @@ int CmdLFfind(const char *Cmd) { return PM3_SUCCESS; } + PrintAndLogEx(INPLACE, "Searching for COTAG tag..."); if (readCOTAGUid()) { - PrintAndLogEx(INPLACE, "Searching for COTAG tag..."); PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") " found!"); return PM3_SUCCESS; } diff --git a/client/src/cmdlfcotag.c b/client/src/cmdlfcotag.c index c339f677a..abe426e30 100644 --- a/client/src/cmdlfcotag.c +++ b/client/src/cmdlfcotag.c @@ -122,15 +122,23 @@ static int CmdCOTAGReader(const char *Cmd) { SendCommandNG(CMD_LF_COTAG_READ, (uint8_t *)&payload, sizeof(payload)); uint8_t timeout = 3; + int res = PM3_SUCCESS; while (!WaitForResponseTimeout(CMD_LF_COTAG_READ, &resp, 2000)) { timeout--; PrintAndLogEx(NORMAL, "." NOLF); if (timeout == 0) { + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(WARNING, "command execution time out"); - return PM3_ETIMEOUT; + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + timeout = 1; + res = PM3_ETIMEOUT; } } + if (res != PM3_SUCCESS) { + return res; + } + if (timeout != 3) PrintAndLogEx(NORMAL, ""); @@ -157,7 +165,6 @@ static command_t CommandTable[] = { {"reader", CmdCOTAGReader, IfPm3Lf, "Attempt to read and extract tag data"}, {NULL, NULL, NULL, NULL} }; - static int CmdHelp(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdsHelp(CommandTable); From 84ebe37725d968ca7f6eca043be1d811b18c3b36 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 21:52:08 +0100 Subject: [PATCH 19/35] lf pcf7931 - now uses cliparser --- client/src/cmdlfpcf7931.c | 194 ++++++++++++++++++++++---------------- 1 file changed, 115 insertions(+), 79 deletions(-) diff --git a/client/src/cmdlfpcf7931.c b/client/src/cmdlfpcf7931.c index 2062c8582..48a029e2b 100644 --- a/client/src/cmdlfpcf7931.c +++ b/client/src/cmdlfpcf7931.c @@ -9,13 +9,12 @@ // Low frequency PCF7931 commands //----------------------------------------------------------------------------- #include "cmdlfpcf7931.h" - #include #include - #include "cmdparser.h" // command_t #include "comms.h" #include "ui.h" +#include "cliparser.h" static int CmdHelp(const char *Cmd); @@ -37,87 +36,106 @@ int pcf7931_resetConfig(void) { configPcf.InitDelay = PCF7931_DEFAULT_INITDELAY; configPcf.OffsetWidth = PCF7931_DEFAULT_OFFSET_WIDTH; configPcf.OffsetPosition = PCF7931_DEFAULT_OFFSET_POSITION; + PrintAndLogEx(INFO, "Configuration resetted"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pcf7931 config`") " to view current settings"); return PM3_SUCCESS; } int pcf7931_printConfig(void) { - PrintAndLogEx(NORMAL, "Password (LSB first on bytes) : %s", sprint_hex(configPcf.Pwd, sizeof(configPcf.Pwd))); - PrintAndLogEx(NORMAL, "Tag initialization delay : %d us", configPcf.InitDelay); - PrintAndLogEx(NORMAL, "Offset low pulses width : %d us", configPcf.OffsetWidth); - PrintAndLogEx(NORMAL, "Offset low pulses position : %d us", configPcf.OffsetPosition); + PrintAndLogEx(INFO, "Password (LSB first on bytes)... " _YELLOW_("%s"), sprint_hex(configPcf.Pwd, sizeof(configPcf.Pwd))); + PrintAndLogEx(INFO, "Tag initialization delay........ " _YELLOW_("%d") " us", configPcf.InitDelay); + PrintAndLogEx(INFO, "Offset low pulses width......... " _YELLOW_("%d") " us", configPcf.OffsetWidth); + PrintAndLogEx(INFO, "Offset low pulses position...... " _YELLOW_("%d") " us", configPcf.OffsetPosition); return PM3_SUCCESS; } -static int usage_pcf7931_read(void) { - PrintAndLogEx(NORMAL, "Usage: lf pcf7931 read [h] "); - PrintAndLogEx(NORMAL, "This command tries to read a PCF7931 tag."); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf pcf7931 read"); - return PM3_SUCCESS; -} +static int CmdLFPCF7931Reader(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf pcf7931 reader", + "read a PCF7931 tag", + "lf pcf7931 reader -@ -> continuous reader mode" + ); -static int usage_pcf7931_write(void) { - PrintAndLogEx(NORMAL, "Usage: lf pcf7931 write [h] "); - PrintAndLogEx(NORMAL, "This command tries to write a PCF7931 tag."); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, " blockaddress Block to save [0-7]"); - PrintAndLogEx(NORMAL, " byteaddress Index of byte inside block to write [0-15]"); - PrintAndLogEx(NORMAL, " data one byte of data (hex)"); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf pcf7931 write 2 1 FF"); - return PM3_SUCCESS; -} + void *argtable[] = { + arg_param_begin, + arg_lit0("@", NULL, "optional - continuous reader mode"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool cm = arg_get_lit(ctx, 1); + CLIParserFree(ctx); -static int usage_pcf7931_config(void) { - PrintAndLogEx(NORMAL, "Usage: lf pcf7931 config [h] [r] "); - PrintAndLogEx(NORMAL, "This command tries to set the configuration used with PCF7931 commands"); - PrintAndLogEx(NORMAL, "The time offsets could be useful to correct slew rate generated by the antenna"); - PrintAndLogEx(NORMAL, "Caling without some parameter will print the current configuration."); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h This help"); - PrintAndLogEx(NORMAL, " r Reset configuration to default values"); - PrintAndLogEx(NORMAL, " pwd Password, hex, 7bytes, LSB-order"); - PrintAndLogEx(NORMAL, " delay Tag initialization delay (in us) decimal"); - PrintAndLogEx(NORMAL, " offset Low pulses width (in us) decimal"); - PrintAndLogEx(NORMAL, " offset Low pulses position (in us) decimal"); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf pcf7931 config"); - PrintAndLogEx(NORMAL, " lf pcf7931 config r"); - PrintAndLogEx(NORMAL, " lf pcf7931 config 11223344556677 20000"); - PrintAndLogEx(NORMAL, " lf pcf7931 config 11223344556677 17500 -10 30"); - return PM3_SUCCESS; -} - -static int CmdLFPCF7931Read(const char *Cmd) { - - uint8_t ctmp = tolower(param_getchar(Cmd, 0)); - if (ctmp == 'h') return usage_pcf7931_read(); - - PacketResponseNG resp; - clearCommandBuffer(); - SendCommandNG(CMD_LF_PCF7931_READ, NULL, 0); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { - PrintAndLogEx(WARNING, "command execution time out"); - return PM3_ETIMEOUT; + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); } + + do { + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_LF_PCF7931_READ, NULL, 0); + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "command execution time out"); + return PM3_ETIMEOUT; + } + } while (cm && !kbd_enter_pressed()); + return PM3_SUCCESS; } static int CmdLFPCF7931Config(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf pcf7931 config", + "This command tries to set the configuration used with PCF7931 commands\n" + "The time offsets could be useful to correct slew rate generated by the antenna\n" + "Caling without some parameter will print the current configuration.", + "lf pcf7931 config --reset\n" + "lf pcf7931 config --pwd 11223344556677 -d 20000\n" + "lf pcf7931 config --pwd 11223344556677 -d 17500 --lw -10 --lp 30" + ); - uint8_t ctmp = tolower(param_getchar(Cmd, 0)); - if (ctmp == 0) return pcf7931_printConfig(); - if (ctmp == 'h') return usage_pcf7931_config(); - if (ctmp == 'r') return pcf7931_resetConfig(); + void *argtable[] = { + arg_param_begin, + arg_lit0("r", "reset", "Reset configuration to default values"), + arg_str0("p", "pwd", "", "Password, 7bytes, LSB-order"), + arg_u64_0("d", "delay", "", "Tag initialization delay (in us)"), + arg_int0(NULL, "lw", "", "offset, low pulses width (in us)"), + arg_int0(NULL, "lp", "", "offset, low pulses position (in us)"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); - if (param_gethex(Cmd, 0, configPcf.Pwd, 14)) return usage_pcf7931_config(); + bool use_reset = arg_get_lit(ctx, 1); + if (use_reset) { + CLIParserFree(ctx); + return pcf7931_resetConfig(); + } - configPcf.InitDelay = (param_get32ex(Cmd, 1, 0, 10) & 0xFFFF); - configPcf.OffsetWidth = (int)(param_get32ex(Cmd, 2, 0, 10) & 0xFFFF); - configPcf.OffsetPosition = (int)(param_get32ex(Cmd, 3, 0, 10) & 0xFFFF); + int pwd_len = 0; + uint8_t pwd[7] = {0}; + CLIGetHexWithReturn(ctx, 2, pwd, &pwd_len); + + uint32_t delay = arg_get_u32_def(ctx, 3, -1); + int ow = arg_get_int_def(ctx, 4, 0xFFFF); + int op = arg_get_int_def(ctx, 5, 0xFFFF); + CLIParserFree(ctx); + + if (pwd_len && pwd_len < sizeof(pwd)) { + PrintAndLogEx(ERR, "Password must be 7 bytes"); + return PM3_EINVARG; + } + + if (pwd_len) { + memcpy(configPcf.Pwd, pwd, sizeof(configPcf.Pwd)); + } + if (delay != -1) { + configPcf.InitDelay = (delay & 0xFFFF); + } + if (ow != 0xFFFF) { + configPcf.OffsetWidth = (ow & 0xFFFF); + } + if (op != 0xFFFF) { + configPcf.OffsetPosition =(op & 0xFFFF); + } pcf7931_printConfig(); return PM3_SUCCESS; @@ -125,21 +143,39 @@ static int CmdLFPCF7931Config(const char *Cmd) { static int CmdLFPCF7931Write(const char *Cmd) { - uint8_t ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || ctmp == 'h') return usage_pcf7931_write(); + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf pcf7931 write", + "This command tries to write a PCF7931 tag.", + "lf pcf7931 write --blk 2 --idx 1 -d FF -> Write 0xFF to block 2, index 1 " + ); - uint8_t block = 0, bytepos = 0, data = 0; + void *argtable[] = { + arg_param_begin, + arg_u64_1("b", "blk", "", "[0-7] block number"), + arg_u64_1("i", "idx", "", "[0-15] index of byte inside block"), + arg_str1("d", "data", "", "one byte to be written"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + uint8_t block = arg_get_u32_def(ctx, 1, 0); + uint8_t idx = arg_get_u32_def(ctx, 2, 0); - if (param_getdec(Cmd, 0, &block)) return usage_pcf7931_write(); - if (param_getdec(Cmd, 1, &bytepos)) return usage_pcf7931_write(); + int data_len = 0; + uint8_t data[1] = {0}; + CLIGetHexWithReturn(ctx, 3, data, &data_len); + CLIParserFree(ctx); - if ((block > 7) || (bytepos > 15)) return usage_pcf7931_write(); + if (block > 7) { + PrintAndLogEx(ERR, "out-of-range error, block must be between 0-7"); + return PM3_EINVARG; + } - data = param_get8ex(Cmd, 2, 0, 16); + if (idx > 15) { + PrintAndLogEx(ERR, "out-of-range error, index must be between 0-15"); + return PM3_EINVARG; + } - PrintAndLogEx(INFO, "Writing block: %d", block); - PrintAndLogEx(INFO, " pos: %d", bytepos); - PrintAndLogEx(INFO, " data: 0x%02X", data); + PrintAndLogEx(INFO, "Writing block %u at idx %u with data 0x%02X", block, idx, data[0]); uint32_t buf[10]; // TODO sparse struct, 7 *bytes* then words at offset 4*7! memcpy(buf, configPcf.Pwd, sizeof(configPcf.Pwd)); @@ -148,16 +184,16 @@ static int CmdLFPCF7931Write(const char *Cmd) { buf[9] = configPcf.InitDelay; clearCommandBuffer(); - SendCommandMIX(CMD_LF_PCF7931_WRITE, block, bytepos, data, buf, sizeof(buf)); + SendCommandMIX(CMD_LF_PCF7931_WRITE, block, idx, data[0], buf, sizeof(buf)); PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pcf7931 read`") " to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf pcf7931 reader`") " to verify"); return PM3_SUCCESS; } static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"read", CmdLFPCF7931Read, IfPm3Lf, "Read content of a PCF7931 transponder"}, + {"reader", CmdLFPCF7931Reader, IfPm3Lf, "Read content of a PCF7931 transponder"}, {"write", CmdLFPCF7931Write, IfPm3Lf, "Write data on a PCF7931 transponder."}, {"config", CmdLFPCF7931Config, AlwaysAvailable, "Configure the password, the tags initialization delay and time offsets (optional)"}, {NULL, NULL, NULL, NULL} From 2c29009bab2c9655f6e8ec97556976f742d7a1c7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 21:52:49 +0100 Subject: [PATCH 20/35] text --- doc/cliparser_todo.txt | 3 --- doc/commands.md | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/cliparser_todo.txt b/doc/cliparser_todo.txt index ba27198d9..c36d232c2 100644 --- a/doc/cliparser_todo.txt +++ b/doc/cliparser_todo.txt @@ -210,9 +210,6 @@ lf nedap generate lf nedap read lf nedap clone lf nedap sim -lf pcf7931 read -lf pcf7931 write -lf pcf7931 config lf t55xx config lf t55xx dangerraw lf t55xx detect diff --git a/doc/commands.md b/doc/commands.md index 8e77bcf57..f4443b5b5 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -824,7 +824,7 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- |`lf pcf7931 help `|Y |`This help` -|`lf pcf7931 read `|N |`Read content of a PCF7931 transponder` +|`lf pcf7931 reader `|N |`Read content of a PCF7931 transponder` |`lf pcf7931 write `|N |`Write data on a PCF7931 transponder.` |`lf pcf7931 config `|Y |`Configure the password, the tags initialization delay and time offsets (optional)` From 70af2bfbc06274a55a7d07e5b7c5eb291803ecbd Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 22:03:09 +0100 Subject: [PATCH 21/35] hf iclass info - uses cliparser --- client/src/cmdhficlass.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index fdfc27946..210d8f86a 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -568,6 +568,17 @@ static int CmdHFiClassSim(const char *Cmd) { } static int CmdHFiClassInfo(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf iclass info", + "Act as a iCLASS reader. Reads / fingerprints a iCLASS tag.", + "hf iclass info"); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); return info_iclass(); } From 3d5e949f470569c340f97ce31d5abdd4c42654d5 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 22:03:38 +0100 Subject: [PATCH 22/35] text --- doc/cliparser_todo.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/cliparser_todo.txt b/doc/cliparser_todo.txt index c36d232c2..2ed2aa2cc 100644 --- a/doc/cliparser_todo.txt +++ b/doc/cliparser_todo.txt @@ -78,7 +78,6 @@ hf felica resetmode hf felica litesim hf felica litedump hf fido info -hf iclass info hf iclass permutekey hf legic reader hf legic info From 23b0ad5183659813f8b820ea8e180c270ee4f5f6 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 1 Dec 2020 22:09:07 +0100 Subject: [PATCH 23/35] textual --- client/src/cmdhficlass.c | 9 +++------ doc/cliparser_todo.txt | 1 - 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 210d8f86a..e266817d1 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -3283,10 +3283,10 @@ static int CmdHFiClassPermuteKey(const char *Cmd) { int len = 0; CLIParserContext *ctx; - CLIParserInit(&ctx, "hf iclass permute", + CLIParserInit(&ctx, "hf iclass permutekey", "Permute function from 'heart of darkness' paper.", - "hf iclass permute --reverse --key 0123456789abcdef\n" - "hf iclass permute --key ff55330f0055330f\n"); + "hf iclass permutekey --reverse --key 0123456789abcdef\n" + "hf iclass permutekey --key ff55330f0055330f\n"); void *argtable[] = { arg_param_begin, @@ -3484,10 +3484,7 @@ int info_iclass(void) { uint8_t cardtype = get_mem_config(hdr); PrintAndLogEx(SUCCESS, " Card type.... " _GREEN_("%s"), card_types[cardtype]); - - } - DropField(); return PM3_SUCCESS; } diff --git a/doc/cliparser_todo.txt b/doc/cliparser_todo.txt index 2ed2aa2cc..864126740 100644 --- a/doc/cliparser_todo.txt +++ b/doc/cliparser_todo.txt @@ -78,7 +78,6 @@ hf felica resetmode hf felica litesim hf felica litedump hf fido info -hf iclass permutekey hf legic reader hf legic info hf legic dump From c76836880af013483e6def3656af7a26a5bdffe9 Mon Sep 17 00:00:00 2001 From: cyberpunk-re Date: Tue, 1 Dec 2020 21:28:37 +0000 Subject: [PATCH 24/35] Fix iso 15693 sim. Provide basic functionality for reader to detect ID --- armsrc/iso15693.c | 115 ++++++++++++++++++++++++++++++++++++---------- test.cmd | 2 + 2 files changed, 93 insertions(+), 24 deletions(-) create mode 100644 test.cmd diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 5861b3d17..9fabe1d18 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -104,10 +104,12 @@ #define ISO15693_MAX_COMMAND_LENGTH 45 // allows write single block with the maximum block size of 256bits. Write multiple blocks not supported yet // 32 + 2 crc + 1 -#define ISO15_MAX_FRAME 35 -#define CMD_ID_RESP 5 -#define CMD_READ_RESP 13 -#define CMD_INV_RESP 12 +#define ISO15_MAX_FRAME 35 +#define CMD_ID_RESP 5 +#define CMD_READ_RESP 13 +#define CMD_INV_RESP 12 +#define CMD_SYSINFO_RESP 17 +#define CMD_READBLOCK_RESP 7 //#define Crc(data, len) Crc(CRC_15693, (data), (len)) #define CheckCrc15(data, len) check_crc(CRC_15693, (data), (len)) @@ -1679,27 +1681,7 @@ void SimTagIso15693(uint8_t *uid) { LED_C_ON(); - // Build INVENTORY command - uint8_t resp_inv[CMD_INV_RESP] = {0}; - resp_inv[0] = 0; // No error, no protocol format extension - resp_inv[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported - - // 64-bit UID - resp_inv[2] = uid[7]; - resp_inv[3] = uid[6]; - resp_inv[4] = uid[5]; - resp_inv[5] = uid[4]; - resp_inv[6] = uid[3]; - resp_inv[7] = uid[2]; - resp_inv[8] = uid[1]; - resp_inv[9] = uid[0]; - - // CRC - AddCrc15(resp_inv, 10); - CodeIso15693AsTag(resp_inv, CMD_INV_RESP); - - tosend_t *ts = get_tosend(); enum { NO_FIELD, IDLE, ACTIVATED, SELECTED, HALTED } chip_state = NO_FIELD; @@ -1745,11 +1727,96 @@ void SimTagIso15693(uint8_t *uid) { if ((cmd_len >= 5) && (cmd[0] & ISO15_REQ_INVENTORY) && (cmd[1] == ISO15_CMD_INVENTORY)) { bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH); uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; + // Build INVENTORY command + uint8_t resp_inv[CMD_INV_RESP] = {0}; + + resp_inv[0] = 0; // No error, no protocol format extension + resp_inv[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported + + // 64-bit UID + resp_inv[2] = uid[7]; + resp_inv[3] = uid[6]; + resp_inv[4] = uid[5]; + resp_inv[5] = uid[4]; + resp_inv[6] = uid[3]; + resp_inv[7] = uid[2]; + resp_inv[8] = uid[1]; + resp_inv[9] = uid[0]; + + // CRC + AddCrc15(resp_inv, 10); + CodeIso15693AsTag(resp_inv, CMD_INV_RESP); + + tosend_t *ts = get_tosend(); + TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow); LogTrace_ISO15693(resp_inv, CMD_INV_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false); chip_state = SELECTED; } + + // GET_SYSTEM_INFO + if ((cmd[1] == ISO15_CMD_SYSINFO)) { + bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH); + uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; + + // Build GET_SYSTEM_INFO command + uint8_t resp_sysinfo[CMD_SYSINFO_RESP] = {0}; + + resp_sysinfo[0] = 0; // Response flags. + resp_sysinfo[1] = 0x0F; // Information flags. + + // 64-bit UID + resp_sysinfo[2] = uid[7]; + resp_sysinfo[3] = uid[6]; + resp_sysinfo[4] = uid[5]; + resp_sysinfo[5] = uid[4]; + resp_sysinfo[6] = uid[3]; + resp_sysinfo[7] = uid[2]; + resp_sysinfo[8] = uid[1]; + resp_sysinfo[9] = uid[0]; + + resp_sysinfo[10] = 0; // DSFID + resp_sysinfo[11] = 0; // AFI + + resp_sysinfo[12] = 0x1B; // Memory size [0]. + resp_sysinfo[13] = 0x03; // Memory size [1]. + resp_sysinfo[14] = 0x01; // Memory size [2]. + + // CRC + AddCrc15(resp_sysinfo, 15); + CodeIso15693AsTag(resp_sysinfo, CMD_SYSINFO_RESP); + + tosend_t *ts = get_tosend(); + + TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow); + LogTrace_ISO15693(resp_sysinfo, CMD_SYSINFO_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false); + } + + // READ_BLOCK + if ((cmd[1] == ISO15_CMD_READ)) { + bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH); + uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; + + // Build GET_SYSTEM_INFO command + uint8_t resp_readblock[CMD_READBLOCK_RESP] = {0}; + + resp_readblock[0] = 0; // Response flags. + resp_readblock[1] = 0; // Block data. + resp_readblock[2] = 0; // Block data. + resp_readblock[3] = 0; // Block data. + resp_readblock[4] = 0; // Block data. + + // CRC + AddCrc15(resp_readblock, 5); + CodeIso15693AsTag(resp_readblock, CMD_READBLOCK_RESP); + + tosend_t *ts = get_tosend(); + + + TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow); + LogTrace_ISO15693(resp_readblock, CMD_READBLOCK_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false); + } } switch_off(); diff --git a/test.cmd b/test.cmd new file mode 100644 index 000000000..c70608298 --- /dev/null +++ b/test.cmd @@ -0,0 +1,2 @@ +hw version +hw version From d792ff822b729dab2fcf6871b86573c3fe3fb185 Mon Sep 17 00:00:00 2001 From: cyberpunk-re Date: Tue, 1 Dec 2020 21:42:22 +0000 Subject: [PATCH 25/35] Proper identation and CHANGELOG entry --- CHANGELOG.md | 1 + armsrc/iso15693.c | 106 +++++++++++++++++++++++----------------------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3c58189e..de0373163 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix `hf 15 sim` - Added basic response to GET_SYSTEM_INFO and READBLOCK requests in order to fix iso15693 tag sim - Added `mf mfu sim t 7 n ` - MFU emulation now supports automatic exit after blocks read. (@cyberpunk-re) - Added T55xx Guide to assist in learning how to use the T55xx chip (@mwalker33) - Fix 'hf iclass wrbl' - dealing with tags in unsecured vs secured pagemode now is correct (@iceman1001) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 9fabe1d18..9b248bb1a 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -1727,27 +1727,28 @@ void SimTagIso15693(uint8_t *uid) { if ((cmd_len >= 5) && (cmd[0] & ISO15_REQ_INVENTORY) && (cmd[1] == ISO15_CMD_INVENTORY)) { bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH); uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; - // Build INVENTORY command - uint8_t resp_inv[CMD_INV_RESP] = {0}; + + // Build INVENTORY command + uint8_t resp_inv[CMD_INV_RESP] = {0}; - resp_inv[0] = 0; // No error, no protocol format extension - resp_inv[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported + resp_inv[0] = 0; // No error, no protocol format extension + resp_inv[1] = 0; // DSFID (data storage format identifier). 0x00 = not supported - // 64-bit UID - resp_inv[2] = uid[7]; - resp_inv[3] = uid[6]; - resp_inv[4] = uid[5]; - resp_inv[5] = uid[4]; - resp_inv[6] = uid[3]; - resp_inv[7] = uid[2]; - resp_inv[8] = uid[1]; - resp_inv[9] = uid[0]; - - // CRC - AddCrc15(resp_inv, 10); - CodeIso15693AsTag(resp_inv, CMD_INV_RESP); + // 64-bit UID + resp_inv[2] = uid[7]; + resp_inv[3] = uid[6]; + resp_inv[4] = uid[5]; + resp_inv[5] = uid[4]; + resp_inv[6] = uid[3]; + resp_inv[7] = uid[2]; + resp_inv[8] = uid[1]; + resp_inv[9] = uid[0]; + + // CRC + AddCrc15(resp_inv, 10); + CodeIso15693AsTag(resp_inv, CMD_INV_RESP); - tosend_t *ts = get_tosend(); + tosend_t *ts = get_tosend(); TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow); LogTrace_ISO15693(resp_inv, CMD_INV_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false); @@ -1760,34 +1761,34 @@ void SimTagIso15693(uint8_t *uid) { bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH); uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; - // Build GET_SYSTEM_INFO command - uint8_t resp_sysinfo[CMD_SYSINFO_RESP] = {0}; + // Build GET_SYSTEM_INFO command + uint8_t resp_sysinfo[CMD_SYSINFO_RESP] = {0}; - resp_sysinfo[0] = 0; // Response flags. - resp_sysinfo[1] = 0x0F; // Information flags. + resp_sysinfo[0] = 0; // Response flags. + resp_sysinfo[1] = 0x0F; // Information flags. - // 64-bit UID - resp_sysinfo[2] = uid[7]; - resp_sysinfo[3] = uid[6]; - resp_sysinfo[4] = uid[5]; - resp_sysinfo[5] = uid[4]; - resp_sysinfo[6] = uid[3]; - resp_sysinfo[7] = uid[2]; - resp_sysinfo[8] = uid[1]; - resp_sysinfo[9] = uid[0]; + // 64-bit UID + resp_sysinfo[2] = uid[7]; + resp_sysinfo[3] = uid[6]; + resp_sysinfo[4] = uid[5]; + resp_sysinfo[5] = uid[4]; + resp_sysinfo[6] = uid[3]; + resp_sysinfo[7] = uid[2]; + resp_sysinfo[8] = uid[1]; + resp_sysinfo[9] = uid[0]; - resp_sysinfo[10] = 0; // DSFID - resp_sysinfo[11] = 0; // AFI + resp_sysinfo[10] = 0; // DSFID + resp_sysinfo[11] = 0; // AFI - resp_sysinfo[12] = 0x1B; // Memory size [0]. - resp_sysinfo[13] = 0x03; // Memory size [1]. - resp_sysinfo[14] = 0x01; // Memory size [2]. + resp_sysinfo[12] = 0x1B; // Memory size [0]. + resp_sysinfo[13] = 0x03; // Memory size [1]. + resp_sysinfo[14] = 0x01; // Memory size [2]. - // CRC - AddCrc15(resp_sysinfo, 15); - CodeIso15693AsTag(resp_sysinfo, CMD_SYSINFO_RESP); + // CRC + AddCrc15(resp_sysinfo, 15); + CodeIso15693AsTag(resp_sysinfo, CMD_SYSINFO_RESP); - tosend_t *ts = get_tosend(); + tosend_t *ts = get_tosend(); TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow); LogTrace_ISO15693(resp_sysinfo, CMD_SYSINFO_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false); @@ -1798,22 +1799,21 @@ void SimTagIso15693(uint8_t *uid) { bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH); uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM; - // Build GET_SYSTEM_INFO command - uint8_t resp_readblock[CMD_READBLOCK_RESP] = {0}; + // Build GET_SYSTEM_INFO command + uint8_t resp_readblock[CMD_READBLOCK_RESP] = {0}; - resp_readblock[0] = 0; // Response flags. - resp_readblock[1] = 0; // Block data. - resp_readblock[2] = 0; // Block data. - resp_readblock[3] = 0; // Block data. - resp_readblock[4] = 0; // Block data. - - // CRC - AddCrc15(resp_readblock, 5); - CodeIso15693AsTag(resp_readblock, CMD_READBLOCK_RESP); - - tosend_t *ts = get_tosend(); + resp_readblock[0] = 0; // Response flags. + resp_readblock[1] = 0; // Block data. + resp_readblock[2] = 0; // Block data. + resp_readblock[3] = 0; // Block data. + resp_readblock[4] = 0; // Block data. + // CRC + AddCrc15(resp_readblock, 5); + CodeIso15693AsTag(resp_readblock, CMD_READBLOCK_RESP); + tosend_t *ts = get_tosend(); + TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow); LogTrace_ISO15693(resp_readblock, CMD_READBLOCK_RESP, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false); } From a03d725a7f4aca820b268c8b1011f5b1c8cafffb Mon Sep 17 00:00:00 2001 From: cyberpunk-re Date: Tue, 1 Dec 2020 22:56:08 +0000 Subject: [PATCH 26/35] Comments --- armsrc/iso15693.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 9b248bb1a..b6d1b7ed8 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -1765,7 +1765,7 @@ void SimTagIso15693(uint8_t *uid) { uint8_t resp_sysinfo[CMD_SYSINFO_RESP] = {0}; resp_sysinfo[0] = 0; // Response flags. - resp_sysinfo[1] = 0x0F; // Information flags. + resp_sysinfo[1] = 0x0F; // Information flags (0x0F - DSFID, AFI, Mem size, IC) // 64-bit UID resp_sysinfo[2] = uid[7]; @@ -1780,9 +1780,9 @@ void SimTagIso15693(uint8_t *uid) { resp_sysinfo[10] = 0; // DSFID resp_sysinfo[11] = 0; // AFI - resp_sysinfo[12] = 0x1B; // Memory size [0]. - resp_sysinfo[13] = 0x03; // Memory size [1]. - resp_sysinfo[14] = 0x01; // Memory size [2]. + resp_sysinfo[12] = 0x1B; // Memory size. + resp_sysinfo[13] = 0x03; // Memory size. + resp_sysinfo[14] = 0x01; // IC reference. // CRC AddCrc15(resp_sysinfo, 15); From e485d8dea4f5a885f038c25b4ddc3ba3e57bff98 Mon Sep 17 00:00:00 2001 From: cyberpunk-re Date: Tue, 1 Dec 2020 23:36:22 +0000 Subject: [PATCH 27/35] Removed test.cmd --- test.cmd | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 test.cmd diff --git a/test.cmd b/test.cmd deleted file mode 100644 index c70608298..000000000 --- a/test.cmd +++ /dev/null @@ -1,2 +0,0 @@ -hw version -hw version From 512b8aa272a3d9882531bde2784762f55ede6118 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Dec 2020 12:51:37 +0100 Subject: [PATCH 28/35] lf nedap - now uses cliparser, supports continuos mode, EM (untested) --- client/src/cmdlfnedap.c | 354 +++++++++++++++++++++------------------- doc/cliparser_todo.txt | 4 - doc/commands.md | 3 +- 3 files changed, 183 insertions(+), 178 deletions(-) diff --git a/client/src/cmdlfnedap.c b/client/src/cmdlfnedap.c index 1ee2923c1..1e87c85bf 100644 --- a/client/src/cmdlfnedap.c +++ b/client/src/cmdlfnedap.c @@ -24,6 +24,7 @@ #include "protocols.h" #include "cliparser.h" #include "cmdlfem4x05.h" // EM defines +#include "commonutil.h" #define FIXED_71 0x71 #define FIXED_40 0x40 @@ -32,60 +33,6 @@ static int CmdHelp(const char *Cmd); -static int usage_lf_nedap_gen(void) { - PrintAndLogEx(NORMAL, "generate Nedap bitstream in DemodBuffer"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf nedap generate [h] [s ] c i [l]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " s : optional, default=5"); - PrintAndLogEx(NORMAL, " c : customerCode"); - PrintAndLogEx(NORMAL, " i : ID (max 99999)"); - PrintAndLogEx(NORMAL, " l : optional - long (128), default to short (64)"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf nedap generate s 1 c 123 i 12345")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - -static int usage_lf_nedap_clone(void) { - PrintAndLogEx(NORMAL, "clone a Nedap tag to a T55x7 or Q5/T5555 tag."); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf nedap clone [h] [s ] c i [l] "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " s : optional, default=5"); - PrintAndLogEx(NORMAL, " c : customerCode"); - PrintAndLogEx(NORMAL, " i : ID (max 99999)"); - PrintAndLogEx(NORMAL, " l : optional - long (128), default to short (64)"); - PrintAndLogEx(NORMAL, " Q5 : optional - specify writing to Q5/T5555 tag"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf nedap clone s 1 c 123 i 12345")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - -static int usage_lf_nedap_sim(void) { - PrintAndLogEx(NORMAL, "simulate Nedap card."); - PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf nedap sim [h] [s ] c i [l]"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " s : subtype, default=5"); - PrintAndLogEx(NORMAL, " c : customerCode"); - PrintAndLogEx(NORMAL, " i : ID (max 99999)"); - PrintAndLogEx(NORMAL, " l : long (128), default to short (64)"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); -// TODO proper example? - PrintAndLogEx(NORMAL, _YELLOW_(" lf nedap sim s 1 c 7 i 1337")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - const uint8_t translateTable[10] = {8, 2, 1, 12, 4, 5, 10, 13, 0, 9}; const uint8_t invTranslateTable[16] = {8, 2, 1, 0xff, 4, 5, 0xff, 0xff, 0, 9, 6, 0xff, 3, 7, 0xff, 0xff}; const uint8_t preamble[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}; // zero inside @@ -197,7 +144,14 @@ int demodNedap(bool verbose) { badgeId = r1 * 10000 + r2 * 1000 + r3 * 100 + r4 * 10 + r5; - PrintAndLogEx(SUCCESS, "NEDAP - Card: " _YELLOW_("%05u") " subtype: " _YELLOW_("%1u")" customer code: " _YELLOW_("%03x") ", Raw: " _YELLOW_("%s"), badgeId, subtype, customerCode, sprint_hex_inrow(data, size / 8)); + PrintAndLogEx(SUCCESS, "NEDAP (%s) - ID: " _YELLOW_("%05u") " subtype: " _YELLOW_("%1u")" customer code: " _YELLOW_("%u / 0x%03X") " Raw: " _YELLOW_("%s") + , (size == 128) ? "128b" : "64b" + , badgeId + , subtype + , customerCode + , customerCode + , sprint_hex_inrow(data, size / 8) + ); PrintAndLogEx(DEBUG, "Checksum (%s) 0x%04X", _GREEN_("ok"), checksum); } else { @@ -320,10 +274,32 @@ lf t55xx wr b 4 d 4c0003ff */ -static int CmdLFNedapRead(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - lf_read(false, 16000); - return demodNedap(true); +static int CmdLFNedapReader(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf nedap reader", + "read a Nedap tag", + "lf nedap reader -@ -> continuous reader mode" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0("@", NULL, "optional - continuous reader mode"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool cm = arg_get_lit(ctx, 1); + CLIParserFree(ctx); + + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + + do { + lf_read(false, 16000); + demodNedap(!cm); + } while (cm && !kbd_enter_pressed()); + + return PM3_SUCCESS; } static void NedapGen(uint8_t subType, uint16_t customerCode, uint32_t id, bool isLong, uint8_t *data) { // 8 or 16 @@ -385,147 +361,182 @@ static void NedapGen(uint8_t subType, uint16_t customerCode, uint32_t id, bool i } } -static int (*usage_to_be_displayed)(void) = NULL; - -static int CmdLfNedapGen(const char *Cmd) { - uint8_t cmdp = 0, subType = 5, data[16], i, bin[128]; - uint16_t customerCode = 0; - uint32_t id = 0; - bool isLong = false, errors = false; - - int (*usage)(void) = usage_lf_nedap_gen; - if (usage_to_be_displayed != NULL) { - usage = usage_to_be_displayed; - usage_to_be_displayed = NULL; - } - - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 's': - subType = param_get8ex(Cmd, cmdp + 1, 5, 10); - cmdp += 2; - break; - case 'c': - customerCode = param_get32ex(Cmd, cmdp + 1, 0, 16); - cmdp += 2; - break; - case 'i': - id = param_get32ex(Cmd, cmdp + 1, 0, 10); - cmdp += 2; - break; - case 'l': - isLong = true; - cmdp++; - break; - case 'q': - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } - //Validations - if ((!customerCode) || (!id) || (subType > 0xF) || (customerCode > 0xFFF) || (id > 99999)) - errors = true; - - if (errors || cmdp == 0) { - usage(); - return PM3_EINVARG; - } - - PrintAndLogEx(SUCCESS, - "Tag - subtype: %1u , customer code: %03x , ID: %05u | %s" - , subType - , customerCode - , id - , isLong ? "(128b)" : "(64b)" +static int CmdLFNedapClone(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf nedap clone", + "clone a Nedap tag to a T55x7, Q5/T5555 or EM4305/4469 tag.", + "lf nedap clone --st 1 --cc 101 --id 1337" ); - NedapGen(subType, customerCode, id, isLong, data); + void *argtable[] = { + arg_param_begin, + arg_u64_0(NULL, "st", "", "optional - sub type (default 5)"), + arg_u64_1(NULL, "cc", "", "customer code (0-4095)"), + arg_u64_1(NULL, "id", "", "ID (0-99999)"), + arg_lit0("l", "long", "optional - long (128), default to short (64)"), + arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"), + arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); - for (i = 0; i < (isLong ? 16 : 8); i++) - num_to_bytebits(data[i], 8, bin + i * 8); + uint8_t sub_type = arg_get_u32_def(ctx, 1, 5); + uint16_t customer_code = arg_get_u32_def(ctx, 2, 0); + uint32_t id = arg_get_u32_def(ctx, 3, 0); + bool is_long = arg_get_lit(ctx, 4); + bool q5 = arg_get_lit(ctx, 5); + bool em = arg_get_lit(ctx, 6); + CLIParserFree(ctx); - setDemodBuff(bin, (isLong ? 128 : 64), 0); - return PM3_SUCCESS; -} - -static int CmdLFNedapClone(const char *Cmd) { - uint8_t max; - uint32_t blocks[5] = {0}; - - char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_nedap_clone(); - - usage_to_be_displayed = usage_lf_nedap_clone; - - int ret = CmdLfNedapGen(Cmd); - if (ret != PM3_SUCCESS) - return ret; - - if ((DemodBufferLen != 128) && (DemodBufferLen != 64)) { - PrintAndLogEx(ERR, "Error with tag bitstream generation."); - return PM3_ESOFT; + // Validations + if (q5 && em) { + PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time"); + return PM3_EINVARG; } + if (sub_type > 0xF) { + PrintAndLogEx(FAILED, "out-of-range, valid subtype is between 0-15"); + return PM3_EINVARG; + } + + if (customer_code > 0xFFF) { + PrintAndLogEx(FAILED, "out-of-range, valid customer code is between 0-4095"); + return PM3_EINVARG; + } + + if (id > 99999) { + PrintAndLogEx(FAILED, "out-of-range, id max value is 99999"); + return PM3_EINVARG; + } + + PrintAndLogEx(SUCCESS, "NEDAP (%s) - ID: " _GREEN_("%05u") " subtype: " _GREEN_("%1u") " customer code: " _GREEN_("%u / 0x%03X") + , is_long ? "128b" : "64b" + , id + , sub_type + , customer_code + , customer_code + ); + //NEDAP - compat mode, ASK/DIphase, data rate 64, 4 data blocks // DI-phase (CDP) T55x7_MODULATION_DIPHASE - - if (DemodBufferLen == 64) { - max = 3; - blocks[0] = T55X7_NEDAP_64_CONFIG_BLOCK; - } else { + uint8_t max; + uint32_t blocks[5] = {0}; + if (is_long) { max = 5; blocks[0] = T55X7_NEDAP_128_CONFIG_BLOCK; + } else { + max = 3; + blocks[0] = T55X7_NEDAP_64_CONFIG_BLOCK; } - bool q5 = (strstr(Cmd, "q") != NULL); + char cardtype[16] = {"T55x7"}; + + // Q5 if (q5) { - if (DemodBufferLen == 64) { - blocks[0] = T5555_FIXED | T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT; - } else { + if (is_long) { blocks[0] = T5555_FIXED | T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 4 << T5555_MAXBLOCK_SHIFT; + } else { + blocks[0] = T5555_FIXED | T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT; } } - for (uint8_t i = 1; i < max ; i++) { - blocks[i] = bytebits_to_byte(DemodBuffer + ((i - 1) * 32), 32); + // EM4305 + if (em) { + if (is_long) { + blocks[0] = EM4305_NEDAP_128_CONFIG_BLOCK; + } else { + blocks[0] = EM4305_NEDAP_64_CONFIG_BLOCK; + } + snprintf(cardtype, sizeof(cardtype), "EM4305/4469"); } - PrintAndLogEx(SUCCESS, "Preparing to clone NEDAP to " _YELLOW_("%s") " tag", (q5) ? "Q5/T5555" : "T55x7"); + // generate nedap bitstream + uint8_t data[16]; + NedapGen(sub_type, customer_code, id, is_long, data); + + for (uint8_t i = 1; i < max ; i++) { + blocks[i] = bytes_to_num (data + ((i - 1) * 4), 4); + } + + PrintAndLogEx(SUCCESS, "Preparing to clone NEDAP to " _YELLOW_("%s") " tag", cardtype); print_blocks(blocks, max); - int res = clone_t55xx_tag(blocks, max); + int res; + if (em) { + res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false); + } else { + res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + } + if (res == PM3_SUCCESS) { PrintAndLogEx(INFO, "The block 0 was changed (eXtended) which can be hard to detect."); - PrintAndLogEx(INFO, " Configure it manually " _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`")); + PrintAndLogEx(INFO, "Configure it manually " _YELLOW_("`lf t55xx config b 64 d BI i 1 o 32`")); } else { PrintAndLogEx(NORMAL, ""); } PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf nedap read`") " to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf nedap reader`") " to verify"); return res; } static int CmdLFNedapSim(const char *Cmd) { - char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_nedap_sim(); + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf nedap sim", + "Enables simulation of NEDAP card with specified card number.\n" + "Simulation runs until the button is pressed or another USB command is issued.", + "lf nedap sim --st 1 --cc 101 --id 1337" + ); - usage_to_be_displayed = usage_lf_nedap_sim; + void *argtable[] = { + arg_param_begin, + arg_u64_0(NULL, "st", "", "optional - sub type (default 5)"), + arg_u64_1(NULL, "cc", "", "customer code (0-4095)"), + arg_u64_1(NULL, "id", "", "ID (0-99999)"), + arg_lit0("l", "long", "optional - long (128), default to short (64)"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); - int ret = CmdLfNedapGen(Cmd); - if (ret != PM3_SUCCESS) - return ret; - - if ((DemodBufferLen != 128) && (DemodBufferLen != 64)) { - PrintAndLogEx(ERR, "Error with tag bitstream generation."); - return PM3_ESOFT; + uint8_t sub_type = arg_get_u32_def(ctx, 1, 5); + uint16_t customer_code = arg_get_u32_def(ctx, 2, 0); + uint32_t id = arg_get_u32_def(ctx, 3, 0); + bool is_long = arg_get_lit(ctx, 4); + CLIParserFree(ctx); + + if (sub_type > 0xF) { + PrintAndLogEx(FAILED, "out-of-range, valid subtype is between 0-15"); + return PM3_EINVARG; } - PrintAndLogEx(SUCCESS, "Simulating NEDAP - Raw"); - CmdPrintDemodBuff("x"); + if (customer_code > 0xFFF) { + PrintAndLogEx(FAILED, "out-of-range, valid customer code is between 0-4095"); + return PM3_EINVARG; + } + + if (id > 99999) { + PrintAndLogEx(FAILED, "out-of-range, id max value is 99999"); + return PM3_EINVARG; + } + + PrintAndLogEx(SUCCESS, "NEDAP (%s) - ID: " _GREEN_("%05u") " subtype: " _GREEN_("%1u") " customer code: " _GREEN_("%u / 0x%03X") + , is_long ? "128b" : "64b" + , id + , sub_type + , customer_code + , customer_code + ); + + // generate nedap bitstream + uint8_t max = (is_long) ? 16 : 8; + uint8_t data[16]; + NedapGen(sub_type, customer_code, id, is_long, data); + + uint8_t bs[16 * 8]; + for (uint8_t i = 0; i < max; i++) { + num_to_bytebits(data[i], 8, bs + i * 8); + } + + PrintAndLogEx(SUCCESS, "Simulating NEDAP - Raw: " _YELLOW_("%s"), sprint_hex_inrow(data, max)); // NEDAP, Biphase = 2, clock 64, inverted, (DIPhase == inverted BIphase) lf_asksim_t *payload = calloc(1, sizeof(lf_asksim_t) + DemodBufferLen); @@ -533,7 +544,7 @@ static int CmdLFNedapSim(const char *Cmd) { payload->invert = 1; payload->separator = 0; payload->clock = 64; - memcpy(payload->data, DemodBuffer, DemodBufferLen); + memcpy(payload->data, bs, (max * 8)); clearCommandBuffer(); SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + DemodBufferLen); @@ -550,12 +561,11 @@ static int CmdLFNedapSim(const char *Cmd) { } static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"demod", CmdLFNedapDemod, AlwaysAvailable, "Demodulate Nedap tag from the GraphBuffer"}, - {"generate", CmdLfNedapGen, AlwaysAvailable, "Generate Nedap bitstream in DemodBuffer"}, - {"read", CmdLFNedapRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, - {"clone", CmdLFNedapClone, IfPm3Lf, "Clone Nedap tag to T55x7 or Q5/T5555"}, - {"sim", CmdLFNedapSim, IfPm3Lf, "Simulate Nedap tag"}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"demod", CmdLFNedapDemod, AlwaysAvailable, "Demodulate Nedap tag from the GraphBuffer"}, + {"reader", CmdLFNedapReader, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, + {"clone", CmdLFNedapClone, IfPm3Lf, "Clone Nedap tag to T55x7 or Q5/T5555"}, + {"sim", CmdLFNedapSim, IfPm3Lf, "Simulate Nedap tag"}, {NULL, NULL, NULL, NULL} }; diff --git a/doc/cliparser_todo.txt b/doc/cliparser_todo.txt index 864126740..6d1b6ed86 100644 --- a/doc/cliparser_todo.txt +++ b/doc/cliparser_todo.txt @@ -204,10 +204,6 @@ lf hitag cc lf indala demod lf indala altdemod lf indala sim -lf nedap generate -lf nedap read -lf nedap clone -lf nedap sim lf t55xx config lf t55xx dangerraw lf t55xx detect diff --git a/doc/commands.md b/doc/commands.md index f4443b5b5..6a9b61b40 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -759,8 +759,7 @@ Check column "offline" for their availability. |------- |------- |----------- |`lf nedap help `|Y |`This help` |`lf nedap demod `|Y |`Demodulate Nedap tag from the GraphBuffer` -|`lf nedap generate `|Y |`Generate Nedap bitstream in DemodBuffer` -|`lf nedap read `|N |`Attempt to read and extract tag data from the antenna` +|`lf nedap reader `|N |`Attempt to read and extract tag data from the antenna` |`lf nedap clone `|N |`Clone Nedap tag to T55x7 or Q5/T5555` |`lf nedap sim `|N |`Simulate Nedap tag` From 50be1c72b3527f141445dc270c0f63358504e4d2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Dec 2020 13:00:12 +0100 Subject: [PATCH 29/35] adapt nedan test to new output --- tools/pm3_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index 6edfc80ea..b8d20c08b 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -412,7 +412,7 @@ while true; do "Motorola - fmt: 26 FC: 258 Card: 2, Raw: A0000000A0002021"; then break; fi if ! CheckExecute slow "lf T55 nedap test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nedap.pm3; lf search 1'" "NEDAP ID found"; then break; fi if ! CheckExecute slow "lf T55 nedap test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nedap.pm3; lf nedap demod'" \ - "NEDAP - Card: 12345 subtype: 1 customer code: 123, Raw: FF82246508209953"; then break; fi + "NEDAP (64b) - ID: 12345 subtype: 1 customer code: 291 / 0x123 Raw: FF82246508209953"; then break; fi if ! CheckExecute slow "lf T55 nexwatch test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch.pm3; lf search 1'" "NexWatch ID found"; then break; fi if ! CheckExecute slow "lf T55 nexwatch test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_nexwatch.pm3; lf nexwatch demod'" \ "Raw : 56000000213C9F8F150C00"; then break; fi From dfecb6a5ee242f4fa17ea70302a9f68661934ca7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Dec 2020 14:50:24 +0100 Subject: [PATCH 30/35] lf indala - finished cliparser changes --- doc/cliparser_todo.txt | 3 --- tools/pm3_tests.sh | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/doc/cliparser_todo.txt b/doc/cliparser_todo.txt index 6d1b6ed86..4d85a78fd 100644 --- a/doc/cliparser_todo.txt +++ b/doc/cliparser_todo.txt @@ -201,9 +201,6 @@ lf hitag sniff lf hitag writer lf hitag dump lf hitag cc -lf indala demod -lf indala altdemod -lf indala sim lf t55xx config lf t55xx dangerraw lf t55xx detect diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index b8d20c08b..baf08ad5d 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -391,7 +391,7 @@ while true; do "Fmt 26 FC: 123 Card: 1337 checksum: 10"; then break; fi if ! CheckExecute slow "lf T55 indala_224 test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_224.pm3; lf search 1'" "Indala ID found"; then break; fi if ! CheckExecute slow "lf T55 indala_224 test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_indala_224.pm3; lf indala demod'" \ - "Indala - len 224, Raw: 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"; then break; fi + "Indala - len 224 Raw: 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"; then break; fi if ! CheckExecute slow "lf T55 io test" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_io.pm3; lf search 1'" "IO Prox ID found"; then break; fi if ! CheckExecute slow "lf T55 io test2" "$CLIENTBIN -c 'data load -f traces/lf_ATA5577_io.pm3; lf io demod'" \ "IO Prox - XSF(01)01:01337, Raw: 007840603059cf3f (ok)"; then break; fi From effe02d1d39de21e466976653b83c8cacdfbf585 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Dec 2020 15:24:11 +0100 Subject: [PATCH 31/35] hf iclass reader - unified to support -@ --- client/src/cmdhficlass.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index e266817d1..b0bca9951 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -587,7 +587,7 @@ int read_iclass_csn(bool loop, bool verbose) { uint32_t flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE); int res = PM3_SUCCESS; - while (kbd_enter_pressed() == false) { + do { clearCommandBuffer(); SendCommandMIX(CMD_HF_ICLASS_READER, flags, 0, 0, NULL, 0); @@ -596,27 +596,23 @@ int read_iclass_csn(bool loop, bool verbose) { uint8_t status = resp.oldarg[0] & 0xff; - if (loop == false) { + if (loop) { + if (status == 0xFF) { + continue; + } + } else { + if (status == 0 || status == 0xFF) { if (verbose) PrintAndLogEx(WARNING, "iCLASS / ISO15693 card select failed"); res = PM3_EOPABORTED; break; } - } else { - if (status == 0xFF) - continue; } picopass_hdr *hdr = (picopass_hdr *)resp.data.asBytes; - - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(SUCCESS, " CSN: " _GREEN_("%s"), sprint_hex(hdr->csn, sizeof(hdr->csn))); - PrintAndLogEx(SUCCESS, " Config: " _GREEN_("%s"), sprint_hex((uint8_t *)&hdr->conf, sizeof(hdr->conf))); - - if (loop == false) - break; + PrintAndLogEx(SUCCESS, "iCLASS / Picopass CSN: " _GREEN_("%s"), sprint_hex(hdr->csn, sizeof(hdr->csn))); } - } + } while (loop && kbd_enter_pressed() == false); DropField(); return res; @@ -626,22 +622,24 @@ static int CmdHFiClassReader(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf iclass reader", - "Act as a iCLASS reader. Look for iCLASS tags until Enter or the pm3 button is pressed\n", - "hf iclass reader\n" - "hf iclass reader -1"); + "Act as a iCLASS reader. Look for iCLASS tags until Enter or the pm3 button is pressed", + "hf iclass reader -@ -> continuous reader mode" + ); void *argtable[] = { arg_param_begin, - arg_lit0("1", "one", "read once"), + arg_lit0("@", NULL, "optional - continuous reader mode"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - bool read_once = arg_get_lit(ctx, 1); + bool cm = arg_get_lit(ctx, 1); CLIParserFree(ctx); - PrintAndLogEx(INFO, "Starting iCLASS reader mode"); - PrintAndLogEx(INFO, "press " _YELLOW_("`enter`") " to cancel"); - return read_iclass_csn(!read_once, true); + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + + return read_iclass_csn(cm, true); } static int CmdHFiClassELoad(const char *Cmd) { From 54e7f8d438a0e214fb13ab12505705c52977d8c2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Dec 2020 17:13:42 +0100 Subject: [PATCH 32/35] ... --- client/src/cmdlfindala.c | 307 +++++++++++++++++++++++---------------- 1 file changed, 179 insertions(+), 128 deletions(-) diff --git a/client/src/cmdlfindala.c b/client/src/cmdlfindala.c index 35d02bcd7..e0ca3d74e 100644 --- a/client/src/cmdlfindala.c +++ b/client/src/cmdlfindala.c @@ -38,41 +38,6 @@ static uint8_t preamble224[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // standard 64 bit indala formats including 26 bit 40134 format static uint8_t preamble64[] = {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; -static int usage_lf_indala_demod(void) { - PrintAndLogEx(NORMAL, "Tries to psk demodulate the graphbuffer as Indala "); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf indala demod [h] <0|1> "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " clock : Set clock (as integer) optional, if not set, autodetect."); - PrintAndLogEx(NORMAL, " invert : 1 for invert output"); - PrintAndLogEx(NORMAL, " maxerror : Set maximum allowed errors, default = 100."); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf indala demod")); - PrintAndLogEx(NORMAL, _YELLOW_(" lf indala demod 32") " = demod a Indala tag from GraphBuffer using a clock of RF/32"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf indala demod 32 1") " = demod a Indala tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf indala demod 64 1 0") " = demod a Indala tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - -static int usage_lf_indala_sim(void) { - PrintAndLogEx(NORMAL, "Enables simulation of Indala card with specified uid."); - PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Usage: lf indala sim [h] "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h : This help"); - PrintAndLogEx(NORMAL, " u : 64/224 UID"); - PrintAndLogEx(NORMAL, " c : Cardnumber for Heden 2L format (decimal)"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" lf indala sim deadc0de")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} - #define HEDEN2L_OFFSET 31 static void encodeHeden2L(uint8_t *dest, uint32_t cardnumber) { @@ -119,7 +84,7 @@ static void encodeHeden2L(uint8_t *dest, uint32_t cardnumber) { dest[i / 8] = bytebits_to_byte(template + i, 8); } - PrintAndLogEx(INFO, "Heden-2L card number %u", cardnumber); + PrintAndLogEx(INFO, "Heden-2L card number " _GREEN_("%u"), cardnumber); } static void decodeHeden2L(uint8_t *bits) { @@ -186,7 +151,7 @@ int demodIndalaEx(int clk, int invert, int maxErr, bool verbose) { uint64_t foo = uid2 & 0x7FFFFFFF; if (DemodBufferLen == 64) { - PrintAndLogEx(SUCCESS, "Indala - len %zu, Raw: %x%08x", DemodBufferLen, uid1, uid2); + PrintAndLogEx(SUCCESS, "Indala - len " _GREEN_("%zu") " Raw: %x%08x", DemodBufferLen, uid1, uid2); uint16_t p1 = 0; p1 |= DemodBuffer[32 + 3] << 8; @@ -253,7 +218,7 @@ int demodIndalaEx(int clk, int invert, int maxErr, bool verbose) { uint32_t uid7 = bytebits_to_byte(DemodBuffer + 192, 32); PrintAndLogEx( SUCCESS - , "Indala - len %zu, Raw: %x%08x%08x%08x%08x%08x%08x" + , "Indala - len " _GREEN_("%zu") " Raw: %x%08x%08x%08x%08x%08x%08x" , DemodBufferLen , uid1 , uid2 @@ -278,28 +243,55 @@ int demodIndala(bool verbose) { static int CmdIndalaDemod(const char *Cmd) { - char cmdp = tolower(param_getchar(Cmd, 0)); - if (cmdp == 'h') return usage_lf_indala_demod(); + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf indala demod", + "Tries to psk demodulate the graphbuffer as Indala Prox", + "lf indala demod\n" + "lf indala demod --clock 32 -> demod a Indala tag from GraphBuffer using a clock of RF/32\n" + "lf indala demod --clock 32 -i -> demod a Indala tag from GraphBuffer using a clock of RF/32 and inverting data\n" + "lf indala demod --clock 64 -i --maxerror 0 -> demod a Indala tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors" + ); - int clk = 32, invert = 0, maxErr = 100; - if (strlen(Cmd) > 0) { - sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); - } - if (clk == 1) { - invert = 1; - clk = 0; - } - if (invert != 0 && invert != 1) { - PrintAndLogEx(WARNING, "Invalid value for invert: %i", invert); - return PM3_EINVARG; - } - return demodIndalaEx(clk, invert, maxErr, true); + void *argtable[] = { + arg_param_begin, + arg_int0(NULL, "clock", "", "optional - set clock (as integer), if not set, autodetect."), + arg_int0(NULL, "maxerr", "", "optional - set maximum allowed errors, default = 100"), + arg_lit0("i", "invert", "optional - invert output"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + uint32_t clk = arg_get_u32_def(ctx, 1, 32); + uint32_t max_err = arg_get_u32_def(ctx, 2, 100); + bool invert = arg_get_lit(ctx, 3); + CLIParserFree(ctx); + + return demodIndalaEx(clk, invert, max_err, true); } + // older alternative indala demodulate (has some positives and negatives) // returns false positives more often - but runs against more sets of samples // poor psk signal can be difficult to demod this approach might succeed when the other fails // but the other appears to currently be more accurate than this approach most of the time. static int CmdIndalaDemodAlt(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf indala altdemod", + "Tries to psk demodulate the graphbuffer as Indala Prox\n" + "This is uses a alternative way to demodulate and was used from the beginning in the Pm3 client.\n" + "It's now considered obsolete but remains because it has sometimes its advantages.", + "lf indala altdemod\n" + "lf indala altdemod --long -> demod a Indala tag from GraphBuffer as 224 bit long format" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0("l", "long", "optional - demod as 224b long format"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool is_long = arg_get_lit(ctx, 1); + CLIParserFree(ctx); + // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID int state = -1; int count = 0; @@ -360,7 +352,7 @@ static int CmdIndalaDemodAlt(const char *Cmd) { // Finding the start of a UID int uidlen, long_wait; - if (strcmp(Cmd, "224") == 0) { + if (is_long) { uidlen = 224; long_wait = 30; } else { @@ -533,26 +525,56 @@ static int CmdIndalaReader(const char *Cmd) { static int CmdIndalaSim(const char *Cmd) { - char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim(); + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf indala sim", + "Enables simulation of IOProx card with specified facility-code and card number.\n" + "Simulation runs until the button is pressed or another USB command is issued.", + "lf indala sim --heden 888\n" + "lf indala sim --raw a0000000a0002021\n" + "lf indala sim --raw 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5" + ); + void *argtable[] = { + arg_param_begin, + arg_strx0("r", "raw", "", "raw bytes"), + arg_int0(NULL, "heden", "", "Cardnumber for Heden 2L format"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + // raw param + int raw_len = 0; + uint8_t raw[(7 * 4) + 1 ]; + CLIGetHexWithReturn(ctx, 1, raw, &raw_len); + + bool is_long_uid = (raw_len == 28); + + int32_t cardnumber; + bool got_cn = false; + if (is_long_uid == false) { + + // Heden param + cardnumber = arg_get_int_def(ctx, 2, -1); + got_cn = (cardnumber != -1); + } + + CLIParserFree(ctx); + + if (got_cn) { + encodeHeden2L(raw, cardnumber); + raw_len = 8; + } + + // convert to binarray uint8_t bs[224]; memset(bs, 0x00, sizeof(bs)); - // uid - uint8_t hexuid[100]; - int len = 0; - param_gethex_ex(Cmd, 0, hexuid, &len); - - if (len > 28) - return usage_lf_indala_sim(); - - // convert to binarray uint8_t counter = 223; - for (uint8_t i = 0; i < len; i++) { + for (uint8_t i = 0; i < raw_len; i++) { + uint8_t tmp = raw[i]; for (uint8_t j = 0; j < 8; j++) { - bs[counter--] = hexuid[i] & 1; - hexuid[i] >>= 1; + bs[counter--] = tmp & 1; + tmp >>= 1; } } @@ -560,7 +582,10 @@ static int CmdIndalaSim(const char *Cmd) { // It has to send either 64bits (8bytes) or 224bits (28bytes). Zero padding needed if not. // lf simpsk 1 c 32 r 2 d 0102030405060708 - PrintAndLogEx(SUCCESS, "Simulating Indala UID: %s", sprint_hex(hexuid, len)); + PrintAndLogEx(SUCCESS, "Simulating " _YELLOW_("%s") " Indala raw " _YELLOW_("%s") + , (is_long_uid) ? "224b" : "64b" + , sprint_hex_inrow(raw, raw_len) + ); PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command"); // indala PSK, clock 32, carrier 0 @@ -570,8 +595,6 @@ static int CmdIndalaSim(const char *Cmd) { payload->clock = 32; memcpy(payload->data, bs, sizeof(bs)); - PrintAndLogEx(INFO, "Simulating"); - clearCommandBuffer(); SendCommandNG(CMD_LF_PSK_SIMULATE, (uint8_t *)payload, sizeof(lf_psksim_t) + sizeof(bs)); free(payload); @@ -588,8 +611,6 @@ static int CmdIndalaSim(const char *Cmd) { static int CmdIndalaClone(const char *Cmd) { int32_t cardnumber; - uint32_t blocks[8] = {0}; - uint8_t max = 0; uint8_t fc = 0; uint16_t cn = 0; @@ -599,28 +620,27 @@ static int CmdIndalaClone(const char *Cmd) { "lf indala clone --heden 888\n" "lf indala clone --fc 123 --cn 1337\n" "lf indala clone -r a0000000a0002021\n" - "lf indala clone -l -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"); + "lf indala clone -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"); void *argtable[] = { arg_param_begin, - arg_lit0("l", "long", "optional - long UID 224 bits"), - arg_int0("c", "heden", "", "Cardnumber for Heden 2L format"), - arg_strx0("r", "raw", "", "raw bytes"), - arg_lit0("q", "Q5", "optional - specify writing to Q5/T5555 tag"), - arg_int0(NULL, "fc", "", "Facility Code (26 bit format)"), - arg_int0(NULL, "cn", "", "Cardnumber (26 bit format)"), + arg_strx0("r", "raw", "", "raw bytes"), + arg_int0(NULL, "heden", "", "Cardnumber for Heden 2L format"), + arg_int0(NULL, "fc", "", "Facility Code (26 bit format)"), + arg_int0(NULL, "cn", "", "Cardnumber (26 bit format)"), + arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"), + arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); - - bool is_long_uid = arg_get_lit(ctx, 1); - // raw param - int datalen = 0; - uint8_t data[(7 * 4) + 1 ]; - CLIGetHexWithReturn(ctx, 3, data, &datalen); + int raw_len = 0; + uint8_t raw[(7 * 4) + 1]; + CLIGetHexWithReturn(ctx, 1, raw, &raw_len); - bool is_t5555 = arg_get_lit(ctx, 4); + bool is_long_uid = (raw_len == 28); + bool q5 = arg_get_lit(ctx, 5); + bool em = arg_get_lit(ctx, 6); bool got_cn = false, got_26 = false; if (is_long_uid == false) { @@ -630,43 +650,59 @@ static int CmdIndalaClone(const char *Cmd) { got_cn = (cardnumber != -1); // 26b FC/CN param - fc = arg_get_int_def(ctx, 5, 0); - cn = arg_get_int_def(ctx, 6, 0); + fc = arg_get_int_def(ctx, 3, 0); + cn = arg_get_int_def(ctx, 4, 0); got_26 = (fc != 0 && cn != 0); } - CLIParserFree(ctx); - PrintAndLogEx(INFO, "Target chip " _YELLOW_("%s"), (is_t5555) ? "Q5/T5555" : "T55x7"); + if (q5 && em) { + PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time"); + return PM3_EINVARG; + } + uint8_t max = 0; + uint32_t blocks[8] = {0}; + char cardtype[16] = {"T55x7"}; + if (is_long_uid) { + + blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT); + if (q5) { + blocks[0] = T5555_FIXED | T5555_SET_BITRATE(32) | T5555_MODULATION_PSK2 | (7 << T5555_MAXBLOCK_SHIFT); + snprintf(cardtype, sizeof(cardtype), "Q5/T5555"); + } + + if (em) { + blocks[0] = EM4305_INDALA_224_CONFIG_BLOCK; + snprintf(cardtype, sizeof(cardtype), "EM4305/4469"); + } + + blocks[1] = bytes_to_num(raw, 4); + blocks[2] = bytes_to_num(raw + 4, 4); + blocks[3] = bytes_to_num(raw + 8, 4); + blocks[4] = bytes_to_num(raw + 12, 4); + blocks[5] = bytes_to_num(raw + 16, 4); + blocks[6] = bytes_to_num(raw + 20, 4); + blocks[7] = bytes_to_num(raw + 24, 4); + max = 8; + // 224 BIT UID // config for Indala (RF/32;PSK2 with RF/2;Maxblock=7) - PrintAndLogEx(INFO, "Preparing to clone Indala 224bit tag"); - PrintAndLogEx(INFO, "Using raw " _GREEN_("%s"), sprint_hex_inrow(data, datalen)); + PrintAndLogEx(INFO, "Preparing to clone Indala 224bit to " _YELLOW_("%s") " raw " _GREEN_("%s") + , cardtype + , sprint_hex_inrow(raw, raw_len) + ); - if (is_t5555) - blocks[0] = T5555_FIXED | T5555_SET_BITRATE(32) | T5555_MODULATION_PSK2 | (7 << T5555_MAXBLOCK_SHIFT); - else - blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (7 << T55x7_MAXBLOCK_SHIFT); - blocks[1] = bytes_to_num(data, 4); - blocks[2] = bytes_to_num(data + 4, 4); - blocks[3] = bytes_to_num(data + 8, 4); - blocks[4] = bytes_to_num(data + 12, 4); - blocks[5] = bytes_to_num(data + 16, 4); - blocks[6] = bytes_to_num(data + 20, 4); - blocks[7] = bytes_to_num(data + 24, 4); - max = 8; } else { // 64 BIT UID if (got_cn) { - PrintAndLogEx(INFO, "Using Indala HEDEN cardnumber %u", cardnumber); - encodeHeden2L(data, cardnumber); - datalen = 8; + encodeHeden2L(raw, cardnumber); + raw_len = 8; } else if (got_26) { - PrintAndLogEx(INFO, "Using Indala 26b FC %u CN %u", fc, cn); + PrintAndLogEx(INFO, "Using Indala 26b FC " _GREEN_("%u") " CN " _GREEN_("%u"), fc, cn); // Used with the 26bit FC/CSN uint8_t *bits = calloc(INDALA_ARR_LEN, sizeof(uint8_t)); @@ -681,37 +717,52 @@ static int CmdIndalaClone(const char *Cmd) { return PM3_ESOFT; } - data[0] = bytebits_to_byte(bits, 8); - data[1] = bytebits_to_byte(bits + 8, 8); - data[2] = bytebits_to_byte(bits + 16, 8); - data[3] = bytebits_to_byte(bits + 24, 8); - data[4] = bytebits_to_byte(bits + 32, 8); - data[5] = bytebits_to_byte(bits + 40, 8); - data[6] = bytebits_to_byte(bits + 48, 8); - data[7] = bytebits_to_byte(bits + 56, 8); - datalen = 8; + raw[0] = bytebits_to_byte(bits, 8); + raw[1] = bytebits_to_byte(bits + 8, 8); + raw[2] = bytebits_to_byte(bits + 16, 8); + raw[3] = bytebits_to_byte(bits + 24, 8); + raw[4] = bytebits_to_byte(bits + 32, 8); + raw[5] = bytebits_to_byte(bits + 40, 8); + raw[6] = bytebits_to_byte(bits + 48, 8); + raw[7] = bytebits_to_byte(bits + 56, 8); + raw_len = 8; free(bits); } - // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) - PrintAndLogEx(INFO, "Preparing to clone Indala 64bit tag"); - PrintAndLogEx(INFO, "Using raw " _GREEN_("%s"), sprint_hex_inrow(data, datalen)); + blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT); - if (is_t5555) + if (q5) { blocks[0] = T5555_FIXED | T5555_SET_BITRATE(32) | T5555_MODULATION_PSK1 | (2 << T5555_MAXBLOCK_SHIFT); - else - blocks[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT); + snprintf(cardtype, sizeof(cardtype), "Q5/T5555"); + } + + if (em) { + blocks[0] = EM4305_INDALA_64_CONFIG_BLOCK; + snprintf(cardtype, sizeof(cardtype), "EM4305/4469"); + } - blocks[1] = bytes_to_num(data, 4); - blocks[2] = bytes_to_num(data + 4, 4); + blocks[1] = bytes_to_num(raw, 4); + blocks[2] = bytes_to_num(raw + 4, 4); max = 3; + + // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2) + PrintAndLogEx(INFO, "Preparing to clone Indala 64bit to " _YELLOW_("%s") " raw " _GREEN_("%s") + , cardtype + , sprint_hex_inrow(raw, raw_len) + ); } print_blocks(blocks, max); - int res = clone_t55xx_tag(blocks, max); + + int res; + if (em) { + res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false); + } else { + res = clone_t55xx_tag(blocks, ARRAYLEN(blocks)); + } PrintAndLogEx(SUCCESS, "Done"); - PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf indala read`") " to verify"); + PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf indala reader`") " to verify"); return res; } From 1a2b89d92fb559954d38dd527cfcf872e3787500 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Dec 2020 17:14:27 +0100 Subject: [PATCH 33/35] lesser time 6 -> 3 sec wait --- client/src/cmdlfcotag.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/src/cmdlfcotag.c b/client/src/cmdlfcotag.c index abe426e30..0c24f0461 100644 --- a/client/src/cmdlfcotag.c +++ b/client/src/cmdlfcotag.c @@ -123,14 +123,13 @@ static int CmdCOTAGReader(const char *Cmd) { uint8_t timeout = 3; int res = PM3_SUCCESS; - while (!WaitForResponseTimeout(CMD_LF_COTAG_READ, &resp, 2000)) { + while (!WaitForResponseTimeout(CMD_LF_COTAG_READ, &resp, 1000)) { timeout--; PrintAndLogEx(NORMAL, "." NOLF); if (timeout == 0) { PrintAndLogEx(NORMAL, ""); PrintAndLogEx(WARNING, "command execution time out"); SendCommandNG(CMD_BREAK_LOOP, NULL, 0); - timeout = 1; res = PM3_ETIMEOUT; } } From a03240a0dbbcc8f978ee3cdd7cad378a16db9e0e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 2 Dec 2020 17:14:57 +0100 Subject: [PATCH 34/35] text --- client/src/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index b0bca9951..b68081746 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -588,7 +588,6 @@ int read_iclass_csn(bool loop, bool verbose) { int res = PM3_SUCCESS; do { - clearCommandBuffer(); SendCommandMIX(CMD_HF_ICLASS_READER, flags, 0, 0, NULL, 0); PacketResponseNG resp; @@ -610,6 +609,7 @@ int read_iclass_csn(bool loop, bool verbose) { } picopass_hdr *hdr = (picopass_hdr *)resp.data.asBytes; + PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "iCLASS / Picopass CSN: " _GREEN_("%s"), sprint_hex(hdr->csn, sizeof(hdr->csn))); } } while (loop && kbd_enter_pressed() == false); From 81917aebdf2cf076c022775135b1731f648d4c7d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 3 Dec 2020 14:52:07 +0100 Subject: [PATCH 35/35] tune hw tune warnings --- client/src/cmddata.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 6f70ca2cc..3aa7b07fd 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -1702,9 +1702,11 @@ int CmdTuneSamples(const char *Cmd) { if (package->peak_v > NON_VOLTAGE && package->peak_f > 0) PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (package->peak_v * ANTENNA_ERROR) / 1000.0, LF_DIV2FREQ(package->peak_f)); + // Empirical measures in mV const double vdd_rdv4 = 9000; - const double vdd_other = 5400; // Empirical measures in mV + const double vdd_other = 5400; double vdd = IfPm3Rdv4Fw() ? vdd_rdv4 : vdd_other; + if (package->peak_v > NON_VOLTAGE && package->peak_f > 0) { // Q measure with Q=f/delta_f @@ -1737,9 +1739,15 @@ int CmdTuneSamples(const char *Cmd) { // cross-check results if (lfq1 > 3) { double approx_vdd = (double)package->peak_v * 3.14 / 2 / lfq1; - if ((approx_vdd > (vdd_rdv4 + vdd_other) / 2) && (! IfPm3Rdv4Fw())) + // Got 8858 on a RDV4 with large antenna 134/14 + // Got 8761 on a non-RDV4 + const double approx_vdd_other_max = 8840; + + // 1% over threshold and supposedly non-RDV4 + if ((approx_vdd > approx_vdd_other_max * 1.01) && (! IfPm3Rdv4Fw())) PrintAndLogEx(WARNING, "Contradicting measures seem to indicate you're running a " _YELLOW_("PM3_OTHER firmware on a RDV4") ", please check your setup"); - if ((approx_vdd < (vdd_rdv4 + vdd_other) / 2) && (IfPm3Rdv4Fw())) + // 1% below threshold and supposedly RDV4 + if ((approx_vdd < approx_vdd_other_max * 0.99) && (IfPm3Rdv4Fw())) PrintAndLogEx(WARNING, "Contradicting measures seem to indicate you're running a " _YELLOW_("PM3_RDV4 firmware on a non-RDV4") ", please check your setup"); } }