diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 327069971..b5be04593 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1553,7 +1553,6 @@ int usage_hf_mfu_pwdgen(void){ return 0; } -#define DUMP_PREFIX_LENGTH 48 void printMFUdump(mfu_dump_t* card) { printMFUdumpEx(card, 255, 0); } @@ -1659,9 +1658,9 @@ void printMFUdumpEx(mfu_dump_t* card, uint16_t pages, uint8_t startpage) { // Read and Dump Card Contents, using auto detection of tag size. int CmdHF14AMfUDump(const char *Cmd){ - FILE *fout; + uint8_t fileNameLen = 0; char filename[FILE_PATH_SIZE] = {0x00}; - char *fnameptr = filename; + char *fptr = filename; uint8_t data[1024] = {0x00}; memset(data, 0x00, sizeof(data)); @@ -1674,7 +1673,7 @@ int CmdHF14AMfUDump(const char *Cmd){ uint8_t authenticationkey[16] = {0x00}; memset(authenticationkey, 0x00, sizeof(authenticationkey)); uint8_t *authKeyPtr = authenticationkey; - size_t fileNlen = 0; + bool errors = false; bool swapEndian = false; bool manualPages = false; @@ -1703,9 +1702,7 @@ int CmdHF14AMfUDump(const char *Cmd){ cmdp++; break; case 'f': - fileNlen = param_getstr(Cmd, cmdp+1, filename, sizeof(filename)); - if (!fileNlen) errors = true; - if (fileNlen > FILE_PATH_SIZE-5) fileNlen = FILE_PATH_SIZE-5; + fileNameLen = param_getstr(Cmd, cmdp+1, filename, sizeof(filename)); cmdp += 2; break; case 'p': //set start page @@ -1785,9 +1782,9 @@ int CmdHF14AMfUDump(const char *Cmd){ pages = bufferSize/4; - uint8_t get_pack[] = {0,0}; iso14a_card_select_t card; 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}; @@ -1801,8 +1798,8 @@ int CmdHF14AMfUDump(const char *Cmd){ //attempt to read pack if (!ul_auth_select( &card, tagtype, true, authKeyPtr, get_pack, sizeof(get_pack))) { //reset pack - get_pack[0]=0; - get_pack[1]=0; + get_pack[0] = 0; + get_pack[1] = 0; } DropField(); @@ -1864,23 +1861,16 @@ int CmdHF14AMfUDump(const char *Cmd){ printMFUdumpEx(&dump_file_data, pages, startPage); // user supplied filename? - if (fileNlen < 1) { - // UID = data 0-1-2 4-5-6-7 (skips a beat) - sprintf(fnameptr,"%02X%02X%02X%02X%02X%02X%02X.bin", - data[0],data[1], data[2], data[4],data[5],data[6], data[7]); - } else { - sprintf(fnameptr + fileNlen,".bin"); - } + if (fileNameLen < 1) { - if ((fout = fopen(filename,"wb")) == NULL) { - PrintAndLogEx(WARNING, "Could not create file name %s", filename); - return 1; - } - fwrite( &dump_file_data, 1, pages*4 + DUMP_PREFIX_LENGTH, fout ); - if (fout) - fclose(fout); - - PrintAndLogEx(SUCCESS, "Dumped %d pages, wrote %d bytes to %s", pages + (DUMP_PREFIX_LENGTH/4), pages*4 + DUMP_PREFIX_LENGTH, filename); + PrintAndLogEx(INFO, "Using UID as filename"); + + fptr += sprintf(fptr, "hf-mfu-"); + FillFileNameByUID(fptr, card.uid, "-dump", card.uidlen); + } + uint16_t datalen = pages*4 + DUMP_PREFIX_LENGTH; + saveFile(filename, "bin", (uint8_t*)&dump_file_data, datalen); + saveFileJSON(filename, "json", jsfMfuMemory, (uint8_t*)&dump_file_data, datalen); if ( is_partial ) PrintAndLogEx(WARNING, "Partial dump created. (%d of %d blocks)", pages, card_mem_size); diff --git a/client/cmdhfmfu.h b/client/cmdhfmfu.h index 491218b1b..b03444839 100644 --- a/client/cmdhfmfu.h +++ b/client/cmdhfmfu.h @@ -10,6 +10,9 @@ #include "util.h" #include "protocols.h" #include "comms.h" +#include "loclass/fileutils.h" + +#define DUMP_PREFIX_LENGTH 48 typedef struct { uint8_t version[8]; diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index 367b19c97..b099d6a35 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -208,6 +208,34 @@ int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType fty } } break; + case jsfMfuMemory: + JsonSaveStr(root, "FileType", "mfu"); + + mfu_dump_t* tmp = (mfu_dump_t*)data; + + uint8_t uid[7] = {0}; + memcpy(uid, tmp->data, 3); + memcpy(uid+3, tmp->data+4, 4); + + 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"); + + // size of header 48b + size_t len = (datalen - DUMP_PREFIX_LENGTH) / 4; + + for (int i = 0; i < len; i++) { + + char path[PATH_MAX_LENGTH] = {0}; + sprintf(path, "$.blocks.%d", i); + JsonSaveBufAsHexCompact(root, path, tmp->data + (i * 4), 4); + } + break; } int res = json_dump_file(root, fileName, JSON_INDENT(2)); @@ -395,6 +423,29 @@ int loadFileJSON(const char *preferredName, const char *suffix, void* data, size *datalen = sptr; } + if (!strcmp(ctype, "mfu")) { + size_t sptr = 0; + for (int i = 0; i < 256; i++) { + if (sptr + 4 > maxdatalen) { + retval = 5; + goto out; + } + + char path[30] = {0}; + sprintf(path, "$.blocks.%d", i); + + size_t len = 0; + JsonLoadBufAsHex(root, path, &udata[sptr], 4, &len); + if (!len) + break; + + sptr += len; + } + + *datalen = sptr; + } + + PrintAndLog("Loaded JSON: (%s) OK.", fileName); out: json_decref(root); diff --git a/client/loclass/fileutils.h b/client/loclass/fileutils.h index 3852b4bf4..b73f5fc30 100644 --- a/client/loclass/fileutils.h +++ b/client/loclass/fileutils.h @@ -49,10 +49,12 @@ #include "../ui.h" #include "../emv/emvjson.h" #include "mifare4.h" +#include "cmdhfmfu.h" typedef enum { jsfRaw, jsfCardMemory, + jsfMfuMemory, } JSONFileType; int fileExists(const char *filename);