1 //----------------------------------------------------------------------------- 
   2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com> 
   4 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   5 // at your option, any later version. See the LICENSE.txt file for the text of 
   7 //----------------------------------------------------------------------------- 
   8 // Low frequency EM4x commands 
   9 //----------------------------------------------------------------------------- 
  14 #include "cmdlfem4x.h" 
  15 #include "proxmark3.h" 
  20 #include "cmdparser.h" 
  25 #include "protocols.h" 
  26 #include "util_posix.h" 
  28 uint64_t g_em410xId
=0; 
  30 static int CmdHelp(const char *Cmd
); 
  31 void ConstructEM410xEmulGraph(const char *uid
,const  uint8_t clock
); 
  33 int CmdEMdemodASK(const char *Cmd
) 
  35         char cmdp 
= param_getchar(Cmd
, 0); 
  36         int findone 
= (cmdp 
== '1') ? 1 : 0; 
  37         UsbCommand c
={CMD_EM410X_DEMOD
}; 
  44 //print 64 bit EM410x ID in multiple formats 
  45 void printEM410x(uint32_t hi
, uint64_t id
) 
  52                 for (ii
=5; ii
>0;ii
--){ 
  54                                 id2lo
=(id2lo
<<1LL) | ((id 
& (iii 
<< (i
+((ii
-1)*8)))) >> (i
+((ii
-1)*8))); 
  59                         PrintAndLog("\nEM TAG ID      : %06X%016" PRIX64
, hi
, id
); 
  62                         PrintAndLog("\nEM TAG ID      : %010" PRIX64
, id
); 
  63                         PrintAndLog("\nPossible de-scramble patterns"); 
  64                         PrintAndLog("Unique TAG ID  : %010" PRIX64
,  id2lo
); 
  65                         PrintAndLog("HoneyWell IdentKey {"); 
  66                         PrintAndLog("DEZ 8          : %08" PRIu64
,id 
& 0xFFFFFF); 
  67                         PrintAndLog("DEZ 10         : %010" PRIu64
,id 
& 0xFFFFFFFF); 
  68                         PrintAndLog("DEZ 5.5        : %05lld.%05" PRIu64
,(id
>>16LL) & 0xFFFF,(id 
& 0xFFFF)); 
  69                         PrintAndLog("DEZ 3.5A       : %03lld.%05" PRIu64
,(id
>>32ll),(id 
& 0xFFFF)); 
  70                         PrintAndLog("DEZ 3.5B       : %03lld.%05" PRIu64
,(id 
& 0xFF000000) >> 24,(id 
& 0xFFFF)); 
  71                         PrintAndLog("DEZ 3.5C       : %03lld.%05" PRIu64
,(id 
& 0xFF0000) >> 16,(id 
& 0xFFFF)); 
  72                         PrintAndLog("DEZ 14/IK2     : %014" PRIu64
,id
); 
  73                         PrintAndLog("DEZ 15/IK3     : %015" PRIu64
,id2lo
); 
  74                         PrintAndLog("DEZ 20/ZK      : %02" PRIu64 
"%02" PRIu64 
"%02" PRIu64 
"%02" PRIu64 
"%02" PRIu64 
"%02" PRIu64 
"%02" PRIu64 
"%02" PRIu64 
"%02" PRIu64 
"%02" PRIu64
, 
  75                             (id2lo 
& 0xf000000000) >> 36, 
  76                             (id2lo 
& 0x0f00000000) >> 32, 
  77                             (id2lo 
& 0x00f0000000) >> 28, 
  78                             (id2lo 
& 0x000f000000) >> 24, 
  79                             (id2lo 
& 0x0000f00000) >> 20, 
  80                             (id2lo 
& 0x00000f0000) >> 16, 
  81                             (id2lo 
& 0x000000f000) >> 12, 
  82                             (id2lo 
& 0x0000000f00) >> 8, 
  83                             (id2lo 
& 0x00000000f0) >> 4, 
  84                             (id2lo 
& 0x000000000f) 
  86                         uint64_t paxton 
= (((id
>>32) << 24) | (id 
& 0xffffff))  + 0x143e00; 
  87                         PrintAndLog("}\nOther          : %05" PRIu64 
"_%03" PRIu64 
"_%08" PRIu64 
"",(id
&0xFFFF),((id
>>16LL) & 0xFF),(id 
& 0xFFFFFF)); 
  88                         PrintAndLog("Pattern Paxton : %" PRIu64 
" [0x%" PRIX64 
"]", paxton
, paxton
); 
  90                         uint32_t p1id 
= (id 
& 0xFFFFFF); 
  91                         uint8_t arr
[32] = {0x00}; 
  94                         for (; i 
< 24; ++i
, --j 
){ 
  95                                 arr
[i
] = (p1id 
>> i
) & 1; 
 129                         PrintAndLog("Pattern 1      : %d [0x%X]", p1
, p1
); 
 131                         uint16_t sebury1 
= id 
& 0xFFFF; 
 132                         uint8_t  sebury2 
= (id 
>> 16) & 0x7F; 
 133                         uint32_t sebury3 
= id 
& 0x7FFFFF; 
 134                         PrintAndLog("Pattern Sebury : %d %d %d  [0x%X 0x%X 0x%X]", sebury1
, sebury2
, sebury3
, sebury1
, sebury2
, sebury3
); 
 140 /* Read the ID of an EM410x tag. 
 142  *   1111 1111 1           <-- standard non-repeatable header 
 143  *   XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID 
 145  *   CCCC                  <-- each bit here is parity for the 10 bits above in corresponding column 
 146  *   0                     <-- stop bit, end of tag 
 148 int AskEm410xDecode(bool verbose
, uint32_t *hi
, uint64_t *lo 
) 
 151         uint8_t BitStream
[512]={0}; 
 152         size_t BitLen 
= sizeof(BitStream
); 
 153         if ( !getDemodBuf(BitStream
, &BitLen
) ) return 0; 
 155         if (Em410xDecode(BitStream
, &BitLen
, &idx
, hi
, lo
)) { 
 156                 //set GraphBuffer for clone or sim command 
 157                 setDemodBuf(DemodBuffer
, (BitLen
==40) ? 64 : 128, idx
+1); 
 158                 setClockGrid(g_DemodClock
, g_DemodStartIdx 
+ ((idx
+1)*g_DemodClock
)); 
 161                         PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx
, BitLen
); 
 165                         PrintAndLog("EM410x pattern found: "); 
 166                         printEM410x(*hi
, *lo
); 
 174 //askdemod then call Em410xdecode 
 175 int AskEm410xDemod(const char *Cmd
, uint32_t *hi
, uint64_t *lo
, bool verbose
) 
 178         if (!ASKDemod_ext(Cmd
, false, false, 1, &st
)) return 0; 
 179         return AskEm410xDecode(verbose
, hi
, lo
); 
 183 //takes 3 arguments - clock, invert and maxErr as integers 
 184 //attempts to demodulate ask while decoding manchester 
 185 //prints binary found and saves in graphbuffer for further commands 
 186 int CmdAskEM410xDemod(const char *Cmd
) 
 188         char cmdp 
= param_getchar(Cmd
, 0); 
 189         if (strlen(Cmd
) > 10 || cmdp 
== 'h' || cmdp 
== 'H') { 
 190                 PrintAndLog("Usage:  lf em 410xdemod [clock] <0|1> [maxError]"); 
 191                 PrintAndLog("     [set clock as integer] optional, if not set, autodetect."); 
 192                 PrintAndLog("     <invert>, 1 for invert output"); 
 193                 PrintAndLog("     [set maximum allowed errors], default = 100."); 
 195                 PrintAndLog("    sample: lf em 410xdemod        = demod an EM410x Tag ID from GraphBuffer"); 
 196                 PrintAndLog("          : lf em 410xdemod 32     = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32"); 
 197                 PrintAndLog("          : lf em 410xdemod 32 1   = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data"); 
 198                 PrintAndLog("          : lf em 410xdemod 1      = demod an EM410x Tag ID from GraphBuffer while inverting data"); 
 199                 PrintAndLog("          : lf em 410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors"); 
 204         return AskEm410xDemod(Cmd
, &hi
, &lo
, true); 
 207 int usage_lf_em410x_sim(void) { 
 208         PrintAndLog("Simulating EM410x tag"); 
 210         PrintAndLog("Usage:  lf em 410xsim [h] <uid> <clock>"); 
 211         PrintAndLog("Options:"); 
 212         PrintAndLog("       h         - this help"); 
 213         PrintAndLog("       uid       - uid (10 HEX symbols)"); 
 214         PrintAndLog("       clock     - clock (32|64) (optional)"); 
 215         PrintAndLog("samples:"); 
 216         PrintAndLog("      lf em 410xsim 0F0368568B"); 
 217         PrintAndLog("      lf em 410xsim 0F0368568B 32"); 
 221 // Construct the graph for emulating an EM410X tag 
 222 void ConstructEM410xEmulGraph(const char *uid
,const  uint8_t clock
) 
 224         int i
, n
, j
, binary
[4], parity
[4]; 
 225         /* clear our graph */ 
 228         /* write 9 start bits */ 
 229         for (i 
= 0; i 
< 9; i
++) 
 230                 AppendGraph(0, clock
, 1); 
 232         /* for each hex char */ 
 233         parity
[0] = parity
[1] = parity
[2] = parity
[3] = 0; 
 234         for (i 
= 0; i 
< 10; i
++){ 
 235                 /* read each hex char */ 
 236                 sscanf(&uid
[i
], "%1x", &n
); 
 237                 for (j 
= 3; j 
>= 0; j
--, n
/= 2) 
 240                 /* append each bit */ 
 241                 AppendGraph(0, clock
, binary
[0]); 
 242                 AppendGraph(0, clock
, binary
[1]); 
 243                 AppendGraph(0, clock
, binary
[2]); 
 244                 AppendGraph(0, clock
, binary
[3]); 
 246                 /* append parity bit */ 
 247                 AppendGraph(0, clock
, binary
[0] ^ binary
[1] ^ binary
[2] ^ binary
[3]); 
 249                 /* keep track of column parity */ 
 250                 parity
[0] ^= binary
[0]; 
 251                 parity
[1] ^= binary
[1]; 
 252                 parity
[2] ^= binary
[2]; 
 253                 parity
[3] ^= binary
[3]; 
 257         AppendGraph(0, clock
, parity
[0]); 
 258         AppendGraph(0, clock
, parity
[1]); 
 259         AppendGraph(0, clock
, parity
[2]); 
 260         AppendGraph(0, clock
, parity
[3]); 
 263         AppendGraph(1, clock
, 0); 
 266 // emulate an EM410X tag 
 267 int CmdEM410xSim(const char *Cmd
) 
 269         char cmdp 
= param_getchar(Cmd
, 0); 
 270         uint8_t uid
[5] = {0x00}; 
 272         if (cmdp 
== 'h' || cmdp 
== 'H') return usage_lf_em410x_sim(); 
 273         /* clock is 64 in EM410x tags */ 
 276         if (param_gethex(Cmd
, 0, uid
, 10)) { 
 277                 PrintAndLog("UID must include 10 HEX symbols"); 
 280         param_getdec(Cmd
,1, &clock
); 
 282         PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X  clock: %d", uid
[0],uid
[1],uid
[2],uid
[3],uid
[4],clock
); 
 283         PrintAndLog("Press pm3-button to abort simulation"); 
 285         ConstructEM410xEmulGraph(Cmd
, clock
); 
 287         CmdLFSim("0"); //240 start_gap. 
 291 int usage_lf_em410x_brute(void) { 
 292                 PrintAndLog("Bruteforcing by emulating EM410x tag"); 
 294                 PrintAndLog("Usage:  lf em 410xbrute [h] ids.txt [d 2000] [clock]"); 
 295                 PrintAndLog("Options:"); 
 296                 PrintAndLog("       h             - this help"); 
 297                 PrintAndLog("       ids.txt       - file with UIDs in HEX format, one per line"); 
 298                 PrintAndLog("       d (2000)      - pause delay in milliseconds between UIDs simulation, default 1000 ms (optional)"); 
 299                 PrintAndLog("       c (32)        - clock (32|64), default 64 (optional)"); 
 300                 PrintAndLog("samples:"); 
 301                 PrintAndLog("      lf em 410xbrute ids.txt"); 
 302                 PrintAndLog("      lf em 410xbrute ids.txt c 32"); 
 303                 PrintAndLog("      lf em 410xbrute ids.txt d 3000"); 
 304                 PrintAndLog("      lf em 410xbrute ids.txt d 3000 32"); 
 308 int CmdEM410xBrute(const char *Cmd
) 
 310         char filename
[FILE_PATH_SIZE
]={0}; 
 314         uint8_t stUidBlock 
= 20; 
 315         uint8_t *uidBlock 
= NULL
, *p 
= NULL
; 
 317         uint8_t uid
[5] = {0x00}; 
 318         /* clock is 64 in EM410x tags */ 
 320         /* default pause time: 1 second */ 
 321         uint32_t delay 
= 1000; 
 323         char cmdp 
= param_getchar(Cmd
, 0); 
 325         if (cmdp 
== 'h' || cmdp 
== 'H') return usage_lf_em410x_brute(); 
 328         cmdp 
= param_getchar(Cmd
, 1); 
 330         if (cmdp 
== 'd' || cmdp 
== 'D') { 
 331                 delay 
= param_get32ex(Cmd
, 2, 1000, 10); 
 332                 param_getdec(Cmd
, 4, &clock
); 
 333         } else if (cmdp 
== 'c' || cmdp 
== 'C') { 
 334                 param_getdec(Cmd
, 2, &clock
); 
 335                 delay 
= param_get32ex(Cmd
, 4, 1000, 10); 
 338         param_getstr(Cmd
, 0, filename
); 
 340         uidBlock 
= calloc(stUidBlock
, 5); 
 341         if (uidBlock 
== NULL
) return 1; 
 343         if (strlen(filename
) > 0) { 
 344                 if ((f 
= fopen(filename
, "r")) == NULL
) { 
 345                         PrintAndLog("Error: Could not open UIDs file [%s]",filename
); 
 350                 PrintAndLog("Error: Please specify a filename"); 
 355         while( fgets(buf
, sizeof(buf
), f
) ) { 
 356                 if (strlen(buf
) < 10 || buf
[9] == '\n') continue; 
 357                 while (fgetc(f
) != '\n' && !feof(f
));  //goto next line 
 359                 //The line start with # is comment, skip 
 360                 if( buf
[0]=='#' ) continue; 
 362                 if (param_gethex(buf
, 0, uid
, 10)) { 
 363                         PrintAndLog("UIDs must include 10 HEX symbols"); 
 371                 if ( stUidBlock 
- uidcnt 
< 2) { 
 372                                 p 
= realloc(uidBlock
, 5*(stUidBlock
+=10)); 
 374                                         PrintAndLog("Cannot allocate memory for UIDs"); 
 381                 memset(uidBlock 
+ 5 * uidcnt
, 0, 5); 
 382                 num_to_bytes(strtoll(buf
, NULL
, 16), 5, uidBlock 
+ 5*uidcnt
); 
 384                 memset(buf
, 0, sizeof(buf
)); 
 389                 PrintAndLog("No UIDs found in file"); 
 393         PrintAndLog("Loaded %d UIDs from %s, pause delay: %d ms", uidcnt
, filename
, delay
); 
 396         for(uint32_t c 
= 0; c 
< uidcnt
; ++c 
) { 
 403                         printf("\nAborted via keyboard!\n"); 
 408                 sprintf(testuid
, "%010lX", bytes_to_num(uidBlock 
+ 5*c
, 5)); 
 409                 PrintAndLog("Bruteforce %d / %d: simulating UID  %s, clock %d", c 
+ 1, uidcnt
, testuid
, clock
); 
 411                 ConstructEM410xEmulGraph(testuid
, clock
); 
 413                 CmdLFSim("0"); //240 start_gap. 
 423 /* Function is equivalent of lf read + data samples + em410xread 
 424  * looped until an EM410x tag is detected 
 426  * Why is CmdSamples("16000")? 
 427  *  TBD: Auto-grow sample size based on detected sample rate.  IE: If the 
 428  *       rate gets lower, then grow the number of samples 
 429  *  Changed by martin, 4000 x 4 = 16000, 
 430  *  see http://www.proxmark.org/forum/viewtopic.php?pid=7235#p7235 
 432  *  EDIT -- capture enough to get 2 complete preambles at the slowest data rate known to be used (rf/64) (64*64*2+9 = 8201)     marshmellow 
 434 int CmdEM410xWatch(const char *Cmd
) 
 438                         printf("\naborted via keyboard!\n"); 
 442         } while (!CmdAskEM410xDemod("")); 
 447 //currently only supports manchester modulations 
 448 int CmdEM410xWatchnSpoof(const char *Cmd
) 
 451         PrintAndLog("# Replaying captured ID: %010"PRIx64
, g_em410xId
); 
 456 int CmdEM410xWrite(const char *Cmd
) 
 458         uint64_t id 
= 0xFFFFFFFFFFFFFFFF; // invalid id value 
 459         int card 
= 0xFF; // invalid card value 
 460         unsigned int clock 
= 0; // invalid clock value 
 462         sscanf(Cmd
, "%" SCNx64 
" %d %d", &id
, &card
, &clock
); 
 465         if (id 
== 0xFFFFFFFFFFFFFFFF) { 
 466                 PrintAndLog("Error! ID is required.\n"); 
 469         if (id 
>= 0x10000000000) { 
 470                 PrintAndLog("Error! Given EM410x ID is longer than 40 bits.\n"); 
 476                 PrintAndLog("Error! Card type required.\n"); 
 480                 PrintAndLog("Error! Bad card type selected.\n"); 
 489         // Allowed clock rates: 16, 32, 40 and 64 
 490         if ((clock 
!= 16) && (clock 
!= 32) && (clock 
!= 64) && (clock 
!= 40)) { 
 491                 PrintAndLog("Error! Clock rate %d not valid. Supported clock rates are 16, 32, 40 and 64.\n", clock
); 
 496                 PrintAndLog("Writing %s tag with UID 0x%010" PRIx64 
" (clock rate: %d)", "T55x7", id
, clock
); 
 497                 // NOTE: We really should pass the clock in as a separate argument, but to 
 498                 //   provide for backwards-compatibility for older firmware, and to avoid 
 499                 //   having to add another argument to CMD_EM410X_WRITE_TAG, we just store 
 500                 //   the clock rate in bits 8-15 of the card value 
 501                 card 
= (card 
& 0xFF) | ((clock 
<< 8) & 0xFF00); 
 502         }       else if (card 
== 0) { 
 503                 PrintAndLog("Writing %s tag with UID 0x%010" PRIx64
, "T5555", id
, clock
); 
 504                 card 
= (card 
& 0xFF) | ((clock 
<< 8) & 0xFF00); 
 506                 PrintAndLog("Error! Bad card type selected.\n"); 
 510         UsbCommand c 
= {CMD_EM410X_WRITE_TAG
, {card
, (uint32_t)(id 
>> 32), (uint32_t)id
}}; 
 516 //**************** Start of EM4x50 Code ************************ 
 517 bool EM_EndParityTest(uint8_t *BitStream
, size_t size
, uint8_t rows
, uint8_t cols
, uint8_t pType
) 
 519         if (rows
*cols
>size
) return false; 
 521         //assume last col is a parity and do not test 
 522         for (uint8_t colNum 
= 0; colNum 
< cols
-1; colNum
++) { 
 523                 for (uint8_t rowNum 
= 0; rowNum 
< rows
; rowNum
++) { 
 524                         colP 
^= BitStream
[(rowNum
*cols
)+colNum
]; 
 526                 if (colP 
!= pType
) return false; 
 531 bool EM_ByteParityTest(uint8_t *BitStream
, size_t size
, uint8_t rows
, uint8_t cols
, uint8_t pType
) 
 533         if (rows
*cols
>size
) return false; 
 535         //assume last row is a parity row and do not test 
 536         for (uint8_t rowNum 
= 0; rowNum 
< rows
-1; rowNum
++) { 
 537                 for (uint8_t colNum 
= 0; colNum 
< cols
; colNum
++) { 
 538                         rowP 
^= BitStream
[(rowNum
*cols
)+colNum
]; 
 540                 if (rowP 
!= pType
) return false; 
 545 uint32_t OutputEM4x50_Block(uint8_t *BitStream
, size_t size
, bool verbose
, bool pTest
) 
 547         if (size
<45) return 0; 
 548         uint32_t code 
= bytebits_to_byte(BitStream
,8); 
 549         code 
= code
<<8 | bytebits_to_byte(BitStream
+9,8); 
 550         code 
= code
<<8 | bytebits_to_byte(BitStream
+18,8); 
 551         code 
= code
<<8 | bytebits_to_byte(BitStream
+27,8); 
 552         if (verbose 
|| g_debugMode
){ 
 553                 for (uint8_t i 
= 0; i
<5; i
++){ 
 554                         if (i 
== 4) PrintAndLog(""); //parity byte spacer 
 555                         PrintAndLog("%d%d%d%d%d%d%d%d %d -> 0x%02x", 
 565                             bytebits_to_byte(BitStream
+i
*9,8) 
 569                         PrintAndLog("Parity Passed"); 
 571                         PrintAndLog("Parity Failed"); 
 575 /* Read the transmitted data of an EM4x50 tag from the graphbuffer 
 578  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity 
 579  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity 
 580  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity 
 581  *  XXXXXXXX [row parity bit (even)] <- 8 bits plus parity 
 582  *  CCCCCCCC                         <- column parity bits 
 584  *  LW                               <- Listen Window 
 586  * This pattern repeats for every block of data being transmitted. 
 587  * Transmission starts with two Listen Windows (LW - a modulated 
 588  * pattern of 320 cycles each (32/32/128/64/64)). 
 590  * Note that this data may or may not be the UID. It is whatever data 
 591  * is stored in the blocks defined in the control word First and Last 
 592  * Word Read values. UID is stored in block 32. 
 594  //completed by Marshmellow 
 595 int EM4x50Read(const char *Cmd
, bool verbose
) 
 597         uint8_t fndClk
[] = {8,16,32,40,50,64,128}; 
 601         int i
, j
, startblock
, skip
, block
, start
, end
, low
, high
, minClk
; 
 602         bool complete 
= false; 
 603         int tmpbuff
[MAX_GRAPH_TRACE_LEN 
/ 64]; 
 609         memset(tmpbuff
, 0, MAX_GRAPH_TRACE_LEN 
/ 64); 
 611         // get user entry if any 
 612         sscanf(Cmd
, "%i %i", &clk
, &invert
); 
 614         // first get high and low values 
 615         for (i 
= 0; i 
< GraphTraceLen
; i
++) { 
 616                 if (GraphBuffer
[i
] > high
) 
 617                         high 
= GraphBuffer
[i
]; 
 618                 else if (GraphBuffer
[i
] < low
) 
 619                         low 
= GraphBuffer
[i
]; 
 625         // get to first full low to prime loop and skip incomplete first pulse 
 626         while ((GraphBuffer
[i
] < high
) && (i 
< GraphTraceLen
)) 
 628         while ((GraphBuffer
[i
] > low
) && (i 
< GraphTraceLen
)) 
 632         // populate tmpbuff buffer with pulse lengths 
 633         while (i 
< GraphTraceLen
) { 
 634                 // measure from low to low 
 635                 while ((GraphBuffer
[i
] > low
) && (i 
< GraphTraceLen
)) 
 638                 while ((GraphBuffer
[i
] < high
) && (i 
< GraphTraceLen
)) 
 640                 while ((GraphBuffer
[i
] > low
) && (i 
< GraphTraceLen
)) 
 642                 if (j
>=(MAX_GRAPH_TRACE_LEN
/64)) { 
 645                 tmpbuff
[j
++]= i 
- start
; 
 646                 if (i
-start 
< minClk 
&& i 
< GraphTraceLen
) { 
 652                 for (uint8_t clkCnt 
= 0; clkCnt
<7; clkCnt
++) { 
 653                         tol 
= fndClk
[clkCnt
]/8; 
 654                         if (minClk 
>= fndClk
[clkCnt
]-tol 
&& minClk 
<= fndClk
[clkCnt
]+1) { 
 662         // look for data start - should be 2 pairs of LW (pulses of clk*3,clk*2) 
 664         for (i
= 0; i 
< j 
- 4 ; ++i
) { 
 666                 if (tmpbuff
[i
] >= clk
*3-tol 
&& tmpbuff
[i
] <= clk
*3+tol
)  //3 clocks 
 667                         if (tmpbuff
[i
+1] >= clk
*2-tol 
&& tmpbuff
[i
+1] <= clk
*2+tol
)  //2 clocks 
 668                                 if (tmpbuff
[i
+2] >= clk
*3-tol 
&& tmpbuff
[i
+2] <= clk
*3+tol
) //3 clocks 
 669                                         if (tmpbuff
[i
+3] >= clk
-tol
)  //1.5 to 2 clocks - depends on bit following 
 677         // skip over the remainder of LW 
 678         skip 
+= tmpbuff
[i
+1] + tmpbuff
[i
+2] + clk
; 
 679         if (tmpbuff
[i
+3]>clk
) 
 680                 phaseoff 
= tmpbuff
[i
+3]-clk
; 
 683         // now do it again to find the end 
 685         for (i 
+= 3; i 
< j 
- 4 ; ++i
) { 
 687                 if (tmpbuff
[i
] >= clk
*3-tol 
&& tmpbuff
[i
] <= clk
*3+tol
)  //3 clocks 
 688                         if (tmpbuff
[i
+1] >= clk
*2-tol 
&& tmpbuff
[i
+1] <= clk
*2+tol
)  //2 clocks 
 689                                 if (tmpbuff
[i
+2] >= clk
*3-tol 
&& tmpbuff
[i
+2] <= clk
*3+tol
) //3 clocks 
 690                                         if (tmpbuff
[i
+3] >= clk
-tol
)  //1.5 to 2 clocks - depends on bit following 
 698         if (verbose 
|| g_debugMode
) { 
 700                         PrintAndLog("\nNote: one block = 50 bits (32 data, 12 parity, 6 marker)"); 
 702                         PrintAndLog("No data found!, clock tried:%d",clk
); 
 703                         PrintAndLog("Try again with more samples."); 
 704                         PrintAndLog("  or after a 'data askedge' command to clean up the read"); 
 707         } else if (start 
< 0) return 0; 
 709         snprintf(tmp2
, sizeof(tmp2
),"%d %d 1000 %d", clk
, invert
, clk
*47); 
 710         // save GraphBuffer - to restore it later 
 711         save_restoreGB(GRAPH_SAVE
); 
 712         // get rid of leading crap 
 713         snprintf(tmp
, sizeof(tmp
), "%i", skip
); 
 716         bool AllPTest 
= true; 
 717         // now work through remaining buffer printing out data blocks 
 721                 if (verbose 
|| g_debugMode
) PrintAndLog("\nBlock %i:", block
); 
 724                 // look for LW before start of next block 
 725                 for ( ; i 
< j 
- 4 ; ++i
) { 
 727                         if (tmpbuff
[i
] >= clk
*3-tol 
&& tmpbuff
[i
] <= clk
*3+tol
) 
 728                                 if (tmpbuff
[i
+1] >= clk
-tol
) 
 731                 if (i 
>= j
-4) break; //next LW not found 
 733                 if (tmpbuff
[i
+1]>clk
) 
 734                         phaseoff 
= tmpbuff
[i
+1]-clk
; 
 738                 if (ASKDemod(tmp2
, false, false, 1) < 1) { 
 739                         save_restoreGB(GRAPH_RESTORE
); 
 742                 //set DemodBufferLen to just one block 
 743                 DemodBufferLen 
= skip
/clk
; 
 745                 pTest 
= EM_ByteParityTest(DemodBuffer
,DemodBufferLen
,5,9,0); 
 746                 pTest 
&= EM_EndParityTest(DemodBuffer
,DemodBufferLen
,5,9,0); 
 749                 Code
[block
] = OutputEM4x50_Block(DemodBuffer
,DemodBufferLen
,verbose
, pTest
); 
 750                 if (g_debugMode
) PrintAndLog("\nskipping %d samples, bits:%d", skip
, skip
/clk
); 
 751                 //skip to start of next block 
 752                 snprintf(tmp
,sizeof(tmp
),"%i",skip
); 
 755                 if (i 
>= end
) break; //in case chip doesn't output 6 blocks 
 758         if (verbose 
|| g_debugMode 
|| AllPTest
){ 
 760                         PrintAndLog("*** Warning!"); 
 761                         PrintAndLog("Partial data - no end found!"); 
 762                         PrintAndLog("Try again with more samples."); 
 764                 PrintAndLog("Found data at sample: %i - using clock: %i", start
, clk
); 
 766                 for (block
=0; block 
< end
; block
++){ 
 767                         PrintAndLog("Block %d: %08x",block
,Code
[block
]); 
 770                         PrintAndLog("Parities Passed"); 
 772                         PrintAndLog("Parities Failed"); 
 773                         PrintAndLog("Try cleaning the read samples with 'data askedge'"); 
 777         //restore GraphBuffer 
 778         save_restoreGB(GRAPH_RESTORE
); 
 779         return (int)AllPTest
; 
 782 int CmdEM4x50Read(const char *Cmd
) 
 784         return EM4x50Read(Cmd
, true); 
 787 //**************** Start of EM4x05/EM4x69 Code ************************ 
 788 int usage_lf_em_read(void) { 
 789         PrintAndLog("Read EM4x05/EM4x69.  Tag must be on antenna. "); 
 791         PrintAndLog("Usage:  lf em 4x05readword [h] <address> <pwd>"); 
 792         PrintAndLog("Options:"); 
 793         PrintAndLog("       h         - this help"); 
 794         PrintAndLog("       address   - memory address to read. (0-15)"); 
 795         PrintAndLog("       pwd       - password (hex) (optional)"); 
 796         PrintAndLog("samples:"); 
 797         PrintAndLog("      lf em 4x05readword 1"); 
 798         PrintAndLog("      lf em 4x05readword 1 11223344"); 
 802 // for command responses from em4x05 or em4x69 
 803 // download samples from device and copy them to the Graphbuffer 
 804 bool downloadSamplesEM() { 
 805         // 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples) 
 807         GetFromBigBuf(got
, sizeof(got
), 0); 
 808         if ( !WaitForResponseTimeout(CMD_ACK
, NULL
, 4000) ) { 
 809                 PrintAndLog("command execution time out"); 
 812         setGraphBuf(got
, sizeof(got
)); 
 816 bool EM4x05testDemodReadData(uint32_t *word
, bool readCmd
) { 
 817         // em4x05/em4x69 command response preamble is 00001010 
 818         // skip first two 0 bits as they might have been missed in the demod 
 819         uint8_t preamble
[] = {0,0,1,0,1,0}; 
 822         // set size to 20 to only test first 14 positions for the preamble or less if not a read command 
 823         size_t size 
= (readCmd
) ? 20 : 11; 
 825         size 
= (size 
> DemodBufferLen
) ? DemodBufferLen 
: size
; 
 827         if ( !preambleSearchEx(DemodBuffer
, preamble
, sizeof(preamble
), &size
, &startIdx
, true) ) { 
 828                 if (g_debugMode
) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx
); 
 831         // if this is a readword command, get the read bytes and test the parities 
 833                 if (!EM_EndParityTest(DemodBuffer 
+ startIdx 
+ sizeof(preamble
), 45, 5, 9, 0)) { 
 834                         if (g_debugMode
) PrintAndLog("DEBUG: Error - End Parity check failed"); 
 837                 // test for even parity bits and remove them. (leave out the end row of parities so 36 bits) 
 838                 if ( removeParity(DemodBuffer
, startIdx 
+ sizeof(preamble
),9,0,36) == 0 ) { 
 839                         if (g_debugMode
) PrintAndLog("DEBUG: Error - Parity not detected"); 
 843                 setDemodBuf(DemodBuffer
, 32, 0); 
 846                 *word 
= bytebits_to_byteLSBF(DemodBuffer
, 32); 
 851 // FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE 
 852 // should cover 90% of known used configs 
 853 // the rest will need to be manually demoded for now... 
 854 int demodEM4x05resp(uint32_t *word
, bool readCmd
) { 
 857         // test for FSK wave (easiest to 99% ID) 
 858         if (GetFskClock("", false, false)) { 
 859                 //valid fsk clocks found 
 860                 ans 
= FSKrawDemod("0 0", false); 
 862                         if (g_debugMode
) PrintAndLog("DEBUG: Error - EM4305: FSK Demod failed, ans: %d", ans
); 
 864                         if (EM4x05testDemodReadData(word
, readCmd
)) { 
 869         // PSK clocks should be easy to detect ( but difficult to demod a non-repeating pattern... ) 
 870         ans 
= GetPskClock("", false, false); 
 873                 ans 
= PSKDemod("0 0 6", false); 
 875                         if (g_debugMode
) PrintAndLog("DEBUG: Error - EM4305: PSK1 Demod failed, ans: %d", ans
); 
 877                         if (EM4x05testDemodReadData(word
, readCmd
)) { 
 881                                 psk1TOpsk2(DemodBuffer
, DemodBufferLen
); 
 882                                 if (EM4x05testDemodReadData(word
, readCmd
)) { 
 887                         ans 
= PSKDemod("0 1 6", false); 
 889                                 if (g_debugMode
) PrintAndLog("DEBUG: Error - EM4305: PSK1 Demod failed, ans: %d", ans
); 
 891                                 if (EM4x05testDemodReadData(word
, readCmd
)) { 
 895                                         psk1TOpsk2(DemodBuffer
, DemodBufferLen
); 
 896                                         if (EM4x05testDemodReadData(word
, readCmd
)) { 
 904         // manchester is more common than biphase... try first 
 905         bool stcheck 
= false; 
 906         // try manchester - NOTE: ST only applies to T55x7 tags. 
 907         ans 
= ASKDemod_ext("0,0,1", false, false, 1, &stcheck
); 
 909                 if (g_debugMode
) PrintAndLog("DEBUG: Error - EM4305: ASK/Manchester Demod failed, ans: %d", ans
); 
 911                 if (EM4x05testDemodReadData(word
, readCmd
)) { 
 917         ans 
= ASKbiphaseDemod("0 0 1", false); 
 919                 if (g_debugMode
) PrintAndLog("DEBUG: Error - EM4305: ASK/biphase Demod failed, ans: %d", ans
); 
 921                 if (EM4x05testDemodReadData(word
, readCmd
)) { 
 926         //try diphase (differential biphase or inverted) 
 927         ans 
= ASKbiphaseDemod("0 1 1", false); 
 929                 if (g_debugMode
) PrintAndLog("DEBUG: Error - EM4305: ASK/biphase Demod failed, ans: %d", ans
); 
 931                 if (EM4x05testDemodReadData(word
, readCmd
)) { 
 939 int EM4x05ReadWord_ext(uint8_t addr
, uint32_t pwd
, bool usePwd
, uint32_t *wordData
) { 
 940         UsbCommand c 
= {CMD_EM4X_READ_WORD
, {addr
, pwd
, usePwd
}}; 
 941         clearCommandBuffer(); 
 944         if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 2500)){ 
 945                 PrintAndLog("Command timed out"); 
 948         if ( !downloadSamplesEM() ) { 
 951         int testLen 
= (GraphTraceLen 
< 1000) ? GraphTraceLen 
: 1000; 
 952         if (graphJustNoise(GraphBuffer
, testLen
)) { 
 953                 PrintAndLog("no tag not found"); 
 957         return demodEM4x05resp(wordData
, true); 
 960 int EM4x05ReadWord(uint8_t addr
, uint32_t pwd
, bool usePwd
) { 
 961         uint32_t wordData 
= 0; 
 962         int success 
= EM4x05ReadWord_ext(addr
, pwd
, usePwd
, &wordData
); 
 964                 PrintAndLog("%s Address %02d | %08X", (addr
>13) ? "Lock":" Got",addr
,wordData
); 
 966                 PrintAndLog("Read Address %02d | failed",addr
); 
 971 int CmdEM4x05ReadWord(const char *Cmd
) { 
 975         uint8_t ctmp 
= param_getchar(Cmd
, 0); 
 976         if ( strlen(Cmd
) == 0 || ctmp 
== 'H' || ctmp 
== 'h' ) return usage_lf_em_read(); 
 978         addr 
= param_get8ex(Cmd
, 0, 50, 10); 
 979         // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) 
 980         pwd 
=  param_get32ex(Cmd
, 1, 1, 16); 
 983                 PrintAndLog("Address must be between 0 and 15"); 
 987                 PrintAndLog("Reading address %02u", addr
); 
 990                 PrintAndLog("Reading address %02u | password %08X", addr
, pwd
); 
 993         return EM4x05ReadWord(addr
, pwd
, usePwd
); 
 996 int usage_lf_em_dump(void) { 
 997         PrintAndLog("Dump EM4x05/EM4x69.  Tag must be on antenna. "); 
 999         PrintAndLog("Usage:  lf em 4x05dump [h] <pwd>"); 
1000         PrintAndLog("Options:"); 
1001         PrintAndLog("       h         - this help"); 
1002         PrintAndLog("       pwd       - password (hex) (optional)"); 
1003         PrintAndLog("samples:"); 
1004         PrintAndLog("      lf em 4x05dump"); 
1005         PrintAndLog("      lf em 4x05dump 11223344"); 
1009 int CmdEM4x05dump(const char *Cmd
) { 
1012         bool usePwd 
= false; 
1013         uint8_t ctmp 
= param_getchar(Cmd
, 0); 
1014         if ( ctmp 
== 'H' || ctmp 
== 'h' ) return usage_lf_em_dump(); 
1016         // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) 
1017         pwd 
= param_get32ex(Cmd
, 0, 1, 16); 
1023         for (; addr 
< 16; addr
++) { 
1026                                 PrintAndLog(" PWD Address %02u | %08X",addr
,pwd
); 
1028                                 PrintAndLog(" PWD Address 02 | cannot read"); 
1031                         success 
&= EM4x05ReadWord(addr
, pwd
, usePwd
); 
1039 int usage_lf_em_write(void) { 
1040         PrintAndLog("Write EM4x05/EM4x69.  Tag must be on antenna. "); 
1042         PrintAndLog("Usage:  lf em 4x05writeword [h] a <address> d <data> p <pwd> [s] [i]"); 
1043         PrintAndLog("Options:"); 
1044         PrintAndLog("       h           - this help"); 
1045         PrintAndLog("       a <address> - memory address to write to. (0-15)"); 
1046         PrintAndLog("       d <data>    - data to write (hex)"); 
1047         PrintAndLog("       p <pwd>     - password (hex) (optional)"); 
1048         PrintAndLog("       s           - swap the data bit order before write"); 
1049         PrintAndLog("       i           - invert the data bits before write"); 
1050         PrintAndLog("samples:"); 
1051         PrintAndLog("      lf em 4x05writeword a 5 d 11223344"); 
1052         PrintAndLog("      lf em 4x05writeword a 5 p deadc0de d 11223344 s i"); 
1056 // note: em4x05 doesn't have a way to invert data output so we must invert the data prior to writing 
1057 //         it if invertion is needed. (example FSK2a vs FSK) 
1058 //       also em4x05 requires swapping word data when compared to the data used for t55xx chips. 
1059 int EM4x05WriteWord(uint8_t addr
, uint32_t data
, uint32_t pwd
, bool usePwd
, bool swap
, bool invert
) { 
1060         if (swap
) data 
= SwapBits(data
, 32); 
1062         if (invert
) data 
^= 0xFFFFFFFF; 
1064         if ( (addr 
> 15) ) { 
1065                 PrintAndLog("Address must be between 0 and 15"); 
1069                 PrintAndLog("Writing address %d data %08X", addr
, data
); 
1071                 PrintAndLog("Writing address %d data %08X using password %08X", addr
, data
, pwd
); 
1074         uint16_t flag 
= (addr 
<< 8 ) | usePwd
; 
1076         UsbCommand c 
= {CMD_EM4X_WRITE_WORD
, {flag
, data
, pwd
}}; 
1077         clearCommandBuffer(); 
1080         if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 2000)){ 
1081                 PrintAndLog("Error occurred, device did not respond during write operation."); 
1084         if ( !downloadSamplesEM() ) { 
1087         //check response for 00001010 for write confirmation! 
1090         int result 
= demodEM4x05resp(&dummy
,false); 
1092                 PrintAndLog("Write Verified"); 
1094                 PrintAndLog("Write could not be verified"); 
1099 int CmdEM4x05WriteWord(const char *Cmd
) { 
1100         bool errors 
= false; 
1101         bool usePwd 
= false; 
1102         uint32_t data 
= 0xFFFFFFFF; 
1103         uint32_t pwd 
= 0xFFFFFFFF; 
1105         bool invert 
= false; 
1106         uint8_t addr 
= 16; // default to invalid address 
1107         bool gotData 
= false; 
1109         while(param_getchar(Cmd
, cmdp
) != 0x00) 
1111                 switch(param_getchar(Cmd
, cmdp
)) 
1115                         return usage_lf_em_write(); 
1118                         addr 
= param_get8ex(Cmd
, cmdp
+1, 16, 10); 
1123                         data 
= param_get32ex(Cmd
, cmdp
+1, 0, 16); 
1134                         pwd 
= param_get32ex(Cmd
, cmdp
+1, 1, 16); 
1136                                 PrintAndLog("invalid pwd"); 
1148                         PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
)); 
1155         if(errors
) return usage_lf_em_write(); 
1157         if ( strlen(Cmd
) == 0 ) return usage_lf_em_write(); 
1160                 PrintAndLog("You must enter the data you want to write"); 
1161                 return usage_lf_em_write(); 
1163         return EM4x05WriteWord(addr
, data
, pwd
, usePwd
, swap
, invert
); 
1166 void printEM4x05config(uint32_t wordData
) { 
1167         uint16_t datarate 
= EM4x05_GET_BITRATE(wordData
); 
1168         uint8_t encoder 
= ((wordData 
>> 6) & 0xF); 
1170         memset(enc
,0,sizeof(enc
)); 
1172         uint8_t PSKcf 
= (wordData 
>> 10) & 0x3; 
1174         memset(cf
,0,sizeof(cf
)); 
1175         uint8_t delay 
= (wordData 
>> 12) & 0x3; 
1177         memset(cdelay
,0,sizeof(cdelay
)); 
1178         uint8_t numblks 
= EM4x05_GET_NUM_BLOCKS(wordData
); 
1179         uint8_t LWR 
= numblks
+5-1; //last word read 
1181                 case 0: snprintf(enc
,sizeof(enc
),"NRZ"); break; 
1182                 case 1: snprintf(enc
,sizeof(enc
),"Manchester"); break; 
1183                 case 2: snprintf(enc
,sizeof(enc
),"Biphase"); break; 
1184                 case 3: snprintf(enc
,sizeof(enc
),"Miller"); break; 
1185                 case 4: snprintf(enc
,sizeof(enc
),"PSK1"); break; 
1186                 case 5: snprintf(enc
,sizeof(enc
),"PSK2"); break; 
1187                 case 6: snprintf(enc
,sizeof(enc
),"PSK3"); break; 
1188                 case 7: snprintf(enc
,sizeof(enc
),"Unknown"); break; 
1189                 case 8: snprintf(enc
,sizeof(enc
),"FSK1"); break; 
1190                 case 9: snprintf(enc
,sizeof(enc
),"FSK2"); break; 
1191                 default: snprintf(enc
,sizeof(enc
),"Unknown"); break; 
1195                 case 0: snprintf(cf
,sizeof(cf
),"RF/2"); break; 
1196                 case 1: snprintf(cf
,sizeof(cf
),"RF/8"); break; 
1197                 case 2: snprintf(cf
,sizeof(cf
),"RF/4"); break; 
1198                 case 3: snprintf(cf
,sizeof(cf
),"unknown"); break; 
1202                 case 0: snprintf(cdelay
, sizeof(cdelay
),"no delay"); break; 
1203                 case 1: snprintf(cdelay
, sizeof(cdelay
),"BP/8 or 1/8th bit period delay"); break; 
1204                 case 2: snprintf(cdelay
, sizeof(cdelay
),"BP/4 or 1/4th bit period delay"); break; 
1205                 case 3: snprintf(cdelay
, sizeof(cdelay
),"no delay"); break; 
1207         uint8_t readLogin 
= (wordData 
& EM4x05_READ_LOGIN_REQ
)>>18; 
1208         uint8_t readHKL 
= (wordData 
& EM4x05_READ_HK_LOGIN_REQ
)>>19; 
1209         uint8_t writeLogin 
= (wordData 
& EM4x05_WRITE_LOGIN_REQ
)>>20; 
1210         uint8_t writeHKL 
= (wordData 
& EM4x05_WRITE_HK_LOGIN_REQ
)>>21; 
1211         uint8_t raw 
= (wordData 
& EM4x05_READ_AFTER_WRITE
)>>22; 
1212         uint8_t disable 
= (wordData 
& EM4x05_DISABLE_ALLOWED
)>>23; 
1213         uint8_t rtf 
= (wordData 
& EM4x05_READER_TALK_FIRST
)>>24; 
1214         uint8_t pigeon 
= (wordData 
& (1<<26))>>26; 
1215         PrintAndLog("ConfigWord: %08X (Word 4)\n", wordData
); 
1216         PrintAndLog("Config Breakdown:"); 
1217         PrintAndLog(" Data Rate:  %02u | RF/%u", wordData 
& 0x3F, datarate
); 
1218         PrintAndLog("   Encoder:   %u | %s", encoder
, enc
); 
1219         PrintAndLog("    PSK CF:   %u | %s", PSKcf
, cf
); 
1220         PrintAndLog("     Delay:   %u | %s", delay
, cdelay
); 
1221         PrintAndLog(" LastWordR:  %02u | Address of last word for default read - meaning %u blocks are output", LWR
, numblks
); 
1222         PrintAndLog(" ReadLogin:   %u | Read Login is %s", readLogin
, readLogin 
? "Required" : "Not Required"); 
1223         PrintAndLog("   ReadHKL:   %u | Read Housekeeping Words Login is %s", readHKL
, readHKL 
? "Required" : "Not Required"); 
1224         PrintAndLog("WriteLogin:   %u | Write Login is %s", writeLogin
, writeLogin 
? "Required" : "Not Required"); 
1225         PrintAndLog("  WriteHKL:   %u | Write Housekeeping Words Login is %s", writeHKL
, writeHKL 
? "Required" : "Not Required"); 
1226         PrintAndLog("    R.A.W.:   %u | Read After Write is %s", raw
, raw 
? "On" : "Off"); 
1227         PrintAndLog("   Disable:   %u | Disable Command is %s", disable
, disable 
? "Accepted" : "Not Accepted"); 
1228         PrintAndLog("    R.T.F.:   %u | Reader Talk First is %s", rtf
, rtf 
? "Enabled" : "Disabled"); 
1229         PrintAndLog("    Pigeon:   %u | Pigeon Mode is %s\n", pigeon
, pigeon 
? "Enabled" : "Disabled"); 
1232 void printEM4x05info(uint8_t chipType
, uint8_t cap
, uint16_t custCode
, uint32_t serial
) { 
1234                 case 9: PrintAndLog("\n Chip Type:   %u | EM4305", chipType
); break; 
1235                 case 4: PrintAndLog(" Chip Type:   %u | Unknown", chipType
); break; 
1236                 case 2: PrintAndLog(" Chip Type:   %u | EM4469", chipType
); break; 
1237                 //add more here when known 
1238                 default: PrintAndLog(" Chip Type:   %u Unknown", chipType
); break; 
1242                 case 3: PrintAndLog("  Cap Type:   %u | 330pF",cap
); break; 
1243                 case 2: PrintAndLog("  Cap Type:   %u | %spF",cap
, (chipType
==2)? "75":"210"); break; 
1244                 case 1: PrintAndLog("  Cap Type:   %u | 250pF",cap
); break; 
1245                 case 0: PrintAndLog("  Cap Type:   %u | no resonant capacitor",cap
); break; 
1246                 default: PrintAndLog("  Cap Type:   %u | unknown",cap
); break; 
1249         PrintAndLog(" Cust Code: %03u | %s", custCode
, (custCode 
== 0x200) ? "Default": "Unknown"); 
1251                 PrintAndLog("\n  Serial #: %08X\n", serial
); 
1255 void printEM4x05ProtectionBits(uint32_t wordData
) { 
1256         for (uint8_t i 
= 0; i 
< 15; i
++) { 
1257                 PrintAndLog("      Word:  %02u | %s", i
, (((1 << i
) & wordData 
) || i 
< 2) ? "Is Write Locked" : "Is Not Write Locked"); 
1259                         PrintAndLog("      Word:  %02u | %s", i
+1, (((1 << i
) & wordData 
) || i 
< 2) ? "Is Write Locked" : "Is Not Write Locked"); 
1264 //quick test for EM4x05/EM4x69 tag 
1265 bool EM4x05Block0Test(uint32_t *wordData
) { 
1266         if (EM4x05ReadWord_ext(0,0,false,wordData
) == 1) { 
1272 int CmdEM4x05info(const char *Cmd
) { 
1275         uint32_t wordData 
= 0; 
1276         bool usePwd 
= false; 
1277         uint8_t ctmp 
= param_getchar(Cmd
, 0); 
1278         if ( ctmp 
== 'H' || ctmp 
== 'h' ) return usage_lf_em_dump(); 
1280         // for now use default input of 1 as invalid (unlikely 1 will be a valid password...) 
1281         pwd 
= param_get32ex(Cmd
, 0, 1, 16); 
1287         // read word 0 (chip info) 
1288         // block 0 can be read even without a password. 
1289         if ( !EM4x05Block0Test(&wordData
) ) 
1292         uint8_t chipType 
= (wordData 
>> 1) & 0xF; 
1293         uint8_t cap 
= (wordData 
>> 5) & 3; 
1294         uint16_t custCode 
= (wordData 
>> 9) & 0x3FF; 
1296         // read word 1 (serial #) doesn't need pwd 
1298         if (EM4x05ReadWord_ext(1, 0, false, &wordData
) != 1) { 
1299                 //failed, but continue anyway... 
1301         printEM4x05info(chipType
, cap
, custCode
, wordData
); 
1303         // read word 4 (config block) 
1304         // needs password if one is set 
1306         if ( EM4x05ReadWord_ext(4, pwd
, usePwd
, &wordData
) != 1 ) { 
1308                 PrintAndLog("Config block read failed - might be password protected."); 
1311         printEM4x05config(wordData
); 
1313         // read word 14 and 15 to see which is being used for the protection bits 
1315         if ( EM4x05ReadWord_ext(14, pwd
, usePwd
, &wordData
) != 1 ) { 
1319         // if status bit says this is not the used protection word 
1320         if (!(wordData 
& 0x8000)) { 
1321                 if ( EM4x05ReadWord_ext(15, pwd
, usePwd
, &wordData
) != 1 ) { 
1326         if (!(wordData 
& 0x8000)) { 
1327                 //something went wrong 
1330         printEM4x05ProtectionBits(wordData
); 
1336 static command_t CommandTable
[] = 
1338         {"help",      CmdHelp
, 1, "This help"}, 
1339         {"410xread",  CmdEMdemodASK
, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"}, 
1340         {"410xdemod", CmdAskEM410xDemod
,  1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"}, 
1341         {"410xsim",   CmdEM410xSim
, 0, "<UID> [clock rate] -- Simulate EM410x tag"}, 
1342         {"410xbrute",   CmdEM410xBrute
, 0, "ids.txt [d (delay in ms)] [c (clock rate)] -- Bruteforcing by simulating EM410x tags (1 UID/s)"}, 
1343         {"410xwatch", CmdEM410xWatch
, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"}, 
1344         {"410xspoof", CmdEM410xWatchnSpoof
, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" }, 
1345         {"410xwrite", CmdEM410xWrite
, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"}, 
1346         {"4x05dump",  CmdEM4x05dump
, 0, "(pwd) -- Read EM4x05/EM4x69 all word data"}, 
1347         {"4x05info",  CmdEM4x05info
, 0, "(pwd) -- Get info from EM4x05/EM4x69 tag"}, 
1348         {"4x05readword",  CmdEM4x05ReadWord
, 0, "<Word> (pwd) -- Read EM4x05/EM4x69 word data"}, 
1349         {"4x05writeword", CmdEM4x05WriteWord
, 0, "<Word> <data> (pwd) -- Write EM4x05/EM4x69 word data"}, 
1350         {"4x50read",  CmdEM4x50Read
, 1, "demod data from EM4x50 tag from the graph buffer"}, 
1351         {NULL
, NULL
, 0, NULL
} 
1354 int CmdLFEM4X(const char *Cmd
) 
1356         CmdsParse(CommandTable
, Cmd
); 
1360 int CmdHelp(const char *Cmd
) 
1362         CmdsHelp(CommandTable
);