Merge branch 'master' into dav-tmp

solved merge conflict
This commit is contained in:
tharexde 2020-06-30 01:05:10 +02:00
commit da44e0fc96
13 changed files with 330 additions and 170 deletions

View file

@ -1276,8 +1276,7 @@ int PSKDemod(const char *Cmd, bool verbose) {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static int CmdIdteckDemod(const char *Cmd) { int demodIdteck(void) {
(void)Cmd; // Cmd is not used so far
if (PSKDemod("", false) != PM3_SUCCESS) { if (PSKDemod("", false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck PSKDemod failed"); PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck PSKDemod failed");
@ -1337,10 +1336,12 @@ static int CmdIdteckDemod(const char *Cmd) {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
int demodIdteck(void) { /*
return CmdIdteckDemod(""); static int CmdIdteckDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodIdteck();
} }
*/
// by marshmellow // by marshmellow
// takes 3 arguments - clock, invert, maxErr as integers // takes 3 arguments - clock, invert, maxErr as integers
@ -1710,6 +1711,7 @@ int CmdTuneSamples(const char *Cmd) {
} }
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "---------- " _CYAN_("LF Antenna") " ----------");
// in mVolt // in mVolt
struct p { struct p {
uint32_t v_lf134; uint32_t v_lf134;
@ -1746,8 +1748,9 @@ int CmdTuneSamples(const char *Cmd) {
else else
sprintf(judgement, _GREEN_("OK")); sprintf(judgement, _GREEN_("OK"));
PrintAndLogEx((package->peak_v < LF_UNUSABLE_V) ? WARNING : SUCCESS, "LF antenna is %s \n", judgement); PrintAndLogEx((package->peak_v < LF_UNUSABLE_V) ? WARNING : SUCCESS, "LF antenna is %s", judgement);
PrintAndLogEx(INFO, "---------- " _CYAN_("HF Antenna") " ----------");
// HF evaluation // HF evaluation
if (package->v_hf > NON_VOLTAGE) if (package->v_hf > NON_VOLTAGE)
PrintAndLogEx(SUCCESS, "HF antenna: %5.2f V - 13.56 MHz", (package->v_hf * ANTENNA_ERROR) / 1000.0); PrintAndLogEx(SUCCESS, "HF antenna: %5.2f V - 13.56 MHz", (package->v_hf * ANTENNA_ERROR) / 1000.0);
@ -1761,7 +1764,7 @@ int CmdTuneSamples(const char *Cmd) {
else else
sprintf(judgement, _GREEN_("OK")); sprintf(judgement, _GREEN_("OK"));
PrintAndLogEx((package->v_hf < HF_UNUSABLE_V) ? WARNING : SUCCESS, "HF antenna is %s \n", judgement); PrintAndLogEx((package->v_hf < HF_UNUSABLE_V) ? WARNING : SUCCESS, "HF antenna is %s", judgement);
// graph LF measurements // graph LF measurements
// even here, these values has 3% error. // even here, these values has 3% error.

View file

@ -1693,7 +1693,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
uint8_t key[6] = {0, 0, 0, 0, 0, 0}; uint8_t key[6] = {0, 0, 0, 0, 0, 0};
uint8_t trgkey[6] = {0, 0, 0, 0, 0, 0}; uint8_t trgkey[6] = {0, 0, 0, 0, 0, 0};
uint8_t cmdp = 0; uint8_t cmdp = 0;
char filename[FILE_PATH_SIZE] = {0}, *fptr; char filename[FILE_PATH_SIZE] = {0};
char szTemp[FILE_PATH_SIZE - 20]; char szTemp[FILE_PATH_SIZE - 20];
char ctmp; char ctmp;
@ -1706,19 +1706,21 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
switch (tolower(param_getchar(Cmd, cmdp))) { switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h': case 'h':
return usage_hf14_hardnested(); return usage_hf14_hardnested();
case 'r': case 'r': {
fptr = GenerateFilename("hf-mf-", "-nonces.bin"); char *fptr = GenerateFilename("hf-mf-", "-nonces.bin");
if (fptr == NULL) if (fptr == NULL)
strncpy(filename, "nonces.bin", FILE_PATH_SIZE - 1); strncpy(filename, "nonces.bin", FILE_PATH_SIZE - 1);
else else
strncpy(filename, fptr, FILE_PATH_SIZE - 1); strncpy(filename, fptr, FILE_PATH_SIZE - 1);
free(fptr);
nonce_file_read = true; nonce_file_read = true;
if (!param_gethex(Cmd, cmdp + 1, trgkey, 12)) { if (!param_gethex(Cmd, cmdp + 1, trgkey, 12)) {
know_target_key = true; know_target_key = true;
} }
cmdp++; cmdp++;
break; break;
}
case 't': case 't':
tests = param_get32ex(Cmd, cmdp + 1, 100, 10); tests = param_get32ex(Cmd, cmdp + 1, 100, 10);
if (!param_gethex(Cmd, cmdp + 2, trgkey, 12)) { if (!param_gethex(Cmd, cmdp + 2, trgkey, 12)) {
@ -1729,9 +1731,9 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
default: default:
if (param_getchar(Cmd, cmdp) == 0x00) { if (param_getchar(Cmd, cmdp) == 0x00) {
PrintAndLogEx(WARNING, "Block number is missing"); PrintAndLogEx(WARNING, "Block number is missing");
return 1; return usage_hf14_hardnested();
} }
blockNo = param_get8(Cmd, cmdp); blockNo = param_get8(Cmd, cmdp);
ctmp = tolower(param_getchar(Cmd, cmdp + 1)); ctmp = tolower(param_getchar(Cmd, cmdp + 1));
if (ctmp != 'a' && ctmp != 'b') { if (ctmp != 'a' && ctmp != 'b') {
@ -1775,13 +1777,15 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
case 's': case 's':
slow = true; slow = true;
break; break;
case 'w': case 'w': {
nonce_file_write = true; nonce_file_write = true;
fptr = GenerateFilename("hf-mf-", "-nonces.bin"); char *fptr = GenerateFilename("hf-mf-", "-nonces.bin");
if (fptr == NULL) if (fptr == NULL)
return 1; return 1;
strncpy(filename, fptr, FILE_PATH_SIZE - 1); strncpy(filename, fptr, FILE_PATH_SIZE - 1);
free(fptr);
break; break;
}
case 'u': case 'u':
param_getstr(Cmd, cmdp + 1, szTemp, FILE_PATH_SIZE - 20); param_getstr(Cmd, cmdp + 1, szTemp, FILE_PATH_SIZE - 20);
snprintf(filename, FILE_PATH_SIZE, "hf-mf-%s-nonces.bin", szTemp); snprintf(filename, FILE_PATH_SIZE, "hf-mf-%s-nonces.bin", szTemp);
@ -1837,7 +1841,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
// check if tag doesn't have static nonce // check if tag doesn't have static nonce
if (detect_classic_static_nonce() == 1) { if (detect_classic_static_nonce() == 1) {
PrintAndLogEx(WARNING, "Static nonce detected. Quitting..."); PrintAndLogEx(WARNING, "Static nonce detected. Quitting...");
PrintAndLogEx(INFO, "\t Try use `" _YELLOW_("hf mf staticnested") "`"); PrintAndLogEx(HINT, "\tTry use `" _YELLOW_("hf mf staticnested") "`");
return PM3_EOPABORTED; return PM3_EOPABORTED;
} }
@ -1849,11 +1853,13 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
} }
} }
PrintAndLogEx(NORMAL, "--target block no:%3d, target key type:%c, known target key: 0x%02x%02x%02x%02x%02x%02x%s, file action: %s, Slow: %s, Tests: %d ", PrintAndLogEx(INFO, "Target block no:%3d, target key type:%c, known target key: 0x%02x%02x%02x%02x%02x%02x%s",
trgBlockNo, trgBlockNo,
trgKeyType ? 'B' : 'A', trgKeyType ? 'B' : 'A',
trgkey[0], trgkey[1], trgkey[2], trgkey[3], trgkey[4], trgkey[5], trgkey[0], trgkey[1], trgkey[2], trgkey[3], trgkey[4], trgkey[5],
know_target_key ? "" : " (not set)", know_target_key ? "" : " (not set)"
);
PrintAndLogEx(INFO , "File action: %s, Slow: %s, Tests: %d ",
nonce_file_write ? "write" : nonce_file_read ? "read" : "none", nonce_file_write ? "write" : nonce_file_read ? "read" : "none",
slow ? "Yes" : "No", slow ? "Yes" : "No",
tests); tests);
@ -1861,7 +1867,9 @@ static int CmdHF14AMfNestedHard(const char *Cmd) {
uint64_t foundkey = 0; uint64_t foundkey = 0;
int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, filename); int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey, filename);
if (tests == 0) DropField(); if (tests == 0)
DropField();
if (isOK) { if (isOK) {
switch (isOK) { switch (isOK) {
case 1 : case 1 :

View file

@ -30,10 +30,14 @@
#include "mifare/desfire_crypto.h" #include "mifare/desfire_crypto.h"
#include "crapto1/crapto1.h" #include "crapto1/crapto1.h"
#include "fileutils.h" #include "fileutils.h"
#include "mifare/mifaredefault.h" // default keys
#include "mifare/ndef.h" // NDEF
#define MAX_KEY_LEN 24 #define MAX_KEY_LEN 24
#define MAX_KEYS_LIST_LEN 1024 #define MAX_KEYS_LIST_LEN 1024
#define status(x) ( ((uint16_t)(0x91<<8)) + (uint16_t)x )
struct desfire_key default_key = {0}; struct desfire_key default_key = {0};
uint8_t desdefaultkeys[3][8] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //Official uint8_t desdefaultkeys[3][8] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //Official
@ -113,8 +117,6 @@ typedef enum {
MFDES_VALUE_FILE MFDES_VALUE_FILE
} MFDES_FILE_TYPE_T; } MFDES_FILE_TYPE_T;
#define status(x) ( ((uint16_t)(0x91<<8)) + (uint16_t)x )
// NXP Appnote AN10787 - Application Directory (MAD) // NXP Appnote AN10787 - Application Directory (MAD)
typedef enum { typedef enum {
CL_ADMIN = 0, CL_ADMIN = 0,
@ -389,7 +391,6 @@ static char *getVersionStr(uint8_t major, uint8_t minor) {
return buf; return buf;
} }
static int DESFIRESendApdu(bool activate_field, bool leavefield_on, sAPDU apdu, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint16_t *sw) { static int DESFIRESendApdu(bool activate_field, bool leavefield_on, sAPDU apdu, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint16_t *sw) {
*result_len = 0; *result_len = 0;
@ -956,7 +957,6 @@ static void AuthToError(int error) {
} }
} }
// -- test if card supports 0x0A // -- test if card supports 0x0A
static int test_desfire_authenticate(void) { static int test_desfire_authenticate(void) {
uint8_t data[] = {0x00}; uint8_t data[] = {0x00};
@ -1011,7 +1011,8 @@ static int desfire_print_freemem(uint32_t free_mem) {
static int handler_desfire_freemem(uint32_t *free_mem) { static int handler_desfire_freemem(uint32_t *free_mem) {
if (free_mem == NULL) return PM3_EINVARG; if (free_mem == NULL) return PM3_EINVARG;
sAPDU apdu = {0x90, MFDES_GET_FREE_MEMORY, 0x00, 0x00, 0x00, NULL}; // 0x6E uint8_t data[] = {0x00};
sAPDU apdu = {0x90, MFDES_GET_FREE_MEMORY, 0x00, 0x00, 0x00, data}; // 0x6E
*free_mem = 0; *free_mem = 0;
uint32_t recv_len = 0; uint32_t recv_len = 0;
uint16_t sw = 0; uint16_t sw = 0;
@ -1071,7 +1072,7 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n
break; break;
} }
uint32_t cmdcnt = 0; size_t cmdcnt = 0;
memcpy(data + cmdcnt + 1, new_key, new_key_length); memcpy(data + cmdcnt + 1, new_key, new_key_length);
if ((tag->authenticated_key_no & 0x0f) != (key_no & 0x0f)) { if ((tag->authenticated_key_no & 0x0f) != (key_no & 0x0f)) {
@ -1405,16 +1406,16 @@ static int handler_desfire_appids(uint8_t *dest, uint32_t *app_ids_len) {
// --- GET DF NAMES // --- GET DF NAMES
static int handler_desfire_dfnames(dfname_t *dest, uint8_t *dfname_count) { static int handler_desfire_dfnames(dfname_t *dest, uint8_t *dfname_count) {
*dfname_count = 0;
if (g_debugMode > 1) { if (g_debugMode > 1) {
if (dest == NULL) PrintAndLogEx(ERR, "DEST=NULL"); if (dest == NULL) PrintAndLogEx(ERR, "DEST = NULL");
if (dfname_count == NULL) PrintAndLogEx(ERR, "DFNAME_COUNT=NULL"); if (dfname_count == NULL) PrintAndLogEx(ERR, "DFNAME_COUNT = NULL");
} }
if (dest == NULL || dfname_count == NULL) return PM3_EINVARG; if (dest == NULL || dfname_count == NULL)
return PM3_EINVARG;
*dfname_count = 0; *dfname_count = 0;
sAPDU apdu = {0x90, MFDES_GET_DF_NAMES, 0x00, 0x00, 0x00, NULL}; //0x6d sAPDU apdu = {0x90, MFDES_GET_DF_NAMES, 0x00, 0x00, 0x00, NULL}; //0x6d
uint32_t recv_len = 0; uint32_t recv_len = 0;
uint16_t sw = 0; uint16_t sw = 0;
@ -1648,9 +1649,11 @@ static int handler_desfire_readdata(mfdes_data_t *data, MFDES_FILE_TYPE_T type,
return res; return res;
} }
static int handler_desfire_getvalue(mfdes_value_t *value, uint32_t *resplen, uint8_t cs) { static int handler_desfire_getvalue(mfdes_value_t *value, uint32_t *resplen, uint8_t cs) {
if (value->fileno > 0x1F) return PM3_EINVARG;
if (value->fileno > 0x1F)
return PM3_EINVARG;
sAPDU apdu = {0x90, MFDES_GET_VALUE, 0x00, 0x00, 0x01, &value->fileno}; // 0xBD sAPDU apdu = {0x90, MFDES_GET_VALUE, 0x00, 0x00, 0x01, &value->fileno}; // 0xBD
uint16_t sw = 0; uint16_t sw = 0;
*resplen = 0; *resplen = 0;
@ -1735,7 +1738,6 @@ static int handler_desfire_writedata(mfdes_data_t *data, MFDES_FILE_TYPE_T type,
return res; return res;
} }
static int handler_desfire_deletefile(uint8_t fileno) { static int handler_desfire_deletefile(uint8_t fileno) {
if (fileno > 0x1F) return PM3_EINVARG; if (fileno > 0x1F) return PM3_EINVARG;
sAPDU apdu = {0x90, MFDES_DELETE_FILE, 0x00, 0x00, 1, &fileno}; // 0xDF sAPDU apdu = {0x90, MFDES_DELETE_FILE, 0x00, 0x00, 1, &fileno}; // 0xDF
@ -2096,7 +2098,6 @@ static int CmdHF14ADesSelectApp(const char *Cmd) {
return res; return res;
} }
static int CmdHF14ADesCreateApp(const char *Cmd) { static int CmdHF14ADesCreateApp(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes createaid", CLIParserInit(&ctx, "hf mfdes createaid",
@ -2290,7 +2291,6 @@ static int selectfile(uint8_t *aid, uint32_t fileno, uint8_t *cs) {
return res; return res;
} }
static int CmdHF14ADesClearRecordFile(const char *Cmd) { static int CmdHF14ADesClearRecordFile(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes clearrecord", CLIParserInit(&ctx, "hf mfdes clearrecord",
@ -2442,7 +2442,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) {
int fidlength = 0; int fidlength = 0;
uint8_t fid[2] = {0}; uint8_t fid[2] = {0};
CLIParamHexToBuf(arg_get_str(ctx, 2), fid, 2, &fidlength); int res_flen = CLIParamHexToBuf(arg_get_str(ctx, 2), fid, 2, &fidlength);
uint8_t comset = arg_get_int(ctx, 3); uint8_t comset = arg_get_int(ctx, 3);
int arlength = 0; int arlength = 0;
@ -2487,7 +2487,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
if (fidlength != 2) { if (res_flen || fidlength != 2) {
PrintAndLogEx(ERR, "ISO File id must have 2 hex bytes length."); PrintAndLogEx(ERR, "ISO File id must have 2 hex bytes length.");
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -2633,11 +2633,11 @@ static int CmdHF14ADesReadData(const char *Cmd) {
int offsetlength = 0; int offsetlength = 0;
uint8_t offset[3] = {0}; uint8_t offset[3] = {0};
CLIParamHexToBuf(arg_get_str(ctx, 2), offset, 3, &offsetlength); int res_offset = CLIParamHexToBuf(arg_get_str(ctx, 2), offset, 3, &offsetlength);
int flength = 0; int flength = 0;
uint8_t filesize[3] = {0}; uint8_t filesize[3] = {0};
CLIParamHexToBuf(arg_get_str(ctx, 3), filesize, 3, &flength); int res_flen = CLIParamHexToBuf(arg_get_str(ctx, 3), filesize, 3, &flength);
int type = arg_get_int(ctx, 4); int type = arg_get_int(ctx, 4);
@ -2652,7 +2652,7 @@ static int CmdHF14ADesReadData(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
if (offsetlength != 3 && offsetlength != 0) { if (res_offset || (offsetlength != 3 && offsetlength != 0)) {
PrintAndLogEx(ERR, "Offset needs 3 hex bytes"); PrintAndLogEx(ERR, "Offset needs 3 hex bytes");
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -2667,6 +2667,11 @@ static int CmdHF14ADesReadData(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
if (res_flen) {
PrintAndLogEx(ERR, "File size input error");
return PM3_EINVARG;
}
swap24(filesize); swap24(filesize);
swap24(offset); swap24(offset);
@ -2750,7 +2755,7 @@ static int CmdHF14ADesChangeValue(const char *Cmd) {
value.fileno = _fileno[0]; value.fileno = _fileno[0];
int vlength = 0x0; int vlength = 0x0;
CLIParamHexToBuf(arg_get_str(ctx, 2), value.value, 4, &vlength); int res_val = CLIParamHexToBuf(arg_get_str(ctx, 2), value.value, 4, &vlength);
int mode = arg_get_int(ctx, 3); int mode = arg_get_int(ctx, 3);
int aidlength = 3; int aidlength = 3;
@ -2765,7 +2770,7 @@ static int CmdHF14ADesChangeValue(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
if (vlength != 4) { if (res_val || vlength != 4) {
PrintAndLogEx(ERR, "Value needs 4 hex bytes."); PrintAndLogEx(ERR, "Value needs 4 hex bytes.");
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -2820,7 +2825,6 @@ static int CmdHF14ADesChangeValue(const char *Cmd) {
return res; return res;
} }
static int CmdHF14ADesWriteData(const char *Cmd) { static int CmdHF14ADesWriteData(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
@ -2849,16 +2853,14 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
int offsetlength = 0; int offsetlength = 0;
uint8_t offset[3] = {0}; uint8_t offset[3] = {0};
CLIParamHexToBuf(arg_get_str(ctx, 2), offset, 3, &offsetlength); int res_offset = CLIParamHexToBuf(arg_get_str(ctx, 2), offset, 3, &offsetlength);
int dlength = 0xFFFF; // iceman: we only have a 1024 byte commandline input array. So this is pointlessly large.
uint8_t *data = (uint8_t *)calloc(dlength, sizeof(uint8_t)); // with 2char hex, 512bytes could be input.
if (data == NULL) { // Instead large binary inputs should be BINARY files and written to card.
PrintAndLogEx(ERR, "failed to allocate memory"); int dlength = 512;
CLIParserFree(ctx); uint8_t data[512] = {0};
return PM3_EMALLOC; int res_data = CLIParamHexToBuf(arg_get_str(ctx, 3), data, 512, &dlength);
}
CLIParamHexToBuf(arg_get_str(ctx, 3), data, 0xFFFF, &dlength);
int type = arg_get_int(ctx, 4); int type = arg_get_int(ctx, 4);
int aidlength = 3; int aidlength = 3;
@ -2872,31 +2874,26 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
if (type < 0 || type > 1) { if (type < 0 || type > 1) {
PrintAndLogEx(ERR, "Unknown type (0=Standard/Backup, 1=Record)"); PrintAndLogEx(ERR, "Unknown type (0=Standard/Backup, 1=Record)");
if (data) free(data);
return PM3_EINVARG; return PM3_EINVARG;
} }
if (dlength == 0) { if (res_data || dlength == 0) {
PrintAndLogEx(ERR, "Data needs some hex bytes to write"); PrintAndLogEx(ERR, "Data needs some hex bytes to write");
if (data) free(data);
return PM3_EINVARG; return PM3_EINVARG;
} }
if (offsetlength != 3 && offsetlength != 0) { if (res_offset || (offsetlength != 3 && offsetlength != 0)) {
PrintAndLogEx(ERR, "Offset needs 3 hex bytes"); PrintAndLogEx(ERR, "Offset needs 3 hex bytes");
if (data) free(data);
return PM3_EINVARG; return PM3_EINVARG;
} }
if (filenolen != 1) { if (filenolen != 1) {
PrintAndLogEx(ERR, "File number is missing"); PrintAndLogEx(ERR, "File number is missing");
if (data) free(data);
return PM3_EINVARG; return PM3_EINVARG;
} }
if (_fileno[0] > 0x1F) { if (_fileno[0] > 0x1F) {
PrintAndLogEx(ERR, "File number range is invalid (0x00-0x1F)"); PrintAndLogEx(ERR, "File number range is invalid (0x00-0x1F)");
if (data) free(data);
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -2919,11 +2916,11 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
uint8_t cs = 0; uint8_t cs = 0;
if (selectfile(aid, _fileno[0], &cs) != PM3_SUCCESS) { if (selectfile(aid, _fileno[0], &cs) != PM3_SUCCESS) {
PrintAndLogEx(ERR, _RED_(" Error on selecting file.")); PrintAndLogEx(ERR, _RED_(" Error on selecting file."));
DropField();
return PM3_ESOFT; return PM3_ESOFT;
} }
int res = PM3_ESOFT; int res = PM3_ESOFT;
if (data != NULL) {
ft.data = data; ft.data = data;
res = handler_desfire_writedata(&ft, type, cs); res = handler_desfire_writedata(&ft, type, cs);
if (res == PM3_SUCCESS) { if (res == PM3_SUCCESS) {
@ -2931,13 +2928,10 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
} else { } else {
PrintAndLogEx(ERR, "Couldn't read data. Error %d", res); PrintAndLogEx(ERR, "Couldn't read data. Error %d", res);
} }
free(data);
}
DropField(); DropField();
return res; return res;
} }
static int CmdHF14ADesCreateRecordFile(const char *Cmd) { static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
CLIParserContext *ctx; CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes createrecordfile", CLIParserInit(&ctx, "hf mfdes createrecordfile",
@ -2967,7 +2961,7 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
int fidlength = 0; int fidlength = 0;
uint8_t fid[2] = {0}; uint8_t fid[2] = {0};
CLIParamHexToBuf(arg_get_str(ctx, 2), fid, 2, &fidlength); int res_flen = CLIParamHexToBuf(arg_get_str(ctx, 2), fid, 2, &fidlength);
uint8_t comset = arg_get_int(ctx, 3); uint8_t comset = arg_get_int(ctx, 3);
int arlength = 0; int arlength = 0;
@ -3028,7 +3022,7 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
return PM3_EINVARG; return PM3_EINVARG;
} }
if (fidlength != 2) { if (res_flen || fidlength != 2) {
PrintAndLogEx(ERR, "ISO File id must have 2 hex bytes length."); PrintAndLogEx(ERR, "ISO File id must have 2 hex bytes length.");
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -3214,24 +3208,20 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) {
"\n\thf mfdes formatpicc\n" "\n\thf mfdes formatpicc\n"
"Make sure to authenticate picc before running this command.\n" "Make sure to authenticate picc before running this command.\n"
); );
CLIParserFree(ctx);
sAPDU apdu = {0x90, MFDES_FORMAT_PICC, 0x00, 0x00, 0, NULL}; // 0xDF sAPDU apdu = {0x90, MFDES_FORMAT_PICC, 0x00, 0x00, 0, NULL}; // 0xDF
uint16_t sw = 0; uint16_t sw = 0;
uint32_t recvlen = 0; uint32_t recvlen = 0;
int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true);
if (res != PM3_SUCCESS) { if (res != PM3_SUCCESS) {
PrintAndLogEx(WARNING, _RED_(" Can't format picc -> %s"), GetErrorString(res, &sw)); PrintAndLogEx(WARNING, _RED_(" Can't format picc -> %s"), GetErrorString(res, &sw));
DropField();
return res;
} else { } else {
PrintAndLogEx(INFO, "Card successfully reset"); PrintAndLogEx(INFO, "Card successfully reset");
return PM3_SUCCESS;
} }
DropField(); DropField();
return PM3_SUCCESS; return res;
} }
static int CmdHF14ADesInfo(const char *Cmd) { static int CmdHF14ADesInfo(const char *Cmd) {
(void)Cmd; // Cmd is not used so far (void)Cmd; // Cmd is not used so far
DropField(); DropField();
@ -3370,7 +3360,6 @@ static int CmdHF14ADesInfo(const char *Cmd) {
return PM3_SUCCESS; return PM3_SUCCESS;
} }
static void DecodeFileType(uint8_t filetype) { static void DecodeFileType(uint8_t filetype) {
switch (filetype) { switch (filetype) {
case 0x00: case 0x00:
@ -3777,11 +3766,13 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
uint8_t cmdAuthAlgo = arg_get_int_def(ctx, 2, 0); uint8_t cmdAuthAlgo = arg_get_int_def(ctx, 2, 0);
uint8_t key[24] = {0}; uint8_t key[24] = {0};
int keylen = 0; int keylen = 0;
CLIParamHexToBuf(arg_get_str(ctx, 3), key, 24, &keylen); int res_klen = CLIParamHexToBuf(arg_get_str(ctx, 3), key, 24, &keylen);
uint8_t newcmdAuthAlgo = arg_get_int_def(ctx, 4, 0); uint8_t newcmdAuthAlgo = arg_get_int_def(ctx, 4, 0);
uint8_t newkey[24] = {0}; uint8_t newkey[24] = {0};
int newkeylen = 0; int newkeylen = 0;
CLIParamHexToBuf(arg_get_str(ctx, 5), newkey, 24, &newkeylen); int res_newklen = CLIParamHexToBuf(arg_get_str(ctx, 5), newkey, 24, &newkeylen);
uint8_t aesversion = arg_get_int_def(ctx, 6, 0); uint8_t aesversion = arg_get_int_def(ctx, 6, 0);
CLIParserFree(ctx); CLIParserFree(ctx);
@ -3805,12 +3796,12 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
newkeylength = 24; newkeylength = 24;
} }
if ((keylen < 8) || (keylen > 24)) { if (res_klen || (keylen < 8) || (keylen > 24)) {
PrintAndLogEx(ERR, "Specified key must have %d bytes length.", keylen); PrintAndLogEx(ERR, "Specified key must have %d bytes length.", keylen);
return PM3_EINVARG; return PM3_EINVARG;
} }
if ((newkeylen < 8) || (newkeylen > 24)) { if (res_newklen || (newkeylen < 8) || (newkeylen > 24)) {
PrintAndLogEx(ERR, "Specified key must have %d bytes length.", newkeylen); PrintAndLogEx(ERR, "Specified key must have %d bytes length.", newkeylen);
return PM3_EINVARG; return PM3_EINVARG;
} }
@ -4470,6 +4461,107 @@ static int CmdHF14ADesList(const char *Cmd) {
return CmdTraceList("des"); return CmdTraceList("des");
} }
/*
static int CmdHF14aDesNDEF(const char *Cmd) {
DropField();
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes ndef",
"Prints NFC Data Exchange Format (NDEF)",
"Usage:\n"
_YELLOW_("\thf mfdes ndef") " -> shows NDEF data\n"
_YELLOW_("\thf mfdes ndef -vv") " -> shows NDEF parsed and raw data\n"
_YELLOW_("\thf mfdes ndef -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7") " -> shows NDEF data with custom AID and key\n");
void *argtable[] = {
arg_param_begin,
arg_litn("vV", "verbose", 0, 2, "show technical data"),
arg_str0("", "aid", "<aid>", "replace default aid for NDEF"),
arg_str0("kK", "key", "<key>", "replace default key for NDEF"),
arg_lit0("bB", "keyb", "use key B for access sectors (by default: key A)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool verbose = arg_get_lit(ctx, 1);
bool verbose2 = arg_get_lit(ctx, 1) > 1;
uint8_t aid[2] = {0};
int aidlen;
CLIGetHexWithReturn(ctx, 2, aid, &aidlen);
uint8_t key[16] = {0};
int keylen;
CLIGetHexWithReturn(ctx, 3, key, &keylen);
bool keyB = arg_get_lit(ctx, 4);
uint16_t ndefAID = 0xe103;
if (aidlen == 2)
ndefAID = (aid[0] << 8) + aid[1];
uint8_t ndefkey[16] = {0};
memcpy(ndefkey, g_mifarep_ndef_key, 16);
if (keylen == 16) {
memcpy(ndefkey, key, 16);
}
uint8_t data[4096] = {0};
int datalen = 0;
for (int j = (int)file_ids_len - 1; j >= 0; j--) {
PrintAndLogEx(SUCCESS, "\n\n Fileid %d (0x%02x)", file_ids[j], file_ids[j]);
uint8_t filesettings[20] = {0};
uint32_t fileset_len = 0;
res = handler_desfire_filesettings(file_ids[j], filesettings, &fileset_len);
if (res != PM3_SUCCESS) continue;
int maclen = 0; // To be implemented
if (fileset_len == 1 + 1 + 2 + 3 + maclen) {
int filesize = (filesettings[6] << 16) + (filesettings[5] << 8) + filesettings[4];
mfdes_data_t fdata;
fdata.fileno = file_ids[j];
memset(fdata.offset, 0, 3);
memset(fdata.length, 0, 3);
uint8_t *data = (uint8_t *)calloc(filesize, sizeof(uint8_t));
if (data == NULL) {
DropField();
return PM3_EMALLOC;
}
fdata.data = data;
int res = handler_desfire_readdata(&fdata, MFDES_DATA_FILE, filesettings[1]);
if (res == PM3_SUCCESS) {
uint32_t len = le24toh(fdata.length);
NDEFDecodeAndPrint(data, datalen, verbose);
} else {
PrintAndLogEx(ERR, "Couldn't read value. Error %d", res);
res = handler_desfire_select_application(aid);
if (res != PM3_SUCCESS) continue;
}
free(data);
}
// PrintAndLogEx(INFO, "reading data from tag");
if (!datalen) {
PrintAndLogEx(ERR, "no NDEF data");
return PM3_SUCCESS;
}
if (verbose2) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("DESfire NDEF raw") " ----------------");
dump_buffer(data, datalen, stdout, 1);
}
PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfdes ndef -vv`") " for more details");
return PM3_SUCCESS;
}
*/
/*static int CmdTest(const char *Cmd) { /*static int CmdTest(const char *Cmd) {
(void)Cmd; // Cmd is not used so far (void)Cmd; // Cmd is not used so far
uint8_t IV[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t IV[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -4496,7 +4588,6 @@ static int CmdHF14ADesList(const char *Cmd) {
static command_t CommandTable[] = { static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"}, {"help", CmdHelp, AlwaysAvailable, "This help"},
//{"test", CmdTest, AlwaysAvailable, "Test"},
{"info", CmdHF14ADesInfo, IfPm3Iso14443a, "Tag information"}, {"info", CmdHF14ADesInfo, IfPm3Iso14443a, "Tag information"},
{"list", CmdHF14ADesList, AlwaysAvailable, "List DESFire (ISO 14443A) history"}, {"list", CmdHF14ADesList, AlwaysAvailable, "List DESFire (ISO 14443A) history"},
{"enum", CmdHF14ADesEnumApplications, IfPm3Iso14443a, "Tries enumerate all applications"}, {"enum", CmdHF14ADesEnumApplications, IfPm3Iso14443a, "Tries enumerate all applications"},
@ -4518,6 +4609,7 @@ static command_t CommandTable[] = {
{"formatpicc", CmdHF14ADesFormatPICC, IfPm3Iso14443a, "Format PICC"}, {"formatpicc", CmdHF14ADesFormatPICC, IfPm3Iso14443a, "Format PICC"},
{"dump", CmdHF14ADesDump, IfPm3Iso14443a, "Dump all files"}, {"dump", CmdHF14ADesDump, IfPm3Iso14443a, "Dump all files"},
{"chk", CmdHF14aDesChk, IfPm3Iso14443a, "Check keys"}, {"chk", CmdHF14aDesChk, IfPm3Iso14443a, "Check keys"},
// {"ndef", CmdHF14aDesNDEF, IfPm3Iso14443a, "Prints NDEF records from card"},
{NULL, NULL, NULL, NULL} {NULL, NULL, NULL, NULL}
}; };

View file

@ -1429,9 +1429,9 @@ static int CmdHFMFPNDEF(const char *Cmd) {
CLIParserInit(&ctx, "hf mfp ndef", CLIParserInit(&ctx, "hf mfp ndef",
"Prints NFC Data Exchange Format (NDEF)", "Prints NFC Data Exchange Format (NDEF)",
"Usage:\n" "Usage:\n"
"\thf mfp ndef -> shows NDEF data\n" _YELLOW_("\thf mfp ndef") " -> shows NDEF data\n"
"\thf mfp ndef -vv -> shows NDEF parsed and raw data\n" _YELLOW_("\thf mfp ndef -vv") " -> shows NDEF parsed and raw data\n"
"\thf mfp ndef -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key\n"); _YELLOW_("\thf mfp ndef -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7") " -> shows NDEF data with custom AID and key\n");
void *argtable[] = { void *argtable[] = {
arg_param_begin, arg_param_begin,
@ -1530,12 +1530,12 @@ static int CmdHFMFPNDEF(const char *Cmd) {
if (verbose2) { if (verbose2) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("MFC NDEF raw") " ----------------"); PrintAndLogEx(INFO, "--- " _CYAN_("MF Plus NDEF raw") " ----------------");
dump_buffer(data, datalen, stdout, 1); dump_buffer(data, datalen, stdout, 1);
} }
NDEFDecodeAndPrint(data, datalen, verbose); NDEFDecodeAndPrint(data, datalen, verbose);
PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mf ndef -vv`") " for more details"); PrintAndLogEx(HINT, "Try " _YELLOW_("`hf mfp ndef -vv`") " for more details");
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -624,8 +624,8 @@ static int CmdEM410xWrite(const char *Cmd) {
// Allowed clock rates: 16, 32, 40 and 64 // Allowed clock rates: 16, 32, 40 and 64
if ((clock1 != 16) && (clock1 != 32) && (clock1 != 64) && (clock1 != 40)) { if ((clock1 != 16) && (clock1 != 32) && (clock1 != 64) && (clock1 != 40)) {
PrintAndLogEx(ERR, "error, clock rate" _RED_("%d")" not valid"); PrintAndLogEx(FAILED, "error, clock rate" _RED_("%d")" not valid", clock1);
PrintAndLogEx(INFO, "supported clock rates: " _YELLOW_("16, 32, 40, 60") "\n", clock1); PrintAndLogEx(INFO, "supported clock rates: " _YELLOW_("16, 32, 40, 60") "\n");
usage_lf_em410x_write(); usage_lf_em410x_write();
return PM3_EINVARG; return PM3_EINVARG;
} }

View file

@ -240,7 +240,7 @@ static void print_result(const em4x50_word_t *words, int fwr, int lwr, bool verb
} }
} }
static void print_info_result(PacketResponseNG *resp, const em4x50_data_t *etd, bool bverbose) { static void print_info_result(PacketResponseNG *resp, const em4x50_data_t *etd, bool verbose) {
// display all information of info result in structured format // display all information of info result in structured format
@ -265,7 +265,7 @@ static void print_info_result(PacketResponseNG *resp, const em4x50_data_t *etd,
// data section // data section
PrintAndLogEx(NORMAL, _YELLOW_("\n em4x50 data:")); PrintAndLogEx(NORMAL, _YELLOW_("\n em4x50 data:"));
if (bverbose) { if (verbose) {
// detailed data section // detailed data section
print_result(words, 0, EM4X50_NO_WORDS - 1, true); print_result(words, 0, EM4X50_NO_WORDS - 1, true);
@ -459,7 +459,7 @@ static void print_write_result(PacketResponseNG *resp, const em4x50_data_t *etd)
bool login = resp->status & STATUS_LOGIN; bool login = resp->status & STATUS_LOGIN;
uint8_t *data = resp->data.asBytes; uint8_t *data = resp->data.asBytes;
char string[NO_CHARS_MAX] = {0}, pstring[NO_CHARS_MAX] = {0}; char string[NO_CHARS_MAX] = {0}, pstring[NO_CHARS_MAX] = {0};
em4x50_word_t word; em4x50_word_t words[EM4X50_NO_WORDS];
prepare_result(data, etd->address, etd->address, &word); prepare_result(data, etd->address, etd->address, &word);
print_result(&word, etd->address, etd->address, true); print_result(&word, etd->address, etd->address, true);
@ -654,7 +654,7 @@ static void print_read_result(PacketResponseNG *resp, const em4x50_data_t *etd,
int now = (resp->status & STATUS_NO_WORDS) >> 2; int now = (resp->status & STATUS_NO_WORDS) >> 2;
char string[NO_CHARS_MAX] = {0}, pstring[NO_CHARS_MAX] = {0}; char string[NO_CHARS_MAX] = {0}, pstring[NO_CHARS_MAX] = {0};
uint8_t *data = resp->data.asBytes; uint8_t *data = resp->data.asBytes;
em4x50_word_t word; em4x50_word_t words[EM4X50_NO_WORDS];
if (addr_given) { if (addr_given) {

View file

@ -169,7 +169,7 @@ static int CmdIOProxDemod(const char *Cmd) {
calccrc &= 0xff; calccrc &= 0xff;
calccrc = 0xff - calccrc; calccrc = 0xff - calccrc;
char crc_str[30] = {0}; char crc_str[36] = {0};
if (crc == calccrc) { if (crc == calccrc) {
snprintf(crc_str, sizeof(crc_str), "(" _GREEN_("ok") ")" ); snprintf(crc_str, sizeof(crc_str), "(" _GREEN_("ok") ")" );

View file

@ -119,8 +119,8 @@ int demodMotorola(void) {
checksum |= DemodBuffer[63] << 0; // b1 checksum |= DemodBuffer[63] << 0; // b1
PrintAndLogEx(SUCCESS, "Motorola - len: " _GREEN_("26") " FC: " _GREEN_("%u") " Card: " _GREEN_("%u") ", Raw: %08X%08X", fc, csn, raw1, raw2); PrintAndLogEx(SUCCESS, "Motorola - fmt: " _GREEN_("26") " FC: " _GREEN_("%u") " Card: " _GREEN_("%u") ", Raw: %08X%08X", fc, csn, raw1, raw2);
PrintAndLogEx(DEBUG, "checksum: " _GREEN_("%1d%1d"), fc, csn, checksum >> 1 & 0x01, checksum & 0x01); PrintAndLogEx(DEBUG, "checksum: " _GREEN_("%1d%1d"), checksum >> 1 & 0x01, checksum & 0x01);
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -389,7 +389,7 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
return data; return data;
switch (communication_settings & MDCM_MASK) { switch (communication_settings & MDCM_MASK) {
case MDCM_PLAIN: case MDCM_PLAIN: {
if (AS_LEGACY == DESFIRE(tag)->authentication_scheme) if (AS_LEGACY == DESFIRE(tag)->authentication_scheme)
break; break;
@ -404,9 +404,9 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
*/ */
append_mac = false; append_mac = false;
}
/* pass through */ /* pass through */
case MDCM_MACED: case MDCM_MACED: {
communication_settings |= NO_CRC; communication_settings |= NO_CRC;
switch (DESFIRE(tag)->authentication_scheme) { switch (DESFIRE(tag)->authentication_scheme) {
@ -455,7 +455,8 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
} }
break; break;
case MDCM_ENCIPHERED: }
case MDCM_ENCIPHERED: {
/* |<-------------- data -------------->| /* |<-------------- data -------------->|
* |<--- offset -->| | * |<--- offset -->| |
* +---------------+--------------------+-----+---------+ * +---------------+--------------------+-----+---------+
@ -473,23 +474,27 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
if (!(communication_settings & ENC_COMMAND)) if (!(communication_settings & ENC_COMMAND))
break; break;
edl = enciphered_data_length(tag, *nbytes - offset, communication_settings) + offset; edl = enciphered_data_length(tag, *nbytes - offset, communication_settings) + offset;
// Fill in the crypto buffer with data ... // Fill in the crypto buffer with data ...
memcpy(res, data, *nbytes); memcpy(res, data, *nbytes);
if (!(communication_settings & NO_CRC)) { if (!(communication_settings & NO_CRC)) {
// ... CRC ... // ... CRC ...
switch (DESFIRE(tag)->authentication_scheme) { switch (DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY: case AS_LEGACY: {
AddCrc14A(res + offset, *nbytes - offset); AddCrc14A(res + offset, *nbytes - offset);
*nbytes += 2; *nbytes += 2;
break; break;
case AS_NEW: }
case AS_NEW: {
crc32_append(res, *nbytes); crc32_append(res, *nbytes);
*nbytes += 4; *nbytes += 4;
break; break;
} }
} }
}
// ... and padding // ... and padding
memset(res + *nbytes, 0, edl - *nbytes); memset(res + *nbytes, 0, edl - *nbytes);
@ -497,12 +502,13 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
mifare_cypher_blocks_chained(tag, NULL, NULL, res + offset, *nbytes - offset, MCD_SEND, (AS_NEW == DESFIRE(tag)->authentication_scheme) ? MCO_ENCYPHER : MCO_DECYPHER); mifare_cypher_blocks_chained(tag, NULL, NULL, res + offset, *nbytes - offset, MCD_SEND, (AS_NEW == DESFIRE(tag)->authentication_scheme) ? MCO_ENCYPHER : MCO_DECYPHER);
break; break;
default: }
default: {
*nbytes = -1; *nbytes = -1;
res = NULL; res = NULL;
break; break;
} }
}
return res; return res;

View file

@ -121,9 +121,13 @@ static int print_aid_description(json_t *root, uint16_t aid, char *fmt, bool ver
const char *company = mad_json_get_str(elm, "company"); const char *company = mad_json_get_str(elm, "company");
const char *provider = mad_json_get_str(elm, "service_provider"); const char *provider = mad_json_get_str(elm, "service_provider");
const char *integrator = mad_json_get_str(elm, "system_integrator"); const char *integrator = mad_json_get_str(elm, "system_integrator");
if (application && company) {
char result[4 + strlen(application) + strlen(company)]; char result[4 + strlen(application) + strlen(company)];
sprintf(result, " %s [%s]", application, company); sprintf(result, " %s [%s]", application, company);
PrintAndLogEx(INFO, fmt, result); PrintAndLogEx(INFO, fmt, result);
}
if (verbose) { if (verbose) {
PrintAndLogEx(SUCCESS, " MAD: %s", vmad); PrintAndLogEx(SUCCESS, " MAD: %s", vmad);
if (application) if (application)

View file

@ -86,7 +86,6 @@ int preferences_load(void) {
// to better control json cant find file error msg. // to better control json cant find file error msg.
char *fn = prefGetFilename(); char *fn = prefGetFilename();
if (fileExists(fn)) { if (fileExists(fn)) {
PrintAndLogEx(INFO, "Loading preferences...");
if (loadFileJSON(fn, &dummyData, sizeof(dummyData), &dummyDL, &preferences_load_callback) == PM3_SUCCESS) { if (loadFileJSON(fn, &dummyData, sizeof(dummyData), &dummyDL, &preferences_load_callback) == PM3_SUCCESS) {
session.preferences_loaded = true; session.preferences_loaded = true;
} }
@ -384,75 +383,75 @@ static const char *prefShowMsg(prefShowOpt_t Opt) {
return ""; return "";
} }
static void showEmojiState(prefShowOpt_t Opt) { static void showEmojiState(prefShowOpt_t opt) {
switch (session.emoji_mode) { switch (session.emoji_mode) {
case ALIAS: case ALIAS:
PrintAndLogEx(NORMAL, " %s emoji.................. "_GREEN_("alias"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s emoji.................. "_GREEN_("alias"), prefShowMsg(opt));
break; break;
case EMOJI: case EMOJI:
PrintAndLogEx(NORMAL, " %s emoji.................. "_GREEN_("emoji"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s emoji.................. "_GREEN_("emoji"), prefShowMsg(opt));
break; break;
case ALTTEXT: case ALTTEXT:
PrintAndLogEx(NORMAL, " %s emoji.................. "_GREEN_("alttext"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s emoji.................. "_GREEN_("alttext"), prefShowMsg(opt));
break; break;
case ERASE: case ERASE:
PrintAndLogEx(NORMAL, " %s emoji.................. "_GREEN_("erase"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s emoji.................. "_GREEN_("erase"), prefShowMsg(opt));
break; break;
default: default:
PrintAndLogEx(NORMAL, " %s emoji.................. "_RED_("unknown"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s emoji.................. "_RED_("unknown"), prefShowMsg(opt));
} }
} }
static void showColorState(prefShowOpt_t Opt) { static void showColorState(prefShowOpt_t opt) {
if (session.supports_colors) if (session.supports_colors)
PrintAndLogEx(NORMAL, " %s color.................. "_GREEN_("ansi"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s color.................. "_GREEN_("ansi"), prefShowMsg(opt));
else else
PrintAndLogEx(NORMAL, " %s color.................. "_WHITE_("off"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s color.................. "_WHITE_("off"), prefShowMsg(opt));
} }
static void showClientDebugState(prefShowOpt_t Opt) { static void showClientDebugState(prefShowOpt_t opt) {
switch (session.client_debug_level) { switch (session.client_debug_level) {
case cdbOFF: case cdbOFF:
PrintAndLogEx(NORMAL, " %s client debug........... "_WHITE_("off"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s client debug........... "_WHITE_("off"), prefShowMsg(opt));
break; break;
case cdbSIMPLE: case cdbSIMPLE:
PrintAndLogEx(NORMAL, " %s client debug........... "_GREEN_("simple"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s client debug........... "_GREEN_("simple"), prefShowMsg(opt));
break; break;
case cdbFULL: case cdbFULL:
PrintAndLogEx(NORMAL, " %s client debug........... "_GREEN_("full"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s client debug........... "_GREEN_("full"), prefShowMsg(opt));
break; break;
default: default:
PrintAndLogEx(NORMAL, " %s client debug........... "_RED_("unknown"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s client debug........... "_RED_("unknown"), prefShowMsg(opt));
} }
} }
/* /*
static void showDeviceDebugState(prefShowOpt_t Opt) { static void showDeviceDebugState(prefShowOpt_t opt) {
switch (session.device_debug_level) { switch (session.device_debug_level) {
case ddbOFF: case ddbOFF:
PrintAndLogEx(NORMAL, " %s device debug........... "_WHITE_("off"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s device debug........... "_WHITE_("off"), prefShowMsg(opt));
break; break;
case ddbERROR: case ddbERROR:
PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("error"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("error"), prefShowMsg(opt));
break; break;
case ddbINFO: case ddbINFO:
PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("info"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("info"), prefShowMsg(opt));
break; break;
case ddbDEBUG: case ddbDEBUG:
PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("debug"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("debug"), prefShowMsg(opt));
break; break;
case ddbEXTENDED: case ddbEXTENDED:
PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("extended"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("extended"), prefShowMsg(opt));
break; break;
default: default:
PrintAndLogEx(NORMAL, " %s device debug........... "_RED_("unknown"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s device debug........... "_RED_("unknown"), prefShowMsg(opt));
} }
} }
*/ */
/* /*
static void showSavePathState(savePaths_t pathIndex, prefShowOpt_t Opt) { static void showSavePathState(savePaths_t pathIndex, prefShowOpt_t opt) {
char tempStr[50]; char tempStr[50];
@ -470,29 +469,30 @@ static void showSavePathState(savePaths_t pathIndex, prefShowOpt_t Opt) {
strcpy (tempStr,_RED_("unknown")" save path......"); strcpy (tempStr,_RED_("unknown")" save path......");
} }
if ((session.defaultPaths[pathIndex] == NULL) || (strcmp(session.defaultPaths[pathIndex],"") == 0)) if ((session.defaultPaths[pathIndex] == NULL) || (strcmp(session.defaultPaths[pathIndex],"") == 0))
PrintAndLogEx(NORMAL, " %s %s "_WHITE_("not set"), prefShowMsg(Opt),tempStr); PrintAndLogEx(INFO, " %s %s "_WHITE_("not set"), prefShowMsg(opt),tempStr);
else else
PrintAndLogEx(NORMAL, " %s %s "_GREEN_("%s"), prefShowMsg(Opt), tempStr, session.defaultPaths[pathIndex]); PrintAndLogEx(INFO, " %s %s "_GREEN_("%s"), prefShowMsg(opt), tempStr, session.defaultPaths[pathIndex]);
} }
static void showPlotPosState(void) { static void showPlotPosState(void) {
PrintAndLogEx(NORMAL, " Plot window............ X "_GREEN_("%4d")" Y "_GREEN_("%4d")" H "_GREEN_("%4d")" W "_GREEN_("%4d"), PrintAndLogEx(INFO, " Plot window............ X "_GREEN_("%4d")" Y "_GREEN_("%4d")" H "_GREEN_("%4d")" W "_GREEN_("%4d"),
session.plot.x, session.plot.y, session.plot.h, session.plot.w); session.plot.x, session.plot.y, session.plot.h, session.plot.w);
} }
static void showOverlayPosState(void) { static void showOverlayPosState(void) {
PrintAndLogEx(NORMAL, " Slider/Overlay window.. X "_GREEN_("%4d")" Y "_GREEN_("%4d")" H "_GREEN_("%4d")" W "_GREEN_("%4d"), PrintAndLogEx(INFO, " Slider/Overlay window.. X "_GREEN_("%4d")" Y "_GREEN_("%4d")" H "_GREEN_("%4d")" W "_GREEN_("%4d"),
session.overlay.x, session.overlay.y, session.overlay.h, session.overlay.w); session.overlay.x, session.overlay.y, session.overlay.h, session.overlay.w);
} }
*/ */
static void showHintsState(prefShowOpt_t Opt) { static void showHintsState(prefShowOpt_t opt) {
if (session.show_hints) if (session.show_hints)
PrintAndLogEx(NORMAL, " %s hints.................. "_GREEN_("on"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s hints.................. "_GREEN_("on"), prefShowMsg(opt));
else else
PrintAndLogEx(NORMAL, " %s hints.................. "_WHITE_("off"), prefShowMsg(Opt)); PrintAndLogEx(INFO, " %s hints.................. "_WHITE_("off"), prefShowMsg(opt));
} }
static int setCmdEmoji(const char *Cmd) { static int setCmdEmoji(const char *Cmd) {
uint8_t cmdp = 0; uint8_t cmdp = 0;
bool errors = false; bool errors = false;
@ -909,13 +909,14 @@ static int CmdPrefShow(const char *Cmd) {
if (session.preferences_loaded) { if (session.preferences_loaded) {
char *fn = prefGetFilename(); char *fn = prefGetFilename();
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, _CYAN_("Preferences loaded from " _YELLOW_("%s")), fn); PrintAndLogEx(INFO, "Using "_YELLOW_("%s"), fn);
free(fn); free(fn);
} else { } else {
PrintAndLogEx(ERR, "Preferences not loaded"); PrintAndLogEx(ERR, "Preferences not loaded");
return PM3_ESOFT; return PM3_ESOFT;
} }
PrintAndLogEx(INFO, "Current settings");
showEmojiState(prefShowNone); showEmojiState(prefShowNone);
showHintsState(prefShowNone); showHintsState(prefShowNone);
showColorState(prefShowNone); showColorState(prefShowNone);
@ -927,6 +928,7 @@ static int CmdPrefShow(const char *Cmd) {
showClientDebugState(prefShowNone); showClientDebugState(prefShowNone);
// showDeviceDebugState(prefShowNone); // showDeviceDebugState(prefShowNone);
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS; return PM3_SUCCESS;
} }
/* /*

View file

@ -18,8 +18,10 @@
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
#include <readline/readline.h> #include <readline/readline.h>
#include <readline/history.h> #include <readline/history.h>
#include <signal.h>
#endif #endif
#include <ctype.h> #include <ctype.h>
#include "usart_defs.h" #include "usart_defs.h"
#include "util_posix.h" #include "util_posix.h"
#include "proxgui.h" #include "proxgui.h"
@ -134,6 +136,37 @@ static int check_comm(void) {
} }
return 0; return 0;
} }
static void flush_history(void) {
#ifdef HAVE_READLINE
if (session.history_path) {
write_history(session.history_path);
free(session.history_path);
}
#endif
}
#ifdef HAVE_READLINE
# if defined(_WIN32)
/*
static bool WINAPI terminate_handler(DWORD t) {
if (t == CTRL_C_EVENT) {
flush_history();
return true;
}
return false;
}
*/
# else
struct sigaction old_action;
static void terminate_handler(int signum) {
sigaction(SIGINT, &old_action, NULL);
flush_history();
kill(0, SIGINT);
}
#endif
#endif
// first slot is always NULL, indicating absence of script when idx=0 // first slot is always NULL, indicating absence of script when idx=0
static FILE *cmdscriptfile[MAX_NESTED_CMDSCRIPT + 1] = {0}; static FILE *cmdscriptfile[MAX_NESTED_CMDSCRIPT + 1] = {0};
@ -211,16 +244,29 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) {
} }
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
char *my_history_path = NULL; session.history_path = NULL;
if (searchHomeFilePath(&my_history_path, NULL, PROXHISTORY, true) != PM3_SUCCESS) { if (searchHomeFilePath(&session.history_path, NULL, PROXHISTORY, true) != PM3_SUCCESS) {
PrintAndLogEx(ERR, "No history will be recorded"); PrintAndLogEx(ERR, "No history will be recorded");
my_history_path = NULL; session.history_path = NULL;
} else { } else {
read_history(my_history_path);
# if defined(_WIN32)
// SetConsoleCtrlHandler((PHANDLER_ROUTINE)terminate_handler, true);
# else
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_handler = &terminate_handler;
sigaction(SIGINT, &action, &old_action);
# endif
rl_catch_signals = 1;
rl_set_signals();
read_history(session.history_path);
} }
#endif #endif
// loops every time enter is pressed... // loops every time enter is pressed...
while (1) { while (1) {
bool printprompt = false; bool printprompt = false;
if (session.pm3_present) { if (session.pm3_present) {
if (conn.send_via_fpc_usart == false) if (conn.send_via_fpc_usart == false)
@ -391,11 +437,9 @@ check_script:
pop_cmdscriptfile(); pop_cmdscriptfile();
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
if (my_history_path) { flush_history();
write_history(my_history_path);
free(my_history_path);
}
#endif #endif
if (cmd) { if (cmd) {
free(cmd); free(cmd);
cmd = NULL; cmd = NULL;
@ -1027,7 +1071,7 @@ int main(int argc, char *argv[]) {
#ifdef HAVE_GUI #ifdef HAVE_GUI
# ifdef _WIN32 # if defined(_WIN32)
InitGraphics(argc, argv, script_cmds_file, script_cmd, stayInCommandLoop); InitGraphics(argc, argv, script_cmds_file, script_cmd, stayInCommandLoop);
MainGraphics(); MainGraphics();
# else # else

View file

@ -43,6 +43,7 @@ typedef struct {
// char *defaultPaths[spItemCount]; // Array should allow loop searching for files // char *defaultPaths[spItemCount]; // Array should allow loop searching for files
clientdebugLevel_t client_debug_level; clientdebugLevel_t client_debug_level;
// uint8_t device_debug_level; // uint8_t device_debug_level;
char *history_path;
} session_arg_t; } session_arg_t;
extern session_arg_t session; extern session_arg_t session;