X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/6658905f18a1eebc148836f26c731dea9c1377dc..30f2a7d38fd35b2427a7eb42e1cd75fb1105f927:/winsrc/command.cpp diff --git a/winsrc/command.cpp b/winsrc/command.cpp index 1da1e1c2..f947f45c 100644 --- a/winsrc/command.cpp +++ b/winsrc/command.cpp @@ -1302,6 +1302,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 +1598,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 { @@ -1510,39 +1661,41 @@ static void Cmdmanchesterdemod(char *str) { } // 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); @@ -1705,6 +1884,7 @@ static struct { "ltrim", CmdLtrim, "trim from left of trace", "scale", CmdScale, "set cursor display scale", "flexdemod", CmdFlexdemod, "demod samples for FlexPass", + "indalademod", CmdIndalademod, "demod samples for Indala", "save", CmdSave, "save trace (from graph window)", "load", CmdLoad, "load trace (to graph window", "hisimlisten", CmdHisimlisten, "get HF samples as fake tag", @@ -1723,6 +1903,8 @@ static struct { "lcdreset", CmdLcdReset, "Hardware reset LCD", "lcd", CmdLcd, "Send command/data to LCD", "test", CmdTest, "Placeholder command for testing new code", + "setlfdivisor", CmdSetDivisor, "Drive LF antenna at 12Mhz/(divisor+1)", + "sweeplf", CmdSweepLF, "Sweep through LF freq range and store results in buffer", "quit", CmdQuit, "quit program" };