X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/393c3ef933553e628635590ca2b8237d07e9e0e3..a6293168da03b547d7cb283f94d8e7aa7109069a:/client/cmdlf.c diff --git a/client/cmdlf.c b/client/cmdlf.c index ceb84e3e..af24aa80 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1,8 +1,19 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2010 iZsh +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// Low frequency commands +//----------------------------------------------------------------------------- + #include #include #include #include -#include "proxusb.h" +//#include "proxusb.h" +#include "proxmark3.h" #include "data.h" #include "graph.h" #include "ui.h" @@ -13,445 +24,602 @@ #include "cmdlfhid.h" #include "cmdlfti.h" #include "cmdlfem4x.h" +#include "cmdlfhitag.h" +#include "cmdlft55xx.h" +#include "cmdlfpcf7931.h" +#include "cmdlfio.h" static int CmdHelp(const char *Cmd); /* send a command before reading */ int CmdLFCommandRead(const char *Cmd) { - static char dummy[3]; + static char dummy[3]; - dummy[0]= ' '; + dummy[0]= ' '; - UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; - sscanf(Cmd, "%i %i %i %s %s", &c.arg[0], &c.arg[1], &c.arg[2], (char *) &c.d.asBytes,(char *) &dummy+1); - // in case they specified 'h' - strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); - SendCommand(&c); - return 0; + UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; + sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1)); + // in case they specified 'h' + strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); + SendCommand(&c); + return 0; } int CmdFlexdemod(const char *Cmd) { - int i; - for (i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] < 0) { - GraphBuffer[i] = -1; - } else { - GraphBuffer[i] = 1; - } - } - -#define LONG_WAIT 100 - int start; - for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { - int first = GraphBuffer[start]; - for (i = start; i < start + LONG_WAIT; i++) { - if (GraphBuffer[i] != first) { - break; - } - } - if (i == (start + LONG_WAIT)) { - break; - } - } - if (start == GraphTraceLen - LONG_WAIT) { - PrintAndLog("nothing to wait for"); - return 0; - } - - GraphBuffer[start] = 2; - GraphBuffer[start+1] = -2; - - uint8_t bits[64]; - - int bit; - i = start; - for (bit = 0; bit < 64; bit++) { - int j; - int sum = 0; - for (j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } - if (sum > 0) { - bits[bit] = 1; - } else { - bits[bit] = 0; - } - PrintAndLog("bit %d sum %d", bit, sum); - } - - for (bit = 0; bit < 64; bit++) { - int j; - int sum = 0; - for (j = 0; j < 16; j++) { - sum += GraphBuffer[i++]; - } - if (sum > 0 && bits[bit] != 1) { - PrintAndLog("oops1 at %d", bit); - } - if (sum < 0 && bits[bit] != 0) { - PrintAndLog("oops2 at %d", bit); - } - } - - GraphTraceLen = 32*64; - i = 0; - int phase = 0; - for (bit = 0; bit < 64; bit++) { - if (bits[bit] == 0) { - phase = 0; - } else { - phase = 1; - } - int j; - for (j = 0; j < 32; j++) { - GraphBuffer[i++] = phase; - phase = !phase; - } - } - - RepaintGraphWindow(); - return 0; + int i; + for (i = 0; i < GraphTraceLen; ++i) { + if (GraphBuffer[i] < 0) { + GraphBuffer[i] = -1; + } else { + GraphBuffer[i] = 1; + } + } + + #define LONG_WAIT 100 + int start; + for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { + int first = GraphBuffer[start]; + for (i = start; i < start + LONG_WAIT; i++) { + if (GraphBuffer[i] != first) { + break; + } + } + if (i == (start + LONG_WAIT)) { + break; + } + } + if (start == GraphTraceLen - LONG_WAIT) { + PrintAndLog("nothing to wait for"); + return 0; + } + + GraphBuffer[start] = 2; + GraphBuffer[start+1] = -2; + + uint8_t bits[64]; + + int bit; + i = start; + for (bit = 0; bit < 64; bit++) { + int j; + int sum = 0; + for (j = 0; j < 16; j++) { + sum += GraphBuffer[i++]; + } + if (sum > 0) { + bits[bit] = 1; + } else { + bits[bit] = 0; + } + PrintAndLog("bit %d sum %d", bit, sum); + } + + for (bit = 0; bit < 64; bit++) { + int j; + int sum = 0; + for (j = 0; j < 16; j++) { + sum += GraphBuffer[i++]; + } + if (sum > 0 && bits[bit] != 1) { + PrintAndLog("oops1 at %d", bit); + } + if (sum < 0 && bits[bit] != 0) { + PrintAndLog("oops2 at %d", bit); + } + } + + GraphTraceLen = 32*64; + i = 0; + int phase = 0; + for (bit = 0; bit < 64; bit++) { + if (bits[bit] == 0) { + phase = 0; + } else { + phase = 1; + } + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } + + RepaintGraphWindow(); + return 0; } - + int CmdIndalaDemod(const char *Cmd) { - // 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 - uint8_t rawbits[4096]; - int rawbit = 0; - int worst = 0, worstPos = 0; - PrintAndLog("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; - } - } - PrintAndLog("Recovered %d raw bits", rawbit); - PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); - - // Finding the start of a UID - int uidlen, long_wait; - if (strcmp(Cmd, "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) { - PrintAndLog("nothing to wait for"); - return 0; - } - - // Inverting signal if needed - if (first == 1) { - for (i = start; i < rawbit; i++) { - rawbits[i] = !rawbits[i]; - } - } - - // Dumping UID - uint8_t bits[224]; - char showbits[225]; - showbits[uidlen]='\0'; - int bit; - i = start; - int times = 0; - if (uidlen > rawbit) { - PrintAndLog("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'; - PrintAndLog("Partial UID=%s", showbits); - return 0; - } else { - for (bit = 0; bit < uidlen; bit++) { - bits[bit] = rawbits[i++]; - showbits[bit] = '0' + bits[bit]; - } - times = 1; - } - PrintAndLog("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; - } - PrintAndLog("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(); - return 0; + // 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 + uint8_t rawbits[4096]; + int rawbit = 0; + int worst = 0, worstPos = 0; + // PrintAndLog("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; + } + } + if (rawbit>0){ + PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32); + PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); + } else return 0; + // Finding the start of a UID + int uidlen, long_wait; + if (strcmp(Cmd, "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) { + PrintAndLog("nothing to wait for"); + return 0; + } + + // Inverting signal if needed + if (first == 1) { + for (i = start; i < rawbit; i++) { + rawbits[i] = !rawbits[i]; + } + } + + // Dumping UID + uint8_t bits[224]; + char showbits[225]; + showbits[uidlen]='\0'; + int bit; + i = start; + int times = 0; + if (uidlen > rawbit) { + PrintAndLog("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'; + PrintAndLog("Partial UID=%s", showbits); + return 0; + } else { + for (bit = 0; bit < uidlen; bit++) { + bits[bit] = rawbits[i++]; + showbits[bit] = '0' + bits[bit]; + } + times = 1; + } + + //convert UID to HEX + uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; + int idx; + uid1=0; + uid2=0; + if (uidlen==64){ + for( idx=0; idx<64; idx++) { + if (showbits[idx] == '0') { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|0; + } else { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|1; + } + } + PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2); + } + else { + uid3=0; + uid4=0; + uid5=0; + uid6=0; + uid7=0; + for( idx=0; idx<224; idx++) { + uid1=(uid1<<1)|(uid2>>31); + uid2=(uid2<<1)|(uid3>>31); + uid3=(uid3<<1)|(uid4>>31); + uid4=(uid4<<1)|(uid5>>31); + uid5=(uid5<<1)|(uid6>>31); + uid6=(uid6<<1)|(uid7>>31); + if (showbits[idx] == '0') uid7=(uid7<<1)|0; + else uid7=(uid7<<1)|1; + } + PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + } + + // Checking UID against next occurrences + 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; + } + PrintAndLog("Occurrences: %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(); + return 1; +} + +int CmdIndalaClone(const char *Cmd) +{ + unsigned int uid1, uid2, uid3, uid4, uid5, uid6, uid7; + UsbCommand c; + uid1=0; + uid2=0; + uid3=0; + uid4=0; + uid5=0; + uid6=0; + uid7=0; + int n = 0, i = 0; + + if (strchr(Cmd,'l') != 0) { + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (uid3 >> 28); + uid3 = (uid3 << 4) | (uid4 >> 28); + uid4 = (uid4 << 4) | (uid5 >> 28); + uid5 = (uid5 << 4) | (uid6 >> 28); + uid6 = (uid6 << 4) | (uid7 >> 28); + uid7 = (uid7 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7); + c.cmd = CMD_INDALA_CLONE_TAG_L; + c.d.asDwords[0] = uid1; + c.d.asDwords[1] = uid2; + c.d.asDwords[2] = uid3; + c.d.asDwords[3] = uid4; + c.d.asDwords[4] = uid5; + c.d.asDwords[5] = uid6; + c.d.asDwords[6] = uid7; + } + else + { + while (sscanf(&Cmd[i++], "%1x", &n ) == 1) { + uid1 = (uid1 << 4) | (uid2 >> 28); + uid2 = (uid2 << 4) | (n & 0xf); + } + PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2); + c.cmd = CMD_INDALA_CLONE_TAG; + c.arg[0] = uid1; + c.arg[1] = uid2; + } + + SendCommand(&c); + return 0; } int CmdLFRead(const char *Cmd) { - UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; - // 'h' means higher-low-frequency, 134 kHz - if(*Cmd == 'h') { - c.arg[0] = 1; - } else if (*Cmd == '\0') { - c.arg[0] = 0; - } else { - PrintAndLog("use 'read' or 'read h'"); - return 0; - } - SendCommand(&c); - WaitForResponse(CMD_ACK); - return 0; + UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K}; + // 'h' means higher-low-frequency, 134 kHz + if(*Cmd == 'h') { + c.arg[0] = 1; + } else if (*Cmd == '\0') { + c.arg[0] = 0; + } else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) { + PrintAndLog("use 'read' or 'read h', or 'read '"); + return 0; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; } static void ChkBitstream(const char *str) { - int i; - - /* convert to bitstream if necessary */ - for (i = 0; i < (int)(GraphTraceLen / 2); i++) - { - if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) - { - CmdBitstream(str); - break; - } - } + int i; + + /* convert to bitstream if necessary */ + for (i = 0; i < (int)(GraphTraceLen / 2); i++) + { + if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) + { + CmdBitstream(str); + break; + } + } } int CmdLFSim(const char *Cmd) { - int i; - static int gap; - - sscanf(Cmd, "%i", &gap); - - /* convert to bitstream if necessary */ - ChkBitstream(Cmd); - - PrintAndLog("Sending data, please wait..."); - for (i = 0; i < GraphTraceLen; i += 48) { - UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; - int j; - for (j = 0; j < 48; j++) { - c.d.asBytes[j] = GraphBuffer[i+j]; - } - SendCommand(&c); - WaitForResponse(CMD_ACK); - } - - PrintAndLog("Starting simulator..."); - UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; - SendCommand(&c); - return 0; + int i; + static int gap; + + sscanf(Cmd, "%i", &gap); + + /* convert to bitstream if necessary */ + ChkBitstream(Cmd); + + PrintAndLog("Sending data, please wait..."); + for (i = 0; i < GraphTraceLen; i += 48) { + UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; + int j; + for (j = 0; j < 48; j++) { + c.d.asBytes[j] = GraphBuffer[i+j]; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + } + + PrintAndLog("Starting simulator..."); + UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}}; + SendCommand(&c); + return 0; } int CmdLFSimBidir(const char *Cmd) { - /* Set ADC to twice the carrier for a slight supersampling */ - UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}}; - SendCommand(&c); - return 0; + /* Set ADC to twice the carrier for a slight supersampling */ + UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}}; + SendCommand(&c); + return 0; } /* simulate an LF Manchester encoded tag with specified bitstream, clock rate and inter-id gap */ int CmdLFSimManchester(const char *Cmd) { - static int clock, gap; - static char data[1024], gapstring[8]; + static int clock, gap; + static char data[1024], gapstring[8]; - /* get settings/bits */ - sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); + /* get settings/bits */ + sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); - /* clear our graph */ - ClearGraph(0); + /* clear our graph */ + ClearGraph(0); - /* fill it with our bitstream */ - for (int i = 0; i < strlen(data) ; ++i) - AppendGraph(0, clock, data[i]- '0'); + /* fill it with our bitstream */ + for (int i = 0; i < strlen(data) ; ++i) + AppendGraph(0, clock, data[i]- '0'); - /* modulate */ - CmdManchesterMod(""); + /* modulate */ + CmdManchesterMod(""); - /* show what we've done */ - RepaintGraphWindow(); + /* show what we've done */ + RepaintGraphWindow(); - /* simulate */ - sprintf(&gapstring[0], "%i", gap); - CmdLFSim(gapstring); - return 0; + /* simulate */ + sprintf(&gapstring[0], "%i", gap); + CmdLFSim(gapstring); + return 0; +} + +int CmdLFSnoop(const char *Cmd) +{ + UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES}; + // 'h' means higher-low-frequency, 134 kHz + c.arg[0] = 0; + c.arg[1] = -1; + if (*Cmd == 0) { + // empty + } else if (*Cmd == 'l') { + sscanf(Cmd, "l %"lli, &c.arg[1]); + } else if(*Cmd == 'h') { + c.arg[0] = 1; + sscanf(Cmd, "h %"lli, &c.arg[1]); + } else if (sscanf(Cmd, "%"lli" %"lli, &c.arg[0], &c.arg[1]) < 1) { + PrintAndLog("use 'snoop' or 'snoop {l,h} [trigger threshold]', or 'snoop [trigger threshold]'"); + return 0; + } + SendCommand(&c); + WaitForResponse(CMD_ACK,NULL); + return 0; } int CmdVchDemod(const char *Cmd) { - // Is this the entire sync pattern, or does this also include some - // data bits that happen to be the same everywhere? That would be - // lovely to know. - static const int SyncPattern[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - }; - - // So first, we correlate for the sync pattern, and mark that. - int bestCorrel = 0, bestPos = 0; - int i; - // It does us no good to find the sync pattern, with fewer than - // 2048 samples after it... - for (i = 0; i < (GraphTraceLen-2048); i++) { - int sum = 0; - int j; - for (j = 0; j < arraylen(SyncPattern); j++) { - sum += GraphBuffer[i+j]*SyncPattern[j]; - } - if (sum > bestCorrel) { - bestCorrel = sum; - bestPos = i; - } - } - PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel); - - char bits[257]; - bits[256] = '\0'; - - int worst = INT_MAX; - int worstPos; - - for (i = 0; i < 2048; i += 8) { - int sum = 0; - int j; - for (j = 0; j < 8; j++) { - sum += GraphBuffer[bestPos+i+j]; - } - if (sum < 0) { - bits[i/8] = '.'; - } else { - bits[i/8] = '1'; - } - if(abs(sum) < worst) { - worst = abs(sum); - worstPos = i; - } - } - PrintAndLog("bits:"); - PrintAndLog("%s", bits); - PrintAndLog("worst metric: %d at pos %d", worst, worstPos); - - if (strcmp(Cmd, "clone")==0) { - GraphTraceLen = 0; - char *s; - for(s = bits; *s; s++) { - int j; - for(j = 0; j < 16; j++) { - GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0; - } - } - RepaintGraphWindow(); - } - return 0; + // Is this the entire sync pattern, or does this also include some + // data bits that happen to be the same everywhere? That would be + // lovely to know. + static const int SyncPattern[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + + // So first, we correlate for the sync pattern, and mark that. + int bestCorrel = 0, bestPos = 0; + int i; + // It does us no good to find the sync pattern, with fewer than + // 2048 samples after it... + for (i = 0; i < (GraphTraceLen-2048); i++) { + int sum = 0; + int j; + for (j = 0; j < arraylen(SyncPattern); j++) { + sum += GraphBuffer[i+j]*SyncPattern[j]; + } + if (sum > bestCorrel) { + bestCorrel = sum; + bestPos = i; + } + } + PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel); + + char bits[257]; + bits[256] = '\0'; + + int worst = INT_MAX; + int worstPos = 0; + + for (i = 0; i < 2048; i += 8) { + int sum = 0; + int j; + for (j = 0; j < 8; j++) { + sum += GraphBuffer[bestPos+i+j]; + } + if (sum < 0) { + bits[i/8] = '.'; + } else { + bits[i/8] = '1'; + } + if(abs(sum) < worst) { + worst = abs(sum); + worstPos = i; + } + } + PrintAndLog("bits:"); + PrintAndLog("%s", bits); + PrintAndLog("worst metric: %d at pos %d", worst, worstPos); + + if (strcmp(Cmd, "clone")==0) { + GraphTraceLen = 0; + char *s; + for(s = bits; *s; s++) { + int j; + for(j = 0; j < 16; j++) { + GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0; + } + } + RepaintGraphWindow(); + } + return 0; +} + +//by marshmellow +int CmdLFfind(const char *Cmd) +{ + int ans=0; + if (!offline){ + ans=CmdLFRead(""); + ans=CmdSamples("20000"); + } + if (GraphTraceLen<1000) return 0; + PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag"); + PrintAndLog("Checking for known tags:"); + + ans=Cmdaskmandemod(""); + if (ans>0) { + PrintAndLog("Valid EM410x ID Found!"); + return 1; + } + ans=CmdFSKdemodHID(""); + if (ans>0) { + PrintAndLog("Valid HID Prox ID Found!"); + return 1; + } + ans=CmdFSKdemodIO(""); + if (ans>0) { + PrintAndLog("Valid IO Prox ID Found!"); + return 1; + } + //add psk and indala + ans=CmdIndalaDecode(""); + if (ans>0) { + PrintAndLog("Valid Indala ID Found!"); + return 1; + } + // ans=CmdIndalaDemod("224"); + // if (ans>0) return 1; + PrintAndLog("No Known Tags Found!\n"); + return 0; } static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, - {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, - {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, - {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, - {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, - {"read", CmdLFRead, 0, "['h'] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134)"}, - {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, - {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, - {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, - {"ti", CmdLFTI, 1, "{ TI RFIDs... }"}, - {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, - {NULL, NULL, 0, NULL} + {"help", CmdHelp, 1, "This help"}, + {"cmdread", CmdLFCommandRead, 0, " <'0' period> <'1' period> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, + {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"}, + {"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"}, + {"hid", CmdLFHID, 1, "{ HID RFIDs... }"}, + {"io", CmdLFIO, 1, "{ ioProx tags... }"}, + {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, + {"indalaclone", CmdIndalaClone, 0, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, + {"read", CmdLFRead, 0, "['h' or ] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, + {"search", CmdLFfind, 1, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, + {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, + {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, + {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, + {"snoop", CmdLFSnoop, 0, "['l'|'h'|] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, + {"ti", CmdLFTI, 1, "{ TI RFIDs... }"}, + {"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"}, + {"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"}, + {"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"}, + {"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"}, + {NULL, NULL, 0, NULL} }; int CmdLF(const char *Cmd) { - CmdsParse(CommandTable, Cmd); - return 0; + CmdsParse(CommandTable, Cmd); + return 0; } int CmdHelp(const char *Cmd) { - CmdsHelp(CommandTable); - return 0; + CmdsHelp(CommandTable); + return 0; }