diff --git a/CHANGELOG.md b/CHANGELOG.md index 74f5f8006..68657412f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,30 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Add support new frame format in all Lua scripts (@iceman) + - Add CMD_CAPABILITIES for pm3 to inform dynamically the client (@doegox) + - Change baudrate handling, make it clear it's only indicative for USB-CDC & BT (@doegox) + - Change much faster flashmem writes (@doegox) + - Change: new progressive light scheme for 'hw detectreader' (@doegox) + - Add common error definitions system for retvals (@doegox) + - Change USART RX & TX code and fix delays handling to make it more robust, especially over BT (@doegox) + - Add support for new frames format, speedup & huge changes, see doc/new_frame_format.txt (@doegox) + - Change: loadFile* & saveFile* accept filenames with (or still without) extension (@doegox) + - Fix LoadEML to accept final "\n", e.g. from pm3_mfd2eml.py (@doegox) + - Change: rework shell scripts for easy client or flasher (@doegox) + - Fix: stop poking Internet when compiling (@doegox) + - Add support for multiple commands to "-c", e.g. proxmark3 -c "hw ping;hw version" (@doegox) + - Fix external flash writing bitflips issues at 24MHz (@doegox) + - Add color support to Dbprintf & alike and rework Dbprintf flags (@doegox) + - Change: archive (and fix) hid-flasher (@doegox) + - Add standalone placeholder to simplify new standalone integration (@doegox) + - Change: refactor standalone mode info string (@iceman) + - Add iceman skeleton standalone mode for ppl to use as base for their new modes (@iceman) + - Change: move compilation options to Makefile.hal (@doegox) + - Fix compilation under OSX (@iceman) + - Add openocd config files for JLink (@doegox) + - Fix compilation dependencies for recovery (@doegox) + - Fix segfault when loading a file (@doegox) - Change/Add new dump format for Ultralight/NTAG, counters support, simulation (@mceloff) - Add 'hf mf sim' full-byte split anticollision support (@mceloff) - Fix/Add 'hf mf sim' bugs fix, RATS support, etc (@mceloff) diff --git a/client/cmdflashmem.c b/client/cmdflashmem.c index cbf336773..3a202c875 100644 --- a/client/cmdflashmem.c +++ b/client/cmdflashmem.c @@ -222,7 +222,7 @@ static int CmdFlashMemLoad(const char *Cmd) { switch (d) { case DICTIONARY_MIFARE: start_index = DEFAULT_MF_KEYS_OFFSET; - res = loadFileDICTIONARY(filename, "dic", data + 2, &datalen, 6, &keycount); + res = loadFileDICTIONARY(filename, data + 2, &datalen, 6, &keycount); if (res || !keycount) { free(data); return PM3_EFILE; @@ -233,7 +233,7 @@ static int CmdFlashMemLoad(const char *Cmd) { break; case DICTIONARY_T55XX: start_index = DEFAULT_T55XX_KEYS_OFFSET; - res = loadFileDICTIONARY(filename, "dic", data + 2, &datalen, 4, &keycount); + res = loadFileDICTIONARY(filename, data + 2, &datalen, 4, &keycount); if (res || !keycount) { free(data); return PM3_EFILE; @@ -244,7 +244,7 @@ static int CmdFlashMemLoad(const char *Cmd) { break; case DICTIONARY_ICLASS: start_index = DEFAULT_ICLASS_KEYS_OFFSET; - res = loadFileDICTIONARY(filename, "dic", data + 2, &datalen, 8, &keycount); + res = loadFileDICTIONARY(filename, data + 2, &datalen, 8, &keycount); if (res || !keycount) { free(data); return PM3_EFILE; @@ -254,8 +254,8 @@ static int CmdFlashMemLoad(const char *Cmd) { datalen += 2; break; case DICTIONARY_NONE: - res = loadFile(filename, "bin", data, FLASH_MEM_MAX_SIZE, &datalen); - //int res = loadFileEML( filename, "eml", data, &datalen); + res = loadFile(filename, ".bin", data, FLASH_MEM_MAX_SIZE, &datalen); + //int res = loadFileEML( filename, data, &datalen); if (res) { free(data); return PM3_EFILE; @@ -367,8 +367,8 @@ static int CmdFlashMemSave(const char *Cmd) { return PM3_EFLASH; } - saveFile(filename, "bin", dump, len); - saveFileEML(filename, "eml", dump, len, 16); + saveFile(filename, ".bin", dump, len); + saveFileEML(filename, dump, len, 16); free(dump); return PM3_SUCCESS; } diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 54a292447..3512e4860 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -961,8 +961,8 @@ static int CmdHF14BDump(const char *Cmd) { size_t datalen = (blocks + 1) * 4; - saveFileEML(filename, "eml", data, datalen, 4); - saveFile(filename, "bin", data, datalen); + saveFileEML(filename, data, datalen, 4); + saveFile(filename, ".bin", data, datalen); out: return switch_off_field_14b(); } diff --git a/client/cmdhf15.c b/client/cmdhf15.c index 3035d017c..b55904bd6 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -833,8 +833,8 @@ static int CmdHF15Dump(const char *Cmd) { PrintAndLogEx(NORMAL, "\n"); size_t datalen = blocknum * 4; - saveFileEML(filename, "eml", data, datalen, 4); - saveFile(filename, "bin", data, datalen); + saveFileEML(filename, data, datalen, 4); + saveFile(filename, ".bin", data, datalen); return 0; } diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 3c32af50a..a794358a7 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -422,7 +422,7 @@ static int CmdHFiClassSim(const char *Cmd) { memcpy(dump + i * 24 + 16, resp.data.asBytes + i * 16 + 8, 8); } /** Now, save to dumpfile **/ - saveFile("iclass_mac_attack", "bin", dump, datalen); + saveFile("iclass_mac_attack", ".bin", dump, datalen); free(dump); break; } @@ -474,7 +474,7 @@ static int CmdHFiClassSim(const char *Cmd) { // copy NR_MAC (eight bytes from the response) ( 8b csn + 8b epurse == 16) memcpy(dump + i * MAC_ITEM_SIZE + 16, resp.data.asBytes + i * 16 + 8, 8); } - saveFile("iclass_mac_attack_keyroll_A", "bin", dump, datalen); + saveFile("iclass_mac_attack_keyroll_A", ".bin", dump, datalen); //KEYROLL 2 memset(dump, 0, datalen); @@ -489,7 +489,7 @@ static int CmdHFiClassSim(const char *Cmd) { memcpy(dump + i * MAC_ITEM_SIZE + 16, resp.data.asBytes + resp_index + 8, 8); resp_index++; } - saveFile("iclass_mac_attack_keyroll_B", "bin", dump, datalen); + saveFile("iclass_mac_attack_keyroll_B", ".bin", dump, datalen); free(dump); break; } @@ -707,7 +707,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { } } - saveFile(outfilename, "bin", decrypted, fsize); + saveFile(outfilename, ".bin", decrypted, fsize); printIclassDumpContents(decrypted, 1, (fsize / 8), fsize); free(decrypted); return 0; @@ -1067,7 +1067,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) { // save the dump to .bin file PrintAndLogEx(SUCCESS, "saving dump file - %d blocks read", gotBytes / 8); - saveFile(filename, "bin", tag_data, gotBytes); + saveFile(filename, ".bin", tag_data, gotBytes); return 1; } diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 21f40dacd..ca5f53a2b 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -1199,8 +1199,8 @@ static int CmdLegicESave(const char *Cmd) { else sprintf(fnameptr + fileNlen, ".bin"); - saveFileEML(filename, "eml", data, numofbytes, 8); - saveFile(filename, "bin", data, numofbytes); + saveFileEML(filename, data, numofbytes, 8); + saveFile(filename, ".bin", data, numofbytes); return 0; } diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 052bcd191..45be7c2bc 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -678,7 +678,7 @@ static uint16_t NumOfBlocks(char card) { case '4' : return MIFARE_4K_MAXBLOCK; default : - return MIFARE_1K_MAXBLOCK; + return 0; } } @@ -693,7 +693,7 @@ static uint8_t NumOfSectors(char card) { case '4' : return MIFARE_4K_MAXSECTOR; default : - return MIFARE_1K_MAXSECTOR; + return 0; } } @@ -748,6 +748,7 @@ static int CmdHF14AMfDump(const char *Cmd) { default: if (cmdp == 0) { numSectors = NumOfSectors(param_getchar(Cmd, cmdp)); + if (numSectors == 0) return usage_hf14_dump(); cmdp++; } else { PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); @@ -904,9 +905,9 @@ static int CmdHF14AMfDump(const char *Cmd) { uint16_t bytes = 16 * (FirstBlockOfSector(numSectors - 1) + NumBlocksPerSector(numSectors - 1)); - saveFile(dataFilename, "bin", (uint8_t *)carddata, bytes); - saveFileEML(dataFilename, "eml", (uint8_t *)carddata, bytes, MFBLOCK_SIZE); - saveFileJSON(dataFilename, "json", jsfCardMemory, (uint8_t *)carddata, bytes); + saveFile(dataFilename, ".bin", (uint8_t *)carddata, bytes); + saveFileEML(dataFilename, (uint8_t *)carddata, bytes, MFBLOCK_SIZE); + saveFileJSON(dataFilename, jsfCardMemory, (uint8_t *)carddata, bytes); return 0; } @@ -948,6 +949,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { default: if (cmdp == 0) { numSectors = NumOfSectors(param_getchar(Cmd, cmdp)); + if (numSectors == 0) return usage_hf14_restore(); cmdp++; } else { PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); @@ -1101,6 +1103,7 @@ static int CmdHF14AMfNested(const char *Cmd) { } } else { SectorsCnt = NumOfSectors(cmdp); + if (SectorsCnt == 0) return usage_hf14_nested(); } uint8_t j = 4; @@ -1803,6 +1806,7 @@ static int CmdHF14AMfChk(const char *Cmd) { if (param_getchar(Cmd, 0) == '*') { blockNo = 3; SectorsCnt = NumOfSectors(param_getchar(Cmd + 1, 0)); + if (SectorsCnt == 0) return usage_hf14_chk(); } else { blockNo = param_get8(Cmd, 0); } @@ -2562,12 +2566,13 @@ int CmdHF14AMfELoad(const char *Cmd) { if (numblk2 > 0) numBlocks = numblk2; - param_getstr(Cmd, nameParamNo, filename, sizeof(filename)); + if (0 == param_getstr(Cmd, nameParamNo, filename, sizeof(filename))) + return usage_hf14_eload(); uint8_t *data = calloc(4096, sizeof(uint8_t)); size_t datalen = 0; - //int res = loadFile(filename, "bin", data, maxdatalen, &datalen); - int res = loadFileEML(filename, "eml", data, &datalen); + //int res = loadFile(filename, ".bin", data, maxdatalen, &datalen); + int res = loadFileEML(filename, data, &datalen); if (res) { free(data); return 1; @@ -2641,7 +2646,12 @@ static int CmdHF14AMfESave(const char *Cmd) { char c = tolower(param_getchar(Cmd, 0)); if (c == 'h') return usage_hf14_esave(); - blocks = NumOfBlocks(c); + if (c != 0) { + blocks = NumOfBlocks(c); + if (blocks == 0) return usage_hf14_esave(); + } else { + blocks = MIFARE_1K_MAXBLOCK; + } bytes = blocks * MFBLOCK_SIZE; dump = calloc(bytes, sizeof(uint8_t)); @@ -2667,9 +2677,9 @@ static int CmdHF14AMfESave(const char *Cmd) { FillFileNameByUID(fnameptr, dump, "-dump", 4); } - saveFile(filename, "bin", dump, bytes); - saveFileEML(filename, "eml", dump, bytes, MFBLOCK_SIZE); - saveFileJSON(filename, "json", jsfCardMemory, dump, bytes); + saveFile(filename, ".bin", dump, bytes); + saveFileEML(filename, dump, bytes, MFBLOCK_SIZE); + saveFileJSON(filename, jsfCardMemory, dump, bytes); free(dump); return 0; } @@ -2690,7 +2700,12 @@ static int CmdHF14AMfECFill(const char *Cmd) { keyType = 1; c = tolower(param_getchar(Cmd, 1)); - numSectors = NumOfSectors(c); + if (c != 0) { + numSectors = NumOfSectors(c); + if (numSectors == 0) return usage_hf14_ecfill(); + } else { + numSectors = MIFARE_1K_MAXSECTOR; + } PrintAndLogEx(NORMAL, "--params: numSectors: %d, keyType: %c\n", numSectors, (keyType == 0) ? 'A' : 'B'); clearCommandBuffer(); @@ -2708,7 +2723,12 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) { if (c == 'h') return usage_hf14_ekeyprn(); - numSectors = NumOfSectors(c); + if (c != 0) { + numSectors = NumOfSectors(c); + if (numSectors == 0) return usage_hf14_ekeyprn(); + } else { + numSectors = MIFARE_1K_MAXSECTOR; + } PrintAndLogEx(NORMAL, "|---|----------------|----------------|"); PrintAndLogEx(NORMAL, "|sec|key A |key B |"); @@ -2861,12 +2881,12 @@ static int CmdHF14AMfCLoad(const char *Cmd) { size_t datalen = 0; int res = 0; if (fillFromBin) { - res = loadFile(fileName, "bin", data, maxdatalen, &datalen); + res = loadFile(fileName, ".bin", data, maxdatalen, &datalen); } else { if (fillFromJson) { - res = loadFileJSON(fileName, "json", data, maxdatalen, &datalen); + res = loadFileJSON(fileName, data, maxdatalen, &datalen); } else { - res = loadFileEML(Cmd, "eml", data, &datalen); + res = loadFileEML(Cmd, data, &datalen); } } @@ -3100,9 +3120,9 @@ static int CmdHF14AMfCSave(const char *Cmd) { PrintAndLogEx(SUCCESS, "uploaded %d bytes to emulator memory", bytes); } - saveFile(filename, "bin", dump, bytes); - saveFileEML(filename, "eml", dump, bytes, MFBLOCK_SIZE); - saveFileJSON(filename, "json", jsfCardMemory, dump, bytes); + saveFile(filename, ".bin", dump, bytes); + saveFileEML(filename, dump, bytes, MFBLOCK_SIZE); + saveFileJSON(filename, jsfCardMemory, dump, bytes); free(dump); return 0; } diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 42816243b..7b242ace1 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1969,8 +1969,8 @@ static int CmdHF14AMfUDump(const char *Cmd) { FillFileNameByUID(fptr, card.uid, "-dump", card.uidlen); } uint16_t datalen = pages * 4 + MFU_DUMP_PREFIX_LENGTH; - saveFile(filename, "bin", (uint8_t *)&dump_file_data, datalen); - saveFileJSON(filename, "json", jsfMfuMemory, (uint8_t *)&dump_file_data, datalen); + saveFile(filename, ".bin", (uint8_t *)&dump_file_data, datalen); + saveFileJSON(filename, jsfMfuMemory, (uint8_t *)&dump_file_data, datalen); if (is_partial) PrintAndLogEx(WARNING, "Partial dump created. (%d of %d blocks)", pages, card_mem_size); diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 008c53d1b..3d4138565 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -293,7 +293,7 @@ static int CmdLFHitagSim(const char *Cmd) { break; case 'e': param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); - res = loadFileEML(filename, "eml", data, &datalen); + res = loadFileEML(filename, data, &datalen); if (res > 0 || datalen != maxdatalen) { PrintAndLogDevice(FAILED, "error, bytes read mismatch file size"); errors = true; @@ -304,7 +304,7 @@ static int CmdLFHitagSim(const char *Cmd) { break; case 'j': param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); - res = loadFileJSON(filename, "json", data, maxdatalen, &datalen); + res = loadFileJSON(filename, data, maxdatalen, &datalen); if (res > 0) { errors = true; break; @@ -314,7 +314,7 @@ static int CmdLFHitagSim(const char *Cmd) { break; case 'b': param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); - res = loadFile(filename, "bin", data, maxdatalen, &datalen); + res = loadFile(filename, ".bin", data, maxdatalen, &datalen); if (res > 0) { errors = true; break; @@ -579,9 +579,9 @@ static int CmdLFHitagReader(const char *Cmd) { fnameptr += sprintf(fnameptr, "lf-hitag-"); FillFileNameByUID(fnameptr, data, "-dump", 4); - saveFile(filename, "bin", data, 48); - saveFileEML(filename, "eml", data, 48, 4); - saveFileJSON(filename, "json", jsfHitag, data, 48); + saveFile(filename, ".bin", data, 48); + saveFileEML(filename, data, 48, 4); + saveFileJSON(filename, jsfHitag, data, 48); // block3, 1 byte printHitagConfiguration(data[4 * 3]); @@ -607,7 +607,7 @@ static int CmdLFHitagCheckChallenges(const char *Cmd) { case 'f': //file with all the challenges to try param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)); - res = loadFile(filename, "cc", data, 8 * 60, &datalen); + res = loadFile(filename, ".cc", data, 8 * 60, &datalen); if (res > 0) { errors = true; break; diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 668a461e0..8057c7469 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -1903,7 +1903,7 @@ static int CmdT55xxChkPwds(const char *Cmd) { return 1; } - int res = loadFileDICTIONARY(filename, "dic", keyBlock, &datalen, 4, &keycount); + int res = loadFileDICTIONARY(filename, keyBlock, &datalen, 4, &keycount); if (res || keycount == 0) { PrintAndLogEx(WARNING, "No keys found in file"); free(keyBlock); diff --git a/client/cmdtrace.c b/client/cmdtrace.c index 7402dfc08..f243999a5 100644 --- a/client/cmdtrace.c +++ b/client/cmdtrace.c @@ -563,7 +563,7 @@ static int CmdTraceSave(const char *Cmd) { if (strlen(Cmd) < 1 || cmdp == 'h') return usage_trace_save(); param_getstr(Cmd, 0, filename, sizeof(filename)); - saveFile(filename, "bin", trace, traceLen); + saveFile(filename, ".bin", trace, traceLen); return 0; } diff --git a/client/loclass/fileutils.c b/client/loclass/fileutils.c index f01fe93aa..5e3b423f7 100644 --- a/client/loclass/fileutils.c +++ b/client/loclass/fileutils.c @@ -57,15 +57,49 @@ int fileExists(const char *filename) { return result == 0; } -int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) { - int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10); - char *fileName = calloc(size, sizeof(char)); +static char *filenamemcopy(const char *preferredName, const char *suffix) { + if (preferredName == NULL) return NULL; + if (suffix == NULL) return NULL; + char *fileName = (char *) calloc(strlen(preferredName) + strlen(suffix) + 1, sizeof(uint8_t)); + if (fileName == NULL) + return NULL; + strcpy(fileName, preferredName); + if (str_endswith(fileName, suffix)) + return fileName; + strcat(fileName, suffix); + return fileName; +} + +static char *newfilenamemcopy(const char *preferredName, const char *suffix) { + if (preferredName == NULL) return NULL; + if (suffix == NULL) return NULL; + char *preferredNameTmp = (char *) calloc(strlen(preferredName) + 1, sizeof(uint8_t)); + if (preferredNameTmp == NULL) + return NULL; + strcpy(preferredNameTmp, preferredName); + if (str_endswith(preferredNameTmp, suffix)) + preferredNameTmp[strlen(preferredNameTmp) - strlen(suffix)] = '\0'; + char *fileName = (char *) calloc(strlen(preferredNameTmp) + strlen(suffix) + 1 + 10, sizeof(uint8_t)); // 10: room for filenum to ensure new filename + if (fileName == NULL) { + free(preferredNameTmp); + return NULL; + } int num = 1; - sprintf(fileName, "%s.%s", preferredName, suffix); + sprintf(fileName, "%s%s", preferredNameTmp, suffix); while (fileExists(fileName)) { - sprintf(fileName, "%s-%d.%s", preferredName, num, suffix); + sprintf(fileName, "%s-%d%s", preferredNameTmp, num, suffix); num++; } + free(preferredNameTmp); + return fileName; +} + +int saveFile(const char *preferredName, const char *suffix, const void *data, size_t datalen) { + + if (data == NULL) return 1; + char *fileName = newfilenamemcopy(preferredName, suffix); + if (fileName == NULL) return 1; + /* We should have a valid filename now, e.g. dumpdata-3.bin */ /*Opening file for writing in binary mode*/ @@ -83,23 +117,15 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si return 0; } -int saveFileEML(const char *preferredName, const char *suffix, uint8_t *data, size_t datalen, size_t blocksize) { +int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize) { - if (preferredName == NULL) return 1; - if (suffix == NULL) return 1; if (data == NULL) return 1; + char *fileName = newfilenamemcopy(preferredName, ".eml"); + if (fileName == NULL) return 1; int retval = 0; int blocks = datalen / blocksize; uint16_t currblock = 1; - int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10); - char *fileName = calloc(size, sizeof(char)); - int num = 1; - sprintf(fileName, "%s.%s", preferredName, suffix); - while (fileExists(fileName)) { - sprintf(fileName, "%s-%d.%s", preferredName, num, suffix); - num++; - } /* We should have a valid filename now, e.g. dumpdata-3.bin */ @@ -136,20 +162,13 @@ out: return retval; } -int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType ftype, uint8_t *data, size_t datalen) { - if (preferredName == NULL) return 1; - if (suffix == NULL) return 1; +int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, size_t datalen) { + if (data == NULL) return 1; + char *fileName = newfilenamemcopy(preferredName, ".json"); + if (fileName == NULL) return 1; int retval = 0; - int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10); - char *fileName = calloc(size, sizeof(char)); - int num = 1; - sprintf(fileName, "%s.%s", preferredName, suffix); - while (fileExists(fileName)) { - sprintf(fileName, "%s-%d.%s", preferredName, num, suffix); - num++; - } json_t *root = json_object(); JsonSaveStr(root, "Created", "proxmark3"); @@ -274,14 +293,11 @@ out: int loadFile(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) { - if (preferredName == NULL) return 1; - if (suffix == NULL) return 1; if (data == NULL) return 1; + char *fileName = filenamemcopy(preferredName, suffix); + if (fileName == 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) { @@ -336,17 +352,14 @@ out: return retval; } -int loadFileEML(const char *preferredName, const char *suffix, void *data, size_t *datalen) { +int loadFileEML(const char *preferredName, void *data, size_t *datalen) { - if (preferredName == NULL) return 1; - if (suffix == NULL) return 1; if (data == NULL) return 1; + char *fileName = filenamemcopy(preferredName, ".eml"); + if (fileName == 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) { @@ -365,6 +378,8 @@ int loadFileEML(const char *preferredName, const char *suffix, void *data, size_ memset(line, 0, sizeof(line)); if (fgets(line, sizeof(line), f) == NULL) { + if (feof(f)) + break; fclose(f); PrintAndLogEx(FAILED, "File reading error."); retval = 2; @@ -391,20 +406,17 @@ out: return retval; } -int loadFileJSON(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen) { +int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen) { - if (preferredName == NULL) return 1; - if (suffix == NULL) return 1; if (data == NULL) return 1; + char *fileName = filenamemcopy(preferredName, ".json"); + if (fileName == NULL) return 1; *datalen = 0; json_t *root; json_error_t error; int retval = 0; - int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10); - char *fileName = calloc(size, sizeof(char)); - sprintf(fileName, "%s.%s", preferredName, suffix); root = json_load_file(fileName, 0, &error); if (!root) { @@ -500,11 +512,12 @@ out: return retval; } -int loadFileDICTIONARY(const char *preferredName, const char *suffix, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) { +int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt) { + - if (preferredName == NULL) return 1; - if (suffix == NULL) return 1; if (data == NULL) return 1; + char *fileName = filenamemcopy(preferredName, ".dic"); + if (fileName == NULL) return 1; // t5577 == 4bytes // mifare == 6 bytes @@ -521,9 +534,6 @@ int loadFileDICTIONARY(const char *preferredName, const char *suffix, void *data size_t counter = 0; 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, "r"); if (!f) { diff --git a/client/loclass/fileutils.h b/client/loclass/fileutils.h index 57dfbebc8..dae23a1b1 100644 --- a/client/loclass/fileutils.h +++ b/client/loclass/fileutils.h @@ -70,7 +70,7 @@ int fileExists(const char *filename); * E.g. dumpdata-15.txt * * @param preferredName - * @param suffix the file suffix. Leave out the ".". + * @param suffix the file suffix. Including 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 @@ -83,13 +83,12 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si * 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 * @param datalen the length of the data * @param blocksize the length of one row * @return 0 for ok, 1 for failz */ -int saveFileEML(const char *preferredName, const char *suffix, uint8_t *data, size_t datalen, size_t blocksize); +int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t blocksize); /** STUB * @brief Utility function to save JSON data to a file. This method takes a preferred name, but if that @@ -97,20 +96,19 @@ int saveFileEML(const char *preferredName, const char *suffix, uint8_t *data, si * E.g. dumpdata-15.json * * @param preferredName - * @param suffix the file suffix. Leave out the ".". * @param ftype type of file. * @param data The binary data to write to the file * @param datalen the length of the data * @return 0 for ok, 1 for failz */ -int saveFileJSON(const char *preferredName, const char *suffix, JSONFileType ftype, uint8_t *data, size_t datalen); +int saveFileJSON(const char *preferredName, JSONFileType ftype, 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 suffix the file suffix. Including the ".". * @param data The data array to store the loaded bytes from file * @param maxdatalen the number of bytes that your data array has * @param datalen the number of bytes loaded from file @@ -123,25 +121,23 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m * 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 */ -int loadFileEML(const char *preferredName, const char *suffix, void *data, size_t *datalen); +int loadFileEML(const char *preferredName, void *data, size_t *datalen); /** * @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 maxdatalen maximum size of data array in bytes * @param datalen the number of bytes loaded from file * @return 0 for ok, 1 for failz */ -int loadFileJSON(const char *preferredName, const char *suffix, void *data, size_t maxdatalen, size_t *datalen); +int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_t *datalen); /** @@ -149,14 +145,13 @@ int loadFileJSON(const char *preferredName, const char *suffix, void *data, size * E.g. default_keys.dic * * @param preferredName - * @param suffix the file suffix. Leave out the ".". * @param data The data array to store the loaded bytes from file * @param maxdatalen maximum size of data array in bytes * @param datalen the number of bytes loaded from file * @param keylen the number of bytes a key per row is * @return 0 for ok, 1 for failz */ -int loadFileDICTIONARY(const char *preferredName, const char *suffix, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); +int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, uint8_t keylen, uint16_t *keycnt); /** * @brief Utility function to check and convert old mfu dump format to new diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index 4a7780ff9..244f3e6a1 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -92,13 +92,13 @@ Command = { end o.data = data return o - end, + end, parse = function (packet) local count, cmd, arg1, arg2, arg3, data = bin.unpack('LLLLH511', packet) return Command:new{cmd = cmd, arg1 = arg1, arg2 = arg2, arg3 = arg3, data = data} - end + end } --- commented out, not used. +-- commented out, not used. function Command:__tostring() local output = ("%s\r\nargs : (%s, %s, %s)\r\ndata:\r\n%s\r\n"):format( _commands.tostring(self.cmd), @@ -128,7 +128,7 @@ function Command:__responsetostring() tostring(self.resp_arg1), tostring(self.resp_arg2), tostring(self.resp_arg3))) - print('NG ::', self.resp_ng) + print('NG ::', self.resp_ng) print('package ::', self.resp_response) end @@ -144,10 +144,10 @@ function Command:sendMIX( ignore_response, timeout ) local data = self.data local cmd = self.cmd local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3 - + local err, msg = core.SendCommandMIX(cmd, arg1, arg2, arg3, data) if err == nil then return err, msg end - + if ignore_response then return true, nil end if timeout == nil then timeout = TIMEOUT end @@ -156,13 +156,13 @@ function Command:sendMIX( ignore_response, timeout ) if response == nil then return nil, 'Error, waiting for response timed out :: '..msg end - - -- lets digest + + -- lets digest local data local count, cmd, length, magic, status, crc, arg1, arg2, arg3 = bin.unpack('SSIsSLLL', response) count, data, ng = bin.unpack('H'..length..'C', response, count) - ---[[ uncomment if you want to debug + +--[[ uncomment if you want to debug self.resp_cmd = cmd self.resp_length = length self.resp_magic = magic @@ -181,20 +181,20 @@ function Command:sendMIX( ignore_response, timeout ) end function Command:sendNG( ignore_response, timeout ) local data = self.data - local cmd = self.cmd + local cmd = self.cmd local err, msg = core.SendCommandNG(cmd, data) if err == nil then return err, msg end - + if ignore_response then return true, nil end - + if timeout == nil then timeout = TIMEOUT end - + local response, msg = core.WaitForResponseTimeout(cmd, timeout) if response == nil then return nil, 'Error, waiting for response timed out :: '..msg end - - -- lets digest + + -- lets digest local data local count, cmd, length, magic, status, crc, arg1, arg2, arg3 = bin.unpack('SSIsSLLL', response) count, data, ng = bin.unpack('H'..length..'C', response, count) diff --git a/client/lualibs/read14a.lua b/client/lualibs/read14a.lua index dfa2ea73c..012102931 100644 --- a/client/lualibs/read14a.lua +++ b/client/lualibs/read14a.lua @@ -92,7 +92,7 @@ local function read14443a(dont_disconnect, no_rats) if no_rats then command.arg1 = command.arg1 + ISO14A_COMMAND.ISO14A_NO_RATS end - + local result,err = command:sendMIX() if result then local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result) diff --git a/client/proxmark3.c b/client/proxmark3.c index 5cf045170..bb6553a09 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -97,7 +97,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool pm3_present) { // loops every time enter is pressed... while (1) { - + bool printprompt = false; // this should hook up the PM3 again. /* if ( IsOffline() ) { @@ -134,13 +134,13 @@ main_loop(char *script_cmds_file, char *script_cmd, bool pm3_present) { strcleanrn(script_cmd_buf, sizeof(script_cmd_buf)); if ((cmd = strmcopy(script_cmd_buf)) != NULL) - PrintAndLogEx(NORMAL, PROXPROMPT"%s\n", cmd); + printprompt = true; } } else { // If there is a script command if (execCommand) { if ((cmd = strmcopy(script_cmd)) != NULL) - PrintAndLogEx(NORMAL, PROXPROMPT"%s", cmd); + printprompt = true; uint16_t len = strlen(script_cmd) + 1; script_cmd += len; if (script_cmd_len == len - 1) @@ -165,7 +165,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool pm3_present) { strcleanrn(script_cmd_buf, sizeof(script_cmd_buf)); if ((cmd = strmcopy(script_cmd_buf)) != NULL) - PrintAndLogEx(NORMAL, PROXPROMPT"%s", cmd); + printprompt = true; } else { cmd = readline(PROXPROMPT); @@ -179,10 +179,20 @@ main_loop(char *script_cmds_file, char *script_cmd, bool pm3_present) { // rtrim size_t l = strlen(cmd); - if (l > 0 && isspace(cmd[l - 1])) - cmd[l - 1] = 0x00; + while (l > 0 && isspace(cmd[l - 1])) { + cmd[--l] = '\0'; + } + // ltrim + size_t off = 0; + while ((cmd[off] != '\0') && isspace(cmd[off])) + off++; + for (size_t i = 0; i < strlen(cmd) - off; i++) + cmd[i] = cmd[i + off]; + cmd[strlen(cmd) - off] = '\0'; - if (cmd[0] != 0x00) { + if (cmd[0] != '\0') { + if (printprompt) + PrintAndLogEx(NORMAL, PROXPROMPT"%s", cmd); int ret = CommandReceived(cmd); HIST_ENTRY *entry = history_get(history_length); if ((!entry) || (strcmp(entry->line, cmd) != 0)) @@ -259,7 +269,7 @@ static void show_help(bool showFullHelp, char *exec_name) { PrintAndLogEx(NORMAL, " -t/--text dump all interactive command's help at once"); PrintAndLogEx(NORMAL, " -m/--markdown dump all interactive help at once in markdown syntax"); PrintAndLogEx(NORMAL, " -p/--port serial port to connect to"); - PrintAndLogEx(NORMAL, " -b/--baud serial port speed"); + PrintAndLogEx(NORMAL, " -b/--baud serial port speed (only needed for physical UART, not for USB-CDC or BT)"); PrintAndLogEx(NORMAL, " -w/--wait 20sec waiting the serial port to appear in the OS"); PrintAndLogEx(NORMAL, " -f/--flush output will be flushed after every print"); PrintAndLogEx(NORMAL, " -c/--command execute one proxmark3 command (or several separated by ';')."); @@ -433,15 +443,9 @@ int main(int argc, char *argv[]) { if (!script_cmds_file && !stdinOnPipe) showBanner(); - - // default speed for USB 460800, USART(FPC serial) 115200 baud + // Let's take a baudrate ok for real UART, USB-CDC & BT don't use that info anyway if (speed == 0) -#ifdef WITH_FPC_HOST - // Let's assume we're talking by default to pm3 over usart in this mode speed = USART_BAUD_RATE; -#else - speed = 460800; -#endif if (script_cmd) { while (script_cmd[strlen(script_cmd) - 1] == ' ') diff --git a/client/scripting.c b/client/scripting.c index 309e5dc40..5aa76d33c 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -73,10 +73,10 @@ static int l_SendCommandOLD(lua_State *L) { } // parse input - cmd = luaL_checknumber(L, 1); + cmd = luaL_checknumber(L, 1); arg0 = luaL_checknumber(L, 2); arg1 = luaL_checknumber(L, 3); - arg2 = luaL_checknumber(L, 4); + arg2 = luaL_checknumber(L, 4); // data const char *p_data = luaL_checklstring(L, 5, &size); @@ -93,7 +93,7 @@ static int l_SendCommandOLD(lua_State *L) { } SendCommandOLD(cmd, arg0, arg1, arg2, data, len); - lua_pushboolean(L, true); + lua_pushboolean(L, true); return 1; } @@ -120,10 +120,10 @@ static int l_SendCommandMIX(lua_State *L) { return returnToLuaWithError(L, "You need to supply five parameters"); // parse input - cmd = luaL_checknumber(L, 1); + cmd = luaL_checknumber(L, 1); arg0 = luaL_checknumber(L, 2); arg1 = luaL_checknumber(L, 3); - arg2 = luaL_checknumber(L, 4); + arg2 = luaL_checknumber(L, 4); // data const char *p_data = luaL_checklstring(L, 5, &size); @@ -162,7 +162,7 @@ static int l_SendCommandNG(lua_State *L) { return returnToLuaWithError(L, "You need to supply two parameters"); // parse input - uint64_t cmd = luaL_checknumber(L, 1); + uint64_t cmd = luaL_checknumber(L, 1); // data const char *p_data = luaL_checklstring(L, 2, &size); diff --git a/client/scripts/ndef_dump.lua b/client/scripts/ndef_dump.lua index d184ee2d1..a89c4f32a 100644 --- a/client/scripts/ndef_dump.lua +++ b/client/scripts/ndef_dump.lua @@ -1,6 +1,6 @@ local getopt = require('getopt') local cmds = require('commands') -local lib14a = require('read14a') +local taglib = require('taglib') local utils = require('utils') copyright = '' @@ -64,58 +64,93 @@ local function help() print(example) print(usage) end --- --- Sends an instruction to do nothing, only disconnect -function disconnect() - local command = Command:newMIX{cmd = cmds.CMD_READER_ISO_14443a, arg1 = 0,} - -- We can ignore the response here, no ACK is returned for this command - -- Check /armsrc/iso14443a.c, ReaderIso14443a() for details - return command:sendMIX(true) + +--- This function is a lua-implementation of +-- cmdhf14a.c:waitCmd(uint8_t iSelect) +local function waitCmd(iSelect) + local response = core.WaitForResponseTimeout(cmds.CMD_ACK, 1000) + if response then + local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',response) + + local iLen = arg0 + if iSelect then iLen = arg1 end + dbg(("Received %i octets (arg0:%d, arg1:%d)"):format(iLen, arg0, arg1)) + if iLen == 0 then return nil, "No response from tag" end + local recv = string.sub(response,count, iLen+count-1) + return recv + end + return nil, "No response from device" end --- -- -local function getblockdata(response) - if not response then - return nil, 'No response from device' - end - - local count, cmd, arg0 = bin.unpack('LL', response) - if arg0 == 1 then - local count, arg1, arg2, data = bin.unpack('LLH511', response, count) - return data:sub(1, 32) - else - return nil, "Couldn't read block" - end +local function show(data) + local formatString = ('H%d'):format(string.len(data)) + local _,hexdata = bin.unpack(formatString, data) + dbg('Hexdata', hexdata) +end +--- Fire up a connection with a tag, return uid +-- @return UID if successfull +-- @return nil, errormessage if unsuccessfull +local function open() + dbg('Opening connection') + core.clearCommandBuffer() + local x = string.format('hf 14a raw -r -p -s') + dbg(x) + core.console(x) + dbg('done') + data, err = waitCmd(true) + if err then return oops(err) end + show(data) + local formatString = ('H%d'):format(string.len(data)) + local _,uid = bin.unpack(formatString, data) + return uid +end +--- Shut down tag communication +-- return no return values +local function close() + dbg('Closing connection') + core.clearCommandBuffer() + local x = string.format('hf 14a raw -r') + dbg(x) + core.console(x) + dbg('done') end ---_ Gets data from a block -- @return {block, block+1, block+2, block+3} if successfull -- @return nil, errormessage if unsuccessfull -local function getBlock(blockno) - local block, err - local cmd = Command:newMIX{cmd = cmds.CMD_MIFAREU_READBL, arg1 = blockno, data = 0} - block, err = getblockdata(cmd:sendMIX(false)) - if not block then return oops(err) end - - if #block < 32 then - return nil, ('Expected at least 16 bytes, got %d - this tag is not NDEF-compliant'):format(string.len(data)) +local function getBlock(block) + local data, err + + core.clearCommandBuffer() + + local x = string.format('hf 14a raw -r -c -p 30 %02x', block) + dbg(x) + core.console(x) + dbg('done') + -- By now, there should be an ACK waiting from the device, since + -- we used the -r flag (don't read response). + + data, err = waitCmd(false) + if err then return oops(err) end + show(data) + + if string.len(data) < 18 then + return nil, ('Expected at least 18 bytes, got %d - this tag is not NDEF-compliant'):format(string.len(data)) end - print('block', block) -- Now, parse out the block data -- 0534 00B9 049C AD7F 4A00 0000 E110 1000 2155 -- b0b0 b0b0 b1b1 b1b1 b2b2 b2b2 b3b3 b3b3 CRCC - b0 = string.sub(block, 1, 8) - b1 = string.sub(block, 9, 16) - b2 = string.sub(block, 17, 24) - b3 = string.sub(block, 25, 32) + b0 = string.sub(data, 1, 4) + b1 = string.sub(data, 5, 8) + b2 = string.sub(data, 9, 12) + b3 = string.sub(data, 13, 16) return {b0, b1, b2, b3} -end ---- --- +end + local function main( args) print( string.rep('--',20) ) print( string.rep('--',20) ) - dbg('script started') local err, data, data2, k, v, i -- Read the parameters @@ -124,21 +159,6 @@ local function main( args) if o == 'd' then DEBUG = true end end - -- First of all, connect - info, err = lib14a.read(true, true) - if err then - disconnect(); - return oops(err) - end - core.clearCommandBuffer() - - if info.name:match("Ultralight") then - dbg('Found a tag') - else - disconnect() - return oops('Not a Ultralightbased card. This script reads NDEF formatted UL/NTAGS') - end - -- Info contained within the tag (block 0 example) -- 0534 00B9 049C AD7F 4A00 0000 E110 1000 2155 -- b0b0 b0b0 b1b1 b1b1 b2b2 b2b2 b3b3 b3b3 CRCC @@ -147,24 +167,31 @@ local function main( args) -- N = NDEF-Structure-Compliant (if value is E1) -- V = NFC Forum Specification version (if 10 = v1.0) + -- First, 'connect' (fire up the field) and get the uid + local uidHexstr = open() + -- First, get blockt 3 byte 2 local blocks, err = getBlock(0) if err then - disconnect() - return oops(err) + close() + return oops(err) end -- Block 3 contains number of blocks - local b3chars = utils.ConvertHexToBytes(blocks[4]); + local b3chars = {string.byte(blocks[4], 1,4)} local numBlocks = b3chars[3] * 2 + 6 print("Number of blocks:", numBlocks) -- NDEF compliant? if b3chars[1] ~= 0xE1 then - disconnect() + close() return oops('This tag is not NDEF-Compliant') end - local ndefversion = b3chars[2] + local ndefVersion = b3chars[2] + + -- Block 1, byte 1 contains manufacturer info + local bl1_b1 = string.byte(blocks[1], 1) + local manufacturer = taglib.lookupManufacturer(bl1_b1) -- Reuse existing info local blockData = {blocks[1], blocks[2], blocks[3], blocks[4]} @@ -175,28 +202,22 @@ local function main( args) removing bytes from 5 to 18 from each answer. --]] print('Dumping data...please wait') - for i = 4, numBlocks - 1, 1 do + for i=4,numBlocks-1,1 do blocks, err = getBlock(i) - if err then - disconnect(); - return oops(err) - end + if err then close(); return oops(err) end table.insert(blockData, blocks[1]) end -- Deactivate field - disconnect() + close() -- Print results - print('Tag info') - print('UID ', info.uid) - print('NDEF version', ('%02x'):format(ndefversion)) - print('Manufacturer', info.manufacturer) - print('Type ', info.name) + print(string.format('Tag manufacturer: %s', manufacturer)) + print(string.format('Tag UID: %s', uidHexstr)) + print(string.format('Tag NDEF version: 0x%02x', ndefVersion)) for k,v in ipairs(blockData) do print(string.format('Block %02x: %02x %02x %02x %02x', k-1, string.byte(v, 1,4))) end - - local filename, err = utils.WriteDumpFile(info.uid, blockData) + local filename, err = utils.writeDumpFile(uidHexstr, blockData) if err then return oops(err) end print(string.format('Dumped data into %s', filename)) diff --git a/client/scripts/test_t55x7.lua b/client/scripts/test_t55x7.lua index 478336313..412f4acb8 100644 --- a/client/scripts/test_t55x7.lua +++ b/client/scripts/test_t55x7.lua @@ -80,7 +80,7 @@ local function help() print(desc) print("Example usage") print(example) - print(usage) + print(usage) end --- -- Exit message @@ -261,7 +261,7 @@ local function test(modulation) , arg2 = block } local response, err = wc:sendMIX(false) - if not response then return oops(err) end + if not response then return oops(err) end -- Detect local res, msg = core.t55xx_detect() @@ -323,7 +323,7 @@ local function main(args) end exitMsg('Tests finished') - core.console( + core.console( format('rem [SUMMARY] Success rate: %d/%d tests passed%s' , total_pass , total_tests diff --git a/client/scripts/tnp3clone.lua b/client/scripts/tnp3clone.lua index 0bb18375b..1e3545a1b 100644 --- a/client/scripts/tnp3clone.lua +++ b/client/scripts/tnp3clone.lua @@ -63,7 +63,7 @@ local function getblockdata(response) if not response then return nil, 'No response from device' end - + local count, cmd, arg0 = bin.unpack('LL', response) if arg0 == 1 then local count, arg1, arg2, data = bin.unpack('LLH511', response, count) @@ -81,7 +81,7 @@ local function readblock( blocknum, keyA ) return b end --- --- decode response and get the blockdata from backdoor magic command +-- decode response and get the blockdata from backdoor magic command local function readmagicblock( blocknum ) -- Read block N local CSETBLOCK_SINGLE_OPERATION = 0x1F diff --git a/client/scripts/tnp3dump.lua b/client/scripts/tnp3dump.lua index b0db89718..7da530f7d 100644 --- a/client/scripts/tnp3dump.lua +++ b/client/scripts/tnp3dump.lua @@ -91,7 +91,7 @@ local function getblockdata(response) if not response then return nil, 'No response from device' end - + local count, cmd, arg0 = bin.unpack('LL', response) if arg0 == 1 then local count, arg1, arg2, data = bin.unpack('LLH511', response, count) @@ -132,7 +132,7 @@ local function main(args) local cmdSetDbgOff = "hf mf dbg 0" core.console( cmdSetDbgOff) utils.Sleep(0.5) - + result, err = lib14a.read(false, true) if not result then return oops(err) end @@ -170,7 +170,7 @@ local function main(args) cmd = Command:newMIX{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0, data = keyA} block0, err = getblockdata(cmd:sendMIX(false)) if not block0 then return oops(err) end - + core.clearCommandBuffer() -- Read block 1 diff --git a/client/scripts/tnp3sim.lua b/client/scripts/tnp3sim.lua index 8ba56238d..8e595363e 100644 --- a/client/scripts/tnp3sim.lua +++ b/client/scripts/tnp3sim.lua @@ -242,7 +242,7 @@ local function LoadEmulator(uid, blocks) blockdata = AddKey(keys, _, blockdata) end end - + io.write( _..',') io.flush() core.clearCommandBuffer() diff --git a/client/scripts/ufodump.lua b/client/scripts/ufodump.lua index d21e00497..655d6e7ed 100644 --- a/client/scripts/ufodump.lua +++ b/client/scripts/ufodump.lua @@ -15,7 +15,7 @@ xor: the first three block (0,1,2) is not XORED. The rest seems to be xored. example = [[ -- default script run ufodump - + -- stop at block 10 script run ufodump -b 10 ]] @@ -48,7 +48,7 @@ end local function oops(err) print('ERROR:', err) core.clearCommandBuffer() - return nil, err + return nil, err end --- -- Usage help @@ -59,7 +59,7 @@ local function help() print(desc) print('Example usage') print(example) - print(usage) + print(usage) end -- --- Picks out and displays the data read from a tag @@ -103,7 +103,7 @@ function sendRaw(rawdata, options) -- of the ASCII-string rawdata arg2 = string.len(rawdata)/2, data = rawdata} - + return command:sendMIX(options.ignore_response) end -- diff --git a/client/scripts/ul_uid.lua b/client/scripts/ul_uid.lua index 7b806b1fe..9ac89c211 100644 --- a/client/scripts/ul_uid.lua +++ b/client/scripts/ul_uid.lua @@ -57,7 +57,7 @@ local function help() print(desc) print('Example usage') print(example) - print(usage) + print(usage) end -- --- Set UID on magic command enabled diff --git a/client/util.c b/client/util.c index ce21ffbee..50bbe0516 100644 --- a/client/util.c +++ b/client/util.c @@ -822,10 +822,22 @@ void str_lower(char *s) { for (size_t i = 0; i < strlen(s); i++) s[i] = tolower(s[i]); } + +// check for prefix in string bool str_startswith(const char *s, const char *pre) { return strncmp(pre, s, strlen(pre)) == 0; } +// check for suffix in string +bool str_endswith(const char *s, const char *suffix) { + size_t ls = strlen(s); + size_t lsuffix = strlen(suffix); + if (ls >= lsuffix) { + return strncmp(suffix, s + (ls - lsuffix), lsuffix) == 0; + } + return false; +} + // Replace unprintable characters with a dot in char buffer void clean_ascii(unsigned char *buf, size_t len) { for (size_t i = 0; i < len; i++) { @@ -848,7 +860,7 @@ void strcreplace(char *buf, size_t len, char from, char to) { } } -char *strmcopy(char *buf) { +char *strmcopy(const char *buf) { char *str = (char *) calloc(strlen(buf) + 1, sizeof(uint8_t)); if (str != NULL) { memset(str, 0, strlen(buf) + 1); diff --git a/client/util.h b/client/util.h index b55cfc435..78ecf6b91 100644 --- a/client/util.h +++ b/client/util.h @@ -231,8 +231,9 @@ int num_CPUs(void); // number of logical CPUs void str_lower(char *s); // converts string to lower case bool str_startswith(const char *s, const char *pre); // check for prefix in string +bool str_endswith(const char *s, const char *suffix); // check for suffix in string void clean_ascii(unsigned char *buf, size_t len); void strcleanrn(char *buf, size_t len); void strcreplace(char *buf, size_t len, char from, char to); -char *strmcopy(char *buf); +char *strmcopy(const char *buf); #endif diff --git a/common/usb_cdc.c b/common/usb_cdc.c index 04f86ad71..63d5c66d0 100644 --- a/common/usb_cdc.c +++ b/common/usb_cdc.c @@ -420,7 +420,7 @@ const char *getStringDescriptor(uint8_t idx) { reg |= REG_NO_EFFECT_1_ALL; \ reg &= ~(flags); \ pUdp->UDP_CSR[(endpoint)] = reg; \ - } \ + } // reset flags in the UDP_CSR register and waits for synchronization #define UDP_SET_EP_FLAGS(endpoint, flags) { \ @@ -429,7 +429,7 @@ const char *getStringDescriptor(uint8_t idx) { reg |= REG_NO_EFFECT_1_ALL; \ reg |= (flags); \ pUdp->UDP_CSR[(endpoint)] = reg; \ - } \ + } typedef struct { @@ -439,12 +439,12 @@ typedef struct { uint8_t DataBits; } AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING; -AT91S_CDC_LINE_CODING line = { - 115200, // baudrate - 0, // 1 Stop Bit - 0, // None Parity - 8 -}; // 8 Data bits +AT91S_CDC_LINE_CODING line = { // purely informative, actual values don't matter + USART_BAUD_RATE, // baudrate + 0, // 1 Stop Bit + 0, // None Parity + 8 // 8 Data bits +}; static void SpinDelay(int ms) { int us = ms * 1000; diff --git a/common/usb_cdc.h b/common/usb_cdc.h index 3dbe9df5f..64dfbcd4d 100644 --- a/common/usb_cdc.h +++ b/common/usb_cdc.h @@ -37,6 +37,7 @@ #include #include "at91sam7s512.h" +#include "usart.h" #include "config_gpio.h" #include "proxmark3.h" // USB_CONNECT() #include "common.h" diff --git a/tools/mkversion.pl b/tools/mkversion.pl index 715b8081c..aaac146f8 100644 --- a/tools/mkversion.pl +++ b/tools/mkversion.pl @@ -14,7 +14,7 @@ $ENV{'LC_ALL'} = "C"; $ENV{'LANG'} = "C"; # if you are making your own fork, change this line to reflect your fork-name -my $fullgitinfo = 'RRG'; +my $fullgitinfo = 'RRG/Iceman'; my $ctime; # GIT status 0 = dirty, 1 = clean , 2 = undecided my $clean = 2;