From e5c5629cf2761f1a582a84d66d4a0b59129b824e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 7 Mar 2021 23:43:53 +0100 Subject: [PATCH 1/4] Some tunings of otptear: - make tearoff_delay_us and tearoff_enabled globals - use tearoff_hook and remove Dbprintf in critical tearoff timing - move initial write from MifareU_Otp_Tearoff to CmdHF14AMfuOtpTearoff and make it optional (old behavior was writing initial 00000000 when -d was not provided) - tearoff: compare with initial write, not with previous tearoff outcome - rephrase some messages - track all begin and end of erase and write phases, with quite complex logic to cover multiple cases (starting in middle of erased phase, starting with write 0, ...) and report them - check against initial write error - repeat same timing (up to 10x) in case of write/read errors then quit - typos --- armsrc/appmain.c | 4 +- armsrc/iclass.c | 2 +- armsrc/iso14443a.c | 2 +- armsrc/iso14443b.c | 2 +- armsrc/iso15693.c | 6 +- armsrc/lfops.c | 4 +- armsrc/mifarecmd.c | 21 ++---- client/src/cmdhfmfu.c | 169 +++++++++++++++++++++++++----------------- include/common.h | 4 + 9 files changed, 121 insertions(+), 93 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index d9162dda8..e9c34e2cc 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -73,8 +73,8 @@ extern uint32_t _stack_start, _stack_end; struct common_area common_area __attribute__((section(".commonarea"))); static int button_status = BUTTON_NO_CLICK; static bool allow_send_wtx = false; -static uint16_t tearoff_delay_us = 0; -static bool tearoff_enabled = false; +uint16_t tearoff_delay_us = 0; +bool tearoff_enabled = false; int tearoff_hook(void) { if (tearoff_enabled) { diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 4d5975324..e149254f7 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1881,7 +1881,7 @@ void iClass_WriteBlock(uint8_t *msg) { iclass_send_as_reader(write, write_len, &start_time, &eof_time); - if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured + if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred res = false; switch_off(); if (payload->req.send_reply) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index cd07a4007..1509cc80c 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -2972,7 +2972,7 @@ void ReaderIso14443a(PacketCommandNG *c) { } } - if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured + if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred FpgaDisableTracing(); reply_mix(CMD_ACK, 0, 0, 0, NULL, 0); } else { diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 09c5e775e..c747a0e27 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -2092,7 +2092,7 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) { uint32_t eof_time = 0; CodeAndTransmit14443bAsReader(cmd, len, &start_time, &eof_time); - if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured + if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred FpgaDisableTracing(); reply_mix(CMD_HF_ISO14443B_COMMAND, -2, 0, 0, NULL, 0); } else { diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index de7a409bd..66539c807 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -1477,7 +1477,7 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, bool speed_fast, uint8_t tosend_t *ts = get_tosend(); TransmitTo15693Tag(ts->buf, ts->max, &start_time); - if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured + if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred res = PM3_ETEAROFF; @@ -1598,7 +1598,7 @@ void ReaderIso15693(uint32_t parameter) { uint32_t eof_time; int recvlen = SendDataTag(cmd, sizeof(cmd), true, true, answer, ISO15693_MAX_RESPONSE_LENGTH, start_time, ISO15693_READER_TIMEOUT, &eof_time); - if (recvlen == PM3_ETEAROFF) { // tearoff occured + if (recvlen == PM3_ETEAROFF) { // tearoff occurred reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0); } else { @@ -1928,7 +1928,7 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint uint32_t start_time = 0; int recvlen = SendDataTag(data, datalen, true, speed, (recv ? recvbuf : NULL), sizeof(recvbuf), start_time, timeout, &eof_time); - if (recvlen == PM3_ETEAROFF) { // tearoff occured + if (recvlen == PM3_ETEAROFF) { // tearoff occurred reply_mix(CMD_ACK, recvlen, 0, 0, NULL, 0); } else { diff --git a/armsrc/lfops.c b/armsrc/lfops.c index b4daed774..9555e59c1 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -2639,7 +2639,7 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) { SendForward(len, false); - if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured + if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred StopTicks(); reply_ng(CMD_LF_EM4X_WRITEWORD, PM3_ETEAROFF, NULL, 0); } else { @@ -2681,7 +2681,7 @@ void EM4xProtectWord(uint32_t data, uint32_t pwd, uint8_t usepwd) { SendForward(len, false); - if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occured + if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred StopTicks(); reply_ng(CMD_LF_EM4X_PROTECTWORD, PM3_ETEAROFF, NULL, 0); } else { diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 2ea7aa1b8..bcb47aa24 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2713,20 +2713,15 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) { // // Tear-off attack against MFU. // - Moebius et al -void MifareU_Otp_Tearoff(uint8_t blno, uint32_t tearoff_time, uint8_t *datain) { +void MifareU_Otp_Tearoff(uint8_t blno, uint32_t tearoff_time, uint8_t *data_testwrite) { uint8_t blockNo = blno; - uint8_t data_fullwrite[4] = {0x00}; - uint8_t data_testwrite[4] = {0x00}; - memcpy(data_fullwrite, datain, 4); - memcpy(data_testwrite, datain + 4, 4); if (DBGLEVEL >= DBG_DEBUG) DbpString("Preparing OTP tear-off"); if (tearoff_time > 43000) tearoff_time = 43000; - - MifareUWriteBlockEx(blockNo, 0, data_fullwrite, false); - + tearoff_delay_us = tearoff_time; + tearoff_enabled = true; LEDsoff(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -2750,15 +2745,9 @@ void MifareU_Otp_Tearoff(uint8_t blno, uint32_t tearoff_time, uint8_t *datain) { return; }; // send - ReaderTransmit(cmd, sizeof(cmd), NULL); - - // Wait before cutting power. aka tear-off LED_D_ON(); - - SpinDelayUsPrecision(tearoff_time); - if (DBGLEVEL >= DBG_DEBUG) Dbprintf(_YELLOW_("OTP tear-off triggered!")); - switch_off(); - + ReaderTransmit(cmd, sizeof(cmd), NULL); + tearoff_hook(); reply_ng(CMD_HF_MFU_OTP_TEAROFF, PM3_SUCCESS, NULL, 0); } diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index 4e4f5c6f4..9488378fd 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -3102,7 +3102,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { "hf mfu otptear -b 3 -i 100 -s 1000\n" "hf mfu otptear -b 3 -i 1 -e 200\n" "hf mfu otptear -b 3 -i 100 -s 200 -e 2500 -d FFFFFFFF -t EEEEEEEE\n" - "hf mfu otptear -b 3 -i 100 -s 200 -e 2500 -d FFFFFFFF -t EEEEEEEE -m 00000000 -> quite when OTP is reset" + "hf mfu otptear -b 3 -i 100 -s 200 -e 2500 -d FFFFFFFF -t EEEEEEEE -m 00000000 -> quit when OTP is reset" ); void *argtable[] = { @@ -3112,7 +3112,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { arg_u64_0("e", "end", "", "end time (def 3000 us)"), arg_u64_0("s", "start", "", "start time (def 0 us)"), arg_str0("d", "data", "", "initialise data before run (4 bytes)"), - arg_str0("t", "test", "", "test write data (4 bytes)"), + arg_str0("t", "test", "", "test write data (4 bytes, 00000000 by default)"), arg_str0("m", "match", "", "exit criteria, if block matches this value (4 bytes)"), arg_param_end }; @@ -3126,6 +3126,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { int d_len = 0; uint8_t data[4] = {0x00}; CLIGetHexWithReturn(ctx, 5, data, &d_len); + bool use_data = (d_len > 0); int t_len = 0; uint8_t test[4] = {0x00}; @@ -3150,7 +3151,7 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { return PM3_EINVARG; } if (start > (end - steps)) { - PrintAndLogEx(WARNING, "Start time larger then (end time + steps)"); + PrintAndLogEx(WARNING, "Start time larger than (end time + steps)"); return PM3_EINVARG; } @@ -3169,26 +3170,34 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { return PM3_EINVARG; } - uint8_t teardata[8] = {0x00}; - memcpy(teardata, data, sizeof(data)); - memcpy(teardata + sizeof(data), test, sizeof(test)); + uint8_t teardata[4] = {0x00}; + memcpy(teardata, test, sizeof(test)); PrintAndLogEx(INFO, "----------------- " _CYAN_("MFU Tear off") " ---------------------"); PrintAndLogEx(INFO, "Starting Tear-off test"); PrintAndLogEx(INFO, "Target block no: %u", blockno); - PrintAndLogEx(INFO, "Target inital block data : %s", sprint_hex_inrow(teardata, 4)); - PrintAndLogEx(INFO, "Target write block data : %s", sprint_hex_inrow(teardata + 4, 4)); + if (use_data) { + PrintAndLogEx(INFO, "Target inital block data : %s", sprint_hex_inrow(data, 4)); + } + PrintAndLogEx(INFO, "Target write block data : %s", sprint_hex_inrow(teardata, 4)); + if (use_match) { + PrintAndLogEx(INFO, "Target match block data : %s", sprint_hex_inrow(match, 4)); + } PrintAndLogEx(INFO, "----------------------------------------------------"); uint8_t isOK; - bool got_pre = false, got_post = false, lock_on = false; + bool lock_on = false; uint8_t pre[4] = {0}; uint8_t post[4] = {0}; uint32_t current = start; - int phase_clear = -1; - int phase_newwr = -1; + int phase_begin_clear = -1; + int phase_end_clear = -1; + int phase_begin_newwr = -1; + int phase_end_newwr = -1; + bool skip_phase1 = false; uint8_t retries = 0; + uint8_t error_retries = 0; - while (current <= (end - steps)) { + while ((current <= (end - steps)) && (error_retries < 10)) { if (kbd_enter_pressed()) { PrintAndLogEx(INFO, "\naborted via keyboard!\n"); @@ -3198,10 +3207,27 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { PrintAndLogEx(INFO, "Using tear-off delay " _GREEN_("%" PRIu32) " us", current); clearCommandBuffer(); - SendCommandMIX(CMD_HF_MIFAREU_READBL, blockno, 0, 0, NULL, 0); PacketResponseNG resp; - got_pre = false; + if (use_data) { + SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, blockno, 0, 0, data, d_len); + bool got_written = false; + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + isOK = resp.oldarg[0] & 0xff; + if (isOK) { + got_written = true; + } + } + if (! got_written) { + PrintAndLogEx(FAILED, "Failed to write block BEFORE"); + error_retries++; + continue; // try again + } + } + + SendCommandMIX(CMD_HF_MIFAREU_READBL, blockno, 0, 0, NULL, 0); + + bool got_pre = false; if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { isOK = resp.oldarg[0] & 0xFF; if (isOK) { @@ -3209,9 +3235,13 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { got_pre = true; } } - + if (! got_pre) { + PrintAndLogEx(FAILED, "Failed to read block BEFORE"); + error_retries++; + continue; // try again + } clearCommandBuffer(); - SendCommandMIX(CMD_HF_MFU_OTP_TEAROFF, blockno, current, 0, teardata, 8); + SendCommandMIX(CMD_HF_MFU_OTP_TEAROFF, blockno, current, 0, teardata, sizeof(teardata)); // we be getting ACK that we are silently ignoring here.. @@ -3222,10 +3252,11 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { if (resp.status != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Tear off reporting failure to select tag"); + error_retries++; continue; } - got_post = false; + bool got_post = false; clearCommandBuffer(); SendCommandMIX(CMD_HF_MIFAREU_READBL, blockno, 0, 0, NULL, 0); if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { @@ -3235,55 +3266,53 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { got_post = true; } } + if (! got_post) { + PrintAndLogEx(FAILED, "Failed to read block BEFORE"); + error_retries++; + continue; // try again + } + error_retries = 0; + char prestr[20] = {0}; + snprintf(prestr, sizeof(prestr), "%s", sprint_hex_inrow(pre, sizeof(pre))); + char poststr[20] = {0}; + snprintf(poststr, sizeof(poststr), "%s", sprint_hex_inrow(post, sizeof(post))); - if (got_pre && got_post) { - - char prestr[20] = {0}; - snprintf(prestr, sizeof(prestr), "%s", sprint_hex_inrow(pre, sizeof(pre))); - char poststr[20] = {0}; - snprintf(poststr, sizeof(poststr), "%s", sprint_hex_inrow(post, sizeof(post))); - - if (memcmp(pre, post, sizeof(pre)) == 0) { - - PrintAndLogEx(INFO, "Current %02d (0x%02X) %s" - , blockno - , blockno - , poststr - ); - } else { - - // skip first message, since its the reset write. - if (current == start) { - PrintAndLogEx(INFO, "Inital write"); - } else { - PrintAndLogEx(INFO, _CYAN_("Tear off occured") " : %02d (0x%02X) %s vs " _RED_("%s") - , blockno - , blockno - , prestr - , poststr - ); - - lock_on = true; - - if (phase_clear == -1) - phase_clear = current; - - // new write phase must be atleast 100us later.. - if (phase_clear > -1 && phase_newwr == -1 && current > (phase_clear + 100)) - phase_newwr = current; - } - } - - if (use_match && memcmp(pre, match, sizeof(pre)) == 0) { - PrintAndLogEx(SUCCESS, "Block matches!\n"); - break; - } + if (memcmp(pre, post, sizeof(pre)) == 0) { + PrintAndLogEx(INFO, "Current : %02d (0x%02X) %s" + , blockno + , blockno + , poststr + ); } else { - if (got_pre == false) - PrintAndLogEx(FAILED, "Failed to read block BEFORE"); - if (got_post == false) - PrintAndLogEx(FAILED, "Failed to read block AFTER"); + PrintAndLogEx(INFO, _CYAN_("Tear off occurred") " : %02d (0x%02X) %s => " _RED_("%s") + , blockno + , blockno + , prestr + , poststr + ); + + lock_on = true; + + if ((phase_begin_clear == -1) && (bitcount32(*(uint32_t*)pre) > bitcount32(*(uint32_t*)post))) + phase_begin_clear = current; + + if ((phase_begin_clear > -1) && (phase_end_clear == -1) && (bitcount32(*(uint32_t*)post) == 0)) + phase_end_clear = current; + + if ((current == start) && (phase_end_clear > -1)) + skip_phase1 = true; + // new write phase must be atleast 100us later.. + if (((bitcount32(*(uint32_t*)pre) == 0) || (phase_end_clear > -1)) && (phase_begin_newwr == -1) && (bitcount32(*(uint32_t*)post) != 0) && (skip_phase1 || (current > (phase_end_clear + 100)))) + phase_begin_newwr = current; + + if ((phase_begin_newwr > -1) && (phase_end_newwr == -1) && (memcmp(post, teardata, sizeof(teardata)) == 0)) + phase_end_newwr = current; + } + + if (use_match && memcmp(post, match, sizeof(post)) == 0) { + PrintAndLogEx(SUCCESS, "Block matches stop condition!\n"); + break; } /* TEMPORALLY DISABLED @@ -3314,11 +3343,17 @@ static int CmdHF14AMfuOtpTearoff(const char *Cmd) { } PrintAndLogEx(INFO, "----------------------------------------------------"); - if (phase_clear > - 1) { - PrintAndLogEx(INFO, "New phase boundary around " _YELLOW_("%d") " us", phase_clear); + if ((phase_begin_clear > - 1) && (phase_begin_clear != start)) { + PrintAndLogEx(INFO, "Erase phase start boundary around " _YELLOW_("%5d") " us", phase_begin_clear); } - if (phase_newwr > - 1) { - PrintAndLogEx(INFO, "New phase boundary around " _YELLOW_("%d") " us", phase_newwr); + if ((phase_end_clear > - 1) && (phase_end_clear != start)){ + PrintAndLogEx(INFO, "Erase phase end boundary around " _YELLOW_("%5d") " us", phase_end_clear); + } + if (phase_begin_newwr > - 1) { + PrintAndLogEx(INFO, "Write phase start boundary around " _YELLOW_("%5d") " us", phase_begin_newwr); + } + if (phase_end_newwr > - 1) { + PrintAndLogEx(INFO, "Write phase end boundary around " _YELLOW_("%5d") " us", phase_end_newwr); } PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; diff --git a/include/common.h b/include/common.h index 3c6245e52..f0ba424c8 100644 --- a/include/common.h +++ b/include/common.h @@ -56,6 +56,10 @@ struct version_information { #define DBG_EXTENDED 4 // errors + info + debug + breaking debug messages extern int DBGLEVEL; +// tear-off +extern uint16_t tearoff_delay_us; +extern bool tearoff_enabled; + // reader voltage field detector #define MF_MINFIELDV 4000 From f2a0f3e272f6893cabf9e260b7251f7e39e78daa Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 7 Mar 2021 23:48:48 +0100 Subject: [PATCH 2/4] replace static countones & bitcount by utils in client --- client/src/cmdhficlass.c | 10 +--------- client/src/cmdlffdxb.c | 12 +----------- client/src/cmdlfnedap.c | 12 +----------- 3 files changed, 3 insertions(+), 31 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 2fda649b8..7225a443b 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -103,14 +103,6 @@ static inline uint32_t leadingzeros(uint64_t a) { #else return 0; #endif -} -static inline uint32_t countones(uint64_t a) { -#if defined __GNUC__ - return __builtin_popcountll(a); -#else - return 0; -#endif - } const char *card_types[] = { @@ -2034,7 +2026,7 @@ static int CmdHFiClass_ReadBlock(const char *Cmd) { uint64_t a = bytes_to_num(data, 8); bool starts = (leadingzeros(a) < 12); - bool ones = (countones(a) > 16 && countones(a) < 48); + bool ones = (bitcount64(a) > 16 && bitcount64(a) < 48); if (starts && ones) { PrintAndLogEx(INFO, "data looks encrypted, False Positives " _YELLOW_("ARE") " possible"); diff --git a/client/src/cmdlffdxb.c b/client/src/cmdlffdxb.c index fdead8ea9..4287db630 100644 --- a/client/src/cmdlffdxb.c +++ b/client/src/cmdlffdxb.c @@ -118,16 +118,6 @@ static void verify_values(uint64_t *animalid, uint32_t *countryid, uint32_t *ext } } -static inline uint32_t bitcount(uint32_t a) { -#if defined __GNUC__ - return __builtin_popcountl(a); -#else - a = a - ((a >> 1) & 0x55555555); - a = (a & 0x33333333) + ((a >> 2) & 0x33333333); - return (((a + (a >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24; -#endif -} - // FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits) // 8 databits + 1 parity (1) // CIITT 16 chksum @@ -594,7 +584,7 @@ int demodFDXB(bool verbose) { uint8_t bt_par = (extended & 0x100) >> 8; uint8_t bt_temperature = extended & 0xff; - uint8_t bt_calc_parity = (bitcount(bt_temperature) & 0x1) ? 0 : 1; + uint8_t bt_calc_parity = (bitcount32(bt_temperature) & 0x1) ? 0 : 1; uint8_t is_bt_temperature = (bt_calc_parity == bt_par) && !(extended & 0xe00) ; if (is_bt_temperature) { diff --git a/client/src/cmdlfnedap.c b/client/src/cmdlfnedap.c index 20cb5eec5..829a5b106 100644 --- a/client/src/cmdlfnedap.c +++ b/client/src/cmdlfnedap.c @@ -37,20 +37,10 @@ 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 -static inline uint32_t bitcount(uint32_t a) { -#if defined __GNUC__ - return __builtin_popcountl(a); -#else - a = a - ((a >> 1) & 0x55555555); - a = (a & 0x33333333) + ((a >> 2) & 0x33333333); - return (((a + (a >> 4)) & 0x0f0f0f0f) * 0x01010101) >> 24; -#endif -} - static uint8_t isEven_64_63(const uint8_t *data) { // 8 uint32_t tmp[2]; memcpy(tmp, data, 8); - return (bitcount(tmp[0]) + (bitcount(tmp[1] & 0xfeffffff))) & 1; + return (bitcount32(tmp[0]) + (bitcount32(tmp[1] & 0xfeffffff))) & 1; } //NEDAP demod - ASK/Biphase (or Diphase), RF/64 with preamble of 1111111110 (always a 128 bit data stream) From fd656541dd68ccf4c6edf978f3ae3930f47b98d0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 8 Mar 2021 00:28:38 +0100 Subject: [PATCH 3/4] fix lf t55xx wipe - calling write with correct params --- client/src/cmdlft55xx.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 7e86e1c78..11f397ca1 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -2939,35 +2939,36 @@ static int CmdT55xxWipe(const char *Cmd) { PrintAndLogEx(INFO, "Begin wiping..."); // Creating cmd string for write block :) - char writeData[36] = {0}; - char *ptrData = writeData; - snprintf(ptrData, sizeof(writeData), "-b 0 "); + char wcmd[36] = {0}; + char *pwcmd = wcmd; + + snprintf(pwcmd, sizeof(wcmd), "-b 0 "); if (usepwd) { - snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "p %08x ", password); + snprintf(pwcmd + strlen(wcmd), sizeof(wcmd) - strlen(wcmd), "-p %08x ", password); } - snprintf(ptrData + strlen(writeData), sizeof(writeData) - strlen(writeData), "d %08X", block0); + snprintf(pwcmd + strlen(wcmd), sizeof(wcmd) - strlen(wcmd), "-d %08X", block0); - if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) + if (CmdT55xxWriteBlock(pwcmd) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk 0"); for (uint8_t blk = 1; blk < 8; blk++) { - snprintf(ptrData, sizeof(writeData), "-b %d -d 0", blk); + snprintf(pwcmd, sizeof(wcmd), "-b %d -d 00000000", blk); - if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) + if (CmdT55xxWriteBlock(pwcmd) != PM3_SUCCESS) PrintAndLogEx(WARNING, "Warning: error writing blk %d", blk); - memset(writeData, 0x00, sizeof(writeData)); + memset(wcmd, 0x00, sizeof(wcmd)); } // Check and rest t55xx downlink mode. if (config.downlink_mode != T55XX_DLMODE_FIXED) { // Detect found a different mode so card must support - snprintf(ptrData, sizeof(writeData), "-b 3 --pg1 -d 00000000"); - if (CmdT55xxWriteBlock(ptrData) != PM3_SUCCESS) { + snprintf(pwcmd, sizeof(wcmd), "-b 3 --pg1 -d 00000000"); + if (CmdT55xxWriteBlock(pwcmd) != PM3_SUCCESS) { PrintAndLogEx(WARNING, "Warning: failed writing block 3 page 1 (config)"); } - memset(writeData, 0x00, sizeof(writeData)); + memset(wcmd, 0x00, sizeof(wcmd)); } return PM3_SUCCESS; } From 07422419946649779492357ea45a3bc37722cb33 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 8 Mar 2021 00:47:11 +0100 Subject: [PATCH 4/4] fix lf t55 config - bitrate and macros (thanks @mwalker33) --- client/src/cmdlft55xx.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index 11f397ca1..5c298e85b 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -447,7 +447,7 @@ static int CmdT55xxSetConfig(const char *Cmd) { arg_lit0(NULL, "st", "set/reset Sequence Terminator on"), arg_int0(NULL, "rate", "", "set bitrate <8|16|32|40|50|64|100|128>"), arg_str0("c", "blk0", "", "set configuration from a block0 (4 hex bytes)"), - arg_int0("o", "offset", "", "set offset, where data should start decode in bitstream"), + arg_int0("o", "offset", "<0-255>", "set offset, where data should start decode in bitstream "), }; uint8_t idx = 19; @@ -467,7 +467,8 @@ static int CmdT55xxSetConfig(const char *Cmd) { bool use_q5 = arg_get_lit(ctx, idx++); bool use_st = arg_get_lit(ctx, idx++); - int bitrate = arg_get_int_def(ctx, idx++, -1); + int bitrate = arg_get_int_def(ctx, idx, -1); + idx++; bool gotconf = false; uint32_t block0 = 0; @@ -481,7 +482,8 @@ static int CmdT55xxSetConfig(const char *Cmd) { gotconf = true; } - int offset = arg_get_int_def(ctx, idx++, -1); + int offset = arg_get_int_def(ctx, idx, -1); + idx++; bool r0 = arg_get_lit(ctx, idx++); bool r1 = arg_get_lit(ctx, idx++); @@ -519,7 +521,7 @@ static int CmdT55xxSetConfig(const char *Cmd) { } // validate user specified offset - if (offset > -1) { + if (offset > -1 && offset < 0x100) { config.offset = offset; } @@ -2941,7 +2943,7 @@ static int CmdT55xxWipe(const char *Cmd) { // Creating cmd string for write block :) char wcmd[36] = {0}; char *pwcmd = wcmd; - + snprintf(pwcmd, sizeof(wcmd), "-b 0 "); if (usepwd) {