mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 18:48:13 -07:00
commit
5a56504fc1
13 changed files with 500 additions and 481 deletions
|
@ -30,13 +30,13 @@
|
|||
|
||||
|
||||
void ModInfo(void) {
|
||||
DbpString(" HF - Long-range relay 14a over serial<->IP - a.k.a. CardHopper (Sam Haskins)");
|
||||
DbpString(" HF - Long-range relay 14a over serial<->IP - a.k.a. CardHopper (Sam Haskins)");
|
||||
}
|
||||
|
||||
|
||||
typedef struct PACKED {
|
||||
uint8_t len;
|
||||
uint8_t dat[255];
|
||||
uint8_t len;
|
||||
uint8_t dat[255];
|
||||
} packet_t;
|
||||
|
||||
// Magic numbers
|
||||
|
@ -52,283 +52,292 @@ static void become_reader(void);
|
|||
static void select_card(void);
|
||||
|
||||
static void become_card(void);
|
||||
static void prepare_emulation(uint8_t*, uint16_t*, uint8_t*, packet_t*);
|
||||
static void cook_ats(packet_t*, uint8_t, uint8_t);
|
||||
static bool try_use_canned_response(uint8_t*, int, tag_response_info_t*);
|
||||
static void reply_with_packet(packet_t*);
|
||||
static void prepare_emulation(uint8_t *, uint16_t *, uint8_t *, packet_t *);
|
||||
static void cook_ats(packet_t *, uint8_t, uint8_t);
|
||||
static bool try_use_canned_response(uint8_t *, int, tag_response_info_t *);
|
||||
static void reply_with_packet(packet_t *);
|
||||
|
||||
static void read_packet(packet_t*);
|
||||
static void write_packet(packet_t*);
|
||||
static void read_packet(packet_t *);
|
||||
static void write_packet(packet_t *);
|
||||
|
||||
static bool GetIso14443aCommandFromReaderInterruptible(uint8_t*, uint8_t*, int*);
|
||||
static bool GetIso14443aCommandFromReaderInterruptible(uint8_t *, uint8_t *, int *);
|
||||
|
||||
|
||||
void RunMod(void) {
|
||||
StandAloneMode();
|
||||
DbpString(_CYAN_("[@]") " CardHopper has started - waiting for mode");
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
StandAloneMode();
|
||||
DbpString(_CYAN_("[@]") " CardHopper has started - waiting for mode");
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
|
||||
// Indicate we are alive and in CardHopper
|
||||
LEDsoff();
|
||||
LED_A_ON();
|
||||
LED_D_ON();
|
||||
// Indicate we are alive and in CardHopper
|
||||
LEDsoff();
|
||||
LED_A_ON();
|
||||
LED_D_ON();
|
||||
|
||||
while (1) {
|
||||
WDT_HIT();
|
||||
while (1) {
|
||||
WDT_HIT();
|
||||
|
||||
packet_t modeRx = { 0 };
|
||||
read_packet(&modeRx);
|
||||
packet_t modeRx = { 0 };
|
||||
read_packet(&modeRx);
|
||||
|
||||
if (memcmp(magicREAD, modeRx.dat, sizeof(magicREAD)) == 0) {
|
||||
DbpString(_CYAN_("[@]") " I am a READER. I talk to a CARD.");
|
||||
become_reader();
|
||||
} else if (memcmp(magicCARD, modeRx.dat, sizeof(magicCARD)) == 0) {
|
||||
DbpString(_CYAN_("[@]") " I am a CARD. I talk to a READER.");
|
||||
become_card();
|
||||
} else if (memcmp(magicEND, modeRx.dat, sizeof(magicEND)) == 0) {
|
||||
break;
|
||||
} else {
|
||||
DbpString(_YELLOW_("[!]") " unknown mode!");
|
||||
Dbhexdump(modeRx.len, modeRx.dat, true);
|
||||
if (memcmp(magicREAD, modeRx.dat, sizeof(magicREAD)) == 0) {
|
||||
DbpString(_CYAN_("[@]") " I am a READER. I talk to a CARD.");
|
||||
become_reader();
|
||||
} else if (memcmp(magicCARD, modeRx.dat, sizeof(magicCARD)) == 0) {
|
||||
DbpString(_CYAN_("[@]") " I am a CARD. I talk to a READER.");
|
||||
become_card();
|
||||
} else if (memcmp(magicEND, modeRx.dat, sizeof(magicEND)) == 0) {
|
||||
break;
|
||||
} else {
|
||||
DbpString(_YELLOW_("[!]") " unknown mode!");
|
||||
Dbhexdump(modeRx.len, modeRx.dat, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DbpString(_CYAN_("[@]") " exiting ...");
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
DbpString(_CYAN_("[@]") " exiting ...");
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
|
||||
static void become_reader(void) {
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
||||
select_card(); // also sends UID, ATS
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
||||
select_card(); // also sends UID, ATS
|
||||
|
||||
DbpString(_CYAN_("[@]") " entering reader main loop ...");
|
||||
packet_t packet = { 0 };
|
||||
packet_t *rx = &packet;
|
||||
packet_t *tx = &packet;
|
||||
uint8_t toCard[256] = { 0 };
|
||||
uint8_t parity[MAX_PARITY_SIZE] = { 0 };
|
||||
DbpString(_CYAN_("[@]") " entering reader main loop ...");
|
||||
packet_t packet = { 0 };
|
||||
packet_t *rx = &packet;
|
||||
packet_t *tx = &packet;
|
||||
uint8_t toCard[256] = { 0 };
|
||||
uint8_t parity[MAX_PARITY_SIZE] = { 0 };
|
||||
|
||||
while(1) {
|
||||
WDT_HIT();
|
||||
while (1) {
|
||||
WDT_HIT();
|
||||
|
||||
read_packet(rx);
|
||||
if (memcmp(magicRSRT, rx->dat, sizeof(magicRSRT)) == 0) break;
|
||||
read_packet(rx);
|
||||
if (memcmp(magicRSRT, rx->dat, sizeof(magicRSRT)) == 0) break;
|
||||
|
||||
memcpy(toCard, rx->dat, rx->len);
|
||||
AddCrc14A(toCard, rx->len);
|
||||
ReaderTransmit(toCard, rx->len + 2, NULL);
|
||||
memcpy(toCard, rx->dat, rx->len);
|
||||
AddCrc14A(toCard, rx->len);
|
||||
ReaderTransmit(toCard, rx->len + 2, NULL);
|
||||
|
||||
tx->len = ReaderReceive(tx->dat, parity);
|
||||
if (tx->len == 0) {
|
||||
tx->len = sizeof(magicERR);
|
||||
memcpy(tx->dat, magicERR, sizeof(magicERR));
|
||||
} else tx->len -= 2; // cut off the CRC
|
||||
tx->len = ReaderReceive(tx->dat, parity);
|
||||
if (tx->len == 0) {
|
||||
tx->len = sizeof(magicERR);
|
||||
memcpy(tx->dat, magicERR, sizeof(magicERR));
|
||||
} else tx->len -= 2; // cut off the CRC
|
||||
|
||||
write_packet(tx);
|
||||
}
|
||||
write_packet(tx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void select_card(void) {
|
||||
iso14a_card_select_t card = { 0 };
|
||||
while(1) {
|
||||
WDT_HIT();
|
||||
iso14a_card_select_t card = { 0 };
|
||||
while (1) {
|
||||
WDT_HIT();
|
||||
|
||||
int ret = iso14443a_select_card(NULL, &card, NULL, true, 0, false);
|
||||
if (ret && ret != 1)
|
||||
Dbprintf(_RED_("[!]") " Error selecting card: %d", ret);
|
||||
if (ret == 1) break;
|
||||
int ret = iso14443a_select_card(NULL, &card, NULL, true, 0, false);
|
||||
if (ret && ret != 1)
|
||||
Dbprintf(_RED_("[!]") " Error selecting card: %d", ret);
|
||||
if (ret == 1) break;
|
||||
|
||||
SpinDelay(20);
|
||||
}
|
||||
SpinDelay(20);
|
||||
}
|
||||
|
||||
DbpString(_CYAN_("[@]") " UID:");
|
||||
Dbhexdump(card.uidlen, card.uid, false);
|
||||
DbpString(_CYAN_("[@]") " ATS:");
|
||||
Dbhexdump(card.ats_len - 2 /* no CRC */, card.ats, false);
|
||||
DbpString(_CYAN_("[@]") " UID:");
|
||||
Dbhexdump(card.uidlen, card.uid, false);
|
||||
DbpString(_CYAN_("[@]") " ATS:");
|
||||
Dbhexdump(card.ats_len - 2 /* no CRC */, card.ats, false);
|
||||
|
||||
packet_t tx = { 0 };
|
||||
tx.len = card.uidlen;
|
||||
memcpy(tx.dat, card.uid, tx.len);
|
||||
write_packet(&tx);
|
||||
packet_t tx = { 0 };
|
||||
tx.len = card.uidlen;
|
||||
memcpy(tx.dat, card.uid, tx.len);
|
||||
write_packet(&tx);
|
||||
|
||||
tx.len = card.ats_len - 2;
|
||||
memcpy(tx.dat, card.ats, tx.len);
|
||||
write_packet(&tx);
|
||||
tx.len = card.ats_len - 2;
|
||||
memcpy(tx.dat, card.ats, tx.len);
|
||||
write_packet(&tx);
|
||||
}
|
||||
|
||||
|
||||
static void become_card(void) {
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
||||
|
||||
uint8_t tagType;
|
||||
uint16_t flags;
|
||||
uint8_t data[PM3_CMD_DATA_SIZE] = { 0 };
|
||||
packet_t ats = { 0 };
|
||||
prepare_emulation(&tagType, &flags, data, &ats);
|
||||
uint8_t tagType;
|
||||
uint16_t flags;
|
||||
uint8_t data[PM3_CMD_DATA_SIZE] = { 0 };
|
||||
packet_t ats = { 0 };
|
||||
prepare_emulation(&tagType, &flags, data, &ats);
|
||||
|
||||
tag_response_info_t *canned;
|
||||
uint32_t cuid;
|
||||
uint32_t counters[3] = { 0 };
|
||||
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
|
||||
uint8_t pages;
|
||||
SimulateIso14443aInit(tagType, flags, data, &canned, &cuid, counters, tearings, &pages);
|
||||
tag_response_info_t *canned;
|
||||
uint32_t cuid;
|
||||
uint32_t counters[3] = { 0 };
|
||||
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
|
||||
uint8_t pages;
|
||||
SimulateIso14443aInit(tagType, flags, data, &canned, &cuid, counters, tearings, &pages);
|
||||
|
||||
DbpString(_CYAN_("[@]") " Setup done - entering emulation loop");
|
||||
int fromReaderLen;
|
||||
uint8_t fromReaderDat[256] = { 0 };
|
||||
uint8_t parity[MAX_PARITY_SIZE] = { 0 };
|
||||
packet_t packet = { 0 };
|
||||
packet_t *tx = &packet;
|
||||
packet_t *rx = &packet;
|
||||
DbpString(_CYAN_("[@]") " Setup done - entering emulation loop");
|
||||
int fromReaderLen;
|
||||
uint8_t fromReaderDat[256] = { 0 };
|
||||
uint8_t parity[MAX_PARITY_SIZE] = { 0 };
|
||||
packet_t packet = { 0 };
|
||||
packet_t *tx = &packet;
|
||||
packet_t *rx = &packet;
|
||||
|
||||
while (1) {
|
||||
WDT_HIT();
|
||||
while (1) {
|
||||
WDT_HIT();
|
||||
|
||||
if (!GetIso14443aCommandFromReaderInterruptible(fromReaderDat, parity, &fromReaderLen)) {
|
||||
if (usart_rxdata_available()) {
|
||||
read_packet(rx);
|
||||
if (memcmp(magicRSRT, rx->dat, sizeof(magicRSRT)) == 0) {
|
||||
DbpString(_CYAN_("[@]") " Breaking from reader loop");
|
||||
break;
|
||||
if (!GetIso14443aCommandFromReaderInterruptible(fromReaderDat, parity, &fromReaderLen)) {
|
||||
if (usart_rxdata_available()) {
|
||||
read_packet(rx);
|
||||
if (memcmp(magicRSRT, rx->dat, sizeof(magicRSRT)) == 0) {
|
||||
DbpString(_CYAN_("[@]") " Breaking from reader loop");
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
// Option 1: Use a canned response
|
||||
if (try_use_canned_response(fromReaderDat, fromReaderLen, canned)) continue;
|
||||
|
||||
// Option 2: Reply with our cooked ATS
|
||||
if (fromReaderDat[0] == ISO14443A_CMD_RATS && fromReaderLen == 4) {
|
||||
reply_with_packet(&ats);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Option 3: Relay the message
|
||||
tx->len = fromReaderLen - 2; // cut off the crc
|
||||
memcpy(tx->dat, fromReaderDat, tx->len);
|
||||
write_packet(tx);
|
||||
|
||||
read_packet(rx);
|
||||
reply_with_packet(rx);
|
||||
}
|
||||
|
||||
// Option 1: Use a canned response
|
||||
if (try_use_canned_response(fromReaderDat, fromReaderLen, canned)) continue;
|
||||
|
||||
// Option 2: Reply with our cooked ATS
|
||||
if (fromReaderDat[0] == ISO14443A_CMD_RATS && fromReaderLen == 4) {
|
||||
reply_with_packet(&ats);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Option 3: Relay the message
|
||||
tx->len = fromReaderLen - 2; // cut off the crc
|
||||
memcpy(tx->dat, fromReaderDat, tx->len);
|
||||
write_packet(tx);
|
||||
|
||||
read_packet(rx);
|
||||
reply_with_packet(rx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void prepare_emulation(uint8_t *tagType, uint16_t *flags, uint8_t *data, packet_t *ats) {
|
||||
packet_t tagTypeRx = { 0 }; read_packet(&tagTypeRx);
|
||||
packet_t timeModeRx = { 0 }; read_packet(&timeModeRx);
|
||||
packet_t uidRx = { 0 }; read_packet(&uidRx);
|
||||
read_packet(ats);
|
||||
packet_t tagTypeRx = { 0 };
|
||||
read_packet(&tagTypeRx);
|
||||
packet_t timeModeRx = { 0 };
|
||||
read_packet(&timeModeRx);
|
||||
packet_t uidRx = { 0 };
|
||||
read_packet(&uidRx);
|
||||
read_packet(ats);
|
||||
|
||||
*tagType = tagTypeRx.dat[0];
|
||||
Dbprintf(_CYAN_("[@]") " Using tag type: %hhu", *tagType);
|
||||
*tagType = tagTypeRx.dat[0];
|
||||
Dbprintf(_CYAN_("[@]") " Using tag type: %hhu", *tagType);
|
||||
|
||||
DbpString(_CYAN_("[@]") " Time control parameters:");
|
||||
Dbhexdump(timeModeRx.len, timeModeRx.dat, false);
|
||||
uint8_t fwi = timeModeRx.dat[0] & 0x0f;
|
||||
uint8_t sfgi = timeModeRx.dat[1] & 0x0f;
|
||||
Dbprintf(_CYAN_("[@]") " Parsed as fwi = %hhu, sfgi = %hhu", fwi, sfgi);
|
||||
DbpString(_CYAN_("[@]") " Time control parameters:");
|
||||
Dbhexdump(timeModeRx.len, timeModeRx.dat, false);
|
||||
uint8_t fwi = timeModeRx.dat[0] & 0x0f;
|
||||
uint8_t sfgi = timeModeRx.dat[1] & 0x0f;
|
||||
Dbprintf(_CYAN_("[@]") " Parsed as fwi = %hhu, sfgi = %hhu", fwi, sfgi);
|
||||
|
||||
if (fwi == 0xf) {
|
||||
DbpString(_YELLOW_("[!]") " Refusing to use 15 as FWI - will use 14");
|
||||
fwi = 0xe;
|
||||
}
|
||||
if (sfgi == 0xf) {
|
||||
DbpString(_YELLOW_("[!]") " Refusing to use 15 as SFGI - will use 14");
|
||||
sfgi = 0xe;
|
||||
}
|
||||
if (fwi == 0xf) {
|
||||
DbpString(_YELLOW_("[!]") " Refusing to use 15 as FWI - will use 14");
|
||||
fwi = 0xe;
|
||||
}
|
||||
if (sfgi == 0xf) {
|
||||
DbpString(_YELLOW_("[!]") " Refusing to use 15 as SFGI - will use 14");
|
||||
sfgi = 0xe;
|
||||
}
|
||||
|
||||
memcpy(data, uidRx.dat, uidRx.len);
|
||||
*flags = (uidRx.len == 10 ? FLAG_10B_UID_IN_DATA : (uidRx.len == 7 ? FLAG_7B_UID_IN_DATA : FLAG_4B_UID_IN_DATA));
|
||||
DbpString(_CYAN_("[@]") " UID:");
|
||||
Dbhexdump(uidRx.len, data, false);
|
||||
Dbprintf(_CYAN_("[@]") " Flags: %hu", *flags);
|
||||
memcpy(data, uidRx.dat, uidRx.len);
|
||||
*flags = (uidRx.len == 10 ? FLAG_10B_UID_IN_DATA : (uidRx.len == 7 ? FLAG_7B_UID_IN_DATA : FLAG_4B_UID_IN_DATA));
|
||||
DbpString(_CYAN_("[@]") " UID:");
|
||||
Dbhexdump(uidRx.len, data, false);
|
||||
Dbprintf(_CYAN_("[@]") " Flags: %hu", *flags);
|
||||
|
||||
DbpString(_CYAN_("[@]") " Original ATS:");
|
||||
Dbhexdump(ats->len, ats->dat, false);
|
||||
cook_ats(ats, fwi, sfgi);
|
||||
DbpString(_CYAN_("[@]") " Cooked ATS:");
|
||||
Dbhexdump(ats->len, ats->dat, false);
|
||||
DbpString(_CYAN_("[@]") " Original ATS:");
|
||||
Dbhexdump(ats->len, ats->dat, false);
|
||||
cook_ats(ats, fwi, sfgi);
|
||||
DbpString(_CYAN_("[@]") " Cooked ATS:");
|
||||
Dbhexdump(ats->len, ats->dat, false);
|
||||
}
|
||||
|
||||
|
||||
static void cook_ats(packet_t *ats, uint8_t fwi, uint8_t sfgi) {
|
||||
if (ats->len != ats->dat[0]) {
|
||||
DbpString(_RED_("[!]") " Malformed ATS - unable to cook; things may go wrong!");
|
||||
return;
|
||||
}
|
||||
if (ats->len != ats->dat[0]) {
|
||||
DbpString(_RED_("[!]") " Malformed ATS - unable to cook; things may go wrong!");
|
||||
return;
|
||||
}
|
||||
|
||||
// If the ATS is too short (unusual), pad it to length with hopefully-sensible data
|
||||
// Might be better for the phone side to do this tbh
|
||||
if (ats->len == 1) {
|
||||
ats->len = 4;
|
||||
ats->dat[0] = 0x04; ats->dat[1] = 0x78; ats->dat[2] = 0x77; ats->dat[3] = 0x80;
|
||||
} else if (ats->len == 2) {
|
||||
ats->len = 4;
|
||||
ats->dat[0] = 0x04; ats->dat[2] = 0x77; ats->dat[3] = 0x80;
|
||||
} else if (ats->len == 3) {
|
||||
ats->len = 4;
|
||||
ats->dat[0] = 0x04; ats->dat[3] = 0x80;
|
||||
}
|
||||
// If the ATS is too short (unusual), pad it to length with hopefully-sensible data
|
||||
// Might be better for the phone side to do this tbh
|
||||
if (ats->len == 1) {
|
||||
ats->len = 4;
|
||||
ats->dat[0] = 0x04;
|
||||
ats->dat[1] = 0x78;
|
||||
ats->dat[2] = 0x77;
|
||||
ats->dat[3] = 0x80;
|
||||
} else if (ats->len == 2) {
|
||||
ats->len = 4;
|
||||
ats->dat[0] = 0x04;
|
||||
ats->dat[2] = 0x77;
|
||||
ats->dat[3] = 0x80;
|
||||
} else if (ats->len == 3) {
|
||||
ats->len = 4;
|
||||
ats->dat[0] = 0x04;
|
||||
ats->dat[3] = 0x80;
|
||||
}
|
||||
|
||||
// Set the SFGI as well as the FWI - needed for some older readers (firmware revs?)
|
||||
uint8_t cookedTB0 = (fwi << 4) | sfgi;
|
||||
ats->dat[3] = cookedTB0;
|
||||
// Set the SFGI as well as the FWI - needed for some older readers (firmware revs?)
|
||||
uint8_t cookedTB0 = (fwi << 4) | sfgi;
|
||||
ats->dat[3] = cookedTB0;
|
||||
}
|
||||
|
||||
|
||||
static bool try_use_canned_response(uint8_t *dat, int len, tag_response_info_t *canned) {
|
||||
if ((dat[0] == ISO14443A_CMD_REQA || dat[0] == ISO14443A_CMD_WUPA) && len == 1) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_ATQA);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (dat[1] == 0x20 && len == 2) {
|
||||
if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_UIDC1);
|
||||
return true;
|
||||
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_UIDC2);
|
||||
return true;
|
||||
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_UIDC3);
|
||||
return true;
|
||||
if ((dat[0] == ISO14443A_CMD_REQA || dat[0] == ISO14443A_CMD_WUPA) && len == 1) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_ATQA);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dat[1] == 0x70 && len == 9) {
|
||||
if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_SAKC1);
|
||||
return true;
|
||||
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_SAKC2);
|
||||
return true;
|
||||
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_SAKC3);
|
||||
return true;
|
||||
if (dat[1] == 0x20 && len == 2) {
|
||||
if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_UIDC1);
|
||||
return true;
|
||||
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_UIDC2);
|
||||
return true;
|
||||
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_UIDC3);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dat[0] == ISO14443A_CMD_PPS) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_PPS);
|
||||
return true;
|
||||
}
|
||||
if (dat[1] == 0x70 && len == 9) {
|
||||
if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_SAKC1);
|
||||
return true;
|
||||
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_SAKC2);
|
||||
return true;
|
||||
} else if (dat[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_SAKC3);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// No response is expected to these 14a commands
|
||||
if ((dat[0] == 0xf2 && len == 4) || dat[0] == 0xfa) return true;
|
||||
if (dat[0] == ISO14443A_CMD_HALT && len == 4) return true;
|
||||
if (dat[0] == ISO14443A_CMD_PPS) {
|
||||
EmSendPrecompiledCmd(canned + RESP_INDEX_PPS);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ignore Apple ECP2 polling
|
||||
if (dat[0] == 0x6a) return true;
|
||||
// No response is expected to these 14a commands
|
||||
if ((dat[0] == 0xf2 && len == 4) || dat[0] == 0xfa) return true;
|
||||
if (dat[0] == ISO14443A_CMD_HALT && len == 4) return true;
|
||||
|
||||
return false;
|
||||
// Ignore Apple ECP2 polling
|
||||
if (dat[0] == 0x6a) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -336,73 +345,73 @@ static uint8_t g_responseBuffer [512 ] = { 0 };
|
|||
static uint8_t g_modulationBuffer[1024] = { 0 };
|
||||
|
||||
static void reply_with_packet(packet_t *packet) {
|
||||
tag_response_info_t response = { 0 };
|
||||
response.response = g_responseBuffer;
|
||||
response.modulation = g_modulationBuffer;
|
||||
tag_response_info_t response = { 0 };
|
||||
response.response = g_responseBuffer;
|
||||
response.modulation = g_modulationBuffer;
|
||||
|
||||
memcpy(response.response, packet->dat, packet->len);
|
||||
AddCrc14A(response.response, packet->len);
|
||||
response.response_n = packet->len + 2;
|
||||
memcpy(response.response, packet->dat, packet->len);
|
||||
AddCrc14A(response.response, packet->len);
|
||||
response.response_n = packet->len + 2;
|
||||
|
||||
prepare_tag_modulation(&response, sizeof(g_modulationBuffer));
|
||||
EmSendPrecompiledCmd(&response);
|
||||
prepare_tag_modulation(&response, sizeof(g_modulationBuffer));
|
||||
EmSendPrecompiledCmd(&response);
|
||||
}
|
||||
|
||||
|
||||
static void read_packet(packet_t *packet) {
|
||||
while(!usart_rxdata_available()) {
|
||||
WDT_HIT();
|
||||
SpinDelayUs(100);
|
||||
}
|
||||
while (!usart_rxdata_available()) {
|
||||
WDT_HIT();
|
||||
SpinDelayUs(100);
|
||||
}
|
||||
|
||||
uint32_t dataReceived = usart_read_ng((uint8_t*) packet, sizeof(packet_t)) - 1;
|
||||
while(dataReceived != packet->len) {
|
||||
while(!usart_rxdata_available()) WDT_HIT();
|
||||
uint32_t dataReceived = usart_read_ng((uint8_t *) packet, sizeof(packet_t)) - 1;
|
||||
while (dataReceived != packet->len) {
|
||||
while (!usart_rxdata_available()) WDT_HIT();
|
||||
|
||||
dataReceived += usart_read_ng(packet->dat + dataReceived, 255 - dataReceived);
|
||||
}
|
||||
usart_writebuffer_sync(magicACK, sizeof(magicACK));
|
||||
dataReceived += usart_read_ng(packet->dat + dataReceived, 255 - dataReceived);
|
||||
}
|
||||
usart_writebuffer_sync(magicACK, sizeof(magicACK));
|
||||
}
|
||||
|
||||
|
||||
static void write_packet(packet_t *packet) {
|
||||
usart_writebuffer_sync((uint8_t*) packet, packet->len + 1);
|
||||
usart_writebuffer_sync((uint8_t *) packet, packet->len + 1);
|
||||
}
|
||||
|
||||
|
||||
static bool GetIso14443aCommandFromReaderInterruptible(uint8_t *received, uint8_t *par, int *len) {
|
||||
LED_D_OFF();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
||||
LED_D_OFF();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
||||
|
||||
Uart14aInit(received, par);
|
||||
Uart14aInit(received, par);
|
||||
|
||||
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
(void)b;
|
||||
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
(void)b;
|
||||
|
||||
uint8_t flip = 0;
|
||||
uint16_t checker = 4000;
|
||||
for (;;) {
|
||||
WDT_HIT();
|
||||
uint8_t flip = 0;
|
||||
uint16_t checker = 4000;
|
||||
for (;;) {
|
||||
WDT_HIT();
|
||||
|
||||
if (flip == 3) {
|
||||
if (usart_rxdata_available())
|
||||
return false;
|
||||
if (flip == 3) {
|
||||
if (usart_rxdata_available())
|
||||
return false;
|
||||
|
||||
flip = 0;
|
||||
flip = 0;
|
||||
}
|
||||
|
||||
if (checker-- == 0) {
|
||||
flip++;
|
||||
checker = 4000;
|
||||
}
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
if (MillerDecoding(b, 0)) {
|
||||
*len = GetUart14a()->len;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (checker-- == 0) {
|
||||
flip++;
|
||||
checker = 4000;
|
||||
}
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
if (MillerDecoding(b, 0)) {
|
||||
*len = GetUart14a()->len;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -376,27 +376,27 @@ static int bruteforce(const uint8_t address, const uint8_t *rnd, const uint8_t *
|
|||
uint16_t rev_k = reflect16(k);
|
||||
switch (address) {
|
||||
case 9:
|
||||
c = set_byte(&temp_rnd[0], rev_rnd[0] + ((rev_k ) & 0xFFu));
|
||||
c = set_byte(&temp_rnd[0], rev_rnd[0] + ((rev_k) & 0xFFu));
|
||||
c = set_byte(&temp_rnd[1], rev_rnd[1] + c + ((rev_k >> 8) & 0xFFu));
|
||||
c = set_byte(&temp_rnd[2], rev_rnd[2] + c);
|
||||
c = set_byte(&temp_rnd[3], rev_rnd[3] + c);
|
||||
c = set_byte(&temp_rnd[4], rev_rnd[4] + c);
|
||||
c = set_byte(&temp_rnd[5], rev_rnd[5] + c);
|
||||
set_byte( &temp_rnd[6], rev_rnd[6] + c);
|
||||
set_byte(&temp_rnd[6], rev_rnd[6] + c);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
c = set_byte(&temp_rnd[2], rev_rnd[2] + ((rev_k ) & 0xFFu));
|
||||
c = set_byte(&temp_rnd[2], rev_rnd[2] + ((rev_k) & 0xFFu));
|
||||
c = set_byte(&temp_rnd[3], rev_rnd[3] + c + ((rev_k >> 8) & 0xFFu));
|
||||
c = set_byte(&temp_rnd[4], rev_rnd[4] + c);
|
||||
c = set_byte(&temp_rnd[5], rev_rnd[5] + c);
|
||||
set_byte( &temp_rnd[6], rev_rnd[6] + c);
|
||||
set_byte(&temp_rnd[6], rev_rnd[6] + c);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
c = set_byte(&temp_rnd[4], rev_rnd[4] + ((rev_k ) & 0xFFu));
|
||||
c = set_byte(&temp_rnd[4], rev_rnd[4] + ((rev_k) & 0xFFu));
|
||||
c = set_byte(&temp_rnd[5], rev_rnd[5] + c + ((rev_k >> 8) & 0xFFu));
|
||||
set_byte( &temp_rnd[6], rev_rnd[6] + c);
|
||||
set_byte(&temp_rnd[6], rev_rnd[6] + c);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -853,8 +853,8 @@ void em4x70_write_pin(const em4x70_data_t *etd, bool ledcontrol) {
|
|||
if (em4x70_read_id()) {
|
||||
|
||||
// Write new PIN
|
||||
if ((write((etd->pin ) & 0xFFFF, EM4X70_PIN_WORD_UPPER) == PM3_SUCCESS) &&
|
||||
(write((etd->pin >> 16) & 0xFFFF, EM4X70_PIN_WORD_LOWER) == PM3_SUCCESS)) {
|
||||
if ((write((etd->pin) & 0xFFFF, EM4X70_PIN_WORD_UPPER) == PM3_SUCCESS) &&
|
||||
(write((etd->pin >> 16) & 0xFFFF, EM4X70_PIN_WORD_LOWER) == PM3_SUCCESS)) {
|
||||
|
||||
// Now Try to authenticate using the new PIN
|
||||
|
||||
|
|
|
@ -111,27 +111,27 @@ void SetupSpi(int mode) {
|
|||
AT91C_SPI_NCPHA | // Clock Phase data captured on leading edge, changes on following edge
|
||||
(0 << 0); // Clock Polarity inactive state is logic 0
|
||||
break;
|
||||
/*
|
||||
case SPI_LCD_MODE:
|
||||
AT91C_BASE_SPI->SPI_MR =
|
||||
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
|
||||
(0xB << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
|
||||
( 0 << 7) | // Local Loopback Disabled
|
||||
( 1 << 4) | // Mode Fault Detection disabled
|
||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||
( 0 << 1) | // Fixed Peripheral Select
|
||||
( 1 << 0); // Master Mode
|
||||
/*
|
||||
case SPI_LCD_MODE:
|
||||
AT91C_BASE_SPI->SPI_MR =
|
||||
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
|
||||
(0xB << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
|
||||
( 0 << 7) | // Local Loopback Disabled
|
||||
( 1 << 4) | // Mode Fault Detection disabled
|
||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||
( 0 << 1) | // Fixed Peripheral Select
|
||||
( 1 << 0); // Master Mode
|
||||
|
||||
AT91C_BASE_SPI->SPI_CSR[2] =
|
||||
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
||||
( 1 << 16) | // Delay Before SPCK (1 MCK period)
|
||||
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24MHz/6 = 4M baud
|
||||
AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits)
|
||||
( 0 << 3) | // Chip Select inactive after transfer
|
||||
( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||
break;
|
||||
*/
|
||||
AT91C_BASE_SPI->SPI_CSR[2] =
|
||||
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
||||
( 1 << 16) | // Delay Before SPCK (1 MCK period)
|
||||
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24MHz/6 = 4M baud
|
||||
AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits)
|
||||
( 0 << 3) | // Chip Select inactive after transfer
|
||||
( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
DisableSpi();
|
||||
break;
|
||||
|
|
|
@ -90,17 +90,17 @@ uint32_t _hitag2_byte(uint64_t *x) {
|
|||
}
|
||||
|
||||
void hitag2_cipher_reset(struct hitag2_tag *tag, const uint8_t *iv) {
|
||||
uint64_t key = ((uint64_t)tag->sectors[2][2] ) |
|
||||
uint64_t key = ((uint64_t)tag->sectors[2][2]) |
|
||||
((uint64_t)tag->sectors[2][3] << 8) |
|
||||
((uint64_t)tag->sectors[1][0] << 16) |
|
||||
((uint64_t)tag->sectors[1][1] << 24) |
|
||||
((uint64_t)tag->sectors[1][2] << 32) |
|
||||
((uint64_t)tag->sectors[1][3] << 40);
|
||||
uint32_t uid = ((uint32_t)tag->sectors[0][0] ) |
|
||||
uint32_t uid = ((uint32_t)tag->sectors[0][0]) |
|
||||
((uint32_t)tag->sectors[0][1] << 8) |
|
||||
((uint32_t)tag->sectors[0][2] << 16) |
|
||||
((uint32_t)tag->sectors[0][3] << 24);
|
||||
uint32_t iv_ = (((uint32_t)(iv[0])) ) |
|
||||
uint32_t iv_ = (((uint32_t)(iv[0]))) |
|
||||
(((uint32_t)(iv[1])) << 8) |
|
||||
(((uint32_t)(iv[2])) << 16) |
|
||||
(((uint32_t)(iv[3])) << 24);
|
||||
|
|
|
@ -199,7 +199,7 @@ int rdv40_spiffs_check(void) {
|
|||
void write_to_spiffs(const char *filename, const uint8_t *src, uint32_t size) {
|
||||
spiffs_file fd = SPIFFS_open(&fs, filename, SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
|
||||
// Note: SPIFFS_write() doesn't declare third parameter as const (but should)
|
||||
if (SPIFFS_write(&fs, fd, (void*)src, size) < 0) {
|
||||
if (SPIFFS_write(&fs, fd, (void *)src, size) < 0) {
|
||||
Dbprintf("wr errno %i\n", SPIFFS_errno(&fs));
|
||||
}
|
||||
SPIFFS_close(&fs, fd);
|
||||
|
@ -208,7 +208,7 @@ void write_to_spiffs(const char *filename, const uint8_t *src, uint32_t size) {
|
|||
void append_to_spiffs(const char *filename, const uint8_t *src, uint32_t size) {
|
||||
spiffs_file fd = SPIFFS_open(&fs, filename, SPIFFS_APPEND | SPIFFS_RDWR, 0);
|
||||
// Note: SPIFFS_write() doesn't declare third parameter as const (but should)
|
||||
if (SPIFFS_write(&fs, fd, (void*)src, size) < 0) {
|
||||
if (SPIFFS_write(&fs, fd, (void *)src, size) < 0) {
|
||||
Dbprintf("errno %i\n", SPIFFS_errno(&fs));
|
||||
}
|
||||
SPIFFS_close(&fs, fd);
|
||||
|
|
|
@ -42,8 +42,10 @@
|
|||
|
||||
#define PICOPASS_BLOCK_SIZE 8
|
||||
#define NUM_CSNS 9
|
||||
#define MAC_ITEM_SIZE 24 // csn(8) + epurse(8) + nr(4) + mac(4) = 24 bytes
|
||||
#define ICLASS_KEYS_MAX 8
|
||||
#define ICLASS_AUTH_RETRY 10
|
||||
#define ICLASS_CFG_BLK_SR_BIT 0xA0 // indicates SIO present when set in block6[0] (legacy tags)
|
||||
#define ICLASS_DECRYPTION_BIN "iclass_decryptionkey.bin"
|
||||
|
||||
static void print_picopass_info(const picopass_hdr_t *hdr);
|
||||
|
@ -54,13 +56,13 @@ static void iclass_set_last_known_card(picopass_hdr_t *card) {
|
|||
memcpy(&iclass_last_known_card, card, sizeof(picopass_hdr_t));
|
||||
}
|
||||
|
||||
static uint8_t empty[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
static uint8_t zeros[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
static uint8_t empty[PICOPASS_BLOCK_SIZE] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
static uint8_t zeros[PICOPASS_BLOCK_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
static void printIclassSIO(uint8_t *iclass_dump);
|
||||
|
||||
static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = {
|
||||
static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][PICOPASS_BLOCK_SIZE] = {
|
||||
{ 0xAE, 0xA6, 0x84, 0xA6, 0xDA, 0xB2, 0x32, 0x78 },
|
||||
{ 0xFD, 0xCB, 0x5A, 0x52, 0xEA, 0x8F, 0x30, 0x90 },
|
||||
{ 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87 },
|
||||
|
@ -747,7 +749,7 @@ static int CmdHFiClassSim(const char *Cmd) {
|
|||
// remember to change the define NUM_CSNS to match.
|
||||
|
||||
// pre-defined 9 CSN by iceman
|
||||
uint8_t csns[8 * NUM_CSNS] = {
|
||||
uint8_t csns[NUM_CSNS * PICOPASS_BLOCK_SIZE] = {
|
||||
0x01, 0x0A, 0x0F, 0xFF, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x0C, 0x06, 0x0C, 0xFE, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
0x10, 0x97, 0x83, 0x7B, 0xF7, 0xFF, 0x12, 0xE0,
|
||||
|
@ -779,7 +781,7 @@ static int CmdHFiClassSim(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "press " _YELLOW_("`enter`") " to cancel");
|
||||
PacketResponseNG resp;
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ICLASS_SIMULATE, sim_type, NUM_CSNS, 1, csns, 8 * NUM_CSNS);
|
||||
SendCommandMIX(CMD_HF_ICLASS_SIMULATE, sim_type, NUM_CSNS, 1, csns, NUM_CSNS * PICOPASS_BLOCK_SIZE);
|
||||
|
||||
while (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
|
||||
tries++;
|
||||
|
@ -799,7 +801,7 @@ static int CmdHFiClassSim(const char *Cmd) {
|
|||
if (num_mac == 0)
|
||||
break;
|
||||
|
||||
size_t datalen = NUM_CSNS * 24;
|
||||
size_t datalen = NUM_CSNS * MAC_ITEM_SIZE;
|
||||
uint8_t *dump = calloc(datalen, sizeof(uint8_t));
|
||||
if (!dump) {
|
||||
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
||||
|
@ -811,11 +813,11 @@ static int CmdHFiClassSim(const char *Cmd) {
|
|||
uint8_t i = 0;
|
||||
for (i = 0 ; i < NUM_CSNS ; i++) {
|
||||
//copy CSN
|
||||
memcpy(dump + i * 24, csns + i * 8, 8);
|
||||
memcpy(dump + (i * MAC_ITEM_SIZE), csns + i * 8, 8);
|
||||
//copy epurse
|
||||
memcpy(dump + i * 24 + 8, resp.data.asBytes + i * 16, 8);
|
||||
memcpy(dump + (i * MAC_ITEM_SIZE) + 8, resp.data.asBytes + i * 16, 8);
|
||||
// NR_MAC (eight bytes from the response) ( 8b csn + 8b epurse == 16)
|
||||
memcpy(dump + i * 24 + 16, resp.data.asBytes + i * 16 + 8, 8);
|
||||
memcpy(dump + (i * MAC_ITEM_SIZE) + 16, resp.data.asBytes + i * 16 + 8, 8);
|
||||
}
|
||||
/** Now, save to dumpfile **/
|
||||
saveFile("iclass_mac_attack", ".bin", dump, datalen);
|
||||
|
@ -830,7 +832,7 @@ static int CmdHFiClassSim(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "press Enter to cancel");
|
||||
PacketResponseNG resp;
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ICLASS_SIMULATE, sim_type, NUM_CSNS, 1, csns, 8 * NUM_CSNS);
|
||||
SendCommandMIX(CMD_HF_ICLASS_SIMULATE, sim_type, NUM_CSNS, 1, csns, NUM_CSNS * PICOPASS_BLOCK_SIZE);
|
||||
|
||||
while (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
|
||||
tries++;
|
||||
|
@ -850,25 +852,23 @@ static int CmdHFiClassSim(const char *Cmd) {
|
|||
if (num_mac == 0)
|
||||
break;
|
||||
|
||||
size_t datalen = NUM_CSNS * 24;
|
||||
size_t datalen = NUM_CSNS * MAC_ITEM_SIZE;
|
||||
uint8_t *dump = calloc(datalen, sizeof(uint8_t));
|
||||
if (!dump) {
|
||||
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
||||
#define MAC_ITEM_SIZE 24
|
||||
|
||||
//KEYROLL 1
|
||||
//Need zeroes for the CC-field
|
||||
memset(dump, 0, datalen);
|
||||
for (uint8_t i = 0; i < NUM_CSNS ; i++) {
|
||||
// copy CSN
|
||||
memcpy(dump + i * MAC_ITEM_SIZE, csns + i * 8, 8); //CSN
|
||||
memcpy(dump + (i * MAC_ITEM_SIZE), csns + i * 8, 8); //CSN
|
||||
// copy EPURSE
|
||||
memcpy(dump + i * MAC_ITEM_SIZE + 8, resp.data.asBytes + i * 16, 8);
|
||||
memcpy(dump + (i * MAC_ITEM_SIZE) + 8, resp.data.asBytes + i * 16, 8);
|
||||
// copy NR_MAC (eight bytes from the response) ( 8b csn + 8b epurse == 16)
|
||||
memcpy(dump + i * MAC_ITEM_SIZE + 16, resp.data.asBytes + i * 16 + 8, 8);
|
||||
memcpy(dump + (i * MAC_ITEM_SIZE) + 16, resp.data.asBytes + i * 16 + 8, 8);
|
||||
}
|
||||
saveFile("iclass_mac_attack_keyroll_A", ".bin", dump, datalen);
|
||||
|
||||
|
@ -877,11 +877,11 @@ static int CmdHFiClassSim(const char *Cmd) {
|
|||
for (uint8_t i = 0; i < NUM_CSNS; i++) {
|
||||
uint8_t resp_index = (i + NUM_CSNS) * 16;
|
||||
// Copy CSN
|
||||
memcpy(dump + i * MAC_ITEM_SIZE, csns + i * 8, 8);
|
||||
memcpy(dump + (i * MAC_ITEM_SIZE), csns + i * 8, 8);
|
||||
// copy EPURSE
|
||||
memcpy(dump + i * MAC_ITEM_SIZE + 8, resp.data.asBytes + resp_index, 8);
|
||||
memcpy(dump + (i * MAC_ITEM_SIZE) + 8, resp.data.asBytes + resp_index, 8);
|
||||
// copy NR_MAC (eight bytes from the response) ( 8b csn + 8 epurse == 16)
|
||||
memcpy(dump + i * MAC_ITEM_SIZE + 16, resp.data.asBytes + resp_index + 8, 8);
|
||||
memcpy(dump + (i * MAC_ITEM_SIZE) + 16, resp.data.asBytes + resp_index + 8, 8);
|
||||
resp_index++;
|
||||
}
|
||||
saveFile("iclass_mac_attack_keyroll_B", ".bin", dump, datalen);
|
||||
|
@ -2638,7 +2638,7 @@ static void detect_credential(uint8_t *data, bool *legacy, bool *se, bool *sr) {
|
|||
*legacy = true;
|
||||
|
||||
// SR bit set in legacy config block
|
||||
if ((data[6 * PICOPASS_BLOCK_SIZE] & 0xA0) == 0xA0) {
|
||||
if ((data[6 * PICOPASS_BLOCK_SIZE] & ICLASS_CFG_BLK_SR_BIT) == ICLASS_CFG_BLK_SR_BIT) {
|
||||
// If the card is blank (all FF's) then we'll reach here too, so check for an empty block 10
|
||||
// to avoid false positivies
|
||||
if (memcmp(data + (10 * PICOPASS_BLOCK_SIZE), "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", PICOPASS_BLOCK_SIZE)) {
|
||||
|
@ -2898,12 +2898,14 @@ static int CmdHFiClassView(const char *Cmd) {
|
|||
CLIParserInit(&ctx, "hf iclass view",
|
||||
"Print a iCLASS tag dump file (bin/eml/json)",
|
||||
"hf iclass view -f hf-iclass-AA162D30F8FF12F1-dump.bin\n"
|
||||
"hf iclass view --first 1 -f hf-iclass-AA162D30F8FF12F1-dump.bin\n");
|
||||
"hf iclass view --first 1 -f hf-iclass-AA162D30F8FF12F1-dump.bin\n\n"
|
||||
"If --first is not specified it will default to the first user block\n"
|
||||
"which is block 6 for secured chips or block 3 for non-secured chips");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1("f", "file", "<fn>", "filename of dump (bin/eml/json)"),
|
||||
arg_int0(NULL, "first", "<dec>", "Begin printing from this block (default first user block - 6 or 3 on non secured chips)"),
|
||||
arg_int0(NULL, "first", "<dec>", "Begin printing from this block (default first user block)"),
|
||||
arg_int0(NULL, "last", "<dec>", "End printing at this block (default 0, ALL)"),
|
||||
arg_lit0("v", "verbose", "verbose output"),
|
||||
arg_lit0("z", "dense", "dense dump output style"),
|
||||
|
|
|
@ -854,7 +854,7 @@ void Plot::Zoom(double factor, uint32_t refX) {
|
|||
}
|
||||
}
|
||||
} else { // Zoom out
|
||||
if (g_GraphPixelsPerPointNew >= (1.0 / ZOOM_LIMIT) ) {
|
||||
if (g_GraphPixelsPerPointNew >= (1.0 / ZOOM_LIMIT)) {
|
||||
g_GraphPixelsPerPoint = g_GraphPixelsPerPointNew;
|
||||
// shift graph towards refX when zooming out
|
||||
if (refX > g_GraphStart) {
|
||||
|
@ -951,7 +951,7 @@ void Plot::wheelEvent(QWheelEvent *event) {
|
|||
Zoom(1.0 / ZOOM_STEP, x);
|
||||
}
|
||||
} else {
|
||||
Move(PageWidth * delta * move_offset / 120 );
|
||||
Move(PageWidth * delta * move_offset / 120);
|
||||
}
|
||||
this->update();
|
||||
}
|
||||
|
@ -981,7 +981,7 @@ void Plot::keyPressEvent(QKeyEvent *event) {
|
|||
if (event->modifiers() & Qt::ControlModifier)
|
||||
offset = 1;
|
||||
else
|
||||
offset = int(ZOOM_LIMIT/g_GraphPixelsPerPoint);
|
||||
offset = int(ZOOM_LIMIT / g_GraphPixelsPerPoint);
|
||||
}
|
||||
|
||||
switch (event->key()) {
|
||||
|
@ -990,13 +990,13 @@ void Plot::keyPressEvent(QKeyEvent *event) {
|
|||
if (event->modifiers() & Qt::ControlModifier) {
|
||||
Zoom(ZOOM_STEP, CursorBPos);
|
||||
} else {
|
||||
Zoom(ZOOM_STEP*2, CursorBPos);
|
||||
Zoom(ZOOM_STEP * 2, CursorBPos);
|
||||
}
|
||||
} else {
|
||||
if (event->modifiers() & Qt::ControlModifier) {
|
||||
Zoom(ZOOM_STEP, CursorAPos);
|
||||
} else {
|
||||
Zoom(ZOOM_STEP*2, CursorAPos);
|
||||
Zoom(ZOOM_STEP * 2, CursorAPos);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1006,13 +1006,13 @@ void Plot::keyPressEvent(QKeyEvent *event) {
|
|||
if (event->modifiers() & Qt::ControlModifier) {
|
||||
Zoom(1.0 / ZOOM_STEP, CursorBPos);
|
||||
} else {
|
||||
Zoom(1.0 / (ZOOM_STEP*2), CursorBPos);
|
||||
Zoom(1.0 / (ZOOM_STEP * 2), CursorBPos);
|
||||
}
|
||||
} else {
|
||||
if (event->modifiers() & Qt::ControlModifier) {
|
||||
Zoom(1.0 / ZOOM_STEP, CursorAPos);
|
||||
} else {
|
||||
Zoom(1.0 / (ZOOM_STEP*2), CursorAPos);
|
||||
Zoom(1.0 / (ZOOM_STEP * 2), CursorAPos);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1266,6 +1266,8 @@ inline uint64_t leadingzeros64(uint64_t a) {
|
|||
}
|
||||
|
||||
|
||||
// byte_strstr searches for the first occurrence of pattern in src
|
||||
// returns the byte offset the pattern is found at, or -1 if not found
|
||||
int byte_strstr(const uint8_t *src, size_t srclen, const uint8_t *pattern, size_t plen) {
|
||||
|
||||
size_t max = srclen - plen + 1;
|
||||
|
@ -1289,6 +1291,9 @@ int byte_strstr(const uint8_t *src, size_t srclen, const uint8_t *pattern, size_
|
|||
return -1;
|
||||
}
|
||||
|
||||
// byte_strrstr is like byte_strstr except searches in reverse
|
||||
// ie it returns the last occurrence of the pattern in src instead of the first
|
||||
// returns the byte offset the pattern is found at, or -1 if not found
|
||||
int byte_strrstr(const uint8_t *src, size_t srclen, const uint8_t *pattern, size_t plen) {
|
||||
for (int i = srclen - plen; i >= 0; i--) {
|
||||
// compare only first byte
|
||||
|
|
|
@ -162,254 +162,254 @@ uint64_t bytes_to_num(const uint8_t *src, size_t len) {
|
|||
|
||||
uint16_t MemLeToUint2byte(const uint8_t *data) {
|
||||
return (uint16_t)(
|
||||
(((uint16_t)(data[1])) << (8*1)) +
|
||||
(((uint16_t)(data[0])) << (8*0))
|
||||
);
|
||||
(((uint16_t)(data[1])) << (8 * 1)) +
|
||||
(((uint16_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t MemLeToUint3byte(const uint8_t *data) {
|
||||
return (uint32_t)(
|
||||
(((uint32_t)(data[2])) << (8*2)) +
|
||||
(((uint32_t)(data[1])) << (8*1)) +
|
||||
(((uint32_t)(data[0])) << (8*0))
|
||||
);
|
||||
(((uint32_t)(data[2])) << (8 * 2)) +
|
||||
(((uint32_t)(data[1])) << (8 * 1)) +
|
||||
(((uint32_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t MemLeToUint4byte(const uint8_t *data) {
|
||||
return (uint32_t)(
|
||||
(((uint32_t)(data[3])) << (8*3)) +
|
||||
(((uint32_t)(data[2])) << (8*2)) +
|
||||
(((uint32_t)(data[1])) << (8*1)) +
|
||||
(((uint32_t)(data[0])) << (8*0))
|
||||
);
|
||||
(((uint32_t)(data[3])) << (8 * 3)) +
|
||||
(((uint32_t)(data[2])) << (8 * 2)) +
|
||||
(((uint32_t)(data[1])) << (8 * 1)) +
|
||||
(((uint32_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemLeToUint5byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[4])) << (8*4)) +
|
||||
(((uint64_t)(data[3])) << (8*3)) +
|
||||
(((uint64_t)(data[2])) << (8*2)) +
|
||||
(((uint64_t)(data[1])) << (8*1)) +
|
||||
(((uint64_t)(data[0])) << (8*0))
|
||||
);
|
||||
(((uint64_t)(data[4])) << (8 * 4)) +
|
||||
(((uint64_t)(data[3])) << (8 * 3)) +
|
||||
(((uint64_t)(data[2])) << (8 * 2)) +
|
||||
(((uint64_t)(data[1])) << (8 * 1)) +
|
||||
(((uint64_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemLeToUint6byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[5])) << (8*5)) +
|
||||
(((uint64_t)(data[4])) << (8*4)) +
|
||||
(((uint64_t)(data[3])) << (8*3)) +
|
||||
(((uint64_t)(data[2])) << (8*2)) +
|
||||
(((uint64_t)(data[1])) << (8*1)) +
|
||||
(((uint64_t)(data[0])) << (8*0))
|
||||
);
|
||||
(((uint64_t)(data[5])) << (8 * 5)) +
|
||||
(((uint64_t)(data[4])) << (8 * 4)) +
|
||||
(((uint64_t)(data[3])) << (8 * 3)) +
|
||||
(((uint64_t)(data[2])) << (8 * 2)) +
|
||||
(((uint64_t)(data[1])) << (8 * 1)) +
|
||||
(((uint64_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemLeToUint7byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[6])) << (8*6)) +
|
||||
(((uint64_t)(data[5])) << (8*5)) +
|
||||
(((uint64_t)(data[4])) << (8*4)) +
|
||||
(((uint64_t)(data[3])) << (8*3)) +
|
||||
(((uint64_t)(data[2])) << (8*2)) +
|
||||
(((uint64_t)(data[1])) << (8*1)) +
|
||||
(((uint64_t)(data[0])) << (8*0))
|
||||
);
|
||||
(((uint64_t)(data[6])) << (8 * 6)) +
|
||||
(((uint64_t)(data[5])) << (8 * 5)) +
|
||||
(((uint64_t)(data[4])) << (8 * 4)) +
|
||||
(((uint64_t)(data[3])) << (8 * 3)) +
|
||||
(((uint64_t)(data[2])) << (8 * 2)) +
|
||||
(((uint64_t)(data[1])) << (8 * 1)) +
|
||||
(((uint64_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemLeToUint8byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[7])) << (8*7)) +
|
||||
(((uint64_t)(data[6])) << (8*6)) +
|
||||
(((uint64_t)(data[5])) << (8*5)) +
|
||||
(((uint64_t)(data[4])) << (8*4)) +
|
||||
(((uint64_t)(data[3])) << (8*3)) +
|
||||
(((uint64_t)(data[2])) << (8*2)) +
|
||||
(((uint64_t)(data[1])) << (8*1)) +
|
||||
(((uint64_t)(data[0])) << (8*0))
|
||||
);
|
||||
(((uint64_t)(data[7])) << (8 * 7)) +
|
||||
(((uint64_t)(data[6])) << (8 * 6)) +
|
||||
(((uint64_t)(data[5])) << (8 * 5)) +
|
||||
(((uint64_t)(data[4])) << (8 * 4)) +
|
||||
(((uint64_t)(data[3])) << (8 * 3)) +
|
||||
(((uint64_t)(data[2])) << (8 * 2)) +
|
||||
(((uint64_t)(data[1])) << (8 * 1)) +
|
||||
(((uint64_t)(data[0])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint16_t MemBeToUint2byte(const uint8_t *data) {
|
||||
return (uint16_t)(
|
||||
(((uint16_t)(data[0])) << (8*1)) +
|
||||
(((uint16_t)(data[1])) << (8*0))
|
||||
);
|
||||
(((uint16_t)(data[0])) << (8 * 1)) +
|
||||
(((uint16_t)(data[1])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t MemBeToUint3byte(const uint8_t *data) {
|
||||
return (uint32_t)(
|
||||
(((uint32_t)(data[0])) << (8*2)) +
|
||||
(((uint32_t)(data[1])) << (8*1)) +
|
||||
(((uint32_t)(data[2])) << (8*0))
|
||||
);
|
||||
(((uint32_t)(data[0])) << (8 * 2)) +
|
||||
(((uint32_t)(data[1])) << (8 * 1)) +
|
||||
(((uint32_t)(data[2])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t MemBeToUint4byte(const uint8_t *data) {
|
||||
return (uint32_t)(
|
||||
(((uint32_t)(data[0])) << (8*3)) +
|
||||
(((uint32_t)(data[1])) << (8*2)) +
|
||||
(((uint32_t)(data[2])) << (8*1)) +
|
||||
(((uint32_t)(data[3])) << (8*0))
|
||||
);
|
||||
(((uint32_t)(data[0])) << (8 * 3)) +
|
||||
(((uint32_t)(data[1])) << (8 * 2)) +
|
||||
(((uint32_t)(data[2])) << (8 * 1)) +
|
||||
(((uint32_t)(data[3])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemBeToUint5byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[0])) << (8*4)) +
|
||||
(((uint64_t)(data[1])) << (8*3)) +
|
||||
(((uint64_t)(data[2])) << (8*2)) +
|
||||
(((uint64_t)(data[3])) << (8*1)) +
|
||||
(((uint64_t)(data[4])) << (8*0))
|
||||
);
|
||||
(((uint64_t)(data[0])) << (8 * 4)) +
|
||||
(((uint64_t)(data[1])) << (8 * 3)) +
|
||||
(((uint64_t)(data[2])) << (8 * 2)) +
|
||||
(((uint64_t)(data[3])) << (8 * 1)) +
|
||||
(((uint64_t)(data[4])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemBeToUint6byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[0])) << (8*5)) +
|
||||
(((uint64_t)(data[1])) << (8*4)) +
|
||||
(((uint64_t)(data[2])) << (8*3)) +
|
||||
(((uint64_t)(data[3])) << (8*2)) +
|
||||
(((uint64_t)(data[4])) << (8*1)) +
|
||||
(((uint64_t)(data[5])) << (8*0))
|
||||
);
|
||||
(((uint64_t)(data[0])) << (8 * 5)) +
|
||||
(((uint64_t)(data[1])) << (8 * 4)) +
|
||||
(((uint64_t)(data[2])) << (8 * 3)) +
|
||||
(((uint64_t)(data[3])) << (8 * 2)) +
|
||||
(((uint64_t)(data[4])) << (8 * 1)) +
|
||||
(((uint64_t)(data[5])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemBeToUint7byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[0])) << (8*6)) +
|
||||
(((uint64_t)(data[1])) << (8*5)) +
|
||||
(((uint64_t)(data[2])) << (8*4)) +
|
||||
(((uint64_t)(data[3])) << (8*3)) +
|
||||
(((uint64_t)(data[4])) << (8*2)) +
|
||||
(((uint64_t)(data[5])) << (8*1)) +
|
||||
(((uint64_t)(data[6])) << (8*0))
|
||||
);
|
||||
(((uint64_t)(data[0])) << (8 * 6)) +
|
||||
(((uint64_t)(data[1])) << (8 * 5)) +
|
||||
(((uint64_t)(data[2])) << (8 * 4)) +
|
||||
(((uint64_t)(data[3])) << (8 * 3)) +
|
||||
(((uint64_t)(data[4])) << (8 * 2)) +
|
||||
(((uint64_t)(data[5])) << (8 * 1)) +
|
||||
(((uint64_t)(data[6])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
uint64_t MemBeToUint8byte(const uint8_t *data) {
|
||||
return (uint64_t)(
|
||||
(((uint64_t)(data[0])) << (8*7)) +
|
||||
(((uint64_t)(data[1])) << (8*6)) +
|
||||
(((uint64_t)(data[2])) << (8*5)) +
|
||||
(((uint64_t)(data[3])) << (8*4)) +
|
||||
(((uint64_t)(data[4])) << (8*3)) +
|
||||
(((uint64_t)(data[5])) << (8*2)) +
|
||||
(((uint64_t)(data[6])) << (8*1)) +
|
||||
(((uint64_t)(data[7])) << (8*0))
|
||||
);
|
||||
(((uint64_t)(data[0])) << (8 * 7)) +
|
||||
(((uint64_t)(data[1])) << (8 * 6)) +
|
||||
(((uint64_t)(data[2])) << (8 * 5)) +
|
||||
(((uint64_t)(data[3])) << (8 * 4)) +
|
||||
(((uint64_t)(data[4])) << (8 * 3)) +
|
||||
(((uint64_t)(data[5])) << (8 * 2)) +
|
||||
(((uint64_t)(data[6])) << (8 * 1)) +
|
||||
(((uint64_t)(data[7])) << (8 * 0))
|
||||
);
|
||||
}
|
||||
|
||||
void Uint2byteToMemLe(uint8_t *data, uint16_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint3byteToMemLe(uint8_t *data, uint32_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint4byteToMemLe(uint8_t *data, uint32_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8*3)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint5byteToMemLe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8*3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8*4)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint6byteToMemLe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8*3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8*4)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8*5)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint7byteToMemLe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8*3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8*4)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8*5)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8*6)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8 * 6)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint8byteToMemLe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8*3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8*4)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8*5)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8*6)) & 0xffu);
|
||||
data[7] = (uint8_t)((value >> (8*7)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8 * 6)) & 0xffu);
|
||||
data[7] = (uint8_t)((value >> (8 * 7)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint2byteToMemBe(uint8_t *data, uint16_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint3byteToMemBe(uint8_t *data, uint32_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint4byteToMemBe(uint8_t *data, uint32_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*3)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint5byteToMemBe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*4)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*3)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint6byteToMemBe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*5)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*4)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*3)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint7byteToMemBe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*6)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*5)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*4)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8*3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 6)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
void Uint8byteToMemBe(uint8_t *data, uint64_t value) {
|
||||
data[0] = (uint8_t)((value >> (8*7)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8*6)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8*5)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8*4)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8*3)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8*2)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8*1)) & 0xffu);
|
||||
data[7] = (uint8_t)((value >> (8*0)) & 0xffu);
|
||||
data[0] = (uint8_t)((value >> (8 * 7)) & 0xffu);
|
||||
data[1] = (uint8_t)((value >> (8 * 6)) & 0xffu);
|
||||
data[2] = (uint8_t)((value >> (8 * 5)) & 0xffu);
|
||||
data[3] = (uint8_t)((value >> (8 * 4)) & 0xffu);
|
||||
data[4] = (uint8_t)((value >> (8 * 3)) & 0xffu);
|
||||
data[5] = (uint8_t)((value >> (8 * 2)) & 0xffu);
|
||||
data[6] = (uint8_t)((value >> (8 * 1)) & 0xffu);
|
||||
data[7] = (uint8_t)((value >> (8 * 0)) & 0xffu);
|
||||
}
|
||||
|
||||
// RotateLeft - Ultralight, Desfire
|
||||
|
|
|
@ -3397,13 +3397,16 @@
|
|||
"description": "Print a iCLASS tag dump file (bin/eml/json)",
|
||||
"notes": [
|
||||
"hf iclass view -f hf-iclass-AA162D30F8FF12F1-dump.bin",
|
||||
"hf iclass view --first 1 -f hf-iclass-AA162D30F8FF12F1-dump.bin"
|
||||
"hf iclass view --first 1 -f hf-iclass-AA162D30F8FF12F1-dump.bin",
|
||||
"",
|
||||
"If --first is not specified it will default to the first user block",
|
||||
"which is block 6 for secured chips or block 3 for non-secured chips"
|
||||
],
|
||||
"offline": true,
|
||||
"options": [
|
||||
"-h, --help This help",
|
||||
"-f, --file <fn> filename of dump (bin/eml/json)",
|
||||
"--first <dec> Begin printing from this block (default first user block - 6 or 3 on non secured chips)",
|
||||
"--first <dec> Begin printing from this block (default first user block)",
|
||||
"--last <dec> End printing at this block (default 0, ALL)",
|
||||
"-v, --verbose verbose output",
|
||||
"-z, --dense dense dump output style"
|
||||
|
@ -11834,6 +11837,6 @@
|
|||
"metadata": {
|
||||
"commands_extracted": 686,
|
||||
"extracted_by": "PM3Help2JSON v1.00",
|
||||
"extracted_on": "2023-08-22T23:15:58"
|
||||
"extracted_on": "2023-08-24T05:14:06"
|
||||
}
|
||||
}
|
|
@ -857,4 +857,4 @@ int main(int argc, const char *argv[]) {
|
|||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1143,4 +1143,4 @@ int main(int argc, const char *argv[]) {
|
|||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -262,7 +262,7 @@ static int zlib_decompress(FILE *infile, FILE *outfiles[], uint8_t num_outfiles,
|
|||
for (uint16_t j = 0; j < num_outfiles; j++) {
|
||||
if (k * FPGA_INTERLEAVE_SIZE < outfilesizes[j]) {
|
||||
uint16_t chunk = (outfilesizes[j] - (k * FPGA_INTERLEAVE_SIZE) < FPGA_INTERLEAVE_SIZE) ?
|
||||
outfilesizes[j] - (k * FPGA_INTERLEAVE_SIZE) : FPGA_INTERLEAVE_SIZE;
|
||||
outfilesizes[j] - (k * FPGA_INTERLEAVE_SIZE) : FPGA_INTERLEAVE_SIZE;
|
||||
|
||||
fwrite(outbufall + offset, chunk, sizeof(char), outfiles[j]);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue