X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/fddf220a8bb4fd84ec38d23031859f6ca9540084..c07b79fcbf72f530cbff5bc1e49c12bff311f50f:/client/cmdlf.c diff --git a/client/cmdlf.c b/client/cmdlf.c index 86bb35ce..b3986897 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -12,7 +12,7 @@ #include #include #include -#include "proxusb.h" +#include "proxmark3.h" #include "data.h" #include "graph.h" #include "ui.h" @@ -23,6 +23,10 @@ #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); @@ -34,7 +38,7 @@ int CmdLFCommandRead(const char *Cmd) 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); + 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); @@ -52,7 +56,7 @@ int CmdFlexdemod(const char *Cmd) } } -#define LONG_WAIT 100 + #define LONG_WAIT 100 int start; for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) { int first = GraphBuffer[start]; @@ -72,22 +76,18 @@ int CmdFlexdemod(const char *Cmd) GraphBuffer[start] = 2; GraphBuffer[start+1] = -2; + uint8_t bits[64] = {0x00}; - uint8_t bits[64]; - - int bit; + int bit, sum; i = start; for (bit = 0; bit < 64; bit++) { - int j; - int sum = 0; - for (j = 0; j < 16; j++) { + sum = 0; + for (int j = 0; j < 16; j++) { sum += GraphBuffer[i++]; } - if (sum > 0) { - bits[bit] = 1; - } else { - bits[bit] = 0; - } + + bits[bit] = (sum > 0) ? 1 : 0; + PrintAndLog("bit %d sum %d", bit, sum); } @@ -105,15 +105,14 @@ int CmdFlexdemod(const char *Cmd) } } + // HACK writing back to graphbuffer. GraphTraceLen = 32*64; i = 0; int phase = 0; for (bit = 0; bit < 64; bit++) { - if (bits[bit] == 0) { - phase = 0; - } else { - phase = 1; - } + + phase = (bits[bit] == 0) ? 0 : 1; + int j; for (j = 0; j < 32; j++) { GraphBuffer[i++] = phase; @@ -124,7 +123,7 @@ int CmdFlexdemod(const char *Cmd) RepaintGraphWindow(); return 0; } - + int CmdIndalaDemod(const char *Cmd) { // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID @@ -132,12 +131,14 @@ int CmdIndalaDemod(const char *Cmd) 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); + // 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)) { @@ -166,8 +167,13 @@ int CmdIndalaDemod(const char *Cmd) count = 0; } } - PrintAndLog("Recovered %d raw bits", rawbit); - PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos); + + 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; @@ -178,6 +184,7 @@ int CmdIndalaDemod(const char *Cmd) uidlen = 64; long_wait = 29; } + int start; int first = 0; for (start = 0; start <= rawbit - uidlen; start++) { @@ -191,6 +198,7 @@ int CmdIndalaDemod(const char *Cmd) break; } } + if (start == rawbit - uidlen + 1) { PrintAndLog("nothing to wait for"); return 0; @@ -204,12 +212,12 @@ int CmdIndalaDemod(const char *Cmd) } // Dumping UID - uint8_t bits[224]; - char showbits[225]; - showbits[uidlen]='\0'; + uint8_t bits[224] = {0x00}; + char showbits[225] = {0x00}; 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++) { @@ -227,11 +235,47 @@ int CmdIndalaDemod(const char *Cmd) } times = 1; } - PrintAndLog("UID=%s", showbits); + + //convert UID to HEX + uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; + int idx; + uid1 = 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 = uid4 = uid5 = uid6 = 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 occurences - for (; i + uidlen <= rawbit;) { + // Checking UID against next occurrences int failed = 0; + for (; i + uidlen <= rawbit;) { + failed = 0; for (bit = 0; bit < uidlen; bit++) { if (bits[bit] != rawbits[i++]) { failed = 1; @@ -243,9 +287,12 @@ int CmdIndalaDemod(const char *Cmd) } times += 1; } - PrintAndLog("Occurences: %d (expected %d)", times, (rawbit - start) / uidlen); + + PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); // Remodulating for tag cloning + // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod) + // since this changes graphbuffer data. GraphTraceLen = 32*uidlen; i = 0; int phase = 0; @@ -263,23 +310,68 @@ int CmdIndalaDemod(const char *Cmd) } RepaintGraphWindow(); + return 1; +} + +int CmdIndalaClone(const char *Cmd) +{ + UsbCommand c; + unsigned int uid1, uid2, uid3, uid4, uid5, uid6, uid7; + + uid1 = uid2 = uid3 = uid4 = uid5 = uid6 = 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'"); + } else if (sscanf(Cmd, "%"lli, &c.arg[0]) != 1) { + PrintAndLog("Samples 1: 'lf read'"); + PrintAndLog(" 2: 'lf read h'"); + PrintAndLog(" 3: 'lf read '"); return 0; } SendCommand(&c); - WaitForResponse(CMD_ACK); + WaitForResponse(CMD_ACK,NULL); return 0; } @@ -316,7 +408,7 @@ int CmdLFSim(const char *Cmd) c.d.asBytes[j] = GraphBuffer[i+j]; } SendCommand(&c); - WaitForResponse(CMD_ACK); + WaitForResponse(CMD_ACK,NULL); } PrintAndLog("Starting simulator..."); @@ -327,7 +419,9 @@ int CmdLFSim(const char *Cmd) int CmdLFSimBidir(const char *Cmd) { - /* Set ADC to twice the carrier for a slight supersampling */ + // Set ADC to twice the carrier for a slight supersampling + // HACK: not implemented in ARMSRC. + PrintAndLog("Not implemented yet."); UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}}; SendCommand(&c); return 0; @@ -339,28 +433,47 @@ int CmdLFSimManchester(const char *Cmd) static int clock, gap; static char data[1024], gapstring[8]; - /* get settings/bits */ sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); - /* clear our graph */ ClearGraph(0); - /* fill it with our bitstream */ for (int i = 0; i < strlen(data) ; ++i) AppendGraph(0, clock, data[i]- '0'); - /* modulate */ CmdManchesterMod(""); - /* show what we've done */ RepaintGraphWindow(); - /* 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 == '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("usage 1: snoop"); + PrintAndLog(" 2: snoop {l,h} [trigger threshold]"); + PrintAndLog(" 3: 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 @@ -437,6 +550,45 @@ int CmdVchDemod(const char *Cmd) 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"}, @@ -444,13 +596,20 @@ static command_t CommandTable[] = {"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)"}, - {"read", CmdLFRead, 0, "['h'] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134)"}, + {"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} };