X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/e7aee94e6a3f4f7ef38a4d06b837cf6141e731b9..24fe4dffb49ca5c50983c54f1b1d51028c06390d:/winsrc/command.cpp diff --git a/winsrc/command.cpp b/winsrc/command.cpp index 14974528..e94c234c 100644 --- a/winsrc/command.cpp +++ b/winsrc/command.cpp @@ -12,6 +12,7 @@ #include "prox.h" #include "../common/iso14443_crc.c" +#include "../common/crc16.c" #define arraylen(x) (sizeof(x)/sizeof((x)[0])) #define BIT(x) GraphBuffer[x * clock] @@ -206,6 +207,13 @@ static void CmdHi14asnoop(char *str) SendCommand(&c, FALSE); } +static void CmdLegicRfSim(char *str) +{ + UsbCommand c; + c.cmd = CMD_SIMULATE_TAG_LEGIC_RF; + SendCommand(&c, FALSE); +} + static void CmdFPGAOff(char *str) // ## FPGA Control { UsbCommand c; @@ -272,9 +280,9 @@ static void CmdEM410xwatch(char *str) * pattern of 320 cycles each (32/32/128/64/64)). * * Note that this data may or may not be the UID. It is whatever data - * is stored in the blocks defined in the control word First and Last + * is stored in the blocks defined in the control word First and Last * Word Read values. UID is stored in block 32. - */ + */ static void CmdEM4x50read(char *str) { int i, j, startblock, clock, skip, block, start, end, low, high; @@ -288,7 +296,7 @@ static void CmdEM4x50read(char *str) /* first get high and low values */ for (i = 0; i < GraphTraceLen; i++) { - if (GraphBuffer[i] > high) + if (GraphBuffer[i] > high) high = GraphBuffer[i]; else if (GraphBuffer[i] < low) low = GraphBuffer[i]; @@ -300,17 +308,19 @@ static void CmdEM4x50read(char *str) while(i < GraphTraceLen) { // measure from low to low - while(GraphBuffer[i] > low) + while((GraphBuffer[i] > low) && (i low) + while((GraphBuffer[i] > low) && (i(MAX_GRAPH_TRACE_LEN/64)) { + break; + } tmpbuff[j++]= i - start; } - /* look for data start - should be 2 pairs of LW (pulses of 192,128) */ start= -1; skip= 0; @@ -330,7 +340,7 @@ static void CmdEM4x50read(char *str) /* skip over the remainder of the LW */ skip += tmpbuff[i+1]+tmpbuff[i+2]; - while(GraphBuffer[skip] > low) + while(skip < MAX_GRAPH_TRACE_LEN && GraphBuffer[skip] > low) ++skip; skip += 8; @@ -457,14 +467,14 @@ static void CmdEM410xread(char *str) if (hithigh && hitlow) break; } - + /* If we didn't hit both high and low peaks, we had a bit transition */ if (!hithigh || !hitlow) bit ^= 1; - + BitStream[bit2idx++] = bit; } - + retest: /* We go till 5 before the graph ends because we'll get that far below */ for (i = 1; i < bit2idx - 5; i++) @@ -539,7 +549,7 @@ retest: header = 0; } } - + /* if we've already retested after flipping bits, return */ if (retested++) return; @@ -660,6 +670,15 @@ static void CmdLosim(char *str) SendCommand(&c, FALSE); } +static void CmdLosimBidir(char *str) +{ + UsbCommand c; + c.cmd = CMD_LF_SIMULATE_BIDIR; + c.ext1 = 47; /* Set ADC to twice the carrier for a slight supersampling */ + c.ext2 = 384; + SendCommand(&c, FALSE); +} + static void CmdLoread(char *str) { UsbCommand c; @@ -698,7 +717,7 @@ static void CmdLoCommandRead(char *str) static char dummy[3]; dummy[0]= ' '; - + UsbCommand c; c.cmd = CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K; sscanf(str, "%i %i %i %s %s", &c.ext1, &c.ext2, &c.ext3, (char *) &c.d.asBytes,(char *) &dummy+1); @@ -795,7 +814,6 @@ static void CmdHisamples(char *str) RepaintGraphWindow(); } - static int CmdHisamplest(char *str, int nrlow) { int cnt = 0; @@ -1395,44 +1413,150 @@ static void CmdHi15demod(char *str) PrintToScrollback("CRC=%04x", Iso15693Crc(outBuf, k-2)); } -static void CmdTiread(char *str) +static void CmdFSKdemod(char *cmdline) { - UsbCommand c; - c.cmd = CMD_ACQUIRE_RAW_BITS_TI_TYPE; - SendCommand(&c, FALSE); -} + static const int LowTone[] = { + 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, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, -1, -1, -1, -1, -1 + }; + static const int HighTone[] = { + 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, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, + 1, 1, 1, 1, -1, -1, -1, -1, -1, + }; -static void CmdTibits(char *str) -{ - int cnt = 0; - int i; - for(i = 0; i < 1536; i += 12) { - UsbCommand c; - c.cmd = CMD_DOWNLOAD_RAW_BITS_TI_TYPE; - c.ext1 = i; - SendCommand(&c, FALSE); - ReceiveCommand(&c); - if(c.cmd != CMD_DOWNLOADED_RAW_BITS_TI_TYPE) { - PrintToScrollback("bad resp"); - return; + int lowLen = sizeof(LowTone)/sizeof(int); + int highLen = sizeof(HighTone)/sizeof(int); + int convLen = (highLen>lowLen)?highLen:lowLen; + DWORD hi = 0, lo = 0; + + int i, j; + int minMark=0, maxMark=0; + + for(i = 0; i < GraphTraceLen - convLen; i++) { + int lowSum = 0, highSum = 0; + + for(j = 0; j < lowLen; j++) { + lowSum += LowTone[j]*GraphBuffer[i+j]; + } + for(j = 0; j < highLen; j++) { + highSum += HighTone[j]*GraphBuffer[i+j]; } + lowSum = abs((100*lowSum) / lowLen); + highSum = abs((100*highSum) / highLen); + GraphBuffer[i] = (highSum << 16) | lowSum; + } + + for(i = 0; i < GraphTraceLen - convLen - 16; i++) { int j; - for(j = 0; j < 12; j++) { - int k; - for(k = 31; k >= 0; k--) { - if(c.d.asDwords[j] & (1 << k)) { - GraphBuffer[cnt++] = 1; - } else { - GraphBuffer[cnt++] = -1; - } - } + int lowTot = 0, highTot = 0; + // 10 and 8 are f_s divided by f_l and f_h, rounded + for(j = 0; j < 10; j++) { + lowTot += (GraphBuffer[i+j] & 0xffff); + } + for(j = 0; j < 8; j++) { + highTot += (GraphBuffer[i+j] >> 16); } + GraphBuffer[i] = lowTot - highTot; + if (GraphBuffer[i]>maxMark) maxMark=GraphBuffer[i]; + if (GraphBuffer[i] max) { + max = dec; + maxPos = i; + } + } + + // place start of bit sync marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos+1] = minMark; + + maxPos += j; + + // place end of bit sync marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos+1] = minMark; + + PrintToScrollback("actual data bits start at sample %d", maxPos); + PrintToScrollback("length %d/%d", highLen, lowLen); + + BYTE bits[46]; + bits[sizeof(bits)-1] = '\0'; + + // find bit pairs and manchester decode them + for(i = 0; i < arraylen(bits)-1; i++) { + int dec = 0; + for(j = 0; j < lowLen; j++) { + dec -= GraphBuffer[maxPos+j]; + } + for(; j < lowLen + highLen; j++) { + dec += GraphBuffer[maxPos+j]; + } + maxPos += j; + // place inter bit marker in graph + GraphBuffer[maxPos] = maxMark; + GraphBuffer[maxPos+1] = minMark; + + // hi and lo form a 64 bit pair + hi = (hi<<1)|(lo>>31); + lo = (lo<<1); + // store decoded bit as binary (in hi/lo) and text (in bits[]) + if(dec<0) { + bits[i] = '1'; + lo|=1; + } else { + bits[i] = '0'; + } + } + PrintToScrollback("bits: '%s'", bits); + PrintToScrollback("hex: %08x %08x", hi, lo); +} + +// read a TI tag and return its ID +static void CmdTIRead(char *str) +{ + UsbCommand c; + c.cmd = CMD_READ_TI_TYPE; + SendCommand(&c, FALSE); } -static void CmdTidemod(char *cmdline) +// write new data to a r/w TI tag +static void CmdTIWrite(char *str) +{ + UsbCommand c; + int res=0; + + c.cmd = CMD_WRITE_TI_TYPE; + res = sscanf(str, "0x%x 0x%x 0x%x ", &c.ext1, &c.ext2, &c.ext3); + if (res == 2) c.ext3=0; + if (res<2) + PrintToScrollback("Please specify the data as two hex strings, optionally the CRC as a third"); + else + SendCommand(&c, FALSE); +} + +static void CmdTIDemod(char *cmdline) { /* MATLAB as follows: f_s = 2000000; % sampling frequency @@ -1448,46 +1572,57 @@ h = 2*pi*ones(1, floor(f_s*T_h))*(f_h/f_s); l = sign(sin(cumsum(l))); h = sign(sin(cumsum(h))); */ - static const int LowTone[] = { - 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, -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, -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, -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, 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, 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, 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, -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, - }; - static const int HighTone[] = { - 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, 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, 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, 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, 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, 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, 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, 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, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, - }; - int convLen = max(arraylen(HighTone), arraylen(LowTone)); +// 2M*16/134.2k = 238 + static const int LowTone[] = { + 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, -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, -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, -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, 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, 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, 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, -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 + }; +// 2M*16/123.2k = 260 + static const int HighTone[] = { + 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, + 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, + 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, 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, 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, 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, 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, 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, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1 + }; + int lowLen = sizeof(LowTone)/sizeof(int); + int highLen = sizeof(HighTone)/sizeof(int); + int convLen = (highLen>lowLen)?highLen:lowLen; + WORD crc; + int i, j, TagType; + int lowSum = 0, highSum = 0;; + int lowTot = 0, highTot = 0; - int i; for(i = 0; i < GraphTraceLen - convLen; i++) { - int j; - int lowSum = 0, highSum = 0;; - int lowLen = arraylen(LowTone); - int highLen = arraylen(HighTone); + lowSum = 0; + highSum = 0;; for(j = 0; j < lowLen; j++) { lowSum += LowTone[j]*GraphBuffer[i+j]; @@ -1497,12 +1632,15 @@ h = sign(sin(cumsum(h))); } lowSum = abs((100*lowSum) / lowLen); highSum = abs((100*highSum) / highLen); + lowSum = (lowSum<0)?-lowSum:lowSum; + highSum = (highSum<0)?-highSum:highSum; + GraphBuffer[i] = (highSum << 16) | lowSum; } for(i = 0; i < GraphTraceLen - convLen - 16; i++) { - int j; - int lowTot = 0, highTot = 0; + lowTot = 0; + highTot = 0; // 16 and 15 are f_s divided by f_l and f_h, rounded for(j = 0; j < 16; j++) { lowTot += (GraphBuffer[i+j] & 0xffff); @@ -1517,17 +1655,29 @@ h = sign(sin(cumsum(h))); RepaintGraphWindow(); - // Okay, so now we have unsliced soft decisions; find bit-sync, and then - // get some bits. + // TI tag data format is 16 prebits, 8 start bits, 64 data bits, + // 16 crc CCITT bits, 8 stop bits, 15 end bits + + // the 16 prebits are always low + // the 8 start and stop bits of a tag must match + // the start/stop prebits of a ro tag are 01111110 + // the start/stop prebits of a rw tag are 11111110 + // the 15 end bits of a ro tag are all low + // the 15 end bits of a rw tag match bits 15-1 of the data bits + // Okay, so now we have unsliced soft decisions; + // find bit-sync, and then get some bits. + // look for 17 low bits followed by 6 highs (common pattern for ro and rw tags) int max = 0, maxPos = 0; for(i = 0; i < 6000; i++) { int j; int dec = 0; - for(j = 0; j < 8*arraylen(LowTone); j++) { + // searching 17 consecutive lows + for(j = 0; j < 17*lowLen; j++) { dec -= GraphBuffer[i+j]; } - for(; j < 8*arraylen(LowTone) + 8*arraylen(HighTone); j++) { + // searching 7 consecutive highs + for(; j < 17*lowLen + 6*highLen; j++) { dec += GraphBuffer[i+j]; } if(dec > max) { @@ -1535,61 +1685,113 @@ h = sign(sin(cumsum(h))); maxPos = i; } } - GraphBuffer[maxPos] = 800; - GraphBuffer[maxPos+1] = -800; - maxPos += 8*arraylen(LowTone); + // place a marker in the buffer to visually aid location + // of the start of sync GraphBuffer[maxPos] = 800; GraphBuffer[maxPos+1] = -800; - maxPos += 8*arraylen(HighTone); + // advance pointer to start of actual data stream (after 16 pre and 8 start bits) + maxPos += 17*lowLen; + maxPos += 6*highLen; + + // place a marker in the buffer to visually aid location + // of the end of sync GraphBuffer[maxPos] = 800; GraphBuffer[maxPos+1] = -800; PrintToScrollback("actual data bits start at sample %d", maxPos); - PrintToScrollback("length %d/%d", arraylen(HighTone), arraylen(LowTone)); - - GraphBuffer[maxPos] = 800; - GraphBuffer[maxPos+1] = -800; + PrintToScrollback("length %d/%d", highLen, lowLen); - BYTE bits[64+16+8+1]; + BYTE bits[1+64+16+8+16]; bits[sizeof(bits)-1] = '\0'; - for(i = 0; i < arraylen(bits); i++) { + DWORD shift3 = 0x7e000000, shift2 = 0, shift1 = 0, shift0 = 0; + + for(i = 0; i < arraylen(bits)-1; i++) { int high = 0; int low = 0; int j; - for(j = 0; j < arraylen(LowTone); j++) { + for(j = 0; j < lowLen; j++) { low -= GraphBuffer[maxPos+j]; } - for(j = 0; j < arraylen(HighTone); j++) { + for(j = 0; j < highLen; j++) { high += GraphBuffer[maxPos+j]; } + if(high > low) { bits[i] = '1'; - maxPos += arraylen(HighTone); + maxPos += highLen; + // bitstream arrives lsb first so shift right + shift3 |= (1<<31); } else { bits[i] = '.'; - maxPos += arraylen(LowTone); + maxPos += lowLen; } + + // 128 bit right shift register + shift0 = (shift0>>1) | (shift1 << 31); + shift1 = (shift1>>1) | (shift2 << 31); + shift2 = (shift2>>1) | (shift3 << 31); + shift3 >>= 1; + + // place a marker in the buffer between bits to visually aid location GraphBuffer[maxPos] = 800; GraphBuffer[maxPos+1] = -800; } - PrintToScrollback("bits: '%s'", bits); + PrintToScrollback("Info: raw tag bits = %s", bits); - DWORD h = 0, l = 0; - for(i = 0; i < 32; i++) { - if(bits[i] == '1') { - l |= (1<>8)&0xff; + if ( TagType != ((shift0>>16)&0xff) ) { + PrintToScrollback("Error: start and stop bits do not match!"); + return; + } + else if (TagType == 0x7e) { + PrintToScrollback("Info: Readonly TI tag detected."); + return; } - for(i = 32; i < 64; i++) { - if(bits[i] == '1') { - h |= (1<<(i-32)); + else if (TagType == 0xfe) { + PrintToScrollback("Info: Rewriteable TI tag detected."); + + // put 64 bit data into shift1 and shift0 + shift0 = (shift0>>24) | (shift1 << 8); + shift1 = (shift1>>24) | (shift2 << 8); + + // align 16 bit crc into lower half of shift2 + shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff; + + // align 16 bit "end bits" or "ident" into lower half of shift3 + shift3 >>= 16; + + // only 15 bits compare, last bit of ident is not valid + if ( (shift3^shift0)&0x7fff ) { + PrintToScrollback("Error: Ident mismatch!"); + } + // WARNING the order of the bytes in which we calc crc below needs checking + // i'm 99% sure the crc algorithm is correct, but it may need to eat the + // bytes in reverse or something + // calculate CRC + crc=0; + crc = update_crc16(crc, (shift0)&0xff); + crc = update_crc16(crc, (shift0>>8)&0xff); + crc = update_crc16(crc, (shift0>>16)&0xff); + crc = update_crc16(crc, (shift0>>24)&0xff); + crc = update_crc16(crc, (shift1)&0xff); + crc = update_crc16(crc, (shift1>>8)&0xff); + crc = update_crc16(crc, (shift1>>16)&0xff); + crc = update_crc16(crc, (shift1>>24)&0xff); + PrintToScrollback("Info: Tag data = %08X%08X", shift1, shift0); + if (crc != (shift2&0xffff)) { + PrintToScrollback("Error: CRC mismatch, calculated %04X, got ^04X", crc, shift2&0xffff); + } else { + PrintToScrollback("Info: CRC %04X is good", crc); } } - PrintToScrollback("hex: %08x %08x", h, l); + else { + PrintToScrollback("Unknown tag type."); + return; + } } static void CmdNorm(char *str) @@ -1613,6 +1815,40 @@ static void CmdNorm(char *str) RepaintGraphWindow(); } +static void CmdAmp(char *str) +{ + int i, rising, falling; + int max = INT_MIN, min = INT_MAX; + for(i = 10; i < GraphTraceLen; i++) { + if(GraphBuffer[i] > max) { + max = GraphBuffer[i]; + } + if(GraphBuffer[i] < min) { + min = GraphBuffer[i]; + } + } + if(max != min) { + rising= falling= 0; + for(i = 0; i < GraphTraceLen; i++) { + if(GraphBuffer[i+1] < GraphBuffer[i]) { + if(rising) { + GraphBuffer[i]= max; + rising= 0; + } + falling= 1; + } + if(GraphBuffer[i+1] > GraphBuffer[i]) { + if(falling) { + GraphBuffer[i]= min; + falling= 0; + } + rising= 1; + } + } + } + RepaintGraphWindow(); +} + static void CmdDec(char *str) { int i; @@ -1667,6 +1903,20 @@ static void CmdZerocrossings(char *str) RepaintGraphWindow(); } +static void CmdThreshold(char *str) +{ + int i; + int threshold = atoi(str); + + for(i = 0; i < GraphTraceLen; i++) { + if(GraphBuffer[i]>= threshold) + GraphBuffer[i]=1; + else + GraphBuffer[i]=-1; + } + RepaintGraphWindow(); +} + static void CmdLtrim(char *str) { int i; @@ -2029,9 +2279,11 @@ static void Cmdaskdemod(char *str) { int c, high = 0, low = 0; // TODO: complain if we do not give 2 arguments here ! + // (AL - this doesn't make sense! we're only using one argument!!!) sscanf(str, "%i", &c); /* Detect high and lows and clock */ + // (AL - clock???) for (i = 0; i < GraphTraceLen; i++) { if (GraphBuffer[i] > high) @@ -2039,6 +2291,10 @@ static void Cmdaskdemod(char *str) { else if (GraphBuffer[i] < low) low = GraphBuffer[i]; } + if(c != 0 && c != 1) { + PrintToScrollback("Invalid argument: %s",str); + return; + } if (GraphBuffer[0] > 0) { GraphBuffer[0] = 1-c; @@ -2283,7 +2539,12 @@ static void Cmdmanchesterdemod(char *str) { /* Detect first transition */ /* Lo-Hi (arbitrary) */ - for (i = 0; i < GraphTraceLen; i++) + /* skip to the first high */ + for (i= 0; i < GraphTraceLen; i++) + if(GraphBuffer[i] == high) + break; + /* now look for the first low */ + for (; i < GraphTraceLen; i++) { if (GraphBuffer[i] == low) { @@ -2397,7 +2658,7 @@ static void Cmdmanchesterdemod(char *str) { return; } } - } + } } PrintToScrollback("Manchester decoded bitstream"); @@ -2423,8 +2684,6 @@ static void Cmdmanchesterdemod(char *str) { } } - - /* * Usage ??? */ @@ -2452,6 +2711,12 @@ static void CmdPlot(char *str) ShowGraphWindow(); } +static void CmdGrid(char *str) +{ + sscanf(str, "%i %i", &PlotGridX, &PlotGridY); + RepaintGraphWindow(); +} + static void CmdHide(char *str) { HideGraphWindow(); @@ -2528,6 +2793,13 @@ static void CmdReadmem(char *str) SendCommand(&c, FALSE); } +static void CmdVersion(char *str) +{ + UsbCommand c; + c.cmd = CMD_VERSION; + SendCommand(&c, FALSE); +} + static void CmdLcdReset(char *str) { UsbCommand c; @@ -2548,12 +2820,6 @@ static void CmdLcd(char *str) } } - - -static void CmdTest(char *str) -{ -} - /* * Sets the divisor for LF frequency clock: lets the user choose any LF frequency below * 600kHz. @@ -2571,6 +2837,22 @@ static void CmdSetDivisor(char *str) } } +static void CmdSetMux(char *str) +{ + UsbCommand c; + c.cmd = CMD_SET_ADC_MUX; + if(strcmp(str, "lopkd") == 0) { + c.ext1 = 0; + } else if(strcmp(str, "loraw") == 0) { + c.ext1 = 1; + } else if(strcmp(str, "hipkd") == 0) { + c.ext1 = 2; + } else if(strcmp(str, "hiraw") == 0) { + c.ext1 = 3; + } + SendCommand(&c, FALSE); +} + typedef void HandlerFunction(char *cmdline); /* in alphabetic order */ @@ -2580,71 +2862,79 @@ static struct { int offline; // 1 if the command can be used when in offline mode char *docString; } CommandTable[] = { - {"askdemod", Cmdaskdemod,1, " <0|1> -- Attempt to demodulate simple ASK tags"}, - {"autocorr", CmdAutoCorr,1, " -- Autocorrelation over window"}, - {"bitsamples", CmdBitsamples,0, " Get raw samples as bitstring"}, - {"bitstream", Cmdbitstream,1, "[clock rate] -- Convert waveform into a bitstream"}, - {"buffclear", CmdBuffClear,0, " Clear sample buffer and graph window"}, - {"dec", CmdDec,1, " Decimate samples"}, - {"detectclock", Cmddetectclockrate,1, " Detect clock rate"}, - {"detectreader", CmdDetectReader,0, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"}, - {"em410xsim", CmdEM410xsim,1, " -- Simulate EM410x tag"}, - {"em410xread", CmdEM410xread,1, "[clock rate] -- Extract ID from EM410x tag"}, - {"em410xwatch", CmdEM410xwatch,0, " Watches for EM410x tags"}, - {"em4x50read", CmdEM4x50read,1, " Extract data from EM4x50 tag"}, - {"exit", CmdQuit,1, " Exit program"}, - {"flexdemod", CmdFlexdemod,1, " Demodulate samples for FlexPass"}, - {"fpgaoff", CmdFPGAOff,0, " Set FPGA off"}, // ## FPGA Control - {"hexsamples", CmdHexsamples,0, " -- Dump big buffer as hex bytes"}, - {"hi14alist", CmdHi14alist,0, " List ISO 14443a history"}, // ## New list command - {"hi14areader", CmdHi14areader,0, " Act like an ISO14443 Type A reader"}, // ## New reader command - {"hi14asim", CmdHi14asim,0, " -- Fake ISO 14443a tag"}, // ## Simulate 14443a tag - {"hi14asnoop", CmdHi14asnoop,0, " Eavesdrop ISO 14443 Type A"}, // ## New snoop command - {"hi14bdemod", CmdHi14bdemod,1, " Demodulate ISO14443 Type B from tag"}, - {"hi14list", CmdHi14list,0, " List ISO 14443 history"}, - {"hi14read", CmdHi14read,0, " Read HF tag (ISO 14443)"}, - {"hi14sim", CmdHi14sim,0, " Fake ISO 14443 tag"}, - {"hi14snoop", CmdHi14snoop,0, " Eavesdrop ISO 14443"}, - {"hi15demod", CmdHi15demod,1, " Demodulate ISO15693 from tag"}, - {"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 - {"hiddemod", CmdHiddemod,1, " Demodulate HID Prox Card II (not optimal)"}, - {"hide", CmdHide,1, " Hide graph window"}, - {"hidfskdemod", CmdHIDdemodFSK,0, " Realtime HID FSK demodulator"}, - {"hidsimtag", CmdHIDsimTAG,0, " -- HID tag simulator"}, - {"higet", CmdHi14read_sim,0, " -- Get samples HF, 'analog'"}, - {"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"}, - {"hisimlisten", CmdHisimlisten,0, " Get HF samples as fake tag"}, - {"hpf", CmdHpf,1, " Remove DC offset from trace"}, - {"indalademod", CmdIndalademod,0, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, - {"lcd", CmdLcd,0, " -- Send command/data to LCD"}, - {"lcdreset", CmdLcdReset,0, " Hardware reset LCD"}, - {"load", CmdLoad,1, " -- Load trace (to graph window"}, - {"locomread", CmdLoCommandRead,0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, - {"loread", CmdLoread,0, "['h'] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134)"}, - {"losamples", CmdLosamples,0, "[128 - 16000] -- Get raw samples for LF tag"}, - {"losim", CmdLosim,0, " Simulate LF tag"}, - {"ltrim", CmdLtrim,1, " -- Trim samples from left of trace"}, - {"mandemod", Cmdmanchesterdemod,1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, - {"manmod", Cmdmanchestermod,1, "[clock rate] -- Manchester modulate a binary stream"}, - {"norm", CmdNorm,1, " Normalize max/min to +/-500"}, - {"plot", CmdPlot,1, " Show graph window"}, - {"quit", CmdQuit,1, " Quit program"}, - {"readmem", CmdReadmem,0, " [address] Read memory at decimal address from flash"}, - {"reset", CmdReset,0, " Reset the Proxmark3"}, - {"save", CmdSave,1, " -- Save trace (from graph window)"}, - {"scale", CmdScale,1, " -- Set cursor display scale"}, - {"setlfdivisor", CmdSetDivisor,0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"}, - {"sri512read", CmdSri512read,0, " -- Read contents of a SRI512 tag"}, - {"tibits", CmdTibits,0, " Get raw bits for TI-type LF tag"}, - {"tidemod", CmdTidemod,0, " Demodulate raw bits for TI-type LF tag"}, - {"tiread", CmdTiread,0, " Read a TI-type 134 kHz tag"}, - {"tune", CmdTune,0, " Measure antenna tuning"}, - {"vchdemod", CmdVchdemod,0, "['clone'] -- Demodulate samples for VeriChip"}, - {"zerocrossings", CmdZerocrossings,1, " Count time between zero-crossings"}, + {"amp", CmdAmp, 1, "Amplify peaks"}, + {"askdemod", Cmdaskdemod, 1, "<0|1> -- Attempt to demodulate simple ASK tags"}, + {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, + {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, + {"bitstream", Cmdbitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, + {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, + {"dec", CmdDec, 1, "Decimate samples"}, + {"detectclock", Cmddetectclockrate, 1, "Detect clock rate"}, + {"detectreader", CmdDetectReader, 0, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"}, + {"em410xsim", CmdEM410xsim, 1, " -- Simulate EM410x tag"}, + {"em410xread", CmdEM410xread, 1, "[clock rate] -- Extract ID from EM410x tag"}, + {"em410xwatch", CmdEM410xwatch, 0, "Watches for EM410x tags"}, + {"em4x50read", CmdEM4x50read, 1, "Extract data from EM4x50 tag"}, + {"exit", CmdQuit, 1, "Exit program"}, + {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, + {"fpgaoff", CmdFPGAOff, 0, "Set FPGA off"}, + {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, + {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, + {"hexsamples", CmdHexsamples, 0, " -- Dump big buffer as hex bytes"}, + {"hi14alist", CmdHi14alist, 0, "List ISO 14443a history"}, + {"hi14areader", CmdHi14areader, 0, "Act like an ISO14443 Type A reader"}, + {"hi14asim", CmdHi14asim, 0, " -- Fake ISO 14443a tag"}, + {"hi14asnoop", CmdHi14asnoop, 0, "Eavesdrop ISO 14443 Type A"}, + {"hi14bdemod", CmdHi14bdemod, 1, "Demodulate ISO14443 Type B from tag"}, + {"hi14list", CmdHi14list, 0, "List ISO 14443 history"}, + {"hi14read", CmdHi14read, 0, "Read HF tag (ISO 14443)"}, + {"hi14sim", CmdHi14sim, 0, "Fake ISO 14443 tag"}, + {"hi14snoop", CmdHi14snoop, 0, "Eavesdrop ISO 14443"}, + {"hi15demod", CmdHi15demod, 1, "Demodulate ISO15693 from tag"}, + {"hi15read", CmdHi15read, 0, "Read HF tag (ISO 15693)"}, + {"hi15reader", CmdHi15reader, 0, "Act like an ISO15693 reader"}, + {"hi15sim", CmdHi15tag, 0, "Fake an ISO15693 tag"}, + {"hiddemod", CmdHiddemod, 1, "Demodulate HID Prox Card II (not optimal)"}, + {"hide", CmdHide, 1, "Hide graph window"}, + {"hidfskdemod", CmdHIDdemodFSK, 0, "Realtime HID FSK demodulator"}, + {"hidsimtag", CmdHIDsimTAG, 0, " -- HID tag simulator"}, + {"higet", CmdHi14read_sim, 0, " -- Get samples HF, 'analog'"}, + {"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"}, + {"hisimlisten", CmdHisimlisten, 0, "Get HF samples as fake tag"}, + {"hpf", CmdHpf, 1, "Remove DC offset from trace"}, + {"indalademod", CmdIndalademod, 0, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, + {"lcd", CmdLcd, 0, " -- Send command/data to LCD"}, + {"lcdreset", CmdLcdReset, 0, "Hardware reset LCD"}, + {"legicrfsim", CmdLegicRfSim, 0, "Start the LEGIC RF tag simulator"}, + {"load", CmdLoad, 1, " -- Load trace (to graph window"}, + {"locomread", CmdLoCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, + {"loread", CmdLoread, 0, "['h'] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134)"}, + {"losamples", CmdLosamples, 0, "[128 - 16000] -- Get raw samples for LF tag"}, + {"losim", CmdLosim, 0, "Simulate LF tag"}, + {"losimbidir", CmdLosimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, + {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, + {"mandemod", Cmdmanchesterdemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, + {"manmod", Cmdmanchestermod, 1, "[clock rate] -- Manchester modulate a binary stream"}, + {"norm", CmdNorm, 1, "Normalize max/min to +/-500"}, + {"plot", CmdPlot, 1, "Show graph window"}, + {"quit", CmdQuit, 1, "Quit program"}, + {"readmem", CmdReadmem, 0, "[address] -- Read memory at decimal address from flash"}, + {"reset", CmdReset, 0, "Reset the Proxmark3"}, + {"save", CmdSave, 1, " -- Save trace (from graph window)"}, + {"scale", CmdScale, 1, " -- Set cursor display scale"}, + {"setlfdivisor", CmdSetDivisor, 0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"}, + {"setmux", CmdSetMux, 0, " -- Set the ADC mux to a specific value"}, + {"sri512read", CmdSri512read, 0, " -- Read contents of a SRI512 tag"}, + {"tidemod", CmdTIDemod, 1, "Demodulate raw bits for TI-type LF tag"}, + {"tiread", CmdTIRead, 0, "Read and decode a TI 134 kHz tag"}, + {"tiwrite", CmdTIWrite, 0, "Write new data to a r/w TI 134 kHz tag"}, + {"threshold", CmdThreshold, 1, "Maximize/minimize every value in the graph window depending on threshold"}, + {"tune", CmdTune, 0, "Measure antenna tuning"}, + {"vchdemod", CmdVchdemod, 0, "['clone'] -- Demodulate samples for VeriChip"}, + {"version", CmdVersion, 0, "Show version inforation about the connected Proxmark"}, + {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"}, }; static struct { @@ -2749,16 +3039,18 @@ void UsbCommandReceived(UsbCommand *c) vHf = c->ext2 & 0xffff;; peakf = c->ext3 & 0xffff; peakv = c->ext3 >> 16; - PrintToScrollback("# LF antenna: %.2f V @ 125.00Khz", vLf125/1000.0); - PrintToScrollback("# LF antenna: %.2f V @ 134.00Khz", vLf134/1000.0); - PrintToScrollback("# LF optimal: %.2f V @ %.2fKHz", peakv/1000.0, 12000.0/(peakf+1)); - PrintToScrollback("# HF antenna: %.2f V @ 13.56Mhz", vHf/1000.0); + PrintToScrollback(""); + PrintToScrollback(""); + PrintToScrollback("# LF antenna: %5.2f V @ 125.00 kHz", vLf125/1000.0); + PrintToScrollback("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0); + PrintToScrollback("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1)); + PrintToScrollback("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0); if (peakv<2000) - PrintToScrollback("# Your LF antenna is unusable."); + PrintToScrollback("# Your LF antenna is unusable."); else if (peakv<10000) PrintToScrollback("# Your LF antenna is marginal."); if (vHf<2000) - PrintToScrollback("# Your HF antenna is unusable."); + PrintToScrollback("# Your HF antenna is unusable."); else if (vHf<5000) PrintToScrollback("# Your HF antenna is marginal."); break;