From 7b0ca4369511446425c924dd9e254f9f4ad77ada Mon Sep 17 00:00:00 2001 From: nvx Date: Sun, 26 Nov 2023 18:39:36 +1000 Subject: [PATCH] Fix iClass dump truncating the AA2 area and improve dump reliability by fixing cmd retry delays. --- armsrc/iclass.c | 8 +++++++- client/src/cmdhficlass.c | 32 +++++++++++++++++--------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 405ad610f..283577e3a 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1254,6 +1254,12 @@ static bool iclass_send_cmd_with_retries(uint8_t *cmd, size_t cmdsize, uint8_t * if (res == PM3_SUCCESS && expected_size == resp_len) { return true; } + + // Timed out waiting for the tag to reply, but perhaps the tag did hear the command and is attempting to reply + // So wait long enough for the tag to encode it's reply plus required frame delays on each side before retrying + // And then double it, because in practice it seems to make it much more likely to succeed + // Response time calculation from expected_size lifted from GetIso15693AnswerFromTag + *start_time = *eof_time + ((DELAY_ICLASS_VICC_TO_VCD_READER + DELAY_ISO15693_VCD_TO_VICC_READER + (expected_size * 8 * 8 * 16)) * 2); } return false; } @@ -1739,7 +1745,7 @@ void iClass_Dump(uint8_t *msg) { } PACKED response; response.isOK = dumpsuccess; - response.block_cnt = i; + response.block_cnt = i - cmd->start_block; response.bb_offset = dataout - BigBuf_get_addr(); reply_ng(CMD_HF_ICLASS_DUMP, PM3_SUCCESS, (uint8_t *)&response, sizeof(response)); } diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 313ecf2ce..afaf6cab9 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -2067,17 +2067,15 @@ static int CmdHFiClassDump(const char *Cmd) { return PM3_ETIMEOUT; } - if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) { - // all memory available - memcpy(tag_data + (8 * 3), tempbuf + (8 * 3), (blocks_read * 8)); - } else { + if (pagemap != PICOPASS_NON_SECURE_PAGEMODE) { // div key KD - memcpy(tag_data + (8 * 3), tempbuf + (8 * 3), 8); - // AIA data - memcpy(tag_data + (8 * 5), tempbuf + (8 * 5), 8); - // AA1 data - memcpy(tag_data + (8 * 6), tempbuf + (8 * 6), ((blocks_read - 6) * 8)); + memcpy(tag_data + (PICOPASS_BLOCK_SIZE * 3), + tempbuf + (PICOPASS_BLOCK_SIZE * 3), PICOPASS_BLOCK_SIZE); } + // all memory available + memcpy(tag_data + (PICOPASS_BLOCK_SIZE * payload.start_block), + tempbuf + (PICOPASS_BLOCK_SIZE * payload.start_block), + blocks_read * PICOPASS_BLOCK_SIZE); uint16_t bytes_got = (app_limit1 + 1) * 8; @@ -2135,12 +2133,14 @@ static int CmdHFiClassDump(const char *Cmd) { } // div key KC - memcpy(tag_data + (8 * 4), tempbuf + (8 * 4), 8); + memcpy(tag_data + (PICOPASS_BLOCK_SIZE * 4), tempbuf + (PICOPASS_BLOCK_SIZE * 4), PICOPASS_BLOCK_SIZE); // AA2 data - memcpy(tag_data + (8 * (app_limit1 + 1)), tempbuf + (8 * (app_limit1 + 1)), (blocks_read * 8)); + memcpy(tag_data + (PICOPASS_BLOCK_SIZE * payload.start_block), + tempbuf + (PICOPASS_BLOCK_SIZE * payload.start_block), + blocks_read * PICOPASS_BLOCK_SIZE); - bytes_got = (blocks_read * 8); + bytes_got += (blocks_read * PICOPASS_BLOCK_SIZE); aa2_success = true; } @@ -3036,7 +3036,7 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e int sio_start_block = 0, sio_end_block = 0; if (sio_start && sio_length > 0) { sio_start_block = (sio_start - iclass_dump) / PICOPASS_BLOCK_SIZE; - sio_end_block = sio_start_block + (sio_length + PICOPASS_BLOCK_SIZE - 1) / PICOPASS_BLOCK_SIZE - 1; + sio_end_block = sio_start_block + ((sio_length + PICOPASS_BLOCK_SIZE - 1) / PICOPASS_BLOCK_SIZE) - 1; } int i = startblock; @@ -3107,7 +3107,7 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e regular_print_block = true; } else { - const char *info_ks[] = {"CSN", "Config", "E-purse", "Debit", "Credit", "AIA", "User"}; + const char *info_ks[] = {"CSN", "Config", "E-purse", "Debit", "Credit", "AIA", "User", "User AA2"}; if (i >= 6 && i <= 9 && is_legacy) { // legacy credential @@ -3132,6 +3132,8 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e } else { if (i < 6) { block_info = info_ks[i]; + } else if (i > hdr->conf.app_limit) { + block_info = info_ks[7]; } else { block_info = info_ks[6]; } @@ -3156,7 +3158,7 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e if (in_repeated_block == false) { PrintAndLogEx(INFO, - "%3d/0x%02X | %s | %s | %s ", + "%3d/0x%02X | %s | %s | %s", i, i, sprint_hex_ascii(blk, 8),