]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
CHG: "hf legic write" got a make over in how its called. Now called with 'offset...
authoriceman1001 <iceman@iuse.se>
Fri, 7 Oct 2016 09:58:14 +0000 (11:58 +0200)
committericeman1001 <iceman@iuse.se>
Fri, 7 Oct 2016 09:58:14 +0000 (11:58 +0200)
'hf legic write o 10 d 11223344'  -  this will write 4 bytes (0x11,0x22,0x33,0x44) to tag from offset 10 (0x0A)

armsrc/legicrf.c
client/cmdhflegic.c

index ff193edb31a0429ba9746dc91343a11fcbb56052..223a777209cf401175fd08e0bbb5ff15f6249869 100644 (file)
@@ -417,11 +417,13 @@ int legic_write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz) {
        crc_update(&legic_crc, index, addr_sz);
        crc_update(&legic_crc, byte, 8);
        uint32_t crc = crc_finish(&legic_crc);
+       /*
        uint32_t crc2 = legic4Crc(LEGIC_WRITE, index, byte, addr_sz+1);
        if ( crc != crc2 ) {
                Dbprintf("crc is missmatch");
                return 1;
        }
+       */
        // send write command
        uint32_t cmd = ((crc     <<(addr_sz+1+8)) //CRC
                    |(byte    <<(addr_sz+1))   //Data
@@ -443,7 +445,7 @@ int legic_write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz) {
     int next_bit_at = 0;
 
        // ACK 3.6ms = 3600us * 1.5 = 5400ticks.
-       WaitTicks(5360);
+       WaitTicks(5400);
 
     for( t = 0; t < 80; ++t) {
         edges = 0;
@@ -512,16 +514,18 @@ OUT:
 
 void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) {
 
+       #define LOWERLIMIT 4
+
+       int r = 0;
        uint8_t isOK = 1;
+       legic_card_select_t card;
        
-       // UID not is writeable.
-       if ( offset <= 4 ) {
+       // uid NOT is writeable.
+       if ( offset <= LOWERLIMIT ) {
                isOK = 0;
                goto OUT;
        }
        
-       legic_card_select_t card;
-       
        LegicCommonInit();
        
        if ( legic_select_card_iv(&card, iv) ) {
@@ -529,39 +533,25 @@ void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) {
                goto OUT;
        }
        
-       if (len + offset >= card.cardsize)
-               len = card.cardsize - offset;
-
+       switch_off_tag_rwd();
+       
+       if ( len + offset + LOWERLIMIT >= card.cardsize) {
+               isOK = 0;
+               goto OUT;
+       }
+       
        setup_phase_reader(iv);
 
     LED_B_ON();        
-       int r = 0;
-       // how about we write backwards instead. no need for this extra DCF check.      
-       // index = len - cardsize
-       // stops uid 01234, 
-       /*
-       len = 20
-       offset = 5
-       
-       index = 20+5 = 25
-       if ( index > cardsize ) return -1;
-       
-       loop
-               write( data[index], index , card.addrsize);
-               --index;
-       end loop        
-       */
-       uint16_t index = len;
-       while(index > 4) {
+       while( len > 0 ) {
 
-               r = legic_write_byte( index, data[ index ], card.addrsize);
-               
-               if ( r ) {
-                       Dbprintf("operation aborted @ 0x%03.3x", index);
+               int r = legic_write_byte( len + offset + LOWERLIMIT, data[len], card.addrsize);
+               if ( r == -1 ) {
+                       Dbprintf("operation aborted @ 0x%03.3x", len);
                        isOK = 0;
                        goto OUT;
                }
-               --index;
+               --len;
                WDT_HIT();
        }
 
index 3ee6c5d5d401a401fc70e83b1daa401e13c48a75..50c2976f394bc536d1c97eb72d64b55ba100fc36 100644 (file)
@@ -60,15 +60,15 @@ int usage_legic_sim(void){
 }
 int usage_legic_write(void){
        PrintAndLog(" Write sample buffer to a legic tag. (use after load or read)");
-       PrintAndLog("Usage:  hf legic write [h] <offset> <length> <IV>");
+       PrintAndLog("Usage:  hf legic write [h] o <offset> d <data (hex symbols)>");
        PrintAndLog("Options:");
        PrintAndLog("  h             : this help");
-       PrintAndLog("  <offset>      : offset in data array to start writing from (hex)");
-       PrintAndLog("  <length>      : number of bytes to write (hex)");
-       PrintAndLog("  <IV>          : (optional) Initialization vector to use (ODD and 7bits)");
+       PrintAndLog("  o <offset>    : offset in data array to start writing");
+       //PrintAndLog("  <IV>          : (optional) Initialization vector to use (ODD and 7bits)");
+       PrintAndLog("  d <data>      : bytes to write (hex symbols)");
        PrintAndLog("");
        PrintAndLog("Samples:");
-       PrintAndLog("      hf legic write 10 4      - writes 0x4 to byte[0x10]");
+       PrintAndLog("      hf legic write o 10 d 11223344    - Write 0x11223344 starting from offset 0x10");
        return 0;
 }
 int usage_legic_reader(void){
@@ -538,7 +538,6 @@ int CmdLegicLoad(const char *Cmd) {
                index += res;
                        
                if ( index == USB_CMD_DATA_SIZE ){
-//                     PrintAndLog("sent %d | %d | %d", index, offset, totalbytes);
                        UsbCommand c = { CMD_DOWNLOADED_SIM_SAMPLES_125K, {offset, 0, 0}};
                        memcpy(c.d.asBytes, data, sizeof(data));
                        clearCommandBuffer();
@@ -640,20 +639,74 @@ int CmdLegicRfSim(const char *Cmd) {
 
 int CmdLegicRfWrite(const char *Cmd) {
 
-       // offset - in tag memory
-       // length - num of bytes to be written
-
-       char cmdp = param_getchar(Cmd, 0);
-       if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_write();
-       
-       uint32_t offset = 0, len = 0, IV = 0;
-       
-    int res = sscanf(Cmd, "%x %x %x", &offset, &len, &IV);
-       if(res < 2) {
-               PrintAndLog("Please specify the offset and length as two hex strings and, optionally, the IV also as an hex string");
-        return -1;
-    }
+       uint8_t *data = NULL;
+       uint8_t cmdp = 0;
+       bool errors = false;
+       int len = 0, bg, en;
+       uint32_t offset = 0, IV = 0x55;
        
+       while(param_getchar(Cmd, cmdp) != 0x00) {
+               switch(param_getchar(Cmd, cmdp)) {
+               case 'd':
+               case 'D':
+                       // peek at length of the input string so we can
+                       // figure out how many elements to malloc in "data"
+                       bg=en=0;
+                       if (param_getptr(Cmd, &bg, &en, cmdp+1)) {
+                               errors = true;
+                               break;
+                       }
+                       len = (en - bg + 1);
+
+                       // check that user entered even number of characters
+                       // for hex data string
+                       if (len & 1) {
+                               errors = true;
+                               break;
+                       }
+
+                       // 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");
+                               errors = true;
+                               break;
+                       }
+                       
+                       if (param_gethex(Cmd, cmdp+1, data, len)) {
+                               errors = true;
+                               break;
+                       }
+
+                       len >>= 1;      
+                       cmdp += 2;
+                       break;
+               case 'o':
+               case 'O':
+                       offset = param_get32ex(Cmd, cmdp+1, 4, 10);
+                       cmdp += 2;
+                       break;
+               case 'h':
+               case 'H':
+                       errors = true;
+                       break;
+               default:
+                       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+                       errors = true;
+                       break;
+               }
+               if (errors) break;
+       }
+       //Validations
+       if (errors){
+               if (data) 
+                       free(data);
+               return usage_legic_write();
+       }
+
        // tagtype
        legic_card_select_t card;
        if (legic_get_type(&card)) {
@@ -664,25 +717,30 @@ int CmdLegicRfWrite(const char *Cmd) {
        legic_print_type(card.cardsize, 0);
        
        // OUT-OF-BOUNDS check
-       if ( len + offset > card.cardsize ) {
-               PrintAndLog("Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset);
+       // UID 4 bytes can't be written to.
+       if ( len + offset + 4 >= card.cardsize ) {
+               PrintAndLog("Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset + 4);
                return -2;
        }
-       
+
        legic_chk_iv(&IV);
        
-    UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}};   
+       PrintAndLog("Writing to tag");
+    UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}};
+       memcpy(c.d.asBytes, data, len);
+       
        clearCommandBuffer();
     SendCommand(&c);
        UsbCommand resp;
-       if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
-               uint8_t isOK = resp.arg[0] & 0xFF;
-                if ( !isOK )
-                        PrintAndLog("failed writing tag");
-       } else {
+       if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
                PrintAndLog("command execution time out");
                return 1;
        }
+       uint8_t isOK = resp.arg[0] & 0xFF;
+       if ( !isOK ) {
+               PrintAndLog("failed writing tag");
+               return 1;
+       }
        
     return 0;
 }
Impressum, Datenschutz