mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
FIX: 'hf mf cload' - showing helptext instead of loading file.
Added support for easy loading of bin/eml files in this patch aswell.
This commit is contained in:
parent
d2f3a9fd68
commit
6a21df3443
3 changed files with 377 additions and 269 deletions
442
client/cmdhfmf.c
442
client/cmdhfmf.c
|
@ -394,7 +394,6 @@ int GetHFMF14AUID(uint8_t *uid, int *uidlen) {
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
|
||||||
//if (!silent)
|
|
||||||
PrintAndLogEx(WARNING, "iso14443a card select failed");
|
PrintAndLogEx(WARNING, "iso14443a card select failed");
|
||||||
DropField();
|
DropField();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -419,8 +418,7 @@ char * GenerateFilename(const char *prefix, const char *suffix){
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(fptr, prefix);
|
strcpy(fptr, prefix);
|
||||||
FillFileNameByUID(fptr,uid,suffix,uidlen);
|
FillFileNameByUID(fptr, uid, suffix, uidlen);
|
||||||
|
|
||||||
return fptr;
|
return fptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,13 +426,13 @@ int CmdHF14ADarkside(const char *Cmd) {
|
||||||
uint8_t blockno = 0, key_type = MIFARE_AUTH_KEYA;
|
uint8_t blockno = 0, key_type = MIFARE_AUTH_KEYA;
|
||||||
uint64_t key = 0;
|
uint64_t key = 0;
|
||||||
|
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
if ( cmdp == 'H' || cmdp == 'h') return usage_hf14_mifare();
|
if ( cmdp == 'h' ) return usage_hf14_mifare();
|
||||||
|
|
||||||
blockno = param_get8(Cmd, 0);
|
blockno = param_get8(Cmd, 0);
|
||||||
|
|
||||||
cmdp = param_getchar(Cmd, 1);
|
cmdp = tolower(param_getchar(Cmd, 1));
|
||||||
if (cmdp == 'B' || cmdp == 'b')
|
if (cmdp == 'b')
|
||||||
key_type = MIFARE_AUTH_KEYB;
|
key_type = MIFARE_AUTH_KEYB;
|
||||||
|
|
||||||
int isOK = mfDarkside(blockno, key_type, &key);
|
int isOK = mfDarkside(blockno, key_type, &key);
|
||||||
|
@ -457,10 +455,9 @@ int CmdHF14AMfWrBl(const char *Cmd) {
|
||||||
uint8_t keyType = 0;
|
uint8_t keyType = 0;
|
||||||
uint8_t key[6] = {0, 0, 0, 0, 0, 0};
|
uint8_t key[6] = {0, 0, 0, 0, 0, 0};
|
||||||
uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
char cmdp = 0x00;
|
char cmdp = 0x00;
|
||||||
|
|
||||||
if (strlen(Cmd)<3) {
|
if (strlen(Cmd) < 3) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf mf wrbl <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");
|
PrintAndLogEx(NORMAL, "Usage: hf mf wrbl <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");
|
PrintAndLogEx(NORMAL, " hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");
|
||||||
|
@ -468,20 +465,25 @@ int CmdHF14AMfWrBl(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
blockNo = param_get8(Cmd, 0);
|
blockNo = param_get8(Cmd, 0);
|
||||||
cmdp = param_getchar(Cmd, 1);
|
cmdp = tolower(param_getchar(Cmd, 1));
|
||||||
if (cmdp == 0x00) {
|
if (cmdp == 0x00) {
|
||||||
PrintAndLogEx(NORMAL, "Key type must be A or B");
|
PrintAndLogEx(NORMAL, "Key type must be A or B");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (cmdp != 'A' && cmdp != 'a') keyType = 1;
|
|
||||||
|
if (cmdp != 'a')
|
||||||
|
keyType = 1;
|
||||||
|
|
||||||
if (param_gethex(Cmd, 2, key, 12)) {
|
if (param_gethex(Cmd, 2, key, 12)) {
|
||||||
PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols");
|
PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param_gethex(Cmd, 3, bldata, 32)) {
|
if (param_gethex(Cmd, 3, bldata, 32)) {
|
||||||
PrintAndLogEx(NORMAL, "Block data must include 32 HEX symbols");
|
PrintAndLogEx(NORMAL, "Block data must include 32 HEX symbols");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6));
|
PrintAndLogEx(NORMAL, "--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6));
|
||||||
PrintAndLogEx(NORMAL, "--data: %s", sprint_hex(bldata, 16));
|
PrintAndLogEx(NORMAL, "--data: %s", sprint_hex(bldata, 16));
|
||||||
|
|
||||||
|
@ -516,12 +518,15 @@ int CmdHF14AMfRdBl(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
blockNo = param_get8(Cmd, 0);
|
blockNo = param_get8(Cmd, 0);
|
||||||
cmdp = param_getchar(Cmd, 1);
|
cmdp = tolower(param_getchar(Cmd, 1));
|
||||||
if (cmdp == 0x00) {
|
if (cmdp == 0x00) {
|
||||||
PrintAndLogEx(NORMAL, "Key type must be A or B");
|
PrintAndLogEx(NORMAL, "Key type must be A or B");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (cmdp != 'A' && cmdp != 'a') keyType = 1;
|
|
||||||
|
if (cmdp != 'a')
|
||||||
|
keyType = 1;
|
||||||
|
|
||||||
if (param_gethex(Cmd, 2, key, 12)) {
|
if (param_gethex(Cmd, 2, key, 12)) {
|
||||||
PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols");
|
PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -558,7 +563,7 @@ int CmdHF14AMfRdSc(const char *Cmd) {
|
||||||
uint8_t *data = NULL;
|
uint8_t *data = NULL;
|
||||||
char cmdp = 0x00;
|
char cmdp = 0x00;
|
||||||
|
|
||||||
if (strlen(Cmd)<3) {
|
if (strlen(Cmd) < 3) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: hf mf rdsc <sector number> <key A/B> <key (12 hex symbols)>");
|
PrintAndLogEx(NORMAL, "Usage: hf mf rdsc <sector number> <key A/B> <key (12 hex symbols)>");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " hf mf rdsc 0 A FFFFFFFFFFFF ");
|
PrintAndLogEx(NORMAL, " hf mf rdsc 0 A FFFFFFFFFFFF ");
|
||||||
|
@ -570,12 +575,16 @@ int CmdHF14AMfRdSc(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "Sector number must be less than 40");
|
PrintAndLogEx(NORMAL, "Sector number must be less than 40");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
cmdp = param_getchar(Cmd, 1);
|
|
||||||
if (cmdp != 'a' && cmdp != 'A' && cmdp != 'b' && cmdp != 'B') {
|
cmdp = tolower(param_getchar(Cmd, 1));
|
||||||
|
if (cmdp != 'a' && cmdp != 'b') {
|
||||||
PrintAndLogEx(NORMAL, "Key type must be A or B");
|
PrintAndLogEx(NORMAL, "Key type must be A or B");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (cmdp != 'A' && cmdp != 'a') keyType = 1;
|
|
||||||
|
if (cmdp != 'a')
|
||||||
|
keyType = 1;
|
||||||
|
|
||||||
if (param_gethex(Cmd, 2, key, 12)) {
|
if (param_gethex(Cmd, 2, key, 12)) {
|
||||||
PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols");
|
PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -682,15 +691,15 @@ int CmdHF14AMfDump(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyFilename[0] == 0x00)
|
if ( keyFilename[0] == 0x00 ) {
|
||||||
{
|
fptr = GenerateFilename("hf-mf-", "-key.bin");
|
||||||
fptr = GenerateFilename("hf-mf-","-key.bin");
|
|
||||||
if (fptr == NULL)
|
if (fptr == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
strcpy(keyFilename, fptr);
|
strcpy(keyFilename, fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fin = fopen(keyFilename,"rb")) == NULL) {
|
if ((fin = fopen(keyFilename, "rb")) == NULL) {
|
||||||
PrintAndLogEx(WARNING, "Could not find file %s", keyFilename);
|
PrintAndLogEx(WARNING, "Could not find file %s", keyFilename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -828,9 +837,10 @@ int CmdHF14AMfDump(const char *Cmd) {
|
||||||
|
|
||||||
if (isOK) {
|
if (isOK) {
|
||||||
if (dataFilename[0] == 0x00) {
|
if (dataFilename[0] == 0x00) {
|
||||||
fptr=GenerateFilename("hf-mf-","-data.bin");
|
fptr = GenerateFilename("hf-mf-", "-data.bin");
|
||||||
if (fptr == NULL)
|
if (fptr == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
strcpy(dataFilename, fptr);
|
strcpy(dataFilename, fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -862,12 +872,10 @@ int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
FILE *fdump, *fkeys;
|
FILE *fdump, *fkeys;
|
||||||
|
|
||||||
while(param_getchar(Cmd, cmdp) != 0x00) {
|
while(param_getchar(Cmd, cmdp) != 0x00) {
|
||||||
switch(param_getchar(Cmd, cmdp)) {
|
switch(tolower(param_getchar(Cmd, cmdp))) {
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'H':
|
|
||||||
return usage_hf14_restore();
|
return usage_hf14_restore();
|
||||||
case 'u':
|
case 'u':
|
||||||
case 'U':
|
|
||||||
param_getstr(Cmd, cmdp+1, szTemp, FILE_PATH_SIZE);
|
param_getstr(Cmd, cmdp+1, szTemp, FILE_PATH_SIZE);
|
||||||
if(keyFilename[0]==0x00)
|
if(keyFilename[0]==0x00)
|
||||||
snprintf(keyFilename, FILE_PATH_SIZE, "hf-mf-%s-key.bin", szTemp);
|
snprintf(keyFilename, FILE_PATH_SIZE, "hf-mf-%s-key.bin", szTemp);
|
||||||
|
@ -876,38 +884,33 @@ int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
cmdp+=2;
|
cmdp+=2;
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
case 'K':
|
|
||||||
param_getstr(Cmd, cmdp+1, keyFilename, FILE_PATH_SIZE);
|
param_getstr(Cmd, cmdp+1, keyFilename, FILE_PATH_SIZE);
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
case 'F':
|
|
||||||
param_getstr(Cmd, cmdp+1, dataFilename, FILE_PATH_SIZE);
|
param_getstr(Cmd, cmdp+1, dataFilename, FILE_PATH_SIZE);
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (cmdp==0)
|
if ( cmdp == 0 ) {
|
||||||
{
|
|
||||||
numSectors = NumOfSectors(param_getchar(Cmd, cmdp));
|
numSectors = NumOfSectors(param_getchar(Cmd, cmdp));
|
||||||
cmdp++;
|
cmdp++;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
||||||
return usage_hf14_restore();
|
return usage_hf14_restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(keyFilename[0]==0x00)
|
if ( keyFilename[0] == 0x00 ) {
|
||||||
{
|
fptr = GenerateFilename("hf-mf-", "-key.bin");
|
||||||
fptr=GenerateFilename("hf-mf-","-key.bin");
|
|
||||||
if (fptr == NULL)
|
if (fptr == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
strcpy(keyFilename,fptr);
|
|
||||||
|
strcpy(keyFilename, fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fkeys = fopen(keyFilename,"rb")) == NULL) {
|
if ((fkeys = fopen(keyFilename, "rb")) == NULL) {
|
||||||
PrintAndLogEx(WARNING, "Could not find file %s", keyFilename);
|
PrintAndLogEx(WARNING, "Could not find file %s", keyFilename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -915,7 +918,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
size_t bytes_read;
|
size_t bytes_read;
|
||||||
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
||||||
bytes_read = fread( keyA[sectorNo], 1, 6, fkeys );
|
bytes_read = fread( keyA[sectorNo], 1, 6, fkeys );
|
||||||
if ( bytes_read != 6) {
|
if ( bytes_read != 6 ) {
|
||||||
PrintAndLogEx(NORMAL, "File reading error (%s).", keyFilename);
|
PrintAndLogEx(NORMAL, "File reading error (%s).", keyFilename);
|
||||||
fclose(fkeys);
|
fclose(fkeys);
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -924,7 +927,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
|
|
||||||
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
||||||
bytes_read = fread( keyB[sectorNo], 1, 6, fkeys );
|
bytes_read = fread( keyB[sectorNo], 1, 6, fkeys );
|
||||||
if ( bytes_read != 6) {
|
if ( bytes_read != 6 ) {
|
||||||
PrintAndLogEx(NORMAL, "File reading error (%s).", keyFilename);
|
PrintAndLogEx(NORMAL, "File reading error (%s).", keyFilename);
|
||||||
fclose(fkeys);
|
fclose(fkeys);
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -933,22 +936,22 @@ int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
|
|
||||||
fclose(fkeys);
|
fclose(fkeys);
|
||||||
|
|
||||||
if( dataFilename[0]==0x00)
|
if ( dataFilename[0] == 0x00 ) {
|
||||||
{
|
fptr = GenerateFilename("hf-mf-", "-data.bin");
|
||||||
fptr=GenerateFilename("hf-mf-","-data.bin");
|
|
||||||
if (fptr == NULL)
|
if (fptr == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
strcpy(dataFilename,fptr);
|
strcpy(dataFilename,fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fdump = fopen(dataFilename,"rb")) == NULL) {
|
if ((fdump = fopen(dataFilename, "rb")) == NULL) {
|
||||||
PrintAndLogEx(WARNING, "Could not find file %s", dataFilename);
|
PrintAndLogEx(WARNING, "Could not find file %s", dataFilename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
PrintAndLogEx(NORMAL, "Restoring %s to card", dataFilename);
|
PrintAndLogEx(NORMAL, "Restoring %s to card", dataFilename);
|
||||||
|
|
||||||
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
||||||
for(blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
|
for (blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
|
||||||
UsbCommand c = {CMD_MIFARE_WRITEBL, {FirstBlockOfSector(sectorNo) + blockNo, keyType, 0}};
|
UsbCommand c = {CMD_MIFARE_WRITEBL, {FirstBlockOfSector(sectorNo) + blockNo, keyType, 0}};
|
||||||
memcpy(c.d.asBytes, key, 6);
|
memcpy(c.d.asBytes, key, 6);
|
||||||
bytes_read = fread(bldata, 1, 16, fdump);
|
bytes_read = fread(bldata, 1, 16, fdump);
|
||||||
|
@ -1011,19 +1014,20 @@ int CmdHF14AMfNested(const char *Cmd) {
|
||||||
uint8_t standart[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
uint8_t standart[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
uint8_t tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
char *fptr;
|
char *fptr;
|
||||||
if (strlen(Cmd)<3) return usage_hf14_nested();
|
|
||||||
|
if (strlen(Cmd) < 3) return usage_hf14_nested();
|
||||||
|
|
||||||
char cmdp, ctmp;
|
char cmdp, ctmp;
|
||||||
cmdp = param_getchar(Cmd, 0);
|
cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
blockNo = param_get8(Cmd, 1);
|
blockNo = param_get8(Cmd, 1);
|
||||||
ctmp = param_getchar(Cmd, 2);
|
ctmp = tolower(param_getchar(Cmd, 2));
|
||||||
|
|
||||||
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
|
if (ctmp != 'a' && ctmp != 'b') {
|
||||||
PrintAndLogEx(WARNING, "key type must be A or B");
|
PrintAndLogEx(WARNING, "key type must be A or B");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctmp != 'A' && ctmp != 'a')
|
if (ctmp != 'a')
|
||||||
keyType = 1;
|
keyType = 1;
|
||||||
|
|
||||||
if (param_gethex(Cmd, 3, key, 12)) {
|
if (param_gethex(Cmd, 3, key, 12)) {
|
||||||
|
@ -1031,27 +1035,27 @@ int CmdHF14AMfNested(const char *Cmd) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdp == 'o' || cmdp == 'O') {
|
if (cmdp == 'o') {
|
||||||
cmdp = 'o';
|
|
||||||
trgBlockNo = param_get8(Cmd, 4);
|
trgBlockNo = param_get8(Cmd, 4);
|
||||||
ctmp = param_getchar(Cmd, 5);
|
ctmp = tolower(param_getchar(Cmd, 5));
|
||||||
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
|
if (ctmp != 'a' && ctmp != 'b') {
|
||||||
PrintAndLogEx(WARNING, "target key type must be A or B");
|
PrintAndLogEx(WARNING, "target key type must be A or B");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (ctmp != 'A' && ctmp != 'a')
|
if (ctmp != 'a') {
|
||||||
trgKeyType = 1;
|
trgKeyType = 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SectorsCnt = NumOfSectors(cmdp);
|
SectorsCnt = NumOfSectors(cmdp);
|
||||||
}
|
}
|
||||||
|
|
||||||
ctmp = param_getchar(Cmd, 4);
|
ctmp = tolower(param_getchar(Cmd, 4));
|
||||||
transferToEml |= (ctmp == 't' || ctmp == 'T');
|
transferToEml |= (ctmp == 't');
|
||||||
createDumpFile |= (ctmp == 'd' || ctmp == 'D');
|
createDumpFile |= (ctmp == 'd');
|
||||||
|
|
||||||
ctmp = param_getchar(Cmd, 6);
|
ctmp = tolower(param_getchar(Cmd, 6));
|
||||||
transferToEml |= (ctmp == 't' || ctmp == 'T');
|
transferToEml |= (ctmp == 't');
|
||||||
createDumpFile |= (ctmp == 'd' || ctmp == 'D');
|
createDumpFile |= (ctmp == 'd');
|
||||||
|
|
||||||
// check if we can authenticate to sector
|
// check if we can authenticate to sector
|
||||||
res = mfCheckKeys(blockNo, keyType, true, 1, key, &key64);
|
res = mfCheckKeys(blockNo, keyType, true, 1, key, &key64);
|
||||||
|
@ -1203,7 +1207,7 @@ int CmdHF14AMfNested(const char *Cmd) {
|
||||||
|
|
||||||
// Create dump file
|
// Create dump file
|
||||||
if (createDumpFile) {
|
if (createDumpFile) {
|
||||||
fptr = GenerateFilename("hf-mf-","-key.bin");
|
fptr = GenerateFilename("hf-mf-", "-key.bin");
|
||||||
if (fptr == NULL)
|
if (fptr == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -1286,12 +1290,13 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||||
|
|
||||||
}
|
}
|
||||||
blockNo = param_get8(Cmd, cmdp);
|
blockNo = param_get8(Cmd, cmdp);
|
||||||
ctmp = param_getchar(Cmd, cmdp+1);
|
ctmp = tolower(param_getchar(Cmd, cmdp+1));
|
||||||
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
|
if (ctmp != 'a' && ctmp != 'b') {
|
||||||
PrintAndLogEx(NORMAL, "Key type must be A or B");
|
PrintAndLogEx(NORMAL, "Key type must be A or B");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (ctmp != 'A' && ctmp != 'a') {
|
|
||||||
|
if (ctmp != 'a') {
|
||||||
keyType = 1;
|
keyType = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1300,20 +1305,20 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(param_getchar(Cmd, cmdp+3) == 0x00)
|
if (param_getchar(Cmd, cmdp+3) == 0x00)
|
||||||
{
|
{
|
||||||
PrintAndLogEx(NORMAL, "Target block number is missing");
|
PrintAndLogEx(NORMAL, "Target block number is missing");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trgBlockNo = param_get8(Cmd, cmdp+3);
|
trgBlockNo = param_get8(Cmd, cmdp+3);
|
||||||
|
|
||||||
ctmp = param_getchar(Cmd, cmdp+4);
|
ctmp = tolower(param_getchar(Cmd, cmdp+4));
|
||||||
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
|
if (ctmp != 'a' && ctmp != 'b') {
|
||||||
PrintAndLogEx(NORMAL, "Target key type must be A or B");
|
PrintAndLogEx(NORMAL, "Target key type must be A or B");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (ctmp != 'A' && ctmp != 'a') {
|
if (ctmp != 'a') {
|
||||||
trgKeyType = 1;
|
trgKeyType = 1;
|
||||||
}
|
}
|
||||||
cmdp += 5;
|
cmdp += 5;
|
||||||
|
@ -1615,11 +1620,11 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (createDumpFile) {
|
if (createDumpFile) {
|
||||||
fptr = GenerateFilename("hf-mf-","-key.bin");
|
fptr = GenerateFilename("hf-mf-", "-key.bin");
|
||||||
if (fptr == NULL)
|
if (fptr == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
FILE *fkeys = fopen(fptr,"wb");
|
FILE *fkeys = fopen(fptr, "wb");
|
||||||
if (fkeys == NULL) {
|
if (fkeys == NULL) {
|
||||||
PrintAndLogEx(WARNING, "Could not create file %s", fptr);
|
PrintAndLogEx(WARNING, "Could not create file %s", fptr);
|
||||||
free(keyBlock);
|
free(keyBlock);
|
||||||
|
@ -1902,11 +1907,11 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (createDumpFile) {
|
if (createDumpFile) {
|
||||||
fptr = GenerateFilename("hf-mf-","-key.bin");
|
fptr = GenerateFilename("hf-mf-", "-key.bin");
|
||||||
if (fptr == NULL)
|
if (fptr == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
FILE *fkeys = fopen(fptr,"wb");
|
FILE *fkeys = fopen(fptr, "wb");
|
||||||
if (fkeys == NULL) {
|
if (fkeys == NULL) {
|
||||||
PrintAndLogEx(WARNING, "Could not create file %s", fptr);
|
PrintAndLogEx(WARNING, "Could not create file %s", fptr);
|
||||||
free(keyBlock);
|
free(keyBlock);
|
||||||
|
@ -1951,6 +1956,7 @@ static void emptySectorTable(){
|
||||||
k_sector[i].foundKey[1] = false;
|
k_sector[i].foundKey[1] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showSectorTable(){
|
void showSectorTable(){
|
||||||
if (k_sector != NULL) {
|
if (k_sector != NULL) {
|
||||||
printKeyTable(k_sectorsCount, k_sector);
|
printKeyTable(k_sectorsCount, k_sector);
|
||||||
|
@ -1958,6 +1964,7 @@ void showSectorTable(){
|
||||||
k_sector = NULL;
|
k_sector = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) {
|
void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) {
|
||||||
|
|
||||||
uint64_t key = 0;
|
uint64_t key = 0;
|
||||||
|
@ -2002,33 +2009,26 @@ int CmdHF14AMf1kSim(const char *Cmd) {
|
||||||
uint8_t flags = (FLAG_UID_IN_EMUL | FLAG_4B_UID_IN_DATA);
|
uint8_t flags = (FLAG_UID_IN_EMUL | FLAG_4B_UID_IN_DATA);
|
||||||
int uidlen = 0;
|
int uidlen = 0;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
bool errors = false;
|
bool errors = false, verbose = false, setEmulatorMem = false;
|
||||||
bool verbose = false;
|
|
||||||
bool setEmulatorMem = false;
|
|
||||||
nonces_t data[1];
|
nonces_t data[1];
|
||||||
|
|
||||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch(param_getchar(Cmd, cmdp)) {
|
switch( tolower(param_getchar(Cmd, cmdp))) {
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'E':
|
|
||||||
setEmulatorMem = true;
|
setEmulatorMem = true;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'H':
|
|
||||||
return usage_hf14_mf1ksim();
|
return usage_hf14_mf1ksim();
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'I':
|
|
||||||
flags |= FLAG_INTERACTIVE;
|
flags |= FLAG_INTERACTIVE;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
case 'N':
|
|
||||||
exitAfterNReads = param_get8(Cmd, cmdp+1);
|
exitAfterNReads = param_get8(Cmd, cmdp+1);
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
case 'U':
|
|
||||||
param_gethex_ex(Cmd, cmdp+1, uid, &uidlen);
|
param_gethex_ex(Cmd, cmdp+1, uid, &uidlen);
|
||||||
switch(uidlen) {
|
switch(uidlen) {
|
||||||
case 20: flags = FLAG_10B_UID_IN_DATA; break;
|
case 20: flags = FLAG_10B_UID_IN_DATA; break;
|
||||||
|
@ -2039,12 +2039,10 @@ int CmdHF14AMf1kSim(const char *Cmd) {
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
case 'V':
|
|
||||||
verbose = true;
|
verbose = true;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
case 'X':
|
|
||||||
flags |= FLAG_NR_AR_ATTACK;
|
flags |= FLAG_NR_AR_ATTACK;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
|
@ -2110,11 +2108,11 @@ int CmdHF14AMfSniff(const char *Cmd){
|
||||||
if ( ctmp == 'h' || ctmp == 'H' ) return usage_hf14_sniff();
|
if ( ctmp == 'h' || ctmp == 'H' ) return usage_hf14_sniff();
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ctmp = param_getchar(Cmd, i);
|
ctmp = tolower(param_getchar(Cmd, i));
|
||||||
if (ctmp == 'l' || ctmp == 'L') wantLogToFile = true;
|
if (ctmp == 'l') wantLogToFile = true;
|
||||||
if (ctmp == 'd' || ctmp == 'D') wantDecrypt = true;
|
if (ctmp == 'd') wantDecrypt = true;
|
||||||
//if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO
|
//if (ctmp == 'e') wantSaveToEml = true; TODO
|
||||||
if (ctmp == 'f' || ctmp == 'F') wantSaveToEmlFile = true;
|
if (ctmp == 'f') wantSaveToEmlFile = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "-------------------------------------------------------------------------\n");
|
PrintAndLogEx(NORMAL, "-------------------------------------------------------------------------\n");
|
||||||
|
@ -2244,8 +2242,8 @@ int CmdHF14AMfSniff(const char *Cmd){
|
||||||
|
|
||||||
int CmdHF14AMfDbg(const char *Cmd) {
|
int CmdHF14AMfDbg(const char *Cmd) {
|
||||||
|
|
||||||
char ctmp = param_getchar(Cmd, 0);
|
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_dbg();
|
if (strlen(Cmd) < 1 || ctmp == 'h' ) return usage_hf14_dbg();
|
||||||
|
|
||||||
uint8_t dbgMode = param_get8ex(Cmd, 0, 0, 10);
|
uint8_t dbgMode = param_get8ex(Cmd, 0, 0, 10);
|
||||||
if (dbgMode > 4) return usage_hf14_dbg();
|
if (dbgMode > 4) return usage_hf14_dbg();
|
||||||
|
@ -2261,15 +2259,15 @@ int CmdHF14AMfKeyBrute(const char *Cmd) {
|
||||||
uint8_t key[6] = {0, 0, 0, 0, 0, 0};
|
uint8_t key[6] = {0, 0, 0, 0, 0, 0};
|
||||||
uint64_t foundkey = 0;
|
uint64_t foundkey = 0;
|
||||||
|
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||||
if ( cmdp == 'H' || cmdp == 'h') return usage_hf14_keybrute();
|
if ( cmdp == 'h' ) return usage_hf14_keybrute();
|
||||||
|
|
||||||
// block number
|
// block number
|
||||||
blockNo = param_get8(Cmd, 0);
|
blockNo = param_get8(Cmd, 0);
|
||||||
|
|
||||||
// keytype
|
// keytype
|
||||||
cmdp = param_getchar(Cmd, 1);
|
cmdp = tolower(param_getchar(Cmd, 1));
|
||||||
if (cmdp == 'B' || cmdp == 'b') keytype = 1;
|
if ( cmdp == 'b' ) keytype = 1;
|
||||||
|
|
||||||
// key
|
// key
|
||||||
if (param_gethex(Cmd, 2, key, 12)) return usage_hf14_keybrute();
|
if (param_gethex(Cmd, 2, key, 12)) return usage_hf14_keybrute();
|
||||||
|
@ -2317,15 +2315,15 @@ void printKeyTable( uint8_t sectorscnt, sector_t *e_sector ){
|
||||||
int CmdHF14AMfEGet(const char *Cmd) {
|
int CmdHF14AMfEGet(const char *Cmd) {
|
||||||
uint8_t blockNo = 0;
|
uint8_t blockNo = 0;
|
||||||
uint8_t data[16] = {0x00};
|
uint8_t data[16] = {0x00};
|
||||||
char c = param_getchar(Cmd, 0);
|
char c = tolower(param_getchar(Cmd, 0));
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || c == 'h' || c == 'H') return usage_hf14_eget();
|
if (strlen(Cmd) < 1 || c == 'h') return usage_hf14_eget();
|
||||||
|
|
||||||
blockNo = param_get8(Cmd, 0);
|
blockNo = param_get8(Cmd, 0);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
if (!mfEmlGetMem(data, blockNo, 1)) {
|
if (!mfEmlGetMem(data, blockNo, 1)) {
|
||||||
PrintAndLogEx(NORMAL, "data[%3d]:%s", blockNo, sprint_hex(data, 16));
|
PrintAndLogEx(NORMAL, "data[%3d]:%s", blockNo, sprint_hex(data, sizeof(data)));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||||
}
|
}
|
||||||
|
@ -2333,8 +2331,8 @@ int CmdHF14AMfEGet(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHF14AMfEClear(const char *Cmd) {
|
int CmdHF14AMfEClear(const char *Cmd) {
|
||||||
char c = param_getchar(Cmd, 0);
|
char c = tolower(param_getchar(Cmd, 0));
|
||||||
if (c == 'h' || c == 'H') return usage_hf14_eclr();
|
if (c == 'h') return usage_hf14_eclr();
|
||||||
|
|
||||||
UsbCommand cmd = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};
|
UsbCommand cmd = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
@ -2343,12 +2341,12 @@ int CmdHF14AMfEClear(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHF14AMfESet(const char *Cmd) {
|
int CmdHF14AMfESet(const char *Cmd) {
|
||||||
char c = param_getchar(Cmd, 0);
|
char c = tolower(param_getchar(Cmd, 0));
|
||||||
uint8_t memBlock[16];
|
uint8_t memBlock[16];
|
||||||
uint8_t blockNo = 0;
|
uint8_t blockNo = 0;
|
||||||
memset(memBlock, 0x00, sizeof(memBlock));
|
memset(memBlock, 0x00, sizeof(memBlock));
|
||||||
|
|
||||||
if (strlen(Cmd) < 3 || c == 'h' || c == 'H')
|
if (strlen(Cmd) < 3 || c == 'h')
|
||||||
return usage_hf14_eset();
|
return usage_hf14_eset();
|
||||||
|
|
||||||
blockNo = param_get8(Cmd, 0);
|
blockNo = param_get8(Cmd, 0);
|
||||||
|
@ -2363,91 +2361,70 @@ int CmdHF14AMfESet(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHF14AMfELoad(const char *Cmd) {
|
int CmdHF14AMfELoad(const char *Cmd) {
|
||||||
FILE * f;
|
|
||||||
char filename[FILE_PATH_SIZE];
|
|
||||||
char *fnameptr = filename;
|
|
||||||
char buf[64] = {0x00};
|
|
||||||
uint8_t buf8[64] = {0x00};
|
|
||||||
int i, len, blockNum, numBlocks;
|
|
||||||
int nameParamNo = 1;
|
|
||||||
uint8_t blockWidth = 32;
|
|
||||||
uint32_t tmp;
|
|
||||||
char c = param_getchar(Cmd, 0);
|
|
||||||
|
|
||||||
if ( c == 'h' || c == 'H' || c == 0x00)
|
|
||||||
return usage_hf14_eload();
|
|
||||||
|
|
||||||
|
size_t counter = 0;
|
||||||
|
char filename[FILE_PATH_SIZE];
|
||||||
|
int blockNum, numBlocks, nameParamNo = 1;
|
||||||
|
uint8_t blockWidth = 16;
|
||||||
|
char c = tolower(param_getchar(Cmd, 0));
|
||||||
|
|
||||||
|
if ( strlen(Cmd) < 2 && c == 'h' )
|
||||||
|
return usage_hf14_eload();
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '0' : numBlocks = 5*4; break;
|
case '0' : numBlocks = 5*4; break;
|
||||||
case '1' :
|
case '1' :
|
||||||
case '\0': numBlocks = 16*4; break;
|
case '\0': numBlocks = 16*4; break;
|
||||||
case '2' : numBlocks = 32*4; break;
|
case '2' : numBlocks = 32*4; break;
|
||||||
case '4' : numBlocks = 256; break;
|
case '4' : numBlocks = 256; break;
|
||||||
case 'U' : // fall through
|
case 'u' : numBlocks = 255; blockWidth = 4; break;
|
||||||
case 'u' : numBlocks = 255; blockWidth = 8; break;
|
|
||||||
default: {
|
default: {
|
||||||
numBlocks = 16*4;
|
numBlocks = 16*4;
|
||||||
nameParamNo = 0;
|
nameParamNo = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32_t numblk2 = param_get32ex(Cmd,2,0,10);
|
uint32_t numblk2 = param_get32ex(Cmd, 2, 0, 10);
|
||||||
if (numblk2 > 0) numBlocks = numblk2;
|
if (numblk2 > 0)
|
||||||
|
numBlocks = numblk2;
|
||||||
|
|
||||||
len = param_getstr(Cmd, nameParamNo, filename, sizeof(filename));
|
param_getstr(Cmd, nameParamNo, filename, sizeof(filename));
|
||||||
|
|
||||||
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
|
uint8_t *data = calloc(1, 4096);
|
||||||
|
size_t datalen = 0;
|
||||||
fnameptr += len;
|
//int res = loadFile(filename, "bin", data, &datalen);
|
||||||
|
int res = loadFileEML( filename, "eml", data, &datalen);
|
||||||
sprintf(fnameptr, ".eml");
|
if ( res ) {
|
||||||
|
free(data);
|
||||||
// open file
|
|
||||||
f = fopen(filename, "r");
|
|
||||||
if (f == NULL) {
|
|
||||||
PrintAndLogEx(WARNING, "File %s not found or locked", filename);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 64 or 256 blocks.
|
||||||
|
if ( (datalen % blockWidth) != 0 ) {
|
||||||
|
PrintAndLogEx(FAILED, "File content error. Size doesn't match blockwidth ");
|
||||||
|
free(data);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Copying to emulator memory");
|
||||||
|
|
||||||
blockNum = 0;
|
blockNum = 0;
|
||||||
while (!feof(f)){
|
while ( datalen ) {
|
||||||
memset(buf, 0, sizeof(buf));
|
|
||||||
|
|
||||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
if (mfEmlSetMem_xt(data + counter, blockNum, 1, blockWidth)) {
|
||||||
|
PrintAndLogEx(FAILED, "Cant set emul block: %3d", blockNum);
|
||||||
if (blockNum >= numBlocks) break;
|
free(data);
|
||||||
|
|
||||||
PrintAndLogEx(WARNING, "File reading error.");
|
|
||||||
fclose(f);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(buf) < blockWidth){
|
|
||||||
if(strlen(buf) && feof(f))
|
|
||||||
break;
|
|
||||||
PrintAndLogEx(WARNING, "File content error. Block data must include %d HEX symbols", blockWidth);
|
|
||||||
fclose(f);
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < blockWidth; i += 2) {
|
|
||||||
sscanf(&buf[i], "%02x", &tmp);
|
|
||||||
buf8[i / 2] = tmp & 0xFF;
|
|
||||||
}
|
|
||||||
if (mfEmlSetMem_xt(buf8, blockNum, 1, blockWidth/2)) {
|
|
||||||
PrintAndLogEx(WARNING, "Cant set emul block: %3d", blockNum);
|
|
||||||
fclose(f);
|
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
printf("."); fflush(stdout);
|
printf("."); fflush(stdout);
|
||||||
blockNum++;
|
|
||||||
|
|
||||||
if (blockNum >= numBlocks) break;
|
blockNum++;
|
||||||
|
counter += blockWidth;
|
||||||
|
datalen -= blockWidth;
|
||||||
}
|
}
|
||||||
fclose(f);
|
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
PrintAndLogEx(NORMAL, "\n");
|
||||||
|
|
||||||
// Ultralight /Ntag
|
// Ultralight /Ntag
|
||||||
if ( blockWidth == 8 ) {
|
if ( blockWidth == 4 ) {
|
||||||
if ((blockNum != numBlocks)) {
|
if ((blockNum != numBlocks)) {
|
||||||
PrintAndLogEx(FAILED, "Warning, Ultralight/Ntag file content, Loaded %d blocks into emulator memory", blockNum);
|
PrintAndLogEx(FAILED, "Warning, Ultralight/Ntag file content, Loaded %d blocks into emulator memory", blockNum);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2479,7 +2456,7 @@ int CmdHF14AMfESave(const char *Cmd) {
|
||||||
blocks = NumOfBlocks(c);
|
blocks = NumOfBlocks(c);
|
||||||
bytes = blocks * MFBLOCK_SIZE;
|
bytes = blocks * MFBLOCK_SIZE;
|
||||||
|
|
||||||
dump = malloc(bytes);
|
dump = calloc(sizeof(uint8_t), bytes);
|
||||||
if (!dump) {
|
if (!dump) {
|
||||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -2511,21 +2488,22 @@ int CmdHF14AMfESave(const char *Cmd) {
|
||||||
int CmdHF14AMfECFill(const char *Cmd) {
|
int CmdHF14AMfECFill(const char *Cmd) {
|
||||||
uint8_t keyType = 0;
|
uint8_t keyType = 0;
|
||||||
uint8_t numSectors = 16;
|
uint8_t numSectors = 16;
|
||||||
char c = param_getchar(Cmd, 0);
|
char c = tolower(param_getchar(Cmd, 0));
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || c == 'h' || c == 'H')
|
if (strlen(Cmd) < 1 || c == 'h')
|
||||||
return usage_hf14_ecfill();
|
return usage_hf14_ecfill();
|
||||||
|
|
||||||
if (c != 'a' && c != 'A' && c != 'b' && c != 'B') {
|
if (c != 'a' && c != 'b') {
|
||||||
PrintAndLogEx(WARNING, "Key type must be A or B");
|
PrintAndLogEx(WARNING, "Key type must be A or B");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (c != 'A' && c != 'a') keyType = 1;
|
if (c != 'a')
|
||||||
|
keyType = 1;
|
||||||
|
|
||||||
c = param_getchar(Cmd, 1);
|
c = tolower(param_getchar(Cmd, 1));
|
||||||
numSectors = NumOfSectors(c);
|
numSectors = NumOfSectors(c);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "--params: numSectors: %d, keyType: %c\n", numSectors, (keyType==0) ? 'A' : 'B');
|
PrintAndLogEx(NORMAL, "--params: numSectors: %d, keyType: %c\n", numSectors, (keyType == 0) ? 'A' : 'B');
|
||||||
UsbCommand cmd = {CMD_MIFARE_EML_CARDLOAD, {numSectors, keyType, 0}};
|
UsbCommand cmd = {CMD_MIFARE_EML_CARDLOAD, {numSectors, keyType, 0}};
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&cmd);
|
SendCommand(&cmd);
|
||||||
|
@ -2538,9 +2516,8 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) {
|
||||||
uint8_t data[16];
|
uint8_t data[16];
|
||||||
uint64_t keyA, keyB;
|
uint64_t keyA, keyB;
|
||||||
|
|
||||||
char c = param_getchar(Cmd, 0);
|
char c = tolower(param_getchar(Cmd, 0));
|
||||||
|
if ( c == 'h' )
|
||||||
if ( c == 'h' || c == 'H' )
|
|
||||||
return usage_hf14_ekeyprn();
|
return usage_hf14_ekeyprn();
|
||||||
|
|
||||||
numSectors = NumOfSectors(c);
|
numSectors = NumOfSectors(c);
|
||||||
|
@ -2569,9 +2546,8 @@ int CmdHF14AMfCSetUID(const char *Cmd) {
|
||||||
uint8_t atqa[2] = {0x00};
|
uint8_t atqa[2] = {0x00};
|
||||||
uint8_t sak[1] = {0x00};
|
uint8_t sak[1] = {0x00};
|
||||||
uint8_t atqaPresent = 1;
|
uint8_t atqaPresent = 1;
|
||||||
int res;
|
int res, argi = 0;
|
||||||
char ctmp;
|
char ctmp;
|
||||||
int argi=0;
|
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h')
|
if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h')
|
||||||
return usage_hf14_csetuid();
|
return usage_hf14_csetuid();
|
||||||
|
@ -2581,8 +2557,8 @@ int CmdHF14AMfCSetUID(const char *Cmd) {
|
||||||
|
|
||||||
argi++;
|
argi++;
|
||||||
|
|
||||||
ctmp = param_getchar(Cmd, argi);
|
ctmp = tolower(param_getchar(Cmd, argi));
|
||||||
if (ctmp == 'w' || ctmp == 'W') {
|
if (ctmp == 'w') {
|
||||||
wipeCard = 1;
|
wipeCard = 1;
|
||||||
atqaPresent = 0;
|
atqaPresent = 0;
|
||||||
}
|
}
|
||||||
|
@ -2603,9 +2579,9 @@ int CmdHF14AMfCSetUID(const char *Cmd) {
|
||||||
atqaPresent = 0;
|
atqaPresent = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!wipeCard) {
|
if (!wipeCard) {
|
||||||
ctmp = param_getchar(Cmd, argi);
|
ctmp = tolower(param_getchar(Cmd, argi));
|
||||||
if (ctmp == 'w' || ctmp == 'W') {
|
if (ctmp == 'w') {
|
||||||
wipeCard = 1;
|
wipeCard = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2628,16 +2604,16 @@ int CmdHF14AMfCSetBlk(const char *Cmd) {
|
||||||
uint8_t blockNo = 0;
|
uint8_t blockNo = 0;
|
||||||
uint8_t params = MAGIC_SINGLE;
|
uint8_t params = MAGIC_SINGLE;
|
||||||
int res;
|
int res;
|
||||||
char ctmp = param_getchar(Cmd, 0);
|
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_csetblk();
|
if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf14_csetblk();
|
||||||
|
|
||||||
blockNo = param_get8(Cmd, 0);
|
blockNo = param_get8(Cmd, 0);
|
||||||
|
|
||||||
if (param_gethex(Cmd, 1, block, 32)) return usage_hf14_csetblk();
|
if (param_gethex(Cmd, 1, block, 32)) return usage_hf14_csetblk();
|
||||||
|
|
||||||
ctmp = param_getchar(Cmd, 2);
|
ctmp = tolower(param_getchar(Cmd, 2));
|
||||||
if (ctmp == 'w' || ctmp == 'W')
|
if (ctmp == 'w')
|
||||||
params |= MAGIC_WIPE;
|
params |= MAGIC_WIPE;
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "--block number:%2d data:%s", blockNo, sprint_hex(block, 16));
|
PrintAndLogEx(NORMAL, "--block number:%2d data:%s", blockNo, sprint_hex(block, 16));
|
||||||
|
@ -2651,21 +2627,16 @@ int CmdHF14AMfCSetBlk(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHF14AMfCLoad(const char *Cmd) {
|
int CmdHF14AMfCLoad(const char *Cmd) {
|
||||||
FILE * f;
|
|
||||||
char filename[FILE_PATH_SIZE];
|
|
||||||
char * fnameptr = filename;
|
|
||||||
char buf[35] = {0x00}; // 32+newline chars+1 null terminator
|
|
||||||
uint8_t buf8[16] = {0x00};
|
uint8_t buf8[16] = {0x00};
|
||||||
uint8_t fillFromEmulator = 0;
|
uint8_t fillFromEmulator = 0;
|
||||||
uint32_t tmp;
|
int blockNum, flags = 0;
|
||||||
int i, len, blockNum, flags=0;
|
|
||||||
|
|
||||||
memset(filename, 0, sizeof(filename));
|
|
||||||
|
|
||||||
char ctmp = param_getchar(Cmd, 0);
|
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
|
if ( strlen(Cmd) == 1 ) {
|
||||||
if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf14_cload();
|
if (ctmp == 'h' || ctmp == 0x00) return usage_hf14_cload();
|
||||||
if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
|
if (ctmp == 'e' ) fillFromEmulator = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (fillFromEmulator) {
|
if (fillFromEmulator) {
|
||||||
for (blockNum = 0; blockNum < 16 * 4; blockNum += 1) {
|
for (blockNum = 0; blockNum < 16 * 4; blockNum += 1) {
|
||||||
|
@ -2685,69 +2656,66 @@ int CmdHF14AMfCLoad(const char *Cmd) {
|
||||||
}
|
}
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
PrintAndLogEx(NORMAL, "\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(Cmd);
|
|
||||||
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
|
|
||||||
|
|
||||||
memcpy(filename, Cmd, len);
|
uint8_t *data = calloc(1, 4096);
|
||||||
fnameptr += len;
|
size_t datalen = 0;
|
||||||
|
//int res = loadFile(Cmd, "bin", data, &datalen);
|
||||||
sprintf(fnameptr, ".eml");
|
int res = loadFileEML( Cmd, "eml", data, &datalen);
|
||||||
|
if ( res ) {
|
||||||
// open file
|
free(data);
|
||||||
f = fopen(filename, "r");
|
|
||||||
if (f == NULL) {
|
|
||||||
PrintAndLogEx(WARNING, "File not found or locked.");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockNum = 0;
|
|
||||||
while (!feof(f)){
|
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
// PrintAndLogEx(INFO, "DATA | %s", sprint_hex(data+1000, 24) );
|
||||||
|
|
||||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
|
||||||
fclose(f);
|
|
||||||
PrintAndLogEx(WARNING, "File reading error.");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(buf) < 32) {
|
// 64 or 256blocks.
|
||||||
if(strlen(buf) && feof(f))
|
if (datalen != 1024 && datalen != 4096) {
|
||||||
break;
|
PrintAndLogEx(WARNING, "File content error. ");
|
||||||
PrintAndLogEx(WARNING, "File content error. Block data must include 32 HEX symbols");
|
free(data);
|
||||||
fclose(f);
|
return 2;
|
||||||
return 2;
|
}
|
||||||
}
|
|
||||||
for (i = 0; i < 32; i += 2) {
|
PrintAndLogEx(INFO, "Copying to magic card");
|
||||||
sscanf(&buf[i], "%02x", &tmp);
|
|
||||||
buf8[i / 2] = tmp & 0xFF;
|
blockNum = 0;
|
||||||
}
|
while ( datalen ) {
|
||||||
|
|
||||||
if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence
|
|
||||||
if (blockNum == 1) flags = 0; // just write
|
|
||||||
if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Switch off field.
|
|
||||||
|
|
||||||
if (mfCSetBlock(blockNum, buf8, NULL, flags)) {
|
// switch on field and send magic sequence
|
||||||
|
if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC;
|
||||||
|
|
||||||
|
// write
|
||||||
|
if (blockNum == 1) flags = 0;
|
||||||
|
|
||||||
|
// Switch off field.
|
||||||
|
if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF;
|
||||||
|
|
||||||
|
if (mfCSetBlock(blockNum, data + (16 * blockNum), NULL, flags)) {
|
||||||
PrintAndLogEx(WARNING, "Can't set magic card block: %d", blockNum);
|
PrintAndLogEx(WARNING, "Can't set magic card block: %d", blockNum);
|
||||||
fclose(f);
|
free(data);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
datalen -= 16;
|
||||||
|
|
||||||
printf("."); fflush(stdout);
|
printf("."); fflush(stdout);
|
||||||
blockNum++;
|
blockNum++;
|
||||||
|
|
||||||
if (blockNum >= 16 * 4) break; // magic card type - mifare 1K
|
// magic card type - mifare 1K
|
||||||
|
if (blockNum >= 16 * 4) break;
|
||||||
}
|
}
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
PrintAndLogEx(NORMAL, "\n");
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
// 64 or 256blocks.
|
// 64 or 256blocks.
|
||||||
if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){
|
if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){
|
||||||
PrintAndLogEx(WARNING, "File content error. There must be 64 blocks");
|
PrintAndLogEx(WARNING, "File content error. There must be 64 blocks");
|
||||||
|
free(data);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
PrintAndLogEx(SUCCESS, "Loaded %d blocks from file: %s", blockNum, filename);
|
|
||||||
|
PrintAndLogEx(SUCCESS, "Card loaded %d blocks from file", blockNum);
|
||||||
|
free(data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,26 +135,126 @@ out:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int saveFileJSON(const char *preferredName, const char *suffix, uint8_t* data, size_t datalen) {
|
||||||
* Utility function to print to console. This is used consistently within the library instead
|
//stub - for merlokk ;)
|
||||||
* of printf, but it actually only calls printf (and adds a linebreak).
|
return 1;
|
||||||
* The reason to have this method is to
|
|
||||||
* make it simple to plug this library into proxmark, which has this function already to
|
|
||||||
* write also to a logfile. When doing so, just delete this function.
|
|
||||||
* @param fmt
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
void PrintAndLogDevice(logLevel_t level, char *fmt, ...) {
|
|
||||||
char buffer[2048] = {0};
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
PrintAndLogEx(level, buffer);
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
int loadFile(const char *preferredName, const char *suffix, void* data, size_t* datalen) {
|
||||||
|
|
||||||
|
if ( preferredName == NULL ) return 1;
|
||||||
|
if ( suffix == NULL ) return 1;
|
||||||
|
|
||||||
|
int retval = 0;
|
||||||
|
int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10);
|
||||||
|
char * fileName = calloc(size, sizeof(char));
|
||||||
|
sprintf(fileName,"%s.%s", preferredName, suffix);
|
||||||
|
|
||||||
|
FILE *f = fopen(fileName, "rb");
|
||||||
|
if ( !f ) {
|
||||||
|
PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName);
|
||||||
|
retval = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get filesize in order to malloc memory
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long fsize = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
|
if ( fsize < 0 ) {
|
||||||
|
PrintAndLogDevice(FAILED, "error, when getting filesize");
|
||||||
|
retval = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *dump = calloc(fsize, sizeof(uint8_t));
|
||||||
|
if ( !dump ) {
|
||||||
|
PrintAndLogDevice(FAILED, "error, cannot allocate memory");
|
||||||
|
retval = 2;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bytes_read = fread(dump, 1, fsize, f);
|
||||||
|
|
||||||
|
if ( bytes_read != fsize ) {
|
||||||
|
PrintAndLogDevice(FAILED, "error, bytes read mismatch file size");
|
||||||
|
free(dump);
|
||||||
|
retval = 3;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(data, dump, bytes_read);
|
||||||
|
free(dump);
|
||||||
|
|
||||||
|
PrintAndLogDevice(SUCCESS, "loaded %d bytes from binary file %s", bytes_read, fileName);
|
||||||
|
|
||||||
|
*datalen = bytes_read;
|
||||||
|
|
||||||
|
out:
|
||||||
|
fclose(f);
|
||||||
|
free(fileName);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int loadFileEML(const char *preferredName, const char *suffix, void* data, size_t* datalen) {
|
||||||
|
|
||||||
|
if ( preferredName == NULL ) return 1;
|
||||||
|
if ( suffix == NULL ) return 1;
|
||||||
|
|
||||||
|
size_t counter = 0;
|
||||||
|
int retval = 0, hexlen = 0;
|
||||||
|
int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10);
|
||||||
|
char * fileName = calloc(size, sizeof(char));
|
||||||
|
sprintf(fileName,"%s.%s", preferredName, suffix);
|
||||||
|
|
||||||
|
FILE *f = fopen(fileName, "r");
|
||||||
|
if ( !f ) {
|
||||||
|
PrintAndLogDevice(FAILED, "file: %s: not found or locked.", fileName);
|
||||||
|
retval = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 128 + 2 newline chars + 1 null terminator
|
||||||
|
char line[131];
|
||||||
|
memset(line, 0, sizeof(line));
|
||||||
|
uint8_t buf[64] = {0x00};
|
||||||
|
|
||||||
|
while ( !feof(f) ) {
|
||||||
|
|
||||||
|
memset(line, 0, sizeof(line));
|
||||||
|
|
||||||
|
if (fgets(line, sizeof(line), f) == NULL){
|
||||||
|
fclose(f);
|
||||||
|
PrintAndLogEx(FAILED, "File reading error.");
|
||||||
|
retval = 2;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( line[0] == '#' )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int res = param_gethex_to_eol(line, 0, buf, sizeof(buf), &hexlen);
|
||||||
|
if (res == 0 || res == 1) {
|
||||||
|
memcpy(data + counter, buf, hexlen);
|
||||||
|
counter += hexlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
PrintAndLogDevice(SUCCESS, "loaded %d bytes from text file %s", counter, fileName);
|
||||||
|
*datalen = counter;
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(fileName);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int loadFileJSON(const char *preferredName, const char *suffix, void* data, size_t* datalen) {
|
||||||
|
//stub - for merlokk ;)
|
||||||
|
datalen = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#else //if we're on ARM
|
#else //if we're on ARM
|
||||||
|
|
||||||
//void PrintAndLogDevice(logLevel_t level, char *fmt, ...) { return; }
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,10 +48,13 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "../ui.h"
|
#include "../ui.h"
|
||||||
|
|
||||||
|
int fileExists(const char *filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Utility function to save data to a binary file. This method takes a preferred name, but if that
|
* @brief Utility function to save data to a binary file. This method takes a preferred name, but if that
|
||||||
* file already exists, it tries with another name until it finds something suitable.
|
* file already exists, it tries with another name until it finds something suitable.
|
||||||
* E.g. dumpdata-15.txt
|
* E.g. dumpdata-15.txt
|
||||||
|
*
|
||||||
* @param preferredName
|
* @param preferredName
|
||||||
* @param suffix the file suffix. Leave out the ".".
|
* @param suffix the file suffix. Leave out the ".".
|
||||||
* @param data The binary data to write to the file
|
* @param data The binary data to write to the file
|
||||||
|
@ -61,9 +64,10 @@
|
||||||
extern int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen);
|
extern int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Utility function to save data to a textfile. This method takes a preferred name, but if that
|
* @brief Utility function to save data to a textfile (EML). This method takes a preferred name, but if that
|
||||||
* file already exists, it tries with another name until it finds something suitable.
|
* file already exists, it tries with another name until it finds something suitable.
|
||||||
* E.g. dumpdata-15.txt
|
* E.g. dumpdata-15.txt
|
||||||
|
*
|
||||||
* @param preferredName
|
* @param preferredName
|
||||||
* @param suffix the file suffix. Leave out the ".".
|
* @param suffix the file suffix. Leave out the ".".
|
||||||
* @param data The binary data to write to the file
|
* @param data The binary data to write to the file
|
||||||
|
@ -72,16 +76,55 @@ extern int saveFile(const char *preferredName, const char *suffix, const void* d
|
||||||
* @return 0 for ok, 1 for failz
|
* @return 0 for ok, 1 for failz
|
||||||
*/
|
*/
|
||||||
extern int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, size_t datalen, size_t blocksize);
|
extern int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, size_t datalen, size_t blocksize);
|
||||||
/**
|
|
||||||
* @brief Utility function to save load binary data from a a file. This method takes a filename,
|
|
||||||
* Should only be used for fixed-size binary files
|
|
||||||
* @param fileName the name of the file
|
|
||||||
* @param data a buffer to place data in
|
|
||||||
* @param datalen the length of the data/data.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
|
|
||||||
int fileExists(const char *filename);
|
/** STUB
|
||||||
|
* @brief Utility function to save JSON data to a file. This method takes a preferred name, but if that
|
||||||
|
* file already exists, it tries with another name until it finds something suitable.
|
||||||
|
* E.g. dumpdata-15.json
|
||||||
|
*
|
||||||
|
* @param preferredName
|
||||||
|
* @param suffix the file suffix. Leave out the ".".
|
||||||
|
* @param data The binary data to write to the file
|
||||||
|
* @param datalen the length of the data
|
||||||
|
* @return 0 for ok, 1 for failz
|
||||||
|
*/
|
||||||
|
extern int saveFileJSON(const char *preferredName, const char *suffix, uint8_t* data, size_t datalen);
|
||||||
|
|
||||||
|
/** STUB
|
||||||
|
* @brief Utility function to load data from a binary file. This method takes a preferred name.
|
||||||
|
* E.g. dumpdata-15.bin
|
||||||
|
*
|
||||||
|
* @param preferredName
|
||||||
|
* @param suffix the file suffix. Leave out the ".".
|
||||||
|
* @param data The data array to store the loaded bytes from file
|
||||||
|
* @param datalen the number of bytes loaded from file
|
||||||
|
* @return 0 for ok, 1 for failz
|
||||||
|
*/
|
||||||
|
extern int loadFile(const char *preferredName, const char *suffix, void* data, size_t* datalen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Utility function to load data from a textfile (EML). This method takes a preferred name.
|
||||||
|
* E.g. dumpdata-15.txt
|
||||||
|
*
|
||||||
|
* @param preferredName
|
||||||
|
* @param suffix the file suffix. Leave out the ".".
|
||||||
|
* @param data The data array to store the loaded bytes from file
|
||||||
|
* @param datalen the number of bytes loaded from file
|
||||||
|
* @return 0 for ok, 1 for failz
|
||||||
|
*/
|
||||||
|
extern int loadFileEML(const char *preferredName, const char *suffix, void* data, size_t* datalen);
|
||||||
|
|
||||||
|
/** STUB
|
||||||
|
* @brief Utility function to load data from a JSON textfile. This method takes a preferred name.
|
||||||
|
* E.g. dumpdata-15.json
|
||||||
|
*
|
||||||
|
* @param preferredName
|
||||||
|
* @param suffix the file suffix. Leave out the ".".
|
||||||
|
* @param data The data array to store the loaded bytes from file
|
||||||
|
* @param datalen the number of bytes loaded from file
|
||||||
|
* @return 0 for ok, 1 for failz
|
||||||
|
*/
|
||||||
|
extern int loadFileJSON(const char *preferredName, const char *suffix, void* data, size_t* datalen);
|
||||||
|
|
||||||
#define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args)
|
#define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args)
|
||||||
#else
|
#else
|
||||||
|
@ -98,7 +141,4 @@ int fileExists(const char *filename);
|
||||||
|
|
||||||
#endif //ON_DEVICE
|
#endif //ON_DEVICE
|
||||||
|
|
||||||
|
|
||||||
//void PrintAndLogDevice(logLevel_t level, char *fmt, ...);
|
|
||||||
|
|
||||||
#endif // FILEUTILS_H
|
#endif // FILEUTILS_H
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue