From f0fa6638141409674b64481557aba051935b1685 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 7 Oct 2016 11:58:14 +0200 Subject: [PATCH] CHG: "hf legic write" got a make over in how its called. Now called with 'offset' and 'data' '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 | 52 ++++++++------------ client/cmdhflegic.c | 114 +++++++++++++++++++++++++++++++++----------- 2 files changed, 107 insertions(+), 59 deletions(-) diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index ff193edb..223a7772 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -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(); } diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 3ee6c5d5..50c2976f 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -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] "); + PrintAndLog("Usage: hf legic write [h] o d "); PrintAndLog("Options:"); PrintAndLog(" h : this help"); - PrintAndLog(" : offset in data array to start writing from (hex)"); - PrintAndLog(" : number of bytes to write (hex)"); - PrintAndLog(" : (optional) Initialization vector to use (ODD and 7bits)"); + PrintAndLog(" o : offset in data array to start writing"); + //PrintAndLog(" : (optional) Initialization vector to use (ODD and 7bits)"); + PrintAndLog(" d : 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; } -- 2.39.2