]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
EM4x05/EM4x69 continued + a couple of icemans utils.
authormarshmellow42 <marshmellowrf@gmail.com>
Thu, 16 Feb 2017 04:27:15 +0000 (23:27 -0500)
committermarshmellow42 <marshmellowrf@gmail.com>
Thu, 16 Feb 2017 04:27:15 +0000 (23:27 -0500)
client/cmdlfem4x.c
client/util.c
client/util.h
common/lfdemod.c

index 820b24e9a499b8bdfad20bdfe7338558195edea6..7d8d2931aa0ea186d88898a6f1f34530c3e4e4a6 100644 (file)
@@ -533,6 +533,9 @@ uint8_t EMpreambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, siz
        return 0;
 }
 
+// FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE 
+// should cover 90% of known used configs
+// the rest will need to be manually demoded for now...
 int demodEM4x05resp(uint8_t bitsNeeded) {
        int ans = 0;
        bool demodFound = false;
@@ -546,7 +549,6 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
                ans = FSKrawDemod("0 0", false);
                if (!ans) {
                        if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: FSK Demod failed");
-                       //return -1;
                } else {
                        // set size to 10 to only test first 4 positions for the preamble
                        size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10;
@@ -557,7 +559,6 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
                        uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx);
                        if ( errChk == 0) {
                                if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx);
-                               //return -1;
                        } else {
                                //can't test size because the preamble doesn't repeat :(
                                //meaning chances of false positives are high.
@@ -565,10 +566,37 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
                        }
                }
        }
+       // PSK clocks should be easy to detect ( but difficult to demod a non-repeating pattern... )
+       if (!demodFound) {
+               ans = GetPskClock("", FALSE, FALSE);
+               if (ans>0) {
+                       PrintAndLog("PSK response possibly found, run `data rawd p1` to attempt to demod");
+               }
+       }
 
-       ans = GetPskClock("", FALSE, FALSE);
-       if (ans>0) {
-               PrintAndLog("PSK response possibly found, run `data rawd p1` to attempt to demod");
+       // more common than biphase
+       if (!demodFound) {
+               DemodBufferLen = 0x00;
+               // try manchester - NOTE: ST only applies to T55x7 tags.
+               ans = ASKDemod_ext("0,0,1", false, false, 1, false);
+               if (!ans) {
+                       if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/Manchester Demod failed");
+               } else {
+                       // set size to 10 to only test first 4 positions for the preamble
+                       size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10;
+                       size_t startIdx = 0; 
+
+                       if (g_debugMode) PrintAndLog("ANS: %d | %u | %u", ans, startIdx, size);
+
+                       uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx);
+                       if ( errChk == 0) {
+                               if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx);
+                       } else {
+                               //can't test size because the preamble doesn't repeat :(
+                               //meaning chances of false positives are high.
+                               demodFound = true;
+                       }
+               }
        }
 
        if (!demodFound) {
@@ -577,7 +605,6 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
                ans = ASKbiphaseDemod("0 0 1", FALSE);
                if (!ans) { 
                        if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/biphase Demod failed");
-                       //return -1;
                } else {
                        // set size to 10 to only test first 4 positions for the preamble
                        size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10;
@@ -588,7 +615,6 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
                        uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx);
                        if ( errChk == 0) {
                                if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx);
-                               //return -1;
                        } else {
                                //can't test size because the preamble doesn't repeat :(
                                //meaning chances of false positives are high.
@@ -599,11 +625,10 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
 
        if (!demodFound) {
                DemodBufferLen = 0x00;
-               // try manchester - NOTE: ST only applies to T55x7 tags.
-               ans = ASKDemod_ext("0,0,1", false, false, 1, false);
-               if (!ans) {
-                       if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/Manchester Demod failed");
-                       //return -1;
+               //try diphase (differential biphase or inverted)
+               ans = ASKbiphaseDemod("0 1 1", FALSE);
+               if (!ans) { 
+                       if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/biphase Demod failed");
                } else {
                        // set size to 10 to only test first 4 positions for the preamble
                        size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10;
@@ -614,7 +639,6 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
                        uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx);
                        if ( errChk == 0) {
                                if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx);
-                               //return -1;
                        } else {
                                //can't test size because the preamble doesn't repeat :(
                                //meaning chances of false positives are high.
@@ -624,8 +648,10 @@ int demodEM4x05resp(uint8_t bitsNeeded) {
        }
 
        if (demodFound && bitsNeeded < DemodBufferLen) {
-               setDemodBuf(DemodBuffer + ans + sizeof(preamble), bitsNeeded, 0);
-               CmdPrintDemodBuff("x");
+               if (bitsNeeded > 0) {
+                       setDemodBuf(DemodBuffer + ans + sizeof(preamble), bitsNeeded, 0);
+                       CmdPrintDemodBuff("x");                 
+               }
                return 1;
        }
        return -1;
@@ -673,10 +699,9 @@ int CmdReadWord(const char *Cmd) {
                return -1;
        }
 
-       //need 32 bits for read word
-       demodEM4x05resp(32);
-
-       return 1;
+       //attempt demod:
+       //need 32 bits from a read word
+       return demodEM4x05resp(32);
 }
 
 int usage_lf_em_write(void) {
@@ -693,6 +718,7 @@ int usage_lf_em_write(void) {
        PrintAndLog("      lf em writeword 1 deadc0de 11223344");
        return 0;
 }
+
 int CmdWriteWord(const char *Cmd) {
        uint8_t ctmp = param_getchar(Cmd, 0);
        if ( strlen(Cmd) == 0 || ctmp == 'H' || ctmp == 'h' ) return usage_lf_em_write();
@@ -738,7 +764,14 @@ int CmdWriteWord(const char *Cmd) {
        }
        setGraphBuf(got, sizeof(got));
        //todo: check response for 00001010 then write data for write confirmation!
-       return 0;
+       
+       //attempt demod:
+       //need 0 bits demoded (after preamble) to verify write cmd
+       int result = demodEM4x05resp(0);
+       if (result == 1) {
+               PrintAndLog("Write Verified");
+       }
+       return result;
 }
 
 /*
index e4add6c09e0112390ce332f2d7052ea56899973c..374ae397a3415d9b8c916cc3573357c36193e89c 100644 (file)
@@ -110,6 +110,23 @@ void print_hex(const uint8_t * data, const size_t len)
        printf("\n");
 }
 
+void print_hex_break(const uint8_t *data, const size_t len, uint8_t breaks) {
+
+       int rownum = 0;
+       printf("[%02d] | ", rownum);
+       for (int i = 0; i < len; ++i) {
+
+               printf("%02X ", data[i]);
+               
+               // check if a line break is needed
+               if ( breaks > 0 && !((i+1) % breaks) && (i+1 < len) ) {
+                       ++rownum;
+                       printf("\n[%02d] | ", rownum);
+               }
+       }
+       printf("\n");
+}
+
 char *sprint_hex(const uint8_t *data, const size_t len) {
        
        int maxLen = ( len > 1024/3) ? 1024/3 : len;
@@ -139,7 +156,7 @@ char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t brea
 
        size_t in_index = 0;
        // loop through the out_index to make sure we don't go too far
-       for (size_t out_index=0; out_index < max_len; out_index++) {
+       for (size_t out_index=0; out_index < max_len-1; out_index++) {
                // set character - (should be binary but verify it isn't more than 1 digit)
                if (data[in_index]<10)
                        sprintf(tmp++, "%u", (unsigned int) data[in_index]);
@@ -158,6 +175,41 @@ char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t brea
 char *sprint_bin(const uint8_t *data, const size_t len) {
        return sprint_bin_break(data, len, 0);
 }
+
+char *sprint_hex_ascii(const uint8_t *data, const size_t len) {
+       static char buf[1024];
+       char *tmp = buf;
+       memset(buf, 0x00, 1024);
+       size_t max_len = (len > 1010) ? 1010 : len;
+
+       sprintf(tmp, "%s| ", sprint_hex(data, max_len) );
+       
+       size_t i = 0;
+       size_t pos = (max_len * 3)+2;
+       while(i < max_len){
+               char c = data[i];
+               if ( (c < 32) || (c == 127))
+                       c = '.';
+               sprintf(tmp+pos+i, "%c",  c);
+               ++i;
+       }
+       return buf;
+}
+
+char *sprint_ascii(const uint8_t *data, const size_t len) {
+       static char buf[1024];
+       char *tmp = buf;
+       memset(buf, 0x00, 1024);
+       size_t max_len = (len > 1010) ? 1010 : len;
+       size_t i = 0;
+       while(i < max_len){
+               char c = data[i];
+               tmp[i] = ((c < 32) || (c == 127)) ? '.' : c;
+               ++i;
+       }
+       return buf;
+}
+
 void num_to_bytes(uint64_t n, size_t len, uint8_t* dest)
 {
        while (len--) {
@@ -184,6 +236,15 @@ void num_to_bytebits(uint64_t      n, size_t len, uint8_t *dest) {
        }
 }
 
+//least significant bit first
+void num_to_bytebitsLSBF(uint64_t n, size_t len, uint8_t *dest) {
+       for(int i = 0 ; i < len ; ++i) {
+               dest[i] =  n & 1;
+               n >>= 1;
+       }
+}
+
+
 // aa,bb,cc,dd,ee,ff,gg,hh, ii,jj,kk,ll,mm,nn,oo,pp
 // to
 // hh,gg,ff,ee,dd,cc,bb,aa, pp,oo,nn,mm,ll,kk,jj,ii
@@ -200,6 +261,16 @@ uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockS
        return tmp;
 }
 
+// takes a uint8_t src array, for len items and reverses the byte order in blocksizes (8,16,32,64), 
+// returns: the dest array contains the reordered src array.
+void SwapEndian64ex(const uint8_t *src, const size_t len, const uint8_t blockSize, uint8_t *dest){
+       for (uint8_t block=0; block < (uint8_t)(len/blockSize); block++){
+               for (size_t i = 0; i < blockSize; i++){
+                       dest[i+(blockSize*block)] = src[(blockSize-1-i)+(blockSize*block)];
+               }
+       }
+}
+
 //assumes little endian
 char * printBits(size_t const size, void const * const ptr)
 {
@@ -332,8 +403,6 @@ uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base)
                return strtoull(&line[bg], NULL, base);
        else
                return deflt;
-
-       return 0;
 }
 
 int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt)
@@ -490,6 +559,7 @@ void wiegand_add_parity(uint8_t *target, uint8_t *source, uint8_t length)
     *(target)= GetParity(source + length / 2, ODD, length / 2);
 }
 
+// xor two arrays together for len items.  The dst array contains the new xored values.
 void xor(unsigned char *dst, unsigned char *src, size_t len) {
    for( ; len > 0; len--,dst++,src++)
        *dst ^= *src;
index 1b6b2fb1d1435e5702b89f5dc861df111711c8aa..8c0ed950db3f38df1600aad2ca281fa3ad876148 100644 (file)
@@ -13,7 +13,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include <time.h>
+#include <time.h>    //time, gmtime
 #include "data.h"    //for FILE_PATH_SIZE
 
 #ifndef ROTR
@@ -42,12 +42,16 @@ void print_hex(const uint8_t * data, const size_t len);
 char * sprint_hex(const uint8_t * data, const size_t len);
 char * sprint_bin(const uint8_t * data, const size_t len);
 char * sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks);
+char * sprint_hex_ascii(const uint8_t *data, const size_t len);
+char * sprint_ascii(const uint8_t *data, const size_t len);
 
 void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
 uint64_t bytes_to_num(uint8_t* src, size_t len);
 void num_to_bytebits(uint64_t  n, size_t len, uint8_t *dest);
+void num_to_bytebitsLSBF(uint64_t n, size_t len, uint8_t *dest);
 char * printBits(size_t const size, void const * const ptr);
 uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);
+void SwapEndian64ex(const uint8_t *src, const size_t len, const uint8_t blockSize, uint8_t *dest);
 
 char param_getchar(const char *line, int paramnum);
 int param_getptr(const char *line, int *bg, int *en, int paramnum);
index 8324c440f4c19f918159215ff6dc94b397596f80..6c09c9ee5ed4a5cd7bf133da14baea8039457bb5 100644 (file)
@@ -148,6 +148,9 @@ uint32_t bytebits_to_byteLSBF(uint8_t *src, size_t numbits)
 //search for given preamble in given BitStream and return success=1 or fail=0 and startIndex and length
 uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx)
 {
+       // Sanity check.  If preamble length is bigger than bitstream length.
+       if ( *size <= pLen ) return 0;
+
        uint8_t foundCnt=0;
        for (int idx=0; idx < *size - pLen; idx++){
                if (memcmp(BitStream+idx, preamble, pLen) == 0){
Impressum, Datenschutz