From 70459879e98e1e7a2a5627c4008f0ad38b8dc782 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Tue, 10 Nov 2015 11:42:59 +0100 Subject: [PATCH] added @marshmellows new viking demod. adjusted it to fit with the clone/demod that is under "lf viking" commands. did some code clean up, 3spaces into tab. --- CHANGELOG.md | 6 + armsrc/appmain.c | 2 +- armsrc/apps.h | 3 +- armsrc/lfops.c | 21 +-- client/cmddata.c | 53 +------ client/cmddata.h | 4 +- client/cmdlf.c | 368 ++++++++++++++++++++++--------------------- client/cmdlfviking.c | 71 ++++++--- common/lfdemod.c | 47 +++--- common/lfdemod.h | 4 +- 10 files changed, 276 insertions(+), 303 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 213fb07d..c2857eae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac -- ### Added +- Added viking demod to `lf search` (marshmellow) +- `data askvikingdemod` demod viking id tag from graphbuffer (marshmellow) - `lf t55xx resetread` added reset then read command - should allow determining start of stream transmissions (marshmellow) - `lf t55xx wakeup` added wake with password (AOR) to allow lf search or standard lf read after (iceman, marshmellow) @@ -22,8 +24,12 @@ of stream transmissions (marshmellow) - Added 'hw status'. This command makes the ARM print out some runtime information. (holiman) - Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman) - Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman) +- Added 'hf snoop'. This command take digitalized signal from FPGA and put in BigBuffer. (pwpiwi + enio) +- Added Topaz (NFC type 1) protocol support ('hf topaz reader', 'hf list topaz', 'hf 14a raw -T', 'hf topaz snoop'). (piwi) +- Added option c to 'hf list' (mark CRC bytes) (piwi) ### Changed +- Adjusted lf em410x em410xsim to accept a clock argument - Adjusted lf t55xx dump to allow overriding the safety check and warning text (marshmellow) - Adjusted lf t55xx write input variables (marshmellow) - Adjusted lf t55xx read with password safety check and warning text and adjusted the input variables (marshmellow & iceman) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 8c982eaf..c51aa54e 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1005,7 +1005,7 @@ void UsbPacketReceived(uint8_t *packet, int len) break; case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation CmdAWIDdemodFSK(c->arg[0], 0, 0, 1); - break; + break; case CMD_VIKING_CLONE_TAG: CopyViKingtoT55x7(c->arg[0],c->arg[1]); break; diff --git a/armsrc/apps.h b/armsrc/apps.h index c2bd5204..52c4b77c 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -89,7 +89,8 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo); void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7 void T55xxResetRead(void); -void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode); +void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg); +void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg); void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd); void T55xxWakeUp(uint32_t Pwd); void TurnReadLFOn(); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 8e3a0dfe..4a9e07b1 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -1132,7 +1132,7 @@ void T55xxResetRead(void) { } // Write one card block in page 0, no lock -void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) { +void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { LED_A_ON(); bool PwdMode = arg & 0x1; uint8_t Page = (arg & 0x2)>>1; @@ -1178,7 +1178,7 @@ void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg } // Write one card block in page 0, no lock -void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) { +void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { T55xxWriteBlockExt(Data, Block, Pwd, arg); cmd_send(CMD_ACK,0,0,0,0,0); } @@ -1260,10 +1260,8 @@ void T55xxWakeUp(uint32_t Pwd){ void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { // write last block first and config block last (if included) - for (uint8_t i = numblocks+startblock; i > startblock; i--) { - //Dbprintf("write- Blk: %d, d:%08X",i-1,blockdata[i-1]); + for (uint8_t i = numblocks+startblock; i > startblock; i--) T55xxWriteBlockExt(blockdata[i-1],i-1,0,0); - } } // Copy HID id to card and setup block 0 config @@ -1652,13 +1650,10 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode } void CopyViKingtoT55x7(uint32_t block1, uint32_t block2) { - LED_D_ON(); - T55xxWriteBlock(block1,1,0,0); - T55xxWriteBlock(block2,2,0,0); - T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T55x7_MAXBLOCK_SHIFT,0,0,0); - // T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T5555_MAXBLOCK_SHIFT,0,0,1); - // ICEMAN NOTES: - // Shouldn't this one be: T55x7_MAXBLOCK_SHIFT and 0 in password mode - LED_D_OFF(); + + uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2}; + // Program the data blocks for supplied ID and the block 0 config + WriteT55xx(data, 0, 3); + LED_D_OFF(); } diff --git a/client/cmddata.c b/client/cmddata.c index f4b596aa..ea58eb54 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1250,7 +1250,7 @@ int CmdFSKdemodAWID(const char *Cmd) // | | | | | | | // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96 // ----------------------------------------------------------------------------- - // 00000001 000 1 110 1 101 1 011 1 1 d01 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1 + // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1 // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96 // |---26 bit---| |-----117----||-------------142-------------| // b = format bit len, o = odd parity of last 3 bits @@ -1419,7 +1419,6 @@ int CmdFSKdemodPyramid(const char *Cmd) uint32_t fc = 0; uint32_t cardnum = 0; uint32_t code1 = 0; - //uint32_t code2 = 0; if (fmtLen==26){ fc = bytebits_to_byte(BitStream+73, 8); cardnum = bytebits_to_byte(BitStream+81, 16); @@ -1878,54 +1877,6 @@ int CmdRawDemod(const char *Cmd) return ans; } -int AmVikingDecode(const uint8_t *id){ - // searching the buffer for the id - //uint8_t id_bits[32]; - // convert 4 bytes of id to 32 bits present in 32 bytes data; - //bytes_to_bits(id,4,id_bits,sizeof(id_bits)); - - //print_arraybinary(id_bits,sizeof(id_bits)); - PrintAndLog(" binary: %s", printBits(4, id) ); - - //size_t idx = 0; - size_t BitLen = DemodBufferLen; - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - memcpy(BitStream, DemodBuffer, BitLen); - - // if (VikingDecode(BitStream,BitLen,&idx,id_bits,sizeof(id_bits)) == 1) - // { - // setDemodBuf(BitStream,64, idx); - // PrintAndLog("Found Viking tag\n"); - // CmdPrintDemodBuff("x"); - // } - // else - // { - // PrintAndLog("Not found Viking tag\n"); - // } - return 0; -} -int AMVikingDemod(const uint8_t *id){ - // demod am clock 32 fail - if (!ASKDemod("32",g_debugMode,false,1)) - return 0; - // search for the card id from bitstream. - return AmVikingDecode(id); -} -//by Gusto -// takes 1 argument <8 bytes of Hex number on the card -// print binary found and saves in grapbuffer for further commands -int CmdAMVikingDemod(const char *Cmd){ - uint8_t id[4]; - if (param_gethex(Cmd,0,id,8) == 1) - { - PrintAndLog("Usage: data vikingdemod CardID 8 bytes of hex number"); - return 0; - } - PrintAndLog("Card ID : %02X%02X%02X%02X\n",id[0],id[1],id[2],id[3]); - // try to demod AMViking - return AMVikingDemod(id); -} - int CmdGrid(const char *Cmd) { sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); @@ -2415,6 +2366,7 @@ static command_t CommandTable[] = {"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using the length of sample differences to detect the edge of a wave (use 20-45, def:25)"}, {"askem410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"}, {"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"}, + {"askvikingdemod", CmdVikingDemod, 1, "Demodulate a Viking AM tag from GraphBuffer"}, {"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"}, {"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"}, {"bin2hex", Cmdbin2hex, 1, "bin2hex -- Converts binary to hexadecimal"}, @@ -2424,7 +2376,6 @@ static command_t CommandTable[] = {"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"}, {"fdxbdemod", CmdFDXBdemodBI , 1, "Demodulate a FDX-B ISO11784/85 Biphase tag from GraphBuffer"}, {"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate an AWID FSK tag from GraphBuffer"}, - {"vikingdemod", CmdAMVikingDemod, 1, "Demodulate a Viking AM tag from GraphBuffer"}, //{"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"}, {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate a HID FSK tag from GraphBuffer"}, {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate an IO Prox FSK tag from GraphBuffer"}, diff --git a/client/cmddata.h b/client/cmddata.h index c70f938e..c3303c54 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -17,6 +17,7 @@ int CmdData(const char *Cmd); void printDemodBuff(void); void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx); int CmdAskEM410xDemod(const char *Cmd); +int CmdVikingDemod(const char *Cmd); int CmdG_Prox_II_Demod(const char *Cmd); int Cmdaskrawdemod(const char *Cmd); int Cmdaskmandemod(const char *Cmd); @@ -67,8 +68,7 @@ int PSKDemod(const char *Cmd, bool verbose); int NRZrawDemod(const char *Cmd, bool verbose); void printEM410x(uint32_t hi, uint64_t id); int getSamples(const char *Cmd, bool silent); -int AMVikingDemod(const uint8_t *cardid); -int CmdAMVikingDemod(const char *cmd); + #define MAX_DEMOD_BUF_LEN (1024*128) extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; diff --git a/client/cmdlf.c b/client/cmdlf.c index ef5817ac..4cf9c815 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -127,6 +127,18 @@ int usage_lf_simpsk(void) { PrintAndLog(" d Data to sim as hex - omit to sim from DemodBuffer"); return 0; } +int usage_lf_find(void){ + PrintAndLog("Usage: lf search <0|1> [u]"); + PrintAndLog(" , if not set, try reading data from tag."); + PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags."); + PrintAndLog(""); + PrintAndLog(" sample: lf search = try reading data from tag & search for known tags"); + PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags"); + PrintAndLog(" : lf search u = try reading data from tag & search for known and unknown tags"); + PrintAndLog(" : lf search 1 u = use data from GraphBuffer & search for known and unknown tags"); + return 0; +} + /* send a LF command before reading */ int CmdLFCommandRead(const char *Cmd) @@ -269,191 +281,186 @@ int CmdFlexdemod(const char *Cmd) 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; - } - } - - 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); + // 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; - } + // 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; - } - } + 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; - } + 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]; - } - } + // Inverting signal if needed + if (first == 1) { + for (i = start; i < rawbit; i++) { + rawbits[i] = !rawbits[i]; + } + } - // Dumping UID + // Dumping UID uint8_t bits[224] = {0x00}; char showbits[225] = {0x00}; - int bit; - i = start; - int times = 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; - } + 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; + //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 { + 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); - + 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); - } + } + PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7); + } - // Checking UID against next occurrences - int failed = 0; + // 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; - break; - } - } - if (failed == 1) { - break; - } - times += 1; - } + 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); + PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen); - // Remodulating for tag cloning + // 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; - 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; - } - } + GraphTraceLen = 32 * uidlen; + i = 0; + int phase = 0; + for (bit = 0; bit < uidlen; bit++) { + phase = (bits[bit] == 0) ? 0 : 1; + int j; + for (j = 0; j < 32; j++) { + GraphBuffer[i++] = phase; + phase = !phase; + } + } - RepaintGraphWindow(); - return 1; + RepaintGraphWindow(); + return 1; } int CmdIndalaClone(const char *Cmd) @@ -1043,25 +1050,14 @@ int CmdVchDemod(const char *Cmd) //by marshmellow int CmdLFfind(const char *Cmd) { - int ans=0; + int ans = 0; char cmdp = param_getchar(Cmd, 0); char testRaw = param_getchar(Cmd, 1); - if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: lf search <0|1> [u]"); - PrintAndLog(" , if not set, try reading data from tag."); - PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags."); - PrintAndLog(""); - PrintAndLog(" sample: lf search = try reading data from tag & search for known tags"); - PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags"); - PrintAndLog(" : lf search u = try reading data from tag & search for known and unknown tags"); - PrintAndLog(" : lf search 1 u = use data from GraphBuffer & search for known and unknown tags"); - - return 0; - } + if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') return usage_lf_find(); if (!offline && (cmdp != '1')){ - CmdLFRead("s"); - getSamples("30000",false); + CmdLFRead("s"); + getSamples("30000",false); } else if (GraphTraceLen < 1000) { PrintAndLog("Data in Graphbuffer was too small."); return 0; @@ -1133,6 +1129,12 @@ int CmdLFfind(const char *Cmd) return 1; } + ans=CmdVikingDemod(""); + if (ans>0) { + PrintAndLog("\nValid Viking ID Found!"); + return 1; + } + ans=CmdPSKNexWatch(""); if (ans>0) { PrintAndLog("\nValid NexWatch ID Found!"); @@ -1171,15 +1173,15 @@ int CmdLFfind(const char *Cmd) } } } - ans=GetFskClock("",FALSE,FALSE); + ans=GetFskClock("",FALSE,FALSE); if (ans != 0){ //fsk - ans=FSKrawDemod("",TRUE); - if (ans>0) { - PrintAndLog("\nUnknown FSK Modulated Tag Found!"); - return 1; - } + ans=FSKrawDemod("",TRUE); + if (ans>0) { + PrintAndLog("\nUnknown FSK Modulated Tag Found!"); + return 1; + } } - ans=ASKDemod("0 0 0",TRUE,FALSE,1); + ans=ASKDemod("0 0 0",TRUE,FALSE,1); if (ans>0) { PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!"); PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'"); @@ -1187,10 +1189,10 @@ int CmdLFfind(const char *Cmd) } ans=CmdPSK1rawDemod(""); if (ans>0) { - PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'"); - PrintAndLog("\nCould also be PSK3 - [currently not supported]"); - PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod"); - return 1; + PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'"); + PrintAndLog("\nCould also be PSK3 - [currently not supported]"); + PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod"); + return 1; } PrintAndLog("\nNo Data Found!\n"); } diff --git a/client/cmdlfviking.c b/client/cmdlfviking.c index f888ba8b..e50bc878 100644 --- a/client/cmdlfviking.c +++ b/client/cmdlfviking.c @@ -12,43 +12,68 @@ #include "cmdlfviking.h" #include "lfdemod.h" static int CmdHelp(const char *Cmd); + +int usage_lf_viking_clone(void){ + PrintAndLog("clone a Viking AM tag to a T55x7 tag."); + PrintAndLog("Usage: lf viking clone "); + return 0; +} + +//by marshmellow +//see ASKDemod for what args are accepted int CmdVikingDemod(const char *Cmd) { - uint8_t id[4]; - if (param_gethex(Cmd,0,id,8) == 1) - { - PrintAndLog("Usage: lf viking demod "); - return 0; - } - UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {false,0,0}}; - SendCommand(&c); - WaitForResponse(CMD_ACK,NULL); - getSamples("40000",true); - // try to demod AMViking - return AMVikingDemod(id); + CmdLFRead("s"); + getSamples("30000",false); + + if (!ASKDemod(Cmd, false, false, 1)) { + if (g_debugMode) PrintAndLog("ASKDemod failed"); + return 0; + } + size_t size = DemodBufferLen; + + int ans = VikingDemod_AM(DemodBuffer, &size); + if (ans < 0) { + if (g_debugMode) PrintAndLog("Error Viking_Demod"); + return 0; + } + //got a good demod + uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans, 32); + uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32); + uint32_t cardid = bytebits_to_byte(DemodBuffer+ans+24, 32); + uint8_t checksum = bytebits_to_byte(DemodBuffer+ans+32+24, 8); + PrintAndLog("Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, checksum); + PrintAndLog("Raw: %08X%08X", raw1,raw2); + setDemodBuf(DemodBuffer+ans, 64, 0); + return 1; } + int CmdVikingClone(const char *Cmd) { uint32_t b1,b2; // get the tag number 64 bits (8 bytes) in hex uint8_t id[8]; - if (param_gethex(Cmd,0,id,16) == 1) - { - PrintAndLog("Usage: lf viking clone "); - return 0; - } - b1 = bytes_to_num(id,sizeof(uint32_t)); - b2 = bytes_to_num(id + sizeof(uint32_t),sizeof(uint32_t)); + + char cmdp = param_getchar(Cmd, 0); + if (strlen(Cmd) < 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_viking_clone(); + + if (param_gethex(Cmd, 0, id, 16) == 1) + return usage_lf_viking_clone(); + + b1 = bytes_to_num(id, sizeof(uint32_t)); + b2 = bytes_to_num(id + sizeof(uint32_t), sizeof(uint32_t)); UsbCommand c = {CMD_VIKING_CLONE_TAG,{b1,b2}}; - SendCommand(&c); + clearCommandBuffer(); + SendCommand(&c); + //check for ACK? return 0; } static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help"}, - {"demod",CmdVikingDemod ,1, "<8 digits tag id> -- Extract tag data"}, - {"clone", CmdVikingClone, 1, "<16 digits card data> clone viking tag"}, + {"help", CmdHelp, 1, "This help"}, + {"demod", CmdVikingDemod, 1, "Extract tag data"}, + {"clone", CmdVikingClone, 1, "<16 digits card data> clone viking tag"}, {NULL, NULL, 0, NULL} }; diff --git a/common/lfdemod.c b/common/lfdemod.c index 9a4051c9..a3689357 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -599,6 +599,26 @@ int IOdemodFSK(uint8_t *dest, size_t size) return -5; } +// by marshmellow +// find viking preamble 0xF200 in already demoded data +int VikingDemod_AM(uint8_t *dest, size_t *size) { + if (justNoise(dest, *size)) return -1; + //make sure buffer has data + if (*size < 64*2) return -2; + + size_t startIdx = 0; + uint8_t preamble[] = {1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx); + if (errChk == 0) return -4; //preamble not found + uint32_t checkCalc = bytebits_to_byte(dest+startIdx,8) ^ bytebits_to_byte(dest+startIdx+8,8) ^ bytebits_to_byte(dest+startIdx+16,8) + ^ bytebits_to_byte(dest+startIdx+24,8) ^ bytebits_to_byte(dest+startIdx+32,8) ^ bytebits_to_byte(dest+startIdx+40,8) + ^ bytebits_to_byte(dest+startIdx+48,8) ^ bytebits_to_byte(dest+startIdx+56,8); + if ( checkCalc != 0xA8 ) return -5; + if (*size != 64) return -5; + //return start position + return (int) startIdx; +} + // by marshmellow // takes a array of binary values, start position, length of bits per parity (includes parity bit), // Parity Type (1 for odd; 0 for even; 2 Always 1's), and binary Length (length to run) @@ -1505,30 +1525,3 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert) *size = numBits; return errCnt; } -// on successful return 1 otherwise return 0 -int VikingDecode(uint8_t *BitStream, - size_t size, - size_t *startIdx, - uint8_t *id_bits, - size_t id_bits_size) -{ - //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future - // otherwise could be a void with no arguments - //set defaults - uint32_t i = 0; - uint32_t lastcheckindex = size - (id_bits_size * 2); - int found = 0; - while (i < lastcheckindex) - { - if (memcmp(BitStream + i,id_bits,id_bits_size) == 0) - { - *startIdx = i; - found = 1; - break; - } - i++; - } - return found; -} - - diff --git a/common/lfdemod.h b/common/lfdemod.h index 5cf87058..cc4fa27a 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -48,8 +48,8 @@ int gProxII_Demod(uint8_t BitStream[], size_t *size); int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); int IOdemodFSK(uint8_t *dest, size_t size); int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert); -int PyramiddemodFSK(uint8_t *dest, size_t *size); int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); -int VikingDecode(uint8_t *BitStream, size_t size, size_t *startIdx,uint8_t *id_bit,size_t id_bits_size); +int PyramiddemodFSK(uint8_t *dest, size_t *size); +int VikingDemod_AM(uint8_t *dest, size_t *size); #endif -- 2.39.5