UL/NTAG new dump file format. Added counters support, simulation

This commit is contained in:
Eloff
2019-04-21 03:18:00 +03:00
parent c7a4d7af3a
commit db3103b531
9 changed files with 123 additions and 74 deletions

View File

@@ -1619,11 +1619,15 @@ void printMFUdumpEx(mfu_dump_t *card, uint16_t pages, uint8_t startpage) {
PrintAndLogEx(NORMAL, "----------+-------------------------+---------");
PrintAndLogEx(NORMAL, "Version | %s| %s", sprint_hex(card->version, sizeof(card->version)), sprint_ascii(card->version, sizeof(card->version)));
PrintAndLogEx(NORMAL, "TBD | %-24s| %s", sprint_hex(card->tbo, sizeof(card->tbo)), sprint_ascii(card->tbo, sizeof(card->tbo)));
PrintAndLogEx(NORMAL, "Tearing | %-24s| %s", sprint_hex(card->tearing, sizeof(card->tearing)), sprint_ascii(card->tearing, sizeof(card->tearing)));
PrintAndLogEx(NORMAL, "Pack | %-24s| %s", sprint_hex(card->pack, sizeof(card->pack)), sprint_ascii(card->pack, sizeof(card->pack)));
PrintAndLogEx(NORMAL, "TBD | %-24s| %s", sprint_hex(card->tbo1, sizeof(card->tbo1)), sprint_ascii(card->tbo1, sizeof(card->tbo1)));
PrintAndLogEx(NORMAL, "Signature1| %s| %s", sprint_hex(card->signature, 16), sprint_ascii(card->signature, 16));
PrintAndLogEx(NORMAL, "Signature2| %s| %s", sprint_hex(card->signature + 16, 16), sprint_ascii(card->signature + 16, 16));
PrintAndLogEx(NORMAL, "Counter0 | %-24s| %s", sprint_hex(card->counter_tearing[0], 3), sprint_ascii(card->counter_tearing[0], 3));
PrintAndLogEx(NORMAL, "Tearing0 | %-24s| %s", sprint_hex(card->counter_tearing[0] + 3, 1), sprint_ascii(card->counter_tearing[0] + 3, 1));
PrintAndLogEx(NORMAL, "Counter1 | %-24s| %s", sprint_hex(card->counter_tearing[1], 3), sprint_ascii(card->counter_tearing[1], 3));
PrintAndLogEx(NORMAL, "Tearing1 | %-24s| %s", sprint_hex(card->counter_tearing[1] + 3, 1), sprint_ascii(card->counter_tearing[1] + 3, 1));
PrintAndLogEx(NORMAL, "Counter2 | %-24s| %s", sprint_hex(card->counter_tearing[2], 3), sprint_ascii(card->counter_tearing[2], 3));
PrintAndLogEx(NORMAL, "Tearing3 | %-24s| %s", sprint_hex(card->counter_tearing[2] + 3, 1), sprint_ascii(card->counter_tearing[2] + 3, 1));
PrintAndLogEx(NORMAL, "-------------------------------------------------------------");
PrintAndLogEx(NORMAL, "\nBlock# | Data |lck| Ascii");
PrintAndLogEx(NORMAL, "---------+-------------+---+------");
@@ -1889,8 +1893,7 @@ static int CmdHF14AMfUDump(const char *Cmd) {
mfu_dump_t dump_file_data;
uint8_t get_pack[] = {0, 0};
uint8_t get_version[] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t get_tearing[] = {0, 0, 0};
uint8_t get_counter[] = {0, 0, 0};
uint8_t get_counter_tearing[][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};
uint8_t dummy_pack[] = {0, 0};
uint8_t get_signature[32];
memset(get_signature, 0, sizeof(get_signature));
@@ -1920,8 +1923,8 @@ static int CmdHF14AMfUDump(const char *Cmd) {
ulev1_getVersion(get_version, sizeof(get_version));
for (uint8_t n = 0; n < 3; ++n) {
ulev1_readTearing(n, get_tearing + n, 1);
ulev1_readCounter(n, get_counter, sizeof(get_counter));
ulev1_readTearing(n, &get_counter_tearing[n][3], 1);
ulev1_readCounter(n, &get_counter_tearing[n][0], 3);
}
DropField();
@@ -1935,7 +1938,8 @@ static int CmdHF14AMfUDump(const char *Cmd) {
}
// format and add keys to block dump output
if (hasAuthKey) {
// only add keys if not partial read, and complete pages read
if (!is_partial && pages == card_mem_size && hasAuthKey) {
// if we didn't swapendian before - do it now for the sprint_hex call
// NOTE: default entry is bigendian (unless swapped), sprint_hex outputs little endian
// need to swap to keep it the same
@@ -1954,11 +1958,11 @@ static int CmdHF14AMfUDump(const char *Cmd) {
}
//add *special* blocks to dump
//iceman: need to add counters and pwd values to the dump format
// pack and pwd saved into last pages of dump, if was not partial read
dump_file_data.pages = pages - 1;
memcpy(dump_file_data.version, get_version, sizeof(dump_file_data.version));
memcpy(dump_file_data.tearing, get_tearing, sizeof(dump_file_data.tearing));
memcpy(dump_file_data.pack, get_pack, sizeof(dump_file_data.pack));
memcpy(dump_file_data.signature, get_signature, sizeof(dump_file_data.signature));
memcpy(dump_file_data.counter_tearing, get_counter_tearing, sizeof(dump_file_data.counter_tearing));
memcpy(dump_file_data.data, data, pages * 4);
printMFUdumpEx(&dump_file_data, pages, startPage);
@@ -2092,16 +2096,22 @@ static int CmdHF14AMfURestore(const char *Cmd) {
// read all data
size_t bytes_read = fread(dump, 1, fsize, f);
fclose(f);
if (bytes_read < 48) {
if (bytes_read < DUMP_PREFIX_LENGTH) {
PrintAndLogEx(WARNING, "Error, dump file is too small");
free(dump);
return 1;
}
PrintAndLogEx(INFO, "Restoring " _YELLOW_("%s")" to card", filename);
mfu_dump_t *mem = (mfu_dump_t *)dump;
uint8_t pages = (bytes_read - 48) / 4;
uint8_t pages = (bytes_read - DUMP_PREFIX_LENGTH) / 4;
if (pages - 1 != mem->pages) {
PrintAndLogEx(WARNING, "Error, invalid dump, wrong page count");
free(dump);
return 1;
}
PrintAndLogEx(INFO, "Restoring " _YELLOW_("%s")" to card", filename);
// print dump
printMFUdumpEx(mem, pages, 0);
@@ -2134,7 +2144,7 @@ static int CmdHF14AMfURestore(const char *Cmd) {
if (read_key) {
// try reading key from dump and use.
memcpy(c.d.asBytes, mem->data + (bytes_read - 48 - 8), 4);
memcpy(c.d.asBytes, mem->data + (bytes_read - DUMP_PREFIX_LENGTH - 8), 4);
} else {
memcpy(c.d.asBytes, p_authkey, 4);
}
@@ -2150,10 +2160,9 @@ static int CmdHF14AMfURestore(const char *Cmd) {
memcpy(c.d.asBytes + 4, authkey, 4);
}
// pack
// pack now stored in dump
c.arg[0] = MFU_NTAG_SPECIAL_PACK;
c.d.asBytes[0] = mem->pack[0];
c.d.asBytes[1] = mem->pack[1];
memcpy(c.d.asBytes, mem->data + (bytes_read - DUMP_PREFIX_LENGTH - 4), 2);
c.d.asBytes[2] = 0;
c.d.asBytes[3] = 0;
PrintAndLogEx(NORMAL, "special PACK block written 0x%X - %s\n", MFU_NTAG_SPECIAL_PACK, sprint_hex(c.d.asBytes, 4));

View File

@@ -12,16 +12,16 @@
#include "comms.h"
#include "loclass/fileutils.h"
#define DUMP_PREFIX_LENGTH 48
// Length must be aligned to 4 bytes (UL/NTAG page)
#define DUMP_PREFIX_LENGTH 56
typedef struct {
uint8_t version[8];
uint8_t tbo[2];
uint8_t tearing[3];
uint8_t pack[2];
uint8_t tbo1[1];
uint8_t pages; // max page number in dump
uint8_t signature[32];
//uint8_t counter[3];
uint8_t counter_tearing[3][4]; // 3 bytes counter, 1 byte tearing flag
uint8_t data[1024];
} mfu_dump_t;

View File

@@ -221,13 +221,16 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty
JsonSaveBufAsHexCompact(root, "$.Card.UID", uid, sizeof(uid));
JsonSaveBufAsHexCompact(root, "$.Card.Version", tmp->version, sizeof(tmp->version));
JsonSaveBufAsHexCompact(root, "$.Card.TBO_0", tmp->tbo, sizeof(tmp->tbo));
JsonSaveBufAsHexCompact(root, "$.Card.Tearing", tmp->tearing, sizeof(tmp->tearing));
JsonSaveBufAsHexCompact(root, "$.Card.Pack", tmp->pack, sizeof(tmp->pack));
JsonSaveBufAsHexCompact(root, "$.Card.TBO_1", tmp->tbo1, sizeof(tmp->tbo1));
JsonSaveBufAsHexCompact(root, "$.Card.Signature", tmp->signature, sizeof(tmp->signature));
JsonSaveStr(root, "$.Card.Counter", "N/A");
JsonSaveBufAsHexCompact(root, "$.Card.Counter0", tmp->counter_tearing[0], 3);
JsonSaveBufAsHexCompact(root, "$.Card.Tearing0", tmp->counter_tearing[0] + 3, 1);
JsonSaveBufAsHexCompact(root, "$.Card.Counter1", tmp->counter_tearing[1], 3);
JsonSaveBufAsHexCompact(root, "$.Card.Tearing1", tmp->counter_tearing[1] + 3, 1);
JsonSaveBufAsHexCompact(root, "$.Card.Counter2", tmp->counter_tearing[2], 3);
JsonSaveBufAsHexCompact(root, "$.Card.Tearing2", tmp->counter_tearing[2] + 3, 1);
// size of header 48b
// size of header 56b
size_t len = (datalen - DUMP_PREFIX_LENGTH) / 4;
for (size_t i = 0; i < len; i++) {

View File

@@ -104,11 +104,11 @@ local function main(args)
-- lua uses start index and endindex, not count.
-- UID is 3three skip bcc0 then 4bytes.
-- 1 lua is one-index.
-- 1 + 96 (48*2) new dump format has version/signature/counter data here
-- 97,98,99,100,101,102 UID first three bytes
-- 103,104 bcc0
-- 105--- UID last four bytes
local uid = string.sub(dumpdata, 97, 97+5)..string.sub(dumpdata, 97+8, 97+8+7)
-- 1 + 112 (56*2) new dump format has version/signature/counter data here
-- 113,114,115,116,117,118 UID first three bytes
-- 119,120 bcc0
-- 121--- UID last four bytes
local uid = string.sub(dumpdata, 113, 113+5)..string.sub(dumpdata, 113+8, 113+8+7)
output = output or (uid .. ".eml")
-- Format some linebreaks