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 commands 
   9 //----------------------------------------------------------------------------- 
  15 #include "proxmark3.h" 
  19 #include "cmdparser.h" 
  23 #include "cmdlfawid26.h" 
  26 #include "cmdlfem4x.h" 
  27 #include "cmdlfhitag.h" 
  28 #include "cmdlft55xx.h" 
  29 #include "cmdlfpcf7931.h" 
  32 static int CmdHelp(const char *Cmd
); 
  34 /* send a command before reading */ 
  35 int CmdLFCommandRead(const char *Cmd
) 
  41   UsbCommand c 
= {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K
}; 
  42   sscanf(Cmd
, "%"lli
" %"lli
" %"lli
" %s %s", &c
.arg
[0], &c
.arg
[1], &c
.arg
[2],(char*)(&c
.d
.asBytes
),(char*)(&dummy
+1)); 
  43   // in case they specified 'h' 
  44   strcpy((char *)&c
.d
.asBytes 
+ strlen((char *)c
.d
.asBytes
), dummy
); 
  49 int CmdFlexdemod(const char *Cmd
) 
  52   for (i 
= 0; i 
< GraphTraceLen
; ++i
) { 
  53     if (GraphBuffer
[i
] < 0) { 
  62   for (start 
= 0; start 
< GraphTraceLen 
- LONG_WAIT
; start
++) { 
  63     int first 
= GraphBuffer
[start
]; 
  64     for (i 
= start
; i 
< start 
+ LONG_WAIT
; i
++) { 
  65       if (GraphBuffer
[i
] != first
) { 
  69     if (i 
== (start 
+ LONG_WAIT
)) { 
  73   if (start 
== GraphTraceLen 
- LONG_WAIT
) { 
  74     PrintAndLog("nothing to wait for"); 
  78   GraphBuffer
[start
] = 2; 
  79   GraphBuffer
[start
+1] = -2; 
  85   for (bit 
= 0; bit 
< 64; bit
++) { 
  88     for (j 
= 0; j 
< 16; j
++) { 
  89       sum 
+= GraphBuffer
[i
++]; 
  96     PrintAndLog("bit %d sum %d", bit
, sum
); 
  99   for (bit 
= 0; bit 
< 64; bit
++) { 
 102     for (j 
= 0; j 
< 16; j
++) { 
 103       sum 
+= GraphBuffer
[i
++]; 
 105     if (sum 
> 0 && bits
[bit
] != 1) { 
 106       PrintAndLog("oops1 at %d", bit
); 
 108     if (sum 
< 0 && bits
[bit
] != 0) { 
 109       PrintAndLog("oops2 at %d", bit
); 
 113   GraphTraceLen 
= 32*64; 
 116   for (bit 
= 0; bit 
< 64; bit
++) { 
 117     if (bits
[bit
] == 0) { 
 123     for (j 
= 0; j 
< 32; j
++) { 
 124       GraphBuffer
[i
++] = phase
; 
 129   RepaintGraphWindow(); 
 133 int CmdIndalaDemod(const char *Cmd
) 
 135   // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID 
 140   // worst case with GraphTraceLen=64000 is < 4096 
 141   // under normal conditions it's < 2048 
 142   uint8_t rawbits
[4096]; 
 144   int worst 
= 0, worstPos 
= 0; 
 145   PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen 
/ 32); 
 146   for (i 
= 0; i 
< GraphTraceLen
-1; i 
+= 2) { 
 148     if ((GraphBuffer
[i
] > GraphBuffer
[i 
+ 1]) && (state 
!= 1)) { 
 150         for (j 
= 0; j 
<  count 
- 8; j 
+= 16) { 
 151           rawbits
[rawbit
++] = 0; 
 153         if ((abs(count 
- j
)) > worst
) { 
 154           worst 
= abs(count 
- j
); 
 160     } else if ((GraphBuffer
[i
] < GraphBuffer
[i 
+ 1]) && (state 
!= 0)) { 
 162         for (j 
= 0; j 
<  count 
- 8; j 
+= 16) { 
 163           rawbits
[rawbit
++] = 1; 
 165         if ((abs(count 
- j
)) > worst
) { 
 166           worst 
= abs(count 
- j
); 
 175     PrintAndLog("Recovered %d raw bits, expected: %d", rawbit
, GraphTraceLen
/32); 
 176   PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst
, worstPos
); 
 178   // Finding the start of a UID 
 179   int uidlen
, long_wait
; 
 180   if (strcmp(Cmd
, "224") == 0) { 
 189   for (start 
= 0; start 
<= rawbit 
- uidlen
; start
++) { 
 190     first 
= rawbits
[start
]; 
 191     for (i 
= start
; i 
< start 
+ long_wait
; i
++) { 
 192       if (rawbits
[i
] != first
) { 
 196     if (i 
== (start 
+ long_wait
)) { 
 200   if (start 
== rawbit 
- uidlen 
+ 1) { 
 201     PrintAndLog("nothing to wait for"); 
 205   // Inverting signal if needed 
 207     for (i 
= start
; i 
< rawbit
; i
++) { 
 208       rawbits
[i
] = !rawbits
[i
]; 
 215   showbits
[uidlen
]='\0'; 
 219   if (uidlen 
> rawbit
) { 
 220     PrintAndLog("Warning: not enough raw bits to get a full UID"); 
 221     for (bit 
= 0; bit 
< rawbit
; bit
++) { 
 222       bits
[bit
] = rawbits
[i
++]; 
 223       // As we cannot know the parity, let's use "." and "/" 
 224       showbits
[bit
] = '.' + bits
[bit
]; 
 226     showbits
[bit
+1]='\0'; 
 227     PrintAndLog("Partial UID=%s", showbits
); 
 230     for (bit 
= 0; bit 
< uidlen
; bit
++) { 
 231       bits
[bit
] = rawbits
[i
++]; 
 232       showbits
[bit
] = '0' + bits
[bit
]; 
 238   uint32_t uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
; 
 243     for( idx
=0; idx
<64; idx
++) { 
 244         if (showbits
[idx
] == '0') { 
 245         uid1
=(uid1
<<1)|(uid2
>>31); 
 248         uid1
=(uid1
<<1)|(uid2
>>31); 
 252     PrintAndLog("UID=%s (%x%08x)", showbits
, uid1
, uid2
); 
 260     for( idx
=0; idx
<224; idx
++) { 
 261         uid1
=(uid1
<<1)|(uid2
>>31); 
 262         uid2
=(uid2
<<1)|(uid3
>>31); 
 263         uid3
=(uid3
<<1)|(uid4
>>31); 
 264         uid4
=(uid4
<<1)|(uid5
>>31); 
 265         uid5
=(uid5
<<1)|(uid6
>>31); 
 266         uid6
=(uid6
<<1)|(uid7
>>31); 
 267         if (showbits
[idx
] == '0') uid7
=(uid7
<<1)|0; 
 268         else uid7
=(uid7
<<1)|1; 
 270     PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits
, uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
); 
 273   // Checking UID against next occurrences 
 274   for (; i 
+ uidlen 
<= rawbit
;) { 
 276     for (bit 
= 0; bit 
< uidlen
; bit
++) { 
 277       if (bits
[bit
] != rawbits
[i
++]) { 
 287   PrintAndLog("Occurrences: %d (expected %d)", times
, (rawbit 
- start
) / uidlen
); 
 289   // Remodulating for tag cloning 
 290   GraphTraceLen 
= 32*uidlen
; 
 293   for (bit 
= 0; bit 
< uidlen
; bit
++) { 
 294     if (bits
[bit
] == 0) { 
 300     for (j 
= 0; j 
< 32; j
++) { 
 301       GraphBuffer
[i
++] = phase
; 
 306   RepaintGraphWindow(); 
 310 int CmdIndalaClone(const char *Cmd
) 
 312   unsigned int uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
; 
 323   if (strchr(Cmd
,'l') != 0) { 
 324     while (sscanf(&Cmd
[i
++], "%1x", &n 
) == 1) { 
 325       uid1 
= (uid1 
<< 4) | (uid2 
>> 28); 
 326       uid2 
= (uid2 
<< 4) | (uid3 
>> 28); 
 327       uid3 
= (uid3 
<< 4) | (uid4 
>> 28); 
 328       uid4 
= (uid4 
<< 4) | (uid5 
>> 28); 
 329       uid5 
= (uid5 
<< 4) | (uid6 
>> 28); 
 330       uid6 
= (uid6 
<< 4) | (uid7 
>> 28); 
 331         uid7 
= (uid7 
<< 4) | (n 
& 0xf); 
 333     PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
); 
 334     c
.cmd 
= CMD_INDALA_CLONE_TAG_L
; 
 335     c
.d
.asDwords
[0] = uid1
; 
 336     c
.d
.asDwords
[1] = uid2
; 
 337     c
.d
.asDwords
[2] = uid3
; 
 338     c
.d
.asDwords
[3] = uid4
; 
 339     c
.d
.asDwords
[4] = uid5
; 
 340     c
.d
.asDwords
[5] = uid6
; 
 341     c
.d
.asDwords
[6] = uid7
; 
 345     while (sscanf(&Cmd
[i
++], "%1x", &n 
) == 1) { 
 346       uid1 
= (uid1 
<< 4) | (uid2 
>> 28); 
 347       uid2 
= (uid2 
<< 4) | (n 
& 0xf); 
 349     PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1
, uid2
); 
 350     c
.cmd 
= CMD_INDALA_CLONE_TAG
; 
 359 int CmdLFRead(const char *Cmd
) 
 361   UsbCommand c 
= {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K
}; 
 362   // 'h' means higher-low-frequency, 134 kHz 
 365   } else if (*Cmd 
== '\0') { 
 367   } else if (sscanf(Cmd
, "%"lli
, &c
.arg
[0]) != 1) { 
 368     PrintAndLog("Samples 1: 'lf read'"); 
 369         PrintAndLog("        2: 'lf read h'"); 
 370         PrintAndLog("        3: 'lf read <divisor>'"); 
 374   WaitForResponse(CMD_ACK
,NULL
); 
 381 static void ChkBitstream(const char *str
) 
 385   /* convert to bitstream if necessary */ 
 386   for (i 
= 0; i 
< (int)(GraphTraceLen 
/ 2); i
++) 
 388     if (GraphBuffer
[i
] > 1 || GraphBuffer
[i
] < 0) 
 396 int CmdLFSim(const char *Cmd
) 
 402   sscanf(Cmd
, "%i", &gap
); 
 404   /* convert to bitstream if necessary */ 
 407   printf("Sending [%d bytes]", GraphTraceLen
); 
 408   for (i 
= 0; i 
< GraphTraceLen
; i 
+= USB_CMD_DATA_SIZE
) { 
 409     UsbCommand c
={CMD_DOWNLOADED_SIM_SAMPLES_125K
, {i
, 0, 0}}; 
 411     for (j 
= 0; j 
< USB_CMD_DATA_SIZE
; j
++) { 
 412       c
.d
.asBytes
[j
] = GraphBuffer
[i
+j
]; 
 415     WaitForResponse(CMD_ACK
,NULL
); 
 419   PrintAndLog("Starting to simulate"); 
 420   UsbCommand c 
= {CMD_SIMULATE_TAG_125K
, {GraphTraceLen
, gap
, 0}}; 
 425 int CmdLFSimBidir(const char *Cmd
) 
 427   /* Set ADC to twice the carrier for a slight supersampling */ 
 428   UsbCommand c 
= {CMD_LF_SIMULATE_BIDIR
, {47, 384, 0}}; 
 433 /* simulate an LF Manchester encoded tag with specified bitstream, clock rate and inter-id gap */ 
 434 int CmdLFSimManchester(const char *Cmd
) 
 436   static int clock
, gap
; 
 437   static char data
[1024], gapstring
[8]; 
 439   /* get settings/bits */ 
 440   sscanf(Cmd
, "%i %s %i", &clock
, &data
[0], &gap
); 
 442   /* clear our graph */ 
 445   /* fill it with our bitstream */ 
 446   for (int i 
= 0; i 
< strlen(data
) ; ++i
) 
 447     AppendGraph(0, clock
, data
[i
]- '0'); 
 450   CmdManchesterMod(""); 
 452   /* show what we've done */ 
 453   RepaintGraphWindow(); 
 456   sprintf(&gapstring
[0], "%i", gap
); 
 461 int CmdLFSnoop(const char *Cmd
) 
 463   UsbCommand c 
= {CMD_LF_SNOOP_RAW_ADC_SAMPLES
}; 
 464   // 'h' means higher-low-frequency, 134 kHz 
 469   } else if (*Cmd 
== 'l') { 
 470     sscanf(Cmd
, "l %"lli
, &c
.arg
[1]); 
 471   } else if(*Cmd 
== 'h') { 
 473     sscanf(Cmd
, "h %"lli
, &c
.arg
[1]); 
 474   } else if (sscanf(Cmd
, "%"lli
" %"lli
, &c
.arg
[0], &c
.arg
[1]) < 1) { 
 475     PrintAndLog("use 'snoop' or 'snoop {l,h} [trigger threshold]', or 'snoop <divisor> [trigger threshold]'"); 
 479   WaitForResponse(CMD_ACK
,NULL
); 
 481   size_t BUFF_SIZE 
= 8000; 
 482   uint8_t data
[BUFF_SIZE
]; 
 484   GetFromBigBuf(data
,BUFF_SIZE
,3560);  //3560 -- should be offset.. 
 485   WaitForResponseTimeout(CMD_ACK
,NULL
, 1500); 
 487         for (int j 
= 0; j 
< BUFF_SIZE
; j
++) { 
 488                 GraphBuffer
[j
] = ((int)data
[j
]); 
 490         GraphTraceLen 
= BUFF_SIZE
; 
 495 int CmdVchDemod(const char *Cmd
) 
 497   // Is this the entire sync pattern, or does this also include some 
 498   // data bits that happen to be the same everywhere? That would be 
 500   static const int SyncPattern
[] = { 
 501     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
 502     1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 503     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
 504     1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 505     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
 506     1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 507     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
 508     1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 509     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1, 
 510     1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 513   // So first, we correlate for the sync pattern, and mark that. 
 514   int bestCorrel 
= 0, bestPos 
= 0; 
 516   // It does us no good to find the sync pattern, with fewer than 
 517   // 2048 samples after it... 
 518   for (i 
= 0; i 
< (GraphTraceLen
-2048); i
++) { 
 521     for (j 
= 0; j 
< arraylen(SyncPattern
); j
++) { 
 522       sum 
+= GraphBuffer
[i
+j
]*SyncPattern
[j
]; 
 524     if (sum 
> bestCorrel
) { 
 529   PrintAndLog("best sync at %d [metric %d]", bestPos
, bestCorrel
); 
 537   for (i 
= 0; i 
< 2048; i 
+= 8) { 
 540     for (j 
= 0; j 
< 8; j
++) { 
 541       sum 
+= GraphBuffer
[bestPos
+i
+j
]; 
 548     if(abs(sum
) < worst
) { 
 553   PrintAndLog("bits:"); 
 554   PrintAndLog("%s", bits
); 
 555   PrintAndLog("worst metric: %d at pos %d", worst
, worstPos
); 
 557   if (strcmp(Cmd
, "clone")==0) { 
 560     for(s 
= bits
; *s
; s
++) { 
 562       for(j 
= 0; j 
< 16; j
++) { 
 563         GraphBuffer
[GraphTraceLen
++] = (*s 
== '1') ? 1 : 0; 
 566     RepaintGraphWindow(); 
 572 int CmdLFfind(const char *Cmd
) 
 577     //ans=CmdSamples("20000"); 
 579   if (GraphTraceLen
<1000) return 0; 
 580   PrintAndLog("Checking for known tags:"); 
 582   ans
=Cmdaskmandemod(""); 
 583   PrintAndLog("ASK_MAN: %s", (ans
)?"YES":"NO" ); 
 585   ans
=CmdFSKdemodHID(""); 
 586   PrintAndLog("HID: %s", (ans
)?"YES":"NO" ); 
 588   ans
=CmdFSKdemodIO(""); 
 589   PrintAndLog("IO prox: %s", (ans
)?"YES":"NO" ); 
 591   ans
=CmdIndalaDemod(""); 
 592   PrintAndLog("Indala (64): %s", (ans
)?"YES":"NO" ); 
 594   ans
=CmdIndalaDemod("224"); 
 595   PrintAndLog("Indala (224): %s", (ans
)?"YES":"NO" ); 
 597   //PrintAndLog("No Known Tags Found!\n"); 
 601 static command_t CommandTable
[] =  
 603   {"help",        CmdHelp
,            1, "This help"}, 
 604   {"cmdread",     CmdLFCommandRead
,   0, "<off period> <'0' period> <'1' period> <command> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"}, 
 606   {"flexdemod",   CmdFlexdemod
,       1, "Demodulate samples for FlexPass"}, 
 607   {"indalademod", CmdIndalaDemod
,     1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, 
 608   {"indalaclone", CmdIndalaClone
,     0, "<UID> ['l']-- Clone Indala to T55x7 (UID in HEX)(option 'l' for 224 UID"}, 
 609   {"vchdemod",    CmdVchDemod
,        1, "['clone'] -- Demodulate samples for VeriChip"}, 
 612   {"read",        CmdLFRead
,          0, "['h' or <divisor>] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, 
 613   {"search",      CmdLFfind
,          1, "Read and Search for valid known tag (in offline mode it you can load first then search)"}, 
 614   {"sim",         CmdLFSim
,           0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, 
 615   {"simbidir",    CmdLFSimBidir
,      0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, 
 616   {"simman",      CmdLFSimManchester
, 0, "<Clock> <Bitstream> [GAP] Simulate arbitrary Manchester LF tag"}, 
 617   {"snoop",       CmdLFSnoop
,         0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"}, 
 619   {"awid26",        CmdLFAWID26
,        1, "{ AWID26 tags }"}, 
 620   {"em4x",        CmdLFEM4X
,          1, "{ EM4X tags }"},       
 621   {"hid",         CmdLFHID
,           1, "{ HID tags }"}, 
 622   {"hitag",       CmdLFHitag
,         1, "{ Hitag tags and transponders }"}, 
 623   {"io",          CmdLFIO
,                1, "{ ioProx tags }"}, 
 624   {"pcf7931",     CmdLFPCF7931
,       1, "{ PCF7931 tags }"}, 
 625   {"ti",          CmdLFTI
,            1, "{ TI tags }"}, 
 626   {"t55xx",       CmdLFT55XX
,         1, "{ T55xx tags }"}, 
 628   {NULL
, NULL
, 0, NULL
} 
 631 int CmdLF(const char *Cmd
) 
 633   CmdsParse(CommandTable
, Cmd
); 
 637 int CmdHelp(const char *Cmd
) 
 639   CmdsHelp(CommandTable
);