mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 02:27:26 -07:00
refactoring loading dump files
This commit is contained in:
parent
d430f51276
commit
d4c3082741
6 changed files with 84 additions and 162 deletions
|
@ -36,8 +36,6 @@
|
|||
#include "cmdhf14a.h" // exchange APDU
|
||||
#include "crypto/libpcrypto.h"
|
||||
|
||||
#define MFBLOCK_SIZE 16
|
||||
|
||||
#define MIFARE_4K_MAXBLOCK 256
|
||||
#define MIFARE_2K_MAXBLOCK 128
|
||||
#define MIFARE_1K_MAXBLOCK 64
|
||||
|
@ -264,7 +262,7 @@ static void mf_print_blocks(uint16_t n, uint8_t *d, bool verbose) {
|
|||
PrintAndLogEx(HINT, _CYAN_("cyan") " = value block with decoded value");
|
||||
|
||||
// MAD detection
|
||||
if (memcmp(d + (3 * MFBLOCK_SIZE), g_mifare_mad_key, 6) == 0) {
|
||||
if (HasMADKey(d)) {
|
||||
PrintAndLogEx(HINT, "MAD key detected. Try " _YELLOW_("`hf mf mad`") " for more details");
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
@ -1110,38 +1108,11 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
|||
}
|
||||
|
||||
// read dump file
|
||||
bytes_read = 0;
|
||||
uint8_t *dump = NULL;
|
||||
int res = 0;
|
||||
DumpFileType_t dftype = getfiletype(datafilename);
|
||||
switch (dftype) {
|
||||
case BIN: {
|
||||
res = loadFile_safe(datafilename, ".bin", (void **)&dump, &bytes_read);
|
||||
break;
|
||||
}
|
||||
case EML: {
|
||||
res = loadFileEML_safe(datafilename, (void **)&dump, &bytes_read);
|
||||
break;
|
||||
}
|
||||
case JSON: {
|
||||
dump = calloc(MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK, sizeof(uint8_t));
|
||||
if (dump == NULL) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
res = loadFileJSON(datafilename, (void *)dump, MIFARE_4K_MAXBLOCK * MFBLOCK_SIZE, &bytes_read, NULL);
|
||||
break;
|
||||
}
|
||||
case DICTIONARY: {
|
||||
PrintAndLogEx(ERR, "Error: Only BIN/JSON/EML formats allowed");
|
||||
free(dump);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
||||
bytes_read = 0;
|
||||
int res = pm3_load_dump(datafilename, (void **)&dump, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK));
|
||||
if (res != PM3_SUCCESS) {
|
||||
free(dump);
|
||||
return PM3_EFILE;
|
||||
return res;
|
||||
}
|
||||
|
||||
// default authentication key
|
||||
|
@ -3944,41 +3915,14 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
|||
}
|
||||
|
||||
uint8_t *data = NULL;
|
||||
size_t datalen = 0;
|
||||
int res = PM3_SUCCESS;
|
||||
DumpFileType_t dftype = getfiletype(filename);
|
||||
switch (dftype) {
|
||||
case BIN: {
|
||||
res = loadFile_safe(filename, ".bin", (void **)&data, &datalen);
|
||||
break;
|
||||
}
|
||||
case EML: {
|
||||
res = loadFileEML_safe(filename, (void **)&data, &datalen);
|
||||
break;
|
||||
}
|
||||
case JSON: {
|
||||
data = calloc(MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK, sizeof(uint8_t));
|
||||
if (data == NULL) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
res = loadFileJSON(filename, (void *)data, MIFARE_4K_MAXBLOCK * MFBLOCK_SIZE, &datalen, NULL);
|
||||
break;
|
||||
}
|
||||
case DICTIONARY: {
|
||||
PrintAndLogEx(ERR, "Error: Only BIN/JSON/EML formats allowed");
|
||||
free(data);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
||||
size_t bytes_read = 0;
|
||||
int res = pm3_load_dump(filename, (void **)&data, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK));
|
||||
if (res != PM3_SUCCESS) {
|
||||
free(data);
|
||||
return PM3_EFILE;
|
||||
return res;
|
||||
}
|
||||
|
||||
// 64 or 256 blocks.
|
||||
if ((datalen % block_width) != 0) {
|
||||
if ((bytes_read % block_width) != 0) {
|
||||
PrintAndLogEx(FAILED, "File content error. Size doesn't match blockwidth ");
|
||||
free(data);
|
||||
return PM3_ESOFT;
|
||||
|
@ -3986,7 +3930,7 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
|||
|
||||
// convert plain or old mfu format to new format
|
||||
if (block_width == MFU_BLOCK_SIZE) {
|
||||
res = convert_mfu_dump_format(&data, &datalen, true);
|
||||
res = convert_mfu_dump_format(&data, &bytes_read, true);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(FAILED, "Failed convert on load to new Ultralight/NTAG format");
|
||||
free(data);
|
||||
|
@ -3997,7 +3941,7 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
|||
printMFUdumpEx(mfu_dump, mfu_dump->pages + 1, 0);
|
||||
|
||||
// update expected blocks to match converted data.
|
||||
block_cnt = datalen / MFU_BLOCK_SIZE;
|
||||
block_cnt = bytes_read / MFU_BLOCK_SIZE;
|
||||
PrintAndLogEx(INFO, "MIFARE Ultralight override, will use %d blocks ( %u bytes )", block_cnt, block_cnt * block_width);
|
||||
}
|
||||
|
||||
|
@ -4010,8 +3954,8 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
|||
size_t offset = 0;
|
||||
int cnt = 0;
|
||||
|
||||
while (datalen && cnt < block_cnt) {
|
||||
if (datalen == block_width) {
|
||||
while (bytes_read && cnt < block_cnt) {
|
||||
if (bytes_read == block_width) {
|
||||
// Disable fast mode on last packet
|
||||
g_conn.block_after_ACK = false;
|
||||
}
|
||||
|
@ -4026,7 +3970,7 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
|||
|
||||
cnt++;
|
||||
offset += block_width;
|
||||
datalen -= block_width;
|
||||
bytes_read -= block_width;
|
||||
}
|
||||
free(data);
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
@ -4642,38 +4586,12 @@ static int CmdHF14AMfCLoad(const char *Cmd) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// reserve memory
|
||||
uint8_t *data = NULL;
|
||||
size_t bytes_read = 0;
|
||||
int res = 0;
|
||||
DumpFileType_t dftype = getfiletype(filename);
|
||||
switch (dftype) {
|
||||
case BIN: {
|
||||
res = loadFile_safe(filename, ".bin", (void **)&data, &bytes_read);
|
||||
break;
|
||||
}
|
||||
case EML: {
|
||||
res = loadFileEML_safe(filename, (void **)&data, &bytes_read);
|
||||
break;
|
||||
}
|
||||
case JSON: {
|
||||
data = calloc(MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK, sizeof(uint8_t));
|
||||
if (data == NULL) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
res = loadFileJSON(filename, (void *)data, MIFARE_4K_MAXBLOCK * MFBLOCK_SIZE, &bytes_read, NULL);
|
||||
break;
|
||||
}
|
||||
case DICTIONARY: {
|
||||
PrintAndLogEx(ERR, "Error: Only BIN/JSON/EML formats allowed");
|
||||
free(data);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
||||
int res = pm3_load_dump(filename, (void **)&data, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK));
|
||||
if (res != PM3_SUCCESS) {
|
||||
free(data);
|
||||
return PM3_EFILE;
|
||||
return res;
|
||||
}
|
||||
|
||||
// 64 or 256blocks.
|
||||
|
@ -5430,37 +5348,9 @@ static int CmdHF14AMfMAD(const char *Cmd) {
|
|||
// reserve memory
|
||||
uint8_t *dump = NULL;
|
||||
size_t bytes_read = 0;
|
||||
int res = 0;
|
||||
DumpFileType_t dftype = getfiletype(filename);
|
||||
switch (dftype) {
|
||||
case BIN: {
|
||||
res = loadFile_safe(filename, ".bin", (void **)&dump, &bytes_read);
|
||||
break;
|
||||
}
|
||||
case EML: {
|
||||
res = loadFileEML_safe(filename, (void **)&dump, &bytes_read);
|
||||
break;
|
||||
}
|
||||
case JSON: {
|
||||
dump = calloc(MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK, sizeof(uint8_t));
|
||||
if (dump == NULL) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
res = loadFileJSON(filename, (void *)dump, MIFARE_4K_MAXBLOCK * MFBLOCK_SIZE, &bytes_read, NULL);
|
||||
break;
|
||||
}
|
||||
case DICTIONARY: {
|
||||
PrintAndLogEx(ERR, "Error: Only BIN/JSON/EML formats allowed");
|
||||
free(dump);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
||||
int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK));
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename);
|
||||
free(dump);
|
||||
return PM3_EFILE;
|
||||
return res;
|
||||
}
|
||||
|
||||
uint16_t block_cnt = MIN(MIFARE_1K_MAXBLOCK, (bytes_read / MFBLOCK_SIZE));
|
||||
|
@ -5477,7 +5367,7 @@ static int CmdHF14AMfMAD(const char *Cmd) {
|
|||
}
|
||||
|
||||
// MAD detection
|
||||
if (memcmp(dump + (3 * MFBLOCK_SIZE), g_mifare_mad_key, 6) != 0) {
|
||||
if (HasMADKey(dump)) {
|
||||
PrintAndLogEx(FAILED, "No MAD key was detected in the dump file");
|
||||
free(dump);
|
||||
return PM3_ESOFT;
|
||||
|
@ -6249,40 +6139,12 @@ static int CmdHF14AMfView(const char *Cmd) {
|
|||
bool verbose = arg_get_lit(ctx, 2);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// reserve memory
|
||||
// read dump file
|
||||
uint8_t *dump = NULL;
|
||||
size_t bytes_read = 0;
|
||||
int res = 0;
|
||||
DumpFileType_t dftype = getfiletype(filename);
|
||||
switch (dftype) {
|
||||
case BIN: {
|
||||
res = loadFile_safe(filename, ".bin", (void **)&dump, &bytes_read);
|
||||
break;
|
||||
}
|
||||
case EML: {
|
||||
res = loadFileEML_safe(filename, (void **)&dump, &bytes_read);
|
||||
break;
|
||||
}
|
||||
case JSON: {
|
||||
dump = calloc(MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK, sizeof(uint8_t));
|
||||
if (dump == NULL) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
res = loadFileJSON(filename, (void *)dump, MIFARE_4K_MAXBLOCK * MFBLOCK_SIZE, &bytes_read, NULL);
|
||||
break;
|
||||
}
|
||||
case DICTIONARY: {
|
||||
PrintAndLogEx(ERR, "Error: Only BIN/JSON/EML formats allowed");
|
||||
free(dump);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
||||
int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK));
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename);
|
||||
free(dump);
|
||||
return PM3_EFILE;
|
||||
return res;
|
||||
}
|
||||
|
||||
uint16_t block_cnt = MIN(MIFARE_1K_MAXBLOCK, (bytes_read / MFBLOCK_SIZE));
|
||||
|
|
|
@ -83,7 +83,7 @@ DumpFileType_t getfiletype(const char *filename) {
|
|||
} else if (str_endswith(s, "json")) {
|
||||
o = JSON;
|
||||
} else if (str_endswith(s, "dic")) {
|
||||
o = DICTIONARY;
|
||||
o = DICTIONARY;
|
||||
} else {
|
||||
// mfd, trc, trace is binary
|
||||
o = BIN;
|
||||
|
@ -1880,3 +1880,41 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con
|
|||
free(filename);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumplen) {
|
||||
|
||||
int res = 0;
|
||||
DumpFileType_t dftype = getfiletype(fn);
|
||||
switch (dftype) {
|
||||
case BIN: {
|
||||
res = loadFile_safe(fn, ".bin", pdump, dumplen);
|
||||
break;
|
||||
}
|
||||
case EML: {
|
||||
res = loadFileEML_safe(fn, pdump, dumplen);
|
||||
break;
|
||||
}
|
||||
case JSON: {
|
||||
*pdump = calloc(maxdumplen, sizeof(uint8_t));
|
||||
if (*pdump == NULL) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
res = loadFileJSON(fn, *pdump, maxdumplen, dumplen, NULL);
|
||||
break;
|
||||
}
|
||||
case DICTIONARY: {
|
||||
PrintAndLogEx(ERR, "Error: Only BIN/EML/JSON formats allowed");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", fn);
|
||||
PrintAndLogEx(INFO, "%d", res);
|
||||
free(*pdump);
|
||||
return PM3_EFILE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
|
@ -260,4 +260,16 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con
|
|||
* @return
|
||||
*/
|
||||
DumpFileType_t getfiletype(const char *filename);
|
||||
|
||||
|
||||
/**
|
||||
* @brief load dump file into a data array dynamically allocated
|
||||
* @param fn
|
||||
* @param pdump pointer to loaded dump
|
||||
* @param dumplen the number of bytes loaded from dump file
|
||||
* @param maxdumplen maximum size of data array in bytes (JSON files)
|
||||
* @return PM3_SUCCESS if OK
|
||||
*/
|
||||
int pm3_load_dump(const char *fn, void **pdump, size_t *dumplen, size_t maxdumplen);
|
||||
|
||||
#endif // FILEUTILS_H
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "util.h"
|
||||
#include "fileutils.h"
|
||||
#include "jansson.h"
|
||||
#include "mifaredefault.h"
|
||||
|
||||
// https://www.nxp.com/docs/en/application-note/AN10787.pdf
|
||||
static json_t *mad_known_aids = NULL;
|
||||
|
@ -396,3 +397,10 @@ int MADDFDecodeAndPrint(uint32_t short_aid) {
|
|||
close_mad_file(mad_known_aids);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
bool HasMADKey(uint8_t *d) {
|
||||
if (d == NULL)
|
||||
return false;
|
||||
|
||||
return (memcmp(d + (3 * MFBLOCK_SIZE), g_mifare_mad_key, 6) != 0);
|
||||
}
|
|
@ -28,5 +28,5 @@ int MAD2DecodeAndPrint(uint8_t *sector, bool swapmad, bool verbose);
|
|||
int MADDFDecodeAndPrint(uint32_t short_aid);
|
||||
int MADCardHolderInfoDecode(uint8_t *data, size_t datalen, bool verbose);
|
||||
void MADPrintHeader(void);
|
||||
|
||||
bool HasMADKey(uint8_t *d);
|
||||
#endif // _MAD_H_
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#define MFBLOCK_SIZE 16
|
||||
|
||||
static const uint64_t g_mifare_default_keys[] = {
|
||||
0xffffffffffff, // Default key (first key used by program if no user defined key)
|
||||
0x000000000000, // Blank key
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue