diff --git a/client/src/cmddata.c b/client/src/cmddata.c index b1f43244b..3765c2ded 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -1276,8 +1276,7 @@ int PSKDemod(const char *Cmd, bool verbose) { return PM3_SUCCESS; } -static int CmdIdteckDemod(const char *Cmd) { - (void)Cmd; // Cmd is not used so far +int demodIdteck(void) { if (PSKDemod("", false) != PM3_SUCCESS) { PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck PSKDemod failed"); @@ -1337,10 +1336,12 @@ static int CmdIdteckDemod(const char *Cmd) { 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 // takes 3 arguments - clock, invert, maxErr as integers @@ -1710,6 +1711,7 @@ int CmdTuneSamples(const char *Cmd) { } PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "---------- " _CYAN_("LF Antenna") " ----------"); // in mVolt struct p { uint32_t v_lf134; @@ -1746,8 +1748,9 @@ int CmdTuneSamples(const char *Cmd) { else 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 if (package->v_hf > NON_VOLTAGE) 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 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 // even here, these values has 3% error. diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index 0aa6bfd9b..c8ab85b14 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -1693,7 +1693,7 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { uint8_t key[6] = {0, 0, 0, 0, 0, 0}; uint8_t trgkey[6] = {0, 0, 0, 0, 0, 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 ctmp; @@ -1706,19 +1706,21 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { switch (tolower(param_getchar(Cmd, cmdp))) { case 'h': return usage_hf14_hardnested(); - case 'r': - fptr = GenerateFilename("hf-mf-", "-nonces.bin"); + case 'r': { + char *fptr = GenerateFilename("hf-mf-", "-nonces.bin"); if (fptr == NULL) strncpy(filename, "nonces.bin", FILE_PATH_SIZE - 1); else strncpy(filename, fptr, FILE_PATH_SIZE - 1); + free(fptr); nonce_file_read = true; if (!param_gethex(Cmd, cmdp + 1, trgkey, 12)) { know_target_key = true; } cmdp++; break; + } case 't': tests = param_get32ex(Cmd, cmdp + 1, 100, 10); if (!param_gethex(Cmd, cmdp + 2, trgkey, 12)) { @@ -1729,9 +1731,9 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { default: if (param_getchar(Cmd, cmdp) == 0x00) { PrintAndLogEx(WARNING, "Block number is missing"); - return 1; - + return usage_hf14_hardnested(); } + blockNo = param_get8(Cmd, cmdp); ctmp = tolower(param_getchar(Cmd, cmdp + 1)); if (ctmp != 'a' && ctmp != 'b') { @@ -1775,13 +1777,15 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { case 's': slow = true; break; - case 'w': + case 'w': { nonce_file_write = true; - fptr = GenerateFilename("hf-mf-", "-nonces.bin"); + char *fptr = GenerateFilename("hf-mf-", "-nonces.bin"); if (fptr == NULL) return 1; strncpy(filename, fptr, FILE_PATH_SIZE - 1); + free(fptr); break; + } case 'u': param_getstr(Cmd, cmdp + 1, szTemp, FILE_PATH_SIZE - 20); 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 if (detect_classic_static_nonce() == 1) { 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; } @@ -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, trgKeyType ? 'B' : 'A', 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", slow ? "Yes" : "No", tests); @@ -1861,7 +1867,9 @@ static int CmdHF14AMfNestedHard(const char *Cmd) { 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); - if (tests == 0) DropField(); + if (tests == 0) + DropField(); + if (isOK) { switch (isOK) { case 1 : diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index 2adbeae75..fe69d1909 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -30,10 +30,14 @@ #include "mifare/desfire_crypto.h" #include "crapto1/crapto1.h" #include "fileutils.h" +#include "mifare/mifaredefault.h" // default keys +#include "mifare/ndef.h" // NDEF #define MAX_KEY_LEN 24 #define MAX_KEYS_LIST_LEN 1024 +#define status(x) ( ((uint16_t)(0x91<<8)) + (uint16_t)x ) + struct desfire_key default_key = {0}; uint8_t desdefaultkeys[3][8] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //Official @@ -113,8 +117,6 @@ typedef enum { MFDES_VALUE_FILE } MFDES_FILE_TYPE_T; -#define status(x) ( ((uint16_t)(0x91<<8)) + (uint16_t)x ) - // NXP Appnote AN10787 - Application Directory (MAD) typedef enum { CL_ADMIN = 0, @@ -389,7 +391,6 @@ static char *getVersionStr(uint8_t major, uint8_t minor) { 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) { *result_len = 0; @@ -956,7 +957,6 @@ static void AuthToError(int error) { } } - // -- test if card supports 0x0A static int test_desfire_authenticate(void) { 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) { 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; uint32_t recv_len = 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; } - uint32_t cmdcnt = 0; + size_t cmdcnt = 0; memcpy(data + cmdcnt + 1, new_key, new_key_length); 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 static int handler_desfire_dfnames(dfname_t *dest, uint8_t *dfname_count) { - *dfname_count = 0; + if (g_debugMode > 1) { - if (dest == NULL) PrintAndLogEx(ERR, "DEST=NULL"); - if (dfname_count == NULL) PrintAndLogEx(ERR, "DFNAME_COUNT=NULL"); + if (dest == NULL) PrintAndLogEx(ERR, "DEST = 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; - sAPDU apdu = {0x90, MFDES_GET_DF_NAMES, 0x00, 0x00, 0x00, NULL}; //0x6d uint32_t recv_len = 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; } - 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 uint16_t sw = 0; *resplen = 0; @@ -1735,7 +1738,6 @@ static int handler_desfire_writedata(mfdes_data_t *data, MFDES_FILE_TYPE_T type, return res; } - static int handler_desfire_deletefile(uint8_t fileno) { if (fileno > 0x1F) return PM3_EINVARG; sAPDU apdu = {0x90, MFDES_DELETE_FILE, 0x00, 0x00, 1, &fileno}; // 0xDF @@ -2096,7 +2098,6 @@ static int CmdHF14ADesSelectApp(const char *Cmd) { return res; } - static int CmdHF14ADesCreateApp(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes createaid", @@ -2290,7 +2291,6 @@ static int selectfile(uint8_t *aid, uint32_t fileno, uint8_t *cs) { return res; } - static int CmdHF14ADesClearRecordFile(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes clearrecord", @@ -2442,7 +2442,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) { int fidlength = 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); int arlength = 0; @@ -2487,7 +2487,7 @@ static int CmdHF14ADesCreateFile(const char *Cmd) { return PM3_EINVARG; } - if (fidlength != 2) { + if (res_flen || fidlength != 2) { PrintAndLogEx(ERR, "ISO File id must have 2 hex bytes length."); return PM3_EINVARG; } @@ -2633,11 +2633,11 @@ static int CmdHF14ADesReadData(const char *Cmd) { int offsetlength = 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; 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); @@ -2652,7 +2652,7 @@ static int CmdHF14ADesReadData(const char *Cmd) { return PM3_EINVARG; } - if (offsetlength != 3 && offsetlength != 0) { + if (res_offset || (offsetlength != 3 && offsetlength != 0)) { PrintAndLogEx(ERR, "Offset needs 3 hex bytes"); return PM3_EINVARG; } @@ -2667,6 +2667,11 @@ static int CmdHF14ADesReadData(const char *Cmd) { return PM3_EINVARG; } + if (res_flen) { + PrintAndLogEx(ERR, "File size input error"); + return PM3_EINVARG; + } + swap24(filesize); swap24(offset); @@ -2750,7 +2755,7 @@ static int CmdHF14ADesChangeValue(const char *Cmd) { value.fileno = _fileno[0]; 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 aidlength = 3; @@ -2765,7 +2770,7 @@ static int CmdHF14ADesChangeValue(const char *Cmd) { return PM3_EINVARG; } - if (vlength != 4) { + if (res_val || vlength != 4) { PrintAndLogEx(ERR, "Value needs 4 hex bytes."); return PM3_EINVARG; } @@ -2820,7 +2825,6 @@ static int CmdHF14ADesChangeValue(const char *Cmd) { return res; } - static int CmdHF14ADesWriteData(const char *Cmd) { CLIParserContext *ctx; @@ -2849,16 +2853,14 @@ static int CmdHF14ADesWriteData(const char *Cmd) { int offsetlength = 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; - uint8_t *data = (uint8_t *)calloc(dlength, sizeof(uint8_t)); - if (data == NULL) { - PrintAndLogEx(ERR, "failed to allocate memory"); - CLIParserFree(ctx); - return PM3_EMALLOC; - } - CLIParamHexToBuf(arg_get_str(ctx, 3), data, 0xFFFF, &dlength); + // iceman: we only have a 1024 byte commandline input array. So this is pointlessly large. + // with 2char hex, 512bytes could be input. + // Instead large binary inputs should be BINARY files and written to card. + int dlength = 512; + uint8_t data[512] = {0}; + int res_data = CLIParamHexToBuf(arg_get_str(ctx, 3), data, 512, &dlength); int type = arg_get_int(ctx, 4); int aidlength = 3; @@ -2872,31 +2874,26 @@ static int CmdHF14ADesWriteData(const char *Cmd) { if (type < 0 || type > 1) { PrintAndLogEx(ERR, "Unknown type (0=Standard/Backup, 1=Record)"); - if (data) free(data); return PM3_EINVARG; } - if (dlength == 0) { + if (res_data || dlength == 0) { PrintAndLogEx(ERR, "Data needs some hex bytes to write"); - if (data) free(data); return PM3_EINVARG; } - if (offsetlength != 3 && offsetlength != 0) { + if (res_offset || (offsetlength != 3 && offsetlength != 0)) { PrintAndLogEx(ERR, "Offset needs 3 hex bytes"); - if (data) free(data); return PM3_EINVARG; } if (filenolen != 1) { PrintAndLogEx(ERR, "File number is missing"); - if (data) free(data); return PM3_EINVARG; } if (_fileno[0] > 0x1F) { PrintAndLogEx(ERR, "File number range is invalid (0x00-0x1F)"); - if (data) free(data); return PM3_EINVARG; } @@ -2919,25 +2916,22 @@ static int CmdHF14ADesWriteData(const char *Cmd) { uint8_t cs = 0; if (selectfile(aid, _fileno[0], &cs) != PM3_SUCCESS) { PrintAndLogEx(ERR, _RED_(" Error on selecting file.")); + DropField(); return PM3_ESOFT; } int res = PM3_ESOFT; - if (data != NULL) { - ft.data = data; - res = handler_desfire_writedata(&ft, type, cs); - if (res == PM3_SUCCESS) { - PrintAndLogEx(SUCCESS, "Successfully wrote data"); - } else { - PrintAndLogEx(ERR, "Couldn't read data. Error %d", res); - } - free(data); + ft.data = data; + res = handler_desfire_writedata(&ft, type, cs); + if (res == PM3_SUCCESS) { + PrintAndLogEx(SUCCESS, "Successfully wrote data"); + } else { + PrintAndLogEx(ERR, "Couldn't read data. Error %d", res); } DropField(); return res; } - static int CmdHF14ADesCreateRecordFile(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf mfdes createrecordfile", @@ -2967,7 +2961,7 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) { int fidlength = 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); int arlength = 0; @@ -3028,7 +3022,7 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) { return PM3_EINVARG; } - if (fidlength != 2) { + if (res_flen || fidlength != 2) { PrintAndLogEx(ERR, "ISO File id must have 2 hex bytes length."); return PM3_EINVARG; } @@ -3214,24 +3208,20 @@ static int CmdHF14ADesFormatPICC(const char *Cmd) { "\n\thf mfdes formatpicc\n" "Make sure to authenticate picc before running this command.\n" ); - + CLIParserFree(ctx); sAPDU apdu = {0x90, MFDES_FORMAT_PICC, 0x00, 0x00, 0, NULL}; // 0xDF uint16_t sw = 0; uint32_t recvlen = 0; int res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true); if (res != PM3_SUCCESS) { PrintAndLogEx(WARNING, _RED_(" Can't format picc -> %s"), GetErrorString(res, &sw)); - DropField(); - return res; } else { PrintAndLogEx(INFO, "Card successfully reset"); - return PM3_SUCCESS; } DropField(); - return PM3_SUCCESS; + return res; } - static int CmdHF14ADesInfo(const char *Cmd) { (void)Cmd; // Cmd is not used so far DropField(); @@ -3370,7 +3360,6 @@ static int CmdHF14ADesInfo(const char *Cmd) { return PM3_SUCCESS; } - static void DecodeFileType(uint8_t filetype) { switch (filetype) { case 0x00: @@ -3777,11 +3766,13 @@ static int CmdHF14ADesChangeKey(const char *Cmd) { uint8_t cmdAuthAlgo = arg_get_int_def(ctx, 2, 0); uint8_t key[24] = {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 newkey[24] = {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); CLIParserFree(ctx); @@ -3805,12 +3796,12 @@ static int CmdHF14ADesChangeKey(const char *Cmd) { newkeylength = 24; } - if ((keylen < 8) || (keylen > 24)) { + if (res_klen || (keylen < 8) || (keylen > 24)) { PrintAndLogEx(ERR, "Specified key must have %d bytes length.", keylen); 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); return PM3_EINVARG; } @@ -4470,6 +4461,107 @@ static int CmdHF14ADesList(const char *Cmd) { 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", "", "replace default aid for NDEF"), + arg_str0("kK", "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) { (void)Cmd; // Cmd is not used so far uint8_t IV[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -4495,29 +4587,29 @@ static int CmdHF14ADesList(const char *Cmd) { */ static command_t CommandTable[] = { - {"help", CmdHelp, AlwaysAvailable, "This help"}, - //{"test", CmdTest, AlwaysAvailable, "Test"}, - {"info", CmdHF14ADesInfo, IfPm3Iso14443a, "Tag information"}, - {"list", CmdHF14ADesList, AlwaysAvailable, "List DESFire (ISO 14443A) history"}, - {"enum", CmdHF14ADesEnumApplications, IfPm3Iso14443a, "Tries enumerate all applications"}, - {"auth", CmdHF14ADesAuth, IfPm3Iso14443a, "Tries a MIFARE DesFire Authentication"}, - {"getuid", CmdHF14ADesGetUID, IfPm3Iso14443a, "Get random uid"}, - {"selectaid", CmdHF14ADesSelectApp, IfPm3Iso14443a, "Select Application ID"}, - {"createaid", CmdHF14ADesCreateApp, IfPm3Iso14443a, "Create Application ID"}, - {"deleteaid", CmdHF14ADesDeleteApp, IfPm3Iso14443a, "Delete Application ID"}, - {"createfile", CmdHF14ADesCreateFile, IfPm3Iso14443a, "Create Standard/Backup File"}, - {"createvaluefile", CmdHF14ADesCreateValueFile, IfPm3Iso14443a, "Create Value File"}, - {"createrecordfile", CmdHF14ADesCreateRecordFile, IfPm3Iso14443a, "Create Linear/Cyclic Record File"}, - {"deletefile", CmdHF14ADesDeleteFile, IfPm3Iso14443a, "Create Delete File"}, - {"clearfile", CmdHF14ADesClearRecordFile, IfPm3Iso14443a, "Clear record File"}, - {"readdata", CmdHF14ADesReadData, IfPm3Iso14443a, "Read data from standard/backup/record file"}, - {"writedata", CmdHF14ADesWriteData, IfPm3Iso14443a, "Write data to standard/backup/record file"}, - {"getvalue", CmdHF14ADesGetValueData, IfPm3Iso14443a, "Get value of file"}, - {"changevalue", CmdHF14ADesChangeValue, IfPm3Iso14443a, "Write value of a value file (credit/debit/clear)"}, - {"changekey", CmdHF14ADesChangeKey, IfPm3Iso14443a, "Change Key"}, - {"formatpicc", CmdHF14ADesFormatPICC, IfPm3Iso14443a, "Format PICC"}, - {"dump", CmdHF14ADesDump, IfPm3Iso14443a, "Dump all files"}, - {"chk", CmdHF14aDesChk, IfPm3Iso14443a, "Check keys"}, + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"info", CmdHF14ADesInfo, IfPm3Iso14443a, "Tag information"}, + {"list", CmdHF14ADesList, AlwaysAvailable, "List DESFire (ISO 14443A) history"}, + {"enum", CmdHF14ADesEnumApplications, IfPm3Iso14443a, "Tries enumerate all applications"}, + {"auth", CmdHF14ADesAuth, IfPm3Iso14443a, "Tries a MIFARE DesFire Authentication"}, + {"getuid", CmdHF14ADesGetUID, IfPm3Iso14443a, "Get random uid"}, + {"selectaid", CmdHF14ADesSelectApp, IfPm3Iso14443a, "Select Application ID"}, + {"createaid", CmdHF14ADesCreateApp, IfPm3Iso14443a, "Create Application ID"}, + {"deleteaid", CmdHF14ADesDeleteApp, IfPm3Iso14443a, "Delete Application ID"}, + {"createfile", CmdHF14ADesCreateFile, IfPm3Iso14443a, "Create Standard/Backup File"}, + {"createvaluefile", CmdHF14ADesCreateValueFile, IfPm3Iso14443a, "Create Value File"}, + {"createrecordfile", CmdHF14ADesCreateRecordFile, IfPm3Iso14443a, "Create Linear/Cyclic Record File"}, + {"deletefile", CmdHF14ADesDeleteFile, IfPm3Iso14443a, "Create Delete File"}, + {"clearfile", CmdHF14ADesClearRecordFile, IfPm3Iso14443a, "Clear record File"}, + {"readdata", CmdHF14ADesReadData, IfPm3Iso14443a, "Read data from standard/backup/record file"}, + {"writedata", CmdHF14ADesWriteData, IfPm3Iso14443a, "Write data to standard/backup/record file"}, + {"getvalue", CmdHF14ADesGetValueData, IfPm3Iso14443a, "Get value of file"}, + {"changevalue", CmdHF14ADesChangeValue, IfPm3Iso14443a, "Write value of a value file (credit/debit/clear)"}, + {"changekey", CmdHF14ADesChangeKey, IfPm3Iso14443a, "Change Key"}, + {"formatpicc", CmdHF14ADesFormatPICC, IfPm3Iso14443a, "Format PICC"}, + {"dump", CmdHF14ADesDump, IfPm3Iso14443a, "Dump all files"}, + {"chk", CmdHF14aDesChk, IfPm3Iso14443a, "Check keys"}, +// {"ndef", CmdHF14aDesNDEF, IfPm3Iso14443a, "Prints NDEF records from card"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/src/cmdhfmfp.c b/client/src/cmdhfmfp.c index a3c9d195c..1e1f7aeef 100644 --- a/client/src/cmdhfmfp.c +++ b/client/src/cmdhfmfp.c @@ -1429,9 +1429,9 @@ static int CmdHFMFPNDEF(const char *Cmd) { CLIParserInit(&ctx, "hf mfp ndef", "Prints NFC Data Exchange Format (NDEF)", "Usage:\n" - "\thf mfp ndef -> shows NDEF data\n" - "\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") " -> shows NDEF data\n" + _YELLOW_("\thf mfp ndef -vv") " -> shows NDEF parsed and raw data\n" + _YELLOW_("\thf mfp ndef -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7") " -> shows NDEF data with custom AID and key\n"); void *argtable[] = { arg_param_begin, @@ -1530,12 +1530,12 @@ static int CmdHFMFPNDEF(const char *Cmd) { if (verbose2) { PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, "--- " _CYAN_("MFC NDEF raw") " ----------------"); + PrintAndLogEx(INFO, "--- " _CYAN_("MF Plus NDEF raw") " ----------------"); dump_buffer(data, datalen, stdout, 1); } 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; } diff --git a/client/src/cmdlfem4x.c b/client/src/cmdlfem4x.c index 27de68519..8fbb0e509 100644 --- a/client/src/cmdlfem4x.c +++ b/client/src/cmdlfem4x.c @@ -624,8 +624,8 @@ static int CmdEM410xWrite(const char *Cmd) { // Allowed clock rates: 16, 32, 40 and 64 if ((clock1 != 16) && (clock1 != 32) && (clock1 != 64) && (clock1 != 40)) { - PrintAndLogEx(ERR, "error, clock rate" _RED_("%d")" not valid"); - PrintAndLogEx(INFO, "supported clock rates: " _YELLOW_("16, 32, 40, 60") "\n", clock1); + PrintAndLogEx(FAILED, "error, clock rate" _RED_("%d")" not valid", clock1); + PrintAndLogEx(INFO, "supported clock rates: " _YELLOW_("16, 32, 40, 60") "\n"); usage_lf_em410x_write(); return PM3_EINVARG; } diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index 20db97a14..62d8c143f 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -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 @@ -265,7 +265,7 @@ static void print_info_result(PacketResponseNG *resp, const em4x50_data_t *etd, // data section PrintAndLogEx(NORMAL, _YELLOW_("\n em4x50 data:")); - if (bverbose) { + if (verbose) { // detailed data section 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; uint8_t *data = resp->data.asBytes; 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); 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; char string[NO_CHARS_MAX] = {0}, pstring[NO_CHARS_MAX] = {0}; uint8_t *data = resp->data.asBytes; - em4x50_word_t word; + em4x50_word_t words[EM4X50_NO_WORDS]; if (addr_given) { @@ -666,7 +666,7 @@ static void print_read_result(PacketResponseNG *resp, const em4x50_data_t *etd, string[0] = '\0'; sprintf(pstring, "\n reading " _GREEN_("ok ")); strcat(string, pstring); - + if (pwd_given) { if (login) { sprintf(pstring, "(login with password 0x%02x%02x%02x%02x)", diff --git a/client/src/cmdlfio.c b/client/src/cmdlfio.c index e9a0b25ae..421ed6927 100644 --- a/client/src/cmdlfio.c +++ b/client/src/cmdlfio.c @@ -169,7 +169,7 @@ static int CmdIOProxDemod(const char *Cmd) { calccrc &= 0xff; calccrc = 0xff - calccrc; - char crc_str[30] = {0}; + char crc_str[36] = {0}; if (crc == calccrc) { snprintf(crc_str, sizeof(crc_str), "(" _GREEN_("ok") ")" ); diff --git a/client/src/cmdlfmotorola.c b/client/src/cmdlfmotorola.c index 36777be02..16d1d8dc5 100644 --- a/client/src/cmdlfmotorola.c +++ b/client/src/cmdlfmotorola.c @@ -119,8 +119,8 @@ int demodMotorola(void) { 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(DEBUG, "checksum: " _GREEN_("%1d%1d"), fc, csn, checksum >> 1 & 0x01, checksum & 0x01); + 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"), checksum >> 1 & 0x01, checksum & 0x01); return PM3_SUCCESS; } diff --git a/client/src/mifare/desfire_crypto.c b/client/src/mifare/desfire_crypto.c index 7260f4731..9eca32e44 100644 --- a/client/src/mifare/desfire_crypto.c +++ b/client/src/mifare/desfire_crypto.c @@ -389,7 +389,7 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, return data; switch (communication_settings & MDCM_MASK) { - case MDCM_PLAIN: + case MDCM_PLAIN: { if (AS_LEGACY == DESFIRE(tag)->authentication_scheme) break; @@ -404,9 +404,9 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, */ append_mac = false; - + } /* pass through */ - case MDCM_MACED: + case MDCM_MACED: { communication_settings |= NO_CRC; switch (DESFIRE(tag)->authentication_scheme) { @@ -455,7 +455,8 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, } break; - case MDCM_ENCIPHERED: + } + case MDCM_ENCIPHERED: { /* |<-------------- data -------------->| * |<--- offset -->| | * +---------------+--------------------+-----+---------+ @@ -473,21 +474,25 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, if (!(communication_settings & ENC_COMMAND)) break; + edl = enciphered_data_length(tag, *nbytes - offset, communication_settings) + offset; // Fill in the crypto buffer with data ... memcpy(res, data, *nbytes); + if (!(communication_settings & NO_CRC)) { // ... CRC ... switch (DESFIRE(tag)->authentication_scheme) { - case AS_LEGACY: + case AS_LEGACY: { AddCrc14A(res + offset, *nbytes - offset); *nbytes += 2; break; - case AS_NEW: + } + case AS_NEW: { crc32_append(res, *nbytes); *nbytes += 4; break; + } } } // ... and padding @@ -497,11 +502,12 @@ 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); break; - default: - + } + default: { *nbytes = -1; res = NULL; break; + } } return res; diff --git a/client/src/mifare/mad.c b/client/src/mifare/mad.c index badc4b813..1fe3cfb02 100644 --- a/client/src/mifare/mad.c +++ b/client/src/mifare/mad.c @@ -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 *provider = mad_json_get_str(elm, "service_provider"); const char *integrator = mad_json_get_str(elm, "system_integrator"); - char result[4 + strlen(application) + strlen(company)]; - sprintf(result, " %s [%s]", application, company); - PrintAndLogEx(INFO, fmt, result); + + if (application && company) { + char result[4 + strlen(application) + strlen(company)]; + sprintf(result, " %s [%s]", application, company); + PrintAndLogEx(INFO, fmt, result); + } + if (verbose) { PrintAndLogEx(SUCCESS, " MAD: %s", vmad); if (application) diff --git a/client/src/preferences.c b/client/src/preferences.c index 8ddd0f150..02e0b80cb 100644 --- a/client/src/preferences.c +++ b/client/src/preferences.c @@ -86,7 +86,6 @@ int preferences_load(void) { // to better control json cant find file error msg. char *fn = prefGetFilename(); if (fileExists(fn)) { - PrintAndLogEx(INFO, "Loading preferences..."); if (loadFileJSON(fn, &dummyData, sizeof(dummyData), &dummyDL, &preferences_load_callback) == PM3_SUCCESS) { session.preferences_loaded = true; } @@ -384,75 +383,75 @@ static const char *prefShowMsg(prefShowOpt_t Opt) { return ""; } -static void showEmojiState(prefShowOpt_t Opt) { +static void showEmojiState(prefShowOpt_t opt) { switch (session.emoji_mode) { case ALIAS: - PrintAndLogEx(NORMAL, " %s emoji.................. "_GREEN_("alias"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s emoji.................. "_GREEN_("alias"), prefShowMsg(opt)); break; case EMOJI: - PrintAndLogEx(NORMAL, " %s emoji.................. "_GREEN_("emoji"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s emoji.................. "_GREEN_("emoji"), prefShowMsg(opt)); break; case ALTTEXT: - PrintAndLogEx(NORMAL, " %s emoji.................. "_GREEN_("alttext"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s emoji.................. "_GREEN_("alttext"), prefShowMsg(opt)); break; case ERASE: - PrintAndLogEx(NORMAL, " %s emoji.................. "_GREEN_("erase"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s emoji.................. "_GREEN_("erase"), prefShowMsg(opt)); break; 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) - PrintAndLogEx(NORMAL, " %s color.................. "_GREEN_("ansi"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s color.................. "_GREEN_("ansi"), prefShowMsg(opt)); 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) { case cdbOFF: - PrintAndLogEx(NORMAL, " %s client debug........... "_WHITE_("off"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s client debug........... "_WHITE_("off"), prefShowMsg(opt)); break; case cdbSIMPLE: - PrintAndLogEx(NORMAL, " %s client debug........... "_GREEN_("simple"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s client debug........... "_GREEN_("simple"), prefShowMsg(opt)); break; case cdbFULL: - PrintAndLogEx(NORMAL, " %s client debug........... "_GREEN_("full"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s client debug........... "_GREEN_("full"), prefShowMsg(opt)); break; 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) { case ddbOFF: - PrintAndLogEx(NORMAL, " %s device debug........... "_WHITE_("off"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s device debug........... "_WHITE_("off"), prefShowMsg(opt)); break; case ddbERROR: - PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("error"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("error"), prefShowMsg(opt)); break; case ddbINFO: - PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("info"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("info"), prefShowMsg(opt)); break; case ddbDEBUG: - PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("debug"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("debug"), prefShowMsg(opt)); break; case ddbEXTENDED: - PrintAndLogEx(NORMAL, " %s device debug........... "_GREEN_("extended"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s device debug........... "_GREEN_("extended"), prefShowMsg(opt)); break; 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]; @@ -470,29 +469,30 @@ static void showSavePathState(savePaths_t pathIndex, prefShowOpt_t Opt) { strcpy (tempStr,_RED_("unknown")" save path......"); } 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 - 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) { - 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); } 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); } */ -static void showHintsState(prefShowOpt_t Opt) { +static void showHintsState(prefShowOpt_t opt) { if (session.show_hints) - PrintAndLogEx(NORMAL, " %s hints.................. "_GREEN_("on"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s hints.................. "_GREEN_("on"), prefShowMsg(opt)); else - PrintAndLogEx(NORMAL, " %s hints.................. "_WHITE_("off"), prefShowMsg(Opt)); + PrintAndLogEx(INFO, " %s hints.................. "_WHITE_("off"), prefShowMsg(opt)); } + static int setCmdEmoji(const char *Cmd) { uint8_t cmdp = 0; bool errors = false; @@ -909,13 +909,14 @@ static int CmdPrefShow(const char *Cmd) { if (session.preferences_loaded) { char *fn = prefGetFilename(); PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(INFO, _CYAN_("Preferences loaded from " _YELLOW_("%s")), fn); + PrintAndLogEx(INFO, "Using "_YELLOW_("%s"), fn); free(fn); } else { PrintAndLogEx(ERR, "Preferences not loaded"); return PM3_ESOFT; } + PrintAndLogEx(INFO, "Current settings"); showEmojiState(prefShowNone); showHintsState(prefShowNone); showColorState(prefShowNone); @@ -927,6 +928,7 @@ static int CmdPrefShow(const char *Cmd) { showClientDebugState(prefShowNone); // showDeviceDebugState(prefShowNone); + PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } /* diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 50d7d660b..1bf08f1d3 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -18,8 +18,10 @@ #ifdef HAVE_READLINE #include #include +#include #endif #include + #include "usart_defs.h" #include "util_posix.h" #include "proxgui.h" @@ -134,6 +136,37 @@ static int check_comm(void) { } 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 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 - char *my_history_path = NULL; - if (searchHomeFilePath(&my_history_path, NULL, PROXHISTORY, true) != PM3_SUCCESS) { + session.history_path = NULL; + if (searchHomeFilePath(&session.history_path, NULL, PROXHISTORY, true) != PM3_SUCCESS) { PrintAndLogEx(ERR, "No history will be recorded"); - my_history_path = NULL; + session.history_path = NULL; } 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 + // loops every time enter is pressed... while (1) { + bool printprompt = false; if (session.pm3_present) { if (conn.send_via_fpc_usart == false) @@ -391,11 +437,9 @@ check_script: pop_cmdscriptfile(); #ifdef HAVE_READLINE - if (my_history_path) { - write_history(my_history_path); - free(my_history_path); - } + flush_history(); #endif + if (cmd) { free(cmd); cmd = NULL; @@ -1027,7 +1071,7 @@ int main(int argc, char *argv[]) { #ifdef HAVE_GUI -# ifdef _WIN32 +# if defined(_WIN32) InitGraphics(argc, argv, script_cmds_file, script_cmd, stayInCommandLoop); MainGraphics(); # else diff --git a/client/src/ui.h b/client/src/ui.h index 60064c0aa..7a5b7911d 100644 --- a/client/src/ui.h +++ b/client/src/ui.h @@ -43,6 +43,7 @@ typedef struct { // char *defaultPaths[spItemCount]; // Array should allow loop searching for files clientdebugLevel_t client_debug_level; // uint8_t device_debug_level; + char *history_path; } session_arg_t; extern session_arg_t session;