Merge pull request #1154 from tcprst/14a_cliparser

hf 14a config - now use cliparser
This commit is contained in:
Philippe Teuwen 2020-12-31 11:48:25 +01:00 committed by GitHub
commit e6d71fafb1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 177 additions and 196 deletions

View file

@ -133,35 +133,30 @@ static hf14a_config hf14aconfig = { 0, 0, 0, 0, 0 } ;
void printHf14aConfig(void) {
DbpString(_CYAN_("HF 14a config"));
Dbprintf(" [a] Anticol override....%i %s%s%s",
hf14aconfig.forceanticol,
(hf14aconfig.forceanticol == 0) ? "( " _GREEN_("No") " ) follow standard " : "",
(hf14aconfig.forceanticol == 1) ? "( " _RED_("Yes") " ) always do anticol" : "",
(hf14aconfig.forceanticol == 2) ? "( " _RED_("Yes") " ) always skip anticol" : ""
Dbprintf(" [a] Anticol override....%s%s%s",
(hf14aconfig.forceanticol == 0) ? _GREEN_("std") " : follow standard " : "",
(hf14aconfig.forceanticol == 1) ? _RED_("force") " : always do anticol" : "",
(hf14aconfig.forceanticol == 2) ? _RED_("skip") " : always skip anticol" : ""
);
Dbprintf(" [b] BCC override........%i %s%s%s",
hf14aconfig.forcebcc,
(hf14aconfig.forcebcc == 0) ? "( " _GREEN_("No") " ) follow standard" : "",
(hf14aconfig.forcebcc == 1) ? "( " _RED_("Yes") " ) always do CL2" : "",
(hf14aconfig.forcebcc == 2) ? "( " _RED_("Yes") " ) always use card BCC" : ""
Dbprintf(" [b] BCC override........%s%s%s",
(hf14aconfig.forcebcc == 0) ? _GREEN_("std") " : follow standard" : "",
(hf14aconfig.forcebcc == 1) ? _RED_("fix") " : fix bad BCC" : "",
(hf14aconfig.forcebcc == 2) ? _RED_("ignore") " : ignore bad BCC, always use card BCC" : ""
);
Dbprintf(" [2] CL2 override........%i %s%s%s",
hf14aconfig.forcecl2,
(hf14aconfig.forcecl2 == 0) ? "( " _GREEN_("No") " ) follow standard" : "",
(hf14aconfig.forcecl2 == 1) ? "( " _RED_("Yes") " ) always do CL2" : "",
(hf14aconfig.forcecl2 == 2) ? "( " _RED_("Yes") " ) always skip CL2" : ""
Dbprintf(" [2] CL2 override........%s%s%s",
(hf14aconfig.forcecl2 == 0) ? _GREEN_("std") " : follow standard" : "",
(hf14aconfig.forcecl2 == 1) ? _RED_("force") " : always do CL2" : "",
(hf14aconfig.forcecl2 == 2) ? _RED_("skip") " : always skip CL2" : ""
);
Dbprintf(" [3] CL3 override........%i %s%s%s",
hf14aconfig.forcecl3,
(hf14aconfig.forcecl3 == 0) ? "( " _GREEN_("No") " ) follow standard" : "",
(hf14aconfig.forcecl3 == 1) ? "( " _RED_("Yes") " ) always do CL3" : "",
(hf14aconfig.forcecl3 == 2) ? "( " _RED_("Yes") " ) always skip CL3" : ""
Dbprintf(" [3] CL3 override........%s%s%s",
(hf14aconfig.forcecl3 == 0) ? _GREEN_("std") " : follow standard" : "",
(hf14aconfig.forcecl3 == 1) ? _RED_("force") " : always do CL3" : "",
(hf14aconfig.forcecl3 == 2) ? _RED_("skip") " : always skip CL3" : ""
);
Dbprintf(" [r] RATS override.......%i %s%s%s",
hf14aconfig.forcerats,
(hf14aconfig.forcerats == 0) ? "( " _GREEN_("No") " ) follow standard " : "",
(hf14aconfig.forcerats == 1) ? "( " _RED_("Yes") " ) always do RATS" : "",
(hf14aconfig.forcerats == 2) ? "( " _RED_("Yes") " ) always skip RATS" : ""
Dbprintf(" [r] RATS override.......%s%s%s",
(hf14aconfig.forcerats == 0) ? _GREEN_("std") " : follow standard " : "",
(hf14aconfig.forcerats == 1) ? _RED_("force") " : always do RATS" : "",
(hf14aconfig.forcerats == 2) ? _RED_("skip") " : always skip RATS" : ""
);
}

View file

@ -170,45 +170,6 @@ const char *getTagInfo(uint8_t uid) {
static uint16_t frameLength = 0;
uint16_t atsFSC[] = {16, 24, 32, 40, 48, 64, 96, 128, 256};
static int usage_hf_14a_config(void) {
PrintAndLogEx(NORMAL, "Usage: hf 14a config [a 0|1|2] [b 0|1|2] [2 0|1|2] [3 0|1|2]");
PrintAndLogEx(NORMAL, "\nOptions:");
PrintAndLogEx(NORMAL, " h This help");
PrintAndLogEx(NORMAL, " a 0|1|2 ATQA<>anticollision: 0=follow standard 1=execute anticol 2=skip anticol");
PrintAndLogEx(NORMAL, " b 0|1|2 BCC: 0=follow standard 1=use fixed BCC 2=use card BCC");
PrintAndLogEx(NORMAL, " 2 0|1|2 SAK<>CL2: 0=follow standard 1=execute CL2 2=skip CL2");
PrintAndLogEx(NORMAL, " 3 0|1|2 SAK<>CL3: 0=follow standard 1=execute CL3 2=skip CL3");
PrintAndLogEx(NORMAL, " r 0|1|2 SAK<>ATS: 0=follow standard 1=execute RATS 2=skip RATS");
PrintAndLogEx(NORMAL, "\nExamples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config ")" Print current configuration");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 1 ")" Force execution of anticollision");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 0 ")" Restore ATQA interpretation");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config b 1 ")" Force fix of bad BCC in anticollision");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config b 0 ")" Restore BCC check");
PrintAndLogEx(NORMAL, "\nExamples to revive Gen2/DirectWrite magic cards failing at anticollision:");
PrintAndLogEx(NORMAL, _CYAN_(" MFC 1k 4b UID")":");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 1 b 2 2 2 r 2"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf mf wrbl 0 A FFFFFFFFFFFF 11223344440804006263646566676869"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 0 b 0 2 0 r 0"));
PrintAndLogEx(NORMAL, _CYAN_(" MFC 4k 4b UID")":");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 1 b 2 2 2 r 2"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf mf wrbl 0 A FFFFFFFFFFFF 11223344441802006263646566676869"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 0 b 0 2 0 r 0"));
PrintAndLogEx(NORMAL, _CYAN_(" MFC 1k 7b UID")":");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 1 b 2 2 1 3 2 r 2"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf mf wrbl 0 A FFFFFFFFFFFF 04112233445566084400626364656667"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 0 b 0 2 0 3 0 r 0"));
PrintAndLogEx(NORMAL, _CYAN_(" MFC 4k 7b UID")":");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 1 b 2 2 1 3 2 r 2"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf mf wrbl 0 A FFFFFFFFFFFF 04112233445566184200626364656667"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 0 b 0 2 0 3 0 r 0"));
PrintAndLogEx(NORMAL, _CYAN_(" MFUL ")"/" _CYAN_(" MFUL EV1 ")"/" _CYAN_(" MFULC")":");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 1 b 2 2 1 3 2 r 2"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu setuid 04112233445566"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config a 0 b 0 2 0 3 0 r 0"));
return PM3_SUCCESS;
}
static int CmdHF14AList(const char *Cmd) {
char args[128] = {0};
if (strlen(Cmd) == 0) {
@ -237,142 +198,168 @@ int hf14a_getconfig(hf14a_config *config) {
return PM3_SUCCESS;
}
int hf14a_setconfig(hf14a_config *config) {
int hf14a_setconfig(hf14a_config *config, bool verbose) {
if (!session.pm3_present) return PM3_ENOTTY;
clearCommandBuffer();
if (config != NULL)
if (config != NULL) {
SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)config, sizeof(hf14a_config));
else
if (verbose) {
SendCommandNG(CMD_HF_ISO14443A_PRINT_CONFIG, NULL, 0);
}
} else {
SendCommandNG(CMD_HF_ISO14443A_PRINT_CONFIG, NULL, 0);
}
return PM3_SUCCESS;
}
static int hf_14a_config_example(void) {
PrintAndLogEx(NORMAL, "\nExamples to revive Gen2/DirectWrite magic cards failing at anticollision:");
PrintAndLogEx(NORMAL, _CYAN_(" MFC 1k 4b UID")":");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config --atqa force --bcc ignore --cl2 skip --rats skip"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf mf wrbl 0 A FFFFFFFFFFFF 11223344440804006263646566676869"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config --std"));
PrintAndLogEx(NORMAL, _CYAN_(" MFC 4k 4b UID")":");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config --atqa force --bcc ignore --cl2 skip --rats skip"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf mf wrbl 0 A FFFFFFFFFFFF 11223344441802006263646566676869"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config --std"));
PrintAndLogEx(NORMAL, _CYAN_(" MFC 1k 7b UID")":");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config --atqa force --bcc ignore --cl2 force --cl3 skip --rats skip"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf mf wrbl 0 A FFFFFFFFFFFF 04112233445566084400626364656667"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config --std"));
PrintAndLogEx(NORMAL, _CYAN_(" MFC 4k 7b UID")":");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config --atqa forcce --bcc ignore --cl2 force --cl3 skip --rats skip"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf mf wrbl 0 A FFFFFFFFFFFF 04112233445566184200626364656667"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config --std"));
PrintAndLogEx(NORMAL, _CYAN_(" MFUL ")"/" _CYAN_(" MFUL EV1 ")"/" _CYAN_(" MFULC")":");
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config --atqa force --bcc ignore --cl2 force --cl3 skip -rats skip"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf mfu setuid 04112233445566"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf 14a config --std"));
return PM3_SUCCESS;
}
static int CmdHf14AConfig(const char *Cmd) {
if (!session.pm3_present) return PM3_ENOTTY;
// if called with no params, just print the device config
if (strlen(Cmd) == 0) {
return hf14a_setconfig(NULL);
}
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a config",
"Configure 14a settings (use with caution)",
"hf 14a config -> Print current configuration\n"
"hf 14a config --std -> Reset default configuration (follow standard)\n"
"hf 14a config --atqa std -> Follow standard\n"
"hf 14a config --atqa force -> Force execution of anticollision\n"
"hf 14a config --atqa skip -> Skip anticollision\n"
"hf 14a config --bcc std -> Follow standard\n"
"hf 14a config --bcc fix -> Fix bad BCC in anticollision\n"
"hf 14a config --bcc ignore -> Ignore bad BCC and use it as such\n"
"hf 14a config --cl2 std -> Follow standard\n"
"hf 14a config --cl2 force -> Execute CL2\n"
"hf 14a config --cl2 skip -> Skip CL2\n"
"hf 14a config --cl3 std -> Follow standard\n"
"hf 14a config --cl3 force -> Execute CL3\n"
"hf 14a config --cl3 skip -> Skip CL3\n"
"hf 14a config --rats std -> Follow standard\n"
"hf 14a config --rats force -> Execute RATS\n"
"hf 14a config --rats skip -> Skip RATS");
hf14a_config config = {
.forceanticol = -1,
.forcebcc = -1,
.forcecl2 = -1,
.forcecl3 = -1,
.forcerats = -1
void *argtable[] = {
arg_param_begin,
arg_str0(NULL, "atqa", "<std|force|skip>", "Configure ATQA<>anticollision behavior"),
arg_str0(NULL, "bcc", "<std|fix|ignore>", "Configure BCC behavior"),
arg_str0(NULL, "cl2", "<std|force|skip>", "Configure SAK<>CL2 behavior"),
arg_str0(NULL, "cl3", "<std|force|skip>", "Configure SAK<>CL3 behavior"),
arg_str0(NULL, "rats", "<std|force|skip>", "Configure RATS behavior"),
arg_lit0(NULL, "std", "Reset default configuration: follow all standard"),
arg_lit0("v", "verbose", "verbose output, also prints examples for reviving Gen2 cards"),
arg_param_end
};
bool errors = false;
uint8_t cmdp = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (param_getchar(Cmd, cmdp)) {
case 'h':
return usage_hf_14a_config();
case 'a':
switch (param_getchar(Cmd, cmdp + 1)) {
case '0':
config.forceanticol = 0;
break;
case '1':
config.forceanticol = 1;
break;
case '2':
config.forceanticol = 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown value '%c'", param_getchar(Cmd, cmdp + 1));
errors = 1;
break;
}
cmdp += 2;
break;
case 'b':
switch (param_getchar(Cmd, cmdp + 1)) {
case '0':
config.forcebcc = 0;
break;
case '1':
config.forcebcc = 1;
break;
case '2':
config.forcebcc = 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown value '%c'", param_getchar(Cmd, cmdp + 1));
errors = 1;
break;
}
cmdp += 2;
break;
case '2':
switch (param_getchar(Cmd, cmdp + 1)) {
case '0':
config.forcecl2 = 0;
break;
case '1':
config.forcecl2 = 1;
break;
case '2':
config.forcecl2 = 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown value '%c'", param_getchar(Cmd, cmdp + 1));
errors = 1;
break;
}
cmdp += 2;
break;
case '3':
switch (param_getchar(Cmd, cmdp + 1)) {
case '0':
config.forcecl3 = 0;
break;
case '1':
config.forcecl3 = 1;
break;
case '2':
config.forcecl3 = 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown value '%c'", param_getchar(Cmd, cmdp + 1));
errors = 1;
break;
}
cmdp += 2;
break;
case 'r':
switch (param_getchar(Cmd, cmdp + 1)) {
case '0':
config.forcerats = 0;
break;
case '1':
config.forcerats = 1;
break;
case '2':
config.forcerats = 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown value '%c'", param_getchar(Cmd, cmdp + 1));
errors = 1;
break;
}
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = 1;
break;
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool defaults = arg_get_lit(ctx, 6);
int vlen = 0;
char value[10];
int atqa = defaults ? 0 : -1;
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)value, sizeof(value), &vlen);
if (vlen > 0) {
if (strcmp(value, "std") == 0) atqa = 0;
else if (strcmp(value, "force") == 0) atqa = 1;
else if (strcmp(value, "skip") == 0) atqa = 2;
else {
PrintAndLogEx(ERR, "atqa argument must be 'std', 'force', or 'skip'");
CLIParserFree(ctx);
return PM3_EINVARG;
}
}
int bcc = defaults ? 0 : -1;
CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)value, sizeof(value), &vlen);
if (vlen > 0) {
if (strcmp(value, "std") == 0) bcc = 0;
else if (strcmp(value, "fix") == 0) bcc = 1;
else if (strcmp(value, "ignore") == 0) bcc = 2;
else {
PrintAndLogEx(ERR, "bcc argument must be 'std', 'fix', or 'ignore'");
CLIParserFree(ctx);
return PM3_EINVARG;
}
}
int cl2 = defaults ? 0 : -1;
CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)value, sizeof(value), &vlen);
if (vlen > 0) {
if (strcmp(value, "std") == 0) cl2 = 0;
else if (strcmp(value, "force") == 0) cl2 = 1;
else if (strcmp(value, "skip") == 0) cl2 = 2;
else {
PrintAndLogEx(ERR, "cl2 argument must be 'std', 'force', or 'skip'");
CLIParserFree(ctx);
return PM3_EINVARG;
}
}
int cl3 = defaults ? 0 : -1;
CLIParamStrToBuf(arg_get_str(ctx, 4), (uint8_t *)value, sizeof(value), &vlen);
if (vlen > 0) {
if (strcmp(value, "std") == 0) cl3 = 0;
else if (strcmp(value, "force") == 0) cl3 = 1;
else if (strcmp(value, "skip") == 0) cl3 = 2;
else {
PrintAndLogEx(ERR, "cl3 argument must be 'std', 'force', or 'skip'");
CLIParserFree(ctx);
return PM3_EINVARG;
}
}
int rats = defaults ? 0 : -1;
CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t *)value, sizeof(value), &vlen);
if (vlen > 0) {
if (strcmp(value, "std") == 0) rats = 0;
else if (strcmp(value, "force") == 0) rats = 1;
else if (strcmp(value, "skip") == 0) rats = 2;
else {
PrintAndLogEx(ERR, "rats argument must be 'std', 'force', or 'skip'");
CLIParserFree(ctx);
return PM3_EINVARG;
}
}
// validations
if (errors) return usage_hf_14a_config();
bool verbose = arg_get_lit(ctx, 7);
return hf14a_setconfig(&config);
CLIParserFree(ctx);
// validations
if (strlen(Cmd) == 0) {
return hf14a_setconfig(NULL, verbose);
}
if (verbose) {
hf_14a_config_example();
}
hf14a_config config = {
.forceanticol = atqa,
.forcebcc = bcc,
.forcecl2 = cl2,
.forcecl3 = cl3,
.forcerats = rats
};
return hf14a_setconfig(&config, verbose);
}
int Hf14443_4aGetCardData(iso14a_card_select_t *card) {

View file

@ -27,7 +27,7 @@ int CmdHF14ASniff(const char *Cmd); // used by hf topaz sniff
int CmdHF14ASim(const char *Cmd); // used by hf mfu sim
int hf14a_getconfig(hf14a_config *config);
int hf14a_setconfig(hf14a_config *config);
int hf14a_setconfig(hf14a_config *config, bool verbose);
int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search);
const char *getTagInfo(uint8_t uid);
int Hf14443_4aGetCardData(iso14a_card_select_t *card);

View file

@ -41,7 +41,6 @@ data print
data samples
data setdebugmode
data tune
hf 14a config
hf 14b sriwrite
hf 15 dump
hf 15 info

View file

@ -45,12 +45,12 @@ Here are some tips if the card doesn't react or gives error on a simple `hf 14a
Let's force a 4b UID anticollision and see what happens:
```
hf 14a config a 1 b 2 2 2 r 2
hf 14a config --atqa force --bcc ignore --cl2 skip --rats skip
hf 14a reader
```
It it responds, we know it's a TypeA card. But maybe it's a 7b UID, so let's force a 7b UID anticollision:
```
hf 14a config a 1 b 2 2 1 3 2 r 2
hf 14a config --atqa force --bcc ignore --cl2 force --cl3 skip --rats skip
hf 14a reader
```
At this stage, you know if it's a TypeA 4b or 7b card and you can check further on this page how to reconfigure different types of cards.
@ -58,7 +58,7 @@ At this stage, you know if it's a TypeA 4b or 7b card and you can check further
To restore anticollision config of the Proxmark3:
```
hf 14a config a 0 b 0 2 0 3 0 r 0
hf 14a config --std
```
# MIFARE Classic
@ -335,26 +335,26 @@ hf mf wrbl 0 A FFFFFFFFFFFF 11223344440804006263646566676869
When "soft-bricked" (by writing invalid data in block0), these ones may help:
```
hf 14a config h
hf 14a config -h
```
e.g. for 4b UID:
```
hf 14a config a 1 b 2 2 2 r 2
hf 14a config --atqa force --bcc ignore --cl2 skip --rats skip
hf mf wrbl 0 A FFFFFFFFFFFF 11223344440804006263646566676869 # for 1k
hf mf wrbl 0 A FFFFFFFFFFFF 11223344441802006263646566676869 # for 4k
hf 14a config a 0 b 0 2 0 r 0
hf 14a config --std
hf 14a reader
```
e.g. for 7b UID:
```
hf 14a config a 1 b 2 2 1 3 2 r 2
hf 14a config --atqa force --bcc ignore --cl2 force --cl3 skip --rats skip
hf mf wrbl 0 A FFFFFFFFFFFF 04112233445566084400626364656667 # for 1k
hf mf wrbl 0 A FFFFFFFFFFFF 04112233445566184200626364656667 # for 4k
hf 14a config a 0 b 0 2 0 3 0 r 0
hf 14a config --std
hf 14a reader
```
## MIFARE Classic DirectWrite, FUID version aka 1-write
@ -537,7 +537,7 @@ script run hf_mfu_setuid -h
When "soft-bricked" (by writing invalid data in block0), these ones may help:
```
hf 14a config h
hf 14a config -h
script run run hf_mf_magicrevive -u
```
@ -599,14 +599,14 @@ hf 14a raw -c a2 02 44480000
When "soft-bricked" (by writing invalid data in block0), these ones may help:
```
hf 14a config h
hf 14a config -h
```
E.g.:
```
hf 14a config a 1 b 2 2 1 3 2 r 2
hf 14a config --atqa force --bcc ignore --cl2 force --cl3 skip --rats skip
hf mfu setuid 04112233445566
hf 14a config a 0 b 0 2 0 3 0 r 0
hf 14a config --std
hf 14a reader
```