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)
This commit is contained in:
iceman1001 2016-10-07 11:58:14 +02:00
parent ac42d5be85
commit f0fa663814
2 changed files with 107 additions and 59 deletions

View 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();
}

View 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
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();
}
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;
}
// 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;
}