From 1b492a97af74c0cb6c9886bce8b777d6bb50798d Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 26 Dec 2014 20:02:59 +0100 Subject: [PATCH] ADD: marshmellows new lf command and DetectClock. (works great!) FIX: a suggested patch for "hf mf csetuid" (https://github.com/Proxmark/proxmark3/issues/35) FIX: fixed a bug in iso14443a_select_card where the len variable wasnt set, this made desfire/magic cards not work. --- armsrc/iso14443a.c | 36 +-- armsrc/lfops.c | 81 ++++-- armsrc/mifarecmd.c | 23 +- armsrc/mifaredesfire.c | 4 +- client/cmddata.c | 640 ++++++++++++++++++++++++++++++++++++++++- client/cmddata.h | 4 + client/cmdhf14a.c | 1 - client/cmdhfmf.c | 15 +- client/cmdlf.c | 3 + client/cmdlfawid26.c | 24 +- client/cmdlfawid26.h | 2 +- client/cmdlfhid.c | 1 + client/cmdlfio.c | 2 +- client/graph.c | 99 +++++-- client/mifarehost.c | 9 +- client/uart.c | 1 + client/util.c | 6 +- client/util.h | 2 +- 18 files changed, 851 insertions(+), 102 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 269a00c5..8399c6f8 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -394,8 +394,12 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) } else if (Uart.len & 0x0007) { // there are some parity bits to store Uart.parityBits <<= (8 - (Uart.len & 0x0007)); // left align remaining parity bits Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them - return TRUE; // we are finished with decoding the raw data sequence } + if ( Uart.len) { + return TRUE; // we are finished with decoding the raw data sequence + } else { + UartReset(); // Nothing receiver - start over + } } if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC UartReset(); @@ -556,6 +560,8 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non } else if (Demod.len & 0x0007) { // there are some parity bits to store Demod.parityBits <<= (8 - (Demod.len & 0x0007)); // left align remaining parity bits Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them + } + if (Demod.len) { return TRUE; // we are finished with decoding the raw data sequence } else { // nothing received. Start over DemodReset(); @@ -1627,7 +1633,7 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start //----------------------------------------------------------------------------- static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { - uint16_t c; + uint32_t c; // Set FPGA mode to "reader listen mode", no modulation (listen // only, since we are receiving, not transmitting). @@ -1715,8 +1721,6 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) * fills the uid pointer unless NULL * fills resp_data unless NULL */ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, uint32_t* cuid_ptr) { - - iso14a_set_timeout(10500); // 10ms default 10*105 = //uint8_t deselect[] = {0xc2}; //DESELECT //uint8_t halt[] = { 0x50, 0x00, 0x57, 0xCD }; // HALT @@ -1732,7 +1736,7 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u size_t uid_resp_len; uint8_t sak = 0x04; // cascade uid int cascade_level = 0; - int len; + int len =0; // test for the SKYLANDERS TOY. // ReaderTransmit(deselect,sizeof(deselect), NULL); @@ -1812,7 +1816,11 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u ReaderTransmit(sel_uid,sizeof(sel_uid), NULL); // Receive the SAK - if (!ReaderReceive(resp, resp_par)) return 0; + if (!ReaderReceive(resp, resp_par)){ + return 0; + } + + sak = resp[0]; // Test if more parts of the uid are coming @@ -1840,23 +1848,17 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u p_hi14a_card->sak = sak; p_hi14a_card->ats_len = 0; } - - if( (sak & 0x20) == 0) { - return 2; // non iso14443a compliant tag - } + // non iso14443a compliant tag + if( (sak & 0x20) == 0) return 2; + // Request for answer to select AppendCrc14443a(rats, 2); ReaderTransmit(rats, sizeof(rats), NULL); - - len = ReaderReceive(resp, resp_par); - Dbprintf("RATS Reponse: %d", len); - if(!len) { - Dbprintf("RATS: %02x %02x %02x", resp[0], resp[1], resp[2]); - return 0; - } + if (!(len = ReaderReceive(resp, resp_par))) return 0; + if(p_hi14a_card) { memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats)); p_hi14a_card->ats_len = len; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index fa0516c9..5e01e9b0 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -721,14 +721,28 @@ void CmdHIDsimTAG(int hi, int lo, uint8_t ledcontrol) LED_A_OFF(); } +//translate wave to 11111100000 (1 for each short wave 0 for each long wave) size_t fsk_demod(uint8_t * dest, size_t size) { uint32_t last_transition = 0; uint32_t idx = 1; - - // 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; + uint32_t maxVal=0; + // // 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 + + // we do care about the actual value as sometimes near the center of the + // wave we may get static that changes direction of wave for one value + // if our value is too low it might affect the read. and if our tag or + // antenna is weak a setting too high might not see anything. [marshmellow] + if (size<100) return size; + for(idx=1; idx<100; idx++){ + if(maxVal= 2000) return 2000;//something bad happened + return (uint32_t) (f + (float)0.5); +} -size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, uint8_t maxConsequtiveBits, uint8_t invert ) +//translate 11111100000 to 10 +size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert )// uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, { uint8_t lastval=dest[0]; uint32_t idx=0; @@ -769,10 +789,12 @@ size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint continue; } //if lastval was 1, we have a 1->0 crossing - if ( dest[idx-1] ) { - n=(n+1) / h2l_crossing_value; + if ( dest[idx-1]==1 ) { + n=myround((float)(n+1)/((float)(rfLen)/(float)8)); + //n=(n+1) / h2l_crossing_value; } else {// 0->1 crossing - n=(n+1) / l2h_crossing_value; + n=myround((float)(n+1)/((float)(rfLen-2)/(float)10)); + //n=(n+1) / l2h_crossing_value; } if (n == 0) n = 1; @@ -792,7 +814,7 @@ size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint return numBits; } -// loop to capture raw HID waveform then FSK demodulate the TAG ID from it +// loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { uint8_t *dest = get_bigbufptr_recvrespbuf(); @@ -817,7 +839,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) // 1->0 : fc/8 in sets of 6 (RF/50 / 8 = 6.25) // 0->1 : fc/10 in sets of 5 (RF/50 / 10= 5) // do not invert - size = aggregate_bits(dest,size, 6,5,5,0); + size = aggregate_bits(dest,size, 50,5,0); //6,5,5,0 WDT_HIT(); @@ -826,8 +848,11 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; int numshifts = 0; idx = 0; + //one scan + uint8_t sameCardCount =0; while( idx + sizeof(frame_marker_mask) < size) { // search for a start of frame marker + if (sameCardCount>2) break; //only up to 2 valid sets of data for the same read of looping card data if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) { // frame marker found idx+=sizeof(frame_marker_mask); @@ -905,6 +930,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); } + sameCardCount++; if (findone){ if (ledcontrol) LED_A_OFF(); return; @@ -955,14 +981,24 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) DoAcquisition125k_internal(-1,true); size = sizeof(BigBuf); - + //make sure buffer has data + if (size < 64) return; + //test samples are not just noise + uint8_t testMax=0; + for(idx=0;idx<64;idx++){ + if (testMax170){ + //Dbprintf("testMax: %d",testMax); // FSK demodulator size = fsk_demod(dest, size); // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns // 1->0 : fc/8 in sets of 7 (RF/64 / 8 = 8) // 0->1 : fc/10 in sets of 6 (RF/64 / 10 = 6.4) - size = aggregate_bits(dest, size, 7,6,13,1); //13 max Consecutive should be ok as most 0s in row should be 10 for init seq - invert bits - + size = aggregate_bits(dest, size, 64, 13, 1); //13 max Consecutive should be ok as most 0s in row should be 10 for init seq - invert bits + WDT_HIT(); //Index map //0 10 20 30 40 50 60 //| | | | | | | @@ -972,12 +1008,14 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // //XSF(version)facility:codeone+codetwo //Handle the data - + uint8_t sameCardCount=0; uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; - - for( idx=0; idx < (size - 64); idx++) { + for( idx=0; idx < (size - 74); idx++) { + if (sameCardCount>2) break; if ( memcmp(dest + idx, mask, sizeof(mask))==0) { //frame marker found + if (!dest[idx+8] && dest[idx+17]==1 && dest[idx+26]==1 && dest[idx+35]==1 && dest[idx+44]==1 && dest[idx+53]==1){ + //confirmed proper separator bits found if(findone){ //only print binary if we are doing one Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]); Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]); @@ -989,9 +1027,9 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) } code = bytebits_to_byte(dest+idx,32); code2 = bytebits_to_byte(dest+idx+32,32); - short version = bytebits_to_byte(dest+idx+28,8); //14,4 - char facilitycode = bytebits_to_byte(dest+idx+19,8) ; - uint16_t number = (bytebits_to_byte(dest+idx+37,8)<<8)|(bytebits_to_byte(dest+idx+46,8)); //36,9 + short version = bytebits_to_byte(dest+idx+27,8); //14,4 + uint8_t facilitycode = bytebits_to_byte(dest+idx+19,8) ; + uint16_t number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 Dbprintf("XSF(%02d)%02x:%d (%08x%08x)",version,facilitycode,number,code,code2); @@ -1000,6 +1038,9 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) if (ledcontrol) LED_A_OFF(); isFinish = 1; break; + } + sameCardCount++; + } } } } @@ -1183,7 +1224,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; ++i; LED_D_OFF(); - if (i > bufferlength) break; + if (i >= bufferlength) break; } } diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index b9b8098a..1352215e 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -601,7 +601,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160 for (i = 141; i < 1200; i++) { nttmp = prng_successor(nttmp, 1); - if (nttmp == nt2) {break;} + if (nttmp == nt2) break; } if (i != 1200) { @@ -945,8 +945,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + // reset FPGA and LED if (workFlags & 0x08) { - // clear trace iso14a_clear_trace(); iso14a_set_tracing(TRUE); @@ -956,16 +956,18 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai LED_B_OFF(); LED_C_OFF(); - SpinDelay(300); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(100); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + //SpinDelay(300); + //FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + //SpinDelay(100); + //FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); } while (true) { + // get UID from chip if (workFlags & 0x01) { if(!iso14443a_select_card(uid, NULL, &cuid)) { + Dbprintf("ICE"); if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); break; }; @@ -1041,7 +1043,6 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai LED_B_OFF(); if ((workFlags & 0x10) || (!isOK)) { - // Thats it... FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); } @@ -1082,10 +1083,10 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai LED_B_OFF(); LED_C_OFF(); - SpinDelay(300); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(100); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + // SpinDelay(300); + // FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // SpinDelay(100); + // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); } while (true) { diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index 0d8de438..56166777 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -32,9 +32,7 @@ bool InitDesfireCard(){ int len = iso14443a_select_card(NULL,card,NULL); if (!len) { - if (MF_DBGLEVEL >= 1) { - Dbprintf("Can't select card"); - } + if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); OnError(); return false; } diff --git a/client/cmddata.c b/client/cmddata.c index 0ba04b79..b2c68b97 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -70,6 +70,7 @@ int CmdAmp(const char *Cmd) * Arguments: * c : 0 or 1 */ + //this method is dependant on all highs and lows to be the same(or clipped) this creates issues[marshmellow] it also ignores the clock int Cmdaskdemod(const char *Cmd) { int i; @@ -118,6 +119,274 @@ int Cmdaskdemod(const char *Cmd) return 0; } +void printBitStream(int BitStream[], uint32_t bitLen){ + uint32_t i = 0; + if (bitLen<16) return; + if (bitLen>512) bitLen=512; + 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; +} +void printBitStream2(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; + 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 +//takes 1s and 0s and searches for EM410x format - output EM ID +int Em410xDecode(const char *Cmd) +{ + //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future + // otherwise could be a void with no arguments + //set defaults + int high=0, low=0; + uint64_t lo=0; //hi=0, + + uint32_t i = 0; + uint32_t initLoopMax = 1000; + if (initLoopMax>GraphTraceLen) initLoopMax=GraphTraceLen; + + for (;i < initLoopMax; ++i) //1000 samples should be plenty to find high and low values + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } + if (((high !=1)||(low !=0))){ //allow only 1s and 0s + PrintAndLog("no data found"); + return 0; + } + uint8_t parityTest=0; + // 111111111 bit pattern represent start of frame + int frame_marker_mask[] = {1,1,1,1,1,1,1,1,1}; + uint32_t idx = 0; + uint32_t ii=0; + uint8_t resetCnt = 0; + while( (idx + 64) < GraphTraceLen) { +restart: + // search for a start of frame marker + if ( memcmp(GraphBuffer+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=9;//sizeof(frame_marker_mask); + for (i=0; i<10;i++){ + for(ii=0; ii<5; ++ii){ + parityTest += GraphBuffer[(i*5)+ii+idx]; + } + if (parityTest== ((parityTest>>1)<<1)){ + parityTest=0; + for (ii=0; ii<4;++ii){ + //hi = (hi<<1)|(lo>>31); + lo=(lo<<1LL)|(GraphBuffer[(i*5)+ii+idx]); + } + //PrintAndLog("DEBUG: EM parity passed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d,lo: %d",parityTest,i,ii,idx,GraphBuffer[idx+ii+(i*5)-5],GraphBuffer[idx+ii+(i*5)-4],GraphBuffer[idx+ii+(i*5)-3],GraphBuffer[idx+ii+(i*5)-2],GraphBuffer[idx+ii+(i*5)-1],lo); + }else {//parity failed + //PrintAndLog("DEBUG: EM parity failed parity val: %d, i:%d, ii:%d,idx:%d, Buffer: %d%d%d%d%d",parityTest,i,ii,idx,GraphBuffer[idx+ii+(i*5)-5],GraphBuffer[idx+ii+(i*5)-4],GraphBuffer[idx+ii+(i*5)-3],GraphBuffer[idx+ii+(i*5)-2],GraphBuffer[idx+ii+(i*5)-1]); + parityTest=0; + idx-=8; + if (resetCnt>5)return 0; + resetCnt++; + goto restart;//continue; + } + } + //skip last 5 bit parity test for simplicity. + + //get Unique ID + uint64_t iii=1; + uint64_t id2lo=0; //id2hi=0, + //for (i=0;i<8;i++){ //for uint32 instead of uint64 + // id2hi=(id2hi<<1)|((hi & (iii<<(i)))>>i); + //} + for (ii=5; ii>0;ii--){ + for (i=0;i<8;i++){ + id2lo=(id2lo<<1LL)|((lo & (iii<<(i+((ii-1)*8))))>>(i+((ii-1)*8))); + } + } + //output em id + PrintAndLog("EM TAG ID : %010llx", lo); + PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi, + PrintAndLog("DEZ 8 : %08lld",lo & 0xFFFFFF); + PrintAndLog("DEZ 10 : %010lld",lo & 0xFFFFFF); + PrintAndLog("DEZ 5.5 : %05lld.%05lld",(lo>>16LL) & 0xFFFF,(lo & 0xFFFF)); + PrintAndLog("DEZ 3.5A : %03lld.%05lld",(lo>>32ll),(lo & 0xFFFF)); + PrintAndLog("DEZ 14/IK2 : %014lld",lo); + PrintAndLog("DEZ 15/IK3 : %015lld",id2lo); + PrintAndLog("Other : %05lld_%03lld_%08lld",(lo&0xFFFF),((lo>>16LL) & 0xFF),(lo & 0xFFFFFF)); + return 0; + }else{ + idx++; + } + } + return 0; +} + + +//by marshmellow +//takes 2 arguments - clock and invert both as integers +//prints binary found and saves in graphbuffer for further commands +int Cmdaskmandemod(const char *Cmd) +{ + uint32_t i; + int invert=0; //invert default + int high = 0, low = 0; + int clk=DetectClock(0); //clock default + uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0}; + sscanf(Cmd, "%i %i", &clk, &invert); + if (clk<8) clk =64; + if (clk<32) clk=32; + if (invert != 0 && invert != 1) { + PrintAndLog("Invalid argument: %s", Cmd); + return 0; + } + uint32_t initLoopMax = 1000; + if (initLoopMax>GraphTraceLen) initLoopMax=GraphTraceLen; + // Detect high and lows + PrintAndLog("Using Clock: %d and invert=%d",clk,invert); + for (i = 0; i < initLoopMax; ++i) //1000 samples should be plenty to find high and low values + { + if (GraphBuffer[i] > high) + high = GraphBuffer[i]; + else if (GraphBuffer[i] < low) + low = GraphBuffer[i]; + } + if ((high < 30) && ((high !=1)||(low !=-1))){ //throw away static - allow 1 and -1 (in case of threshold command first) + PrintAndLog("no data found"); + return 0; + } + //13% fuzz in case highs and lows aren't clipped [marshmellow] + high=(int)(0.75*high); + low=(int)(0.75*low); + + //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low); + int lastBit = 0; //set first clock check + uint32_t bitnum = 0; //output counter + 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 + uint32_t iii = 0; + uint32_t gLen = GraphTraceLen; + if (gLen > 500) gLen=500; + uint8_t errCnt =0; + uint32_t bestStart = GraphTraceLen; + uint32_t bestErrCnt = (GraphTraceLen/1000); + //PrintAndLog("DEBUG - lastbit - %d",lastBit); + //loop to find first wave that works + for (iii=0; iii < gLen; ++iii){ + if ((GraphBuffer[iii]>=high)||(GraphBuffer[iii]<=low)){ + lastBit=iii-clk; + //loop through to see if this start location works + for (i = iii; i < GraphTraceLen; ++i) { + if ((GraphBuffer[i] >= high) && ((i-lastBit)>(clk-tol))){ + lastBit+=clk; + BitStream[bitnum] = invert; + bitnum++; + } else if ((GraphBuffer[i] <= low) && ((i-lastBit)>(clk-tol))){ + //low found and we are expecting a bar + lastBit+=clk; + BitStream[bitnum] = 1-invert; + bitnum++; + } else { + //mid value found or no bar supposed to be here + if ((i-lastBit)>(clk+tol)){ + //should have hit a high or low based on clock!! + + + //debug + //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){ + BitStream[bitnum]=77; + bitnum++; + } + + + errCnt++; + lastBit+=clk;//skip over until hit too many errors + if (errCnt>((GraphTraceLen/1000))){ //allow 1 error for every 1000 samples else start over + errCnt=0; + bitnum=0;//start over + break; + } + } + } + } + //we got more than 64 good bits and not all errors + if ((bitnum > (64+errCnt)) && (errCnt<(GraphTraceLen/1000))) { + //possible good read + if (errCnt==0) break; //great read - finish + if (bestStart == iii) break; //if current run == bestErrCnt run (after exhausted testing) then finish + if (errCnt=gLen){ //exhausted test + //if there was a ok test go back to that one and re-run the best run (then dump after that run) + if (bestErrCnt < (GraphTraceLen/1000)) iii=bestStart; + } + } + if (bitnum>16){ + + PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum); + //move BitStream back to GraphBuffer + ClearGraph(0); + for (i=0; i < bitnum; ++i){ + GraphBuffer[i]=BitStream[i]; + } + GraphTraceLen=bitnum; + RepaintGraphWindow(); + //output + if (errCnt>0){ + PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt); + } + PrintAndLog("ASK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printBitStream2(BitStream,bitnum); + Em410xDecode(Cmd); + } + return 0; +} + int CmdAutoCorr(const char *Cmd) { static int CorrelBuffer[MAX_GRAPH_TRACE_LEN]; @@ -263,7 +532,370 @@ int CmdDetectClockRate(const char *Cmd) return 0; } -int CmdFSKdemod(const char *Cmd) +//by marshmellow +//demod GraphBuffer wave to 0s and 1s for each wave - 0s for short waves 1s for long waves +size_t fsk_wave_demod(int size) +{ + uint32_t last_transition = 0; + uint32_t idx = 1; + uint32_t maxVal = 0; + // 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 + for(idx=1; idx1 transition + if (GraphBuffer[idx-1] < GraphBuffer[idx]) { // 0 -> 1 transition + if (idx-last_transition<6){ + // do nothing with extra garbage (shouldn't be any) noise tolerance? + } else if(idx-last_transition < 9) { + GraphBuffer[numBits]=1; + // Other fsk demods reverse this making the short waves 1 and long waves 0 + // this is really backwards... smaller waves will typically be 0 and larger 1 [marshmellow] + // but will leave as is and invert when needed later + } else{ + GraphBuffer[numBits]=0; + } + last_transition = idx; + numBits++; + // PrintAndLog("numbits %d",numBits); + } + } + return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 +} +uint32_t myround(float f) +{ + if (f >= UINT_MAX) return UINT_MAX; + return (uint32_t) (f + (float)0.5); +} + +//by marshmellow (from holiman's base) +//translate 11111100000 to 10 +size_t aggregate_bits(int size, uint8_t rfLen, uint8_t maxConsequtiveBits, uint8_t invert) //,uint8_t l2h_crossing_value +{ + int lastval=GraphBuffer[0]; + uint32_t idx=0; + size_t numBits=0; + uint32_t n=1; + uint32_t n2=0; + for( idx=1; idx < size; idx++) { + + if (GraphBuffer[idx]==lastval) { + n++; + continue; + } + // if lastval was 1, we have a 1->0 crossing + if ( GraphBuffer[idx-1]==1 ) { + n=myround((float)(n+1)/((float)(rfLen)/(float)8)); //-2 noise tolerance + + // n=(n+1) / h2l_crossing_value; + //truncating could get us into trouble + //now we will try with actual clock (RF/64 or RF/50) variable instead + //then devide with float casting then truncate after more acurate division + //and round to nearest int + //like n = (((float)n)/(float)rfLen/(float)10); + } else {// 0->1 crossing + n=myround((float)(n+1)/((float)(rfLen-2)/(float)10)); // as int 120/6 = 20 as float 120/(64/10) = 18 (18.75) + //n=(n+1) / l2h_crossing_value; + } + if (n == 0) n = 1; //this should never happen... should we error if it does? + + if (n < maxConsequtiveBits) // Consecutive //when the consecutive bits are low - the noise tolerance can be high + //if it is high then we must be careful how much noise tolerance we allow + { + if (invert==0){ // do not invert bits + for (n2=0; n20 && strlen(Cmd)<=2) { + rfLen=param_get8(Cmd, 0); //if rfLen option only is used + if (rfLen==1){ + invert=1; //if invert option only is used + rfLen = 50; + } else if(rfLen==0) rfLen=50; + } + if (strlen(Cmd)>2) { + rfLen=param_get8(Cmd, 0); //if both options are used + invert=param_get8(Cmd,1); + } + PrintAndLog("Args invert: %d \nClock:%d",invert,rfLen); + + size_t size = fskdemod(rfLen,invert); + + PrintAndLog("FSK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + if(size > (7*32)+2) size = (7*32)+2; //only output a max of 7 blocks of 32 bits most tags will have full bit stream inside that sample size + printBitStream(GraphBuffer,size); + + ClearGraph(1); + return 0; +} + +//by marshmellow +int CmdFSKdemodHID(const char *Cmd) +{ + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + //set defaults + uint8_t rfLen = 50; + uint8_t invert=0;//param_get8(Cmd, 0); + size_t idx=0; + uint32_t hi2=0, hi=0, lo=0; + + //get binary from fsk wave + size_t size = fskdemod(rfLen,invert); + + // final loop, go over previously decoded fsk data and now manchester decode into usable tag ID + // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 + int frame_marker_mask[] = {1,1,1,0,0,0}; + int numshifts = 0; + idx = 0; + while( idx + 6 < size) { + // search for a start of frame marker + + if ( memcmp(GraphBuffer+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=6;//sizeof(frame_marker_mask); //size of int is >6 + while(GraphBuffer[idx] != GraphBuffer[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 (GraphBuffer[idx] && !GraphBuffer[idx+1]) // 1 0 + lo=(lo<<1)|0; + else // 0 1 + lo=(lo<<1)|1; + numshifts++; + idx += 2; + } + + //PrintAndLog("Num shifts: %d ", numshifts); + // Hopefully, we read a tag and hit upon the next frame marker + if(idx + 6 < size) + { + if ( memcmp(GraphBuffer+(idx), frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { + if (hi2 != 0){ //extra large HID tags + PrintAndLog("TAG ID: %x%08x%08x (%d)", + (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + } + else { //standard HID tags <38 bits + //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd + uint8_t bitlen = 0; + uint32_t fc = 0; + uint32_t cardnum = 0; + if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used + uint32_t lo2=0; + lo2=(((hi & 15) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit + uint8_t idx3 = 1; + while(lo2>1){ //find last bit set to 1 (format len bit) + lo2=lo2>>1; + idx3++; + } + bitlen =idx3+19; + fc =0; + cardnum=0; + if(bitlen==26){ + cardnum = (lo>>1)&0xFFFF; + fc = (lo>>17)&0xFF; + } + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + if(bitlen==34){ + cardnum = (lo>>1)&0xFFFF; + fc= ((hi&1)<<15)|(lo>>17); + } + if(bitlen==35){ + cardnum = (lo>>1)&0xFFFFF; + fc = ((hi&1)<<11)|(lo>>21); + } + } + else { //if bit 38 is not set then 37 bit format is used + bitlen= 37; + fc =0; + cardnum=0; + if(bitlen==37){ + cardnum = (lo>>1)&0x7FFFF; + fc = ((hi&0xF)<<12)|(lo>>20); + } + } + + PrintAndLog("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); + ClearGraph(1); + return 0; + } + } + } + // reset + hi2 = hi = lo = 0; + numshifts = 0; + }else + { + idx++; + } + } + if (idx + sizeof(frame_marker_mask) >= size){ + PrintAndLog("start bits for hid not found"); + PrintAndLog("FSK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printBitStream(GraphBuffer,size); + + } + ClearGraph(1); + return 0; +} + +//by marshmellow +int CmdFSKdemodIO(const char *Cmd) +{ + //raw fsk demod no manchester decoding no start bit finding just get binary from wave + //set defaults + uint8_t rfLen = 64; + uint8_t invert=1; + size_t idx=0; + uint8_t testMax=0; + //test samples are not just noise + if (GraphTraceLen < 64) return 0; + for(idx=0;idx<64;idx++){ + if (testMax40){ + //Index map + //0 10 20 30 40 50 60 + //| | | | | | | + //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23 + //----------------------------------------------------------------------------- + //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 + // + //XSF(version)facility:codeone+codetwo (raw) + //Handle the data + int mask[] = {0,0,0,0,0,0,0,0,0,1}; + for( idx=0; idx < (size - 74); idx++) { + if ( memcmp(GraphBuffer + idx, mask, sizeof(mask))==0) { + //frame marker found + if (GraphBuffer[idx+17]==1 && GraphBuffer[idx+26]==1 && GraphBuffer[idx+35]==1 && GraphBuffer[idx+44]==1 && GraphBuffer[idx+53]==1){ + //confirmed proper separator bits found + + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx], GraphBuffer[idx+1], GraphBuffer[idx+2], GraphBuffer[idx+3], GraphBuffer[idx+4], GraphBuffer[idx+5], GraphBuffer[idx+6], GraphBuffer[idx+7], GraphBuffer[idx+8]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx+9], GraphBuffer[idx+10], GraphBuffer[idx+11],GraphBuffer[idx+12],GraphBuffer[idx+13],GraphBuffer[idx+14],GraphBuffer[idx+15],GraphBuffer[idx+16],GraphBuffer[idx+17]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx+18], GraphBuffer[idx+19], GraphBuffer[idx+20],GraphBuffer[idx+21],GraphBuffer[idx+22],GraphBuffer[idx+23],GraphBuffer[idx+24],GraphBuffer[idx+25],GraphBuffer[idx+26]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx+27], GraphBuffer[idx+28], GraphBuffer[idx+29],GraphBuffer[idx+30],GraphBuffer[idx+31],GraphBuffer[idx+32],GraphBuffer[idx+33],GraphBuffer[idx+34],GraphBuffer[idx+35]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx+36], GraphBuffer[idx+37], GraphBuffer[idx+38],GraphBuffer[idx+39],GraphBuffer[idx+40],GraphBuffer[idx+41],GraphBuffer[idx+42],GraphBuffer[idx+43],GraphBuffer[idx+44]); + PrintAndLog("%d%d%d%d%d%d%d%d %d",GraphBuffer[idx+45], GraphBuffer[idx+46], GraphBuffer[idx+47],GraphBuffer[idx+48],GraphBuffer[idx+49],GraphBuffer[idx+50],GraphBuffer[idx+51],GraphBuffer[idx+52],GraphBuffer[idx+53]); + PrintAndLog("%d%d%d%d%d%d%d%d %d%d",GraphBuffer[idx+54],GraphBuffer[idx+55],GraphBuffer[idx+56],GraphBuffer[idx+57],GraphBuffer[idx+58],GraphBuffer[idx+59],GraphBuffer[idx+60],GraphBuffer[idx+61],GraphBuffer[idx+62],GraphBuffer[idx+63]); + + uint32_t code = bytebits_to_byte(GraphBuffer+idx,32); + uint32_t code2 = bytebits_to_byte(GraphBuffer+idx+32,32); + short version = bytebits_to_byte(GraphBuffer+idx+27,8); //14,4 + uint8_t facilitycode = bytebits_to_byte(GraphBuffer+idx+19,8) ; + uint16_t number = (bytebits_to_byte(GraphBuffer+idx+36,8)<<8)|(bytebits_to_byte(GraphBuffer+idx+45,8)); //36,9 + + PrintAndLog("XSF(%02d)%02x:%d (%08x%08x)",version,facilitycode,number,code,code2); + ClearGraph(1); + return 0; + } else { + PrintAndLog("thought we had a valid tag but did not match format"); + } + } + } + if (idx >= (size-74)){ + PrintAndLog("start bits for io prox not found"); + PrintAndLog("FSK decoded bitstream:"); + // Now output the bitstream to the scrollback by line of 16 bits + printBitStream(GraphBuffer,size); + } + } + ClearGraph(1); + return 0; +} +int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating { static const int LowTone[] = { 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, @@ -320,7 +952,7 @@ int CmdFSKdemod(const char *Cmd) GraphTraceLen -= (convLen + 16); RepaintGraphWindow(); - // Find bit-sync (3 lo followed by 3 high) + // 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; @@ -954,6 +1586,7 @@ static command_t CommandTable[] = {"help", CmdHelp, 1, "This help"}, {"amp", CmdAmp, 1, "Amplify peaks"}, {"askdemod", Cmdaskdemod, 1, "<0|1> -- Attempt to demodulate simple ASK tags"}, + {"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0 or 1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"}, {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, @@ -962,6 +1595,9 @@ static command_t CommandTable[] = {"detectclock", CmdDetectClockRate, 1, "Detect clock rate"}, {"dirthreshold", CmdDirectionalThreshold, 1, " -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."}, {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"}, + {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"}, + {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"}, + {"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] Demodulate graph window from FSK to binary (clock = 64 or 50)(invert = 1 or 0)"}, {"grid", CmdGrid, 1, " -- overlay grid on graph window, use zero value to turn off either"}, {"hexsamples", CmdHexsamples, 0, " [] -- Dump big buffer as hex bytes"}, {"hide", CmdHide, 1, "Hide graph window"}, diff --git a/client/cmddata.h b/client/cmddata.h index 8073c34c..432ae687 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -17,6 +17,7 @@ int CmdData(const char *Cmd); int CmdAmp(const char *Cmd); int Cmdaskdemod(const char *Cmd); +int Cmdaskrawdemod(const char *Cmd); int CmdAutoCorr(const char *Cmd); int CmdBitsamples(const char *Cmd); int CmdBitstream(const char *Cmd); @@ -24,6 +25,9 @@ int CmdBuffClear(const char *Cmd); int CmdDec(const char *Cmd); int CmdDetectClockRate(const char *Cmd); int CmdFSKdemod(const char *Cmd); +int CmdFSKdemodHID(const char *Cmd); +int CmdFSKdemodIO(const char *Cmd); +int CmdFSKrawdemod(const char *Cmd); int CmdGrid(const char *Cmd); int CmdHexsamples(const char *Cmd); int CmdHide(const char *Cmd); diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index bfa7bfbf..f09c555b 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -231,7 +231,6 @@ int CmdHF14AReader(const char *Cmd) c.arg[1] = 0; c.arg[2] = 0; SendCommand(&c); - if(card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes bool ta1 = 0, tb1 = 0, tc1 = 0; diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 748e9c45..f32ae444 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -124,10 +124,10 @@ int CmdHF14AMfWrBl(const char *Cmd) PrintAndLog("--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6)); PrintAndLog("--data: %s", sprint_hex(bldata, 16)); - UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; + UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); memcpy(c.d.asBytes + 10, bldata, 16); - SendCommand(&c); + SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -168,9 +168,9 @@ int CmdHF14AMfRdBl(const char *Cmd) } PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6)); - UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; + UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); - SendCommand(&c); + SendCommand(&c); UsbCommand resp; if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { @@ -1460,11 +1460,12 @@ int CmdHF14AMfCSetUID(const char *Cmd) res = mfCSetUID(uid, oldUid, wipeCard); if (res) { - PrintAndLog("Can't set UID. error=%d", res); - return 1; - } + PrintAndLog("Can't set UID. error=%d", res); + return 1; + } PrintAndLog("old UID:%s", sprint_hex(oldUid, 4)); + PrintAndLog("new UID:%s", sprint_hex(uid, 4)); return 0; } diff --git a/client/cmdlf.c b/client/cmdlf.c index faf95ccd..97dcf0ba 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -371,6 +371,9 @@ int CmdLFRead(const char *Cmd) } SendCommand(&c); WaitForResponse(CMD_ACK,NULL); + + // load samples + CmdSamples(""); return 0; } diff --git a/client/cmdlfawid26.c b/client/cmdlfawid26.c index 0e1fca8e..71f227f2 100644 --- a/client/cmdlfawid26.c +++ b/client/cmdlfawid26.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "proxmark3.h" #include "ui.h" //#include "graph.h" @@ -43,22 +44,25 @@ int CmdClone(const char *Cmd) // char block2 = "00107060"; // char block3 = "00107060"; + unsigned char buf[10] = {0x00}; + unsigned char *resp = buf; + awid26_hex_to_uid(resp, ""); // PrintAndLog("Writing block %d with data %08X", Block, Data); return 0; } // convert 96 bit AWID FSK data to 8 digit BCD UID -bool awid26_hex_to_uid(unsigned char *response, unsigned char *awid26) +bool awid26_hex_to_uid(unsigned char *response, char *awid26) { - // uint8_t i, tmp[96], tmp1[7]; - // int site; - // int id; + uint8_t i, tmp[96], tmp1[7]; + int site; + int id; - // if(!hextobinarray(tmp, awid26)) - // return false; + if(!hextobinarray(tmp, awid26)) + return false; // // data is in blocks of 4 bits - every 4th bit is parity, except the first // // block which is all zeros @@ -71,7 +75,7 @@ bool awid26_hex_to_uid(unsigned char *response, unsigned char *awid26) // // check and strip parity on the rest // for(i= 1 ; i < 23 ; ++i) - // if(tmp[(i * 4) - 1] != parity(tmp + (i - 1) * 4, ODD, 3)) + // if(tmp[(i * 4) - 1] != GetParity(tmp + (i - 1) * 4, ODD, 3)) // return false; // else // memcpy((tmp + (i - 1) * 3), tmp + (i - 1) * 4, 3); @@ -86,9 +90,9 @@ bool awid26_hex_to_uid(unsigned char *response, unsigned char *awid26) // memcpy(tmp, tmp +8, 58); // // standard wiegand parity check - even for 1st 12 bits, odd for 2nd 12 - // if(tmp[0] != parity(tmp + 1, EVEN, 12)) + // if(tmp[0] != GetParity(tmp + 1, EVEN, 12)) // return false; - // if(tmp[25] != parity(tmp + 13, ODD, 12)) + // if(tmp[25] != GetParity(tmp + 13, ODD, 12)) // return false; // // convert to hex, ignoring parity bits @@ -146,7 +150,7 @@ bool bcd_to_awid26_bin(unsigned char *awid26, unsigned char *bcd) // // add parity bits // for(i= 1 ; i < 24 ; ++i) - // awid26[((i + 1) * 4) - 1]= parity(&awid26[i * 4], ODD, 3); + // awid26[((i + 1) * 4) - 1]= GetParity(&awid26[i * 4], ODD, 3); return false; } diff --git a/client/cmdlfawid26.h b/client/cmdlfawid26.h index cb1cd9e2..7c23d567 100644 --- a/client/cmdlfawid26.h +++ b/client/cmdlfawid26.h @@ -13,6 +13,6 @@ int CmdLFAWID26(const char *Cmd); int CmdClone(const char *Cmd); -bool awid26_hex_to_uid(unsigned char *response, unsigned char *awid26); +bool awid26_hex_to_uid(unsigned char *response, char *awid26); bool bcd_to_awid26_bin(unsigned char *awid26, unsigned char *bcd); #endif diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index ce21ddc8..93d06406 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -58,6 +58,7 @@ int CmdHIDSim(const char *Cmd) } PrintAndLog("Emulating tag with ID %x%16x", hi, lo); + PrintAndLog("Press pm3-button to abort simulation"); UsbCommand c = {CMD_HID_SIM_TAG, {hi, lo, 0}}; SendCommand(&c); diff --git a/client/cmdlfio.c b/client/cmdlfio.c index 78d8fa21..129323ac 100644 --- a/client/cmdlfio.c +++ b/client/cmdlfio.c @@ -55,7 +55,7 @@ int CmdIOClone(const char *Cmd) } PrintAndLog("Cloning tag with ID %08x %08x", hi, lo); - + PrintAndLog("Press pm3-button to abort simulation"); c.cmd = CMD_IO_CLONE_TAG; c.arg[0] = hi; c.arg[1] = lo; diff --git a/client/graph.c b/client/graph.c index 7b45f3f2..bb815995 100644 --- a/client/graph.c +++ b/client/graph.c @@ -51,13 +51,15 @@ int ClearGraph(int redraw) /* * Detect clock rate */ -int DetectClock(int peak) + //decommissioned - has difficulty detecting rf/32 and only works if data is manchester encoded +/* +int DetectClock2(int peak) { int i; int clock = 0xFFFF; int lastpeak = 0; - /* Detect peak if we don't have one */ + // Detect peak if we don't have one if (!peak) for (i = 0; i < GraphTraceLen; ++i) if (GraphBuffer[i] > peak) @@ -65,36 +67,90 @@ int DetectClock(int peak) for (i = 1; i < GraphTraceLen; ++i) { - /* If this is the beginning of a peak */ - if (GraphBuffer[i - 1] != GraphBuffer[i] && GraphBuffer[i] == peak) + // If this is the beginning of a peak + if (GraphBuffer[i - 1] != GraphBuffer[i] && GraphBuffer[i] >= peak) { - /* Find lowest difference between peaks */ + // Find lowest difference between peaks if (lastpeak && i - lastpeak < clock) clock = i - lastpeak; lastpeak = i; } } - int clockmod = clock%8; - if ( clockmod == 0) return clock; - - // When detected clock is 31 or 33 then return 32 +} +*/ - printf("Found clock at %d ", clock); - switch( clockmod ) +// by marshmellow +// not perfect especially with lower clocks or VERY good antennas (heavy wave clipping) +// maybe somehow adjust peak trimming value based on samples to fix? +int DetectClock(int peak) { - case 7: clock++; break; - case 6: clock += 2 ; break; - case 1: clock--; break; - case 2: clock -= 2; break; - } - if ( clock < 32) - clock = 32; - - printf("- adjusted it to %d \n", clock); - return clock; + int i=0; + int low=0; + int clk[]={16,32,40,50,64,100,128,256}; + if (!peak){ + for (i=0;ipeak){ + peak = GraphBuffer[i]; + } + if(GraphBuffer[i]=peak) || (GraphBuffer[ii]<=low)){ + //numbits=0; + //good=1; + errCnt[clkCnt]=0; + for (i=0; i<((int)(GraphTraceLen/clk[clkCnt])-1); ++i){ + if (GraphBuffer[ii+(i*clk[clkCnt])]>=peak || GraphBuffer[ii+(i*clk[clkCnt])]<=low){ + //numbits++; + }else if(GraphBuffer[ii+(i*clk[clkCnt])-tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])-tol]<=low){ + }else if(GraphBuffer[ii+(i*clk[clkCnt])+tol]>=peak || GraphBuffer[ii+(i*clk[clkCnt])+tol]<=low){ + }else{ //error no peak detected + //numbits=0; + //good=0; + errCnt[clkCnt]++; + //break; + } + } + if(errCnt[clkCnt]==0) return clk[clkCnt]; + if(errCnt[clkCnt]fd, F_SETLK, &fl) == -1) { // A conflicting lock is held by another process + free(sp); return CLAIMED_SERIAL_PORT; } diff --git a/client/util.c b/client/util.c index 0418dd98..b8d5c316 100644 --- a/client/util.c +++ b/client/util.c @@ -372,7 +372,7 @@ void binarraytobinstring(char *target, char *source, int length) } // return parity bit required to match type -uint8_t parity( char *bits, uint8_t type, int length) +uint8_t GetParity( char *bits, uint8_t type, int length) { int x; @@ -386,8 +386,8 @@ uint8_t parity( char *bits, uint8_t type, int length) // add HID parity to binary array: EVEN prefix for 1st half of ID, ODD suffix for 2nd half void wiegand_add_parity(char *target, char *source, char length) { - *(target++)= parity(source, EVEN, length / 2); + *(target++)= GetParity(source, EVEN, length / 2); memcpy(target, source, length); target += length; - *(target)= parity(source + length / 2, ODD, length / 2); + *(target)= GetParity(source + length / 2, ODD, length / 2); } diff --git a/client/util.h b/client/util.h index 10bafba9..22d41e0c 100644 --- a/client/util.h +++ b/client/util.h @@ -56,6 +56,6 @@ int param_getstr(const char *line, int paramnum, char * str); int hextobinstring( char *target, char *source); int binarraytohex( char *target, char *source, int length); void binarraytobinstring(char *target, char *source, int length); -uint8_t parity( char *string, uint8_t type, int length); +uint8_t GetParity( char *string, uint8_t type, int length); void wiegand_add_parity(char *target, char *source, char length); -- 2.39.2