From: iceman1001 Date: Sun, 9 Oct 2016 13:41:31 +0000 (+0200) Subject: CHG: "hf legic write" - now writes on the limits better. X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/539fd59ebe7f3ed79a7d9327d4499aa42fd47382?ds=sidebyside CHG: "hf legic write" - now writes on the limits better. 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' --- diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index e40124bc..9abc7761 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -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; } diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 08e283b5..b2d207e5 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -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; }