From ba225905d31e9d78fd3f0487af69d2e471559613 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 26 Oct 2022 06:57:21 +0200 Subject: [PATCH] changed "mf eload" / "iclass eload" to be able to transfer a file from SPIFFS to EMULATOR memory. Original idea from @natesales --- armsrc/appmain.c | 24 ++++++++++++++++++++++++ armsrc/spiffs.c | 24 ++++++++++++------------ client/src/cmdhficlass.c | 34 +++++++++++++++++++++++++++++++++- client/src/cmdhfmf.c | 36 ++++++++++++++++++++++++++++++++++-- include/pm3_cmd.h | 5 ++--- 5 files changed, 105 insertions(+), 18 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 73ef066af..07c3375f0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2313,6 +2313,30 @@ static void PacketReceived(PacketCommandNG *packet) { LED_B_OFF(); break; } + case CMD_SPIFFS_ELOAD: { + LED_B_ON(); + + uint8_t *em = BigBuf_get_EM_addr(); + if (em == NULL) { + reply_ng(CMD_SPIFFS_ELOAD, PM3_EMALLOC, NULL, 0); + LED_B_OFF(); + break; + } + + char *fn = (char *)packet->data.asBytes; + + uint32_t size = size_in_spiffs(fn); + if (size == 0) { + reply_ng(CMD_SPIFFS_ELOAD, PM3_SUCCESS, NULL, 0); + LED_B_OFF(); + break; + } + + rdv40_spiffs_read_as_filetype(fn, em, size, RDV40_SPIFFS_SAFETY_SAFE); + reply_ng(CMD_SPIFFS_ELOAD, PM3_SUCCESS, NULL, 0); + LED_B_OFF(); + break; + } case CMD_FLASHMEM_SET_SPIBAUDRATE: { if (packet->length != sizeof(uint32_t)) break; diff --git a/armsrc/spiffs.c b/armsrc/spiffs.c index cea6946d3..54d1360d6 100644 --- a/armsrc/spiffs.c +++ b/armsrc/spiffs.c @@ -578,18 +578,18 @@ int rdv40_spiffs_make_symlink(char *linkdest, char *filename, RDV40SpiFFSSafetyL int rdv40_spiffs_read_as_filetype(char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) { RDV40_SPIFFS_SAFE_FUNCTION( RDV40SpiFFSFileType filetype = filetype_in_spiffs((char *)filename); - switch (filetype) { - case RDV40_SPIFFS_FILETYPE_REAL: - rdv40_spiffs_read((char *)filename, (uint8_t *)dst, size, level); - break; - case RDV40_SPIFFS_FILETYPE_SYMLINK: - rdv40_spiffs_read_as_symlink(filename, (uint8_t *)dst, size, level); - break; - case RDV40_SPIFFS_FILETYPE_BOTH: - case RDV40_SPIFFS_FILETYPE_UNKNOWN: - default: - ; - } + switch (filetype) { + case RDV40_SPIFFS_FILETYPE_REAL: + rdv40_spiffs_read((char *)filename, (uint8_t *)dst, size, level); + break; + case RDV40_SPIFFS_FILETYPE_SYMLINK: + rdv40_spiffs_read_as_symlink(filename, (uint8_t *)dst, size, level); + break; + case RDV40_SPIFFS_FILETYPE_BOTH: + case RDV40_SPIFFS_FILETYPE_UNKNOWN: + default: + break; + } ) } diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index b4c9d934b..7d8138e7b 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -990,13 +990,14 @@ static int CmdHFiClassELoad(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf iclass eload", "Load emulator memory with data from (bin/eml/json) iCLASS dump file", - "hf iclass eload -f hf-iclass-AA162D30F8FF12F1-dump.bin\n" "hf iclass eload -f hf-iclass-AA162D30F8FF12F1-dump.eml\n" + "hf iclass eload -f hf-iclass-AA162D30F8FF12F1-dump.bin -m\n" ); void *argtable[] = { arg_param_begin, arg_str1("f", "file", "", "filename of dump (bin/eml/json)"), + arg_lit0("m", "mem", "use RDV4 spiffs"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -1011,8 +1012,39 @@ static int CmdHFiClassELoad(const char *Cmd) { return PM3_EINVARG; } + bool use_spiffs = arg_get_lit(ctx, 2); CLIParserFree(ctx); + // use RDV4 spiffs + if (use_spiffs && IfPm3Flash() == false) { + PrintAndLogEx(WARNING, "Device not compiled to support spiffs"); + return PM3_EINVARG; + } + + if (use_spiffs) { + + if (fnlen > 32) { + PrintAndLogEx(WARNING, "filename too long for spiffs, expected 32, got %u", fnlen); + return PM3_EINVARG; + } + + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_ELOAD, (uint8_t *)filename, fnlen); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_SPIFFS_ELOAD, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + + if (resp.status != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Loading file from spiffs to emulatore memory failed"); + return PM3_EFLASH; + } + + PrintAndLogEx(SUCCESS, "File transfered from spiffs to device emulator memory"); + return PM3_SUCCESS; + } + // read dump file uint8_t *dump = NULL; size_t bytes_read = 2048; diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 4fdeedbe0..e0bd6cc69 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -3890,6 +3890,7 @@ int CmdHF14AMfELoad(const char *Cmd) { arg_lit0(NULL, "2k", "MIFARE Classic/Plus 2k"), arg_lit0(NULL, "4k", "MIFARE Classic 4k / S70"), arg_lit0(NULL, "ul", "MIFARE Ultralight family"), + arg_lit0("m", "mem", "use RDV4 spiffs"), arg_int0("q", "qty", "", "manually set number of blocks (overrides)"), arg_param_end }; @@ -3905,7 +3906,8 @@ int CmdHF14AMfELoad(const char *Cmd) { bool m4 = arg_get_lit(ctx, 5); bool mu = arg_get_lit(ctx, 6); - int numblks = arg_get_int_def(ctx, 7, -1); + bool use_spiffs = arg_get_lit(ctx, 7); + int numblks = arg_get_int_def(ctx, 8, -1); CLIParserFree(ctx); @@ -3945,6 +3947,36 @@ int CmdHF14AMfELoad(const char *Cmd) { PrintAndLogEx(INFO, "overriding number of blocks, will use %d blocks ( %u bytes )", block_cnt, block_cnt * block_width); } + // use RDV4 spiffs + if (use_spiffs && IfPm3Flash() == false) { + PrintAndLogEx(WARNING, "Device not compiled to support spiffs"); + return PM3_EINVARG; + } + + if (use_spiffs) { + + if (fnlen > 32) { + PrintAndLogEx(WARNING, "filename too long for spiffs, expected 32, got %u", fnlen); + return PM3_EINVARG; + } + + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_ELOAD, (uint8_t *)filename, fnlen); + PacketResponseNG resp; + if (WaitForResponseTimeout(CMD_SPIFFS_ELOAD, &resp, 2000) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + + if (resp.status != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Loading file from spiffs to emulatore memory failed"); + return PM3_EFLASH; + } + + PrintAndLogEx(SUCCESS, "File transfered from spiffs to device emulator memory"); + return PM3_SUCCESS; + } + uint8_t *data = NULL; size_t bytes_read = 0; int res = pm3_load_dump(filename, (void **)&data, &bytes_read, (block_width * block_cnt + hdr_len)); @@ -4204,7 +4236,7 @@ static int CmdHF14AMfECFill(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mf ecfill", "Dump card and transfer the data to emulator memory.\n" - "Keys must be laid in the emulator memory", + "Keys must be in the emulator memory", "hf mf ecfill --> use key type A\n" "hf mf ecfill --4k -b --> target 4K card with key type B" ); diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 5a49871e1..412ca2ba6 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -416,16 +416,15 @@ typedef struct { #define CMD_SPIFFS_WIPE 0x013A // This take a +0x2000 as they are high level helper and special functions -// As the others, they may have safety level argument if it makkes sense +// As the others, they may have safety level argument if it makes sense #define CMD_SPIFFS_PRINT_TREE 0x2130 #define CMD_SPIFFS_GET_TREE 0x2131 #define CMD_SPIFFS_TEST 0x2132 #define CMD_SPIFFS_PRINT_FSINFO 0x2133 #define CMD_SPIFFS_DOWNLOAD 0x2134 #define CMD_SPIFFS_DOWNLOADED 0x2135 +#define CMD_SPIFFS_ELOAD 0x2136 #define CMD_SPIFFS_CHECK 0x3000 -// more ? - // RDV40, Smart card operations #define CMD_SMART_RAW 0x0140