From 169780fec0e63e25903db19271524f0630f7df2a Mon Sep 17 00:00:00 2001 From: Yann GASCUEL <34003959+lnv42@users.noreply.github.com> Date: Thu, 25 Jan 2024 14:04:29 +0100 Subject: [PATCH] iso15: fix restore with new dump format --- client/src/cmdhf15.c | 67 ++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index 3cdd256ef..8ff3fe3e6 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -2583,8 +2583,7 @@ static int CmdHF15Restore(const char *Cmd) { uint8_t arglen = arg_add_default(argtable); argtable[arglen++] = arg_str0("f", "file", "", "Specify a filename for dump file"), argtable[arglen++] = arg_int0("r", "retry", "", "number of retries (def 3)"), - argtable[arglen++] = arg_int0(NULL, "bs", "", "block size (def 4)"), - argtable[arglen++] = arg_lit0("v", "verbose", "verbose output"); + argtable[arglen++] = arg_lit0("v", "verbose", "verbose output"); argtable[arglen++] = arg_param_end; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -2602,8 +2601,7 @@ static int CmdHF15Restore(const char *Cmd) { CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); uint32_t retries = arg_get_u32_def(ctx, 7, 3); - int blocksize = arg_get_int_def(ctx, 8, 4); - bool verbose = arg_get_lit(ctx, 9); + bool verbose = arg_get_lit(ctx, 8); CLIParserFree(ctx); // sanity checks @@ -2617,11 +2615,6 @@ static int CmdHF15Restore(const char *Cmd) { return PM3_EINVARG; } - if (blocksize < 4) { - PrintAndLogEx(WARNING, "Blocksize too small, using default 4 bytes"); - blocksize = 4; - } - // default fallback to scan for tag. // overriding unaddress parameter :) if (uidlen != HF15_UID_LENGTH) { @@ -2641,8 +2634,6 @@ static int CmdHF15Restore(const char *Cmd) { PrintAndLogEx(SUCCESS, "Using unaddressed mode"); } - PrintAndLogEx(INFO, "Using block size... " _YELLOW_("%d"), blocksize); - // TI needs OPTION if (uid[7] == 0xE0 && uid[6] == 0x07) { if (verbose) { @@ -2652,18 +2643,33 @@ static int CmdHF15Restore(const char *Cmd) { } // read dump file - uint8_t *dump = NULL; + iso15_tag_t *tag = NULL; size_t bytes_read = 0; // blocksize bytes * 256 blocks. Should be enough - int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (blocksize * 256)); + int res = pm3_load_dump(filename, (void **)&tag, &bytes_read, sizeof(iso15_tag_t)); if (res != PM3_SUCCESS) { return res; } - if ((bytes_read % blocksize) != 0) { - PrintAndLogEx(WARNING, "datalen %zu isn't dividable with blocksize %d", bytes_read, blocksize); - free(dump); - return PM3_ESOFT; + if (bytes_read != sizeof(iso15_tag_t)) { + PrintAndLogEx(FAILED, "Memory image is not matching tag structure."); + free(tag); + return PM3_EINVARG; + } + if (bytes_read == 0) { + PrintAndLogEx(FAILED, "Memory image empty."); + free(tag); + return PM3_EINVARG; + } + + if ((tag->pagesCount > ISO15693_TAG_MAX_PAGES) || + ((tag->pagesCount * tag->bytesPerPage) > ISO15693_TAG_MAX_SIZE) || + (tag->pagesCount == 0) || + (tag->bytesPerPage == 0)) { + PrintAndLogEx(FAILED, "Tag size error: pagesCount=%d, bytesPerPage=%d", + tag->pagesCount, tag->bytesPerPage); + free(tag); + return PM3_EINVARG; } PrintAndLogEx(INFO, "Restoring data blocks"); @@ -2678,19 +2684,18 @@ static int CmdHF15Restore(const char *Cmd) { int retval = PM3_SUCCESS; size_t bytes = 0; uint16_t i = 0; - while (bytes < bytes_read) { - - uint8_t data[blocksize]; + uint8_t *data = calloc(tag->bytesPerPage, sizeof(uint8_t)); + uint32_t tried = 0; + while (bytes < (tag->pagesCount * tag->bytesPerPage)) { // copy over the data to the request - memcpy(data, dump + bytes, blocksize); + memcpy(data, &tag->data[bytes], tag->bytesPerPage); - uint32_t tried = 0; for (tried = 0; tried < retries; tried++) { - retval = hf_15_write_blk(&pm3flags, flags, uid, fast, i, data, blocksize); + retval = hf_15_write_blk(&pm3flags, flags, uid, fast + , i, data, tag->bytesPerPage); if (retval == PM3_SUCCESS) { - PrintAndLogEx(INPLACE, "blk %3d", i); if (i == 0) { @@ -2708,24 +2713,20 @@ static int CmdHF15Restore(const char *Cmd) { } if (tried >= retries) { - free(dump); + free(data); + free(tag); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(FAILED, "Too many retries (" _RED_("fail") " )"); DropField(); return retval; } - bytes += blocksize; + bytes += tag->bytesPerPage; i++; - - if (retval == PM3_EOUTOFBOUND) { - // we only get this when we reached end of tag memory - // break out of while loop - break; - } } - free(dump); + free(data); + free(tag); DropField(); PrintAndLogEx(NORMAL, "");