From 4d264fa63c753f1df41bb0f0401a8f2d3a263773 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 29 Apr 2022 16:32:01 +0200 Subject: [PATCH] Preparing EM4100 clone to EM4305 --- armsrc/Standalone/lf_em4100rswb.c | 2 +- armsrc/appmain.c | 10 ++++--- armsrc/lfops.c | 36 ++++++++++++++++++++----- client/src/cmdlfem410x.c | 44 +++++++++++++++++++------------ include/pm3_cmd.h | 2 +- 5 files changed, 64 insertions(+), 30 deletions(-) diff --git a/armsrc/Standalone/lf_em4100rswb.c b/armsrc/Standalone/lf_em4100rswb.c index 574619da9..501af3f5a 100644 --- a/armsrc/Standalone/lf_em4100rswb.c +++ b/armsrc/Standalone/lf_em4100rswb.c @@ -62,7 +62,7 @@ #endif #define LF_CLOCK 64 // for 125kHz -#define LF_RWSB_T55XX_TYPE 1 // Tag type: 0 - T5555, 1-T55x7 +#define LF_RWSB_T55XX_TYPE 1 // Tag type: 0 - T5555, 1-T55x7, 2-EM4x05 #define LF_RWSB_UNKNOWN_RESULT 0 #define LF_RWSB_BRUTE_STOPED 1 diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 84a7ea5ff..e329b2e23 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -913,16 +913,18 @@ static void PacketReceived(PacketCommandNG *packet) { reply_ng(CMD_LF_EM410X_WATCH, res, NULL, 0); break; } - case CMD_LF_EM410X_WRITE: { + case CMD_LF_EM410X_CLONE: { struct p { - uint8_t card; + bool Q5; + bool EM; uint8_t clock; uint32_t high; uint32_t low; } PACKED; struct p *payload = (struct p *)packet->data.asBytes; - int res = copy_em410x_to_t55xx(payload->card, payload->clock, payload->high, payload->low, true); - reply_ng(CMD_LF_EM410X_WRITE, res, NULL, 0); + uint8_t card = payload->Q5 ? 0 : (payload->EM ? 2 : 1); + int res = copy_em410x_to_t55xx(card, payload->clock, payload->high, payload->low, true); + reply_ng(CMD_LF_EM410X_CLONE, res, NULL, 0); break; } case CMD_LF_TI_READ: { diff --git a/armsrc/lfops.c b/armsrc/lfops.c index e404344d4..6b99c876a 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2295,10 +2295,10 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT, boo if (g_dbglevel == DBG_DEBUG) { Dbprintf("# | data ( EM4x05 )"); Dbprintf("--+----------------"); - Dbprintf("0 | ", data[0]); - Dbprintf("1 | ", data[1]); - Dbprintf("2 | ", data[2]); - Dbprintf("3 | ", data[3]); + Dbprintf("0 | %08x", data[0]); + Dbprintf("1 | %08x", data[1]); + Dbprintf("2 | %08x", data[2]); + Dbprintf("3 | %08x", data[3]); Dbprintf("--+----------------"); } //WriteEM4x05(data, 0, last_block + 1); @@ -2325,6 +2325,14 @@ void CopyVikingtoT55xx(uint8_t *blocks, bool q5, bool em, bool ledcontrol) { // Program the data blocks for supplied ID and the block 0 config if (em) { Dbprintf("Clone Viking to EM4x05 is untested and disabled until verified"); + if (g_dbglevel == DBG_DEBUG) { + Dbprintf("# | data ( EM4x05 )"); + Dbprintf("--+----------------"); + Dbprintf("0 | %08x", data[0]); + Dbprintf("1 | %08x", data[1]); + Dbprintf("2 | %08x", data[2]); + Dbprintf("--+----------------"); + } //WriteEM4x05(data, 0, 3); } else { WriteT55xx(data, 0, 3, ledcontrol); @@ -2413,15 +2421,29 @@ int copy_em410x_to_t55xx(uint8_t card, uint8_t clock, uint32_t id_hi, uint32_t i if (card == 1) { // T55x7 data[0] = clockbits | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT); + } else if (card == 2) { // EM4x05 + data[0] = (EM4x05_SET_BITRATE(clock) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(2)); } else { // T5555 (Q5) data[0] = T5555_SET_BITRATE(clock) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT); } - - WriteT55xx(data, 0, 3, ledcontrol); + if (card == 2) { + Dbprintf("Clone EM410x to EM4x05 is untested and disabled until verified"); + if (g_dbglevel == DBG_DEBUG) { + Dbprintf("# | data ( EM4x05 )"); + Dbprintf("--+----------------"); + Dbprintf("0 | %08x", data[0]); + Dbprintf("1 | %08x", data[1]); + Dbprintf("2 | %08x", data[2]); + Dbprintf("--+----------------"); + } + //WriteEM4x05(data, 0, 3); + } else { + WriteT55xx(data, 0, 3, ledcontrol); + } if (ledcontrol) LEDsoff(); Dbprintf("Tag %s written with 0x%08x%08x\n", - card ? "T55x7" : "T5555", + card == 0 ? "T5555" : (card == 1 ? "T55x7" : "EM4x05"), (uint32_t)(id >> 32), (uint32_t)id); return PM3_SUCCESS; diff --git a/client/src/cmdlfem410x.c b/client/src/cmdlfem410x.c index 3b183f2d8..ef9caf959 100644 --- a/client/src/cmdlfem410x.c +++ b/client/src/cmdlfem410x.c @@ -630,16 +630,18 @@ static int CmdEM410xSpoof(const char *Cmd) { static int CmdEM410xClone(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf em 410x clone", - "Writes EM410x ID to a T55x7 or Q5/T5555 tag", - "lf em 410x clone --id 0F0368568B -> write T55x7 tag\n" - "lf em 410x clone --id 0F0368568B --q5 -> write Q5/T5555 tag" + "clone a EM410x ID to a T55x7, Q5/T5555 or EM4305/4469 tag.", + "lf em 410x clone --id 0F0368568B -> encode for T55x7 tag\n" + "lf em 410x clone --id 0F0368568B --q5 -> encode for Q5/T5555 tag\n" + "lf em 410x clone --id 0F0368568B --em -> encode for EM4305/4469" ); void *argtable[] = { arg_param_begin, arg_u64_0(NULL, "clk", "", "<16|32|40|64> clock (default 64)"), arg_str1(NULL, "id", "", "EM Tag ID number (5 hex bytes)"), - arg_lit0(NULL, "q5", "specify writing to Q5/T5555 tag"), + 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); @@ -650,9 +652,19 @@ static int CmdEM410xClone(const char *Cmd) { uint8_t uid[5] = {0}; CLIGetHexWithReturn(ctx, 2, uid, &uid_len); bool q5 = arg_get_lit(ctx, 3); + bool em = arg_get_lit(ctx, 4); CLIParserFree(ctx); uint64_t id = bytes_to_num(uid, uid_len); + if (id == 0) { + PrintAndLogEx(ERR, "Cardnumber can't be zero"); + return PM3_EINVARG; + } + + if (q5 && em) { + PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time"); + return PM3_EINVARG; + } // Allowed clock rates: 16, 32, 40 and 64 if ((clk != 16) && (clk != 32) && (clk != 64) && (clk != 40)) { @@ -665,29 +677,27 @@ static int CmdEM410xClone(const char *Cmd) { snprintf(cardtype, sizeof(cardtype), "Q5/T5555"); } - PrintAndLogEx(SUCCESS, "Preparing to clone EM4102 to " _YELLOW_("%s") " tag with EM Tag ID " _GREEN_("%010" PRIX64) " (RF/%d)", cardtype, id, clk); - // NOTE: We really should pass the clock in as a separate argument, but to - // provide for backwards-compatibility for older firmware, and to avoid - // having to add another argument to CMD_LF_EM410X_WRITE, we just store - // the clock rate in bits 8-15 of the card value + PrintAndLogEx(SUCCESS, "Preparing to clone EM4102 to " _YELLOW_("%s") " tag with EM Tag ID " _GREEN_("%010" PRIX64) " (RF/%d)", q5 ? "Q5/T5555" : (em ? "EM4305/4469" : "T55x7"), id, clk); struct { - uint8_t card; + bool Q5; + bool EM; uint8_t clock; uint32_t high; uint32_t low; - } PACKED params; + } PACKED payload; - params.card = (q5) ? 0 : 1; - params.clock = clk; - params.high = (uint32_t)(id >> 32); - params.low = (uint32_t)id; + payload.Q5 = q5; + payload.EM = em; + payload.clock = clk; + payload.high = (uint32_t)(id >> 32); + payload.low = (uint32_t)id; clearCommandBuffer(); - SendCommandNG(CMD_LF_EM410X_WRITE, (uint8_t *)¶ms, sizeof(params)); + SendCommandNG(CMD_LF_EM410X_CLONE, (uint8_t *)&payload, sizeof(payload)); PacketResponseNG resp; - WaitForResponse(CMD_LF_EM410X_WRITE, &resp); + WaitForResponse(CMD_LF_EM410X_CLONE, &resp); switch (resp.status) { case PM3_SUCCESS: { PrintAndLogEx(SUCCESS, "Done"); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index c97124cc0..e62c0375e 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -455,7 +455,7 @@ typedef struct { #define CMD_LF_SIMULATE_BIDIR 0x020E #define CMD_SET_ADC_MUX 0x020F #define CMD_LF_HID_CLONE 0x0210 -#define CMD_LF_EM410X_WRITE 0x0211 +#define CMD_LF_EM410X_CLONE 0x0211 #define CMD_LF_T55XX_READBL 0x0214 #define CMD_LF_T55XX_WRITEBL 0x0215 #define CMD_LF_T55XX_RESET_READ 0x0216