mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 22:03:42 -07:00
Merge pull request #1728 from nvx/feature/iclass_dump_view_suppress_repeated_blocks
Changed `hf iclass view` to suppress consecutive blocks with repeated contents
This commit is contained in:
commit
5512413272
5 changed files with 128 additions and 20 deletions
|
@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
- Changed `hf iclass view` and related to suppress consecutive blocks with repeated contents with a `-z` flag, or `prefs set output --dense` (@nvx)
|
||||||
- Changed `hf iclass list` to display matched keys on the CHECK command rather than the card response, and made it check for elite keys too (@nvx)
|
- Changed `hf iclass list` to display matched keys on the CHECK command rather than the card response, and made it check for elite keys too (@nvx)
|
||||||
- Fixed `hf iclass info` and `hf iclass view` key access info looking at the wrong card config bit (@nvx)
|
- Fixed `hf iclass info` and `hf iclass view` key access info looking at the wrong card config bit (@nvx)
|
||||||
- Added `hf gallagher decode` command and fix Gallagher diversification for card master key (@nvx)
|
- Added `hf gallagher decode` command and fix Gallagher diversification for card master key (@nvx)
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "proxendian.h"
|
#include "proxendian.h"
|
||||||
#include "iclass_cmd.h"
|
#include "iclass_cmd.h"
|
||||||
#include "crypto/asn1utils.h" // ASN1 decoder
|
#include "crypto/asn1utils.h" // ASN1 decoder
|
||||||
|
#include "preferences.h"
|
||||||
|
|
||||||
|
|
||||||
#define PICOPASS_BLOCK_SIZE 8
|
#define PICOPASS_BLOCK_SIZE 8
|
||||||
|
@ -1103,6 +1104,7 @@ static int CmdHFiClassEView(const char *Cmd) {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_int0("s", "size", "<256|2048>", "number of bytes to save (default 256)"),
|
arg_int0("s", "size", "<256|2048>", "number of bytes to save (default 256)"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
|
arg_lit0("z", "dense", "dense dump output style"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
@ -1110,6 +1112,7 @@ static int CmdHFiClassEView(const char *Cmd) {
|
||||||
uint16_t blocks = 32;
|
uint16_t blocks = 32;
|
||||||
uint16_t bytes = arg_get_int_def(ctx, 1, 256);
|
uint16_t bytes = arg_get_int_def(ctx, 1, 256);
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
|
bool dense_output = g_session.dense_output || arg_get_lit(ctx, 3);
|
||||||
blocks = bytes / 8;
|
blocks = bytes / 8;
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
@ -1144,7 +1147,7 @@ static int CmdHFiClassEView(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
printIclassDumpContents(dump, 1, blocks, bytes);
|
printIclassDumpContents(dump, 1, blocks, bytes, dense_output);
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printIclassSIO(dump);
|
printIclassSIO(dump);
|
||||||
|
@ -1177,6 +1180,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
arg_str0("k", "key", "<hex>", "3DES transport key"),
|
arg_str0("k", "key", "<hex>", "3DES transport key"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
arg_lit0(NULL, "d6", "decode as block 6"),
|
arg_lit0(NULL, "d6", "decode as block 6"),
|
||||||
|
arg_lit0("z", "dense", "dense dump output style"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(clictx, Cmd, argtable, false);
|
CLIExecWithReturn(clictx, Cmd, argtable, false);
|
||||||
|
@ -1200,6 +1204,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
|
|
||||||
bool verbose = arg_get_lit(clictx, 4);
|
bool verbose = arg_get_lit(clictx, 4);
|
||||||
bool use_decode6 = arg_get_lit(clictx, 5);
|
bool use_decode6 = arg_get_lit(clictx, 5);
|
||||||
|
bool dense_output = g_session.dense_output || arg_get_lit(clictx, 6);
|
||||||
CLIParserFree(clictx);
|
CLIParserFree(clictx);
|
||||||
|
|
||||||
// sanity checks
|
// sanity checks
|
||||||
|
@ -1337,7 +1342,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
|
|
||||||
pm3_save_dump(fptr, decrypted, decryptedlen, jsfIclass, PICOPASS_BLOCK_SIZE);
|
pm3_save_dump(fptr, decrypted, decryptedlen, jsfIclass, PICOPASS_BLOCK_SIZE);
|
||||||
|
|
||||||
printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen);
|
printIclassDumpContents(decrypted, 1, (decryptedlen / 8), decryptedlen, dense_output);
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printIclassSIO(decrypted);
|
printIclassSIO(decrypted);
|
||||||
|
@ -1564,6 +1569,7 @@ static int CmdHFiClassDump(const char *Cmd) {
|
||||||
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
||||||
arg_lit0(NULL, "raw", "raw, the key is interpreted as raw block 3/4"),
|
arg_lit0(NULL, "raw", "raw, the key is interpreted as raw block 3/4"),
|
||||||
arg_lit0(NULL, "nr", "replay of NR/MAC"),
|
arg_lit0(NULL, "nr", "replay of NR/MAC"),
|
||||||
|
arg_lit0("z", "dense", "dense dump output style"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
@ -1647,6 +1653,7 @@ static int CmdHFiClassDump(const char *Cmd) {
|
||||||
bool elite = arg_get_lit(ctx, 6);
|
bool elite = arg_get_lit(ctx, 6);
|
||||||
bool rawkey = arg_get_lit(ctx, 7);
|
bool rawkey = arg_get_lit(ctx, 7);
|
||||||
bool use_replay = arg_get_lit(ctx, 8);
|
bool use_replay = arg_get_lit(ctx, 8);
|
||||||
|
bool dense_output = g_session.dense_output || arg_get_lit(ctx, 9);
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
@ -1879,7 +1886,7 @@ write_dump:
|
||||||
PrintAndLogEx(INFO, "Reading AA2 failed. dumping AA1 data to file");
|
PrintAndLogEx(INFO, "Reading AA2 failed. dumping AA1 data to file");
|
||||||
|
|
||||||
// print the dump
|
// print the dump
|
||||||
printIclassDumpContents(tag_data, 1, (bytes_got / 8), bytes_got);
|
printIclassDumpContents(tag_data, 1, (bytes_got / 8), bytes_got, dense_output);
|
||||||
|
|
||||||
// use CSN as filename
|
// use CSN as filename
|
||||||
if (filename[0] == 0) {
|
if (filename[0] == 0) {
|
||||||
|
@ -2489,7 +2496,7 @@ static void printIclassSIO(uint8_t *iclass_dump) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize) {
|
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize, bool dense_output) {
|
||||||
|
|
||||||
picopass_hdr_t *hdr = (picopass_hdr_t *)iclass_dump;
|
picopass_hdr_t *hdr = (picopass_hdr_t *)iclass_dump;
|
||||||
// picopass_ns_hdr_t *ns_hdr = (picopass_ns_hdr_t *)iclass_dump;
|
// picopass_ns_hdr_t *ns_hdr = (picopass_ns_hdr_t *)iclass_dump;
|
||||||
|
@ -2550,6 +2557,7 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e
|
||||||
if (i != 1)
|
if (i != 1)
|
||||||
PrintAndLogEx(INFO, " ......");
|
PrintAndLogEx(INFO, " ......");
|
||||||
|
|
||||||
|
bool in_repeated_block = false;
|
||||||
while (i <= endblock) {
|
while (i <= endblock) {
|
||||||
uint8_t *blk = iclass_dump + (i * 8);
|
uint8_t *blk = iclass_dump + (i * 8);
|
||||||
|
|
||||||
|
@ -2591,21 +2599,17 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e
|
||||||
|
|
||||||
const char *lockstr = (bl_lock) ? _RED_("x") : " ";
|
const char *lockstr = (bl_lock) ? _RED_("x") : " ";
|
||||||
|
|
||||||
|
const char *block_info;
|
||||||
|
bool regular_print_block = false;
|
||||||
if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) {
|
if (pagemap == PICOPASS_NON_SECURE_PAGEMODE) {
|
||||||
const char *info_nonks[] = {"CSN", "Config", "AIA", "User"};
|
const char *info_nonks[] = {"CSN", "Config", "AIA", "User"};
|
||||||
const char *s = info_nonks[3];
|
|
||||||
if (i < 3) {
|
if (i < 3) {
|
||||||
s = info_nonks[i];
|
block_info = info_nonks[i];
|
||||||
|
} else {
|
||||||
|
block_info = info_nonks[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "%3d/0x%02X | %s | %s | %s "
|
regular_print_block = true;
|
||||||
, i
|
|
||||||
, i
|
|
||||||
, sprint_hex_ascii(blk, 8)
|
|
||||||
, lockstr
|
|
||||||
, s
|
|
||||||
);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const char *info_ks[] = {"CSN", "Config", "E-purse", "Debit", "Credit", "AIA", "User"};
|
const char *info_ks[] = {"CSN", "Config", "E-purse", "Debit", "Credit", "AIA", "User"};
|
||||||
|
|
||||||
|
@ -2637,13 +2641,40 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e
|
||||||
, lockstr
|
, lockstr
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const char *s = info_ks[6];
|
|
||||||
if (i < 6) {
|
if (i < 6) {
|
||||||
s = info_ks[i];
|
block_info = info_ks[i];
|
||||||
|
} else {
|
||||||
|
block_info = info_ks[6];
|
||||||
}
|
}
|
||||||
PrintAndLogEx(INFO, "%3d/0x%02X | %s | %s | %s ", i, i, sprint_hex_ascii(blk, 8), lockstr, s);
|
|
||||||
|
regular_print_block = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (regular_print_block) {
|
||||||
|
// suppress repeating blocks, truncate as such that the first and last block with the same data is shown
|
||||||
|
// but the blocks in between are replaced with a single line of "*" if dense_output is enabled
|
||||||
|
if (dense_output && i > 6 && i < (endblock - 1) && !in_repeated_block && !memcmp(blk, blk - 8, 8) &&
|
||||||
|
!memcmp(blk, blk + 8, 8) && !memcmp(blk, blk + 16, 8)) {
|
||||||
|
// we're in a user block that isn't the first user block nor last two user blocks,
|
||||||
|
// and the current block data is the same as the previous and next two block
|
||||||
|
in_repeated_block = true;
|
||||||
|
PrintAndLogEx(INFO, "*");
|
||||||
|
} else if (in_repeated_block && (memcmp(blk, blk + 8, 8) || i == endblock)) {
|
||||||
|
// in a repeating block, but the next block doesn't match anymore, or we're at the end block
|
||||||
|
in_repeated_block = false;
|
||||||
|
}
|
||||||
|
if (!in_repeated_block) {
|
||||||
|
PrintAndLogEx(INFO,
|
||||||
|
"%3d/0x%02X | %s | %s | %s ",
|
||||||
|
i,
|
||||||
|
i,
|
||||||
|
sprint_hex_ascii(blk, 8),
|
||||||
|
lockstr,
|
||||||
|
block_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
PrintAndLogEx(INFO, "---------+-------------------------+----------+---+----------------");
|
PrintAndLogEx(INFO, "---------+-------------------------+----------+---+----------------");
|
||||||
|
@ -2672,6 +2703,7 @@ static int CmdHFiClassView(const char *Cmd) {
|
||||||
arg_int0(NULL, "first", "<dec>", "Begin printing from this block (default block 6)"),
|
arg_int0(NULL, "first", "<dec>", "Begin printing from this block (default block 6)"),
|
||||||
arg_int0(NULL, "last", "<dec>", "End printing at this block (default 0, ALL)"),
|
arg_int0(NULL, "last", "<dec>", "End printing at this block (default 0, ALL)"),
|
||||||
arg_lit0("v", "verbose", "verbose output"),
|
arg_lit0("v", "verbose", "verbose output"),
|
||||||
|
arg_lit0("z", "dense", "dense dump output style"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
@ -2683,6 +2715,7 @@ static int CmdHFiClassView(const char *Cmd) {
|
||||||
int startblock = arg_get_int_def(ctx, 2, 0);
|
int startblock = arg_get_int_def(ctx, 2, 0);
|
||||||
int endblock = arg_get_int_def(ctx, 3, 0);
|
int endblock = arg_get_int_def(ctx, 3, 0);
|
||||||
bool verbose = arg_get_lit(ctx, 4);
|
bool verbose = arg_get_lit(ctx, 4);
|
||||||
|
bool dense_output = g_session.dense_output || arg_get_lit(ctx, 5);
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
@ -2703,7 +2736,7 @@ static int CmdHFiClassView(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
print_picopass_header((picopass_hdr_t *) dump);
|
print_picopass_header((picopass_hdr_t *) dump);
|
||||||
print_picopass_info((picopass_hdr_t *) dump);
|
print_picopass_info((picopass_hdr_t *) dump);
|
||||||
printIclassDumpContents(dump, startblock, endblock, bytes_read);
|
printIclassDumpContents(dump, startblock, endblock, bytes_read, dense_output);
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printIclassSIO(dump);
|
printIclassSIO(dump);
|
||||||
|
|
|
@ -26,7 +26,7 @@ int CmdHFiClass(const char *Cmd);
|
||||||
|
|
||||||
int info_iclass(void);
|
int info_iclass(void);
|
||||||
int read_iclass_csn(bool loop, bool verbose);
|
int read_iclass_csn(bool loop, bool verbose);
|
||||||
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize);
|
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize, bool dense_output);
|
||||||
void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite);
|
void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite);
|
||||||
|
|
||||||
void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, uint32_t keycnt, iclass_premac_t *list);
|
void GenerateMacFrom(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, uint32_t keycnt, iclass_premac_t *list);
|
||||||
|
|
|
@ -63,6 +63,7 @@ int preferences_load(void) {
|
||||||
g_session.overlay.w = g_session.plot.w;
|
g_session.overlay.w = g_session.plot.w;
|
||||||
g_session.overlay_sliders = true;
|
g_session.overlay_sliders = true;
|
||||||
g_session.show_hints = true;
|
g_session.show_hints = true;
|
||||||
|
g_session.dense_output = false;
|
||||||
|
|
||||||
g_session.bar_mode = STYLE_VALUE;
|
g_session.bar_mode = STYLE_VALUE;
|
||||||
setDefaultPath(spDefault, "");
|
setDefaultPath(spDefault, "");
|
||||||
|
@ -185,6 +186,8 @@ void preferences_save_callback(json_t *root) {
|
||||||
|
|
||||||
JsonSaveBoolean(root, "show.hints", g_session.show_hints);
|
JsonSaveBoolean(root, "show.hints", g_session.show_hints);
|
||||||
|
|
||||||
|
JsonSaveBoolean(root, "output.dense", g_session.dense_output);
|
||||||
|
|
||||||
JsonSaveBoolean(root, "os.supports.colors", g_session.supports_colors);
|
JsonSaveBoolean(root, "os.supports.colors", g_session.supports_colors);
|
||||||
|
|
||||||
JsonSaveStr(root, "file.default.savepath", g_session.defaultPaths[spDefault]);
|
JsonSaveStr(root, "file.default.savepath", g_session.defaultPaths[spDefault]);
|
||||||
|
@ -319,6 +322,9 @@ void preferences_load_callback(json_t *root) {
|
||||||
if (json_unpack_ex(root, &up_error, 0, "{s:b}", "show.hints", &b1) == 0)
|
if (json_unpack_ex(root, &up_error, 0, "{s:b}", "show.hints", &b1) == 0)
|
||||||
g_session.show_hints = (bool)b1;
|
g_session.show_hints = (bool)b1;
|
||||||
|
|
||||||
|
if (json_unpack_ex(root, &up_error, 0, "{s:b}", "output.dense", &b1) == 0)
|
||||||
|
g_session.dense_output = (bool)b1;
|
||||||
|
|
||||||
if (json_unpack_ex(root, &up_error, 0, "{s:b}", "os.supports.colors", &b1) == 0)
|
if (json_unpack_ex(root, &up_error, 0, "{s:b}", "os.supports.colors", &b1) == 0)
|
||||||
g_session.supports_colors = (bool)b1;
|
g_session.supports_colors = (bool)b1;
|
||||||
|
|
||||||
|
@ -517,6 +523,11 @@ static void showBarModeState(prefShowOpt_t opt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void showOutputState(prefShowOpt_t opt) {
|
||||||
|
PrintAndLogEx(INFO, " %s output................. %s", prefShowMsg(opt),
|
||||||
|
g_session.dense_output ? _GREEN_("dense") : _WHITE_("normal"));
|
||||||
|
}
|
||||||
|
|
||||||
static void showClientExeDelayState(void) {
|
static void showClientExeDelayState(void) {
|
||||||
PrintAndLogEx(INFO, " Cmd execution delay.... "_GREEN_("%u"), g_session.client_exe_delay);
|
PrintAndLogEx(INFO, " Cmd execution delay.... "_GREEN_("%u"), g_session.client_exe_delay);
|
||||||
}
|
}
|
||||||
|
@ -738,6 +749,49 @@ static int setCmdDeviceDebug (const char *Cmd)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int setCmdOutput(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "prefs set output",
|
||||||
|
"Set dump output style to condense consecutive repeated data",
|
||||||
|
"prefs set output --normal --> sets the output style to normal\n"
|
||||||
|
"prefs set output --dense --> sets the output style to dense"
|
||||||
|
);
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_lit0(NULL, "normal", "normal output"),
|
||||||
|
arg_lit0(NULL, "dense", "dense output"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
bool use_off = arg_get_lit(ctx, 1);
|
||||||
|
bool use_on = arg_get_lit(ctx, 2);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
if ((use_off + use_on) > 1) {
|
||||||
|
PrintAndLogEx(FAILED, "Can only set one option");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool new_value = g_session.dense_output;
|
||||||
|
if (use_off) {
|
||||||
|
new_value = false;
|
||||||
|
}
|
||||||
|
if (use_on) {
|
||||||
|
new_value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_session.dense_output != new_value) {
|
||||||
|
showOutputState(prefShowOLD);
|
||||||
|
g_session.dense_output = new_value;
|
||||||
|
showOutputState(prefShowNEW);
|
||||||
|
preferences_save();
|
||||||
|
} else {
|
||||||
|
showOutputState(prefShowNone);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int setCmdExeDelay(const char *Cmd) {
|
static int setCmdExeDelay(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
|
@ -1044,6 +1098,22 @@ static int getCmdDebug(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int getCmdOutput(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "prefs get output",
|
||||||
|
"Get preference of dump output style",
|
||||||
|
"prefs get output"
|
||||||
|
);
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
showOutputState(prefShowNone);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int getCmdPlotSlider(const char *Cmd) {
|
static int getCmdPlotSlider(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "prefs get plotsliders",
|
CLIParserInit(&ctx, "prefs get plotsliders",
|
||||||
|
@ -1119,6 +1189,7 @@ static command_t CommandTableGet[] = {
|
||||||
// {"devicedebug", getCmdDeviceDebug, AlwaysAvailable, "Get device debug level"},
|
// {"devicedebug", getCmdDeviceDebug, AlwaysAvailable, "Get device debug level"},
|
||||||
{"emoji", getCmdEmoji, AlwaysAvailable, "Get emoji display preference"},
|
{"emoji", getCmdEmoji, AlwaysAvailable, "Get emoji display preference"},
|
||||||
{"hints", getCmdHint, AlwaysAvailable, "Get hint display preference"},
|
{"hints", getCmdHint, AlwaysAvailable, "Get hint display preference"},
|
||||||
|
{"output", getCmdOutput, AlwaysAvailable, "Get dump output style preference"},
|
||||||
{"plotsliders", getCmdPlotSlider, AlwaysAvailable, "Get plot slider display preference"},
|
{"plotsliders", getCmdPlotSlider, AlwaysAvailable, "Get plot slider display preference"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -1133,7 +1204,8 @@ static command_t CommandTableSet[] = {
|
||||||
{"hints", setCmdHint, AlwaysAvailable, "Set hint display"},
|
{"hints", setCmdHint, AlwaysAvailable, "Set hint display"},
|
||||||
{"savepaths", setCmdSavePaths, AlwaysAvailable, "... to be adjusted next ... "},
|
{"savepaths", setCmdSavePaths, AlwaysAvailable, "... to be adjusted next ... "},
|
||||||
// {"devicedebug", setCmdDeviceDebug, AlwaysAvailable, "Set device debug level"},
|
// {"devicedebug", setCmdDeviceDebug, AlwaysAvailable, "Set device debug level"},
|
||||||
{"plotsliders", setCmdPlotSliders, AlwaysAvailable, "Set plot slider display"},
|
{"output", setCmdOutput, AlwaysAvailable, "Set dump output style"},
|
||||||
|
{"plotsliders", setCmdPlotSliders, AlwaysAvailable, "Set plot slider display"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1189,6 +1261,7 @@ static int CmdPrefShow(const char *Cmd) {
|
||||||
// showDeviceDebugState(prefShowNone);
|
// showDeviceDebugState(prefShowNone);
|
||||||
showBarModeState(prefShowNone);
|
showBarModeState(prefShowNone);
|
||||||
showClientExeDelayState();
|
showClientExeDelayState();
|
||||||
|
showOutputState(prefShowNone);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
|
|
@ -47,6 +47,7 @@ typedef struct {
|
||||||
bool pm3_present;
|
bool pm3_present;
|
||||||
bool help_dump_mode;
|
bool help_dump_mode;
|
||||||
bool show_hints;
|
bool show_hints;
|
||||||
|
bool dense_output;
|
||||||
bool window_changed; // track if plot/overlay pos/size changed to save on exit
|
bool window_changed; // track if plot/overlay pos/size changed to save on exit
|
||||||
qtWindow_t plot;
|
qtWindow_t plot;
|
||||||
qtWindow_t overlay;
|
qtWindow_t overlay;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue