From 72e930ef3206224ae0ff0696a8a146a0b26268f7 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 23 Oct 2014 18:36:44 +0200 Subject: [PATCH 1/1] FIXED: lf t55xx fsk now demods but only to binary. ADD: holimans lf io / hid fskdemod changes. --- armsrc/appmain.c | 38 +++- armsrc/apps.h | 5 +- armsrc/lfops.c | 496 ++++++++++++++++---------------------------- client/cmdhf15.c | 2 +- client/cmdhw.c | 2 +- client/cmdlft55xx.c | 24 +-- client/cmdlft55xx.h | 1 + client/cmdmain.c | 34 ++- client/proxmark3.c | 5 + client/ui.c | 20 +- 10 files changed, 272 insertions(+), 355 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index afed56b7..b9ad1abd 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -24,6 +24,7 @@ #include "legicrf.h" #include "../include/hitag2.h" + #ifdef WITH_LCD #include "LCD.h" #endif @@ -359,6 +360,7 @@ void SamyRun() int selected = 0; int playing = 0; + int cardRead = 0; // Turn on selected LED LED(selected + 1, 0); @@ -374,7 +376,7 @@ void SamyRun() SpinDelay(300); // Button was held for a second, begin recording - if (button_pressed > 0) + if (button_pressed > 0 && cardRead == 0) { LEDsoff(); LED(selected + 1, 0); @@ -400,6 +402,40 @@ void SamyRun() // If we were previously playing, set playing off // so next button push begins playing what we recorded playing = 0; + + cardRead = 1; + + } + + else if (button_pressed > 0 && cardRead == 1) + { + LEDsoff(); + LED(selected + 1, 0); + LED(LED_ORANGE, 0); + + // record + Dbprintf("Cloning %x %x %x", selected, high[selected], low[selected]); + + // wait for button to be released + while(BUTTON_PRESS()) + WDT_HIT(); + + /* need this delay to prevent catching some weird data */ + SpinDelay(500); + + CopyHIDtoT55x7(high[selected], low[selected], 0, 0); + Dbprintf("Cloned %x %x %x", selected, high[selected], low[selected]); + + LEDsoff(); + LED(selected + 1, 0); + // Finished recording + + // If we were previously playing, set playing off + // so next button push begins playing what we recorded + playing = 0; + + cardRead = 0; + } // Change where to record (or begin playing) diff --git a/armsrc/apps.h b/armsrc/apps.h index 6f96875b..a4dd3d08 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -72,7 +72,10 @@ void ToSendReset(void); void ListenReaderField(int limit); void AcquireRawAdcSamples125k(int at134khz); void SnoopLFRawAdcSamples(int divisor, int trigger_threshold); -void DoAcquisition125k(int trigger_threshold); +void DoAcquisition125k_internal(int trigger_threshold, bool silent); +void DoAcquisition125k_threshold(int trigger_threshold); +void DoAcquisition125k(); + extern int ToSendMax; extern uint8_t ToSend[]; extern uint32_t BigBuf[]; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index e086a717..136a1567 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -42,17 +42,17 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) void AcquireRawAdcSamples125k(int divisor) { LFSetupFPGAForADC(divisor, true); - DoAcquisition125k(-1); + DoAcquisition125k(); } void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) { LFSetupFPGAForADC(divisor, false); - DoAcquisition125k(trigger_threshold); + DoAcquisition125k_threshold(trigger_threshold); } // split into two routines so we can avoid timing issues after sending commands // -void DoAcquisition125k(int trigger_threshold) +void DoAcquisition125k_internal(int trigger_threshold, bool silent) { uint8_t *dest = mifare_get_bigbufptr(); int n = 8000; @@ -75,11 +75,18 @@ void DoAcquisition125k(int trigger_threshold) if (++i >= n) break; } } - Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", + if (!silent){ + Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); - + } } - +void DoAcquisition125k_threshold(int trigger_threshold) { + DoAcquisition125k_internal(trigger_threshold, true); +} +void DoAcquisition125k() { + DoAcquisition125k_internal(-1, true); +} + void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { int at134khz; @@ -138,7 +145,7 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // now do the read - DoAcquisition125k(-1); + DoAcquisition125k(); } /* blank r/w tag data stream @@ -614,331 +621,206 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol) LED_A_OFF(); } - -// loop to capture raw HID waveform then FSK demodulate the TAG ID from it -void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) +size_t fsk_demod(uint8_t * dest, size_t size) { - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, n=0, i=0, idx=0, found=0, lastval=0; - uint32_t hi2=0, hi=0, lo=0; + uint32_t last_transition = 0; + uint32_t idx = 1; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // we don't care about actual value, only if it's more or less than a + // threshold essentially we capture zero crossings for later analysis + uint8_t threshold_value = 127; - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // sync to first lo-hi transition, and threshold - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); + //Need to threshold first sample + dest[0] = (dest[0] < threshold_value) ? 0 : 1; - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + size_t numBits = 0; + // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8) + // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere + // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10 + for(idx = 1; idx < size; idx++) { + // threshold current value + dest[idx] = (dest[idx] < threshold_value) ? 0 : 1; - for(;;) { - WDT_HIT(); - if (ledcontrol) - LED_A_ON(); - if(BUTTON_PRESS()) { - DbpString("Stopped"); - if (ledcontrol) - LED_A_OFF(); - return; - } + // Check for 0->1 transition + if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition - i = 0; - m = sizeof(BigBuf); - memset(dest,128,m); - for(;;) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x43; - if (ledcontrol) - LED_D_ON(); - } - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - // we don't care about actual value, only if it's more or less than a - // threshold essentially we capture zero crossings for later analysis - if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; - i++; - if (ledcontrol) - LED_D_OFF(); - if(i >= m) { - break; - } - } + dest[numBits] = (idx-last_transition < 9) ? 1 : 0; + last_transition = idx; + numBits++; } + } + return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 +} - // FSK demodulator - // sync to first lo-hi transition - for( idx=1; idx0 crossing + if ( dest[idx-1] ) { + n=(n+1) / h2l_crossing_value; + } else {// 0->1 crossing + n=(n+1) / l2h_crossing_value; + } + if (n == 0) n = 1; + + if(n < maxConsequtiveBits) + { + memset(dest+numBits, dest[idx-1] , n); + numBits += n; } + n=0; + lastval=dest[idx]; + }//end for + + return numBits; + +} +// loop to capture raw HID waveform then FSK demodulate the TAG ID from it +void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) +{ + uint8_t *dest = (uint8_t *)BigBuf; + + size_t size=0,idx=0; //, found=0; + uint32_t hi2=0, hi=0, lo=0; + + + while(!BUTTON_PRESS()) { + + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(0,true); + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8) - // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere - // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10 - for( i=0; idx0 : fc/8 in sets of 6 + // 0->1 : fc/10 in sets of 5 + size = aggregate_bits(dest,size, 6,5,5); + WDT_HIT(); // final loop, go over previously decoded manchester data and decode into usable tag ID // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 - for( idx=0; idx>1) & 0xFFFF); - } - else { - Dbprintf("TAG ID: %x%08x (%d)", - (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - } - /* if we're only looking for one tag */ - if (findone) - { - *high = hi; - *low = lo; - return; - } - hi2=0; - hi=0; - lo=0; - found=0; - } - } - if (found) { - if (dest[idx] && (!dest[idx+1]) ) { + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=sizeof(frame_marker_mask); + + while(dest[idx] != dest[idx+1] && idx < size-2) + { // Keep going until next frame marker (or error) + // Shift in a bit. Start by shifting high registers hi2=(hi2<<1)|(hi>>31); hi=(hi<<1)|(lo>>31); + //Then, shift in a 0 or one into low + if (dest[idx] && !dest[idx+1]) // 1 0 lo=(lo<<1)|0; - } else if ( (!dest[idx]) && dest[idx+1]) { - hi2=(hi2<<1)|(hi>>31); - hi=(hi<<1)|(lo>>31); - lo=(lo<<1)|1; - } else { - found=0; - hi2=0; - hi=0; - lo=0; + else // 0 1 + lo=(lo<<1)| + 1; + numshifts ++; + idx += 2; } - idx++; - } - if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) ) - { - found=1; - idx+=6; - if (found && (hi|lo)) { - if (hi2 != 0){ - Dbprintf("TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - } - else { - Dbprintf("TAG ID: %x%08x (%d)", - (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - } - /* if we're only looking for one tag */ - if (findone) - { - *high = hi; - *low = lo; - return; + //Dbprintf("Num shifts: %d ", numshifts); + // Hopefully, we read a tag and hit upon the next frame marker + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { + if (hi2 != 0){ + Dbprintf("TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + } + else { + Dbprintf("TAG ID: %x%08x (%d)", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); } - hi2=0; - hi=0; - lo=0; - found=0; } + + // reset + hi2 = hi = lo = 0; + numshifts = 0; + }else + { + idx++; } } WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } +uint32_t bytebits_to_byte(uint8_t* src, int numbits) +{ + uint32_t num = 0; + for(int i = 0 ; i < numbits ; i++) + { + num = (num << 1) | (*src); + src++; + } + return num; +} + + void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) { - uint8_t *dest = mifare_get_bigbufptr(); - int m=0, n=0, i=0, idx=0, lastval=0; - int found=0; - uint32_t code=0, code2=0; + uint8_t *dest = (uint8_t *)BigBuf; - LFSetupFPGAForADC(0, true); + size_t size=0, idx=0; + uint32_t code=0, code2=0; - for(;;) { - WDT_HIT(); - if (ledcontrol) - LED_A_ON(); - if(BUTTON_PRESS()) { - DbpString("Stopped"); - if (ledcontrol) - LED_A_OFF(); - return; - } - i = 0; - m = 30000; - memset(dest,128,m); - for(;;) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x43; - if (ledcontrol) - LED_D_ON(); - } - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - // we don't care about actual value, only if it's more or less than a - // threshold essentially we capture zero crossings for later analysis - dest[i] = (dest[i] < 127) ? 0 : 1; - ++i; - if (ledcontrol) - LED_D_OFF(); - if(i >= m) - break; - } - } + while(!BUTTON_PRESS()) { - // FSK demodulator + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(0,true); - // sync to first lo-hi transition - for( idx=1; idx0 : fc/8 in sets of 7 + // 0->1 : fc/10 in sets of 6 + size = aggregate_bits(dest, size, 7,6,13); - m=i; WDT_HIT(); - for( idx=0; idx -- Drive LF antenna at 12Mhz/(divisor+1)"}, {"setmux", CmdSetMux, 0, " -- Set the ADC mux to a specific value"}, {"tune", CmdTune, 0, "Measure antenna tuning"}, - {"version", CmdVersion, 0, "Show version inforation about the connected Proxmark"}, + {"version", CmdVersion, 0, "Show version information about the connected Proxmark"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 9206fd2a..8420465b 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -28,9 +28,7 @@ static int CmdHelp(const char *Cmd); int CmdReadBlk(const char *Cmd) { - //default to invalid block int Block = -1; - UsbCommand c; sscanf(Cmd, "%d", &Block); @@ -39,10 +37,8 @@ int CmdReadBlk(const char *Cmd) return 1; } - //PrintAndLog(" Reading page 0 block : %d", Block); - // this command fills up BigBuff - // + UsbCommand c; c.cmd = CMD_T55XX_READ_BLOCK; c.d.asBytes[0] = 0x00; c.arg[0] = 0; @@ -57,10 +53,10 @@ int CmdReadBlk(const char *Cmd) WaitForResponseTimeout(CMD_ACK,NULL, 1500); for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) { - GraphBuffer[j] = ((int)data[j]) ; + GraphBuffer[j] = (int)data[j]; } GraphTraceLen = LF_TRACE_BUFF_SIZE; - CmdIceManchester(Cmd); + CmdIceManchester(Block); RepaintGraphWindow(); return 0; } @@ -97,9 +93,7 @@ int CmdReadBlkPWD(const char *Cmd) GraphBuffer[j] = ((int)data[j]) - 128; } GraphTraceLen = LF_TRACE_BUFF_SIZE; - - CmdIceManchester(Cmd); - + CmdIceManchester(Block); RepaintGraphWindow(); return 0; } @@ -349,6 +343,10 @@ int CmdIceFsk(const char *Cmd){ return 0; } int CmdIceManchester(const char *Cmd){ + ManchesterDemod( -1); + return 0; +} +int ManchesterDemod(int block){ int blockNum = -1; uint32_t blockData; @@ -357,9 +355,9 @@ int CmdIceManchester(const char *Cmd){ manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream); blockData = PackBits(5, 32, bitstream); - sscanf(Cmd, "%d", &blockNum); + if ( blockNum > -1){ - PrintAndLog(" Block %d : 0x%08X %s", blockNum, blockData, sprint_bin(bitstream+5,32) ); + PrintAndLog(" Block %d : 0x%08X %s", blockNum, blockData, sprint_bin(bitstream+5,32) ); }else{ PrintAndLog(" Decoded : 0x%08X %s", blockData, sprint_bin(bitstream+5,32) ); } @@ -484,7 +482,7 @@ static command_t CommandTable[] = {"info", CmdInfo, 0, "[1] Read T55xx configuration data (page0 /blk 0)"}, {"dump", CmdDump, 0, "[password] Dump T55xx card block 0-7. optional with password"}, {"fsk", CmdIceFsk, 0, "FSK demod"}, - {"man", CmdIceManchester, 0, "Manchester demod"}, + {"man", CmdIceManchester, 0, "Manchester demod (with SST)"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlft55xx.h b/client/cmdlft55xx.h index d5c55f11..8c0cdf58 100644 --- a/client/cmdlft55xx.h +++ b/client/cmdlft55xx.h @@ -20,6 +20,7 @@ int CmdReadTrace(const char *Cmd); int CmdInfo(const char *Cmd); int CmdIceFsk(const char *Cmd); int CmdIceManchester(const char *Cmd); +int ManchesterDemod(int block); char * GetBitRateStr(uint32_t id); char * GetSaferStr(uint32_t id); char * GetModulationStr( uint32_t id); diff --git a/client/cmdmain.c b/client/cmdmain.c index c56aaa63..bf69c5ad 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -26,6 +26,10 @@ #include "util.h" #include "cmdscript.h" +int delta125[2]; +int delta134[2]; +int deltahf[2]; +int deltaReset = 0; unsigned int current_command = CMD_UNKNOWN; //unsigned int received_command = CMD_UNKNOWN; @@ -210,13 +214,30 @@ void UsbCommandReceived(UsbCommand *UC) int vLf125, vLf134, vHf; vLf125 = UC->arg[0] & 0xffff; vLf134 = UC->arg[0] >> 16; - vHf = UC->arg[1] & 0xffff;; - peakf = UC->arg[2] & 0xffff; - peakv = UC->arg[2] >> 16; + vHf = UC->arg[1] & 0xffff;; + peakf = UC->arg[2] & 0xffff; + peakv = UC->arg[2] >> 16; + + //Reset delta trigger every 3:d time + + if ( deltaReset == 4){ + delta125[0] = vLf125; + delta134[0] = vLf134; + deltahf[0] = vHf; + } else if ( deltaReset == 2){ + delta125[1] = vLf125; + delta134[1] = vLf134; + deltahf[1] = vHf; + } + + if ( deltaReset == 0){ + + } + PrintAndLog(""); PrintAndLog("# LF antenna: %5.2f V @ 125.00 kHz", vLf125/1000.0); PrintAndLog("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0); - PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1)); + 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); if (peakv<2000) PrintAndLog("# Your LF antenna is unusable."); @@ -226,7 +247,10 @@ void UsbCommandReceived(UsbCommand *UC) PrintAndLog("# Your HF antenna is unusable."); else if (vHf<5000) PrintAndLog("# Your HF antenna is marginal."); - } break; + } + + deltaReset = (deltaReset == 0) ? 4 : deltaReset>>1; + break; case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: { // printf("received samples: "); diff --git a/client/proxmark3.c b/client/proxmark3.c index a9819b54..d2bb2011 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -48,6 +48,11 @@ void SendCommand(UsbCommand *c) { return; } + /** + The while-loop below causes hangups at times, when the pm3 unit is unresponsive + or disconnected. The main console thread is alive, but comm thread just spins here. + Not good.../holiman + **/ while(txcmd_pending); txcmd = *c; txcmd_pending = true; diff --git a/client/ui.c b/client/ui.c index 094b8e56..59ca72dc 100644 --- a/client/ui.c +++ b/client/ui.c @@ -116,8 +116,8 @@ int manchester_decode( int * data, const size_t len, uint8_t * dataout){ clock = GetT55x7Clock( data, len, high ); startindex = DetectFirstTransition(data, len, high); - // PrintAndLog(" Clock : %d", clock); - // PrintAndLog(" startindex : %d", startindex); + PrintAndLog(" Clock : %d", clock); + PrintAndLog(" startindex : %d", startindex); if (high != 1) bitlength = ManchesterConvertFrom255(data, len, bitStream, high, low, clock, startindex); @@ -579,25 +579,21 @@ void iceFsk3(int * data, const size_t len){ printf("000111 position: %d \n", startPos); - startPos += 6*fieldlen+1; + startPos += 6*fieldlen+5; + int bit =0; printf("BINARY\n"); printf("R/40 : "); for (i =startPos ; i < len; i += 40){ - if ( data[i] > 0 ) - printf("1"); - else - printf("0"); + bit = data[i]>0 ? 1:0; + printf("%d", bit ); } printf("\n"); printf("R/50 : "); for (i =startPos ; i < len; i += 50){ - if ( data[i] > 0 ) - printf("1"); - else - printf("0"); - } + bit = data[i]>0 ? 1:0; + printf("%d", bit ); } printf("\n"); } -- 2.39.5