From f6a6ec844769337cdb04be65a05e8d705c0b33ae Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 12 Apr 2019 01:55:25 +0200 Subject: [PATCH] Rework Cmd exposed API, use more static and fix [-Wmissing-prototypes], ongoing... --- client/cmddata.c | 7 +- client/cmddata.h | 3 +- client/cmdlf.c | 20 +- client/cmdlfawid.c | 149 +++++++------- client/cmdlfawid.h | 7 +- client/cmdlfcotag.c | 20 +- client/cmdlfcotag.h | 5 +- client/cmdlfem4x.c | 58 +++--- client/cmdlfem4x.h | 16 +- client/cmdlffdx.c | 154 +++++++------- client/cmdlffdx.h | 7 +- client/cmdlfguard.c | 463 ++++++++++++++++++++++--------------------- client/cmdlfguard.h | 8 +- client/cmdlfhid.c | 33 +-- client/cmdlfhid.h | 7 +- client/cmdlfhitag.c | 32 +-- client/cmdlfhitag.h | 9 +- client/cmdlfindala.c | 252 +++++++++++------------ client/cmdlfindala.h | 8 +- client/cmdlfio.c | 243 ++++++++++++----------- client/cmdlfio.h | 5 +- 21 files changed, 760 insertions(+), 746 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 795cc060d..67e711293 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1141,7 +1141,7 @@ int PSKDemod(const char *Cmd, bool verbose) { return 1; } -int CmdIdteckDemod(const char *Cmd) { +static int CmdIdteckDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far if (!PSKDemod("", false)) { @@ -1202,6 +1202,11 @@ int CmdIdteckDemod(const char *Cmd) { return 1; } +int demodIdteck(void) { + return CmdIdteckDemod(""); +} + + // by marshmellow // takes 3 arguments - clock, invert, maxErr as integers // attempts to demodulate nrz only diff --git a/client/cmddata.h b/client/cmddata.h index ce1bfd16a..94b537d65 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -54,7 +54,6 @@ int CmdDetectClockRate(const char *Cmd); int CmdFSKrawdemod(const char *Cmd); int CmdPSK1rawDemod(const char *Cmd); int CmdPSK2rawDemod(const char *Cmd); -int CmdIdteckDemod(const char *Cmd); int CmdGrid(const char *Cmd); int CmdGetBitStream(const char *Cmd); int CmdHexsamples(const char *Cmd); @@ -88,6 +87,8 @@ int AskEdgeDetect(const int *in, int *out, int len, int threshold); int CmdDataIIR(const char *Cmd); +int demodIdteck(void); + #define MAX_DEMOD_BUF_LEN (1024*128) #define BIGBUF_SIZE 40000 extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; diff --git a/client/cmdlf.c b/client/cmdlf.c index f00525bee..f0a75cd58 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -886,8 +886,8 @@ int CmdLFfind(const char *Cmd) { // The improved noise detection will find Cotag. if (getSignalProperties()->isnoise) { - if (CmdLFHitagReader("26") == 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") " found!"); return 1;} - if (CmdCOTAGRead("") > 0) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") " found!"); return 1;} + if (readHitagUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Hitag") " found!"); return 1;} + if (readCOTAGUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") " found!"); return 1;} PrintAndLogEx(FAILED, "\n" _YELLOW_("No data found!") " - Signal looks like noise. Maybe not an LF tag?"); return 0; @@ -896,16 +896,16 @@ int CmdLFfind(const char *Cmd) { if (EM4x50Read("", false)) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM4x50 ID") " found!"); return 1;} - if (CmdHIDDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;} - if (CmdAWIDDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("AWID ID") " found!"); goto out;} + if (demodHID()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;} + if (demodAWID()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("AWID ID") " found!"); goto out;} if (demodParadox()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Paradox ID") " found!"); goto out;} - if (CmdEM410xDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") " found!"); goto out;} - if (CmdFdxDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-B ID") " found!"); goto out;} - if (CmdGuardDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Guardall G-Prox II ID") " found!"); goto out; } - if (CmdIdteckDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") " found!"); goto out;} - if (CmdIndalaDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") " found!"); goto out;} - if (CmdIOProxDemod("")) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("IO Prox ID") " found!"); goto out;} + if (demodEM410x()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") " found!"); goto out;} + if (demodFDX()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-B ID") " found!"); goto out;} + if (demodGuard()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Guardall G-Prox II ID") " found!"); goto out; } + if (demodIdteck()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") " found!"); goto out;} + if (demodIndala()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") " found!"); goto out;} + if (demodIOProx()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("IO Prox ID") " found!"); goto out;} if (demodJablotron()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Jablotron ID") " found!"); goto out;} if (demodNedap()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NEDAP ID") " found!"); goto out;} if (demodNexWatch()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NexWatch ID") " found!"); goto out;} diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 74dc2e302..b8f42448b 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -13,7 +13,7 @@ #include "cmdlfawid.h" // AWID function declarations static int CmdHelp(const char *Cmd); - +/* static int usage_lf_awid_read(void) { PrintAndLogEx(NORMAL, "Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); @@ -29,7 +29,7 @@ static int usage_lf_awid_read(void) { PrintAndLogEx(NORMAL, " lf awid read 1"); return 0; } - +*/ static int usage_lf_awid_sim(void) { PrintAndLogEx(NORMAL, "Enables simulation of AWID card with specified facility-code and card number."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); @@ -122,60 +122,6 @@ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, ui return true; } -//refactored by marshmellow -int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) { - - // the return bits, preamble 0000 0001 - bits[7] = 1; - - uint8_t pre[66]; - memset(pre, 0, sizeof(pre)); - - // add formatlength - num_to_bytebits(fmtlen, 8, pre); - - // add facilitycode, cardnumber and wiegand parity bits - switch (fmtlen) { - case 26: { - uint8_t wiegand[24]; - num_to_bytebits(fc, 8, wiegand); - num_to_bytebits(cn, 16, wiegand + 8); - wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand)); - break; - } - case 34: { - uint8_t wiegand[32]; - num_to_bytebits(fc, 8, wiegand); - num_to_bytebits(cn, 24, wiegand + 8); - wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand)); - break; - } - case 37: { - uint8_t wiegand[31]; - num_to_bytebits(fc, 13, wiegand); - num_to_bytebits(cn, 18, wiegand + 13); - wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand)); - break; - } - case 50: { - uint8_t wiegand[48]; - num_to_bytebits(fc, 16, wiegand); - num_to_bytebits(cn, 32, wiegand + 16); - wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand)); - break; - } - } - - // add AWID 4bit parity - size_t bitLen = addParity(pre, bits + 8, 66, 4, 1); - - if (bitLen != 88) return 0; - - PrintAndLogEx(SUCCESS, "awid raw bits:\n %s \n", sprint_bin(bits, bitLen)); - - return 1; -} - static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) { switch (*fmtlen) { case 50: @@ -218,15 +164,10 @@ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) { break; } } - -// this read is the "normal" read, which download lf signal and tries to demod here. -int CmdAWIDRead(const char *Cmd) { - lf_read(true, 12000); - return CmdAWIDDemod(Cmd); -} +/* // this read loops on device side. // uses the demod in lfops.c -int CmdAWIDRead_device(const char *Cmd) { +static int CmdAWIDRead_device(const char *Cmd) { if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_awid_read(); uint8_t findone = (Cmd[0] == '1') ? 1 : 0; @@ -235,11 +176,11 @@ int CmdAWIDRead_device(const char *Cmd) { SendCommand(&c); return 0; } - +*/ //by marshmellow //AWID Prox demod - FSK2a RF/50 with preamble of 00000001 (always a 96 bit data stream) //print full AWID Prox ID and some bit format details if found -int CmdAWIDDemod(const char *Cmd) { +static int CmdAWIDDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; size_t size = getFromGraphBuf(bits); @@ -370,7 +311,13 @@ int CmdAWIDDemod(const char *Cmd) { return 1; } -int CmdAWIDSim(const char *Cmd) { +// this read is the "normal" read, which download lf signal and tries to demod here. +static int CmdAWIDRead(const char *Cmd) { + lf_read(true, 12000); + return CmdAWIDDemod(Cmd); +} + +static int CmdAWIDSim(const char *Cmd) { uint32_t fc = 0, cn = 0; uint8_t fmtlen = 0; uint8_t bits[96]; @@ -410,7 +357,7 @@ int CmdAWIDSim(const char *Cmd) { return 0; } -int CmdAWIDClone(const char *Cmd) { +static int CmdAWIDClone(const char *Cmd) { uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0}; uint32_t fc = 0, cn = 0; uint8_t fmtlen = 0; @@ -461,7 +408,7 @@ int CmdAWIDClone(const char *Cmd) { return 0; } -int CmdAWIDBrute(const char *Cmd) { +static int CmdAWIDBrute(const char *Cmd) { bool errors = false, verbose = false; uint32_t fc = 0, cn = 0, delay = 1000; @@ -567,14 +514,72 @@ static command_t CommandTable[] = { {NULL, NULL, 0, NULL} }; +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return 0; +} + int CmdLFAWID(const char *Cmd) { clearCommandBuffer(); CmdsParse(CommandTable, Cmd); return 0; } -int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return 0; +//refactored by marshmellow +int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) { + + // the return bits, preamble 0000 0001 + bits[7] = 1; + + uint8_t pre[66]; + memset(pre, 0, sizeof(pre)); + + // add formatlength + num_to_bytebits(fmtlen, 8, pre); + + // add facilitycode, cardnumber and wiegand parity bits + switch (fmtlen) { + case 26: { + uint8_t wiegand[24]; + num_to_bytebits(fc, 8, wiegand); + num_to_bytebits(cn, 16, wiegand + 8); + wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand)); + break; + } + case 34: { + uint8_t wiegand[32]; + num_to_bytebits(fc, 8, wiegand); + num_to_bytebits(cn, 24, wiegand + 8); + wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand)); + break; + } + case 37: { + uint8_t wiegand[31]; + num_to_bytebits(fc, 13, wiegand); + num_to_bytebits(cn, 18, wiegand + 13); + wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand)); + break; + } + case 50: { + uint8_t wiegand[48]; + num_to_bytebits(fc, 16, wiegand); + num_to_bytebits(cn, 32, wiegand + 16); + wiegand_add_parity(pre + 8, wiegand, sizeof(wiegand)); + break; + } + } + + // add AWID 4bit parity + size_t bitLen = addParity(pre, bits + 8, 66, 4, 1); + + if (bitLen != 88) return 0; + + PrintAndLogEx(SUCCESS, "awid raw bits:\n %s \n", sprint_bin(bits, bitLen)); + + return 1; +} + +int demodAWID(void) { + return CmdAWIDDemod(""); } diff --git a/client/cmdlfawid.h b/client/cmdlfawid.h index 85d23ec3b..e51e986a6 100644 --- a/client/cmdlfawid.h +++ b/client/cmdlfawid.h @@ -25,11 +25,8 @@ int CmdLFAWID(const char *Cmd); -int CmdAWIDDemod(const char *Cmd); -int CmdAWIDRead(const char *Cmd); -int CmdAWIDSim(const char *Cmd); -int CmdAWIDClone(const char *Cmd); -int CmdAWIDBrute(const char *Cmd); + +int demodAWID(void); int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits); #endif diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index 838384e73..5ccdbfb68 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -27,7 +27,7 @@ static int usage_lf_cotag_read(void) { // COTAG demod should be able to use GraphBuffer, // when data load samples -int CmdCOTAGDemod(const char *Cmd) { +static int CmdCOTAGDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far uint8_t bits[COTAG_BITS] = {0}; @@ -67,7 +67,7 @@ int CmdCOTAGDemod(const char *Cmd) { // 0 = HIGH/LOW signal - maxlength bigbuff // 1 = translation for HI/LO into bytes with manchester 0,1 - length 300 // 2 = raw signal - maxlength bigbuff -int CmdCOTAGRead(const char *Cmd) { +static int CmdCOTAGRead(const char *Cmd) { if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read(); @@ -110,14 +110,22 @@ static command_t CommandTable[] = { {NULL, NULL, 0, NULL} }; +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return 0; +} + int CmdLFCOTAG(const char *Cmd) { clearCommandBuffer(); CmdsParse(CommandTable, Cmd); return 0; } -int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return 0; +int demodCOTAG(void) { + return CmdCOTAGDemod(""); +} + +int readCOTAGUid(void) { + return CmdCOTAGRead > 0; } diff --git a/client/cmdlfcotag.h b/client/cmdlfcotag.h index 179048c68..e4b12235d 100644 --- a/client/cmdlfcotag.h +++ b/client/cmdlfcotag.h @@ -24,7 +24,6 @@ #endif int CmdLFCOTAG(const char *Cmd); -int CmdCOTAGRead(const char *Cmd); -int CmdCOTAGDemod(const char *Cmd); - +int demodCOTAG(void); +int readCOTAGUid(void); #endif diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 55993e211..773fff29a 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -188,7 +188,7 @@ static int usage_lf_em4x05_info(void) { */ // Construct the graph for emulating an EM410X tag -void ConstructEM410xEmulGraph(const char *uid, const uint8_t clock) { +static void ConstructEM410xEmulGraph(const char *uid, const uint8_t clock) { int i, j, binary[4], parity[4]; uint32_t n; @@ -383,28 +383,22 @@ int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose) { if (!ASKDemod_ext(Cmd, false, false, 1, &st)) return 0; return AskEm410xDecode(verbose, hi, lo); } - -// this read is the "normal" read, which download lf signal and tries to demod here. -int CmdEM410xRead(const char *Cmd) { - lf_read(true, 8192); - return CmdEM410xDemod(Cmd); -} - +/* // this read loops on device side. // uses the demod in lfops.c -int CmdEM410xRead_device(const char *Cmd) { +static int CmdEM410xRead_device(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); uint8_t findone = (cmdp == '1') ? 1 : 0; UsbCommand c = {CMD_EM410X_DEMOD, {findone, 0, 0}, {{0}}}; SendCommand(&c); return 0; } - +*/ //by marshmellow //takes 3 arguments - clock, invert and maxErr as integers //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands -int CmdEM410xDemod(const char *Cmd) { +static int CmdEM410xDemod(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) > 10 || cmdp == 'h') return usage_lf_em410x_demod(); @@ -417,8 +411,14 @@ int CmdEM410xDemod(const char *Cmd) { return 1; } +// this read is the "normal" read, which download lf signal and tries to demod here. +static int CmdEM410xRead(const char *Cmd) { + lf_read(true, 8192); + return CmdEM410xDemod(Cmd); +} + // emulate an EM410X tag -int CmdEM410xSim(const char *Cmd) { +static int CmdEM410xSim(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_lf_em410x_sim(); @@ -443,7 +443,7 @@ int CmdEM410xSim(const char *Cmd) { return 0; } -int CmdEM410xBrute(const char *Cmd) { +static int CmdEM410xBrute(const char *Cmd) { char filename[FILE_PATH_SIZE] = {0}; FILE *f = NULL; char buf[11]; @@ -565,7 +565,7 @@ int CmdEM410xBrute(const char *Cmd) { * * EDIT -- capture enough to get 2 complete preambles at the slowest data rate known to be used (rf/64) (64*64*2+9 = 8201) marshmellow */ -int CmdEM410xWatch(const char *Cmd) { +static int CmdEM410xWatch(const char *Cmd) { (void)Cmd; // Cmd is not used so far do { if (ukbhit()) { @@ -581,7 +581,7 @@ int CmdEM410xWatch(const char *Cmd) { } //currently only supports manchester modulations -int CmdEM410xWatchnSpoof(const char *Cmd) { +static int CmdEM410xWatchnSpoof(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_lf_em410x_ws(); @@ -593,7 +593,7 @@ int CmdEM410xWatchnSpoof(const char *Cmd) { return 0; } -int CmdEM410xWrite(const char *Cmd) { +static int CmdEM410xWrite(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 0x00 || cmdp == 'h') return usage_lf_em410x_write(); @@ -956,18 +956,18 @@ int EM4x50Read(const char *Cmd, bool verbose) { return (int)AllPTest; } -int CmdEM4x50Read(const char *Cmd) { +static int CmdEM4x50Read(const char *Cmd) { uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_lf_em4x50_read(); return EM4x50Read(Cmd, true); } -int CmdEM4x50Write(const char *Cmd) { +static int CmdEM4x50Write(const char *Cmd) { uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_lf_em4x50_write(); PrintAndLogEx(NORMAL, "no implemented yet"); return 0; } -int CmdEM4x50Dump(const char *Cmd) { +static int CmdEM4x50Dump(const char *Cmd) { uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_lf_em4x50_dump(); PrintAndLogEx(NORMAL, "no implemented yet"); @@ -1143,7 +1143,7 @@ int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t *word) return demodEM4x05resp(word); } -int CmdEM4x05Dump(const char *Cmd) { +static int CmdEM4x05Dump(const char *Cmd) { uint8_t addr = 0; uint32_t pwd = 0; bool usePwd = false; @@ -1176,7 +1176,7 @@ int CmdEM4x05Dump(const char *Cmd) { return success; } -int CmdEM4x05Read(const char *Cmd) { +static int CmdEM4x05Read(const char *Cmd) { uint8_t addr; uint32_t pwd; bool usePwd = false; @@ -1206,7 +1206,7 @@ int CmdEM4x05Read(const char *Cmd) { return isOk; } -int CmdEM4x05Write(const char *Cmd) { +static int CmdEM4x05Write(const char *Cmd) { uint8_t ctmp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_write(); @@ -1419,7 +1419,7 @@ bool EM4x05IsBlock0(uint32_t *word) { return (res > 0) ? true : false; } -int CmdEM4x05Info(const char *Cmd) { +static int CmdEM4x05Info(const char *Cmd) { #define EM_SERIAL_BLOCK 1 #define EM_CONFIG_BLOCK 4 #define EM_PROT1_BLOCK 14 @@ -1488,14 +1488,18 @@ static command_t CommandTable[] = { {NULL, NULL, 0, NULL} }; +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return 0; +} + int CmdLFEM4X(const char *Cmd) { clearCommandBuffer(); CmdsParse(CommandTable, Cmd); return 0; } -int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return 0; +int demodEM410x(void) { + return CmdEM410xDemod(""); } diff --git a/client/cmdlfem4x.h b/client/cmdlfem4x.h index b4182f4ab..12f27c2c7 100644 --- a/client/cmdlfem4x.h +++ b/client/cmdlfem4x.h @@ -27,21 +27,7 @@ int CmdLFEM4X(const char *Cmd); -int CmdEM410xDemod(const char *Cmd); -int CmdEM410xRead(const char *Cmd); -int CmdEM410xSim(const char *Cmd); -int CmdEM410xBrute(const char *Cmd); -int CmdEM410xWatch(const char *Cmd); -int CmdEM410xWatchnSpoof(const char *Cmd); -int CmdEM410xWrite(const char *Cmd); -int CmdEM4x05Dump(const char *Cmd); -int CmdEM4x05Info(const char *Cmd); -int CmdEM4x05Read(const char *Cmd); -int CmdEM4x05Write(const char *Cmd); -int CmdEM4x50Read(const char *Cmd); -int CmdEM4x50Write(const char *Cmd); -int CmdEM4x50Dump(const char *Cmd); - +int demodEM410x(void); int EM4x50Read(const char *Cmd, bool verbose); bool EM4x05IsBlock0(uint32_t *word); diff --git a/client/cmdlffdx.c b/client/cmdlffdx.c index 024b79f1e..510c38e4a 100644 --- a/client/cmdlffdx.c +++ b/client/cmdlffdx.c @@ -64,20 +64,6 @@ static int usage_lf_fdx_sim(void) { return 0; } -// Ask/Biphase Demod then try to locate an ISO 11784/85 ID -// BitStream must contain previously askrawdemod and biphasedemoded data -int detectFDXB(uint8_t *dest, size_t *size) { - //make sure buffer has enough data - if (*size < 128 * 2) return -1; - size_t startIdx = 0; - uint8_t preamble[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; - if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) - return -2; //preamble not found - if (*size != 128) return -3; //wrong demoded size - //return start position - return (int)startIdx; -} - // clearing the topbit needed for the preambl detection. static void verify_values(uint32_t countryid, uint64_t animalid) { if ((animalid & 0x3FFFFFFFFF) != animalid) { @@ -90,56 +76,6 @@ static void verify_values(uint32_t countryid, uint64_t animalid) { } } -int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) { - - // add preamble ten 0x00 and one 0x01 - memset(bits, 0x00, 10); - bits[10] = 1; - - // 128bits - // every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite - memset(bits, 0x01, 128); - - // add preamble ten 0x00 and one 0x01 - memset(bits, 0x00, 10); - - // add reserved - num_to_bytebitsLSBF(0x00, 7, bits + 66); - num_to_bytebitsLSBF(0x00 >> 7, 7, bits + 74); - - // add animal flag - OK - bits[65] = isanimal; - - // add extended flag - OK - bits[81] = isextended; - - // add national code 40bits - OK - num_to_bytebitsLSBF(national_id >> 0, 8, bits + 11); - num_to_bytebitsLSBF(national_id >> 8, 8, bits + 20); - num_to_bytebitsLSBF(national_id >> 16, 8, bits + 29); - num_to_bytebitsLSBF(national_id >> 24, 8, bits + 38); - num_to_bytebitsLSBF(national_id >> 32, 6, bits + 47); - - // add country code - OK - num_to_bytebitsLSBF(country >> 0, 2, bits + 53); - num_to_bytebitsLSBF(country >> 2, 8, bits + 56); - - // add crc-16 - OK - uint8_t raw[8]; - for (uint8_t i = 0; i < 8; ++i) - raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8); - - uint16_t crc = crc16_kermit(raw, 8); - num_to_bytebitsLSBF(crc >> 0, 8, bits + 83); - num_to_bytebitsLSBF(crc >> 8, 8, bits + 92); - - // extended data - OK - num_to_bytebitsLSBF(extended >> 0, 8, bits + 101); - num_to_bytebitsLSBF(extended >> 8, 8, bits + 110); - num_to_bytebitsLSBF(extended >> 16, 8, bits + 119); - return 1; -} - // FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits) // 8 databits + 1 parity (1) // CIITT 16 chksum @@ -157,7 +93,8 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t -- sample: 985121004515220 [ 37FF65B88EF94 ] */ -int CmdFDXBdemodBI(const char *Cmd) { +/* +static int CmdFDXBdemodBI(const char *Cmd) { (void)Cmd; // Cmd is not used so far int clk = 32; @@ -229,11 +166,11 @@ int CmdFDXBdemodBI(const char *Cmd) { } return 1; } - +*/ //see ASKDemod for what args are accepted //almost the same demod as cmddata.c/CmdFDXBdemodBI -int CmdFdxDemod(const char *Cmd) { +static int CmdFdxDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far //Differential Biphase / di-phase (inverted biphase) @@ -303,12 +240,12 @@ int CmdFdxDemod(const char *Cmd) { return 1; } -int CmdFdxRead(const char *Cmd) { +static int CmdFdxRead(const char *Cmd) { lf_read(true, 10000); return CmdFdxDemod(Cmd); } -int CmdFdxClone(const char *Cmd) { +static int CmdFdxClone(const char *Cmd) { uint32_t countryid = 0; uint64_t animalid = 0; @@ -360,7 +297,7 @@ int CmdFdxClone(const char *Cmd) { return 0; } -int CmdFdxSim(const char *Cmd) { +static int CmdFdxSim(const char *Cmd) { uint32_t countryid = 0; uint64_t animalid = 0; @@ -399,14 +336,83 @@ static command_t CommandTable[] = { {NULL, NULL, 0, NULL} }; +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return 0; +} + int CmdLFFdx(const char *Cmd) { clearCommandBuffer(); CmdsParse(CommandTable, Cmd); return 0; } -int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return 0; +// Ask/Biphase Demod then try to locate an ISO 11784/85 ID +// BitStream must contain previously askrawdemod and biphasedemoded data +int detectFDXB(uint8_t *dest, size_t *size) { + //make sure buffer has enough data + if (*size < 128 * 2) return -1; + size_t startIdx = 0; + uint8_t preamble[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) + return -2; //preamble not found + if (*size != 128) return -3; //wrong demoded size + //return start position + return (int)startIdx; } + +int demodFDX(void) { + return CmdFdxDemod(""); +} + +int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) { + + // add preamble ten 0x00 and one 0x01 + memset(bits, 0x00, 10); + bits[10] = 1; + + // 128bits + // every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite + memset(bits, 0x01, 128); + + // add preamble ten 0x00 and one 0x01 + memset(bits, 0x00, 10); + + // add reserved + num_to_bytebitsLSBF(0x00, 7, bits + 66); + num_to_bytebitsLSBF(0x00 >> 7, 7, bits + 74); + + // add animal flag - OK + bits[65] = isanimal; + + // add extended flag - OK + bits[81] = isextended; + + // add national code 40bits - OK + num_to_bytebitsLSBF(national_id >> 0, 8, bits + 11); + num_to_bytebitsLSBF(national_id >> 8, 8, bits + 20); + num_to_bytebitsLSBF(national_id >> 16, 8, bits + 29); + num_to_bytebitsLSBF(national_id >> 24, 8, bits + 38); + num_to_bytebitsLSBF(national_id >> 32, 6, bits + 47); + + // add country code - OK + num_to_bytebitsLSBF(country >> 0, 2, bits + 53); + num_to_bytebitsLSBF(country >> 2, 8, bits + 56); + + // add crc-16 - OK + uint8_t raw[8]; + for (uint8_t i = 0; i < 8; ++i) + raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8); + + uint16_t crc = crc16_kermit(raw, 8); + num_to_bytebitsLSBF(crc >> 0, 8, bits + 83); + num_to_bytebitsLSBF(crc >> 8, 8, bits + 92); + + // extended data - OK + num_to_bytebitsLSBF(extended >> 0, 8, bits + 101); + num_to_bytebitsLSBF(extended >> 8, 8, bits + 110); + num_to_bytebitsLSBF(extended >> 16, 8, bits + 119); + return 1; +} + diff --git a/client/cmdlffdx.h b/client/cmdlffdx.h index 85787f3a8..5e6c5ab48 100644 --- a/client/cmdlffdx.h +++ b/client/cmdlffdx.h @@ -20,11 +20,8 @@ #include "lfdemod.h" // parityTest int CmdLFFdx(const char *Cmd); -int CmdFdxClone(const char *Cmd); -int CmdFdxSim(const char *Cmd); -int CmdFdxRead(const char *Cmd); -int CmdFdxDemod(const char *Cmd); - +int detectFDXB(uint8_t *dest, size_t *size); +int demodFDX(void); int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits); #endif diff --git a/client/cmdlfguard.c b/client/cmdlfguard.c index 33bcef7f4..3fb84a639 100644 --- a/client/cmdlfguard.c +++ b/client/cmdlfguard.c @@ -44,8 +44,241 @@ static int usage_lf_guard_sim(void) { return 0; } +//by marshmellow +//attempts to demodulate and identify a G_Prox_II verex/chubb card +//WARNING: if it fails during some points it will destroy the DemodBuffer data +// but will leave the GraphBuffer intact. +//if successful it will push askraw data back to demod buffer ready for emulation +static int CmdGuardDemod(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + + //Differential Biphase + //get binary from ask wave + if (!ASKbiphaseDemod("0 64 0 0", false)) { + PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ASKbiphaseDemod failed"); + return 0; + } + + size_t size = DemodBufferLen; + + int preambleIndex = detectGProxII(DemodBuffer, &size); + if (preambleIndex < 0) { + + if (preambleIndex == -1) + PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII too few bits found"); + else if (preambleIndex == -2) + PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII preamble not found"); + else if (preambleIndex == -3) + PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII size not correct: %d", size); + else if (preambleIndex == -5) + PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII wrong spacerbits"); + else + PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ans: %d", preambleIndex); + return 0; + } + + //got a good demod of 96 bits + uint8_t ByteStream[8] = {0x00}; + uint8_t xorKey = 0; + size_t startIdx = preambleIndex + 6; //start after 6 bit preamble + + uint8_t bits_no_spacer[90]; + //so as to not mess with raw DemodBuffer copy to a new sample array + memcpy(bits_no_spacer, DemodBuffer + startIdx, 90); + // remove the 18 (90/5=18) parity bits (down to 72 bits (96-6-18=72)) + size_t len = removeParity(bits_no_spacer, 0, 5, 3, 90); //source, startloc, paritylen, ptype, length_to_run + if (len != 72) { + PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII spacer removal did not produce 72 bits: %u, start: %u", len, startIdx); + return 0; + } + // get key and then get all 8 bytes of payload decoded + xorKey = (uint8_t)bytebits_to_byteLSBF(bits_no_spacer, 8); + for (size_t idx = 0; idx < 8; idx++) { + ByteStream[idx] = ((uint8_t)bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8)) ^ xorKey; + PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %u after xor: %02x", (unsigned int)idx, ByteStream[idx]); + } + + setDemodBuff(DemodBuffer, 96, preambleIndex); + setClockGrid(g_DemodClock, g_DemodStartIdx + (preambleIndex * g_DemodClock)); + + //ByteStream contains 8 Bytes (64 bits) of decrypted raw tag data + uint8_t fmtLen = ByteStream[0] >> 2; + uint32_t FC = 0; + uint32_t Card = 0; + //get raw 96 bits to print + uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32); + uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); + uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32); + bool unknown = false; + switch (fmtLen) { + case 36: + FC = ((ByteStream[3] & 0x7F) << 7) | (ByteStream[4] >> 1); + Card = ((ByteStream[4] & 1) << 19) | (ByteStream[5] << 11) | (ByteStream[6] << 3) | (ByteStream[7] >> 5); + break; + case 26: + FC = ((ByteStream[3] & 0x7F) << 1) | (ByteStream[4] >> 7); + Card = ((ByteStream[4] & 0x7F) << 9) | (ByteStream[5] << 1) | (ByteStream[6] >> 7); + break; + default : + unknown = true; + break; + } + if (!unknown) + PrintAndLogEx(SUCCESS, "G-Prox-II Found: Format Len: %ubit - FC: %u - Card: %u, Raw: %08x%08x%08x", fmtLen, FC, Card, raw1, raw2, raw3); + else + PrintAndLogEx(SUCCESS, "Unknown G-Prox-II Fmt Found: Format Len: %u, Raw: %08x%08x%08x", fmtLen, raw1, raw2, raw3); + + return 1; +} + +static int CmdGuardRead(const char *Cmd) { + lf_read(true, 10000); + return CmdGuardDemod(Cmd); +} + +static int CmdGuardClone(const char *Cmd) { + + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_clone(); + + uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0; + uint8_t i; + uint8_t bs[96]; + memset(bs, 0x00, sizeof(bs)); + + //GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks + uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0}; + + if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone(); + + fmtlen &= 0x7f; + facilitycode = (fc & 0x000000FF); + cardnumber = (cn & 0x0000FFFF); + + if (!getGuardBits(fmtlen, facilitycode, cardnumber, bs)) { + PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + return 1; + } + + // Q5 + if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q') + blocks[0] = T5555_MODULATION_FSK2 | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT; + + blocks[1] = bytebits_to_byte(bs, 32); + blocks[2] = bytebits_to_byte(bs + 32, 32); + blocks[3] = bytebits_to_byte(bs + 64, 32); + + PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); + print_blocks(blocks, 4); + + UsbCommand resp; + UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0, 0, 0}, {{0}}}; + + for (i = 0; i < 4; ++i) { + c.arg[0] = blocks[i]; + c.arg[1] = i; + clearCommandBuffer(); + SendCommand(&c); + if (!WaitForResponseTimeout(CMD_ACK, &resp, T55XX_WRITE_TIMEOUT)) { + PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); + return -1; + } + } + return 0; +} + +static int CmdGuardSim(const char *Cmd) { + + // Guard uses: clk: 64, invert: 0, encoding: 2 (ASK Biphase) + uint8_t clock1 = 64, encoding = 2, separator = 0, invert = 0; + uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0; + + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_sim(); + + if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_sim(); + + uint8_t bs[96]; + size_t size = sizeof(bs); + memset(bs, 0x00, size); + + fmtlen &= 0x7F; + facilitycode = (fc & 0x000000FF); + cardnumber = (cn & 0x0000FFFF); + + if (!getGuardBits(fmtlen, facilitycode, cardnumber, bs)) { + PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + return 1; + } + + PrintAndLogEx(SUCCESS, "Simulating Guardall - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber); + + uint64_t arg1, arg2; + arg1 = (clock1 << 8) | encoding; + arg2 = (invert << 8) | separator; + + UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}, {{0}}}; + memcpy(c.d.asBytes, bs, size); + clearCommandBuffer(); + SendCommand(&c); + return 0; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, 1, "this help"}, + {"demod", CmdGuardDemod, 1, "demodulate a G Prox II tag from the GraphBuffer"}, + {"read", CmdGuardRead, 0, "attempt to read and extract tag data from the antenna"}, + {"clone", CmdGuardClone, 0, "clone Guardall tag"}, + {"sim", CmdGuardSim, 0, "simulate Guardall tag"}, + {NULL, NULL, 0, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return 0; +} + +int CmdLFGuard(const char *Cmd) { + clearCommandBuffer(); + CmdsParse(CommandTable, Cmd); + return 0; +} + +// by marshmellow +// demod gProxIIDemod +// error returns as -x +// success returns start position in bitstream +// Bitstream must contain previously askrawdemod and biphasedemoded data +int detectGProxII(uint8_t *bits, size_t *size) { + + size_t startIdx = 0; + uint8_t preamble[] = {1, 1, 1, 1, 1, 0}; + + // sanity check + if (*size < sizeof(preamble)) return -1; + + if (!preambleSearch(bits, preamble, sizeof(preamble), size, &startIdx)) + return -2; //preamble not found + + //gProxII should be 96 bits + if (*size != 96) return -3; + + //check first 6 spacer bits to verify format + if (!bits[startIdx + 5] && !bits[startIdx + 10] && !bits[startIdx + 15] && !bits[startIdx + 20] && !bits[startIdx + 25] && !bits[startIdx + 30]) { + //confirmed proper separator bits found + //return start position + return (int) startIdx; + } + return -5; //spacer bits not found - not a valid gproxII +} + +int demodGuard(void) { + return CmdGuardDemod(""); +} + // Works for 26bits. -int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) { +int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) { uint8_t xorKey = 0x66; uint8_t i; @@ -139,231 +372,3 @@ int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) { return 1; } -// by marshmellow -// demod gProxIIDemod -// error returns as -x -// success returns start position in bitstream -// Bitstream must contain previously askrawdemod and biphasedemoded data -int detectGProxII(uint8_t *bits, size_t *size) { - - size_t startIdx = 0; - uint8_t preamble[] = {1, 1, 1, 1, 1, 0}; - - // sanity check - if (*size < sizeof(preamble)) return -1; - - if (!preambleSearch(bits, preamble, sizeof(preamble), size, &startIdx)) - return -2; //preamble not found - - //gProxII should be 96 bits - if (*size != 96) return -3; - - //check first 6 spacer bits to verify format - if (!bits[startIdx + 5] && !bits[startIdx + 10] && !bits[startIdx + 15] && !bits[startIdx + 20] && !bits[startIdx + 25] && !bits[startIdx + 30]) { - //confirmed proper separator bits found - //return start position - return (int) startIdx; - } - return -5; //spacer bits not found - not a valid gproxII -} - -//by marshmellow -//attempts to demodulate and identify a G_Prox_II verex/chubb card -//WARNING: if it fails during some points it will destroy the DemodBuffer data -// but will leave the GraphBuffer intact. -//if successful it will push askraw data back to demod buffer ready for emulation -int CmdGuardDemod(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - - //Differential Biphase - //get binary from ask wave - if (!ASKbiphaseDemod("0 64 0 0", false)) { - PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ASKbiphaseDemod failed"); - return 0; - } - - size_t size = DemodBufferLen; - - int preambleIndex = detectGProxII(DemodBuffer, &size); - if (preambleIndex < 0) { - - if (preambleIndex == -1) - PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII too few bits found"); - else if (preambleIndex == -2) - PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII preamble not found"); - else if (preambleIndex == -3) - PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII size not correct: %d", size); - else if (preambleIndex == -5) - PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII wrong spacerbits"); - else - PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ans: %d", preambleIndex); - return 0; - } - - //got a good demod of 96 bits - uint8_t ByteStream[8] = {0x00}; - uint8_t xorKey = 0; - size_t startIdx = preambleIndex + 6; //start after 6 bit preamble - - uint8_t bits_no_spacer[90]; - //so as to not mess with raw DemodBuffer copy to a new sample array - memcpy(bits_no_spacer, DemodBuffer + startIdx, 90); - // remove the 18 (90/5=18) parity bits (down to 72 bits (96-6-18=72)) - size_t len = removeParity(bits_no_spacer, 0, 5, 3, 90); //source, startloc, paritylen, ptype, length_to_run - if (len != 72) { - PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII spacer removal did not produce 72 bits: %u, start: %u", len, startIdx); - return 0; - } - // get key and then get all 8 bytes of payload decoded - xorKey = (uint8_t)bytebits_to_byteLSBF(bits_no_spacer, 8); - for (size_t idx = 0; idx < 8; idx++) { - ByteStream[idx] = ((uint8_t)bytebits_to_byteLSBF(bits_no_spacer + 8 + (idx * 8), 8)) ^ xorKey; - PrintAndLogEx(DEBUG, "DEBUG: gProxII byte %u after xor: %02x", (unsigned int)idx, ByteStream[idx]); - } - - setDemodBuff(DemodBuffer, 96, preambleIndex); - setClockGrid(g_DemodClock, g_DemodStartIdx + (preambleIndex * g_DemodClock)); - - //ByteStream contains 8 Bytes (64 bits) of decrypted raw tag data - uint8_t fmtLen = ByteStream[0] >> 2; - uint32_t FC = 0; - uint32_t Card = 0; - //get raw 96 bits to print - uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32); - uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); - uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32); - bool unknown = false; - switch (fmtLen) { - case 36: - FC = ((ByteStream[3] & 0x7F) << 7) | (ByteStream[4] >> 1); - Card = ((ByteStream[4] & 1) << 19) | (ByteStream[5] << 11) | (ByteStream[6] << 3) | (ByteStream[7] >> 5); - break; - case 26: - FC = ((ByteStream[3] & 0x7F) << 1) | (ByteStream[4] >> 7); - Card = ((ByteStream[4] & 0x7F) << 9) | (ByteStream[5] << 1) | (ByteStream[6] >> 7); - break; - default : - unknown = true; - break; - } - if (!unknown) - PrintAndLogEx(SUCCESS, "G-Prox-II Found: Format Len: %ubit - FC: %u - Card: %u, Raw: %08x%08x%08x", fmtLen, FC, Card, raw1, raw2, raw3); - else - PrintAndLogEx(SUCCESS, "Unknown G-Prox-II Fmt Found: Format Len: %u, Raw: %08x%08x%08x", fmtLen, raw1, raw2, raw3); - - return 1; -} - -int CmdGuardRead(const char *Cmd) { - lf_read(true, 10000); - return CmdGuardDemod(Cmd); -} - -int CmdGuardClone(const char *Cmd) { - - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_clone(); - - uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0; - uint8_t i; - uint8_t bs[96]; - memset(bs, 0x00, sizeof(bs)); - - //GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks - uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0}; - - if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone(); - - fmtlen &= 0x7f; - facilitycode = (fc & 0x000000FF); - cardnumber = (cn & 0x0000FFFF); - - if (!GetGuardBits(fmtlen, facilitycode, cardnumber, bs)) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); - return 1; - } - - // Q5 - if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q') - blocks[0] = T5555_MODULATION_FSK2 | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT; - - blocks[1] = bytebits_to_byte(bs, 32); - blocks[2] = bytebits_to_byte(bs + 32, 32); - blocks[3] = bytebits_to_byte(bs + 64, 32); - - PrintAndLogEx(INFO, "Preparing to clone Guardall to T55x7 with Facility Code: %u, Card Number: %u", facilitycode, cardnumber); - print_blocks(blocks, 4); - - UsbCommand resp; - UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0, 0, 0}, {{0}}}; - - for (i = 0; i < 4; ++i) { - c.arg[0] = blocks[i]; - c.arg[1] = i; - clearCommandBuffer(); - SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK, &resp, T55XX_WRITE_TIMEOUT)) { - PrintAndLogEx(WARNING, "Error occurred, device did not respond during write operation."); - return -1; - } - } - return 0; -} - -int CmdGuardSim(const char *Cmd) { - - // Guard uses: clk: 64, invert: 0, encoding: 2 (ASK Biphase) - uint8_t clock1 = 64, encoding = 2, separator = 0, invert = 0; - uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0; - - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_sim(); - - if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_sim(); - - uint8_t bs[96]; - size_t size = sizeof(bs); - memset(bs, 0x00, size); - - fmtlen &= 0x7F; - facilitycode = (fc & 0x000000FF); - cardnumber = (cn & 0x0000FFFF); - - if (!GetGuardBits(fmtlen, facilitycode, cardnumber, bs)) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); - return 1; - } - - PrintAndLogEx(SUCCESS, "Simulating Guardall - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber); - - uint64_t arg1, arg2; - arg1 = (clock1 << 8) | encoding; - arg2 = (invert << 8) | separator; - - UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}, {{0}}}; - memcpy(c.d.asBytes, bs, size); - clearCommandBuffer(); - SendCommand(&c); - return 0; -} - -static command_t CommandTable[] = { - {"help", CmdHelp, 1, "this help"}, - {"demod", CmdGuardDemod, 1, "demodulate a G Prox II tag from the GraphBuffer"}, - {"read", CmdGuardRead, 0, "attempt to read and extract tag data from the antenna"}, - {"clone", CmdGuardClone, 0, "clone Guardall tag"}, - {"sim", CmdGuardSim, 0, "simulate Guardall tag"}, - {NULL, NULL, 0, NULL} -}; - -int CmdLFGuard(const char *Cmd) { - clearCommandBuffer(); - CmdsParse(CommandTable, Cmd); - return 0; -} - -int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return 0; -} diff --git a/client/cmdlfguard.h b/client/cmdlfguard.h index 8e8d2663d..c6725ed07 100644 --- a/client/cmdlfguard.h +++ b/client/cmdlfguard.h @@ -23,9 +23,7 @@ #include "crc.h" int CmdLFGuard(const char *Cmd); -int CmdGuardDemod(const char *Cmd); -int CmdGuardRead(const char *Cmd); -int CmdGuardClone(const char *Cmd); -int CmdGuardSim(const char *Cmd); - +int detectGProxII(uint8_t *bits, size_t *size); +int demodGuard(void); +int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits); #endif diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index c07fc2c1f..0eb76a8bf 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -15,7 +15,7 @@ #endif static int CmdHelp(const char *Cmd); - +/* static int usage_lf_hid_read(void) { PrintAndLogEx(NORMAL, "Enables HID compatible reader mode printing details."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); @@ -31,6 +31,7 @@ static int usage_lf_hid_read(void) { PrintAndLogEx(NORMAL, " lf hid read 1"); return 0; } +*/ static int usage_lf_hid_wiegand(void) { PrintAndLogEx(NORMAL, "This command converts facility code/card number to Wiegand code"); PrintAndLogEx(NORMAL, ""); @@ -124,7 +125,7 @@ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, ui //by marshmellow (based on existing demod + holiman's refactor) //HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded) //print full HID Prox ID and some bit format details if found -int CmdHIDDemod(const char *Cmd) { +static int CmdHIDDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far //raw fsk demod no manchester decoding no start bit finding just get binary from wave uint32_t hi2 = 0, hi = 0, lo = 0; @@ -230,14 +231,14 @@ int CmdHIDDemod(const char *Cmd) { } // this read is the "normal" read, which download lf signal and tries to demod here. -int CmdHIDRead(const char *Cmd) { +static int CmdHIDRead(const char *Cmd) { lf_read(true, 12000); return CmdHIDDemod(Cmd); } - +/* // this read loops on device side. // uses the demod in lfops.c -int CmdHIDRead_device(const char *Cmd) { +static int CmdHIDRead_device(const char *Cmd) { if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_hid_read(); uint8_t findone = (Cmd[0] == '1') ? 1 : 0; @@ -246,8 +247,8 @@ int CmdHIDRead_device(const char *Cmd) { SendCommand(&c); return 0; } - -int CmdHIDSim(const char *Cmd) { +*/ +static int CmdHIDSim(const char *Cmd) { uint32_t hi = 0, lo = 0; uint32_t n = 0, i = 0; @@ -268,7 +269,7 @@ int CmdHIDSim(const char *Cmd) { return 0; } -int CmdHIDClone(const char *Cmd) { +static int CmdHIDClone(const char *Cmd) { uint32_t hi2 = 0, hi = 0, lo = 0; uint32_t n = 0, i = 0; @@ -473,7 +474,7 @@ void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, ui } } -int CmdHIDWiegand(const char *Cmd) { +static int CmdHIDWiegand(const char *Cmd) { uint32_t oem = 0, fc = 0; uint64_t cardnum = 0; uint8_t bits[BITS] = {0}; @@ -515,7 +516,7 @@ int CmdHIDWiegand(const char *Cmd) { return 0; } -int CmdHIDBrute(const char *Cmd) { +static int CmdHIDBrute(const char *Cmd) { bool errors = false, verbose = false; uint32_t fc = 0, cn = 0, delay = 1000; @@ -615,14 +616,18 @@ static command_t CommandTable[] = { {NULL, NULL, 0, NULL} }; +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return 0; +} + int CmdLFHID(const char *Cmd) { clearCommandBuffer(); CmdsParse(CommandTable, Cmd); return 0; } -int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return 0; +int demodHID(void) { + return CmdHIDDemod(""); } diff --git a/client/cmdlfhid.h b/client/cmdlfhid.h index f7d3802f0..8270b6469 100644 --- a/client/cmdlfhid.h +++ b/client/cmdlfhid.h @@ -25,13 +25,8 @@ #include "lfdemod.h" int CmdLFHID(const char *Cmd); -int CmdHIDDemod(const char *Cmd); -int CmdHIDRead(const char *Cmd); -int CmdHIDSim(const char *Cmd); -int CmdHIDClone(const char *Cmd); -int CmdHIDWiegand(const char *Cmd); -int CmdHIDBrute(const char *Cmd); +int demodHID(void); //void calc26(uint16_t fc, uint32_t cardno, uint8_t *out); void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits, uint8_t oem); #endif diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index f627b4733..3212f4454 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -64,6 +64,7 @@ static int usage_hitag_info(void) { PrintAndLogEx(NORMAL, " lf hitag info"); return 0; } +/* static int usage_hitag_dump(void) { PrintAndLogEx(NORMAL, "Usage: lf hitag dump [h] p f "); PrintAndLogEx(NORMAL, "Options:"); @@ -76,6 +77,7 @@ static int usage_hitag_dump(void) { PrintAndLogEx(NORMAL, " lf hitag dump p 4D494B52 f mydump"); return 0; } +*/ static int usage_hitag_reader(void) { PrintAndLogEx(NORMAL, "Hitag reader functions"); PrintAndLogEx(NORMAL, "Usage: lf hitag reader [h] "); @@ -120,7 +122,7 @@ static int usage_hitag_checkchallenges(void) { return 0; } -int CmdLFHitagList(const char *Cmd) { +static int CmdLFHitagList(const char *Cmd) { (void)Cmd; // Cmd is not used so far CmdTraceList("hitag"); return 0; @@ -253,7 +255,7 @@ int CmdLFHitagList(const char *Cmd) { */ } -int CmdLFHitagSniff(const char *Cmd) { +static int CmdLFHitagSniff(const char *Cmd) { char ctmp = tolower(param_getchar(Cmd, 0)); if (ctmp == 'h') return usage_hitag_sniff(); @@ -264,7 +266,7 @@ int CmdLFHitagSniff(const char *Cmd) { return 0; } -int CmdLFHitagSim(const char *Cmd) { +static int CmdLFHitagSim(const char *Cmd) { bool errors = false; bool tag_mem_supplied = false; @@ -476,7 +478,7 @@ static bool getHitagUid(uint32_t *uid) { return true; } -int CmdLFHitagInfo(const char *Cmd) { +static int CmdLFHitagInfo(const char *Cmd) { PrintAndLogEx(INFO, "Hitag2 tag information "); PrintAndLogEx(INFO, "To be done!"); PrintAndLogEx(INFO, "------------------------------------"); @@ -509,7 +511,7 @@ int CmdLFHitagInfo(const char *Cmd) { // TODO: iceman // Hitag2 reader, problem is that this command mixes up stuff. So 26 give uid. 21 etc will also give you a memory dump !? // -int CmdLFHitagReader(const char *Cmd) { +static int CmdLFHitagReader(const char *Cmd) { UsbCommand c = {CMD_READER_HITAG, {0, 0, 0}, {{0}}}; hitag_data *htd = (hitag_data *)c.d.asBytes; @@ -590,7 +592,7 @@ int CmdLFHitagReader(const char *Cmd) { return 0; } -int CmdLFHitagCheckChallenges(const char *Cmd) { +static int CmdLFHitagCheckChallenges(const char *Cmd) { UsbCommand c = { CMD_TEST_HITAGS_TRACES, {0, 0, 0}, {{0}}}; char filename[FILE_PATH_SIZE] = { 0x00 }; @@ -640,7 +642,7 @@ int CmdLFHitagCheckChallenges(const char *Cmd) { return 0; } -int CmdLFHitagWriter(const char *Cmd) { +static int CmdLFHitagWriter(const char *Cmd) { UsbCommand c = { CMD_WR_HITAG_S, {0, 0, 0}, {{0}}}; hitag_data *htd = (hitag_data *)c.d.asBytes; hitag_function htf = param_get32ex(Cmd, 0, 0, 10); @@ -681,7 +683,8 @@ int CmdLFHitagWriter(const char *Cmd) { return 0; } -int CmdLFHitagDump(const char *Cmd) { +/* +static int CmdLFHitagDump(const char *Cmd) { PrintAndLogEx(INFO, "Dumping of tag memory"); PrintAndLogEx(INFO, "To be done!"); @@ -689,6 +692,7 @@ int CmdLFHitagDump(const char *Cmd) { if (ctmp == 'h') return usage_hitag_dump(); return 0; } +*/ static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help" }, @@ -702,14 +706,18 @@ static command_t CommandTable[] = { { NULL, NULL, 0, NULL } }; +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return 0; +} + int CmdLFHitag(const char *Cmd) { clearCommandBuffer(); CmdsParse(CommandTable, Cmd); return 0; } -int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return 0; +int readHitagUid(void) { + return CmdLFHitagReader("26") == 0; } diff --git a/client/cmdlfhitag.h b/client/cmdlfhitag.h index 650e5d892..264a245a1 100644 --- a/client/cmdlfhitag.h +++ b/client/cmdlfhitag.h @@ -13,13 +13,6 @@ int CmdLFHitag(const char *Cmd); -int CmdLFHitagList(const char *Cmd); -int CmdLFHitagSniff(const char *Cmd); -int CmdLFHitagSim(const char *Cmd); -int CmdLFHitagInfo(const char *Cmd); -int CmdLFHitagReader(const char *Cmd); -int CmdLFHitagCheckChallenges(const char *Cmd); -int CmdLFHitagWriter(const char *Cmd); -int CmdLFHitagDump(const char *Cmd); +int readHitagUid(void); #endif diff --git a/client/cmdlfindala.c b/client/cmdlfindala.c index 5bcf52eb0..be850d43f 100644 --- a/client/cmdlfindala.c +++ b/client/cmdlfindala.c @@ -50,126 +50,10 @@ static int usage_lf_indala_sim(void) { return 0; } -// redesigned by marshmellow adjusted from existing decode functions -// indala id decoding -static int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert) { - - uint8_t preamble64_i[] = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; - uint8_t preamble224_i[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; - - size_t idx = 0; - size_t found_size = *size; - - // PSK1 - bool res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx); - if (res) { - PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64"); - goto out; - } - idx = 0; - found_size = *size; - res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx); - if (res) { - PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64 inverted preamble"); - goto inv; - } - - /* - idx = 0; - found_size = *size; - res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx); - if ( res ) { - PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224"); - goto out; - } - - idx = 0; - found_size = *size; - res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx); - if ( res ) { - PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224 inverted preamble"); - goto inv; - } - */ - - // PSK2 - psk1TOpsk2(dest, *size); - PrintAndLogEx(DEBUG, "DEBUG: detectindala Converting PSK1 -> PSK2"); - - idx = 0; - found_size = *size; - res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx); - if (res) { - PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 preamble"); - goto out; - } - - idx = 0; - found_size = *size; - res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx); - if (res) { - PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 preamble"); - goto out; - } - - idx = 0; - found_size = *size; - res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx); - if (res) { - PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 inverted preamble"); - goto inv; - } - - idx = 0; - found_size = *size; - res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx); - if (res) { - PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 inverted preamble"); - goto inv; - } - -inv: - if (res == 0) { - return -4; - } - - *invert ^= 1; - - if (*invert && idx > 0) { - for (size_t i = idx - 1; i < found_size + idx + 2; i++) { - dest[i] ^= 1; - } - } - - PrintAndLogEx(DEBUG, "DEBUG: Warning - Indala had to invert bits"); - -out: - - *size = found_size; - - //PrintAndLogEx(INFO, "DEBUG: detectindala RES = %d | %d | %d", res, found_size, idx); - - if (found_size != 224 && found_size != 64) { - PrintAndLogEx(INFO, "DEBUG: detectindala | %d", found_size); - return -5; - } - - // 224 formats are typically PSK2 (afaik 2017 Marshmellow) - // note loses 1 bit at beginning of transformation... - return (int) idx; - -} - -// this read is the "normal" read, which download lf signal and tries to demod here. -int CmdIndalaRead(const char *Cmd) { - lf_read(true, 30000); - return CmdIndalaDemod(Cmd); -} - // Indala 26 bit decode // by marshmellow // optional arguments - same as PSKDemod (clock & invert & maxerr) -int CmdIndalaDemod(const char *Cmd) { +static int CmdIndalaDemod(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (cmdp == 'h') return usage_lf_indala_demod(); @@ -283,7 +167,7 @@ int CmdIndalaDemod(const char *Cmd) { // returns false positives more often - but runs against more sets of samples // poor psk signal can be difficult to demod this approach might succeed when the other fails // but the other appears to currently be more accurate than this approach most of the time. -int CmdIndalaDemodAlt(const char *Cmd) { +static int CmdIndalaDemodAlt(const char *Cmd) { // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID int state = -1; int count = 0; @@ -477,7 +361,13 @@ int CmdIndalaDemodAlt(const char *Cmd) { return 1; } -int CmdIndalaSim(const char *Cmd) { +// this read is the "normal" read, which download lf signal and tries to demod here. +static int CmdIndalaRead(const char *Cmd) { + lf_read(true, 30000); + return CmdIndalaDemod(Cmd); +} + +static int CmdIndalaSim(const char *Cmd) { char cmdp = tolower(param_getchar(Cmd, 0)); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim(); @@ -522,7 +412,7 @@ int CmdIndalaSim(const char *Cmd) { } // iceman - needs refactoring -int CmdIndalaClone(const char *Cmd) { +static int CmdIndalaClone(const char *Cmd) { bool isLongUid = false; uint8_t data[7 * 4]; @@ -582,14 +472,128 @@ static command_t CommandTable[] = { {NULL, NULL, 0, NULL} }; +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return 0; +} + int CmdLFINDALA(const char *Cmd) { clearCommandBuffer(); CmdsParse(CommandTable, Cmd); return 0; } -int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return 0; +// redesigned by marshmellow adjusted from existing decode functions +// indala id decoding +int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert) { + + uint8_t preamble64_i[] = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; + uint8_t preamble224_i[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; + + size_t idx = 0; + size_t found_size = *size; + + // PSK1 + bool res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx); + if (res) { + PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64"); + goto out; + } + idx = 0; + found_size = *size; + res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx); + if (res) { + PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 64 inverted preamble"); + goto inv; + } + + /* + idx = 0; + found_size = *size; + res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx); + if ( res ) { + PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224"); + goto out; + } + + idx = 0; + found_size = *size; + res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx); + if ( res ) { + PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224 inverted preamble"); + goto inv; + } + */ + + // PSK2 + psk1TOpsk2(dest, *size); + PrintAndLogEx(DEBUG, "DEBUG: detectindala Converting PSK1 -> PSK2"); + + idx = 0; + found_size = *size; + res = preambleSearch(dest, preamble64, sizeof(preamble64), &found_size, &idx); + if (res) { + PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 preamble"); + goto out; + } + + idx = 0; + found_size = *size; + res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx); + if (res) { + PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 preamble"); + goto out; + } + + idx = 0; + found_size = *size; + res = preambleSearch(dest, preamble64_i, sizeof(preamble64_i), &found_size, &idx); + if (res) { + PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 64 inverted preamble"); + goto inv; + } + + idx = 0; + found_size = *size; + res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx); + if (res) { + PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK2 found 224 inverted preamble"); + goto inv; + } + +inv: + if (res == 0) { + return -4; + } + + *invert ^= 1; + + if (*invert && idx > 0) { + for (size_t i = idx - 1; i < found_size + idx + 2; i++) { + dest[i] ^= 1; + } + } + + PrintAndLogEx(DEBUG, "DEBUG: Warning - Indala had to invert bits"); + +out: + + *size = found_size; + + //PrintAndLogEx(INFO, "DEBUG: detectindala RES = %d | %d | %d", res, found_size, idx); + + if (found_size != 224 && found_size != 64) { + PrintAndLogEx(INFO, "DEBUG: detectindala | %d", found_size); + return -5; + } + + // 224 formats are typically PSK2 (afaik 2017 Marshmellow) + // note loses 1 bit at beginning of transformation... + return (int) idx; + +} + +int demodIndala(void) { + return CmdIndalaDemod(""); } diff --git a/client/cmdlfindala.h b/client/cmdlfindala.h index b107efdc7..1de894bf7 100644 --- a/client/cmdlfindala.h +++ b/client/cmdlfindala.h @@ -25,14 +25,10 @@ int CmdLFINDALA(const char *Cmd); -int CmdIndalaDemod(const char *Cmd); -int CmdIndalaDemodAlt(const char *Cmd); -int CmdIndalaRead(const char *Cmd); -int CmdIndalaClone(const char *Cmd); -int CmdIndalaSim(const char *Cmd); - +int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert); int detectIndala26(uint8_t *bitStream, size_t *size, uint8_t *invert); int detectIndala64(uint8_t *bitStream, size_t *size, uint8_t *invert); int detectIndala224(uint8_t *bitStream, size_t *size, uint8_t *invert); +int demodIndala(void); #endif diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 9db05ef99..92f954511 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -11,7 +11,7 @@ #include "cmdlfio.h" static int CmdHelp(const char *Cmd); - +/* static int usage_lf_io_read(void) { PrintAndLogEx(NORMAL, "Enables IOProx compatible reader mode printing details of scanned tags."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); @@ -27,7 +27,7 @@ static int usage_lf_io_read(void) { PrintAndLogEx(NORMAL, " lf io read 1"); return 0; } - +*/ static int usage_lf_io_sim(void) { PrintAndLogEx(NORMAL, "Enables simulation of IOProx card with specified facility-code and card number."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); @@ -60,15 +60,10 @@ static int usage_lf_io_clone(void) { PrintAndLogEx(NORMAL, " lf io clone 26 101 1337"); return 0; } - -// this read is the "normal" read, which download lf signal and tries to demod here. -int CmdIOProxRead(const char *Cmd) { - lf_read(true, 12000); - return CmdIOProxDemod(Cmd); -} +/* // this read loops on device side. // uses the demod in lfops.c -int CmdIOProxRead_device(const char *Cmd) { +static int CmdIOProxRead_device(const char *Cmd) { if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_io_read(); int findone = (Cmd[0] == '1') ? 1 : 0; UsbCommand c = {CMD_IO_DEMOD_FSK, {findone, 0, 0}, {{0}}}; @@ -76,11 +71,11 @@ int CmdIOProxRead_device(const char *Cmd) { SendCommand(&c); return 0; } - +*/ //by marshmellow //IO-Prox demod - FSK RF/64 with preamble of 000000001 //print ioprox ID and some format details -int CmdIOProxDemod(const char *Cmd) { +static int CmdIOProxDemod(const char *Cmd) { (void)Cmd; // Cmd is not used so far int retval = 0; int idx = 0; @@ -177,6 +172,124 @@ int CmdIOProxDemod(const char *Cmd) { return retval; } +// this read is the "normal" read, which download lf signal and tries to demod here. +static int CmdIOProxRead(const char *Cmd) { + lf_read(true, 12000); + return CmdIOProxDemod(Cmd); +} +static int CmdIOProxSim(const char *Cmd) { + uint16_t cn = 0; + uint8_t version = 0, fc = 0; + uint8_t bits[64]; + size_t size = sizeof(bits); + memset(bits, 0x00, size); + + char cmdp = tolower(param_getchar(Cmd, 0)); + if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_sim(); + + version = param_get8(Cmd, 0); + fc = param_get8(Cmd, 1); + cn = param_get32ex(Cmd, 2, 0, 10); + + if (!version || !fc || !cn) return usage_lf_io_sim(); + + if ((cn & 0xFFFF) != cn) { + cn &= 0xFFFF; + PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn); + } + + // clock 64, FSK2a fcHIGH 10 | fcLOW 8 + uint8_t clk = 64, invert = 1, high = 10, low = 8; + uint16_t arg1, arg2; + arg1 = high << 8 | low; + arg2 = invert << 8 | clk; + + PrintAndLogEx(SUCCESS, "Simulating IOProx version: %u FC: %u; CN: %u\n", version, fc, cn); + PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command"); + + if (!getIOProxBits(version, fc, cn, bits)) { + PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + return 1; + } + // IOProx uses: fcHigh: 10, fcLow: 8, clk: 64, invert: 1 + // arg1 --- fcHigh<<8 + fcLow + // arg2 --- Invert and clk setting + // size --- 64 bits == 8 bytes + UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}, {{0}}}; + memcpy(c.d.asBytes, bits, size); + clearCommandBuffer(); + SendCommand(&c); + return 0; +} + +static int CmdIOProxClone(const char *Cmd) { + + uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; + uint16_t cn = 0; + uint8_t version = 0, fc = 0; + uint8_t bits[64]; + memset(bits, 0, sizeof(bits)); + + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_io_clone(); + + version = param_get8(Cmd, 0); + fc = param_get8(Cmd, 1); + cn = param_get32ex(Cmd, 2, 0, 10); + + if (!version || !fc || !cn) return usage_lf_io_clone(); + + if ((cn & 0xFFFF) != cn) { + cn &= 0xFFFF; + PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn); + } + + if (!getIOProxBits(version, fc, cn, bits)) { + PrintAndLogEx(WARNING, "Error with tag bitstream generation."); + return 1; + } + + if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q') + blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT; + + blocks[1] = bytebits_to_byte(bits, 32); + blocks[2] = bytebits_to_byte(bits + 32, 32); + + PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn); + print_blocks(blocks, 3); + + //UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}, {{0}}}; + UsbCommand c = {CMD_IO_CLONE_TAG, {blocks[1], blocks[2], 0}, {{0}}}; + clearCommandBuffer(); + SendCommand(&c); + return 0; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, 1, "this help"}, + {"demod", CmdIOProxDemod, 1, "demodulate an IOProx tag from the GraphBuffer"}, + {"read", CmdIOProxRead, 1, "attempt to read and extract tag data"}, + {"clone", CmdIOProxClone, 0, "clone IOProx to T55x7"}, + {"sim", CmdIOProxSim, 0, "simulate IOProx tag"}, + {NULL, NULL, 0, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return 0; +} + +int CmdLFIO(const char *Cmd) { + clearCommandBuffer(); + CmdsParse(CommandTable, Cmd); + return 0; +} + +int demodIOProx(void) { + return CmdIOProxDemod(""); +} + //Index map //0 10 20 30 40 50 60 //| | | | | | | @@ -244,111 +357,3 @@ int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits) { return 1; } -int CmdIOProxSim(const char *Cmd) { - uint16_t cn = 0; - uint8_t version = 0, fc = 0; - uint8_t bits[64]; - size_t size = sizeof(bits); - memset(bits, 0x00, size); - - char cmdp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_io_sim(); - - version = param_get8(Cmd, 0); - fc = param_get8(Cmd, 1); - cn = param_get32ex(Cmd, 2, 0, 10); - - if (!version || !fc || !cn) return usage_lf_io_sim(); - - if ((cn & 0xFFFF) != cn) { - cn &= 0xFFFF; - PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn); - } - - // clock 64, FSK2a fcHIGH 10 | fcLOW 8 - uint8_t clk = 64, invert = 1, high = 10, low = 8; - uint16_t arg1, arg2; - arg1 = high << 8 | low; - arg2 = invert << 8 | clk; - - PrintAndLogEx(SUCCESS, "Simulating IOProx version: %u FC: %u; CN: %u\n", version, fc, cn); - PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command"); - - if (!getIOProxBits(version, fc, cn, bits)) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); - return 1; - } - // IOProx uses: fcHigh: 10, fcLow: 8, clk: 64, invert: 1 - // arg1 --- fcHigh<<8 + fcLow - // arg2 --- Invert and clk setting - // size --- 64 bits == 8 bytes - UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}, {{0}}}; - memcpy(c.d.asBytes, bits, size); - clearCommandBuffer(); - SendCommand(&c); - return 0; -} - -int CmdIOProxClone(const char *Cmd) { - - uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; - uint16_t cn = 0; - uint8_t version = 0, fc = 0; - uint8_t bits[64]; - memset(bits, 0, sizeof(bits)); - - char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_io_clone(); - - version = param_get8(Cmd, 0); - fc = param_get8(Cmd, 1); - cn = param_get32ex(Cmd, 2, 0, 10); - - if (!version || !fc || !cn) return usage_lf_io_clone(); - - if ((cn & 0xFFFF) != cn) { - cn &= 0xFFFF; - PrintAndLogEx(INFO, "Card Number Truncated to 16-bits (IOProx): %u", cn); - } - - if (!getIOProxBits(version, fc, cn, bits)) { - PrintAndLogEx(WARNING, "Error with tag bitstream generation."); - return 1; - } - - if (param_getchar(Cmd, 3) == 'Q' || param_getchar(Cmd, 3) == 'q') - blocks[0] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT; - - blocks[1] = bytebits_to_byte(bits, 32); - blocks[2] = bytebits_to_byte(bits + 32, 32); - - PrintAndLogEx(INFO, "Preparing to clone IOProx to T55x7 with Version: %u FC: %u, CN: %u", version, fc, cn); - print_blocks(blocks, 3); - - //UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}, {{0}}}; - UsbCommand c = {CMD_IO_CLONE_TAG, {blocks[1], blocks[2], 0}, {{0}}}; - clearCommandBuffer(); - SendCommand(&c); - return 0; -} - -static command_t CommandTable[] = { - {"help", CmdHelp, 1, "this help"}, - {"demod", CmdIOProxDemod, 1, "demodulate an IOProx tag from the GraphBuffer"}, - {"read", CmdIOProxRead, 1, "attempt to read and extract tag data"}, - {"clone", CmdIOProxClone, 0, "clone IOProx to T55x7"}, - {"sim", CmdIOProxSim, 0, "simulate IOProx tag"}, - {NULL, NULL, 0, NULL} -}; - -int CmdLFIO(const char *Cmd) { - clearCommandBuffer(); - CmdsParse(CommandTable, Cmd); - return 0; -} - -int CmdHelp(const char *Cmd) { - (void)Cmd; // Cmd is not used so far - CmdsHelp(CommandTable); - return 0; -} diff --git a/client/cmdlfio.h b/client/cmdlfio.h index ecb442ff7..39abbc767 100644 --- a/client/cmdlfio.h +++ b/client/cmdlfio.h @@ -17,11 +17,8 @@ #include "cmddata.h" int CmdLFIO(const char *Cmd); -int CmdIOProxDemod(const char *Cmd); -int CmdIOProxRead(const char *Cmd); -int CmdIOProxSim(const char *Cmd); -int CmdIOProxClone(const char *Cmd); +int demodIOProx(void); int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits); #endif