]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
ADD: marshmellows new lf command and DetectClock. (works great!)
authoriceman1001 <iceman@iuse.se>
Fri, 26 Dec 2014 19:02:59 +0000 (20:02 +0100)
committericeman1001 <iceman@iuse.se>
Fri, 26 Dec 2014 19:02:59 +0000 (20:02 +0100)
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.

18 files changed:
armsrc/iso14443a.c
armsrc/lfops.c
armsrc/mifarecmd.c
armsrc/mifaredesfire.c
client/cmddata.c
client/cmddata.h
client/cmdhf14a.c
client/cmdhfmf.c
client/cmdlf.c
client/cmdlfawid26.c
client/cmdlfawid26.h
client/cmdlfhid.c
client/cmdlfio.c
client/graph.c
client/mifarehost.c
client/uart.c
client/util.c
client/util.h

index 269a00c5437c96f784d4262d88379d7fb5999902..8399c6f84bb7e24eeeeee8258622dd7b60930d95 100644 (file)
@@ -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;
index fa0516c9fa93cd77418ae2d49911f8c64908ca4f..5e01e9b0de21778da8245d93d752b32c0875c5ef 100644 (file)
@@ -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<dest[idx]) maxVal = dest[idx];
+    }
+    // set close to the top of the wave threshold with 13% margin for error
+    // less likely to get a false transition up there. 
+    // (but have to be careful not to go too high and miss some short waves)
+       uint32_t threshold_value = (uint32_t)(maxVal*.87);      idx=1;
+       //uint8_t threshold_value = 127;
 
        // sync to first lo-hi transition, and threshold
 
@@ -754,8 +768,14 @@ size_t fsk_demod(uint8_t * dest, size_t size)
        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 >= 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 (testMax<dest[idx]) testMax=dest[idx];
+               }
+               idx=0;
+               //if not just noise
+               if (testMax>170){
+                       //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;
                }
        }
  
index b9b8098a403c1d346858f42cdc1fa9f781d82c9a..1352215e2314df9488cfb8e64eecb1f62b7bbeaf 100644 (file)
@@ -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\r
                        for (i = 141; i < 1200; i++) {\r
                                nttmp = prng_successor(nttmp, 1);\r
-                               if (nttmp == nt2) {break;}\r
+                               if (nttmp == nt2) break;\r
                        }\r
 \r
                        if (i != 1200) {\r
@@ -945,8 +945,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
        uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
        uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;\r
        \r
+       // reset FPGA and LED\r
        if (workFlags & 0x08) {\r
-               // clear trace\r
                iso14a_clear_trace();\r
                iso14a_set_tracing(TRUE);\r
 \r
@@ -956,16 +956,18 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                LED_B_OFF();\r
                LED_C_OFF();\r
        \r
-               SpinDelay(300);\r
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-               SpinDelay(100);\r
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
+               //SpinDelay(300);\r
+               //FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               //SpinDelay(100);\r
+               //FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
        }\r
 \r
        while (true) {\r
+\r
                // get UID from chip\r
                if (workFlags & 0x01) {\r
                        if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+                               Dbprintf("ICE");\r
                                if (MF_DBGLEVEL >= 1)   Dbprintf("Can't select card");\r
                                break;\r
                        };\r
@@ -1041,7 +1043,6 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
        LED_B_OFF();\r
 \r
        if ((workFlags & 0x10) || (!isOK)) {\r
-               // Thats it...\r
                FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
                LEDsoff();\r
        }\r
@@ -1082,10 +1083,10 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                LED_B_OFF();\r
                LED_C_OFF();\r
        \r
-               SpinDelay(300);\r
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-               SpinDelay(100);\r
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
+               // SpinDelay(300);\r
+               // FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               // SpinDelay(100);\r
+               // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
        }\r
 \r
        while (true) {\r
index 0d8de438a71eec2ffa95167a4fa7b33ac75db058..56166777bc62d6e2806546c0b1ed22211cf0351d 100644 (file)
@@ -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;
        }
index 0ba04b794218b068daf347fd3c445c3c135ae504..b2c68b9747b87f2ac5ffc01b3ee2c269fcb72d5f 100644 (file)
@@ -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<bestErrCnt){  //set this as new best run
+          bestErrCnt=errCnt;
+          bestStart = iii;
+        }
+      }
+    }
+    if (iii>=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; idx<size; idx++){
+    if(maxVal<GraphBuffer[idx]) maxVal = GraphBuffer[idx];
+  }
+  // set close to the top of the wave threshold with 13% margin for error
+  // less likely to get a false transition up there. 
+  // (but have to be careful not to go too high and miss some short waves)
+  uint32_t threshold_value = (uint32_t)(maxVal*.87);
+  idx=1;
+  // int threshold_value = 100;
+  
+  // sync to first lo-hi transition, and threshold
+  //  PrintAndLog("FSK init complete size: %d",size);//debug
+  // Need to threshold first sample
+  if(GraphBuffer[0] < threshold_value) GraphBuffer[0] = 0;
+  else GraphBuffer[0] = 1;
+  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 
+    if (GraphBuffer[idx] < threshold_value) GraphBuffer[idx] = 0;
+    else GraphBuffer[idx] = 1;
+    // Check for 0->1 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; n2<n; n2++){
+          GraphBuffer[numBits+n2]=GraphBuffer[idx-1];
+        }
+        //memset(GraphBuffer+numBits, GraphBuffer[idx-1] , n);
+      }else{        // invert bits
+        for (n2=0; n2<n; n2++){
+          GraphBuffer[numBits+n2]=GraphBuffer[idx-1]^1;
+        }
+        //memset(GraphBuffer+numBits, GraphBuffer[idx-1]^1 , n);  
+      }      
+      numBits += n;
+    }
+    n=0;
+    lastval=GraphBuffer[idx];
+  }//end for
+  return numBits;
+}
+
+//by marshmellow  (from holiman's base)
+// full fsk demod from GraphBuffer wave to decoded 1s and 0s (no mandemod)
+size_t fskdemod(uint8_t rfLen, uint8_t invert)
+{
+  //uint8_t h2l_crossing_value = 6;
+  //uint8_t l2h_crossing_value = 5;
+  
+  // if (rfLen==64)  //currently only know settings for RF/64 change from default if option entered
+  // {
+  //   h2l_crossing_value=8;  //or 8  as 64/8 = 8
+  //   l2h_crossing_value=6;  //or 6.4 as 64/10 = 6.4
+  // }
+  size_t size  = GraphTraceLen; 
+    // FSK demodulator
+  size = fsk_wave_demod(size);
+  size = aggregate_bits(size,rfLen,192,invert);
+ // size = aggregate_bits(size, h2l_crossing_value, l2h_crossing_value,192, invert); //192=no limit to same values
+  //done messing with GraphBuffer - repaint
+  RepaintGraphWindow();
+  return size;
+}
+uint32_t bytebits_to_byte(int* src, int numbits)
+{
+  uint32_t num = 0;
+  for(int i = 0 ; i < numbits ; i++)
+  {
+    num = (num << 1) | (*src);
+    src++;
+  }
+  return num;
+}
+
+//by marshmellow
+//fsk demod and print binary
+int CmdFSKrawdemod(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;
+  //set options from parameters entered with the command
+  if (strlen(Cmd)>0 && 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 (testMax<GraphBuffer[idx]) testMax=GraphBuffer[idx];
+  }
+  idx=0;
+  //get full binary from fsk wave
+  size_t size = fskdemod(rfLen,invert); 
+  //if not just noise
+  //PrintAndLog("testMax %d",testMax);
+  if (testMax>40){
+    //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, "<window length> -- 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, "<thres up> <thres down> -- 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, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
   {"hexsamples",    CmdHexsamples,      0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},  
   {"hide",          CmdHide,            1, "Hide graph window"},
index 8073c34cbcc821473da36ebd96ebbed1d1b477ad..432ae68750cf6f7490522400f45c0490f55fee37 100644 (file)
@@ -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);
index bfa7bfbfdc91ddf34099e588e351c66eaeb8edd9..f09c555b96e1c2d8c4c863fa794bac47ee32e508 100644 (file)
@@ -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;
index 748e9c45fbf4e5a42af13c1d2cf0c31ff49c06a1..f32ae444f077271a41ec6f96030b1e16b1154be4 100644 (file)
@@ -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));\r
        PrintAndLog("--data: %s", sprint_hex(bldata, 16));\r
        \r
-  UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};\r
+       UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};\r
        memcpy(c.d.asBytes, key, 6);\r
        memcpy(c.d.asBytes + 10, bldata, 16);\r
-  SendCommand(&c);\r
+       SendCommand(&c);\r
 \r
        UsbCommand resp;\r
        if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
@@ -168,9 +168,9 @@ int CmdHF14AMfRdBl(const char *Cmd)
        }\r
        PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6));\r
        \r
-  UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};\r
+       UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};\r
        memcpy(c.d.asBytes, key, 6);\r
-  SendCommand(&c);\r
+       SendCommand(&c);\r
 \r
        UsbCommand resp;\r
        if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
@@ -1460,11 +1460,12 @@ int CmdHF14AMfCSetUID(const char *Cmd)
 \r
        res = mfCSetUID(uid, oldUid, wipeCard);\r
        if (res) {\r
-                       PrintAndLog("Can't set UID. error=%d", res);\r
-                       return 1;\r
-               }\r
+               PrintAndLog("Can't set UID. error=%d", res);\r
+               return 1;\r
+       }\r
        \r
        PrintAndLog("old UID:%s", sprint_hex(oldUid, 4));\r
+       PrintAndLog("new UID:%s", sprint_hex(uid, 4));\r
        return 0;\r
 }\r
 \r
index faf95ccdfe25b4054ffb1e43f5363ae3c1a4acd2..97dcf0bae25a5c2ab26aa3f82ac50cd2c351e3b7 100644 (file)
@@ -371,6 +371,9 @@ int CmdLFRead(const char *Cmd)
   }
   SendCommand(&c);
   WaitForResponse(CMD_ACK,NULL);
+  
+  // load samples 
+  CmdSamples("");
   return 0;
 }
 
index 0e1fca8ed44fe1384bb75d3fc7513dfa48d5d2a8..71f227f24f4ac2ea768ae52375ac139052a564c6 100644 (file)
@@ -10,6 +10,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <inttypes.h>
+#include <stdbool.h>
 #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;
 }
index cb1cd9e213017e04455d94407aa89ee65ff5b3e6..7c23d567a587c4c829c58b3b82f5a3b90c4c1b8d 100644 (file)
@@ -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
index ce21ddc8d9f3b0fa97e21da7207acf8034b0d803..93d06406851c581ed8e35e55786c76ee50b5157c 100644 (file)
@@ -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);
index 78d8fa213a9d63d12c6a7542fe4ca6af5a13db62..129323aca9ed423ac3f4c41f85a244322a2b7752 100644 (file)
@@ -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;
index 7b45f3f2f1cf00d1df8bf1295fdb04d0dafd79b2..bb8159951b2eb8c4637b5a0664f3fbb33d690ed3 100644 (file)
@@ -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;i<GraphTraceLen;++i){
+      if(GraphBuffer[i]>peak){
+        peak = GraphBuffer[i]; 
+      }
+      if(GraphBuffer[i]<low){
+        low = GraphBuffer[i];
+      }
+    }
+    peak=(int)(peak*.75);
+    low= (int)(low*.75);
+  }
+  //int numbits;
+  int ii;
+  int loopCnt = 256;
+  if (GraphTraceLen<loopCnt) loopCnt = GraphTraceLen;
+  int clkCnt;
+  int tol = 0;
+  int bestErr=1000;
+  int errCnt[]={0,0,0,0,0,0,0,0};
+ // int good;
+  for(clkCnt=0; clkCnt<6;++clkCnt){
+    if (clk[clkCnt]==32){
+      tol=1;
+    }else{
+      tol=0;
+    }
+    bestErr=1000;
+    for (ii=0; ii<loopCnt; ++ii){
+      if ((GraphBuffer[ii]>=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]<bestErr) bestErr=errCnt[clkCnt];
+      }
+    } 
+    errCnt[clkCnt]=bestErr;
+  }
+  int iii=0;
+  int best=0;
+  for (iii=0; iii<6;++iii){
+    if (errCnt[iii]<errCnt[best]){
+      best = iii;
+    }
+  }
+  PrintAndLog("clkCnt: %d, ii: %d, i: %d peak: %d, low: %d, errcnt: %d, errCnt64: %d",clkCnt,ii,i,peak,low,errCnt[best],errCnt[4]);
+  return clk[best];
 }
+               
 
 /* Get or auto-detect clock rate */
 int GetClock(const char *str, int peak, int verbose)
@@ -109,6 +165,7 @@ int GetClock(const char *str, int peak, int verbose)
   if (!clock)
   {
     clock = DetectClock(peak);
+    //clock2 = DetectClock2(peak);
     /* Only print this message if we're not looping something */
     if (!verbose)
       PrintAndLog("Auto-detected clock rate: %d", clock);
index 8874519504a79380d6b58acc1d19e1ea14343172..41ea1030517d7319f166914ea5e3673fa10e9acb 100644 (file)
@@ -232,8 +232,7 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
 // "MAGIC" CARD\r
 \r
 int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {\r
-       uint8_t block0[16];\r
-       memset(block0, 0, 16);\r
+       uint8_t block0[16] = {0x00};\r
        memcpy(block0, uid, 4); \r
        block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC\r
        // mifare classic SAK(byte 5) and ATQA(byte 6 and 7)\r
@@ -245,13 +244,13 @@ int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {
 }\r
 \r
 int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params) {\r
-       uint8_t isOK = 0;\r
 \r
+       uint8_t isOK = 0;\r
        UsbCommand c = {CMD_MIFARE_EML_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};\r
        memcpy(c.d.asBytes, data, 16); \r
        SendCommand(&c);\r
 \r
-  UsbCommand resp;\r
+       UsbCommand resp;\r
        if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
                isOK  = resp.arg[0] & 0xff;\r
                if (uid != NULL) memcpy(uid, resp.d.asBytes, 4);\r
@@ -341,12 +340,14 @@ int loadTraceCard(uint8_t *tuid) {
                memset(buf, 0, sizeof(buf));\r
                if (fgets(buf, sizeof(buf), f) == NULL) {\r
       PrintAndLog("File reading error.");\r
+                       fclose(f);\r
                        return 2;\r
     }\r
 \r
                if (strlen(buf) < 32){\r
                        if (feof(f)) break;\r
                        PrintAndLog("File content error. Block data must include 32 HEX symbols");\r
+                       fclose(f);\r
                        return 2;\r
                }\r
                for (i = 0; i < 32; i += 2)\r
index f7c5e35c3b0d7ad0a04c950c0ab55d328712933b..4b2fee994f533d0044c729f36ce01690c113a8aa 100644 (file)
@@ -73,6 +73,7 @@ serial_port uart_open(const char* pcPortName)
   // Does the system allows us to place a lock on this file descriptor
   if (fcntl(sp->fd, F_SETLK, &fl) == -1) {
     // A conflicting lock is held by another process
+    free(sp);
     return CLAIMED_SERIAL_PORT;
   }
 
index 0418dd98f9f6c4c35f7cc50962766e092011c6e2..b8d5c316cf9bce03cfd4faab842d4ad1e0185423 100644 (file)
@@ -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);
 }
index 10bafba98b75878d339e3755de1a257a0f1fae69..22d41e0c8f3b8807c13dd918b15adfe07494a97a 100644 (file)
@@ -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);
 
Impressum, Datenschutz