update helptexts

This commit is contained in:
iceman1001
2026-06-29 23:51:37 +02:00
parent 21a11320de
commit c6d01e6e72
8 changed files with 161 additions and 100 deletions
+1
View File
@@ -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
+1
View File
@@ -849,6 +849,7 @@ SRCS = mifare/aiddesfire.c \
cipurse/cipursetest.c \
fileutils.c \
flash.c \
frame_progress.c \
generator.c \
graph.c \
hidsio.c \
+1
View File
@@ -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
+31 -12
View File
@@ -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;
+47 -7
View File
@@ -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]);
}
+1 -1
View File
@@ -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" },
+78 -79
View File
@@ -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 <hex> application ID (2 hex bytes)",
"-k, --key <hex> key for data sectors",
"-b, --keyb use key B (def: key A)",
"--mad-key <hex> key for MAD sectors",
"-b, --keyb use key B",
"--madkey <hex> key for MAD sectors",
"--be big-endian AID byte swap",
"--override override failed CRC check",
"-f, --file <fn> save raw data to file"
"-f, --file <fn> save raw data to file",
"-v, --verbose verbose output"
],
"usage": "hf mf madread [-hvb] --aid <hex> [-k <hex>] [--mad-key <hex>] [--be] [--override] [-f <fn>]"
"usage": "hf mf madread [-hbv] --aid <hex> [-k <hex>] [--madkey <hex>] [--be] [--override] [-f <fn>]"
},
"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 <hex> application ID (2 hex bytes)",
"-k, --key <hex> key for data sectors",
"-b, --keyb use key B (def: key A)",
"--mad-key <hex> key for MAD sectors",
"--madkey <hex> key for MAD sectors",
"--be big-endian AID byte swap",
"--override override failed CRC check",
"-d, --data <hex> expected data",
"-f, --file <fn> load expected data from file"
"-f, --file <fn> load expected data from file",
"-v, --verbose verbose output"
],
"usage": "hf mf madverify [-hvb] --aid <hex> [-k <hex>] [--mad-key <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
"usage": "hf mf madverify [-hbv] --aid <hex> [-k <hex>] [--madkey <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
},
"hf mf madwrite": {
"command": "hf mf madwrite",
@@ -6399,17 +6400,17 @@
"offline": false,
"options": [
"-h, --help This help",
"-v, --verbose verbose output",
"--aid <hex> application ID (2 hex bytes)",
"-k, --key <hex> key for data sectors",
"-b, --keyb use key B (def: key A)",
"--mad-key <hex> key for MAD sectors",
"--madkey <hex> key for MAD sectors",
"--be big-endian AID byte swap",
"--override override failed CRC check",
"-d, --data <hex> data to write",
"-f, --file <fn> load data from file"
"-f, --file <fn> load data from file",
"-v, --verbose verbose output"
],
"usage": "hf mf madwrite [-hvb] --aid <hex> [-k <hex>] [--mad-key <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
"usage": "hf mf madwrite [-hbv] --aid <hex> [-k <hex>] [--madkey <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
},
"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 <hex> application ID (2 hex bytes)",
"-k, --key <hex> key for data sectors",
"-b, --keyb use key B (def: key A)",
"--mad-key <hex> key for MAD sectors",
"-b, --keyb use key B",
"--madkey <hex> key for MAD sectors",
"--be big-endian AID byte swap",
"--override override failed CRC check",
"-f, --file <fn> save raw data to file"
"-f, --file <fn> save raw data to file",
"-v, --verbose verbose output"
],
"usage": "hf mfp madread [-hvb] --aid <hex> [-k <hex>] [--mad-key <hex>] [--be] [--override] [-f <fn>]"
"usage": "hf mfp madread [-hbv] --aid <hex> [-k <hex>] [--madkey <hex>] [--be] [--override] [-f <fn>]"
},
"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 <hex> application ID (2 hex bytes)",
"-k, --key <hex> key for data sectors",
"-b, --keyb use key B (def: key A)",
"--mad-key <hex> key for MAD sectors",
"--madkey <hex> key for MAD sectors",
"--be big-endian AID byte swap",
"--override override failed CRC check",
"-d, --data <hex> expected data",
"-f, --file <fn> load expected data from file"
"-f, --file <fn> load expected data from file",
"-v, --verbose verbose output"
],
"usage": "hf mfp madverify [-hvb] --aid <hex> [-k <hex>] [--mad-key <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
"usage": "hf mfp madverify [-hbv] --aid <hex> [-k <hex>] [--madkey <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
},
"hf mfp madwrite": {
"command": "hf mfp madwrite",
@@ -8547,17 +8548,17 @@
"offline": false,
"options": [
"-h, --help This help",
"-v, --verbose verbose output",
"--aid <hex> application ID (2 hex bytes)",
"-k, --key <hex> key for data sectors",
"-b, --keyb use key B (def: key A)",
"--mad-key <hex> key for MAD sectors",
"--madkey <hex> key for MAD sectors",
"--be big-endian AID byte swap",
"--override override failed CRC check",
"-d, --data <hex> data to write",
"-f, --file <fn> load data from file"
"-f, --file <fn> load data from file",
"-v, --verbose verbose output"
],
"usage": "hf mfp madwrite [-hvb] --aid <hex> [-k <hex>] [--mad-key <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
"usage": "hf mfp madwrite [-hbv] --aid <hex> [-k <hex>] [--madkey <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
},
"hf mfp ndefformat": {
"command": "hf mfp ndefformat",
@@ -11045,7 +11046,7 @@
"options": [
"-h, --help This help",
"-p, --pwd <hex> password (00000000)",
"-f, --file <fn> override filename prefix (optional). Default is based on UID",
"-f, --file <fn> override filename prefix (optional). Default is based on UID/Serial",
"--ns no save to file"
],
"usage": "lf em 4x05 dump [-h] [-p <hex>] [-f <fn>] [--ns]"
@@ -14136,13 +14137,29 @@
],
"usage": "lf visa2000 sim [-h] --cn <dec>"
},
"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 <hex>"
],
"offline": true,
"options": [
"-h, --help This help",
"-v, --verbose verbose output",
"-1, --mad1 <hex> MAD 1 Sector 0 data (64 bytes)",
"-2, --mad2 <hex> MAD 2 Sector 16 data (64 bytes)",
"--be big-endian AID byte swap"
],
"usage": "mad decode [-hv] -1 <hex> [-2 <hex>] [--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 <sector0 hex> -> decode MAD1",
"mad decode -d <sector0 hex> --mad2 <sector16 hex> -> 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 <hex> MAD1 sector 0 data (64 bytes)",
"--mad2 <hex> MAD2 sector 16 data (64 bytes)",
"--be big-endian AID byte swap"
],
"usage": "mad decode [-hv] -d <hex> [--mad2 <hex>] [--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 <hex> application ID (2 hex bytes)",
"-k, --key <hex> key for data sectors",
"-b, --keyb use key B (def: key A)",
"--mad-key <hex> key for MAD sectors",
"-b, --keyb use key B",
"--madkey <hex> key for MAD sectors",
"--be big-endian AID byte swap",
"--override override failed CRC check",
"-f, --file <fn> save raw data to file"
"-f, --file <fn> save raw data to file",
"-v, --verbose verbose output"
],
"usage": "mad read [-hvb] --aid <hex> [-k <hex>] [--mad-key <hex>] [--be] [--override] [-f <fn>]"
"usage": "mad read [-hbv] --aid <hex> [-k <hex>] [--madkey <hex>] [--be] [--override] [-f <fn>]"
},
"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 <hex> application ID (2 hex bytes)",
"-k, --key <hex> key for data sectors",
"-b, --keyb use key B (def: key A)",
"--mad-key <hex> key for MAD sectors",
"--madkey <hex> key for MAD sectors",
"--be big-endian AID byte swap",
"--override override failed CRC check",
"-d, --data <hex> expected data",
"-f, --file <fn> load expected data from file"
"-f, --file <fn> load expected data from file",
"-v, --verbose verbose output"
],
"usage": "mad verify [-hvb] --aid <hex> [-k <hex>] [--mad-key <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
"usage": "mad verify [-hbv] --aid <hex> [-k <hex>] [--madkey <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
},
"mad write": {
"command": "mad write",
@@ -14241,17 +14240,17 @@
"offline": false,
"options": [
"-h, --help This help",
"-v, --verbose verbose output",
"--aid <hex> application ID (2 hex bytes)",
"-k, --key <hex> key for data sectors",
"-b, --keyb use key B (def: key A)",
"--mad-key <hex> key for MAD sectors",
"--madkey <hex> key for MAD sectors",
"--be big-endian AID byte swap",
"--override override failed CRC check",
"-d, --data <hex> data to write",
"-f, --file <fn> load data from file"
"-f, --file <fn> load data from file",
"-v, --verbose verbose output"
],
"usage": "mad write [-hvb] --aid <hex> [-k <hex>] [--mad-key <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
"usage": "mad write [-hbv] --aid <hex> [-k <hex>] [--madkey <hex>] [--be] [--override] [-d <hex>] [-f <fn>]"
},
"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"
}
}
+1 -1
View File
@@ -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`