hf iclass dump --page support

This commit is contained in:
Raheem Idowu
2026-04-04 17:15:13 -04:00
parent 2e49d441b9
commit 22dae554c7
5 changed files with 51 additions and 16 deletions
+1 -2
View File
@@ -2356,8 +2356,7 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_ICLASS_READER: {
iclass_card_select_t *payload = (iclass_card_select_t *) packet->data.asBytes;
ReaderIClass(payload->flags);
ReaderIClass(packet->data.asBytes);
break;
}
case CMD_HF_ICLASS_EML_MEMSET: {
+29 -6
View File
@@ -1373,7 +1373,7 @@ static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t *
* @return false = fail
* true = Got all.
*/
static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, uint8_t *status, bool shallow_mod) {
static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, uint8_t *status, bool shallow_mod, uint8_t page) {
static uint8_t act_all[] = { ICLASS_CMD_ACTALL };
static uint8_t identify[] = { ICLASS_CMD_READ_OR_IDENTIFY, 0x00, 0x73, 0x33 };
@@ -1421,6 +1421,19 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3
// save CSN
memcpy(hdr->csn, resp, sizeof(hdr->csn));
// card selected, select page
uint8_t pagesel_resp[10];
start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
uint8_t pagesel[] = {0x80 | ICLASS_CMD_PAGESEL, page, 0x00, 0x00};
AddCrc(pagesel + 1, 1);
bool pagesel_res = iclass_send_cmd_with_retries(pagesel, sizeof(pagesel), pagesel_resp, sizeof(resp),
10, 2, &start_time, ICLASS_READER_TIMEOUT_OTHERS, eof_time, shallow_mod);
if (pagesel_res == false) {
return false;
}
// card selected, now read config (block1) (only 8 bytes no CRC)
start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
iclass_send_as_reader(read_conf, sizeof(read_conf), &start_time, eof_time, shallow_mod);
@@ -1495,12 +1508,21 @@ static bool select_iclass_tag_ex(picopass_hdr_t *hdr, bool use_credit_key, uint3
bool select_iclass_tag(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, bool shallow_mod) {
uint8_t result = 0;
return select_iclass_tag_ex(hdr, use_credit_key, eof_time, &result, shallow_mod);
return select_iclass_tag_ex(hdr, use_credit_key, eof_time, &result, shallow_mod, 0); // page 0 unless specified
}
bool select_iclass_tag_and_page(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, bool shallow_mod, uint8_t page) {
uint8_t result = 0;
return select_iclass_tag_ex(hdr, use_credit_key, eof_time, &result, shallow_mod, page);
}
// Reader iClass Anticollission
// turn off afterwards
void ReaderIClass(uint8_t flags) {
void ReaderIClass(uint8_t *msg) {
iclass_card_select_t *cmd = (iclass_card_select_t *)msg;
uint8_t flags = cmd->flags;
uint8_t page = cmd->page;
// flag to use credit key
bool use_credit_key = ((flags & FLAG_ICLASS_READER_CREDITKEY) == FLAG_ICLASS_READER_CREDITKEY);
@@ -1519,7 +1541,7 @@ void ReaderIClass(uint8_t flags) {
uint32_t eof_time = 0;
picopass_hdr_t hdr = {0};
if (select_iclass_tag_ex(&hdr, use_credit_key, &eof_time, &res, shallow_mod) == false) {
if (select_iclass_tag_ex(&hdr, use_credit_key, &eof_time, &res, shallow_mod, page) == false) {
reply_ng(CMD_HF_ICLASS_READER, PM3_ERFTRANS, NULL, 0);
goto out;
}
@@ -1767,6 +1789,7 @@ void iClass_Dump(uint8_t *msg) {
iclass_dump_req_t *cmd = (iclass_dump_req_t *)msg;
iclass_auth_req_t *req = &cmd->req;
bool shallow_mod = req->shallow_mod;
uint8_t page = cmd->page;
uint8_t *dataout = BigBuf_calloc(ICLASS_16KS_SIZE);
if (dataout == NULL) {
@@ -1781,12 +1804,12 @@ void iClass_Dump(uint8_t *msg) {
Iso15693InitReader();
// select tag.
// select tag and page
uint32_t eof_time = 0;
picopass_hdr_t hdr = {0};
memset(&hdr, 0xff, sizeof(picopass_hdr_t));
bool res = select_iclass_tag(&hdr, req->use_credit_key, &eof_time, shallow_mod);
bool res = select_iclass_tag_and_page(&hdr, req->use_credit_key, &eof_time, shallow_mod, page);
if (res == false) {
if (req->send_reply) {
reply_ng(CMD_HF_ICLASS_DUMP, PM3_ETIMEOUT, NULL, 0);
+2 -1
View File
@@ -47,7 +47,7 @@
#define AddCrc(data, len) compute_crc(CRC_ICLASS, (data), (len), (data)+(len), (data)+(len)+1)
void SniffIClass(uint8_t jam_search_len, uint8_t *jam_search_string);
void ReaderIClass(uint8_t flags);
void ReaderIClass(uint8_t *flags);
void iClass_WriteBlock(uint8_t *msg);
void iclass_credit_epurse(iclass_credit_epurse_t *payload);
@@ -67,6 +67,7 @@ void iClass_ReadBlock(uint8_t *msg);
bool iclass_read_block(uint16_t blockno, uint8_t *data, uint32_t *start_time, uint32_t *eof_time, bool shallow_mod);
bool select_iclass_tag(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, bool shallow_mod);
bool select_iclass_tag_and_page(picopass_hdr_t *hdr, bool use_credit_key, uint32_t *eof_time, bool shallow_mod, uint8_t page);
bool authenticate_iclass_tag(iclass_auth_req_t *payload, picopass_hdr_t *hdr, uint32_t *start_time, uint32_t *eof_time, uint8_t *mac_out);
uint8_t get_pagemap(const picopass_hdr_t *hdr);
+17 -7
View File
@@ -1639,7 +1639,8 @@ static int CmdHFiClassInfo(const char *Cmd) {
int read_iclass_csn(bool loop, bool verbose, bool shallow_mod) {
iclass_card_select_t payload = {
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE)
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE),
.page = 0 // no page selection support for reader mode yet
};
if (shallow_mod) {
@@ -2431,7 +2432,8 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) {
static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool verbose, bool shallow_mod) {
iclass_card_select_t payload = {
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE)
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE),
.page = 0 // no page selection support here yet
};
if (shallow_mod) {
@@ -2481,7 +2483,8 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool verbose, bool shallow_
static int iclass_dump_non_secure(bool shallow_mod, uint8_t *tag_data, uint16_t *taglen) {
iclass_card_select_t payload_rdr = {
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE)
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE),
.page = 0 // no page selection support here yet
};
if (shallow_mod) {
@@ -2606,6 +2609,7 @@ static int CmdHFiClassDump(const char *Cmd) {
arg_lit0(NULL, "force", "force unsecure card read"),
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
arg_lit0(NULL, "ns", "no save to file"),
arg_int0(NULL, "page", "<dec>", "which page to dump from"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@@ -2632,6 +2636,7 @@ static int CmdHFiClassDump(const char *Cmd) {
bool force = arg_get_lit(ctx, 10);
bool shallow_mod = arg_get_lit(ctx, 11);
bool nosave = arg_get_lit(ctx, 12);
int page = arg_get_int_def(ctx, 13, 0);
CLIParserFree(ctx);
@@ -2702,7 +2707,8 @@ static int CmdHFiClassDump(const char *Cmd) {
memset(tag_data, 0xFF, sizeof(tag_data));
iclass_card_select_t payload_rdr = {
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE)
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE),
.page = page
};
if (shallow_mod) {
@@ -2791,6 +2797,7 @@ static int CmdHFiClassDump(const char *Cmd) {
.req.do_auth = auth,
.req.shallow_mod = shallow_mod,
.end_block = app_limit1,
.page = page,
};
memcpy(payload.req.key, key, 8);
@@ -3891,7 +3898,8 @@ static int CmdHFiClass_TearBlock(const char *Cmd) {
//check if the card is in secure mode or not
iclass_card_select_t payload_rdr = {
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE)
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE),
.page = 0 // no page selection support for tearblock yet
};
if (shallow_mod) {
@@ -4444,7 +4452,8 @@ static int CmdHFiClass_BlackTears(const char *Cmd) {
//check if the card is in secure mode or not
iclass_card_select_t payload_rdr = {
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE)
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE),
.page = 0 // no page selection support for blacktears yet
};
clearCommandBuffer();
@@ -7891,7 +7900,8 @@ int CmdHFiClass(const char *Cmd) {
int info_iclass(bool shallow_mod) {
iclass_card_select_t payload = {
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE)
.flags = (FLAG_ICLASS_READER_INIT | FLAG_ICLASS_READER_CLEARTRACE),
.page = 0 // no page selection support for info yet
};
if (shallow_mod) {
+2
View File
@@ -79,6 +79,7 @@ typedef struct {
// iCLASS dump data structure
typedef struct {
iclass_auth_req_t req;
uint8_t page;
uint8_t start_block;
uint8_t end_block;
} PACKED iclass_dump_req_t;
@@ -187,6 +188,7 @@ typedef struct {
// reader flags
typedef struct {
uint8_t flags;
uint8_t page;
} PACKED iclass_card_select_t;
// reader flags