Preparing EM4100 clone to EM4305

This commit is contained in:
Philippe Teuwen 2022-04-29 16:32:01 +02:00
parent f25c7b1179
commit 4d264fa63c
5 changed files with 64 additions and 30 deletions

View file

@ -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

View file

@ -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: {

View file

@ -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;

View file

@ -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", "<dec>", "<16|32|40|64> clock (default 64)"),
arg_str1(NULL, "id", "<hex>", "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 *)&params, 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");

View file

@ -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