cliparser: remove global vars

This commit is contained in:
Philippe Teuwen 2020-06-01 17:30:33 +02:00
commit 6326c4126c
13 changed files with 393 additions and 330 deletions

View file

@ -10,50 +10,50 @@
#include "cliparser.h"
#include <string.h>
#include <stdlib.h>
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;
}

View file

@ -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);

View file

@ -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", "<hex>", "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;

View file

@ -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];

View file

@ -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, "<APDU (hex) | data (hex)>", "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, "<enable/disable or 0/1>", 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");

View file

@ -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, "<HEX/ASCII application parameter (32b HEX/1..16 chars)>", 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, "<HEX/ASCII application parameter (32b HEX/1..16 chars)>", 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 file name>", "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 file name>", "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);

View file

@ -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 (hex 1b)>", "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, "<Key Value (HEX 16 bytes)>", 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, "<Key Num> 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, "<UIDF0|UIDF1|UIDF2|UIDF3>", "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();

View file

@ -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", "<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", "<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", "<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", "<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", "<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", "<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", "<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>", "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>", "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) {

View file

@ -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, "<HEX key (16b)>", 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, "<HEX key (16b)>", 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, "<Key Value (HEX 16 bytes)>", 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: <Key Num> 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, "<Key Value (HEX 16 bytes)>", 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, "<Key Value (HEX 16 bytes)>", 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, "<Key (HEX 16 bytes)>", 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)

View file

@ -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:

View file

@ -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", "<decimal>", "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

View file

@ -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, "<uid (hex)>", 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;

View file

@ -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, "<HEX applet AID>", 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, "<HEX PDOLdata/PDOL>", 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, "<SFI 1byte HEX><SFIrecord 1byte HEX>", 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, "<HEX CDOLdata/CDOL>", 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, "<HEX DDOLdata/DDOL>", 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()) {