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:
Chris 2018-11-12 22:17:49 +01:00
commit 6a21df3443
3 changed files with 377 additions and 269 deletions

View file

@ -394,7 +394,6 @@ int GetHFMF14AUID(uint8_t *uid, int *uidlen) {
SendCommand(&c);
UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
//if (!silent)
PrintAndLogEx(WARNING, "iso14443a card select failed");
DropField();
return 0;
@ -419,8 +418,7 @@ char * GenerateFilename(const char *prefix, const char *suffix){
}
strcpy(fptr, prefix);
FillFileNameByUID(fptr,uid,suffix,uidlen);
FillFileNameByUID(fptr, uid, suffix, uidlen);
return fptr;
}
@ -428,13 +426,13 @@ int CmdHF14ADarkside(const char *Cmd) {
uint8_t blockno = 0, key_type = MIFARE_AUTH_KEYA;
uint64_t key = 0;
char cmdp = param_getchar(Cmd, 0);
if ( cmdp == 'H' || cmdp == 'h') return usage_hf14_mifare();
char cmdp = tolower(param_getchar(Cmd, 0));
if ( cmdp == 'h' ) return usage_hf14_mifare();
blockno = param_get8(Cmd, 0);
cmdp = param_getchar(Cmd, 1);
if (cmdp == 'B' || cmdp == 'b')
cmdp = tolower(param_getchar(Cmd, 1));
if (cmdp == 'b')
key_type = MIFARE_AUTH_KEYB;
int isOK = mfDarkside(blockno, key_type, &key);
@ -457,10 +455,9 @@ int CmdHF14AMfWrBl(const char *Cmd) {
uint8_t keyType = 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};
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, "Examples:");
PrintAndLogEx(NORMAL, " hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");
@ -468,20 +465,25 @@ int CmdHF14AMfWrBl(const char *Cmd) {
}
blockNo = param_get8(Cmd, 0);
cmdp = param_getchar(Cmd, 1);
cmdp = tolower(param_getchar(Cmd, 1));
if (cmdp == 0x00) {
PrintAndLogEx(NORMAL, "Key type must be A or B");
return 1;
}
if (cmdp != 'A' && cmdp != 'a') keyType = 1;
if (cmdp != 'a')
keyType = 1;
if (param_gethex(Cmd, 2, key, 12)) {
PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols");
return 1;
}
if (param_gethex(Cmd, 3, bldata, 32)) {
PrintAndLogEx(NORMAL, "Block data must include 32 HEX symbols");
return 1;
}
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));
@ -516,12 +518,15 @@ int CmdHF14AMfRdBl(const char *Cmd) {
}
blockNo = param_get8(Cmd, 0);
cmdp = param_getchar(Cmd, 1);
cmdp = tolower(param_getchar(Cmd, 1));
if (cmdp == 0x00) {
PrintAndLogEx(NORMAL, "Key type must be A or B");
return 1;
}
if (cmdp != 'A' && cmdp != 'a') keyType = 1;
if (cmdp != 'a')
keyType = 1;
if (param_gethex(Cmd, 2, key, 12)) {
PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols");
return 1;
@ -558,7 +563,7 @@ int CmdHF14AMfRdSc(const char *Cmd) {
uint8_t *data = NULL;
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, "Examples:");
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");
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");
return 1;
}
if (cmdp != 'A' && cmdp != 'a') keyType = 1;
if (cmdp != 'a')
keyType = 1;
if (param_gethex(Cmd, 2, key, 12)) {
PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols");
return 1;
@ -682,15 +691,15 @@ int CmdHF14AMfDump(const char *Cmd) {
}
}
if (keyFilename[0] == 0x00)
{
fptr = GenerateFilename("hf-mf-","-key.bin");
if ( keyFilename[0] == 0x00 ) {
fptr = GenerateFilename("hf-mf-", "-key.bin");
if (fptr == NULL)
return 1;
strcpy(keyFilename, fptr);
}
if ((fin = fopen(keyFilename,"rb")) == NULL) {
if ((fin = fopen(keyFilename, "rb")) == NULL) {
PrintAndLogEx(WARNING, "Could not find file %s", keyFilename);
return 1;
}
@ -828,9 +837,10 @@ int CmdHF14AMfDump(const char *Cmd) {
if (isOK) {
if (dataFilename[0] == 0x00) {
fptr=GenerateFilename("hf-mf-","-data.bin");
fptr = GenerateFilename("hf-mf-", "-data.bin");
if (fptr == NULL)
return 1;
strcpy(dataFilename, fptr);
}
@ -862,12 +872,10 @@ int CmdHF14AMfRestore(const char *Cmd) {
FILE *fdump, *fkeys;
while(param_getchar(Cmd, cmdp) != 0x00) {
switch(param_getchar(Cmd, cmdp)) {
switch(tolower(param_getchar(Cmd, cmdp))) {
case 'h':
case 'H':
return usage_hf14_restore();
case 'u':
case 'U':
param_getstr(Cmd, cmdp+1, szTemp, FILE_PATH_SIZE);
if(keyFilename[0]==0x00)
snprintf(keyFilename, FILE_PATH_SIZE, "hf-mf-%s-key.bin", szTemp);
@ -876,38 +884,33 @@ int CmdHF14AMfRestore(const char *Cmd) {
cmdp+=2;
break;
case 'k':
case 'K':
param_getstr(Cmd, cmdp+1, keyFilename, FILE_PATH_SIZE);
cmdp += 2;
break;
case 'f':
case 'F':
param_getstr(Cmd, cmdp+1, dataFilename, FILE_PATH_SIZE);
cmdp += 2;
break;
default:
if (cmdp==0)
{
if ( cmdp == 0 ) {
numSectors = NumOfSectors(param_getchar(Cmd, cmdp));
cmdp++;
}
else
{
} else {
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
return usage_hf14_restore();
}
}
}
if(keyFilename[0]==0x00)
{
fptr=GenerateFilename("hf-mf-","-key.bin");
if ( keyFilename[0] == 0x00 ) {
fptr = GenerateFilename("hf-mf-", "-key.bin");
if (fptr == NULL)
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);
return 1;
}
@ -915,7 +918,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
size_t bytes_read;
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
bytes_read = fread( keyA[sectorNo], 1, 6, fkeys );
if ( bytes_read != 6) {
if ( bytes_read != 6 ) {
PrintAndLogEx(NORMAL, "File reading error (%s).", keyFilename);
fclose(fkeys);
return 2;
@ -924,7 +927,7 @@ int CmdHF14AMfRestore(const char *Cmd) {
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
bytes_read = fread( keyB[sectorNo], 1, 6, fkeys );
if ( bytes_read != 6) {
if ( bytes_read != 6 ) {
PrintAndLogEx(NORMAL, "File reading error (%s).", keyFilename);
fclose(fkeys);
return 2;
@ -933,22 +936,22 @@ int CmdHF14AMfRestore(const char *Cmd) {
fclose(fkeys);
if( dataFilename[0]==0x00)
{
fptr=GenerateFilename("hf-mf-","-data.bin");
if ( dataFilename[0] == 0x00 ) {
fptr = GenerateFilename("hf-mf-", "-data.bin");
if (fptr == NULL)
return 1;
strcpy(dataFilename,fptr);
}
if ((fdump = fopen(dataFilename,"rb")) == NULL) {
if ((fdump = fopen(dataFilename, "rb")) == NULL) {
PrintAndLogEx(WARNING, "Could not find file %s", dataFilename);
return 1;
}
PrintAndLogEx(NORMAL, "Restoring %s to card", dataFilename);
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}};
memcpy(c.d.asBytes, key, 6);
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 tempkey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
char *fptr;
if (strlen(Cmd)<3) return usage_hf14_nested();
if (strlen(Cmd) < 3) return usage_hf14_nested();
char cmdp, ctmp;
cmdp = param_getchar(Cmd, 0);
cmdp = tolower(param_getchar(Cmd, 0));
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");
return 1;
}
if (ctmp != 'A' && ctmp != 'a')
if (ctmp != 'a')
keyType = 1;
if (param_gethex(Cmd, 3, key, 12)) {
@ -1031,27 +1035,27 @@ int CmdHF14AMfNested(const char *Cmd) {
return 1;
}
if (cmdp == 'o' || cmdp == 'O') {
cmdp = 'o';
if (cmdp == 'o') {
trgBlockNo = param_get8(Cmd, 4);
ctmp = param_getchar(Cmd, 5);
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
ctmp = tolower(param_getchar(Cmd, 5));
if (ctmp != 'a' && ctmp != 'b') {
PrintAndLogEx(WARNING, "target key type must be A or B");
return 1;
}
if (ctmp != 'A' && ctmp != 'a')
if (ctmp != 'a') {
trgKeyType = 1;
}
} else {
SectorsCnt = NumOfSectors(cmdp);
}
ctmp = param_getchar(Cmd, 4);
transferToEml |= (ctmp == 't' || ctmp == 'T');
createDumpFile |= (ctmp == 'd' || ctmp == 'D');
ctmp = tolower(param_getchar(Cmd, 4));
transferToEml |= (ctmp == 't');
createDumpFile |= (ctmp == 'd');
ctmp = param_getchar(Cmd, 6);
transferToEml |= (ctmp == 't' || ctmp == 'T');
createDumpFile |= (ctmp == 'd' || ctmp == 'D');
ctmp = tolower(param_getchar(Cmd, 6));
transferToEml |= (ctmp == 't');
createDumpFile |= (ctmp == 'd');
// check if we can authenticate to sector
res = mfCheckKeys(blockNo, keyType, true, 1, key, &key64);
@ -1203,7 +1207,7 @@ int CmdHF14AMfNested(const char *Cmd) {
// Create dump file
if (createDumpFile) {
fptr = GenerateFilename("hf-mf-","-key.bin");
fptr = GenerateFilename("hf-mf-", "-key.bin");
if (fptr == NULL)
return 1;
@ -1286,12 +1290,13 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
}
blockNo = param_get8(Cmd, cmdp);
ctmp = param_getchar(Cmd, cmdp+1);
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
ctmp = tolower(param_getchar(Cmd, cmdp+1));
if (ctmp != 'a' && ctmp != 'b') {
PrintAndLogEx(NORMAL, "Key type must be A or B");
return 1;
}
if (ctmp != 'A' && ctmp != 'a') {
if (ctmp != 'a') {
keyType = 1;
}
@ -1300,20 +1305,20 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
return 1;
}
if(param_getchar(Cmd, cmdp+3) == 0x00)
if (param_getchar(Cmd, cmdp+3) == 0x00)
{
PrintAndLogEx(NORMAL, "Target block number is missing");
return 1;
}
trgBlockNo = param_get8(Cmd, cmdp+3);
ctmp = param_getchar(Cmd, cmdp+4);
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
ctmp = tolower(param_getchar(Cmd, cmdp+4));
if (ctmp != 'a' && ctmp != 'b') {
PrintAndLogEx(NORMAL, "Target key type must be A or B");
return 1;
}
if (ctmp != 'A' && ctmp != 'a') {
if (ctmp != 'a') {
trgKeyType = 1;
}
cmdp += 5;
@ -1615,11 +1620,11 @@ out:
}
if (createDumpFile) {
fptr = GenerateFilename("hf-mf-","-key.bin");
fptr = GenerateFilename("hf-mf-", "-key.bin");
if (fptr == NULL)
return 1;
FILE *fkeys = fopen(fptr,"wb");
FILE *fkeys = fopen(fptr, "wb");
if (fkeys == NULL) {
PrintAndLogEx(WARNING, "Could not create file %s", fptr);
free(keyBlock);
@ -1902,11 +1907,11 @@ out:
}
if (createDumpFile) {
fptr = GenerateFilename("hf-mf-","-key.bin");
fptr = GenerateFilename("hf-mf-", "-key.bin");
if (fptr == NULL)
return 1;
FILE *fkeys = fopen(fptr,"wb");
FILE *fkeys = fopen(fptr, "wb");
if (fkeys == NULL) {
PrintAndLogEx(WARNING, "Could not create file %s", fptr);
free(keyBlock);
@ -1951,6 +1956,7 @@ static void emptySectorTable(){
k_sector[i].foundKey[1] = false;
}
}
void showSectorTable(){
if (k_sector != NULL) {
printKeyTable(k_sectorsCount, k_sector);
@ -1958,6 +1964,7 @@ void showSectorTable(){
k_sector = NULL;
}
}
void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose) {
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);
int uidlen = 0;
uint8_t cmdp = 0;
bool errors = false;
bool verbose = false;
bool setEmulatorMem = false;
bool errors = false, verbose = false, setEmulatorMem = false;
nonces_t data[1];
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch(param_getchar(Cmd, cmdp)) {
switch( tolower(param_getchar(Cmd, cmdp))) {
case 'e':
case 'E':
setEmulatorMem = true;
cmdp++;
break;
case 'h':
case 'H':
return usage_hf14_mf1ksim();
case 'i':
case 'I':
flags |= FLAG_INTERACTIVE;
cmdp++;
break;
case 'n':
case 'N':
exitAfterNReads = param_get8(Cmd, cmdp+1);
cmdp += 2;
break;
case 'u':
case 'U':
param_gethex_ex(Cmd, cmdp+1, uid, &uidlen);
switch(uidlen) {
case 20: flags = FLAG_10B_UID_IN_DATA; break;
@ -2039,12 +2039,10 @@ int CmdHF14AMf1kSim(const char *Cmd) {
cmdp += 2;
break;
case 'v':
case 'V':
verbose = true;
cmdp++;
break;
case 'x':
case 'X':
flags |= FLAG_NR_AR_ATTACK;
cmdp++;
break;
@ -2110,11 +2108,11 @@ int CmdHF14AMfSniff(const char *Cmd){
if ( ctmp == 'h' || ctmp == 'H' ) return usage_hf14_sniff();
for (int i = 0; i < 4; i++) {
ctmp = param_getchar(Cmd, i);
if (ctmp == 'l' || ctmp == 'L') wantLogToFile = true;
if (ctmp == 'd' || ctmp == 'D') wantDecrypt = true;
//if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO
if (ctmp == 'f' || ctmp == 'F') wantSaveToEmlFile = true;
ctmp = tolower(param_getchar(Cmd, i));
if (ctmp == 'l') wantLogToFile = true;
if (ctmp == 'd') wantDecrypt = true;
//if (ctmp == 'e') wantSaveToEml = true; TODO
if (ctmp == 'f') wantSaveToEmlFile = true;
}
PrintAndLogEx(NORMAL, "-------------------------------------------------------------------------\n");
@ -2244,8 +2242,8 @@ int CmdHF14AMfSniff(const char *Cmd){
int CmdHF14AMfDbg(const char *Cmd) {
char ctmp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_dbg();
char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || ctmp == 'h' ) return usage_hf14_dbg();
uint8_t dbgMode = param_get8ex(Cmd, 0, 0, 10);
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};
uint64_t foundkey = 0;
char cmdp = param_getchar(Cmd, 0);
if ( cmdp == 'H' || cmdp == 'h') return usage_hf14_keybrute();
char cmdp = tolower(param_getchar(Cmd, 0));
if ( cmdp == 'h' ) return usage_hf14_keybrute();
// block number
blockNo = param_get8(Cmd, 0);
// keytype
cmdp = param_getchar(Cmd, 1);
if (cmdp == 'B' || cmdp == 'b') keytype = 1;
cmdp = tolower(param_getchar(Cmd, 1));
if ( cmdp == 'b' ) keytype = 1;
// key
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) {
uint8_t blockNo = 0;
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);
PrintAndLogEx(NORMAL, "");
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 {
PrintAndLogEx(WARNING, "Command execute timeout");
}
@ -2333,8 +2331,8 @@ int CmdHF14AMfEGet(const char *Cmd) {
}
int CmdHF14AMfEClear(const char *Cmd) {
char c = param_getchar(Cmd, 0);
if (c == 'h' || c == 'H') return usage_hf14_eclr();
char c = tolower(param_getchar(Cmd, 0));
if (c == 'h') return usage_hf14_eclr();
UsbCommand cmd = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};
clearCommandBuffer();
@ -2343,12 +2341,12 @@ int CmdHF14AMfEClear(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 blockNo = 0;
memset(memBlock, 0x00, sizeof(memBlock));
if (strlen(Cmd) < 3 || c == 'h' || c == 'H')
if (strlen(Cmd) < 3 || c == 'h')
return usage_hf14_eset();
blockNo = param_get8(Cmd, 0);
@ -2363,91 +2361,70 @@ int CmdHF14AMfESet(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) {
case '0' : numBlocks = 5*4; break;
case '1' :
case '\0': numBlocks = 16*4; break;
case '2' : numBlocks = 32*4; break;
case '4' : numBlocks = 256; break;
case 'U' : // fall through
case 'u' : numBlocks = 255; blockWidth = 8; break;
case 'u' : numBlocks = 255; blockWidth = 4; break;
default: {
numBlocks = 16*4;
nameParamNo = 0;
}
}
uint32_t numblk2 = param_get32ex(Cmd,2,0,10);
if (numblk2 > 0) numBlocks = numblk2;
uint32_t numblk2 = param_get32ex(Cmd, 2, 0, 10);
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;
fnameptr += len;
sprintf(fnameptr, ".eml");
// open file
f = fopen(filename, "r");
if (f == NULL) {
PrintAndLogEx(WARNING, "File %s not found or locked", filename);
uint8_t *data = calloc(1, 4096);
size_t datalen = 0;
//int res = loadFile(filename, "bin", data, &datalen);
int res = loadFileEML( filename, "eml", data, &datalen);
if ( res ) {
free(data);
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;
while (!feof(f)){
memset(buf, 0, sizeof(buf));
while ( datalen ) {
if (fgets(buf, sizeof(buf), f) == NULL) {
if (blockNum >= numBlocks) break;
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);
if (mfEmlSetMem_xt(data + counter, blockNum, 1, blockWidth)) {
PrintAndLogEx(FAILED, "Cant set emul block: %3d", blockNum);
free(data);
return 3;
}
printf("."); fflush(stdout);
blockNum++;
if (blockNum >= numBlocks) break;
blockNum++;
counter += blockWidth;
datalen -= blockWidth;
}
fclose(f);
PrintAndLogEx(NORMAL, "\n");
// Ultralight /Ntag
if ( blockWidth == 8 ) {
if ( blockWidth == 4 ) {
if ((blockNum != numBlocks)) {
PrintAndLogEx(FAILED, "Warning, Ultralight/Ntag file content, Loaded %d blocks into emulator memory", blockNum);
return 0;
@ -2479,7 +2456,7 @@ int CmdHF14AMfESave(const char *Cmd) {
blocks = NumOfBlocks(c);
bytes = blocks * MFBLOCK_SIZE;
dump = malloc(bytes);
dump = calloc(sizeof(uint8_t), bytes);
if (!dump) {
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
return 1;
@ -2511,21 +2488,22 @@ int CmdHF14AMfESave(const char *Cmd) {
int CmdHF14AMfECFill(const char *Cmd) {
uint8_t keyType = 0;
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();
if (c != 'a' && c != 'A' && c != 'b' && c != 'B') {
if (c != 'a' && c != 'b') {
PrintAndLogEx(WARNING, "Key type must be A or B");
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);
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}};
clearCommandBuffer();
SendCommand(&cmd);
@ -2538,9 +2516,8 @@ int CmdHF14AMfEKeyPrn(const char *Cmd) {
uint8_t data[16];
uint64_t keyA, keyB;
char c = param_getchar(Cmd, 0);
if ( c == 'h' || c == 'H' )
char c = tolower(param_getchar(Cmd, 0));
if ( c == 'h' )
return usage_hf14_ekeyprn();
numSectors = NumOfSectors(c);
@ -2569,9 +2546,8 @@ int CmdHF14AMfCSetUID(const char *Cmd) {
uint8_t atqa[2] = {0x00};
uint8_t sak[1] = {0x00};
uint8_t atqaPresent = 1;
int res;
int res, argi = 0;
char ctmp;
int argi=0;
if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h')
return usage_hf14_csetuid();
@ -2581,8 +2557,8 @@ int CmdHF14AMfCSetUID(const char *Cmd) {
argi++;
ctmp = param_getchar(Cmd, argi);
if (ctmp == 'w' || ctmp == 'W') {
ctmp = tolower(param_getchar(Cmd, argi));
if (ctmp == 'w') {
wipeCard = 1;
atqaPresent = 0;
}
@ -2603,9 +2579,9 @@ int CmdHF14AMfCSetUID(const char *Cmd) {
atqaPresent = 0;
}
if(!wipeCard) {
ctmp = param_getchar(Cmd, argi);
if (ctmp == 'w' || ctmp == 'W') {
if (!wipeCard) {
ctmp = tolower(param_getchar(Cmd, argi));
if (ctmp == 'w') {
wipeCard = 1;
}
}
@ -2628,16 +2604,16 @@ int CmdHF14AMfCSetBlk(const char *Cmd) {
uint8_t blockNo = 0;
uint8_t params = MAGIC_SINGLE;
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);
if (param_gethex(Cmd, 1, block, 32)) return usage_hf14_csetblk();
ctmp = param_getchar(Cmd, 2);
if (ctmp == 'w' || ctmp == 'W')
ctmp = tolower(param_getchar(Cmd, 2));
if (ctmp == 'w')
params |= MAGIC_WIPE;
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) {
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 fillFromEmulator = 0;
uint32_t tmp;
int i, len, blockNum, flags=0;
memset(filename, 0, sizeof(filename));
int blockNum, flags = 0;
char ctmp = param_getchar(Cmd, 0);
if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf14_cload();
if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
char ctmp = tolower(param_getchar(Cmd, 0));
if ( strlen(Cmd) == 1 ) {
if (ctmp == 'h' || ctmp == 0x00) return usage_hf14_cload();
if (ctmp == 'e' ) fillFromEmulator = 1;
}
if (fillFromEmulator) {
for (blockNum = 0; blockNum < 16 * 4; blockNum += 1) {
@ -2685,69 +2656,66 @@ int CmdHF14AMfCLoad(const char *Cmd) {
}
PrintAndLogEx(NORMAL, "\n");
return 0;
}
len = strlen(Cmd);
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
}
memcpy(filename, Cmd, len);
fnameptr += len;
sprintf(fnameptr, ".eml");
// open file
f = fopen(filename, "r");
if (f == NULL) {
PrintAndLogEx(WARNING, "File not found or locked.");
uint8_t *data = calloc(1, 4096);
size_t datalen = 0;
//int res = loadFile(Cmd, "bin", data, &datalen);
int res = loadFileEML( Cmd, "eml", data, &datalen);
if ( res ) {
free(data);
return 1;
}
blockNum = 0;
while (!feof(f)){
memset(buf, 0, sizeof(buf));
if (fgets(buf, sizeof(buf), f) == NULL) {
fclose(f);
PrintAndLogEx(WARNING, "File reading error.");
return 2;
}
// PrintAndLogEx(INFO, "DATA | %s", sprint_hex(data+1000, 24) );
if (strlen(buf) < 32) {
if(strlen(buf) && feof(f))
break;
PrintAndLogEx(WARNING, "File content error. Block data must include 32 HEX symbols");
fclose(f);
return 2;
}
for (i = 0; i < 32; i += 2) {
sscanf(&buf[i], "%02x", &tmp);
buf8[i / 2] = tmp & 0xFF;
}
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.
// 64 or 256blocks.
if (datalen != 1024 && datalen != 4096) {
PrintAndLogEx(WARNING, "File content error. ");
free(data);
return 2;
}
PrintAndLogEx(INFO, "Copying to magic card");
blockNum = 0;
while ( datalen ) {
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);
fclose(f);
free(data);
return 3;
}
datalen -= 16;
printf("."); fflush(stdout);
blockNum++;
if (blockNum >= 16 * 4) break; // magic card type - mifare 1K
// magic card type - mifare 1K
if (blockNum >= 16 * 4) break;
}
PrintAndLogEx(NORMAL, "\n");
fclose(f);
// 64 or 256blocks.
if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){
PrintAndLogEx(WARNING, "File content error. There must be 64 blocks");
free(data);
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;
}

View file

@ -135,26 +135,126 @@ out:
return retval;
}
/**
* Utility function to print to console. This is used consistently within the library instead
* of printf, but it actually only calls printf (and adds a linebreak).
* 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 saveFileJSON(const char *preferredName, const char *suffix, uint8_t* data, size_t datalen) {
//stub - for merlokk ;)
return 1;
}
*/
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
//void PrintAndLogDevice(logLevel_t level, char *fmt, ...) { return; }
#endif

View file

@ -48,10 +48,13 @@
#include <stdarg.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
* file already exists, it tries with another name until it finds something suitable.
* E.g. dumpdata-15.txt
*
* @param preferredName
* @param suffix the file suffix. Leave out the ".".
* @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);
/**
* @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.
* E.g. dumpdata-15.txt
*
* @param preferredName
* @param suffix the file suffix. Leave out the ".".
* @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
*/
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)
#else
@ -98,7 +141,4 @@ int fileExists(const char *filename);
#endif //ON_DEVICE
//void PrintAndLogDevice(logLevel_t level, char *fmt, ...);
#endif // FILEUTILS_H