mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -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 "cmdhf14a.h" // exchange APDU
|
||||||
#include "crypto/libpcrypto.h"
|
#include "crypto/libpcrypto.h"
|
||||||
|
|
||||||
#define MFBLOCK_SIZE 16
|
|
||||||
|
|
||||||
#define MIFARE_4K_MAXBLOCK 256
|
#define MIFARE_4K_MAXBLOCK 256
|
||||||
#define MIFARE_2K_MAXBLOCK 128
|
#define MIFARE_2K_MAXBLOCK 128
|
||||||
#define MIFARE_1K_MAXBLOCK 64
|
#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");
|
PrintAndLogEx(HINT, _CYAN_("cyan") " = value block with decoded value");
|
||||||
|
|
||||||
// MAD detection
|
// 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(HINT, "MAD key detected. Try " _YELLOW_("`hf mf mad`") " for more details");
|
||||||
}
|
}
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
@ -1110,38 +1108,11 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// read dump file
|
// read dump file
|
||||||
bytes_read = 0;
|
|
||||||
uint8_t *dump = NULL;
|
uint8_t *dump = NULL;
|
||||||
int res = 0;
|
bytes_read = 0;
|
||||||
DumpFileType_t dftype = getfiletype(datafilename);
|
int res = pm3_load_dump(datafilename, (void **)&dump, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK));
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
free(dump);
|
return res;
|
||||||
return PM3_EFILE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// default authentication key
|
// default authentication key
|
||||||
|
@ -3944,41 +3915,14 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *data = NULL;
|
uint8_t *data = NULL;
|
||||||
size_t datalen = 0;
|
size_t bytes_read = 0;
|
||||||
int res = PM3_SUCCESS;
|
int res = pm3_load_dump(filename, (void **)&data, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK));
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
free(data);
|
return res;
|
||||||
return PM3_EFILE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 64 or 256 blocks.
|
// 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 ");
|
PrintAndLogEx(FAILED, "File content error. Size doesn't match blockwidth ");
|
||||||
free(data);
|
free(data);
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
@ -3986,7 +3930,7 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
||||||
|
|
||||||
// convert plain or old mfu format to new format
|
// convert plain or old mfu format to new format
|
||||||
if (block_width == MFU_BLOCK_SIZE) {
|
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) {
|
if (res != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(FAILED, "Failed convert on load to new Ultralight/NTAG format");
|
PrintAndLogEx(FAILED, "Failed convert on load to new Ultralight/NTAG format");
|
||||||
free(data);
|
free(data);
|
||||||
|
@ -3997,7 +3941,7 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
||||||
printMFUdumpEx(mfu_dump, mfu_dump->pages + 1, 0);
|
printMFUdumpEx(mfu_dump, mfu_dump->pages + 1, 0);
|
||||||
|
|
||||||
// update expected blocks to match converted data.
|
// 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);
|
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;
|
size_t offset = 0;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
while (datalen && cnt < block_cnt) {
|
while (bytes_read && cnt < block_cnt) {
|
||||||
if (datalen == block_width) {
|
if (bytes_read == block_width) {
|
||||||
// Disable fast mode on last packet
|
// Disable fast mode on last packet
|
||||||
g_conn.block_after_ACK = false;
|
g_conn.block_after_ACK = false;
|
||||||
}
|
}
|
||||||
|
@ -4026,7 +3970,7 @@ int CmdHF14AMfELoad(const char *Cmd) {
|
||||||
|
|
||||||
cnt++;
|
cnt++;
|
||||||
offset += block_width;
|
offset += block_width;
|
||||||
datalen -= block_width;
|
bytes_read -= block_width;
|
||||||
}
|
}
|
||||||
free(data);
|
free(data);
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
@ -4642,38 +4586,12 @@ static int CmdHF14AMfCLoad(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reserve memory
|
||||||
uint8_t *data = NULL;
|
uint8_t *data = NULL;
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
int res = 0;
|
int res = pm3_load_dump(filename, (void **)&data, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK));
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
free(data);
|
return res;
|
||||||
return PM3_EFILE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 64 or 256blocks.
|
// 64 or 256blocks.
|
||||||
|
@ -5430,37 +5348,9 @@ static int CmdHF14AMfMAD(const char *Cmd) {
|
||||||
// reserve memory
|
// reserve memory
|
||||||
uint8_t *dump = NULL;
|
uint8_t *dump = NULL;
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
int res = 0;
|
int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK));
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename);
|
return res;
|
||||||
free(dump);
|
|
||||||
return PM3_EFILE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t block_cnt = MIN(MIFARE_1K_MAXBLOCK, (bytes_read / MFBLOCK_SIZE));
|
uint16_t block_cnt = MIN(MIFARE_1K_MAXBLOCK, (bytes_read / MFBLOCK_SIZE));
|
||||||
|
@ -5477,7 +5367,7 @@ static int CmdHF14AMfMAD(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MAD detection
|
// 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");
|
PrintAndLogEx(FAILED, "No MAD key was detected in the dump file");
|
||||||
free(dump);
|
free(dump);
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
@ -6249,40 +6139,12 @@ static int CmdHF14AMfView(const char *Cmd) {
|
||||||
bool verbose = arg_get_lit(ctx, 2);
|
bool verbose = arg_get_lit(ctx, 2);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
// reserve memory
|
// read dump file
|
||||||
uint8_t *dump = NULL;
|
uint8_t *dump = NULL;
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
int res = 0;
|
int res = pm3_load_dump(filename, (void **)&dump, &bytes_read, (MFBLOCK_SIZE * MIFARE_4K_MAXBLOCK));
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(FAILED, "File: " _YELLOW_("%s") ": not found or locked.", filename);
|
return res;
|
||||||
free(dump);
|
|
||||||
return PM3_EFILE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t block_cnt = MIN(MIFARE_1K_MAXBLOCK, (bytes_read / MFBLOCK_SIZE));
|
uint16_t block_cnt = MIN(MIFARE_1K_MAXBLOCK, (bytes_read / MFBLOCK_SIZE));
|
||||||
|
|
|
@ -1880,3 +1880,41 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con
|
||||||
free(filename);
|
free(filename);
|
||||||
return PM3_SUCCESS;
|
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
|
* @return
|
||||||
*/
|
*/
|
||||||
DumpFileType_t getfiletype(const char *filename);
|
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
|
#endif // FILEUTILS_H
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "jansson.h"
|
#include "jansson.h"
|
||||||
|
#include "mifaredefault.h"
|
||||||
|
|
||||||
// https://www.nxp.com/docs/en/application-note/AN10787.pdf
|
// https://www.nxp.com/docs/en/application-note/AN10787.pdf
|
||||||
static json_t *mad_known_aids = NULL;
|
static json_t *mad_known_aids = NULL;
|
||||||
|
@ -396,3 +397,10 @@ int MADDFDecodeAndPrint(uint32_t short_aid) {
|
||||||
close_mad_file(mad_known_aids);
|
close_mad_file(mad_known_aids);
|
||||||
return PM3_SUCCESS;
|
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 MADDFDecodeAndPrint(uint32_t short_aid);
|
||||||
int MADCardHolderInfoDecode(uint8_t *data, size_t datalen, bool verbose);
|
int MADCardHolderInfoDecode(uint8_t *data, size_t datalen, bool verbose);
|
||||||
void MADPrintHeader(void);
|
void MADPrintHeader(void);
|
||||||
|
bool HasMADKey(uint8_t *d);
|
||||||
#endif // _MAD_H_
|
#endif // _MAD_H_
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
#define MFBLOCK_SIZE 16
|
||||||
|
|
||||||
static const uint64_t g_mifare_default_keys[] = {
|
static const uint64_t g_mifare_default_keys[] = {
|
||||||
0xffffffffffff, // Default key (first key used by program if no user defined key)
|
0xffffffffffff, // Default key (first key used by program if no user defined key)
|
||||||
0x000000000000, // Blank key
|
0x000000000000, // Blank key
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue