]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmf.c
added functionality: dump card memory, save|load card memory.
[proxmark3-svn] / client / cmdhfmf.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2011 Merlok
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 // High frequency MIFARE commands
9 //-----------------------------------------------------------------------------
10
11 #include "cmdhfmf.h"
12 #include "proxmark3.h"
13
14 static int CmdHelp(const char *Cmd);
15
16
17 int CmdHF14AMifare(const char *Cmd)
18 {
19 uint32_t uid = 0;
20 uint32_t nt = 0;
21 uint64_t par_list = 0, ks_list = 0, r_key = 0;
22 uint8_t isOK = 0;
23 uint8_t keyBlock[6] = {0,0,0,0,0,0};
24
25 if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, keyBlock, 8)) {
26 PrintAndLog("Nt must include 8 HEX symbols");
27 return 1;
28 }
29
30 UsbCommand c = {CMD_READER_MIFARE, {(uint32_t)bytes_to_num(keyBlock, 4), 0, 0}};
31 SendCommand(&c);
32
33 //flush queue
34 while (ukbhit()) getchar();
35
36 // message
37 printf("-------------------------------------------------------------------------\n");
38 printf("Executing command. It may take up to 30 min.\n");
39 printf("Press the key on proxmark3 device to abort proxmark3.\n");
40 printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");
41 printf("-------------------------------------------------------------------------\n");
42
43 // wait cycle
44 while (true) {
45 printf(".");
46 if (ukbhit()) {
47 getchar();
48 printf("\naborted via keyboard!\n");
49 break;
50 }
51
52 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);
53 if (resp != NULL) {
54 isOK = resp->arg[0] & 0xff;
55
56 uid = (uint32_t)bytes_to_num(resp->d.asBytes + 0, 4);
57 nt = (uint32_t)bytes_to_num(resp->d.asBytes + 4, 4);
58 par_list = bytes_to_num(resp->d.asBytes + 8, 8);
59 ks_list = bytes_to_num(resp->d.asBytes + 16, 8);
60
61 printf("\n\n");
62 PrintAndLog("isOk:%02x", isOK);
63 if (!isOK) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n");
64 break;
65 }
66 }
67 printf("\n");
68
69 // error
70 if (isOK != 1) return 1;
71
72 // execute original function from util nonce2key
73 if (nonce2key(uid, nt, par_list, ks_list, &r_key)) return 2;
74 printf("------------------------------------------------------------------\n");
75 PrintAndLog("Key found:%012llx \n", r_key);
76
77 num_to_bytes(r_key, 6, keyBlock);
78 isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key);
79 if (!isOK)
80 PrintAndLog("Found valid key:%012llx", r_key);
81 else
82 PrintAndLog("Found invalid key. ( Nt=%08x", nt);
83
84
85 return 0;
86 }
87
88 int CmdHF14AMfWrBl(const char *Cmd)
89 {
90 uint8_t blockNo = 0;
91 uint8_t keyType = 0;
92 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
93 uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
94
95 char cmdp = 0x00;
96
97 if (strlen(Cmd)<3) {
98 PrintAndLog("Usage: hf mf wrbl <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");
99 PrintAndLog(" sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");
100 return 0;
101 }
102
103 blockNo = param_get8(Cmd, 0);
104 cmdp = param_getchar(Cmd, 1);
105 if (cmdp == 0x00) {
106 PrintAndLog("Key type must be A or B");
107 return 1;
108 }
109 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
110 if (param_gethex(Cmd, 2, key, 12)) {
111 PrintAndLog("Key must include 12 HEX symbols");
112 return 1;
113 }
114 if (param_gethex(Cmd, 3, bldata, 32)) {
115 PrintAndLog("Block data must include 32 HEX symbols");
116 return 1;
117 }
118 PrintAndLog("--block no:%02x key type:%02x key:%s", blockNo, keyType, sprint_hex(key, 6));
119 PrintAndLog("--data: %s", sprint_hex(bldata, 16));
120
121 UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};
122 memcpy(c.d.asBytes, key, 6);
123 memcpy(c.d.asBytes + 10, bldata, 16);
124 SendCommand(&c);
125 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
126
127 if (resp != NULL) {
128 uint8_t isOK = resp->arg[0] & 0xff;
129
130 PrintAndLog("isOk:%02x", isOK);
131 } else {
132 PrintAndLog("Command execute timeout");
133 }
134
135 return 0;
136 }
137
138 int CmdHF14AMfRdBl(const char *Cmd)
139 {
140 uint8_t blockNo = 0;
141 uint8_t keyType = 0;
142 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
143
144 char cmdp = 0x00;
145
146
147 if (strlen(Cmd)<3) {
148 PrintAndLog("Usage: hf mf rdbl <block number> <key A/B> <key (12 hex symbols)>");
149 PrintAndLog(" sample: hf mf rdbl 0 A FFFFFFFFFFFF ");
150 return 0;
151 }
152
153 blockNo = param_get8(Cmd, 0);
154 cmdp = param_getchar(Cmd, 1);
155 if (cmdp == 0x00) {
156 PrintAndLog("Key type must be A or B");
157 return 1;
158 }
159 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
160 if (param_gethex(Cmd, 2, key, 12)) {
161 PrintAndLog("Key must include 12 HEX symbols");
162 return 1;
163 }
164 PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6));
165
166 UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};
167 memcpy(c.d.asBytes, key, 6);
168 SendCommand(&c);
169 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
170
171 if (resp != NULL) {
172 uint8_t isOK = resp->arg[0] & 0xff;
173 uint8_t * data = resp->d.asBytes;
174
175 if (isOK)
176 PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));
177 else
178 PrintAndLog("isOk:%02x", isOK);
179 } else {
180 PrintAndLog("Command execute timeout");
181 }
182
183 return 0;
184 }
185
186 int CmdHF14AMfRdSc(const char *Cmd)
187 {
188 int i;
189 uint8_t sectorNo = 0;
190 uint8_t keyType = 0;
191 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
192
193 uint8_t isOK = 0;
194 uint8_t * data = NULL;
195
196 char cmdp = 0x00;
197
198 if (strlen(Cmd)<3) {
199 PrintAndLog("Usage: hf mf rdsc <sector number> <key A/B> <key (12 hex symbols)>");
200 PrintAndLog(" sample: hf mf rdsc 0 A FFFFFFFFFFFF ");
201 return 0;
202 }
203
204 sectorNo = param_get8(Cmd, 0);
205 if (sectorNo > 63) {
206 PrintAndLog("Sector number must be less than 64");
207 return 1;
208 }
209 cmdp = param_getchar(Cmd, 1);
210 if (cmdp == 0x00) {
211 PrintAndLog("Key type must be A or B");
212 return 1;
213 }
214 if (cmdp != 'A' && cmdp != 'a') keyType = 1;
215 if (param_gethex(Cmd, 2, key, 12)) {
216 PrintAndLog("Key must include 12 HEX symbols");
217 return 1;
218 }
219 PrintAndLog("--sector no:%02x key type:%02x key:%s ", sectorNo, keyType, sprint_hex(key, 6));
220
221 UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};
222 memcpy(c.d.asBytes, key, 6);
223 SendCommand(&c);
224 UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
225 PrintAndLog(" ");
226
227 if (resp != NULL) {
228 isOK = resp->arg[0] & 0xff;
229 data = resp->d.asBytes;
230
231 PrintAndLog("isOk:%02x", isOK);
232 if (isOK)
233 for (i = 0; i < 2; i++) {
234 PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
235 }
236 } else {
237 PrintAndLog("Command1 execute timeout");
238 }
239
240 // response2
241 resp = WaitForResponseTimeout(CMD_ACK, 500);
242 PrintAndLog(" ");
243
244 if (resp != NULL) {
245 isOK = resp->arg[0] & 0xff;
246 data = resp->d.asBytes;
247
248 if (isOK)
249 for (i = 0; i < 2; i++) {
250 PrintAndLog("data:%s", sprint_hex(data + i * 16, 16));
251 }
252 } else {
253 PrintAndLog("Command2 execute timeout");
254 }
255
256 return 0;
257 }
258
259 int CmdHF14AMfNested(const char *Cmd)
260 {
261 int i, j, res, iterations;
262 sector * e_sector = NULL;
263 uint8_t blockNo = 0;
264 uint8_t keyType = 0;
265 uint8_t trgBlockNo = 0;
266 uint8_t trgKeyType = 0;
267 uint8_t blDiff = 0;
268 int SectorsCnt = 0;
269 uint8_t key[6] = {0, 0, 0, 0, 0, 0};
270 uint8_t keyBlock[16 * 6];
271 uint64_t key64 = 0;
272 int transferToEml = 0;
273
274 char cmdp, ctmp;
275
276 if (strlen(Cmd)<3) {
277 PrintAndLog("Usage:");
278 PrintAndLog(" all sectors: hf mf nested <card memory> <block number> <key A/B> <key (12 hex symbols)> [t]");
279 PrintAndLog(" one sector: hf mf nested o <block number> <key A/B> <key (12 hex symbols)> [t]");
280 PrintAndLog(" <target block number> <target key A/B>");
281 PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
282 PrintAndLog("t - transfer keys into emulator memory");
283 PrintAndLog(" ");
284 PrintAndLog(" sample1: hf mf nested 1 0 A FFFFFFFFFFFF ");
285 PrintAndLog(" sample1: hf mf nested 1 0 A FFFFFFFFFFFF t ");
286 PrintAndLog(" sample2: hf mf nested o 0 A FFFFFFFFFFFF 4 A");
287 return 0;
288 }
289
290 cmdp = param_getchar(Cmd, 0);
291 blockNo = param_get8(Cmd, 1);
292 ctmp = param_getchar(Cmd, 2);
293 if (ctmp == 0x00) {
294 PrintAndLog("Key type must be A or B");
295 return 1;
296 }
297 if (ctmp != 'A' && ctmp != 'a') keyType = 1;
298 if (param_gethex(Cmd, 3, key, 12)) {
299 PrintAndLog("Key must include 12 HEX symbols");
300 return 1;
301 }
302
303 if (cmdp == 'o' || cmdp == 'O') {
304 cmdp = 'o';
305 trgBlockNo = param_get8(Cmd, 4);
306 ctmp = param_getchar(Cmd, 5);
307 if (ctmp == 0x00) {
308 PrintAndLog("Target key type must be A or B");
309 return 1;
310 }
311 if (ctmp != 'A' && ctmp != 'a') trgKeyType = 1;
312 } else {
313 switch (cmdp) {
314 case '0': SectorsCnt = 05; break;
315 case '1': SectorsCnt = 16; break;
316 case '2': SectorsCnt = 32; break;
317 case '4': SectorsCnt = 64; break;
318 default: SectorsCnt = 16;
319 }
320 }
321
322 ctmp = param_getchar(Cmd, 4);
323 if (ctmp == 't' || ctmp == 'T') transferToEml = 1;
324 ctmp = param_getchar(Cmd, 6);
325 transferToEml |= (ctmp == 't' || ctmp == 'T');
326
327 PrintAndLog("--block no:%02x key type:%02x key:%s etrans:%d", blockNo, keyType, sprint_hex(key, 6), transferToEml);
328 if (cmdp == 'o')
329 PrintAndLog("--target block no:%02x target key type:%02x ", trgBlockNo, trgKeyType);
330
331 if (cmdp == 'o') {
332 if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock)) {
333 PrintAndLog("Nested error.");
334 return 2;
335 }
336
337 for (i = 0; i < 16; i++) {
338 PrintAndLog("cnt=%d key= %s", i, sprint_hex(keyBlock + i * 6, 6));
339 }
340
341 // test keys
342 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);
343 if (res)
344 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
345 if (!res) {
346 PrintAndLog("Found valid key:%012llx", key64);
347
348 // transfer key to the emulator
349 if (transferToEml) {
350 mfEmlGetMem(keyBlock, (trgBlockNo / 4) * 4 + 3, 1);
351
352 if (!trgKeyType)
353 num_to_bytes(key64, 6, keyBlock);
354 else
355 num_to_bytes(key64, 6, &keyBlock[10]);
356 mfEmlSetMem(keyBlock, (trgBlockNo / 4) * 4 + 3, 1);
357 }
358 } else {
359 PrintAndLog("No valid key found");
360 }
361 } else // ------------------------------------ multiple sectors working
362 {
363 blDiff = blockNo % 4;
364 PrintAndLog("Block shift=%d", blDiff);
365 e_sector = calloc(SectorsCnt, sizeof(sector));
366 if (e_sector == NULL) return 1;
367
368 //test current key 4 sectors
369 memcpy(keyBlock, key, 6);
370 num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 1 * 6));
371 num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 2 * 6));
372 num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock + 3 * 6));
373 num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock + 4 * 6));
374 num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 5 * 6));
375
376 PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt);
377 for (i = 0; i < SectorsCnt; i++) {
378 for (j = 0; j < 2; j++) {
379 if (e_sector[i].foundKey[j]) continue;
380
381 res = mfCheckKeys(i * 4 + blDiff, j, 6, keyBlock, &key64);
382
383 if (!res) {
384 e_sector[i].Key[j] = key64;
385 e_sector[i].foundKey[j] = 1;
386 }
387 }
388 }
389
390
391 // nested sectors
392 iterations = 0;
393 PrintAndLog("nested...");
394 for (i = 0; i < NESTED_SECTOR_RETRY; i++) {
395 for (trgBlockNo = blDiff; trgBlockNo < SectorsCnt * 4; trgBlockNo = trgBlockNo + 4)
396 for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) {
397 if (e_sector[trgBlockNo / 4].foundKey[trgKeyType]) continue;
398 if (mfnested(blockNo, keyType, key, trgBlockNo, trgKeyType, keyBlock)) continue;
399
400 iterations++;
401
402 //try keys from nested
403 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, keyBlock, &key64);
404 if (res)
405 res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
406 if (!res) {
407 PrintAndLog("Found valid key:%012llx", key64);
408 e_sector[trgBlockNo / 4].foundKey[trgKeyType] = 1;
409 e_sector[trgBlockNo / 4].Key[trgKeyType] = key64;
410 }
411 }
412 }
413
414 PrintAndLog("Iterations count: %d", iterations);
415 //print them
416 PrintAndLog("|---|----------------|---|----------------|---|");
417 PrintAndLog("|sec|key A |res|key B |res|");
418 PrintAndLog("|---|----------------|---|----------------|---|");
419 for (i = 0; i < SectorsCnt; i++) {
420 PrintAndLog("|%03d| %012llx | %d | %012llx | %d |", i,
421 e_sector[i].Key[0], e_sector[i].foundKey[0], e_sector[i].Key[1], e_sector[i].foundKey[1]);
422 }
423 PrintAndLog("|---|----------------|---|----------------|---|");
424
425 // transfer them to the emulator
426 if (transferToEml) {
427 for (i = 0; i < SectorsCnt; i++) {
428 mfEmlGetMem(keyBlock, i * 4 + 3, 1);
429 if (e_sector[i].foundKey[0])
430 num_to_bytes(e_sector[i].Key[0], 6, keyBlock);
431 if (e_sector[i].foundKey[1])
432 num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]);
433 mfEmlSetMem(keyBlock, i * 4 + 3, 1);
434 }
435 }
436
437 free(e_sector);
438 }
439
440 return 0;
441 }
442
443 int CmdHF14AMfChk(const char *Cmd)
444 {
445 int i, res;
446 int keycnt = 0;
447 char ctmp = 0x00;
448 uint8_t blockNo = 0;
449 uint8_t keyType = 0;
450 uint8_t keyBlock[8 * 6];
451 uint64_t key64 = 0;
452
453 memset(keyBlock, 0x00, sizeof(keyBlock));
454
455 if (strlen(Cmd)<3) {
456 PrintAndLog("Usage: hf mf chk <block number> <key A/B> [<key (12 hex symbols)>]");
457 PrintAndLog(" sample: hf mf chk 0 A FFFFFFFFFFFF a0a1a2a3a4a5 b01b2b3b4b5 ");
458 return 0;
459 }
460
461 blockNo = param_get8(Cmd, 0);
462 ctmp = param_getchar(Cmd, 1);
463 if (ctmp == 0x00) {
464 PrintAndLog("Key type must be A or B");
465 return 1;
466 }
467 if (ctmp != 'A' && ctmp != 'a') keyType = 1;
468
469 for (i = 0; i < 6; i++) {
470 if (!isxdigit(param_getchar(Cmd, 2 + i))) break;
471
472 if (param_gethex(Cmd, 2 + i, keyBlock + 6 * i, 12)) {
473 PrintAndLog("Key[%d] must include 12 HEX symbols", i);
474 return 1;
475 }
476 keycnt = i + 1;
477 }
478
479 if (keycnt == 0) {
480 PrintAndLog("There is must be at least one key");
481 return 1;
482 }
483
484 PrintAndLog("--block no:%02x key type:%02x key count:%d ", blockNo, keyType, keycnt);
485
486 res = mfCheckKeys(blockNo, keyType, keycnt, keyBlock, &key64);
487 if (res !=1) {
488 if (!res)
489 PrintAndLog("isOk:%02x valid key:%012llx", 1, key64);
490 else
491 PrintAndLog("isOk:%02x", 0);
492 } else {
493 PrintAndLog("Command execute timeout");
494 }
495
496 return 0;
497 }
498
499 int CmdHF14AMf1kSim(const char *Cmd)
500 {
501 uint8_t uid[4] = {0, 0, 0, 0};
502
503 if (param_getchar(Cmd, 0) == 'h') {
504 PrintAndLog("Usage: hf mf sim <uid (8 hex symbols)>");
505 PrintAndLog(" sample: hf mf sim 0a0a0a0a ");
506 return 0;
507 }
508
509 if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 8)) {
510 PrintAndLog("UID must include 8 HEX symbols");
511 return 1;
512 }
513 PrintAndLog(" uid:%s ", sprint_hex(uid, 4));
514
515 UsbCommand c = {CMD_SIMULATE_MIFARE_CARD, {0, 0, 0}};
516 memcpy(c.d.asBytes, uid, 4);
517 SendCommand(&c);
518
519 return 0;
520 }
521
522 int CmdHF14AMfDbg(const char *Cmd)
523 {
524 int dbgMode = param_get32ex(Cmd, 0, 0, 10);
525 if (dbgMode > 4) {
526 PrintAndLog("Max debud mode parameter is 4 \n");
527 }
528
529 if (strlen(Cmd) < 1 || !param_getchar(Cmd, 0) || dbgMode > 4) {
530 PrintAndLog("Usage: hf mf dbg <debug level>");
531 PrintAndLog(" 0 - no debug messages");
532 PrintAndLog(" 1 - error messages");
533 PrintAndLog(" 2 - all messages");
534 PrintAndLog(" 4 - extended debug mode");
535 return 0;
536 }
537
538 UsbCommand c = {CMD_MIFARE_SET_DBGMODE, {dbgMode, 0, 0}};
539 SendCommand(&c);
540
541 return 0;
542 }
543
544 int CmdHF14AMfEGet(const char *Cmd)
545 {
546 uint8_t blockNo = 0;
547 uint8_t data[3 * 16];
548 int i;
549
550 if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
551 PrintAndLog("Usage: hf mf eget <block number>");
552 PrintAndLog(" sample: hf mf eget 0 ");
553 return 0;
554 }
555
556 blockNo = param_get8(Cmd, 0);
557 if (blockNo >= 16 * 4) {
558 PrintAndLog("Block number must be in [0..63] as in MIFARE classic.");
559 return 1;
560 }
561
562 PrintAndLog(" ");
563 if (!mfEmlGetMem(data, blockNo, 3)) {
564 for (i = 0; i < 3; i++) {
565 PrintAndLog("data[%d]:%s", blockNo + i, sprint_hex(data + i * 16, 16));
566 }
567 } else {
568 PrintAndLog("Command execute timeout");
569 }
570
571 return 0;
572 }
573
574 int CmdHF14AMfEClear(const char *Cmd)
575 {
576 if (param_getchar(Cmd, 0) == 'h') {
577 PrintAndLog("Usage: hf mf eclr");
578 PrintAndLog("It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF \n");
579 return 0;
580 }
581
582 UsbCommand c = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};
583 SendCommand(&c);
584 return 0;
585 }
586
587 int CmdHF14AMfESet(const char *Cmd)
588 {
589 uint8_t memBlock[16];
590 uint8_t blockNo = 0;
591
592 memset(memBlock, 0x00, sizeof(memBlock));
593
594 if (strlen(Cmd) < 3 || param_getchar(Cmd, 0) == 'h') {
595 PrintAndLog("Usage: hf mf eset <block number> <block data (32 hex symbols)>");
596 PrintAndLog(" sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f ");
597 return 0;
598 }
599
600 blockNo = param_get8(Cmd, 0);
601 if (blockNo >= 16 * 4) {
602 PrintAndLog("Block number must be in [0..63] as in MIFARE classic.");
603 return 1;
604 }
605
606 if (param_gethex(Cmd, 1, memBlock, 32)) {
607 PrintAndLog("block data must include 32 HEX symbols");
608 return 1;
609 }
610
611 // 1 - blocks count
612 UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNo, 1, 0}};
613 memcpy(c.d.asBytes, memBlock, 16);
614 SendCommand(&c);
615 return 0;
616 }
617
618 int CmdHF14AMfELoad(const char *Cmd)
619 {
620 FILE * f;
621 char filename[20];
622 char * fnameptr = filename;
623 char buf[64];
624 uint8_t buf8[64];
625 int i, len, blockNum;
626
627 memset(filename, 0, sizeof(filename));
628 memset(buf, 0, sizeof(buf));
629
630 if (param_getchar(Cmd, 0) == 'h') {
631 PrintAndLog("It loads emul dump from the file `filename.eml`");
632 PrintAndLog("Usage: hf mf eload <file name w/o `.eml`>");
633 PrintAndLog(" sample: hf mf eload filename");
634 return 0;
635 }
636
637 len = strlen(Cmd);
638 if (len > 14) len = 14;
639
640 if (len < 1) {
641 }
642
643 memcpy(filename, Cmd, len);
644 fnameptr += len;
645
646 sprintf(fnameptr, ".eml");
647
648 // open file
649 f = fopen(filename, "r");
650 if (f == NULL) {
651 PrintAndLog("File not found or locked.");
652 return 1;
653 }
654
655 blockNum = 0;
656 while(!feof(f)){
657 memset(buf, 0, sizeof(buf));
658 fgets(buf, sizeof(buf), f);
659 if (strlen(buf) < 32){
660 PrintAndLog("File content error. Block data must include 32 HEX symbols");
661 return 2;
662 }
663 for (i = 0; i < 32; i += 2)
664 sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
665 // PrintAndLog("data[%02d]:%s", blockNum, sprint_hex(buf8, 16));
666
667 if (mfEmlSetMem(buf8, blockNum, 1)) {
668 PrintAndLog("Cant set emul block: %d", blockNum);
669 return 3;
670 }
671 blockNum++;
672
673 if (blockNum >= 16 * 4) break;
674 }
675 fclose(f);
676
677 if (blockNum != 16 * 4){
678 PrintAndLog("File content error. There must be 64 blocks");
679 return 4;
680 }
681 PrintAndLog("Loaded from file: %s", filename);
682 return 0;
683 }
684
685 int CmdHF14AMfESave(const char *Cmd)
686 {
687 FILE * f;
688 char filename[20];
689 char * fnameptr = filename;
690 uint8_t buf[64];
691 int i, j, len;
692
693 memset(filename, 0, sizeof(filename));
694 memset(buf, 0, sizeof(buf));
695
696 if (param_getchar(Cmd, 0) == 'h') {
697 PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`");
698 PrintAndLog("Usage: hf mf esave [file name w/o `.eml`]");
699 PrintAndLog(" sample: hf mf esave ");
700 PrintAndLog(" hf mf esave filename");
701 return 0;
702 }
703
704 len = strlen(Cmd);
705 if (len > 14) len = 14;
706
707 if (len < 1) {
708 // get filename
709 if (mfEmlGetMem(buf, 0, 1)) {
710 PrintAndLog("Cant get block: %d", 0);
711 return 1;
712 }
713 for (j = 0; j < 7; j++, fnameptr += 2)
714 sprintf(fnameptr, "%02x", buf[j]);
715 } else {
716 memcpy(filename, Cmd, len);
717 fnameptr += len;
718 }
719
720 sprintf(fnameptr, ".eml");
721
722 // open file
723 f = fopen(filename, "w+");
724
725 // put hex
726 for (i = 0; i < 16 * 4; i++) {
727 if (mfEmlGetMem(buf, i, 1)) {
728 PrintAndLog("Cant get block: %d", i);
729 break;
730 }
731 for (j = 0; j < 16; j++)
732 fprintf(f, "%02x", buf[j]);
733 fprintf(f,"\n");
734 }
735 fclose(f);
736
737 PrintAndLog("Saved to file: %s", filename);
738
739 return 0;
740 }
741
742 int CmdHF14AMfECFill(const char *Cmd) {
743 uint8_t keyType = 0;
744
745 if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
746 PrintAndLog("Usage: hf mf efill <key A/B>");
747 PrintAndLog("sample: hf mf efill A");
748 PrintAndLog("Card data blocks transfers to card emulator memory.");
749 PrintAndLog("Keys must be laid in the simulator memory. \n");
750 return 0;
751 }
752
753 char ctmp = param_getchar(Cmd, 0);
754 if (ctmp == 0x00) {
755 PrintAndLog("Key type must be A or B");
756 return 1;
757 }
758 if (ctmp != 'A' && ctmp != 'a') keyType = 1;
759
760 UsbCommand c = {CMD_MIFARE_EML_CARDLOAD, {0, keyType, 0}};
761 SendCommand(&c);
762 return 0;
763 }
764
765 int CmdHF14AMfEKeyPrn(const char *Cmd) {
766 int i;
767 uint8_t data[16];
768 uint64_t keyA, keyB;
769
770 PrintAndLog("|---|----------------|----------------|");
771 PrintAndLog("|sec|key A |key B |");
772 PrintAndLog("|---|----------------|----------------|");
773 for (i = 0; i < 16; i++) {
774 if (mfEmlGetMem(data, i * 4 + 3, 1)) {
775 PrintAndLog("error get block %d", i * 4 + 3);
776 break;
777 }
778 keyA = bytes_to_num(data, 6);
779 keyB = bytes_to_num(data + 10, 6);
780 PrintAndLog("|%03d| %012llx | %012llx |", i, keyA, keyB);
781 }
782 PrintAndLog("|---|----------------|----------------|");
783
784 return 0;
785 }
786
787 static command_t CommandTable[] =
788 {
789 {"help", CmdHelp, 1, "This help"},
790 {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
791 {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},
792 {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},
793 {"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},
794 {"chk", CmdHF14AMfChk, 0, "Test block up to 8 keys"},
795 {"mifare", CmdHF14AMifare, 0, "Read parity error messages. param - <used card nonce>"},
796 {"nested", CmdHF14AMfNested, 0, "Test nested authentication"},
797 {"sim", CmdHF14AMf1kSim, 0, "Simulate MIFARE 1k card"},
798 {"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory block"},
799 {"eget", CmdHF14AMfEGet, 0, "Set simulator memory block"},
800 {"eset", CmdHF14AMfESet, 0, "Get simulator memory block"},
801 {"eload", CmdHF14AMfELoad, 0, "Load from file emul dump"},
802 {"esave", CmdHF14AMfESave, 0, "Save to file emul dump"},
803 {"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"},
804 {"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"},
805 {NULL, NULL, 0, NULL}
806 };
807
808 int CmdHFMF(const char *Cmd)
809 {
810 // flush
811 while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
812
813 CmdsParse(CommandTable, Cmd);
814 return 0;
815 }
816
817 int CmdHelp(const char *Cmd)
818 {
819 CmdsHelp(CommandTable);
820 return 0;
821 }
Impressum, Datenschutz