X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/6658905f18a1eebc148836f26c731dea9c1377dc..d722c4ce7801988cec69aad84a3fe1386d80cd97:/winsrc/command.cpp diff --git a/winsrc/command.cpp b/winsrc/command.cpp index 1da1e1c2..4b18d0a7 100644 --- a/winsrc/command.cpp +++ b/winsrc/command.cpp @@ -42,6 +42,14 @@ static void GetFromBigBuf(BYTE *dest, int bytes) } } +static void CmdReset(char *str) +{ + UsbCommand c; + c.cmd = CMD_HARDWARE_RESET; + SendCommand(&c, FALSE); +} + + static void CmdQuit(char *str) { exit(0); @@ -75,6 +83,19 @@ static void CmdHi14read(char *str) c.ext1 = atoi(str); SendCommand(&c, FALSE); } + + +/* New command to read the contents of a SRI512 tag + * SRI512 tags are ISO14443-B modulated memory tags, + * this command just dumps the contents of the memory/ + */ +static void CmdSri512read(char *str) +{ + UsbCommand c; + c.cmd = CMD_READ_SRI512_TAG; + c.ext1 = atoi(str); + SendCommand(&c, FALSE); +} // ## New command static void CmdHi14areader(char *str) @@ -792,7 +813,7 @@ static void CmdHi15demod(char *str) { // The sampling rate is 106.353 ksps/s, for T = 18.8 us - // SOF defined as + // SOF defined as // 1) Unmodulated time of 56.64us // 2) 24 pulses of 423.75khz // 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz) @@ -820,7 +841,7 @@ static void CmdHi15demod(char *str) 1, 1, 1, 1 }; - // EOF defined as + // EOF defined as // 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us) // 2) 24 pulses of 423.75khz // 3) Unmodulated time of 56.64us @@ -1302,6 +1323,146 @@ static void CmdVchdemod(char *str) } } +static void CmdIndalademod(char *str) +{ + // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID + + int state = -1; + int count = 0; + int i, j; + // worst case with GraphTraceLen=64000 is < 4096 + // under normal conditions it's < 2048 + BYTE rawbits[4096]; + int rawbit = 0; + int worst = 0, worstPos = 0; + PrintToScrollback("Expecting a bit less than %d raw bits", GraphTraceLen/32); + for(i = 0; i < GraphTraceLen-1; i += 2) { + count+=1; + if((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) { + if (state == 0) { + for(j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 0; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 1; + count=0; + } else if((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) { + if (state == 1) { + for(j = 0; j < count - 8; j += 16) { + rawbits[rawbit++] = 1; + } + if ((abs(count - j)) > worst) { + worst = abs(count - j); + worstPos = i; + } + } + state = 0; + count=0; + } + } + PrintToScrollback("Recovered %d raw bits", rawbit); + PrintToScrollback("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); + + // Finding the start of a UID + int uidlen, long_wait; + if(strcmp(str, "224") == 0) { + uidlen=224; + long_wait=30; + } else { + uidlen=64; + long_wait=29; + } + int start; + int first = 0; + for(start = 0; start <= rawbit - uidlen; start++) { + first = rawbits[start]; + for(i = start; i < start + long_wait; i++) { + if(rawbits[i] != first) { + break; + } + } + if(i == (start + long_wait)) { + break; + } + } + if(start == rawbit - uidlen + 1) { + PrintToScrollback("nothing to wait for"); + return; + } + + // Inverting signal if needed + if(first == 1) { + for(i = start; i < rawbit; i++) { + rawbits[i] = !rawbits[i]; + } + } + + // Dumping UID + BYTE bits[224]; + char showbits[225]; + showbits[uidlen]='\0'; + int bit; + i = start; + int times = 0; + if(uidlen > rawbit) { + PrintToScrollback("Warning: not enough raw bits to get a full UID"); + for(bit = 0; bit < rawbit; bit++) { + bits[bit] = rawbits[i++]; + // As we cannot know the parity, let's use "." and "/" + showbits[bit] = '.' + bits[bit]; + } + showbits[bit+1]='\0'; + PrintToScrollback("Partial UID=%s", showbits); + return; + } else { + for(bit = 0; bit < uidlen; bit++) { + bits[bit] = rawbits[i++]; + showbits[bit] = '0' + bits[bit]; + } + times = 1; + } + PrintToScrollback("UID=%s", showbits); + + // Checking UID against next occurences + for(; i + uidlen <= rawbit;) { + int failed = 0; + for(bit = 0; bit < uidlen; bit++) { + if(bits[bit] != rawbits[i++]) { + failed = 1; + break; + } + } + if (failed == 1) { + break; + } + times += 1; + } + PrintToScrollback("Occurences: %d (expected %d)", times, (rawbit - start) / uidlen); + + // Remodulating for tag cloning + GraphTraceLen = 32*uidlen; + i = 0; + int phase = 0; + for(bit = 0; bit < uidlen; bit++) { + if(bits[bit] == 0) { + phase = 0; + } else { + phase = 1; + } + int j; + for(j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } + + RepaintGraphWindow(); +} + static void CmdFlexdemod(char *str) { int i; @@ -1458,26 +1619,31 @@ static void Cmdaskdemod(char *str) { * routine, feel free to improve... * * 1st argument: clock rate (as number of samples per clock rate) + * Typical values can be 64, 32, 128... */ static void Cmdmanchesterdemod(char *str) { int i; int clock; - int grouping=16; int lastval; int lc = 0; int bitidx = 0; - int bitidx2; + int bit2idx = 0; sscanf(str, "%i", &clock); int tolerance = clock/4; - /* Holds the decoded bitstream. */ - int BitStream[MAX_GRAPH_TRACE_LEN*2]; - int BitStream2[MAX_GRAPH_TRACE_LEN]; + /* Holds the decoded bitstream: each clock period contains 2 bits */ + /* later simplified to 1 bit after manchester decoding. */ + /* Add 10 bits to allow for noisy / uncertain traces without aborting */ + /* int BitStream[GraphTraceLen*2/clock+10]; */ + + /* But it does not work if compiling on WIndows: therefore we just allocate a */ + /* large array */ + int BitStream[MAX_GRAPH_TRACE_LEN]; /* Detect first transition */ - /* Lo-Hi (arbitrary) */ + /* Lo-Hi (arbitrary) */ for(i=1;i (GraphTraceLen*2/clock+8) ) { + PrintToScrollback("Error: the clock you gave is probably wrong, aborting."); + return; + } // Then switch depending on lc length: // Tolerance is 1/4 of clock rate (arbitrary) - if ((lc-clock/2) < tolerance) { - // Short pulse + if (abs(lc-clock/2) < tolerance) { + // Short pulse : either "1" or "0" BitStream[bitidx++]=GraphBuffer[i-1]; - } else if ((lc-clock) < tolerance) { - // Long pulse + } else if (abs(lc-clock) < tolerance) { + // Long pulse: either "11" or "00" BitStream[bitidx++]=GraphBuffer[i-1]; BitStream[bitidx++]=GraphBuffer[i-1]; } else { // Error - PrintToScrollback("Warning: Manchester decode error for pulse width detection."); + PrintToScrollback("Warning: Manchester decode error for pulse width detection."); PrintToScrollback("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); } } } // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream - for (bitidx2 = 0; bitidx2255)) { + PrintToScrollback("divisor must be between 19 and 255"); + } else { + SendCommand(&c, FALSE); + PrintToScrollback("Divisor set, expected freq=%dHz", 12000000/(c.ext1+1)); + } +} +static void CmdSweepLF(char *str) +{ + UsbCommand c; + c.cmd = CMD_SWEEP_LF; + SendCommand(&c, FALSE); +} + + typedef void HandlerFunction(char *cmdline); static struct { - char *name; - HandlerFunction *handler; - char *docString; + char *name; + HandlerFunction *handler; + int offline; // 1 if the command can be used when in offline mode + char *docString; } CommandTable[] = { - "tune", CmdTune, "measure antenna tuning", - "tiread", CmdTiread, "read a TI-type 134 kHz tag", - "tibits", CmdTibits, "get raw bits for TI-type LF tag", - "tidemod", CmdTidemod, "demod raw bits for TI-type LF tag", - "vchdemod", CmdVchdemod, "demod samples for VeriChip", - "plot", CmdPlot, "show graph window", - "hide", CmdHide, "hide graph window", - "losim", CmdLosim, "simulate LF tag", - "loread", CmdLoread, "read (125/134 kHz) LF ID-only tag", - "losamples", CmdLosamples, "get raw samples for LF tag", - "hisamples", CmdHisamples, "get raw samples for HF tag", - "hisampless", CmdHisampless, "get signed raw samples, HF tag", - "hisamplest", CmdHi14readt, "get samples HF, for testing", - "higet", CmdHi14read_sim, "get samples HF, 'analog'", - "bitsamples", CmdBitsamples, "get raw samples as bitstring", - "hexsamples", CmdHexsamples, "dump big buffer as hex bytes", - "hi15read", CmdHi15read, "read HF tag (ISO 15693)", - "hi15reader", CmdHi15reader, "act like an ISO15693 reader", // new command greg - "hi15sim", CmdHi15tag, "fake an ISO15693 tag", // new command greg - "hi14read", CmdHi14read, "read HF tag (ISO 14443)", - "hi14areader", CmdHi14areader, "act like an ISO14443 Type A reader", // ## New reader command - "hi15demod", CmdHi15demod, "demod ISO15693 from tag", - "hi14bdemod", CmdHi14bdemod, "demod ISO14443 Type B from tag", - "autocorr", CmdAutoCorr, "autocorrelation over window", - "norm", CmdNorm, "normalize max/min to +/-500", - "dec", CmdDec, "decimate", - "hpf", CmdHpf, "remove DC offset from trace", - "zerocrossings", CmdZerocrossings, "count time between zero-crossings", - "ltrim", CmdLtrim, "trim from left of trace", - "scale", CmdScale, "set cursor display scale", - "flexdemod", CmdFlexdemod, "demod samples for FlexPass", - "save", CmdSave, "save trace (from graph window)", - "load", CmdLoad, "load trace (to graph window", - "hisimlisten", CmdHisimlisten, "get HF samples as fake tag", - "hi14sim", CmdHi14sim, "fake ISO 14443 tag", - "hi14asim", CmdHi14asim, "fake ISO 14443a tag", // ## Simulate 14443a tag - "hi14snoop", CmdHi14snoop, "eavesdrop ISO 14443", - "hi14asnoop", CmdHi14asnoop, "eavesdrop ISO 14443 Type A", // ## New snoop command - "hi14list", CmdHi14list, "list ISO 14443 history", - "hi14alist", CmdHi14alist, "list ISO 14443a history", // ## New list command - "hiddemod", CmdHiddemod, "HID Prox Card II (not optimal)", - "hidfskdemod", CmdHIDdemodFSK, "HID FSK demodulator", - "askdemod", Cmdaskdemod, "Attempt to demodulate simple ASK tags", - "hidsimtag", CmdHIDsimTAG, "HID tag simulator", - "mandemod", Cmdmanchesterdemod, "Try a Manchester demodulation on a binary stream", - "fpgaoff", CmdFPGAOff, "set FPGA off", // ## FPGA Control - "lcdreset", CmdLcdReset, "Hardware reset LCD", - "lcd", CmdLcd, "Send command/data to LCD", - "test", CmdTest, "Placeholder command for testing new code", - "quit", CmdQuit, "quit program" + "tune", CmdTune,0, "measure antenna tuning", + "tiread", CmdTiread,0, "read a TI-type 134 kHz tag", + "tibits", CmdTibits,0, "get raw bits for TI-type LF tag", + "tidemod", CmdTidemod,0, "demod raw bits for TI-type LF tag", + "vchdemod", CmdVchdemod,0, "demod samples for VeriChip", + "plot", CmdPlot,1, "show graph window", + "hide", CmdHide,1, "hide graph window", + "losim", CmdLosim,0, "simulate LF tag", + "loread", CmdLoread,0, "read (125/134 kHz) LF ID-only tag", + "losamples", CmdLosamples,0, "get raw samples for LF tag", + "hisamples", CmdHisamples,0, "get raw samples for HF tag", + "hisampless", CmdHisampless,0, "get signed raw samples, HF tag", + "hisamplest", CmdHi14readt,0, "get samples HF, for testing", + "higet", CmdHi14read_sim,0, "get samples HF, 'analog'", + "bitsamples", CmdBitsamples,0, "get raw samples as bitstring", + "hexsamples", CmdHexsamples,0, "dump big buffer as hex bytes", + "hi15read", CmdHi15read,0, "read HF tag (ISO 15693)", + "hi15reader", CmdHi15reader,0, "act like an ISO15693 reader", // new command greg + "hi15sim", CmdHi15tag,0, "fake an ISO15693 tag", // new command greg + "hi14read", CmdHi14read,0, "read HF tag (ISO 14443)", + "sri512read", CmdSri512read,0, "Read contents of a SRI512 tag", + "hi14areader", CmdHi14areader,0, "act like an ISO14443 Type A reader", // ## New reader command + "hi15demod", CmdHi15demod,1, "demod ISO15693 from tag", + "hi14bdemod", CmdHi14bdemod,1, "demod ISO14443 Type B from tag", + "autocorr", CmdAutoCorr,1, "autocorrelation over window", + "norm", CmdNorm,1, "normalize max/min to +/-500", + "dec", CmdDec,1, "decimate", + "hpf", CmdHpf,1, "remove DC offset from trace", + "zerocrossings", CmdZerocrossings,1, "count time between zero-crossings", + "ltrim", CmdLtrim,1, "trim from left of trace", + "scale", CmdScale,1, "set cursor display scale", + "flexdemod", CmdFlexdemod,1, "demod samples for FlexPass", + "save", CmdSave,1, "save trace (from graph window)", + "load", CmdLoad,1, "load trace (to graph window", + "hisimlisten", CmdHisimlisten,0, "get HF samples as fake tag", + "hi14sim", CmdHi14sim,0, "fake ISO 14443 tag", + "hi14asim", CmdHi14asim,0, "fake ISO 14443a tag", // ## Simulate 14443a tag + "hi14snoop", CmdHi14snoop,0, "eavesdrop ISO 14443", + "hi14asnoop", CmdHi14asnoop,0, "eavesdrop ISO 14443 Type A", // ## New snoop command + "hi14list", CmdHi14list,0, "list ISO 14443 history", + "hi14alist", CmdHi14alist,0, "list ISO 14443a history", // ## New list command + "hiddemod", CmdHiddemod,1, "HID Prox Card II (not optimal)", + "hidfskdemod", CmdHIDdemodFSK,0, "HID FSK demodulator", + "indalademod", CmdIndalademod,0, "demod samples for Indala", + "askdemod", Cmdaskdemod,1, "Attempt to demodulate simple ASK tags", + "hidsimtag", CmdHIDsimTAG,0, "HID tag simulator", + "mandemod", Cmdmanchesterdemod,1, "Try a Manchester demodulation on a binary stream", + "fpgaoff", CmdFPGAOff,0, "set FPGA off", // ## FPGA Control + "lcdreset", CmdLcdReset,0, "Hardware reset LCD", + "lcd", CmdLcd,0, "Send command/data to LCD", + "setlfdivisor", CmdSetDivisor,0, "Drive LF antenna at 12Mhz/(divisor+1)", + "sweeplf", CmdSweepLF,0, "Sweep through LF freq range and store results in buffer", + "reset", CmdReset,0, "Reset the Proxmark3", + "quit", CmdQuit,1, "quit program" }; + //----------------------------------------------------------------------------- // Entry point into our code: called whenever the user types a command and // then presses Enter, which the full command line that they typed. @@ -1737,8 +1944,10 @@ void CommandReceived(char *cmd) PrintToScrollback("> %s", cmd); if(strcmp(cmd, "help")==0) { + if (offline) PrintToScrollback("Operating in OFFLINE mode (no device connected)"); PrintToScrollback("\r\nAvailable commands:"); for(i = 0; i < sizeof(CommandTable) / sizeof(CommandTable[0]); i++) { + if (offline && (CommandTable[i].offline==0)) continue; char line[256]; memset(line, ' ', sizeof(line)); strcpy(line+2, CommandTable[i].name); @@ -1760,6 +1969,10 @@ void CommandReceived(char *cmd) while(*cmd == ' ') { cmd++; } + if (offline && (CommandTable[i].offline==0)) { + PrintToScrollback("Offline mode, cannot use this command."); + return; + } (CommandTable[i].handler)(cmd); return; }