mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-02-13 02:34:48 +08: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, 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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue