From 02aabf90d3ae98568baa87d34e39b764c63c0e2b Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 8 Mar 2021 17:39:21 +0100 Subject: [PATCH] mem spi mount/unmount/test/check/tree/info/remove/rename/wwipe - now uses cliparser. remove/rename uses NG --- armsrc/appmain.c | 42 ++-- client/src/cmdflashmemspiffs.c | 380 +++++++++++++++++++-------------- 2 files changed, 242 insertions(+), 180 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index e9c34e2cc..22190ef1a 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -2097,29 +2097,39 @@ static void PacketReceived(PacketCommandNG *packet) { } case CMD_SPIFFS_REMOVE: { LED_B_ON(); - uint8_t filename[32]; - uint8_t *pfilename = packet->data.asBytes; - memcpy(filename, pfilename, SPIFFS_OBJ_NAME_LEN); - if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Filename received for spiffs REMOVE : %s", filename); - rdv40_spiffs_remove((char *) filename, RDV40_SPIFFS_SAFETY_SAFE); + + struct p { + uint8_t len; + uint8_t fn[32]; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + + if (DBGLEVEL >= DBG_DEBUG) { + Dbprintf("Filename received for spiffs REMOVE : %s", payload->fn); + } + + rdv40_spiffs_remove((char *)payload->fn, RDV40_SPIFFS_SAFETY_SAFE); + reply_ng(CMD_SPIFFS_REMOVE, PM3_SUCCESS, NULL, 0); LED_B_OFF(); break; } case CMD_SPIFFS_RENAME: { LED_B_ON(); - uint8_t src[32]; - uint8_t dest[32]; - uint8_t *pfilename = packet->data.asBytes; - char *token; - token = strtok((char *)pfilename, ","); - strncpy((char *)src, token, sizeof(src) - 1); - token = strtok(NULL, ","); - strncpy((char *)dest, token, sizeof(dest) - 1); + struct p { + uint8_t slen; + uint8_t src[32]; + uint8_t dlen; + uint8_t dest[32]; + } PACKED; + + struct p *payload = (struct p *) packet->data.asBytes; + if (DBGLEVEL >= DBG_DEBUG) { - Dbprintf("Filename received as source for spiffs RENAME : %s", src); - Dbprintf("Filename received as destination for spiffs RENAME : %s", dest); + Dbprintf("Filename received as source for spiffs RENAME : %s", payload->src); + Dbprintf("Filename received as destination for spiffs RENAME : %s", payload->dest); } - rdv40_spiffs_rename((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE); + rdv40_spiffs_rename((char *)payload->src, (char *)payload->dest, RDV40_SPIFFS_SAFETY_SAFE); + reply_ng(CMD_SPIFFS_RENAME, PM3_SUCCESS, NULL, 0); LED_B_OFF(); break; } diff --git a/client/src/cmdflashmemspiffs.c b/client/src/cmdflashmemspiffs.c index 11c4db2d7..f0877ab0d 100644 --- a/client/src/cmdflashmemspiffs.c +++ b/client/src/cmdflashmemspiffs.c @@ -8,34 +8,15 @@ // Proxmark3 RDV40 Flash memory commands //----------------------------------------------------------------------------- #include "cmdflashmemspiffs.h" - #include - -#include "cmdparser.h" // command_t +#include "cmdparser.h" // command_t #include "pmflash.h" #include "fileutils.h" //saveFile -#include "comms.h" //getfromdevice +#include "comms.h" //getfromdevice +#include "cliparser.h" static int CmdHelp(const char *Cmd); -static int usage_flashmemspiffs_remove(void) { - PrintAndLogEx(NORMAL, "Remove a file from spiffs filesystem\n"); - PrintAndLogEx(NORMAL, "Usage: mem spiffs remove "); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" mem spiffs remove lasttag.bin")); - return PM3_SUCCESS; -} - -static int usage_flashmemspiffs_rename(void) { - PrintAndLogEx(NORMAL, "Rename/move a file in spiffs filesystem\n"); - PrintAndLogEx(NORMAL, "Usage: mem spiffs rename "); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_(" mem spiffs rename lasttag.bin oldtag.bin")); - return PM3_SUCCESS; -} - static int usage_flashmemspiffs_copy(void) { PrintAndLogEx(NORMAL, "Copy a file to another (destructively) in spiffs filesystem\n"); PrintAndLogEx(NORMAL, "Usage: mem spiffs copy "); @@ -82,121 +63,260 @@ static int usage_flashmemspiffs_wipe(void) { PrintAndLogEx(NORMAL, _YELLOW_(" mem spiffs wipe")); return PM3_SUCCESS; } + + +int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen) { + + int ret_val = PM3_SUCCESS; + + // We want to mount before multiple operation so the lazy writes/append will not + // trigger a mount + umount each loop iteration (lazy ops device side) + SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); + + // Send to device + uint32_t bytes_sent = 0; + uint32_t bytes_remaining = datalen; + uint32_t append = 0; + + // fast push mode + conn.block_after_ACK = true; + + while (bytes_remaining > 0) { + uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); + + clearCommandBuffer(); + + char fdata[32 + bytes_in_packet]; + memset(fdata, 0, sizeof(fdata)); + memcpy(fdata, destfn, 32); + memcpy(fdata + 32, data + bytes_sent, bytes_in_packet); + + if (bytes_sent > 0) + append = 1; + + SendCommandOLD(CMD_SPIFFS_WRITE, append, bytes_in_packet, 0, fdata, 32 + bytes_in_packet); + + bytes_remaining -= bytes_in_packet; + bytes_sent += bytes_in_packet; + + PacketResponseNG resp; + + uint8_t retry = 3; + while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + PrintAndLogEx(WARNING, "timeout while waiting for reply."); + retry--; + if (retry == 0) { + ret_val = PM3_ETIMEOUT; + goto out; + } + } + + uint8_t isok = resp.oldarg[0] & 0xFF; + if (!isok) { + PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent); + ret_val = PM3_EFLASH; + break; + } + } + +out: + clearCommandBuffer(); + + // turn off fast push mode + conn.block_after_ACK = false; + + // We want to unmount after these to set things back to normal but more than this + // unmouting ensure that SPIFFS CACHES are all flushed so our file is actually written on memory + SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0); + + return ret_val; +} + static int CmdFlashMemSpiFFSMount(const char *Cmd) { - (void)Cmd; // Cmd is not used so far + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem spiffs mount", + "Mount the SPIFFS file system if not already mounted", + "mem spiffs mount"); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); clearCommandBuffer(); SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); return PM3_SUCCESS; } static int CmdFlashMemSpiFFSUnmount(const char *Cmd) { - (void)Cmd; // Cmd is not used so far + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem spiffs unmount", + "Un-mount the SPIFFS file system", + "mem spiffs unmount"); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); clearCommandBuffer(); SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0); return PM3_SUCCESS; } static int CmdFlashMemSpiFFSTest(const char *Cmd) { - (void)Cmd; // Cmd is not used so far + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem spiffs test", + "Test SPIFFS Operations, require wiping pages 0 and 1", + "mem spiffs test"); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); clearCommandBuffer(); SendCommandNG(CMD_SPIFFS_TEST, NULL, 0); return PM3_SUCCESS; } static int CmdFlashMemSpiFFSCheck(const char *Cmd) { - (void)Cmd; // Cmd is not used so far + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem spiffs check", + "Check/try to defrag faulty/fragmented SPIFFS file system", + "mem spiffs check"); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); clearCommandBuffer(); SendCommandNG(CMD_SPIFFS_CHECK, NULL, 0); return PM3_SUCCESS; } static int CmdFlashMemSpiFFSTree(const char *Cmd) { - (void)Cmd; // Cmd is not used so far + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem spiffs tree", + "Print the Flash memory file system tree", + "mem spiffs tree"); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); clearCommandBuffer(); SendCommandNG(CMD_SPIFFS_PRINT_TREE, NULL, 0); return PM3_SUCCESS; } static int CmdFlashMemSpiFFSInfo(const char *Cmd) { - (void)Cmd; // Cmd is not used so far + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem spiffs info", + "Print file system info and usage statistics", + "mem spiffs info"); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); clearCommandBuffer(); SendCommandNG(CMD_SPIFFS_PRINT_FSINFO, NULL, 0); return PM3_SUCCESS; } static int CmdFlashMemSpiFFSRemove(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem spiffs remove", + "Remove a file from SPIFFS filesystem", + "mem spiffs remove -f lasttag.bin" + ); - int len = strlen(Cmd); - if (len < 1) { - return usage_flashmemspiffs_remove(); - } - - char ctmp = tolower(param_getchar(Cmd, 0)); - if (len == 1 && ctmp == 'h') { - return usage_flashmemspiffs_remove(); - } + void *argtable[] = { + arg_param_begin, + arg_str1("f", "filename", "", "file to remove"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + int fnlen = 0; char filename[32] = {0}; - bool errors = false; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, 32, &fnlen); + CLIParserFree(ctx); - if (param_getstr(Cmd, 0, filename, 32) >= 32) { - PrintAndLogEx(FAILED, "Filename too long"); - errors = true; - } + PrintAndLogEx(DEBUG, "Removing `" _YELLOW_("%s") "`", filename); + struct { + uint8_t len; + uint8_t fn[32]; + } PACKED payload; + payload.len = fnlen; + memcpy(payload.fn, filename, fnlen); - // check null filename ? - if (errors) { - usage_flashmemspiffs_remove(); - return PM3_EINVARG; - } + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_REMOVE, (uint8_t *)&payload, sizeof(payload)); + WaitForResponse(CMD_SPIFFS_REMOVE, &resp); + if (resp.status == PM3_SUCCESS) + PrintAndLogEx(INFO, "Done!"); - SendCommandMIX(CMD_SPIFFS_REMOVE, 0, 0, 0, (uint8_t *)filename, 32); return PM3_SUCCESS; } static int CmdFlashMemSpiFFSRename(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem spiffs rename", + "Rename/move a file from SPIFFS filesystem.", + "mem spiffs rename -s aaa.bin -d bbb.bin" + ); - int len = strlen(Cmd); - if (len < 1) { - return usage_flashmemspiffs_rename(); - } + void *argtable[] = { + arg_param_begin, + arg_str1("s", "src", "", "source file name"), + arg_str1("d", "dest", "", "destination file name"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); - char ctmp = tolower(param_getchar(Cmd, 0)); - if (len == 1 && ctmp == 'h') { - return usage_flashmemspiffs_rename(); - } + int slen = 0; + char src[32] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)src, 32, &slen); - char srcfilename[32] = {0}; - char destfilename[32] = {0}; - bool errors = false; + int dlen = 0; + char dest[32] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)dest, 32, &dlen); + CLIParserFree(ctx); - if (param_getstr(Cmd, 0, srcfilename, 32) >= 32) { - PrintAndLogEx(FAILED, "Source Filename too long"); - errors = true; - } - if (srcfilename[0] == '\0') { - PrintAndLogEx(FAILED, "Source Filename missing or invalid"); - errors = true; - } + PrintAndLogEx(DEBUG, "Rename from `" _YELLOW_("%s") "` -> `" _YELLOW_("%s") "`", src, dest); - if (param_getstr(Cmd, 1, destfilename, 32) >= 32) { - PrintAndLogEx(FAILED, "Source Filename too long"); - errors = true; - } - if (destfilename[0] == '\0') { - PrintAndLogEx(FAILED, "Source Filename missing or invalid"); - errors = true; - } + struct { + uint8_t slen; + uint8_t src[32]; + uint8_t dlen; + uint8_t dest[32]; + } PACKED payload; + payload.slen = slen; + payload.dlen = dlen; - // check null filename ? - if (errors) { - usage_flashmemspiffs_rename(); - return PM3_EINVARG; - } + memcpy(payload.src, src, slen); + memcpy(payload.dest, dest, dlen); - char data[65]; - sprintf(data, "%s,%s", srcfilename, destfilename); - SendCommandMIX(CMD_SPIFFS_RENAME, 0, 0, 0, (uint8_t *)data, 65); + PacketResponseNG resp; + clearCommandBuffer(); + SendCommandNG(CMD_SPIFFS_RENAME, (uint8_t *)&payload, sizeof(payload)); + WaitForResponse(CMD_SPIFFS_RENAME, &resp); + if (resp.status == PM3_SUCCESS) + PrintAndLogEx(INFO, "Done!"); + + PrintAndLogEx(HINT, "Try `" _YELLOW_("mem spiffs tree") "` to verify"); return PM3_SUCCESS; } @@ -353,73 +473,6 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) { return PM3_SUCCESS; } -int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen) { - - int ret_val = PM3_SUCCESS; - - // We want to mount before multiple operation so the lazy writes/append will not - // trigger a mount + umount each loop iteration (lazy ops device side) - SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0); - - // Send to device - uint32_t bytes_sent = 0; - uint32_t bytes_remaining = datalen; - uint32_t append = 0; - - // fast push mode - conn.block_after_ACK = true; - - while (bytes_remaining > 0) { - uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); - - clearCommandBuffer(); - - char fdata[32 + bytes_in_packet]; - memset(fdata, 0, sizeof(fdata)); - memcpy(fdata, destfn, 32); - memcpy(fdata + 32, data + bytes_sent, bytes_in_packet); - - if (bytes_sent > 0) - append = 1; - - SendCommandOLD(CMD_SPIFFS_WRITE, append, bytes_in_packet, 0, fdata, 32 + bytes_in_packet); - - bytes_remaining -= bytes_in_packet; - bytes_sent += bytes_in_packet; - - PacketResponseNG resp; - - uint8_t retry = 3; - while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { - PrintAndLogEx(WARNING, "timeout while waiting for reply."); - retry--; - if (retry == 0) { - ret_val = PM3_ETIMEOUT; - goto out; - } - } - - uint8_t isok = resp.oldarg[0] & 0xFF; - if (!isok) { - PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent); - ret_val = PM3_EFLASH; - break; - } - } - -out: - clearCommandBuffer(); - - // turn off fast push mode - conn.block_after_ACK = false; - - // We want to unmount after these to set things back to normal but more than this - // unmouting ensure that SPIFFS CACHES are all flushed so our file is actually written on memory - SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0); - - return ret_val; -} - static int CmdFlashMemSpiFFSWipe(const char *Cmd) { char ctmp = tolower(param_getchar(Cmd, 0)); @@ -433,7 +486,7 @@ static int CmdFlashMemSpiFFSWipe(const char *Cmd) { SendCommandNG(CMD_SPIFFS_WIPE, NULL, 0); WaitForResponse(CMD_SPIFFS_WIPE, &resp); PrintAndLogEx(INFO, "Done!"); - PrintAndLogEx(HINT, "Try use '" _YELLOW_("mem spiffs tree") "' to verify."); + PrintAndLogEx(HINT, "Try `" _YELLOW_("mem spiffs tree") "` to verify"); return PM3_SUCCESS; } @@ -495,20 +548,19 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) { } static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, "Copy a file to another (destructively) in SPIFFS FileSystem in FlashMEM (spiffs)"}, - {"check", CmdFlashMemSpiFFSCheck, IfPm3Flash, "Check/try to defrag faulty/fragmented Filesystem"}, - {"dump", CmdFlashMemSpiFFSDump, IfPm3Flash, "Dump a file from SPIFFS FileSystem in FlashMEM (spiffs)"}, - {"info", CmdFlashMemSpiFFSInfo, IfPm3Flash, "Print filesystem info and usage statistics (spiffs)"}, - {"load", CmdFlashMemSpiFFSLoad, IfPm3Flash, "Upload file into SPIFFS Filesystem (spiffs)"}, - {"mount", CmdFlashMemSpiFFSMount, IfPm3Flash, "Mount the SPIFFS Filesystem if not already mounted (spiffs)"}, - {"remove", CmdFlashMemSpiFFSRemove, IfPm3Flash, "Remove a file from SPIFFS FileSystem in FlashMEM (spiffs)"}, - {"rename", CmdFlashMemSpiFFSRename, IfPm3Flash, "Rename/move a file in SPIFFS FileSystem in FlashMEM (spiffs)"}, - {"test", CmdFlashMemSpiFFSTest, IfPm3Flash, "Test SPIFFS Operations (require wiping pages 0 and 1)"}, - {"tree", CmdFlashMemSpiFFSTree, IfPm3Flash, "Print the Flash Memory FileSystem Tree (spiffs)"}, - {"unmount", CmdFlashMemSpiFFSUnmount, IfPm3Flash, "Un-mount the SPIFFS Filesystem if not already mounted (spiffs)"}, - {"wipe", CmdFlashMemSpiFFSWipe, IfPm3Flash, "Wipe all files from SPIFFS FileSystem." _RED_("* dangerous *") }, + {"copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, "Copy a file to another (destructively) in SPIFFS file system"}, + {"check", CmdFlashMemSpiFFSCheck, IfPm3Flash, "Check/try to defrag faulty/fragmented file system"}, + {"dump", CmdFlashMemSpiFFSDump, IfPm3Flash, "Dump a file from SPIFFS file system"}, + {"info", CmdFlashMemSpiFFSInfo, IfPm3Flash, "Print file system info and usage statistics"}, + {"load", CmdFlashMemSpiFFSLoad, IfPm3Flash, "Upload file into SPIFFS file system"}, + {"mount", CmdFlashMemSpiFFSMount, IfPm3Flash, "Mount the SPIFFS file system if not already mounted"}, + {"remove", CmdFlashMemSpiFFSRemove, IfPm3Flash, "Remove a file from SPIFFS file system"}, + {"rename", CmdFlashMemSpiFFSRename, IfPm3Flash, "Rename/move a file in SPIFFS file system"}, + {"test", CmdFlashMemSpiFFSTest, IfPm3Flash, "Test SPIFFS Operations"}, + {"tree", CmdFlashMemSpiFFSTree, IfPm3Flash, "Print the Flash memory file system tree"}, + {"unmount", CmdFlashMemSpiFFSUnmount, IfPm3Flash, "Un-mount the SPIFFS file system"}, + {"wipe", CmdFlashMemSpiFFSWipe, IfPm3Flash, "Wipe all files from SPIFFS file system. * " _RED_("dangerous") " *" }, {NULL, NULL, NULL, NULL} };