diff --git a/armsrc/appmain.c b/armsrc/appmain.c
index 7c483f2e1..b778fa785 100644
--- a/armsrc/appmain.c
+++ b/armsrc/appmain.c
@@ -1032,7 +1032,13 @@ static void PacketReceived(PacketCommandNG *packet) {
             break;
         }
         case CMD_HF_MIFARE_READER: {
-            ReaderMifare(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]);
+            struct p {
+                uint8_t first_run;
+                uint8_t blockno;
+                uint8_t key_type;
+            } PACKED;
+            struct p *payload = (struct p *) packet->data.asBytes;
+            ReaderMifare(payload->first_run, payload->blockno, payload->key_type);
             break;
         }
         case CMD_HF_MIFARE_READBL: {
diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c
index 348317a8a..81bada416 100644
--- a/armsrc/iso14443a.c
+++ b/armsrc/iso14443a.c
@@ -2791,6 +2791,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
     static uint8_t par_low = 0;
     static uint8_t mf_nr_ar3 = 0;
 
+    int return_status = PM3_SUCCESS;
+
     AddCrc14A(mf_auth, 2);
 
     if (first_try) {
@@ -2807,6 +2809,7 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
     }
 
     LED_C_ON();
+    uint16_t checkbtn_cnt = 0;
     uint16_t i;
     for (i = 0; true; ++i) {
 
@@ -2815,10 +2818,15 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
         WDT_HIT();
 
         // Test if the action was cancelled
-        if (BUTTON_PRESS()) {
-            isOK = -1;
-            break;
+        if (checkbtn_cnt == 2000) {
+            if (BUTTON_PRESS() || data_available()) {
+                isOK = -1;
+                return_status = PM3_EOPABORTED;
+                break;
+            }
+            checkbtn_cnt = 0;
         }
+        ++checkbtn_cnt;
 
         // this part is from Piwi's faster nonce collecting part in Hardnested.
         if (!have_uid) { // need a full select cycle to get the uid first
@@ -2876,8 +2884,16 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
         ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
 
         // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
-        if (ReaderReceive(receivedAnswer, receivedAnswerPar))
+        int resp_res = ReaderReceive(receivedAnswer, receivedAnswerPar);
+        if (resp_res == 1)
             received_nack = true;
+        else if (resp_res == 4) {
+            // did we get lucky and got our dummykey to be valid?
+            // however we dont feed key w uid it the prng..
+            isOK = -6;
+            break;
+        }
+
 
         // we didn't calibrate our clock yet,
         // iceman: has to be calibrated every time.
@@ -3000,26 +3016,36 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype) {
 
     if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Number of sent auth requests: %u", i);
 
-    uint8_t buf[32] = {0x00};
-    memset(buf, 0x00, sizeof(buf));
-    num_to_bytes(cuid, 4, buf);
-    num_to_bytes(nt, 4, buf + 4);
-    memcpy(buf + 8,  par_list, 8);
-    memcpy(buf + 16, ks_list, 8);
-    memcpy(buf + 24, mf_nr_ar, 8);
+    struct {
+        int32_t isOK;
+        uint8_t cuid[4];
+        uint8_t nt[4];
+        uint8_t par_list[8];
+        uint8_t ks_list[8];
+        uint8_t nr[4];
+        uint8_t ar[4];
+    } PACKED payload;
 
-    reply_mix(CMD_ACK, isOK, 0, 0, buf, sizeof(buf));
+    payload.isOK = isOK;
+    num_to_bytes(cuid, 4, payload.cuid);
+    num_to_bytes(nt, 4, payload.nt);
+    memcpy(payload.par_list, par_list, sizeof(payload.par_list));
+    memcpy(payload.ks_list, ks_list, sizeof(payload.ks_list));
+    memcpy(payload.nr, mf_nr_ar, sizeof(payload.nr));
+    memcpy(payload.ar, mf_nr_ar + 4, sizeof(payload.ar));
+
+    reply_ng(CMD_HF_MIFARE_READER, return_status, (uint8_t*)&payload, sizeof(payload));
 
     hf_field_off();
     set_tracing(false);
 }
 
 /*
-*  Mifare Classic NACK-bug detection
-*  Thanks to @doegox for the feedback and new approaches.
+ * Mifare Classic NACK-bug detection
+ * Thanks to @doegox for the feedback and new approaches.
 */
 void DetectNACKbug(void) {
-    uint8_t mf_auth[]     = {0x60, 0x00, 0xF5, 0x7B};
+    uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B};
     uint8_t mf_nr_ar[]    = {0, 0, 0, 0, 0, 0, 0, 0};
     uint8_t uid[10]       = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
@@ -3050,6 +3076,8 @@ void DetectNACKbug(void) {
     sync_time = GetCountSspClk() & 0xfffffff8;
 
     LED_C_ON();
+    uint16_t checkbtn_cnt = 0;
+
     uint16_t i;
     for (i = 1; true; ++i) {
 
@@ -3064,10 +3092,14 @@ void DetectNACKbug(void) {
         WDT_HIT();
 
         // Test if the action was cancelled
-        if (BUTTON_PRESS() || data_available()) {
-            status = PM3_EOPABORTED;
-            break;
+        if (checkbtn_cnt == 2000) {
+            if (BUTTON_PRESS() || data_available()) {
+                status = PM3_EOPABORTED;
+                break;
+            }
+            checkbtn_cnt = 0;
         }
+        ++checkbtn_cnt;
 
         // this part is from Piwi's faster nonce collecting part in Hardnested.
         if (!have_uid) { // need a full select cycle to get the uid first
@@ -3127,10 +3159,11 @@ void DetectNACKbug(void) {
         // Transmit reader nonce with fake par
         ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
 
+        // Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
         if (ReaderReceive(receivedAnswer, receivedAnswerPar)) {
             received_nack = true;
             num_nacks++;
-            // ALWAYS leak Detection.
+            // ALWAYS leak Detection. Well, we could be lucky and get a response nack on first try.
             if (i == num_nacks) {
                 continue;
             }
@@ -3247,7 +3280,6 @@ void DetectNACKbug(void) {
     num_to_bytes(i, 2, data + 2);
     reply_ng(CMD_HF_MIFARE_NACK_DETECT, status, data, 4);
 
-    //reply_mix(CMD_ACK, isOK, num_nacks, i, 0, 0);
     BigBuf_free();
     hf_field_off();
     set_tracing(false);
diff --git a/client/cmddata.c b/client/cmddata.c
index 2e28eeb03..e55b34909 100644
--- a/client/cmddata.c
+++ b/client/cmddata.c
@@ -532,7 +532,7 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType,
         invert = 1;
         clk = 0;
     }
-    uint8_t *bits =  calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t));
+    uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t));
     if (bits == NULL) {
         return PM3_EMALLOC;
     }
@@ -1119,13 +1119,13 @@ int FSKrawDemod(const char *Cmd, bool verbose) {
     if (bits == NULL) {
         return PM3_EMALLOC;
     }
-    
+
     size_t BitLen = getFromGraphBuf(bits);
     if (BitLen == 0) {
         free(bits);
         return PM3_ESOFT;
     }
-    
+
     //get field clock lengths
     if (!fchigh || !fclow) {
         uint16_t fcs = countFC(bits, BitLen, true);
@@ -2243,7 +2243,7 @@ static command_t CommandTable[] = {
     {"tune",            CmdTuneSamples,          IfPm3Present,    "Get hw tune samples for graph window"},
     {"undec",           CmdUndec,                AlwaysAvailable, "Un-decimate samples by 2"},
     {"zerocrossings",   CmdZerocrossings,        AlwaysAvailable, "Count time between zero-crossings"},
-    {"iir",             CmdDataIIR,              IfPm3Present,    "apply IIR buttersworth filter on plotdata"},
+    {"iir",             CmdDataIIR,              AlwaysAvailable,    "apply IIR buttersworth filter on plotdata"},
     {NULL, NULL, NULL, NULL}
 };
 
diff --git a/client/cmdhw.c b/client/cmdhw.c
index c363fdc25..a6f242b8f 100644
--- a/client/cmdhw.c
+++ b/client/cmdhw.c
@@ -467,10 +467,14 @@ static int CmdSetMux(const char *Cmd) {
     str_lower((char *)Cmd);
 
     uint8_t arg = 0;
-    if (strcmp(Cmd, "lopkd") == 0)      arg = 0;
-    else if (strcmp(Cmd, "loraw") == 0) arg = 1;
-    else if (strcmp(Cmd, "hipkd") == 0) arg = 2;
-    else if (strcmp(Cmd, "hiraw") == 0) arg = 3;
+    if (strcmp(Cmd, "lopkd") == 0)
+        arg = 0;
+    else if (strcmp(Cmd, "loraw") == 0)
+        arg = 1;
+    else if (strcmp(Cmd, "hipkd") == 0)
+        arg = 2;
+    else if (strcmp(Cmd, "hiraw") == 0)
+        arg = 3;
     else {
         usage_hw_setmux();
         return PM3_EINVARG;
@@ -570,8 +574,6 @@ static int CmdConnect(const char *Cmd) {
         memcpy(port, conn.serial_port_name, sizeof(port));
     }
 
-    printf("Port:: %s  Baud:: %u\n", port, baudrate);
-
     if (session.pm3_present) {
         CloseProxmark();
     }
@@ -582,14 +584,15 @@ static int CmdConnect(const char *Cmd) {
     if (session.pm3_present && (TestProxmark() != PM3_SUCCESS)) {
         PrintAndLogEx(ERR, _RED_("ERROR:") "cannot communicate with the Proxmark3\n");
         CloseProxmark();
+        return PM3_ENOTTY;
     }
     return PM3_SUCCESS;
 }
 
 static command_t CommandTable[] = {
     {"help",          CmdHelp,        AlwaysAvailable, "This help"},
-    {"dbg",           CmdDbg,         IfPm3Present,    "Set Proxmark3 debug level"},
     {"connect",       CmdConnect,     AlwaysAvailable, "connect Proxmark3 to serial port"},
+    {"dbg",           CmdDbg,         IfPm3Present,    "Set Proxmark3 debug level"},
     {"detectreader",  CmdDetectReader, IfPm3Present,    "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"},
     {"fpgaoff",       CmdFPGAOff,     IfPm3Present,    "Set FPGA off"},
     {"lcd",           CmdLCD,         IfPm3Lcd,        "<HEX command> <count> -- Send command/data to LCD"},
@@ -690,14 +693,22 @@ void pm3_version(bool verbose, bool oneliner) {
         PrintAndLogEx(NORMAL, "\n [ CLIENT ]");
         PrintAndLogEx(NORMAL, "  client: RRG/Iceman"); // TODO version info?
         PrintAndLogEx(NORMAL, "  compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH);
-        PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 ]");
-        PrintAndLogEx(NORMAL, "  external flash:                  %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
-        PrintAndLogEx(NORMAL, "  smartcard reader:                %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent"));
-        PrintAndLogEx(NORMAL, "\n [ PROXMARK RDV4 Extras ]");
-        PrintAndLogEx(NORMAL, "  FPC USART for BT add-on support: %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent"));
 
-        if (IfPm3FpcUsartDevFromUsb())
-            PrintAndLogEx(NORMAL, "  FPC USART for developer support: %s", _GREEN_("present"));
+//#if PLATFORM == PM3RDV4
+        if ( IfPm3Flash() == false && IfPm3Smartcard() == false && IfPm3FpcUsartHost() == false) {
+            PrintAndLogEx(NORMAL, "\n [ PROXMARK3 ]");
+        } else {
+            PrintAndLogEx(NORMAL, "\n [ PROXMARK3 RDV4 ]");
+            PrintAndLogEx(NORMAL, "  external flash:                  %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
+            PrintAndLogEx(NORMAL, "  smartcard reader:                %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent"));
+            PrintAndLogEx(NORMAL, "\n [ PROXMARK3 RDV4 Extras ]");
+            PrintAndLogEx(NORMAL, "  FPC USART for BT add-on support: %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent"));
+
+            if (IfPm3FpcUsartDevFromUsb()) {
+                PrintAndLogEx(NORMAL, "  FPC USART for developer support: %s", _GREEN_("present"));
+            }
+        }
+//#endif
 
         PrintAndLogEx(NORMAL, "");
 
diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c
index 85529609d..992eabdd8 100644
--- a/client/cmdlffdx.c
+++ b/client/cmdlffdx.c
@@ -264,12 +264,7 @@ static int CmdFdxRead(const char *Cmd) {
 static int CmdFdxClone(const char *Cmd) {
 
     uint32_t countryid = 0;
-    uint64_t animalid = 0;
-    uint32_t blocks[5] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0, 0};
-    uint8_t bits[128];
-    uint8_t *bs = bits;
-    memset(bs, 0, sizeof(bits));
-
+    uint64_t animalid = 0;    
     char cmdp = param_getchar(Cmd, 0);
     if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_fdx_clone();
 
@@ -278,63 +273,32 @@ static int CmdFdxClone(const char *Cmd) {
 
     verify_values(countryid, animalid);
 
-    // getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits)
-    if (getFDXBits(animalid, countryid, 1, 0, 0, bs) != PM3_SUCCESS) {
+    uint8_t *bits = calloc(128, sizeof(uint8_t));
+
+    if (getFDXBits(animalid, countryid, 1, 0, 0, bits) != PM3_SUCCESS) {
         PrintAndLogEx(ERR, "Error with tag bitstream generation.");
+        free(bits);
         return PM3_ESOFT;
     }
 
+    uint32_t blocks[5] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0, 0};
+    
     //Q5
     if (param_getchar(Cmd, 2) == 'Q' || param_getchar(Cmd, 2) == 'q')
         blocks[0] = T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(32) | 4 << T5555_MAXBLOCK_SHIFT;
 
     // convert from bit stream to block data
-    blocks[1] = bytebits_to_byte(bs, 32);
-    blocks[2] = bytebits_to_byte(bs + 32, 32);
-    blocks[3] = bytebits_to_byte(bs + 64, 32);
-    blocks[4] = bytebits_to_byte(bs + 96, 32);
+    blocks[1] = bytebits_to_byte(bits, 32);
+    blocks[2] = bytebits_to_byte(bits + 32, 32);
+    blocks[3] = bytebits_to_byte(bits + 64, 32);
+    blocks[4] = bytebits_to_byte(bits + 96, 32);
 
+    free(bits);
+    
     PrintAndLogEx(INFO, "Preparing to clone FDX-B to T55x7 with animal ID: %04u-%"PRIu64, countryid, animalid);
-    print_blocks(blocks, 5);
+    print_blocks(blocks,  ARRAYLEN(blocks));
 
-    uint8_t res = 0;
-    PacketResponseNG resp;
-
-    // fast push mode
-    conn.block_after_ACK = true;
-    for (int i = 4; i >= 0; --i) {
-        if (i == 0) {
-            // Disable fast mode on last packet
-            conn.block_after_ACK = false;
-        }
-        clearCommandBuffer();
-
-        t55xx_write_block_t ng;
-        ng.data = blocks[i];
-        ng.pwd = 0;
-        ng.blockno = i;
-        ng.flags = 0;
-
-        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
-        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
-            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
-            return PM3_ETIMEOUT;
-        }
-
-        if (i == 0) {
-            SetConfigWithBlock0(blocks[0]);
-            if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
-                continue;
-        }
-
-        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
-            res++;
-    }
-
-    if (res == 0)
-        PrintAndLogEx(SUCCESS, "Success writing to tag");
-
-    return PM3_SUCCESS;
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 }
 
 static int CmdFdxSim(const char *Cmd) {
diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c
index fe00d1187..366fe77e3 100644
--- a/client/cmdlfguard.c
+++ b/client/cmdlfguard.c
@@ -14,6 +14,7 @@
 #include <stdlib.h>
 #include <ctype.h>
 
+#include "commonutil.h"     // ARRAYLEN
 #include "cmdparser.h"    // command_t
 #include "comms.h"
 #include "ui.h"
@@ -156,20 +157,20 @@ static int CmdGuardClone(const char *Cmd) {
     if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_guard_clone();
 
     uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
-    uint8_t bs[96];
-    memset(bs, 0x00, sizeof(bs));
-
-    //GuardProxII - compat mode, ASK/Biphase,  data rate 64, 3 data blocks
-    uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
 
     if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone();
-
+    
     fmtlen &= 0x7f;
     facilitycode = (fc & 0x000000FF);
     cardnumber = (cn & 0x0000FFFF);
 
+    //GuardProxII - compat mode, ASK/Biphase,  data rate 64, 3 data blocks
+    uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
+    uint8_t *bs = calloc(96, sizeof(uint8_t));
+    
     if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) {
         PrintAndLogEx(ERR, "Error with tag bitstream generation.");
+        free(bs);
         return PM3_ESOFT;
     }
 
@@ -181,47 +182,12 @@ static int CmdGuardClone(const char *Cmd) {
     blocks[2] = bytebits_to_byte(bs + 32, 32);
     blocks[3] = bytebits_to_byte(bs + 64, 32);
 
+    free(bs);
+    
     PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber);
-    print_blocks(blocks, 4);
+    print_blocks(blocks,  ARRAYLEN(blocks));
 
-    uint8_t res = 0;
-    PacketResponseNG resp;
-
-    // fast push mode
-    conn.block_after_ACK = true;
-    for (uint8_t i = 0; i < 4; i++) {
-        if (i == 3) {
-            // Disable fast mode on last packet
-            conn.block_after_ACK = false;
-        }
-        clearCommandBuffer();
-
-        t55xx_write_block_t ng;
-        ng.data = blocks[i];
-        ng.pwd = 0;
-        ng.blockno = i;
-        ng.flags = 0;
-
-        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
-        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
-            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
-            return PM3_ETIMEOUT;
-        }
-
-        if (i == 0) {
-            SetConfigWithBlock0(blocks[0]);
-            if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
-                continue;
-        }
-
-        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
-            res++;
-    }
-
-    if (res == 0)
-        PrintAndLogEx(SUCCESS, "Success writing to tag");
-
-    return PM3_SUCCESS;
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 }
 
 static int CmdGuardSim(const char *Cmd) {
diff --git a/client/cmdlfhid.h b/client/cmdlfhid.h
index 2b61861ff..5ae2d7753 100644
--- a/client/cmdlfhid.h
+++ b/client/cmdlfhid.h
@@ -16,6 +16,5 @@
 int CmdLFHID(const char *Cmd);
 
 int demodHID(void);
-//void calc26(uint16_t fc, uint32_t cardno, uint8_t *out);
-void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, uint8_t oem);
+
 #endif
diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c
index 673ed1438..eae80564d 100644
--- a/client/cmdlfindala.c
+++ b/client/cmdlfindala.c
@@ -505,43 +505,7 @@ static int CmdIndalaClone(const char *Cmd) {
 
     print_blocks(blocks, max);
 
-    uint8_t res = 0;
-    PacketResponseNG resp;
-
-    // fast push mode
-    conn.block_after_ACK = true;
-    for (uint8_t i = 0; i < max; i++) {
-        if (i == max - 1) {
-            // Disable fast mode on last packet
-            conn.block_after_ACK = false;
-        }
-        clearCommandBuffer();
-        t55xx_write_block_t ng;
-        ng.data = blocks[i];
-        ng.pwd = 0;
-        ng.blockno = i;
-        ng.flags = 0;
-
-        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
-        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
-            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
-            return PM3_ETIMEOUT;
-        }
-
-        if (i == 0) {
-            SetConfigWithBlock0(blocks[0]);
-            if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
-                continue;
-        }
-
-        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
-            res++;
-    }
-
-    if (res == 0)
-        PrintAndLogEx(SUCCESS, "Success writing to tag");
-
-    return PM3_SUCCESS;
+    return clone_t55xx_tag(blocks, max);
 }
 
 static command_t CommandTable[] = {
diff --git a/client/cmdlfio.c b/client/cmdlfio.c
index e17ae82d1..74a9ef92d 100644
--- a/client/cmdlfio.c
+++ b/client/cmdlfio.c
@@ -16,6 +16,7 @@
 
 #include <ctype.h>
 
+#include "commonutil.h"     //ARRAYLEN
 #include "cmdparser.h"    // command_t
 #include "comms.h"
 #include "graph.h"
@@ -272,45 +273,9 @@ static int CmdIOProxClone(const char *Cmd) {
     blocks[2] = bytebits_to_byte(bits + 32, 32);
 
     PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn);
-    print_blocks(blocks, 3);
+    print_blocks(blocks,  ARRAYLEN(blocks));
 
-    uint8_t res = 0;
-    PacketResponseNG resp;
-
-    // fast push mode
-    conn.block_after_ACK = true;
-    for (uint8_t i = 0; i < 3; i++) {
-        if (i == 2) {
-            // Disable fast mode on last packet
-            conn.block_after_ACK = false;
-        }
-        clearCommandBuffer();
-        t55xx_write_block_t ng;
-        ng.data = blocks[i];
-        ng.pwd = 0;
-        ng.blockno = i;
-        ng.flags = 0;
-
-        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
-        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
-            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
-            return PM3_ETIMEOUT;
-        }
-
-        if (i == 0) {
-            SetConfigWithBlock0(blocks[0]);
-            if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
-                continue;
-        }
-
-        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
-            res++;
-    }
-
-    if (res == 0)
-        PrintAndLogEx(SUCCESS, "Success writing to tag");
-
-    return PM3_SUCCESS;
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 }
 
 static command_t CommandTable[] = {
diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c
index 13a1d6e1f..d2a0d9967 100644
--- a/client/cmdlfjablotron.c
+++ b/client/cmdlfjablotron.c
@@ -18,7 +18,7 @@
 
 #include "cmdparser.h"    // command_t
 #include "comms.h"
-#include "commonutil.h"
+#include "commonutil.h" // ARRAYLEN
 #include "ui.h"
 #include "cmddata.h"
 #include "cmdlf.h"
@@ -169,46 +169,9 @@ static int CmdJablotronClone(const char *Cmd) {
     blocks[2] = bytebits_to_byte(bits + 32, 32);
 
     PrintAndLogEx(INFO, "Preparing to clone Jablotron to T55x7 with FullCode: %"PRIx64, fullcode);
-    print_blocks(blocks, 3);
+    print_blocks(blocks,  ARRAYLEN(blocks));
 
-    uint8_t res = 0;
-    PacketResponseNG resp;
-
-    // fast push mode
-    conn.block_after_ACK = true;
-    for (uint8_t i = 0; i < 3; i++) {
-        if (i == 2) {
-            // Disable fast mode on last packet
-            conn.block_after_ACK = false;
-        }
-        clearCommandBuffer();
-
-        t55xx_write_block_t ng;
-        ng.data = blocks[i];
-        ng.pwd = 0;
-        ng.blockno = i;
-        ng.flags = 0;
-
-        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
-        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
-            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
-            return PM3_ETIMEOUT;
-        }
-
-        if (i == 0) {
-            SetConfigWithBlock0(blocks[0]);
-            if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
-                continue;
-        }
-
-        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
-            res++;
-    }
-
-    if (res == 0)
-        PrintAndLogEx(SUCCESS, "Success writing to tag");
-
-    return PM3_SUCCESS;
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 }
 
 static int CmdJablotronSim(const char *Cmd) {
diff --git a/client/cmdlfkeri.c b/client/cmdlfkeri.c
index 49d3c2a33..e36388041 100644
--- a/client/cmdlfkeri.c
+++ b/client/cmdlfkeri.c
@@ -15,6 +15,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 
+#include "commonutil.h"     // ARRAYLEN
 #include "cmdparser.h"    // command_t
 #include "comms.h"
 #include "ui.h"
@@ -155,49 +156,12 @@ static int CmdKeriClone(const char *Cmd) {
     uint64_t data = ((uint64_t)internalid << 3) + 7;
     PrintAndLogEx(INFO, "Preparing to clone KERI to T55x7 with Internal Id: %" PRIx64, internalid);
 
-    //
     blocks[1] = data >> 32;
     blocks[2] = data & 0xFFFFFFFF;
-    print_blocks(blocks, 3);
 
-    uint8_t res = 0;
-    PacketResponseNG resp;
+    print_blocks(blocks,  ARRAYLEN(blocks));
 
-    // fast push mode
-    conn.block_after_ACK = true;
-    for (uint8_t i = 0; i < 3; i++) {
-        if (i == 2) {
-            // Disable fast mode on last packet
-            conn.block_after_ACK = false;
-        }
-        clearCommandBuffer();
-
-        t55xx_write_block_t ng;
-        ng.data = blocks[i];
-        ng.pwd = 0;
-        ng.blockno = i;
-        ng.flags = 0;
-
-        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
-        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
-            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
-            return PM3_ETIMEOUT;
-        }
-
-        if (i == 0) {
-            SetConfigWithBlock0(blocks[0]);
-            if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
-                continue;
-        }
-
-        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
-            res++;
-    }
-
-    if (res == 0)
-        PrintAndLogEx(SUCCESS, "Success writing to tag");
-
-    return PM3_SUCCESS;
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 }
 
 static int CmdKeriSim(const char *Cmd) {
diff --git a/client/cmdlfnedap.c b/client/cmdlfnedap.c
index b186a1354..cab5e55c6 100644
--- a/client/cmdlfnedap.c
+++ b/client/cmdlfnedap.c
@@ -9,6 +9,19 @@
 
 #include "cmdlfnedap.h"
 
+#include <string.h>
+
+#include <ctype.h>
+#include <stdlib.h>
+#include "cmdparser.h"    // command_t
+#include "comms.h"
+#include "crc16.h"
+#include "cmdlft55xx.h" // verifywrite
+#include "ui.h"
+#include "cmddata.h"
+#include "cmdlf.h"
+#include "lfdemod.h"
+
 #define FIXED_71    0x71
 #define FIXED_40    0x40
 #define UNKNOWN_A   0x00
@@ -431,7 +444,7 @@ int CmdLFNedapClone(const char *Cmd) {
         return PM3_ESOFT;
     }
 
-    CmdPrintDemodBuff("x");
+    //CmdPrintDemodBuff("x");
 
 // What we had before in commented code:
     //NEDAP - compat mode, ASK/DIphase, data rate 64, 4 data blocks
@@ -455,47 +468,14 @@ int CmdLFNedapClone(const char *Cmd) {
     PrintAndLogEx(SUCCESS, "Preparing to clone NEDAP to T55x7");
     print_blocks(blocks, max);
 
-    uint8_t res = 0;
-    PacketResponseNG resp;
-
-    // fast push mode
-    conn.block_after_ACK = true;
-    for (uint8_t i = 0; i < max; i++) {
-        if (i == max - 1) {
-            // Disable fast mode on last packet
-            conn.block_after_ACK = false;
-        }
-        clearCommandBuffer();
-        t55xx_write_block_t ng;
-        ng.data = blocks[i];
-        ng.pwd = 0;
-        ng.blockno = i;
-        ng.flags = 0;
-
-        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
-        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
-            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
-            return PM3_ETIMEOUT;
-        }
-
-        if (i == 0) {
-            SetConfigWithBlock0(blocks[0]);
-            if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
-                continue;
-        }
-
-        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
-            res++;
-    }
-
-    if (res == 0)
-        PrintAndLogEx(SUCCESS, "Success writing to tag");
-    else {
-        PrintAndLogEx(NORMAL, "");
+    int res = clone_t55xx_tag(blocks, max);
+    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`"));
+    } else {
+        PrintAndLogEx(NORMAL, "");
     }
-    return PM3_SUCCESS;
+    return res;
 }
 
 static int CmdLFNedapSim(const char *Cmd) {
diff --git a/client/cmdlfnedap.h b/client/cmdlfnedap.h
index 74fdd30fb..fda0e130e 100644
--- a/client/cmdlfnedap.h
+++ b/client/cmdlfnedap.h
@@ -11,19 +11,6 @@
 
 #include "common.h"
 
-#include <string.h>
-
-#include <ctype.h>
-#include <stdlib.h>
-#include "cmdparser.h"    // command_t
-#include "comms.h"
-#include "crc16.h"
-#include "cmdlft55xx.h" // verifywrite
-#include "ui.h"
-#include "cmddata.h"
-#include "cmdlf.h"
-#include "lfdemod.h"
-
 int CmdLFNedap(const char *Cmd);
 
 int demodNedap(void);
diff --git a/client/cmdlfnexwatch.c b/client/cmdlfnexwatch.c
index 5a5e127b1..d4069547b 100644
--- a/client/cmdlfnexwatch.c
+++ b/client/cmdlfnexwatch.c
@@ -9,16 +9,33 @@
 //-----------------------------------------------------------------------------
 
 #include "cmdlfnexwatch.h"
+#include <ctype.h>          // tolower
 
+#include "commonutil.h"     // ARRAYLEN
 #include "cmdparser.h"    // command_t
 #include "comms.h"
 #include "ui.h"
 #include "cmddata.h" // preamblesearch
 #include "cmdlf.h"
 #include "lfdemod.h"
+#include "protocols.h"  // t55xx defines
+#include "cmdlft55xx.h" // clone..
 
 static int CmdHelp(const char *Cmd);
 
+static int usage_lf_nexwatch_clone(void) {
+    PrintAndLogEx(NORMAL, "clone a Nexwatch tag to a T55x7 tag.");
+    PrintAndLogEx(NORMAL, "");
+    PrintAndLogEx(NORMAL, "Usage: lf nexwatch clone [h] [b <raw hex>]");
+    PrintAndLogEx(NORMAL, "Options:");
+    PrintAndLogEx(NORMAL, "  h               : this help");
+    PrintAndLogEx(NORMAL, "  b <raw hex>     : raw hex data. 12 bytes max");
+    PrintAndLogEx(NORMAL, "");
+    PrintAndLogEx(NORMAL, "Examples:");
+    PrintAndLogEx(NORMAL, "       lf nexwatch clone b 5600000000213C9F8F150C0000000000");
+    return PM3_SUCCESS;
+}
+
 static int CmdNexWatchDemod(const char *Cmd) {
     (void)Cmd; // Cmd is not used so far
 
@@ -37,7 +54,7 @@ static int CmdNexWatchDemod(const char *Cmd) {
         // else if (idx == -3)
         // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch problem during PSK demod");
         else if (idx == -4)
-            PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch preamble not found");
+            PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch preamble not found"); 
         // else if (idx == -5)
         // PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch size not correct: %d", size);
         else
@@ -47,7 +64,7 @@ static int CmdNexWatchDemod(const char *Cmd) {
     }
 
     setDemodBuff(DemodBuffer, size, idx + 4);
-    setClockGrid(g_DemodClock, g_DemodStartIdx + ((idx + 4)*g_DemodClock));
+    setClockGrid(g_DemodClock, g_DemodStartIdx + ((idx + 4) * g_DemodClock));
 
 //    idx = 8 + 32; // 8 = preamble, 32 = reserved bits (always 0)
 
@@ -82,10 +99,47 @@ static int CmdNexWatchRead(const char *Cmd) {
 }
 
 static int CmdNexWatchClone(const char *Cmd) {
+    
+    // 56000000 00213C9F 8F150C00 00000000
+    uint32_t blocks[5];
+    bool errors = false;
+    uint8_t cmdp = 0;
+    int datalen = 0;
+
+    while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
+        switch (tolower(param_getchar(Cmd, cmdp))) {
+            case 'h':
+                return usage_lf_nexwatch_clone();
+            case 'b': {
+                // skip first block,  4*4 = 16 bytes left
+                uint8_t rawhex[16] = {0}; 
+                int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen);
+                if ( res != 0 )
+                    errors = true;
+                
+                for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
+                    blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t));
+                }
+                cmdp += 2;
+                break;
+            }
+            default:
+                PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+                errors = true;
+                break;
+        }
+    }
+
+    if (errors || cmdp == 0) return usage_lf_nexwatch_clone();
+
+    //Nexwatch - compat mode, PSK, data rate 40, 3 data blocks
+    blocks[0] = T55x7_MODULATION_PSK1 | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT;
+
+    PrintAndLogEx(INFO, "Preparing to clone NexWatch to T55x7 with raw hex");
+    print_blocks(blocks,  ARRAYLEN(blocks));
+
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 
-    // should be able to clone the raw hex.
-    PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
-    return PM3_SUCCESS;
 }
 
 static int CmdNexWatchSim(const char *Cmd) {
diff --git a/client/cmdlfnoralsy.c b/client/cmdlfnoralsy.c
index fe469720b..9cec6767e 100644
--- a/client/cmdlfnoralsy.c
+++ b/client/cmdlfnoralsy.c
@@ -9,6 +9,20 @@
 //-----------------------------------------------------------------------------
 #include "cmdlfnoralsy.h"
 
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "commonutil.h"     // ARRAYLEN
+#include "cmdparser.h"    // command_t
+#include "comms.h"
+#include "ui.h"
+#include "cmddata.h"
+#include "cmdlf.h"
+#include "protocols.h"  // for T55xx config register definitions
+#include "lfdemod.h"    // parityTest
+#include "cmdlft55xx.h" // verifywrite
+
 static int CmdHelp(const char *Cmd);
 
 static int usage_lf_noralsy_clone(void) {
@@ -128,8 +142,7 @@ static int CmdNoralsyClone(const char *Cmd) {
     uint16_t year = 0;
     uint32_t id = 0;
     uint32_t blocks[4] = {T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | T55x7_ST_TERMINATOR | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0};
-    uint8_t bits[96];
-    memset(bits, 0, sizeof(bits));
+    uint8_t *bits = calloc(96, sizeof(uint8_t));
 
     char cmdp = tolower(param_getchar(Cmd, 0));
     if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_noralsy_clone();
@@ -146,52 +159,16 @@ static int CmdNoralsyClone(const char *Cmd) {
         return PM3_ESOFT;
     }
 
-    //
     blocks[1] = bytebits_to_byte(bits, 32);
     blocks[2] = bytebits_to_byte(bits + 32, 32);
     blocks[3] = bytebits_to_byte(bits + 64, 32);
 
+    free(bits);
+    
     PrintAndLogEx(INFO, "Preparing to clone Noralsy to T55x7 with CardId: %u", id);
-    print_blocks(blocks, 4);
+    print_blocks(blocks,  ARRAYLEN(blocks));
 
-    uint8_t res = 0;
-    PacketResponseNG resp;
-
-    // fast push mode
-    conn.block_after_ACK = true;
-    for (uint8_t i = 0; i < 4; i++) {
-        if (i == 3) {
-            // Disable fast mode on last packet
-            conn.block_after_ACK = false;
-        }
-        clearCommandBuffer();
-        t55xx_write_block_t ng;
-        ng.data = blocks[i];
-        ng.pwd = 0;
-        ng.blockno = i;
-        ng.flags = 0;
-
-        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
-        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
-            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
-            return PM3_ETIMEOUT;
-        }
-
-        if (i == 0) {
-            SetConfigWithBlock0(blocks[0]);
-            if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
-                continue;
-        }
-
-        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
-            res++;
-    }
-
-    if (res == 0)
-        PrintAndLogEx(SUCCESS, "Success writing to tag");
-
-    return PM3_SUCCESS;
-}
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));}
 
 static int CmdNoralsySim(const char *Cmd) {
 
diff --git a/client/cmdlfnoralsy.h b/client/cmdlfnoralsy.h
index 56ae31372..f76accab7 100644
--- a/client/cmdlfnoralsy.h
+++ b/client/cmdlfnoralsy.h
@@ -11,19 +11,6 @@
 
 #include "common.h"
 
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include "cmdparser.h"    // command_t
-#include "comms.h"
-#include "ui.h"
-#include "cmddata.h"
-#include "cmdlf.h"
-#include "protocols.h"  // for T55xx config register definitions
-#include "lfdemod.h"    // parityTest
-#include "cmdlft55xx.h" // verifywrite
-
 int CmdLFNoralsy(const char *Cmd);
 
 int demodNoralsy(void);
diff --git a/client/cmdlfpac.c b/client/cmdlfpac.c
index 175d56ad4..1977224e5 100644
--- a/client/cmdlfpac.c
+++ b/client/cmdlfpac.c
@@ -9,8 +9,34 @@
 //-----------------------------------------------------------------------------
 #include "cmdlfpac.h"
 
+#include <ctype.h>          //tolower
+
+#include "commonutil.h"     // ARRAYLEN
+#include "common.h"
+#include "cmdparser.h"    // command_t
+#include "comms.h"
+#include "ui.h"
+#include "cmddata.h"
+#include "cmdlf.h"
+#include "lfdemod.h"    // preamble test
+#include "protocols.h"  // t55xx defines
+#include "cmdlft55xx.h" // clone..
+
 static int CmdHelp(const char *Cmd);
 
+static int usage_lf_pac_clone(void) {
+    PrintAndLogEx(NORMAL, "clone a Stanley/PAC tag to a T55x7 tag.");
+    PrintAndLogEx(NORMAL, "");
+    PrintAndLogEx(NORMAL, "Usage: lf pac clone [h] [b <raw hex>]");
+    PrintAndLogEx(NORMAL, "Options:");
+    PrintAndLogEx(NORMAL, "  h               : this help");
+    PrintAndLogEx(NORMAL, "  b <raw hex>     : raw hex data. 12 bytes max");
+    PrintAndLogEx(NORMAL, "");
+    PrintAndLogEx(NORMAL, "Examples:");
+    PrintAndLogEx(NORMAL, "       lf pac clone b FF2049906D8511C593155B56D5B2649F ");
+    return PM3_SUCCESS;
+}
+
 //see NRZDemod for what args are accepted
 static int CmdPacDemod(const char *Cmd) {
 
@@ -46,8 +72,8 @@ static int CmdPacDemod(const char *Cmd) {
     // 11111111001000000 10 01001100 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 00001101 10 10001100 10 100000001
     // unknown checksum 9 bits at the end
 
-    PrintAndLogEx(NORMAL, "PAC/Stanley Tag Found -- Raw: %08X%08X%08X%08X", raw1, raw2, raw3, raw4);
-    PrintAndLogEx(NORMAL, "\nHow the Raw ID is translated by the reader is unknown");
+    PrintAndLogEx(SUCCESS, "PAC/Stanley Tag Found -- Raw: %08X%08X%08X%08X", raw1, raw2, raw3, raw4);
+    PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum");
     return PM3_SUCCESS;
 }
 
@@ -57,9 +83,45 @@ static int CmdPacRead(const char *Cmd) {
 }
 
 static int CmdPacClone(const char *Cmd) {
-    // possible to raw hex and clone
-    PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
-    return PM3_SUCCESS;
+    
+    uint32_t blocks[5];
+    bool errors = false;
+    uint8_t cmdp = 0;
+    int datalen = 0;
+
+    while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
+        switch (tolower(param_getchar(Cmd, cmdp))) {
+            case 'h':
+                return usage_lf_pac_clone();
+            case 'b': {
+                // skip first block,  4*4 = 16 bytes left
+                uint8_t rawhex[16] = {0}; 
+                int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen);
+                if ( res != 0 )
+                    errors = true;
+                
+                for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
+                    blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t));
+                }
+                cmdp += 2;
+                break;
+            }
+            default:
+                PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+                errors = true;
+                break;
+        }
+    }
+
+    if (errors || cmdp == 0) return usage_lf_pac_clone();
+
+    //Pac - compat mode, NRZ, data rate 40, 3 data blocks
+    blocks[0] = T55x7_MODULATION_DIRECT | T55x7_BITRATE_RF_40 | 4 << T55x7_MAXBLOCK_SHIFT;
+
+    PrintAndLogEx(INFO, "Preparing to clone Securakey to T55x7 with raw hex");
+    print_blocks(blocks,  ARRAYLEN(blocks));
+
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 }
 
 static int CmdPacSim(const char *Cmd) {
diff --git a/client/cmdlfpac.h b/client/cmdlfpac.h
index edb05b7a5..3c9c4fbda 100644
--- a/client/cmdlfpac.h
+++ b/client/cmdlfpac.h
@@ -10,12 +10,6 @@
 #define CMDLFPAC_H__
 
 #include "common.h"
-#include "cmdparser.h"    // command_t
-#include "comms.h"
-#include "ui.h"
-#include "cmddata.h"
-#include "cmdlf.h"
-#include "lfdemod.h"    // preamble test
 
 int CmdLFPac(const char *Cmd);
 
diff --git a/client/cmdlfparadox.c b/client/cmdlfparadox.c
index 440f47ced..b3307b8a8 100644
--- a/client/cmdlfparadox.c
+++ b/client/cmdlfparadox.c
@@ -14,6 +14,7 @@
 #include <stdlib.h>
 #include <ctype.h>
 
+#include "commonutil.h"     // ARRAYLEN
 #include "cmdparser.h"    // command_t
 #include "comms.h"
 #include "ui.h"
@@ -21,7 +22,24 @@
 #include "cmddata.h"
 #include "cmdlf.h"
 #include "lfdemod.h"
+#include "protocols.h"  // t55xx defines
+#include "cmdlft55xx.h" // clone..
+
 static int CmdHelp(const char *Cmd);
+
+static int usage_lf_paradox_clone(void) {
+    PrintAndLogEx(NORMAL, "clone a Paradox tag to a T55x7 tag.");
+    PrintAndLogEx(NORMAL, "");
+    PrintAndLogEx(NORMAL, "Usage: lf paradox clone [h] [b <raw hex>]");
+    PrintAndLogEx(NORMAL, "Options:");
+    PrintAndLogEx(NORMAL, "  h               : this help");
+    PrintAndLogEx(NORMAL, "  b <raw hex>     : raw hex data. 12 bytes max");
+    PrintAndLogEx(NORMAL, "");
+    PrintAndLogEx(NORMAL, "Examples:");
+    PrintAndLogEx(NORMAL, "       lf paradox clone 0f55555695596a6a9999a59a");
+    return PM3_SUCCESS;
+}
+
 /*
 static int usage_lf_paradox_sim(void) {
     PrintAndLogEx(NORMAL, "Enables simulation of Paradox card with specified card number.");
@@ -113,8 +131,45 @@ static int CmdParadoxRead(const char *Cmd) {
 }
 
 static int CmdParadoxClone(const char *Cmd) {
-    PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
-    return PM3_SUCCESS;
+    
+    uint32_t blocks[4];
+    bool errors = false;
+    uint8_t cmdp = 0;
+    int datalen = 0;
+
+    while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
+        switch (tolower(param_getchar(Cmd, cmdp))) {
+            case 'h':
+                return usage_lf_paradox_clone();
+            case 'b': {
+                // skip first block,  3*4 =12 bytes left
+                uint8_t rawhex[12] = {0}; 
+                int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen);
+                if ( res != 0 )
+                    errors = true;
+                
+                for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
+                    blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t));
+                }
+                cmdp += 2;
+                break;
+            }
+            default:
+                PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+                errors = true;
+                break;
+        }
+    }
+
+    if (errors || cmdp == 0) return usage_lf_paradox_clone();
+
+    //Securakey - compat mode, ASK/Man, data rate 40, 3 data blocks
+    blocks[0] = T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT;
+
+    PrintAndLogEx(INFO, "Preparing to clone Paradox to T55x7 with raw hex");
+    print_blocks(blocks,  ARRAYLEN(blocks));
+
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 }
 
 static int CmdParadoxSim(const char *Cmd) {
diff --git a/client/cmdlfpresco.c b/client/cmdlfpresco.c
index f563e2ef8..cfe56ad5e 100644
--- a/client/cmdlfpresco.c
+++ b/client/cmdlfpresco.c
@@ -9,6 +9,21 @@
 
 #include "cmdlfpresco.h"
 
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "commonutil.h"     // ARRAYLEN
+#include "cmdparser.h"    // command_t
+#include "comms.h"
+#include "ui.h"
+#include "cmddata.h"
+#include "cmdlf.h"
+#include "protocols.h"  // for T55xx config register definitions
+#include "lfdemod.h"    // parityTest
+#include "cmdlft55xx.h" // verifywrite
+
 static int CmdHelp(const char *Cmd);
 
 static int usage_lf_presco_clone(void) {
@@ -119,46 +134,9 @@ static int CmdPrescoClone(const char *Cmd) {
     blocks[4] = fullcode;
 
     PrintAndLogEx(INFO, "Preparing to clone Presco to T55x7 with SiteCode: %u, UserCode: %u, FullCode: %08x", sitecode, usercode, fullcode);
-    print_blocks(blocks, 5);
+    print_blocks(blocks,  ARRAYLEN(blocks));
 
-    uint8_t res = 0;
-    PacketResponseNG resp;
-
-    // fast push mode
-    conn.block_after_ACK = true;
-    for (uint8_t i = 0; i < 5; i++) {
-        if (i == 4) {
-            // Disable fast mode on last packet
-            conn.block_after_ACK = false;
-        }
-        clearCommandBuffer();
-        t55xx_write_block_t ng;
-        ng.data = blocks[i];
-        ng.pwd = 0;
-        ng.blockno = i;
-        ng.flags = 0;
-
-        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
-        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
-            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
-            return PM3_ETIMEOUT;
-        }
-
-        if (i == 0) {
-            SetConfigWithBlock0(blocks[0]);
-            if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
-                continue;
-        }
-
-        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
-            res++;
-
-    }
-
-    if (res == 0)
-        PrintAndLogEx(SUCCESS, "Success writing to tag");
-
-    return PM3_SUCCESS;
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 }
 
 // takes base 12 ID converts to hex
diff --git a/client/cmdlfpresco.h b/client/cmdlfpresco.h
index 8f7c7eb31..098a98342 100644
--- a/client/cmdlfpresco.h
+++ b/client/cmdlfpresco.h
@@ -11,20 +11,6 @@
 
 #include "common.h"
 
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include "cmdparser.h"    // command_t
-#include "comms.h"
-#include "ui.h"
-#include "cmddata.h"
-#include "cmdlf.h"
-#include "protocols.h"  // for T55xx config register definitions
-#include "lfdemod.h"    // parityTest
-#include "cmdlft55xx.h" // verifywrite
-
 int CmdLFPresco(const char *Cmd);
 
 int demodPresco(void);
diff --git a/client/cmdlfpyramid.c b/client/cmdlfpyramid.c
index 216e0834e..fa93a395c 100644
--- a/client/cmdlfpyramid.c
+++ b/client/cmdlfpyramid.c
@@ -8,6 +8,23 @@
 // FSK2a, rf/50, 128 bits (complete)
 //-----------------------------------------------------------------------------
 #include "cmdlfpyramid.h"
+#include "common.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "commonutil.h"   // ARRAYLEN
+#include "cmdparser.h"    // command_t
+#include "comms.h"
+#include "ui.h"
+#include "graph.h"
+#include "cmddata.h"
+#include "cmdlf.h"
+#include "protocols.h"  // for T55xx config register definitions
+#include "lfdemod.h"    // parityTest
+#include "crc.h"
+#include "cmdlft55xx.h" // verifywrite
 
 static int CmdHelp(const char *Cmd);
 
@@ -203,8 +220,10 @@ static int CmdPyramidClone(const char *Cmd) {
 
     uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0;
     uint32_t blocks[5];
-    uint8_t bs[128];
-    memset(bs, 0x00, sizeof(bs));
+    uint8_t *bs = calloc(128, sizeof(uint8_t));
+    if (bs == NULL) {
+        return PM3_EMALLOC;
+    }
 
     if (sscanf(Cmd, "%u %u", &fc, &cn) != 2) return usage_lf_pyramid_clone();
 
@@ -228,47 +247,12 @@ static int CmdPyramidClone(const char *Cmd) {
     blocks[3] = bytebits_to_byte(bs + 64, 32);
     blocks[4] = bytebits_to_byte(bs + 96, 32);
 
+    free(bs);
+
     PrintAndLogEx(INFO, "Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber);
-    print_blocks(blocks, 5);
+    print_blocks(blocks,  ARRAYLEN(blocks));
 
-    uint8_t res = 0;
-    PacketResponseNG resp;
-
-    // fast push mode
-    conn.block_after_ACK = true;
-    for (int8_t i = 0; i < 5; i++) {
-        if (i == 4) {
-            // Disable fast mode on last packet
-            conn.block_after_ACK = false;
-        }
-        clearCommandBuffer();
-        t55xx_write_block_t ng;
-        ng.data = blocks[i];
-        ng.pwd = 0;
-        ng.blockno = i;
-        ng.flags = 0;
-
-        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
-        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
-            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
-            return PM3_ETIMEOUT;
-        }
-
-        if (i == 0) {
-            SetConfigWithBlock0(blocks[0]);
-            if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
-                continue;
-        }
-
-        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
-            res++;
-
-    }
-
-    if (res == 0)
-        PrintAndLogEx(SUCCESS, "Success writing to tag");
-
-    return PM3_SUCCESS;
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 }
 
 static int CmdPyramidSim(const char *Cmd) {
diff --git a/client/cmdlfpyramid.h b/client/cmdlfpyramid.h
index 0a9e2674a..2d717fbb3 100644
--- a/client/cmdlfpyramid.h
+++ b/client/cmdlfpyramid.h
@@ -10,21 +10,6 @@
 #define CMDLFPYRAMID_H__
 
 #include "common.h"
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#include "cmdparser.h"    // command_t
-#include "comms.h"
-#include "ui.h"
-#include "graph.h"
-#include "cmddata.h"
-#include "cmdlf.h"
-#include "protocols.h"  // for T55xx config register definitions
-#include "lfdemod.h"    // parityTest
-#include "crc.h"
-#include "cmdlft55xx.h" // verifywrite
 
 int CmdLFPyramid(const char *Cmd);
 
diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c
index e14a679f2..784286e41 100644
--- a/client/cmdlfsecurakey.c
+++ b/client/cmdlfsecurakey.c
@@ -9,18 +9,35 @@
 //-----------------------------------------------------------------------------
 #include "cmdlfsecurakey.h"
 
-#include <string.h>
+#include <string.h>         // memcpy
+#include <ctype.h>          // tolower
 
-#include "cmdparser.h"    // command_t
+#include "commonutil.h"     // ARRAYLEN
+#include "cmdparser.h"      // command_t
 #include "comms.h"
 #include "ui.h"
 #include "cmddata.h"
 #include "cmdlf.h"
 #include "lfdemod.h"    // preamble test
 #include "parity.h"     // for wiegand parity test
+#include "protocols.h"  // t55xx defines
+#include "cmdlft55xx.h" // clone..
 
 static int CmdHelp(const char *Cmd);
 
+static int usage_lf_securakey_clone(void) {
+    PrintAndLogEx(NORMAL, "clone a Securakey tag to a T55x7 tag.");
+    PrintAndLogEx(NORMAL, "");
+    PrintAndLogEx(NORMAL, "Usage: lf securakey clone [h] [b <raw hex>]");
+    PrintAndLogEx(NORMAL, "Options:");
+    PrintAndLogEx(NORMAL, "  h               : this help");
+    PrintAndLogEx(NORMAL, "  b <raw hex>     : raw hex data. 12 bytes max");
+    PrintAndLogEx(NORMAL, "");
+    PrintAndLogEx(NORMAL, "Examples:");
+    PrintAndLogEx(NORMAL, "       lf securakey clone 7FCB400001ADEA5344300000");
+    return PM3_SUCCESS;
+}
+
 //see ASKDemod for what args are accepted
 static int CmdSecurakeyDemod(const char *Cmd) {
     (void)Cmd; // Cmd is not used so far
@@ -100,6 +117,7 @@ static int CmdSecurakeyDemod(const char *Cmd) {
     PrintAndLogEx(SUCCESS, "Securakey Tag Found--BitLen: %u, Card ID: %u, FC: 0x%X, Raw: %08X%08X%08X", bitLen, cardid, fc, raw1, raw2, raw3);
     if (bitLen <= 32)
         PrintAndLogEx(SUCCESS, "Wiegand: %08X, Parity: %s", (lWiegand << (bitLen / 2)) | rWiegand, parity ? "Passed" : "Failed");
+
     PrintAndLogEx(INFO, "\nHow the FC translates to printed FC is unknown");
     PrintAndLogEx(INFO, "How the checksum is calculated is unknown");
     PrintAndLogEx(INFO, "Help the community identify this format further\n by sharing your tag on the pm3 forum or with forum members");
@@ -112,8 +130,45 @@ static int CmdSecurakeyRead(const char *Cmd) {
 }
 
 static int CmdSecurakeyClone(const char *Cmd) {
-    PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
-    return PM3_SUCCESS;
+    
+    uint32_t blocks[4];
+    bool errors = false;
+    uint8_t cmdp = 0;
+    int datalen = 0;
+
+    while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
+        switch (tolower(param_getchar(Cmd, cmdp))) {
+            case 'h':
+                return usage_lf_securakey_clone();
+            case 'b': {
+                // skip first block,  3*4 = 12 bytes left
+                uint8_t rawhex[12] = {0}; 
+                int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen);
+                if ( res != 0 )
+                    errors = true;
+                
+                for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
+                    blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t));
+                }
+                cmdp += 2;
+                break;
+            }
+            default:
+                PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+                errors = true;
+                break;
+        }
+    }
+
+    if (errors || cmdp == 0) return usage_lf_securakey_clone();
+
+    //Securakey - compat mode, ASK/Man, data rate 40, 3 data blocks
+    blocks[0] = T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_40 | 3 << T55x7_MAXBLOCK_SHIFT;
+
+    PrintAndLogEx(INFO, "Preparing to clone Securakey to T55x7 with raw hex");
+    print_blocks(blocks,  ARRAYLEN(blocks));
+
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 }
 
 static int CmdSecurakeySim(const char *Cmd) {
diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c
index a41cd9f40..8cc8142a7 100644
--- a/client/cmdlft55xx.c
+++ b/client/cmdlft55xx.c
@@ -338,6 +338,59 @@ static int usage_t55xx_protect() {
 
 static int CmdHelp(const char *Cmd);
 
+int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks) {
+    
+    if (blockdata == NULL) 
+        return PM3_EINVARG;
+    if (numblocks < 1 || numblocks > 7)
+        return PM3_EINVARG;
+
+    PacketResponseNG resp;
+
+    // fast push mode
+    conn.block_after_ACK = true;
+
+    for (int8_t i = 0; i < numblocks; i++) {
+
+        // Disable fast mode on last packet
+        if (i == numblocks - 1) {
+            conn.block_after_ACK = false;
+        }
+
+        clearCommandBuffer();
+
+        t55xx_write_block_t ng;
+        ng.data = blockdata[i];
+        ng.pwd = 0;
+        ng.blockno = i;
+        ng.flags = 0;
+
+        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
+        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
+            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
+            return PM3_ETIMEOUT;
+        }
+    }
+ 
+   uint8_t res = 0;
+    for (int8_t i = 0; i < numblocks; i++) {
+
+        if (i == 0) {
+            SetConfigWithBlock0(blockdata[0]);
+            if (t55xxAquireAndCompareBlock0(false, 0, blockdata[0], false))
+                continue;
+        }
+
+        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blockdata[i]) == false)
+            res++;
+    }
+
+    if (res == 0)
+        PrintAndLogEx(SUCCESS, "Success writing to tag");
+    
+    return PM3_SUCCESS;
+}
+
 static bool t55xxProtect(bool lock, bool usepwd, uint8_t override, uint32_t password, uint8_t downlink_mode, uint32_t new_password) {
 
     PrintAndLogEx(INFO, "Checking current configuration");
diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h
index 1b70ca9ca..dce3a1b16 100644
--- a/client/cmdlft55xx.h
+++ b/client/cmdlft55xx.h
@@ -169,4 +169,5 @@ uint8_t  tryOnePassword(uint32_t password, uint8_t downlink_mode);
 void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat);
 void printT5555Trace(t5555_tracedata_t data, uint8_t repeat);
 
+int clone_t55xx_tag(uint32_t *blockdata, uint8_t numblocks);
 #endif
diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c
index 9bbbeaa7e..3a2ad6a5d 100644
--- a/client/cmdlfviking.c
+++ b/client/cmdlfviking.c
@@ -9,6 +9,20 @@
 //-----------------------------------------------------------------------------
 #include "cmdlfviking.h"
 
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "common.h"
+
+#include "cmdparser.h"    // command_t
+#include "comms.h"
+#include "ui.h"
+#include "cmddata.h"
+#include "cmdlf.h"
+#include "lfdemod.h"
+#include "commonutil.h"     // num_to_bytes
+
 static int CmdHelp(const char *Cmd);
 
 static int usage_lf_viking_clone(void) {
diff --git a/client/cmdlfviking.h b/client/cmdlfviking.h
index 344bb3c0c..156d57c7d 100644
--- a/client/cmdlfviking.h
+++ b/client/cmdlfviking.h
@@ -9,21 +9,8 @@
 #ifndef CMDLFVIKING_H__
 #define CMDLFVIKING_H__
 
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-
 #include "common.h"
 
-#include "cmdparser.h"    // command_t
-#include "comms.h"
-#include "ui.h"
-#include "cmddata.h"
-#include "cmdlf.h"
-#include "lfdemod.h"
-#include "commonutil.h"     // num_to_bytes
-
-
 int CmdLFViking(const char *Cmd);
 
 int demodViking(void);
diff --git a/client/cmdlfvisa2000.c b/client/cmdlfvisa2000.c
index 9f80a830d..f60510f23 100644
--- a/client/cmdlfvisa2000.c
+++ b/client/cmdlfvisa2000.c
@@ -11,6 +11,22 @@
 
 #include "cmdlfvisa2000.h"
 
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include "commonutil.h"     // ARRAYLEN
+#include "common.h"
+#include "cmdparser.h"    // command_t
+#include "comms.h"
+#include "ui.h"
+#include "graph.h"
+#include "cmddata.h"
+#include "cmdlf.h"
+#include "protocols.h"  // for T55xx config register definitions
+#include "lfdemod.h"    // parityTest
+#include "cmdlft55xx.h"    // write verify
+
 #define BL0CK1 0x56495332
 
 static int CmdHelp(const char *Cmd);
@@ -165,46 +181,9 @@ static int CmdVisa2kClone(const char *Cmd) {
     blocks[3] = (visa_parity(id) << 4) | visa_chksum(id);
 
     PrintAndLogEx(INFO, "Preparing to clone Visa2000 to T55x7 with CardId: %u", id);
-    print_blocks(blocks, 4);
+    print_blocks(blocks,  ARRAYLEN(blocks));
 
-    uint8_t res = 0;
-    PacketResponseNG resp;
-
-    // fast push mode
-    conn.block_after_ACK = true;
-    for (uint8_t i = 0; i < 4; i++) {
-        if (i == 3) {
-            // Disable fast mode on last packet
-            conn.block_after_ACK = false;
-        }
-        clearCommandBuffer();
-        t55xx_write_block_t ng;
-        ng.data = blocks[i];
-        ng.pwd = 0;
-        ng.blockno = i;
-        ng.flags = 0;
-
-        SendCommandNG(CMD_LF_T55XX_WRITEBL, (uint8_t *)&ng, sizeof(ng));
-        if (!WaitForResponseTimeout(CMD_LF_T55XX_WRITEBL, &resp, T55XX_WRITE_TIMEOUT)) {
-
-            PrintAndLogEx(ERR, "Error occurred, device did not respond during write operation.");
-            return PM3_ETIMEOUT;
-        }
-
-        if (i == 0) {
-            SetConfigWithBlock0(blocks[0]);
-            if (t55xxAquireAndCompareBlock0(false, 0, blocks[0], false))
-                continue;
-        }
-
-        if (t55xxVerifyWrite(i, 0, false, false, 0, 0xFF, blocks[i]) == false)
-            res++;
-    }
-
-    if (res == 0)
-        PrintAndLogEx(SUCCESS, "Success writing to tag");
-
-    return PM3_SUCCESS;
+    return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
 }
 
 static int CmdVisa2kSim(const char *Cmd) {
diff --git a/client/cmdlfvisa2000.h b/client/cmdlfvisa2000.h
index e8995cbdd..63e7fdc67 100644
--- a/client/cmdlfvisa2000.h
+++ b/client/cmdlfvisa2000.h
@@ -9,19 +9,7 @@
 #ifndef CMDLFVISA2000_H__
 #define CMDLFVISA2000_H__
 
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
 #include "common.h"
-#include "cmdparser.h"    // command_t
-#include "comms.h"
-#include "ui.h"
-#include "graph.h"
-#include "cmddata.h"
-#include "cmdlf.h"
-#include "protocols.h"  // for T55xx config register definitions
-#include "lfdemod.h"    // parityTest
-#include "cmdlft55xx.h"    // write verify
 
 int CmdLFVisa2k(const char *Cmd);
 
diff --git a/client/dictionaries/mfc_default_keys.dic b/client/dictionaries/mfc_default_keys.dic
index a12291199..376676f1a 100644
--- a/client/dictionaries/mfc_default_keys.dic
+++ b/client/dictionaries/mfc_default_keys.dic
@@ -1020,3 +1020,9 @@ e6849fcc324b
 39ad2963d3d1
 34b16cd59ff8 # Hotel Berlin Classic room A KEY
 bb2c0007d022 # Hotel Berlin Classic room B KEY
+#
+# Coinmatic laundry Smart card
+# data from: https://pastebin.com/XZQiLtUf
+#
+0734bfb93dab
+85a438f72a8a
diff --git a/client/graph.c b/client/graph.c
index 7031da5e2..be1d64920 100644
--- a/client/graph.c
+++ b/client/graph.c
@@ -84,6 +84,8 @@ void setGraphBuf(uint8_t *buff, size_t size) {
 
 size_t getFromGraphBuf(uint8_t *buff) {
     if (buff == NULL) return 0;
+    if (GraphTraceLen == 0) return 0;
+
     size_t i;
     for (i = 0; i < GraphTraceLen; ++i) {
         //trim
@@ -134,6 +136,11 @@ void convertGraphFromBitstreamEx(int hi, int low) {
     }
 
     size_t size = getFromGraphBuf(bits);
+    if (size == 0) {
+        PrintAndLogEx(WARNING, "Failed to copy from graphbuffer");
+        free(bits);
+        return;
+    }
 
     // set signal properties low/high/mean/amplitude and is_noise detection
     computeSignalProperties(bits, size);
diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c
index e4cec00c0..7cfabf3ee 100644
--- a/client/mifare/mifarehost.c
+++ b/client/mifare/mifarehost.c
@@ -30,7 +30,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
     uint32_t nt = 0, nr = 0, ar = 0;
     uint64_t par_list = 0, ks_list = 0;
     uint64_t *keylist = NULL, *last_keylist = NULL;
-    bool arg0 = true;
+    bool first_run = true;
 
     // message
     PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n");
@@ -40,7 +40,15 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
 
     while (true) {
         clearCommandBuffer();
-        SendCommandMIX(CMD_HF_MIFARE_READER, arg0, blockno, key_type, NULL, 0);
+        struct {
+            uint8_t first_run;
+            uint8_t blockno;
+            uint8_t key_type;
+        } PACKED payload;
+        payload.first_run = first_run;
+        payload.blockno = blockno;
+        payload.key_type = key_type;
+        SendCommandNG(CMD_HF_MIFARE_READER, (uint8_t*)&payload, sizeof(payload));
 
         //flush queue
         while (kbd_enter_pressed()) {
@@ -56,26 +64,47 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
             }
 
             PacketResponseNG resp;
-            if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
-                int16_t isOK  = resp.oldarg[0];
-                if (isOK < 0)
-                    return isOK;
+            if (WaitForResponseTimeout(CMD_HF_MIFARE_READER, &resp, 2000)) {
+                if (resp.status == PM3_EOPABORTED) {
+                    return -1;
+                }
 
-                uid = (uint32_t)bytes_to_num(resp.data.asBytes +  0, 4);
-                nt = (uint32_t)bytes_to_num(resp.data.asBytes +  4, 4);
-                par_list = bytes_to_num(resp.data.asBytes +  8, 8);
-                ks_list = bytes_to_num(resp.data.asBytes +  16, 8);
-                nr = (uint32_t)bytes_to_num(resp.data.asBytes + 24, 4);
-                ar = (uint32_t)bytes_to_num(resp.data.asBytes + 28, 4);
+                struct p {
+                    int32_t isOK;
+                    uint8_t cuid[4];
+                    uint8_t nt[4];
+                    uint8_t par_list[8];
+                    uint8_t ks_list[8];
+                    uint8_t nr[4];
+                    uint8_t ar[4];
+                } PACKED;
+
+               struct p* package = (struct p*) resp.data.asBytes;
+
+                if (package->isOK == -6) {
+                     *key = 0101;
+                      return 1;
+                }
+
+                if (package->isOK < 0)
+                    return package->isOK;
+
+
+                uid = (uint32_t)bytes_to_num(package->cuid, sizeof(package->cuid));
+                nt = (uint32_t)bytes_to_num(package->nt, sizeof(package->nr));
+                par_list = bytes_to_num(package->par_list, sizeof(package->par_list));
+                ks_list = bytes_to_num(package->ks_list, sizeof(package->ks_list));
+                nr = (uint32_t)bytes_to_num(package->nr, 4);
+                ar = (uint32_t)bytes_to_num(package->ar, 4);
                 break;
             }
         }
         PrintAndLogEx(NORMAL, "\n");
 
-        if (par_list == 0 && arg0 == true) {
+        if (par_list == 0 && first_run == true) {
             PrintAndLogEx(SUCCESS, "Parity is all zero. Most likely this card sends NACK on every authentication.");
         }
-        arg0 = false;
+        first_run = false;
 
         uint32_t keycount = nonce2key(uid, nt, nr, ar, par_list, ks_list, &keylist);
 
@@ -124,7 +153,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
             PrintAndLogEx(FAILED, "all candidate keys failed. Restarting darkside attack");
             free(last_keylist);
             last_keylist = keylist;
-            arg0 = true;
+            first_run = true;
         }
     }
     free(last_keylist);