Merge pull request #1129 from tcprst/legic_cliparser

hf legic wipe, dump, restore, eload, esave - now use cliparser
This commit is contained in:
Iceman 2020-12-21 21:10:29 +01:00 committed by GitHub
commit 82362cc9e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 138 additions and 241 deletions

View file

@ -710,7 +710,7 @@ function readFromPM3()
local tag, bytes, infile local tag, bytes, infile
--infile="legic.temp" --infile="legic.temp"
infile=os.tmpname() infile=os.tmpname()
core.console("hf legic dump f "..infile) core.console("hf legic dump -f "..infile)
tag=readFile(infile..".bin") tag=readFile(infile..".bin")
os.remove(infile) os.remove(infile)
os.remove(infile..".bin") os.remove(infile..".bin")

View file

@ -456,7 +456,7 @@ local function writeToTag(plainBytes)
-- write data to file -- write data to file
if (writeOutputBytes(bytes, "hf-legic-UID-dump.bin")) then if (writeOutputBytes(bytes, "hf-legic-UID-dump.bin")) then
-- write pm3-buffer to Tag -- write pm3-buffer to Tag
cmd = ('hf legic restore f hf-legic-UID-dump') cmd = ('hf legic restore -f hf-legic-UID-dump')
core.console(cmd) core.console(cmd)
end end
end end
@ -530,7 +530,7 @@ local function main(args)
res = res .."\ncreated clone_dump from\n\t"..infile.." crc: "..oldcrc.."\ndump_file:" res = res .."\ncreated clone_dump from\n\t"..infile.." crc: "..oldcrc.."\ndump_file:"
res = res .."\n\t"..outfile.." crc: "..string.sub(newcrc, -2) res = res .."\n\t"..outfile.." crc: "..string.sub(newcrc, -2)
res = res .."\nyou may load the new file with:" res = res .."\nyou may load the new file with:"
res = res ..ansicolors.yellow.."hf legic eload f "..outfile..ansicolors.reset res = res ..ansicolors.yellow.."hf legic eload -f "..outfile..ansicolors.reset
res = res .."\n\nif you don't write to tag immediately ('-w' switch) you will need to recalculate each segmentCRC" res = res .."\n\nif you don't write to tag immediately ('-w' switch) you will need to recalculate each segmentCRC"
res = res .."\nafter writing this dump to a tag!" res = res .."\nafter writing this dump to a tag!"
res = res .."\n\na segmentCRC gets calculated over MCD,MSN0..3, Segment-Header0..3" res = res .."\n\na segmentCRC gets calculated over MCD,MSN0..3, Segment-Header0..3"

View file

@ -28,76 +28,6 @@ static int CmdHelp(const char *Cmd);
#define MAX_LENGTH 1024 #define MAX_LENGTH 1024
static int usage_legic_dump(void) {
PrintAndLogEx(NORMAL, "Read all memory from LEGIC Prime MIM22, MIM256, MIM1024");
PrintAndLogEx(NORMAL, "and saves bin/eml/json dump file");
PrintAndLogEx(NORMAL, "It autodetects card type.\n");
PrintAndLogEx(NORMAL, "Usage: hf legic dump [h] [x] [f <filename w/o .bin>]\n");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
PrintAndLogEx(NORMAL, " f <filename> : filename w/o '.bin' to dump bytes");
PrintAndLogEx(NORMAL, " x : deobfuscate dump data (xor with MCC)");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic dump - uses UID as filename"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic dump f myfile"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic dump x"));
return PM3_SUCCESS;
}
static int usage_legic_restore(void) {
PrintAndLogEx(NORMAL, "Reads binary file and it autodetects card type and verifies that the file has the same size");
PrintAndLogEx(NORMAL, "Then write the data back to card. All bytes except the first 7bytes [UID(4) MCC(1) DCF(2)]\n");
PrintAndLogEx(NORMAL, "Usage: hf legic restore [h] [x] [f <filename w/o .bin>]\n");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
PrintAndLogEx(NORMAL, " f <filename> : filename w/o '.bin' to restore bytes on to card from");
PrintAndLogEx(NORMAL, " x : obfuscate dump data (xor with MCC)");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic restore f myfile"));
return PM3_SUCCESS;
}
static int usage_legic_eload(void) {
PrintAndLogEx(NORMAL, "It loads a binary dump into emulator memory\n");
PrintAndLogEx(NORMAL, "Usage: hf legic eload [h] [card memory] [f <file name w/o `.bin`>]\n");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
PrintAndLogEx(NORMAL, " [card memory] : 0 = MIM22");
PrintAndLogEx(NORMAL, " : 1 = MIM256 (default)");
PrintAndLogEx(NORMAL, " : 2 = MIM1024");
PrintAndLogEx(NORMAL, " f <filename> : filename w/o .bin to load");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic eload 2 f myfile"));
return PM3_SUCCESS;
}
static int usage_legic_esave(void) {
PrintAndLogEx(NORMAL, "It saves bin/eml/json dump file of emulator memory\n");
PrintAndLogEx(NORMAL, "Usage: hf legic esave [h] [card memory] f <file name w/o `.bin`>\n");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
PrintAndLogEx(NORMAL, " [card memory] : 0 = MIM22");
PrintAndLogEx(NORMAL, " : 1 = MIM256 (default)");
PrintAndLogEx(NORMAL, " : 2 = MIM1024");
PrintAndLogEx(NORMAL, " f <filename> : filename w/o .bin to load");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic esave 2 - uses UID as filename"));
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic esave 2 f myfile"));
return PM3_SUCCESS;
}
static int usage_legic_wipe(void) {
PrintAndLogEx(NORMAL, "Fills a LEGIC Prime tags memory with zeros. From byte7 and to the end");
PrintAndLogEx(NORMAL, "It autodetects card type\n");
PrintAndLogEx(NORMAL, "Usage: hf legic wipe [h]\n");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf legic wipe"));
return PM3_SUCCESS;
}
static bool legic_xor(uint8_t *data, uint16_t cardsize) { static bool legic_xor(uint8_t *data, uint16_t cardsize) {
if (cardsize <= 22) { if (cardsize <= 22) {
@ -824,38 +754,29 @@ static int CmdLegicReader(const char *Cmd) {
} }
static int CmdLegicDump(const char *Cmd) { static int CmdLegicDump(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf legic dump",
"Read all memory from LEGIC Prime MIM22, MIM256, MIM1024 and saves bin/eml/json dump file\n"
"It autodetects card type.",
"hf legic dump <-- use UID as filename\n"
"hf legic dump -f myfile <-- use user specified filename\n"
"hf legic dump --deobfuscate <-- use UID as filename and deobfuscate data");
int fileNameLen = 0; void *argtable[] = {
char filename[FILE_PATH_SIZE] = {0x00}; arg_param_begin,
char *fptr = filename; arg_str0("f", "file", "<filename>", "specify a filename for dump file"),
bool errors = false, shall_deobsfuscate = false; arg_lit0(NULL, "deobfuscate", "deobfuscate dump data (xor with MCC)"),
uint16_t dumplen; arg_param_end
uint8_t cmdp = 0; };
CLIExecWithReturn(ctx, Cmd, argtable, true);
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { int fnlen = 0;
switch (tolower(param_getchar(Cmd, cmdp))) { char filename[FILE_PATH_SIZE] = {0};
case 'h': CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
return usage_legic_dump();
case 'f': bool shall_deobsfuscate = arg_get_lit(ctx, 2);
fileNameLen = param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE);
if (!fileNameLen) CLIParserFree(ctx);
errors = true;
if (fileNameLen > FILE_PATH_SIZE - 5)
fileNameLen = FILE_PATH_SIZE - 5;
cmdp += 2;
break;
case 'x':
shall_deobsfuscate = true;
cmdp++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
//Validations
if (errors) return usage_legic_dump();
// tagtype // tagtype
legic_card_select_t card; legic_card_select_t card;
@ -863,7 +784,7 @@ static int CmdLegicDump(const char *Cmd) {
PrintAndLogEx(WARNING, "Failed to identify tagtype"); PrintAndLogEx(WARNING, "Failed to identify tagtype");
return PM3_ESOFT; return PM3_ESOFT;
} }
dumplen = card.cardsize; uint16_t dumplen = card.cardsize;
legic_print_type(dumplen, 0); legic_print_type(dumplen, 0);
PrintAndLogEx(SUCCESS, "Reading tag memory %d b...", dumplen); PrintAndLogEx(SUCCESS, "Reading tag memory %d b...", dumplen);
@ -907,10 +828,10 @@ static int CmdLegicDump(const char *Cmd) {
} }
// user supplied filename? // user supplied filename?
if (fileNameLen < 1) { if (fnlen < 1) {
PrintAndLogEx(INFO, "Using UID as filename"); PrintAndLogEx(INFO, "Using UID as filename");
fptr += snprintf(fptr, sizeof(filename), "hf-legic-"); strcat(filename, "hf-legic-");
FillFileNameByUID(fptr, data, "-dump", 4); FillFileNameByUID(filename, data, "-dump", 4);
} }
if (shall_deobsfuscate) { if (shall_deobsfuscate) {
@ -927,44 +848,28 @@ static int CmdLegicDump(const char *Cmd) {
} }
static int CmdLegicRestore(const char *Cmd) { static int CmdLegicRestore(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf legic restore",
"Reads binary file and it autodetects card type and verifies that the file has the same size\n"
"Then write the data back to card. All bytes except the first 7bytes [UID(4) MCC(1) DCF(2)]",
"hf legic restore -f myfile <-- use user specified filename\n"
"hf legic restore -f myfile --obfuscate <-- use UID as filename and deobfuscate data");
char filename[FILE_PATH_SIZE] = {0x00}; void *argtable[] = {
bool errors = false, shall_obsfuscate = false, have_filename = false; arg_param_begin,
size_t numofbytes; arg_str1("f", "file", "<filename>", "specify a filename to restore"),
uint8_t cmdp = 0; arg_lit0(NULL, "obfuscate", "obfuscate dump data (xor with MCC)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { int fnlen = 0;
switch (tolower(param_getchar(Cmd, cmdp))) { char filename[FILE_PATH_SIZE] = {0};
case 'h': { CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
errors = true;
break;
}
case 'f': {
if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) {
PrintAndLogEx(FAILED, "Filename too long");
break;
}
have_filename = true;
cmdp += 2;
break;
}
case 'x': {
shall_obsfuscate = true;
cmdp++;
break;
}
default: {
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
}
if (have_filename == false)
errors = true;
//Validations bool shall_obsfuscate = arg_get_lit(ctx, 2);
if (errors || cmdp == 0) return usage_legic_restore();
CLIParserFree(ctx);
// tagtype // tagtype
legic_card_select_t card; legic_card_select_t card;
@ -982,6 +887,7 @@ static int CmdLegicRestore(const char *Cmd) {
return PM3_EMALLOC; return PM3_EMALLOC;
} }
size_t numofbytes;
if (loadFile_safe(filename, ".bin", (void **)&data, &numofbytes) != PM3_SUCCESS) { if (loadFile_safe(filename, ".bin", (void **)&data, &numofbytes) != PM3_SUCCESS) {
free(data); free(data);
PrintAndLogEx(WARNING, "Error, reading file"); PrintAndLogEx(WARNING, "Error, reading file");
@ -1042,58 +948,47 @@ static int CmdLegicRestore(const char *Cmd) {
} }
static int CmdLegicELoad(const char *Cmd) { static int CmdLegicELoad(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf legic eload",
"Loads a LEGIC binary dump into emulator memory",
"hf legic eload -f myfile -t 0 <- Simulate Type MIM22\n"
"hf legic eload -f myfile -t 1 <- Simulate Type MIM256 (default)\n"
"hf legic eload -f myfile -t 2 <- Simulate Type MIM1024");
size_t numofbytes = 256; void *argtable[] = {
char filename[FILE_PATH_SIZE] = {0x00}; arg_param_begin,
bool errors = false, shall_obsfuscate = false, have_filename = false; arg_str1("f", "file", "<filename>", "Specify a filename to restore"),
uint8_t cmdp = 0; arg_int0("t", "type", "<dec>", "Tag type to simulate."),
arg_lit0(NULL, "obfuscate", "Obfuscate dump data (xor with MCC)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { int fnlen = 0;
switch (tolower(param_getchar(Cmd, cmdp))) { char filename[FILE_PATH_SIZE] = {0};
case 'h' : { CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
return usage_legic_eload();
} size_t numofbytes = 0;
case 'f' : {
if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { switch (arg_get_int_def(ctx, 2, 1)) {
PrintAndLogEx(FAILED, "Filename too long"); case 0:
break;
}
have_filename = true;
cmdp += 2;
break;
}
case 'x': {
shall_obsfuscate = true;
cmdp++;
break;
}
case '0' : {
numofbytes = 22; numofbytes = 22;
cmdp++;
break; break;
} case 1:
case '1' : {
numofbytes = 256; numofbytes = 256;
cmdp++;
break; break;
} case 2:
case '2' : {
numofbytes = 1024; numofbytes = 1024;
cmdp++;
break; break;
default:
PrintAndLogEx(ERR, "Unknown tag type");
CLIParserFree(ctx);
return PM3_EINVARG;
} }
default : {
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
}
if (have_filename == false)
errors = true;
//Validations bool shall_obsfuscate = arg_get_lit(ctx, 3);
if (errors || strlen(Cmd) == 0) return usage_legic_eload();
CLIParserFree(ctx);
// set up buffer // set up buffer
uint8_t *data = calloc(numofbytes, sizeof(uint8_t)); uint8_t *data = calloc(numofbytes, sizeof(uint8_t));
@ -1121,49 +1016,48 @@ static int CmdLegicELoad(const char *Cmd) {
} }
static int CmdLegicESave(const char *Cmd) { static int CmdLegicESave(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf legic esave",
"Saves bin/eml/json dump file of emulator memory",
"hf legic esave <- uses UID as filename\n"
"hf legic esave -f myfile -t 0 <- Type MIM22\n"
"hf legic esave -f myfile -t 1 <- Type MIM256 (default)\n"
"hf legic esave -f myfile -t 2 <- Type MIM1024");
void *argtable[] = {
arg_param_begin,
arg_str0("f", "file", "<filename>", "Specify a filename to save"),
arg_int0("t", "type", "<dec>", "Tag type"),
arg_lit0(NULL, "deobfuscate", "De-obfuscate dump data (xor with MCC)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
char *fptr = filename; CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
int fileNameLen = 0;
size_t numofbytes = 256; size_t numofbytes = 0;
bool errors = false, shall_deobsfuscate = false;
uint8_t cmdp = 0; switch (arg_get_int_def(ctx, 2, 1)) {
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { case 0:
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h' :
return usage_legic_esave();
case 'f' :
fileNameLen = param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE);
if (!fileNameLen)
errors = true;
if (fileNameLen > FILE_PATH_SIZE - 5)
fileNameLen = FILE_PATH_SIZE - 5;
cmdp += 2;
break;
case 'x':
shall_deobsfuscate = true;
cmdp++;
break;
case '0' :
numofbytes = 22; numofbytes = 22;
cmdp++;
break; break;
case '1' : case 1:
numofbytes = 256; numofbytes = 256;
cmdp++;
break; break;
case '2' : case 2:
numofbytes = 1024; numofbytes = 1024;
cmdp++;
break; break;
default: default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); PrintAndLogEx(ERR, "Unknown tag type");
errors = true; CLIParserFree(ctx);
break; return PM3_EINVARG;
} }
}
//Validations bool shall_deobsfuscate = arg_get_lit(ctx, 3);
if (errors || strlen(Cmd) == 0) return usage_legic_esave();
CLIParserFree(ctx);
// set up buffer // set up buffer
uint8_t *data = calloc(numofbytes, sizeof(uint8_t)); uint8_t *data = calloc(numofbytes, sizeof(uint8_t));
@ -1181,10 +1075,10 @@ static int CmdLegicESave(const char *Cmd) {
} }
// user supplied filename? // user supplied filename?
if (fileNameLen < 1) { if (fnlen < 1) {
PrintAndLogEx(INFO, "Using UID as filename"); PrintAndLogEx(INFO, "Using UID as filename");
fptr += snprintf(fptr, sizeof(filename), "hf-legic-"); strcat(filename, "hf-legic-");
FillFileNameByUID(fptr, data, "-dump", 4); FillFileNameByUID(filename, data, "-dump", 4);
} }
if (shall_deobsfuscate) { if (shall_deobsfuscate) {
@ -1198,10 +1092,18 @@ static int CmdLegicESave(const char *Cmd) {
} }
static int CmdLegicWipe(const char *Cmd) { static int CmdLegicWipe(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf legic wipe",
"Fills a LEGIC Prime tags memory with zeros. From byte7 and to the end\n"
"It autodetects card type",
"hf legic wipe");
char cmdp = tolower(param_getchar(Cmd, 0)); void *argtable[] = {
arg_param_begin,
if (cmdp == 'h') return usage_legic_wipe(); arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
// tagtype // tagtype
legic_card_select_t card; legic_card_select_t card;

View file

@ -74,11 +74,6 @@ hf felica resetmode
hf felica litesim hf felica litesim
hf felica litedump hf felica litedump
hf fido info hf fido info
hf legic dump
hf legic restore
hf legic eload
hf legic esave
hf legic wipe
hf mf darkside hf mf darkside
hf mf nested hf mf nested
hf mf hardnested hf mf hardnested