]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
CHG: "hf legic write" - now writes on the limits better.
authoriceman1001 <iceman@iuse.se>
Sun, 9 Oct 2016 13:41:31 +0000 (15:41 +0200)
committericeman1001 <iceman@iuse.se>
Sun, 9 Oct 2016 13:41:31 +0000 (15:41 +0200)
CHG: "hf legic restore" - now restors :)
CHG: "hf legic rdmem" - now has a nice offset row above the read data.  try:  'hf legic rdmem 0 100'

armsrc/legicrf.c
client/cmdhflegic.c

index e40124bc67229ace508aab8f17c0c8761b6a02cd..9abc77612c71fe09333a0c32fc4c2abf99e0f2a8 100644 (file)
@@ -477,7 +477,7 @@ int LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) {
                goto OUT;
        }
 
-       if (len + offset >= card.cardsize)
+       if (len + offset > card.cardsize)
                len = card.cardsize - offset;
 
        LED_B_ON();
@@ -504,7 +504,7 @@ OUT:
 void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) {
 
        #define LOWERLIMIT 4
-       uint8_t isOK = 1;
+       uint8_t isOK = 1, msg = 0;
        legic_card_select_t card;
        
        // uid NOT is writeable.
@@ -517,13 +517,12 @@ void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) {
        
        if ( legic_select_card_iv(&card, iv) ) {
                isOK = 0;
+               msg = 1;
                goto OUT;
        }
        
-       if ( len + offset + LOWERLIMIT >= card.cardsize) {
-               isOK = 0;
-               goto OUT;
-       }
+       if ( len + offset > card.cardsize)
+               len = card.cardsize - offset;
 
     LED_B_ON();        
        while( len > 0 ) {
@@ -536,7 +535,7 @@ void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) {
                WDT_HIT();
        }
 OUT:
-       cmd_send(CMD_ACK, isOK, 0,0,0,0);
+       cmd_send(CMD_ACK, isOK, msg,0,0,0);
        switch_off_tag_rwd();
        LEDsoff();      
 }
@@ -723,7 +722,7 @@ static void frame_handle_tag(struct legic_frame const * const f)
    }
 
    /* Write */
-   if(f->bits == 23) {
+   if (f->bits == 23 || f->bits == 21 ) {
       uint32_t key  = get_key_stream(-1, 23); //legic_frame_drift, 23);
       uint16_t addr = f->data ^ key; 
          addr >>= 1; 
@@ -737,7 +736,7 @@ static void frame_handle_tag(struct legic_frame const * const f)
       legic_state = STATE_DISCON;
       LED_C_OFF();
       Dbprintf("write - addr: %x, data: %x", addr, data);
-         // should send a ACK within 3.5ms too
+         // should send a ACK after 3.6ms 
       return;
    }
 
index 08e283b5b26d12a598833a72ff1c7092c4cde2a9..b2d207e5856bb4cd41ff4b4fb474050ef6843e16 100644 (file)
@@ -506,8 +506,8 @@ int CmdLegicRdmem(const char *Cmd) {
                return 1;
        }
        
-       PrintAndLog("\n ##  | Data");
-       PrintAndLog("-----+-----");
+       PrintAndLog("\n ##  |  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F");
+       PrintAndLog("-----+------------------------------------------------------------------------------------------------");
        print_hex_break( data, readlen, 32);
        free(data);
        return 0;
@@ -551,11 +551,19 @@ int CmdLegicRfWrite(const char *Cmd) {
                                errors = true;
                                break;
                        }
+                       
+                       // limit number of bytes to write. This is not a 'restore' command.
+                       if ( (len>>1) > 100 ){
+                               PrintAndLog("Max bound on 100bytes to write a one time.");
+                               PrintAndLog("Use the 'hf legic restore' command if you want to write the whole tag at once");
+                               errors = true;
+                       }
 
                        // it's possible for user to accidentally enter "b" parameter
                        // more than once - we have to clean previous malloc
                        if (data)
                                free(data);
+                       
                        data = malloc(len >> 1);
                        if ( data == NULL ) {
                                PrintAndLog("Can't allocate memory. exiting");
@@ -604,27 +612,42 @@ int CmdLegicRfWrite(const char *Cmd) {
        legic_print_type(card.cardsize, 0);
        
        // OUT-OF-BOUNDS checks
-       // UID 4 bytes can't be written to.
-       if ( offset < 4 ) {
-               PrintAndLog("Out-of-bounds, UID 4bytes can't be written to. Offset = %d", offset);
+       // UID 4+1 bytes can't be written to.
+       if ( offset < 5 ) {
+               PrintAndLog("Out-of-bounds, bytes 0-1-2-3-4 can't be written to. Offset = %d", offset);
                return -2;
        }
        
-       if ( len + offset + 4 >= card.cardsize ) {
-               PrintAndLog("Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset + 4);
+       if ( len + offset >= card.cardsize ) {
+               PrintAndLog("Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset);
                return -2;
        }
 
+       if (offset == 5 || offset == 6) {
+               PrintAndLog("############# DANGER ################");
+               PrintAndLog("# changing the DCF is irreversible  #");
+               PrintAndLog("#####################################");
+               PrintAndLog("do you really want to continue? y(es) n(o)");              
+               char answer;
+               sscanf("%c", &answer);
+               bool exit = !(answer == 'n' || answer == 'N');
+               if (exit)
+                       return 0;
+               printf("ICE DCF:  %c answer, %d\n", answer, exit);
+               return 0;
+       }
+       
        legic_chk_iv(&IV);
        
        PrintAndLog("Writing to tag");
-    UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}};
-       memcpy(c.d.asBytes, data, len);
-       
-       clearCommandBuffer();
-    SendCommand(&c);
+
+       UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}};
+       memcpy(c.d.asBytes, data, len); 
        UsbCommand resp;
-       if (!WaitForResponseTimeout(CMD_ACK, &resp, 4000)) {
+       clearCommandBuffer();
+       SendCommand(&c);
+       
+       if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
                PrintAndLog("command execution time out");
                return 1;
        }
@@ -633,20 +656,10 @@ int CmdLegicRfWrite(const char *Cmd) {
                PrintAndLog("failed writing tag");
                return 1;
        }
-       
+
     return 0;
 }
 
-/*
-       PrintAndLog("############# DANGER !! #############");
-       PrintAndLog("# changing the DCF is irreversible  #");
-       PrintAndLog("#####################################");
-       PrintAndLog("do youe really want to continue? y(es) n(o)");             
-       // if (scanf(" %c", &answer) > 0 && (answer == 'y' || answer == 'Y')) {
-               // return 0;
-       // }
-*/
-
 int CmdLegicCalcCrc(const char *Cmd){
 
        uint8_t *data = NULL;
@@ -922,7 +935,7 @@ int CmdLegicRestore(const char *Cmd){
        char filename[FILE_PATH_SIZE] = {0x00};
        char *fnameptr = filename;
        size_t fileNlen = 0;
-       bool errors = false;
+       bool errors = true;
        uint16_t numofbytes;    
        uint8_t cmdp = 0;
        
@@ -938,17 +951,20 @@ int CmdLegicRestore(const char *Cmd){
                        case 'I':
                                fileNlen = param_getstr(Cmd, cmdp+1, filename);
                                if (!fileNlen) 
-                                       errors = true; 
+                                       errors = true;
+                               else 
+                                       errors = false;
+                               
                                if (fileNlen > FILE_PATH_SIZE-5) 
                                        fileNlen = FILE_PATH_SIZE-5;
-                               cmdp += 2;
+                               cmdp += 2;                              
                                break;
                        default:
                                PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
                                errors = true;
                                break;
                }
-               if(errors) break;
+               if (errors) break;
        }
 
        //Validations
@@ -987,15 +1003,11 @@ int CmdLegicRestore(const char *Cmd){
        fseek(f, 0, SEEK_SET); // seek back to beginning of file
        
        if ( filesize != numofbytes) {
-               PrintAndLog("Fail, Filesize and cardsize is not equal. [%u != %u]", filesize, numofbytes);
+               PrintAndLog("Fail, filesize and cardsize is not equal. [%u != %u]", filesize, numofbytes);
                free(data);
                fclose(f);
                return 4;
        }
-               
-       
-       PrintAndLog("Reading binary file...");
-
 
        // load file
        size_t bytes_read = fread(data, 1, numofbytes, f);
@@ -1009,12 +1021,36 @@ int CmdLegicRestore(const char *Cmd){
 
        PrintAndLog("Restoring %s to card", filename);
 
-       //loop writing :)
-
-       //endloop
+       // transfer to device
+       size_t len = 0;
+       UsbCommand c = {CMD_WRITER_LEGIC_RF, {0, 0, 0x55}};
+       UsbCommand resp;
+       for(size_t i = 7; i < numofbytes; i += USB_CMD_DATA_SIZE) {
+               
+               len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);         
+               c.arg[0] = i; // offset
+               c.arg[1] = len; // number of bytes
+               memcpy(c.d.asBytes, data+i, len); 
+               PrintAndLog("offset %d | chunk %d | numofbytes %d", i, len, numofbytes);
+               clearCommandBuffer();
+               SendCommand(&c);
+       
+               if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
+                       PrintAndLog("command execution time out");
+                       free(data);     
+                       return 1;
+               }
+               uint8_t isOK = resp.arg[0] & 0xFF;
+               if ( !isOK ) {
+                       PrintAndLog("failed writing tag [msg = %u]", resp.arg[1] & 0xFF);
+                       free(data);     
+                       return 1;
+               }
+               PrintAndLog("Wrote chunk %d - %d", i, len);
+       }       
        
        free(data);     
-       PrintAndLog("\nLoaded %d bytes from file: %s  to emulator memory", numofbytes, filename);
+       PrintAndLog("\nWrote %d bytes from file: %s to card", numofbytes, filename);
        return 0;
 }
 
Impressum, Datenschutz