From 6326c4126c10daeb5d639e665ec23946776fc301 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 1 Jun 2020 17:30:33 +0200 Subject: [PATCH] cliparser: remove global vars --- client/deps/cliparser/cliparser.c | 79 ++++++------ client/deps/cliparser/cliparser.h | 26 ++-- client/src/cmddata.c | 9 +- client/src/cmdhf.c | 6 +- client/src/cmdhf14a.c | 34 ++--- client/src/cmdhffido.c | 62 ++++----- client/src/cmdhfmf.c | 59 +++++---- client/src/cmdhfmfdes.c | 208 ++++++++++++++++-------------- client/src/cmdhfmfp.c | 112 ++++++++-------- client/src/cmdhfmfu.c | 9 +- client/src/cmdlfindala.c | 9 +- client/src/cmdlfmotorola.c | 9 +- client/src/emv/cmdemv.c | 101 ++++++++------- 13 files changed, 393 insertions(+), 330 deletions(-) diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index 27b0ed050..c4795d870 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -10,50 +10,50 @@ #include "cliparser.h" #include +#include -void **argtable = NULL; -size_t argtableLen = 0; -const char *programName = NULL; -const char *programHint = NULL; -const char *programHelp = NULL; -char buf[500] = {0}; - -int CLIParserInit(const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) { - argtable = NULL; - argtableLen = 0; - programName = vprogramName; - programHint = vprogramHint; - programHelp = vprogramHelp; - memset(buf, 0x00, 500); +int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) { + *ctx = malloc(sizeof(CLIParserContext)); + if (!*ctx) { + printf("ERROR: Insufficient memory\n"); + fflush(stdout); + return 2; + } + (*ctx)->argtable = NULL; + (*ctx)->argtableLen = 0; + (*ctx)->programName = vprogramName; + (*ctx)->programHint = vprogramHint; + (*ctx)->programHelp = vprogramHelp; + memset((*ctx)->buf, 0x00, sizeof((*ctx)->buf)); return 0; } -int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) { +int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) { int nerrors; - argtable = vargtable; - argtableLen = vargtableLen; + ctx->argtable = vargtable; + ctx->argtableLen = vargtableLen; /* verify the argtable[] entries were allocated sucessfully */ - if (arg_nullcheck(argtable) != 0) { + if (arg_nullcheck(ctx->argtable) != 0) { /* NULL entries were detected, some allocations must have failed */ printf("ERROR: Insufficient memory\n"); fflush(stdout); return 2; } /* Parse the command line as defined by argtable[] */ - nerrors = arg_parse(argc, argv, argtable); + nerrors = arg_parse(argc, argv, ctx->argtable); /* special case: '--help' takes precedence over error reporting */ - if ((argc < 2 && !allowEmptyExec) || ((struct arg_lit *)argtable[0])->count > 0) { // help must be the first record - printf("Usage: %s", programName); - arg_print_syntaxv(stdout, argtable, "\n"); - if (programHint) - printf("%s\n\n", programHint); - arg_print_glossary(stdout, argtable, " %-20s %s\n"); + if ((argc < 2 && !allowEmptyExec) || ((struct arg_lit *)(ctx->argtable)[0])->count > 0) { // help must be the first record + printf("Usage: %s", ctx->programName); + arg_print_syntaxv(stdout, ctx->argtable, "\n"); + if (ctx->programHint) + printf("%s\n\n", ctx->programHint); + arg_print_glossary(stdout, ctx->argtable, " %-20s %s\n"); printf("\n"); - if (programHelp) - printf("%s \n", programHelp); + if (ctx->programHelp) + printf("%s \n", ctx->programHelp); fflush(stdout); return 1; @@ -62,8 +62,8 @@ int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtable /* If the parser returned any errors then display them and exit */ if (nerrors > 0) { /* Display the error details contained in the arg_end struct.*/ - arg_print_errors(stdout, ((struct arg_end *)argtable[vargtableLen - 1]), programName); - printf("Try '%s --help' for more information.\n", programName); + arg_print_errors(stdout, ((struct arg_end *)(ctx->argtable)[vargtableLen - 1]), ctx->programName); + printf("Try '%s --help' for more information.\n", ctx->programName); fflush(stdout); return 3; } @@ -79,23 +79,25 @@ enum ParserState { #define isSpace(c)(c == ' ' || c == '\t') -int CLIParserParseString(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) { - return CLIParserParseStringEx(str, vargtable, vargtableLen, allowEmptyExec, false); +int CLIParserParseString(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec) { + return CLIParserParseStringEx(ctx, str, vargtable, vargtableLen, allowEmptyExec, false); } -int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) { +int CLIParserParseStringEx(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) { int argc = 0; char *argv[200] = {NULL}; int len = strlen(str); + char buf[500] = {0}; + memset(ctx->buf, 0x00, 500); char *bufptr = buf; char *spaceptr = NULL; enum ParserState state = PS_FIRST; argv[argc++] = bufptr; // param0 = program name - memcpy(buf, programName, strlen(programName) + 1); // with 0x00 - bufptr += strlen(programName) + 1; + memcpy(buf, ctx->programName, strlen(ctx->programName) + 1); // with 0x00 + bufptr += strlen(ctx->programName) + 1; if (len) argv[argc++] = bufptr; @@ -140,13 +142,12 @@ int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableL } } - return CLIParserParseArg(argc, argv, vargtable, vargtableLen, allowEmptyExec); + return CLIParserParseArg(ctx, argc, argv, vargtable, vargtableLen, allowEmptyExec); } -void CLIParserFree(void) { - arg_freetable(argtable, argtableLen); - argtable = NULL; - +void CLIParserFree(CLIParserContext *ctx) { + arg_freetable(ctx->argtable, ctx->argtableLen); + free(ctx); return; } diff --git a/client/deps/cliparser/cliparser.h b/client/deps/cliparser/cliparser.h index 866ee07d6..b0000f77b 100644 --- a/client/deps/cliparser/cliparser.h +++ b/client/deps/cliparser/cliparser.h @@ -27,16 +27,24 @@ #define arg_strx1(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 1, 250, (glossary))) #define arg_strx0(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 0, 250, (glossary))) -#define CLIExecWithReturn(cmd, atbl, ifempty) if (CLIParserParseString(cmd, atbl, arg_getsize(atbl), ifempty)){CLIParserFree();return PM3_ESOFT;} -#define CLIGetHexBLessWithReturn(paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree();return PM3_ESOFT;} -#define CLIGetHexWithReturn(paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return PM3_ESOFT;} -#define CLIGetStrWithReturn(paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree();return PM3_ESOFT;} +#define CLIExecWithReturn(ctx, cmd, atbl, ifempty) if (CLIParserParseString(ctx, cmd, atbl, arg_getsize(atbl), ifempty)){CLIParserFree(ctx);return PM3_ESOFT;} +#define CLIGetHexBLessWithReturn(ctx, paramnum, data, datalen, delta) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data) - (delta), datalen)) {CLIParserFree(ctx);return PM3_ESOFT;} +#define CLIGetHexWithReturn(ctx, paramnum, data, datalen) if (CLIParamHexToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree(ctx);return PM3_ESOFT;} +#define CLIGetStrWithReturn(ctx, paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str(paramnum), data, sizeof(data), datalen)) {CLIParserFree(ctx);return PM3_ESOFT;} -int CLIParserInit(const char *vprogramName, const char *vprogramHint, const char *vprogramHelp); -int CLIParserParseString(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec); -int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData); -int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec); -void CLIParserFree(void); +typedef struct { + void **argtable; + size_t argtableLen; + const char *programName; + const char *programHint; + const char *programHelp; + char buf[500]; +} CLIParserContext; +int CLIParserInit(CLIParserContext **context, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp); +int CLIParserParseString(CLIParserContext *context, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec); +int CLIParserParseStringEx(CLIParserContext *context, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData); +int CLIParserParseArg(CLIParserContext *context, int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec); +void CLIParserFree(CLIParserContext *context); int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen); int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen); diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 5aba8e537..326e0d457 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -2292,7 +2292,8 @@ static int CmdDataNDEF(const char *Cmd) { #define MAX_NDEF_LEN 2048 #endif - CLIParserInit("data ndef", + CLIParserContext *ctx; + CLIParserInit(&ctx, "data ndef", "Prints NFC Data Exchange Format (NDEF)", "Usage:\n\tdata ndef -d 9101085402656e48656c6c6f5101085402656e576f726c64\n"); @@ -2301,12 +2302,12 @@ static int CmdDataNDEF(const char *Cmd) { arg_strx0("dD", "data", "", "NDEF data to decode"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); int datalen = 0; uint8_t data[MAX_NDEF_LEN] = {0}; - CLIGetHexWithReturn(1, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, data, &datalen); + CLIParserFree(ctx); if (datalen == 0) return PM3_EINVARG; diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index ff2a5e79f..6b11a30da 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -254,7 +254,8 @@ int CmdHFSniff(const char *Cmd) { } int CmdHFPlot(const char *Cmd) { - CLIParserInit("hf plot", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf plot", "Plots HF signal after RF signal path and A/D conversion.", "This can be used after any hf command and will show the last few milliseconds of the HF signal.\n" "Note: If the last hf command terminated because of a timeout you will most probably see nothing.\n"); @@ -262,7 +263,8 @@ int CmdHFPlot(const char *Cmd) { arg_param_begin, arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); uint8_t buf[FPGA_TRACE_SIZE]; diff --git a/client/src/cmdhf14a.c b/client/src/cmdhf14a.c index 5f1ec7b18..500406439 100644 --- a/client/src/cmdhf14a.c +++ b/client/src/cmdhf14a.c @@ -364,7 +364,8 @@ static int CmdHF14AInfo(const char *Cmd) { bool do_nack_test = false; bool do_aid_search = false; - CLIParserInit("hf 14a info", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a info", "This command makes more extensive tests against a ISO14443a tag in order to collect information", "Sample:\n\thf 14a info -nsv - shows full information about the card\n"); @@ -375,13 +376,13 @@ static int CmdHF14AInfo(const char *Cmd) { arg_lit0("sS", "aidsearch", "checks if AIDs from aidlist.json is present on the card and prints information about found AIDs"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); verbose = arg_get_lit(1); do_nack_test = arg_get_lit(2); do_aid_search = arg_get_lit(3); - CLIParserFree(); + CLIParserFree(ctx); infoHF14A(verbose, do_nack_test, do_aid_search); return 0; @@ -878,7 +879,8 @@ static int CmdHF14AAPDU(const char *Cmd) { bool extendedAPDU = false; int le = 0; - CLIParserInit("hf 14a apdu", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a apdu", "Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013", "Sample:\n\thf 14a apdu -st 00A404000E325041592E5359532E444446303100\n" "\thf 14a apdu -sd 00A404000E325041592E5359532E444446303100 - decode apdu\n" @@ -897,14 +899,14 @@ static int CmdHF14AAPDU(const char *Cmd) { arg_strx1(NULL, NULL, "", "data if `m` parameter included"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); activateField = arg_get_lit(1); leaveSignalON = arg_get_lit(2); decodeTLV = arg_get_lit(3); decodeAPDU = arg_get_lit(4); - CLIGetHexWithReturn(5, header, &headerlen); + CLIGetHexWithReturn(ctx, 5, header, &headerlen); makeAPDU = headerlen > 0; if (makeAPDU && headerlen != 4) { PrintAndLogEx(ERR, "header length must be 4 bytes instead of %d", headerlen); @@ -917,7 +919,7 @@ static int CmdHF14AAPDU(const char *Cmd) { uint8_t apdudata[PM3_CMD_DATA_SIZE] = {0}; int apdudatalen = 0; - CLIGetHexBLessWithReturn(8, apdudata, &apdudatalen, 1 + 2); + CLIGetHexBLessWithReturn(ctx, 8, apdudata, &apdudatalen, 1 + 2); APDUStruct apdu; apdu.cla = header[0]; @@ -947,10 +949,10 @@ static int CmdHF14AAPDU(const char *Cmd) { } // len = data + PCB(1b) + CRC(2b) - CLIGetHexBLessWithReturn(8, data, &datalen, 1 + 2); + CLIGetHexBLessWithReturn(ctx, 8, data, &datalen, 1 + 2); } - CLIParserFree(); + CLIParserFree(ctx); PrintAndLogEx(NORMAL, ">>>>[%s%s%s] %s", activateField ? "sel " : "", leaveSignalON ? "keep " : "", decodeTLV ? "TLV" : "", sprint_hex(data, datalen)); if (decodeAPDU) { @@ -1162,7 +1164,8 @@ static int waitCmd(uint8_t iSelect) { static int CmdHF14AAntiFuzz(const char *Cmd) { - CLIParserInit("hf 14a antifuzz", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a antifuzz", "Tries to fuzz the ISO14443a anticollision phase", "Usage:\n" "\thf 14a antifuzz -4\n"); @@ -1174,7 +1177,7 @@ static int CmdHF14AAntiFuzz(const char *Cmd) { arg_lit0(NULL, "10", "10 byte uid"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); uint8_t arg0 = FLAG_4B_UID_IN_DATA; if (arg_get_lit(2)) @@ -1182,7 +1185,7 @@ static int CmdHF14AAntiFuzz(const char *Cmd) { if (arg_get_lit(3)) arg0 = FLAG_10B_UID_IN_DATA; - CLIParserFree(); + CLIParserFree(ctx); clearCommandBuffer(); SendCommandMIX(CMD_HF_ISO14443A_ANTIFUZZ, arg0, 0, 0, NULL, 0); return 0; @@ -1190,7 +1193,8 @@ static int CmdHF14AAntiFuzz(const char *Cmd) { static int CmdHF14AChaining(const char *Cmd) { - CLIParserInit("hf 14a chaining", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 14a chaining", "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", "Usage:\n" "\thf 14a chaining disable -> disable chaining\n" @@ -1201,7 +1205,7 @@ static int CmdHF14AChaining(const char *Cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); struct arg_str *str = arg_get_str(1); int len = arg_get_str_len(1); @@ -1212,7 +1216,7 @@ static int CmdHF14AChaining(const char *Cmd) { if (len && (!strcmp(str->sval[0], "disable") || !strcmp(str->sval[0], "0"))) APDUInFramingEnable = false; - CLIParserFree(); + CLIParserFree(ctx); PrintAndLogEx(INFO, "\nISO 14443-4 input chaining %s.\n", APDUInFramingEnable ? "enabled" : "disabled"); diff --git a/client/src/cmdhffido.c b/client/src/cmdhffido.c index 991d7eb5d..22b855e95 100644 --- a/client/src/cmdhffido.c +++ b/client/src/cmdhffido.c @@ -110,7 +110,7 @@ static int CmdHFFidoInfo(const char *cmd) { return 0; } -static json_t *OpenJson(int paramnum, char *fname, void *argtable[], bool *err) { +static json_t *OpenJson(CLIParserContext *ctx, int paramnum, char *fname, void *argtable[], bool *err) { json_t *root = NULL; json_error_t error; *err = false; @@ -119,9 +119,9 @@ static json_t *OpenJson(int paramnum, char *fname, void *argtable[], bool *err) char *cjsonname = (char *)jsonname; int jsonnamelen = 0; - // CLIGetStrWithReturn(paramnum, jsonname, &jsonnamelen); + // CLIGetStrWithReturn(ctx, paramnum, jsonname, &jsonnamelen); if (CLIParamStrToBuf(arg_get_str(paramnum), jsonname, sizeof(jsonname), &jsonnamelen)) { - CLIParserFree(); + CLIParserFree(ctx); return NULL; } @@ -162,7 +162,8 @@ static int CmdHFFidoRegister(const char *cmd) { uint8_t adata[250] = {0}; json_t *root = NULL; - CLIParserInit("hf fido reg", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fido reg", "Initiate a U2F token registration. Needs two 32-byte hash numbers. \nchallenge parameter (32b) and application parameter (32b).", "Usage:\n\thf fido reg -> execute command with 2 parameters, filled 0x00\n" "\thf fido reg 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters" @@ -179,7 +180,7 @@ static int CmdHFFidoRegister(const char *cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); bool APDULogging = arg_get_lit(1); bool verbose = arg_get_lit(2); @@ -189,7 +190,7 @@ static int CmdHFFidoRegister(const char *cmd) { char fname[250] = {0}; bool err; - root = OpenJson(5, fname, argtable, &err); + root = OpenJson(ctx, 5, fname, argtable, &err); if (err) return 1; if (root) { @@ -200,13 +201,13 @@ static int CmdHFFidoRegister(const char *cmd) { if (paramsPlain) { memset(cdata, 0x00, 32); - CLIGetStrWithReturn(6, cdata, &chlen); + CLIGetStrWithReturn(ctx, 6, cdata, &chlen); if (chlen > 16) { PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", chlen); return 1; } } else { - CLIGetHexWithReturn(6, cdata, &chlen); + CLIGetHexWithReturn(ctx, 6, cdata, &chlen); if (chlen && chlen != 32) { PrintAndLogEx(ERR, "ERROR: challenge parameter length must be 32 bytes only."); return 1; @@ -218,13 +219,13 @@ static int CmdHFFidoRegister(const char *cmd) { if (paramsPlain) { memset(adata, 0x00, 32); - CLIGetStrWithReturn(7, adata, &applen); + CLIGetStrWithReturn(ctx, 7, adata, &applen); if (applen > 16) { PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", applen); return 1; } } else { - CLIGetHexWithReturn(7, adata, &applen); + CLIGetHexWithReturn(ctx, 7, adata, &applen); if (applen && applen != 32) { PrintAndLogEx(ERR, "ERROR: application parameter length must be 32 bytes only."); return 1; @@ -233,7 +234,7 @@ static int CmdHFFidoRegister(const char *cmd) { if (applen) memmove(&data[32], adata, 32); - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -393,7 +394,8 @@ static int CmdHFFidoAuthenticate(const char *cmd) { uint8_t keyHandleLen = 0; json_t *root = NULL; - CLIParserInit("hf fido auth", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fido auth", "Initiate a U2F token authentication. Needs key handle and two 32-byte hash numbers. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).", "Usage:\n\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n" "\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f " @@ -414,7 +416,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); bool APDULogging = arg_get_lit(1); bool verbose = arg_get_lit(2); @@ -427,7 +429,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { char fname[250] = {0}; bool err; - root = OpenJson(7, fname, argtable, &err); + root = OpenJson(ctx, 7, fname, argtable, &err); if (err) return 1; if (root) { @@ -442,7 +444,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { } // public key - CLIGetHexWithReturn(8, hdata, &hdatalen); + CLIGetHexWithReturn(ctx, 8, hdata, &hdatalen); if (hdatalen && hdatalen != 65) { PrintAndLogEx(ERR, "ERROR: public key length must be 65 bytes only."); return 1; @@ -452,7 +454,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { public_key_loaded = true; } - CLIGetHexWithReturn(9, hdata, &hdatalen); + CLIGetHexWithReturn(ctx, 9, hdata, &hdatalen); if (hdatalen > 255) { PrintAndLogEx(ERR, "ERROR: application parameter length must be less than 255."); return 1; @@ -465,13 +467,13 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (paramsPlain) { memset(hdata, 0x00, 32); - CLIGetStrWithReturn(9, hdata, &hdatalen); + CLIGetStrWithReturn(ctx, 9, hdata, &hdatalen); if (hdatalen > 16) { PrintAndLogEx(ERR, "ERROR: challenge parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen); return 1; } } else { - CLIGetHexWithReturn(10, hdata, &hdatalen); + CLIGetHexWithReturn(ctx, 10, hdata, &hdatalen); if (hdatalen && hdatalen != 32) { PrintAndLogEx(ERR, "ERROR: challenge parameter length must be 32 bytes only."); return 1; @@ -482,13 +484,13 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (paramsPlain) { memset(hdata, 0x00, 32); - CLIGetStrWithReturn(11, hdata, &hdatalen); + CLIGetStrWithReturn(ctx, 11, hdata, &hdatalen); if (hdatalen > 16) { PrintAndLogEx(ERR, "ERROR: application parameter length in ASCII mode must be less than 16 chars instead of: %d", hdatalen); return 1; } } else { - CLIGetHexWithReturn(10, hdata, &hdatalen); + CLIGetHexWithReturn(ctx, 10, hdata, &hdatalen); if (hdatalen && hdatalen != 32) { PrintAndLogEx(ERR, "ERROR: application parameter length must be 32 bytes only."); return 1; @@ -497,7 +499,7 @@ static int CmdHFFidoAuthenticate(const char *cmd) { if (hdatalen) memmove(&data[32], hdata, 32); - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -641,7 +643,8 @@ static int CmdHFFido2MakeCredential(const char *cmd) { json_t *root = NULL; char fname[300] = {0}; - CLIParserInit("hf fido make", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fido make", "Execute a FIDO2 Make Credential command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.", "Usage:\n\thf fido make -> execute command with default parameters file `fido2.json`\n" "\thf fido make test.json -> execute command with parameters file `text.json`"); @@ -655,7 +658,7 @@ static int CmdHFFido2MakeCredential(const char *cmd) { arg_str0(NULL, NULL, "", "JSON input / output file name for parameters. Default `fido2.json`"), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); bool APDULogging = arg_get_lit(1); bool verbose = arg_get_lit(2); @@ -666,14 +669,14 @@ static int CmdHFFido2MakeCredential(const char *cmd) { uint8_t jsonname[250] = {0}; char *cjsonname = (char *)jsonname; int jsonnamelen = 0; - CLIGetStrWithReturn(5, jsonname, &jsonnamelen); + CLIGetStrWithReturn(ctx, 5, jsonname, &jsonnamelen); if (!jsonnamelen) { strcat(cjsonname, "fido2"); jsonnamelen = strlen(cjsonname); } - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -767,7 +770,8 @@ static int CmdHFFido2GetAssertion(const char *cmd) { json_t *root = NULL; char fname[300] = {0}; - CLIParserInit("hf fido assert", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf fido assert", "Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.", "Usage:\n\thf fido assert -> execute command with default parameters file `fido2.json`\n" "\thf fido assert test.json -l -> execute command with parameters file `text.json` and add to request CredentialId"); @@ -781,7 +785,7 @@ static int CmdHFFido2GetAssertion(const char *cmd) { arg_str0(NULL, NULL, "", "JSON input / output file name for parameters. Default `fido2.json`"), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); bool APDULogging = arg_get_lit(1); bool verbose = arg_get_lit(2); @@ -792,14 +796,14 @@ static int CmdHFFido2GetAssertion(const char *cmd) { uint8_t jsonname[250] = {0}; char *cjsonname = (char *)jsonname; int jsonnamelen = 0; - CLIGetStrWithReturn(5, jsonname, &jsonnamelen); + CLIGetStrWithReturn(ctx, 5, jsonname, &jsonnamelen); if (!jsonnamelen) { strcat(cjsonname, "fido2"); jsonnamelen = strlen(cjsonname); } - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 2257a3172..062f22c06 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -4025,7 +4025,8 @@ static int CmdHF14AMfCWipe(const char *cmd) { uint8_t sak[1] = {0x00}; int sakLen = 0; - CLIParserInit("hf mf cwipe", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf cwipe", "Wipe gen1 magic chinese card. Set UID/ATQA/SAK/Data/Keys/Access to default values.", "Usage:\n\thf mf cwipe -> wipe card.\n" "\thf mf cwipe -u 09080706 -a 0004 -s 18 -- set UID, ATQA and SAK and wipe card."); @@ -4037,12 +4038,12 @@ static int CmdHF14AMfCWipe(const char *cmd) { arg_str0("sS", "sak", "", "SAK for card"), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); - CLIGetHexWithReturn(1, uid, &uidLen); - CLIGetHexWithReturn(2, atqa, &atqaLen); - CLIGetHexWithReturn(3, sak, &sakLen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, uid, &uidLen); + CLIGetHexWithReturn(ctx, 2, atqa, &atqaLen); + CLIGetHexWithReturn(ctx, 3, sak, &sakLen); + CLIParserFree(ctx); if (uidLen && uidLen != 4) { PrintAndLogEx(ERR, "UID length must be 4 bytes instead of: %d", uidLen); @@ -4611,7 +4612,8 @@ static int CmdHF14AMfAuth4(const char *Cmd) { uint8_t key[16] = {0}; int keylen = 0; - CLIParserInit("hf mf auth4", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf auth4", "Executes AES authentication command in ISO14443-4", "Usage:\n\thf mf auth4 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n" "\thf mf auth4 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> executes authentication\n"); @@ -4622,11 +4624,11 @@ static int CmdHF14AMfAuth4(const char *Cmd) { arg_str1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); - CLIGetHexWithReturn(1, keyn, &keynlen); - CLIGetHexWithReturn(2, key, &keylen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, keyn, &keynlen); + CLIGetHexWithReturn(ctx, 2, key, &keylen); + CLIParserFree(ctx); if (keynlen != 2) { PrintAndLogEx(ERR, " must be 2 bytes long instead of: %d", keynlen); @@ -4644,7 +4646,8 @@ static int CmdHF14AMfAuth4(const char *Cmd) { // https://www.nxp.com/docs/en/application-note/AN10787.pdf static int CmdHF14AMfMAD(const char *Cmd) { - CLIParserInit("hf mf mad", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf mad", "Checks and prints Mifare Application Directory (MAD)", "Usage:\n\thf mf mad -> shows MAD if exists\n" "\thf mf mad -a 03e1 -k ffffffffffff -b -> shows NDEF data if exists. read card with custom key and key B\n"); @@ -4657,17 +4660,17 @@ static int CmdHF14AMfMAD(const char *Cmd) { arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool verbose = arg_get_lit(1); uint8_t aid[2] = {0}; int aidlen; - CLIGetHexWithReturn(2, aid, &aidlen); + CLIGetHexWithReturn(ctx, 2, aid, &aidlen); uint8_t key[6] = {0}; int keylen; - CLIGetHexWithReturn(3, key, &keylen); + CLIGetHexWithReturn(ctx, 3, key, &keylen); bool keyB = arg_get_lit(4); - CLIParserFree(); + CLIParserFree(ctx); if (aidlen != 2 && keylen > 0) { PrintAndLogEx(WARNING, "do not need a key without aid."); @@ -4734,7 +4737,8 @@ static int CmdHF14AMfMAD(const char *Cmd) { static int CmdHFMFNDEF(const char *Cmd) { - CLIParserInit("hf mf ndef", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf ndef", "Prints NFC Data Exchange Format (NDEF)", "Usage:\n\thf mf ndef -> shows NDEF data\n" "\thf mf ndef -a 03e1 -k ffffffffffff -b -> shows NDEF data with custom AID, key and with key B\n"); @@ -4747,19 +4751,19 @@ static int CmdHFMFNDEF(const char *Cmd) { arg_lit0("bB", "keyb", "use key B for access sectors (by default: key A)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool verbose = arg_get_lit(1); bool verbose2 = arg_get_lit(1) > 1; uint8_t aid[2] = {0}; int aidlen; - CLIGetHexWithReturn(2, aid, &aidlen); + CLIGetHexWithReturn(ctx, 2, aid, &aidlen); uint8_t key[6] = {0}; int keylen; - CLIGetHexWithReturn(3, key, &keylen); + CLIGetHexWithReturn(ctx, 3, key, &keylen); bool keyB = arg_get_lit(4); - CLIParserFree(); + CLIParserFree(ctx); uint16_t ndefAID = 0x03e1; if (aidlen == 2) @@ -4838,7 +4842,8 @@ static int CmdHFMFNDEF(const char *Cmd) { static int CmdHFMFPersonalize(const char *cmd) { - CLIParserInit("hf mf personalize", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mf personalize", "Personalize the UID of a Mifare Classic EV1 card. This is only possible if it is a 7Byte UID card and if it is not already personalized.", "Usage:\n\thf mf personalize UIDF0 -> double size UID according to ISO/IEC14443-3\n" "\thf mf personalize UIDF1 -> double size UID according to ISO/IEC14443-3, optional usage of selection process shortcut\n" @@ -4853,7 +4858,7 @@ static int CmdHFMFPersonalize(const char *cmd) { arg_str1(NULL, NULL, "", "Personalization Option"), arg_param_end }; - CLIExecWithReturn(cmd, argtable, true); + CLIExecWithReturn(ctx, cmd, argtable, true); char keytypestr[2] = "a"; uint8_t keytype = 0x00; @@ -4863,7 +4868,7 @@ static int CmdHFMFPersonalize(const char *cmd) { if (res || (keytypestr[0] != 'a' && keytypestr[0] != 'b')) { PrintAndLogEx(ERR, "ERROR: not a valid key type. Key type must be A or B"); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (keytypestr[0] == 'b') { @@ -4875,7 +4880,7 @@ static int CmdHFMFPersonalize(const char *cmd) { res = CLIParamHexToBuf(arg_get_str(2), key, 6, &key_len); if (res || (!res && key_len > 0 && key_len != 6)) { PrintAndLogEx(ERR, "ERROR: not a valid key. Key must be 12 hex digits"); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } @@ -4888,7 +4893,7 @@ static int CmdHFMFPersonalize(const char *cmd) { if (res || (!res && opt_len > 0 && opt_len != 5) || (strncmp(pers_optionstr, "uidf0", 5) && strncmp(pers_optionstr, "uidf1", 5) && strncmp(pers_optionstr, "uidf2", 5) && strncmp(pers_optionstr, "uidf3", 5))) { PrintAndLogEx(ERR, "ERROR: invalid personalization option. Must be one of UIDF0, UIDF1, UIDF2, or UIDF3"); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (!strncmp(pers_optionstr, "uidf0", 5)) { @@ -4901,7 +4906,7 @@ static int CmdHFMFPersonalize(const char *cmd) { pers_option = MIFARE_EV1_UIDF3; } - CLIParserFree(); + CLIParserFree(ctx); clearCommandBuffer(); diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index b1de9109e..ed5f50236 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -1782,7 +1782,8 @@ static void swap16(uint8_t *data) { static int CmdHF14ADesCreateApp(const char *Cmd) { - CLIParserInit("hf mfdes createaid", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes createaid", "Create Application ID", "Usage:\n\thf mfdes createaid -a 123456 -f 1111 -k 0E -l 2E -n Test\n" ); @@ -1796,7 +1797,7 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { arg_str0("nN", "name", "", "App ISO-4 Name (optional)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); /* KeySetting 1 (AMK Setting): 0: Allow change master key 1: Free Directory list access without master key @@ -1835,12 +1836,12 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { int keylen1 = 1; int keylen2 = 1; int namelen = 16; - CLIGetHexWithReturn(1, aid, &aidlength); - CLIGetHexWithReturn(2, fid, &fidlength); - CLIGetHexWithReturn(3, keysetting1, &keylen1); - CLIGetHexWithReturn(4, keysetting2, &keylen2); - CLIGetStrWithReturn(5, name, &namelen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 2, fid, &fidlength); + CLIGetHexWithReturn(ctx, 3, keysetting1, &keylen1); + CLIGetHexWithReturn(ctx, 4, keysetting2, &keylen2); + CLIGetStrWithReturn(ctx, 5, name, &namelen); + CLIParserFree(ctx); swap24(aid); swap16(fid); @@ -1908,7 +1909,8 @@ static int CmdHF14ADesCreateApp(const char *Cmd) { } static int CmdHF14ADesDeleteApp(const char *Cmd) { - CLIParserInit("hf mfdes deleteaid", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes deleteaid", "Delete Application ID", "Usage:\n\t-a aid (3 hex bytes, big endian)\n\n" "Example:\n\thf mfdes deleteaid -a 123456\n" @@ -1919,11 +1921,11 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) { arg_strx0("aA", "aid", "", "App ID to delete"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 3; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); + CLIParserFree(ctx); swap24(aid); if (aidlength != 3) { PrintAndLogEx(ERR, "AID must have 3 bytes length."); @@ -1945,7 +1947,8 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) { static int CmdHF14ADesClearRecordFile(const char *Cmd) { - CLIParserInit("hf mfdes clearrecord", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes clearrecord", "Clear record file", "Usage:\n\t" "hf mfdes clearrecord -a 123456 -n 01\n" @@ -1957,19 +1960,19 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) { arg_strx0("nN", "fileno", "", "File Number (1 hex byte, 0x00 - 0x1F)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; uint8_t _fileno[1] = {0}; - CLIGetHexWithReturn(2, _fileno, &filenolen); + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int fidlength = 0; uint8_t fid[2] = {0}; - CLIGetHexWithReturn(3, fid, &fidlength); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 3, fid, &fidlength); + CLIParserFree(ctx); if (filenolen != 1) { PrintAndLogEx(ERR, "Fileno must have 1 bytes length."); @@ -2005,7 +2008,8 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) { } static int CmdHF14ADesDeleteFile(const char *Cmd) { - CLIParserInit("hf mfdes deletefile", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes deletefile", "Delete File", "Usage:\n\t" "hf mfdes deletefile -a 123456 -n 01\n" @@ -2017,19 +2021,19 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) { arg_strx0("nN", "fileno", "", "File Number (1 hex byte, 0x00 - 0x1F)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; uint8_t _fileno[1] = {0}; - CLIGetHexWithReturn(2, _fileno, &filenolen); + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int fidlength = 0; uint8_t fid[2] = {0}; - CLIGetHexWithReturn(3, fid, &fidlength); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 3, fid, &fidlength); + CLIParserFree(ctx); if (filenolen != 1) { PrintAndLogEx(ERR, "Fileno must have 1 bytes length."); @@ -2065,7 +2069,8 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) { } static int CmdHF14ADesCreateFile(const char *Cmd) { - CLIParserInit("hf mfdes createfile", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes createfile", "Create Standard/Backup File", "Usage:" "\n\thf mfdes createfile -a 123456 -f 1111 -n 01 -c 0 -r EEEE -s 000100\n" @@ -2082,30 +2087,30 @@ static int CmdHF14ADesCreateFile(const char *Cmd) { arg_lit0("bB", "backup", "Create backupfile instead of standard file"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; uint8_t _fileno[1] = {0}; - CLIGetHexWithReturn(2, _fileno, &filenolen); + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int fidlength = 0; uint8_t fid[2] = {0}; - CLIGetHexWithReturn(3, fid, &fidlength); + CLIGetHexWithReturn(ctx, 3, fid, &fidlength); uint8_t comset = arg_get_int(4); int arlength = 0; uint8_t ar[2] = {0}; - CLIGetHexWithReturn(5, ar, &arlength); + CLIGetHexWithReturn(ctx, 5, ar, &arlength); int fsizelen = 0; uint8_t filesize[3] = {0}; - CLIGetHexWithReturn(6, filesize, &fsizelen); + CLIGetHexWithReturn(ctx, 6, filesize, &fsizelen); bool isbackup = arg_get_lit(7); - CLIParserFree(); + CLIParserFree(ctx); swap24(aid); swap16(fid); @@ -2175,7 +2180,8 @@ static int CmdHF14ADesCreateFile(const char *Cmd) { } static int CmdHF14ADesGetValueData(const char *Cmd) { - CLIParserInit("hf mfdes getvalue", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes getvalue", "Get value from value file", "Usage:" "\n\thf mfdes getvalue -a 123456 -n 03\n" @@ -2187,16 +2193,16 @@ static int CmdHF14ADesGetValueData(const char *Cmd) { arg_strx0("nN", "fileno", "", "File Number (1 hex byte, 0x00 - 0x1F)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; uint8_t _fileno[1] = {0}; - CLIGetHexWithReturn(2, _fileno, &filenolen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); + CLIParserFree(ctx); if (filenolen != 1) { PrintAndLogEx(ERR, "File number is missing"); @@ -2242,7 +2248,8 @@ static int CmdHF14ADesGetValueData(const char *Cmd) { } static int CmdHF14ADesReadData(const char *Cmd) { - CLIParserInit("hf mfdes readdata", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes readdata", "Read data from File", "Usage:" "\n\thf mfdes readdata -a 123456 -n 01 -t 0 -o 000000 -l 000000\n" @@ -2257,25 +2264,25 @@ static int CmdHF14ADesReadData(const char *Cmd) { arg_int0("type", "type", "", "File Type (0=Standard/Backup, 1=Record)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; uint8_t _fileno[1] = {0}; - CLIGetHexWithReturn(2, _fileno, &filenolen); + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int offsetlength = 0; uint8_t offset[3] = {0}; - CLIGetHexWithReturn(3, offset, &offsetlength); + CLIGetHexWithReturn(ctx, 3, offset, &offsetlength); int flength = 0; uint8_t filesize[3] = {0}; - CLIGetHexWithReturn(4, filesize, &flength); + CLIGetHexWithReturn(ctx, 4, filesize, &flength); int type = arg_get_int(5); - CLIParserFree(); + CLIParserFree(ctx); if (type > 1) { PrintAndLogEx(ERR, "Invalid file type (0=Standard/Backup, 1=Record)"); @@ -2347,7 +2354,8 @@ static int CmdHF14ADesReadData(const char *Cmd) { } static int CmdHF14ADesChangeValue(const char *Cmd) { - CLIParserInit("hf mfdes changevalue", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes changevalue", "Change value (credit/limitedcredit/debit)", "Usage:" "\n\thf mfdes changevalue -a 123456 -n 03 -m 0 -d 00000001\n" @@ -2363,22 +2371,22 @@ static int CmdHF14ADesChangeValue(const char *Cmd) { }; mfdes_value_t value; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; uint8_t _fileno[1] = {0}; - CLIGetHexWithReturn(2, _fileno, &filenolen); + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); value.fileno = _fileno[0]; int vlength = 0x0; - CLIGetHexWithReturn(3, value.value, &vlength); + CLIGetHexWithReturn(ctx, 3, value.value, &vlength); int mode = arg_get_int(4); - CLIParserFree(); + CLIParserFree(ctx); swap24(aid); if (mode > 2) { @@ -2439,7 +2447,8 @@ static int CmdHF14ADesChangeValue(const char *Cmd) { static int CmdHF14ADesWriteData(const char *Cmd) { - CLIParserInit("hf mfdes writedata", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes writedata", "Write data to File", "Usage:" "\n\thf mfdes writedata -a 123456 -n 01 -t 0 -o 000000 -d 3132333435363738\n" @@ -2455,19 +2464,19 @@ static int CmdHF14ADesWriteData(const char *Cmd) { arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; uint8_t _fileno[1] = {0}; - CLIGetHexWithReturn(2, _fileno, &filenolen); + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int offsetlength = 0; uint8_t offset[3] = {0}; - CLIGetHexWithReturn(3, offset, &offsetlength); + CLIGetHexWithReturn(ctx, 3, offset, &offsetlength); int dlength = 0xFFFF; uint8_t *data = (uint8_t *)calloc(dlength, sizeof(uint8_t)); @@ -2477,13 +2486,13 @@ static int CmdHF14ADesWriteData(const char *Cmd) { } if (CLIParamHexToBuf(arg_get_str(4), data, dlength, &dlength)) { free(data); - CLIParserFree(); + CLIParserFree(ctx); return PM3_ESOFT; } int type = arg_get_int(5); - CLIParserFree(); + CLIParserFree(ctx); swap24(aid); swap24(offset); @@ -2555,7 +2564,8 @@ static int CmdHF14ADesWriteData(const char *Cmd) { static int CmdHF14ADesCreateRecordFile(const char *Cmd) { - CLIParserInit("hf mfdes createrecordfile", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes createrecordfile", "Create Linear/Cyclic Record File", "Usage:" "\n\thf mfdes createrecordfile -a 123456 -f 1122 -n 02 -c 0 -r EEEE -s 000010 -m 000005\n" @@ -2573,34 +2583,34 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) { arg_lit0("bB", "cyclic", "Create cyclic record file instead of linear record file"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; uint8_t _fileno[1] = {0}; - CLIGetHexWithReturn(2, _fileno, &filenolen); + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); int fidlength = 0; uint8_t fid[2] = {0}; - CLIGetHexWithReturn(3, fid, &fidlength); + CLIGetHexWithReturn(ctx, 3, fid, &fidlength); uint8_t comset = arg_get_int(4); int arlength = 0; uint8_t ar[2] = {0}; - CLIGetHexWithReturn(5, ar, &arlength); + CLIGetHexWithReturn(ctx, 5, ar, &arlength); int rsizelen = 0; uint8_t recordsize[3] = {0}; - CLIGetHexWithReturn(6, recordsize, &rsizelen); + CLIGetHexWithReturn(ctx, 6, recordsize, &rsizelen); int msizelen = 0; uint8_t maxnumrecords[3] = {0}; - CLIGetHexWithReturn(7, maxnumrecords, &msizelen); + CLIGetHexWithReturn(ctx, 7, maxnumrecords, &msizelen); bool cyclic = arg_get_lit(8); - CLIParserFree(); + CLIParserFree(ctx); swap24(aid); swap16(fid); @@ -2685,7 +2695,8 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) { } static int CmdHF14ADesCreateValueFile(const char *Cmd) { - CLIParserInit("hf mfdes createvaluefile", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes createvaluefile", "Create Value File", "Usage:" "\n\thf mfdes createvaluefile -a 123456 -n 03 -c 0 -r EEEE -l 00000000 -u 00002000 -v 00000001 -m 02\n" @@ -2703,37 +2714,37 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) { arg_strx0("mM", "limitcredit", "", "Limited Credit enabled (1 hex byte [Bit 0=LimitedCredit, 1=FreeValue])"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); int filenolen = 0; uint8_t _fileno[1] = {0}; - CLIGetHexWithReturn(2, _fileno, &filenolen); + CLIGetHexWithReturn(ctx, 2, _fileno, &filenolen); uint8_t comset = arg_get_int(3); int arlength = 0; uint8_t ar[2] = {0}; - CLIGetHexWithReturn(4, ar, &arlength); + CLIGetHexWithReturn(ctx, 4, ar, &arlength); int lllen = 0; uint8_t lowerlimit[4] = {0}; - CLIGetHexWithReturn(5, lowerlimit, &lllen); + CLIGetHexWithReturn(ctx, 5, lowerlimit, &lllen); int ullen = 0; uint8_t upperlimit[4] = {0}; - CLIGetHexWithReturn(6, upperlimit, &ullen); + CLIGetHexWithReturn(ctx, 6, upperlimit, &ullen); int vllen = 0; uint8_t value[4] = {0}; - CLIGetHexWithReturn(7, value, &vllen); + CLIGetHexWithReturn(ctx, 7, value, &vllen); int limitedlen = 0; uint8_t limited[1] = {0}; - CLIGetHexWithReturn(8, limited, &limitedlen); + CLIGetHexWithReturn(ctx, 8, limited, &limitedlen); - CLIParserFree(); + CLIParserFree(ctx); swap24(aid); swap32(lowerlimit); @@ -2813,7 +2824,8 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) { } static int CmdHF14ADesFormatPICC(const char *Cmd) { - CLIParserInit("hf mfdes formatpicc", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes formatpicc", "Formats MIFARE DESFire PICC to factory state", "Usage:\n\t-k PICC key (8 bytes)\n\n" "Example:\n\thf mfdes formatpicc -k 0000000000000000\n" @@ -2824,12 +2836,12 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) { arg_str0("kK", "key", "", "Key for checking (HEX 16 bytes)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); uint8_t key[8] = {0}; int keylen = 8; - CLIGetHexWithReturn(1, key, &keylen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 1, key, &keylen); + CLIParserFree(ctx); if ((keylen < 8) || (keylen > 8)) { PrintAndLogEx(ERR, "Specified key must have 8 bytes length"); @@ -3419,7 +3431,8 @@ static int CmdHF14ADesAuth(const char *Cmd) { uint8_t keylength = 8; bool usedefaultkey = false; - CLIParserInit("hf mfdes auth", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes auth", "Authenticates Mifare DESFire using Key", "Usage:" "\n\thf mfdes auth -m 3 -t 4 -a 808301 -n 0 -k 00000000000000000000000000000000 (AES)" @@ -3436,21 +3449,21 @@ static int CmdHF14ADesAuth(const char *Cmd) { arg_str0("kK", "key", "", "Key for checking (HEX 8-24 bytes)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); uint8_t cmdAuthMode = arg_get_int_def(1, 0); uint8_t cmdAuthAlgo = arg_get_int_def(2, 0); int aidlength = 3; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(3, aid, &aidlength); + CLIGetHexWithReturn(ctx, 3, aid, &aidlength); swap24(aid); uint8_t cmdKeyNo = arg_get_int_def(4, 0); uint8_t key[24] = {0}; int keylen = 0; - CLIGetHexWithReturn(5, key, &keylen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 5, key, &keylen); + CLIParserFree(ctx); if (keylen == 0) { usedefaultkey = true; @@ -3860,7 +3873,8 @@ static int CmdHF14aDesChk(const char *Cmd) { uint32_t k3kkeyListLen = 0; uint8_t foundKeys[4][0xE][24 + 1] = {{{0}}}; - CLIParserInit("hf mfdes chk", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfdes chk", "Checks keys with Mifare Desfire card.", "Usage:\n" " hf mfdes chk -a 123456 -k 000102030405060708090a0b0c0d0e0f -> check key on aid 0x123456\n" @@ -3881,15 +3895,15 @@ static int CmdHF14aDesChk(const char *Cmd) { arg_lit0("vV", "verbose", "Verbose mode."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); int aidlength = 0; uint8_t aid[3] = {0}; - CLIGetHexWithReturn(1, aid, &aidlength); + CLIGetHexWithReturn(ctx, 1, aid, &aidlength); swap24(aid); uint8_t vkey[16] = {0}; int vkeylen = 0; - CLIGetHexWithReturn(2, vkey, &vkeylen); + CLIGetHexWithReturn(ctx, 2, vkey, &vkeylen); if (vkeylen > 0) { if (vkeylen == 8) { @@ -3903,7 +3917,7 @@ static int CmdHF14aDesChk(const char *Cmd) { k3kkeyListLen++; } else { PrintAndLogEx(ERR, "Specified key must have 8, 16 or 24 bytes length."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } } @@ -3912,7 +3926,7 @@ static int CmdHF14aDesChk(const char *Cmd) { int dict_filenamelen = 0; if (CLIParamStrToBuf(arg_get_str(3), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) { PrintAndLogEx(FAILED, "File name too long or invalid."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } @@ -3921,26 +3935,26 @@ static int CmdHF14aDesChk(const char *Cmd) { if (pattern1b && pattern2b) { PrintAndLogEx(ERR, "Pattern search mode must be 2-byte or 1-byte only."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (dict_filenamelen && (pattern1b || pattern2b)) { PrintAndLogEx(ERR, "Pattern search mode and dictionary mode can't be used in one command."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } uint32_t startPattern = 0x0000; uint8_t vpattern[2]; int vpatternlen = 0; - CLIGetHexWithReturn(6, vpattern, &vpatternlen); + CLIGetHexWithReturn(ctx, 6, vpattern, &vpatternlen); if (vpatternlen > 0) { if (vpatternlen > 0 && vpatternlen <= 2) { startPattern = (vpattern[0] << 8) + vpattern[1]; } else { PrintAndLogEx(ERR, "Pattern must be 2-byte length."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (!pattern2b) @@ -3951,14 +3965,14 @@ static int CmdHF14aDesChk(const char *Cmd) { int jsonnamelen = 0; if (CLIParamStrToBuf(arg_get_str(7), jsonname, sizeof(jsonname), &jsonnamelen)) { PrintAndLogEx(ERR, "Invalid json name."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } jsonname[jsonnamelen] = 0; bool verbose = arg_get_lit(8); - CLIParserFree(); + CLIParserFree(ctx); // 1-byte pattern search mode if (pattern1b) { diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index 12fbce4d7..7cdeb5eb1 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -424,7 +424,8 @@ static int CmdHFMFPWritePerso(const char *Cmd) { uint8_t key[64] = {0}; int keyLen = 0; - CLIParserInit("hf mfp wrp", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp wrp", "Executes Write Perso command. Can be used in SL0 mode only.", "Usage:\n\thf mfp wrp 4000 000102030405060708090a0b0c0d0e0f -> write key (00..0f) to key number 4000 \n" "\thf mfp wrp 4000 -> write default key(0xff..0xff) to key number 4000"); @@ -436,12 +437,12 @@ static int CmdHFMFPWritePerso(const char *Cmd) { arg_strx0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool verbose = arg_get_lit(1); - CLIGetHexWithReturn(2, keyNum, &keyNumLen); - CLIGetHexWithReturn(3, key, &keyLen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 2, keyNum, &keyNumLen); + CLIGetHexWithReturn(ctx, 3, key, &keyLen); + CLIParserFree(ctx); mfpSetVerboseMode(verbose); @@ -490,7 +491,8 @@ static int CmdHFMFPInitPerso(const char *Cmd) { uint8_t data[250] = {0}; int datalen = 0; - CLIParserInit("hf mfp initp", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp initp", "Executes Write Perso command for all card's keys. Can be used in SL0 mode only.", "Usage:\n\thf mfp initp 000102030405060708090a0b0c0d0e0f -> fill all the keys with key (00..0f)\n" "\thf mfp initp -vv -> fill all the keys with default key(0xff..0xff) and show all the data exchange"); @@ -501,12 +503,12 @@ static int CmdHFMFPInitPerso(const char *Cmd) { arg_strx0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool verbose = arg_get_lit(1); bool verbose2 = arg_get_lit(1) > 1; - CLIGetHexWithReturn(2, key, &keyLen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 2, key, &keyLen); + CLIParserFree(ctx); if (keyLen && keyLen != 16) { PrintAndLogEx(ERR, "Key length must be 16 bytes instead of: %d", keyLen); @@ -557,7 +559,8 @@ static int CmdHFMFPInitPerso(const char *Cmd) { } static int CmdHFMFPCommitPerso(const char *Cmd) { - CLIParserInit("hf mfp commitp", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp commitp", "Executes Commit Perso command. Can be used in SL0 mode only.", "Usage:\n\thf mfp commitp -> \n"); @@ -567,10 +570,10 @@ static int CmdHFMFPCommitPerso(const char *Cmd) { arg_int0(NULL, NULL, "SL mode", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool verbose = arg_get_lit(1); - CLIParserFree(); + CLIParserFree(ctx); mfpSetVerboseMode(verbose); @@ -603,7 +606,8 @@ static int CmdHFMFPAuth(const char *Cmd) { uint8_t key[250] = {0}; int keylen = 0; - CLIParserInit("hf mfp auth", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp auth", "Executes AES authentication command for Mifare Plus card", "Usage:\n\thf mfp auth 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n" "\thf mfp auth 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -v -> executes authentication and shows all the system data\n"); @@ -615,12 +619,12 @@ static int CmdHFMFPAuth(const char *Cmd) { arg_str1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool verbose = arg_get_lit(1); - CLIGetHexWithReturn(2, keyn, &keynlen); - CLIGetHexWithReturn(3, key, &keylen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 2, keyn, &keynlen); + CLIGetHexWithReturn(ctx, 3, key, &keylen); + CLIParserFree(ctx); if (keynlen != 2) { PrintAndLogEx(ERR, "ERROR: must be 2 bytes long instead of: %d", keynlen); @@ -640,7 +644,8 @@ static int CmdHFMFPRdbl(const char *Cmd) { uint8_t key[250] = {0}; int keylen = 0; - CLIParserInit("hf mfp rdbl", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp rdbl", "Reads several blocks from Mifare Plus card.", "Usage:\n\thf mfp rdbl 0 000102030405060708090a0b0c0d0e0f -> executes authentication and read block 0 data\n" "\thf mfp rdbl 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF and some additional data\n"); @@ -655,15 +660,15 @@ static int CmdHFMFPRdbl(const char *Cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); bool verbose = arg_get_lit(1); int blocksCount = arg_get_int_def(2, 1); bool keyB = arg_get_lit(3); int plain = arg_get_lit(4); uint32_t blockn = arg_get_int(5); - CLIGetHexWithReturn(6, key, &keylen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 6, key, &keylen); + CLIParserFree(ctx); mfpSetVerboseMode(verbose); @@ -752,7 +757,8 @@ static int CmdHFMFPRdsc(const char *Cmd) { uint8_t key[250] = {0}; int keylen = 0; - CLIParserInit("hf mfp rdsc", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp rdsc", "Reads one sector from Mifare Plus card.", "Usage:\n\thf mfp rdsc 0 000102030405060708090a0b0c0d0e0f -> executes authentication and read sector 0 data\n" "\thf mfp rdsc 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF and some additional data\n"); @@ -766,14 +772,14 @@ static int CmdHFMFPRdsc(const char *Cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); bool verbose = arg_get_lit(1); bool keyB = arg_get_lit(2); bool plain = arg_get_lit(3); uint32_t sectorNum = arg_get_int(4); - CLIGetHexWithReturn(5, key, &keylen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 5, key, &keylen); + CLIParserFree(ctx); mfpSetVerboseMode(verbose); @@ -850,7 +856,8 @@ static int CmdHFMFPWrbl(const char *Cmd) { uint8_t datain[250] = {0}; int datainlen = 0; - CLIParserInit("hf mfp wrbl", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp wrbl", "Writes one block to Mifare Plus card.", "Usage:\n\thf mfp wrbl 1 ff0000000000000000000000000000ff 000102030405060708090a0b0c0d0e0f -> writes block 1 data\n" "\thf mfp wrbl 2 ff0000000000000000000000000000ff -v -> writes block 2 data with default key 0xFF..0xFF and some additional data\n"); @@ -864,14 +871,14 @@ static int CmdHFMFPWrbl(const char *Cmd) { arg_str0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); bool verbose = arg_get_lit(1); bool keyB = arg_get_lit(2); uint32_t blockNum = arg_get_int(3); - CLIGetHexWithReturn(4, datain, &datainlen); - CLIGetHexWithReturn(5, key, &keylen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 4, datain, &datainlen); + CLIGetHexWithReturn(ctx, 5, key, &keylen); + CLIParserFree(ctx); mfpSetVerboseMode(verbose); @@ -1047,7 +1054,8 @@ static int CmdHFMFPChk(const char *Cmd) { uint32_t keyListLen = 0; uint8_t foundKeys[2][64][AES_KEY_LEN + 1] = {{{0}}}; - CLIParserInit("hf mfp chk", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp chk", "Checks keys with Mifare Plus card.", "Usage:\n" " hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n" @@ -1071,7 +1079,7 @@ static int CmdHFMFPChk(const char *Cmd) { arg_lit0("vV", "verbose", "verbose mode."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool keyA = arg_get_lit(1); bool keyB = arg_get_lit(2); @@ -1080,14 +1088,14 @@ static int CmdHFMFPChk(const char *Cmd) { uint8_t vkey[16] = {0}; int vkeylen = 0; - CLIGetHexWithReturn(5, vkey, &vkeylen); + CLIGetHexWithReturn(ctx, 5, vkey, &vkeylen); if (vkeylen > 0) { if (vkeylen == 16) { memcpy(&keyList[keyListLen], vkey, 16); keyListLen++; } else { PrintAndLogEx(ERR, "Specified key must have 16 bytes length."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } } @@ -1096,7 +1104,7 @@ static int CmdHFMFPChk(const char *Cmd) { int dict_filenamelen = 0; if (CLIParamStrToBuf(arg_get_str(6), dict_filename, FILE_PATH_SIZE, &dict_filenamelen)) { PrintAndLogEx(FAILED, "File name too long or invalid."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } @@ -1105,26 +1113,26 @@ static int CmdHFMFPChk(const char *Cmd) { if (pattern1b && pattern2b) { PrintAndLogEx(ERR, "Pattern search mode must be 2-byte or 1-byte only."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (dict_filenamelen && (pattern1b || pattern2b)) { PrintAndLogEx(ERR, "Pattern search mode and dictionary mode can't be used in one command."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } uint32_t startPattern = 0x0000; uint8_t vpattern[2]; int vpatternlen = 0; - CLIGetHexWithReturn(9, vpattern, &vpatternlen); + CLIGetHexWithReturn(ctx, 9, vpattern, &vpatternlen); if (vpatternlen > 0) { if (vpatternlen > 0 && vpatternlen <= 2) { startPattern = (vpattern[0] << 8) + vpattern[1]; } else { PrintAndLogEx(ERR, "Pattern must be 2-byte length."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } if (!pattern2b) @@ -1135,14 +1143,14 @@ static int CmdHFMFPChk(const char *Cmd) { int jsonnamelen = 0; if (CLIParamStrToBuf(arg_get_str(10), jsonname, sizeof(jsonname), &jsonnamelen)) { PrintAndLogEx(ERR, "Invalid json name."); - CLIParserFree(); + CLIParserFree(ctx); return PM3_EINVARG; } jsonname[jsonnamelen] = 0; bool verbose = arg_get_lit(11); - CLIParserFree(); + CLIParserFree(ctx); uint8_t startKeyAB = 0; uint8_t endKeyAB = 1; @@ -1277,7 +1285,8 @@ static int CmdHFMFPChk(const char *Cmd) { static int CmdHFMFPMAD(const char *Cmd) { - CLIParserInit("hf mfp mad", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp mad", "Checks and prints Mifare Application Directory (MAD)", "Usage:\n\thf mfp mad -> shows MAD if exists\n" "\thf mfp mad -a 03e1 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data if exists\n"); @@ -1290,18 +1299,18 @@ static int CmdHFMFPMAD(const char *Cmd) { arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool verbose = arg_get_lit(1); uint8_t aid[2] = {0}; int aidlen; - CLIGetHexWithReturn(2, aid, &aidlen); + CLIGetHexWithReturn(ctx, 2, aid, &aidlen); uint8_t key[16] = {0}; int keylen; - CLIGetHexWithReturn(3, key, &keylen); + CLIGetHexWithReturn(ctx, 3, key, &keylen); bool keyB = arg_get_lit(4); - CLIParserFree(); + CLIParserFree(ctx); if (aidlen != 2 && keylen > 0) { PrintAndLogEx(WARNING, "do not need a key without aid."); @@ -1371,7 +1380,8 @@ static int CmdHFMFPMAD(const char *Cmd) { static int CmdHFMFPNDEF(const char *Cmd) { - CLIParserInit("hf mfp ndef", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfp ndef", "Prints NFC Data Exchange Format (NDEF)", "Usage:\n\thf mfp ndef -> shows NDEF data\n" "\thf mfp ndef -a 03e1 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key\n"); @@ -1384,19 +1394,19 @@ static int CmdHFMFPNDEF(const char *Cmd) { arg_lit0("bB", "keyb", "use key B for access sectors (by default: key A)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool verbose = arg_get_lit(1); bool verbose2 = arg_get_lit(1) > 1; uint8_t aid[2] = {0}; int aidlen; - CLIGetHexWithReturn(2, aid, &aidlen); + CLIGetHexWithReturn(ctx, 2, aid, &aidlen); uint8_t key[16] = {0}; int keylen; - CLIGetHexWithReturn(3, key, &keylen); + CLIGetHexWithReturn(ctx, 3, key, &keylen); bool keyB = arg_get_lit(4); - CLIParserFree(); + CLIParserFree(ctx); uint16_t ndefAID = 0x03e1; if (aidlen == 2) diff --git a/client/src/cmdhfmfu.c b/client/src/cmdhfmfu.c index b35a27e49..dd812dd79 100644 --- a/client/src/cmdhfmfu.c +++ b/client/src/cmdhfmfu.c @@ -2915,7 +2915,8 @@ static int CmdHF14MfuNDEF(const char *Cmd) { uint8_t *p_key = key; uint8_t pack[4] = {0, 0, 0, 0}; - CLIParserInit("hf mfu ndef", + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf mfu ndef", "Prints NFC Data Exchange Format (NDEF)", "Usage:\n\thf mfu ndef -> shows NDEF data\n" "\thf mfu ndef -k ffffffff -> shows NDEF data with key\n"); @@ -2926,10 +2927,10 @@ static int CmdHF14MfuNDEF(const char *Cmd) { arg_lit0("lL", "key", "(optional) swap entered key's endianness"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); - CLIGetHexWithReturn(1, key, &keylen); + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIGetHexWithReturn(ctx, 1, key, &keylen); swapEndian = arg_get_lit(2); - CLIParserFree(); + CLIParserFree(ctx); switch (keylen) { case 0: diff --git a/client/src/cmdlfindala.c b/client/src/cmdlfindala.c index d93f152fa..d9d24bfdd 100644 --- a/client/src/cmdlfindala.c +++ b/client/src/cmdlfindala.c @@ -560,7 +560,8 @@ static int CmdIndalaClone(const char *Cmd) { uint8_t fc = 0; uint16_t cn = 0; - CLIParserInit("lf indala clone", + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf indala clone", "clone INDALA tag to T55x7 (or to q5/T5555)", "Examples:\n" "\tlf indala clone --heden 888\n" @@ -578,12 +579,12 @@ static int CmdIndalaClone(const char *Cmd) { arg_int0("", "cn", "", "Cardnumber (26 bit format)"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); is_long_uid = arg_get_lit(1); // raw param - CLIGetHexWithReturn(3, data, &datalen); + CLIGetHexWithReturn(ctx, 3, data, &datalen); is_t5555 = arg_get_lit(4); @@ -599,7 +600,7 @@ static int CmdIndalaClone(const char *Cmd) { got_26 = (fc != 0 && cn != 0); } - CLIParserFree(); + CLIParserFree(ctx); if (is_long_uid) { // 224 BIT UID diff --git a/client/src/cmdlfmotorola.c b/client/src/cmdlfmotorola.c index 3db82a0be..fc2156c1a 100644 --- a/client/src/cmdlfmotorola.c +++ b/client/src/cmdlfmotorola.c @@ -150,7 +150,8 @@ static int CmdMotorolaClone(const char *Cmd) { uint8_t data[8]; int datalen = 0; - CLIParserInit("lf indala clone", + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf indala clone", "Enables cloning of Motorola card with specified uid onto T55x7\n" "defaults to 64.\n", "\n" @@ -163,9 +164,9 @@ static int CmdMotorolaClone(const char *Cmd) { arg_strx1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); - CLIGetHexWithReturn(1, data, &datalen); - CLIParserFree(); + CLIExecWithReturn(ctx, Cmd, argtable, false); + CLIGetHexWithReturn(ctx, 1, data, &datalen); + CLIParserFree(ctx); //TODO add selection of chip for Q5 or T55x7 // data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT; diff --git a/client/src/emv/cmdemv.c b/client/src/emv/cmdemv.c index 347c7916a..4b364c85c 100644 --- a/client/src/emv/cmdemv.c +++ b/client/src/emv/cmdemv.c @@ -68,7 +68,8 @@ static int CmdEMVSelect(const char *Cmd) { uint8_t data[APDU_AID_LEN] = {0}; int datalen = 0; - CLIParserInit("emv select", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv select", "Executes select applet command", "Usage:\n\temv select -s a00000000101 -> select card, select applet\n\temv select -st a00000000101 -> select card, select applet, show result in TLV\n"); @@ -82,7 +83,7 @@ static int CmdEMVSelect(const char *Cmd) { arg_strx0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool activateField = arg_get_lit(1); bool leaveSignalON = arg_get_lit(2); @@ -92,8 +93,8 @@ static int CmdEMVSelect(const char *Cmd) { if (arg_get_lit(5)) channel = ECC_CONTACT; PrintChannel(channel); - CLIGetHexWithReturn(6, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 6, data, &datalen); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -117,7 +118,8 @@ static int CmdEMVSelect(const char *Cmd) { static int CmdEMVSearch(const char *Cmd) { - CLIParserInit("emv search", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv search", "Tries to select all applets from applet list:\n", "Usage:\n\temv search -s -> select card and search\n\temv search -st -> select card, search and show result in TLV\n"); @@ -130,7 +132,7 @@ static int CmdEMVSearch(const char *Cmd) { arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool activateField = arg_get_lit(1); bool leaveSignalON = arg_get_lit(2); @@ -140,7 +142,7 @@ static int CmdEMVSearch(const char *Cmd) { if (arg_get_lit(5)) channel = ECC_CONTACT; PrintChannel(channel); - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -167,7 +169,8 @@ static int CmdEMVSearch(const char *Cmd) { static int CmdEMVPPSE(const char *Cmd) { - CLIParserInit("emv pse", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv pse", "Executes PSE/PPSE select command. It returns list of applet on the card:\n", "Usage:\n\temv pse -s1 -> select, get pse\n\temv pse -st2 -> select, get ppse, show result in TLV\n"); @@ -182,7 +185,7 @@ static int CmdEMVPPSE(const char *Cmd) { arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool activateField = arg_get_lit(1); bool leaveSignalON = arg_get_lit(2); @@ -197,7 +200,7 @@ static int CmdEMVPPSE(const char *Cmd) { if (arg_get_lit(7)) channel = ECC_CONTACT; PrintChannel(channel); - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -223,7 +226,8 @@ static int CmdEMVGPO(const char *Cmd) { uint8_t data[APDU_RES_LEN] = {0}; int datalen = 0; - CLIParserInit("emv gpo", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv gpo", "Executes Get Processing Options command. It returns data in TLV format (0x77 - format2) or plain format (0x80 - format1).\nNeeds a EMV applet to be selected.", "Usage:\n\temv gpo -k -> execute GPO\n" "\temv gpo -t 01020304 -> execute GPO with 4-byte PDOL data, show result in TLV\n" @@ -240,7 +244,7 @@ static int CmdEMVGPO(const char *Cmd) { arg_strx0(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool leaveSignalON = arg_get_lit(1); bool paramsLoadFromFile = arg_get_lit(2); @@ -251,8 +255,8 @@ static int CmdEMVGPO(const char *Cmd) { if (arg_get_lit(6)) channel = ECC_CONTACT; PrintChannel(channel); - CLIGetHexWithReturn(7, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 7, data, &datalen); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -331,7 +335,8 @@ static int CmdEMVReadRecord(const char *Cmd) { uint8_t data[APDU_RES_LEN] = {0}; int datalen = 0; - CLIParserInit("emv readrec", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv readrec", "Executes Read Record command. It returns data in TLV format.\nNeeds a bank applet to be selected and sometimes needs GPO to be executed.", "Usage:\n\temv readrec -k 0101 -> read file SFI=01, SFIrec=01\n\temv readrec -kt 0201-> read file 0201 and show result in TLV\n"); @@ -344,7 +349,7 @@ static int CmdEMVReadRecord(const char *Cmd) { arg_strx1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool leaveSignalON = arg_get_lit(1); bool APDULogging = arg_get_lit(2); @@ -353,8 +358,8 @@ static int CmdEMVReadRecord(const char *Cmd) { if (arg_get_lit(4)) channel = ECC_CONTACT; PrintChannel(channel); - CLIGetHexWithReturn(5, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 5, data, &datalen); + CLIParserFree(ctx); if (datalen != 2) { PrintAndLogEx(ERR, "Command needs to have 2 bytes of data"); @@ -386,7 +391,8 @@ static int CmdEMVAC(const char *Cmd) { uint8_t data[APDU_RES_LEN] = {0}; int datalen = 0; - CLIParserInit("emv genac", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv genac", "Generate Application Cryptogram command. It returns data in TLV format .\nNeeds a EMV applet to be selected and GPO to be executed.", "Usage:\n\temv genac -k 0102 -> generate AC with 2-byte CDOLdata and keep field ON after command\n" "\temv genac -t 01020304 -> generate AC with 4-byte CDOL data, show result in TLV\n" @@ -406,7 +412,7 @@ static int CmdEMVAC(const char *Cmd) { arg_strx1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); bool leaveSignalON = arg_get_lit(1); bool trTypeCDA = arg_get_lit(2); @@ -436,8 +442,8 @@ static int CmdEMVAC(const char *Cmd) { if (arg_get_lit(8)) channel = ECC_CONTACT; PrintChannel(channel); - CLIGetHexWithReturn(9, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 9, data, &datalen); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -505,7 +511,8 @@ static int CmdEMVAC(const char *Cmd) { static int CmdEMVGenerateChallenge(const char *Cmd) { - CLIParserInit("emv challenge", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv challenge", "Executes Generate Challenge command. It returns 4 or 8-byte random number from card.\nNeeds a EMV applet to be selected and GPO to be executed.", "Usage:\n\temv challenge -> get challenge\n\temv challenge -k -> get challenge, keep fileld ON\n"); @@ -516,7 +523,7 @@ static int CmdEMVGenerateChallenge(const char *Cmd) { arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool leaveSignalON = arg_get_lit(1); bool APDULogging = arg_get_lit(2); @@ -524,7 +531,7 @@ static int CmdEMVGenerateChallenge(const char *Cmd) { if (arg_get_lit(3)) channel = ECC_CONTACT; PrintChannel(channel); - CLIParserFree(); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -552,7 +559,8 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) { uint8_t data[APDU_RES_LEN] = {0}; int datalen = 0; - CLIParserInit("emv intauth", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv intauth", "Generate Internal Authenticate command. Usually needs 4-byte random number. It returns data in TLV format .\n" "Needs a EMV applet to be selected and GPO to be executed.", @@ -572,7 +580,7 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) { arg_strx1(NULL, NULL, "", NULL), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, false); + CLIExecWithReturn(ctx, Cmd, argtable, false); bool leaveSignalON = arg_get_lit(1); bool paramsLoadFromFile = arg_get_lit(2); @@ -583,8 +591,8 @@ static int CmdEMVInternalAuthenticate(const char *Cmd) { if (arg_get_lit(6)) channel = ECC_CONTACT; PrintChannel(channel); - CLIGetHexWithReturn(7, data, &datalen); - CLIParserFree(); + CLIGetHexWithReturn(ctx, 7, data, &datalen); + CLIParserFree(ctx); SetAPDULogging(APDULogging); @@ -782,7 +790,8 @@ static int CmdEMVExec(const char *Cmd) { struct tlvdb *tlvRoot = NULL; struct tlv *pdol_data_tlv = NULL; - CLIParserInit("emv exec", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv exec", "Executes EMV contactless transaction", "Usage:\n" "\temv exec -sat -> select card, execute MSD transaction, show APDU and TLV\n" @@ -803,7 +812,7 @@ static int CmdEMVExec(const char *Cmd) { arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool activateField = arg_get_lit(1); bool showAPDU = arg_get_lit(2); @@ -825,7 +834,7 @@ static int CmdEMVExec(const char *Cmd) { channel = ECC_CONTACT; PrintChannel(channel); uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2; - CLIParserFree(); + CLIParserFree(ctx); if (!IfPm3Smartcard()) { if (channel == ECC_CONTACT) { @@ -1375,7 +1384,8 @@ static int CmdEMVScan(const char *Cmd) { json_t *root; json_error_t error; - CLIParserInit("emv scan", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv scan", "Scan EMV card and save it contents to a file.", "It executes EMV contactless transaction and saves result to a file which can be used for emulation\n" "Usage:\n\temv scan -at -> scan MSD transaction mode and show APDU and TLV\n" @@ -1397,7 +1407,7 @@ static int CmdEMVScan(const char *Cmd) { arg_str1(NULL, NULL, "output.json", "JSON output file name"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool showAPDU = arg_get_lit(1); bool decodeTLV = arg_get_lit(2); @@ -1422,8 +1432,8 @@ static int CmdEMVScan(const char *Cmd) { uint8_t relfname[250] = {0}; char *crelfname = (char *)relfname; int relfnamelen = 0; - CLIGetStrWithReturn(12, relfname, &relfnamelen); - CLIParserFree(); + CLIGetStrWithReturn(ctx, 12, relfname, &relfnamelen); + CLIParserFree(ctx); if (!IfPm3Smartcard()) { if (channel == ECC_CONTACT) { @@ -1752,7 +1762,8 @@ static int CmdEMVList(const char *Cmd) { } static int CmdEMVTest(const char *Cmd) { - CLIParserInit("emv test", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv test", "Executes tests\n", "Usage:\n\temv test [l]\n"); @@ -1762,11 +1773,11 @@ static int CmdEMVTest(const char *Cmd) { arg_lit0("lL", "long", "run long tests too"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); bool ignoreTimeTest = arg_get_lit(1); bool runSlowTests = arg_get_lit(2); - CLIParserFree(); + CLIParserFree(ctx); return ExecuteCryptoTests(true, ignoreTimeTest, runSlowTests); } @@ -1781,7 +1792,8 @@ static int CmdEMVRoca(const char *Cmd) { size_t ODAI_listlen = 0; int res; - CLIParserInit("emv roca", + CLIParserContext *ctx; + CLIParserInit(&ctx, "emv roca", "Tries to extract public keys and run the ROCA test against them.\n", "Usage:\n" "\temv roca -w -> select --CONTACT-- card and run test\n" @@ -1795,11 +1807,11 @@ static int CmdEMVRoca(const char *Cmd) { arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default"), arg_param_end }; - CLIExecWithReturn(Cmd, argtable, true); + CLIExecWithReturn(ctx, Cmd, argtable, true); EMVCommandChannel channel = ECC_CONTACTLESS; if (arg_get_lit(1)) { - CLIParserFree(); + CLIParserFree(ctx); return roca_self_test(); } @@ -1807,9 +1819,8 @@ static int CmdEMVRoca(const char *Cmd) { if (arg_get_lit(3)) channel = ECC_CONTACT; - - CLIParserFree(); - + + CLIParserFree(ctx); PrintChannel(channel); if (!IfPm3Smartcard()) {