]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlfem4x.c
Provide msclock() as Milliseconds timer for performance measures (#231)
[proxmark3-svn] / client / cmdlfem4x.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
3 //
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
6 // the license.
7 //-----------------------------------------------------------------------------
8 // Low frequency EM4x commands
9 //-----------------------------------------------------------------------------
10
11 #include <stdio.h>
12 #include <string.h>
13 #include <inttypes.h>
14 #include "proxmark3.h"
15 #include "ui.h"
16 #include "util.h"
17 #include "data.h"
18 #include "graph.h"
19 #include "cmdparser.h"
20 #include "cmddata.h"
21 #include "cmdlf.h"
22 #include "cmdmain.h"
23 #include "cmdlfem4x.h"
24 #include "lfdemod.h"
25
26 char *global_em410xId;
27
28 static int CmdHelp(const char *Cmd);
29
30 int CmdEMdemodASK(const char *Cmd)
31 {
32 char cmdp = param_getchar(Cmd, 0);
33 int findone = (cmdp == '1') ? 1 : 0;
34 UsbCommand c={CMD_EM410X_DEMOD};
35 c.arg[0]=findone;
36 SendCommand(&c);
37 return 0;
38 }
39
40 /* Read the ID of an EM410x tag.
41 * Format:
42 * 1111 1111 1 <-- standard non-repeatable header
43 * XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID
44 * ....
45 * CCCC <-- each bit here is parity for the 10 bits above in corresponding column
46 * 0 <-- stop bit, end of tag
47 */
48 int CmdEM410xRead(const char *Cmd)
49 {
50 uint32_t hi=0;
51 uint64_t lo=0;
52
53 if(!AskEm410xDemod("", &hi, &lo, false)) return 0;
54 PrintAndLog("EM410x pattern found: ");
55 printEM410x(hi, lo);
56 if (hi){
57 PrintAndLog ("EM410x XL pattern found");
58 return 0;
59 }
60 char id[12] = {0x00};
61 sprintf(id, "%010"PRIx64,lo);
62
63 global_em410xId = id;
64 return 1;
65 }
66
67 int usage_lf_em410x_sim(void) {
68 PrintAndLog("Simulating EM410x tag");
69 PrintAndLog("");
70 PrintAndLog("Usage: lf em 410xsim [h] <uid> <clock>");
71 PrintAndLog("Options:");
72 PrintAndLog(" h - this help");
73 PrintAndLog(" uid - uid (10 HEX symbols)");
74 PrintAndLog(" clock - clock (32|64) (optional)");
75 PrintAndLog("samples:");
76 PrintAndLog(" lf em 410xsim 0F0368568B");
77 PrintAndLog(" lf em 410xsim 0F0368568B 32");
78 return 0;
79 }
80
81 // emulate an EM410X tag
82 int CmdEM410xSim(const char *Cmd)
83 {
84 int i, n, j, binary[4], parity[4];
85
86 char cmdp = param_getchar(Cmd, 0);
87 uint8_t uid[5] = {0x00};
88
89 if (cmdp == 'h' || cmdp == 'H') return usage_lf_em410x_sim();
90 /* clock is 64 in EM410x tags */
91 uint8_t clock = 64;
92
93 if (param_gethex(Cmd, 0, uid, 10)) {
94 PrintAndLog("UID must include 10 HEX symbols");
95 return 0;
96 }
97 param_getdec(Cmd,1, &clock);
98
99 PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X clock: %d", uid[0],uid[1],uid[2],uid[3],uid[4],clock);
100 PrintAndLog("Press pm3-button to about simulation");
101
102
103 /* clear our graph */
104 ClearGraph(0);
105
106 /* write 9 start bits */
107 for (i = 0; i < 9; i++)
108 AppendGraph(0, clock, 1);
109
110 /* for each hex char */
111 parity[0] = parity[1] = parity[2] = parity[3] = 0;
112 for (i = 0; i < 10; i++)
113 {
114 /* read each hex char */
115 sscanf(&Cmd[i], "%1x", &n);
116 for (j = 3; j >= 0; j--, n/= 2)
117 binary[j] = n % 2;
118
119 /* append each bit */
120 AppendGraph(0, clock, binary[0]);
121 AppendGraph(0, clock, binary[1]);
122 AppendGraph(0, clock, binary[2]);
123 AppendGraph(0, clock, binary[3]);
124
125 /* append parity bit */
126 AppendGraph(0, clock, binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
127
128 /* keep track of column parity */
129 parity[0] ^= binary[0];
130 parity[1] ^= binary[1];
131 parity[2] ^= binary[2];
132 parity[3] ^= binary[3];
133 }
134
135 /* parity columns */
136 AppendGraph(0, clock, parity[0]);
137 AppendGraph(0, clock, parity[1]);
138 AppendGraph(0, clock, parity[2]);
139 AppendGraph(0, clock, parity[3]);
140
141 /* stop bit */
142 AppendGraph(1, clock, 0);
143
144 CmdLFSim("0"); //240 start_gap.
145 return 0;
146 }
147
148 /* Function is equivalent of lf read + data samples + em410xread
149 * looped until an EM410x tag is detected
150 *
151 * Why is CmdSamples("16000")?
152 * TBD: Auto-grow sample size based on detected sample rate. IE: If the
153 * rate gets lower, then grow the number of samples
154 * Changed by martin, 4000 x 4 = 16000,
155 * see http://www.proxmark.org/forum/viewtopic.php?pid=7235#p7235
156 */
157 int CmdEM410xWatch(const char *Cmd)
158 {
159 do {
160 if (ukbhit()) {
161 printf("\naborted via keyboard!\n");
162 break;
163 }
164
165 CmdLFRead("s");
166 getSamples("8201",true); //capture enough to get 2 complete preambles (4096*2+9)
167 } while (!CmdEM410xRead(""));
168
169 return 0;
170 }
171
172 //currently only supports manchester modulations
173 int CmdEM410xWatchnSpoof(const char *Cmd)
174 {
175 CmdEM410xWatch(Cmd);
176 PrintAndLog("# Replaying captured ID: %s",global_em410xId);
177 CmdLFaskSim("");
178 return 0;
179 }
180
181 int CmdEM410xWrite(const char *Cmd)
182 {
183 uint64_t id = 0xFFFFFFFFFFFFFFFF; // invalid id value
184 int card = 0xFF; // invalid card value
185 unsigned int clock = 0; // invalid clock value
186
187 sscanf(Cmd, "%" SCNx64 " %d %d", &id, &card, &clock);
188
189 // Check ID
190 if (id == 0xFFFFFFFFFFFFFFFF) {
191 PrintAndLog("Error! ID is required.\n");
192 return 0;
193 }
194 if (id >= 0x10000000000) {
195 PrintAndLog("Error! Given EM410x ID is longer than 40 bits.\n");
196 return 0;
197 }
198
199 // Check Card
200 if (card == 0xFF) {
201 PrintAndLog("Error! Card type required.\n");
202 return 0;
203 }
204 if (card < 0) {
205 PrintAndLog("Error! Bad card type selected.\n");
206 return 0;
207 }
208
209 // Check Clock
210 // Default: 64
211 if (clock == 0)
212 clock = 64;
213
214 // Allowed clock rates: 16, 32, 40 and 64
215 if ((clock != 16) && (clock != 32) && (clock != 64) && (clock != 40)) {
216 PrintAndLog("Error! Clock rate %d not valid. Supported clock rates are 16, 32, 40 and 64.\n", clock);
217 return 0;
218 }
219
220 if (card == 1) {
221 PrintAndLog("Writing %s tag with UID 0x%010" PRIx64 " (clock rate: %d)", "T55x7", id, clock);
222 // NOTE: We really should pass the clock in as a separate argument, but to
223 // provide for backwards-compatibility for older firmware, and to avoid
224 // having to add another argument to CMD_EM410X_WRITE_TAG, we just store
225 // the clock rate in bits 8-15 of the card value
226 card = (card & 0xFF) | ((clock << 8) & 0xFF00);
227 } else if (card == 0) {
228 PrintAndLog("Writing %s tag with UID 0x%010" PRIx64, "T5555", id, clock);
229 card = (card & 0xFF) | ((clock << 8) & 0xFF00);
230 } else {
231 PrintAndLog("Error! Bad card type selected.\n");
232 return 0;
233 }
234
235 UsbCommand c = {CMD_EM410X_WRITE_TAG, {card, (uint32_t)(id >> 32), (uint32_t)id}};
236 SendCommand(&c);
237
238 return 0;
239 }
240
241 //**************** Start of EM4x50 Code ************************
242 bool EM_EndParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t cols, uint8_t pType)
243 {
244 if (rows*cols>size) return false;
245 uint8_t colP=0;
246 //assume last col is a parity and do not test
247 for (uint8_t colNum = 0; colNum < cols-1; colNum++) {
248 for (uint8_t rowNum = 0; rowNum < rows; rowNum++) {
249 colP ^= BitStream[(rowNum*cols)+colNum];
250 }
251 if (colP != pType) return false;
252 }
253 return true;
254 }
255
256 bool EM_ByteParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t cols, uint8_t pType)
257 {
258 if (rows*cols>size) return false;
259 uint8_t rowP=0;
260 //assume last row is a parity row and do not test
261 for (uint8_t rowNum = 0; rowNum < rows-1; rowNum++) {
262 for (uint8_t colNum = 0; colNum < cols; colNum++) {
263 rowP ^= BitStream[(rowNum*cols)+colNum];
264 }
265 if (rowP != pType) return false;
266 }
267 return true;
268 }
269
270 uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool pTest)
271 {
272 if (size<45) return 0;
273 uint32_t code = bytebits_to_byte(BitStream,8);
274 code = code<<8 | bytebits_to_byte(BitStream+9,8);
275 code = code<<8 | bytebits_to_byte(BitStream+18,8);
276 code = code<<8 | bytebits_to_byte(BitStream+27,8);
277 if (verbose || g_debugMode){
278 for (uint8_t i = 0; i<5; i++){
279 if (i == 4) PrintAndLog(""); //parity byte spacer
280 PrintAndLog("%d%d%d%d%d%d%d%d %d -> 0x%02x",
281 BitStream[i*9],
282 BitStream[i*9+1],
283 BitStream[i*9+2],
284 BitStream[i*9+3],
285 BitStream[i*9+4],
286 BitStream[i*9+5],
287 BitStream[i*9+6],
288 BitStream[i*9+7],
289 BitStream[i*9+8],
290 bytebits_to_byte(BitStream+i*9,8)
291 );
292 }
293 if (pTest)
294 PrintAndLog("Parity Passed");
295 else
296 PrintAndLog("Parity Failed");
297 }
298 return code;
299 }
300 /* Read the transmitted data of an EM4x50 tag from the graphbuffer
301 * Format:
302 *
303 * XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
304 * XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
305 * XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
306 * XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
307 * CCCCCCCC <- column parity bits
308 * 0 <- stop bit
309 * LW <- Listen Window
310 *
311 * This pattern repeats for every block of data being transmitted.
312 * Transmission starts with two Listen Windows (LW - a modulated
313 * pattern of 320 cycles each (32/32/128/64/64)).
314 *
315 * Note that this data may or may not be the UID. It is whatever data
316 * is stored in the blocks defined in the control word First and Last
317 * Word Read values. UID is stored in block 32.
318 */
319 //completed by Marshmellow
320 int EM4x50Read(const char *Cmd, bool verbose)
321 {
322 uint8_t fndClk[] = {8,16,32,40,50,64,128};
323 int clk = 0;
324 int invert = 0;
325 int tol = 0;
326 int i, j, startblock, skip, block, start, end, low, high, minClk;
327 bool complete = false;
328 int tmpbuff[MAX_GRAPH_TRACE_LEN / 64];
329 uint32_t Code[6];
330 char tmp[6];
331 char tmp2[20];
332 int phaseoff;
333 high = low = 0;
334 memset(tmpbuff, 0, MAX_GRAPH_TRACE_LEN / 64);
335
336 // get user entry if any
337 sscanf(Cmd, "%i %i", &clk, &invert);
338
339 // save GraphBuffer - to restore it later
340 save_restoreGB(1);
341
342 // first get high and low values
343 for (i = 0; i < GraphTraceLen; i++) {
344 if (GraphBuffer[i] > high)
345 high = GraphBuffer[i];
346 else if (GraphBuffer[i] < low)
347 low = GraphBuffer[i];
348 }
349
350 i = 0;
351 j = 0;
352 minClk = 255;
353 // get to first full low to prime loop and skip incomplete first pulse
354 while ((GraphBuffer[i] < high) && (i < GraphTraceLen))
355 ++i;
356 while ((GraphBuffer[i] > low) && (i < GraphTraceLen))
357 ++i;
358 skip = i;
359
360 // populate tmpbuff buffer with pulse lengths
361 while (i < GraphTraceLen) {
362 // measure from low to low
363 while ((GraphBuffer[i] > low) && (i < GraphTraceLen))
364 ++i;
365 start= i;
366 while ((GraphBuffer[i] < high) && (i < GraphTraceLen))
367 ++i;
368 while ((GraphBuffer[i] > low) && (i < GraphTraceLen))
369 ++i;
370 if (j>=(MAX_GRAPH_TRACE_LEN/64)) {
371 break;
372 }
373 tmpbuff[j++]= i - start;
374 if (i-start < minClk && i < GraphTraceLen) {
375 minClk = i - start;
376 }
377 }
378 // set clock
379 if (!clk) {
380 for (uint8_t clkCnt = 0; clkCnt<7; clkCnt++) {
381 tol = fndClk[clkCnt]/8;
382 if (minClk >= fndClk[clkCnt]-tol && minClk <= fndClk[clkCnt]+1) {
383 clk=fndClk[clkCnt];
384 break;
385 }
386 }
387 if (!clk) return 0;
388 } else tol = clk/8;
389
390 // look for data start - should be 2 pairs of LW (pulses of clk*3,clk*2)
391 start = -1;
392 for (i= 0; i < j - 4 ; ++i) {
393 skip += tmpbuff[i];
394 if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) //3 clocks
395 if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) //2 clocks
396 if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) //3 clocks
397 if (tmpbuff[i+3] >= clk-tol) //1.5 to 2 clocks - depends on bit following
398 {
399 start= i + 4;
400 break;
401 }
402 }
403 startblock = i + 4;
404
405 // skip over the remainder of LW
406 skip += tmpbuff[i+1] + tmpbuff[i+2] + clk;
407 if (tmpbuff[i+3]>clk)
408 phaseoff = tmpbuff[i+3]-clk;
409 else
410 phaseoff = 0;
411 // now do it again to find the end
412 end = skip;
413 for (i += 3; i < j - 4 ; ++i) {
414 end += tmpbuff[i];
415 if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) //3 clocks
416 if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) //2 clocks
417 if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) //3 clocks
418 if (tmpbuff[i+3] >= clk-tol) //1.5 to 2 clocks - depends on bit following
419 {
420 complete= true;
421 break;
422 }
423 }
424 end = i;
425 // report back
426 if (verbose || g_debugMode) {
427 if (start >= 0) {
428 PrintAndLog("\nNote: one block = 50 bits (32 data, 12 parity, 6 marker)");
429 } else {
430 PrintAndLog("No data found!, clock tried:%d",clk);
431 PrintAndLog("Try again with more samples.");
432 PrintAndLog(" or after a 'data askedge' command to clean up the read");
433 return 0;
434 }
435 } else if (start < 0) return 0;
436 start = skip;
437 snprintf(tmp2, sizeof(tmp2),"%d %d 1000 %d", clk, invert, clk*47);
438 // get rid of leading crap
439 snprintf(tmp, sizeof(tmp), "%i", skip);
440 CmdLtrim(tmp);
441 bool pTest;
442 bool AllPTest = true;
443 // now work through remaining buffer printing out data blocks
444 block = 0;
445 i = startblock;
446 while (block < 6) {
447 if (verbose || g_debugMode) PrintAndLog("\nBlock %i:", block);
448 skip = phaseoff;
449
450 // look for LW before start of next block
451 for ( ; i < j - 4 ; ++i) {
452 skip += tmpbuff[i];
453 if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol)
454 if (tmpbuff[i+1] >= clk-tol)
455 break;
456 }
457 if (i >= j-4) break; //next LW not found
458 skip += clk;
459 if (tmpbuff[i+1]>clk)
460 phaseoff = tmpbuff[i+1]-clk;
461 else
462 phaseoff = 0;
463 i += 2;
464 if (ASKDemod(tmp2, false, false, 1) < 1) {
465 save_restoreGB(0);
466 return 0;
467 }
468 //set DemodBufferLen to just one block
469 DemodBufferLen = skip/clk;
470 //test parities
471 pTest = EM_ByteParityTest(DemodBuffer,DemodBufferLen,5,9,0);
472 pTest &= EM_EndParityTest(DemodBuffer,DemodBufferLen,5,9,0);
473 AllPTest &= pTest;
474 //get output
475 Code[block] = OutputEM4x50_Block(DemodBuffer,DemodBufferLen,verbose, pTest);
476 if (g_debugMode) PrintAndLog("\nskipping %d samples, bits:%d", skip, skip/clk);
477 //skip to start of next block
478 snprintf(tmp,sizeof(tmp),"%i",skip);
479 CmdLtrim(tmp);
480 block++;
481 if (i >= end) break; //in case chip doesn't output 6 blocks
482 }
483 //print full code:
484 if (verbose || g_debugMode || AllPTest){
485 if (!complete) {
486 PrintAndLog("*** Warning!");
487 PrintAndLog("Partial data - no end found!");
488 PrintAndLog("Try again with more samples.");
489 }
490 PrintAndLog("Found data at sample: %i - using clock: %i", start, clk);
491 end = block;
492 for (block=0; block < end; block++){
493 PrintAndLog("Block %d: %08x",block,Code[block]);
494 }
495 if (AllPTest) {
496 PrintAndLog("Parities Passed");
497 } else {
498 PrintAndLog("Parities Failed");
499 PrintAndLog("Try cleaning the read samples with 'data askedge'");
500 }
501 }
502
503 //restore GraphBuffer
504 save_restoreGB(0);
505 return (int)AllPTest;
506 }
507
508 int CmdEM4x50Read(const char *Cmd)
509 {
510 return EM4x50Read(Cmd, true);
511 }
512
513 //**************** Start of EM4x05/EM4x69 Code ************************
514 int usage_lf_em_read(void) {
515 PrintAndLog("Read EM4x05/EM4x69. Tag must be on antenna. ");
516 PrintAndLog("");
517 PrintAndLog("Usage: lf em 4x05readword [h] <address> <pwd>");
518 PrintAndLog("Options:");
519 PrintAndLog(" h - this help");
520 PrintAndLog(" address - memory address to read. (0-15)");
521 PrintAndLog(" pwd - password (hex) (optional)");
522 PrintAndLog("samples:");
523 PrintAndLog(" lf em 4x05readword 1");
524 PrintAndLog(" lf em 4x05readword 1 11223344");
525 return 0;
526 }
527
528 // for command responses from em4x05 or em4x69
529 // download samples from device and copy them to the Graphbuffer
530 bool downloadSamplesEM() {
531 // 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples)
532 uint8_t got[6000];
533 GetFromBigBuf(got, sizeof(got), 0);
534 if ( !WaitForResponseTimeout(CMD_ACK, NULL, 4000) ) {
535 PrintAndLog("command execution time out");
536 return false;
537 }
538 setGraphBuf(got, sizeof(got));
539 return true;
540 }
541
542 bool EM4x05testDemodReadData(uint32_t *word, bool readCmd) {
543 // em4x05/em4x69 command response preamble is 00001010
544 // skip first two 0 bits as they might have been missed in the demod
545 uint8_t preamble[] = {0,0,1,0,1,0};
546 size_t startIdx = 0;
547
548 // set size to 20 to only test first 14 positions for the preamble or less if not a read command
549 size_t size = (readCmd) ? 20 : 11;
550 // sanity check
551 size = (size > DemodBufferLen) ? DemodBufferLen : size;
552 // test preamble
553 if ( !preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx, true) ) {
554 if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx);
555 return false;
556 }
557 // if this is a readword command, get the read bytes and test the parities
558 if (readCmd) {
559 if (!EM_EndParityTest(DemodBuffer + startIdx + sizeof(preamble), 45, 5, 9, 0)) {
560 if (g_debugMode) PrintAndLog("DEBUG: Error - End Parity check failed");
561 return false;
562 }
563 // test for even parity bits and remove them. (leave out the end row of parities so 36 bits)
564 if ( removeParity(DemodBuffer, startIdx + sizeof(preamble),9,0,36) == 0 ) {
565 if (g_debugMode) PrintAndLog("DEBUG: Error - Parity not detected");
566 return false;
567 }
568
569 setDemodBuf(DemodBuffer, 32, 0);
570 *word = bytebits_to_byteLSBF(DemodBuffer, 32);
571 }
572 return true;
573 }
574
575 // FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE
576 // should cover 90% of known used configs
577 // the rest will need to be manually demoded for now...
578 int demodEM4x05resp(uint32_t *word, bool readCmd) {
579 int ans = 0;
580
581 // test for FSK wave (easiest to 99% ID)
582 if (GetFskClock("", false, false)) {
583 //valid fsk clocks found
584 ans = FSKrawDemod("0 0", false);
585 if (!ans) {
586 if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: FSK Demod failed, ans: %d", ans);
587 } else {
588 if (EM4x05testDemodReadData(word, readCmd)) {
589 return 1;
590 }
591 }
592 }
593 // PSK clocks should be easy to detect ( but difficult to demod a non-repeating pattern... )
594 ans = GetPskClock("", false, false);
595 if (ans>0) {
596 //try psk1
597 ans = PSKDemod("0 0 6", false);
598 if (!ans) {
599 if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: PSK1 Demod failed, ans: %d", ans);
600 } else {
601 if (EM4x05testDemodReadData(word, readCmd)) {
602 return 1;
603 } else {
604 //try psk2
605 psk1TOpsk2(DemodBuffer, DemodBufferLen);
606 if (EM4x05testDemodReadData(word, readCmd)) {
607 return 1;
608 }
609 }
610 //try psk1 inverted
611 ans = PSKDemod("0 1 6", false);
612 if (!ans) {
613 if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: PSK1 Demod failed, ans: %d", ans);
614 } else {
615 if (EM4x05testDemodReadData(word, readCmd)) {
616 return 1;
617 } else {
618 //try psk2
619 psk1TOpsk2(DemodBuffer, DemodBufferLen);
620 if (EM4x05testDemodReadData(word, readCmd)) {
621 return 1;
622 }
623 }
624 }
625 }
626 }
627
628 // manchester is more common than biphase... try first
629 bool stcheck = false;
630 // try manchester - NOTE: ST only applies to T55x7 tags.
631 ans = ASKDemod_ext("0,0,1", false, false, 1, &stcheck);
632 if (!ans) {
633 if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/Manchester Demod failed, ans: %d", ans);
634 } else {
635 if (EM4x05testDemodReadData(word, readCmd)) {
636 return 1;
637 }
638 }
639
640 //try biphase
641 ans = ASKbiphaseDemod("0 0 1", false);
642 if (!ans) {
643 if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/biphase Demod failed, ans: %d", ans);
644 } else {
645 if (EM4x05testDemodReadData(word, readCmd)) {
646 return 1;
647 }
648 }
649
650 //try diphase (differential biphase or inverted)
651 ans = ASKbiphaseDemod("0 1 1", false);
652 if (!ans) {
653 if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/biphase Demod failed, ans: %d", ans);
654 } else {
655 if (EM4x05testDemodReadData(word, readCmd)) {
656 return 1;
657 }
658 }
659
660 return -1;
661 }
662
663 int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t *wordData) {
664 UsbCommand c = {CMD_EM4X_READ_WORD, {addr, pwd, usePwd}};
665 clearCommandBuffer();
666 SendCommand(&c);
667 UsbCommand resp;
668 if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)){
669 PrintAndLog("Command timed out");
670 return -1;
671 }
672 if ( !downloadSamplesEM() ) {
673 return -1;
674 }
675 int testLen = (GraphTraceLen < 1000) ? GraphTraceLen : 1000;
676 if (graphJustNoise(GraphBuffer, testLen)) {
677 PrintAndLog("no tag not found");
678 return -1;
679 }
680 //attempt demod:
681 return demodEM4x05resp(wordData, true);
682 }
683
684 int EM4x05ReadWord(uint8_t addr, uint32_t pwd, bool usePwd) {
685 uint32_t wordData = 0;
686 int success = EM4x05ReadWord_ext(addr, pwd, usePwd, &wordData);
687 if (success == 1)
688 PrintAndLog("%s Address %02d | %08X", (addr>13) ? "Lock":" Got",addr,wordData);
689 else
690 PrintAndLog("Read Address %02d | failed",addr);
691
692 return success;
693 }
694
695 int CmdEM4x05ReadWord(const char *Cmd) {
696 uint8_t addr;
697 uint32_t pwd;
698 bool usePwd = false;
699 uint8_t ctmp = param_getchar(Cmd, 0);
700 if ( strlen(Cmd) == 0 || ctmp == 'H' || ctmp == 'h' ) return usage_lf_em_read();
701
702 addr = param_get8ex(Cmd, 0, 50, 10);
703 // for now use default input of 1 as invalid (unlikely 1 will be a valid password...)
704 pwd = param_get32ex(Cmd, 1, 1, 16);
705
706 if ( (addr > 15) ) {
707 PrintAndLog("Address must be between 0 and 15");
708 return 1;
709 }
710 if ( pwd == 1 ) {
711 PrintAndLog("Reading address %02u", addr);
712 } else {
713 usePwd = true;
714 PrintAndLog("Reading address %02u | password %08X", addr, pwd);
715 }
716
717 return EM4x05ReadWord(addr, pwd, usePwd);
718 }
719
720 int usage_lf_em_dump(void) {
721 PrintAndLog("Dump EM4x05/EM4x69. Tag must be on antenna. ");
722 PrintAndLog("");
723 PrintAndLog("Usage: lf em 4x05dump [h] <pwd>");
724 PrintAndLog("Options:");
725 PrintAndLog(" h - this help");
726 PrintAndLog(" pwd - password (hex) (optional)");
727 PrintAndLog("samples:");
728 PrintAndLog(" lf em 4x05dump");
729 PrintAndLog(" lf em 4x05dump 11223344");
730 return 0;
731 }
732
733 int CmdEM4x05dump(const char *Cmd) {
734 uint8_t addr = 0;
735 uint32_t pwd;
736 bool usePwd = false;
737 uint8_t ctmp = param_getchar(Cmd, 0);
738 if ( ctmp == 'H' || ctmp == 'h' ) return usage_lf_em_dump();
739
740 // for now use default input of 1 as invalid (unlikely 1 will be a valid password...)
741 pwd = param_get32ex(Cmd, 0, 1, 16);
742
743 if ( pwd != 1 ) {
744 usePwd = true;
745 }
746 int success = 1;
747 for (; addr < 16; addr++) {
748 if (addr == 2) {
749 if (usePwd) {
750 PrintAndLog(" PWD Address %02u | %08X",addr,pwd);
751 } else {
752 PrintAndLog(" PWD Address 02 | cannot read");
753 }
754 } else {
755 success &= EM4x05ReadWord(addr, pwd, usePwd);
756 }
757 }
758
759 return success;
760 }
761
762
763 int usage_lf_em_write(void) {
764 PrintAndLog("Write EM4x05/EM4x69. Tag must be on antenna. ");
765 PrintAndLog("");
766 PrintAndLog("Usage: lf em 4x05writeword [h] <address> <data> <pwd>");
767 PrintAndLog("Options:");
768 PrintAndLog(" h - this help");
769 PrintAndLog(" address - memory address to write to. (0-15)");
770 PrintAndLog(" data - data to write (hex)");
771 PrintAndLog(" pwd - password (hex) (optional)");
772 PrintAndLog("samples:");
773 PrintAndLog(" lf em 4x05writeword 1");
774 PrintAndLog(" lf em 4x05writeword 1 deadc0de 11223344");
775 return 0;
776 }
777
778 int CmdEM4x05WriteWord(const char *Cmd) {
779 uint8_t ctmp = param_getchar(Cmd, 0);
780 if ( strlen(Cmd) == 0 || ctmp == 'H' || ctmp == 'h' ) return usage_lf_em_write();
781
782 bool usePwd = false;
783
784 uint8_t addr = 16; // default to invalid address
785 uint32_t data = 0xFFFFFFFF; // default to blank data
786 uint32_t pwd = 0xFFFFFFFF; // default to blank password
787
788 addr = param_get8ex(Cmd, 0, 16, 10);
789 data = param_get32ex(Cmd, 1, 0, 16);
790 pwd = param_get32ex(Cmd, 2, 1, 16);
791
792
793 if ( (addr > 15) ) {
794 PrintAndLog("Address must be between 0 and 15");
795 return 1;
796 }
797 if ( pwd == 1 )
798 PrintAndLog("Writing address %d data %08X", addr, data);
799 else {
800 usePwd = true;
801 PrintAndLog("Writing address %d data %08X using password %08X", addr, data, pwd);
802 }
803
804 uint16_t flag = (addr << 8 ) | usePwd;
805
806 UsbCommand c = {CMD_EM4X_WRITE_WORD, {flag, data, pwd}};
807 clearCommandBuffer();
808 SendCommand(&c);
809 UsbCommand resp;
810 if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)){
811 PrintAndLog("Error occurred, device did not respond during write operation.");
812 return -1;
813 }
814 if ( !downloadSamplesEM() ) {
815 return -1;
816 }
817 //check response for 00001010 for write confirmation!
818 //attempt demod:
819 uint32_t dummy = 0;
820 int result = demodEM4x05resp(&dummy,false);
821 if (result == 1) {
822 PrintAndLog("Write Verified");
823 } else {
824 PrintAndLog("Write could not be verified");
825 }
826 return result;
827 }
828
829 void printEM4x05config(uint32_t wordData) {
830 uint16_t datarate = (((wordData & 0x3F)+1)*2);
831 uint8_t encoder = ((wordData >> 6) & 0xF);
832 char enc[14];
833 memset(enc,0,sizeof(enc));
834
835 uint8_t PSKcf = (wordData >> 10) & 0x3;
836 char cf[10];
837 memset(cf,0,sizeof(cf));
838 uint8_t delay = (wordData >> 12) & 0x3;
839 char cdelay[33];
840 memset(cdelay,0,sizeof(cdelay));
841 uint8_t LWR = (wordData >> 14) & 0xF; //last word read
842
843 switch (encoder) {
844 case 0: snprintf(enc,sizeof(enc),"NRZ"); break;
845 case 1: snprintf(enc,sizeof(enc),"Manchester"); break;
846 case 2: snprintf(enc,sizeof(enc),"Biphase"); break;
847 case 3: snprintf(enc,sizeof(enc),"Miller"); break;
848 case 4: snprintf(enc,sizeof(enc),"PSK1"); break;
849 case 5: snprintf(enc,sizeof(enc),"PSK2"); break;
850 case 6: snprintf(enc,sizeof(enc),"PSK3"); break;
851 case 7: snprintf(enc,sizeof(enc),"Unknown"); break;
852 case 8: snprintf(enc,sizeof(enc),"FSK1"); break;
853 case 9: snprintf(enc,sizeof(enc),"FSK2"); break;
854 default: snprintf(enc,sizeof(enc),"Unknown"); break;
855 }
856
857 switch (PSKcf) {
858 case 0: snprintf(cf,sizeof(cf),"RF/2"); break;
859 case 1: snprintf(cf,sizeof(cf),"RF/8"); break;
860 case 2: snprintf(cf,sizeof(cf),"RF/4"); break;
861 case 3: snprintf(cf,sizeof(cf),"unknown"); break;
862 }
863
864 switch (delay) {
865 case 0: snprintf(cdelay, sizeof(cdelay),"no delay"); break;
866 case 1: snprintf(cdelay, sizeof(cdelay),"BP/8 or 1/8th bit period delay"); break;
867 case 2: snprintf(cdelay, sizeof(cdelay),"BP/4 or 1/4th bit period delay"); break;
868 case 3: snprintf(cdelay, sizeof(cdelay),"no delay"); break;
869 }
870 PrintAndLog("ConfigWord: %08X (Word 4)\n", wordData);
871 PrintAndLog("Config Breakdown:", wordData);
872 PrintAndLog(" Data Rate: %02u | RF/%u", wordData & 0x3F, datarate);
873 PrintAndLog(" Encoder: %u | %s", encoder, enc);
874 PrintAndLog(" PSK CF: %u | %s", PSKcf, cf);
875 PrintAndLog(" Delay: %u | %s", delay, cdelay);
876 PrintAndLog(" LastWordR: %02u | Address of last word for default read", LWR);
877 PrintAndLog(" ReadLogin: %u | Read Login is %s", (wordData & 0x40000)>>18, (wordData & 0x40000) ? "Required" : "Not Required");
878 PrintAndLog(" ReadHKL: %u | Read Housekeeping Words Login is %s", (wordData & 0x80000)>>19, (wordData & 0x80000) ? "Required" : "Not Required");
879 PrintAndLog("WriteLogin: %u | Write Login is %s", (wordData & 0x100000)>>20, (wordData & 0x100000) ? "Required" : "Not Required");
880 PrintAndLog(" WriteHKL: %u | Write Housekeeping Words Login is %s", (wordData & 0x200000)>>21, (wordData & 0x200000) ? "Required" : "Not Required");
881 PrintAndLog(" R.A.W.: %u | Read After Write is %s", (wordData & 0x400000)>>22, (wordData & 0x400000) ? "On" : "Off");
882 PrintAndLog(" Disable: %u | Disable Command is %s", (wordData & 0x800000)>>23, (wordData & 0x800000) ? "Accepted" : "Not Accepted");
883 PrintAndLog(" R.T.F.: %u | Reader Talk First is %s", (wordData & 0x1000000)>>24, (wordData & 0x1000000) ? "Enabled" : "Disabled");
884 PrintAndLog(" Pigeon: %u | Pigeon Mode is %s\n", (wordData & 0x4000000)>>26, (wordData & 0x4000000) ? "Enabled" : "Disabled");
885 }
886
887 void printEM4x05info(uint8_t chipType, uint8_t cap, uint16_t custCode, uint32_t serial) {
888 switch (chipType) {
889 case 9: PrintAndLog("\n Chip Type: %u | EM4305", chipType); break;
890 case 4: PrintAndLog(" Chip Type: %u | Unknown", chipType); break;
891 case 2: PrintAndLog(" Chip Type: %u | EM4469", chipType); break;
892 //add more here when known
893 default: PrintAndLog(" Chip Type: %u Unknown", chipType); break;
894 }
895
896 switch (cap) {
897 case 3: PrintAndLog(" Cap Type: %u | 330pF",cap); break;
898 case 2: PrintAndLog(" Cap Type: %u | %spF",cap, (chipType==2)? "75":"210"); break;
899 case 1: PrintAndLog(" Cap Type: %u | 250pF",cap); break;
900 case 0: PrintAndLog(" Cap Type: %u | no resonant capacitor",cap); break;
901 default: PrintAndLog(" Cap Type: %u | unknown",cap); break;
902 }
903
904 PrintAndLog(" Cust Code: %03u | %s", custCode, (custCode == 0x200) ? "Default": "Unknown");
905 if (serial != 0) {
906 PrintAndLog("\n Serial #: %08X\n", serial);
907 }
908 }
909
910 void printEM4x05ProtectionBits(uint32_t wordData) {
911 for (uint8_t i = 0; i < 15; i++) {
912 PrintAndLog(" Word: %02u | %s", i, (((1 << i) & wordData ) || i < 2) ? "Is Write Locked" : "Is Not Write Locked");
913 if (i==14) {
914 PrintAndLog(" Word: %02u | %s", i+1, (((1 << i) & wordData ) || i < 2) ? "Is Write Locked" : "Is Not Write Locked");
915 }
916 }
917 }
918
919 //quick test for EM4x05/EM4x69 tag
920 bool EM4x05Block0Test(uint32_t *wordData) {
921 if (EM4x05ReadWord_ext(0,0,false,wordData) == 1) {
922 return true;
923 }
924 return false;
925 }
926
927 int CmdEM4x05info(const char *Cmd) {
928 //uint8_t addr = 0;
929 uint32_t pwd;
930 uint32_t wordData = 0;
931 bool usePwd = false;
932 uint8_t ctmp = param_getchar(Cmd, 0);
933 if ( ctmp == 'H' || ctmp == 'h' ) return usage_lf_em_dump();
934
935 // for now use default input of 1 as invalid (unlikely 1 will be a valid password...)
936 pwd = param_get32ex(Cmd, 0, 1, 16);
937
938 if ( pwd != 1 ) {
939 usePwd = true;
940 }
941
942 // read word 0 (chip info)
943 // block 0 can be read even without a password.
944 if ( !EM4x05Block0Test(&wordData) )
945 return -1;
946
947 uint8_t chipType = (wordData >> 1) & 0xF;
948 uint8_t cap = (wordData >> 5) & 3;
949 uint16_t custCode = (wordData >> 9) & 0x3FF;
950
951 // read word 1 (serial #) doesn't need pwd
952 wordData = 0;
953 if (EM4x05ReadWord_ext(1, 0, false, &wordData) != 1) {
954 //failed, but continue anyway...
955 }
956 printEM4x05info(chipType, cap, custCode, wordData);
957
958 // read word 4 (config block)
959 // needs password if one is set
960 wordData = 0;
961 if ( EM4x05ReadWord_ext(4, pwd, usePwd, &wordData) != 1 ) {
962 //failed
963 return 0;
964 }
965 printEM4x05config(wordData);
966
967 // read word 14 and 15 to see which is being used for the protection bits
968 wordData = 0;
969 if ( EM4x05ReadWord_ext(14, pwd, usePwd, &wordData) != 1 ) {
970 //failed
971 return 0;
972 }
973 // if status bit says this is not the used protection word
974 if (!(wordData & 0x8000)) {
975 if ( EM4x05ReadWord_ext(15, pwd, usePwd, &wordData) != 1 ) {
976 //failed
977 return 0;
978 }
979 }
980 if (!(wordData & 0x8000)) {
981 //something went wrong
982 return 0;
983 }
984 printEM4x05ProtectionBits(wordData);
985
986 return 1;
987 }
988
989
990 static command_t CommandTable[] =
991 {
992 {"help", CmdHelp, 1, "This help"},
993 {"410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},
994 {"410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag in GraphBuffer"},
995 {"410xsim", CmdEM410xSim, 0, "<UID> [clock rate] -- Simulate EM410x tag"},
996 {"410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
997 {"410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
998 {"410xwrite", CmdEM410xWrite, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
999 {"4x05dump", CmdEM4x05dump, 0, "(pwd) -- Read EM4x05/EM4x69 all word data"},
1000 {"4x05info", CmdEM4x05info, 0, "(pwd) -- Get info from EM4x05/EM4x69 tag"},
1001 {"4x05readword", CmdEM4x05ReadWord, 0, "<Word> (pwd) -- Read EM4x05/EM4x69 word data"},
1002 {"4x05writeword", CmdEM4x05WriteWord, 0, "<Word> <data> (pwd) -- Write EM4x05/EM4x69 word data"},
1003 {"4x50read", CmdEM4x50Read, 1, "demod data from EM4x50 tag from the graph buffer"},
1004 {NULL, NULL, 0, NULL}
1005 };
1006
1007 int CmdLFEM4X(const char *Cmd)
1008 {
1009 CmdsParse(CommandTable, Cmd);
1010 return 0;
1011 }
1012
1013 int CmdHelp(const char *Cmd)
1014 {
1015 CmdsHelp(CommandTable);
1016 return 0;
1017 }
Impressum, Datenschutz