mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 21:33:47 -07:00
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:
parent
ac42d5be85
commit
f0fa663814
2 changed files with 107 additions and 59 deletions
|
@ -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, index, addr_sz);
|
||||||
crc_update(&legic_crc, byte, 8);
|
crc_update(&legic_crc, byte, 8);
|
||||||
uint32_t crc = crc_finish(&legic_crc);
|
uint32_t crc = crc_finish(&legic_crc);
|
||||||
|
/*
|
||||||
uint32_t crc2 = legic4Crc(LEGIC_WRITE, index, byte, addr_sz+1);
|
uint32_t crc2 = legic4Crc(LEGIC_WRITE, index, byte, addr_sz+1);
|
||||||
if ( crc != crc2 ) {
|
if ( crc != crc2 ) {
|
||||||
Dbprintf("crc is missmatch");
|
Dbprintf("crc is missmatch");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// send write command
|
// send write command
|
||||||
uint32_t cmd = ((crc <<(addr_sz+1+8)) //CRC
|
uint32_t cmd = ((crc <<(addr_sz+1+8)) //CRC
|
||||||
|(byte <<(addr_sz+1)) //Data
|
|(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;
|
int next_bit_at = 0;
|
||||||
|
|
||||||
// ACK 3.6ms = 3600us * 1.5 = 5400ticks.
|
// ACK 3.6ms = 3600us * 1.5 = 5400ticks.
|
||||||
WaitTicks(5360);
|
WaitTicks(5400);
|
||||||
|
|
||||||
for( t = 0; t < 80; ++t) {
|
for( t = 0; t < 80; ++t) {
|
||||||
edges = 0;
|
edges = 0;
|
||||||
|
@ -512,16 +514,18 @@ OUT:
|
||||||
|
|
||||||
void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) {
|
void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) {
|
||||||
|
|
||||||
uint8_t isOK = 1;
|
#define LOWERLIMIT 4
|
||||||
|
|
||||||
// UID not is writeable.
|
int r = 0;
|
||||||
if ( offset <= 4 ) {
|
uint8_t isOK = 1;
|
||||||
|
legic_card_select_t card;
|
||||||
|
|
||||||
|
// uid NOT is writeable.
|
||||||
|
if ( offset <= LOWERLIMIT ) {
|
||||||
isOK = 0;
|
isOK = 0;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
legic_card_select_t card;
|
|
||||||
|
|
||||||
LegicCommonInit();
|
LegicCommonInit();
|
||||||
|
|
||||||
if ( legic_select_card_iv(&card, iv) ) {
|
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;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len + offset >= card.cardsize)
|
switch_off_tag_rwd();
|
||||||
len = card.cardsize - offset;
|
|
||||||
|
if ( len + offset + LOWERLIMIT >= card.cardsize) {
|
||||||
|
isOK = 0;
|
||||||
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
setup_phase_reader(iv);
|
setup_phase_reader(iv);
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
int r = 0;
|
while( len > 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
|
int r = legic_write_byte( len + offset + LOWERLIMIT, data[len], card.addrsize);
|
||||||
if ( index > cardsize ) return -1;
|
if ( r == -1 ) {
|
||||||
|
Dbprintf("operation aborted @ 0x%03.3x", len);
|
||||||
loop
|
|
||||||
write( data[index], index , card.addrsize);
|
|
||||||
--index;
|
|
||||||
end loop
|
|
||||||
*/
|
|
||||||
uint16_t index = len;
|
|
||||||
while(index > 4) {
|
|
||||||
|
|
||||||
r = legic_write_byte( index, data[ index ], card.addrsize);
|
|
||||||
|
|
||||||
if ( r ) {
|
|
||||||
Dbprintf("operation aborted @ 0x%03.3x", index);
|
|
||||||
isOK = 0;
|
isOK = 0;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
--index;
|
--len;
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,15 +60,15 @@ int usage_legic_sim(void){
|
||||||
}
|
}
|
||||||
int usage_legic_write(void){
|
int usage_legic_write(void){
|
||||||
PrintAndLog(" Write sample buffer to a legic tag. (use after load or read)");
|
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("Options:");
|
||||||
PrintAndLog(" h : this help");
|
PrintAndLog(" h : this help");
|
||||||
PrintAndLog(" <offset> : offset in data array to start writing from (hex)");
|
PrintAndLog(" o <offset> : offset in data array to start writing");
|
||||||
PrintAndLog(" <length> : number of bytes to write (hex)");
|
//PrintAndLog(" <IV> : (optional) Initialization vector to use (ODD and 7bits)");
|
||||||
PrintAndLog(" <IV> : (optional) Initialization vector to use (ODD and 7bits)");
|
PrintAndLog(" d <data> : bytes to write (hex symbols)");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Samples:");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
int usage_legic_reader(void){
|
int usage_legic_reader(void){
|
||||||
|
@ -538,7 +538,6 @@ int CmdLegicLoad(const char *Cmd) {
|
||||||
index += res;
|
index += res;
|
||||||
|
|
||||||
if ( index == USB_CMD_DATA_SIZE ){
|
if ( index == USB_CMD_DATA_SIZE ){
|
||||||
// PrintAndLog("sent %d | %d | %d", index, offset, totalbytes);
|
|
||||||
UsbCommand c = { CMD_DOWNLOADED_SIM_SAMPLES_125K, {offset, 0, 0}};
|
UsbCommand c = { CMD_DOWNLOADED_SIM_SAMPLES_125K, {offset, 0, 0}};
|
||||||
memcpy(c.d.asBytes, data, sizeof(data));
|
memcpy(c.d.asBytes, data, sizeof(data));
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
@ -640,19 +639,73 @@ int CmdLegicRfSim(const char *Cmd) {
|
||||||
|
|
||||||
int CmdLegicRfWrite(const char *Cmd) {
|
int CmdLegicRfWrite(const char *Cmd) {
|
||||||
|
|
||||||
// offset - in tag memory
|
uint8_t *data = NULL;
|
||||||
// length - num of bytes to be written
|
uint8_t cmdp = 0;
|
||||||
|
bool errors = false;
|
||||||
|
int len = 0, bg, en;
|
||||||
|
uint32_t offset = 0, IV = 0x55;
|
||||||
|
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
while(param_getchar(Cmd, cmdp) != 0x00) {
|
||||||
if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_write();
|
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);
|
||||||
|
|
||||||
uint32_t offset = 0, len = 0, IV = 0;
|
// check that user entered even number of characters
|
||||||
|
// for hex data string
|
||||||
|
if (len & 1) {
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
int res = sscanf(Cmd, "%x %x %x", &offset, &len, &IV);
|
// it's possible for user to accidentally enter "b" parameter
|
||||||
if(res < 2) {
|
// more than once - we have to clean previous malloc
|
||||||
PrintAndLog("Please specify the offset and length as two hex strings and, optionally, the IV also as an hex string");
|
if (data)
|
||||||
return -1;
|
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
|
// tagtype
|
||||||
legic_card_select_t card;
|
legic_card_select_t card;
|
||||||
|
@ -664,25 +717,30 @@ int CmdLegicRfWrite(const char *Cmd) {
|
||||||
legic_print_type(card.cardsize, 0);
|
legic_print_type(card.cardsize, 0);
|
||||||
|
|
||||||
// OUT-OF-BOUNDS check
|
// OUT-OF-BOUNDS check
|
||||||
if ( len + offset > card.cardsize ) {
|
// UID 4 bytes can't be written to.
|
||||||
PrintAndLog("Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset);
|
if ( len + offset + 4 >= card.cardsize ) {
|
||||||
|
PrintAndLog("Out-of-bounds, Cardsize = %d, [offset+len = %d ]", card.cardsize, len + offset + 4);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
legic_chk_iv(&IV);
|
legic_chk_iv(&IV);
|
||||||
|
|
||||||
|
PrintAndLog("Writing to tag");
|
||||||
UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}};
|
UsbCommand c = {CMD_WRITER_LEGIC_RF, {offset, len, IV}};
|
||||||
|
memcpy(c.d.asBytes, data, len);
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||||
uint8_t isOK = resp.arg[0] & 0xFF;
|
|
||||||
if ( !isOK )
|
|
||||||
PrintAndLog("failed writing tag");
|
|
||||||
} else {
|
|
||||||
PrintAndLog("command execution time out");
|
PrintAndLog("command execution time out");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
uint8_t isOK = resp.arg[0] & 0xFF;
|
||||||
|
if ( !isOK ) {
|
||||||
|
PrintAndLog("failed writing tag");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue