From acaeccf841f65291f5687824cb5322cc661e8183 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Fri, 3 Apr 2015 00:40:38 -0400 Subject: [PATCH 01/16] update changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f3f84ef..72674ec5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,12 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [Unreleased][unreleased] ### Changed +- Improved LF manchester and biphase demodulation and ask clock detection especially for reads with heavy clipping. (marshmellow) - Iclass read, `hf iclass read` now also reads tag config and prints configuration. (holiman) ### Fixed -- Fixed issue #19, problems with LF T55xx commands (marshmellow) +- Fixed EM4x50 read/demod of the tags broadcasted memory blocks. 'lf em4x em4x50read' (not page read) (marshmellow) +- Fixed issue #19, problems with LF T55xx commands (iceman1001, marshmellow) ### Added - Added changelog -- 2.39.5 From 2767fc02919545bd65082b4682b2331def9a5ad5 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 5 Apr 2015 00:58:57 -0400 Subject: [PATCH 02/16] lf cleaning remove unneeded code/functions fix lfdemod askmandemod bug with maxErr=0 silence output for getting samples in lf search --- client/cmddata.c | 747 +++++--------------------------------------- client/cmddata.h | 8 - client/cmdlf.c | 54 +--- client/cmdlf.h | 1 - client/cmdlfem4x.c | 3 +- client/cmdlfhid.c | 6 +- client/cmdlfhid.h | 4 +- client/cmdlfio.c | 8 +- client/cmdlft55xx.c | 135 +++----- client/graph.c | 4 +- client/util.c | 15 +- client/util.h | 1 + common/lfdemod.c | 38 +-- 13 files changed, 170 insertions(+), 854 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 84a450f8..e2e2ca6d 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -58,37 +58,16 @@ int CmdSetDebugMode(const char *Cmd) //by marshmellow void printDemodBuff(void) { - uint32_t i = 0; int bitLen = DemodBufferLen; - if (bitLen<16) { + if (bitLen<1) { PrintAndLog("no bits found in demod buffer"); return; } if (bitLen>512) bitLen=512; //max output to 512 bits if we have more - should be plenty - // ensure equally divided by 16 - bitLen &= 0xfff0; - - for (i = 0; i <= (bitLen-16); i+=16) { - PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", - DemodBuffer[i], - DemodBuffer[i+1], - DemodBuffer[i+2], - DemodBuffer[i+3], - DemodBuffer[i+4], - DemodBuffer[i+5], - DemodBuffer[i+6], - DemodBuffer[i+7], - DemodBuffer[i+8], - DemodBuffer[i+9], - DemodBuffer[i+10], - DemodBuffer[i+11], - DemodBuffer[i+12], - DemodBuffer[i+13], - DemodBuffer[i+14], - DemodBuffer[i+15] - ); - } + char *bin = sprint_bin_break(DemodBuffer,bitLen,16); + PrintAndLog("%s",bin); + return; } @@ -114,105 +93,8 @@ int CmdPrintDemodBuff(const char *Cmd) } return 1; } -int CmdAmp(const char *Cmd) -{ - 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(); - return 0; -} - -/* - * Generic command to demodulate ASK. - * - * Argument is convention: positive or negative (High mod means zero - * or high mod means one) - * - * Updates the Graph trace with 0/1 values - * - * Arguments: - * c : 0 or 1 (or invert) - */ - //this method ignores the clock - - //this function strictly converts highs and lows to 1s and 0s for each sample in the graphbuffer -int Cmdaskdemod(const char *Cmd) -{ - int i; - int c, high = 0, low = 0; - - sscanf(Cmd, "%i", &c); - - /* Detect high and lows */ - for (i = 0; i < GraphTraceLen; ++i) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } - high=abs(high*.75); - low=abs(low*.75); - if (c != 0 && c != 1) { - PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } - //prime loop - if (GraphBuffer[0] > 0) { - GraphBuffer[0] = 1-c; - } else { - GraphBuffer[0] = c; - } - for (i = 1; i < GraphTraceLen; ++i) { - /* Transitions are detected at each peak - * Transitions are either: - * - we're low: transition if we hit a high - * - we're high: transition if we hit a low - * (we need to do it this way because some tags keep high or - * low for long periods, others just reach the peak and go - * down) - */ - //[marhsmellow] change == to >= for high and <= for low for fuzz - if ((GraphBuffer[i] >= high) && (GraphBuffer[i - 1] == c)) { - GraphBuffer[i] = 1 - c; - } else if ((GraphBuffer[i] <= low) && (GraphBuffer[i - 1] == (1 - c))){ - GraphBuffer[i] = c; - } else { - /* No transition */ - GraphBuffer[i] = GraphBuffer[i - 1]; - } - } - RepaintGraphWindow(); - return 0; -} +//by marshmellow //this function strictly converts >1 to 1 and <1 to 0 for each sample in the graphbuffer int CmdGetBitStream(const char *Cmd) { @@ -229,43 +111,6 @@ int CmdGetBitStream(const char *Cmd) return 0; } - -//by marshmellow -void printBitStream(uint8_t BitStream[], uint32_t bitLen) -{ - uint32_t i = 0; - if (bitLen<16) { - PrintAndLog("Too few bits found: %d",bitLen); - return; - } - if (bitLen>512) bitLen=512; - - // ensure equally divided by 16 - bitLen &= 0xfff0; - - - for (i = 0; i <= (bitLen-16); i+=16) { - PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i", - BitStream[i], - BitStream[i+1], - BitStream[i+2], - BitStream[i+3], - BitStream[i+4], - BitStream[i+5], - BitStream[i+6], - BitStream[i+7], - BitStream[i+8], - BitStream[i+9], - BitStream[i+10], - BitStream[i+11], - BitStream[i+12], - BitStream[i+13], - BitStream[i+14], - BitStream[i+15] - ); - } - return; -} //by marshmellow //print 64 bit EM410x ID in multiple formats void printEM410x(uint32_t hi, uint64_t id) @@ -282,11 +127,11 @@ void printEM410x(uint32_t hi, uint64_t id) } if (hi){ //output 88 bit em id - PrintAndLog("\nEM TAG ID : %06x%016llx", hi, id); + PrintAndLog("\nEM TAG ID : %06X%016llX", hi, id); } else{ //output 40 bit em id - PrintAndLog("\nEM TAG ID : %010llx", id); - PrintAndLog("Unique TAG ID : %010llx", id2lo); + PrintAndLog("\nEM TAG ID : %010llX", id); + PrintAndLog("Unique TAG ID : %010llX", id2lo); PrintAndLog("\nPossible de-scramble patterns"); PrintAndLog("HoneyWell IdentKey {"); PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF); @@ -311,7 +156,7 @@ void printEM410x(uint32_t hi, uint64_t id) ); uint64_t paxton = (((id>>32) << 24) | (id & 0xffffff)) + 0x143e00; PrintAndLog("}\nOther : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF)); - PrintAndLog("Pattern Paxton : %0d", paxton); + PrintAndLog("Pattern Paxton : %lld [0x%llX]", paxton, paxton); uint32_t p1id = (id & 0xFFFFFF); uint8_t arr[32] = {0x00}; @@ -352,12 +197,12 @@ void printEM410x(uint32_t hi, uint64_t id) p1 |= arr[2] << 4; p1 |= arr[1] << 5; p1 |= arr[0] << 9; - PrintAndLog("Pattern 1 : 0x%X - %d", p1, p1); + PrintAndLog("Pattern 1 : %d [0x%X]", p1, p1); uint16_t sebury1 = id & 0xFFFF; uint8_t sebury2 = (id >> 16) & 0x7F; uint32_t sebury3 = id & 0x7FFFFF; - PrintAndLog("Pattern Sebury : %d %d %d (hex: %X %X %X)", sebury1, sebury2, sebury3, sebury1, sebury2, sebury3); + PrintAndLog("Pattern Sebury : %d %d %d [0x%X 0x%X 0x%X]", sebury1, sebury2, sebury3, sebury1, sebury2, sebury3); } } return; @@ -430,20 +275,23 @@ int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch) clk=0; } size_t BitLen = getFromGraphBuf(BitStream); - if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); - if (BitLen==0) return 0; - int errCnt=0; + if (g_debugMode) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); + if (!BitLen) return 0; if (maxLenmaxErr){ + if (g_debugMode) PrintAndLog("DEBUG: Too many errors found, errors:%d, bits:%d, clock:%d",errCnt, BitLen, clk); + return 0; + } + if (verbose || g_debugMode) PrintAndLog("\nUsing Clock:%d, Invert:%d, Bits Found:%d",clk,invert,BitLen); //output if (errCnt>0){ - if (verbose || g_debugMode) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + if (verbose || g_debugMode) PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d",errCnt); } if (verbose || g_debugMode) PrintAndLog("ASK/Manchester decoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits @@ -519,7 +367,7 @@ int Cmdmandecoderaw(const char *Cmd) BitStream[i]=DemodBuffer[i]; } if (high>1 || low <0 ){ - PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode"); + PrintAndLog("Error: please raw demod the wave first then manchester raw decode"); return 0; } size=i; @@ -529,7 +377,7 @@ int Cmdmandecoderaw(const char *Cmd) return 0; } PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt); - printBitStream(BitStream, size); + PrintAndLog("%s", sprint_bin_break(BitStream, size, 16)); if (errCnt==0){ uint64_t id = 0; uint32_t hi = 0; @@ -549,11 +397,7 @@ int Cmdmandecoderaw(const char *Cmd) //take 01 or 10 = 0 and 11 or 00 = 1 //takes 2 arguments "offset" default = 0 if 1 it will shift the decode by one bit // and "invert" default = 0 if 1 it will invert output -// since it is not like manchester and doesn't have an incorrect bit pattern we -// cannot determine if our decode is correct or if it should be shifted by one bit -// the argument offset allows us to manually shift if the output is incorrect -// (better would be to demod and decode at the same time so we can distinguish large -// width waves vs small width waves to help the decode positioning) or askbiphdemod +// the argument offset allows us to manually shift if the output is incorrect - [EDIT: now auto detects] int CmdBiphaseDecodeRaw(const char *Cmd) { size_t size=0; @@ -592,39 +436,15 @@ int CmdBiphaseDecodeRaw(const char *Cmd) } if (errCnt>0){ - PrintAndLog("# Errors found during Demod (shown as 77 in bit stream): %d",errCnt); + PrintAndLog("# Errors found during Demod (shown as 7 in bit stream): %d",errCnt); } PrintAndLog("Biphase Decoded using offset: %d - # invert:%d - data:",offset,invert); - printBitStream(BitStream, size); + PrintAndLog("%s", sprint_bin_break(BitStream, size, 16)); if (offset) setDemodBuf(DemodBuffer,DemodBufferLen-offset, offset); //remove first bit from raw demod return 1; } -// set demod buffer back to raw after biphase demod -void setBiphasetoRawDemodBuf(uint8_t *BitStream, size_t size) -{ - uint8_t rawStream[512]={0x00}; - size_t i=0; - uint8_t curPhase=0; - if (size > 256) { - PrintAndLog("ERROR - Biphase Demod Buffer overrun"); - return; - } - for (size_t idx=0; idxmaxErr) { + if (g_debugMode) + PrintAndLog("Too many errors found, errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert); + return 0; + } + if (verbose || g_debugMode) + PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen); //move BitStream back to DemodBuffer setDemodBuf(BitStream,BitLen,0); //output if (errCnt>0 && (verbose || g_debugMode)){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d", errCnt); + PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d", errCnt); } if (verbose || g_debugMode){ PrintAndLog("ASK demoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits - printBitStream(BitStream,BitLen); + printDemodBuff(); } return 1; } @@ -937,67 +762,6 @@ int CmdBitsamples(const char *Cmd) return 0; } -/* - * Convert to a bitstream - */ -int CmdBitstream(const char *Cmd) -{ - int i, j; - int bit; - int gtl; - int clock; - int low = 0; - int high = 0; - int hithigh, hitlow, first; - - /* Detect high and lows and clock */ - for (i = 0; i < GraphTraceLen; ++i) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } - - /* Get our clock */ - clock = GetAskClock(Cmd, high, 1); - gtl = ClearGraph(0); - - bit = 0; - for (i = 0; i < (int)(gtl / clock); ++i) - { - hithigh = 0; - hitlow = 0; - first = 1; - /* Find out if we hit both high and low peaks */ - for (j = 0; j < clock; ++j) - { - if (GraphBuffer[(i * clock) + j] == high) - hithigh = 1; - else if (GraphBuffer[(i * clock) + j] == low) - hitlow = 1; - /* it doesn't count if it's the first part of our read - because it's really just trailing from the last sequence */ - if (first && (hithigh || hitlow)) - hithigh = hitlow = 0; - else - first = 0; - - if (hithigh && hitlow) - break; - } - - /* If we didn't hit both high and low peaks, we had a bit transition */ - if (!hithigh || !hitlow) - bit ^= 1; - - AppendGraph(0, clock, bit); - } - - RepaintGraphWindow(); - return 0; -} - int CmdBuffClear(const char *Cmd) { UsbCommand c = {CMD_BUFF_CLEAR}; @@ -1076,7 +840,7 @@ int CmdGraphShiftZero(const char *Cmd) //by marshmellow //use large jumps in read samples to identify edges of waves and then amplify that wave to max -//similar to dirtheshold, threshold, and askdemod commands +//similar to dirtheshold, threshold commands //takes a threshold length which is the measured length between two samples then determines an edge int CmdAskEdgeDetect(const char *Cmd) { @@ -1134,6 +898,25 @@ int CmdDetectClockRate(const char *Cmd) return ans; } +char *GetFSKType(uint8_t fchigh, uint8_t fclow, uint8_t invert) +{ + char *fskType; + if (fchigh==10 && fclow==8){ + if (invert) //fsk2a + fskType = "FSK2a"; + else //fsk2 + fskType = "FSK2"; + } else if (fchigh == 8 && fclow == 5) { + if (invert) + fskType = "FSK1"; + else + fskType = "FSK1a"; + } else { + fskType = "FSK??"; + } + return fskType; +} + //by marshmellow //fsk raw demod and print binary //takes 4 arguments - Clock, invert, fchigh, fclow @@ -1177,21 +960,20 @@ int FSKrawDemod(const char *Cmd, bool verbose) rfLen = detectFSKClk(BitStream, BitLen, fchigh, fclow); if (rfLen == 0) rfLen = 50; } - if (verbose) PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow); int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow); if (size>0){ setDemodBuf(BitStream,size,0); // Now output the bitstream to the scrollback by line of 16 bits - if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size - if (verbose) { - PrintAndLog("FSK decoded bitstream:"); - printBitStream(BitStream,size); + if (verbose || g_debugMode) { + PrintAndLog("\nUsing Clock:%d, invert:%d, fchigh:%d, fclow:%d", rfLen, invert, fchigh, fclow); + PrintAndLog("%s decoded bitstream:",GetFSKType(fchigh,fclow,invert)); + printDemodBuff(); } return 1; } else{ - if (verbose) PrintAndLog("no FSK data found"); + if (g_debugMode) PrintAndLog("no FSK data found"); } return 0; } @@ -1395,9 +1177,9 @@ int CmdFSKdemodIO(const char *Cmd) return 0; } if (idx==0){ - if (g_debugMode==1){ + if (g_debugMode){ PrintAndLog("DEBUG: IO Prox Data not found - FSK Bits: %d",BitLen); - if (BitLen > 92) printBitStream(BitStream,92); + if (BitLen > 92) PrintAndLog("%s", sprint_bin_break(BitStream,92,16)); } return 0; } @@ -1411,7 +1193,7 @@ int CmdFSKdemodIO(const char *Cmd) //XSF(version)facility:codeone+codetwo (raw) //Handle the data if (idx+64>BitLen) { - if (g_debugMode==1) PrintAndLog("not enough bits found - bitlen: %d",BitLen); + if (g_debugMode) PrintAndLog("not enough bits found - bitlen: %d",BitLen); return 0; } PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]); @@ -1432,7 +1214,6 @@ int CmdFSKdemodIO(const char *Cmd) for (uint8_t i=1; i<6; ++i){ calccrc += bytebits_to_byte(BitStream+idx+9*i,8); - //PrintAndLog("%d", calccrc); } calccrc &= 0xff; calccrc = 0xff - calccrc; @@ -1690,124 +1471,6 @@ int CmdFSKdemodPyramid(const char *Cmd) return 1; } -int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating -{ - 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, - }; - - int lowLen = sizeof (LowTone) / sizeof (int); - int highLen = sizeof (HighTone) / sizeof (int); - int convLen = (highLen > lowLen) ? highLen : lowLen; - uint32_t 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 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] < minMark) minMark = GraphBuffer[i]; - } - - GraphTraceLen -= (convLen + 16); - RepaintGraphWindow(); - - // Find bit-sync (3 lo followed by 3 high) (HID ONLY) - int max = 0, maxPos = 0; - for (i = 0; i < 6000; ++i) { - int dec = 0; - for (j = 0; j < 3 * lowLen; ++j) { - dec -= GraphBuffer[i + j]; - } - for (; j < 3 * (lowLen + highLen ); ++j) { - dec += GraphBuffer[i + j]; - } - if (dec > 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; - - PrintAndLog("actual data bits start at sample %d", maxPos); - PrintAndLog("length %d/%d", highLen, lowLen); - - uint8_t bits[46] = {0x00}; - - // 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'; - } - } - PrintAndLog("bits: '%s'", bits); - PrintAndLog("hex: %08x %08x", hi, lo); - return 0; -} - //by marshmellow //attempt to psk1 demod graph buffer int PSKDemod(const char *Cmd, bool verbose) @@ -1835,17 +1498,17 @@ int PSKDemod(const char *Cmd, bool verbose) int errCnt=0; errCnt = pskRawDemod(BitStream, &BitLen, &clk, &invert); if (errCnt > maxErr){ - if (g_debugMode==1 && verbose) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + if (g_debugMode || verbose) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); return 0; } if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) - if (g_debugMode==1 && verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); + if (g_debugMode || verbose) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt); return 0; } - if (verbose){ - PrintAndLog("Tried PSK Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen); + if (verbose || g_debugMode){ + PrintAndLog("\nUsing Clock:%d, invert:%d, Bits Found:%d",clk,invert,BitLen); if (errCnt>0){ - PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d",errCnt); } } //prime demod buffer for output @@ -1970,7 +1633,7 @@ int NRZrawDemod(const char *Cmd, bool verbose) //prime demod buffer for output setDemodBuf(BitStream,BitLen,0); - if (errCnt>0 && (verbose || g_debugMode)) PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + if (errCnt>0 && (verbose || g_debugMode)) PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d",errCnt); if (verbose || g_debugMode) { PrintAndLog("NRZ demoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits @@ -2026,7 +1689,7 @@ int CmdPSK1rawDemod(const char *Cmd) return 0; } - PrintAndLog("PSK demoded bitstream:"); + PrintAndLog("PSK1 demoded bitstream:"); // Now output the bitstream to the scrollback by line of 16 bits printDemodBuff(); return 1; @@ -2295,10 +1958,10 @@ int CmdTuneSamples(const char *Cmd) PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1)); PrintAndLog("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0); -#define LF_UNUSABLE_V 2948 // was 2000. Changed due to bugfix in voltage measurements. LF results are now 47% higher. -#define LF_MARGINAL_V 14739 // was 10000. Changed due to bugfix bug in voltage measurements. LF results are now 47% higher. -#define HF_UNUSABLE_V 3167 // was 2000. Changed due to bugfix in voltage measurements. HF results are now 58% higher. -#define HF_MARGINAL_V 7917 // was 5000. Changed due to bugfix in voltage measurements. HF results are now 58% higher. + #define LF_UNUSABLE_V 2948 // was 2000. Changed due to bugfix in voltage measurements. LF results are now 47% higher. + #define LF_MARGINAL_V 14739 // was 10000. Changed due to bugfix bug in voltage measurements. LF results are now 47% higher. + #define HF_UNUSABLE_V 3167 // was 2000. Changed due to bugfix in voltage measurements. HF results are now 58% higher. + #define HF_MARGINAL_V 7917 // was 5000. Changed due to bugfix in voltage measurements. HF results are now 58% higher. if (peakv < LF_UNUSABLE_V) PrintAndLog("# Your LF antenna is unusable."); @@ -2374,245 +2037,6 @@ int CmdRtrim(const char *Cmd) return 0; } -/* - * Manchester demodulate a bitstream. The bitstream needs to be already in - * the GraphBuffer as 0 and 1 values - * - * Give the clock rate as argument in order to help the sync - the algorithm - * resyncs at each pulse anyway. - * - * Not optimized by any means, this is the 1st time I'm writing this type of - * routine, feel free to improve... - * - * 1st argument: clock rate (as number of samples per clock rate) - * Typical values can be 64, 32, 128... - */ -int CmdManchesterDemod(const char *Cmd) -{ - int i, j, invert= 0; - int bit; - int clock; - int lastval = 0; - int low = 0; - int high = 0; - int hithigh, hitlow, first; - int lc = 0; - int bitidx = 0; - int bit2idx = 0; - int warnings = 0; - - /* check if we're inverting output */ - if (*Cmd == 'i') - { - PrintAndLog("Inverting output"); - invert = 1; - ++Cmd; - do - ++Cmd; - while(*Cmd == ' '); // in case a 2nd argument was given - } - - /* Holds the decoded bitstream: each clock period contains 2 bits */ - /* later simplified to 1 bit after manchester decoding. */ - /* Add 10 bits to allow for noisy / uncertain traces without aborting */ - /* int BitStream[GraphTraceLen*2/clock+10]; */ - - /* But it does not work if compiling on WIndows: therefore we just allocate a */ - /* large array */ - uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0}; - - /* Detect high and lows */ - for (i = 0; i < GraphTraceLen; i++) - { - if (GraphBuffer[i] > high) - high = GraphBuffer[i]; - else if (GraphBuffer[i] < low) - low = GraphBuffer[i]; - } - - /* Get our clock */ - clock = GetAskClock(Cmd, high, 1); - - int tolerance = clock/4; - - /* Detect first transition */ - /* Lo-Hi (arbitrary) */ - /* 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) - { - lastval = i; - break; - } - } - - /* If we're not working with 1/0s, demod based off clock */ - if (high != 1) - { - bit = 0; /* We assume the 1st bit is zero, it may not be - * the case: this routine (I think) has an init problem. - * Ed. - */ - for (; i < (int)(GraphTraceLen / clock); i++) - { - hithigh = 0; - hitlow = 0; - first = 1; - - /* Find out if we hit both high and low peaks */ - for (j = 0; j < clock; j++) - { - if (GraphBuffer[(i * clock) + j] == high) - hithigh = 1; - else if (GraphBuffer[(i * clock) + j] == low) - hitlow = 1; - - /* it doesn't count if it's the first part of our read - because it's really just trailing from the last sequence */ - if (first && (hithigh || hitlow)) - hithigh = hitlow = 0; - else - first = 0; - - 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 ^ invert; - } - } - - /* standard 1/0 bitstream */ - else - { - - /* Then detect duration between 2 successive transitions */ - for (bitidx = 1; i < GraphTraceLen; i++) - { - if (GraphBuffer[i-1] != GraphBuffer[i]) - { - lc = i-lastval; - lastval = i; - - // Error check: if bitidx becomes too large, we do not - // have a Manchester encoded bitstream or the clock is really - // wrong! - if (bitidx > (GraphTraceLen*2/clock+8) ) { - PrintAndLog("Error: the clock you gave is probably wrong, aborting."); - return 0; - } - // Then switch depending on lc length: - // Tolerance is 1/4 of clock rate (arbitrary) - if (abs(lc-clock/2) < tolerance) { - // Short pulse : either "1" or "0" - BitStream[bitidx++]=GraphBuffer[i-1]; - } else if (abs(lc-clock) < tolerance) { - // Long pulse: either "11" or "00" - BitStream[bitidx++]=GraphBuffer[i-1]; - BitStream[bitidx++]=GraphBuffer[i-1]; - } else { - // Error - warnings++; - PrintAndLog("Warning: Manchester decode error for pulse width detection."); - PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)"); - - if (warnings > 10) - { - PrintAndLog("Error: too many detection errors, aborting."); - return 0; - } - } - } - } - - // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream - // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful - // to stop output at the final bitidx2 value, not bitidx - for (i = 0; i < bitidx; i += 2) { - if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) { - BitStream[bit2idx++] = 1 ^ invert; - } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) { - BitStream[bit2idx++] = 0 ^ invert; - } else { - // We cannot end up in this state, this means we are unsynchronized, - // move up 1 bit: - i++; - warnings++; - PrintAndLog("Unsynchronized, resync..."); - PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)"); - - if (warnings > 10) - { - PrintAndLog("Error: too many decode errors, aborting."); - return 0; - } - } - } - } - - PrintAndLog("Manchester decoded bitstream"); - // Now output the bitstream to the scrollback by line of 16 bits - for (i = 0; i < (bit2idx-16); i+=16) { - PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i", - BitStream[i], - BitStream[i+1], - BitStream[i+2], - BitStream[i+3], - BitStream[i+4], - BitStream[i+5], - BitStream[i+6], - BitStream[i+7], - BitStream[i+8], - BitStream[i+9], - BitStream[i+10], - BitStream[i+11], - BitStream[i+12], - BitStream[i+13], - BitStream[i+14], - BitStream[i+15]); - } - return 0; -} - -/* Modulate our data into manchester */ -int CmdManchesterMod(const char *Cmd) -{ - int i, j; - int clock; - int bit, lastbit, wave; - - /* Get our clock */ - clock = GetAskClock(Cmd, 0, 1); - - wave = 0; - lastbit = 1; - for (i = 0; i < (int)(GraphTraceLen / clock); i++) - { - bit = GraphBuffer[i * clock] ^ 1; - - for (j = 0; j < (int)(clock/2); j++) - GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave; - for (j = (int)(clock/2); j < clock; j++) - GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1; - - /* Keep track of how we start our wave and if we changed or not this time */ - wave ^= bit ^ lastbit; - lastbit = bit; - } - - RepaintGraphWindow(); - return 0; -} - int CmdNorm(const char *Cmd) { int i; @@ -2677,20 +2101,6 @@ int CmdScale(const char *Cmd) return 0; } -int CmdThreshold(const char *Cmd) -{ - int threshold = atoi(Cmd); - - for (int i = 0; i < GraphTraceLen; ++i) { - if (GraphBuffer[i] >= threshold) - GraphBuffer[i] = 1; - else - GraphBuffer[i] = -1; - } - RepaintGraphWindow(); - return 0; -} - int CmdDirectionalThreshold(const char *Cmd) { int8_t upThres = param_get8(Cmd, 0); @@ -2758,19 +2168,15 @@ int CmdZerocrossings(const char *Cmd) static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, - {"amp", CmdAmp, 1, "Amplify peaks"}, - //{"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, {"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave (default = 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"}, {"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"}, {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"}, {"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, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"}, - //{"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, {"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate an AWID FSK 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"}, @@ -2785,9 +2191,7 @@ static command_t CommandTable[] = {"load", CmdLoad, 1, " -- Load trace (to graph window"}, {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, {"rtrim", CmdRtrim, 1, " -- Trim samples from right of trace"}, - //{"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"}, {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream in DemodBuffer"}, - {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"}, {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, {"printdemodbuffer",CmdPrintDemodBuff, 1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"}, @@ -2798,7 +2202,6 @@ static command_t CommandTable[] = {"scale", CmdScale, 1, " -- Set cursor display scale"}, {"setdebugmode", CmdSetDebugMode, 1, "<0|1> -- Turn on or off Debugging Mode for demods"}, {"shiftgraphzero", CmdGraphShiftZero, 1, " -- Shift 0 for Graphed wave + or - shift value"}, - //{"threshold", CmdThreshold, 1, " -- Maximize/minimize every value in the graph window depending on threshold"}, {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, {"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"}, {"undec", CmdUndec, 1, "Un-decimate samples by 2"}, diff --git a/client/cmddata.h b/client/cmddata.h index 97bfdbcc..0d2e32d6 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -15,10 +15,7 @@ command_t * CmdDataCommands(); int CmdData(const char *Cmd); void printDemodBuff(void); -void printBitStream(uint8_t BitStream[], uint32_t bitLen); void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx); -int CmdAmp(const char *Cmd); -int Cmdaskdemod(const char *Cmd); int CmdAskEM410xDemod(const char *Cmd); int CmdG_Prox_II_Demod(const char *Cmd); int Cmdaskrawdemod(const char *Cmd); @@ -27,12 +24,10 @@ int AutoCorrelate(int window, bool SaveGrph, bool verbose); int CmdAutoCorr(const char *Cmd); int CmdBiphaseDecodeRaw(const char *Cmd); int CmdBitsamples(const char *Cmd); -int CmdBitstream(const char *Cmd); int CmdBuffClear(const char *Cmd); int CmdDec(const char *Cmd); int CmdDetectClockRate(const char *Cmd); int CmdFSKdemodAWID(const char *Cmd); -int CmdFSKdemod(const char *Cmd); int CmdFSKdemodHID(const char *Cmd); int CmdFSKdemodIO(const char *Cmd); int CmdFSKdemodParadox(const char *Cmd); @@ -49,8 +44,6 @@ int CmdLoad(const char *Cmd); int CmdLtrim(const char *Cmd); int CmdRtrim(const char *Cmd); int Cmdmandecoderaw(const char *Cmd); -int CmdManchesterDemod(const char *Cmd); -int CmdManchesterMod(const char *Cmd); int CmdNorm(const char *Cmd); int CmdNRZrawDemod(const char *Cmd); int CmdPlot(const char *Cmd); @@ -60,7 +53,6 @@ int CmdSamples(const char *Cmd); int CmdTuneSamples(const char *Cmd); int CmdSave(const char *Cmd); int CmdScale(const char *Cmd); -int CmdThreshold(const char *Cmd); int CmdDirectionalThreshold(const char *Cmd); int CmdZerocrossings(const char *Cmd); int CmdIndalaDecode(const char *Cmd); diff --git a/client/cmdlf.c b/client/cmdlf.c index 3d29fc07..a52e1423 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -522,7 +522,8 @@ static void ChkBitstream(const char *str) } } } -//appears to attempt to simulate manchester +//Attempt to simulate any wave in buffer (one bit per output sample) +// converts GraphBuffer to bitstream (based on zero crossings) if needed. int CmdLFSim(const char *Cmd) { int i,j; @@ -530,11 +531,11 @@ int CmdLFSim(const char *Cmd) sscanf(Cmd, "%i", &gap); - /* convert to bitstream if necessary */ + // convert to bitstream if necessary ChkBitstream(Cmd); - //can send 512 bits at a time (1 byte sent per bit...) + //can send only 512 bits at a time (1 byte sent per bit...) printf("Sending [%d bytes]", GraphTraceLen); for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) { UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}}; @@ -606,8 +607,8 @@ int usage_lf_simpsk(void) // - allow pull data from DemodBuffer int CmdLFfskSim(const char *Cmd) { - //might be able to autodetect FC and clock from Graphbuffer if using demod buffer - //will need FChigh, FClow, Clock, and bitstream + //might be able to autodetect FCs and clock from Graphbuffer if using demod buffer + // otherwise will need FChigh, FClow, Clock, and bitstream uint8_t fcHigh=0, fcLow=0, clk=0; uint8_t invert=0; bool errors = FALSE; @@ -682,6 +683,8 @@ int CmdLFfskSim(const char *Cmd) } else { setDemodBuf(data, dataLen, 0); } + + //default if not found if (clk == 0) clk = 50; if (fcHigh == 0) fcHigh = 10; if (fcLow == 0) fcLow = 8; @@ -706,9 +709,8 @@ int CmdLFfskSim(const char *Cmd) int CmdLFaskSim(const char *Cmd) { //autodetect clock from Graphbuffer if using demod buffer - //will need clock, invert, manchester/raw as m or r, separator as s, and bitstream + // needs clock, invert, manchester/raw as m or r, separator as s, and bitstream uint8_t encoding = 1, separator = 0; - //char cmdp = Cmd[0], par3='m', par4=0; uint8_t clk=0, invert=0; bool errors = FALSE; char hexData[32] = {0x00}; @@ -913,30 +915,6 @@ int CmdLFSimBidir(const char *Cmd) 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]; - - sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap); - - ClearGraph(0); - - for (int i = 0; i < strlen(data) ; ++i) - AppendGraph(0, clock, data[i]- '0'); - - CmdManchesterMod(""); - - RepaintGraphWindow(); - - sprintf(&gapstring[0], "%i", gap); - CmdLFSim(gapstring); - return 0; -} -*/ - int CmdVchDemod(const char *Cmd) { // Is this the entire sync pattern, or does this also include some @@ -1033,8 +1011,8 @@ int CmdLFfind(const char *Cmd) } if (!offline && (cmdp != '1')){ - ans=CmdLFRead(""); - ans=CmdSamples("20000"); + CmdLFRead("s"); + getSamples("30000",false); } else if (GraphTraceLen < 1000) { PrintAndLog("Data in Graphbuffer was too small."); return 0; @@ -1105,20 +1083,18 @@ int CmdLFfind(const char *Cmd) PrintAndLog("\nChecking for Unknown tags:\n"); ans=AutoCorrelate(4000, FALSE, FALSE); if (ans > 0) PrintAndLog("Possible Auto Correlation of %d repeating samples",ans); - ans=GetFskClock("",FALSE,FALSE); //CmdDetectClockRate("F"); // + ans=GetFskClock("",FALSE,FALSE); if (ans != 0){ //fsk - ans=FSKrawDemod("",FALSE); + ans=FSKrawDemod("",TRUE); if (ans>0) { PrintAndLog("\nUnknown FSK Modulated Tag Found!"); - printDemodBuff(); return 1; } } - ans=ASKmanDemod("",FALSE,FALSE); + ans=ASKmanDemod("0 0 0",TRUE,FALSE); 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'"); - printDemodBuff(); return 1; } ans=CmdPSK1rawDemod(""); @@ -1126,7 +1102,6 @@ int CmdLFfind(const char *Cmd) 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"); - printDemodBuff(); return 1; } PrintAndLog("\nNo Data Found!\n"); @@ -1152,7 +1127,6 @@ static command_t CommandTable[] = {"simfsk", CmdLFfskSim, 0, "[c ] [i] [H ] [L ] [d ] -- Simulate LF FSK tag from demodbuffer or input"}, {"simpsk", CmdLFpskSim, 0, "[1|2|3] [c ] [i] [r ] [d ] -- Simulate LF PSK tag from demodbuffer or input"}, {"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... }"}, diff --git a/client/cmdlf.h b/client/cmdlf.h index 254d8807..7dd1b044 100644 --- a/client/cmdlf.h +++ b/client/cmdlf.h @@ -23,7 +23,6 @@ int CmdLFaskSim(const char *Cmd); int CmdLFfskSim(const char *Cmd); int CmdLFpskSim(const char *Cmd); int CmdLFSimBidir(const char *Cmd); -//int CmdLFSimManchester(const char *Cmd); int CmdLFSnoop(const char *Cmd); int CmdVchDemod(const char *Cmd); int CmdLFfind(const char *Cmd); diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 47a5ac3e..552c256e 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -140,7 +140,6 @@ int CmdEM410xSim(const char *Cmd) * rate gets lower, then grow the number of samples * Changed by martin, 4000 x 4 = 16000, * see http://www.proxmark.org/forum/viewtopic.php?pid=7235#p7235 - */ int CmdEM410xWatch(const char *Cmd) { @@ -151,7 +150,7 @@ int CmdEM410xWatch(const char *Cmd) } CmdLFRead("s"); - getSamples("8192",true); //capture enough to get 2 full messages + getSamples("8201",true); //capture enough to get 2 complete preambles (4096*2+9) } while (!CmdEM410xRead("")); return 0; diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index c6d54e78..4e103f1a 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -17,7 +17,7 @@ #include "cmdlfhid.h" static int CmdHelp(const char *Cmd); - +/* int CmdHIDDemod(const char *Cmd) { if (GraphTraceLen < 4800) { @@ -36,7 +36,7 @@ int CmdHIDDemod(const char *Cmd) RepaintGraphWindow(); return 0; } - +*/ int CmdHIDDemodFSK(const char *Cmd) { int findone=0; @@ -106,7 +106,7 @@ int CmdHIDClone(const char *Cmd) static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, - {"demod", CmdHIDDemod, 1, "Demodulate HID Prox Card II (not optimal)"}, + //{"demod", CmdHIDDemod, 1, "Demodulate HID Prox Card II (not optimal)"}, {"fskdemod", CmdHIDDemodFSK, 0, "['1'] Realtime HID FSK demodulator (option '1' for one tag only)"}, {"sim", CmdHIDSim, 0, " -- HID tag simulator"}, {"clone", CmdHIDClone, 0, " ['l'] -- Clone HID to T55x7 (tag must be in antenna)(option 'l' for 84bit ID)"}, diff --git a/client/cmdlfhid.h b/client/cmdlfhid.h index 328f3b13..7021492b 100644 --- a/client/cmdlfhid.h +++ b/client/cmdlfhid.h @@ -12,9 +12,9 @@ #define CMDLFHID_H__ int CmdLFHID(const char *Cmd); - -int CmdHIDDemod(const char *Cmd); +//int CmdHIDDemod(const char *Cmd); int CmdHIDDemodFSK(const char *Cmd); int CmdHIDSim(const char *Cmd); +int CmdHIDClone(const char *Cmd); #endif diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 14ce5498..aa21c44b 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -24,7 +24,7 @@ int CmdIODemodFSK(const char *Cmd) SendCommand(&c); return 0; } - +/* int CmdIOProxDemod(const char *Cmd){ if (GraphTraceLen < 4800) { PrintAndLog("too short; need at least 4800 samples"); @@ -37,7 +37,7 @@ int CmdIOProxDemod(const char *Cmd){ RepaintGraphWindow(); return 0; } - +*/ int CmdIOClone(const char *Cmd) { unsigned int hi = 0, lo = 0; @@ -67,7 +67,7 @@ int CmdIOClone(const char *Cmd) static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, - {"demod", CmdIOProxDemod, 1, "Demodulate Stream"}, + //{"demod", CmdIOProxDemod, 1, "Demodulate Stream"}, {"fskdemod", CmdIODemodFSK, 0, "['1'] Realtime IO FSK demodulator (option '1' for one tag only)"}, {"clone", CmdIOClone, 0, "Clone ioProx Tag"}, {NULL, NULL, 0, NULL} @@ -83,4 +83,4 @@ int CmdHelp(const char *Cmd) { CmdsHelp(CommandTable); return 0; -} \ No newline at end of file +} diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index b6b29c05..64c999d6 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -147,31 +147,37 @@ int CmdT55xxSetConfig(const char *Cmd) { param_getstr(Cmd, cmdp+1, modulation); cmdp += 2; - if ( strcmp(modulation, "FSK" ) == 0) + if ( strcmp(modulation, "FSK" ) == 0) { config.modulation = DEMOD_FSK; - else if ( strcmp(modulation, "FSK1" ) == 0) + } else if ( strcmp(modulation, "FSK1" ) == 0) { config.modulation = DEMOD_FSK1; - else if ( strcmp(modulation, "FSK1a" ) == 0) + config.inverted=1; + } else if ( strcmp(modulation, "FSK1a" ) == 0) { config.modulation = DEMOD_FSK1a; - else if ( strcmp(modulation, "FSK2" ) == 0) + config.inverted=0; + } else if ( strcmp(modulation, "FSK2" ) == 0) { config.modulation = DEMOD_FSK2; - else if ( strcmp(modulation, "FSK2a" ) == 0) + config.inverted=0; + } else if ( strcmp(modulation, "FSK2a" ) == 0) { config.modulation = DEMOD_FSK2a; - else if ( strcmp(modulation, "ASK" ) == 0) + config.inverted=1; + } else if ( strcmp(modulation, "ASK" ) == 0) { config.modulation = DEMOD_ASK; - else if ( strcmp(modulation, "NRZ" ) == 0) + } else if ( strcmp(modulation, "NRZ" ) == 0) { config.modulation = DEMOD_NRZ; - else if ( strcmp(modulation, "PSK1" ) == 0) + } else if ( strcmp(modulation, "PSK1" ) == 0) { config.modulation = DEMOD_PSK1; - else if ( strcmp(modulation, "PSK2" ) == 0) + } else if ( strcmp(modulation, "PSK2" ) == 0) { config.modulation = DEMOD_PSK2; - else if ( strcmp(modulation, "PSK3" ) == 0) + } else if ( strcmp(modulation, "PSK3" ) == 0) { config.modulation = DEMOD_PSK3; - else if ( strcmp(modulation, "BIa" ) == 0) + } else if ( strcmp(modulation, "BIa" ) == 0) { config.modulation = DEMOD_BIa; - else if ( strcmp(modulation, "BI" ) == 0) + config.inverted=1; + } else if ( strcmp(modulation, "BI" ) == 0) { config.modulation = DEMOD_BI; - else { + config.inverted=0; + } else { PrintAndLog("Unknown modulation '%s'", modulation); errors = TRUE; } @@ -264,55 +270,36 @@ bool DecodeT55xxBlock(){ switch( config.modulation ){ case DEMOD_FSK: - //CmdLtrim("26"); sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); CmdLtrim(cmdStr); sprintf(cmdStr,"%d %d", bitRate[config.bitrate], config.inverted ); ans = FSKrawDemod(cmdStr, FALSE); break; case DEMOD_FSK1: - //CmdLtrim("26"); - sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); - CmdLtrim(cmdStr); - sprintf(cmdStr,"%d 1 8 5", bitRate[config.bitrate] ); - ans = FSKrawDemod(cmdStr, FALSE); - break; case DEMOD_FSK1a: - //CmdLtrim("26"); sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); CmdLtrim(cmdStr); - sprintf(cmdStr,"%d 0 8 5", bitRate[config.bitrate] ); + sprintf(cmdStr,"%d %d 8 5", bitRate[config.bitrate], config.inverted ); ans = FSKrawDemod(cmdStr, FALSE); break; case DEMOD_FSK2: - //CmdLtrim("26"); - sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); - CmdLtrim(cmdStr); - sprintf(cmdStr,"%d 0 10 8", bitRate[config.bitrate] ); - ans = FSKrawDemod(cmdStr, FALSE); - break; case DEMOD_FSK2a: - //CmdLtrim("26"); sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); CmdLtrim(cmdStr); - sprintf(cmdStr,"%d 1 10 8", bitRate[config.bitrate] ); + sprintf(cmdStr,"%d %d 10 8", bitRate[config.bitrate], config.inverted ); ans = FSKrawDemod(cmdStr, FALSE); break; case DEMOD_ASK: - sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted ); + sprintf(cmdStr,"%d %d 0", bitRate[config.bitrate], config.inverted ); ans = ASKmanDemod(cmdStr, FALSE, FALSE); break; case DEMOD_PSK1: - sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted ); - ans = PSKDemod(cmdStr, FALSE); - break; - case DEMOD_PSK2: - sprintf(cmdStr,"%d 1", bitRate[config.bitrate] ); + sprintf(cmdStr,"%d %d 0", bitRate[config.bitrate], config.inverted ); ans = PSKDemod(cmdStr, FALSE); - psk1TOpsk2(DemodBuffer, DemodBufferLen); break; - case DEMOD_PSK3: - sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted ); + case DEMOD_PSK2: //inverted won't affect this + case DEMOD_PSK3: //not fully implemented + sprintf(cmdStr,"%d 0 1", bitRate[config.bitrate] ); ans = PSKDemod(cmdStr, FALSE); psk1TOpsk2(DemodBuffer, DemodBufferLen); break; @@ -321,11 +308,8 @@ bool DecodeT55xxBlock(){ ans = NRZrawDemod(cmdStr, FALSE); break; case DEMOD_BI: - sprintf(cmdStr,"0 %d 0 1", bitRate[config.bitrate] ); - ans = ASKbiphaseDemod(cmdStr, FALSE); - break; case DEMOD_BIa: - sprintf(cmdStr,"0 %d 1 1", bitRate[config.bitrate] ); + sprintf(cmdStr,"0 %d %d 0", bitRate[config.bitrate], config.inverted ); ans = ASKbiphaseDemod(cmdStr, FALSE); break; default: @@ -516,33 +500,9 @@ bool testBitRate(uint8_t readRate, uint8_t mod){ uint8_t detRate = 0; switch( mod ){ case DEMOD_FSK: - detRate = GetFskClock("",FALSE, FALSE); - if (expected[readRate] == detRate) { - config.bitrate = readRate; - return TRUE; - } - break; case DEMOD_FSK1: - detRate = GetFskClock("",FALSE, FALSE); - if (expected[readRate] == detRate) { - config.bitrate = readRate; - return TRUE; - } - break; case DEMOD_FSK1a: - detRate = GetFskClock("",FALSE, FALSE); - if (expected[readRate] == detRate) { - config.bitrate = readRate; - return TRUE; - } - break; case DEMOD_FSK2: - detRate = GetFskClock("",FALSE, FALSE); - if (expected[readRate] == detRate) { - config.bitrate = readRate; - return TRUE; - } - break; case DEMOD_FSK2a: detRate = GetFskClock("",FALSE, FALSE); if (expected[readRate] == detRate) { @@ -551,6 +511,8 @@ bool testBitRate(uint8_t readRate, uint8_t mod){ } break; case DEMOD_ASK: + case DEMOD_BI: + case DEMOD_BIa: detRate = GetAskClock("",FALSE, FALSE); if (expected[readRate] == detRate) { config.bitrate = readRate; @@ -558,19 +520,7 @@ bool testBitRate(uint8_t readRate, uint8_t mod){ } break; case DEMOD_PSK1: - detRate = GetPskClock("",FALSE, FALSE); - if (expected[readRate] == detRate) { - config.bitrate = readRate; - return TRUE; - } - break; case DEMOD_PSK2: - detRate = GetPskClock("",FALSE, FALSE); - if (expected[readRate] == detRate) { - config.bitrate = readRate; - return TRUE; - } - break; case DEMOD_PSK3: detRate = GetPskClock("",FALSE, FALSE); if (expected[readRate] == detRate) { @@ -585,13 +535,6 @@ bool testBitRate(uint8_t readRate, uint8_t mod){ return TRUE; } break; - case DEMOD_BI: - detRate = GetAskClock("",FALSE, FALSE); - if (expected[readRate] == detRate) { - config.bitrate = readRate; - return TRUE; - } - break; default: return FALSE; } @@ -606,18 +549,18 @@ bool test(uint8_t mode, uint8_t *offset){ si = idx; if ( PackBits(si, 32, DemodBuffer) == 0x00 ) continue; - uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key + uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key uint8_t resv = PackBits(si, 4, DemodBuffer); si += 4; //was 7 & +=7+3 //should be only 4 bits if extended mode // 2nibble must be zeroed. // moved test to here, since this gets most faults first. if ( resv > 0x00) continue; - uint8_t xtRate = PackBits(si, 3, DemodBuffer); si += 3; //new - uint8_t bitRate = PackBits(si, 3, DemodBuffer); si += 3; //new could check bit rate + uint8_t xtRate = PackBits(si, 3, DemodBuffer); si += 3; //extended mode part of rate + uint8_t bitRate = PackBits(si, 3, DemodBuffer); si += 3; //bit rate uint8_t extend = PackBits(si, 1, DemodBuffer); si += 1; //bit 15 extended mode - uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1; //new - //uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //new could check psk cr - uint8_t nml01 = PackBits(si, 1, DemodBuffer); si += 1+5; //bit 24 , 30, 31 could be tested for 0 if not extended mode + uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1; + //uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //could check psk cr + uint8_t nml01 = PackBits(si, 1, DemodBuffer); si += 1+5; //bit 24, 30, 31 could be tested for 0 if not extended mode uint8_t nml02 = PackBits(si, 2, DemodBuffer); si += 2; //if extended mode @@ -628,9 +571,8 @@ bool test(uint8_t mode, uint8_t *offset){ } //test modulation if (!testModulation(mode, modread)) continue; - - *offset = idx; if (!testBitRate(bitRate, mode)) continue; + *offset = idx; return TRUE; } return FALSE; @@ -922,7 +864,7 @@ int AquireData( uint8_t block ){ } char * GetBitRateStr(uint32_t id){ - static char buf[40]; + static char buf[20]; char *retStr = buf; switch (id){ case 0: @@ -957,7 +899,6 @@ char * GetBitRateStr(uint32_t id){ return buf; } - char * GetSaferStr(uint32_t id){ static char buf[40]; char *retStr = buf; @@ -974,7 +915,7 @@ char * GetSaferStr(uint32_t id){ } char * GetModulationStr( uint32_t id){ - static char buf[40]; + static char buf[60]; char *retStr = buf; switch (id){ diff --git a/client/graph.c b/client/graph.c index ae318ddf..089119d9 100644 --- a/client/graph.c +++ b/client/graph.c @@ -53,11 +53,11 @@ void save_restoreGB(uint8_t saveOpt) static bool GB_Saved = false; if (saveOpt==1) { //save - memcpy(SavedGB,GraphBuffer, sizeof(GraphBuffer)); + memcpy(SavedGB, GraphBuffer, sizeof(GraphBuffer)); SavedGBlen = GraphTraceLen; GB_Saved=true; } else if (GB_Saved){ - memcpy(GraphBuffer,SavedGB, sizeof(GraphBuffer)); + memcpy(GraphBuffer, SavedGB, sizeof(GraphBuffer)); GraphTraceLen = SavedGBlen; } return; diff --git a/client/util.c b/client/util.c index edd9aebc..709e2014 100644 --- a/client/util.c +++ b/client/util.c @@ -121,19 +121,24 @@ char * sprint_hex(const uint8_t * data, const size_t len) { return buf; } -char * sprint_bin(const uint8_t * data, const size_t len) { +char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks) { int maxLen = ( len > 1024) ? 1024 : len; static char buf[1024]; - char * tmp = buf; - size_t i; + char *tmp = buf; - for (i=0; i < maxLen; ++i, ++tmp) - sprintf(tmp, "%u", data[i]); + for (size_t i=0; i < maxLen; ++i){ + sprintf(tmp++, "%u", data[i]); + if (breaks > 0 && !((i+1) % breaks)) + sprintf(tmp++, "%s","\n"); + } return buf; } +char *sprint_bin(const uint8_t *data, const size_t len) { + return sprint_bin_break(data, len, 0); +} void num_to_bytes(uint64_t n, size_t len, uint8_t* dest) { while (len--) { diff --git a/client/util.h b/client/util.h index 5001acdc..a6d0f49f 100644 --- a/client/util.h +++ b/client/util.h @@ -39,6 +39,7 @@ void FillFileNameByUID(char *fileName, uint8_t * uid, char *ext, int byteCount); void print_hex(const uint8_t * data, const size_t len); char * sprint_hex(const uint8_t * data, const size_t len); char * sprint_bin(const uint8_t * data, const size_t len); +char * sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks); void num_to_bytes(uint64_t n, size_t len, uint8_t* dest); uint64_t bytes_to_num(uint8_t* src, size_t len); diff --git a/common/lfdemod.c b/common/lfdemod.c index c00222b3..58221546 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -81,10 +81,8 @@ uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_ // otherwise could be a void with no arguments //set defaults uint32_t i = 0; - if (BitStream[1]>1){ //allow only 1s and 0s - // PrintAndLog("no data found"); - return 0; - } + if (BitStream[1]>1) return 0; //allow only 1s and 0s + // 111111111 bit pattern represent start of frame // include 0 in front to help get start pos uint8_t preamble[] = {0,1,1,1,1,1,1,1,1,1}; @@ -130,7 +128,7 @@ int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int if (smplCnt > clk-(clk/4)-1) { //full clock if (smplCnt > clk + (clk/4)+1) { //too many samples errCnt++; - BinStream[bitCnt++]=77; + BinStream[bitCnt++]=7; } else if (waveHigh) { BinStream[bitCnt++] = invert; BinStream[bitCnt++] = invert; @@ -208,7 +206,7 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max //should have hit a high or low based on clock!! //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit); if (bitnum > 0) { - BinStream[bitnum++] = 77; + BinStream[bitnum++] = 7; errCnt++; } lastBit += *clk;//skip over error @@ -244,6 +242,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size) size_t i, ii; uint16_t bestErr = 1000, bestRun = 0; if (size == 0) return -1; + //find correct start position [alignment] for (ii=0;ii<2;++ii){ for (i=ii; i<*size-2; i+=2) if (BitStream[i]==BitStream[i+1]) @@ -255,13 +254,14 @@ int manrawdecode(uint8_t * BitStream, size_t *size) } errCnt=0; } + //decode for (i=bestRun; i < *size-2; i+=2){ if(BitStream[i] == 1 && (BitStream[i+1] == 0)){ BitStream[bitnum++]=0; } else if((BitStream[i] == 0) && BitStream[i+1] == 1){ BitStream[bitnum++]=1; } else { - BitStream[bitnum++]=77; + BitStream[bitnum++]=7; } if(bitnum>MaxBits) break; } @@ -291,7 +291,7 @@ int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert) for (i=offset; i<*size-3; i+=2){ //check for phase error if (BitStream[i+1]==BitStream[i+2]) { - BitStream[bitnum++]=77; + BitStream[bitnum++]=7; errCnt++; } if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){ @@ -299,7 +299,7 @@ int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert) } else if((BitStream[i]==0 && BitStream[i+1]==0) || (BitStream[i]==1 && BitStream[i+1]==1)){ BitStream[bitnum++]=invert; } else { - BitStream[bitnum++]=77; + BitStream[bitnum++]=7; errCnt++; } if(bitnum>MaxBits) break; @@ -367,7 +367,7 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max BinStream[bitnum++] = *invert ^ 1; } else { if (bitnum > 0) { - BinStream[bitnum++]=77; + BinStream[bitnum++]=7; errCnt++; } } @@ -784,8 +784,9 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) for (i=8; i>1; i--){ if (clk[i] == ans) { *clock = ans; - clockFnd = i; - break; //clock found but continue to find best startpos + //clockFnd = i; + return 0; // for strong waves i don't use the 'best start position' yet... + //break; //clock found but continue to find best startpos [not yet] } } } @@ -806,10 +807,11 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) }else{ tol=0; } - if (!maxErr && loopCnt>clk[clkCnt]*3) loopCnt=clk[clkCnt]*3; + //if no errors allowed - keep start within the first clock + if (!maxErr && size > clk[clkCnt]*3 + tol) loopCnt=clk[clkCnt]*2; bestErr[clkCnt]=1000; //try lining up the peaks by moving starting point (try first few clocks) - for (ii=0; ii < loopCnt-tol-clk[clkCnt]; ii++){ + for (ii=0; ii < loopCnt-clk[clkCnt]; ii++){ if (dest[ii] < peak && dest[ii] > low) continue; errCnt=0; @@ -849,7 +851,7 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) } } } - if (bestErr[best] > maxErr) return -1; + //if (bestErr[best] > maxErr) return -1; *clock = clk[best]; return bestStart[best]; } @@ -1029,7 +1031,7 @@ void psk1TOpsk2(uint8_t *BitStream, size_t size) size_t i=1; uint8_t lastBit=BitStream[0]; for (; i lastClkBit + *clock + tol + fc){ lastClkBit += *clock; //no phase shift but clock bit -- 2.39.5 From 224ce36eb1037ecb48d55066ab2fe36f0a5064df Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 5 Apr 2015 16:37:41 -0400 Subject: [PATCH 03/16] lf t5xx - icemans update --- client/cmdlft55xx.c | 63 ++++++++------ client/scripts/test_t55x7_ask.lua | 3 +- client/scripts/test_t55x7_bi.lua | 9 +- client/scripts/test_t55x7_fsk.lua | 3 +- client/scripts/test_t55x7_psk.lua | 5 +- client/scripts/tnp3clone.lua | 136 ++++++++++++++++++++++++++++++ client/scripts/tnp3dump.lua | 70 +++++++++------ client/scripts/tnp3sim.lua | 128 ++++++++++++++++++++++++++-- 8 files changed, 351 insertions(+), 66 deletions(-) create mode 100644 client/scripts/tnp3clone.lua diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 64c999d6..1a0c0f58 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "proxmark3.h" #include "ui.h" #include "graph.h" @@ -261,7 +262,7 @@ int CmdT55xxReadBlock(const char *Cmd) { bool DecodeT55xxBlock(){ - char buf[8] = {0x00}; + char buf[10] = {0x00}; char *cmdStr = buf; int ans = 0; uint8_t bitRate[8] = {8,16,32,40,50,64,100,128}; @@ -270,46 +271,46 @@ bool DecodeT55xxBlock(){ switch( config.modulation ){ case DEMOD_FSK: - sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); + snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 ); CmdLtrim(cmdStr); - sprintf(cmdStr,"%d %d", bitRate[config.bitrate], config.inverted ); + snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted ); ans = FSKrawDemod(cmdStr, FALSE); break; case DEMOD_FSK1: case DEMOD_FSK1a: - sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); + snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 ); CmdLtrim(cmdStr); - sprintf(cmdStr,"%d %d 8 5", bitRate[config.bitrate], config.inverted ); + snprintf(cmdStr, sizeof(buf),"%d %d 8 5", bitRate[config.bitrate], config.inverted ); ans = FSKrawDemod(cmdStr, FALSE); break; case DEMOD_FSK2: case DEMOD_FSK2a: - sprintf(cmdStr,"%d", bitRate[config.bitrate]/2 ); + snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 ); CmdLtrim(cmdStr); - sprintf(cmdStr,"%d %d 10 8", bitRate[config.bitrate], config.inverted ); + snprintf(cmdStr, sizeof(buf),"%d %d 10 8", bitRate[config.bitrate], config.inverted ); ans = FSKrawDemod(cmdStr, FALSE); break; case DEMOD_ASK: - sprintf(cmdStr,"%d %d 0", bitRate[config.bitrate], config.inverted ); + snprintf(cmdStr, sizeof(buf),"%d %d 0", bitRate[config.bitrate], config.inverted ); ans = ASKmanDemod(cmdStr, FALSE, FALSE); break; case DEMOD_PSK1: - sprintf(cmdStr,"%d %d 0", bitRate[config.bitrate], config.inverted ); + snprintf(cmdStr, sizeof(buf),"%d %d 0", bitRate[config.bitrate], config.inverted ); ans = PSKDemod(cmdStr, FALSE); break; case DEMOD_PSK2: //inverted won't affect this case DEMOD_PSK3: //not fully implemented - sprintf(cmdStr,"%d 0 1", bitRate[config.bitrate] ); + snprintf(cmdStr, sizeof(buf),"%d 0 1", bitRate[config.bitrate] ); ans = PSKDemod(cmdStr, FALSE); psk1TOpsk2(DemodBuffer, DemodBufferLen); break; case DEMOD_NRZ: - sprintf(cmdStr,"%d %d 1", bitRate[config.bitrate], config.inverted ); + snprintf(cmdStr, sizeof(buf),"%d %d 1", bitRate[config.bitrate], config.inverted ); ans = NRZrawDemod(cmdStr, FALSE); break; case DEMOD_BI: case DEMOD_BIa: - sprintf(cmdStr,"0 %d %d 0", bitRate[config.bitrate], config.inverted ); + snprintf(cmdStr, sizeof(buf),"0 %d %d 0", bitRate[config.bitrate], config.inverted ); ans = ASKbiphaseDemod(cmdStr, FALSE); break; default: @@ -578,7 +579,7 @@ bool test(uint8_t mode, uint8_t *offset){ return FALSE; } -void printT55xxBlock(const char *demodStr){ +void printT55xxBlock(const char *blockNum){ uint8_t i = config.offset; uint8_t endpos = 32 + i; @@ -596,7 +597,7 @@ void printT55xxBlock(const char *demodStr){ bits[i - config.offset]=DemodBuffer[i]; blockData = PackBits(0, 32, bits); - PrintAndLog("0x%08X %s [%s]", blockData, sprint_bin(bits,32), demodStr); + PrintAndLog("[%s] 0x%08X %s", blockNum, blockData, sprint_bin(bits,32)); } int special(const char *Cmd) { @@ -688,16 +689,28 @@ int CmdT55xxReadTrace(const char *Cmd) uint32_t bl0 = PackBits(si, 32, DemodBuffer); uint32_t bl1 = PackBits(si+32, 32, DemodBuffer); - uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8; - uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8; - uint32_t cid = PackBits(si, 5, DemodBuffer); si += 5; - uint32_t icr = PackBits(si, 3, DemodBuffer); si += 3; - uint32_t year = PackBits(si, 4, DemodBuffer); si += 4; - uint32_t quarter = PackBits(si, 2, DemodBuffer); si += 2; - uint32_t lotid = PackBits(si, 14, DemodBuffer); si += 14; - uint32_t wafer = PackBits(si, 5, DemodBuffer); si += 5; + uint32_t acl = PackBits(si, 8, DemodBuffer); si += 8; + uint32_t mfc = PackBits(si, 8, DemodBuffer); si += 8; + uint32_t cid = PackBits(si, 5, DemodBuffer); si += 5; + uint32_t icr = PackBits(si, 3, DemodBuffer); si += 3; + uint32_t year = PackBits(si, 4, DemodBuffer); si += 4; + uint32_t quarter = PackBits(si, 2, DemodBuffer); si += 2; + uint32_t lotid = PackBits(si, 14, DemodBuffer); si += 14; + uint32_t wafer = PackBits(si, 5, DemodBuffer); si += 5; uint32_t dw = PackBits(si, 15, DemodBuffer); + time_t t = time(NULL); + struct tm tm = *localtime(&t); + if ( year > tm.tm_year-110) + year += 2000; + else + year += 2010; + + if ( acl != 0xE0 ) { + PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. "); + return 1; + } + PrintAndLog(""); PrintAndLog("-- T55xx Trace Information ----------------------------------"); PrintAndLog("-------------------------------------------------------------"); @@ -716,8 +729,6 @@ int CmdT55xxReadTrace(const char *Cmd) PrintAndLog(" Block 1 : 0x%08X %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat+32,32) ); PrintAndLog("-------------------------------------------------------------"); - if ( acl != 0xE0 ) - PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. "); /* TRACE - BLOCK O Bits Definition HEX @@ -967,8 +978,8 @@ char * GetModelStrFromCID(uint32_t cid){ static char buf[10]; char *retStr = buf; - if (cid == 1) sprintf(retStr,"ATA5577M1"); - if (cid == 2) sprintf(retStr,"ATA5577M2"); + if (cid == 1) snprintf(retStr, sizeof(buf),"ATA5577M1"); + if (cid == 2) snprintf(retStr, sizeof(buf),"ATA5577M2"); return buf; } diff --git a/client/scripts/test_t55x7_ask.lua b/client/scripts/test_t55x7_ask.lua index 569d4260..f8990b15 100644 --- a/client/scripts/test_t55x7_ask.lua +++ b/client/scripts/test_t55x7_ask.lua @@ -95,6 +95,7 @@ end function test() local y + local block = "00" for y = 0x0, 0x1d, 0x4 do for _ = 1, #procedurecmds do local pcmd = procedurecmds[_] @@ -107,7 +108,7 @@ function test() dbg(('lf t55xx write 0 %s'):format(config)) config = tonumber(config,16) - local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config} + local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK,arg1 = config, arg2 = block, arg3 = "00", data = "00"} local err = core.SendCommand(writecmd:getBytes()) if err then return oops(err) end local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) diff --git a/client/scripts/test_t55x7_bi.lua b/client/scripts/test_t55x7_bi.lua index a1793ba6..e8950ab8 100644 --- a/client/scripts/test_t55x7_bi.lua +++ b/client/scripts/test_t55x7_bi.lua @@ -89,6 +89,7 @@ end function test() local y + local block = "00" for y = 1, 0x1D, 4 do for _ = 1, #procedurecmds do local pcmd = procedurecmds[_] @@ -98,10 +99,10 @@ function test() elseif _ == 1 then local config = pcmd:format(config1, y, config2) - dbg(('lf t55xx wr 0 %s'):format(config)) - - config = tonumber(config,16) - local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config} + dbg(('lf t55xx write 0 %s'):format(config)) + + config = tonumber(config,16) + local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK,arg1 = config, arg2 = block, arg3 = "00", data = "00"} local err = core.SendCommand(writecmd:getBytes()) if err then return oops(err) end local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) diff --git a/client/scripts/test_t55x7_fsk.lua b/client/scripts/test_t55x7_fsk.lua index f42dd147..c9c1f09c 100644 --- a/client/scripts/test_t55x7_fsk.lua +++ b/client/scripts/test_t55x7_fsk.lua @@ -92,6 +92,7 @@ end function test(modulation) local y + local block = "00" for y = 0x0, 0x1d, 0x4 do for _ = 1, #procedurecmds do local pcmd = procedurecmds[_] @@ -104,7 +105,7 @@ function test(modulation) dbg(('lf t55xx write 0 %s'):format(config)) config = tonumber(config,16) - local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config} + local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK,arg1 = config, arg2 = block, arg3 = "00", data = "00"} local err = core.SendCommand(writecmd:getBytes()) if err then return oops(err) end local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) diff --git a/client/scripts/test_t55x7_psk.lua b/client/scripts/test_t55x7_psk.lua index cbd78e87..bdd644a7 100644 --- a/client/scripts/test_t55x7_psk.lua +++ b/client/scripts/test_t55x7_psk.lua @@ -108,6 +108,7 @@ end function test(modulation) local bitrate local clockrate + local block = "00" for bitrate = 0x0, 0x1d, 0x4 do for clockrate = 0,8,4 do @@ -125,8 +126,8 @@ function test(modulation) dbg(('lf t55xx write 0 %s'):format(config)) config = tonumber(config,16) - local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config ,arg2 = 0, arg3 = 0} - local err = core.SendCommand(writecommand:getBytes()) + local writecmd = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK,arg1 = config, arg2 = block, arg3 = "00", data = "00"} + local err = core.SendCommand(writecmd:getBytes()) if err then return oops(err) end local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT) else diff --git a/client/scripts/tnp3clone.lua b/client/scripts/tnp3clone.lua new file mode 100644 index 00000000..8c9397a7 --- /dev/null +++ b/client/scripts/tnp3clone.lua @@ -0,0 +1,136 @@ +local cmds = require('commands') +local getopt = require('getopt') +local lib14a = require('read14a') +local utils = require('utils') +local pre = require('precalc') + +local lsh = bit32.lshift +local rsh = bit32.rshift +local bor = bit32.bor +local band = bit32.band + +example =[[ + script run tnp3dump + script run tnp3dump -h + script run tnp3dump -t aa00 + +]] +author = "Iceman" +usage = "script run tnp3clone -t " +desc =[[ +This script will try making a barebone clone of a tnp3 tag on to a magic generation1 card. + +Arguments: + -h : this help + -k : toytype id, 4 hex symbols. +]] + + +-- This is only meant to be used when errors occur +function oops(err) + print("ERROR: ",err) +end +-- Usage help +function help() + print(desc) + print("Example usage") + print(example) +end + +local function waitCmd() + local response = core.WaitForResponseTimeout(cmds.CMD_ACK,2000) + if response then + local count,cmd,arg0 = bin.unpack('LL',response) + if(arg0==1) then + local count,arg1,arg2,data = bin.unpack('LLH511',response,count) + return data:sub(1,32) + else + return nil, "Couldn't read block." + end + end + return nil, "No response from device" +end + +local function readblock( blocknum, keyA ) + -- Read block 0 + cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blocknum, arg2 = 0, arg3 = 0, data = keyA} + err = core.SendCommand(cmd:getBytes()) + if err then return nil, err end + local block0, err = waitCmd() + if err then return nil, err end + return block0 +end +local function readmagicblock( blocknum ) + -- Read block 0 + local CSETBLOCK_SINGLE_OPERATION = 0x1F + cmd = Command:new{cmd = cmds.CMD_MIFARE_CGETBLOCK, arg1 = CSETBLOCK_SINGLE_OPERATION, arg2 = 0, arg3 = blocknum} + err = core.SendCommand(cmd:getBytes()) + if err then return nil, err end + local block0, err = waitCmd() + if err then return nil, err end + return block0 +end + +local function main(args) + + local numBlocks = 64 + local cset = 'hf mf csetbl ' + local cget = 'hf mf cgetbl ' + local empty = '00000000000000000000000000000000' + local AccAndKeyB = '7F078869000000000000' + -- Defaults to Gusto + local toytype = 'C201' + + -- Arguments for the script + for o, a in getopt.getopt(args, 'ht:') do + if o == "h" then return help() end + if o == "t" then toytype = a end + end + + if #toytype ~= 4 then return oops('Wrong size in toytype. (4hex symbols)') end + + -- find tag + result, err = lib14a.read1443a(false) + if not result then return oops(err) end + + -- Show tag info + print((' Found tag %s'):format(result.name)) + + -- load keys + local akeys = pre.GetAll(result.uid) + local keyA = akeys:sub(1, 12 ) + + local b0 = readblock(0,keyA) + if not b0 then + print('failed reading block with factorydefault key. Trying chinese magic read.') + b0, err = readmagicblock(0) + if not b0 then + oops(err) + return oops('failed reading block with chinese magic command. quitting...') + end + end + + -- wipe card. + local cmd = (cset..' %s 0004 08 w'):format( b0) + core.console(cmd) + + + local b1 = toytype..'000000000000000000000000' + local calc = utils.Crc16(b0..b1) + local calcEndian = bor(rsh(calc,8), lsh(band(calc, 0xff), 8)) + + local cmd = (cset..'1 %s%04x'):format( b1, calcEndian) + core.console(cmd) + + local pos, key + for blockNo = 2, numBlocks-1, 1 do + pos = (math.floor( blockNo / 4 ) * 12)+1 + key = akeys:sub(pos, pos + 11 ) + if blockNo%4 == 3 then + cmd = ('%s %d %s%s'):format(cset,blockNo,key,AccAndKeyB) + core.console(cmd) + end + end + core.clearCommandBuffer() +end +main(args) \ No newline at end of file diff --git a/client/scripts/tnp3dump.lua b/client/scripts/tnp3dump.lua index dedd3df1..363998fb 100644 --- a/client/scripts/tnp3dump.lua +++ b/client/scripts/tnp3dump.lua @@ -7,17 +7,20 @@ local md5 = require('md5') local dumplib = require('html_dumplib') local toyNames = require('default_toys') + example =[[ - 1. script run tnp3dump - 2. script run tnp3dump -n - 3. script run tnp3dump -k aabbccddeeff - 4. script run tnp3dump -k aabbccddeeff -n - 5. script run tnp3dump -o myfile - 6. script run tnp3dump -n -o myfile - 7. script run tnp3dump -k aabbccddeeff -n -o myfile + script run tnp3dump + script run tnp3dump -n + script run tnp3dump -p + script run tnp3dump -k aabbccddeeff + script run tnp3dump -k aabbccddeeff -n + script run tnp3dump -o myfile + script run tnp3dump -n -o myfile + script run tnp3dump -p -o myfile + script run tnp3dump -k aabbccddeeff -n -o myfile ]] author = "Iceman" -usage = "script run tnp3dump -k -n -o " +usage = "script run tnp3dump -k -n -p -o " desc =[[ This script will try to dump the contents of a Mifare TNP3xxx card. It will need a valid KeyA in order to find the other keys and decode the card. @@ -25,6 +28,7 @@ Arguments: -h : this help -k : Sector 0 Key A. -n : Use the nested cmd to find all keys + -p : Use the precalc to find all keys -o : filename for the saved dumps ]] @@ -112,15 +116,17 @@ local function main(args) local cmd local err local useNested = false + local usePreCalc = false local cmdReadBlockString = 'hf mf rdbl %d A %s' local input = "dumpkeys.bin" local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M%S"); -- Arguments for the script - for o, a in getopt.getopt(args, 'hk:no:') do + for o, a in getopt.getopt(args, 'hk:npo:') do if o == "h" then return help() end if o == "k" then keyA = a end if o == "n" then useNested = true end + if o == "p" then usePreCalc = true end if o == "o" then outputTemplate = a end end @@ -142,29 +148,34 @@ local function main(args) core.clearCommandBuffer() if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx - return oops('This is not a TNP3xxx tag. aborting.') + -- return oops('This is not a TNP3xxx tag. aborting.') end -- Show tag info - print((' Found tag : %s'):format(result.name)) - print(('Using keyA : %s'):format(keyA)) + print((' Found tag %s'):format(result.name)) + + dbg(('Using keyA : %s'):format(keyA)) --Trying to find the other keys if useNested then core.console( ('hf mf nested 1 0 A %s d'):format(keyA) ) end - + core.clearCommandBuffer() - -- Loading keyfile - print('Loading dumpkeys.bin') - local hex, err = utils.ReadDumpFile(input) - if not hex then - return oops(err) + local akeys = '' + if usePreCalc then + local pre = require('precalc') + akeys = pre.GetAll(result.uid) + else + print('Loading dumpkeys.bin') + local hex, err = utils.ReadDumpFile(input) + if not hex then + return oops(err) + end + akeys = hex:sub(0,12*16) end - - local akeys = hex:sub(0,12*16) - + -- Read block 0 cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA} err = core.SendCommand(cmd:getBytes()) @@ -188,7 +199,7 @@ local function main(args) core.clearCommandBuffer() -- main loop - io.write('Decrypting blocks > ') + io.write('Reading blocks > ') for blockNo = 0, numBlocks-1, 1 do if core.ukbhit() then @@ -204,7 +215,9 @@ local function main(args) local blockdata, err = waitCmd() if err then return oops(err) end + if blockNo%4 ~= 3 then + if blockNo < 8 then -- Block 0-7 not encrypted blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata) @@ -249,23 +262,28 @@ local function main(args) end end - local uid = block0:sub(1,8) local itemtype = block1:sub(1,4) + local cardidLsw = block1:sub(9,16) + local cardidMsw = block1:sub(16,24) local cardid = block1:sub(9,24) local traptype = block1:sub(25,28) -- Write dump to files if not DEBUG then local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'_uid_'..uid..'.bin') - print(("Wrote a BIN dump to the file %s"):format(foo)) + print(("Wrote a BIN dump to: %s"):format(foo)) local bar = dumplib.SaveAsText(emldata, outputTemplate..'_uid_'..uid..'.eml') - print(("Wrote a EML dump to the file %s"):format(bar)) + print(("Wrote a EML dump to: %s"):format(bar)) end + local itemtypename = toyNames[itemtype] + if itemtypename == nil then + itemtypename = toyNames[utils.SwapEndiannessStr(itemtype,16)] + end -- Show info print( string.rep('--',20) ) - print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) ) + print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, itemtypename) ) print( (' Alter ego / traptype : 0x%s'):format(traptype) ) print( (' UID : 0x%s'):format(uid) ) print( (' CARDID : 0x%s'):format(cardid ) ) diff --git a/client/scripts/tnp3sim.lua b/client/scripts/tnp3sim.lua index adc34cce..1d3dbefd 100644 --- a/client/scripts/tnp3sim.lua +++ b/client/scripts/tnp3sim.lua @@ -27,6 +27,17 @@ Arguments: local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds local DEBUG = true -- the debug flag + + +local band = bit32.band +local bor = bit32.bor +local lshift = bit32.lshift +local rshift = bit32.rshift +local byte = string.byte +local char = string.char +local sub = string.sub +local format = string.format + --- -- A debug printout-function function dbg(args) @@ -65,7 +76,6 @@ function ExitMsg(msg) print() end - local function writedumpfile(infile) t = infile:read("*all") len = string.len(t) @@ -187,7 +197,6 @@ local function ValidateCheckSums(blocks) io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk)) end - local function LoadEmulator(blocks) local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20' local cmd @@ -219,6 +228,102 @@ local function LoadEmulator(blocks) io.write('\n') end +local function Num2Card(m, l) + + local k = { + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,0x42, 0x43, 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, + 0x4C, 0x4D, 0x4E, 0x50, 0x51, 0x52, 0x53, 0x54,0x56, 0x57, 0x58, 0x59, 0x5A, 0x00 + } + local msw = tonumber(utils.SwapEndiannessStr(m,32),16) + local lsw = tonumber(utils.SwapEndiannessStr(l,32),16) + + if msw > 0x17ea1 then + return "too big" + end + + if msw == 0x17ea1 and lsw > 0x8931fee8 then + return "out of range" + end + + local s = "" + local index + for i = 1,10 do + index, msw, lsw = DivideByK( msw, lsw) + if ( index <= 1 ) then + s = char(k[index]) .. s + else + s = char(k[index-1]) .. s + end + print (index-1, msw, lsw) + end + return s +end +--33LRT-LM9Q9 +--7, 122, 3474858630 +--20, 4, 1008436634 +--7, 0, 627182959 +--17, 0, 21626998 +--16, 0, 745758 +--23, 0, 25715 +--21, 0, 886 +--16, 0, 30 +--1, 0, 1 +--1, 0, 0 + +function DivideByK(msw, lsw) + + local lowLSW + local highLSW + local remainder = 0 + local RADIX = 29 + + --local num = 0 | band( rshift(msw,16), 0xffff) + local num = band( rshift(msw, 16), 0xffff) + + --highLSW = 0 | lshift( (num / RADIX) , 16) + highLSW = lshift( (num / RADIX) , 16) + remainder = num % RADIX + + num = bor( lshift(remainder,16), band(msw, 0xffff)) + + --highLSW |= num / RADIX + highLSW = highLSW or (num / RADIX) + remainder = num % RADIX + + num = bor( lshift(remainder,16), ( band(rshift(lsw,16), 0xffff))) + + --lowLSW = 0 | (num / RADIX) << 16 + lowLSW = 0 or (lshift( (num / RADIX), 16)) + remainder = num % RADIX + + num = bor( lshift(remainder,16) , band(lsw, 0xffff) ) + + lowLSW = bor(lowLSW, (num / RADIX)) + remainder = num % RADIX + return remainder, highLSW, lowLSW + + -- uint num = 0 | (msw >> 16) & 0xffff; + + -- highLSW = 0 | (num / RADIX) << 16; + -- remainder = num % RADIX; + + -- num = (remainder << 16) | (msw & 0xffff); + + -- highLSW |= num / RADIX; + -- remainder = num % RADIX; + + -- num = (remainder << 16) | ((lsw >> 16) & 0xffff); + + -- lowLSW = 0 | (num / RADIX) << 16; + -- remainder = num % RADIX; + + -- num = (remainder << 16) | (lsw & 0xffff); + + -- lowLSW |= num / RADIX; + -- remainder = num % RADIX; + +end + local function main(args) print( string.rep('--',20) ) @@ -278,15 +383,26 @@ local function main(args) print(' Gathering info') local uid = blocks[0]:sub(1,8) local itemtype = blocks[1]:sub(1,4) - local cardid = blocks[1]:sub(9,24) + local cardidLsw = blocks[1]:sub(9,16) + local cardidMsw = blocks[1]:sub(17,24) + local itemtypename = toyNames[itemtype] + if itemtypename == nil then + itemtypename = toyNames[utils.SwapEndiannessStr(itemtype,16)] + end + -- Show info print( string.rep('--',20) ) - print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) ) + print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, itemtypename) ) print( (' UID : 0x%s'):format(uid) ) - print( (' CARDID : 0x%s'):format(cardid ) ) + print( (' CARDID : 0x%s %s [%s]'):format( + cardidMsw,cardidLsw, + --Num2Card(cardidMsw, cardidLsw)) + '') + ) print( string.rep('--',20) ) + -- lets do something. -- local experience = blocks[8]:sub(1,6) @@ -351,7 +467,7 @@ local function main(args) err = LoadEmulator(blocks) if err then return oops(err) end core.clearCommandBuffer() - print('The simulation is now prepared.\n --> run \"hf mf sim u '..uid..' x\" <--') + print('The simulation is now prepared.\n --> run \"hf mf sim u '..uid..'\" <--') end end main(args) \ No newline at end of file -- 2.39.5 From 1f918317e2e59decbe862c3e1ad65a930e70ac52 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Sun, 5 Apr 2015 21:59:36 -0400 Subject: [PATCH 04/16] add maxErr to data manrawdecode --- client/cmddata.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index e2e2ca6d..d4fc997b 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -350,10 +350,11 @@ int Cmdmandecoderaw(const char *Cmd) size_t size=0; size_t maxErr = 20; char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data manrawdecode"); + if (strlen(Cmd) > 5 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data manrawdecode [maxErr]"); PrintAndLog(" Takes 10 and 01 and converts to 0 and 1 respectively"); PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); + PrintAndLog(" [maxErr] set number of errors allowed (default = 20)"); PrintAndLog(""); PrintAndLog(" sample: data manrawdecode = decode manchester bitstream from the demodbuffer"); return 0; @@ -366,10 +367,12 @@ int Cmdmandecoderaw(const char *Cmd) else if(DemodBuffer[i]1 || low <0 ){ + if (high>7 || low <0 ){ PrintAndLog("Error: please raw demod the wave first then manchester raw decode"); return 0; } + + sscanf(Cmd, "%i", &maxErr); size=i; errCnt=manrawdecode(BitStream, &size); if (errCnt>=maxErr){ @@ -2172,7 +2175,7 @@ static command_t CommandTable[] = {"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"}, {"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"}, - {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"}, + {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"}, {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, {"dec", CmdDec, 1, "Decimate samples"}, @@ -2191,7 +2194,7 @@ static command_t CommandTable[] = {"load", CmdLoad, 1, " -- Load trace (to graph window"}, {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, {"rtrim", CmdRtrim, 1, " -- Trim samples from right of trace"}, - {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream in DemodBuffer"}, + {"manrawdecode", Cmdmandecoderaw, 1, "[maxErr] -- Manchester decode binary stream in DemodBuffer"}, {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, {"printdemodbuffer",CmdPrintDemodBuff, 1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"}, -- 2.39.5 From 2c772e6cf0f18afa7a91bc4b20443570d697a033 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 6 Apr 2015 21:47:09 +0200 Subject: [PATCH 05/16] Added info to changelog about bootroom update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f3f84ef..7ff77396 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [Unreleased][unreleased] ### Changed - Iclass read, `hf iclass read` now also reads tag config and prints configuration. (holiman) +- *bootrom* needs to be flashed, due to new address boundaries between os and fpga, after a size optimization (piwi) ### Fixed - Fixed issue #19, problems with LF T55xx commands (marshmellow) -- 2.39.5 From cc15a1187b698d185a42fe956c0b68b9384eafdd Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 6 Apr 2015 23:17:30 -0400 Subject: [PATCH 06/16] lf cleanup - fixes more lf em em4x50read fixes adjust heavy clipping ask clock detection clean up t55xx minor items --- client/cmddata.c | 2 +- client/cmdlfem4x.c | 130 ++++++++++++++++++++-------------------- client/cmdlft55xx.c | 14 ++--- common/lfdemod.c | 142 ++++++++++++++++++++------------------------ common/lfdemod.h | 3 +- 5 files changed, 142 insertions(+), 149 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index d4fc997b..18b59f21 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -2020,7 +2020,7 @@ int CmdLoad(const char *Cmd) int CmdLtrim(const char *Cmd) { int ds = atoi(Cmd); - + if (GraphTraceLen<=0) return 0; for (int i = ds; i < GraphTraceLen; ++i) GraphBuffer[i-ds] = GraphBuffer[i]; GraphTraceLen -= ds; diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 552c256e..e45c788a 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -27,7 +27,7 @@ static int CmdHelp(const char *Cmd); int CmdEMdemodASK(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); - int findone = (cmdp == '1') ? 1 : 0; + int findone = (cmdp == '1') ? 1 : 0; UsbCommand c={CMD_EM410X_DEMOD}; c.arg[0]=findone; SendCommand(&c); @@ -237,7 +237,7 @@ bool EM_EndParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t col { if (rows*cols>size) return false; uint8_t colP=0; - //assume last row is a parity row and do not test + //assume last col is a parity and do not test for (uint8_t colNum = 0; colNum < cols-1; colNum++) { for (uint8_t rowNum = 0; rowNum < rows; rowNum++) { colP ^= BitStream[(rowNum*cols)+colNum]; @@ -270,7 +270,7 @@ uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool code = code<<8 | bytebits_to_byte(BitStream+27,8); if (verbose || g_debugMode){ for (uint8_t i = 0; i<5; i++){ - if (i == 4) PrintAndLog(""); + if (i == 4) PrintAndLog(""); //parity byte spacer PrintAndLog("%d%d%d%d%d%d%d%d %d -> 0x%02x", BitStream[i*9], BitStream[i*9+1], @@ -289,7 +289,6 @@ uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool else PrintAndLog("Parity Failed"); } - //PrintAndLog("Code: %08x",code); return code; } /* Read the transmitted data of an EM4x50 tag @@ -311,95 +310,103 @@ uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool * is stored in the blocks defined in the control word First and Last * Word Read values. UID is stored in block 32. */ + //completed by Marshmellow int EM4x50Read(const char *Cmd, bool verbose) { - uint8_t fndClk[]={0,8,16,32,40,50,64}; + uint8_t fndClk[] = {8,16,32,40,50,64,128}; int clk = 0; int invert = 0; - sscanf(Cmd, "%i %i", &clk, &invert); int tol = 0; int i, j, startblock, skip, block, start, end, low, high, minClk; - bool complete= false; + bool complete = false; int tmpbuff[MAX_GRAPH_TRACE_LEN / 64]; - save_restoreGB(1); uint32_t Code[6]; char tmp[6]; - char tmp2[20]; - high= low= 0; + high = low = 0; memset(tmpbuff, 0, MAX_GRAPH_TRACE_LEN / 64); - + + // get user entry if any + sscanf(Cmd, "%i %i", &clk, &invert); + + // save GraphBuffer - to restore it later + save_restoreGB(1); + // first get high and low values - for (i = 0; i < GraphTraceLen; i++) - { + for (i = 0; i < GraphTraceLen; i++) { if (GraphBuffer[i] > high) high = GraphBuffer[i]; else if (GraphBuffer[i] < low) low = GraphBuffer[i]; } - // populate a buffer with pulse lengths - i= 0; - j= 0; - minClk= 255; - while (i < GraphTraceLen) - { + i = 0; + j = 0; + minClk = 255; + // get to first full low to prime loop and skip incomplete first pulse + while ((GraphBuffer[i] < high) && (i < GraphTraceLen)) + ++i; + while ((GraphBuffer[i] > low) && (i < GraphTraceLen)) + ++i; + skip = i; + + // populate tmpbuff buffer with pulse lengths + while (i < GraphTraceLen) { // measure from low to low - while ((GraphBuffer[i] > low) && (i low) && (i < GraphTraceLen)) ++i; start= i; - while ((GraphBuffer[i] < high) && (i low) && (i low) && (i < GraphTraceLen)) ++i; if (j>=(MAX_GRAPH_TRACE_LEN/64)) { break; } tmpbuff[j++]= i - start; - if (i-start < minClk) minClk = i-start; + if (i-start < minClk && i < GraphTraceLen) { + minClk = i - start; + } } // set clock - if (!clk){ + if (!clk) { for (uint8_t clkCnt = 0; clkCnt<7; clkCnt++) { tol = fndClk[clkCnt]/8; - if (fndClk[clkCnt]-tol >= minClk) { + if (minClk >= fndClk[clkCnt]-tol && minClk <= fndClk[clkCnt]+1) { clk=fndClk[clkCnt]; break; } } + if (!clk) return 0; } else tol = clk/8; // look for data start - should be 2 pairs of LW (pulses of clk*3,clk*2) - start= -1; - skip= 0; - for (i= 0; i < j - 4 ; ++i) - { + start = -1; + for (i= 0; i < j - 4 ; ++i) { skip += tmpbuff[i]; - if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) - if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) - if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) - if (tmpbuff[i+3] >= clk-tol) + if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) //3 clocks + if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) //2 clocks + if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) //3 clocks + if (tmpbuff[i+3] >= clk-tol) //1.5 to 2 clocks - depends on bit following { start= i + 4; break; } } - startblock= i + 4; + startblock = i + 4; // skip over the remainder of LW skip += tmpbuff[i+1] + tmpbuff[i+2] + clk + clk/8; - int phaseoff = tmpbuff[i+3]-clk; // now do it again to find the end end = skip; - for (i += 3; i < j - 4 ; ++i) - { + for (i += 3; i < j - 4 ; ++i) { end += tmpbuff[i]; - if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3 + tol) - if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2 + tol) - if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3 + tol) - if (tmpbuff[i+3] >= clk-tol) + if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) //3 clocks + if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) //2 clocks + if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) //3 clocks + if (tmpbuff[i+3] >= clk-tol) //1.5 to 2 clocks - depends on bit following { complete= true; break; @@ -409,15 +416,11 @@ int EM4x50Read(const char *Cmd, bool verbose) // report back if (verbose || g_debugMode) { if (start >= 0) { - PrintAndLog("\nNote: should print 45 bits then 0177 (end of block)"); - PrintAndLog(" for each block"); - PrintAndLog(" Also, sometimes the demod gets out of sync and "); - PrintAndLog(" inverts the output - when this happens the 0177"); - PrintAndLog(" will be 3 extra 1's at the end"); - PrintAndLog(" 'data askedge' command may fix that"); + PrintAndLog("\nNote: one block = 50 bits (32 data, 12 parity, 6 marker)"); } else { - PrintAndLog("No data found!"); + PrintAndLog("No data found!, clock tried:%d",clk); PrintAndLog("Try again with more samples."); + PrintAndLog(" or after a 'data askedge' command to clean up the read"); return 0; } if (!complete) @@ -427,24 +430,22 @@ int EM4x50Read(const char *Cmd, bool verbose) PrintAndLog("Try again with more samples."); } } else if (start < 0) return 0; - start=skip; + start = skip; snprintf(tmp2, sizeof(tmp2),"%d %d 1000 %d", clk, invert, clk*47); // get rid of leading crap - snprintf(tmp, sizeof(tmp),"%i",skip); + snprintf(tmp, sizeof(tmp), "%i", skip); CmdLtrim(tmp); bool pTest; - bool AllPTest=true; + bool AllPTest = true; // now work through remaining buffer printing out data blocks block = 0; i = startblock; - while (block < 6) - { + while (block < 6) { if (verbose || g_debugMode) PrintAndLog("\nBlock %i:", block); skip = phaseoff; // look for LW before start of next block - for ( ; i < j - 4 ; ++i) - { + for ( ; i < j - 4 ; ++i) { skip += tmpbuff[i]; if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) if (tmpbuff[i+1] >= clk-tol) @@ -453,7 +454,10 @@ int EM4x50Read(const char *Cmd, bool verbose) skip += clk; phaseoff = tmpbuff[i+1]-clk; i += 2; - if (ASKmanDemod(tmp2, false, false)<1) return 0; + if (ASKmanDemod(tmp2, false, false) < 1) { + save_restoreGB(0); + return 0; + } //set DemodBufferLen to just one block DemodBufferLen = skip/clk; //test parities @@ -461,26 +465,26 @@ int EM4x50Read(const char *Cmd, bool verbose) pTest &= EM_EndParityTest(DemodBuffer,DemodBufferLen,5,9,0); AllPTest &= pTest; //get output - Code[block]=OutputEM4x50_Block(DemodBuffer,DemodBufferLen,verbose, pTest); - if (g_debugMode) PrintAndLog("\nskipping %d samples, bits:%d",start, skip/clk); + Code[block] = OutputEM4x50_Block(DemodBuffer,DemodBufferLen,verbose, pTest); + if (g_debugMode) PrintAndLog("\nskipping %d samples, bits:%d", skip, skip/clk); //skip to start of next block snprintf(tmp,sizeof(tmp),"%i",skip); CmdLtrim(tmp); block++; - if (i>=end) break; //in case chip doesn't output 6 blocks + if (i >= end) break; //in case chip doesn't output 6 blocks } //print full code: if (verbose || g_debugMode || AllPTest){ - PrintAndLog("Found data at sample: %i - using clock: %i",skip,clk); - //PrintAndLog("\nSummary:"); - end=block; - for (block=0; block= high && waveHigh){ smplCnt++; @@ -360,7 +359,7 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max lastBit = start - *clk; for (i = start; i < *size; ++i) { - if (i - lastBit > *clk){ + if (i - lastBit == *clk){ if (BinStream[i] >= high) { BinStream[bitnum++] = *invert; } else if (BinStream[i] <= low) { @@ -373,13 +372,12 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max } midBit = 0; lastBit += *clk; - } else if (i-lastBit > (*clk/2) && midBit == 0){ + } else if (i-lastBit == (*clk/2) && midBit == 0){ if (BinStream[i] >= high) { BinStream[bitnum++] = *invert; } else if (BinStream[i] <= low) { BinStream[bitnum++] = *invert ^ 1; } else { - BinStream[bitnum] = BinStream[bitnum-1]; bitnum++; } @@ -687,11 +685,11 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size) } -uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low) +uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low) { uint16_t allPeaks=1; uint16_t cntPeaks=0; - size_t loopEnd = 572; + size_t loopEnd = 512+60; if (loopEnd > size) loopEnd = size; for (size_t i=60; ilow && dest[i]128) { - if (!high){ - high=1; - if (cnt > highCnt){ - if (highCnt != 0) highCnt2 = highCnt; - highCnt = cnt; - } else if (cnt > highCnt2) { - highCnt2 = cnt; - } - cnt=1; - } else { - cnt++; - } - } else if (dest[idx] <= 128){ - if (high) { - high=0; - if (cnt > highCnt) { - if (highCnt != 0) highCnt2 = highCnt; - highCnt = cnt; - } else if (cnt > highCnt2) { - highCnt2 = cnt; - } - cnt=1; - } else { - cnt++; - } - } + uint8_t fndClk[] = {8,16,32,40,50,64,128}; + size_t startwave; + size_t i = 0; + size_t minClk = 255; + // get to first full low to prime loop and skip incomplete first pulse + while ((dest[i] < high) && (i < size)) + ++i; + while ((dest[i] > low) && (i < size)) + ++i; + + // loop through all samples + while (i < size) { + // measure from low to low + while ((dest[i] > low) && (i < size)) + ++i; + startwave= i; + while ((dest[i] < high) && (i < size)) + ++i; + while ((dest[i] > low) && (i < size)) + ++i; + //get minimum measured distance + if (i-startwave < minClk && i < size) + minClk = i - startwave; } - uint8_t tol; - for (idx=8; idx>0; idx--){ - tol = clk[idx]/8; - if (clk[idx] >= highCnt - tol && clk[idx] <= highCnt + tol) - return clk[idx]; - if (clk[idx] >= highCnt2 - tol && clk[idx] <= highCnt2 + tol) - return clk[idx]; + // set clock + for (uint8_t clkCnt = 0; clkCnt<7; clkCnt++) { + if (minClk >= fndClk[clkCnt]-(fndClk[clkCnt]/8) && minClk <= fndClk[clkCnt]+1) + return fndClk[clkCnt]; } - return -1; + return 0; } // by marshmellow @@ -763,15 +747,15 @@ int DetectStrongAskClock(uint8_t dest[], size_t size) int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) { size_t i=1; - uint8_t clk[]={255,8,16,32,40,50,64,100,128,255}; + uint8_t clk[] = {255,8,16,32,40,50,64,100,128,255}; + uint8_t clkEnd = 9; uint8_t loopCnt = 255; //don't need to loop through entire array... - if (size==0) return -1; - if (size <= loopCnt) loopCnt = size-1; //not enough samples + if (size <= loopCnt) return -1; //not enough samples //if we already have a valid clock uint8_t clockFnd=0; - for (;i<9;++i) - if (clk[i] == *clock) clockFnd=i; + for (;i1; i--){ - if (clk[i] == ans) { - *clock = ans; - //clockFnd = i; - return 0; // for strong waves i don't use the 'best start position' yet... - //break; //clock found but continue to find best startpos [not yet] + if (!clockFnd){ + if (DetectCleanAskWave(dest, size, peak, low)==1){ + int ans = DetectStrongAskClock(dest, size, peak, low); + for (i=clkEnd-1; i>0; i--){ + if (clk[i] == ans) { + *clock = ans; + //clockFnd = i; + return 0; // for strong waves i don't use the 'best start position' yet... + //break; //clock found but continue to find best startpos [not yet] + } } } } + uint8_t ii; uint8_t clkCnt, tol = 0; uint16_t bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000}; uint8_t bestStart[]={0,0,0,0,0,0,0,0,0}; size_t errCnt = 0; size_t arrLoc, loopEnd; - //test each valid clock from smallest to greatest to see which lines up - uint8_t clkEnd=9; - if (clockFnd>0) clkEnd=clockFnd+1; - else clockFnd=1; - for(clkCnt=clockFnd; clkCnt < clkEnd; clkCnt++){ + if (clockFnd>0) { + clkCnt = clockFnd; + clkEnd = clockFnd+1; + } + else clkCnt=1; + + //test each valid clock from smallest to greatest to see which lines up + for(; clkCnt < clkEnd; clkCnt++){ if (clk[clkCnt] == 32){ tol=1; }else{ tol=0; } //if no errors allowed - keep start within the first clock - if (!maxErr && size > clk[clkCnt]*3 + tol) loopCnt=clk[clkCnt]*2; + if (!maxErr && size > clk[clkCnt]*2 + tol && clk[clkCnt]<128) loopCnt=clk[clkCnt]*2; bestErr[clkCnt]=1000; //try lining up the peaks by moving starting point (try first few clocks) - for (ii=0; ii < loopCnt-clk[clkCnt]; ii++){ + for (ii=0; ii < loopCnt; ii++){ if (dest[ii] < peak && dest[ii] > low) continue; errCnt=0; @@ -826,11 +816,11 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) errCnt++; } } - //if we found no errors then we can stop here + //if we found no errors then we can stop here and a low clock (common clocks) // this is correct one - return this clock //PrintAndLog("DEBUG: clk %d, err %d, ii %d, i %d",clk[clkCnt],errCnt,ii,i); - if(errCnt==0 && clkCnt<6) { - *clock = clk[clkCnt]; + if(errCnt==0 && clkCnt<7) { + if (!clockFnd) *clock = clk[clkCnt]; return ii; } //if we found errors see if it is lowest so far and save it as best run @@ -840,9 +830,9 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) } } } - uint8_t iii=0; + uint8_t iii; uint8_t best=0; - for (iii=0; iii<8; ++iii){ + for (iii=1; iii maxErr) return -1; - *clock = clk[best]; + if (!clockFnd) *clock = clk[best]; return bestStart[best]; } diff --git a/common/lfdemod.h b/common/lfdemod.h index 15121cbf..0a4ceed9 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -16,7 +16,8 @@ #include int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr); -uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low); +uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low); +int DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low); int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr); uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo); int ManchesterEncode(uint8_t *BitStream, size_t size); -- 2.39.5 From 49bbc60af37da26b73c71f4ff774841fc2290b72 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 7 Apr 2015 00:53:06 -0400 Subject: [PATCH 07/16] lf cleaning++ data askedgedetect - removed unneeded code lf em em4x50read bug fix / error checking graph-save/restore auto repaint after restore. --- client/cmddata.c | 17 ++++------------- client/cmdlfem4x.c | 31 +++++++++++++++++++------------ client/graph.c | 3 ++- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 18b59f21..d838abd1 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -850,23 +850,14 @@ int CmdAskEdgeDetect(const char *Cmd) int thresLen = 25; sscanf(Cmd, "%i", &thresLen); int shift = 127; - int shiftedVal=0; + for(int i = 1; i=thresLen) //large jump up - shift=127; + GraphBuffer[i-1] = 127; else if(GraphBuffer[i]-GraphBuffer[i-1]<=-1*thresLen) //large jump down - shift=-127; - - shiftedVal=GraphBuffer[i]+shift; - - if (shiftedVal>127) - shiftedVal=127; - else if (shiftedVal<-127) - shiftedVal=-127; - GraphBuffer[i-1] = shiftedVal; + GraphBuffer[i-1] = -127; } RepaintGraphWindow(); - //CmdNorm(""); return 0; } @@ -2171,7 +2162,7 @@ int CmdZerocrossings(const char *Cmd) static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, - {"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave (default = 25)"}, + {"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"}, {"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"}, diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index e45c788a..909045d3 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -323,6 +323,7 @@ int EM4x50Read(const char *Cmd, bool verbose) uint32_t Code[6]; char tmp[6]; char tmp2[20]; + int phaseoff; high = low = 0; memset(tmpbuff, 0, MAX_GRAPH_TRACE_LEN / 64); @@ -396,9 +397,11 @@ int EM4x50Read(const char *Cmd, bool verbose) startblock = i + 4; // skip over the remainder of LW - skip += tmpbuff[i+1] + tmpbuff[i+2] + clk + clk/8; - int phaseoff = tmpbuff[i+3]-clk; - + skip += tmpbuff[i+1] + tmpbuff[i+2] + clk; + if (tmpbuff[i+3]>clk) + phaseoff = tmpbuff[i+3]-clk; + else + phaseoff = 0; // now do it again to find the end end = skip; for (i += 3; i < j - 4 ; ++i) { @@ -423,12 +426,6 @@ int EM4x50Read(const char *Cmd, bool verbose) PrintAndLog(" or after a 'data askedge' command to clean up the read"); return 0; } - if (!complete) - { - PrintAndLog("*** Warning!"); - PrintAndLog("Partial data - no end found!"); - PrintAndLog("Try again with more samples."); - } } else if (start < 0) return 0; start = skip; snprintf(tmp2, sizeof(tmp2),"%d %d 1000 %d", clk, invert, clk*47); @@ -451,8 +448,12 @@ int EM4x50Read(const char *Cmd, bool verbose) if (tmpbuff[i+1] >= clk-tol) break; } + if (i >= j-4) break; //next LW not found skip += clk; - phaseoff = tmpbuff[i+1]-clk; + if (tmpbuff[i+1]>clk) + phaseoff = tmpbuff[i+1]-clk; + else + phaseoff = 0; i += 2; if (ASKmanDemod(tmp2, false, false) < 1) { save_restoreGB(0); @@ -475,16 +476,22 @@ int EM4x50Read(const char *Cmd, bool verbose) } //print full code: if (verbose || g_debugMode || AllPTest){ + if (!complete) { + PrintAndLog("*** Warning!"); + PrintAndLog("Partial data - no end found!"); + PrintAndLog("Try again with more samples."); + } PrintAndLog("Found data at sample: %i - using clock: %i", start, clk); end = block; for (block=0; block < end; block++){ PrintAndLog("Block %d: %08x",block,Code[block]); } - if (AllPTest) + if (AllPTest) { PrintAndLog("Parities Passed"); - else + } else { PrintAndLog("Parities Failed"); PrintAndLog("Try cleaning the read samples with 'data askedge'"); + } } //restore GraphBuffer diff --git a/client/graph.c b/client/graph.c index 089119d9..3bea7881 100644 --- a/client/graph.c +++ b/client/graph.c @@ -56,9 +56,10 @@ void save_restoreGB(uint8_t saveOpt) memcpy(SavedGB, GraphBuffer, sizeof(GraphBuffer)); SavedGBlen = GraphTraceLen; GB_Saved=true; - } else if (GB_Saved){ + } else if (GB_Saved){ //restore memcpy(GraphBuffer, SavedGB, sizeof(GraphBuffer)); GraphTraceLen = SavedGBlen; + RepaintGraphWindow(); } return; } -- 2.39.5 From fef74fdce43605f1710319b2b6e45969a5c62835 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 8 Apr 2015 01:07:39 -0400 Subject: [PATCH 08/16] lf ask consolidation backend: askman and askraw demods merged into askdemod (args adjusted accordingly) re-arranged lfdemod.h in alphabetical order and by category front end: data detectclock a (ask) now also reports the selected best start position for demod data manrawdecode takes an invert arg now --- armsrc/lfops.c | 2 +- client/cmddata.c | 236 ++++++++++++++++++-------------------------- client/cmddata.h | 6 +- client/cmdlf.c | 2 +- client/cmdlfem4x.c | 4 +- client/cmdlft55xx.c | 86 ++++++++-------- client/graph.c | 4 +- common/lfdemod.c | 224 ++++++++++++++++------------------------- common/lfdemod.h | 50 +++++----- 9 files changed, 264 insertions(+), 350 deletions(-) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index e5a40b2e..e45b55fc 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -861,7 +861,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) size = BigBuf_max_traceLen(); //askdemod and manchester decode if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format - errCnt = askmandemod(dest, &size, &clk, &invert, maxErr); + errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1); WDT_HIT(); if (errCnt<0) continue; diff --git a/client/cmddata.c b/client/cmddata.c index d838abd1..a8c809cf 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -208,22 +208,34 @@ void printEM410x(uint32_t hi, uint64_t id) return; } - -int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo) +int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo ) { - int ans = ASKmanDemod(Cmd, FALSE, FALSE); - if (!ans) return 0; - - size_t idx=0; - if (Em410xDecode(DemodBuffer,(size_t *) &DemodBufferLen, &idx, hi, lo)){ + size_t idx = 0; + size_t BitLen = DemodBufferLen; + uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; + memcpy(BitStream, DemodBuffer, BitLen); + if (Em410xDecode(BitStream, &BitLen, &idx, hi, lo)){ + //set GraphBuffer for clone or sim command + setDemodBuf(BitStream, BitLen, idx); if (g_debugMode){ - PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, DemodBufferLen); + PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen); printDemodBuff(); } + if (verbose){ + PrintAndLog("EM410x pattern found: "); + printEM410x(*hi, *lo); + } return 1; } return 0; } + +int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose) +{ + if (!ASKDemod(Cmd, FALSE, FALSE, 1)) return 0; + return AskEm410xDecode(verbose, hi, lo); +} + //by marshmellow //takes 3 arguments - clock, invert and maxErr as integers //attempts to demodulate ask while decoding manchester @@ -244,28 +256,28 @@ int CmdAskEM410xDemod(const char *Cmd) PrintAndLog(" : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors"); return 0; } - uint32_t hi = 0; uint64_t lo = 0; - if (AskEm410xDemod(Cmd, &hi, &lo)) { - PrintAndLog("EM410x pattern found: "); - printEM410x(hi, lo); - return 1; - } - return 0; + uint32_t hi = 0; + return AskEm410xDemod(Cmd, &hi, &lo, true); } -int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch) +//by marshmellow +//Cmd Args: Clock, invert, maxErr, maxLen as integers and amplify as char == 'a' +// (amp may not be needed anymore) +//verbose will print results and demoding messages +//emSearch will auto search for EM410x format in bitstream +//askType switches decode: ask/raw = 0, ask/manchester = 1 +int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) { int invert=0; int clk=0; int maxErr=100; - int maxLen=512*64; - //param_getdec(Cmd, 0, &clk); - //param_getdec(Cmd, 1, &invert); - //maxErr = param_get32ex(Cmd, 2, 0xFFFFFFFF, 10); - //if (maxErr == 0xFFFFFFFF) maxErr=100; + int maxLen=0; + uint8_t askAmp = 0; + char amp = param_getchar(Cmd, 0); uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i %i %i", &clk, &invert, &maxErr, &maxLen); + sscanf(Cmd, "%i %i %i %i %c", &clk, &invert, &maxErr, &maxLen, &); + if (!maxLen) maxLen = 512*64; if (invert != 0 && invert != 1) { PrintAndLog("Invalid argument: %s", Cmd); return 0; @@ -274,12 +286,14 @@ int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch) invert=1; clk=0; } + if (amp == 'a' || amp == 'A') askAmp=1; size_t BitLen = getFromGraphBuf(BitStream); if (g_debugMode) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen); - if (!BitLen) return 0; + if (BitLen<255) return 0; if (maxLen0){ - if (verbose || g_debugMode) PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d",errCnt); - } - if (verbose || g_debugMode) PrintAndLog("ASK/Manchester decoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits setDemodBuf(BitStream,BitLen,0); - if (verbose || g_debugMode) printDemodBuff(); - uint64_t lo =0; - uint32_t hi =0; - size_t idx=0; + if (verbose || g_debugMode){ + if (errCnt>0) PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d",errCnt); + if (askType) PrintAndLog("ASK/Manchester decoded bitstream:"); + else PrintAndLog("ASK/Raw decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printDemodBuff(); + + } + uint64_t lo = 0; + uint32_t hi = 0; if (emSearch){ - if (Em410xDecode(BitStream, &BitLen, &idx, &hi, &lo)){ - //set GraphBuffer for clone or sim command - setDemodBuf(BitStream, BitLen, idx); - if (g_debugMode){ - PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen); - printDemodBuff(); - } - if (verbose) PrintAndLog("EM410x pattern found: "); - if (verbose) printEM410x(hi, lo); - return 1; - } + AskEm410xDecode(true, &hi, &lo); } return 1; } //by marshmellow -//takes 3 arguments - clock, invert, maxErr as integers +//takes 5 arguments - clock, invert, maxErr, maxLen as integers and amplify as char == 'a' //attempts to demodulate ask while decoding manchester //prints binary found and saves in graphbuffer for further commands int Cmdaskmandemod(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 20 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data rawdemod am [clock] <0|1> [maxError] [setSmplLen]"); - PrintAndLog(" [set clock as integer] optional, if not set, autodetect."); - PrintAndLog(" , 1 for invert output"); - PrintAndLog(" [set maximum allowed errors], default = 100."); - PrintAndLog(" [set maximum Samples to read], default = 32768 (512 bits at rf/64)."); + if (strlen(Cmd) > 25 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data rawdemod am [clock] [maxError] [maxLen] [amplify]"); + PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); + PrintAndLog(" , 1 to invert output"); + PrintAndLog(" [set maximum allowed errors], default = 100"); + PrintAndLog(" [set maximum Samples to read], default = 32768 (512 bits at rf/64)"); + PrintAndLog(" , 'a' to attempt demod with ask amplification, default = no amp"); PrintAndLog(""); PrintAndLog(" sample: data rawdemod am = demod an ask/manchester tag from GraphBuffer"); PrintAndLog(" : data rawdemod am 32 = demod an ask/manchester tag from GraphBuffer using a clock of RF/32"); @@ -337,7 +343,7 @@ int Cmdaskmandemod(const char *Cmd) PrintAndLog(" : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); return 0; } - return ASKmanDemod(Cmd, TRUE, TRUE); + return ASKDemod(Cmd, TRUE, TRUE, 1); } //by marshmellow @@ -348,12 +354,14 @@ int Cmdmandecoderaw(const char *Cmd) int i =0; int errCnt=0; size_t size=0; + int invert=0; size_t maxErr = 20; char cmdp = param_getchar(Cmd, 0); if (strlen(Cmd) > 5 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data manrawdecode [maxErr]"); + PrintAndLog("Usage: data manrawdecode [invert] [maxErr]"); PrintAndLog(" Takes 10 and 01 and converts to 0 and 1 respectively"); PrintAndLog(" --must have binary sequence in demodbuffer (run data askrawdemod first)"); + PrintAndLog(" [invert] invert output"); PrintAndLog(" [maxErr] set number of errors allowed (default = 20)"); PrintAndLog(""); PrintAndLog(" sample: data manrawdecode = decode manchester bitstream from the demodbuffer"); @@ -372,9 +380,9 @@ int Cmdmandecoderaw(const char *Cmd) return 0; } - sscanf(Cmd, "%i", &maxErr); + sscanf(Cmd, "%i %i", &invert, &maxErr); size=i; - errCnt=manrawdecode(BitStream, &size); + errCnt=manrawdecode(BitStream, &size, invert); if (errCnt>=maxErr){ PrintAndLog("Too many errors: %d",errCnt); return 0; @@ -448,59 +456,6 @@ int CmdBiphaseDecodeRaw(const char *Cmd) return 1; } -//by marshmellow -//takes 4 arguments - clock, invert, maxErr as integers and amplify as char -//attempts to demodulate ask only -//prints binary found and saves in graphbuffer for further commands -int ASKrawDemod(const char *Cmd, bool verbose) -{ - int invert=0; - int clk=0; - int maxErr=100; - uint8_t askAmp = 0; - char amp = param_getchar(Cmd, 0); - uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0}; - sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &); - if (invert != 0 && invert != 1) { - if (verbose || g_debugMode) PrintAndLog("Invalid argument: %s", Cmd); - return 0; - } - if (clk==1){ - invert=1; - clk=0; - } - if (amp == 'a' || amp == 'A') askAmp=1; - size_t BitLen = getFromGraphBuf(BitStream); - if (BitLen==0) return 0; - int errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp); - if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first) - if (verbose || g_debugMode) PrintAndLog("no data found"); - if (g_debugMode) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert); - return 0; - } - if (errCnt>maxErr) { - if (g_debugMode) - PrintAndLog("Too many errors found, errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert); - return 0; - } - if (verbose || g_debugMode) - PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen); - - //move BitStream back to DemodBuffer - setDemodBuf(BitStream,BitLen,0); - - //output - if (errCnt>0 && (verbose || g_debugMode)){ - PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d", errCnt); - } - if (verbose || g_debugMode){ - PrintAndLog("ASK demoded bitstream:"); - // Now output the bitstream to the scrollback by line of 16 bits - printDemodBuff(); - } - return 1; -} - //by marshmellow // - ASK Demod then Biphase decode GraphBuffer samples int ASKbiphaseDemod(const char *Cmd, bool verbose) @@ -509,11 +464,11 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) int offset=0, clk=0, invert=0, maxErr=0, ans=0; ans = sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr); if (ans>0) - ans = ASKrawDemod(Cmd+1, FALSE); + ans = ASKDemod(Cmd+1, FALSE, FALSE, 0); else - ans = ASKrawDemod(Cmd, FALSE); + ans = ASKDemod(Cmd, FALSE, FALSE, 0); if (!ans) { - if (g_debugMode || verbose) PrintAndLog("Error AskrawDemod: %d", ans); + if (g_debugMode || verbose) PrintAndLog("Error AskDemod: %d", ans); return 0; } @@ -521,8 +476,7 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) size_t size = DemodBufferLen; uint8_t BitStream[MAX_DEMOD_BUF_LEN]; memcpy(BitStream, DemodBuffer, DemodBufferLen); - - int errCnt = BiphaseRawDecode(BitStream, &size, offset, invert); + int errCnt = BiphaseRawDecode(BitStream, &size, offset, 0); if (errCnt < 0){ if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode: %d", errCnt); return 0; @@ -543,12 +497,13 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) int Cmdaskbiphdemod(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data rawdemod ab [offset] [clock] [maxError] "); + if (strlen(Cmd) > 25 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data rawdemod ab [offset] [clock] [maxError] [maxLen] "); PrintAndLog(" [offset], offset to begin biphase, default=0"); PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); PrintAndLog(" , 1 to invert output"); PrintAndLog(" [set maximum allowed errors], default = 100"); + PrintAndLog(" [set maximum Samples to read], default = 32768 (512 bits at rf/64)"); PrintAndLog(" , 'a' to attempt demod with ask amplification, default = no amp"); PrintAndLog(" NOTE: can be entered as second or third argument"); PrintAndLog(" NOTE: can be entered as first, second or last argument"); @@ -556,13 +511,13 @@ int Cmdaskbiphdemod(const char *Cmd) PrintAndLog(""); PrintAndLog(" NOTE: --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester"); PrintAndLog(""); - PrintAndLog(" sample: data rawdemod ab = demod an ask/biph tag from GraphBuffer"); - PrintAndLog(" : data rawdemod ab a = demod an ask/biph tag from GraphBuffer, amplified"); - PrintAndLog(" : data rawdemod ab 1 32 = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32"); - PrintAndLog(" : data rawdemod ab 0 32 1 = demod an ask/biph tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLog(" : data rawdemod ab 0 1 = demod an ask/biph tag from GraphBuffer while inverting data"); - PrintAndLog(" : data rawdemod ab 0 64 1 0 = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); - PrintAndLog(" : data rawdemod ab 0 64 1 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); + PrintAndLog(" sample: data rawdemod ab = demod an ask/biph tag from GraphBuffer"); + PrintAndLog(" : data rawdemod ab 0 a = demod an ask/biph tag from GraphBuffer, amplified"); + PrintAndLog(" : data rawdemod ab 1 32 = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32"); + PrintAndLog(" : data rawdemod ab 0 32 1 = demod an ask/biph tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data rawdemod ab 0 1 = demod an ask/biph tag from GraphBuffer while inverting data"); + PrintAndLog(" : data rawdemod ab 0 64 1 0 = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLog(" : data rawdemod ab 0 64 1 0 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); return 0; } return ASKbiphaseDemod(Cmd, TRUE); @@ -646,27 +601,28 @@ int CmdG_Prox_II_Demod(const char *Cmd) return 1; } -//by marshmellow - see ASKrawDemod +//by marshmellow - see ASKDemod int Cmdaskrawdemod(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data rawdemod ar [clock] [maxError] [amplify]"); + if (strlen(Cmd) > 25 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data rawdemod ar [clock] [maxError] [maxLen] [amplify]"); PrintAndLog(" [set clock as integer] optional, if not set, autodetect"); PrintAndLog(" , 1 to invert output"); PrintAndLog(" [set maximum allowed errors], default = 100"); + PrintAndLog(" [set maximum Samples to read], default = 32768 (1024 bits at rf/64)"); PrintAndLog(" , 'a' to attempt demod with ask amplification, default = no amp"); PrintAndLog(""); - PrintAndLog(" sample: data rawdemod ar = demod an ask tag from GraphBuffer"); - PrintAndLog(" : data rawdemod ar a = demod an ask tag from GraphBuffer, amplified"); - PrintAndLog(" : data rawdemod ar 32 = demod an ask tag from GraphBuffer using a clock of RF/32"); - PrintAndLog(" : data rawdemod ar 32 1 = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data"); - PrintAndLog(" : data rawdemod ar 1 = demod an ask tag from GraphBuffer while inverting data"); - PrintAndLog(" : data rawdemod ar 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); - PrintAndLog(" : data rawdemod ar 64 1 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); + PrintAndLog(" sample: data rawdemod ar = demod an ask tag from GraphBuffer"); + PrintAndLog(" : data rawdemod ar a = demod an ask tag from GraphBuffer, amplified"); + PrintAndLog(" : data rawdemod ar 32 = demod an ask tag from GraphBuffer using a clock of RF/32"); + PrintAndLog(" : data rawdemod ar 32 1 = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data"); + PrintAndLog(" : data rawdemod ar 1 = demod an ask tag from GraphBuffer while inverting data"); + PrintAndLog(" : data rawdemod ar 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); + PrintAndLog(" : data rawdemod ar 64 1 0 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); return 0; } - return ASKrawDemod(Cmd, TRUE); + return ASKDemod(Cmd, TRUE, FALSE, 0); } int AutoCorrelate(int window, bool SaveGrph, bool verbose) @@ -849,7 +805,6 @@ int CmdAskEdgeDetect(const char *Cmd) { int thresLen = 25; sscanf(Cmd, "%i", &thresLen); - int shift = 127; for(int i = 1; i=thresLen) //large jump up @@ -867,9 +822,10 @@ int CmdAskEdgeDetect(const char *Cmd) int CmdDetectClockRate(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); - if (strlen(Cmd) > 3 || strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') { - PrintAndLog("Usage: data detectclock [modulation]"); + if (strlen(Cmd) > 6 || strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') { + PrintAndLog("Usage: data detectclock [modulation] "); PrintAndLog(" [modulation as char], specify the modulation type you want to detect the clock of"); + PrintAndLog(" , specify the clock (optional - to get best start position only)"); PrintAndLog(" 'a' = ask, 'f' = fsk, 'n' = nrz/direct, 'p' = psk"); PrintAndLog(""); PrintAndLog(" sample: data detectclock a = detect the clock of an ask modulated wave in the GraphBuffer"); @@ -879,7 +835,7 @@ int CmdDetectClockRate(const char *Cmd) } int ans=0; if (cmdp == 'a'){ - ans = GetAskClock("", true, false); + ans = GetAskClock(Cmd+1, true, false); } else if (cmdp == 'f'){ ans = GetFskClock("", true, false); } else if (cmdp == 'n'){ @@ -2166,7 +2122,7 @@ static command_t CommandTable[] = {"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"}, {"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)"}, + {"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"}, {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"}, {"dec", CmdDec, 1, "Decimate samples"}, @@ -2185,7 +2141,7 @@ static command_t CommandTable[] = {"load", CmdLoad, 1, " -- Load trace (to graph window"}, {"ltrim", CmdLtrim, 1, " -- Trim samples from left of trace"}, {"rtrim", CmdRtrim, 1, " -- Trim samples from right of trace"}, - {"manrawdecode", Cmdmandecoderaw, 1, "[maxErr] -- Manchester decode binary stream in DemodBuffer"}, + {"manrawdecode", Cmdmandecoderaw, 1, "[invert] [maxErr] -- Manchester decode binary stream in DemodBuffer"}, {"norm", CmdNorm, 1, "Normalize max/min to +/-128"}, {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"}, {"printdemodbuffer",CmdPrintDemodBuff, 1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"}, diff --git a/client/cmddata.h b/client/cmddata.h index 0d2e32d6..9e179b9c 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -56,10 +56,10 @@ int CmdScale(const char *Cmd); int CmdDirectionalThreshold(const char *Cmd); int CmdZerocrossings(const char *Cmd); int CmdIndalaDecode(const char *Cmd); -int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo); +int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo ); +int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose); int ASKbiphaseDemod(const char *Cmd, bool verbose); -int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch); -int ASKrawDemod(const char *Cmd, bool verbose); +int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType); int FSKrawDemod(const char *Cmd, bool verbose); int PSKDemod(const char *Cmd, bool verbose); int NRZrawDemod(const char *Cmd, bool verbose); diff --git a/client/cmdlf.c b/client/cmdlf.c index a52e1423..d441574a 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1091,7 +1091,7 @@ int CmdLFfind(const char *Cmd) return 1; } } - ans=ASKmanDemod("0 0 0",TRUE,FALSE); + 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'"); diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 909045d3..614624a6 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -47,7 +47,7 @@ int CmdEM410xRead(const char *Cmd) uint32_t hi=0; uint64_t lo=0; - if(!AskEm410xDemod("", &hi, &lo)) return 0; + if(!AskEm410xDemod("", &hi, &lo, false)) return 0; PrintAndLog("EM410x pattern found: "); printEM410x(hi, lo); if (hi){ @@ -455,7 +455,7 @@ int EM4x50Read(const char *Cmd, bool verbose) else phaseoff = 0; i += 2; - if (ASKmanDemod(tmp2, false, false) < 1) { + if (ASKDemod(tmp2, false, false, 1) < 1) { save_restoreGB(0); return 0; } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index e0f89153..564ad29d 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -262,11 +262,10 @@ int CmdT55xxReadBlock(const char *Cmd) { bool DecodeT55xxBlock(){ - char buf[10] = {0x00}; + char buf[30] = {0x00}; char *cmdStr = buf; int ans = 0; uint8_t bitRate[8] = {8,16,32,40,50,64,100,128}; - DemodBufferLen = 0x00; //trim 1/2 a clock from beginning @@ -290,7 +289,7 @@ bool DecodeT55xxBlock(){ break; case DEMOD_ASK: snprintf(cmdStr, sizeof(buf),"%d %d 0", bitRate[config.bitrate], config.inverted ); - ans = ASKmanDemod(cmdStr, FALSE, FALSE); + ans = ASKDemod(cmdStr, FALSE, FALSE, 1); break; case DEMOD_PSK1: snprintf(cmdStr, sizeof(buf),"%d %d 0", bitRate[config.bitrate], config.inverted ); @@ -337,72 +336,79 @@ bool tryDetectModulation(){ char cmdStr[8] = {0}; uint8_t hits = 0; t55xx_conf_block_t tests[15]; - + int bitRate=0; if (GetFskClock("", FALSE, FALSE)){ uint8_t fc1 = 0, fc2 = 0, clk=0; fskClocks(&fc1, &fc2, &clk, FALSE); sprintf(cmdStr,"%d", clk/2); CmdLtrim(cmdStr); - if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset)){ + if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)){ tests[hits].modulation = DEMOD_FSK; if (fc1==8 && fc2 == 5) tests[hits].modulation = DEMOD_FSK1a; else if (fc1==10 && fc2 == 8) tests[hits].modulation = DEMOD_FSK2; - + tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } - if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset)) { + if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_FSK; - if (fc1==8 && fc2 == 5) + if (fc1 == 8 && fc2 == 5) tests[hits].modulation = DEMOD_FSK1; - else if (fc1==10 && fc2 == 8) + else if (fc1 == 10 && fc2 == 8) tests[hits].modulation = DEMOD_FSK2a; + tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } } else { - if ( ASKmanDemod("0 0 1", FALSE, FALSE) && test(DEMOD_ASK, &tests[hits].offset)) { + if ( ASKDemod("0 0 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_ASK; + tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; - } + } - if ( ASKmanDemod("0 1 1", FALSE, FALSE) && test(DEMOD_ASK, &tests[hits].offset)) { + if ( ASKDemod("0 1 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_ASK; + tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; - } + } - if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset)) { + if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_NRZ; + tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } - if ( NRZrawDemod("0 1 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset)) { + if ( NRZrawDemod("0 1 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_NRZ; + tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; - } + } - if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) { + if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_PSK1; + tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } - if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) { + if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_PSK1; + tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; @@ -411,8 +417,9 @@ bool tryDetectModulation(){ // PSK2 - needs a call to psk1TOpsk2. if ( PSKDemod("0 0 1", FALSE)) { psk1TOpsk2(DemodBuffer, DemodBufferLen); - if (test(DEMOD_PSK2, &tests[hits].offset)){ + if (test(DEMOD_PSK2, &tests[hits].offset, &bitRate)){ tests[hits].modulation = DEMOD_PSK2; + tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; @@ -422,22 +429,25 @@ bool tryDetectModulation(){ // PSK3 - needs a call to psk1TOpsk2. if ( PSKDemod("0 0 1", FALSE)) { psk1TOpsk2(DemodBuffer, DemodBufferLen); - if (test(DEMOD_PSK3, &tests[hits].offset)){ + if (test(DEMOD_PSK3, &tests[hits].offset, &bitRate)){ tests[hits].modulation = DEMOD_PSK3; + tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } } // inverse waves does not affect this demod - if ( ASKbiphaseDemod("0 0 0 1", FALSE) && test(DEMOD_BI, &tests[hits].offset) ) { + if ( ASKbiphaseDemod("0 0 0 1", FALSE) && test(DEMOD_BI, &tests[hits].offset, &bitRate) ) { tests[hits].modulation = DEMOD_BI; + tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } - if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BIa, &tests[hits].offset) ) { + if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BIa, &tests[hits].offset, &bitRate) ) { tests[hits].modulation = DEMOD_BIa; + tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; @@ -445,6 +455,7 @@ bool tryDetectModulation(){ } if ( hits == 1) { config.modulation = tests[0].modulation; + config.bitrate = tests[0].bitrate; config.inverted = tests[0].inverted; config.offset = tests[0].offset; config.block0 = tests[0].block0; @@ -504,35 +515,27 @@ bool testBitRate(uint8_t readRate, uint8_t mod){ case DEMOD_FSK2: case DEMOD_FSK2a: detRate = GetFskClock("",FALSE, FALSE); - if (expected[readRate] == detRate) { - config.bitrate = readRate; + if (expected[readRate] == detRate) return TRUE; - } break; case DEMOD_ASK: case DEMOD_BI: case DEMOD_BIa: detRate = GetAskClock("",FALSE, FALSE); - if (expected[readRate] == detRate) { - config.bitrate = readRate; + if (expected[readRate] == detRate) return TRUE; - } break; case DEMOD_PSK1: case DEMOD_PSK2: case DEMOD_PSK3: detRate = GetPskClock("",FALSE, FALSE); - if (expected[readRate] == detRate) { - config.bitrate = readRate; + if (expected[readRate] == detRate) return TRUE; - } break; case DEMOD_NRZ: detRate = GetNrzClock("",FALSE, FALSE); - if (expected[readRate] == detRate) { - config.bitrate = readRate; + if (expected[readRate] == detRate) return TRUE; - } break; default: return FALSE; @@ -540,9 +543,9 @@ bool testBitRate(uint8_t readRate, uint8_t mod){ return FALSE; } -bool test(uint8_t mode, uint8_t *offset){ +bool test(uint8_t mode, uint8_t *offset, int *fndBitRate){ - if ( !DemodBufferLen) return FALSE; + if ( DemodBufferLen < 64 ) return FALSE; uint8_t si = 0; for (uint8_t idx = 0; idx < 64; idx++){ si = idx; @@ -555,7 +558,8 @@ bool test(uint8_t mode, uint8_t *offset){ if ( resv > 0x00) continue; uint8_t xtRate = PackBits(si, 3, DemodBuffer); si += 3; //extended mode part of rate - uint8_t bitRate = PackBits(si, 3, DemodBuffer); si += 3; //bit rate + int bitRate = PackBits(si, 3, DemodBuffer); si += 3; //bit rate + if (bitRate > 7) continue; uint8_t extend = PackBits(si, 1, DemodBuffer); si += 1; //bit 15 extended mode uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1; //uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //could check psk cr @@ -571,6 +575,7 @@ bool test(uint8_t mode, uint8_t *offset){ //test modulation if (!testModulation(mode, modread)) continue; if (!testBitRate(bitRate, mode)) continue; + *fndBitRate = bitRate; *offset = idx; return TRUE; } @@ -760,10 +765,10 @@ int CmdT55xxInfo(const char *Cmd){ if (strlen(Cmd)==0) AquireData( CONFIGURATION_BLOCK ); - + if (!DecodeT55xxBlock()) return 1; - if ( !DemodBufferLen) return 1; + if ( DemodBufferLen < 32) return 1; uint8_t si = config.offset; uint32_t bl0 = PackBits(si, 32, DemodBuffer); @@ -873,7 +878,8 @@ int AquireData( uint8_t block ){ } char * GetBitRateStr(uint32_t id){ - static char buf[20]; + static char buf[25]; + char *retStr = buf; switch (id){ case 0: diff --git a/client/graph.c b/client/graph.c index 3bea7881..06279848 100644 --- a/client/graph.c +++ b/client/graph.c @@ -143,10 +143,10 @@ int GetAskClock(const char str[], bool printAns, bool verbose) PrintAndLog("Failed to copy from graphbuffer"); return -1; } - DetectASKClock(grph, size, &clock, 20); + int start = DetectASKClock(grph, size, &clock, 20); // Only print this message if we're not looping something if (printAns){ - PrintAndLog("Auto-detected clock rate: %d", clock); + PrintAndLog("Auto-detected clock rate: %d, Best Starting Position: %d", clock, start); } return clock; } diff --git a/common/lfdemod.c b/common/lfdemod.c index 5bbf8a66..7d40d22e 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -112,7 +112,8 @@ uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_ return 0; } -// demodulates strong heavily clipped samples +//by marshmellow +//demodulates strong heavily clipped samples int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int high, int low) { size_t bitCnt=0, smplCnt=0, errCnt=0; @@ -163,52 +164,81 @@ int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int } //by marshmellow -//takes 3 arguments - clock, invert, maxErr as integers -//attempts to demodulate ask while decoding manchester -//prints binary found and saves in graphbuffer for further commands -int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr) +void askAmp(uint8_t *BitStream, size_t size) { - size_t i; + for(size_t i = 1; i=30) //large jump up + BitStream[i]=127; + else if(BitStream[i]-BitStream[i-1]<=-20) //large jump down + BitStream[i]=-127; + } + return; +} + +//by marshmellow +//attempts to demodulate ask modulations, askType == 0 for ask/raw, askType==1 for ask/manchester +int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType) +{ + if (*size==0) return -1; int start = DetectASKClock(BinStream, *size, clk, maxErr); //clock default if (*clk==0 || start < 0) return -3; - if (*invert != 1) *invert=0; + if (*invert != 1) *invert = 0; + if (amp==1) askAmp(BinStream, *size); + uint8_t initLoopMax = 255; if (initLoopMax > *size) initLoopMax = *size; // Detect high and lows - // 25% fuzz in case highs and lows aren't clipped [marshmellow] + //25% clip in case highs and lows aren't clipped [marshmellow] int high, low; - if (getHiLo(BinStream, initLoopMax, &high, &low, 75, 75) < 1) return -2; //just noise + if (getHiLo(BinStream, initLoopMax, &high, &low, 75, 75) < 1) + return -2; //just noise + size_t errCnt = 0; // if clean clipped waves detected run alternate demod if (DetectCleanAskWave(BinStream, *size, high, low)) { - cleanAskRawDemod(BinStream, size, *clk, *invert, high, low); - return manrawdecode(BinStream, size); + errCnt = cleanAskRawDemod(BinStream, size, *clk, *invert, high, low); + if (askType) //askman + return manrawdecode(BinStream, size, 0); + else //askraw + return errCnt; } - // PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); - int lastBit; //set first clock check - uint16_t bitnum = 0; //output counter + int lastBit; //set first clock check - can go negative + size_t i, bitnum = 0; //output counter + uint8_t midBit = 0; uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave - if (*clk <= 32) tol=1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely - uint16_t errCnt = 0, MaxBits = 512; + if (*clk <= 32) tol = 1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely + size_t MaxBits = 1024; lastBit = start - *clk; + for (i = start; i < *size; ++i) { - if ((BinStream[i] >= high) && ((i-lastBit) > (*clk-tol))){ - //high found and we are expecting a bar - lastBit += *clk; - BinStream[bitnum++] = *invert; - } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){ - //low found and we are expecting a bar + if (i-lastBit >= *clk-tol){ + if (BinStream[i] >= high) { + BinStream[bitnum++] = *invert; + } else if (BinStream[i] <= low) { + BinStream[bitnum++] = *invert ^ 1; + } else if (i-lastBit >= *clk+tol) { + if (bitnum > 0) { + BinStream[bitnum++]=7; + errCnt++; + } + } else { //in tolerance - looking for peak + continue; + } + midBit = 0; lastBit += *clk; - BinStream[bitnum++] = *invert ^ 1; - } else if ((i-lastBit)>(*clk+tol)){ - //should have hit a high or low based on clock!! - //PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit); - if (bitnum > 0) { - BinStream[bitnum++] = 7; - errCnt++; - } - lastBit += *clk;//skip over error + } else if (i-lastBit >= (*clk/2-tol) && !midBit && !askType){ + if (BinStream[i] >= high) { + BinStream[bitnum++] = *invert; + } else if (BinStream[i] <= low) { + BinStream[bitnum++] = *invert ^ 1; + } else if (i-lastBit >= *clk/2+tol) { + BinStream[bitnum] = BinStream[bitnum-1]; + bitnum++; + } else { //in tolerance - looking for peak + continue; + } + midBit = 1; } if (bitnum >= MaxBits) break; } @@ -216,34 +246,18 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max return errCnt; } -//by marshmellow -//encode binary data into binary manchester -int ManchesterEncode(uint8_t *BitStream, size_t size) -{ - size_t modIdx=20000, i=0; - if (size>modIdx) return -1; - for (size_t idx=0; idx < size; idx++){ - BitStream[idx+modIdx++] = BitStream[idx]; - BitStream[idx+modIdx++] = BitStream[idx]^1; - } - for (; i<(size*2); i++){ - BitStream[i] = BitStream[i+20000]; - } - return i; -} - //by marshmellow //take 10 and 01 and manchester decode //run through 2 times and take least errCnt -int manrawdecode(uint8_t * BitStream, size_t *size) +int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert) { uint16_t bitnum=0, MaxBits = 512, errCnt = 0; size_t i, ii; uint16_t bestErr = 1000, bestRun = 0; - if (size == 0) return -1; + if (*size < 16) return -1; //find correct start position [alignment] for (ii=0;ii<2;++ii){ - for (i=ii; i<*size-2; i+=2) + for (i=ii; i<*size-3; i+=2) if (BitStream[i]==BitStream[i+1]) errCnt++; @@ -254,11 +268,11 @@ int manrawdecode(uint8_t * BitStream, size_t *size) errCnt=0; } //decode - for (i=bestRun; i < *size-2; i+=2){ + for (i=bestRun; i < *size-3; i+=2){ if(BitStream[i] == 1 && (BitStream[i+1] == 0)){ - BitStream[bitnum++]=0; + BitStream[bitnum++]=invert; } else if((BitStream[i] == 0) && BitStream[i+1] == 1){ - BitStream[bitnum++]=1; + BitStream[bitnum++]=invert^1; } else { BitStream[bitnum++]=7; } @@ -268,6 +282,22 @@ int manrawdecode(uint8_t * BitStream, size_t *size) return bestErr; } +//by marshmellow +//encode binary data into binary manchester +int ManchesterEncode(uint8_t *BitStream, size_t size) +{ + size_t modIdx=20000, i=0; + if (size>modIdx) return -1; + for (size_t idx=0; idx < size; idx++){ + BitStream[idx+modIdx++] = BitStream[idx]; + BitStream[idx+modIdx++] = BitStream[idx]^1; + } + for (; i<(size*2); i++){ + BitStream[i] = BitStream[i+20000]; + } + return i; +} + //by marshmellow //take 01 or 10 = 1 and 11 or 00 = 0 //check for phase errors - should never have 111 or 000 should be 01001011 or 10110100 for 1010 @@ -307,88 +337,7 @@ int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert) return errCnt; } -//by marshmellow -void askAmp(uint8_t *BitStream, size_t size) -{ - int shift = 127; - int shiftedVal=0; - for(size_t i = 1; i=30) //large jump up - shift=127; - else if(BitStream[i]-BitStream[i-1]<=-20) //large jump down - shift=-127; - - shiftedVal=BitStream[i]+shift; - - if (shiftedVal>255) - shiftedVal=255; - else if (shiftedVal<0) - shiftedVal=0; - BitStream[i-1] = shiftedVal; - } - return; -} - -//by marshmellow -//takes 3 arguments - clock, invert and maxErr as integers -//attempts to demodulate ask only -int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp) -{ - if (*size==0) return -1; - int start = DetectASKClock(BinStream, *size, clk, maxErr); //clock default - if (*clk==0 || start < 0) return -1; - if (*invert != 1) *invert = 0; - if (amp==1) askAmp(BinStream, *size); - - uint8_t initLoopMax = 255; - if (initLoopMax > *size) initLoopMax = *size; - // Detect high and lows - //25% clip in case highs and lows aren't clipped [marshmellow] - int high, low; - if (getHiLo(BinStream, initLoopMax, &high, &low, 75, 75) < 1) - return -1; //just noise - - // if clean clipped waves detected run alternate demod - if (DetectCleanAskWave(BinStream, *size, high, low)) - return cleanAskRawDemod(BinStream, size, *clk, *invert, high, low); - - int lastBit; //set first clock check - can go negative - size_t i, errCnt = 0, bitnum = 0; //output counter - uint8_t midBit = 0; - size_t MaxBits = 1024; - lastBit = start - *clk; - - for (i = start; i < *size; ++i) { - if (i - lastBit == *clk){ - if (BinStream[i] >= high) { - BinStream[bitnum++] = *invert; - } else if (BinStream[i] <= low) { - BinStream[bitnum++] = *invert ^ 1; - } else { - if (bitnum > 0) { - BinStream[bitnum++]=7; - errCnt++; - } - } - midBit = 0; - lastBit += *clk; - } else if (i-lastBit == (*clk/2) && midBit == 0){ - if (BinStream[i] >= high) { - BinStream[bitnum++] = *invert; - } else if (BinStream[i] <= low) { - BinStream[bitnum++] = *invert ^ 1; - } else { - BinStream[bitnum] = BinStream[bitnum-1]; - bitnum++; - } - midBit = 1; - } - if (bitnum >= MaxBits) break; - } - *size = bitnum; - return errCnt; -} - +// by marshmellow // demod gProxIIDemod // error returns as -x // success returns start position in BitStream @@ -684,7 +633,8 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size) return (int)startIdx; } - +// by marshmellow +// to detect a wave that has heavily clipped (clean) samples uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low) { uint16_t allPeaks=1; @@ -792,7 +742,7 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) //test each valid clock from smallest to greatest to see which lines up for(; clkCnt < clkEnd; clkCnt++){ - if (clk[clkCnt] == 32){ + if (clk[clkCnt] <= 32){ tol=1; }else{ tol=0; diff --git a/common/lfdemod.h b/common/lfdemod.h index 0a4ceed9..ab81c34c 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -15,35 +15,37 @@ #define LFDEMOD_H__ #include -int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr); -uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low); -int DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low); -int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr); -uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo); -int ManchesterEncode(uint8_t *BitStream, size_t size); -int manrawdecode(uint8_t *BitStream, size_t *size); -int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert); -int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp); +//generic +int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType); +int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert); +uint32_t bytebits_to_byte(uint8_t* src, size_t numbits); +uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj); +int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr); +uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low); +uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow); +int DetectNRZClock(uint8_t dest[], size_t size, int clock); +int DetectPSKClock(uint8_t dest[], size_t size, int clock); +int DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low); +uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo); +int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow); +int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo); +int ManchesterEncode(uint8_t *BitStream, size_t size); +int manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert); +int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr); +uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType); +uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx); +int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert); +void psk2TOpsk1(uint8_t *BitStream, size_t size); +void psk1TOpsk2(uint8_t *BitStream, size_t size); +size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen); + +//tag specific +int AWIDdemodFSK(uint8_t *dest, size_t *size); 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 fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow); -uint32_t bytebits_to_byte(uint8_t* src, size_t numbits); -int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr); -void psk1TOpsk2(uint8_t *BitStream, size_t size); -void psk2TOpsk1(uint8_t *BitStream, size_t size); -int DetectNRZClock(uint8_t dest[], size_t size, int clock); int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert); int PyramiddemodFSK(uint8_t *dest, size_t *size); -int AWIDdemodFSK(uint8_t *dest, size_t *size); -size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen); -uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj); -uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow); -int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo); int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo); -uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx); -uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType); -int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert); -int DetectPSKClock(uint8_t dest[], size_t size, int clock); #endif -- 2.39.5 From 83602affe5ae7fd7fdc1b91722599c2450285929 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Wed, 8 Apr 2015 13:31:04 +0200 Subject: [PATCH 09/16] Fixed buffer initialization errors, as reported in http://www.proxmark.org/forum/viewtopic.php?pid=15337#p15337 --- armsrc/iclass.c | 3 ++- client/cmdhfmf.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 7b4daa36..56bc29db 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -1675,7 +1675,8 @@ uint8_t handshakeIclassTag(uint8_t *card_data) // Reader iClass Anticollission void ReaderIClass(uint8_t arg0) { - uint8_t card_data[6 * 8]={0xFF}; + uint8_t card_data[6 * 8]={0}; + memset(card_data, 0xFF, sizeof(card_data)); uint8_t last_csn[8]={0}; //Read conf block CRC(0x01) => 0xfa 0x22 diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 468243fc..5f2e8dec 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -434,7 +434,7 @@ int CmdHF14AMfRestore(const char *Cmd) { uint8_t sectorNo,blockNo; uint8_t keyType = 0; - uint8_t key[6] = {0xFF}; + uint8_t key[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; uint8_t bldata[16] = {0x00}; uint8_t keyA[40][6]; uint8_t keyB[40][6]; -- 2.39.5 From 9632ecbe3da943a256b6925cae28965857383926 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 8 Apr 2015 10:12:24 -0400 Subject: [PATCH 10/16] update t5 detection test() missed this file in last commit... sorry. --- client/cmdlft55xx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index a64b1eda..364f0271 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -53,13 +53,13 @@ char * GetSaferStr(uint32_t id); char * GetModulationStr( uint32_t id); char * GetModelStrFromCID(uint32_t cid); char * GetSelectedModulationStr( uint8_t id); -uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bitstream); +uint32_t PackBits(uint8_t start, uint8_t len, uint8_t *bitstream); void printT55xxBlock(const char *demodStr); void printConfiguration( t55xx_conf_block_t b); bool DecodeT55xxBlock(); bool tryDetectModulation(); -bool test(uint8_t mode, uint8_t *offset); +bool test(uint8_t mode, uint8_t *offset, int *fndBitRate); int special(const char *Cmd); int AquireData( uint8_t block ); -- 2.39.5 From 322f7eb111e0337e8a509fa104c23502081d6df5 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 8 Apr 2015 11:18:29 -0400 Subject: [PATCH 11/16] fix to lf t5 detect/read cmds i think this functions fairly well... still some issues with demod positioning for various reasons. ASK/Biph/FSK work pretty well the PSK Demod still needs a little attention to help it better demod various carriers... --- client/cmdlft55xx.c | 162 ++++++++++++++++++++++++-------------------- 1 file changed, 88 insertions(+), 74 deletions(-) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 564ad29d..3134dde7 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -271,7 +271,6 @@ bool DecodeT55xxBlock(){ //trim 1/2 a clock from beginning snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 ); CmdLtrim(cmdStr); - switch( config.modulation ){ case DEMOD_FSK: snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted ); @@ -337,8 +336,9 @@ bool tryDetectModulation(){ uint8_t hits = 0; t55xx_conf_block_t tests[15]; int bitRate=0; + uint8_t fc1 = 0, fc2 = 0, clk=0; + save_restoreGB(1); if (GetFskClock("", FALSE, FALSE)){ - uint8_t fc1 = 0, fc2 = 0, clk=0; fskClocks(&fc1, &fc2, &clk, FALSE); sprintf(cmdStr,"%d", clk/2); CmdLtrim(cmdStr); @@ -366,91 +366,105 @@ bool tryDetectModulation(){ ++hits; } } else { - if ( ASKDemod("0 0 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) { - tests[hits].modulation = DEMOD_ASK; - tests[hits].bitrate = bitRate; - tests[hits].inverted = FALSE; - tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); - ++hits; - } - - if ( ASKDemod("0 1 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) { - tests[hits].modulation = DEMOD_ASK; - tests[hits].bitrate = bitRate; - tests[hits].inverted = TRUE; - tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); - ++hits; - } - - if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) { - tests[hits].modulation = DEMOD_NRZ; - tests[hits].bitrate = bitRate; - tests[hits].inverted = FALSE; - tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); - ++hits; + clk = GetAskClock("", FALSE, FALSE); + if (clk>0) { + sprintf(cmdStr,"%d", clk/2); + CmdLtrim(cmdStr); + if ( ASKDemod("0 0 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) { + tests[hits].modulation = DEMOD_ASK; + tests[hits].bitrate = bitRate; + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + if ( ASKDemod("0 1 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) { + tests[hits].modulation = DEMOD_ASK; + tests[hits].bitrate = bitRate; + tests[hits].inverted = TRUE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + if ( ASKbiphaseDemod("0 0 0 1", FALSE) && test(DEMOD_BI, &tests[hits].offset, &bitRate) ) { + tests[hits].modulation = DEMOD_BI; + tests[hits].bitrate = bitRate; + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BIa, &tests[hits].offset, &bitRate) ) { + tests[hits].modulation = DEMOD_BIa; + tests[hits].bitrate = bitRate; + tests[hits].inverted = TRUE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } } + //undo trim from ask + save_restoreGB(0); + clk = GetNrzClock("", FALSE, FALSE); + if (clk>0) { + sprintf(cmdStr,"%d", clk/2); + CmdLtrim(cmdStr); + if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) { + tests[hits].modulation = DEMOD_NRZ; + tests[hits].bitrate = bitRate; + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } - if ( NRZrawDemod("0 1 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) { - tests[hits].modulation = DEMOD_NRZ; - tests[hits].bitrate = bitRate; - tests[hits].inverted = TRUE; - tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); - ++hits; - } - - if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) { - tests[hits].modulation = DEMOD_PSK1; - tests[hits].bitrate = bitRate; - tests[hits].inverted = FALSE; - tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); - ++hits; + if ( NRZrawDemod("0 1 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) { + tests[hits].modulation = DEMOD_NRZ; + tests[hits].bitrate = bitRate; + tests[hits].inverted = TRUE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } } - if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) { - tests[hits].modulation = DEMOD_PSK1; - tests[hits].bitrate = bitRate; - tests[hits].inverted = TRUE; - tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); - ++hits; - } - - // PSK2 - needs a call to psk1TOpsk2. - if ( PSKDemod("0 0 1", FALSE)) { - psk1TOpsk2(DemodBuffer, DemodBufferLen); - if (test(DEMOD_PSK2, &tests[hits].offset, &bitRate)){ - tests[hits].modulation = DEMOD_PSK2; + //undo trim from nrz + save_restoreGB(0); + clk = GetPskClock("", FALSE, FALSE); + if (clk>0) { + PrintAndLog("clk %d",clk); + sprintf(cmdStr,"%d", clk/2); + CmdLtrim(cmdStr); + if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) { + tests[hits].modulation = DEMOD_PSK1; tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } - } // inverse waves does not affect this demod - - // PSK3 - needs a call to psk1TOpsk2. - if ( PSKDemod("0 0 1", FALSE)) { - psk1TOpsk2(DemodBuffer, DemodBufferLen); - if (test(DEMOD_PSK3, &tests[hits].offset, &bitRate)){ - tests[hits].modulation = DEMOD_PSK3; + if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) { + tests[hits].modulation = DEMOD_PSK1; tests[hits].bitrate = bitRate; - tests[hits].inverted = FALSE; + tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } - } // inverse waves does not affect this demod - - if ( ASKbiphaseDemod("0 0 0 1", FALSE) && test(DEMOD_BI, &tests[hits].offset, &bitRate) ) { - tests[hits].modulation = DEMOD_BI; - tests[hits].bitrate = bitRate; - tests[hits].inverted = FALSE; - tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); - ++hits; - } - if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BIa, &tests[hits].offset, &bitRate) ) { - tests[hits].modulation = DEMOD_BIa; - tests[hits].bitrate = bitRate; - tests[hits].inverted = TRUE; - tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); - ++hits; + // PSK2 - needs a call to psk1TOpsk2. + if ( PSKDemod("0 0 1", FALSE)) { + psk1TOpsk2(DemodBuffer, DemodBufferLen); + if (test(DEMOD_PSK2, &tests[hits].offset, &bitRate)){ + tests[hits].modulation = DEMOD_PSK2; + tests[hits].bitrate = bitRate; + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + } // inverse waves does not affect this demod + // PSK3 - needs a call to psk1TOpsk2. + if ( PSKDemod("0 0 1", FALSE)) { + psk1TOpsk2(DemodBuffer, DemodBufferLen); + if (test(DEMOD_PSK3, &tests[hits].offset, &bitRate)){ + tests[hits].modulation = DEMOD_PSK3; + tests[hits].bitrate = bitRate; + tests[hits].inverted = FALSE; + tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); + ++hits; + } + } // inverse waves does not affect this demod } } if ( hits == 1) { -- 2.39.5 From 411105e03629542fad02902e18248288812a6f87 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 8 Apr 2015 14:19:03 -0400 Subject: [PATCH 12/16] added nexwatch demod & iceman lua added nexwatch demod (also added to lf search) added iceman's lua script adjustments --- client/cmddata.c | 41 ++- client/cmdlf.c | 7 + client/cmdlft55xx.c | 8 +- client/lualibs/commands.lua | 13 +- client/lualibs/default_toys.lua | 514 ++++++++++++++++++++------------ client/scripts/ndef_dump.lua | 2 +- client/scripts/tnp3clone.lua | 43 ++- client/scripts/tnp3dump.lua | 24 +- client/scripts/tnp3sim.lua | 20 +- 9 files changed, 438 insertions(+), 234 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index a8c809cf..556ede06 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1547,11 +1547,49 @@ int CmdIndalaDecode(const char *Cmd) return 1; } +int CmdPSKNexWatch(const char *Cmd) +{ + if (!PSKDemod("", false)) return 0; + uint8_t preamble[28] = {0,0,0,0,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + size_t startIdx = 0, size = DemodBufferLen; + bool invert = false; + if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)){ + // if didn't find preamble try again inverting + if (!PSKDemod("1", false)) return 0; + size = DemodBufferLen; + if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)) return 0; + invert = true; + } + if (size != 128) return 0; + setDemodBuf(DemodBuffer, size, startIdx+4); + startIdx = 8+32; //4 = extra i added, 8 = preamble, 32 = reserved bits (always 0) + //get ID + uint32_t ID = 0; + for (uint8_t wordIdx=0; wordIdx<4; wordIdx++){ + for (uint8_t idx=0; idx<8; idx++){ + ID = (ID << 1) | DemodBuffer[startIdx+wordIdx+(idx*4)]; + } + } + //parity check (TBD) + + //checksum check (TBD) + + //output + PrintAndLog("NexWatch ID: %d", ID); + if (invert){ + PrintAndLog("Had to Invert - probably NexKey"); + for (uint8_t idx=0; idx] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"}, + {"psknexwatchdemod",CmdPSKNexWatch, 1, "Demodulate a NexWatch tag (nexkey, quadrakey) (PSK1) from GraphBuffer"}, {"rawdemod", CmdRawDemod, 1, "[modulation] ... -see help (h option) -- Demodulate the data in the GraphBuffer and output binary"}, {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window (GraphBuffer)"}, {"save", CmdSave, 1, " -- Save trace (from graph window)"}, diff --git a/client/cmdlf.c b/client/cmdlf.c index d441574a..dfbbe992 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1077,6 +1077,13 @@ int CmdLFfind(const char *Cmd) PrintAndLog("\nValid EM4x50 ID Found!"); return 1; } + + ans=CmdPSKNexWatch(""); + if (ans>0) { + PrintAndLog("\nValid NexWatch ID Found!"); + return 1; + } + PrintAndLog("\nNo Known Tags Found!\n"); if (testRaw=='u' || testRaw=='U'){ //test unknown tag formats (raw mode) diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 3134dde7..d4b72b32 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -370,28 +370,28 @@ bool tryDetectModulation(){ if (clk>0) { sprintf(cmdStr,"%d", clk/2); CmdLtrim(cmdStr); - if ( ASKDemod("0 0 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) { + if ( ASKDemod("0 0 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_ASK; tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } - if ( ASKDemod("0 1 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) { + if ( ASKDemod("0 1 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) { tests[hits].modulation = DEMOD_ASK; tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } - if ( ASKbiphaseDemod("0 0 0 1", FALSE) && test(DEMOD_BI, &tests[hits].offset, &bitRate) ) { + if ( ASKbiphaseDemod("0 0 0 0", FALSE) && test(DEMOD_BI, &tests[hits].offset, &bitRate) ) { tests[hits].modulation = DEMOD_BI; tests[hits].bitrate = bitRate; tests[hits].inverted = FALSE; tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer); ++hits; } - if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BIa, &tests[hits].offset, &bitRate) ) { + if ( ASKbiphaseDemod("0 0 1 0", FALSE) && test(DEMOD_BIa, &tests[hits].offset, &bitRate) ) { tests[hits].modulation = DEMOD_BIa; tests[hits].bitrate = bitRate; tests[hits].inverted = TRUE; diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index ad8f6e00..b0257ef0 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -138,6 +138,8 @@ local _commands = { CMD_MIFAREUC_AUTH1 = 0x0724, CMD_MIFAREUC_AUTH2 = 0x0725, CMD_MIFAREUC_READCARD = 0x0726, + CMD_MIFAREUC_SETPWD = 0x0727, + CMD_MIFAREU_SETUID = 0x0728, --// mifare desfire CMD_MIFARE_DESFIRE_READBL = 0x0728, @@ -153,10 +155,10 @@ local _commands = { local _reverse_lookup,k,v = {} -for k, v in pairs(_commands) do - _reverse_lookup[v] = k -end -_commands.tostring = function(command) + for k, v in pairs(_commands) do + _reverse_lookup[v] = k + end + _commands.tostring = function(command) if(type(command) == 'number') then return ("%s (%d)"):format(_reverse_lookup[command]or "ERROR UNDEFINED!", command) end @@ -217,7 +219,6 @@ function Command:getBytes() local data = self.data local cmd = self.cmd local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3 - - return bin.pack("LLLLH",cmd, arg1, arg2, arg3,data); + return bin.pack("LLLLH",cmd, arg1, arg2, arg3, data); end return _commands diff --git a/client/lualibs/default_toys.lua b/client/lualibs/default_toys.lua index 048a29c9..64eed9b3 100644 --- a/client/lualibs/default_toys.lua +++ b/client/lualibs/default_toys.lua @@ -1,196 +1,328 @@ local _names = { - --[[ + --[[ decimal, hexadecimal, ccc, elements, group, name --]] - ["0000"]="WHIRLWIND", - ["0100"]="SONIC BOOM", - ["0200"]="WARNADO", - ["0300"]="LIGHTNINGROD", - ["0400"]="BASH", - ["0500"]="TERRAFIN", - ["0600"]="DINORANG" , - ["0700"]="LIGHTCORE PRISM BREAK", - ["0800"]="SUNBURN", - ["0900"]="LIGHTCORE ERUPTOR", - ["0A00"]="IGNITOR", - ["0B00"]="FLAMESLINGER", - ["0C00"]="ZAP", - ["0D00"]="WHAM SHELL", - ["0E00"]="GILL GRUNT", - ["0F00"]="SLAMBAM", - ["1000"]="SPYRO", - ["1100"]="VOODOOD", - ["1200"]="DOUBLE TROUBLE", - ["1300"]="TRIGGER HAPPY", - ["1400"]="DROBOT", - ["1500"]="DRILLSERGEANT", - ["1600"]="BOOMER", - ["1700"]="WRECKING BALL", - ["1800"]="CAMO", - ["1900"]="ZOOK", - ["1A00"]="STEALTH ELF", - ["1B00"]="STUMP SMASH", - ["1D00"]="HEX", - ["1C00"]="DARK SPYRO", - ["1E00"]="CHOPCHOP", - ["1F00"]="GHOST ROASTER", - ["2000"]="CYNDER", - --[[ - GIANTS - --]] - ["6400"]="GIANT JET-VAC", - ["6500"]="GIANT SWARM", - ["6600"]="GIANT CRUSHER", - ["6700"]="GIANT FLASHWING", - ["6800"]="GIANT HOTHEAD", - ["6900"]="GIANT HOTDOG", - ["6A00"]="GIANT CHILL", - ["6B00"]="GIANT THUMPBACK", - ["6C00"]="GIANT POPFIZZ", - ["6D00"]="GIANT NINJINI", - ["6E00"]="GIANT BOUNCER", - ["6F00"]="GIANT SPROCKET", - ["7000"]="GIANT TREE REX", - ["7100"]="LIGHTCORE SHROOMBOOM", - ["7200"]="GIANT EYEBROAWL", - ["7300"]="GIANT FRIGHTRIDER", - - --[[ - ITEM - --]] - ["C800"]="ANVIL", - ["C900"]="SECRET STASH", - ["CA00"]="REGENERATION", - ["CD00"]="SHIELD", - ["CB00"]="CROSSED SWORDS", - ["CC00"]="HOURGLASS", - ["CE00"]="SPEED BOOTS", - ["CF00"]="SPARX", - ["D000"]="CANNON", - ["D100"]="SCORPIONSTRIKER", - - --[[ - ITEM TRAPS - --]] - ["D200"]="MAGIC TRAP", - ["D300"]="WATER TRAP", - ["D400"]="AIR TRAP", - ["D500"]="UNDEAD TRAP", - ["D600"]="TECH TRAP", - ["D700"]="FIRE TRAP", - ["D800"]="EARTH TRAP", - ["D900"]="LIFE TRAP", - ["DA00"]="DARK TRAP", - ["DB00"]="LIGHT TRAP", - ["DC00"]="KAOS TRAP", - - --[[ - ITEM - --]] - ["E600"]="HAND OF FATE", - ["E700"]="PIGGYBANK", - ["E800"]="ROCKET RAM", - ["E900"]="TIKI SPEAKY", - - - --[[ - EXPANSION - --]] - ["012C"]="DRAGONS PEAK", - ["012D"]="EMPIRE OF ICE", - ["012E"]="PIRATE SEAS", - ["012F"]="DARKLIGHT CRYPT", - ["0130"]="VOLCANIC VAULT", - ["0131"]="MIRROR OF MYSTERY", - ["0132"]="NIGHTMARE EXPRESS", - ["0133"]="SUNSCRAPER SPIRE", - ["0134"]="MIDNIGHT MUSEUM", +{"0", "0000", "0030", "air", "regular", "Whirlwind"}, +--{"0", "0000", "0030", "air", "regular", "Elite Whirlwind"}, +--{"0", "0000", "0030", "air", "regular", "Polar Whirlwind"}, +{"1", "0100", "0030", "air", "regular", "Sonic Boom"}, +{"2", "0200", "0030", "air", "regular", "Warnado"}, +{"3", "0300", "0030", "air", "regular", "Lightning Rod"}, +{"4", "0400", "0030", "earth", "regular", "Bash"}, +--{"4", "0400", "0030", "earth", "regular", "Birthday Bash"}, +{"5", "0500", "0030", "earth", "regular", "Terrafin"}, +--{"5", "0500", "0030", "earth", "regular", "Elite Terrafin"}, +{"6", "0600", "0030", "earth", "regular", "Dino Rang"}, +{"7", "0700", "0030", "earth", "regular", "Prism Break"}, --lightcore +{"8", "0800", "0030", "fire", "regular", "Sunburn"}, +{"9", "0900", "0030", "fire", "regular", "Eruptor"}, --lightcore +--{"9", "0900", "0030", "fire", "regular", "Elite Eruptor"}, +--{"9", "0900", "0030", "fire", "regular", "Volcanic Eruptor"}, +{"10", "0a00", "0030", "fire", "regular", "Ignitor"}, +{"11", "0b00", "0030", "fire", "regular", "Flameslinger"}, +--{"11", "0b00", "0030", "fire", "regular", "Cupid Flameslinger"}, +{"12", "0c00", "0030", "water", "regular", "Zap"}, +{"13", "0d00", "0030", "water", "regular", "Wham Shell"}, +{"14", "0e00", "0030", "water", "regular", "Gill Grunt"}, +--{"14", "0e00", "0030", "water", "regular", "Elite Gill Grunt"}, +{"15", "0f00", "0030", "water", "regular", "Slam Bam"}, +--{"15", "0f00", "0030", "water", "regular", "Surfer Slam Bam"}, +{"16", "1000", "0030", "magic", "regular", "Spyro"}, +{"17", "1100", "0030", "magic", "regular", "Voodood"}, +{"18", "1200", "0030", "magic", "regular", "Double Trouble"}, +--{"18", "1200", "0030", "magic", "regular", "Royal Double Trouble"}, +{"19", "1300", "0030", "tech", "regular", "Trigger Happy"}, +--{"19", "1300", "0030", "tech", "regular", "Elite Trigger Happy"}, +--{"19", "1300", "0030", "tech", "regular", "Springtime Trigger Happy"}, +{"20", "1400", "0030", "tech", "regular", "Drobot"}, +{"21", "1500", "0030", "tech", "regular", "Drill Sergeant"}, +{"22", "1600", "0030", "tech", "regular", "Boomer"}, +--{"22", "1600", "0030", "tech", "regular", "Lucky Boomer"}, +{"23", "1700", "0030", "magic", "regular", "Wrecking Ball"}, +--{"23", "1700", "0030", "magic", "regular", "Buddy Wrecking Ball"}, +{"24", "1800", "0030", "life", "regular", "Camo"}, +{"25", "1900", "0030", "life", "regular", "Zook"}, +{"26", "1a00", "0030", "life", "regular", "Stealth Elf"}, +--{"26", "1a00", "0030", "life", "regular", "Elite Stealth Elf"}, +--{"26", "1a00", "0030", "life", "regular", "Dark Stealth Elf"}, +{"27", "1b00", "0030", "life", "regular", "Stump Smash"}, +--{"27", "1b00", "0030", "life", "regular", "Autumn Stump Smash"}, +{"28", "1c00", "0030", "magic", "regular", "Dark Spyro"}, +--{"28", "1c00", "0030", "magic", "regular", "Elite Spyro"}, +{"29", "1d00", "0030", "undead", "regular", "Hex"}, +--{"29", "1d00", "0030", "undead", "regular", "Hallows' Eve Hex"}, +{"30", "1e00", "0030", "undead", "regular", "Chop Chop"}, +--{"30", "1e00", "0030", "undead", "regular", "Elite Chop Chop"}, +--{"30", "1e00", "0030", "undead", "regular", "Grill Master Chop Chop"}, +{"31", "1f00", "0030", "undead", "regular", "Ghost Roaster"}, +{"32", "2000", "0030", "undead", "regular", "Cynder"}, +--{"32", "2000", "0030", "undead", "regular", "Skeletal Cynder"}, + +{"100", "6400", "0030", "air", "giant", "Jet Vac"}, +{"101", "6500", "0030", "air", "giant", "Swarm"}, +{"102", "6600", "0030", "earth", "giant", "Crusher"}, +{"103", "6700", "0030", "earth", "giant", "Flashwing"}, +--{"103", "6700", "0030", "earth", "giant", "Jade Flashwing"}, +{"104", "6800", "0030", "fire", "giant", "Hot Head"}, +{"105", "6900", "0030", "fire", "giant", "Hot Dog"}, +--{"105", "6900", "0030", "fire", "giant", "Molten Hot Dog"}, +{"106", "6a00", "0030", "water", "giant", "Chill"}, +{"107", "6b00", "0030", "water", "giant", "Thumpback"}, +--{"107", "6b00", "0030", "water", "giant", "Admiral Thumpback"}, +{"108", "6c00", "0030", "magic", "giant", "Pop Fizz"}, +--{"108", "6c00", "0030", "magic", "giant", "Hoppity Pop Fizz"}, +--{"108", "6c00", "0030", "magic", "giant", "Love Potion Pop Fizz"}, +--{"108", "6c00", "0030", "magic", "giant", "Punch Pop Fizz"}, +{"109", "6d00", "0030", "magic", "giant", "Nin Jini"}, +{"110", "6e00", "0030", "tech", "giant", "Bouncer"}, +{"111", "6f00", "0030", "tech", "giant", "Sprocket"}, +{"112", "7000", "0030", "life", "giant", "Tree Rex"}, +--{"112", "7000", "0030", "life", "giant", "Gnarly Tree Rex"}, +{"113", "7100", "0030", "life", "giant", "Shroomboom"}, --lightcore +{"114", "7200", "0030", "undead", "giant", "Eye Broawl"}, +{"115", "7300", "0030", "undead", "giant", "Fright Rider"}, + +{"200", "c800", "0030", "", "item", "Anvil Rain"}, +{"201", "c900", "0030", "", "item", "Platinum Treasure Chest"}, +{"202", "ca00", "0030", "", "item", "Healing Elixer"}, +{"203", "cb00", "0030", "", "item", "Ghost Pirate Swords"}, +{"204", "cc00", "0030", "", "item", "Time Twist Hourglass"}, +{"205", "cd00", "0030", "", "item", "Sky Iron Shield"}, +{"206", "ce00", "0030", "", "item", "Winged Boots"}, +{"207", "cf00", "0030", "", "item", "Sparx"}, +{"208", "d000", "0030", "", "item", "Cannon"}, +{"209", "d100", "0030", "", "item", "Scorpion Striker"}, + +{"210", "d200", "0230", "magic", "trap", "Biter's Bane"}, +{"210", "d200", "0830", "magic", "trap", "Sorcerous Skull"}, +-- legendary Sorcerous Skull? +{"210", "d200", "0b30", "magic", "trap", "Axe Of Illusion"}, +{"210", "d200", "0e30", "magic", "trap", "Arcane Hourglass"}, +{"210", "d200", "1230", "magic", "trap", "Spell Slapper"}, +{"210", "d200", "1430", "magic", "trap", "Rune Rocket"}, + +{"211", "d300", "0130", "water", "trap", "Tidal Tiki"}, +{"211", "d300", "0230", "water", "trap", "Wet Walter"}, +{"211", "d300", "0630", "water", "trap", "Flood Flask"}, +-- legendary flood flask? +{"211", "d300", "0730", "water", "trap", "Soaking Staff"}, +{"211", "d300", "0b30", "water", "trap", "Aqua Axe"}, +{"211", "d300", "1630", "water", "trap", "Frost Helm"}, + +{"212", "d400", "0330", "air", "trap", "Breezy Bird"}, +{"212", "d400", "0630", "air", "trap", "Drafty Decanter"}, +{"212", "d400", "0d30", "air", "trap", "Tempest Timer"}, +{"212", "d400", "1030", "air", "trap", "Cloudy Cobra"}, +{"212", "d400", "1130", "air", "trap", "Storm Warning"}, +{"212", "d400", "1830", "air", "trap", "Cycone Saber"}, + +{"213", "d500", "0430", "undead", "trap", "Spirit Sphere"}, +{"213", "d500", "0830", "undead", "trap", "Spectral Skull"}, +{"213", "d500", "0b30", "undead", "trap", "Haunted Hatchet"}, +{"213", "d500", "0c30", "undead", "trap", "Grim Gripper"}, +{"213", "d500", "1030", "undead", "trap", "Spooky Snake"}, +{"213", "d500", "1730", "undead", "trap", "Dream Piercer"}, + +{"214", "d600", "0030", "tech", "trap", "tech Totem"}, +{"214", "d600", "0730", "tech", "trap", "Automatic Angel"}, +{"214", "d600", "0930", "tech", "trap", "Factory Flower"}, +{"214", "d600", "0c30", "tech", "trap", "Grabbing Gadget"}, +{"214", "d600", "1630", "tech", "trap", "Makers Mana"}, +{"214", "d600", "1a30", "tech", "trap", "Topsy techy"}, + +{"215", "d700", "0530", "fire", "trap", "Eternal Flame"}, +{"215", "d700", "0930", "fire", "trap", "fire Flower"}, +{"215", "d700", "1130", "fire", "trap", "Scorching Stopper"}, +{"215", "d700", "1230", "fire", "trap", "Searing Spinner"}, +{"215", "d700", "1730", "fire", "trap", "Spark Spear"}, +{"215", "d700", "1b30", "fire", "trap", "Blazing Belch"}, + +{"216", "d800", "0030", "earth", "trap", "Banded Boulder"}, +{"216", "d800", "0330", "earth", "trap", "Rock Hawk"}, +{"216", "d800", "0a30", "earth", "trap", "Slag Hammer"}, +{"216", "d800", "0e30", "earth", "trap", "Dust Of Time"}, +{"216", "d800", "1330", "earth", "trap", "Spinning Sandstorm"}, +{"216", "d800", "1a30", "earth", "trap", "Rubble Trouble"}, + +{"217", "d900", "0330", "life", "trap", "Oak Eagle"}, +{"217", "d900", "0530", "life", "trap", "Emerald Energy"}, +{"217", "d900", "0a30", "life", "trap", "Weed Whacker"}, +{"217", "d900", "1030", "life", "trap", "Seed Serpent"}, +{"217", "d900", "1830", "life", "trap", "Jade Blade"}, +{"217", "d900", "1b30", "life", "trap", "Shrub Shrieker"}, + +{"218", "da00", "0030", "dark", "trap", "dark Dagger"}, +{"218", "da00", "1430", "dark", "trap", "Shadow Spider"}, +{"218", "da00", "1a30", "dark", "trap", "Ghastly Grimace"}, + +{"219", "db00", "0030", "light", "trap", "Shining Ship"}, +{"219", "db00", "0f30", "light", "trap", "Heavenly Hawk"}, +{"219", "db00", "1b30", "light", "trap", "Beam Scream"}, + +{"220", "dc00", "3030", "kaos", "trap", "Kaos trap!"}, +--{"220", "dc00", "3130", "kaos", "trap", "Ultimate Kaos trap!"}, ? + + +{"230", "e600", "0030", "none", "item", "Hand Of Fate"}, +{"231", "e700", "0030", "none", "item", "Piggy Bank"}, +{"232", "e800", "0030", "none", "item", "Rocket Ram"}, +{"233", "e900", "0030", "none", "item", "Tiki Speaky"}, + +{"300", "2c01", "0030", "none", "location", "Dragons Peak"}, +{"301", "2d01", "0030", "none", "location", "Empire Of Ice"}, +{"302", "2e01", "0030", "none", "location", "Pirate Seas"}, +{"303", "2f01", "0030", "none", "location", "darklight Crypt"}, +{"304", "3001", "0030", "none", "location", "Volcanic Vault"}, +{"305", "3101", "0030", "none", "location", "Mirror Of Mystery"}, +{"306", "3201", "0030", "none", "location", "Nightmare Express"}, +{"307", "3301", "0030", "none", "location", "Sunscraper Spire"}, +{"308", "3401", "0030", "none", "location", "Midnight Museum"}, + +{"404", "9401", "0030", "earth", "legendary","Bash"}, +{"416", "a001", "0030", "magic", "legendary", "Spyro"}, + --{"", "", "0030", "magic", "legendary", "Deja Vu"}, +{"419", "a301", "0030", "tech", "legendary", "Trigger Happy"}, + --{"", "", "0030", "tech", "legendary", "bouncer"}, + --{"", "", "0030", "tech", "legendary", "jawbreaker"}, +{"430", "ae01", "0030", "undead", "legendary", "Chop Chop"}, + --{"", "", "0030", "undead", "legendary", "grim creeper"}, + --{"", "", "0030", "undead", "legendary", "night shift"}, - --[[ - LEGENDARY - --]] - ["0194"]="LEGENDARY BASH", - ["01A0"]="LEGENDARY SPYRO", - ["01A3"]="LEGENDARY TRIGGER HAPPY", - ["01AE"]="LEGENDARY CHOPCHOP", + --{"", "", "0030", "air", "legendary", "blades"}, + --{"", "", "0030", "air", "legendary", "jet vac"}, + --{"", "", "0030", "air", "legendary", "Free Ranger"}, + --{"", "", "0030", "life", "legendary", "stealth elf"}, + --{"", "", "0030", "life", "legendary", "Bushwhack"}, + --{"", "", "0030", "fire", "legendary", "ignitor"}, + --{"", "", "0030", "water", "legendary", "slam bam"}, + --{"", "", "0030", "water", "legendary", "chill"}, + + --{"", "", "0030", "", "legendary", "zoo lou"}, - --[[ - TRAPTEAM - --]] - ["01C2"]="TRAPTEAM GUSTO", - ["01C3"]="TRAPTEAM THUNDERBOLT", - ["01C4"]="TRAPTEAM FLING KONG", - ["01C5"]="TRAPTEAM BLADES", - ["01C6"]="TRAPTEAM WALLOP", - ["01C7"]="TRAPTEAM HEAD RUSH", - ["01C8"]="TRAPTEAM FIST BUMP", - ["01C9"]="TRAPTEAM ROCKY ROLL", - ["01CA"]="TRAPTEAM WILDFIRE", - ["01CB"]="TRAPTEAM KA BOOM", - ["01CC"]="TRAPTEAM TRAIL BLAZER", - ["01CD"]="TRAPTEAM TORCH", - ["01CE"]="TRAPTEAM SNAP SHOT", - ["01CF"]="TRAPTEAM LOB STAR", - ["01D0"]="TRAPTEAM FLIP WRECK", - ["01D1"]="TRAPTEAM ECHO", - ["01D2"]="TRAPTEAM BLASTERMIND", - ["01D3"]="TRAPTEAM ENIGMA", - ["01D4"]="TRAPTEAM DEJA VU", - ["01D5"]="TRAPTEAM COBRA CADABRA", - ["01D6"]="TRAPTEAM JAWBREAKER", - ["01D7"]="TRAPTEAM GEARSHIFT", - ["01D8"]="TRAPTEAM CHOPPER", - ["01D9"]="TRAPTEAM TREAD HEAD", - ["01DA"]="TRAPTEAM BUSHWHACK", - ["01DB"]="TRAPTEAM TUFF LUCK", - ["01DC"]="TRAPTEAM FOOD FIGHT", - ["01DD"]="TRAPTEAM HIGH FIVE", - ["01DE"]="TRAPTEAM NITRO KRYPT KING", - ["01DF"]="TRAPTEAM SHORT CUT", - ["01E0"]="TRAPTEAM BAT SPIN", - ["01E1"]="TRAPTEAM FUNNY BONE", - ["01E2"]="TRAPTEAM KNIGHT LIGHT", - ["01E3"]="TRAPTEAM SPOTLIGHT", - ["01E4"]="TRAPTEAM KNIGHT MARE", - ["01E5"]="TRAPTEAM BLACKOUT", - - --[[ - PET - --]] - ["01F6"]="PET BOP", - ["01F7"]="PET SPRY", - ["01F8"]="PET HIJINX", - ["01F9"]="PET TERRAFIN", - ["01FA"]="PET BREEZE", - ["01FB"]="PET WEERUPTOR", - ["01FC"]="PET PET VAC", - ["01FD"]="PET SMALL FRY", - ["01FE"]="PET DROBIT", - ["0202"]="PET GILL GRUNT", - ["0207"]="PET TRIGGER SNAPPY", - ["020E"]="PET WHISPER ELF", - ["021C"]="PET BARKLEY", - ["021D"]="PET THUMPLING", - ["021E"]="PET MINI JINI", - ["021F"]="PET EYE SMALL", - - --[[ - SWAP FORCE - --]] - ["0BB8"]="SWAPFORCE SCRATCH", - ["0BB9"]="SWAPFORCE POPTHORN", - ["0BBA"]="SWAPFORCE SLOBBER TOOTH", - ["0BBB"]="SWAPFORCE SCORP", - ["0BBC"]="SWAPFORCE HOG WILD FRYNO", - ["0BBD"]="SWAPFORCE SMOLDER DASH", - ["0BBE"]="SWAPFORCE BUMBLE BLAST", - ["0BBF"]="SWAPFORCE ZOO LOU", - ["0BC0"]="SWAPFORCE DUNE BUG", - ["0BC1"]="SWAPFORCE STAR STRIKE", - ["0BC2"]="SWAPFORCE COUNTDOWN", - ["0BC3"]="SWAPFORCE WIND UP", - ["0BC4"]="SWAPFORCE ROLLER BRAWL", - ["0BC5"]="SWAPFORCE GRIM CREEPER", - ["0BC6"]="SWAPFORCE RIP TIDE", - ["0BC7"]="SWAPFORCE PUNK SHOCK", +{"450", "c201", "0030", "air", "trapmaster", "Gusto"}, +--{"450", "c201", "0234", "air", "trapmaster", "Special Gusto"}, +{"451", "c301", "0030", "air", "trapmaster", "Thunderbolt"}, +--{"451", "c301", "0234", "air", "trapmaster", "Special Thunderbolt"}, +{"452", "c401", "0030", "air", "regular", "Fling Kong"}, +{"453", "c501", "0030", "air", "regular", "Blades"}, +{"454", "c601", "0030", "earth", "trapmaster", "Wallop"}, +--{"454", "c601", "0234", "earth", "trapmaster", "Special Wallop"}, +{"455", "c701", "0030", "earth", "trapmaster", "Head Rush"}, +{"455", "c701", "0234", "earth", "trapmaster", "Nitro Head Rush"}, +{"456", "c801", "0030", "earth", "regular", "Fist Bump"}, +{"457", "c901", "0030", "earth", "regular", "Rocky Roll"}, +--{"457", "c901", "0030", "earth", "regular", "Rocky Egg Roll"}, +{"458", "ca01", "0030", "fire", "trapmaster", "Wildfire"}, +{"458", "ca01", "0234", "fire", "trapmaster", "Dark Wildfire"}, +{"459", "cb01", "0030", "fire", "trapmaster", "Ka Boom"}, +--{"459", "cb01", "0234", "fire", "trapmaster", "Special Ka Boom"}, +{"460", "cc01", "0030", "fire", "regular", "Trail Blazer"}, +{"461", "cd01", "0030", "fire", "regular", "Torch"}, +{"462", "ce01", "0030", "water", "trapmaster", "Snap Shot"}, +{"462", "ce01", "0234", "water", "trapmaster", "Dark Snap Shot"}, +--, "water", "trapmaster", "Instant Snap Shot"}, +--, "water", "trapmaster", "Merry Snap Shot"}, +{"463", "cf01", "0030", "water", "trapmaster", "Lob Star"}, +{"463", "cf01", "0234", "water", "trapmaster", "Winterfest Lob Star"}, +{"464", "d001", "0030", "water", "regular", "Flip Wreck"}, +{"465", "d101", "0030", "water", "regular", "Echo"}, +{"466", "d201", "0030", "magic", "trapmaster", "Blastermind"}, +--{"466", "d201", "0234", "magic", "trapmaster", "Special Blastermind"}, +{"467", "d301", "0030", "magic", "trapmaster", "Enigma"}, +--{"467", "d301", "0234", "magic", "trapmaster", "Special Enigma"}, +{"468", "d401", "0030", "magic", "regular", "Deja Vu"}, +{"469", "d501", "0030", "magic", "regular", "Cobra Cadabra"}, +--{"469", "d501", "0030", "magic", "regular", "Charming Cobra Cadabra"}, +--{"469", "d501", "0030", "magic", "regular", "King Cobra Cadabra"}, +{"470", "d601", "0030", "tech", "trapmaster", "Jawbreaker"}, +--{"470", "d601", "0234", "tech", "trapmaster", "Special Jawbreaker"}, +--{"470", "d601", "0234", "tech", "trapmaster", "Knockout Jawbreaker"}, +{"471", "d701", "0030", "tech", "trapmaster", "Gearshift"}, +--{"471", "d701", "0234", "tech", "trapmaster", "Special Gearshift"}, +{"472", "d801", "0030", "tech", "regular", "Chopper"}, +{"473", "d901", "0030", "tech", "regular", "Tread Head"}, +{"474", "da01", "0030", "life", "trapmaster", "Bushwhack"}, +--{"474", "da01", "0234", "life", "trapmaster", "Special Bushwhack"}, +{"475", "db01", "0030", "life", "trapmaster", "Tuff Luck"}, +--{"475", "db01", "0234", "life", "trapmaster", "Special Tuff Luck"}, +{"476", "dc01", "0030", "life", "regular", "Food Fight"}, +--{"476", "dc01", "0030", "life", "regular", "Dark Food Fight"}, +--{"476", "dc01", "0030", "life", "regular", "Frosted Food Fight"}, +--{"476", "dc01", "0030", "life", "regular", "Instant Food Fight"}, +{"477", "dd01", "0030", "life", "regular", "High Five"}, +{"478", "de01", "0030", "undead", "trapmaster", "Krypt King"}, +{"478", "de01", "0234", "undead", "trapmaster", "Nitro Krypt King"}, +{"479", "df01", "0030", "undead", "trapmaster", "Short Cut"}, +--{"479", "df01", "0234", "undead", "trapmaster", "Special Short Cut"}, +{"480", "e001", "0030", "undead", "regular", "Bat Spin"}, +{"481", "e101", "0030", "undead", "regular", "Funny Bone"}, +--{"481", "e101", "0030", "undead", "regular", "Fortune Funny Bone"}, +{"482", "e201", "0030", "light", "trapmaster", "Knight light"}, +--{"482", "e201", "0234", "light", "trapmaster", "Special Knight light"}, +{"483", "e301", "0030", "light", "regular", "Spotlight"}, +--{"483", "e301", "0234", "light", "regular", "Special Spotlight"}, +{"484", "e401", "0030", "dark", "trapmaster", "Knight Mare"}, +--{"484", "e401", "0234", "dark", "trapmaster", "Special Knight Mare"}, +{"485", "e501", "0030", "dark", "regular", "Blackout"}, +--{"485", "e501", "0234", "dark", "regular", "Special Blackout"}, + +{"502", "f601", "0030", "earth", "mini", "Bop"}, +{"503", "f701", "0030", "magic", "mini", "Spry"}, +{"504", "f801", "0030", "undead", "mini", "Hijinx"}, +{"505", "f901", "0030", "earth", "mini", "Terrabite"}, +{"506", "fa01", "0030", "air", "mini", "Breeze"}, +{"507", "fb01", "0030", "fire", "mini", "Weeruptor"}, +--{"507", "fb01", "0030", "fire", "mini", "Eggsellent Weeruptor"}, +{"508", "fc01", "0030", "air", "mini", "Pet Vac"}, +--{"508", "fc01", "0030", "air", "mini", "Power Punch Pet Vac"}, +{"509", "fd01", "0030", "fire", "mini", "Small Fry"}, +{"510", "fe01", "0030", "tech", "mini", "Drobit"}, +{"514", "0202", "0030", "water", "mini", "Gill Runt"}, +{"519", "0702", "0030", "tech", "mini", "Trigger Snappy"}, +{"526", "0e02", "0030", "life", "mini", "Whisper Elf"}, +{"540", "1c02", "0030", "life", "mini", "Barkley"}, +--{"540", "1c02", "0030", "life", "mini", "Gnarly Barkley"}, +{"541", "1d02", "0030", "water", "mini", "Thumpling"}, +{"542", "1e02", "0030", "magic", "mini", "mini Jini"}, +{"543", "1f02", "0030", "undead", "mini", "Eye Small"}, + +{"3000", "b80b", "0030", "air", "SWAPFORCE", "Scratch"}, +{"3001", "b90b", "0030", "air", "SWAPFORCE", "Pop Thorn"}, +--{"3001", "b90b", "0030", "air", "SWAPFORCE", "Buttered Pop Thorn"}, +{"3002", "ba0b", "0030", "earth", "SWAPFORCE", "Slobber Tooth"}, +--{"3002", "ba0b", "0030", "earth", "SWAPFORCE", "Dark Slobber Tooth"}, +--{"3002", "ba0b", "0030", "earth", "SWAPFORCE", "Sundae Slobber Tooth"}, +{"3003", "bb0b", "0030", "earth", "SWAPFORCE", "Scorp"}, +{"3004", "bc0b", "0138", "fire", "SWAPFORCE", "Hog Wild Fryno"}, +--{"3004", "bc0b", "0138", "fire", "SWAPFORCE", "Flip flop Fryno"}, +{"3005", "bd0b", "0030", "fire", "SWAPFORCE", "Smolderdash"}, +{"3006", "be0b", "0030", "life", "SWAPFORCE", "Bumble Blast"}, +--{"3006", "be0b", "0030", "life", "SWAPFORCE", "Jolly Bumble Blast"}, +{"3007", "bf0b", "0030", "life", "SWAPFORCE", "Zoo Lou"}, +{"3008", "c00b", "0030", "magic", "SWAPFORCE", "Dune Bug"}, +{"3009", "c10b", "0030", "magic", "SWAPFORCE", "Star Strike"}, +--{"3009", "c10b", "0030", "magic", "SWAPFORCE", "Enchanted Star Strike"}, +--{"3009", "c10b", "0030", "magic", "SWAPFORCE", "Mystic Star Strike"}, +{"3010", "c20b", "0030", "tech", "SWAPFORCE", "Countdown"}, +--{"3010", "c20b", "0030", "tech", "SWAPFORCE", "Kickoff Countdown"}, +--{"3010", "c20b", "0030", "tech", "SWAPFORCE", "New Year's Countdown"}, +{"3011", "c30b", "0030", "tech", "SWAPFORCE", "Wind Up"}, +{"3012", "c40b", "0030", "undead", "SWAPFORCE", "Roller Brawl"}, +--{"3012", "c40b", "0030", "undead", "SWAPFORCE", "Snowler Roller Brawl"}, +{"3013", "c50b", "0030", "undead", "SWAPFORCE", "Grim Creeper"}, +{"3014", "c60b", "0030", "water", "SWAPFORCE", "Rip Tide"}, +{"3015", "c70b", "0030", "water", "SWAPFORCE", "Punk Shock"}, +} + +local function find( main, sub) + + for k, v in pairs(_names) do + if ( v[2] == main and v[3] == sub) then + return v + end + end + return nil +end + +return { + Find = find, } -return _names diff --git a/client/scripts/ndef_dump.lua b/client/scripts/ndef_dump.lua index da1a1ef2..3b27cac3 100644 --- a/client/scripts/ndef_dump.lua +++ b/client/scripts/ndef_dump.lua @@ -205,7 +205,7 @@ local function main( args) -- NDEF compliant? if b3chars[1] ~= 0xE1 then - return oops("This tag is not NDEF-Complian") + return oops("This tag is not NDEF-Compliant") end local ndefVersion = b3chars[2] diff --git a/client/scripts/tnp3clone.lua b/client/scripts/tnp3clone.lua index 8c9397a7..cad1ab70 100644 --- a/client/scripts/tnp3clone.lua +++ b/client/scripts/tnp3clone.lua @@ -3,6 +3,7 @@ local getopt = require('getopt') local lib14a = require('read14a') local utils = require('utils') local pre = require('precalc') +local toys = require('default_toys') local lsh = bit32.lshift local rsh = bit32.rshift @@ -10,19 +11,20 @@ local bor = bit32.bor local band = bit32.band example =[[ - script run tnp3dump - script run tnp3dump -h - script run tnp3dump -t aa00 + script run tnp3clone + script run tnp3clone -h + script run tnp3clone -t aa00 -s 0030 ]] author = "Iceman" -usage = "script run tnp3clone -t " +usage = "script run tnp3clone -t -s " desc =[[ This script will try making a barebone clone of a tnp3 tag on to a magic generation1 card. Arguments: -h : this help - -k : toytype id, 4 hex symbols. + -t : toytype id, 4hex symbols. + -s : subtype id, 4hex symbols ]] @@ -73,29 +75,45 @@ end local function main(args) + print( string.rep('--',20) ) + print( string.rep('--',20) ) + local numBlocks = 64 local cset = 'hf mf csetbl ' + local csetuid = 'hf mf csetuid ' local cget = 'hf mf cgetbl ' local empty = '00000000000000000000000000000000' local AccAndKeyB = '7F078869000000000000' -- Defaults to Gusto local toytype = 'C201' + local subtype = '0030' + local DEBUG = true -- Arguments for the script - for o, a in getopt.getopt(args, 'ht:') do + for o, a in getopt.getopt(args, 'ht:s:') do if o == "h" then return help() end if o == "t" then toytype = a end + if o == "s" then subtype = a end end - if #toytype ~= 4 then return oops('Wrong size in toytype. (4hex symbols)') end + if #toytype ~= 4 then return oops('Wrong size - toytype. (4hex symbols)') end + if #subtype ~= 4 then return oops('Wrong size - subtype. (4hex symbols)') end + + -- look up type, find & validate types + local item = toys.Find( toytype, subtype) + if item then + print( (' Looking up input: Found %s - %s (%s)'):format(item[6],item[5], item[4]) ) + else + print('Didn\'t find item type. If you are sure about it, report it in') + end + --15,16 + --13-14 + -- find tag result, err = lib14a.read1443a(false) if not result then return oops(err) end - -- Show tag info - print((' Found tag %s'):format(result.name)) - -- load keys local akeys = pre.GetAll(result.uid) local keyA = akeys:sub(1, 12 ) @@ -111,11 +129,10 @@ local function main(args) end -- wipe card. - local cmd = (cset..' %s 0004 08 w'):format( b0) + local cmd = (csetuid..'%s 0004 08 w'):format(result.uid) core.console(cmd) - - local b1 = toytype..'000000000000000000000000' + local b1 = toytype..'00000000000000000000'..subtype local calc = utils.Crc16(b0..b1) local calcEndian = bor(rsh(calc,8), lsh(band(calc, 0xff), 8)) diff --git a/client/scripts/tnp3dump.lua b/client/scripts/tnp3dump.lua index 363998fb..f93f9728 100644 --- a/client/scripts/tnp3dump.lua +++ b/client/scripts/tnp3dump.lua @@ -5,8 +5,7 @@ local lib14a = require('read14a') local utils = require('utils') local md5 = require('md5') local dumplib = require('html_dumplib') -local toyNames = require('default_toys') - +local toys = require('default_toys') example =[[ script run tnp3dump @@ -129,7 +128,7 @@ local function main(args) if o == "p" then usePreCalc = true end if o == "o" then outputTemplate = a end end - + -- validate input args. keyA = keyA or '4b0b20107ccb' if #(keyA) ~= 12 then @@ -261,13 +260,16 @@ local function main(args) bindata[#bindata+1] = c end end + + print( string.rep('--',20) ) + local uid = block0:sub(1,8) - local itemtype = block1:sub(1,4) + local toytype = block1:sub(1,4) local cardidLsw = block1:sub(9,16) local cardidMsw = block1:sub(16,24) local cardid = block1:sub(9,24) - local traptype = block1:sub(25,28) + local subtype = block1:sub(25,28) -- Write dump to files if not DEBUG then @@ -277,13 +279,15 @@ local function main(args) print(("Wrote a EML dump to: %s"):format(bar)) end - local itemtypename = toyNames[itemtype] - if itemtypename == nil then - itemtypename = toyNames[utils.SwapEndiannessStr(itemtype,16)] + local item = toys.Find(toytype, subtype) + if item then + local itemStr = ('%s - %s (%s)'):format(item[6],item[5], item[4]) + print(' ITEM TYPE : '..itemStr ) + else + print((' ITEM TYPE : 0x%s 0x%s'):format(toytype, subtype)) end + -- Show info - print( string.rep('--',20) ) - print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, itemtypename) ) print( (' Alter ego / traptype : 0x%s'):format(traptype) ) print( (' UID : 0x%s'):format(uid) ) print( (' CARDID : 0x%s'):format(cardid ) ) diff --git a/client/scripts/tnp3sim.lua b/client/scripts/tnp3sim.lua index 1d3dbefd..af3d2d4c 100644 --- a/client/scripts/tnp3sim.lua +++ b/client/scripts/tnp3sim.lua @@ -4,7 +4,7 @@ local bin = require('bin') local lib14a = require('read14a') local utils = require('utils') local md5 = require('md5') -local toyNames = require('default_toys') +local toys = require('default_toys') example =[[ 1. script run tnp3sim @@ -382,18 +382,22 @@ local function main(args) print( string.rep('--',20) ) print(' Gathering info') local uid = blocks[0]:sub(1,8) - local itemtype = blocks[1]:sub(1,4) + local toytype = blocks[1]:sub(1,4) local cardidLsw = blocks[1]:sub(9,16) local cardidMsw = blocks[1]:sub(17,24) + local subtype = blocks[1]:sub(25,28) - local itemtypename = toyNames[itemtype] - if itemtypename == nil then - itemtypename = toyNames[utils.SwapEndiannessStr(itemtype,16)] - end - -- Show info print( string.rep('--',20) ) - print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, itemtypename) ) + + local item = toys.Find( toytype, subtype) + if item then + local itemStr = ('%s - %s (%s)'):format(item[6],item[5], item[4]) + print(' ITEM TYPE :'..itemStr ) + else + print( (' ITEM TYPE : 0x%s 0x%s'):format(toytype, subtype) ) + end + print( (' UID : 0x%s'):format(uid) ) print( (' CARDID : 0x%s %s [%s]'):format( cardidMsw,cardidLsw, -- 2.39.5 From 664f658650f466eaae758bf01088bbeaeace422f Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Wed, 8 Apr 2015 15:08:05 -0400 Subject: [PATCH 13/16] nexwatch fix .h file + icemans mf csetblk w arg forgot to include the new nexwatch command in the header... added icemans hf mf csetblk w parameter fix --- client/cmddata.h | 1 + client/cmdhfmf.c | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/client/cmddata.h b/client/cmddata.h index 9e179b9c..57f04001 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -35,6 +35,7 @@ int CmdFSKdemodPyramid(const char *Cmd); int CmdFSKrawdemod(const char *Cmd); int CmdPSK1rawDemod(const char *Cmd); int CmdPSK2rawDemod(const char *Cmd); +int CmdPSKNexWatch(const char *Cmd); int CmdGrid(const char *Cmd); int CmdGetBitStream(const char *Cmd); int CmdHexsamples(const char *Cmd); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 5f2e8dec..b96c9c1a 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1499,16 +1499,16 @@ int CmdHF14AMfCSetUID(const char *Cmd) int CmdHF14AMfCSetBlk(const char *Cmd) { - uint8_t uid[8] = {0x00}; uint8_t memBlock[16] = {0x00}; uint8_t blockNo = 0; + bool wipeCard = FALSE; int res; if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { - PrintAndLog("Usage: hf mf csetblk "); + PrintAndLog("Usage: hf mf csetblk [w]"); PrintAndLog("sample: hf mf csetblk 1 01020304050607080910111213141516"); - PrintAndLog("Set block data for magic Chinese card (only works with!!!)"); - PrintAndLog("If you want wipe card then add 'w' into command line. \n"); + PrintAndLog("Set block data for magic Chinese card (only works with such cards)"); + PrintAndLog("If you also want wipe the card then add 'w' at the end of the command line"); return 0; } @@ -1519,14 +1519,15 @@ int CmdHF14AMfCSetBlk(const char *Cmd) return 1; } + char ctmp = param_getchar(Cmd, 2); + wipeCard = (ctmp == 'w' || ctmp == 'W'); PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16)); - res = mfCSetBlock(blockNo, memBlock, uid, 0, CSETBLOCK_SINGLE_OPER); + res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER); if (res) { - PrintAndLog("Can't write block. error=%d", res); - return 1; - } - + PrintAndLog("Can't write block. error=%d", res); + return 1; + } return 0; } @@ -1637,7 +1638,7 @@ int CmdHF14AMfCGetBlk(const char *Cmd) { if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { PrintAndLog("Usage: hf mf cgetblk "); PrintAndLog("sample: hf mf cgetblk 1"); - PrintAndLog("Get block data from magic Chinese card (only works with!!!)\n"); + PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n"); return 0; } @@ -1664,7 +1665,7 @@ int CmdHF14AMfCGetSc(const char *Cmd) { if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') { PrintAndLog("Usage: hf mf cgetsc "); PrintAndLog("sample: hf mf cgetsc 0"); - PrintAndLog("Get sector data from magic Chinese card (only works with!!!)\n"); + PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n"); return 0; } -- 2.39.5 From 8e0cf02308a732bf5ddf5bd9263e2895905a9d59 Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Fri, 10 Apr 2015 00:06:59 -0400 Subject: [PATCH 14/16] minor change to lf em4x menu & iceman script... ...updates --- client/cmdlfem4x.c | 4 +-- client/lualibs/default_toys.lua | 17 ++++++---- client/scripts/tnp3clone.lua | 8 +++++ client/scripts/tnp3dump.lua | 55 ++++++++++----------------------- 4 files changed, 38 insertions(+), 46 deletions(-) diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 614624a6..c492a64d 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -604,11 +604,11 @@ static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"em410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"}, - {"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"}, + {"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag in GraphBuffer"}, {"em410xsim", CmdEM410xSim, 0, " -- Simulate EM410x tag"}, {"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"}, {"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" }, - {"em410xwrite", CmdEM410xWrite, 1, " <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"}, + {"em410xwrite", CmdEM410xWrite, 0, " <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"}, {"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"}, {"readword", CmdReadWord, 1, " -- Read EM4xxx word data"}, {"readwordPWD", CmdReadWordPWD, 1, " -- Read EM4xxx word data in password mode"}, diff --git a/client/lualibs/default_toys.lua b/client/lualibs/default_toys.lua index 64eed9b3..f34d510d 100644 --- a/client/lualibs/default_toys.lua +++ b/client/lualibs/default_toys.lua @@ -45,6 +45,7 @@ local _names = { --{"26", "1a00", "0030", "life", "regular", "Elite Stealth Elf"}, --{"26", "1a00", "0030", "life", "regular", "Dark Stealth Elf"}, {"27", "1b00", "0030", "life", "regular", "Stump Smash"}, +{"27", "1b00", "0118", "life", "regular", "Stump Smash"}, --{"27", "1b00", "0030", "life", "regular", "Autumn Stump Smash"}, {"28", "1c00", "0030", "magic", "regular", "Dark Spyro"}, --{"28", "1c00", "0030", "magic", "regular", "Elite Spyro"}, @@ -70,7 +71,7 @@ local _names = { --{"107", "6b00", "0030", "water", "giant", "Admiral Thumpback"}, {"108", "6c00", "0030", "magic", "giant", "Pop Fizz"}, --{"108", "6c00", "0030", "magic", "giant", "Hoppity Pop Fizz"}, ---{"108", "6c00", "0030", "magic", "giant", "Love Potion Pop Fizz"}, +{"108", "6c00", "023c", "magic", "giant", "Love Potion Pop Fizz"}, --{"108", "6c00", "0030", "magic", "giant", "Punch Pop Fizz"}, {"109", "6d00", "0030", "magic", "giant", "Nin Jini"}, {"110", "6e00", "0030", "tech", "giant", "Bouncer"}, @@ -174,8 +175,8 @@ local _names = { {"304", "3001", "0030", "none", "location", "Volcanic Vault"}, {"305", "3101", "0030", "none", "location", "Mirror Of Mystery"}, {"306", "3201", "0030", "none", "location", "Nightmare Express"}, -{"307", "3301", "0030", "none", "location", "Sunscraper Spire"}, -{"308", "3401", "0030", "none", "location", "Midnight Museum"}, +{"307", "3301", "0030", "light", "location", "Sunscraper Spire"}, +{"308", "3401", "0030", "dark", "location", "Midnight Museum"}, {"404", "9401", "0030", "earth", "legendary","Bash"}, {"416", "a001", "0030", "magic", "legendary", "Spyro"}, @@ -219,7 +220,7 @@ local _names = { {"461", "cd01", "0030", "fire", "regular", "Torch"}, {"462", "ce01", "0030", "water", "trapmaster", "Snap Shot"}, {"462", "ce01", "0234", "water", "trapmaster", "Dark Snap Shot"}, ---, "water", "trapmaster", "Instant Snap Shot"}, +{"462", "6c00", "023c", "water", "trapmaster", "Instant Snap Shot"}, --, "water", "trapmaster", "Merry Snap Shot"}, {"463", "cf01", "0030", "water", "trapmaster", "Lob Star"}, {"463", "cf01", "0234", "water", "trapmaster", "Winterfest Lob Star"}, @@ -245,6 +246,7 @@ local _names = { {"475", "db01", "0030", "life", "trapmaster", "Tuff Luck"}, --{"475", "db01", "0234", "life", "trapmaster", "Special Tuff Luck"}, {"476", "dc01", "0030", "life", "regular", "Food Fight"}, +{"476", "dc01", "0612", "life", "regular", "LightCore Food Fight"}, --{"476", "dc01", "0030", "life", "regular", "Dark Food Fight"}, --{"476", "dc01", "0030", "life", "regular", "Frosted Food Fight"}, --{"476", "dc01", "0030", "life", "regular", "Instant Food Fight"}, @@ -255,6 +257,7 @@ local _names = { --{"479", "df01", "0234", "undead", "trapmaster", "Special Short Cut"}, {"480", "e001", "0030", "undead", "regular", "Bat Spin"}, {"481", "e101", "0030", "undead", "regular", "Funny Bone"}, +{"481", "e101", "0612", "undead", "regular", "LightCore Funny Bone"}, --{"481", "e101", "0030", "undead", "regular", "Fortune Funny Bone"}, {"482", "e201", "0030", "light", "trapmaster", "Knight light"}, --{"482", "e201", "0234", "light", "trapmaster", "Special Knight light"}, @@ -292,6 +295,7 @@ local _names = { --{"3002", "ba0b", "0030", "earth", "SWAPFORCE", "Dark Slobber Tooth"}, --{"3002", "ba0b", "0030", "earth", "SWAPFORCE", "Sundae Slobber Tooth"}, {"3003", "bb0b", "0030", "earth", "SWAPFORCE", "Scorp"}, +{"3004", "bc0b", "0030", "fire", "SWAPFORCE", "Fryno"}, {"3004", "bc0b", "0138", "fire", "SWAPFORCE", "Hog Wild Fryno"}, --{"3004", "bc0b", "0138", "fire", "SWAPFORCE", "Flip flop Fryno"}, {"3005", "bd0b", "0030", "fire", "SWAPFORCE", "Smolderdash"}, @@ -314,9 +318,10 @@ local _names = { } local function find( main, sub) - + main = main:lower() + sub = sub:lower() for k, v in pairs(_names) do - if ( v[2] == main and v[3] == sub) then + if ( v[2]:lower() == main and v[3]:lower() == sub) then return v end end diff --git a/client/scripts/tnp3clone.lua b/client/scripts/tnp3clone.lua index cad1ab70..6c4a148c 100644 --- a/client/scripts/tnp3clone.lua +++ b/client/scripts/tnp3clone.lua @@ -25,6 +25,14 @@ Arguments: -h : this help -t : toytype id, 4hex symbols. -s : subtype id, 4hex symbols + + For fun, try the following subtype id: + 0612 - Lightcore + 0118 - Series 1 + 0138 - Series 2 + 0234 - Special + 023c - Special + ]] diff --git a/client/scripts/tnp3dump.lua b/client/scripts/tnp3dump.lua index f93f9728..cd547e8a 100644 --- a/client/scripts/tnp3dump.lua +++ b/client/scripts/tnp3dump.lua @@ -30,9 +30,7 @@ Arguments: -p : Use the precalc to find all keys -o : filename for the saved dumps ]] - -local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20' - +local RANDOM = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20' local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds local DEBUG = false -- the debug flag local numBlocks = 64 @@ -96,16 +94,6 @@ local function waitCmd() return nil, "No response from device" end -local function computeCrc16(s) - local hash = core.crc16(utils.ConvertHexToAscii(s)) - return hash -end - -local function reverseCrcBytes(crc) - crc2 = crc:sub(3,4)..crc:sub(1,2) - return tonumber(crc2,16) -end - local function main(args) print( string.rep('--',20) ) @@ -146,10 +134,6 @@ local function main(args) core.clearCommandBuffer() - if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx - -- return oops('This is not a TNP3xxx tag. aborting.') - end - -- Show tag info print((' Found tag %s'):format(result.name)) @@ -189,6 +173,8 @@ local function main(args) local block1, err = waitCmd() if err then return oops(err) end + local tmpHash = block0..block1..'%02x'..RANDOM + local key local pos = 0 local blockNo @@ -221,20 +207,16 @@ local function main(args) -- Block 0-7 not encrypted blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata) else - local base = ('%s%s%02x%s'):format(block0, block1, blockNo, HASHCONSTANT) - local baseStr = utils.ConvertHexToAscii(base) - local md5hash = md5.sumhexa(baseStr) - local aestest = core.aes(md5hash, blockdata) - - local hex = utils.ConvertAsciiToBytes(aestest) - hex = utils.ConvertBytesToHex(hex) - -- blocks with zero not encrypted. if string.find(blockdata, '^0+$') then blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata) else - blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,hex) - io.write( blockNo..',') + local baseStr = utils.ConvertHexToAscii(tmpHash:format(blockNo)) + local key = md5.sumhexa(baseStr) + local aestest = core.aes128_decrypt(key, blockdata) + local hex = utils.ConvertAsciiToBytes(aestest) + hex = utils.ConvertBytesToHex(hex) + blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,hex) end end else @@ -258,11 +240,10 @@ local function main(args) emldata = emldata..slice..'\n' for c in (str):gmatch('.') do bindata[#bindata+1] = c - end + end end print( string.rep('--',20) ) - local uid = block0:sub(1,8) local toytype = block1:sub(1,4) @@ -273,26 +254,24 @@ local function main(args) -- Write dump to files if not DEBUG then - local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'_uid_'..uid..'.bin') + local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'-'..uid..'.bin') print(("Wrote a BIN dump to: %s"):format(foo)) - local bar = dumplib.SaveAsText(emldata, outputTemplate..'_uid_'..uid..'.eml') + local bar = dumplib.SaveAsText(emldata, outputTemplate..'-'..uid..'.eml') print(("Wrote a EML dump to: %s"):format(bar)) end + + print( string.rep('--',20) ) + -- Show info local item = toys.Find(toytype, subtype) if item then - local itemStr = ('%s - %s (%s)'):format(item[6],item[5], item[4]) - print(' ITEM TYPE : '..itemStr ) + print((' ITEM TYPE : %s - %s (%s)'):format(item[6],item[5], item[4]) ) else print((' ITEM TYPE : 0x%s 0x%s'):format(toytype, subtype)) end - - -- Show info - print( (' Alter ego / traptype : 0x%s'):format(traptype) ) + print( (' UID : 0x%s'):format(uid) ) print( (' CARDID : 0x%s'):format(cardid ) ) - print( string.rep('--',20) ) - end main(args) \ No newline at end of file -- 2.39.5 From 0e6c7336b09102432a728796cf4903efc6d3ec5b Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 23 Apr 2015 09:50:44 +0200 Subject: [PATCH 15/16] Fixed issue with dumping iclass tags > 2KB in size --- client/cmdhficlass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 44b074b3..b8337196 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -345,7 +345,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) if(dataLength > 0) { PrintAndLog("Got %d bytes data (total so far %d)" ,dataLength,iclass_datalen); - memcpy(iclass_data, resp.d.asBytes,dataLength); + memcpy(iclass_data+iclass_datalen, resp.d.asBytes,dataLength); iclass_datalen += dataLength; }else {//Last transfer, datalength 0 means the dump is finished -- 2.39.5 From 4745afb647c96a80f3f088f2afebf9686499680d Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Tue, 28 Apr 2015 15:35:23 -0400 Subject: [PATCH 16/16] Iceman's Issue #96 fix --- client/cmdhf14a.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index d36ebb8b..200c9dcd 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -152,18 +152,43 @@ int CmdHF14AReader(const char *Cmd) return 0; } - PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + if(select_status == 3) { + PrintAndLog("Card doesn't support standard iso14443-3 anticollision"); + PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + // disconnect + c.arg[0] = 0; + c.arg[1] = 0; + c.arg[2] = 0; + SendCommand(&c); + return 0; + } + PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen)); + PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]); PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]); - // Double & triple sized UID, can be mapped to a manufacturer. - // HACK: does this apply for Ultralight cards? - if ( card.uidlen > 4 ) { - PrintAndLog("MANUFACTURER : %s", getTagInfo(card.uid[0])); - } - switch (card.sak) { - case 0x00: PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); break; + case 0x00: + // check if the tag answers to GETVERSION (0x60) + c.arg[0] = ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_DISCONNECT; + c.arg[1] = 1; + c.arg[2] = 0; + c.d.asBytes[0] = 0x60; + SendCommand(&c); + WaitForResponse(CMD_ACK,&resp); + + uint8_t version[8] = {0,0,0,0,0,0,0,0}; + memcpy(&version, resp.d.asBytes, resp.arg[0]); + uint8_t len = resp.arg[0] & 0xff; + switch ( len ){ + // todo, identify "Magic UL-C tags". // they usually have a static nonce response to 0x1A command. + // UL-EV1, size, check version[6] == 0x0b (smaller) 0x0b * 4 == 48 + case 0x0A:PrintAndLog("TYPE : NXP MIFARE Ultralight EV1 %d bytes", (version[6] == 0xB) ? 48 : 128);break; + case 0x01:PrintAndLog("TYPE : NXP MIFARE Ultralight C");break; + case 0x00:PrintAndLog("TYPE : NXP MIFARE Ultralight");break; + } + + break; case 0x01: PrintAndLog("TYPE : NXP TNP3xxx Activision Game Appliance"); break; case 0x04: PrintAndLog("TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); break; case 0x08: PrintAndLog("TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1"); break; @@ -180,6 +205,12 @@ int CmdHF14AReader(const char *Cmd) default: ; } + // Double & triple sized UID, can be mapped to a manufacturer. + // HACK: does this apply for Ultralight cards? + if ( card.uidlen > 4 ) { + PrintAndLog("MANUFACTURER : %s", getTagInfo(card.uid[0])); + } + // try to request ATS even if tag claims not to support it if (select_status == 2) { uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0 -- 2.39.5