mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-10-23 02:13:05 +00:00
New individual json dump file formats for ht1, ht2, htS, htU. '.bin' / binary format for hitag has been deprecated
This commit is contained in:
1 parent
dda9d7dd1c
commit
a1053ad70d
6 files changed
+114
-13
No files matched your search
@@ -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...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added individual json dump formats for ht2, ht1, htS, htU. No more .bin files either for hitag (@iceman1001)
|
||||
- Change NG: iso14a_raw_cmd_t, convert hf 14a raw, dual-mode reader handler (@iceman1001)
|
||||
- Support for flipper ISO15693.nfc dump files (@iceman100)
|
||||
- Change NG: convert CMD_LF_EM4X50_ESET to em4x50_eset_t (@iceman1001)
|
||||
|
||||
+18
-3
@@ -1585,7 +1585,7 @@ out:
|
||||
FillFileNameByUID(fptr, data, "-dump", HITAG_UID_SIZE);
|
||||
}
|
||||
|
||||
pm3_save_dump(filename, data, HITAG2_MAX_BYTE_SIZE, jsfHitag);
|
||||
pm3_save_dump(filename, data, HITAG2_MAX_BYTE_SIZE, jsfHitag2);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1763,13 +1763,15 @@ static int CmdLFHitagSim(const char *Cmd) {
|
||||
CLIParserInit(&ctx, "lf hitag sim",
|
||||
"Simulate Hitag transponder\n"
|
||||
"You need to `lf hitag eload` first",
|
||||
"lf hitag sim -2"
|
||||
"lf hitag sim -2\n"
|
||||
"lf hitag sim -2 -t 30 -> set edge detect threshold to 30"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("1", "ht1", "simulate Hitag 1"),
|
||||
arg_lit0("2", "ht2", "simulate Hitag 2"),
|
||||
arg_int0("t", "threshold", "<dec>", "set edge detect threshold (def: 127)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
@@ -1777,8 +1779,14 @@ static int CmdLFHitagSim(const char *Cmd) {
|
||||
bool use_ht1 = arg_get_lit(ctx, 1);
|
||||
bool use_ht2 = arg_get_lit(ctx, 2);
|
||||
bool use_htm = false; // not implemented yet
|
||||
int threshold = arg_get_int_def(ctx, 3, 127);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (threshold < 0 || threshold > 255) {
|
||||
PrintAndLogEx(ERR, "error, threshold must be 0..255");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if ((use_ht1 + use_ht2 + use_htm) > 1) {
|
||||
PrintAndLogEx(ERR, "error, specify only one Hitag type");
|
||||
return PM3_EINVARG;
|
||||
@@ -1792,8 +1800,15 @@ static int CmdLFHitagSim(const char *Cmd) {
|
||||
// if (use_ht1)
|
||||
// cmd = CMD_LF_HITAG1_SIMULATE;
|
||||
|
||||
// the tag content comes from emulator memory, this only carries the threshold
|
||||
hitag_sim_t payload = {
|
||||
.tag_mem_supplied = false,
|
||||
.rfu = 0,
|
||||
.threshold = (uint16_t)threshold,
|
||||
};
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(cmd, NULL, 0);
|
||||
SendCommandNG(cmd, (uint8_t *)&payload, sizeof(payload));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -650,7 +650,7 @@ static int CmdLFHitagSDump(const char *Cmd) {
|
||||
FillFileNameByUID(fptr, card->pages[HITAGS_UID_PADR], "-dump", HITAGS_PAGE_SIZE);
|
||||
}
|
||||
|
||||
pm3_save_dump(filename, (uint8_t *)card->pages, mem_size, jsfHitag);
|
||||
pm3_save_dump(filename, (uint8_t *)card->pages, mem_size, jsfHitagS);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -494,6 +494,17 @@ static int CmdLFHitagURead(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// A Hitag u reports its UID and IC revision separately from its pages, so
|
||||
// neither survives in the raw dump buffer. saveFileJSON's callback takes only
|
||||
// the json root, so park them here for the duration of the save.
|
||||
static uint8_t s_htu_uid[HITAGU_UID_SIZE] = {0};
|
||||
static uint8_t s_htu_icr = 0;
|
||||
|
||||
static void htu_json_callback(json_t *root) {
|
||||
JsonSaveBufAsHexCompact(root, "$.Card.UID", s_htu_uid, sizeof(s_htu_uid));
|
||||
JsonSaveBufAsHexCompact(root, "$.Card.ICR", &s_htu_icr, sizeof(s_htu_icr));
|
||||
}
|
||||
|
||||
static int CmdLFHitagUDump(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf hitag htu dump",
|
||||
@@ -587,7 +598,9 @@ static int CmdLFHitagUDump(const char *Cmd) {
|
||||
FillFileNameByUID(fptr, card->uid, "-dump", HITAGU_UID_SIZE);
|
||||
}
|
||||
|
||||
pm3_save_dump(filename, (uint8_t *)card->pages, mem_size, jsfHitag);
|
||||
memcpy(s_htu_uid, card->uid, sizeof(s_htu_uid));
|
||||
s_htu_icr = card->icr;
|
||||
pm3_save_dump_cb(filename, (uint8_t *)card->pages, mem_size, jsfHitagU, htu_json_callback);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
+73
-7
@@ -29,6 +29,7 @@
|
||||
#include "cmdhficlass.h" // pagemap
|
||||
#include "iclass_cmd.h"
|
||||
#include "iso15.h"
|
||||
#include "hitag.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "scandir.h"
|
||||
@@ -668,15 +669,53 @@ int prepareJSON(json_t *root, JSONFileType ftype, uint8_t *data, size_t datalen,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case jsfHitag: {
|
||||
uint8_t uid[4] = {0};
|
||||
memcpy(uid, data, 4);
|
||||
JsonSaveStr(root, "FileType", "hitag");
|
||||
JsonSaveBufAsHexCompact(root, "$.Card.UID", uid, sizeof(uid));
|
||||
// Hitag 1 and Hitag 2 both start with the UID in block 0. Hitag 2 also
|
||||
// carries its configuration in block 3, so record it when the dump is
|
||||
// long enough to hold one.
|
||||
case jsfHitag1:
|
||||
case jsfHitag2: {
|
||||
JsonSaveStr(root, "FileType", (ftype == jsfHitag1) ? "hitag1" : "hitag2");
|
||||
JsonSaveBufAsHexCompact(root, "$.Card.UID", data, HITAG_UID_SIZE);
|
||||
|
||||
for (size_t i = 0; i < (datalen / 4); i++) {
|
||||
if ((ftype == jsfHitag2) && (datalen >= 16)) {
|
||||
JsonSaveBufAsHexCompact(root, "$.Card.Config", data + 12, HITAG_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
JsonSaveInt(root, "$.Card.Blocks", (int)(datalen / HITAG_BLOCK_SIZE));
|
||||
|
||||
for (size_t i = 0; i < (datalen / HITAG_BLOCK_SIZE); i++) {
|
||||
snprintf(path, sizeof(path), "$.blocks.%zu", i);
|
||||
JsonSaveBufAsHexCompact(root, path, data + (i * 4), 4);
|
||||
JsonSaveBufAsHexCompact(root, path, data + (i * HITAG_BLOCK_SIZE), HITAG_BLOCK_SIZE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Hitag S keeps the UID in page 0 and the configuration in page 1
|
||||
case jsfHitagS: {
|
||||
JsonSaveStr(root, "FileType", "hitags");
|
||||
JsonSaveBufAsHexCompact(root, "$.Card.UID", data + (HITAGS_UID_PADR * HITAGS_PAGE_SIZE), HITAG_UID_SIZE);
|
||||
|
||||
if (datalen >= ((HITAGS_CONFIG_PADR + 1) * HITAGS_PAGE_SIZE)) {
|
||||
JsonSaveBufAsHexCompact(root, "$.Card.Config", data + (HITAGS_CONFIG_PADR * HITAGS_PAGE_SIZE), HITAGS_PAGE_SIZE);
|
||||
}
|
||||
|
||||
JsonSaveInt(root, "$.Card.Blocks", (int)(datalen / HITAGS_PAGE_SIZE));
|
||||
|
||||
for (size_t i = 0; i < (datalen / HITAGS_PAGE_SIZE); i++) {
|
||||
snprintf(path, sizeof(path), "$.blocks.%zu", i);
|
||||
JsonSaveBufAsHexCompact(root, path, data + (i * HITAGS_PAGE_SIZE), HITAGS_PAGE_SIZE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Hitag u has a 6 byte UID and an ICR that the tag reports separately from
|
||||
// its pages, so neither can be recovered from `data`. The caller supplies
|
||||
// them through the save callback, see pm3_save_dump_cb().
|
||||
case jsfHitagU: {
|
||||
JsonSaveStr(root, "FileType", "hitagu");
|
||||
JsonSaveInt(root, "$.Card.Blocks", (int)(datalen / HITAGU_BLOCK_SIZE));
|
||||
|
||||
for (size_t i = 0; i < (datalen / HITAGU_BLOCK_SIZE); i++) {
|
||||
snprintf(path, sizeof(path), "$.blocks.%zu", i);
|
||||
JsonSaveBufAsHexCompact(root, path, data + (i * HITAGU_BLOCK_SIZE), HITAGU_BLOCK_SIZE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2061,7 +2100,20 @@ int loadFileJSONex(const char *preferredName, void *data, size_t maxdatalen, siz
|
||||
goto out;
|
||||
}
|
||||
|
||||
// The four Hitag flavours share one block layout on disk and differ only in
|
||||
// how many blocks they carry, so one reader serves all of them. A file
|
||||
// written before the per-flavour types existed says only "hitag" and cannot
|
||||
// say which tag it came from - treat those as Hitag 2 and tell the user.
|
||||
if (!strcmp(ctype, "hitag")) {
|
||||
PrintAndLogEx(WARNING, "`" _YELLOW_("hitag") "` is the legacy dump type and does not record which tag it came from");
|
||||
PrintAndLogEx(INFO, "Reading it as " _YELLOW_("Hitag 2") ", re-dump the tag to get a versioned file");
|
||||
}
|
||||
|
||||
if (!strcmp(ctype, "hitag") ||
|
||||
!strcmp(ctype, "hitag1") ||
|
||||
!strcmp(ctype, "hitag2") ||
|
||||
!strcmp(ctype, "hitags") ||
|
||||
!strcmp(ctype, "hitagu")) {
|
||||
size_t sptr = 0;
|
||||
for (int i = 0; i < (maxdatalen / 4); i++) {
|
||||
if (sptr + 4 > maxdatalen) {
|
||||
@@ -3929,6 +3981,20 @@ int pm3_save_dump(const char *fn, uint8_t *d, size_t n, JSONFileType jsft) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int pm3_save_dump_cb(const char *fn, uint8_t *d, size_t n, JSONFileType jsft, void (*callback)(json_t *)) {
|
||||
if (fn == NULL || strlen(fn) == 0) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (d == NULL || n == 0) {
|
||||
PrintAndLogEx(INFO, "No data to save, skipping...");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
saveFile(fn, ".bin", d, n);
|
||||
saveFileJSON(fn, jsft, d, n, callback);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int pm3_save_mf_dump(const char *fn, uint8_t *d, size_t n, JSONFileType jsft) {
|
||||
|
||||
if (fn == NULL || d == NULL || n == 0) {
|
||||
|
||||
@@ -50,7 +50,10 @@ typedef enum {
|
||||
jsfMfc_v2,
|
||||
jsfMfc_v3,
|
||||
jsfMfuMemory,
|
||||
jsfHitag,
|
||||
jsfHitag1,
|
||||
jsfHitag2,
|
||||
jsfHitagS,
|
||||
jsfHitagU,
|
||||
jsfIclass,
|
||||
jsf14b,
|
||||
jsf14b_v2,
|
||||
@@ -442,6 +445,9 @@ int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumpl
|
||||
* @return PM3_SUCCESS if OK
|
||||
*/
|
||||
int pm3_save_dump(const char *fn, uint8_t *d, size_t n, JSONFileType jsft);
|
||||
// as pm3_save_dump, but lets the caller add fields the raw dump cannot carry,
|
||||
// such as the Hitag u UID and ICR which arrive separately from the pages
|
||||
int pm3_save_dump_cb(const char *fn, uint8_t *d, size_t n, JSONFileType jsft, void (*callback)(json_t *));
|
||||
int pm3_save_dump_json(const char *fn, uint8_t *d, size_t n, JSONFileType jsft);
|
||||
|
||||
/** STUB
|
||||
|
||||
Reference in new issue
Block a user