CHG: broke out some help texts and improved them.

CHG: 'hf mf csave' now save mini,1k,2k,4k and to both a bin and eml file.
This commit is contained in:
iceman1001 2017-07-11 17:45:23 +02:00
commit 1f9534e2cc

View file

@ -144,6 +144,143 @@ int usage_hf14_keybrute(void){
return 0; return 0;
} }
int usage_hf14_eget(void){
PrintAndLog("Usage: hf mf eget <block number>");
PrintAndLog(" sample: hf mf eget 0 ");
return 0;
}
int usage_hf14_eclr(void){
PrintAndLog("It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF \n");
PrintAndLog("Usage: hf mf eclr");
return 0;
}
int usage_hf14_eset(void){
PrintAndLog("Usage: hf mf eset <block number> <block data (32 hex symbols)>");
PrintAndLog("sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f ");
return 0;
}
int usage_hf14_eload(void){
PrintAndLog("It loads emul dump from the file `filename.eml`");
PrintAndLog("Usage: hf mf eload [card memory] <file name w/o `.eml`> [numblocks]");
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL");
PrintAndLog("");
PrintAndLog(" sample: hf mf eload filename");
PrintAndLog(" hf mf eload 4 filename");
return 0;
}
int usage_hf14_esave(void){
PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`");
PrintAndLog(" Usage: hf mf esave [card memory] [file name w/o `.eml`]");
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
PrintAndLog("");
PrintAndLog(" sample: hf mf esave ");
PrintAndLog(" hf mf esave 4");
PrintAndLog(" hf mf esave 4 filename");
return 0;
}
int usage_hf14_ecfill(void){
PrintAndLog("Read card and transfer its data to emulator memory.");
PrintAndLog("Keys must be laid in the emulator memory. \n");
PrintAndLog("Usage: hf mf ecfill <key A/B> [card memory]");
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
PrintAndLog("");
PrintAndLog("samples: hf mf ecfill A");
PrintAndLog(" hf mf ecfill A 4");
return 0;
}
int usage_hf14a_ekeyprn(void){
PrintAndLog("It prints the keys loaded in the emulator memory");
PrintAndLog("Usage: hf mf ekeyprn [card memory]");
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
PrintAndLog("");
PrintAndLog(" sample: hf mf ekeyprn 1");
return 0;
}
int usage_hf14_csetuid(void){
PrintAndLog("Set UID, ATQA, and SAK for magic Chinese card. Only works with magic cards");
PrintAndLog("");
PrintAndLog("Usage: hf mf csetuid [h] <UID 8 hex symbols> [ATQA 4 hex symbols] [SAK 2 hex symbols] [w]");
PrintAndLog("Options:");
PrintAndLog(" h this help");
PrintAndLog(" w wipe card before writing");
PrintAndLog(" <uid> UID 8 hex symbols");
PrintAndLog(" <atqa> ATQA 4 hex symbols");
PrintAndLog(" <sak> SAK 2 hex symbols");
PrintAndLog("samples:");
PrintAndLog(" hf mf csetuid 01020304");
PrintAndLog(" hf mf csetuid 01020304 0004 08 w");
return 0;
}
int usage_hf14_csetblk(void){
PrintAndLog("Set block data for magic Chinese card. Only works with magic cards");
PrintAndLog("");
PrintAndLog("Usage: hf mf csetblk [h] <block number> <block data (32 hex symbols)> [w]");
PrintAndLog("Options:");
PrintAndLog(" h this help");
PrintAndLog(" w wipe card before writing");
PrintAndLog(" <block> block number");
PrintAndLog(" <data> block data to write (32 hex symbols)");
PrintAndLog("samples:");
PrintAndLog(" hf mf csetblk 1 01020304050607080910111213141516");
PrintAndLog(" hf mf csetblk 1 01020304050607080910111213141516 w");
return 0;
}
int usage_hf14_cload(void){
PrintAndLog("It loads magic Chinese card from the file `filename.eml`");
PrintAndLog("or from emulator memory");
PrintAndLog("");
PrintAndLog("Usage: hf mf cload [h] [e] <file name w/o `.eml`>");
PrintAndLog("Options:");
PrintAndLog(" h this help");
PrintAndLog(" e load card with data from emulator memory");
PrintAndLog(" <filename> load card with data from file");
PrintAndLog(" samples:");
PrintAndLog(" hf mf cload mydump");
PrintAndLog(" hf mf cload e");
return 0;
}
int usage_hf14_cgetblk(void){
PrintAndLog("Get block data from magic Chinese card. Only works with magic cards\n");
PrintAndLog("");
PrintAndLog("Usage: hf mf cgetblk [h] <block number>");
PrintAndLog("Options:");
PrintAndLog(" h this help");
PrintAndLog(" <block> block number");
PrintAndLog("samples:");
PrintAndLog(" hf mf cgetblk 1");
return 0;
}
int usage_hf14_cgetsc(void){
PrintAndLog("Get sector data from magic Chinese card. Only works with magic cards\n");
PrintAndLog("");
PrintAndLog("Usage: hf mf cgetsc [h] <sector number>");
PrintAndLog("Options:");
PrintAndLog(" h this help");
PrintAndLog(" <sector> sector number");
PrintAndLog("samples:");
PrintAndLog(" hf mf cgetsc 0");
return 0;
}
int usage_hf14_csave(void){
PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");
PrintAndLog("or into emulator memory");
PrintAndLog("");
PrintAndLog("Usage: hf mf csave [h] [e] [u] [card memory] i <file name w/o `.eml`>");
PrintAndLog("Options:");
PrintAndLog(" h this help");
PrintAndLog(" e save data to emulator memory");
PrintAndLog(" u save data to file, use carduid as filename");
PrintAndLog(" card memory 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
PrintAndLog(" i <filename> save data to file");
PrintAndLog("");
PrintAndLog("samples:");
PrintAndLog(" hf mf csave u 1");
PrintAndLog(" hf mf csave e 1");
PrintAndLog(" hf mf csave 4 i filename");
return 0;
}
int CmdHF14AMifare(const char *Cmd) { int CmdHF14AMifare(const char *Cmd) {
uint32_t uid = 0; uint32_t uid = 0;
uint32_t nt = 0, nr = 0; uint32_t nt = 0, nr = 0;
@ -412,6 +549,29 @@ int CmdHF14AMfRdSc(const char *Cmd) {
return 0; return 0;
} }
#define MIFARE_4K_MAXBLOCK 255
#define MIFARE_2K_MAXBLOCK 128
#define MIFARE_1K_MAXBLOCK 64
#define MIFARE_MINI_MAXBLOCK 20
uint8_t NumOfBlocks(char card){
switch(card){
case '0' : return MIFARE_MINI_MAXBLOCK;
case '1' : return MIFARE_1K_MAXBLOCK;
case '2' : return MIFARE_2K_MAXBLOCK;
case '4' : return MIFARE_4K_MAXBLOCK;
default : return MIFARE_1K_MAXBLOCK;
}
}
uint8_t NumOfSectors(char card){
switch(card){
case '0' : return 5;
case '1' : return 16;
case '2' : return 32;
case '4' : return 40;
default : return 16;
}
}
uint8_t FirstBlockOfSector(uint8_t sectorNo) { uint8_t FirstBlockOfSector(uint8_t sectorNo) {
if (sectorNo < 32) { if (sectorNo < 32) {
return sectorNo * 4; return sectorNo * 4;
@ -430,27 +590,16 @@ uint8_t NumBlocksPerSector(uint8_t sectorNo) {
int CmdHF14AMfDump(const char *Cmd) { int CmdHF14AMfDump(const char *Cmd) {
uint8_t sectorNo, blockNo; uint8_t sectorNo, blockNo;
uint8_t keyA[40][6]; uint8_t keyA[40][6];
uint8_t keyB[40][6]; uint8_t keyB[40][6];
uint8_t rights[40][4]; uint8_t rights[40][4];
uint8_t carddata[256][16]; uint8_t carddata[256][16];
uint8_t numSectors = 16; uint8_t numSectors = 16;
FILE *fin, *fout;
FILE *fin;
FILE *fout;
UsbCommand resp; UsbCommand resp;
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
switch (cmdp) { numSectors = NumOfSectors(cmdp);
case '0' : numSectors = 5; break;
case '1' :
case '\0': numSectors = 16; break;
case '2' : numSectors = 32; break;
case '4' : numSectors = 40; break;
default: numSectors = 16;
}
if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mf dump [card memory]"); PrintAndLog("Usage: hf mf dump [card memory]");
@ -617,19 +766,10 @@ int CmdHF14AMfRestore(const char *Cmd) {
uint8_t keyA[40][6]; uint8_t keyA[40][6];
uint8_t keyB[40][6]; uint8_t keyB[40][6];
uint8_t numSectors; uint8_t numSectors;
FILE *fdump, *fkeys;
FILE *fdump;
FILE *fkeys;
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
switch (cmdp) { numSectors = NumOfSectors(cmdp);
case '0' : numSectors = 5; break;
case '1' :
case '\0': numSectors = 16; break;
case '2' : numSectors = 32; break;
case '4' : numSectors = 40; break;
default: numSectors = 16;
}
if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mf restore [card memory]"); PrintAndLog("Usage: hf mf restore [card memory]");
@ -731,7 +871,6 @@ int CmdHF14AMfNested(const char *Cmd) {
uint8_t keyBlock[6*6]; uint8_t keyBlock[6*6];
uint64_t key64 = 0; uint64_t key64 = 0;
bool transferToEml = false; bool transferToEml = false;
bool createDumpFile = false; bool createDumpFile = false;
FILE *fkeys; FILE *fkeys;
uint8_t standart[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t standart[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
@ -768,14 +907,7 @@ int CmdHF14AMfNested(const char *Cmd) {
if (ctmp != 'A' && ctmp != 'a') if (ctmp != 'A' && ctmp != 'a')
trgKeyType = 1; trgKeyType = 1;
} else { } else {
SectorsCnt = NumOfSectors(cmdp);
switch (cmdp) {
case '0': SectorsCnt = 05; break;
case '1': SectorsCnt = 16; break;
case '2': SectorsCnt = 32; break;
case '4': SectorsCnt = 40; break;
default: SectorsCnt = 16;
}
} }
ctmp = param_getchar(Cmd, 4); ctmp = param_getchar(Cmd, 4);
@ -1124,13 +1256,7 @@ int CmdHF14AMfChk(const char *Cmd) {
if (param_getchar(Cmd, 0)=='*') { if (param_getchar(Cmd, 0)=='*') {
blockNo = 3; blockNo = 3;
switch(param_getchar(Cmd+1, 0)) { SectorsCnt = NumOfSectors( param_getchar(Cmd+1, 0) );
case '0': SectorsCnt = 5; break;
case '1': SectorsCnt = 16; break;
case '2': SectorsCnt = 32; break;
case '4': SectorsCnt = 40; break;
default: SectorsCnt = 16;
}
} else { } else {
blockNo = param_get8(Cmd, 0); blockNo = param_get8(Cmd, 0);
} }
@ -1734,16 +1860,13 @@ void printKeyTable( uint8_t sectorscnt, sector_t *e_sector ){
} }
// EMULATOR COMMANDS // EMULATOR COMMANDS
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);
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { if (strlen(Cmd) < 1 || c == 'h' || c == 'H')
PrintAndLog("Usage: hf mf eget <block number>"); return usage_hf14_eget();
PrintAndLog(" sample: hf mf eget 0 ");
return 0;
}
blockNo = param_get8(Cmd, 0); blockNo = param_get8(Cmd, 0);
@ -1753,34 +1876,29 @@ int CmdHF14AMfEGet(const char *Cmd)
} else { } else {
PrintAndLog("Command execute timeout"); PrintAndLog("Command execute timeout");
} }
return 0; return 0;
} }
int CmdHF14AMfEClear(const char *Cmd) int CmdHF14AMfEClear(const char *Cmd) {
{ char c = param_getchar(Cmd, 0);
if (param_getchar(Cmd, 0) == 'h') {
PrintAndLog("Usage: hf mf eclr");
PrintAndLog("It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF \n");
return 0;
}
UsbCommand c = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}}; if (c == 'h' || c == 'H')
SendCommand(&c); return usage_hf14_eclr();
UsbCommand cmd = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};
clearCommandBuffer();
SendCommand(&cmd);
return 0; return 0;
} }
int CmdHF14AMfESet(const char *Cmd) int CmdHF14AMfESet(const char *Cmd) {
{ char c = 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 || param_getchar(Cmd, 0) == 'h') { if (strlen(Cmd) < 3 || c == 'h' || c == 'H')
PrintAndLog("Usage: hf mf eset <block number> <block data (32 hex symbols)>"); return usage_hf14_eset();
PrintAndLog(" sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f ");
return 0;
}
blockNo = param_get8(Cmd, 0); blockNo = param_get8(Cmd, 0);
@ -1790,14 +1908,14 @@ int CmdHF14AMfESet(const char *Cmd)
} }
// 1 - blocks count // 1 - blocks count
UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNo, 1, 0}}; UsbCommand cmd = {CMD_MIFARE_EML_MEMSET, {blockNo, 1, 0}};
memcpy(c.d.asBytes, memBlock, 16); memcpy(cmd.d.asBytes, memBlock, 16);
SendCommand(&c); clearCommandBuffer();
SendCommand(&cmd);
return 0; return 0;
} }
int CmdHF14AMfELoad(const char *Cmd) int CmdHF14AMfELoad(const char *Cmd) {
{
FILE * f; FILE * f;
char filename[FILE_PATH_SIZE]; char filename[FILE_PATH_SIZE];
char *fnameptr = filename; char *fnameptr = filename;
@ -1806,19 +1924,12 @@ int CmdHF14AMfELoad(const char *Cmd)
int i, len, blockNum, numBlocks; int i, len, blockNum, numBlocks;
int nameParamNo = 1; int nameParamNo = 1;
uint8_t blockWidth = 32; uint8_t blockWidth = 32;
char ctmp = param_getchar(Cmd, 0); char c = param_getchar(Cmd, 0);
if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) { if ( c == 'h' || c == 'H' || c == 0x00)
PrintAndLog("It loads emul dump from the file `filename.eml`"); return usage_hf14_eload();
PrintAndLog("Usage: hf mf eload [card memory] <file name w/o `.eml`> [numblocks]");
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K, u = UL");
PrintAndLog("");
PrintAndLog(" sample: hf mf eload filename");
PrintAndLog(" hf mf eload 4 filename");
return 0;
}
switch (ctmp) { 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;
@ -1834,7 +1945,7 @@ int CmdHF14AMfELoad(const char *Cmd)
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); len = param_getstr(Cmd, nameParamNo, filename);
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
@ -1894,8 +2005,7 @@ int CmdHF14AMfELoad(const char *Cmd)
return 0; return 0;
} }
int CmdHF14AMfESave(const char *Cmd) int CmdHF14AMfESave(const char *Cmd) {
{
FILE * f; FILE * f;
char filename[FILE_PATH_SIZE]; char filename[FILE_PATH_SIZE];
char * fnameptr = filename; char * fnameptr = filename;
@ -1906,20 +2016,12 @@ int CmdHF14AMfESave(const char *Cmd)
memset(filename, 0, sizeof(filename)); memset(filename, 0, sizeof(filename));
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
char ctmp = param_getchar(Cmd, 0); char c = param_getchar(Cmd, 0);
if ( ctmp == 'h' || ctmp == 'H') { if ( c == 'h' || c == 'H')
PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`"); return usage_hf14_esave();
PrintAndLog(" Usage: hf mf esave [card memory] [file name w/o `.eml`]");
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
PrintAndLog("");
PrintAndLog(" sample: hf mf esave ");
PrintAndLog(" hf mf esave 4");
PrintAndLog(" hf mf esave 4 filename");
return 0;
}
switch (ctmp) { 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;
@ -1931,7 +2033,7 @@ int CmdHF14AMfESave(const char *Cmd)
} }
} }
len = param_getstr(Cmd,nameParamNo,filename); len = param_getstr(Cmd, nameParamNo, filename);
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
@ -1979,71 +2081,42 @@ int CmdHF14AMfESave(const char *Cmd)
return 0; return 0;
} }
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);
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { if (strlen(Cmd) < 1 || c == 'h' || c == 'H')
PrintAndLog("Usage: hf mf ecfill <key A/B> [card memory]"); return usage_hf14_ecfill();
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
PrintAndLog("");
PrintAndLog("samples: hf mf ecfill A");
PrintAndLog(" hf mf ecfill A 4");
PrintAndLog("Read card and transfer its data to emulator memory.");
PrintAndLog("Keys must be laid in the emulator memory. \n");
return 0;
}
char ctmp = param_getchar(Cmd, 0); if (c != 'a' && c != 'A' && c != 'b' && c != 'B') {
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {
PrintAndLog("Key type must be A or B"); PrintAndLog("Key type must be A or B");
return 1; return 1;
} }
if (ctmp != 'A' && ctmp != 'a') keyType = 1; if (c != 'A' && c != 'a') keyType = 1;
ctmp = param_getchar(Cmd, 1); c = param_getchar(Cmd, 1);
switch (ctmp) { numSectors = NumOfSectors(c);
case '0' : numSectors = 5; break;
case '1' :
case '\0': numSectors = 16; break;
case '2' : numSectors = 32; break;
case '4' : numSectors = 40; break;
default: numSectors = 16;
}
printf("--params: numSectors: %d, keyType:%d", numSectors, keyType); printf("--params: numSectors: %d, keyType:%d", numSectors, keyType);
UsbCommand c = {CMD_MIFARE_EML_CARDLOAD, {numSectors, keyType, 0}}; UsbCommand cmd = {CMD_MIFARE_EML_CARDLOAD, {numSectors, keyType, 0}};
SendCommand(&c); clearCommandBuffer();
SendCommand(&cmd);
return 0; return 0;
} }
int CmdHF14AMfEKeyPrn(const char *Cmd) int CmdHF14AMfEKeyPrn(const char *Cmd) {
{
int i; int i;
uint8_t numSectors; uint8_t numSectors;
uint8_t data[16]; uint8_t data[16];
uint64_t keyA, keyB; uint64_t keyA, keyB;
char cmdp = param_getchar(Cmd, 0); char c = param_getchar(Cmd, 0);
if ( cmdp == 'h' || cmdp == 'H' ) { if ( c == 'h' || c == 'H' )
PrintAndLog("It prints the keys loaded in the emulator memory"); return usage_hf14a_ekeyprn();
PrintAndLog("Usage: hf mf ekeyprn [card memory]");
PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");
PrintAndLog("");
PrintAndLog(" sample: hf mf ekeyprn 1");
return 0;
}
switch (cmdp) { numSectors = NumOfSectors(c);
case '0' : numSectors = 5; break;
case '1' :
case '\0': numSectors = 16; break;
case '2' : numSectors = 32; break;
case '4' : numSectors = 40; break;
default: numSectors = 16;
}
PrintAndLog("|---|----------------|----------------|"); PrintAndLog("|---|----------------|----------------|");
PrintAndLog("|sec|key A |key B |"); PrintAndLog("|sec|key A |key B |");
@ -2058,12 +2131,10 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
PrintAndLog("|%03d| %012" PRIx64 " | %012" PRIx64 " |", i, keyA, keyB); PrintAndLog("|%03d| %012" PRIx64 " | %012" PRIx64 " |", i, keyA, keyB);
} }
PrintAndLog("|---|----------------|----------------|"); PrintAndLog("|---|----------------|----------------|");
return 0; return 0;
} }
// CHINESE MAGIC COMMANDS // CHINESE MAGIC COMMANDS
int CmdHF14AMfCSetUID(const char *Cmd) { int CmdHF14AMfCSetUID(const char *Cmd) {
uint8_t wipeCard = 0; uint8_t wipeCard = 0;
uint8_t uid[8] = {0x00}; uint8_t uid[8] = {0x00};
@ -2075,21 +2146,12 @@ int CmdHF14AMfCSetUID(const char *Cmd) {
char ctmp; char ctmp;
int argi=0; int argi=0;
if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h') { if (strlen(Cmd) < 1 || param_getchar(Cmd, argi) == 'h')
PrintAndLog("Set UID, ATQA, and SAK for magic Chinese card (only works with such cards)"); return usage_hf14_csetuid();
PrintAndLog("If you also want to wipe the card then add 'w' at the end of the command line.");
PrintAndLog(""); if (param_getchar(Cmd, argi) && param_gethex(Cmd, argi, uid, 8))
PrintAndLog("Usage: hf mf csetuid <UID 8 hex symbols> [ATQA 4 hex symbols SAK 2 hex symbols] [w]"); return usage_hf14_csetuid();
PrintAndLog("");
PrintAndLog("sample: hf mf csetuid 01020304");
PrintAndLog(" hf mf csetuid 01020304 0004 08 w");
return 0;
}
if (param_getchar(Cmd, argi) && param_gethex(Cmd, argi, uid, 8)) {
PrintAndLog("UID must include 8 HEX symbols");
return 1;
}
argi++; argi++;
ctmp = param_getchar(Cmd, argi); ctmp = param_getchar(Cmd, argi);
@ -2139,23 +2201,15 @@ 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);
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_csetblk();
PrintAndLog("Usage: hf mf csetblk <block number> <block data (32 hex symbols)> [w]");
PrintAndLog("sample: hf mf csetblk 1 01020304050607080910111213141516");
PrintAndLog("Set block data for magic Chinese card (only works with such cards)");
PrintAndLog("If you also want wipe the card then add 'w' at the end of the command line");
return 0;
}
blockNo = param_get8(Cmd, 0); blockNo = param_get8(Cmd, 0);
if (param_gethex(Cmd, 1, block, 32)) { if (param_gethex(Cmd, 1, block, 32)) return usage_hf14_csetblk();
PrintAndLog("block data must include 32 HEX symbols");
return 1;
}
char ctmp = param_getchar(Cmd, 2); ctmp = param_getchar(Cmd, 2);
if (ctmp == 'w' || ctmp == 'W') if (ctmp == 'w' || ctmp == 'W')
params |= MAGIC_WIPE; params |= MAGIC_WIPE;
@ -2173,8 +2227,8 @@ int CmdHF14AMfCLoad(const char *Cmd) {
FILE * f; FILE * f;
char filename[FILE_PATH_SIZE]; char filename[FILE_PATH_SIZE];
char * fnameptr = filename; char * fnameptr = filename;
char buf[64] = {0x00}; char buf[32] = {0x00};
uint8_t buf8[64] = {0x00}; uint8_t buf8[16] = {0x00};
uint8_t fillFromEmulator = 0; uint8_t fillFromEmulator = 0;
int i, len, blockNum, flags=0; int i, len, blockNum, flags=0;
@ -2182,15 +2236,7 @@ int CmdHF14AMfCLoad(const char *Cmd) {
char ctmp = param_getchar(Cmd, 0); char ctmp = param_getchar(Cmd, 0);
if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) { if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf14_cload();
PrintAndLog("It loads magic Chinese card from the file `filename.eml`");
PrintAndLog("or from emulator memory (option `e`)");
PrintAndLog("Usage: hf mf cload <file name w/o `.eml`>");
PrintAndLog(" or: hf mf cload e ");
PrintAndLog(" sample: hf mf cload filename");
return 0;
}
if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1; if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1;
if (fillFromEmulator) { if (fillFromEmulator) {
@ -2209,7 +2255,8 @@ int CmdHF14AMfCLoad(const char *Cmd) {
} }
} }
return 0; return 0;
} else { }
len = strlen(Cmd); len = strlen(Cmd);
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5; if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
@ -2268,8 +2315,6 @@ int CmdHF14AMfCLoad(const char *Cmd) {
} }
PrintAndLog("Loaded from file: %s", filename); PrintAndLog("Loaded from file: %s", filename);
return 0; return 0;
}
return 0;
} }
int CmdHF14AMfCGetBlk(const char *Cmd) { int CmdHF14AMfCGetBlk(const char *Cmd) {
@ -2277,14 +2322,9 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
uint8_t blockNo = 0; uint8_t blockNo = 0;
int res; int res;
memset(data, 0x00, sizeof(data)); memset(data, 0x00, sizeof(data));
char ctmp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') { char ctmp = param_getchar(Cmd, 0);
PrintAndLog("Usage: hf mf cgetblk <block number>"); if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_cgetblk();
PrintAndLog("sample: hf mf cgetblk 1");
PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n");
return 0;
}
blockNo = param_get8(Cmd, 0); blockNo = param_get8(Cmd, 0);
@ -2301,77 +2341,142 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
} }
int CmdHF14AMfCGetSc(const char *Cmd) { int CmdHF14AMfCGetSc(const char *Cmd) {
uint8_t data[16]; uint8_t *data = NULL;
uint8_t sectorNo = 0; uint8_t sector = 0;
int i, res, flags; int i, res, flags;
memset(data, 0x00, sizeof(data));
char ctmp = param_getchar(Cmd, 0); char ctmp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_hf14_cgetsc();
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') { sector = param_get8(Cmd, 0);
PrintAndLog("Usage: hf mf cgetsc <sector number>"); if (sector > 39) {
PrintAndLog("sample: hf mf cgetsc 0"); PrintAndLog("Sector number must be less then 40");
PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n");
return 0;
}
sectorNo = param_get8(Cmd, 0);
if (sectorNo > 15) {
PrintAndLog("Sector number must be in [0..15] as in MIFARE classic.");
return 1; return 1;
} }
PrintAndLog("--sector number:%d ", sectorNo); PrintAndLog("Sector : %02d/0x%02X ", sector, sector);
PrintAndLog("block | data"); PrintAndLog("block | data");
flags = MAGIC_INIT + MAGIC_WUPC; uint8_t blocks = 4;
for (i = 0; i < 4; i++) { uint8_t start = sector * 4;
if (i == 1) flags = 0; if ( sector > 32 ) {
if (i == 3) flags = MAGIC_HALT + MAGIC_OFF; blocks = 16;
start = 128 + ( sector - 32 ) * 16;
}
res = mfCGetBlock(sectorNo * 4 + i, data, flags); flags = MAGIC_INIT + MAGIC_WUPC;
for (i = 0; i < blocks; i++) {
if (i == 1) flags = 0;
if (i == blocks-1) flags = MAGIC_HALT + MAGIC_OFF;
res = mfCGetBlock( start + i, data, flags);
if (res) { if (res) {
PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res); PrintAndLog("Can't read block. %d error=%d", start + i, res);
return 1; return 1;
} }
PrintAndLog(" %3d | %s", sectorNo * 4 + i, sprint_hex(data, sizeof(data))); PrintAndLog(" %3d | %s", start + i, sprint_hex(data, sizeof(data)));
} }
return 0; return 0;
} }
int CmdHF14AMfCSave(const char *Cmd) { int CmdHF14AMfCSave(const char *Cmd) {
FILE * f; FILE * feml;
char filename[FILE_PATH_SIZE]; FILE * fbin;
char * fnameptr = filename; char filename[2][FILE_PATH_SIZE];
uint8_t fillFromEmulator = 0; char * femlptr = filename[0];
uint8_t buf[64]; char * fbinptr = filename[1];
bool fillFromEmulator = false;
bool errors = false;
bool hasname = false;
uint8_t buf[16];
int i, j, len, flags; int i, j, len, flags;
uint8_t numblocks = 0;
uint8_t cmdp = 0;
char ctmp;
memset(filename, 0, sizeof(filename)); memset(filename, 0, sizeof(filename));
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
char ctmp = param_getchar(Cmd, 0);
if ( ctmp == 'h' || ctmp == 'H' ) { while(param_getchar(Cmd, cmdp) != 0x00) {
PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`"); ctmp = param_getchar(Cmd, cmdp);
PrintAndLog("or into emulator memory (option `e`)"); switch(ctmp) {
PrintAndLog("Usage: hf mf esave [file name w/o `.eml`][e]"); case 'e':
PrintAndLog(" sample: hf mf esave "); case 'E':
PrintAndLog(" hf mf esave filename"); fillFromEmulator = true;
PrintAndLog(" hf mf esave e \n"); cmdp++;
return 0; break;
case 'h':
case 'H':
return usage_hf14_csave();
case '0':
case '1':
case '2':
case '4':
numblocks = NumOfBlocks(ctmp);
cmdp++;
break;
case 'u':
case 'U':
// get filename based on UID
if (mfCGetBlock(0, buf, MAGIC_SINGLE)) {
PrintAndLog("Cant get block: %d", 0);
femlptr += sprintf(femlptr, "dump");
fbinptr += sprintf(fbinptr, "dump");
} else {
for (j = 0; j < 7; j++) {
femlptr += sprintf(femlptr, "%02x", buf[j]);
fbinptr += sprintf(fbinptr, "%02x", buf[j]);
} }
if (ctmp == 'e' || ctmp == 'E') fillFromEmulator = 1; }
hasname = true;
cmdp++;
break;
case 'i':
case 'I':
// input file
len = param_getstr(Cmd, cmdp+1, filename[0]);
if (len < 1) {
errors = true;
break;
}
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
memcpy(filename[0], Cmd, len);
memcpy(filename[1], Cmd, len);
femlptr += len;
fbinptr += len;
hasname = true;
cmdp += 2;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
if (errors) break;
}
// must have filename when saving.
if (!hasname && !fillFromEmulator) errors = true;
//Validations
if (errors) return usage_hf14_csave();
if (fillFromEmulator) { if (fillFromEmulator) {
// put into emulator // put into emulator
flags = MAGIC_INIT + MAGIC_WUPC; flags = MAGIC_INIT + MAGIC_WUPC;
for (i = 0; i < 16 * 4; i++) { for (i = 0; i < numblocks; i++) {
if (i == 1) flags = 0; if (i == 1) flags = 0;
if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; if (i == numblocks - 1) flags = MAGIC_HALT + MAGIC_OFF;
if (mfCGetBlock(i, buf, flags)) { if (mfCGetBlock(i, buf, flags)) {
PrintAndLog("Cant get block: %d", i); PrintAndLog("Cant get block: %d", i);
break; return 3;
} }
if (mfEmlSetMem(buf, i, 1)) { if (mfEmlSetMem(buf, i, 1)) {
@ -2379,57 +2484,49 @@ int CmdHF14AMfCSave(const char *Cmd) {
return 3; return 3;
} }
} }
// exit
return 0; return 0;
} else {
len = strlen(Cmd);
if (len > FILE_PATH_SIZE - 5) len = FILE_PATH_SIZE - 5;
// get filename based on UID
if (len < 1) {
if (mfCGetBlock(0, buf, MAGIC_SINGLE)) {
PrintAndLog("Cant get block: %d", 0);
len = sprintf(fnameptr, "dump");
fnameptr += len;
} else {
for (j = 0; j < 7; j++, fnameptr += 2)
sprintf(fnameptr, "%02x", buf[j]);
}
} else {
memcpy(filename, Cmd, len);
fnameptr += len;
} }
// add .eml extension sprintf(femlptr, ".eml");
sprintf(fnameptr, ".eml"); sprintf(fbinptr, ".bin");
// open file if ((feml = fopen(filename[0], "w+")) == NULL ) {
f = fopen(filename, "w+"); PrintAndLog("File not found or locked");
if (f == NULL) {
PrintAndLog("File not found or locked.");
return 1; return 1;
} }
// put hex if ((fbin = fopen(filename[1], "wb")) == NULL) {
PrintAndLog("File not found or locked");
return 1;
}
// dump to files
flags = MAGIC_INIT + MAGIC_WUPC; flags = MAGIC_INIT + MAGIC_WUPC;
for (i = 0; i < 16 * 4; i++) { for (i = 0; i < numblocks; i++) {
if (i == 1) flags = 0; if (i == 1) flags = 0;
if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; if (i == numblocks - 1) flags = MAGIC_HALT + MAGIC_OFF;
if (mfCGetBlock(i, buf, flags)) { if (mfCGetBlock(i, buf, flags)) {
PrintAndLog("Cant get block: %d", i); PrintAndLog("Cant get block: %d", i);
break; break;
} }
// eml
for (j = 0; j < 16; j++) for (j = 0; j < 16; j++)
fprintf(f, "%02x", buf[j]); fprintf(feml, "%02x", buf[j]);
fprintf(f,"\n"); fprintf(feml,"\n");
// bin
fwrite(buf, 1, sizeof(buf), fbin);
} }
fflush(f);
fclose(f); fflush(feml); fflush(fbin);
PrintAndLog("Saved to file: %s", filename); fclose(feml); fclose(fbin);
for (uint8_t i=0; i<2; ++i)
PrintAndLog("Saved to file: %s", filename[i]);
return 0; return 0;
}
} }
//needs nt, ar, at, Data to decrypt //needs nt, ar, at, Data to decrypt
@ -2464,7 +2561,7 @@ int CmdHf14AMfSetMod(const char *Cmd) {
int gethexfail = param_gethex(Cmd, 1, key, 12); int gethexfail = param_gethex(Cmd, 1, key, 12);
if (mod == 2 || gethexfail) { if (mod == 2 || gethexfail) {
PrintAndLog("Sets the load modulation strength of a MIFARE Classic EV1 card."); PrintAndLog("Sets the load modulation strength of a MIFARE Classic EV1 card.");
PrintAndLog("Usage: hf mf setmod <0/1> <block 0 key A>"); PrintAndLog("Usage: hf mf setmod <0|1> <block 0 key A>");
PrintAndLog(" 0 = normal modulation"); PrintAndLog(" 0 = normal modulation");
PrintAndLog(" 1 = strong modulation (default)"); PrintAndLog(" 1 = strong modulation (default)");
return 1; return 1;
@ -2479,9 +2576,8 @@ int CmdHf14AMfSetMod(const char *Cmd) {
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
uint8_t ok = resp.arg[0] & 0xff; uint8_t ok = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", ok); PrintAndLog("isOk:%02x", ok);
if (!ok) { if (!ok)
PrintAndLog("Failed."); PrintAndLog("Failed.");
}
} else { } else {
PrintAndLog("Command execute timeout"); PrintAndLog("Command execute timeout");
} }