From c6d01e6e7260f968dfeb538f1dfa8ef503dacf5e Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 29 Jun 2026 23:51:37 +0200 Subject: [PATCH] update helptexts --- client/CMakeLists.txt | 1 + client/Makefile | 1 + client/experimental_lib/CMakeLists.txt | 1 + client/src/jansson_path.c | 43 +++++-- client/src/pla.c | 54 +++++++-- client/src/pm3line_vocabulary.h | 2 +- doc/commands.json | 157 ++++++++++++------------- doc/commands.md | 2 +- 8 files changed, 161 insertions(+), 100 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index fda4ea575..fadaa0b00 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -478,6 +478,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/comms.c ${PM3_ROOT}/client/src/fileutils.c ${PM3_ROOT}/client/src/flash.c + ${PM3_ROOT}/client/src/frame_progress.c ${PM3_ROOT}/client/src/graph.c ${PM3_ROOT}/client/src/hidsio.c ${PM3_ROOT}/client/src/iso4217.c diff --git a/client/Makefile b/client/Makefile index 48e291fcd..3ad261b0b 100644 --- a/client/Makefile +++ b/client/Makefile @@ -849,6 +849,7 @@ SRCS = mifare/aiddesfire.c \ cipurse/cipursetest.c \ fileutils.c \ flash.c \ + frame_progress.c \ generator.c \ graph.c \ hidsio.c \ diff --git a/client/experimental_lib/CMakeLists.txt b/client/experimental_lib/CMakeLists.txt index e3ebc1475..4b2ca75f1 100644 --- a/client/experimental_lib/CMakeLists.txt +++ b/client/experimental_lib/CMakeLists.txt @@ -398,6 +398,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/comms.c ${PM3_ROOT}/client/src/fileutils.c ${PM3_ROOT}/client/src/flash.c + ${PM3_ROOT}/client/src/frame_progress.c ${PM3_ROOT}/client/src/graph.c ${PM3_ROOT}/client/src/hidsio.c ${PM3_ROOT}/client/src/iso4217.c diff --git a/client/src/jansson_path.c b/client/src/jansson_path.c index 1f21cb343..3ba114c51 100644 --- a/client/src/jansson_path.c +++ b/client/src/jansson_path.c @@ -34,23 +34,26 @@ static json_malloc_t do_malloc = malloc; static json_free_t do_free = free; static void *jsonp_malloc(size_t size) { - if (!size) + if (size == 0) { return NULL; + } return (*do_malloc)(size); } static void jsonp_free(void *ptr) { - if (!ptr) + if (ptr == NULL) { return; + } (*do_free)(ptr); } static char *jsonp_strndup(const char *str, size_t len) { char *new_str = jsonp_malloc(len + 1); - if (!new_str) + if (new_str == NULL) { return NULL; + } memcpy(new_str, str, len); new_str[len] = '\0'; @@ -85,18 +88,20 @@ static void jsonp_error_init(json_error_t *error, const char *source) { error->line = -1; error->column = -1; error->position = 0; - if (source) + if (source) { jsonp_error_set_source(error, source); - else + } else { error->source[0] = '\0'; + } } } static void jsonp_error_vset(json_error_t *error, int line, int column, size_t position, enum json_error_code code, const char *msg, va_list ap) { - if (!error) + if (error == NULL) { return; + } if (error->text[0] != '\0') { /* error already set */ @@ -131,10 +136,11 @@ json_t *json_path_get(const json_t *json, const char *path) { char *token, *buf, *peek, *endptr, delim = '\0'; const char *expect; - if (!json || !path || path[0] != root_chr) + if (!json || !path || path[0] != root_chr) { return NULL; - else + } else { buf = jsonp_strdup(path); + } peek = buf + 1; cursor = json; @@ -142,27 +148,37 @@ json_t *json_path_get(const json_t *json, const char *path) { expect = path_delims; while (peek && *peek && cursor) { + char *last_peek = peek; peek = strpbrk(peek, expect); + if (peek) { - if (!token && peek != last_peek) + if (!token && peek != last_peek) { goto fail; + } delim = *peek; *peek++ = '\0'; + } else if (expect != path_delims || !token) { goto fail; } if (expect == path_delims) { + if (token) { cursor = json_object_get(cursor, token); } + expect = (delim == array_open ? array_close : path_delims); token = peek; + } else if (expect == array_close) { + size_t index = strtol(token, &endptr, 0); - if (*endptr) + if (*endptr) { goto fail; + } + cursor = json_array_get(cursor, index); token = NULL; expect = path_delims; @@ -236,7 +252,7 @@ int json_path_set_new(json_t *json, const char *path, json_t *value, size_t flag parent = cursor; cursor = json_object_get(parent, token); - if (!cursor) { + if (cursor == NULL) { if (!json_is_object(parent)) { jsonp_error_set(error, -1, -1, peek - buf, json_error_item_not_found, "object expected"); goto fail; @@ -261,16 +277,19 @@ int json_path_set_new(json_t *json, const char *path, json_t *value, size_t flag jsonp_error_set(error, -1, -1, peek - buf, json_error_item_not_found, "array expected"); goto fail; } + index = strtol(token, &endptr, 0); if (*endptr) { jsonp_error_set(error, -1, -1, peek - buf, json_error_item_not_found, "invalid array index"); goto fail; } + cursor = json_array_get(parent, index); - if (!cursor) { + if (cursor == NULL) { jsonp_error_set(error, -1, -1, peek - buf, json_error_item_not_found, "array index out of bound"); goto fail; } + index_saved = index; token = NULL; expect = path_delims; diff --git a/client/src/pla.c b/client/src/pla.c index cda42b8eb..0533520cf 100644 --- a/client/src/pla.c +++ b/client/src/pla.c @@ -37,7 +37,7 @@ json_t *pla_load_ecplist(void) { json_t *root = json_load_file(path, 0, &error); free(path); - if (!root) { + if (root == false) { PrintAndLogEx(ERR, "json error on line %d: %s", error.line, error.text); return NULL; } @@ -60,19 +60,22 @@ json_t *pla_search_ecplist_by_key(json_t *root, const char *type, const char *su // If type filter is specified, check if entry has matching type if (type != NULL) { json_t *type_obj = json_object_get(entry, "type"); - if (!type_obj) { + if (type_obj == NULL) { continue; // Skip entries without type field } bool type_matched = false; + if (json_is_string(type_obj)) { const char *type_str = json_string_value(type_obj); if (type_str && strcmp(type_str, type) == 0) { type_matched = true; } + } else if (json_is_array(type_obj)) { size_t type_index; json_t *type_value; + json_array_foreach(type_obj, type_index, type_value) { const char *type_str = json_string_value(type_value); if (type_str && strcmp(type_str, type) == 0) { @@ -82,9 +85,10 @@ json_t *pla_search_ecplist_by_key(json_t *root, const char *type, const char *su } } - if (!type_matched) { + if (type_matched == false) { continue; // Type doesn't match } + } else { // If no type filter, skip entries that have a type field if (json_object_get(entry, "type")) { @@ -97,16 +101,21 @@ json_t *pla_search_ecplist_by_key(json_t *root, const char *type, const char *su // Check if the subtype matches the "subtype" field (string or array) if (subtype != NULL) { + json_t *subtype_obj = json_object_get(entry, "subtype"); if (subtype_obj) { + if (json_is_string(subtype_obj)) { + const char *subtype_str = json_string_value(subtype_obj); if (subtype_str && strcmp(subtype_str, subtype) == 0) { subtype_matched = true; } + } else if (json_is_array(subtype_obj)) { size_t subtype_index; json_t *subtype_value; + json_array_foreach(subtype_obj, subtype_index, subtype_value) { const char *subtype_str = json_string_value(subtype_value); if (subtype_str && strcmp(subtype_str, subtype) == 0) { @@ -120,16 +129,21 @@ json_t *pla_search_ecplist_by_key(json_t *root, const char *type, const char *su // Check if the key matches the "key" field (string or array) if (key != NULL) { + json_t *key_obj = json_object_get(entry, "key"); if (key_obj) { + if (json_is_string(key_obj)) { + const char *key_str = json_string_value(key_obj); if (key_str && strcmp(key_str, key) == 0) { key_matched = true; } + } else if (json_is_array(key_obj)) { size_t key_index; json_t *key_value; + json_array_foreach(key_obj, key_index, key_value) { const char *key_str = json_string_value(key_value); if (key_str && strcmp(key_str, key) == 0) { @@ -159,7 +173,7 @@ int pla_parse_ecp_subcommand(const char *cmd, uint8_t *frame, size_t frame_size) // Make a mutable copy of the command and replace dots/colons with spaces char *cmd_copy = strdup(cmd); - if (!cmd_copy) { + if (cmd_copy == NULL) { return -1; } @@ -171,7 +185,7 @@ int pla_parse_ecp_subcommand(const char *cmd, uint8_t *frame, size_t frame_size) // Load ecplist.json json_t *ecplist = pla_load_ecplist(); - if (!ecplist) { + if (ecplist == NULL) { PrintAndLogEx(ERR, "Failed to load ecplist.json"); free(cmd_copy); return -1; @@ -182,6 +196,7 @@ int pla_parse_ecp_subcommand(const char *cmd, uint8_t *frame, size_t frame_size) if (strncmp(p, "ecp", 3) == 0) { p += 3; } + while (*p == ' ' || *p == '\t') { p++; } @@ -192,24 +207,31 @@ int pla_parse_ecp_subcommand(const char *cmd, uint8_t *frame, size_t frame_size) // Check if first term is a type ("transit" or "access") if (strncmp(p, "transit", 7) == 0) { + type = "transit"; p += 7; + while (*p == ' ' || *p == '\t') { p++; } + search_term = p; // If second term provided, search by key in transit entries if (*p != '\0') { + json_t *entry = pla_search_ecplist_by_key(ecplist, type, NULL, search_term); if (entry) { // Found matching entry, use its value json_t *value_obj = json_object_get(entry, "value"); if (value_obj) { + const char *hex_str = json_string_value(value_obj); if (hex_str) { + size_t hex_len = strlen(hex_str); if (hex_len % 2 == 0 && hex_len <= frame_size * 2) { + for (size_t i = 0; i < hex_len / 2; i++) { sscanf(hex_str + i * 2, "%2hhx", &frame[i]); } @@ -221,6 +243,7 @@ int pla_parse_ecp_subcommand(const char *cmd, uint8_t *frame, size_t frame_size) // If not found, try interpreting as hex TCI if (result == -1) { + char *endptr; uint32_t tci = strtoul(search_term, &endptr, 16); if (search_term != endptr) { @@ -248,8 +271,10 @@ int pla_parse_ecp_subcommand(const char *cmd, uint8_t *frame, size_t frame_size) } } else if (strncmp(p, "access", 6) == 0) { + type = "access"; p += 6; + while (*p == ' ' || *p == '\t') { p++; } @@ -282,6 +307,7 @@ int pla_parse_ecp_subcommand(const char *cmd, uint8_t *frame, size_t frame_size) while (*p != '\0' && *p != ' ' && *p != '\t') { p++; } + size_t third_term_len = p - third_term; if (third_term_len > 0) { third = str_ndup(third_term, third_term_len); @@ -302,7 +328,7 @@ int pla_parse_ecp_subcommand(const char *cmd, uint8_t *frame, size_t frame_size) // One term: try as subtype first, then as key entry = pla_search_ecplist_by_key(ecplist, type, second, NULL); - if (!entry) { + if (entry == NULL) { entry = pla_search_ecplist_by_key(ecplist, type, NULL, second); } } @@ -311,10 +337,13 @@ int pla_parse_ecp_subcommand(const char *cmd, uint8_t *frame, size_t frame_size) // Found matching entry, use its value json_t *value_obj = json_object_get(entry, "value"); if (value_obj) { + const char *hex_str = json_string_value(value_obj); if (hex_str) { + size_t hex_len = strlen(hex_str); if (hex_len % 2 == 0 && hex_len <= frame_size * 2) { + for (size_t i = 0; i < hex_len / 2; i++) { sscanf(hex_str + i * 2, "%2hhx", &frame[i]); } @@ -326,16 +355,23 @@ int pla_parse_ecp_subcommand(const char *cmd, uint8_t *frame, size_t frame_size) // If not found and no third term, try interpreting second term as hex TCI if (result == -1 && third == NULL) { + char *endptr; tci = strtoul(second, &endptr, 16); + if (second == endptr) { PrintAndLogEx(ERR, "Unknown access subtype/key or invalid TCI: %s", second); free(second); - if (third) free(third); + + if (third) { + free(third); + } + json_decref(ecplist); free(cmd_copy); return -1; } + } else if (result == -1 && third != NULL) { PrintAndLogEx(ERR, "No matching access entry for subtype '%s' and key '%s'", second, third); free(second); @@ -371,12 +407,16 @@ int pla_parse_ecp_subcommand(const char *cmd, uint8_t *frame, size_t frame_size) // No type specified, search for entries without type field by key json_t *entry = pla_search_ecplist_by_key(ecplist, search_term, NULL, NULL); if (entry) { + json_t *value_obj = json_object_get(entry, "value"); if (value_obj) { + const char *hex_str = json_string_value(value_obj); if (hex_str) { + size_t hex_len = strlen(hex_str); if (hex_len % 2 == 0 && hex_len <= frame_size * 2) { + for (size_t i = 0; i < hex_len / 2; i++) { sscanf(hex_str + i * 2, "%2hhx", &frame[i]); } diff --git a/client/src/pm3line_vocabulary.h b/client/src/pm3line_vocabulary.h index b0e50fad5..50a6d5aa4 100644 --- a/client/src/pm3line_vocabulary.h +++ b/client/src/pm3line_vocabulary.h @@ -922,10 +922,10 @@ const static vocabulary_t vocabulary[] = { { 0, "lf visa2000 reader" }, { 0, "lf visa2000 clone" }, { 0, "lf visa2000 sim" }, + { 1, "mad help" }, { 0, "mad read" }, { 0, "mad write" }, { 0, "mad verify" }, - { 1, "mad help" }, { 1, "mad decode" }, { 1, "mad encode" }, { 1, "mad test" }, diff --git a/doc/commands.json b/doc/commands.json index df093608f..d5a87a64f 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -596,10 +596,11 @@ }, "data num": { "command": "data num", - "description": "Function takes a decimal or hexdecimal number and print it in decimal/hex/binary Will print message if number is a prime number", + "description": "Function takes a decimal or hexdecimal number and print it in decimal/hex/binary Includes Manchester encoding and decoding of the value Will print message if number is a prime number", "notes": [ "data num --dec 2023", - "data num --hex 2A" + "data num --hex 2A", + "data num --hex 556555476555695559695555" ], "offline": true, "options": [ @@ -6347,46 +6348,46 @@ "command": "hf mf madread", "description": "Read application data from sectors matching a MAD AID", "notes": [ - "mad read --aid e103 -> read NDEF data (auto-detect card)", + "mad read --aid e103 -> read NDEF data", "mad read --aid e103 -k ffffffffffff -b -> Classic, key B", "mad read --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> Plus", - "mad read --aid e103 -v -f mydata.bin -> verbose, save to file" + "mad read --aid e103 -v -f mydata.bin" ], "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose output", "--aid application ID (2 hex bytes)", "-k, --key key for data sectors", - "-b, --keyb use key B (def: key A)", - "--mad-key key for MAD sectors", + "-b, --keyb use key B", + "--madkey key for MAD sectors", "--be big-endian AID byte swap", "--override override failed CRC check", - "-f, --file save raw data to file" + "-f, --file save raw data to file", + "-v, --verbose verbose output" ], - "usage": "hf mf madread [-hvb] --aid [-k ] [--mad-key ] [--be] [--override] [-f ]" + "usage": "hf mf madread [-hbv] --aid [-k ] [--madkey ] [--be] [--override] [-f ]" }, "hf mf madverify": { "command": "hf mf madverify", "description": "Read back and verify application data against expected content", "notes": [ - "mad verify --aid e103 -d 0102030405060708 -> verify data", - "mad verify --aid e103 -f mydata.bin -> verify against file" + "mad verify --aid e103 -d 0102030405060708", + "mad verify --aid e103 -f mydata.bin" ], "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose output", "--aid application ID (2 hex bytes)", "-k, --key key for data sectors", "-b, --keyb use key B (def: key A)", - "--mad-key key for MAD sectors", + "--madkey key for MAD sectors", "--be big-endian AID byte swap", "--override override failed CRC check", "-d, --data expected data", - "-f, --file load expected data from file" + "-f, --file load expected data from file", + "-v, --verbose verbose output" ], - "usage": "hf mf madverify [-hvb] --aid [-k ] [--mad-key ] [--be] [--override] [-d ] [-f ]" + "usage": "hf mf madverify [-hbv] --aid [-k ] [--madkey ] [--be] [--override] [-d ] [-f ]" }, "hf mf madwrite": { "command": "hf mf madwrite", @@ -6399,17 +6400,17 @@ "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose output", "--aid application ID (2 hex bytes)", "-k, --key key for data sectors", "-b, --keyb use key B (def: key A)", - "--mad-key key for MAD sectors", + "--madkey key for MAD sectors", "--be big-endian AID byte swap", "--override override failed CRC check", "-d, --data data to write", - "-f, --file load data from file" + "-f, --file load data from file", + "-v, --verbose verbose output" ], - "usage": "hf mf madwrite [-hvb] --aid [-k ] [--mad-key ] [--be] [--override] [-d ] [-f ]" + "usage": "hf mf madwrite [-hbv] --aid [-k ] [--madkey ] [--be] [--override] [-d ] [-f ]" }, "hf mf nack": { "command": "hf mf nack", @@ -8495,46 +8496,46 @@ "command": "hf mfp madread", "description": "Read application data from sectors matching a MAD AID", "notes": [ - "mad read --aid e103 -> read NDEF data (auto-detect card)", + "mad read --aid e103 -> read NDEF data", "mad read --aid e103 -k ffffffffffff -b -> Classic, key B", "mad read --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> Plus", - "mad read --aid e103 -v -f mydata.bin -> verbose, save to file" + "mad read --aid e103 -v -f mydata.bin" ], "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose output", "--aid application ID (2 hex bytes)", "-k, --key key for data sectors", - "-b, --keyb use key B (def: key A)", - "--mad-key key for MAD sectors", + "-b, --keyb use key B", + "--madkey key for MAD sectors", "--be big-endian AID byte swap", "--override override failed CRC check", - "-f, --file save raw data to file" + "-f, --file save raw data to file", + "-v, --verbose verbose output" ], - "usage": "hf mfp madread [-hvb] --aid [-k ] [--mad-key ] [--be] [--override] [-f ]" + "usage": "hf mfp madread [-hbv] --aid [-k ] [--madkey ] [--be] [--override] [-f ]" }, "hf mfp madverify": { "command": "hf mfp madverify", "description": "Read back and verify application data against expected content", "notes": [ - "mad verify --aid e103 -d 0102030405060708 -> verify data", - "mad verify --aid e103 -f mydata.bin -> verify against file" + "mad verify --aid e103 -d 0102030405060708", + "mad verify --aid e103 -f mydata.bin" ], "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose output", "--aid application ID (2 hex bytes)", "-k, --key key for data sectors", "-b, --keyb use key B (def: key A)", - "--mad-key key for MAD sectors", + "--madkey key for MAD sectors", "--be big-endian AID byte swap", "--override override failed CRC check", "-d, --data expected data", - "-f, --file load expected data from file" + "-f, --file load expected data from file", + "-v, --verbose verbose output" ], - "usage": "hf mfp madverify [-hvb] --aid [-k ] [--mad-key ] [--be] [--override] [-d ] [-f ]" + "usage": "hf mfp madverify [-hbv] --aid [-k ] [--madkey ] [--be] [--override] [-d ] [-f ]" }, "hf mfp madwrite": { "command": "hf mfp madwrite", @@ -8547,17 +8548,17 @@ "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose output", "--aid application ID (2 hex bytes)", "-k, --key key for data sectors", "-b, --keyb use key B (def: key A)", - "--mad-key key for MAD sectors", + "--madkey key for MAD sectors", "--be big-endian AID byte swap", "--override override failed CRC check", "-d, --data data to write", - "-f, --file load data from file" + "-f, --file load data from file", + "-v, --verbose verbose output" ], - "usage": "hf mfp madwrite [-hvb] --aid [-k ] [--mad-key ] [--be] [--override] [-d ] [-f ]" + "usage": "hf mfp madwrite [-hbv] --aid [-k ] [--madkey ] [--be] [--override] [-d ] [-f ]" }, "hf mfp ndefformat": { "command": "hf mfp ndefformat", @@ -11045,7 +11046,7 @@ "options": [ "-h, --help This help", "-p, --pwd password (00000000)", - "-f, --file override filename prefix (optional). Default is based on UID", + "-f, --file override filename prefix (optional). Default is based on UID/Serial", "--ns no save to file" ], "usage": "lf em 4x05 dump [-h] [-p ] [-f ] [--ns]" @@ -14136,13 +14137,29 @@ ], "usage": "lf visa2000 sim [-h] --cn " }, + "mad decode": { + "command": "mad decode", + "description": "Decode a MAD byte array and print the directory. Use Sector 0 == MAD 1 Sector 16 == MAD 2", + "notes": [ + "mad decode --mad1 " + ], + "offline": true, + "options": [ + "-h, --help This help", + "-v, --verbose verbose output", + "-1, --mad1 MAD 1 Sector 0 data (64 bytes)", + "-2, --mad2 MAD 2 Sector 16 data (64 bytes)", + "--be big-endian AID byte swap" + ], + "usage": "mad decode [-hv] -1 [-2 ] [--be]" + }, "mad encode": { "command": "mad encode", "description": "Encode a MAD byte array from AID-to-sector mappings", "notes": [ "mad encode --aid E103:1-3 --aid 484D:4 -> MAD1 with NDEF + HID", "mad encode --aid E103:1-3,5 -> non-contiguous sectors", - "mad encode --aid E103:1-3,17-18 --aid 484D:4 -> MAD1 + MAD2", + "mad encode --aid E103:1-3,17-18 --aid 484D:4 -> MAD1 + MAD2 + HID", "mad encode --aid E103:1-3 -q -> quiet, hex only" ], "offline": true, @@ -14156,50 +14173,32 @@ }, "mad help": { "command": "mad help", - "description": "-------- --------------- MAD ----------------- -------- ------------- General --------------- help This help decode Decode MAD byte array encode Encode MAD byte array from AID mappings test Run MAD regression tests --------------------------------------------------------------------------------------- mad decode available offline: yes Decode a MAD byte array and print the directory", + "description": "help This help -------- --------------- MAD ----------------- -------- ------------- General --------------- decode Decode MAD byte array encode Encode MAD byte array from AID mappings test Run MAD regression tests --------------------------------------------------------------------------------------- mad read available offline: no Read application data from sectors matching a MAD AID", "notes": [ - "mad decode -d -> decode MAD1", - "mad decode -d --mad2 -> decode MAD1 + MAD2" + "mad read --aid e103 -> read NDEF data", + "mad read --aid e103 -k ffffffffffff -b -> Classic, key B", + "mad read --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> Plus", + "mad read --aid e103 -v -f mydata.bin" ], "offline": true, "options": [ "-h, --help This help", - "-v, --verbose verbose output", - "-d, --data MAD1 sector 0 data (64 bytes)", - "--mad2 MAD2 sector 16 data (64 bytes)", - "--be big-endian AID byte swap" - ], - "usage": "mad decode [-hv] -d [--mad2 ] [--be]" - }, - "mad read": { - "command": "mad read", - "description": "Read application data from sectors matching a MAD AID", - "notes": [ - "mad read --aid e103 -> read NDEF data (auto-detect card)", - "mad read --aid e103 -k ffffffffffff -b -> Classic, key B", - "mad read --aid e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> Plus", - "mad read --aid e103 -v -f mydata.bin -> verbose, save to file" - ], - "offline": false, - "options": [ - "-h, --help This help", - "-v, --verbose verbose output", "--aid application ID (2 hex bytes)", "-k, --key key for data sectors", - "-b, --keyb use key B (def: key A)", - "--mad-key key for MAD sectors", + "-b, --keyb use key B", + "--madkey key for MAD sectors", "--be big-endian AID byte swap", "--override override failed CRC check", - "-f, --file save raw data to file" + "-f, --file save raw data to file", + "-v, --verbose verbose output" ], - "usage": "mad read [-hvb] --aid [-k ] [--mad-key ] [--be] [--override] [-f ]" + "usage": "mad read [-hbv] --aid [-k ] [--madkey ] [--be] [--override] [-f ]" }, "mad test": { "command": "mad test", - "description": "Run MAD regression tests (offline, no card needed)", + "description": "Run MAD regression tests. Runs offline with no card needed", "notes": [ - "mad test", - "mad test -v -> verbose output" + "mad test" ], "offline": true, "options": [ @@ -14212,23 +14211,23 @@ "command": "mad verify", "description": "Read back and verify application data against expected content", "notes": [ - "mad verify --aid e103 -d 0102030405060708 -> verify data", - "mad verify --aid e103 -f mydata.bin -> verify against file" + "mad verify --aid e103 -d 0102030405060708", + "mad verify --aid e103 -f mydata.bin" ], "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose output", "--aid application ID (2 hex bytes)", "-k, --key key for data sectors", "-b, --keyb use key B (def: key A)", - "--mad-key key for MAD sectors", + "--madkey key for MAD sectors", "--be big-endian AID byte swap", "--override override failed CRC check", "-d, --data expected data", - "-f, --file load expected data from file" + "-f, --file load expected data from file", + "-v, --verbose verbose output" ], - "usage": "mad verify [-hvb] --aid [-k ] [--mad-key ] [--be] [--override] [-d ] [-f ]" + "usage": "mad verify [-hbv] --aid [-k ] [--madkey ] [--be] [--override] [-d ] [-f ]" }, "mad write": { "command": "mad write", @@ -14241,17 +14240,17 @@ "offline": false, "options": [ "-h, --help This help", - "-v, --verbose verbose output", "--aid application ID (2 hex bytes)", "-k, --key key for data sectors", "-b, --keyb use key B (def: key A)", - "--mad-key key for MAD sectors", + "--madkey key for MAD sectors", "--be big-endian AID byte swap", "--override override failed CRC check", "-d, --data data to write", - "-f, --file load data from file" + "-f, --file load data from file", + "-v, --verbose verbose output" ], - "usage": "mad write [-hvb] --aid [-k ] [--mad-key ] [--be] [--override] [-d ] [-f ]" + "usage": "mad write [-hbv] --aid [-k ] [--madkey ] [--be] [--override] [-d ] [-f ]" }, "mem dump": { "command": "mem dump", @@ -15661,6 +15660,6 @@ "metadata": { "commands_extracted": 878, "extracted_by": "PM3Help2JSON v1.00", - "extracted_on": "2026-06-22T22:01:12+00:00" + "extracted_on": "2026-06-29T21:47:47+00:00" } } diff --git a/doc/commands.md b/doc/commands.md index e7d04fcf2..d0134df29 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -1542,10 +1542,10 @@ Check column "offline" for their availability. |command |offline |description |------- |------- |----------- +|`mad help `|Y |`This help` |`mad read `|N |`Read data from MAD AID sectors` |`mad write `|N |`Write data to MAD AID sectors` |`mad verify `|N |`Verify data in MAD AID sectors` -|`mad help `|Y |`This help` |`mad decode `|Y |`Decode MAD byte array` |`mad encode `|Y |`Encode MAD byte array from AID mappings` |`mad test `|Y |`Run MAD regression tests`