diff --git a/armsrc/Standalone/hf_iceclass.c b/armsrc/Standalone/hf_iceclass.c index 2a0ef6236..00de115e6 100644 --- a/armsrc/Standalone/hf_iceclass.c +++ b/armsrc/Standalone/hf_iceclass.c @@ -125,7 +125,7 @@ static void download_instructions(uint8_t t) { case ICE_STATE_FULLSIM: { DbpString("The emulator memory was saved to SPIFFS"); DbpString("1. " _YELLOW_("mem spiffs dump o " HF_ICLASS_FULLSIM_MOD_BIN " f " HF_ICLASS_FULLSIM_MOD" e")); - DbpString("2. " _YELLOW_("hf iclass view f " HF_ICLASS_FULLSIM_MOD_BIN)); + DbpString("2. " _YELLOW_("hf iclass view -f " HF_ICLASS_FULLSIM_MOD_BIN)); break; } case ICE_STATE_ATTACK: { diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 8dfe7720a..6417de85b 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -18,6 +18,7 @@ #include "cmdparser.h" // command_t #include "commonutil.h" // ARRAYLEN #include "cmdtrace.h" +#include "cliparser.h" #include "util_posix.h" #include "comms.h" #include "des.h" @@ -224,21 +225,6 @@ static int usage_hf_iclass_readblock(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_hf_iclass_view(void) { - PrintAndLogEx(NORMAL, "Print a iCLASS tag dump file\n"); - PrintAndLogEx(NORMAL, "Usage: hf iClass view [f ] [s ] [e ] [v]\n"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h Show this help"); - PrintAndLogEx(NORMAL, " f filename of dump"); - PrintAndLogEx(NORMAL, " s print from this block (default block6)"); - PrintAndLogEx(NORMAL, " e end printing at this block (default 0, ALL)"); - PrintAndLogEx(NORMAL, " v verbose output"); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass view f hf-iclass-AA162D30F8FF12F1-dump.bin")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass view s 1 f hf-iclass-AA162D30F8FF12F1-dump.bin")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} static int usage_hf_iclass_calc_newkey(void) { PrintAndLogEx(NORMAL, "Calculate new key for updating\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass calc_newkey o n s [csn] e\n"); @@ -359,20 +345,7 @@ static int usage_hf_iclass_lookup(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_hf_iclass_permutekey(void) { - PrintAndLogEx(NORMAL, "Permute function from 'heart of darkness' paper.\n"); - PrintAndLogEx(NORMAL, "Usage: hf iclass permute [h] \n"); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h Show this help"); - PrintAndLogEx(NORMAL, " r reverse permuted key"); - PrintAndLogEx(NORMAL, " f permute key"); - PrintAndLogEx(NORMAL, " input bytes"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass permute r 0123456789abcdef")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} + static int cmp_uint32(const void *a, const void *b) { @@ -2680,43 +2653,31 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e } static int CmdHFiClassView(const char *Cmd) { - int startblock = 0; - int endblock = 0; - char filename[FILE_PATH_SIZE]; - bool errors = false, verbose = false; - uint8_t cmdp = 0; - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_hf_iclass_view(); - case 'f': - if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { - PrintAndLogEx(FAILED, "Filename too long"); - errors = true; - break; - } - cmdp += 2; - break; - case 's': - startblock = param_get8ex(Cmd, cmdp + 1, 0, 10); - cmdp += 2; - break; - case 'e': - endblock = param_get8ex(Cmd, cmdp + 1, 0, 10); - cmdp += 2; - break; - case 'v': - verbose = true; - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf iclass view", + "Print a iCLASS tag dump file", + "hf iclass view -f hf-iclass-AA162D30F8FF12F1-dump.bin\n" + "hf iclass view --startblock 1 --file hf-iclass-AA162D30F8FF12F1-dump.bin\n"); - if (errors || (strlen(Cmd) == 0)) return usage_hf_iclass_view(); + void *argtable[] = { + arg_param_begin, + arg_str1("f", "file", "", "filename of dump"), + arg_int0("s", "startblock", "", "print from this block (default block6)"), + arg_int0("e", "endblock", "", "end printing at this block (default 0, ALL)"), + arg_lit0("v", "verbose", "verbose output"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int fnlen = 0; + char filename[FILE_PATH_SIZE]; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t*)filename, FILE_PATH_SIZE, &fnlen); + + int startblock = arg_get_int_def(ctx, 2, 0); + int endblock = arg_get_int_def(ctx, 3, 0); + bool verbose = arg_get_lit(ctx, 4); + + CLIParserFree(ctx); uint8_t *dump = NULL; size_t bytes_read = 0; @@ -3522,17 +3483,26 @@ static int CmdHFiClassPermuteKey(const char *Cmd) { uint8_t data[16] = {0}; bool isReverse = false; int len = 0; - char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h') - return usage_hf_iclass_permutekey(); - isReverse = (cmdp == 'r'); + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf iclass permute", + "Permute function from 'heart of darkness' paper.", + "hf iclass permute --reverse --key 0123456789abcdef\n" + "hf iclass permute --key ff55330f0055330f\n"); - param_gethex_ex(Cmd, 1, data, &len); - if (len % 2) - return usage_hf_iclass_permutekey(); + void *argtable[] = { + arg_param_begin, + arg_lit0("r", "reverse", "reverse permuted key"), + arg_str1(NULL, "key", "", "input key"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); - len >>= 1; + isReverse = arg_get_lit(ctx, 1); + + CLIGetHexWithReturn(ctx, 2, data, &len); + + CLIParserFree(ctx); memcpy(key, data, 8); @@ -3580,7 +3550,7 @@ static command_t CommandTable[] = { {"encrypt", CmdHFiClassEncryptBlk, AlwaysAvailable, "[options..] Encrypt given block data"}, {"decrypt", CmdHFiClassDecrypt, AlwaysAvailable, "[options..] Decrypt given block data or tag dump file" }, {"managekeys", CmdHFiClassManageKeys, AlwaysAvailable, "[options..] Manage keys to use with iclass commands"}, - {"permutekey", CmdHFiClassPermuteKey, IfPm3Iclass, " Permute function from 'heart of darkness' paper"}, + {"permute", CmdHFiClassPermuteKey, IfPm3Iclass, " Permute function from 'heart of darkness' paper"}, {"view", CmdHFiClassView, AlwaysAvailable, "[options..] Display content from tag dump file"}, {NULL, NULL, NULL, NULL} diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index bee2b2b5e..5e46f68df 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -46,9 +46,10 @@ Reverse permute iCLASS master key ``` Options --- -r reverse permuted key +-r --reverse : reverse permuted key + --key : input key -pm3 --> hf iclass permute r 3F90EBF0910F7B6F +pm3 --> hf iclass permute --reverse --key 3F90EBF0910F7B6F ``` iCLASS Reader diff --git a/doc/commands.md b/doc/commands.md index 94d28dfdf..c0aeea991 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -241,7 +241,7 @@ Check column "offline" for their availability. ### hf iclass { ICLASS RFIDs... } - + |command |offline |description |------- |------- |----------- |`hf iclass help `|Y |`This help` @@ -265,8 +265,8 @@ Check column "offline" for their availability. |`hf iclass encrypt `|Y |`[options..] Encrypt given block data` |`hf iclass decrypt `|Y |`[options..] Decrypt given block data or tag dump file` |`hf iclass managekeys `|Y |`[options..] Manage keys to use with iclass commands` -|`hf iclass permutekey `|N |` Permute function from 'heart of darkness' paper` -|`hf iclass view `|Y |`[options..] Display content from tag dump file` +|`hf iclass permute `|N |` Permute function from 'heart of darkness' paper` +|`hf iclass view `|Y |`[options..] Display content from tag dump file` ### hf legic @@ -304,7 +304,7 @@ Check column "offline" for their availability. |`hf lto wrbl `|N |`Write block` |`hf lto list `|Y |`List LTO-CM history` - + ### hf mf { MIFARE RFIDs... }