]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmf.c
   1 //----------------------------------------------------------------------------- 
   2 // Copyright (C) 2011,2012 Merlok 
   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 // High frequency MIFARE commands 
   9 //----------------------------------------------------------------------------- 
  12 #include "proxmark3.h" 
  14 static int CmdHelp(const char *Cmd
); 
  16 int CmdHF14AMifare(const char *Cmd
) 
  20         uint64_t par_list 
= 0, ks_list 
= 0, r_key 
= 0; 
  22         uint8_t keyBlock
[8] = {0}; 
  24         if (param_getchar(Cmd
, 0) && param_gethex(Cmd
, 0, keyBlock
, 8)) { 
  25                 PrintAndLog("Nt must include 8 HEX symbols"); 
  30         UsbCommand c 
= {CMD_READER_MIFARE
, {(uint32_t)bytes_to_num(keyBlock
, 4), 0, 0}}; 
  35         while (ukbhit())        getchar(); 
  38         printf("-------------------------------------------------------------------------\n"); 
  39         printf("Executing command. It may take up to 30 min.\n"); 
  40         printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n"); 
  41         printf("-------------------------------------------------------------------------\n"); 
  49                         printf("\naborted via keyboard!\n"); 
  53                 UsbCommand 
* resp 
= WaitForResponseTimeout(CMD_ACK
, 2000); 
  55                         isOK  
= resp
->arg
[0] & 0xff; 
  57                         uid 
= (uint32_t)bytes_to_num(resp
->d
.asBytes 
+  0, 4); 
  58                         nt 
=  (uint32_t)bytes_to_num(resp
->d
.asBytes 
+  4, 4); 
  59                         par_list 
= bytes_to_num(resp
->d
.asBytes 
+  8, 8); 
  60                         ks_list 
= bytes_to_num(resp
->d
.asBytes 
+  16, 8); 
  63                         PrintAndLog("isOk:%02x", isOK
); 
  64                         if (!isOK
) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n"); 
  71         if (isOK 
!= 1) return 1; 
  73         // execute original function from util nonce2key 
  74         if (nonce2key(uid
, nt
, par_list
, ks_list
, &r_key
)) return 2; 
  75         printf("------------------------------------------------------------------\n"); 
  76         PrintAndLog("Key found:%012llx \n", r_key
); 
  78         num_to_bytes(r_key
, 6, keyBlock
); 
  79         isOK 
= mfCheckKeys(0, 0, 1, keyBlock
, &r_key
); 
  81                 PrintAndLog("Found valid key:%012llx", r_key
); 
  84                 PrintAndLog("Found invalid key. ( Nt=%08x ,Trying use it to run again...", nt
);  
  92 int CmdHF14AMfWrBl(const char *Cmd
) 
  96         uint8_t key
[6] = {0, 0, 0, 0, 0, 0}; 
  97         uint8_t bldata
[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
 102                 PrintAndLog("Usage:  hf mf wrbl    <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>"); 
 103                 PrintAndLog("        sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F"); 
 107         blockNo 
= param_get8(Cmd
, 0); 
 108         cmdp 
= param_getchar(Cmd
, 1); 
 110                 PrintAndLog("Key type must be A or B"); 
 113         if (cmdp 
!= 'A' && cmdp 
!= 'a') keyType 
= 1; 
 114         if (param_gethex(Cmd
, 2, key
, 12)) { 
 115                 PrintAndLog("Key must include 12 HEX symbols"); 
 118         if (param_gethex(Cmd
, 3, bldata
, 32)) { 
 119                 PrintAndLog("Block data must include 32 HEX symbols"); 
 122         PrintAndLog("--block no:%02x key type:%02x key:%s", blockNo
, keyType
, sprint_hex(key
, 6)); 
 123         PrintAndLog("--data: %s", sprint_hex(bldata
, 16)); 
 125   UsbCommand c 
= {CMD_MIFARE_WRITEBL
, {blockNo
, keyType
, 0}}; 
 126         memcpy(c
.d
.asBytes
, key
, 6); 
 127         memcpy(c
.d
.asBytes 
+ 10, bldata
, 16); 
 129         UsbCommand 
* resp 
= WaitForResponseTimeout(CMD_ACK
, 1500); 
 132                 uint8_t                isOK  
= resp
->arg
[0] & 0xff; 
 134                 PrintAndLog("isOk:%02x", isOK
); 
 136                 PrintAndLog("Command execute timeout"); 
 142 int CmdHF14AMfRdBl(const char *Cmd
) 
 146         uint8_t key
[6] = {0, 0, 0, 0, 0, 0}; 
 152                 PrintAndLog("Usage:  hf mf rdbl    <block number> <key A/B> <key (12 hex symbols)>"); 
 153                 PrintAndLog("        sample: hf mf rdbl 0 A FFFFFFFFFFFF "); 
 157         blockNo 
= param_get8(Cmd
, 0); 
 158         cmdp 
= param_getchar(Cmd
, 1); 
 160                 PrintAndLog("Key type must be A or B"); 
 163         if (cmdp 
!= 'A' && cmdp 
!= 'a') keyType 
= 1; 
 164         if (param_gethex(Cmd
, 2, key
, 12)) { 
 165                 PrintAndLog("Key must include 12 HEX symbols"); 
 168         PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo
, keyType
, sprint_hex(key
, 6)); 
 170   UsbCommand c 
= {CMD_MIFARE_READBL
, {blockNo
, keyType
, 0}}; 
 171         memcpy(c
.d
.asBytes
, key
, 6); 
 173         UsbCommand 
* resp 
= WaitForResponseTimeout(CMD_ACK
, 1500); 
 176                 uint8_t                isOK  
= resp
->arg
[0] & 0xff; 
 177                 uint8_t              * data  
= resp
->d
.asBytes
; 
 180                         PrintAndLog("isOk:%02x data:%s", isOK
, sprint_hex(data
, 16)); 
 182                         PrintAndLog("isOk:%02x", isOK
); 
 184                 PrintAndLog("Command execute timeout"); 
 190 int CmdHF14AMfRdSc(const char *Cmd
) 
 193         uint8_t sectorNo 
= 0; 
 195         uint8_t key
[6] = {0, 0, 0, 0, 0, 0}; 
 198         uint8_t * data  
= NULL
; 
 203                 PrintAndLog("Usage:  hf mf rdsc    <sector number> <key A/B> <key (12 hex symbols)>"); 
 204                 PrintAndLog("        sample: hf mf rdsc 0 A FFFFFFFFFFFF "); 
 208         sectorNo 
= param_get8(Cmd
, 0); 
 210                 PrintAndLog("Sector number must be less than 64"); 
 213         cmdp 
= param_getchar(Cmd
, 1); 
 215                 PrintAndLog("Key type must be A or B"); 
 218         if (cmdp 
!= 'A' && cmdp 
!= 'a') keyType 
= 1; 
 219         if (param_gethex(Cmd
, 2, key
, 12)) { 
 220                 PrintAndLog("Key must include 12 HEX symbols"); 
 223         PrintAndLog("--sector no:%02x key type:%02x key:%s ", sectorNo
, keyType
, sprint_hex(key
, 6)); 
 225   UsbCommand c 
= {CMD_MIFARE_READSC
, {sectorNo
, keyType
, 0}}; 
 226         memcpy(c
.d
.asBytes
, key
, 6); 
 228         UsbCommand 
* resp 
= WaitForResponseTimeout(CMD_ACK
, 1500); 
 232                 isOK  
= resp
->arg
[0] & 0xff; 
 233                 data  
= resp
->d
.asBytes
; 
 235                 PrintAndLog("isOk:%02x", isOK
); 
 237                         for (i 
= 0; i 
< 2; i
++) { 
 238                                 PrintAndLog("data:%s", sprint_hex(data 
+ i 
* 16, 16)); 
 241                 PrintAndLog("Command1 execute timeout"); 
 245         resp 
= WaitForResponseTimeout(CMD_ACK
, 500); 
 249                 isOK  
= resp
->arg
[0] & 0xff; 
 250                 data  
= resp
->d
.asBytes
; 
 253                         for (i 
= 0; i 
< 2; i
++) { 
 254                                 PrintAndLog("data:%s", sprint_hex(data 
+ i 
* 16, 16)); 
 257                 PrintAndLog("Command2 execute timeout"); 
 263 int CmdHF14AMfDump(const char *Cmd
) 
 269         uint8_t rights
[40][4]; 
 276         if ((fin 
= fopen("dumpkeys.bin","rb")) == NULL
) { 
 277                 PrintAndLog("Could not find file dumpkeys.bin"); 
 281         if ((fout 
= fopen("dumpdata.bin","wb")) == NULL
) {  
 282                 PrintAndLog("Could not create file name dumpdata.bin"); 
 288         for (i
=0 ; i
<16 ; i
++) { 
 289                 fread ( keyA
[i
], 1, 6, fin 
); 
 291         for (i
=0 ; i
<16 ; i
++) { 
 292                 fread ( keyB
[i
], 1, 6, fin 
); 
 295         // Read access rights to sectors 
 297         PrintAndLog("|-----------------------------------------|"); 
 298         PrintAndLog("|------ Reading sector access bits...-----|"); 
 299         PrintAndLog("|-----------------------------------------|"); 
 301         for (i 
= 0 ; i 
< 16 ; i
++) { 
 302                 UsbCommand c 
= {CMD_MIFARE_READBL
, {4*i 
+ 3, 0, 0}}; 
 303                 memcpy(c
.d
.asBytes
, keyA
[i
], 6); 
 305                 resp 
= WaitForResponseTimeout(CMD_ACK
, 1500); 
 308                         uint8_t isOK  
= resp
->arg
[0] & 0xff; 
 309                         uint8_t *data  
= resp
->d
.asBytes
; 
 311                                 rights
[i
][0] = ((data
[7] & 0x10)>>4) | ((data
[8] & 0x1)<<1) | ((data
[8] & 0x10)>>2); 
 312                                 rights
[i
][1] = ((data
[7] & 0x20)>>5) | ((data
[8] & 0x2)<<0) | ((data
[8] & 0x20)>>3); 
 313                                 rights
[i
][2] = ((data
[7] & 0x40)>>6) | ((data
[8] & 0x4)>>1) | ((data
[8] & 0x40)>>4); 
 314                                 rights
[i
][3] = ((data
[7] & 0x80)>>7) | ((data
[8] & 0x8)>>2) | ((data
[8] & 0x80)>>5); 
 317                                 PrintAndLog("Could not get access rights for block %d", i
); 
 321                         PrintAndLog("Command execute timeout"); 
 325         // Read blocks and print to file 
 327         PrintAndLog("|-----------------------------------------|"); 
 328         PrintAndLog("|----- Dumping all blocks to file... -----|"); 
 329         PrintAndLog("|-----------------------------------------|"); 
 331         for (i
=0 ; i
<16 ; i
++) { 
 332                 for (j
=0 ; j
<4 ; j
++) { 
 334                                 UsbCommand c 
= {CMD_MIFARE_READBL
, {i
*4 + j
, 0, 0}}; 
 335                                 memcpy(c
.d
.asBytes
, keyA
[i
], 6); 
 337                                 resp 
= WaitForResponseTimeout(CMD_ACK
, 1500); 
 340                                 if ((rights
[i
][j
] == 6) | (rights
[i
][j
] == 5)) { 
 341                                         UsbCommand c 
= {CMD_MIFARE_READBL
, {i
*4+j
, 1, 0}}; 
 342                                         memcpy(c
.d
.asBytes
, keyB
[i
], 6); 
 344                                         resp 
= WaitForResponseTimeout(CMD_ACK
, 1500); 
 346                                 else if (rights
[i
][j
] == 7) { 
 347                                         PrintAndLog("Access rights do not allow reading of sector %d block %d",i
,j
); 
 350                                         UsbCommand c 
= {CMD_MIFARE_READBL
, {i
*4+j
, 0, 0}}; 
 351                                         memcpy(c
.d
.asBytes
, keyA
[i
], 6); 
 353                                         resp 
= WaitForResponseTimeout(CMD_ACK
, 1500); 
 358                                 uint8_t isOK  
= resp
->arg
[0] & 0xff; 
 359                                 uint8_t *data  
= resp
->d
.asBytes
; 
 361                                         data
[0]  = (keyA
[i
][0]); 
 362                                         data
[1]  = (keyA
[i
][1]); 
 363                                         data
[2]  = (keyA
[i
][2]); 
 364                                         data
[3]  = (keyA
[i
][3]); 
 365                                         data
[4]  = (keyA
[i
][4]); 
 366                                         data
[5]  = (keyA
[i
][5]); 
 367                                         data
[10] = (keyB
[i
][0]); 
 368                                         data
[11] = (keyB
[i
][1]); 
 369                                         data
[12] = (keyB
[i
][2]); 
 370                                         data
[13] = (keyB
[i
][3]); 
 371                                         data
[14] = (keyB
[i
][4]); 
 372                                         data
[15] = (keyB
[i
][5]); 
 375                                         fwrite ( data
, 1, 16, fout 
); 
 378                                         PrintAndLog("Could not get access rights for block %d", i
); 
 382                                 PrintAndLog("Command execute timeout"); 
 393 int CmdHF14AMfRestore(const char *Cmd
) 
 398         uint8_t key
[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
 399         uint8_t bldata
[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
 406         if ((fdump 
= fopen("dumpdata.bin","rb")) == NULL
) { 
 407                 PrintAndLog("Could not find file dumpdata.bin"); 
 410         if ((fkeys 
= fopen("dumpkeys.bin","rb")) == NULL
) { 
 411                 PrintAndLog("Could not find file dumpkeys.bin"); 
 415         for (i
=0 ; i
<16 ; i
++) { 
 416                 fread(keyA
[i
], 1, 6, fkeys
); 
 418         for (i
=0 ; i
<16 ; i
++) { 
 419                 fread(keyB
[i
], 1, 6, fkeys
); 
 422         PrintAndLog("Restoring dumpdata.bin to card"); 
 424         for (i
=0 ; i
<16 ; i
++) { 
 425                 for( j
=0 ; j
<4 ; j
++) { 
 426                         UsbCommand c 
= {CMD_MIFARE_WRITEBL
, {i
*4 + j
, keyType
, 0}}; 
 427                         memcpy(c
.d
.asBytes
, key
, 6); 
 429                         fread(bldata
, 1, 16, fdump
); 
 432                                 bldata
[0]  = (keyA
[i
][0]); 
 433                                 bldata
[1]  = (keyA
[i
][1]); 
 434                                 bldata
[2]  = (keyA
[i
][2]); 
 435                                 bldata
[3]  = (keyA
[i
][3]); 
 436                                 bldata
[4]  = (keyA
[i
][4]); 
 437                                 bldata
[5]  = (keyA
[i
][5]); 
 438                                 bldata
[10] = (keyB
[i
][0]); 
 439                                 bldata
[11] = (keyB
[i
][1]); 
 440                                 bldata
[12] = (keyB
[i
][2]); 
 441                                 bldata
[13] = (keyB
[i
][3]); 
 442                                 bldata
[14] = (keyB
[i
][4]); 
 443                                 bldata
[15] = (keyB
[i
][5]); 
 446                         PrintAndLog("Writing to block %2d: %s", i
*4+j
, sprint_hex(bldata
, 16)); 
 449                         PrintAndLog("Writing to block %2d: %s Confirm? [Y,N]", i*4+j, sprint_hex(bldata, 16)); 
 452                         if ((ch != 'y') && (ch != 'Y')){ 
 453                                 PrintAndLog("Aborting !"); 
 458                         memcpy(c
.d
.asBytes 
+ 10, bldata
, 16); 
 460                         UsbCommand 
*resp 
= WaitForResponseTimeout(CMD_ACK
, 1500); 
 463                                 uint8_t isOK  
= resp
->arg
[0] & 0xff; 
 464                                 PrintAndLog("isOk:%02x", isOK
); 
 466                                 PrintAndLog("Command execute timeout"); 
 476 int CmdHF14AMfNested(const char *Cmd
) 
 478         int i
, j
, res
, iterations
; 
 479         sector  
*       e_sector 
= NULL
; 
 482         uint8_t trgBlockNo 
= 0; 
 483         uint8_t trgKeyType 
= 0; 
 486         uint8_t key
[6] = {0, 0, 0, 0, 0, 0}; 
 487         uint8_t keyBlock
[16 * 6]; 
 489         int transferToEml 
= 0; 
 491         int createDumpFile 
= 0; 
 493         uint8_t standart
[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
 494         uint8_t tempkey
[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
 499                 PrintAndLog("Usage:"); 
 500                 PrintAndLog(" all sectors:  hf mf nested  <card memory> <block number> <key A/B> <key (12 hex symbols)> [t,d]"); 
 501                 PrintAndLog(" one sector:   hf mf nested  o <block number> <key A/B> <key (12 hex symbols)>"); 
 502                 PrintAndLog("               <target block number> <target key A/B> [t]"); 
 503                 PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K"); 
 504                 PrintAndLog("t - transfer keys into emulator memory"); 
 505                 PrintAndLog("d - write keys to binary file"); 
 507                 PrintAndLog("      sample1: hf mf nested 1 0 A FFFFFFFFFFFF "); 
 508                 PrintAndLog("      sample1: hf mf nested 1 0 A FFFFFFFFFFFF t "); 
 509                 PrintAndLog("      sample1: hf mf nested 1 0 A FFFFFFFFFFFF d "); 
 510                 PrintAndLog("      sample2: hf mf nested o 0 A FFFFFFFFFFFF 4 A"); 
 514         cmdp 
= param_getchar(Cmd
, 0); 
 515         blockNo 
= param_get8(Cmd
, 1); 
 516         ctmp 
= param_getchar(Cmd
, 2); 
 518                 PrintAndLog("Key type must be A or B"); 
 521         if (ctmp 
!= 'A' && ctmp 
!= 'a') keyType 
= 1; 
 522         if (param_gethex(Cmd
, 3, key
, 12)) { 
 523                 PrintAndLog("Key must include 12 HEX symbols"); 
 527         if (cmdp 
== 'o' || cmdp 
== 'O') { 
 529                 trgBlockNo 
= param_get8(Cmd
, 4); 
 530                 ctmp 
= param_getchar(Cmd
, 5); 
 532                         PrintAndLog("Target key type must be A or B"); 
 535                 if (ctmp 
!= 'A' && ctmp 
!= 'a') trgKeyType 
= 1; 
 538                         case '0': SectorsCnt 
= 05; break; 
 539                         case '1': SectorsCnt 
= 16; break; 
 540                         case '2': SectorsCnt 
= 32; break; 
 541                         case '4': SectorsCnt 
= 64; break; 
 542                         default:  SectorsCnt 
= 16; 
 546         ctmp 
= param_getchar(Cmd
, 4); 
 547         if              (ctmp 
== 't' || ctmp 
== 'T') transferToEml 
= 1; 
 548         else if (ctmp 
== 'd' || ctmp 
== 'D') createDumpFile 
= 1; 
 550         ctmp 
= param_getchar(Cmd
, 6); 
 551         transferToEml 
|= (ctmp 
== 't' || ctmp 
== 'T'); 
 552         transferToEml 
|= (ctmp 
== 'd' || ctmp 
== 'D'); 
 554         PrintAndLog("--block no:%02x key type:%02x key:%s etrans:%d", blockNo
, keyType
, sprint_hex(key
, 6), transferToEml
); 
 556                 PrintAndLog("--target block no:%02x target key type:%02x ", trgBlockNo
, trgKeyType
); 
 559                 if (mfnested(blockNo
, keyType
, key
, trgBlockNo
, trgKeyType
, keyBlock
)) { 
 560                         PrintAndLog("Nested error."); 
 564                 for (i 
= 0; i 
< 16; i
++) { 
 565                         PrintAndLog("count=%d key= %s", i
, sprint_hex(keyBlock 
+ i 
* 6, 6)); 
 569                 res 
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, keyBlock
, &key64
); 
 571                         res 
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, &keyBlock
[6 * 8], &key64
); 
 573                         PrintAndLog("Found valid key:%012llx", key64
); 
 575                         // transfer key to the emulator 
 577                                 mfEmlGetMem(keyBlock
, (trgBlockNo 
/ 4) * 4 + 3, 1); 
 580                                         num_to_bytes(key64
, 6, keyBlock
); 
 582                                         num_to_bytes(key64
, 6, &keyBlock
[10]); 
 583                                 mfEmlSetMem(keyBlock
, (trgBlockNo 
/ 4) * 4 + 3, 1);              
 586                         PrintAndLog("No valid key found"); 
 589         else { // ------------------------------------  multiple sectors working 
 590                 blDiff 
= blockNo 
% 4; 
 591                 PrintAndLog("Block shift=%d", blDiff
); 
 592                 e_sector 
= calloc(SectorsCnt
, sizeof(sector
)); 
 593                 if (e_sector 
== NULL
) return 1; 
 595                 //test current key 4 sectors 
 596                 memcpy(keyBlock
, key
, 6); 
 597                 num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock 
+ 1 * 6)); 
 598                 num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock 
+ 2 * 6)); 
 599                 num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock 
+ 3 * 6)); 
 600                 num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock 
+ 4 * 6)); 
 601                 num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock 
+ 5 * 6)); 
 603                 PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt
); 
 604                 for (i 
= 0; i 
< SectorsCnt
; i
++) { 
 605                         for (j 
= 0; j 
< 2; j
++) { 
 606                                 if (e_sector
[i
].foundKey
[j
]) continue; 
 608                                 res 
= mfCheckKeys(i 
* 4 + blDiff
, j
, 6, keyBlock
, &key64
); 
 611                                         e_sector
[i
].Key
[j
] = key64
; 
 612                                         e_sector
[i
].foundKey
[j
] = 1; 
 619                 PrintAndLog("nested..."); 
 620                 for (i 
= 0; i 
< NESTED_SECTOR_RETRY
; i
++) { 
 621                         for (trgBlockNo 
= blDiff
; trgBlockNo 
< SectorsCnt 
* 4; trgBlockNo 
= trgBlockNo 
+ 4)  
 622                                 for (trgKeyType 
= 0; trgKeyType 
< 2; trgKeyType
++) {  
 623                                         if (e_sector
[trgBlockNo 
/ 4].foundKey
[trgKeyType
]) continue; 
 624                                         if (mfnested(blockNo
, keyType
, key
, trgBlockNo
, trgKeyType
, keyBlock
)) continue; 
 628                                         //try keys from nested 
 629                                         res 
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, keyBlock
, &key64
); 
 631                                                 res 
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, &keyBlock
[6 * 8], &key64
); 
 633                                                 PrintAndLog("Found valid key:%012llx", key64
);   
 634                                                 e_sector
[trgBlockNo 
/ 4].foundKey
[trgKeyType
] = 1; 
 635                                                 e_sector
[trgBlockNo 
/ 4].Key
[trgKeyType
] = key64
; 
 640                 PrintAndLog("Iterations count: %d", iterations
); 
 642                 PrintAndLog("|---|----------------|---|----------------|---|"); 
 643                 PrintAndLog("|sec|key A           |res|key B           |res|"); 
 644                 PrintAndLog("|---|----------------|---|----------------|---|"); 
 645                 for (i 
= 0; i 
< SectorsCnt
; i
++) { 
 646                         PrintAndLog("|%03d|  %012llx  | %d |  %012llx  | %d |", i
,  
 647                                 e_sector
[i
].Key
[0], e_sector
[i
].foundKey
[0], e_sector
[i
].Key
[1], e_sector
[i
].foundKey
[1]); 
 649                 PrintAndLog("|---|----------------|---|----------------|---|"); 
 651                 // transfer them to the emulator 
 653                         for (i 
= 0; i 
< SectorsCnt
; i
++) { 
 654                                 mfEmlGetMem(keyBlock
, i 
* 4 + 3, 1); 
 655                                 if (e_sector
[i
].foundKey
[0]) 
 656                                         num_to_bytes(e_sector
[i
].Key
[0], 6, keyBlock
); 
 657                                 if (e_sector
[i
].foundKey
[1]) 
 658                                         num_to_bytes(e_sector
[i
].Key
[1], 6, &keyBlock
[10]); 
 659                                 mfEmlSetMem(keyBlock
, i 
* 4 + 3, 1); 
 664                 if (createDumpFile
) { 
 665                         if ((fkeys 
= fopen("dumpkeys.bin","wb")) == NULL
) {  
 666                                 PrintAndLog("Could not create file dumpkeys.bin"); 
 670                         PrintAndLog("Printing keys to bynary file dumpkeys.bin..."); 
 671                         for(i
=0; i
<16; i
++) { 
 672                                 if (e_sector
[i
].foundKey
[0]){ 
 673                                         num_to_bytes(e_sector
[i
].Key
[0], 6, tempkey
); 
 674                                         fwrite ( tempkey
, 1, 6, fkeys 
); 
 677                                         fwrite ( &standart
, 1, 6, fkeys 
); 
 680                         for(i
=0; i
<16; i
++) { 
 681                                 if (e_sector
[i
].foundKey
[1]){ 
 682                                         num_to_bytes(e_sector
[i
].Key
[1], 6, tempkey
); 
 683                                         fwrite ( tempkey
, 1, 6, fkeys 
); 
 686                                         fwrite ( &standart
, 1, 6, fkeys 
); 
 699 get_trailer_block (uint32_t uiBlock
) 
 701   // Test if we are in the small or big sectors 
 702   uint32_t trailer_block 
= 0; 
 704     trailer_block 
= uiBlock 
+ (3 - (uiBlock 
% 4)); 
 706     trailer_block 
= uiBlock 
+ (15 - (uiBlock 
% 16)); 
 708   return trailer_block
; 
 710 int CmdHF14AMfChk(const char *Cmd
) 
 713         char filename
[256]={0}; 
 715         uint8_t *keyBlock 
= NULL
, *p
; 
 716         uint8_t stKeyBlock 
= 20; 
 722         uint8_t SectorsCnt 
= 1; 
 726         int transferToEml 
= 0; 
 727         int createDumpFile 
= 0; 
 729         keyBlock 
= calloc(stKeyBlock
, 6); 
 730         if (keyBlock 
== NULL
) return 1; 
 732         num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock 
+ 0 * 6)); // Default key (first key used by program if no user defined key) 
 733         num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock 
+ 1 * 6)); // Blank key 
 734         num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock 
+ 2 * 6)); // NFCForum MAD key 
 735         num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock 
+ 3 * 6)); 
 736         num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock 
+ 4 * 6)); 
 737         num_to_bytes(0x4d3a99c351dd, 6, (uint8_t*)(keyBlock 
+ 5 * 6)); 
 738         num_to_bytes(0x1a982c7e459a, 6, (uint8_t*)(keyBlock 
+ 6 * 6)); 
 739         num_to_bytes(0xd3f7d3f7d3f7, 6, (uint8_t*)(keyBlock 
+ 7 * 6)); 
 740         num_to_bytes(0x714c5c886e97, 6, (uint8_t*)(keyBlock 
+ 8 * 6)); 
 741         num_to_bytes(0x587ee5f9350f, 6, (uint8_t*)(keyBlock 
+ 9 * 6)); 
 742         num_to_bytes(0xa0478cc39091, 6, (uint8_t*)(keyBlock 
+ 10 * 6)); 
 743         num_to_bytes(0x533cb6c723f6, 6, (uint8_t*)(keyBlock 
+ 11 * 6)); 
 744         num_to_bytes(0x8fd0a4f256e9, 6, (uint8_t*)(keyBlock 
+ 12 * 6)); 
 747                 PrintAndLog("Usage:  hf mf chk <block number>/<*card memory> <key type (A/B/?)> [t] [<key (12 hex symbols)>] [<dic (*.dic)>]"); 
 748                 PrintAndLog("          * - all sectors"); 
 749                 PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K"); 
 750 //              PrintAndLog("d - write keys to binary file\n"); 
 752                 PrintAndLog("      sample: hf mf chk 0 A 1234567890ab keys.dic"); 
 753                 PrintAndLog("              hf mf chk *1 ? t"); 
 757         if (param_getchar(Cmd
, 0)=='*') { 
 759                 switch(param_getchar(Cmd
+1, 0)) { 
 760                         case '0': SectorsCnt 
=  5; break; 
 761                         case '1': SectorsCnt 
= 16; break; 
 762                         case '2': SectorsCnt 
= 32; break; 
 763                         case '4': SectorsCnt 
= 40; break; 
 764                         default:  SectorsCnt 
= 16; 
 768                 blockNo 
= param_get8(Cmd
, 0); 
 770         ctmp 
= param_getchar(Cmd
, 1); 
 782                 PrintAndLog("Key type must be A , B or ?"); 
 786         ctmp 
= param_getchar(Cmd
, 2); 
 787         if              (ctmp 
== 't' || ctmp 
== 'T') transferToEml 
= 1; 
 788         else if (ctmp 
== 'd' || ctmp 
== 'D') createDumpFile 
= 1; 
 790         for (i 
= transferToEml 
|| createDumpFile
; param_getchar(Cmd
, 2 + i
); i
++) { 
 791                 if (!param_gethex(Cmd
, 2 + i
, keyBlock 
+ 6 * keycnt
, 12)) { 
 792                         if ( stKeyBlock 
- keycnt 
< 2) { 
 793                                 p 
= realloc(keyBlock
, 6*(stKeyBlock
+=10)); 
 795                                         PrintAndLog("Cannot allocate memory for Keys"); 
 801                         PrintAndLog("chk key[%d] %02x%02x%02x%02x%02x%02x", keycnt
, 
 802                         (keyBlock 
+ 6*keycnt
)[0],(keyBlock 
+ 6*keycnt
)[1], (keyBlock 
+ 6*keycnt
)[2], 
 803                         (keyBlock 
+ 6*keycnt
)[3], (keyBlock 
+ 6*keycnt
)[4],     (keyBlock 
+ 6*keycnt
)[5], 6); 
 807                         if ( param_getstr(Cmd
, 2 + i
,filename
) > 255 ) { 
 808                                 PrintAndLog("File name too long"); 
 813                         if ( (f 
= fopen( filename 
, "r")) ) { 
 815                                         memset(buf
, 0, sizeof(buf
)); 
 816                                         fgets(buf
, sizeof(buf
), f
); 
 818                                         if (strlen(buf
) < 12 || buf
[11] == '\n') 
 821                                         while (fgetc(f
) != '\n' && !feof(f
)) ;  //goto next line 
 823                                         if( buf
[0]=='#' ) continue;     //The line start with # is remcommnet,skip 
 825                                         if (!isxdigit(buf
[0])){ 
 826                                                 PrintAndLog("File content error. '%s' must include 12 HEX symbols",buf
); 
 832                                         if ( stKeyBlock 
- keycnt 
< 2) { 
 833                                                 p 
= realloc(keyBlock
, 6*(stKeyBlock
+=10)); 
 835                                                         PrintAndLog("Cannot allocate memory for defKeys"); 
 841                                         memset(keyBlock 
+ 6 * keycnt
, 0, 6); 
 842                                         num_to_bytes(strtoll(buf
, NULL
, 16), 6, keyBlock 
+ 6*keycnt
); 
 843                                         PrintAndLog("chk custom key[%d] %012llx", keycnt
, bytes_to_num(keyBlock 
+ 6*keycnt
, 6)); 
 847                                 PrintAndLog("File: %s: not found or locked.", filename
); 
 856                 PrintAndLog("No key specified,try default keys"); 
 857                 for (;keycnt 
<=12; keycnt
++) 
 858                         PrintAndLog("chk default key[%d] %02x%02x%02x%02x%02x%02x", keycnt
, 
 859                         (keyBlock 
+ 6*keycnt
)[0],(keyBlock 
+ 6*keycnt
)[1], (keyBlock 
+ 6*keycnt
)[2], 
 860                         (keyBlock 
+ 6*keycnt
)[3], (keyBlock 
+ 6*keycnt
)[4],     (keyBlock 
+ 6*keycnt
)[5], 6); 
 863         for ( int t 
= !keyType 
; t 
< 2 ; keyType
==2?(t
++):(t
=2) ) { 
 865                 for (int i
=0; i
<SectorsCnt
; ++i
) { 
 866                         PrintAndLog("--SectorsCnt:%d block no:0x%02x key type:%C key count:%d ", i
,      b
, t
?'B':'A', keycnt
); 
 867                         int size 
= keycnt
>8?8:keycnt
; 
 868                         for (int c 
= 0; c 
< keycnt
; c
+=size
) { 
 869                                 size
=keycnt
-c
>8?8:keycnt
-c
;                      
 870                                 res 
= mfCheckKeys(b
, t
, size
, keyBlock 
+6*c
, &key64
); 
 873                                                 PrintAndLog("Found valid key:[%012llx]",key64
); 
 876                                                         mfEmlGetMem(block
, get_trailer_block(b
), 1); 
 877                                                         num_to_bytes(key64
, 6, block 
+ t
*10); 
 878                                                         mfEmlSetMem(block
, get_trailer_block(b
), 1); 
 883                                                 printf("Not found yet, keycnt:%d\r", c
+size
); 
 887                                         PrintAndLog("Command execute timeout"); 
 890                         b
<127?(b
+=4):(b
+=16);    
 898         if (createDumpFile) { 
 899                 if ((fkeys = fopen("dumpkeys.bin","wb")) == NULL) {  
 900                         PrintAndLog("Could not create file dumpkeys.bin"); 
 904                 PrintAndLog("Printing keys to bynary file dumpkeys.bin..."); 
 905                 for(i=0; i<16; i++) { 
 906                         if (e_sector[i].foundKey[0]){ 
 907                                 num_to_bytes(e_sector[i].Key[0], 6, tempkey); 
 908                                 fwrite ( tempkey, 1, 6, fkeys ); 
 911                                 fwrite ( &standart, 1, 6, fkeys ); 
 914                 for(i=0; i<16; i++) { 
 915                         if (e_sector[i].foundKey[1]){ 
 916                                 num_to_bytes(e_sector[i].Key[1], 6, tempkey); 
 917                                 fwrite ( tempkey, 1, 6, fkeys ); 
 920                                 fwrite ( &standart, 1, 6, fkeys ); 
 929 int CmdHF14AMf1kSim(const char *Cmd
) 
 931         uint8_t uid
[4] = {0, 0, 0, 0}; 
 933         if (param_getchar(Cmd
, 0) == 'h') { 
 934                 PrintAndLog("Usage:  hf mf sim  <uid (8 hex symbols)>"); 
 935                 PrintAndLog("           sample: hf mf sim 0a0a0a0a "); 
 939         if (param_getchar(Cmd
, 0) && param_gethex(Cmd
, 0, uid
, 8)) { 
 940                 PrintAndLog("UID must include 8 HEX symbols"); 
 943         PrintAndLog(" uid:%s ", sprint_hex(uid
, 4)); 
 945   UsbCommand c 
= {CMD_SIMULATE_MIFARE_CARD
, {0, 0, 0}}; 
 946         memcpy(c
.d
.asBytes
, uid
, 4); 
 952 int CmdHF14AMfDbg(const char *Cmd
) 
 954         int dbgMode 
= param_get32ex(Cmd
, 0, 0, 10); 
 956                 PrintAndLog("Max debud mode parameter is 4 \n"); 
 959         if (strlen(Cmd
) < 1 || !param_getchar(Cmd
, 0) || dbgMode 
> 4) { 
 960                 PrintAndLog("Usage:  hf mf dbg  <debug level>"); 
 961                 PrintAndLog(" 0 - no debug messages"); 
 962                 PrintAndLog(" 1 - error messages"); 
 963                 PrintAndLog(" 2 - all messages"); 
 964                 PrintAndLog(" 4 - extended debug mode"); 
 968   UsbCommand c 
= {CMD_MIFARE_SET_DBGMODE
, {dbgMode
, 0, 0}}; 
 974 int CmdHF14AMfEGet(const char *Cmd
) 
 977         uint8_t data
[3 * 16]; 
 980         if (strlen(Cmd
) < 1 || param_getchar(Cmd
, 0) == 'h') { 
 981                 PrintAndLog("Usage:  hf mf eget <block number>"); 
 982                 PrintAndLog(" sample: hf mf eget 0 "); 
 986         blockNo 
= param_get8(Cmd
, 0); 
 987         if (blockNo 
>= 32 * 4 + 8 * 16) { 
 988                 PrintAndLog("Block number must be in [0..255] as in MIFARE classic."); 
 993         if (!mfEmlGetMem(data
, blockNo
, 3)) { 
 994                 for (i 
= 0; i 
< 3; i
++) { 
 995                         PrintAndLog("data[%d]:%s", blockNo 
+ i
, sprint_hex(data 
+ i 
* 16, 16)); 
 998                 PrintAndLog("Command execute timeout"); 
1004 int CmdHF14AMfEClear(const char *Cmd
) 
1006         if (param_getchar(Cmd
, 0) == 'h') { 
1007                 PrintAndLog("Usage:  hf mf eclr"); 
1008                 PrintAndLog("It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF \n"); 
1012   UsbCommand c 
= {CMD_MIFARE_EML_MEMCLR
, {0, 0, 0}}; 
1017 int CmdHF14AMfESet(const char *Cmd
) 
1019         uint8_t memBlock
[16]; 
1020         uint8_t blockNo 
= 0; 
1022         memset(memBlock
, 0x00, sizeof(memBlock
)); 
1024         if (strlen(Cmd
) < 3 || param_getchar(Cmd
, 0) == 'h') { 
1025                 PrintAndLog("Usage:  hf mf eset <block number> <block data (32 hex symbols)>"); 
1026                 PrintAndLog(" sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f "); 
1030         blockNo 
= param_get8(Cmd
, 0); 
1031         if (blockNo 
>= 32 * 4 + 8 * 16) { 
1032                 PrintAndLog("Block number must be in [0..255] as in MIFARE classic."); 
1036         if (param_gethex(Cmd
, 1, memBlock
, 32)) { 
1037                 PrintAndLog("block data must include 32 HEX symbols"); 
1042   UsbCommand c 
= {CMD_MIFARE_EML_MEMSET
, {blockNo
, 1, 0}}; 
1043         memcpy(c
.d
.asBytes
, memBlock
, 16); 
1048 int CmdHF14AMfELoad(const char *Cmd
) 
1052         char * fnameptr 
= filename
; 
1055         int i
, len
, blockNum
; 
1057         memset(filename
, 0, sizeof(filename
)); 
1058         memset(buf
, 0, sizeof(buf
)); 
1060         if (param_getchar(Cmd
, 0) == 'h' || param_getchar(Cmd
, 0)== 0x00) { 
1061                 PrintAndLog("It loads emul dump from the file `filename.eml`"); 
1062                 PrintAndLog("Usage:  hf mf eload <file name w/o `.eml`>"); 
1063                 PrintAndLog(" sample: hf mf eload filename"); 
1068         if (len 
> 14) len 
= 14; 
1070         memcpy(filename
, Cmd
, len
); 
1073         sprintf(fnameptr
, ".eml");  
1076         f 
= fopen(filename
, "r"); 
1078                 PrintAndLog("File not found or locked."); 
1084                 memset(buf
, 0, sizeof(buf
)); 
1085                 fgets(buf
, sizeof(buf
), f
); 
1087                 if (strlen(buf
) < 32){ 
1088                         if(strlen(buf
) && feof(f
)) 
1090                         PrintAndLog("File content error. Block data must include 32 HEX symbols"); 
1093                 for (i 
= 0; i 
< 32; i 
+= 2) 
1094                   sscanf(&buf
[i
], "%02x", (unsigned int *)&buf8
[i 
/ 2]); 
1095 //                      PrintAndLog("data[%02d]:%s", blockNum, sprint_hex(buf8, 16)); 
1097                 if (mfEmlSetMem(buf8
, blockNum
, 1)) { 
1098                         PrintAndLog("Cant set emul block: %d", blockNum
); 
1103                 if (blockNum 
>= 32 * 4 + 8 * 16) break; 
1107         if (blockNum 
!= 16 * 4 && blockNum 
!= 32 * 4 + 8 * 16){ 
1108                 PrintAndLog("File content error. There must be 64 blocks"); 
1111         PrintAndLog("Loaded from file: %s", filename
); 
1115 int CmdHF14AMfESave(const char *Cmd
) 
1119         char * fnameptr 
= filename
; 
1123         memset(filename
, 0, sizeof(filename
)); 
1124         memset(buf
, 0, sizeof(buf
)); 
1126         if (param_getchar(Cmd
, 0) == 'h') { 
1127                 PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`"); 
1128                 PrintAndLog("Usage:  hf mf esave [file name w/o `.eml`]"); 
1129                 PrintAndLog(" sample: hf mf esave "); 
1130                 PrintAndLog("         hf mf esave filename"); 
1135         if (len 
> 14) len 
= 14; 
1139                 if (mfEmlGetMem(buf
, 0, 1)) { 
1140                         PrintAndLog("Cant get block: %d", 0); 
1143                 for (j 
= 0; j 
< 7; j
++, fnameptr 
+= 2) 
1144                         sprintf(fnameptr
, "%02x", buf
[j
]);  
1146                 memcpy(filename
, Cmd
, len
); 
1150         sprintf(fnameptr
, ".eml");  
1153         f 
= fopen(filename
, "w+"); 
1156         for (i 
= 0; i 
< 32 * 4 + 8 * 16; i
++) { 
1157                 if (mfEmlGetMem(buf
, i
, 1)) { 
1158                         PrintAndLog("Cant get block: %d", i
); 
1161                 for (j 
= 0; j 
< 16; j
++) 
1162                         fprintf(f
, "%02x", buf
[j
]);  
1167         PrintAndLog("Saved to file: %s", filename
); 
1172 int CmdHF14AMfECFill(const char *Cmd
) 
1174         uint8_t keyType 
= 0; 
1176         if (strlen(Cmd
) < 1 || param_getchar(Cmd
, 0) == 'h') { 
1177                 PrintAndLog("Usage:  hf mf efill <key A/B>"); 
1178                 PrintAndLog("sample:  hf mf efill A"); 
1179                 PrintAndLog("Card data blocks transfers to card emulator memory."); 
1180                 PrintAndLog("Keys must be laid in the simulator memory. \n"); 
1184         char ctmp 
= param_getchar(Cmd
, 0); 
1186                 PrintAndLog("Key type must be A or B"); 
1189         if (ctmp 
!= 'A' && ctmp 
!= 'a') keyType 
= 1; 
1191   UsbCommand c 
= {CMD_MIFARE_EML_CARDLOAD
, {0, keyType
, 0}}; 
1196 int CmdHF14AMfEKeyPrn(const char *Cmd
) 
1200         uint64_t keyA
, keyB
; 
1202         PrintAndLog("|---|----------------|----------------|"); 
1203         PrintAndLog("|sec|key A           |key B           |"); 
1204         PrintAndLog("|---|----------------|----------------|"); 
1205         for (i 
= 0; i 
< 40; i
++) { 
1206                 b
<127?(b
+=4):(b
+=16); 
1207                 if (mfEmlGetMem(data
, b
, 1)) { 
1208                         PrintAndLog("error get block %d", b
); 
1211                 keyA 
= bytes_to_num(data
, 6); 
1212                 keyB 
= bytes_to_num(data 
+ 10, 6); 
1213                 PrintAndLog("|%03d|  %012llx  |  %012llx  |", i
, keyA
, keyB
); 
1215         PrintAndLog("|---|----------------|----------------|"); 
1220 int CmdHF14AMfCSetUID(const char *Cmd
) 
1222         uint8_t wipeCard 
= 0; 
1227         if (strlen(Cmd
) < 1 || param_getchar(Cmd
, 0) == 'h') { 
1228                 PrintAndLog("Usage:  hf mf csetuid <UID 8 hex symbols> <w>"); 
1229                 PrintAndLog("sample:  hf mf csetuid 01020304 w"); 
1230                 PrintAndLog("Set UID for magic Chinese card (only works with!!!)"); 
1231                 PrintAndLog("If you want wipe card then add 'w' into command line. \n"); 
1235         if (param_getchar(Cmd
, 0) && param_gethex(Cmd
, 0, uid
, 8)) { 
1236                 PrintAndLog("UID must include 8 HEX symbols"); 
1240         char ctmp 
= param_getchar(Cmd
, 1); 
1241         if (ctmp 
== 'w' || ctmp 
== 'W') wipeCard 
= 1; 
1243         PrintAndLog("--wipe card:%02x uid:%s", wipeCard
, sprint_hex(uid
, 4)); 
1245         res 
= mfCSetUID(uid
, oldUid
, wipeCard
); 
1247                         PrintAndLog("Can't set UID. error=%d", res
); 
1251         PrintAndLog("old UID:%s", sprint_hex(oldUid
, 4)); 
1255 int CmdHF14AMfCSetBlk(const char *Cmd
) 
1258         uint8_t memBlock
[16]; 
1259         uint8_t blockNo 
= 0; 
1261         memset(memBlock
, 0x00, sizeof(memBlock
)); 
1263         if (strlen(Cmd
) < 1 || param_getchar(Cmd
, 0) == 'h') { 
1264                 PrintAndLog("Usage:  hf mf csetblk <block number> <block data (32 hex symbols)>"); 
1265                 PrintAndLog("sample:  hf mf csetblk 1 01020304050607080910111213141516"); 
1266                 PrintAndLog("Set block data for magic Chinese card (only works with!!!)"); 
1267                 PrintAndLog("If you want wipe card then add 'w' into command line. \n"); 
1271         blockNo 
= param_get8(Cmd
, 0); 
1272         if (blockNo 
>= 32 * 4 + 8 * 16) { 
1273                 PrintAndLog("Block number must be in [0..255] as in MIFARE classic."); 
1277         if (param_gethex(Cmd
, 1, memBlock
, 32)) { 
1278                 PrintAndLog("block data must include 32 HEX symbols"); 
1282         PrintAndLog("--block number:%02x data:%s", blockNo
, sprint_hex(memBlock
, 16)); 
1284         res 
= mfCSetBlock(blockNo
, memBlock
, uid
, 0, CSETBLOCK_SINGLE_OPER
); 
1286                         PrintAndLog("Can't write block. error=%d", res
); 
1290         PrintAndLog("UID:%s", sprint_hex(uid
, 4)); 
1294 int CmdHF14AMfCLoad(const char *Cmd
) 
1298         char * fnameptr 
= filename
; 
1301         uint8_t fillFromEmulator 
= 0; 
1302         int i
, len
, blockNum
, flags
; 
1304         memset(filename
, 0, sizeof(filename
)); 
1305         memset(buf
, 0, sizeof(buf
)); 
1307         if (param_getchar(Cmd
, 0) == 'h' || param_getchar(Cmd
, 0)== 0x00) { 
1308                 PrintAndLog("It loads magic Chinese card (only works with!!!) from the file `filename.eml`"); 
1309                 PrintAndLog("or from emulator memory (option `e`)"); 
1310                 PrintAndLog("Usage:  hf mf cload <file name w/o `.eml`>"); 
1311                 PrintAndLog("   or:  hf mf cload e "); 
1312                 PrintAndLog(" sample: hf mf cload filename"); 
1316         char ctmp 
= param_getchar(Cmd
, 0); 
1317         if (ctmp 
== 'e' || ctmp 
== 'E') fillFromEmulator 
= 1; 
1319         if (fillFromEmulator
) { 
1320                 flags 
= CSETBLOCK_INIT_FIELD 
+ CSETBLOCK_WUPC
; 
1321                 for (blockNum 
= 0; blockNum 
< 16 * 4; blockNum 
+= 1) { 
1322                         if (mfEmlGetMem(buf8
, blockNum
, 1)) { 
1323                                 PrintAndLog("Cant get block: %d", blockNum
); 
1327                         if (blockNum 
== 2) flags 
= 0; 
1328                         if (blockNum 
== 16 * 4 - 1) flags 
= CSETBLOCK_HALT 
+ CSETBLOCK_RESET_FIELD
; 
1330                         if (mfCSetBlock(blockNum
, buf8
, NULL
, 0, flags
)) { 
1331                                 PrintAndLog("Cant set magic card block: %d", blockNum
); 
1338                 if (len 
> 14) len 
= 14; 
1340                 memcpy(filename
, Cmd
, len
); 
1343                 sprintf(fnameptr
, ".eml");  
1346                 f 
= fopen(filename
, "r"); 
1348                         PrintAndLog("File not found or locked."); 
1353                 flags 
= CSETBLOCK_INIT_FIELD 
+ CSETBLOCK_WUPC
; 
1355                         memset(buf
, 0, sizeof(buf
)); 
1356                         fgets(buf
, sizeof(buf
), f
); 
1358                         if (strlen(buf
) < 32){ 
1359                                 if(strlen(buf
) && feof(f
)) 
1361                                 PrintAndLog("File content error. Block data must include 32 HEX symbols"); 
1364                         for (i 
= 0; i 
< 32; i 
+= 2) 
1365                                 sscanf(&buf
[i
], "%02x", (unsigned int *)&buf8
[i 
/ 2]); 
1367                         if (blockNum 
== 2) flags 
= 0; 
1368                         if (blockNum 
== 16 * 4 - 1) flags 
= CSETBLOCK_HALT 
+ CSETBLOCK_RESET_FIELD
; 
1370                         if (mfCSetBlock(blockNum
, buf8
, NULL
, 0, flags
)) { 
1371                                 PrintAndLog("Cant set magic card block: %d", blockNum
); 
1376                         if (blockNum 
>= 16 * 4) break;  // magic card type - mifare 1K 
1380                 if (blockNum 
!= 16 * 4 && blockNum 
!= 32 * 4 + 8 * 16){ 
1381                         PrintAndLog("File content error. There must be 64 blocks"); 
1384                 PrintAndLog("Loaded from file: %s", filename
); 
1389 int CmdHF14AMfCGetBlk(const char *Cmd
) { 
1390         uint8_t memBlock
[16]; 
1391         uint8_t blockNo 
= 0; 
1393         memset(memBlock
, 0x00, sizeof(memBlock
)); 
1395         if (strlen(Cmd
) < 1 || param_getchar(Cmd
, 0) == 'h') { 
1396                 PrintAndLog("Usage:  hf mf cgetblk <block number>"); 
1397                 PrintAndLog("sample:  hf mf cgetblk 1"); 
1398                 PrintAndLog("Get block data from magic Chinese card (only works with!!!)\n"); 
1402         blockNo 
= param_get8(Cmd
, 0); 
1403         if (blockNo 
>= 32 * 4 + 8 * 16) { 
1404                 PrintAndLog("Block number must be in [0..255] as in MIFARE classic."); 
1408         PrintAndLog("--block number:%02x ", blockNo
); 
1410         res 
= mfCGetBlock(blockNo
, memBlock
, CSETBLOCK_SINGLE_OPER
); 
1412                         PrintAndLog("Can't read block. error=%d", res
); 
1416         PrintAndLog("block data:%s", sprint_hex(memBlock
, 16)); 
1420 int CmdHF14AMfCGetSc(const char *Cmd
) { 
1421         uint8_t memBlock
[16]; 
1422         uint8_t sectorNo 
= 0; 
1424         memset(memBlock
, 0x00, sizeof(memBlock
)); 
1426         if (strlen(Cmd
) < 1 || param_getchar(Cmd
, 0) == 'h') { 
1427                 PrintAndLog("Usage:  hf mf cgetsc <sector number>"); 
1428                 PrintAndLog("sample:  hf mf cgetsc 0"); 
1429                 PrintAndLog("Get sector data from magic Chinese card (only works with!!!)\n"); 
1433         sectorNo 
= param_get8(Cmd
, 0); 
1434         if (sectorNo 
> 15) { 
1435                 PrintAndLog("Sector number must be in [0..15] as in MIFARE classic."); 
1439         PrintAndLog("--sector number:%02x ", sectorNo
); 
1441         flags 
= CSETBLOCK_INIT_FIELD 
+ CSETBLOCK_WUPC
; 
1442         for (i 
= 0; i 
< 4; i
++) { 
1443                 if (i 
== 1) flags 
= 0; 
1444                 if (i 
== 3) flags 
= CSETBLOCK_HALT 
+ CSETBLOCK_RESET_FIELD
; 
1446                 res 
= mfCGetBlock(sectorNo 
* 4 + i
, memBlock
, flags
); 
1448                         PrintAndLog("Can't read block. %02x error=%d", sectorNo 
* 4 + i
, res
); 
1452                 PrintAndLog("block %02x data:%s", sectorNo 
* 4 + i
, sprint_hex(memBlock
, 16)); 
1457 int CmdHF14AMfCSave(const char *Cmd
) { 
1461         char * fnameptr 
= filename
; 
1462         uint8_t fillFromEmulator 
= 0; 
1464         int i
, j
, len
, flags
; 
1466         memset(filename
, 0, sizeof(filename
)); 
1467         memset(buf
, 0, sizeof(buf
)); 
1469         if (param_getchar(Cmd
, 0) == 'h') { 
1470                 PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`"); 
1471                 PrintAndLog("or into emulator memory (option `e`)"); 
1472                 PrintAndLog("Usage:  hf mf esave [file name w/o `.eml`][e]"); 
1473                 PrintAndLog(" sample: hf mf esave "); 
1474                 PrintAndLog("         hf mf esave filename"); 
1475                 PrintAndLog("         hf mf esave e \n"); 
1479         char ctmp 
= param_getchar(Cmd
, 0); 
1480         if (ctmp 
== 'e' || ctmp 
== 'E') fillFromEmulator 
= 1; 
1482         if (fillFromEmulator
) { 
1483                 // put into emulator 
1484                 flags 
= CSETBLOCK_INIT_FIELD 
+ CSETBLOCK_WUPC
; 
1485                 for (i 
= 0; i 
< 16 * 4; i
++) { 
1486                         if (i 
== 1) flags 
= 0; 
1487                         if (i 
== 16 * 4 - 1) flags 
= CSETBLOCK_HALT 
+ CSETBLOCK_RESET_FIELD
; 
1489                         if (mfCGetBlock(i
, buf
, flags
)) { 
1490                                 PrintAndLog("Cant get block: %d", i
); 
1494                         if (mfEmlSetMem(buf
, i
, 1)) { 
1495                                 PrintAndLog("Cant set emul block: %d", i
); 
1502                 if (len 
> 14) len 
= 14; 
1506                         if (mfCGetBlock(0, buf
, CSETBLOCK_SINGLE_OPER
)) { 
1507                                 PrintAndLog("Cant get block: %d", 0); 
1510                         for (j 
= 0; j 
< 7; j
++, fnameptr 
+= 2) 
1511                                 sprintf(fnameptr
, "%02x", buf
[j
]);  
1513                         memcpy(filename
, Cmd
, len
); 
1517                 sprintf(fnameptr
, ".eml");  
1520                 f 
= fopen(filename
, "w+"); 
1523                 flags 
= CSETBLOCK_INIT_FIELD 
+ CSETBLOCK_WUPC
; 
1524                 for (i 
= 0; i 
< 16 * 4; i
++) { 
1525                         if (i 
== 1) flags 
= 0; 
1526                         if (i 
== 16 * 4 - 1) flags 
= CSETBLOCK_HALT 
+ CSETBLOCK_RESET_FIELD
; 
1528                         if (mfCGetBlock(i
, buf
, flags
)) { 
1529                                 PrintAndLog("Cant get block: %d", i
); 
1532                         for (j 
= 0; j 
< 16; j
++) 
1533                                 fprintf(f
, "%02x", buf
[j
]);  
1538                 PrintAndLog("Saved to file: %s", filename
); 
1544 int CmdHF14AMfSniff(const char *Cmd
){ 
1546         bool wantLogToFile 
= 1; 
1547         bool wantDecrypt 
= 1; 
1548         bool wantSaveToEml 
= 0; 
1549         bool wantSaveToEmlFile 
= 0; 
1562         uint8_t * bufPtr 
= buf
; 
1563         memset(buf
, 0x00, 3000); 
1565         if (param_getchar(Cmd
, 0) == 'h') { 
1566                 PrintAndLog("It continuously get data from the field and saves it to: log, emulator, emulator file."); 
1567                 PrintAndLog("You can specify:"); 
1568                 PrintAndLog("    l - save encrypted sequence to logfile `uid.log`"); 
1569                 PrintAndLog("    d - decrypt sequence and put it to log file `uid.log`"); 
1570                 PrintAndLog(" n/a   e - decrypt sequence, collect read and write commands and save the result of the sequence to emulator memory"); 
1571                 PrintAndLog("    r - decrypt sequence, collect read and write commands and save the result of the sequence to emulator dump file `uid.eml`"); 
1572                 PrintAndLog("Usage:  hf mf sniff [l][d][e][r]"); 
1573                 PrintAndLog("  sample: hf mf sniff l d e"); 
1577         for (int i 
= 0; i 
< 4; i
++) { 
1578                 char ctmp 
= param_getchar(Cmd
, i
); 
1579                 if (ctmp 
== 'l' || ctmp 
== 'L') wantLogToFile 
= true; 
1580                 if (ctmp 
== 'd' || ctmp 
== 'D') wantDecrypt 
= true; 
1581                 if (ctmp 
== 'e' || ctmp 
== 'E') wantSaveToEml 
= true; 
1582                 if (ctmp 
== 'f' || ctmp 
== 'F') wantSaveToEmlFile 
= true; 
1585         printf("-------------------------------------------------------------------------\n"); 
1586         printf("Executing command. \n"); 
1587         printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n"); 
1588         printf("Press the key on pc keyboard to abort the client.\n"); 
1589         printf("-------------------------------------------------------------------------\n"); 
1591   UsbCommand c 
= {CMD_MIFARE_SNIFFER
, {0, 0, 0}}; 
1600                         printf("\naborted via keyboard!\n"); 
1604                 UsbCommand 
* resp 
= WaitForResponseTimeout(CMD_ACK
, 2000); 
1606                         res 
= resp
->arg
[0] & 0xff; 
1610                         if (res 
== 0) return 0; 
1614                                         memset(buf
, 0x00, 3000); 
1616                                 memcpy(bufPtr
, resp
->d
.asBytes
, len
); 
1621                                 blockLen 
= bufPtr 
- buf
; 
1624                                 PrintAndLog("received trace len: %d packages: %d", blockLen
, pckNum
); 
1626                                 while (bufPtr 
- buf 
+ 9 < blockLen
) { 
1627                                   isTag 
= bufPtr
[3] & 0x80 ? true:false; 
1631                                         if ((len 
== 14) && (bufPtr
[0] = 0xff) && (bufPtr
[1] = 0xff)) { 
1632                                                 memcpy(uid
, bufPtr 
+ 2, 7); 
1633                                                 memcpy(atqa
, bufPtr 
+ 2 + 7, 2); 
1636                                                 PrintAndLog("tag select uid:%s atqa:%02x %02x sak:0x%02x", sprint_hex(uid
, 7), atqa
[0], atqa
[1], sak
); 
1637                                                 if (wantLogToFile
) { 
1638                                                         FillFileNameByUID(logHexFileName
, uid
, ".log", 7); 
1639                                                         AddLogCurrentDT(logHexFileName
); 
1641                                                 if (wantDecrypt
) mfTraceInit(uid
, atqa
, sak
, wantSaveToEmlFile
); 
1643                                                 PrintAndLog("%s(%d):%s", isTag 
? "TAG":"RDR", num
, sprint_hex(bufPtr
, len
)); 
1644                                                 if (wantLogToFile
) AddLogHex(logHexFileName
, isTag 
? "TAG: ":"RDR: ", bufPtr
, len
); 
1645                                                 if (wantDecrypt
) mfTraceDecode(bufPtr
, len
, wantSaveToEmlFile
); 
1656 static command_t CommandTable
[] = 
1658   {"help",              CmdHelp
,                                                1, "This help"}, 
1659   {"dbg",                       CmdHF14AMfDbg
,                  0, "Set default debug mode"}, 
1660   {"rdbl",              CmdHF14AMfRdBl
,                 0, "Read MIFARE classic block"}, 
1661   {"rdsc",              CmdHF14AMfRdSc
,                 0, "Read MIFARE classic sector"}, 
1662   {"dump",              CmdHF14AMfDump
,                 0, "Dump MIFARE classic tag to binary file"}, 
1663   {"restore",   CmdHF14AMfRestore
,      0, "Restore MIFARE classic binary file to BLANK tag"}, 
1664   {"wrbl",              CmdHF14AMfWrBl
,                 0, "Write MIFARE classic block"}, 
1665   {"chk",                       CmdHF14AMfChk
,                  0, "Test block keys"}, 
1666   {"mifare",    CmdHF14AMifare
,                 0, "Read parity error messages. param - <used card nonce>"}, 
1667   {"nested",    CmdHF14AMfNested
,               0, "Test nested authentication"}, 
1668   {"sniff",             CmdHF14AMfSniff
,                0, "Sniff card-reader communication"}, 
1669   {"sim",                       CmdHF14AMf1kSim
,                0, "Simulate MIFARE card"}, 
1670   {"eclr",              CmdHF14AMfEClear
,               0, "Clear simulator memory block"}, 
1671   {"eget",              CmdHF14AMfEGet
,                 0, "Get simulator memory block"}, 
1672   {"eset",              CmdHF14AMfESet
,                 0, "Set simulator memory block"}, 
1673   {"eload",             CmdHF14AMfELoad
,                0, "Load from file emul dump"}, 
1674   {"esave",             CmdHF14AMfESave
,                0, "Save to file emul dump"}, 
1675   {"ecfill",    CmdHF14AMfECFill
,               0, "Fill simulator memory with help of keys from simulator"}, 
1676   {"ekeyprn",   CmdHF14AMfEKeyPrn
,      0, "Print keys from simulator memory"}, 
1677   {"csetuid",   CmdHF14AMfCSetUID
,      0, "Set UID for magic Chinese card"}, 
1678   {"csetblk",   CmdHF14AMfCSetBlk
,      0, "Write block into magic Chinese card"}, 
1679   {"cgetblk",   CmdHF14AMfCGetBlk
,      0, "Read block from magic Chinese card"}, 
1680   {"cgetsc",    CmdHF14AMfCGetSc
,               0, "Read sector from magic Chinese card"}, 
1681   {"cload",             CmdHF14AMfCLoad
,                0, "Load dump into magic Chinese card"}, 
1682   {"csave",             CmdHF14AMfCSave
,                0, "Save dump from magic Chinese card into file or emulator"}, 
1683   {NULL
, NULL
, 0, NULL
} 
1686 int CmdHFMF(const char *Cmd
) 
1689         while (WaitForResponseTimeout(CMD_ACK
, 500) != NULL
) ; 
1691   CmdsParse(CommandTable
, Cmd
); 
1695 int CmdHelp(const char *Cmd
) 
1697   CmdsHelp(CommandTable
);